@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.
- package/README.md +88 -0
- package/THIRD-PARTY-NOTICES.md +48 -0
- package/dist/data.json +4037 -386
- package/dist/demo-graph.d.ts +21 -12
- package/dist/demo-graph.js +37 -21
- package/dist/extractor.d.ts +24 -17
- package/dist/extractor.js +299 -156
- package/dist/index.d.ts +12 -7
- package/dist/index.js +9 -7
- package/dist/llms-full.txt +8248 -2013
- package/dist/llms.txt +98 -93
- package/dist/markdown.d.ts +69 -23
- package/dist/markdown.js +131 -72
- package/dist/md/blocks/app-shell-01.md +135 -0
- package/dist/md/blocks/auth-form-01.md +135 -0
- package/dist/md/blocks/cta-01.md +88 -0
- package/dist/md/blocks/data-table-01.md +196 -0
- package/dist/md/blocks/feature-grid-01.md +92 -0
- package/dist/md/blocks/hero-01.md +90 -0
- package/dist/md/blocks/instrument-panel-01.md +109 -0
- package/dist/md/blocks/logo-strip-01.md +97 -0
- package/dist/md/blocks/note-grid-01.md +98 -0
- package/dist/md/blocks/page-header-01.md +97 -0
- package/dist/md/blocks/pricing-01.md +91 -0
- package/dist/md/blocks/process-rail-01.md +106 -0
- package/dist/md/blocks/product-grid-01.md +107 -0
- package/dist/md/blocks/settings-panel-01.md +146 -0
- package/dist/md/blocks/site-footer.md +103 -11
- package/dist/md/blocks/site-header.md +107 -11
- package/dist/md/blocks/stack-grid-01.md +108 -0
- package/dist/md/blocks/stats-01.md +89 -0
- package/dist/md/blocks/status-ledger-01.md +121 -0
- package/dist/md/changelogs/prism-llms.md +244 -0
- package/dist/md/changelogs/prism-mcp-server.md +95 -0
- package/dist/md/changelogs/prism-tokens.md +126 -0
- package/dist/md/changelogs/prism-ui.md +467 -0
- package/dist/md/components/accordion.md +108 -0
- package/dist/md/components/alert.md +90 -7
- package/dist/md/components/avatar.md +89 -7
- package/dist/md/components/badge.md +74 -7
- package/dist/md/components/breadcrumb.md +84 -7
- package/dist/md/components/button.md +90 -7
- package/dist/md/components/card.md +90 -7
- package/dist/md/components/checkbox.md +101 -7
- package/dist/md/components/cta-link.md +98 -0
- package/dist/md/components/diagram.md +124 -0
- package/dist/md/components/dialog.md +128 -0
- package/dist/md/components/dropdown-menu.md +125 -0
- package/dist/md/components/fact-list.md +85 -0
- package/dist/md/components/field.md +116 -0
- package/dist/md/components/input.md +86 -7
- package/dist/md/components/kbd.md +77 -0
- package/dist/md/components/pagination.md +95 -7
- package/dist/md/components/popover.md +95 -7
- package/dist/md/components/product-mark.md +114 -0
- package/dist/md/components/product-switcher.md +88 -0
- package/dist/md/components/progress.md +88 -7
- package/dist/md/components/prose.md +91 -0
- package/dist/md/components/radio-group.md +111 -0
- package/dist/md/components/section.md +91 -0
- package/dist/md/components/select.md +143 -7
- package/dist/md/components/separator.md +77 -0
- package/dist/md/components/skeleton.md +71 -7
- package/dist/md/components/slider.md +90 -7
- package/dist/md/components/switch.md +104 -7
- package/dist/md/components/table.md +104 -7
- package/dist/md/components/tabs.md +105 -7
- package/dist/md/components/textarea.md +101 -0
- package/dist/md/components/tooltip.md +95 -7
- package/dist/md/components/typography.md +82 -7
- package/dist/md/content/about-content.md +36 -0
- package/dist/md/content/audience.md +43 -0
- package/dist/md/content/glossary.md +69 -0
- package/dist/md/content/product-vocabulary.md +53 -0
- package/dist/md/content/voice.md +52 -0
- package/dist/md/content/writing-mechanics.md +58 -0
- package/dist/md/foundation/colors.md +10 -0
- package/dist/md/foundation/iconography.md +14 -0
- package/dist/md/foundation/motion.md +10 -0
- package/dist/md/foundation/radii.md +9 -0
- package/dist/md/foundation/shadows.md +9 -0
- package/dist/md/foundation/spacings.md +8 -0
- package/dist/md/foundation/typography.md +9 -0
- package/dist/md/foundation/variables.md +9 -0
- package/dist/md/overview/architecture.md +76 -0
- package/dist/md/overview/brand.md +41 -0
- package/dist/md/overview/composition.md +77 -0
- package/dist/md/overview/quickstart.md +97 -0
- package/dist/md/overview/theming.md +89 -0
- package/dist/md/overview/using-llms.md +83 -0
- package/dist/md/pages/auth-page.md +149 -0
- package/dist/md/pages/blog-post-page.md +136 -0
- package/dist/md/pages/dashboard-page.md +241 -0
- package/dist/md/pages/docs-shell.md +210 -15
- package/dist/md/pages/marketing-page.md +199 -0
- package/dist/md/pages/not-found-page.md +105 -0
- package/dist/md/pages/settings-page.md +206 -0
- package/dist/prism-skill.md +50 -0
- package/dist/store.d.ts +203 -0
- package/dist/store.js +317 -0
- package/package.json +29 -26
- package/dist/demo-graph.d.ts.map +0 -1
- package/dist/demo-graph.js.map +0 -1
- package/dist/extractor.d.ts.map +0 -1
- package/dist/extractor.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/markdown.d.ts.map +0 -1
- package/dist/markdown.js.map +0 -1
- package/dist/md/blocks/component-demo.md +0 -19
- package/dist/md/blocks/page-header.md +0 -19
- package/dist/md/components/affix.md +0 -14
- package/dist/md/components/anchor.md +0 -14
- package/dist/md/components/auto-complete.md +0 -14
- package/dist/md/components/back-top.md +0 -14
- package/dist/md/components/border-beam.md +0 -14
- package/dist/md/components/calendar.md +0 -14
- package/dist/md/components/carousel.md +0 -14
- package/dist/md/components/cascader.md +0 -14
- package/dist/md/components/col.md +0 -14
- package/dist/md/components/collapse.md +0 -14
- package/dist/md/components/color-picker.md +0 -14
- package/dist/md/components/date-picker.md +0 -14
- package/dist/md/components/descriptions.md +0 -14
- package/dist/md/components/display-title.md +0 -20
- package/dist/md/components/divider.md +0 -14
- package/dist/md/components/drawer.md +0 -14
- package/dist/md/components/dropdown.md +0 -14
- package/dist/md/components/empty.md +0 -14
- package/dist/md/components/flex.md +0 -14
- package/dist/md/components/float-button.md +0 -14
- package/dist/md/components/form.md +0 -14
- package/dist/md/components/grid.md +0 -14
- package/dist/md/components/image.md +0 -14
- package/dist/md/components/input-number.md +0 -14
- package/dist/md/components/layout.md +0 -14
- package/dist/md/components/list.md +0 -14
- package/dist/md/components/listy.md +0 -14
- package/dist/md/components/masonry.md +0 -14
- package/dist/md/components/mentions.md +0 -14
- package/dist/md/components/menu.md +0 -14
- package/dist/md/components/modal.md +0 -14
- package/dist/md/components/popconfirm.md +0 -14
- package/dist/md/components/qrcode.md +0 -14
- package/dist/md/components/radio.md +0 -14
- package/dist/md/components/rate.md +0 -14
- package/dist/md/components/result.md +0 -14
- package/dist/md/components/row.md +0 -14
- package/dist/md/components/segmented.md +0 -14
- package/dist/md/components/space.md +0 -14
- package/dist/md/components/spin.md +0 -14
- package/dist/md/components/splitter.md +0 -14
- package/dist/md/components/statistic.md +0 -14
- package/dist/md/components/steps.md +0 -14
- package/dist/md/components/tag.md +0 -14
- package/dist/md/components/time-picker.md +0 -14
- package/dist/md/components/timeline.md +0 -14
- package/dist/md/components/tour.md +0 -14
- package/dist/md/components/transfer.md +0 -14
- package/dist/md/components/tree-select.md +0 -14
- package/dist/md/components/tree.md +0 -14
- package/dist/md/components/upload.md +0 -14
- package/dist/md/components/watermark.md +0 -14
- package/dist/md/docs/brand.md +0 -41
- package/dist/md/pages/blog-layout.md +0 -19
- package/dist/md/theme/blue-dark.md +0 -127
- package/dist/md/theme/blue-light.md +0 -129
- package/dist/md/theme/green-dark.md +0 -127
- package/dist/md/theme/green-light.md +0 -129
- package/dist/md/theme/lavender-dark.md +0 -127
- package/dist/md/theme/lavender-light.md +0 -129
- package/dist/md/theme/peach-dark.md +0 -127
- package/dist/md/theme/peach-light.md +0 -129
- package/dist/md/theme/rose-dark.md +0 -127
- 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
|
-
|
|
3
|
+
The single-line text control for a form.
|
|
4
4
|
|
|
5
|
-
```
|
|
6
|
-
import { Input } from '@nanisoft/prism-ui/components'
|
|
5
|
+
```tsx
|
|
6
|
+
import { Input } from '@nanisoft/prism-ui/components/input'
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Overview
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3
|
+
The control that moves between pages of a paged collection.
|
|
4
4
|
|
|
5
|
-
```
|
|
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
|
-
|
|
9
|
+
## Overview
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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.
|