@nanisoft/prism-llms 0.4.0 → 0.5.1

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.
Files changed (175) hide show
  1. package/README.md +88 -0
  2. package/THIRD-PARTY-NOTICES.md +48 -0
  3. package/dist/data.json +4037 -386
  4. package/dist/demo-graph.d.ts +21 -12
  5. package/dist/demo-graph.js +37 -21
  6. package/dist/extractor.d.ts +24 -17
  7. package/dist/extractor.js +299 -156
  8. package/dist/index.d.ts +12 -7
  9. package/dist/index.js +9 -7
  10. package/dist/llms-full.txt +8248 -2013
  11. package/dist/llms.txt +98 -93
  12. package/dist/markdown.d.ts +69 -23
  13. package/dist/markdown.js +131 -72
  14. package/dist/md/blocks/app-shell-01.md +135 -0
  15. package/dist/md/blocks/auth-form-01.md +135 -0
  16. package/dist/md/blocks/cta-01.md +88 -0
  17. package/dist/md/blocks/data-table-01.md +196 -0
  18. package/dist/md/blocks/feature-grid-01.md +92 -0
  19. package/dist/md/blocks/hero-01.md +90 -0
  20. package/dist/md/blocks/instrument-panel-01.md +109 -0
  21. package/dist/md/blocks/logo-strip-01.md +97 -0
  22. package/dist/md/blocks/note-grid-01.md +98 -0
  23. package/dist/md/blocks/page-header-01.md +97 -0
  24. package/dist/md/blocks/pricing-01.md +91 -0
  25. package/dist/md/blocks/process-rail-01.md +106 -0
  26. package/dist/md/blocks/product-grid-01.md +107 -0
  27. package/dist/md/blocks/settings-panel-01.md +146 -0
  28. package/dist/md/blocks/site-footer.md +103 -11
  29. package/dist/md/blocks/site-header.md +107 -11
  30. package/dist/md/blocks/stack-grid-01.md +108 -0
  31. package/dist/md/blocks/stats-01.md +89 -0
  32. package/dist/md/blocks/status-ledger-01.md +121 -0
  33. package/dist/md/changelogs/prism-llms.md +244 -0
  34. package/dist/md/changelogs/prism-mcp-server.md +95 -0
  35. package/dist/md/changelogs/prism-tokens.md +126 -0
  36. package/dist/md/changelogs/prism-ui.md +467 -0
  37. package/dist/md/components/accordion.md +108 -0
  38. package/dist/md/components/alert.md +90 -7
  39. package/dist/md/components/avatar.md +89 -7
  40. package/dist/md/components/badge.md +74 -7
  41. package/dist/md/components/breadcrumb.md +84 -7
  42. package/dist/md/components/button.md +90 -7
  43. package/dist/md/components/card.md +90 -7
  44. package/dist/md/components/checkbox.md +101 -7
  45. package/dist/md/components/cta-link.md +98 -0
  46. package/dist/md/components/diagram.md +124 -0
  47. package/dist/md/components/dialog.md +128 -0
  48. package/dist/md/components/dropdown-menu.md +125 -0
  49. package/dist/md/components/fact-list.md +85 -0
  50. package/dist/md/components/field.md +116 -0
  51. package/dist/md/components/input.md +86 -7
  52. package/dist/md/components/kbd.md +77 -0
  53. package/dist/md/components/pagination.md +95 -7
  54. package/dist/md/components/popover.md +95 -7
  55. package/dist/md/components/product-mark.md +114 -0
  56. package/dist/md/components/product-switcher.md +88 -0
  57. package/dist/md/components/progress.md +88 -7
  58. package/dist/md/components/prose.md +91 -0
  59. package/dist/md/components/radio-group.md +111 -0
  60. package/dist/md/components/section.md +91 -0
  61. package/dist/md/components/select.md +143 -7
  62. package/dist/md/components/separator.md +77 -0
  63. package/dist/md/components/skeleton.md +71 -7
  64. package/dist/md/components/slider.md +90 -7
  65. package/dist/md/components/switch.md +104 -7
  66. package/dist/md/components/table.md +104 -7
  67. package/dist/md/components/tabs.md +105 -7
  68. package/dist/md/components/textarea.md +101 -0
  69. package/dist/md/components/tooltip.md +95 -7
  70. package/dist/md/components/typography.md +82 -7
  71. package/dist/md/content/about-content.md +36 -0
  72. package/dist/md/content/audience.md +43 -0
  73. package/dist/md/content/glossary.md +69 -0
  74. package/dist/md/content/product-vocabulary.md +53 -0
  75. package/dist/md/content/voice.md +52 -0
  76. package/dist/md/content/writing-mechanics.md +58 -0
  77. package/dist/md/foundation/colors.md +10 -0
  78. package/dist/md/foundation/iconography.md +14 -0
  79. package/dist/md/foundation/motion.md +10 -0
  80. package/dist/md/foundation/radii.md +9 -0
  81. package/dist/md/foundation/shadows.md +9 -0
  82. package/dist/md/foundation/spacings.md +8 -0
  83. package/dist/md/foundation/typography.md +9 -0
  84. package/dist/md/foundation/variables.md +9 -0
  85. package/dist/md/overview/architecture.md +76 -0
  86. package/dist/md/overview/brand.md +41 -0
  87. package/dist/md/overview/composition.md +77 -0
  88. package/dist/md/overview/quickstart.md +97 -0
  89. package/dist/md/overview/theming.md +89 -0
  90. package/dist/md/overview/using-llms.md +83 -0
  91. package/dist/md/pages/auth-page.md +149 -0
  92. package/dist/md/pages/blog-post-page.md +136 -0
  93. package/dist/md/pages/dashboard-page.md +241 -0
  94. package/dist/md/pages/docs-shell.md +210 -15
  95. package/dist/md/pages/marketing-page.md +199 -0
  96. package/dist/md/pages/not-found-page.md +105 -0
  97. package/dist/md/pages/settings-page.md +206 -0
  98. package/dist/prism-skill.md +50 -0
  99. package/dist/store.d.ts +203 -0
  100. package/dist/store.js +317 -0
  101. package/package.json +29 -26
  102. package/dist/demo-graph.d.ts.map +0 -1
  103. package/dist/demo-graph.js.map +0 -1
  104. package/dist/extractor.d.ts.map +0 -1
  105. package/dist/extractor.js.map +0 -1
  106. package/dist/index.d.ts.map +0 -1
  107. package/dist/index.js.map +0 -1
  108. package/dist/markdown.d.ts.map +0 -1
  109. package/dist/markdown.js.map +0 -1
  110. package/dist/md/blocks/component-demo.md +0 -19
  111. package/dist/md/blocks/page-header.md +0 -19
  112. package/dist/md/components/affix.md +0 -14
  113. package/dist/md/components/anchor.md +0 -14
  114. package/dist/md/components/auto-complete.md +0 -14
  115. package/dist/md/components/back-top.md +0 -14
  116. package/dist/md/components/border-beam.md +0 -14
  117. package/dist/md/components/calendar.md +0 -14
  118. package/dist/md/components/carousel.md +0 -14
  119. package/dist/md/components/cascader.md +0 -14
  120. package/dist/md/components/col.md +0 -14
  121. package/dist/md/components/collapse.md +0 -14
  122. package/dist/md/components/color-picker.md +0 -14
  123. package/dist/md/components/date-picker.md +0 -14
  124. package/dist/md/components/descriptions.md +0 -14
  125. package/dist/md/components/display-title.md +0 -20
  126. package/dist/md/components/divider.md +0 -14
  127. package/dist/md/components/drawer.md +0 -14
  128. package/dist/md/components/dropdown.md +0 -14
  129. package/dist/md/components/empty.md +0 -14
  130. package/dist/md/components/flex.md +0 -14
  131. package/dist/md/components/float-button.md +0 -14
  132. package/dist/md/components/form.md +0 -14
  133. package/dist/md/components/grid.md +0 -14
  134. package/dist/md/components/image.md +0 -14
  135. package/dist/md/components/input-number.md +0 -14
  136. package/dist/md/components/layout.md +0 -14
  137. package/dist/md/components/list.md +0 -14
  138. package/dist/md/components/listy.md +0 -14
  139. package/dist/md/components/masonry.md +0 -14
  140. package/dist/md/components/mentions.md +0 -14
  141. package/dist/md/components/menu.md +0 -14
  142. package/dist/md/components/modal.md +0 -14
  143. package/dist/md/components/popconfirm.md +0 -14
  144. package/dist/md/components/qrcode.md +0 -14
  145. package/dist/md/components/radio.md +0 -14
  146. package/dist/md/components/rate.md +0 -14
  147. package/dist/md/components/result.md +0 -14
  148. package/dist/md/components/row.md +0 -14
  149. package/dist/md/components/segmented.md +0 -14
  150. package/dist/md/components/space.md +0 -14
  151. package/dist/md/components/spin.md +0 -14
  152. package/dist/md/components/splitter.md +0 -14
  153. package/dist/md/components/statistic.md +0 -14
  154. package/dist/md/components/steps.md +0 -14
  155. package/dist/md/components/tag.md +0 -14
  156. package/dist/md/components/time-picker.md +0 -14
  157. package/dist/md/components/timeline.md +0 -14
  158. package/dist/md/components/tour.md +0 -14
  159. package/dist/md/components/transfer.md +0 -14
  160. package/dist/md/components/tree-select.md +0 -14
  161. package/dist/md/components/tree.md +0 -14
  162. package/dist/md/components/upload.md +0 -14
  163. package/dist/md/components/watermark.md +0 -14
  164. package/dist/md/docs/brand.md +0 -41
  165. package/dist/md/pages/blog-layout.md +0 -19
  166. package/dist/md/theme/blue-dark.md +0 -127
  167. package/dist/md/theme/blue-light.md +0 -129
  168. package/dist/md/theme/green-dark.md +0 -127
  169. package/dist/md/theme/green-light.md +0 -129
  170. package/dist/md/theme/lavender-dark.md +0 -127
  171. package/dist/md/theme/lavender-light.md +0 -129
  172. package/dist/md/theme/peach-dark.md +0 -127
  173. package/dist/md/theme/peach-light.md +0 -129
  174. package/dist/md/theme/rose-dark.md +0 -127
  175. package/dist/md/theme/rose-light.md +0 -129
