@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.
Files changed (69) hide show
  1. package/fragments.json +1 -1
  2. package/package.json +3 -3
  3. package/src/components/Accordion/Accordion.contract.json +169 -0
  4. package/src/components/Alert/Alert.contract.json +157 -0
  5. package/src/components/AppShell/AppShell.contract.json +155 -0
  6. package/src/components/Avatar/Avatar.contract.json +189 -0
  7. package/src/components/Badge/Badge.contract.json +187 -0
  8. package/src/components/BentoGrid/BentoGrid.contract.json +135 -0
  9. package/src/components/Box/Box.contract.json +423 -0
  10. package/src/components/Breadcrumbs/Breadcrumbs.contract.json +143 -0
  11. package/src/components/Button/Button.contract.json +205 -0
  12. package/src/components/ButtonGroup/ButtonGroup.contract.json +140 -0
  13. package/src/components/Card/Card.contract.json +185 -0
  14. package/src/components/Chart/Chart.contract.json +129 -0
  15. package/src/components/Checkbox/Checkbox.contract.json +246 -0
  16. package/src/components/Chip/Chip.contract.json +212 -0
  17. package/src/components/CodeBlock/CodeBlock.contract.json +388 -0
  18. package/src/components/Collapsible/Collapsible.contract.json +154 -0
  19. package/src/components/ColorPicker/ColorPicker.contract.json +212 -0
  20. package/src/components/Combobox/Combobox.contract.json +297 -0
  21. package/src/components/Command/Command.contract.json +165 -0
  22. package/src/components/ConversationList/ConversationList.contract.json +151 -0
  23. package/src/components/DataTable/DataTable.contract.json +302 -0
  24. package/src/components/DatePicker/DatePicker.contract.json +288 -0
  25. package/src/components/Dialog/Dialog.contract.json +159 -0
  26. package/src/components/Drawer/Drawer.contract.json +160 -0
  27. package/src/components/Editor/Editor.contract.json +263 -0
  28. package/src/components/EmptyState/EmptyState.contract.json +133 -0
  29. package/src/components/Field/Field.contract.json +157 -0
  30. package/src/components/Fieldset/Fieldset.contract.json +117 -0
  31. package/src/components/Form/Form.contract.json +145 -0
  32. package/src/components/Grid/Grid.contract.json +195 -0
  33. package/src/components/Header/Header.contract.json +194 -0
  34. package/src/components/Icon/Icon.contract.json +194 -0
  35. package/src/components/Image/Image.contract.json +209 -0
  36. package/src/components/Input/Input.contract.json +344 -0
  37. package/src/components/Link/Link.contract.json +180 -0
  38. package/src/components/List/List.contract.json +154 -0
  39. package/src/components/Listbox/Listbox.contract.json +158 -0
  40. package/src/components/Loading/Loading.contract.json +167 -0
  41. package/src/components/Markdown/Markdown.contract.json +127 -0
  42. package/src/components/Menu/Menu.contract.json +177 -0
  43. package/src/components/Message/Message.contract.json +183 -0
  44. package/src/components/NavigationMenu/NavigationMenu.contract.json +203 -0
  45. package/src/components/Pagination/Pagination.contract.json +163 -0
  46. package/src/components/Popover/Popover.contract.json +163 -0
  47. package/src/components/Progress/Progress.contract.json +176 -0
  48. package/src/components/Prompt/Prompt.contract.json +211 -0
  49. package/src/components/RadioGroup/RadioGroup.contract.json +226 -0
  50. package/src/components/ScrollArea/ScrollArea.contract.json +131 -0
  51. package/src/components/Select/Select.contract.json +269 -0
  52. package/src/components/Separator/Separator.contract.json +143 -0
  53. package/src/components/Sidebar/Sidebar.contract.json +258 -0
  54. package/src/components/Skeleton/Skeleton.contract.json +166 -0
  55. package/src/components/Slider/Slider.contract.json +248 -0
  56. package/src/components/Stack/Stack.contract.json +220 -0
  57. package/src/components/Table/Table.contract.json +171 -0
  58. package/src/components/TableOfContents/TableOfContents.contract.json +145 -0
  59. package/src/components/Tabs/Tabs.contract.json +159 -0
  60. package/src/components/Text/Text.contract.json +239 -0
  61. package/src/components/Textarea/Textarea.contract.json +308 -0
  62. package/src/components/Theme/Theme.contract.json +152 -0
  63. package/src/components/ThinkingIndicator/ThinkingIndicator.contract.json +165 -0
  64. package/src/components/Toast/Toast.contract.json +181 -0
  65. package/src/components/Toggle/Toggle.contract.json +231 -0
  66. package/src/components/ToggleGroup/ToggleGroup.contract.json +206 -0
  67. package/src/components/Tooltip/Tooltip.contract.json +214 -0
  68. package/src/components/VisuallyHidden/VisuallyHidden.contract.json +116 -0
  69. package/src/tokens/_derive.scss +4 -1
