@fragments-sdk/ui 0.17.1 → 0.18.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/fragments.json +1 -1
- package/package.json +3 -3
- package/src/components/Accordion/Accordion.contract.json +169 -0
- package/src/components/Alert/Alert.contract.json +157 -0
- package/src/components/AppShell/AppShell.contract.json +155 -0
- package/src/components/Avatar/Avatar.contract.json +189 -0
- package/src/components/Badge/Badge.contract.json +187 -0
- package/src/components/BentoGrid/BentoGrid.contract.json +135 -0
- package/src/components/Box/Box.contract.json +423 -0
- package/src/components/Breadcrumbs/Breadcrumbs.contract.json +143 -0
- package/src/components/Button/Button.contract.json +205 -0
- package/src/components/ButtonGroup/ButtonGroup.contract.json +140 -0
- package/src/components/Card/Card.contract.json +185 -0
- package/src/components/Chart/Chart.contract.json +129 -0
- package/src/components/Checkbox/Checkbox.contract.json +246 -0
- package/src/components/Chip/Chip.contract.json +212 -0
- package/src/components/CodeBlock/CodeBlock.contract.json +388 -0
- package/src/components/Collapsible/Collapsible.contract.json +154 -0
- package/src/components/ColorPicker/ColorPicker.contract.json +212 -0
- package/src/components/Combobox/Combobox.contract.json +297 -0
- package/src/components/Command/Command.contract.json +165 -0
- package/src/components/ConversationList/ConversationList.contract.json +151 -0
- package/src/components/DataTable/DataTable.contract.json +302 -0
- package/src/components/DatePicker/DatePicker.contract.json +288 -0
- package/src/components/Dialog/Dialog.contract.json +159 -0
- package/src/components/Drawer/Drawer.contract.json +160 -0
- package/src/components/Editor/Editor.contract.json +263 -0
- package/src/components/EmptyState/EmptyState.contract.json +133 -0
- package/src/components/Field/Field.contract.json +157 -0
- package/src/components/Fieldset/Fieldset.contract.json +117 -0
- package/src/components/Form/Form.contract.json +145 -0
- package/src/components/Grid/Grid.contract.json +195 -0
- package/src/components/Header/Header.contract.json +194 -0
- package/src/components/Icon/Icon.contract.json +194 -0
- package/src/components/Image/Image.contract.json +209 -0
- package/src/components/Input/Input.contract.json +344 -0
- package/src/components/Link/Link.contract.json +180 -0
- package/src/components/List/List.contract.json +154 -0
- package/src/components/Listbox/Listbox.contract.json +158 -0
- package/src/components/Loading/Loading.contract.json +167 -0
- package/src/components/Markdown/Markdown.contract.json +127 -0
- package/src/components/Menu/Menu.contract.json +177 -0
- package/src/components/Message/Message.contract.json +183 -0
- package/src/components/NavigationMenu/NavigationMenu.contract.json +203 -0
- package/src/components/Pagination/Pagination.contract.json +163 -0
- package/src/components/Popover/Popover.contract.json +163 -0
- package/src/components/Progress/Progress.contract.json +176 -0
- package/src/components/Prompt/Prompt.contract.json +211 -0
- package/src/components/RadioGroup/RadioGroup.contract.json +226 -0
- package/src/components/ScrollArea/ScrollArea.contract.json +131 -0
- package/src/components/Select/Select.contract.json +269 -0
- package/src/components/Separator/Separator.contract.json +143 -0
- package/src/components/Sidebar/Sidebar.contract.json +258 -0
- package/src/components/Skeleton/Skeleton.contract.json +166 -0
- package/src/components/Slider/Slider.contract.json +248 -0
- package/src/components/Stack/Stack.contract.json +220 -0
- package/src/components/Table/Table.contract.json +171 -0
- package/src/components/TableOfContents/TableOfContents.contract.json +145 -0
- package/src/components/Tabs/Tabs.contract.json +159 -0
- package/src/components/Text/Text.contract.json +239 -0
- package/src/components/Textarea/Textarea.contract.json +308 -0
- package/src/components/Theme/Theme.contract.json +152 -0
- package/src/components/ThinkingIndicator/ThinkingIndicator.contract.json +165 -0
- package/src/components/Toast/Toast.contract.json +181 -0
- package/src/components/Toggle/Toggle.contract.json +231 -0
- package/src/components/ToggleGroup/ToggleGroup.contract.json +206 -0
- package/src/components/Tooltip/Tooltip.contract.json +214 -0
- package/src/components/VisuallyHidden/VisuallyHidden.contract.json +116 -0
- package/src/tokens/_derive.scss +4 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://usefragments.com/schemas/contract.v1.json",
|
|
3
|
+
"name": "Message",
|
|
4
|
+
"description": "Individual chat message display with role-based styling",
|
|
5
|
+
"category": "ai",
|
|
6
|
+
"tags": [
|
|
7
|
+
"message",
|
|
8
|
+
"chat",
|
|
9
|
+
"ai",
|
|
10
|
+
"conversation",
|
|
11
|
+
"bubble"
|
|
12
|
+
],
|
|
13
|
+
"status": "stable",
|
|
14
|
+
"sourcePath": "src/components/Message/index.tsx",
|
|
15
|
+
"exportName": "Message",
|
|
16
|
+
"propsSummary": [
|
|
17
|
+
"role: user|assistant|system (required)",
|
|
18
|
+
"children: node (required)",
|
|
19
|
+
"status: sending|streaming|complete|error (default: complete)",
|
|
20
|
+
"timestamp: object",
|
|
21
|
+
"avatar: node",
|
|
22
|
+
"actions: node"
|
|
23
|
+
],
|
|
24
|
+
"props": {
|
|
25
|
+
"role": {
|
|
26
|
+
"type": "enum",
|
|
27
|
+
"description": "Message role determines styling and alignment",
|
|
28
|
+
"required": true,
|
|
29
|
+
"values": [
|
|
30
|
+
"user",
|
|
31
|
+
"assistant",
|
|
32
|
+
"system"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"children": {
|
|
36
|
+
"type": "node",
|
|
37
|
+
"description": "Message content",
|
|
38
|
+
"required": true
|
|
39
|
+
},
|
|
40
|
+
"status": {
|
|
41
|
+
"type": "enum",
|
|
42
|
+
"description": "Message state",
|
|
43
|
+
"default": "complete",
|
|
44
|
+
"required": false,
|
|
45
|
+
"values": [
|
|
46
|
+
"sending",
|
|
47
|
+
"streaming",
|
|
48
|
+
"complete",
|
|
49
|
+
"error"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"timestamp": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"description": "When the message was sent",
|
|
55
|
+
"required": false
|
|
56
|
+
},
|
|
57
|
+
"avatar": {
|
|
58
|
+
"type": "node",
|
|
59
|
+
"description": "Custom avatar override (null to hide)",
|
|
60
|
+
"required": false
|
|
61
|
+
},
|
|
62
|
+
"actions": {
|
|
63
|
+
"type": "node",
|
|
64
|
+
"description": "Hover actions (copy, regenerate)",
|
|
65
|
+
"required": false
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"usage": {
|
|
69
|
+
"when": [
|
|
70
|
+
"Displaying individual messages in a chat interface",
|
|
71
|
+
"Building AI assistant or chatbot UIs",
|
|
72
|
+
"Need role-based message styling (user vs assistant)",
|
|
73
|
+
"Messages need actions like copy, regenerate, or feedback"
|
|
74
|
+
],
|
|
75
|
+
"whenNot": [
|
|
76
|
+
"Simple text display without chat context (use Text)",
|
|
77
|
+
"Notification-style messages (use Alert or Toast)",
|
|
78
|
+
"Comment threads with nested replies (use Card with custom layout)"
|
|
79
|
+
],
|
|
80
|
+
"guidelines": [
|
|
81
|
+
"Always provide a role prop to determine styling",
|
|
82
|
+
"Use status prop to show message state (sending, streaming, error)",
|
|
83
|
+
"Consider showing timestamps for longer conversations",
|
|
84
|
+
"Provide hover actions for assistant messages (copy, regenerate)"
|
|
85
|
+
],
|
|
86
|
+
"accessibility": [
|
|
87
|
+
"Uses semantic HTML for message structure",
|
|
88
|
+
"Role-based styling has sufficient color contrast",
|
|
89
|
+
"Actions are keyboard accessible",
|
|
90
|
+
"Streaming indicator respects reduced motion preferences"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"examples": [
|
|
94
|
+
{
|
|
95
|
+
"name": "User Message",
|
|
96
|
+
"description": "Message from the user (right-aligned)",
|
|
97
|
+
"code": "<Message role=\"user\">\n <Message.Content>\n Hello! Can you help me with a coding question?\n </Message.Content>\n</Message>"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "Assistant Message",
|
|
101
|
+
"description": "Response from the AI assistant",
|
|
102
|
+
"code": "<Message role=\"assistant\">\n <Message.Content>\n Of course! I'd be happy to help. What would you like to know?\n </Message.Content>\n</Message>"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "System Message",
|
|
106
|
+
"description": "System notification or context",
|
|
107
|
+
"code": "<Message role=\"system\">\n <Message.Content>\n Conversation started. Model: GPT-4\n </Message.Content>\n</Message>"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "Streaming",
|
|
111
|
+
"description": "Message being streamed (with cursor)",
|
|
112
|
+
"code": "<Message role=\"assistant\" status=\"streaming\">\n <Message.Content>\n I'm currently generating a response for you\n </Message.Content>\n</Message>"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "With Timestamp",
|
|
116
|
+
"description": "Message with timestamp display",
|
|
117
|
+
"code": "<Message role=\"assistant\" timestamp={new Date(Date.now() - 300000)}>\n <Message.Content>\n This message was sent 5 minutes ago.\n </Message.Content>\n <Message.Timestamp />\n</Message>"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "Error State",
|
|
121
|
+
"description": "Message that failed to send",
|
|
122
|
+
"code": "<Message role=\"user\" status=\"error\">\n <Message.Content>\n This message failed to send.\n </Message.Content>\n</Message>"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "Custom Avatars",
|
|
126
|
+
"description": "Messages with image-based avatars",
|
|
127
|
+
"code": "<>\n <Message\n role=\"user\"\n avatar={<Message.Avatar src=\"https://i.pravatar.cc/64?u=user\" alt=\"Jane\" />}\n >\n <Message.Content>\n Can you help me understand this error?\n </Message.Content>\n </Message>\n <Message\n role=\"assistant\"\n avatar={<Message.Avatar src=\"https://i.pravatar.cc/64?u=bot\" alt=\"AI Assistant\" />}\n >\n <Message.Content>\n Sure! Let me take a look at that for you.\n </Message.Content>\n </Message>\n</>"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "With Actions",
|
|
131
|
+
"description": "Message with hover actions",
|
|
132
|
+
"code": "<Message\n role=\"assistant\"\n actions={\n <>\n <button style={{ padding: '4px 8px', fontSize: '12px' }}>Copy</button>\n <button style={{ padding: '4px 8px', fontSize: '12px' }}>Regenerate</button>\n </>\n }\n>\n <Message.Content>\n Hover over this message to see the actions.\n </Message.Content>\n</Message>"
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
"relations": [
|
|
136
|
+
{
|
|
137
|
+
"component": "ConversationList",
|
|
138
|
+
"relationship": "parent",
|
|
139
|
+
"note": "Messages are typically used within ConversationList"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"component": "Avatar",
|
|
143
|
+
"relationship": "child",
|
|
144
|
+
"note": "Use Avatar component for custom avatar content"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"component": "ThinkingIndicator",
|
|
148
|
+
"relationship": "sibling",
|
|
149
|
+
"note": "Show ThinkingIndicator while awaiting assistant response"
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
"contract": {
|
|
153
|
+
"propsSummary": [
|
|
154
|
+
"role: \"user\" | \"assistant\" | \"system\" - determines styling",
|
|
155
|
+
"children: ReactNode - message content",
|
|
156
|
+
"status: \"sending\" | \"streaming\" | \"complete\" | \"error\" - message state",
|
|
157
|
+
"timestamp: Date - when message was sent",
|
|
158
|
+
"avatar: ReactNode - custom avatar (null to hide)",
|
|
159
|
+
"actions: ReactNode - hover actions",
|
|
160
|
+
"Avatar.src: string - image URL for avatar",
|
|
161
|
+
"Avatar.alt: string - alt text for image avatar"
|
|
162
|
+
],
|
|
163
|
+
"a11yRules": [
|
|
164
|
+
"A11Y_COLOR_CONTRAST",
|
|
165
|
+
"A11Y_MOTION_PREFERENCE"
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
"ai": {
|
|
169
|
+
"compositionPattern": "compound",
|
|
170
|
+
"subComponents": [
|
|
171
|
+
"Content",
|
|
172
|
+
"Actions",
|
|
173
|
+
"Timestamp",
|
|
174
|
+
"Avatar"
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
"provenance": {
|
|
178
|
+
"source": "migrated",
|
|
179
|
+
"verified": false,
|
|
180
|
+
"frameworkSupport": "native",
|
|
181
|
+
"extractedAt": "2026-03-13T23:19:00.333Z"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://usefragments.com/schemas/contract.v1.json",
|
|
3
|
+
"name": "NavigationMenu",
|
|
4
|
+
"description": "Rich navigation menu for site headers with dropdown content panels, animated viewport transitions, and automatic mobile drawer. Supports structured links with titles, descriptions, and icons.",
|
|
5
|
+
"category": "navigation",
|
|
6
|
+
"tags": [
|
|
7
|
+
"navigation",
|
|
8
|
+
"menu",
|
|
9
|
+
"header",
|
|
10
|
+
"dropdown",
|
|
11
|
+
"navbar",
|
|
12
|
+
"mobile",
|
|
13
|
+
"responsive",
|
|
14
|
+
"drawer"
|
|
15
|
+
],
|
|
16
|
+
"status": "stable",
|
|
17
|
+
"sourcePath": "src/components/NavigationMenu/index.tsx",
|
|
18
|
+
"exportName": "NavigationMenu",
|
|
19
|
+
"propsSummary": [
|
|
20
|
+
"children: node (required)",
|
|
21
|
+
"value: string",
|
|
22
|
+
"defaultValue: string",
|
|
23
|
+
"onValueChange: function",
|
|
24
|
+
"orientation: horizontal|vertical (default: horizontal)",
|
|
25
|
+
"delayDuration: number (default: 200)",
|
|
26
|
+
"skipDelayDuration: number (default: 300)",
|
|
27
|
+
"icons: object"
|
|
28
|
+
],
|
|
29
|
+
"props": {
|
|
30
|
+
"children": {
|
|
31
|
+
"type": "node",
|
|
32
|
+
"description": "NavigationMenu.List, NavigationMenu.Viewport, and optionally NavigationMenu.MobileContent",
|
|
33
|
+
"required": true
|
|
34
|
+
},
|
|
35
|
+
"value": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"description": "Controlled open item value",
|
|
38
|
+
"required": false
|
|
39
|
+
},
|
|
40
|
+
"defaultValue": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Default open item value",
|
|
43
|
+
"default": "''",
|
|
44
|
+
"required": false
|
|
45
|
+
},
|
|
46
|
+
"onValueChange": {
|
|
47
|
+
"type": "function",
|
|
48
|
+
"description": "Callback when open item changes",
|
|
49
|
+
"required": false
|
|
50
|
+
},
|
|
51
|
+
"orientation": {
|
|
52
|
+
"type": "enum",
|
|
53
|
+
"description": "'horizontal' | 'vertical'",
|
|
54
|
+
"default": "horizontal",
|
|
55
|
+
"required": false,
|
|
56
|
+
"values": [
|
|
57
|
+
"horizontal",
|
|
58
|
+
"vertical"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"delayDuration": {
|
|
62
|
+
"type": "number",
|
|
63
|
+
"description": "Hover delay before opening (ms)",
|
|
64
|
+
"default": "200",
|
|
65
|
+
"required": false
|
|
66
|
+
},
|
|
67
|
+
"skipDelayDuration": {
|
|
68
|
+
"type": "number",
|
|
69
|
+
"description": "Duration after close during which moving to another trigger opens instantly (ms)",
|
|
70
|
+
"default": "300",
|
|
71
|
+
"required": false
|
|
72
|
+
},
|
|
73
|
+
"icons": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"description": "Optional icon overrides for triggerChevron, mobileMenu, mobileClose, and drawerClose controls",
|
|
76
|
+
"required": false
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"usage": {
|
|
80
|
+
"when": [
|
|
81
|
+
"Site-level header navigation with rich dropdown content",
|
|
82
|
+
"Navigation with titles, descriptions, and icons in dropdowns",
|
|
83
|
+
"Responsive navigation that converts to a mobile drawer automatically",
|
|
84
|
+
"Multi-section navigation requiring animated viewport transitions"
|
|
85
|
+
],
|
|
86
|
+
"whenNot": [
|
|
87
|
+
"Simple flat navigation without dropdowns (use Header.Nav)",
|
|
88
|
+
"Application menus with actions like cut/paste (use Menu)",
|
|
89
|
+
"Sidebar navigation (use Sidebar)",
|
|
90
|
+
"Breadcrumb trail navigation (use Breadcrumbs)"
|
|
91
|
+
],
|
|
92
|
+
"guidelines": [
|
|
93
|
+
"Place inside Header component for site-level navigation",
|
|
94
|
+
"Use NavigationMenu.Viewport for animated content panel transitions",
|
|
95
|
+
"Use NavigationMenu.MobileContent to add extra sections to the mobile drawer",
|
|
96
|
+
"Use structured links (title + description) for rich dropdown content",
|
|
97
|
+
"Use simple NavigationMenu.Link for items without dropdown content",
|
|
98
|
+
"NavigationMenu.Link asChild composes click handlers and respects event.preventDefault()",
|
|
99
|
+
"Triggers open on hover (desktop) with configurable delay",
|
|
100
|
+
"Use the icons prop to replace trigger chevrons and mobile drawer controls with icons from any package"
|
|
101
|
+
],
|
|
102
|
+
"accessibility": [
|
|
103
|
+
"Uses disclosure pattern (not menu role) per W3C guidance",
|
|
104
|
+
"Keyboard: Arrow keys navigate between triggers, Enter/Space toggles, Escape closes",
|
|
105
|
+
"Content panels have role=\"region\" with aria-labelledby pointing to trigger",
|
|
106
|
+
"Mobile drawer has focus trap, Escape to close, and aria-modal",
|
|
107
|
+
"Supports prefers-reduced-motion for all animations"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"examples": [
|
|
111
|
+
{
|
|
112
|
+
"name": "Default",
|
|
113
|
+
"description": "Two trigger items with dropdown content and one direct link",
|
|
114
|
+
"code": "<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"products\">\n <NavigationMenu.Trigger>Products</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <NavigationMenu.Link href=\"/analytics\" title=\"Analytics\" description=\"Track your metrics and KPIs.\" />\n <NavigationMenu.Link href=\"/automation\" title=\"Automation\" description=\"Automate your workflows.\" />\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"resources\">\n <NavigationMenu.Trigger>Resources</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <NavigationMenu.Link href=\"/docs\" title=\"Documentation\" description=\"Comprehensive API reference.\" />\n <NavigationMenu.Link href=\"/blog\" title=\"Blog\" description=\"Latest news and updates.\" />\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/pricing\">Pricing</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "With Rich Content",
|
|
118
|
+
"description": "Grid layout with icons, titles, and descriptions",
|
|
119
|
+
"code": "<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"platform\">\n <NavigationMenu.Trigger>Platform</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px', padding: '8px', minWidth: '400px' }}>\n <NavigationMenu.Link\n href=\"/dashboard\"\n title=\"Dashboard\"\n description=\"Overview of your project metrics.\"\n />\n <NavigationMenu.Link\n href=\"/analytics\"\n title=\"Analytics\"\n description=\"Deep dive into your data.\"\n />\n <NavigationMenu.Link\n href=\"/reports\"\n title=\"Reports\"\n description=\"Generate custom reports.\"\n />\n <NavigationMenu.Link\n href=\"/settings\"\n title=\"Settings\"\n description=\"Configure your workspace.\"\n />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "With Simple Links",
|
|
123
|
+
"description": "Mix of triggers with simple link lists and plain links",
|
|
124
|
+
"code": "<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"company\">\n <NavigationMenu.Trigger>Company</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'flex', flexDirection: 'column', padding: '4px', minWidth: '160px' }}>\n <NavigationMenu.Link href=\"/about\">About</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/careers\">Careers</NavigationMenu.Link>\n <NavigationMenu.Link href=\"/contact\">Contact</NavigationMenu.Link>\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/blog\">Blog</NavigationMenu.Link>\n </NavigationMenu.Item>\n <NavigationMenu.Item>\n <NavigationMenu.Link href=\"/docs\">Docs</NavigationMenu.Link>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "With Featured Card",
|
|
128
|
+
"description": "Highlighted featured item alongside regular links",
|
|
129
|
+
"code": "<NavigationMenu>\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"learn\">\n <NavigationMenu.Trigger>Learn</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', padding: '8px', minWidth: '420px' }}>\n <NavigationMenu.Link\n href=\"/quickstart\"\n title=\"Quick Start\"\n description=\"Get up and running in 5 minutes with our getting started guide.\"\n featured\n />\n <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n <NavigationMenu.Link href=\"/docs\" title=\"Documentation\" description=\"API reference and guides.\" />\n <NavigationMenu.Link href=\"/examples\" title=\"Examples\" description=\"Browse example projects.\" />\n </div>\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n</NavigationMenu>"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"name": "Vertical",
|
|
133
|
+
"description": "Vertical orientation with content panels to the right",
|
|
134
|
+
"code": "<div style={{ display: 'flex' }}>\n <NavigationMenu orientation=\"vertical\">\n <NavigationMenu.List>\n <NavigationMenu.Item value=\"overview\">\n <NavigationMenu.Trigger>Overview</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ padding: '8px', minWidth: '200px' }}>\n <NavigationMenu.Link href=\"/intro\" title=\"Introduction\" description=\"Learn the basics.\" />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n <NavigationMenu.Item value=\"guides\">\n <NavigationMenu.Trigger>Guides</NavigationMenu.Trigger>\n <NavigationMenu.Content>\n <div style={{ padding: '8px', minWidth: '200px' }}>\n <NavigationMenu.Link href=\"/install\" title=\"Installation\" description=\"Get started quickly.\" />\n <NavigationMenu.Link href=\"/config\" title=\"Configuration\" description=\"Customize your setup.\" />\n </div>\n </NavigationMenu.Content>\n </NavigationMenu.Item>\n </NavigationMenu.List>\n <NavigationMenu.Viewport />\n </NavigationMenu>\n</div>"
|
|
135
|
+
}
|
|
136
|
+
],
|
|
137
|
+
"relations": [
|
|
138
|
+
{
|
|
139
|
+
"component": "Header",
|
|
140
|
+
"relationship": "sibling",
|
|
141
|
+
"note": "Place NavigationMenu inside Header for site navigation"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"component": "Sidebar",
|
|
145
|
+
"relationship": "alternative",
|
|
146
|
+
"note": "Use Sidebar for persistent side navigation, NavigationMenu for header dropdowns"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"component": "Menu",
|
|
150
|
+
"relationship": "alternative",
|
|
151
|
+
"note": "Use Menu for action menus (role=menu), NavigationMenu for site navigation (disclosure pattern)"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"component": "Breadcrumbs",
|
|
155
|
+
"relationship": "sibling",
|
|
156
|
+
"note": "Use Breadcrumbs for hierarchical page trail, NavigationMenu for site-level navigation"
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"contract": {
|
|
160
|
+
"propsSummary": [
|
|
161
|
+
"value: string — controlled open item",
|
|
162
|
+
"onValueChange: (value) => void — open state handler",
|
|
163
|
+
"orientation: horizontal | vertical — layout direction",
|
|
164
|
+
"delayDuration: number — hover open delay (default: 200ms)",
|
|
165
|
+
"icons: { triggerChevron?, mobileMenu?, mobileClose?, drawerClose? } — custom internal control icons",
|
|
166
|
+
"NavigationMenu.Link: title + description + icon for structured links, or children for simple links",
|
|
167
|
+
"NavigationMenu.Link asChild: composes child and menu click handlers (preventDefault keeps menu open)",
|
|
168
|
+
"NavigationMenu.MobileContent: slot for extra mobile-only sections"
|
|
169
|
+
],
|
|
170
|
+
"a11yRules": [
|
|
171
|
+
"A11Y_DISCLOSURE_PATTERN",
|
|
172
|
+
"A11Y_KEYBOARD_NAV",
|
|
173
|
+
"A11Y_FOCUS_TRAP"
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
"ai": {
|
|
177
|
+
"compositionPattern": "compound",
|
|
178
|
+
"subComponents": [
|
|
179
|
+
"List",
|
|
180
|
+
"Item",
|
|
181
|
+
"Trigger",
|
|
182
|
+
"Content",
|
|
183
|
+
"Link",
|
|
184
|
+
"Indicator",
|
|
185
|
+
"Viewport",
|
|
186
|
+
"MobileBrand",
|
|
187
|
+
"MobileContent",
|
|
188
|
+
"MobileSection"
|
|
189
|
+
],
|
|
190
|
+
"requiredChildren": [
|
|
191
|
+
"List"
|
|
192
|
+
],
|
|
193
|
+
"commonPatterns": [
|
|
194
|
+
"<NavigationMenu><NavigationMenu.List><NavigationMenu.Item value=\"docs\"><NavigationMenu.Trigger>Docs</NavigationMenu.Trigger><NavigationMenu.Content><NavigationMenu.Link href=\"/guides\" title=\"Guides\" description=\"Learn the basics\" /></NavigationMenu.Content></NavigationMenu.Item></NavigationMenu.List><NavigationMenu.Viewport /></NavigationMenu>"
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
"provenance": {
|
|
198
|
+
"source": "migrated",
|
|
199
|
+
"verified": false,
|
|
200
|
+
"frameworkSupport": "native",
|
|
201
|
+
"extractedAt": "2026-03-13T23:19:01.458Z"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://usefragments.com/schemas/contract.v1.json",
|
|
3
|
+
"name": "Pagination",
|
|
4
|
+
"description": "Page navigation for paginated data. Supports controlled/uncontrolled, page counts, and edge/sibling customization.",
|
|
5
|
+
"category": "navigation",
|
|
6
|
+
"tags": [
|
|
7
|
+
"pagination",
|
|
8
|
+
"paging",
|
|
9
|
+
"pages",
|
|
10
|
+
"navigation"
|
|
11
|
+
],
|
|
12
|
+
"status": "stable",
|
|
13
|
+
"sourcePath": "src/components/Pagination/index.tsx",
|
|
14
|
+
"exportName": "Pagination",
|
|
15
|
+
"propsSummary": [
|
|
16
|
+
"children: node (required)",
|
|
17
|
+
"totalPages: number (required)",
|
|
18
|
+
"page: number",
|
|
19
|
+
"defaultPage: number (default: 1)",
|
|
20
|
+
"onPageChange: function",
|
|
21
|
+
"edgeCount: number (default: 1)",
|
|
22
|
+
"siblingCount: number (default: 1)"
|
|
23
|
+
],
|
|
24
|
+
"props": {
|
|
25
|
+
"children": {
|
|
26
|
+
"type": "node",
|
|
27
|
+
"description": "",
|
|
28
|
+
"required": true
|
|
29
|
+
},
|
|
30
|
+
"totalPages": {
|
|
31
|
+
"type": "number",
|
|
32
|
+
"description": "Total number of pages",
|
|
33
|
+
"required": true
|
|
34
|
+
},
|
|
35
|
+
"page": {
|
|
36
|
+
"type": "number",
|
|
37
|
+
"description": "Controlled current page (1-indexed)",
|
|
38
|
+
"required": false
|
|
39
|
+
},
|
|
40
|
+
"defaultPage": {
|
|
41
|
+
"type": "number",
|
|
42
|
+
"description": "Default page (uncontrolled)",
|
|
43
|
+
"default": "1",
|
|
44
|
+
"required": false
|
|
45
|
+
},
|
|
46
|
+
"onPageChange": {
|
|
47
|
+
"type": "function",
|
|
48
|
+
"description": "Called when page changes",
|
|
49
|
+
"required": false
|
|
50
|
+
},
|
|
51
|
+
"edgeCount": {
|
|
52
|
+
"type": "number",
|
|
53
|
+
"description": "Number of pages shown at edges",
|
|
54
|
+
"default": "1",
|
|
55
|
+
"required": false
|
|
56
|
+
},
|
|
57
|
+
"siblingCount": {
|
|
58
|
+
"type": "number",
|
|
59
|
+
"description": "Number of pages shown around current",
|
|
60
|
+
"default": "1",
|
|
61
|
+
"required": false
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"usage": {
|
|
65
|
+
"when": [
|
|
66
|
+
"Navigating through paginated data sets",
|
|
67
|
+
"Table or list pagination controls",
|
|
68
|
+
"Search results with multiple pages",
|
|
69
|
+
"Any content split across multiple pages"
|
|
70
|
+
],
|
|
71
|
+
"whenNot": [
|
|
72
|
+
"Small lists that fit on one page",
|
|
73
|
+
"Infinite scroll patterns (use IntersectionObserver)",
|
|
74
|
+
"Tab-based navigation (use Tabs)",
|
|
75
|
+
"Step-by-step wizards (use Stepper)"
|
|
76
|
+
],
|
|
77
|
+
"guidelines": [
|
|
78
|
+
"Place below the content being paginated",
|
|
79
|
+
"Use edgeCount to always show first/last pages",
|
|
80
|
+
"Use siblingCount to control how many pages surround the current page",
|
|
81
|
+
"Pair with Table component for data table pagination",
|
|
82
|
+
"Pagination forwards standard nav props (id, aria-*, data-*, event handlers) to the root <nav>",
|
|
83
|
+
"Previous/Next/Item buttons compose your onClick handlers; call event.preventDefault() to stop the page change"
|
|
84
|
+
],
|
|
85
|
+
"accessibility": [
|
|
86
|
+
"Uses nav element with aria-label=\"Pagination\"",
|
|
87
|
+
"aria-current=\"page\" marks the active page",
|
|
88
|
+
"Previous/Next buttons have descriptive aria-labels",
|
|
89
|
+
"Disabled buttons at boundaries prevent invalid navigation"
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
"examples": [
|
|
93
|
+
{
|
|
94
|
+
"name": "Default",
|
|
95
|
+
"description": "Basic pagination with 10 pages",
|
|
96
|
+
"code": "<Pagination totalPages={10} defaultPage={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"name": "With Edge Pages",
|
|
100
|
+
"description": "Shows 2 pages at each edge",
|
|
101
|
+
"code": "<Pagination totalPages={20} defaultPage={10} edgeCount={2} siblingCount={1}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"name": "Compact",
|
|
105
|
+
"description": "No siblings, minimal display",
|
|
106
|
+
"code": "<Pagination totalPages={20} defaultPage={10} siblingCount={0}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "Controlled",
|
|
110
|
+
"description": "Controlled pagination at page 3",
|
|
111
|
+
"code": "<Pagination totalPages={5} page={3}>\n <Pagination.Previous />\n <Pagination.Items />\n <Pagination.Next />\n</Pagination>"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"relations": [
|
|
115
|
+
{
|
|
116
|
+
"component": "Table",
|
|
117
|
+
"relationship": "sibling",
|
|
118
|
+
"note": "Commonly paired for table pagination"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"component": "Listbox",
|
|
122
|
+
"relationship": "alternative",
|
|
123
|
+
"note": "Use Listbox for small sets of options"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"contract": {
|
|
127
|
+
"propsSummary": [
|
|
128
|
+
"totalPages: number - total page count (required)",
|
|
129
|
+
"page: number - controlled current page (1-indexed)",
|
|
130
|
+
"defaultPage: number - initial page (default: 1)",
|
|
131
|
+
"onPageChange: (page) => void - page change handler",
|
|
132
|
+
"edgeCount: number - pages at edges (default: 1)",
|
|
133
|
+
"siblingCount: number - pages around current (default: 1)",
|
|
134
|
+
"Forwards standard HTML nav attributes to the root element"
|
|
135
|
+
],
|
|
136
|
+
"a11yRules": [
|
|
137
|
+
"A11Y_NAV_LABEL",
|
|
138
|
+
"A11Y_CURRENT_PAGE"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"ai": {
|
|
142
|
+
"compositionPattern": "compound",
|
|
143
|
+
"subComponents": [
|
|
144
|
+
"Previous",
|
|
145
|
+
"Next",
|
|
146
|
+
"Items",
|
|
147
|
+
"Item",
|
|
148
|
+
"Ellipsis"
|
|
149
|
+
],
|
|
150
|
+
"requiredChildren": [
|
|
151
|
+
"Items"
|
|
152
|
+
],
|
|
153
|
+
"commonPatterns": [
|
|
154
|
+
"<Pagination totalPages={totalPages} page={currentPage} onPageChange={setPage}><Pagination.Previous /><Pagination.Items /><Pagination.Next /></Pagination>"
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
"provenance": {
|
|
158
|
+
"source": "migrated",
|
|
159
|
+
"verified": false,
|
|
160
|
+
"frameworkSupport": "native",
|
|
161
|
+
"extractedAt": "2026-03-13T23:19:01.648Z"
|
|
162
|
+
}
|
|
163
|
+
}
|