@@ -0,0 +1,125 @@
1
+ # DropdownMenu
2
+
3
+ The menu of actions and choices opened from one trigger.
4
+
5
+ ```tsx
6
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from '@nanisoft/prism-ui/components/dropdown-menu'
7
+ ```
8
+
9
+ ## Overview
10
+
11
+ A DropdownMenu is a list of actions and choices opened from one trigger. It
12
+ ships as `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`,
13
+ `DropdownMenuItem`, `DropdownMenuCheckboxItem`, `DropdownMenuRadioItem`,
14
+ `DropdownMenuLabel`, `DropdownMenuSeparator`, `DropdownMenuGroup`,
15
+ `DropdownMenuSub`, `DropdownMenuSubTrigger` and `DropdownMenuSubContent`.
16
+
17
+ The menu supports arrow-key navigation, typeahead by item label, Home and End,
18
+ and Escape to close. A submenu opens from its trigger with the right arrow, and
19
+ focus returns to the trigger when the menu closes.
20
+
21
+ ## Guidelines
22
+
23
+ ### When to use
24
+
25
+ Use a DropdownMenu for a short list of commands attached to one control: a row's
26
+ actions, an account menu, or a toolbar overflow. It keeps secondary actions out
27
+ of the way without losing them.
28
+
29
+ ### When not to use
30
+
31
+ Do not hide a primary action in a menu. If it is the main thing a view is for,
32
+ keep it visible as a Button.
33
+
34
+ Do not use a DropdownMenu for navigation between pages, and do not nest menus
35
+ more than one level deep. Both cases want a page or a sidebar.
36
+
37
+ ### Best practices
38
+
39
+ - Put a `DropdownMenuLabel` inside a `DropdownMenuGroup`. The label is tied to
40
+ its group, so it must have one.
41
+ - Use `DropdownMenuCheckboxItem` for toggles that do not close the menu, so the
42
+ reader can change several in a row.
43
+ - Put a destructive action last, after a `DropdownMenuSeparator`, with
44
+ `variant="destructive"`.
45
+ - Keep items to a verb or a short noun phrase, and name the object when the
46
+ action is ambiguous: "Duplicate project" beats "Duplicate".
47
+ - One level of `DropdownMenuSub` is the ceiling. Beyond that, promote the
48
+ commands to a page.
49
+
50
+ ### Content guidelines
51
+
52
+ - Write items as imperative commands: "Duplicate", "Archive", "Sign out".
53
+ - Use sentence case and no trailing periods.
54
+ - Group related commands and label the group in sentence case, such as
55
+ "Account" or "Danger zone".
56
+
57
+ **A menu with items, a checkbox item and a nested submenu.**
58
+
59
+ ```tsx
60
+ 'use client'
61
+
62
+ import {
63
+ DropdownMenu,
64
+ DropdownMenuCheckboxItem,
65
+ DropdownMenuContent,
66
+ DropdownMenuGroup,
67
+ DropdownMenuItem,
68
+ DropdownMenuLabel,
69
+ DropdownMenuSeparator,
70
+ DropdownMenuSub,
71
+ DropdownMenuSubContent,
72
+ DropdownMenuSubTrigger,
73
+ DropdownMenuTrigger,
74
+ } from '@nanisoft/prism-ui/components/dropdown-menu'
75
+
76
+ /** A menu with items, a checkbox item and a nested submenu. */
77
+ export default function DropdownMenuDemo() {
78
+ return (
79
+ <DropdownMenu>
80
+ <DropdownMenuTrigger>Open menu</DropdownMenuTrigger>
81
+ <DropdownMenuContent className="w-56">
82
+ <DropdownMenuGroup>
83
+ <DropdownMenuLabel>Account</DropdownMenuLabel>
84
+ <DropdownMenuItem>Profile</DropdownMenuItem>
85
+ <DropdownMenuItem>Settings</DropdownMenuItem>
86
+ </DropdownMenuGroup>
87
+ <DropdownMenuSeparator />
88
+ <DropdownMenuCheckboxItem defaultChecked>
89
+ Show archived rows
90
+ </DropdownMenuCheckboxItem>
91
+ <DropdownMenuSub>
92
+ <DropdownMenuSubTrigger>Invite</DropdownMenuSubTrigger>
93
+ <DropdownMenuSubContent>
94
+ <DropdownMenuItem>Send by email</DropdownMenuItem>
95
+ <DropdownMenuItem>Copy invite link</DropdownMenuItem>
96
+ </DropdownMenuSubContent>
97
+ </DropdownMenuSub>
98
+ <DropdownMenuSeparator />
99
+ <DropdownMenuItem variant="destructive">Sign out</DropdownMenuItem>
100
+ </DropdownMenuContent>
101
+ </DropdownMenu>
102
+ )
103
+ }
104
+ ```
105
+
106
+ ## Props
107
+
108
+ **`open`** `boolean` · optional · default: — — The controlled open state.
109
+ **`defaultOpen`** `boolean` · optional · default: — — The initially open state, for an uncontrolled menu.
110
+ **`onOpenChange`** `(open: boolean) => void` · optional · default: — — Called when the open state changes.
111
+ **`disabled`** `boolean` · optional · default: — — Whether the menu ignores user interaction.
112
+ **`children`** `React.ReactNode` · optional · default: — — The trigger and the menu content.
113
+ **`side`** `'top' | 'right' | 'bottom' | 'left'` · optional · default: `bottom` — Which side of the trigger the menu is placed on.
114
+ **`align`** `'start' | 'center' | 'end'` · optional · default: `start` — How the menu aligns against the trigger.
115
+ **`sideOffset`** `number` · optional · default: `4` — The distance in pixels between the trigger and the menu.
116
+ **`alignOffset`** `number` · optional · default: `0` — The offset in pixels along the alignment axis.
117
+ **`inset`** `boolean` · optional · default: `false` — Whether the item aligns with the labels above it.
118
+ **`variant`** `'default' | 'destructive'` · optional · default: `default` — Whether the item reads as a destructive action.
119
+ **`closeOnClick`** `boolean` · optional · default: `true` — Whether the menu closes when the item is chosen.
120
+ **`checked`** `boolean` · optional · default: — — The controlled ticked state.
121
+ **`defaultChecked`** `boolean` · optional · default: — — The initially ticked state, for an uncontrolled item.
122
+ **`onCheckedChange`** `(checked: boolean) => void` · optional · default: — — Called when the ticked state changes.
123
+ **`value`** `string` · optional · default: — — The controlled value of the selected radio item.
124
+ **`defaultValue`** `string` · optional · default: — — The initially selected value, for an uncontrolled group.
125
+ **`onValueChange`** `(value: string) => void` · optional · default: — — Called when the selected value changes.
@@ -0,0 +1,85 @@
1
+ # FactList
2
+
3
+ A short list of named facts as a definition list, where a value may be a link and the term column stays aligned down its length.
4
+
5
+ ```tsx
6
+ import { FactList } from '@nanisoft/prism-ui/components/fact-list'
7
+ ```
8
+
9
+ ## Overview
10
+
11
+ A FactList is a short list of named facts: a term beside its value, in a column a
12
+ reader can scan. It renders a real `<dl>`, so a screen reader announces the term
13
+ before the value instead of reading a list of labels and then a list of answers.
14
+
15
+ Every NaniSoft site states facts beside prose: what a plan costs, what a feed
16
+ carries, which version a document describes, when a collector went live. Each one
17
+ re-derived a `<dl>`, and each one got the alignment and the term-before-value
18
+ wiring subtly wrong.
19
+
20
+ ## Guidelines
21
+
22
+ ### When to use
23
+
24
+ Use a FactList for two to six facts that belong to one thing and are worth reading
25
+ together: a release, a feed source, a plan, a deployment.
26
+
27
+ Use it beside prose rather than inside it. A fact in the middle of a paragraph is
28
+ a sentence, and a sentence is not a fact list.
29
+
30
+ ### When not to use
31
+
32
+ Do not use a FactList for a table of records. That is `Table`, and a fact list of
33
+ twenty rows is a table with its column headers removed.
34
+
35
+ Do not use it for a set of links. That is a footer's column or a plain list, and a
36
+ column of destinations is not a column of terms.
37
+
38
+ Do not use it to compare products. A comparison has a row per product and a column
39
+ per fact, and this is the other way round.
40
+
41
+ ### Best practices
42
+
43
+ - Keep the label column short. The column is a fixed fraction so a list of facts
44
+ lines up down its whole length, and a label that wraps costs every other row its
45
+ alignment.
46
+ - Give a fact an `href` only when the fact is kept somewhere else. A link to a fact
47
+ already on the page is a click that changes nothing.
48
+ - Omit `label` when the list is already inside something that names it.
49
+ - An empty list renders nothing, so a caller with nothing to state does not get a
50
+ bordered box with a title above it.
51
+
52
+ ### Content guidelines
53
+
54
+ - Write a label as a name, not a question: "Last capture", not "When did it last
55
+ capture".
56
+ - Keep a value to a word or a short phrase. A value that needs a sentence belongs
57
+ in a `NoteGrid01` row.
58
+ - Write values as they would be read aloud, because that is how they are scanned.
59
+
60
+ **Named facts, with one value that is a link and one that is a count.**
61
+
62
+ ```tsx
63
+ import { FactList } from '@nanisoft/prism-ui/components/fact-list'
64
+
65
+ /** Named facts, with one value that is a link and one that is a count. */
66
+ export default function FactListDemo() {
67
+ return (
68
+ <FactList
69
+ label="Release"
70
+ facts={[
71
+ { label: 'Version', value: '0.5.1' },
72
+ { label: 'Package', value: '@nanisoft/prism-ui' },
73
+ { label: 'Axes', value: 'Two: pack and mode' },
74
+ { label: 'Changelog', value: 'Read it', href: '/changelogs/prism-ui' },
75
+ ]}
76
+ />
77
+ )
78
+ }
79
+ ```
80
+
81
+ ## Props
82
+
83
+ **`facts`** `readonly Fact[]` · required · default: — — The facts, in the order a reader should meet them. Order is the caller's because it is a claim about importance, and a list that sorted itself would be making that claim on the caller's behalf.
84
+ **`label`** `ReactNode` · optional · default: — — A heading above the list, for a set of facts that needs to say what it is. Rendered as a `dt`-level caption rather than as a heading, so it does not compete with the document's own outline.
85
+ **`className`** `string` · optional · default: — — Layout only, exactly as on every Component. Changing a Prism-owned visual property from here is prohibited.
@@ -0,0 +1,116 @@
1
+ # Field
2
+
3
+ The labelled wrapper that pairs a form control with its label, description and error.
4
+
5
+ ```tsx
6
+ import { Field, FieldLabel, FieldDescription, FieldError, FieldGroup } from '@nanisoft/prism-ui/components/field'
7
+ ```
8
+
9
+ ## Overview
10
+
11
+ A Field pairs a form control with its label, its helper text and its error. It
12
+ ships as `Field`, `FieldLabel`, `FieldDescription`, `FieldError` and
13
+ `FieldGroup`, all from the same module.
14
+
15
+ The parts are presentational, and the consumer owns the wiring. `FieldLabel`
16
+ renders a native `<label>` and takes the control's `id` as `htmlFor`.
17
+ `FieldDescription` and `FieldError` take an `id` that the control references
18
+ through `aria-describedby`. Nothing generates an `id`, so a field stays a
19
+ Server Component and the markup is settled before it reaches the browser.
20
+
21
+ `FieldError` carries `role="alert"`, so it is announced when it appears. Render
22
+ it only while the field is invalid, and mark the control itself with
23
+ `aria-invalid` so the failure is visible as well as spoken.
24
+
25
+ ## Guidelines
26
+
27
+ ### When to use
28
+
29
+ Use a Field around any form control that needs a visible label. Pair it with
30
+ `Input`, `Textarea` or a future control that does not ship its own label.
31
+
32
+ Use `FieldGroup` when several fields belong to one decision, such as an address
33
+ or a notification preference, so the set reads as one block.
34
+
35
+ ### When not to use
36
+
37
+ Do not use a Field as a layout grid. It controls label, control, helper and
38
+ error order, not column placement; wrap fields in your own grid for that.
39
+
40
+ Do not use `FieldDescription` as the only label. A placeholder or a hint is not
41
+ an accessible name, and it disappears as soon as the reader types.
42
+
43
+ Do not render `FieldError` alongside valid content. An error that is always
44
+ present stops meaning anything.
45
+
46
+ ### Best practices
47
+
48
+ - Put the label above the control. It survives zoom and translation better than
49
+ a label to the side.
50
+ - Point `htmlFor` at the control's `id`, and keep those two values stable so the
51
+ label is programmatically attached rather than merely adjacent.
52
+ - Reference both the description and the error from `aria-describedby`, and put
53
+ the error first when both are present.
54
+ - Replace the helper text with the error while the field is invalid instead of
55
+ stacking both. The reader needs one instruction at a time.
56
+ - Mark the control with `aria-invalid` and let the error sentence say what to do
57
+ next. The colour is a reinforcement, never the message.
58
+ - Group related fields with `FieldGroup` and give the group a heading when it
59
+ helps a screen reader move through a long form.
60
+
61
+ ### Content guidelines
62
+
63
+ - Start an error with what is wrong and how to fix it: "Enter an address in the
64
+ form name@example.com", not "Invalid input".
65
+ - Keep a helper line to one sentence. A paragraph belongs above the field, not
66
+ under it.
67
+ - Do not label a field with an instruction. "Email" is a name; "Enter your
68
+ email address to continue" is copy that belongs beside the control.
69
+
70
+ **A group of fields: two valid controls and one showing an error.**
71
+
72
+ ```tsx
73
+ import {
74
+ Field,
75
+ FieldDescription,
76
+ FieldError,
77
+ FieldGroup,
78
+ FieldLabel,
79
+ } from '@nanisoft/prism-ui/components/field'
80
+ import { Input } from '@nanisoft/prism-ui/components/input'
81
+ import { Textarea } from '@nanisoft/prism-ui/components/textarea'
82
+
83
+ /** A group of fields: two valid controls and one showing an error. */
84
+ export default function FieldDemo() {
85
+ return (
86
+ <FieldGroup className="max-w-measure-narrow">
87
+ <Field>
88
+ <FieldLabel htmlFor="field-display-name">Display name</FieldLabel>
89
+ <Input id="field-display-name" defaultValue="Ada Lovelace" />
90
+ <FieldDescription>Shown on your profile and in mentions.</FieldDescription>
91
+ </Field>
92
+ <Field>
93
+ <FieldLabel htmlFor="field-bio">Bio</FieldLabel>
94
+ <Textarea id="field-bio" placeholder="A sentence about yourself." />
95
+ </Field>
96
+ <Field>
97
+ <FieldLabel htmlFor="field-email">Email</FieldLabel>
98
+ <Input
99
+ id="field-email"
100
+ type="email"
101
+ defaultValue="not-an-email"
102
+ aria-invalid
103
+ aria-describedby="field-email-error"
104
+ />
105
+ <FieldError id="field-email-error">
106
+ Enter an address in the form name@example.com.
107
+ </FieldError>
108
+ </Field>
109
+ </FieldGroup>
110
+ )
111
+ }
112
+ ```
113
+
114
+ ## Props
115
+
116
+ > Extends: the native `<div>` element. No additional Prism-specific props.
@@ -1,14 +1,93 @@
1
1
  # Input