@@ -0,0 +1,214 @@
1
+ {
2
+ "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
+ "name": "Tooltip",
4
+ "description": "Contextual help text that appears on hover or focus. Perfect for explaining icons, truncated text, or providing additional context.",
5
+ "category": "feedback",
6
+ "tags": [
7
+ "tooltip",
8
+ "hint",
9
+ "help",
10
+ "hover",
11
+ "contextual"
12
+ ],
13
+ "status": "stable",
14
+ "sourcePath": "src/components/Tooltip/index.tsx",
15
+ "exportName": "Tooltip",
16
+ "propsSummary": [
17
+ "children: element (required)",
18
+ "content: node (required)",
19
+ "side: top|bottom|left|right (default: top)",
20
+ "align: start|center|end (default: center)",
21
+ "sideOffset: number (default: 6)",
22
+ "delay: number",
23
+ "closeDelay: number",
24
+ "disabled: boolean (default: false)",
25
+ "arrow: boolean (default: true)",
26
+ "open: boolean",
27
+ "defaultOpen: boolean",
28
+ "onOpenChange: function",
29
+ "contentProps: object",
30
+ "style: object"
31
+ ],
32
+ "props": {
33
+ "children": {
34
+ "type": "element",
35
+ "description": "The element that triggers the tooltip",
36
+ "required": true
37
+ },
38
+ "content": {
39
+ "type": "node",
40
+ "description": "Content to display in the tooltip",
41
+ "required": true
42
+ },
43
+ "side": {
44
+ "type": "enum",
45
+ "description": "Which side to show the tooltip",
46
+ "default": "top",
47
+ "required": false,
48
+ "values": [
49
+ "top",
50
+ "bottom",
51
+ "left",
52
+ "right"
53
+ ]
54
+ },
55
+ "align": {
56
+ "type": "enum",
57
+ "description": "Alignment along the side",
58
+ "default": "center",
59
+ "required": false,
60
+ "values": [
61
+ "start",
62
+ "center",
63
+ "end"
64
+ ]
65
+ },
66
+ "sideOffset": {
67
+ "type": "number",
68
+ "description": "Distance from trigger in pixels",
69
+ "default": "6",
70
+ "required": false
71
+ },
72
+ "delay": {
73
+ "type": "number",
74
+ "description": "Delay before showing (ms)",
75
+ "default": "400",
76
+ "required": false
77
+ },
78
+ "closeDelay": {
79
+ "type": "number",
80
+ "description": "Delay before hiding (ms)",
81
+ "default": "0",
82
+ "required": false
83
+ },
84
+ "disabled": {
85
+ "type": "boolean",
86
+ "description": "Disable the tooltip",
87
+ "default": "false",
88
+ "required": false
89
+ },
90
+ "arrow": {
91
+ "type": "boolean",
92
+ "description": "Show arrow pointing to trigger",
93
+ "default": "true",
94
+ "required": false
95
+ },
96
+ "open": {
97
+ "type": "boolean",
98
+ "description": "Controlled open state",
99
+ "required": false
100
+ },
101
+ "defaultOpen": {
102
+ "type": "boolean",
103
+ "description": "Default open state",
104
+ "default": "false",
105
+ "required": false
106
+ },
107
+ "onOpenChange": {
108
+ "type": "function",
109
+ "description": "Callback when open state changes",
110
+ "required": false
111
+ },
112
+ "contentProps": {
113
+ "type": "object",
114
+ "description": "Props forwarded to the tooltip popup element (preferred way to pass popup attrs/className/style)",
115
+ "required": false
116
+ },
117
+ "style": {
118
+ "type": "object",
119
+ "description": "",
120
+ "required": false
121
+ }
122
+ },
123
+ "usage": {
124
+ "when": [
125
+ "Explaining icon-only buttons",
126
+ "Showing full text for truncated content",
127
+ "Providing keyboard shortcuts",
128
+ "Brief contextual help that fits in one line"
129
+ ],
130
+ "whenNot": [
131
+ "Long-form help content (use Popover)",
132
+ "Critical information users must see (use Alert)",
133
+ "Interactive content (use Popover or Menu)",
134
+ "Mobile-primary interfaces (tooltips require hover)"
135
+ ],
136
+ "guidelines": [
137
+ "Keep tooltip text concise (under 80 characters)",
138
+ "Use sentence case, no period for single sentences",
139
+ "Avoid duplicating visible label text",
140
+ "Consider mobile users who cannot hover",
141
+ "Use contentProps for tooltip popup attributes/styling; top-level HTML attrs are applied to the popup for backward compatibility"
142
+ ],
143
+ "accessibility": [
144
+ "Accessible via focus as well as hover",
145
+ "Uses role=\"tooltip\" with proper aria association",
146
+ "Delay prevents tooltips from appearing during navigation"
147
+ ]
148
+ },
149
+ "examples": [
150
+ {
151
+ "name": "Default",
152
+ "description": "Basic tooltip on hover",
153
+ "code": "<Tooltip content=\"Save your changes\">\n <Button>Save</Button>\n</Tooltip>"
154
+ },
155
+ {
156
+ "name": "Positions",
157
+ "description": "Tooltips on different sides",
158
+ "code": "<div style={{ display: 'flex', gap: '16px', padding: '40px' }}>\n <Tooltip content=\"Top tooltip\" side=\"top\">\n <Button variant=\"secondary\">Top</Button>\n </Tooltip>\n <Tooltip content=\"Bottom tooltip\" side=\"bottom\">\n <Button variant=\"secondary\">Bottom</Button>\n </Tooltip>\n <Tooltip content=\"Left tooltip\" side=\"left\">\n <Button variant=\"secondary\">Left</Button>\n </Tooltip>\n <Tooltip content=\"Right tooltip\" side=\"right\">\n <Button variant=\"secondary\">Right</Button>\n </Tooltip>\n</div>"
159
+ },
160
+ {
161
+ "name": "With Shortcut",
162
+ "description": "Tooltip showing keyboard shortcut",
163
+ "code": "<Tooltip content=\"Undo (Ctrl+Z)\">\n <Button variant=\"ghost\">Undo</Button>\n</Tooltip>"
164
+ },
165
+ {
166
+ "name": "No Arrow",
167
+ "description": "Tooltip without arrow",
168
+ "code": "<Tooltip content=\"Clean tooltip\" arrow={false}>\n <Button variant=\"secondary\">Hover me</Button>\n</Tooltip>"
169
+ },
170
+ {
171
+ "name": "With Content Props",
172
+ "description": "Pass popup attributes/styling using contentProps",
173
+ "code": "<Tooltip content=\"Custom popup attrs\" contentProps={{ id: 'custom-tooltip-popup' }}>\n <Button variant=\"secondary\">Hover me</Button>\n</Tooltip>"
174
+ }
175
+ ],
176
+ "relations": [
177
+ {
178
+ "component": "Popover",
179
+ "relationship": "alternative",
180
+ "note": "Use Popover for interactive or longer content"
181
+ },
182
+ {
183
+ "component": "Alert",
184
+ "relationship": "alternative",
185
+ "note": "Use Alert for critical information that must be visible"
186
+ }
187
+ ],
188
+ "contract": {
189
+ "propsSummary": [
190
+ "content: ReactNode - tooltip content",
191
+ "side: top|bottom|left|right - position",
192
+ "delay: number - show delay in ms (default: 400)",
193
+ "arrow: boolean - show arrow (default: true)",
194
+ "contentProps: HTMLAttributes<HTMLDivElement> - popup element props"
195
+ ],
196
+ "a11yRules": [
197
+ "A11Y_TOOLTIP_FOCUS",
198
+ "A11Y_TOOLTIP_ROLE"
199
+ ]
200
+ },
201
+ "ai": {
202
+ "compositionPattern": "compound",
203
+ "subComponents": [
204
+ "Root",
205
+ "Provider"
206
+ ]
207
+ },
208
+ "provenance": {
209
+ "source": "migrated",
210
+ "verified": false,
211
+ "frameworkSupport": "native",
212
+ "extractedAt": "2026-03-13T23:19:07.058Z"
213
+ }
214
+ }
@@ -0,0 +1,116 @@
1
+ {
2
+ "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
+ "name": "VisuallyHidden",
4
+ "description": "Hides content visually while keeping it accessible to screen readers. Essential for accessible icon-only buttons and supplementary text.",
5
+ "category": "navigation",
6
+ "tags": [
7
+ "accessibility",
8
+ "a11y",
9
+ "screen-reader",
10
+ "hidden",
11
+ "sr-only"
12
+ ],
13
+ "status": "stable",
14
+ "sourcePath": "src/components/VisuallyHidden/index.tsx",
15
+ "exportName": "VisuallyHidden",
16
+ "propsSummary": [
17
+ "children: node (required)",
18
+ "as: span|div (default: span)"
19
+ ],
20
+ "props": {
21
+ "children": {
22
+ "type": "node",
23
+ "description": "Content to hide visually",
24
+ "required": true
25
+ },
26
+ "as": {
27
+ "type": "enum",
28
+ "description": "HTML element to render",
29
+ "default": "span",
30
+ "required": false,
31
+ "values": [
32
+ "span",
33
+ "div"
34
+ ]
35
+ }
36
+ },
37
+ "usage": {
38
+ "when": [
39
+ "Providing accessible labels for icon-only buttons",
40
+ "Adding context that screen readers need but sighted users don't",
41
+ "Hiding decorative content while providing text alternatives",
42
+ "Skip links for keyboard navigation"
43
+ ],
44
+ "whenNot": [
45
+ "Hiding content from everyone (use display: none or conditional render)",
46
+ "Content that should be visible on focus (use focus-visible styles)",
47
+ "Temporarily hidden content (use proper ARIA attributes)",
48
+ "Lazy-loaded content (use suspense or loading states)"
49
+ ],
50
+ "guidelines": [
51
+ "Always use with icon-only interactive elements",
52
+ "Keep hidden text concise but descriptive",
53
+ "Test with screen readers to verify announcements",
54
+ "Don't overuse; visible text is often better",
55
+ "VisuallyHidden forwards DOM props and className to the rendered element"
56
+ ],
57
+ "accessibility": [
58
+ "Content is announced by screen readers",
59
+ "Content is focusable if interactive elements are inside",
60
+ "Essential for WCAG 2.1 compliance with icon-only controls",
61
+ "Must convey equivalent information to visual content"
62
+ ]
63
+ },
64
+ "examples": [
65
+ {
66
+ "name": "Icon Button Label",
67
+ "description": "Accessible label for icon-only button",
68
+ "code": "<button style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n border: '1px solid var(--fui-border-default)',\n borderRadius: '8px',\n background: 'var(--fui-color-surface-primary)',\n cursor: 'pointer'\n}}>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n <VisuallyHidden>Search</VisuallyHidden>\n</button>"
69
+ },
70
+ {
71
+ "name": "Supplementary Text",
72
+ "description": "Additional context for screen readers",
73
+ "code": "<a href=\"#\" style={{ color: 'var(--fui-color-accent)' }}>\n Read more\n <VisuallyHidden> about our accessibility features</VisuallyHidden>\n</a>"
74
+ },
75
+ {
76
+ "name": "Skip Link",
77
+ "description": "Navigation aid that becomes visible on focus",
78
+ "code": "<div>\n <VisuallyHidden as=\"div\">\n <a\n href=\"#main-content\"\n style={{\n position: 'absolute',\n padding: '8px 16px',\n background: 'var(--fui-color-accent)',\n color: 'white'\n }}\n >\n Skip to main content\n </a>\n </VisuallyHidden>\n <p style={{ color: 'var(--fui-color-text-tertiary)', fontSize: '14px' }}>\n (Screen reader only: \"Skip to main content\" link)\n </p>\n</div>"
79
+ }
80
+ ],
81
+ "relations": [
82
+ {
83
+ "component": "Button",
84
+ "relationship": "child",
85
+ "note": "Use inside icon-only buttons for accessible labels"
86
+ },
87
+ {
88
+ "component": "Icon",
89
+ "relationship": "sibling",
90
+ "note": "Pair with icons to provide text alternatives"
91
+ }
92
+ ],
93
+ "contract": {
94
+ "propsSummary": [
95
+ "children: ReactNode - hidden text (required)",
96
+ "as: span|div - HTML element",
97
+ "Forwards standard DOM props (id, aria-*, data-*, className, handlers)"
98
+ ],
99
+ "a11yRules": [
100
+ "A11Y_SR_ONLY",
101
+ "A11Y_ICON_LABEL"
102
+ ]
103
+ },
104
+ "ai": {
105
+ "compositionPattern": "compound",
106
+ "subComponents": [
107
+ "Root"
108
+ ]
109
+ },
110
+ "provenance": {
111
+ "source": "migrated",
112
+ "verified": false,
113
+ "frameworkSupport": "native",
114
+ "extractedAt": "2026-03-13T23:19:06.625Z"
115
+ }
116
+ }
@@ -214,7 +214,10 @@
214
214
  }
215
215
 
216
216
  // Light mode background — stone uses white, colorful palettes use palette[50]
217
- $bg: if($palette-name != 'stone', get-shade($palette, 50), #ffffff);
217
+ $bg: #ffffff;
218
+ @if $palette-name != 'stone' {
219
+ $bg: get-shade($palette, 50);
220
+ }
218
221
 
219
222
  @return (
220
223
  primary: get-shade($palette, 900), // Main text (high contrast)