@krizaka/ui 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -1
- package/dist/action-bar.d.ts +38 -0
- package/dist/action-bar.js +52 -0
- package/dist/action-bar.js.map +1 -0
- package/dist/argument-card.d.ts +67 -0
- package/dist/argument-card.js +69 -0
- package/dist/argument-card.js.map +1 -0
- package/dist/audio-player.js +1 -1
- package/dist/block-link-BAg4eoZk.d.ts +12 -0
- package/dist/blocks.css +529 -0
- package/dist/button.js +5 -94
- package/dist/button.js.map +1 -1
- package/dist/card-grid.d.ts +42 -0
- package/dist/card-grid.js +47 -0
- package/dist/card-grid.js.map +1 -0
- package/dist/chunk-2AGSO3WH.js +20 -0
- package/dist/chunk-2AGSO3WH.js.map +1 -0
- package/dist/chunk-AB5D3KBG.js +37 -0
- package/dist/chunk-AB5D3KBG.js.map +1 -0
- package/dist/{chunk-YX6CNVJA.js → chunk-CPA5CF35.js} +1 -1
- package/dist/chunk-CPA5CF35.js.map +1 -0
- package/dist/chunk-K3SWZXYT.js +92 -0
- package/dist/chunk-K3SWZXYT.js.map +1 -0
- package/dist/{chunk-XUMJA5ZI.js → chunk-X6TW3X6Y.js} +2 -2
- package/dist/chunk-XCBVFMNV.js +41 -0
- package/dist/{chunk-YX6CNVJA.js.map → chunk-XCBVFMNV.js.map} +1 -1
- package/dist/chunk-XVLWVTQA.js +28 -0
- package/dist/chunk-XVLWVTQA.js.map +1 -0
- package/dist/chunk-Z6FUPB3Q.js +102 -0
- package/dist/chunk-Z6FUPB3Q.js.map +1 -0
- package/dist/code-block.d.ts +42 -0
- package/dist/code-block.js +202 -0
- package/dist/code-block.js.map +1 -0
- package/dist/combobox.js +2 -2
- package/dist/cta-panel.d.ts +23 -0
- package/dist/cta-panel.js +20 -0
- package/dist/cta-panel.js.map +1 -0
- package/dist/data-table.js +1 -1
- package/dist/date-picker.js +1 -1
- package/dist/decision-list.d.ts +34 -0
- package/dist/decision-list.js +67 -0
- package/dist/decision-list.js.map +1 -0
- package/dist/file-upload.js +1 -1
- package/dist/filter-bar.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/link-card.d.ts +35 -0
- package/dist/link-card.js +46 -0
- package/dist/link-card.js.map +1 -0
- package/dist/mascot-quote.d.ts +42 -0
- package/dist/mascot-quote.js +267 -0
- package/dist/mascot-quote.js.map +1 -0
- package/dist/media-capture.js +1 -1
- package/dist/motion.css +25 -1
- package/dist/native.d.ts +28 -1
- package/dist/native.js +29 -5
- package/dist/native.js.map +1 -1
- package/dist/page-hero.d.ts +44 -0
- package/dist/page-hero.js +41 -0
- package/dist/page-hero.js.map +1 -0
- package/dist/page.d.ts +116 -0
- package/dist/page.js +17 -0
- package/dist/page.js.map +1 -0
- package/dist/pagination.js +25 -44
- package/dist/pagination.js.map +1 -1
- package/dist/pointer-light.d.ts +20 -0
- package/dist/pointer-light.js +12 -0
- package/dist/pointer-light.js.map +1 -0
- package/dist/search-field.js +1 -1
- package/dist/section-backdrop.js +4 -22
- package/dist/section-backdrop.js.map +1 -1
- package/dist/tag-input.js +2 -2
- package/dist/terminal-replay.d.ts +68 -0
- package/dist/terminal-replay.js +231 -0
- package/dist/terminal-replay.js.map +1 -0
- package/dist/toc.d.ts +23 -0
- package/dist/toc.js +39 -0
- package/dist/toc.js.map +1 -0
- package/dist/video-player.js +1 -1
- package/package.json +193 -8
- package/registry/action-bar.json +205 -0
- package/registry/alert.json +1 -1
- package/registry/argument-card.json +327 -0
- package/registry/audio-player.json +2 -2
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +5 -5
- package/registry/card-grid.json +221 -0
- package/registry/card.json +3 -3
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/code-block.json +262 -0
- package/registry/combobox.json +2 -2
- package/registry/command.json +1 -1
- package/registry/confirm-button.json +3 -3
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +154 -0
- package/registry/data-table.json +2 -2
- package/registry/date-picker.json +2 -2
- package/registry/decision-list.json +144 -0
- package/registry/dialog.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/examples/action-bar/buttons.d.ts +4 -0
- package/registry/examples/action-bar/buttons.js +22 -0
- package/registry/examples/action-bar/buttons.tsx +17 -0
- package/registry/examples/action-bar/icons.d.ts +4 -0
- package/registry/examples/action-bar/icons.js +24 -0
- package/registry/examples/action-bar/icons.tsx +23 -0
- package/registry/examples/argument-card/building-block.d.ts +4 -0
- package/registry/examples/argument-card/building-block.js +29 -0
- package/registry/examples/argument-card/building-block.tsx +29 -0
- package/registry/examples/argument-card/grid.d.ts +4 -0
- package/registry/examples/argument-card/grid.js +17 -0
- package/registry/examples/argument-card/grid.tsx +19 -0
- package/registry/examples/argument-card/unfold.d.ts +4 -0
- package/registry/examples/argument-card/unfold.js +26 -0
- package/registry/examples/argument-card/unfold.tsx +21 -0
- package/registry/examples/card-grid/products.d.ts +4 -0
- package/registry/examples/card-grid/products.js +16 -0
- package/registry/examples/card-grid/products.tsx +13 -0
- package/registry/examples/card-grid/reveal.d.ts +4 -0
- package/registry/examples/card-grid/reveal.js +13 -0
- package/registry/examples/card-grid/reveal.tsx +16 -0
- package/registry/examples/code-block/build-tools.d.ts +4 -0
- package/registry/examples/code-block/build-tools.js +30 -0
- package/registry/examples/code-block/build-tools.tsx +25 -0
- package/registry/examples/code-block/file.d.ts +4 -0
- package/registry/examples/code-block/file.js +17 -0
- package/registry/examples/code-block/file.tsx +13 -0
- package/registry/examples/cta-panel/discuss.d.ts +4 -0
- package/registry/examples/cta-panel/discuss.js +31 -0
- package/registry/examples/cta-panel/discuss.tsx +23 -0
- package/registry/examples/decision-list/product.d.ts +4 -0
- package/registry/examples/decision-list/product.js +35 -0
- package/registry/examples/decision-list/product.tsx +30 -0
- package/registry/examples/link-card/docs-hub.d.ts +4 -0
- package/registry/examples/link-card/docs-hub.js +18 -0
- package/registry/examples/link-card/docs-hub.tsx +20 -0
- package/registry/examples/link-card/external.d.ts +4 -0
- package/registry/examples/link-card/external.js +22 -0
- package/registry/examples/link-card/external.tsx +16 -0
- package/registry/examples/link-card/stack.d.ts +4 -0
- package/registry/examples/link-card/stack.js +26 -0
- package/registry/examples/link-card/stack.tsx +21 -0
- package/registry/examples/mascot-quote/callout.d.ts +4 -0
- package/registry/examples/mascot-quote/callout.js +11 -0
- package/registry/examples/mascot-quote/callout.tsx +10 -0
- package/registry/examples/mascot-quote/inline.d.ts +4 -0
- package/registry/examples/mascot-quote/inline.js +11 -0
- package/registry/examples/mascot-quote/inline.tsx +10 -0
- package/registry/examples/page/backdrop.d.ts +4 -0
- package/registry/examples/page/backdrop.js +23 -0
- package/registry/examples/page/backdrop.tsx +18 -0
- package/registry/examples/page/facts.d.ts +4 -0
- package/registry/examples/page/facts.js +24 -0
- package/registry/examples/page/facts.tsx +21 -0
- package/registry/examples/page/frame.d.ts +4 -0
- package/registry/examples/page/frame.js +15 -0
- package/registry/examples/page/frame.tsx +17 -0
- package/registry/examples/page/sections.d.ts +4 -0
- package/registry/examples/page/sections.js +14 -0
- package/registry/examples/page/sections.tsx +15 -0
- package/registry/examples/page-hero/building-block.d.ts +4 -0
- package/registry/examples/page-hero/building-block.js +24 -0
- package/registry/examples/page-hero/building-block.tsx +20 -0
- package/registry/examples/page-hero/hub.d.ts +4 -0
- package/registry/examples/page-hero/hub.js +21 -0
- package/registry/examples/page-hero/hub.tsx +15 -0
- package/registry/examples/pointer-light/list.d.ts +4 -0
- package/registry/examples/pointer-light/list.js +16 -0
- package/registry/examples/pointer-light/list.tsx +14 -0
- package/registry/examples/terminal-replay/at-rest.d.ts +4 -0
- package/registry/examples/terminal-replay/at-rest.js +32 -0
- package/registry/examples/terminal-replay/at-rest.tsx +26 -0
- package/registry/examples/terminal-replay/session.d.ts +4 -0
- package/registry/examples/terminal-replay/session.js +34 -0
- package/registry/examples/terminal-replay/session.tsx +28 -0
- package/registry/examples/toc/reading-page.d.ts +4 -0
- package/registry/examples/toc/reading-page.js +21 -0
- package/registry/examples/toc/reading-page.tsx +21 -0
- package/registry/examples/video-player/native/default.dark.png +0 -0
- package/registry/examples/video-player/native/default.light.png +0 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +2 -2
- package/registry/filter-bar.json +2 -2
- package/registry/glow-card.json +1 -1
- package/registry/image-cropper.json +1 -1
- package/registry/index.json +241 -1
- package/registry/iso.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/link-card.json +279 -0
- package/registry/loader.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +191 -0
- package/registry/mascots.json +1 -1
- package/registry/media-capture.json +4 -4
- package/registry/meter.json +1 -1
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +254 -0
- package/registry/page.json +497 -0
- package/registry/pagination.json +2 -2
- package/registry/pointer-light.json +119 -0
- package/registry/popover.json +1 -1
- package/registry/progress.json +1 -1
- package/registry/radio-group.json +1 -1
- package/registry/search-field.json +2 -2
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/skeleton.json +3 -3
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/stat.json +1 -1
- package/registry/stepper.json +1 -1
- package/registry/switch.json +1 -1
- package/registry/tabs.json +1 -1
- package/registry/tag-input.json +1 -1
- package/registry/terminal-replay.json +317 -0
- package/registry/theme.json +1 -1
- package/registry/toast.json +1 -1
- package/registry/toc.json +157 -0
- package/registry/tooltip.json +1 -1
- package/registry/video-player.json +4 -4
- package/registry/video-trimmer.json +3 -3
- /package/dist/{chunk-XUMJA5ZI.js.map → chunk-X6TW3X6Y.js.map} +0 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "code-block",
|
|
3
|
+
"type": "primitive",
|
|
4
|
+
"title": "Code block",
|
|
5
|
+
"summary": "A code sample: its language and file name, the code highlighted on the tokens (it scrolls sideways, never shrinks) and a copy button that says it copied — `CodeTabs` puts several build tools side by side.",
|
|
6
|
+
"description": "A code sample: its language and file name, the code highlighted on the tokens (it scrolls sideways, never shrinks) and a copy button that says it copied — `CodeTabs` puts several build tools side by side.",
|
|
7
|
+
"status": "beta",
|
|
8
|
+
"category": "blocks",
|
|
9
|
+
"platforms": "web",
|
|
10
|
+
"whenToUse": [
|
|
11
|
+
"Installation lines, a configuration file, the few lines a reader copies to start.",
|
|
12
|
+
"The same thing in Maven, Gradle and npm (`CodeTabs`)."
|
|
13
|
+
],
|
|
14
|
+
"whenNotToUse": [
|
|
15
|
+
{
|
|
16
|
+
"when": "For a word of code inside a sentence: use `Ticks` from the page entry.",
|
|
17
|
+
"use": "page"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"when": "For a keyboard shortcut.",
|
|
21
|
+
"use": "kbd"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"bestPractices": [
|
|
25
|
+
"Show the file the lines belong in (`pom.xml`, `application.yml`); `Terminal` for a command.",
|
|
26
|
+
"Keep samples short enough to copy whole; link to the full file instead of pasting it.",
|
|
27
|
+
"The copy words arrive as props (`copyLabel`, `copiedLabel`)."
|
|
28
|
+
],
|
|
29
|
+
"accessibility": {
|
|
30
|
+
"keyboard": [
|
|
31
|
+
{
|
|
32
|
+
"keys": "Tab",
|
|
33
|
+
"action": "Focuses the code, which then scrolls with the arrow keys; then the copy button."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"keys": "Arrow keys",
|
|
37
|
+
"action": "In CodeTabs, move between the tabs (Radix Tabs)."
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"notes": [
|
|
41
|
+
"A `figure` whose caption is the file name; the button's label changes to the copied words in a polite live region.",
|
|
42
|
+
"The colours of the highlighter are the tokens' text roles (≥ 4.5:1 on the code surface, both themes)."
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"related": [
|
|
46
|
+
"tabs",
|
|
47
|
+
"page",
|
|
48
|
+
"kbd"
|
|
49
|
+
],
|
|
50
|
+
"web": {
|
|
51
|
+
"entry": "@krizaka/ui/code-block",
|
|
52
|
+
"import": "import { CodeBlock, CodeTabs, highlight } from \"@krizaka/ui/code-block\";",
|
|
53
|
+
"props": [
|
|
54
|
+
{
|
|
55
|
+
"component": "CodeBlock",
|
|
56
|
+
"description": "A code sample: language and file name, highlighted code that scrolls sideways, a copy button.",
|
|
57
|
+
"props": [
|
|
58
|
+
{
|
|
59
|
+
"name": "code",
|
|
60
|
+
"type": "string",
|
|
61
|
+
"default": null,
|
|
62
|
+
"description": "The code, as it is copied.",
|
|
63
|
+
"required": true
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "copiedLabel",
|
|
67
|
+
"type": "string",
|
|
68
|
+
"default": null,
|
|
69
|
+
"description": "What the button says once the code is copied (announced politely).",
|
|
70
|
+
"required": true
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "copyLabel",
|
|
74
|
+
"type": "string",
|
|
75
|
+
"default": null,
|
|
76
|
+
"description": "The copy button's words.",
|
|
77
|
+
"required": true
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "file",
|
|
81
|
+
"type": "ReactNode",
|
|
82
|
+
"default": null,
|
|
83
|
+
"description": "The file it belongs in (`pom.xml`, `application.yml`), or what it is (`Terminal`).",
|
|
84
|
+
"required": false
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "highlight",
|
|
88
|
+
"type": "boolean",
|
|
89
|
+
"default": "true",
|
|
90
|
+
"description": "Colours comments, strings, annotations, tags and keywords (the tokens' roles).",
|
|
91
|
+
"required": false
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "language",
|
|
95
|
+
"type": "string",
|
|
96
|
+
"default": "text",
|
|
97
|
+
"description": "Its language, shown as a tag and used by the highlighter: `xml`, `kotlin`, `ts`, `bash`, `yaml`…",
|
|
98
|
+
"required": false
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"component": "CodeTabs",
|
|
104
|
+
"description": "Several ways to write the same thing (Maven · Gradle · npm): segmented tabs above code samples.",
|
|
105
|
+
"props": [
|
|
106
|
+
{
|
|
107
|
+
"name": "label",
|
|
108
|
+
"type": "string",
|
|
109
|
+
"default": null,
|
|
110
|
+
"description": "What the tabs choose between (`Build tool`): the tab list's accessible name.",
|
|
111
|
+
"required": true
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "tabs",
|
|
115
|
+
"type": "readonly { id: string; label: ReactNode; content: ReactNode; }[]",
|
|
116
|
+
"default": null,
|
|
117
|
+
"description": "The ways to write it: an id, the tab's words, its sample (a `CodeBlock`).",
|
|
118
|
+
"required": true
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "defaultValue",
|
|
122
|
+
"type": "string",
|
|
123
|
+
"default": null,
|
|
124
|
+
"description": "The tab open at first. Defaults to the first one.",
|
|
125
|
+
"required": false
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"examples": [
|
|
131
|
+
{
|
|
132
|
+
"name": "file",
|
|
133
|
+
"title": "A file",
|
|
134
|
+
"description": "A YAML sample in its file, with a comment and the copy button.",
|
|
135
|
+
"path": "examples/code-block/file.tsx",
|
|
136
|
+
"module": "@krizaka/ui/registry/examples/code-block/file",
|
|
137
|
+
"code": "import { CodeBlock } from \"@krizaka/ui/code-block\";\n\nconst code = `spring:\n application:\n name: billing # one name, used by logs and traces\nkrizaka:\n messaging:\n dead-letter: true`;\n\n// A sample in its file: the language, the file name, a copy button that says it copied. Long lines scroll sideways.\nexport default function CodeBlockFile() {\n return <CodeBlock className=\"w-full max-w-xl\" code={code} language=\"yaml\" file=\"application.yml\" copyLabel=\"Copy\" copiedLabel=\"Copied\" />;\n}\n"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "build-tools",
|
|
141
|
+
"title": "Build tools",
|
|
142
|
+
"description": "`CodeTabs`: Maven and Gradle side by side.",
|
|
143
|
+
"path": "examples/code-block/build-tools.tsx",
|
|
144
|
+
"module": "@krizaka/ui/registry/examples/code-block/build-tools",
|
|
145
|
+
"code": "import { CodeBlock, CodeTabs } from \"@krizaka/ui/code-block\";\n\nconst maven = `<parent>\n <groupId>com.krizaka</groupId>\n <artifactId>krizaka-parent</artifactId>\n <version>0.1.0</version>\n</parent>`;\nconst gradle = `dependencies {\n implementation(platform(\"com.krizaka:krizaka-bom:0.1.0\"))\n}`;\n\n// The same thing in several build tools: segmented tabs (arrow keys between them) above the samples.\nexport default function CodeBlockBuildTools() {\n const copy = { copyLabel: \"Copy\", copiedLabel: \"Copied\" };\n return (\n <CodeTabs\n className=\"w-full max-w-xl\"\n label=\"Build tool\"\n tabs={[\n { id: \"maven\", label: \"Maven\", content: <CodeBlock code={maven} language=\"xml\" file=\"pom.xml\" {...copy} /> },\n { id: \"gradle\", label: \"Gradle\", content: <CodeBlock code={gradle} language=\"kotlin\" file=\"build.gradle.kts\" {...copy} /> },\n ]}\n />\n );\n}\n"
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"native": null,
|
|
150
|
+
"files": [
|
|
151
|
+
{
|
|
152
|
+
"path": "code-block/code-block.tsx",
|
|
153
|
+
"content": "// Client (the copy button, the tabs). A sample of code (blocks.css): its language and its file name, the code\n// highlighted (it scrolls sideways, never shrinks, and takes the keyboard's focus to scroll), a copy button that says\n// it copied in a polite live region. CodeTabs puts several ways to write the same thing (Maven · Gradle · npm) under\n// the tabs of @krizaka/ui.\nimport * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { CheckGlyph, CopyGlyph } from \"../glyphs\";\nimport { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"../tabs/tabs\";\nimport { highlight } from \"./highlight\";\n\nexport type CodeBlockProps = Omit<React.HTMLAttributes<HTMLElement>, \"children\"> & {\n /** The code, as it is copied. */\n code: string;\n /** Its language, shown as a tag and used by the highlighter: `xml`, `kotlin`, `ts`, `bash`, `yaml`… */\n language?: string;\n /** The file it belongs in (`pom.xml`, `application.yml`), or what it is (`Terminal`). */\n file?: React.ReactNode;\n /** The copy button's words. */\n copyLabel: string;\n /** What the button says once the code is copied (announced politely). */\n copiedLabel: string;\n /**\n * Colours comments, strings, annotations, tags and keywords (the tokens' roles).\n * @default true\n */\n highlight?: boolean;\n /** Called after the code is copied. */\n onCopy?: () => void;\n};\n\n/** A code sample: language and file name, highlighted code that scrolls sideways, a copy button. */\nexport function CodeBlock({ code, language = \"text\", file, copyLabel, copiedLabel, highlight: colour = true, onCopy, className, ...props }: CodeBlockProps) {\n const [copied, setCopied] = React.useState(false);\n React.useEffect(() => {\n if (!copied) return;\n const t = setTimeout(() => setCopied(false), 1800);\n return () => clearTimeout(t);\n }, [copied]);\n const copy = () =>\n navigator.clipboard?.writeText(code).then(() => {\n setCopied(true);\n onCopy?.();\n });\n return (\n <figure className={cn(\"kz-code\", className)} {...props}>\n <figcaption className=\"kz-code-bar\">\n <span className=\"kz-code-file\">\n {language !== \"text\" && <span className=\"kz-code-lang\">{language}</span>}\n {file}\n </span>\n <button type=\"button\" className=\"kz-code-copy\" onClick={copy} data-copied={copied ? \"\" : undefined}>\n {copied ? <CheckGlyph className=\"h-3.5 w-3.5\" /> : <CopyGlyph className=\"h-3.5 w-3.5\" />}\n <span aria-live=\"polite\">{copied ? copiedLabel : copyLabel}</span>\n </button>\n </figcaption>\n <pre tabIndex={0}>\n <code data-language={language}>{colour ? highlight(code, language) : code}</code>\n </pre>\n </figure>\n );\n}\n\nexport type CodeTabsProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"dir\" | \"defaultValue\"> & {\n /** What the tabs choose between (`Build tool`): the tab list's accessible name. */\n label: string;\n /** The ways to write it: an id, the tab's words, its sample (a `CodeBlock`). */\n tabs: readonly { id: string; label: React.ReactNode; content: React.ReactNode }[];\n /** The tab open at first. Defaults to the first one. */\n defaultValue?: string;\n};\n\n/** Several ways to write the same thing (Maven · Gradle · npm): segmented tabs above code samples. */\nexport function CodeTabs({ label, tabs, defaultValue, className, ...props }: CodeTabsProps) {\n return (\n <TabsRoot defaultValue={defaultValue ?? tabs[0]?.id} variant=\"segmented\" className={cn(\"kz-code-tabs\", className)} {...props}>\n <TabsList aria-label={label}>\n {tabs.map((t) => (\n <TabsTrigger key={t.id} value={t.id}>\n {t.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {tabs.map((t) => (\n <TabsContent key={t.id} value={t.id}>\n {t.content}\n </TabsContent>\n ))}\n </TabsRoot>\n );\n}\n"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"path": "code-block/highlight.tsx",
|
|
157
|
+
"content": "// A small highlighter for the samples of a page (blocks.css `.kz-tk-*`): comments, strings, annotations, XML tags and\n// keywords — no highlighter in the bundle, no colour outside the tokens (each ≥ 4.5:1 on the code surface in both\n// themes). It colours what helps reading a sample; it is not a parser.\nimport type * as React from \"react\";\n\nconst CLASS = { comment: \"kz-tk-comment\", string: \"kz-tk-string\", annotation: \"kz-tk-annotation\", tag: \"kz-tk-tag\", keyword: \"kz-tk-keyword\" } as const;\ntype Kind = keyof typeof CLASS;\n\nconst KEYWORDS =\n \"public|private|protected|final|static|class|interface|record|extends|implements|return|new|try|catch|throw|throws|if|else|void|import|from|export|function|const|let|var|val|fun|true|false|null|this|default|async|await|type\";\n\nconst TOKEN = new RegExp(\n [\n String.raw`(?<comment>\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\/|<!--[\\s\\S]*?-->|(?:^|(?<=[\\s]))#[^\\n]*)`,\n String.raw`(?<string>\"(?:[^\"\\\\\\n]|\\\\.)*\"|'(?:[^'\\\\\\n]|\\\\.)*'|\\x60(?:[^\\x60\\\\]|\\\\.)*\\x60)`,\n String.raw`(?<annotation>@[A-Za-z][\\w.]*)`,\n String.raw`(?<tag><\\/?[A-Za-z][\\w.:-]*|\\/?>)`,\n String.raw`(?<keyword>\\b(?:${KEYWORDS})\\b)`,\n ].join(\"|\"),\n \"g\",\n);\n\n/** Splits `code` into text and coloured spans. A `#` after a space starts a comment (shell, YAML, properties), not in CSS or code. */\nexport function highlight(code: string, language: string): React.ReactNode[] {\n const out: React.ReactNode[] = [];\n let last = 0;\n for (const m of code.matchAll(TOKEN)) {\n const kind = Object.entries(m.groups ?? {}).find(([, v]) => v !== undefined)?.[0] as Kind | undefined;\n if (!kind) continue;\n if (kind === \"tag\" && !/^(xml|html|svg|jsx|tsx)$/.test(language)) continue;\n if (kind === \"comment\" && m[0].startsWith(\"#\") && /^(css|scss|tsx?|jsx?|java|kotlin|kt)$/.test(language)) continue;\n if (kind === \"string\" && m[0].startsWith(\"'\") && /^(xml|html|kotlin|kt|java)$/.test(language)) continue;\n if (m.index > last) out.push(code.slice(last, m.index));\n out.push(\n <span key={m.index} className={CLASS[kind]}>\n {m[0]}\n </span>,\n );\n last = m.index + m[0].length;\n }\n if (last < code.length) out.push(code.slice(last));\n return out;\n}\n"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"path": "code-block/index.ts",
|
|
161
|
+
"content": "/** @krizaka/ui/code-block — `CodeBlock` (file, highlighted code, copy) and `CodeTabs` (Maven · Gradle · npm). Client. */\nexport { CodeBlock, type CodeBlockProps, CodeTabs, type CodeTabsProps } from \"./code-block\";\nexport { highlight } from \"./highlight\";\n"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"path": "code-block/meta.ts",
|
|
165
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Code block\",\n summary:\n \"A code sample: its language and file name, the code highlighted on the tokens (it scrolls sideways, never shrinks) and a copy button that says it copied — `CodeTabs` puts several build tools side by side.\",\n status: \"beta\",\n category: \"blocks\",\n platforms: \"web\",\n whenToUse: [\n \"Installation lines, a configuration file, the few lines a reader copies to start.\",\n \"The same thing in Maven, Gradle and npm (`CodeTabs`).\",\n ],\n whenNotToUse: [\n { when: \"For a word of code inside a sentence: use `Ticks` from the page entry.\", use: \"page\" },\n { when: \"For a keyboard shortcut.\", use: \"kbd\" },\n ],\n bestPractices: [\n \"Show the file the lines belong in (`pom.xml`, `application.yml`); `Terminal` for a command.\",\n \"Keep samples short enough to copy whole; link to the full file instead of pasting it.\",\n \"The copy words arrive as props (`copyLabel`, `copiedLabel`).\",\n ],\n accessibility: {\n keyboard: [\n { keys: \"Tab\", action: \"Focuses the code, which then scrolls with the arrow keys; then the copy button.\" },\n { keys: \"Arrow keys\", action: \"In CodeTabs, move between the tabs (Radix Tabs).\" },\n ],\n notes: [\n \"A `figure` whose caption is the file name; the button's label changes to the copied words in a polite live region.\",\n \"The colours of the highlighter are the tokens' text roles (≥ 4.5:1 on the code surface, both themes).\",\n ],\n },\n related: [\"tabs\", \"page\", \"kbd\"],\n web: {\n imports: [\"CodeBlock\", \"CodeTabs\", \"highlight\"],\n examples: [\n { name: \"file\", title: \"A file\", description: \"A YAML sample in its file, with a comment and the copy button.\" },\n { name: \"build-tools\", title: \"Build tools\", description: \"`CodeTabs`: Maven and Gradle side by side.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"path": "glyphs.tsx",
|
|
169
|
+
"content": "// The small line glyphs the data and media primitives draw (play, volume, search, chevrons…): decorative, 24-unit\n// box, `currentColor`, sized by the caller's class. Shared by the entries that need them; never exported on its own —\n// a product draws its own icons with @krizaka/icons.\nimport type * as React from \"react\";\n\ntype GlyphProps = { className?: string };\n\nfunction Glyph({ className = \"h-4 w-4\", fill, children }: GlyphProps & { fill?: boolean; children: React.ReactNode }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n className={className}\n fill={fill ? \"currentColor\" : \"none\"}\n stroke={fill ? \"none\" : \"currentColor\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n >\n {children}\n </svg>\n );\n}\n\nexport const PlayGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <path d=\"M8 5.5v13a1 1 0 0 0 1.5.86l10.4-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z\" />\n </Glyph>\n);\nexport const PauseGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </Glyph>\n);\nexport const VolumeGlyph = ({ muted, ...p }: GlyphProps & { muted?: boolean }) => (\n <Glyph {...p}>\n <path d=\"M11 5 6 9H3v6h3l5 4V5Z\" />\n {muted ? <path d=\"m22 9-6 6m0-6 6 6\" /> : <path d=\"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13\" />}\n </Glyph>\n);\nexport const FullscreenGlyph = ({ exit, ...p }: GlyphProps & { exit?: boolean }) => (\n <Glyph {...p}>\n {exit ? <path d=\"M9 4v5H4m11-5v5h5M9 20v-5H4m11 5v-5h5\" /> : <path d=\"M4 9V4h5m6 0h5v5M4 15v5h5m11-5v5h-5\" />}\n </Glyph>\n);\nexport const CaptionsGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M10 10.5a2 2 0 1 0 0 3M17 10.5a2 2 0 1 0 0 3\" />\n </Glyph>\n);\nexport const PipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"12\" width=\"6\" height=\"4\" rx=\"1\" />\n </Glyph>\n);\nexport const SearchGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </Glyph>\n);\nexport const CloseGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Glyph>\n);\nexport const ChevronGlyph = ({ direction = \"down\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" | \"up\" | \"down\" }) => (\n <Glyph {...p}>\n <path d={{ left: \"m15 6-6 6 6 6\", right: \"m9 6 6 6-6 6\", up: \"m6 15 6-6 6 6\", down: \"m6 9 6 6 6-6\" }[direction]} />\n </Glyph>\n);\nexport const CheckGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Glyph>\n);\nexport const PlusGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 5v14M5 12h14\" />\n </Glyph>\n);\nexport const CalendarGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 10h18M8 3v4M16 3v4\" />\n </Glyph>\n);\nexport const UploadGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 16V4m0 0L7 9m5-5 5 5\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Glyph>\n);\nexport const FileGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z\" />\n <path d=\"M14 3v5h5\" />\n </Glyph>\n);\nexport const CameraGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 8h3l2-3h6l2 3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z\" />\n <circle cx=\"12\" cy=\"13.5\" r=\"3.5\" />\n </Glyph>\n);\nexport const FlipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 0 1 14-5.3M20 12a8 8 0 0 1-14 5.3\" />\n <path d=\"M18 3v4h-4M6 21v-4h4\" />\n </Glyph>\n);\nexport const RetryGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 1 0 2.3-5.7L4 8.5\" />\n <path d=\"M4 4v4.5h4.5\" />\n </Glyph>\n);\nexport const SortGlyph = ({ direction, ...p }: GlyphProps & { direction?: \"ascending\" | \"descending\" }) => (\n <Glyph {...p}>\n {direction === \"ascending\" ? <path d=\"m7 14 5-5 5 5\" /> : direction === \"descending\" ? <path d=\"m7 10 5 5 5-5\" /> : <path d=\"m8 9 4-4 4 4M8 15l4 4 4-4\" />}\n </Glyph>\n);\nexport const ArrowGlyph = ({ direction = \"right\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" }) => (\n <Glyph {...p}>\n <path d={direction === \"left\" ? \"M19 12H5m0 0 6-6m-6 6 6 6\" : \"M5 12h14m0 0-6-6m6 6-6 6\"} />\n </Glyph>\n);\nexport const ExternalGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 4h6v6M20 4l-9 9\" />\n <path d=\"M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4\" />\n </Glyph>\n);\nexport const WarningGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 4 2.5 20h19L12 4Z\" />\n <path d=\"M12 10v4M12 17.2v.1\" />\n </Glyph>\n);\nexport const CopyGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3\" />\n </Glyph>\n);\n"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"path": "meta.ts",
|
|
173
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"action-bar\"\n | \"alert\"\n | \"argument-card\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"cta-panel\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"link-card\"\n | \"loader\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"dependencies": [],
|
|
177
|
+
"registryDependencies": [
|
|
178
|
+
"cn",
|
|
179
|
+
"tabs"
|
|
180
|
+
],
|
|
181
|
+
"demo": {
|
|
182
|
+
"path": "examples/code-block/file.tsx",
|
|
183
|
+
"content": "import { CodeBlock } from \"@krizaka/ui/code-block\";\n\nconst code = `spring:\n application:\n name: billing # one name, used by logs and traces\nkrizaka:\n messaging:\n dead-letter: true`;\n\n// A sample in its file: the language, the file name, a copy button that says it copied. Long lines scroll sideways.\nexport default function CodeBlockFile() {\n return <CodeBlock className=\"w-full max-w-xl\" code={code} language=\"yaml\" file=\"application.yml\" copyLabel=\"Copy\" copiedLabel=\"Copied\" />;\n}\n"
|
|
184
|
+
},
|
|
185
|
+
"props": [
|
|
186
|
+
{
|
|
187
|
+
"component": "CodeBlock",
|
|
188
|
+
"description": "A code sample: language and file name, highlighted code that scrolls sideways, a copy button.",
|
|
189
|
+
"props": [
|
|
190
|
+
{
|
|
191
|
+
"name": "code",
|
|
192
|
+
"type": "string",
|
|
193
|
+
"default": null,
|
|
194
|
+
"description": "The code, as it is copied.",
|
|
195
|
+
"required": true
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"name": "copiedLabel",
|
|
199
|
+
"type": "string",
|
|
200
|
+
"default": null,
|
|
201
|
+
"description": "What the button says once the code is copied (announced politely).",
|
|
202
|
+
"required": true
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"name": "copyLabel",
|
|
206
|
+
"type": "string",
|
|
207
|
+
"default": null,
|
|
208
|
+
"description": "The copy button's words.",
|
|
209
|
+
"required": true
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "file",
|
|
213
|
+
"type": "ReactNode",
|
|
214
|
+
"default": null,
|
|
215
|
+
"description": "The file it belongs in (`pom.xml`, `application.yml`), or what it is (`Terminal`).",
|
|
216
|
+
"required": false
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"name": "highlight",
|
|
220
|
+
"type": "boolean",
|
|
221
|
+
"default": "true",
|
|
222
|
+
"description": "Colours comments, strings, annotations, tags and keywords (the tokens' roles).",
|
|
223
|
+
"required": false
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"name": "language",
|
|
227
|
+
"type": "string",
|
|
228
|
+
"default": "text",
|
|
229
|
+
"description": "Its language, shown as a tag and used by the highlighter: `xml`, `kotlin`, `ts`, `bash`, `yaml`…",
|
|
230
|
+
"required": false
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"component": "CodeTabs",
|
|
236
|
+
"description": "Several ways to write the same thing (Maven · Gradle · npm): segmented tabs above code samples.",
|
|
237
|
+
"props": [
|
|
238
|
+
{
|
|
239
|
+
"name": "label",
|
|
240
|
+
"type": "string",
|
|
241
|
+
"default": null,
|
|
242
|
+
"description": "What the tabs choose between (`Build tool`): the tab list's accessible name.",
|
|
243
|
+
"required": true
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"name": "tabs",
|
|
247
|
+
"type": "readonly { id: string; label: ReactNode; content: ReactNode; }[]",
|
|
248
|
+
"default": null,
|
|
249
|
+
"description": "The ways to write it: an id, the tab's words, its sample (a `CodeBlock`).",
|
|
250
|
+
"required": true
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"name": "defaultValue",
|
|
254
|
+
"type": "string",
|
|
255
|
+
"default": null,
|
|
256
|
+
"description": "The tab open at first. Defaults to the first one.",
|
|
257
|
+
"required": false
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
package/registry/combobox.json
CHANGED
|
@@ -285,7 +285,7 @@
|
|
|
285
285
|
},
|
|
286
286
|
{
|
|
287
287
|
"path": "glyphs.tsx",
|
|
288
|
-
"content": "// The small line glyphs the data and media primitives draw (play, volume, search, chevrons…): decorative, 24-unit\n// box, `currentColor`, sized by the caller's class. Shared by the entries that need them; never exported on its own —\n// a product draws its own icons with @krizaka/icons.\nimport type * as React from \"react\";\n\ntype GlyphProps = { className?: string };\n\nfunction Glyph({ className = \"h-4 w-4\", fill, children }: GlyphProps & { fill?: boolean; children: React.ReactNode }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n className={className}\n fill={fill ? \"currentColor\" : \"none\"}\n stroke={fill ? \"none\" : \"currentColor\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n >\n {children}\n </svg>\n );\n}\n\nexport const PlayGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <path d=\"M8 5.5v13a1 1 0 0 0 1.5.86l10.4-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z\" />\n </Glyph>\n);\nexport const PauseGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </Glyph>\n);\nexport const VolumeGlyph = ({ muted, ...p }: GlyphProps & { muted?: boolean }) => (\n <Glyph {...p}>\n <path d=\"M11 5 6 9H3v6h3l5 4V5Z\" />\n {muted ? <path d=\"m22 9-6 6m0-6 6 6\" /> : <path d=\"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13\" />}\n </Glyph>\n);\nexport const FullscreenGlyph = ({ exit, ...p }: GlyphProps & { exit?: boolean }) => (\n <Glyph {...p}>\n {exit ? <path d=\"M9 4v5H4m11-5v5h5M9 20v-5H4m11 5v-5h5\" /> : <path d=\"M4 9V4h5m6 0h5v5M4 15v5h5m11-5v5h-5\" />}\n </Glyph>\n);\nexport const CaptionsGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M10 10.5a2 2 0 1 0 0 3M17 10.5a2 2 0 1 0 0 3\" />\n </Glyph>\n);\nexport const PipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"12\" width=\"6\" height=\"4\" rx=\"1\" />\n </Glyph>\n);\nexport const SearchGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </Glyph>\n);\nexport const CloseGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Glyph>\n);\nexport const ChevronGlyph = ({ direction = \"down\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" | \"up\" | \"down\" }) => (\n <Glyph {...p}>\n <path d={{ left: \"m15 6-6 6 6 6\", right: \"m9 6 6 6-6 6\", up: \"m6 15 6-6 6 6\", down: \"m6 9 6 6 6-6\" }[direction]} />\n </Glyph>\n);\nexport const CheckGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Glyph>\n);\nexport const PlusGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 5v14M5 12h14\" />\n </Glyph>\n);\nexport const CalendarGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 10h18M8 3v4M16 3v4\" />\n </Glyph>\n);\nexport const UploadGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 16V4m0 0L7 9m5-5 5 5\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Glyph>\n);\nexport const FileGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z\" />\n <path d=\"M14 3v5h5\" />\n </Glyph>\n);\nexport const CameraGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 8h3l2-3h6l2 3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z\" />\n <circle cx=\"12\" cy=\"13.5\" r=\"3.5\" />\n </Glyph>\n);\nexport const FlipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 0 1 14-5.3M20 12a8 8 0 0 1-14 5.3\" />\n <path d=\"M18 3v4h-4M6 21v-4h4\" />\n </Glyph>\n);\nexport const RetryGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 1 0 2.3-5.7L4 8.5\" />\n <path d=\"M4 4v4.5h4.5\" />\n </Glyph>\n);\nexport const SortGlyph = ({ direction, ...p }: GlyphProps & { direction?: \"ascending\" | \"descending\" }) => (\n <Glyph {...p}>\n {direction === \"ascending\" ? <path d=\"m7 14 5-5 5 5\" /> : direction === \"descending\" ? <path d=\"m7 10 5 5 5-5\" /> : <path d=\"m8 9 4-4 4 4M8 15l4 4 4-4\" />}\n </Glyph>\n);\n"
|
|
288
|
+
"content": "// The small line glyphs the data and media primitives draw (play, volume, search, chevrons…): decorative, 24-unit\n// box, `currentColor`, sized by the caller's class. Shared by the entries that need them; never exported on its own —\n// a product draws its own icons with @krizaka/icons.\nimport type * as React from \"react\";\n\ntype GlyphProps = { className?: string };\n\nfunction Glyph({ className = \"h-4 w-4\", fill, children }: GlyphProps & { fill?: boolean; children: React.ReactNode }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n className={className}\n fill={fill ? \"currentColor\" : \"none\"}\n stroke={fill ? \"none\" : \"currentColor\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n >\n {children}\n </svg>\n );\n}\n\nexport const PlayGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <path d=\"M8 5.5v13a1 1 0 0 0 1.5.86l10.4-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z\" />\n </Glyph>\n);\nexport const PauseGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </Glyph>\n);\nexport const VolumeGlyph = ({ muted, ...p }: GlyphProps & { muted?: boolean }) => (\n <Glyph {...p}>\n <path d=\"M11 5 6 9H3v6h3l5 4V5Z\" />\n {muted ? <path d=\"m22 9-6 6m0-6 6 6\" /> : <path d=\"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13\" />}\n </Glyph>\n);\nexport const FullscreenGlyph = ({ exit, ...p }: GlyphProps & { exit?: boolean }) => (\n <Glyph {...p}>\n {exit ? <path d=\"M9 4v5H4m11-5v5h5M9 20v-5H4m11 5v-5h5\" /> : <path d=\"M4 9V4h5m6 0h5v5M4 15v5h5m11-5v5h-5\" />}\n </Glyph>\n);\nexport const CaptionsGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M10 10.5a2 2 0 1 0 0 3M17 10.5a2 2 0 1 0 0 3\" />\n </Glyph>\n);\nexport const PipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"12\" width=\"6\" height=\"4\" rx=\"1\" />\n </Glyph>\n);\nexport const SearchGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </Glyph>\n);\nexport const CloseGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Glyph>\n);\nexport const ChevronGlyph = ({ direction = \"down\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" | \"up\" | \"down\" }) => (\n <Glyph {...p}>\n <path d={{ left: \"m15 6-6 6 6 6\", right: \"m9 6 6 6-6 6\", up: \"m6 15 6-6 6 6\", down: \"m6 9 6 6 6-6\" }[direction]} />\n </Glyph>\n);\nexport const CheckGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Glyph>\n);\nexport const PlusGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 5v14M5 12h14\" />\n </Glyph>\n);\nexport const CalendarGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 10h18M8 3v4M16 3v4\" />\n </Glyph>\n);\nexport const UploadGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 16V4m0 0L7 9m5-5 5 5\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Glyph>\n);\nexport const FileGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z\" />\n <path d=\"M14 3v5h5\" />\n </Glyph>\n);\nexport const CameraGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 8h3l2-3h6l2 3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z\" />\n <circle cx=\"12\" cy=\"13.5\" r=\"3.5\" />\n </Glyph>\n);\nexport const FlipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 0 1 14-5.3M20 12a8 8 0 0 1-14 5.3\" />\n <path d=\"M18 3v4h-4M6 21v-4h4\" />\n </Glyph>\n);\nexport const RetryGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 1 0 2.3-5.7L4 8.5\" />\n <path d=\"M4 4v4.5h4.5\" />\n </Glyph>\n);\nexport const SortGlyph = ({ direction, ...p }: GlyphProps & { direction?: \"ascending\" | \"descending\" }) => (\n <Glyph {...p}>\n {direction === \"ascending\" ? <path d=\"m7 14 5-5 5 5\" /> : direction === \"descending\" ? <path d=\"m7 10 5 5 5-5\" /> : <path d=\"m8 9 4-4 4 4M8 15l4 4 4-4\" />}\n </Glyph>\n);\nexport const ArrowGlyph = ({ direction = \"right\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" }) => (\n <Glyph {...p}>\n <path d={direction === \"left\" ? \"M19 12H5m0 0 6-6m-6 6 6 6\" : \"M5 12h14m0 0-6-6m6 6-6 6\"} />\n </Glyph>\n);\nexport const ExternalGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 4h6v6M20 4l-9 9\" />\n <path d=\"M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4\" />\n </Glyph>\n);\nexport const WarningGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 4 2.5 20h19L12 4Z\" />\n <path d=\"M12 10v4M12 17.2v.1\" />\n </Glyph>\n);\nexport const CopyGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3\" />\n </Glyph>\n);\n"
|
|
289
289
|
},
|
|
290
290
|
{
|
|
291
291
|
"path": "listbox.ts",
|
|
@@ -297,7 +297,7 @@
|
|
|
297
297
|
},
|
|
298
298
|
{
|
|
299
299
|
"path": "meta.ts",
|
|
300
|
-
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"data-table\"\n | \"date-picker\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"pagination\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n
|
|
300
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"action-bar\"\n | \"alert\"\n | \"argument-card\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"cta-panel\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"link-card\"\n | \"loader\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
301
301
|
}
|
|
302
302
|
],
|
|
303
303
|
"dependencies": [
|
package/registry/command.json
CHANGED
|
@@ -243,7 +243,7 @@
|
|
|
243
243
|
},
|
|
244
244
|
{
|
|
245
245
|
"path": "meta.ts",
|
|
246
|
-
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"data-table\"\n | \"date-picker\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"pagination\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n
|
|
246
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"action-bar\"\n | \"alert\"\n | \"argument-card\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"cta-panel\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"link-card\"\n | \"loader\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
247
247
|
}
|
|
248
248
|
],
|
|
249
249
|
"dependencies": [
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
148
|
"name": "size",
|
|
149
|
-
"type": "\"
|
|
149
|
+
"type": "\"sm\" | \"md\" | \"lg\" | \"icon\"",
|
|
150
150
|
"default": "md",
|
|
151
151
|
"description": "sm · md · lg, or `icon` (a square).",
|
|
152
152
|
"required": false
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
},
|
|
219
219
|
{
|
|
220
220
|
"path": "meta.ts",
|
|
221
|
-
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"data-table\"\n | \"date-picker\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"pagination\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n
|
|
221
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"action-bar\"\n | \"alert\"\n | \"argument-card\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"cta-panel\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"link-card\"\n | \"loader\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
222
222
|
}
|
|
223
223
|
],
|
|
224
224
|
"dependencies": [
|
|
@@ -323,7 +323,7 @@
|
|
|
323
323
|
},
|
|
324
324
|
{
|
|
325
325
|
"name": "size",
|
|
326
|
-
"type": "\"
|
|
326
|
+
"type": "\"sm\" | \"md\" | \"lg\" | \"icon\"",
|
|
327
327
|
"default": "md",
|
|
328
328
|
"description": "sm · md · lg, or `icon` (a square).",
|
|
329
329
|
"required": false
|
package/registry/countdown.json
CHANGED
|
@@ -317,7 +317,7 @@
|
|
|
317
317
|
},
|
|
318
318
|
{
|
|
319
319
|
"path": "meta.ts",
|
|
320
|
-
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"data-table\"\n | \"date-picker\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"pagination\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n
|
|
320
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"action-bar\"\n | \"alert\"\n | \"argument-card\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"cta-panel\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"link-card\"\n | \"loader\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
321
321
|
}
|
|
322
322
|
],
|
|
323
323
|
"dependencies": [
|