2
2
 
3
- antd Input, unchanged — a pass-through re-export. Import from '@nanisoft/prism-ui'.
3
+ The single-line text control for a form.
4
4
 
5
- ```ts
6
- import { Input } from '@nanisoft/prism-ui/components';
5
+ ```tsx
6
+ import { Input } from '@nanisoft/prism-ui/components/input'
7
7
  ```
8
8
 
9
- `Input` is antd's [Input](https://ant.design/components/input), re-exported unchanged.
9
+ ## Overview
10
10
 
11
- - Extends: antd **Input** — for inherited props and demos, use the antd MCP (`antd_info Input`).
12
- - Always import from '@nanisoft/prism-ui', never from `antd` directly.
11
+ An Input is the single-line text control. It renders a native `<input>`, so it
12
+ submits, validates, autocompletes and takes focus without extra work, and it
13
+ accepts every standard input type.
13
14
 
14
- _No additional props beyond the antd base component._
15
+ The focus ring is drawn at full strength rather than at half alpha, so it clears
16
+ the 3:1 non-text threshold on every surface. When the control is marked with
17
+ `aria-invalid`, the border and the ring switch to the destructive token, which
18
+ makes a failed field visible as well as announced.
19
+
20
+ ## Guidelines
21
+
22
+ ### When to use
23
+
24
+ Use an Input for a short, single-line value: a name, an address, a search term,
25
+ a quantity, a date or a password.
26
+
27
+ Pair it with a Field so the control keeps a visible label, and pass the correct
28
+ `type` so mobile keyboards and browser validation both do their job.
29
+
30
+ ### When not to use
31
+
32
+ Do not use an Input for free-form text longer than a line. A Textarea gives the
33
+ reader room to see what they have written.
34
+
35
+ Do not use one for a choice between options. A radio group, a select or a
36
+ switch states the options and their current state; a text box asks the reader to
37
+ remember them.
38
+
39
+ Do not use an Input as a display field for a value the reader cannot change.
40
+ Render the value as text.
41
+
42
+ ### Best practices
43
+
44
+ - Keep a visible label. A placeholder is a hint, not a name, and it vanishes on
45
+ the first keystroke.
46
+ - Choose the `type` and `inputMode` that match the value, and set `autoComplete`
47
+ so the browser can fill it. Getting this right saves more effort than any
48
+ visual detail.
49
+ - Show the error beside the field and mark the control with `aria-invalid`.
50
+ Colour alone never carries the failure.
51
+ - Disable a control only when the reason is visible nearby. A disabled input
52
+ with no explanation is a dead end.
53
+ - Keep the default height and radius. Size is a token decision, and a taller
54
+ input breaks alignment with every other control on the row.
55
+
56
+ ### Content guidelines
57
+
58
+ - A placeholder may show the expected format, for example `name@example.com`,
59
+ and nothing more.
60
+ - A helper line states the rule, not the field's name: "At least eight
61
+ characters", not "Password".
62
+ - Do not write an error in the imperative twice. One instruction per message.
63
+
64
+ **Input types at rest, disabled, and marked invalid.**
65
+
66
+ ```tsx
67
+ import { Field, FieldLabel } from '@nanisoft/prism-ui/components/field'
68
+ import { Input } from '@nanisoft/prism-ui/components/input'
69
+
70
+ /** Input types at rest, disabled, and marked invalid. */
71
+ export default function InputDemo() {
72
+ return (
73
+ <div className="flex max-w-measure-narrow flex-col gap-4">
74
+ <Field>
75
+ <FieldLabel htmlFor="input-email">Email</FieldLabel>
76
+ <Input id="input-email" type="email" placeholder="name@example.com" />
77
+ </Field>
78
+ <Field>
79
+ <FieldLabel htmlFor="input-workspace">Workspace</FieldLabel>
80
+ <Input id="input-workspace" defaultValue="Locked workspace" disabled />
81
+ </Field>
82
+ <Field>
83
+ <FieldLabel htmlFor="input-handle">Handle</FieldLabel>
84
+ <Input id="input-handle" defaultValue="with spaces" aria-invalid />
85
+ </Field>
86
+ </div>
87
+ )
88
+ }
89
+ ```
90
+
91
+ ## Props
92
+
93
+ > Extends: the native `<input>` element. No additional Prism-specific props.
@@ -0,0 +1,77 @@
1
+ # Kbd
2
+
3
+ The inline label for a keyboard key or shortcut.
4
+
5
+ ```tsx
6
+ import { Kbd } from '@nanisoft/prism-ui/components/kbd'
7
+ ```
8
+
9
+ ## Overview
10
+
11
+ A Kbd is the inline label for a keyboard key or shortcut. It renders a native
12
+ `<kbd>`, so assistive technology can identify it as input the reader types
13
+ rather than as text to read.
14
+
15
+ It sits inline with surrounding copy and takes its surface from the muted token.
16
+ Shortcuts are written with one element per key, so `Ctrl` and `K` are two Kbd
17
+ elements with a space between them.
18
+
19
+ ## Guidelines
20
+
21
+ ### When to use
22
+
23
+ Use a Kbd when the reader must press a key to do something: a documented
24
+ shortcut, a hint in a menu or a tooltip, or an onboarding step that names the
25
+ keys.
26
+
27
+ ### When not to use
28
+
29
+ Do not use a Kbd for a piece of code or a filename. Inline code already has its
30
+ own treatment.
31
+
32
+ Do not use one as a button label. A control that can be clicked shows a verb; a
33
+ keyboard shortcut is an alternative, not the action.
34
+
35
+ Do not use a Kbd for input the reader does not type, such as the name of a menu
36
+ command.
37
+
38
+ ### Best practices
39
+
40
+ - Use one Kbd per key. A single element holding the whole chord hides the
41
+ individual keys from anyone scanning or reading by element.
42
+ - Name the modifier as the keyboard shows it and say which platform you assume.
43
+ There is no server-safe way to detect the reader's platform, so "Ctrl on
44
+ Windows and Linux, Cmd on macOS" is more honest than picking one.
45
+ - Keep the hint inside a sentence that already states the action, so the keys
46
+ are never the only instruction.
47
+ - Do not style a Kbd to look pressable. It reports a key, it does not receive a
48
+ press, and it is excluded from pointer events on purpose.
49
+ - Keep the label to the key itself. Do not add the word "key" after it, because
50
+ the element already says what it is.
51
+
52
+ **Shortcuts written with one element per key.**
53
+
54
+ ```tsx
55
+ import { Kbd } from '@nanisoft/prism-ui/components/kbd'
56
+
57
+ /** Shortcuts written with one element per key. */
58
+ export default function KbdDemo() {
59
+ return (
60
+ <div className="flex flex-col gap-3 text-sm">
61
+ <p className="flex items-center gap-1.5">
62
+ Open the command menu <Kbd>Ctrl</Kbd> <Kbd>K</Kbd>
63
+ </p>
64
+ <p className="flex items-center gap-1.5">
65
+ Save the draft <Kbd>Ctrl</Kbd> <Kbd>S</Kbd>
66
+ </p>
67
+ <p className="flex items-center gap-1.5">
68
+ Close the dialog <Kbd>Esc</Kbd>
69
+ </p>
70
+ </div>
71
+ )
72
+ }
73
+ ```
74
+
75
+ ## Props
76
+
77
+ > Extends: the native `<kbd>` element. No additional Prism-specific props.
@@ -1,14 +1,102 @@
1
1
  # Pagination
2
2
 
3
- antd Pagination, unchanged — a pass-through re-export. Import from '@nanisoft/prism-ui'.
3
+ The control that moves between pages of a paged collection.
4
4
 
5
- ```ts
6
- import { Pagination } from '@nanisoft/prism-ui/components';
5
+ ```tsx
6
+ import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis } from '@nanisoft/prism-ui/components/pagination'
7
7
  ```
