@fragments-sdk/ui 0.8.8 → 0.9.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 +2 -2
- package/src/components/Accordion/Accordion.module.scss +1 -1
- package/src/components/Accordion/Accordion.test.tsx +1 -2
- package/src/components/Avatar/Avatar.fragment.tsx +18 -0
- package/src/components/Avatar/Avatar.test.tsx +18 -0
- package/src/components/Avatar/index.tsx +16 -0
- package/src/components/Badge/index.tsx +2 -0
- package/src/components/BentoGrid/BentoGrid.fragment.tsx +147 -0
- package/src/components/BentoGrid/BentoGrid.module.scss +123 -0
- package/src/components/BentoGrid/BentoGrid.test.tsx +140 -0
- package/src/components/BentoGrid/index.tsx +150 -0
- package/src/components/Button/index.tsx +2 -0
- package/src/components/Card/index.tsx +2 -0
- package/src/components/Chart/Chart.test.tsx +2 -2
- package/src/components/Checkbox/index.tsx +2 -0
- package/src/components/CodeBlock/index.tsx +1 -1
- package/src/components/Command/Command.test.tsx +1 -1
- package/src/components/Command/index.tsx +1 -1
- package/src/components/DatePicker/index.tsx +1 -1
- package/src/components/Dialog/index.tsx +2 -0
- package/src/components/Drawer/index.tsx +2 -0
- package/src/components/EmptyState/index.tsx +2 -0
- package/src/components/Field/index.tsx +2 -0
- package/src/components/Fieldset/index.tsx +2 -0
- package/src/components/Form/index.tsx +2 -0
- package/src/components/Header/Header.module.scss +4 -0
- package/src/components/Icon/index.tsx +2 -0
- package/src/components/List/index.tsx +2 -0
- package/src/components/Menu/index.tsx +2 -0
- package/src/components/NavigationMenu/NavigationMenu.module.scss +1 -2
- package/src/components/NavigationMenu/NavigationMenuContext.ts +2 -0
- package/src/components/NavigationMenu/index.tsx +51 -24
- package/src/components/NavigationMenu/useNavigationMenu.ts +3 -0
- package/src/components/Pagination/index.tsx +2 -0
- package/src/components/Popover/index.tsx +2 -0
- package/src/components/Progress/index.tsx +2 -0
- package/src/components/RadioGroup/index.tsx +2 -0
- package/src/components/Separator/index.tsx +2 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Theme/index.tsx +4 -3
- package/src/components/Toggle/index.tsx +2 -0
- package/src/components/ToggleGroup/ToggleGroup.fragment.tsx +96 -79
- package/src/components/ToggleGroup/index.tsx +2 -0
- package/src/components/Tooltip/index.tsx +2 -0
- package/src/index.ts +3 -2
- package/src/styles/globals.scss +5 -0
- package/src/tokens/_variables.scss +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { defineFragment } from
|
|
3
|
-
import { ToggleGroup } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { defineFragment } from "@fragments-sdk/cli/core";
|
|
3
|
+
import { ToggleGroup } from ".";
|
|
4
4
|
|
|
5
5
|
function DefaultExample() {
|
|
6
|
-
const [value, setValue] = React.useState(
|
|
6
|
+
const [value, setValue] = React.useState("left");
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
9
|
<ToggleGroup value={value} onChange={setValue}>
|
|
@@ -15,7 +15,7 @@ function DefaultExample() {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function PillsExample() {
|
|
18
|
-
const [value, setValue] = React.useState(
|
|
18
|
+
const [value, setValue] = React.useState("all");
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
21
|
<ToggleGroup value={value} onChange={setValue} variant="pills">
|
|
@@ -27,7 +27,7 @@ function PillsExample() {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function OutlineExample() {
|
|
30
|
-
const [value, setValue] = React.useState(
|
|
30
|
+
const [value, setValue] = React.useState("day");
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
33
|
<ToggleGroup value={value} onChange={setValue} variant="outline">
|
|
@@ -39,11 +39,11 @@ function OutlineExample() {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function SizesExample() {
|
|
42
|
-
const [value1, setValue1] = React.useState(
|
|
43
|
-
const [value2, setValue2] = React.useState(
|
|
42
|
+
const [value1, setValue1] = React.useState("a");
|
|
43
|
+
const [value2, setValue2] = React.useState("a");
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
|
-
<div style={{ display:
|
|
46
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
|
47
47
|
<ToggleGroup value={value1} onChange={setValue1} size="sm">
|
|
48
48
|
<ToggleGroup.Item value="a">Small</ToggleGroup.Item>
|
|
49
49
|
<ToggleGroup.Item value="b">Size</ToggleGroup.Item>
|
|
@@ -57,12 +57,19 @@ function SizesExample() {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function ViewSwitcherExample() {
|
|
60
|
-
const [view, setView] = React.useState(
|
|
60
|
+
const [view, setView] = React.useState("grid");
|
|
61
61
|
|
|
62
62
|
return (
|
|
63
63
|
<ToggleGroup value={view} onChange={setView} size="sm">
|
|
64
64
|
<ToggleGroup.Item value="grid">
|
|
65
|
-
<svg
|
|
65
|
+
<svg
|
|
66
|
+
width="16"
|
|
67
|
+
height="16"
|
|
68
|
+
viewBox="0 0 24 24"
|
|
69
|
+
fill="none"
|
|
70
|
+
stroke="currentColor"
|
|
71
|
+
strokeWidth="2"
|
|
72
|
+
>
|
|
66
73
|
<rect x="3" y="3" width="7" height="7" />
|
|
67
74
|
<rect x="14" y="3" width="7" height="7" />
|
|
68
75
|
<rect x="3" y="14" width="7" height="7" />
|
|
@@ -70,7 +77,14 @@ function ViewSwitcherExample() {
|
|
|
70
77
|
</svg>
|
|
71
78
|
</ToggleGroup.Item>
|
|
72
79
|
<ToggleGroup.Item value="list">
|
|
73
|
-
<svg
|
|
80
|
+
<svg
|
|
81
|
+
width="16"
|
|
82
|
+
height="16"
|
|
83
|
+
viewBox="0 0 24 24"
|
|
84
|
+
fill="none"
|
|
85
|
+
stroke="currentColor"
|
|
86
|
+
strokeWidth="2"
|
|
87
|
+
>
|
|
74
88
|
<line x1="3" y1="6" x2="21" y2="6" />
|
|
75
89
|
<line x1="3" y1="12" x2="21" y2="12" />
|
|
76
90
|
<line x1="3" y1="18" x2="21" y2="18" />
|
|
@@ -81,13 +95,15 @@ function ViewSwitcherExample() {
|
|
|
81
95
|
}
|
|
82
96
|
|
|
83
97
|
function DisabledItemExample() {
|
|
84
|
-
const [value, setValue] = React.useState(
|
|
98
|
+
const [value, setValue] = React.useState("basic");
|
|
85
99
|
|
|
86
100
|
return (
|
|
87
101
|
<ToggleGroup value={value} onChange={setValue}>
|
|
88
102
|
<ToggleGroup.Item value="basic">Basic</ToggleGroup.Item>
|
|
89
103
|
<ToggleGroup.Item value="pro">Pro</ToggleGroup.Item>
|
|
90
|
-
<ToggleGroup.Item value="enterprise" disabled>
|
|
104
|
+
<ToggleGroup.Item value="enterprise" disabled>
|
|
105
|
+
Enterprise
|
|
106
|
+
</ToggleGroup.Item>
|
|
91
107
|
</ToggleGroup>
|
|
92
108
|
);
|
|
93
109
|
}
|
|
@@ -96,104 +112,105 @@ export default defineFragment({
|
|
|
96
112
|
component: ToggleGroup,
|
|
97
113
|
|
|
98
114
|
meta: {
|
|
99
|
-
name:
|
|
100
|
-
description:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
name: "ToggleGroup",
|
|
116
|
+
description:
|
|
117
|
+
"A group of toggle buttons where only one can be selected at a time. Useful for switching between views, modes, or options.",
|
|
118
|
+
category: "forms",
|
|
119
|
+
status: "stable",
|
|
120
|
+
tags: ["toggle", "group", "fragmented", "control", "tabs", "switch"],
|
|
121
|
+
since: "0.2.0",
|
|
105
122
|
},
|
|
106
123
|
|
|
107
124
|
usage: {
|
|
108
125
|
when: [
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
126
|
+
"Switching between mutually exclusive views or modes",
|
|
127
|
+
"Selecting one option from a small set (2-5 options)",
|
|
128
|
+
"Fragmented controls like view switchers",
|
|
129
|
+
"Filter or sort options",
|
|
113
130
|
],
|
|
114
131
|
whenNot: [
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
132
|
+
"Multiple selections allowed (use Checkbox group)",
|
|
133
|
+
"Many options (use Select or RadioGroup)",
|
|
134
|
+
"Navigation between pages (use Tabs)",
|
|
135
|
+
"On/off toggle (use Switch component)",
|
|
119
136
|
],
|
|
120
137
|
guidelines: [
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
"Keep options to 2-5 items for clarity",
|
|
139
|
+
"Use clear, concise labels",
|
|
140
|
+
"Consider icons for common actions (grid/list view)",
|
|
141
|
+
"Ensure adequate touch targets on mobile",
|
|
125
142
|
],
|
|
126
143
|
accessibility: [
|
|
127
144
|
'Uses role="group" for semantic grouping',
|
|
128
145
|
'Each item has role="radio" with aria-checked',
|
|
129
|
-
|
|
130
|
-
|
|
146
|
+
"Keyboard navigable with Tab and arrow keys",
|
|
147
|
+
"Focus visible on active item",
|
|
131
148
|
],
|
|
132
149
|
},
|
|
133
150
|
|
|
134
151
|
props: {
|
|
135
152
|
value: {
|
|
136
|
-
type:
|
|
137
|
-
description:
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "Currently selected value",
|
|
138
155
|
required: true,
|
|
139
156
|
},
|
|
140
157
|
onChange: {
|
|
141
|
-
type:
|
|
142
|
-
description:
|
|
158
|
+
type: "function",
|
|
159
|
+
description: "Called with new value when selection changes",
|
|
143
160
|
required: true,
|
|
144
161
|
},
|
|
145
162
|
children: {
|
|
146
|
-
type:
|
|
147
|
-
description:
|
|
163
|
+
type: "node",
|
|
164
|
+
description: "ToggleGroup.Item components",
|
|
148
165
|
required: true,
|
|
149
166
|
},
|
|
150
167
|
variant: {
|
|
151
|
-
type:
|
|
152
|
-
description:
|
|
153
|
-
values: [
|
|
154
|
-
default:
|
|
168
|
+
type: "enum",
|
|
169
|
+
description: "Visual style",
|
|
170
|
+
values: ["default", "pills", "outline"],
|
|
171
|
+
default: "default",
|
|
155
172
|
},
|
|
156
173
|
size: {
|
|
157
|
-
type:
|
|
158
|
-
description:
|
|
159
|
-
values: [
|
|
160
|
-
default:
|
|
174
|
+
type: "enum",
|
|
175
|
+
description: "Size variant",
|
|
176
|
+
values: ["sm", "md"],
|
|
177
|
+
default: "md",
|
|
161
178
|
},
|
|
162
179
|
gap: {
|
|
163
|
-
type:
|
|
164
|
-
description:
|
|
165
|
-
values: [
|
|
166
|
-
default:
|
|
180
|
+
type: "enum",
|
|
181
|
+
description: "Gap between items (pills/outline variants)",
|
|
182
|
+
values: ["none", "xs", "sm"],
|
|
183
|
+
default: "xs",
|
|
167
184
|
},
|
|
168
185
|
},
|
|
169
186
|
|
|
170
187
|
relations: [
|
|
171
|
-
{
|
|
172
|
-
|
|
173
|
-
|
|
188
|
+
{
|
|
189
|
+
component: "RadioGroup",
|
|
190
|
+
relationship: "alternative",
|
|
191
|
+
note: "RadioGroup for form-style single selection",
|
|
192
|
+
},
|
|
193
|
+
{ component: "Tabs", relationship: "alternative", note: "Tabs for content panel switching" },
|
|
194
|
+
{ component: "Switch", relationship: "sibling", note: "Switch for single on/off control" },
|
|
174
195
|
],
|
|
175
196
|
|
|
176
197
|
contract: {
|
|
177
198
|
propsSummary: [
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
],
|
|
185
|
-
scenarioTags: [
|
|
186
|
-
'forms.selection',
|
|
187
|
-
'input.toggle',
|
|
188
|
-
'control.fragmented',
|
|
199
|
+
"value: string - selected value (required)",
|
|
200
|
+
"onChange: (value: string) => void - change handler (required)",
|
|
201
|
+
"children: ToggleGroup.Item[] - toggle items",
|
|
202
|
+
"variant: default|pills|outline - visual style",
|
|
203
|
+
"size: sm|md - size variant",
|
|
204
|
+
"gap: none|xs|sm - spacing",
|
|
189
205
|
],
|
|
190
|
-
|
|
206
|
+
scenarioTags: ["forms.selection", "input.toggle", "control.fragmented"],
|
|
207
|
+
a11yRules: ["A11Y_GROUP_ROLE", "A11Y_KEYBOARD_ACCESSIBLE"],
|
|
191
208
|
},
|
|
192
209
|
|
|
193
210
|
variants: [
|
|
194
211
|
{
|
|
195
|
-
name:
|
|
196
|
-
description:
|
|
212
|
+
name: "Default",
|
|
213
|
+
description: "Basic toggle group",
|
|
197
214
|
code: `<ToggleGroup value={value} onChange={setValue}>
|
|
198
215
|
<ToggleGroup.Item value="left">Left</ToggleGroup.Item>
|
|
199
216
|
<ToggleGroup.Item value="center">Center</ToggleGroup.Item>
|
|
@@ -202,8 +219,8 @@ export default defineFragment({
|
|
|
202
219
|
render: () => <DefaultExample />,
|
|
203
220
|
},
|
|
204
221
|
{
|
|
205
|
-
name:
|
|
206
|
-
description:
|
|
222
|
+
name: "Pills Variant",
|
|
223
|
+
description: "Pill-shaped toggle buttons",
|
|
207
224
|
code: `<ToggleGroup value={value} onChange={setValue} variant="pills">
|
|
208
225
|
<ToggleGroup.Item value="all">All</ToggleGroup.Item>
|
|
209
226
|
<ToggleGroup.Item value="active">Active</ToggleGroup.Item>
|
|
@@ -212,8 +229,8 @@ export default defineFragment({
|
|
|
212
229
|
render: () => <PillsExample />,
|
|
213
230
|
},
|
|
214
231
|
{
|
|
215
|
-
name:
|
|
216
|
-
description:
|
|
232
|
+
name: "Outline Variant",
|
|
233
|
+
description: "Outlined toggle buttons",
|
|
217
234
|
code: `<ToggleGroup value={value} onChange={setValue} variant="outline">
|
|
218
235
|
<ToggleGroup.Item value="day">Day</ToggleGroup.Item>
|
|
219
236
|
<ToggleGroup.Item value="week">Week</ToggleGroup.Item>
|
|
@@ -222,8 +239,8 @@ export default defineFragment({
|
|
|
222
239
|
render: () => <OutlineExample />,
|
|
223
240
|
},
|
|
224
241
|
{
|
|
225
|
-
name:
|
|
226
|
-
description:
|
|
242
|
+
name: "Sizes",
|
|
243
|
+
description: "Different size variants",
|
|
227
244
|
code: `<ToggleGroup value={value} onChange={setValue} size="sm">
|
|
228
245
|
<ToggleGroup.Item value="a">Small</ToggleGroup.Item>
|
|
229
246
|
<ToggleGroup.Item value="b">Size</ToggleGroup.Item>
|
|
@@ -235,8 +252,8 @@ export default defineFragment({
|
|
|
235
252
|
render: () => <SizesExample />,
|
|
236
253
|
},
|
|
237
254
|
{
|
|
238
|
-
name:
|
|
239
|
-
description:
|
|
255
|
+
name: "View Switcher",
|
|
256
|
+
description: "Common pattern for switching between views",
|
|
240
257
|
code: `<ToggleGroup value={view} onChange={setView} size="sm">
|
|
241
258
|
<ToggleGroup.Item value="grid"><GridIcon /></ToggleGroup.Item>
|
|
242
259
|
<ToggleGroup.Item value="list"><ListIcon /></ToggleGroup.Item>
|
|
@@ -244,8 +261,8 @@ export default defineFragment({
|
|
|
244
261
|
render: () => <ViewSwitcherExample />,
|
|
245
262
|
},
|
|
246
263
|
{
|
|
247
|
-
name:
|
|
248
|
-
description:
|
|
264
|
+
name: "With Disabled Item",
|
|
265
|
+
description: "Toggle group with a disabled option",
|
|
249
266
|
code: `<ToggleGroup value={value} onChange={setValue}>
|
|
250
267
|
<ToggleGroup.Item value="basic">Basic</ToggleGroup.Item>
|
|
251
268
|
<ToggleGroup.Item value="pro">Pro</ToggleGroup.Item>
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
1
|
// Import CSS variables and base styles
|
|
4
2
|
// This ensures --fui-* variables are available when using any component
|
|
5
3
|
import './styles/globals.scss';
|
|
@@ -184,6 +182,9 @@ export {
|
|
|
184
182
|
// Grid
|
|
185
183
|
export { Grid, type GridProps, type GridItemProps, type ResponsiveColumns } from './components/Grid';
|
|
186
184
|
|
|
185
|
+
// BentoGrid
|
|
186
|
+
export { BentoGrid, type BentoGridProps, type BentoGridItemProps, type ResponsiveSpan } from './components/BentoGrid';
|
|
187
|
+
|
|
187
188
|
// Separator
|
|
188
189
|
export { Separator, type SeparatorProps } from './components/Separator';
|
|
189
190
|
|
package/src/styles/globals.scss
CHANGED
|
@@ -44,6 +44,11 @@ body {
|
|
|
44
44
|
font-feature-settings: "rlig" 1, "calt" 1;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Global link reset
|
|
48
|
+
a {
|
|
49
|
+
text-decoration: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
*::selection {
|
|
48
53
|
background-color: var(--fui-color-success-bg, rgba(16, 163, 127, 0.1));
|
|
49
54
|
color: var(--fui-text-primary, #171717);
|
|
@@ -350,7 +350,7 @@ $fui-theme-toggle-lg-height: 34px !default;
|
|
|
350
350
|
$fui-theme-toggle-lg-icon: 18px !default;
|
|
351
351
|
|
|
352
352
|
// CodeBlock (light mode)
|
|
353
|
-
$fui-code-bg:
|
|
353
|
+
$fui-code-bg: #1e1e1e !default;
|
|
354
354
|
$fui-code-header-bg: var(--fui-bg-elevated) !default;
|
|
355
355
|
$fui-code-text: #d4d4d4 !default;
|
|
356
356
|
$fui-code-text-muted: #6b7280 !default;
|