From 891051091718f99c9c96e902a325262c552261b4 Mon Sep 17 00:00:00 2001 From: jnywong Date: Mon, 13 Jan 2025 11:19:26 +0000 Subject: [PATCH 01/19] Add button directive Co-authored-by: Angus Hollands --- packages/myst-directives/src/button.ts | 37 ++++++++++++++++++++++++++ packages/myst-spec-ext/src/types.ts | 2 ++ 2 files changed, 39 insertions(+) create mode 100644 packages/myst-directives/src/button.ts diff --git a/packages/myst-directives/src/button.ts b/packages/myst-directives/src/button.ts new file mode 100644 index 000000000..87efe4713 --- /dev/null +++ b/packages/myst-directives/src/button.ts @@ -0,0 +1,37 @@ +import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common'; +import type { Link } from 'myst-spec-ext'; +import { addClassOptions, classDirectiveOption } from './utils.js'; + +export const buttonDirective: DirectiveSpec = { + name: 'button', + doc: 'Button to navigate to external or internal links.', + arg: { + type: String, + doc: 'Target link of the button.', + required: true, + }, + options: { + ...classDirectiveOption('button'), + }, + body: { + type: 'myst', + doc: 'The body of the button.', + required: false, + }, + run(data: DirectiveData): GenericNode[] { + const children: GenericNode[] = []; + if (data.body) { + children.push(...data.body as GenericNode[]); + } + const node: Link = { + type: 'link', + kind: 'button', + url: data.arg as string, + children: children as any[], + }; + addClassOptions(data, node) + return [ + node + ]; + }, +}; diff --git a/packages/myst-spec-ext/src/types.ts b/packages/myst-spec-ext/src/types.ts index b808b82be..8b241d688 100644 --- a/packages/myst-spec-ext/src/types.ts +++ b/packages/myst-spec-ext/src/types.ts @@ -284,6 +284,8 @@ export type Link = SpecLink & { static?: true; protocol?: string; error?: true; + kind?: 'button'; + class?: Image['class']; }; // Search types From 9a8dae9a17c6a8bb1b83e0d1d377b724f48ac268 Mon Sep 17 00:00:00 2001 From: jnywong Date: Mon, 13 Jan 2025 13:40:04 +0000 Subject: [PATCH 02/19] Update index.ts --- packages/myst-directives/src/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/myst-directives/src/index.ts b/packages/myst-directives/src/index.ts index f3766426d..8d6f15c48 100644 --- a/packages/myst-directives/src/index.ts +++ b/packages/myst-directives/src/index.ts @@ -1,4 +1,5 @@ import { admonitionDirective } from './admonition.js'; +import { buttonDirective } from './button.js'; import { bibliographyDirective } from './bibliography.js'; import { codeDirective, codeCellDirective } from './code.js'; import { dropdownDirective } from './dropdown.js'; @@ -21,6 +22,7 @@ import { divDirective } from './div.js'; export const defaultDirectives = [ admonitionDirective, + buttonDirective, bibliographyDirective, csvTableDirective, codeDirective, @@ -50,6 +52,7 @@ export const defaultDirectives = [ export * from './utils.js'; export { admonitionDirective } from './admonition.js'; +export { buttonDirective } from './button.js'; export { bibliographyDirective } from './bibliography.js'; export { codeDirective } from './code.js'; export { dropdownDirective } from './dropdown.js'; From 413f7066e9a20d95233b583d247504c9bd0073b3 Mon Sep 17 00:00:00 2001 From: jnywong Date: Mon, 13 Jan 2025 14:36:45 +0000 Subject: [PATCH 03/19] Change from directive to role --- package-lock.json | 16 +++ packages/myst-cli/package.json | 1 + packages/myst-cli/src/process/myst.ts | 6 +- packages/myst-directives/src/button.ts | 37 ------ packages/myst-directives/src/index.ts | 3 - packages/myst-ext-button/.eslintrc.cjs | 4 + packages/myst-ext-button/CHANGELOG.md | 125 ++++++++++++++++++ packages/myst-ext-button/README.md | 3 + packages/myst-ext-button/package.json | 41 ++++++ packages/myst-ext-button/src/index.ts | 30 +++++ packages/myst-ext-button/tests/button.spec.ts | 0 packages/myst-ext-button/tsconfig.json | 8 ++ 12 files changed, 233 insertions(+), 41 deletions(-) delete mode 100644 packages/myst-directives/src/button.ts create mode 100644 packages/myst-ext-button/.eslintrc.cjs create mode 100644 packages/myst-ext-button/CHANGELOG.md create mode 100644 packages/myst-ext-button/README.md create mode 100644 packages/myst-ext-button/package.json create mode 100644 packages/myst-ext-button/src/index.ts create mode 100644 packages/myst-ext-button/tests/button.spec.ts create mode 100644 packages/myst-ext-button/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 40bbd6411..e7c3028bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10032,6 +10032,10 @@ "resolved": "packages/myst-execute", "link": true }, + "node_modules/myst-ext-button": { + "resolved": "packages/myst-ext-button", + "link": true + }, "node_modules/myst-ext-card": { "resolved": "packages/myst-ext-card", "link": true @@ -15482,6 +15486,7 @@ "myst-common": "^1.7.6", "myst-config": "^1.7.6", "myst-execute": "^0.1.2", + "myst-ext-button": "^0.0.0", "myst-ext-card": "^1.0.9", "myst-ext-exercise": "^1.0.9", "myst-ext-grid": "^1.0.9", @@ -15776,6 +15781,17 @@ "node": "^16.13.0 || >=18.0.0" } }, + "packages/myst-ext-button": { + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "myst-common": "^1.7.2", + "myst-spec-ext": "^1.7.6" + }, + "devDependencies": { + "myst-parser": "^1.5.7" + } + }, "packages/myst-ext-card": { "version": "1.0.9", "license": "MIT", diff --git a/packages/myst-cli/package.json b/packages/myst-cli/package.json index d9e8133b5..29e78d42d 100644 --- a/packages/myst-cli/package.json +++ b/packages/myst-cli/package.json @@ -72,6 +72,7 @@ "myst-common": "^1.7.6", "myst-config": "^1.7.6", "myst-execute": "^0.1.2", + "myst-ext-button": "^0.0.0", "myst-ext-card": "^1.0.9", "myst-ext-exercise": "^1.0.9", "myst-ext-grid": "^1.0.9", diff --git a/packages/myst-cli/src/process/myst.ts b/packages/myst-cli/src/process/myst.ts index 175139819..d9461e08e 100644 --- a/packages/myst-cli/src/process/myst.ts +++ b/packages/myst-cli/src/process/myst.ts @@ -1,4 +1,5 @@ import { mystParse } from 'myst-parser'; +import { buttonRole } from 'myst-ext-button'; import { cardDirective } from 'myst-ext-card'; import { gridDirectives } from 'myst-ext-grid'; import { proofDirective } from 'myst-ext-proof'; @@ -47,7 +48,10 @@ export function parseMyst( extensions: { frontmatter: !opts?.ignoreFrontmatter, }, - roles: [...(session.plugins?.roles ?? [])], + roles: [ + buttonRole, + ...(session.plugins?.roles ?? []) + ], vfile, }); logMessagesFromVFile(session, vfile); diff --git a/packages/myst-directives/src/button.ts b/packages/myst-directives/src/button.ts deleted file mode 100644 index 87efe4713..000000000 --- a/packages/myst-directives/src/button.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common'; -import type { Link } from 'myst-spec-ext'; -import { addClassOptions, classDirectiveOption } from './utils.js'; - -export const buttonDirective: DirectiveSpec = { - name: 'button', - doc: 'Button to navigate to external or internal links.', - arg: { - type: String, - doc: 'Target link of the button.', - required: true, - }, - options: { - ...classDirectiveOption('button'), - }, - body: { - type: 'myst', - doc: 'The body of the button.', - required: false, - }, - run(data: DirectiveData): GenericNode[] { - const children: GenericNode[] = []; - if (data.body) { - children.push(...data.body as GenericNode[]); - } - const node: Link = { - type: 'link', - kind: 'button', - url: data.arg as string, - children: children as any[], - }; - addClassOptions(data, node) - return [ - node - ]; - }, -}; diff --git a/packages/myst-directives/src/index.ts b/packages/myst-directives/src/index.ts index 8d6f15c48..f3766426d 100644 --- a/packages/myst-directives/src/index.ts +++ b/packages/myst-directives/src/index.ts @@ -1,5 +1,4 @@ import { admonitionDirective } from './admonition.js'; -import { buttonDirective } from './button.js'; import { bibliographyDirective } from './bibliography.js'; import { codeDirective, codeCellDirective } from './code.js'; import { dropdownDirective } from './dropdown.js'; @@ -22,7 +21,6 @@ import { divDirective } from './div.js'; export const defaultDirectives = [ admonitionDirective, - buttonDirective, bibliographyDirective, csvTableDirective, codeDirective, @@ -52,7 +50,6 @@ export const defaultDirectives = [ export * from './utils.js'; export { admonitionDirective } from './admonition.js'; -export { buttonDirective } from './button.js'; export { bibliographyDirective } from './bibliography.js'; export { codeDirective } from './code.js'; export { dropdownDirective } from './dropdown.js'; diff --git a/packages/myst-ext-button/.eslintrc.cjs b/packages/myst-ext-button/.eslintrc.cjs new file mode 100644 index 000000000..76787609a --- /dev/null +++ b/packages/myst-ext-button/.eslintrc.cjs @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ['curvenote'], +}; diff --git a/packages/myst-ext-button/CHANGELOG.md b/packages/myst-ext-button/CHANGELOG.md new file mode 100644 index 000000000..627aa43d5 --- /dev/null +++ b/packages/myst-ext-button/CHANGELOG.md @@ -0,0 +1,125 @@ +# myst-ext-card + +## 1.0.9 + +### Patch Changes + +- ce3c11c: Update inter-version deps + +## 1.0.8 + +### Patch Changes + +- c758f1b5: Directive option flag is always a boolean +- 0a516e5: Add documentation and an alias for url/link in cards. + +## 1.0.7 + +### Patch Changes + +- b3e9df9d: Update to Project Jupyter and change all URLs +- Updated dependencies [b3e9df9d] + - myst-common@1.5.1 + +## 1.0.6 + +### Patch Changes + +- 69457615: Update dependencies +- Updated dependencies [e0cd47e3] + - myst-common@1.3.0 + +## 1.0.5 + +### Patch Changes + +- 6354420: Update versions of myst packages + +## 1.0.4 + +### Patch Changes + +- 4183c05c: Change to use String/Number/Boolean instead of ParsedEnumType +- d35e02bc: Change from alias as string to alias as a string-list. +- Updated dependencies [d35e02bc] +- Updated dependencies [b74fb3c1] +- Updated dependencies [ed7b430f] +- Updated dependencies [239ae762] +- Updated dependencies [b74fb3c1] +- Updated dependencies [86c78957] +- Updated dependencies [d35e02bc] +- Updated dependencies [d35e02bc] +- Updated dependencies [99659250] + - myst-common@1.1.7 + +## 1.0.3 + +### Patch Changes + +- 7752cb70: Bump dependency versions +- Updated dependencies [7752cb70] + - myst-common@1.1.5 + +## 1.0.2 + +### Patch Changes + +- Updates to internal dependencies +- Updated dependencies [44ff6917] +- Updated dependencies + - myst-common@1.1.0 + +## 1.0.1 + +### Patch Changes + +- b0a2a34b: Move repositories from mystjs --> mystmd +- Updated dependencies [b0a2a34b] + - myst-common@1.0.2 + +## 1.0.0 + +### Major Changes + +- 00c05fe9: Migrate to ESM modules + +## 0.0.7 + +### Patch Changes + +- Updated dependencies [79e24fd7] + - myst-common@0.0.17 + +## 0.0.6 + +### Patch Changes + +- Updated dependencies [d28b5e9d] + - myst-common@0.0.16 + +## 0.0.5 + +### Patch Changes + +- Updated dependencies [c832b38e] + - myst-common@0.0.15 + +## 0.0.4 + +### Patch Changes + +- Updated dependencies [9105d991] + - myst-common@0.0.14 + +## 0.0.3 + +### Patch Changes + +- Updated dependencies + - myst-common@0.0.13 + +## 0.0.2 + +### Patch Changes + +- a22fafa0: Separate packages for card/tab/grid/reactive roles/directives diff --git a/packages/myst-ext-button/README.md b/packages/myst-ext-button/README.md new file mode 100644 index 000000000..bdf031fd0 --- /dev/null +++ b/packages/myst-ext-button/README.md @@ -0,0 +1,3 @@ +# myst-ext-button + +`mystmd` extension for `button` role diff --git a/packages/myst-ext-button/package.json b/packages/myst-ext-button/package.json new file mode 100644 index 000000000..24770f392 --- /dev/null +++ b/packages/myst-ext-button/package.json @@ -0,0 +1,41 @@ +{ + "name": "myst-ext-button", + "version": "0.0.0", + "sideEffects": false, + "license": "MIT", + "description": "MyST extension for button role", + "author": "Jenny Wong ", + "homepage": "https://github.com/jupyter-book/mystmd/tree/main/packages/myst-ext-button", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jupyter-book/mystmd.git" + }, + "scripts": { + "clean": "rimraf dist", + "lint": "eslint \"src/**/!(*.spec).ts\" -c ./.eslintrc.cjs", + "lint:format": "npx prettier --check \"src/**/*.ts\"", + "test": "vitest run", + "test:watch": "vitest watch", + "build:esm": "tsc", + "build": "npm-run-all -l clean -p build:esm" + }, + "bugs": { + "url": "https://github.com/jupyter-book/mystmd/issues" + }, + "dependencies": { + "myst-common": "^1.7.2", + "myst-spec-ext": "^1.7.6" + }, + "devDependencies": { + "myst-parser": "^1.5.7" + } +} diff --git a/packages/myst-ext-button/src/index.ts b/packages/myst-ext-button/src/index.ts new file mode 100644 index 000000000..dc5bc9193 --- /dev/null +++ b/packages/myst-ext-button/src/index.ts @@ -0,0 +1,30 @@ +import type { RoleSpec, RoleData, GenericNode } from 'myst-common'; +import type { Link } from 'myst-spec-ext'; + +const REF_PATTERN = /^(.+?)<([^<>]+)>$/; + +export const buttonRole: RoleSpec = { + name: 'button', + doc: 'Button to navigate to external or internal links.', + body: { + type: String, + doc: 'The body of the button.', + required: true, + }, + run(data: RoleData): GenericNode[] { + const body = data.body as string; + const match = REF_PATTERN.exec(body); + const [, modified, rawLabel] = match ?? []; + const url = rawLabel ?? body; + const node: Link = { + type: 'link', + kind: 'button', + url, + children: [], + }; + if (modified) node.children = [{ type: 'text', value: modified.trim() }]; + return [ + node + ]; + }, +}; diff --git a/packages/myst-ext-button/tests/button.spec.ts b/packages/myst-ext-button/tests/button.spec.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/myst-ext-button/tsconfig.json b/packages/myst-ext-button/tsconfig.json new file mode 100644 index 000000000..1c5c0f1c4 --- /dev/null +++ b/packages/myst-ext-button/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig/base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["."], + "exclude": ["dist", "build", "node_modules", "src/**/*.spec.ts", "tests"] +} From 3a3feea38203712201d4930a39f2767d68650a47 Mon Sep 17 00:00:00 2001 From: jnywong Date: Mon, 13 Jan 2025 15:49:01 +0000 Subject: [PATCH 04/19] Delete changelog --- packages/myst-ext-button/CHANGELOG.md | 125 -------------------------- 1 file changed, 125 deletions(-) delete mode 100644 packages/myst-ext-button/CHANGELOG.md diff --git a/packages/myst-ext-button/CHANGELOG.md b/packages/myst-ext-button/CHANGELOG.md deleted file mode 100644 index 627aa43d5..000000000 --- a/packages/myst-ext-button/CHANGELOG.md +++ /dev/null @@ -1,125 +0,0 @@ -# myst-ext-card - -## 1.0.9 - -### Patch Changes - -- ce3c11c: Update inter-version deps - -## 1.0.8 - -### Patch Changes - -- c758f1b5: Directive option flag is always a boolean -- 0a516e5: Add documentation and an alias for url/link in cards. - -## 1.0.7 - -### Patch Changes - -- b3e9df9d: Update to Project Jupyter and change all URLs -- Updated dependencies [b3e9df9d] - - myst-common@1.5.1 - -## 1.0.6 - -### Patch Changes - -- 69457615: Update dependencies -- Updated dependencies [e0cd47e3] - - myst-common@1.3.0 - -## 1.0.5 - -### Patch Changes - -- 6354420: Update versions of myst packages - -## 1.0.4 - -### Patch Changes - -- 4183c05c: Change to use String/Number/Boolean instead of ParsedEnumType -- d35e02bc: Change from alias as string to alias as a string-list. -- Updated dependencies [d35e02bc] -- Updated dependencies [b74fb3c1] -- Updated dependencies [ed7b430f] -- Updated dependencies [239ae762] -- Updated dependencies [b74fb3c1] -- Updated dependencies [86c78957] -- Updated dependencies [d35e02bc] -- Updated dependencies [d35e02bc] -- Updated dependencies [99659250] - - myst-common@1.1.7 - -## 1.0.3 - -### Patch Changes - -- 7752cb70: Bump dependency versions -- Updated dependencies [7752cb70] - - myst-common@1.1.5 - -## 1.0.2 - -### Patch Changes - -- Updates to internal dependencies -- Updated dependencies [44ff6917] -- Updated dependencies - - myst-common@1.1.0 - -## 1.0.1 - -### Patch Changes - -- b0a2a34b: Move repositories from mystjs --> mystmd -- Updated dependencies [b0a2a34b] - - myst-common@1.0.2 - -## 1.0.0 - -### Major Changes - -- 00c05fe9: Migrate to ESM modules - -## 0.0.7 - -### Patch Changes - -- Updated dependencies [79e24fd7] - - myst-common@0.0.17 - -## 0.0.6 - -### Patch Changes - -- Updated dependencies [d28b5e9d] - - myst-common@0.0.16 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies [c832b38e] - - myst-common@0.0.15 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies [9105d991] - - myst-common@0.0.14 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies - - myst-common@0.0.13 - -## 0.0.2 - -### Patch Changes - -- a22fafa0: Separate packages for card/tab/grid/reactive roles/directives From b68fb3b07396ef412829a9c7fae393960116e8dd Mon Sep 17 00:00:00 2001 From: jnywong Date: Wed, 15 Jan 2025 12:11:08 +0000 Subject: [PATCH 05/19] Fix linting --- packages/myst-cli/src/process/myst.ts | 5 +---- packages/myst-ext-button/src/index.ts | 10 ++++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/myst-cli/src/process/myst.ts b/packages/myst-cli/src/process/myst.ts index d9461e08e..389b65e2a 100644 --- a/packages/myst-cli/src/process/myst.ts +++ b/packages/myst-cli/src/process/myst.ts @@ -48,10 +48,7 @@ export function parseMyst( extensions: { frontmatter: !opts?.ignoreFrontmatter, }, - roles: [ - buttonRole, - ...(session.plugins?.roles ?? []) - ], + roles: [buttonRole, ...(session.plugins?.roles ?? [])], vfile, }); logMessagesFromVFile(session, vfile); diff --git a/packages/myst-ext-button/src/index.ts b/packages/myst-ext-button/src/index.ts index dc5bc9193..735ba3914 100644 --- a/packages/myst-ext-button/src/index.ts +++ b/packages/myst-ext-button/src/index.ts @@ -7,9 +7,9 @@ export const buttonRole: RoleSpec = { name: 'button', doc: 'Button to navigate to external or internal links.', body: { - type: String, - doc: 'The body of the button.', - required: true, + type: String, + doc: 'The body of the button.', + required: true, }, run(data: RoleData): GenericNode[] { const body = data.body as string; @@ -23,8 +23,6 @@ export const buttonRole: RoleSpec = { children: [], }; if (modified) node.children = [{ type: 'text', value: modified.trim() }]; - return [ - node - ]; + return [node]; }, }; From 2f735713b621ae523197b0076b8243a2fad8c035 Mon Sep 17 00:00:00 2001 From: jnywong Date: Wed, 15 Jan 2025 12:29:51 +0000 Subject: [PATCH 06/19] Remove test --- packages/myst-ext-button/tests/button.spec.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/myst-ext-button/tests/button.spec.ts diff --git a/packages/myst-ext-button/tests/button.spec.ts b/packages/myst-ext-button/tests/button.spec.ts deleted file mode 100644 index e69de29bb..000000000 From 3b0795ef40a09ba6b9162132ef52359fd08c7cda Mon Sep 17 00:00:00 2001 From: jnywong Date: Wed, 15 Jan 2025 12:44:14 +0000 Subject: [PATCH 07/19] Add buttonRoles test --- packages/myst-ext-button/tests/button.spec.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 packages/myst-ext-button/tests/button.spec.ts diff --git a/packages/myst-ext-button/tests/button.spec.ts b/packages/myst-ext-button/tests/button.spec.ts new file mode 100644 index 000000000..ff4c6e166 --- /dev/null +++ b/packages/myst-ext-button/tests/button.spec.ts @@ -0,0 +1,31 @@ +import { describe, expect, it } from 'vitest'; +import { buttonRole } from '../src'; +import type { RoleData } from 'myst-common'; + +describe('Button component', () => { + it('should process button role correctly', () => { + const data: RoleData = { body: 'Click me' }; + const result = buttonRole.run(data); + expect(result).toEqual([ + { + type: 'link', + kind: 'button', + url: 'http://example.com', + children: [{ type: 'text', value: 'Click me' }], + }, + ]); + }); + + it('should process button role without label correctly', () => { + const data: RoleData = { body: 'http://example.com' }; + const result = buttonRole.run(data); + expect(result).toEqual([ + { + type: 'link', + kind: 'button', + url: 'http://example.com', + children: [], + }, + ]); + }); +}); From f30bb66a0d39753cdbf33cc66721d311a2ebfbcc Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Thu, 23 Jan 2025 13:22:41 +0000 Subject: [PATCH 08/19] refactor: use 'class' exclusively for buttons --- packages/myst-ext-button/src/index.ts | 2 +- packages/myst-ext-button/tests/button.spec.ts | 16 +++++++++------- packages/myst-spec-ext/src/types.ts | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/myst-ext-button/src/index.ts b/packages/myst-ext-button/src/index.ts index 735ba3914..cd93b91c8 100644 --- a/packages/myst-ext-button/src/index.ts +++ b/packages/myst-ext-button/src/index.ts @@ -18,9 +18,9 @@ export const buttonRole: RoleSpec = { const url = rawLabel ?? body; const node: Link = { type: 'link', - kind: 'button', url, children: [], + class: 'button', // TODO: allow users to extend this }; if (modified) node.children = [{ type: 'text', value: modified.trim() }]; return [node]; diff --git a/packages/myst-ext-button/tests/button.spec.ts b/packages/myst-ext-button/tests/button.spec.ts index ff4c6e166..8dceb74e5 100644 --- a/packages/myst-ext-button/tests/button.spec.ts +++ b/packages/myst-ext-button/tests/button.spec.ts @@ -1,15 +1,18 @@ import { describe, expect, it } from 'vitest'; import { buttonRole } from '../src'; -import type { RoleData } from 'myst-common'; +import { VFile } from 'vfile'; describe('Button component', () => { it('should process button role correctly', () => { - const data: RoleData = { body: 'Click me' }; - const result = buttonRole.run(data); + const result = buttonRole.run( + { name: 'button', body: 'Click me' }, + new VFile(), + ); + expect(result).toEqual([ { type: 'link', - kind: 'button', + class: 'button', url: 'http://example.com', children: [{ type: 'text', value: 'Click me' }], }, @@ -17,12 +20,11 @@ describe('Button component', () => { }); it('should process button role without label correctly', () => { - const data: RoleData = { body: 'http://example.com' }; - const result = buttonRole.run(data); + const result = buttonRole.run({ name: 'button', body: 'http://example.com' }, new VFile()); expect(result).toEqual([ { type: 'link', - kind: 'button', + class: 'button', url: 'http://example.com', children: [], }, diff --git a/packages/myst-spec-ext/src/types.ts b/packages/myst-spec-ext/src/types.ts index 8b241d688..0a2d793b9 100644 --- a/packages/myst-spec-ext/src/types.ts +++ b/packages/myst-spec-ext/src/types.ts @@ -275,6 +275,7 @@ export type CrossReference = SpecCrossReference & { dataUrl?: string; remoteBaseUrl?: string; html_id?: string; + class?: Image['class']; }; export type Link = SpecLink & { @@ -284,7 +285,6 @@ export type Link = SpecLink & { static?: true; protocol?: string; error?: true; - kind?: 'button'; class?: Image['class']; }; From 67850a6d5931b2192fdce6436f46b7bdc0706086 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Thu, 23 Jan 2025 17:04:35 +0000 Subject: [PATCH 09/19] chore: add changeset --- .changeset/lazy-houses-tell.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/lazy-houses-tell.md diff --git a/.changeset/lazy-houses-tell.md b/.changeset/lazy-houses-tell.md new file mode 100644 index 000000000..b37eb3fdc --- /dev/null +++ b/.changeset/lazy-houses-tell.md @@ -0,0 +1,7 @@ +--- +"myst-ext-button": patch +"myst-spec-ext": patch +"myst-cli": patch +--- + +Add new button role From 6a1c60e3e5a8bbacacfdb19c54fc2ad1235a2873 Mon Sep 17 00:00:00 2001 From: jnywong Date: Fri, 24 Jan 2025 12:25:39 +0000 Subject: [PATCH 10/19] Update doc --- packages/myst-ext-button/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/myst-ext-button/src/index.ts b/packages/myst-ext-button/src/index.ts index cd93b91c8..830878c13 100644 --- a/packages/myst-ext-button/src/index.ts +++ b/packages/myst-ext-button/src/index.ts @@ -5,7 +5,7 @@ const REF_PATTERN = /^(.+?)<([^<>]+)>$/; export const buttonRole: RoleSpec = { name: 'button', - doc: 'Button to navigate to external or internal links.', + doc: 'Button element with an action to navigate to internal or external links.', body: { type: String, doc: 'The body of the button.', From 45c9b9be4eca34ae64281da5055db8c5a23babc5 Mon Sep 17 00:00:00 2001 From: jnywong Date: Fri, 24 Jan 2025 12:25:57 +0000 Subject: [PATCH 11/19] Add buttonRole to directives plugin --- docs/directives.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/directives.mjs b/docs/directives.mjs index 4f28ca3d7..d2007009a 100644 --- a/docs/directives.mjs +++ b/docs/directives.mjs @@ -3,6 +3,7 @@ import { mystParse } from 'myst-parser'; import { defaultDirectives } from 'myst-directives'; import { defaultRoles } from 'myst-roles'; import { cardDirective } from 'myst-ext-card'; +import { buttonRole } from 'myst-ext-button'; import { gridDirectives } from 'myst-ext-grid'; import { proofDirective } from 'myst-ext-proof'; import { exerciseDirectives } from 'myst-ext-exercise'; @@ -17,7 +18,7 @@ const allDirectives = [ cardDirective, proofDirective, ]; -const allRoles = [...defaultRoles]; +const allRoles = [...defaultRoles, buttonRole]; /** * @param {import('myst-common').OptionDefinition} option From f8827ca59cf902889fc3ded89e8da67a5e4bda97 Mon Sep 17 00:00:00 2001 From: jnywong Date: Fri, 24 Jan 2025 12:26:08 +0000 Subject: [PATCH 12/19] Add buttonRole to roles reference --- docs/roles.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/roles.md b/docs/roles.md index 56dbac85d..28990e3f7 100644 --- a/docs/roles.md +++ b/docs/roles.md @@ -6,6 +6,9 @@ description: A full list of the roles included in MyST Markdown by default. :::{myst:role} abbreviation ::: +:::{myst:role} button +::: + :::{myst:role} chemicalFormula ::: From 06316d4ce50d5ffb15cbc40b1fb715e92997e86c Mon Sep 17 00:00:00 2001 From: jnywong Date: Fri, 24 Jan 2025 13:25:58 +0000 Subject: [PATCH 13/19] Add button docs --- docs/dropdowns-cards-and-tabs.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index 224cfbe68..320fe5aef 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -77,7 +77,7 @@ Footer Note that, card headers and footers are optional. If you don’t include ^^^ or +++ in your card, they will not show up. ```` -### `card` reference +#### `card` reference **Arguments** _(optional, markdown)_ : The `card` can take a single argument that is the title as a string. @@ -94,6 +94,18 @@ Note that, card headers and footers are optional. If you don’t include ^^^ or link _(optional, string)_ : If given, clicking the card will direct you to the URL given here. +### Buttons + +A button is an element with text content that triggers an action to navigate to an internal or external reference upon a user click. Use the {myst:role}`button` role followed by the text content and target path to create a button. + +```{myst} +{button}`MyST Role Spec ` +``` + +```{myst} +{button}`MyST-MD GitHub Date: Fri, 24 Jan 2025 14:33:22 +0000 Subject: [PATCH 14/19] Typo --- docs/dropdowns-cards-and-tabs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index 320fe5aef..e1ab91953 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -103,7 +103,7 @@ A button is an element with text content that triggers an action to navigate to ``` ```{myst} -{button}`MyST-MD GitHub ``` ### Grids From 4b473ebbb3fe23bd3b488c3e2eda56e5af830ab4 Mon Sep 17 00:00:00 2001 From: jnywong Date: Fri, 24 Jan 2025 14:34:27 +0000 Subject: [PATCH 15/19] Typo --- docs/dropdowns-cards-and-tabs.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index e1ab91953..40cb975c8 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -98,6 +98,10 @@ Note that, card headers and footers are optional. If you don’t include ^^^ or A button is an element with text content that triggers an action to navigate to an internal or external reference upon a user click. Use the {myst:role}`button` role followed by the text content and target path to create a button. +{button}`MyST Role Spec ` + +{button}`MyST-MD GitHub ` + ```{myst} {button}`MyST Role Spec ` ``` From f6d5bcc6d639435baf49daeecd42d2ba8375d11a Mon Sep 17 00:00:00 2001 From: jnywong Date: Fri, 24 Jan 2025 15:21:57 +0000 Subject: [PATCH 16/19] Minor edit --- docs/dropdowns-cards-and-tabs.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index 40cb975c8..63e13e09e 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -98,16 +98,12 @@ Note that, card headers and footers are optional. If you don’t include ^^^ or A button is an element with text content that triggers an action to navigate to an internal or external reference upon a user click. Use the {myst:role}`button` role followed by the text content and target path to create a button. -{button}`MyST Role Spec ` - -{button}`MyST-MD GitHub ` - ```{myst} {button}`MyST Role Spec ` ``` ```{myst} -{button}`MyST-MD GitHub +{button}`MyST-MD GitHub ` ``` ### Grids From ebb93aaf5593f44d2d262d2a5199ec13e2133187 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 27 Jan 2025 15:17:33 +0000 Subject: [PATCH 17/19] docs: use MyST directive for extensions --- docs/dropdowns-cards-and-tabs.md | 47 ++++++++------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index 63e13e09e..5b13bcd33 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -76,23 +76,8 @@ Footer Note that, card headers and footers are optional. If you don’t include ^^^ or +++ in your card, they will not show up. ```` - -#### `card` reference - -**Arguments** _(optional, markdown)_ -: The `card` can take a single argument that is the title as a string. - -**Options** -: No options for the `card` are required - - header _(optional, markdown)_ - : Styled content at the top of the card - - footer _(optional, markdown)_ - : Styled content at the bottom of the card - - link _(optional, string)_ - : If given, clicking the card will direct you to the URL given here. +:::{myst:directive} card +::: ### Buttons @@ -105,6 +90,8 @@ A button is an element with text content that triggers an action to navigate to ```{myst} {button}`MyST-MD GitHub ` ``` +:::{myst:directive} button +::: ### Grids @@ -136,6 +123,9 @@ Execute notebook cells, store results, and insert outputs across pages. :::: ``` +:::{myst:directive} grid +::: + ## Tabs You can also produce tabbed content. This allows you to display a variety of tabbed content blocks that users can click on. @@ -166,23 +156,8 @@ Synced content for tab 2 ``` ```` -### `tab-item` reference - -**Arguments** _(required: `1`, string)_ -: The `tab-item` requires a single argument that is the title as a string. - - ```{warning} - :class: dropdown - # Note: the `tab-item` title is not currently not parsed - - The current implementation does not parse the tab title properly, and markup in this field will not be parsed. - ``` - -**Options** -: No options for the `tab-item` are required - - sync _(optional, string)_ - : A key that is used to sync the selected tab across multiple tab-sets. +:::{myst:directive} tab-set +::: - selected _(flag, no-value)_ - : a flag indicating whether the tab should be selected by default. +:::{myst:directive} tab-item +::: From aa3d6a863a95717abf2c9c6b14219910b4e02537 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 27 Jan 2025 15:18:13 +0000 Subject: [PATCH 18/19] docs: use myst:role instead of myst:directive --- docs/dropdowns-cards-and-tabs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index 5b13bcd33..133aefe81 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -90,7 +90,7 @@ A button is an element with text content that triggers an action to navigate to ```{myst} {button}`MyST-MD GitHub ` ``` -:::{myst:directive} button +:::{myst:role} button ::: ### Grids From 7e72ca2238a53c1d741f874d5431ddf6d6ed6df6 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 27 Jan 2025 15:28:29 +0000 Subject: [PATCH 19/19] fix: correct heading depth --- docs/dropdowns-cards-and-tabs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/dropdowns-cards-and-tabs.md b/docs/dropdowns-cards-and-tabs.md index 133aefe81..5fb0b5adc 100644 --- a/docs/dropdowns-cards-and-tabs.md +++ b/docs/dropdowns-cards-and-tabs.md @@ -27,7 +27,7 @@ You can also hide the body of your admonition blocks so that users must click a To turn an admonition into a dropdown, add the option `:class: dropdown` to them. See [](#admonition-dropdown) for more information. ``` -### Cards +## Cards Cards provide an easy way for you to content into a standard “header”, “body”, “footer” structure that has a similar alignment and visual style. It is useful for creating galleries or high-visibility collections of links and information. For example, a card with a header, title, body, and footer: @@ -79,7 +79,7 @@ Note that, card headers and footers are optional. If you don’t include ^^^ or :::{myst:directive} card ::: -### Buttons +## Buttons A button is an element with text content that triggers an action to navigate to an internal or external reference upon a user click. Use the {myst:role}`button` role followed by the text content and target path to create a button. @@ -93,7 +93,7 @@ A button is an element with text content that triggers an action to navigate to :::{myst:role} button ::: -### Grids +## Grids Grids allow you to structure arbitrary chunks of content in a grid-like system.