8
8
 
9
- `Pagination` is antd's [Pagination](https://ant.design/components/pagination), re-exported unchanged.
9
+ ## Overview
10
10
 
11
- - Extends: antd **Pagination** — for inherited props and demos, use the antd MCP (`antd_info Pagination`).
12
- - Always import from '@nanisoft/prism-ui', never from `antd` directly.
11
+ A Pagination moves between the pages of a paged collection. It ships as a
12
+ parent and six parts: `Pagination`, `PaginationContent`, `PaginationItem`,
13
+ `PaginationLink`, `PaginationPrevious`, `PaginationNext` and
14
+ `PaginationEllipsis`, all from the same module.
13
15
 
14
- _No additional props beyond the antd base component._
16
+ `Pagination` is a labelled `<nav>`, and `PaginationContent` is a `<ul>` so the
17
+ page numbers form one list for assistive technology. The current page is marked
18
+ with `aria-current="page"`, the step controls carry their own accessible names,
19
+ and the ellipsis is hidden from the accessibility tree because the links around
20
+ it already name the range.
21
+
22
+ ## Guidelines
23
+
24
+ ### When to use
25
+
26
+ Use a Pagination when a result set is longer than one screen and the total is
27
+ known. The page a reader is on, and how many pages exist, are both part of the
28
+ information the control carries.
29
+
30
+ ### When not to use
31
+
32
+ Do not use it for a short list that fits on one page. A single page link is
33
+ furniture around nothing.
34
+
35
+ Do not use it as a step control in a wizard. A checkout or an onboarding flow
36
+ has a fixed order and no page numbers, so a pair of previous and next buttons
37
+ describes it better.
38
+
39
+ Do not replace it with infinite scroll and no page numbers. A reader who cannot
40
+ return to a position loses their place.
41
+
42
+ ### Best practices
43
+
44
+ - Render the current page as a link with `isActive`, so it is announced with
45
+ `aria-current="page"` and stays consistent in the row.
46
+ - Show a window of pages, not every page. Use `PaginationEllipsis` for the
47
+ hidden run and keep the first, last and neighbours visible.
48
+ - Keep `PaginationPrevious` and `PaginationNext` at the ends of the row. On
49
+ narrow layouts their labels collapse to the chevron and the accessible name
50
+ stays complete.
51
+ - Pass a real `href` on each link. A page of results is a location, so the link
52
+ should be right-clickable and openable in a new tab.
53
+ - State the range near the control, for example "1 to 20 of 348". Page numbers
54
+ alone do not tell the reader how much remains.
55
+
56
+ **A paged result set with the second page current.**
57
+
58
+ ```tsx
59
+ import {
60
+ Pagination,
61
+ PaginationContent,
62
+ PaginationEllipsis,
63
+ PaginationItem,
64
+ PaginationLink,
65
+ PaginationNext,
66
+ PaginationPrevious,
67
+ } from '@nanisoft/prism-ui/components/pagination'
68
+
69
+ /** A paged result set with the second page current. */
70
+ export default function PaginationDemo() {
71
+ return (
72
+ <Pagination>
73
+ <PaginationContent>
74
+ <PaginationItem>
75
+ <PaginationPrevious href="#" />
76
+ </PaginationItem>
77
+ <PaginationItem>
78
+ <PaginationLink href="#">1</PaginationLink>
79
+ </PaginationItem>
80
+ <PaginationItem>
81
+ <PaginationLink href="#" isActive>
82
+ 2
83
+ </PaginationLink>
84
+ </PaginationItem>
85
+ <PaginationItem>
86
+ <PaginationLink href="#">3</PaginationLink>
87
+ </PaginationItem>
88
+ <PaginationItem>
89
+ <PaginationEllipsis />
90
+ </PaginationItem>
91
+ <PaginationItem>
92
+ <PaginationNext href="#" />
93
+ </PaginationItem>
94
+ </PaginationContent>
95
+ </Pagination>
96
+ )
97
+ }
98
+ ```
99
+
100
+ ## Props
101
+
102
+ > Extends: the native `<nav>` element. No additional Prism-specific props.