@fragments-sdk/ui 0.4.0 → 0.6.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/README.md +98 -2
- package/fragments.json +1 -1
- package/package.json +4 -3
- package/src/components/Accordion/Accordion.fragment.tsx +1 -1
- package/src/components/Alert/Alert.fragment.tsx +1 -1
- package/src/components/AppShell/AppShell.fragment.tsx +4 -4
- package/src/components/Avatar/Avatar.fragment.tsx +2 -2
- package/src/components/Badge/Badge.fragment.tsx +2 -2
- package/src/components/Badge/Badge.module.scss +1 -1
- package/src/components/Box/Box.fragment.tsx +1 -1
- package/src/components/Button/Button.fragment.tsx +2 -2
- package/src/components/ButtonGroup/ButtonGroup.fragment.tsx +153 -0
- package/src/components/Card/Card.fragment.tsx +1 -1
- package/src/components/Chart/Chart.fragment.tsx +213 -0
- package/src/components/Chart/Chart.module.scss +123 -0
- package/src/components/Chart/index.tsx +267 -0
- package/src/components/Checkbox/Checkbox.fragment.tsx +1 -1
- package/src/components/CodeBlock/CodeBlock.fragment.tsx +265 -6
- package/src/components/CodeBlock/CodeBlock.module.scss +141 -3
- package/src/components/CodeBlock/index.tsx +250 -36
- package/src/components/Collapsible/Collapsible.fragment.tsx +199 -0
- package/src/components/Collapsible/Collapsible.module.scss +117 -0
- package/src/components/Collapsible/index.tsx +219 -0
- package/src/components/ColorPicker/ColorPicker.fragment.tsx +196 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +33 -23
- package/src/components/ColorPicker/index.tsx +34 -12
- package/src/components/Combobox/Combobox.fragment.tsx +220 -0
- package/src/components/Combobox/Combobox.module.scss +268 -0
- package/src/components/Combobox/index.tsx +398 -0
- package/src/components/ConversationList/ConversationList.fragment.tsx +202 -0
- package/src/components/ConversationList/ConversationList.module.scss +160 -0
- package/src/components/ConversationList/index.tsx +254 -0
- package/src/components/Dialog/Dialog.fragment.tsx +3 -3
- package/src/components/EmptyState/EmptyState.fragment.tsx +2 -2
- package/src/components/Field/Field.fragment.tsx +3 -3
- package/src/components/Fieldset/Fieldset.fragment.tsx +7 -7
- package/src/components/Form/Form.fragment.tsx +11 -11
- package/src/components/Grid/Grid.fragment.tsx +1 -1
- package/src/components/Header/Header.fragment.tsx +4 -4
- package/src/components/Header/Header.module.scss +9 -10
- package/src/components/Icon/Icon.fragment.tsx +2 -2
- package/src/components/Image/Image.fragment.tsx +2 -2
- package/src/components/Input/Input.fragment.tsx +1 -1
- package/src/components/Input/Input.module.scss +2 -2
- package/src/components/Link/Link.fragment.tsx +1 -1
- package/src/components/List/List.fragment.tsx +2 -2
- package/src/components/Listbox/Listbox.fragment.tsx +1 -1
- package/src/components/Loading/Loading.fragment.tsx +153 -0
- package/src/components/Loading/Loading.module.scss +256 -0
- package/src/components/Loading/index.tsx +236 -0
- package/src/components/Menu/Menu.fragment.tsx +3 -3
- package/src/components/Message/Message.fragment.tsx +200 -0
- package/src/components/Message/Message.module.scss +224 -0
- package/src/components/Message/index.tsx +278 -0
- package/src/components/Popover/Popover.fragment.tsx +4 -4
- package/src/components/Progress/Progress.fragment.tsx +1 -1
- package/src/components/Prompt/Prompt.fragment.tsx +2 -2
- package/src/components/RadioGroup/RadioGroup.fragment.tsx +1 -1
- package/src/components/RadioGroup/RadioGroup.module.scss +7 -4
- package/src/components/Select/Select.fragment.tsx +1 -1
- package/src/components/Select/Select.module.scss +8 -0
- package/src/components/Select/index.tsx +85 -5
- package/src/components/Separator/Separator.fragment.tsx +1 -1
- package/src/components/Sidebar/Sidebar.fragment.tsx +2 -2
- package/src/components/Sidebar/Sidebar.module.scss +19 -0
- package/src/components/Sidebar/index.tsx +52 -11
- package/src/components/Skeleton/Skeleton.fragment.tsx +1 -1
- package/src/components/Slider/Slider.fragment.tsx +201 -0
- package/src/components/Stack/Stack.fragment.tsx +194 -0
- package/src/components/Table/Table.fragment.tsx +3 -3
- package/src/components/Tabs/Tabs.fragment.tsx +1 -1
- package/src/components/Tabs/Tabs.module.scss +2 -2
- package/src/components/Text/Text.fragment.tsx +188 -0
- package/src/components/Textarea/Textarea.fragment.tsx +1 -1
- package/src/components/Theme/Theme.fragment.tsx +2 -2
- package/src/components/Theme/ThemeToggle.module.scss +13 -13
- package/src/components/ThinkingIndicator/ThinkingIndicator.fragment.tsx +182 -0
- package/src/components/ThinkingIndicator/ThinkingIndicator.module.scss +226 -0
- package/src/components/ThinkingIndicator/index.tsx +258 -0
- package/src/components/Toast/Toast.fragment.tsx +1 -1
- package/src/components/Toggle/Toggle.fragment.tsx +1 -1
- package/src/components/ToggleGroup/ToggleGroup.fragment.tsx +207 -0
- package/src/components/Tooltip/Tooltip.fragment.tsx +3 -3
- package/src/components/VisuallyHidden/VisuallyHidden.fragment.tsx +2 -2
- package/src/index.ts +99 -3
- package/src/recipes/AIChat.recipe.ts +266 -0
- package/src/tokens/_computed.scss +212 -0
- package/src/tokens/_density.scss +171 -0
- package/src/tokens/_derive.scss +287 -0
- package/src/tokens/_index.scss +39 -1
- package/src/tokens/_mixins.scss +41 -0
- package/src/tokens/_palettes.scss +185 -0
- package/src/tokens/_radius.scss +107 -0
- package/src/tokens/_seeds.scss +59 -0
- package/src/tokens/_variables.scss +171 -130
- package/src/components/ColorChip/ColorChip.module.scss +0 -165
- package/src/components/ColorChip/index.tsx +0 -157
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import styles from './ThinkingIndicator.module.scss';
|
|
5
|
+
import '../../styles/globals.scss';
|
|
6
|
+
import { Loading } from '../Loading';
|
|
7
|
+
|
|
8
|
+
// ============================================
|
|
9
|
+
// Types
|
|
10
|
+
// ============================================
|
|
11
|
+
|
|
12
|
+
export type ThinkingVariant = 'dots' | 'pulse' | 'spinner';
|
|
13
|
+
export type StepStatus = 'pending' | 'active' | 'complete' | 'error';
|
|
14
|
+
|
|
15
|
+
export interface ThinkingStep {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
status?: StepStatus;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ThinkingIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
22
|
+
/** Whether thinking is active */
|
|
23
|
+
active?: boolean;
|
|
24
|
+
/** Status text */
|
|
25
|
+
label?: string;
|
|
26
|
+
/** Animation style */
|
|
27
|
+
variant?: ThinkingVariant;
|
|
28
|
+
/** Show elapsed time */
|
|
29
|
+
showElapsed?: boolean;
|
|
30
|
+
/** Multi-step progress */
|
|
31
|
+
steps?: ThinkingStep[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ThinkingStepsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ThinkingStepProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
39
|
+
/** Step label */
|
|
40
|
+
label: string;
|
|
41
|
+
/** Step status */
|
|
42
|
+
status?: StepStatus;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ============================================
|
|
46
|
+
// Context
|
|
47
|
+
// ============================================
|
|
48
|
+
|
|
49
|
+
interface ThinkingIndicatorContextValue {
|
|
50
|
+
active: boolean;
|
|
51
|
+
variant: ThinkingVariant;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const ThinkingIndicatorContext = React.createContext<ThinkingIndicatorContextValue | null>(null);
|
|
55
|
+
|
|
56
|
+
function useThinkingIndicatorContext() {
|
|
57
|
+
const context = React.useContext(ThinkingIndicatorContext);
|
|
58
|
+
if (!context) {
|
|
59
|
+
throw new Error('ThinkingIndicator compound components must be used within a ThinkingIndicator');
|
|
60
|
+
}
|
|
61
|
+
return context;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ============================================
|
|
65
|
+
// Hooks
|
|
66
|
+
// ============================================
|
|
67
|
+
|
|
68
|
+
function useElapsedTime(active: boolean): string {
|
|
69
|
+
const [elapsed, setElapsed] = React.useState(0);
|
|
70
|
+
const startTimeRef = React.useRef<number>(Date.now());
|
|
71
|
+
|
|
72
|
+
React.useEffect(() => {
|
|
73
|
+
if (!active) {
|
|
74
|
+
setElapsed(0);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
startTimeRef.current = Date.now();
|
|
79
|
+
const interval = setInterval(() => {
|
|
80
|
+
setElapsed(Date.now() - startTimeRef.current);
|
|
81
|
+
}, 1000);
|
|
82
|
+
|
|
83
|
+
return () => clearInterval(interval);
|
|
84
|
+
}, [active]);
|
|
85
|
+
|
|
86
|
+
if (elapsed < 1000) return '';
|
|
87
|
+
|
|
88
|
+
const seconds = Math.floor(elapsed / 1000);
|
|
89
|
+
if (seconds < 60) return `${seconds}s`;
|
|
90
|
+
|
|
91
|
+
const minutes = Math.floor(seconds / 60);
|
|
92
|
+
const remainingSeconds = seconds % 60;
|
|
93
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ============================================
|
|
97
|
+
// Icons
|
|
98
|
+
// ============================================
|
|
99
|
+
|
|
100
|
+
function CheckIcon() {
|
|
101
|
+
return (
|
|
102
|
+
<svg
|
|
103
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
104
|
+
width="12"
|
|
105
|
+
height="12"
|
|
106
|
+
viewBox="0 0 24 24"
|
|
107
|
+
fill="none"
|
|
108
|
+
stroke="currentColor"
|
|
109
|
+
strokeWidth="3"
|
|
110
|
+
strokeLinecap="round"
|
|
111
|
+
strokeLinejoin="round"
|
|
112
|
+
aria-hidden="true"
|
|
113
|
+
>
|
|
114
|
+
<polyline points="20 6 9 17 4 12" />
|
|
115
|
+
</svg>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function ErrorIcon() {
|
|
120
|
+
return (
|
|
121
|
+
<svg
|
|
122
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
123
|
+
width="12"
|
|
124
|
+
height="12"
|
|
125
|
+
viewBox="0 0 24 24"
|
|
126
|
+
fill="none"
|
|
127
|
+
stroke="currentColor"
|
|
128
|
+
strokeWidth="3"
|
|
129
|
+
strokeLinecap="round"
|
|
130
|
+
strokeLinejoin="round"
|
|
131
|
+
aria-hidden="true"
|
|
132
|
+
>
|
|
133
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
134
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
135
|
+
</svg>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ============================================
|
|
140
|
+
// Sub-components
|
|
141
|
+
// ============================================
|
|
142
|
+
|
|
143
|
+
function ThinkingSteps({ children, className, ...htmlProps }: ThinkingStepsProps) {
|
|
144
|
+
const classes = [styles.steps, className].filter(Boolean).join(' ');
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<div {...htmlProps} className={classes}>
|
|
148
|
+
{children}
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function ThinkingStep({
|
|
154
|
+
label,
|
|
155
|
+
status = 'pending',
|
|
156
|
+
className,
|
|
157
|
+
...htmlProps
|
|
158
|
+
}: ThinkingStepProps) {
|
|
159
|
+
const classes = [
|
|
160
|
+
styles.step,
|
|
161
|
+
styles[`step${status.charAt(0).toUpperCase() + status.slice(1)}`],
|
|
162
|
+
className,
|
|
163
|
+
].filter(Boolean).join(' ');
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<div {...htmlProps} className={classes}>
|
|
167
|
+
<span className={styles.stepIndicator}>
|
|
168
|
+
{status === 'complete' && <CheckIcon />}
|
|
169
|
+
{status === 'error' && <ErrorIcon />}
|
|
170
|
+
{status === 'active' && <Loading size="sm" variant="spinner" color="current" label="" />}
|
|
171
|
+
{status === 'pending' && <span className={styles.stepDot} />}
|
|
172
|
+
</span>
|
|
173
|
+
<span className={styles.stepLabel}>{label}</span>
|
|
174
|
+
</div>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ============================================
|
|
179
|
+
// Main Component
|
|
180
|
+
// ============================================
|
|
181
|
+
|
|
182
|
+
function ThinkingIndicatorRoot({
|
|
183
|
+
active = true,
|
|
184
|
+
label = 'Thinking...',
|
|
185
|
+
variant = 'dots',
|
|
186
|
+
showElapsed = false,
|
|
187
|
+
steps,
|
|
188
|
+
className,
|
|
189
|
+
...htmlProps
|
|
190
|
+
}: ThinkingIndicatorProps) {
|
|
191
|
+
const elapsedTime = useElapsedTime(active && showElapsed);
|
|
192
|
+
|
|
193
|
+
const contextValue: ThinkingIndicatorContextValue = {
|
|
194
|
+
active,
|
|
195
|
+
variant,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
if (!active) return null;
|
|
199
|
+
|
|
200
|
+
const classes = [
|
|
201
|
+
styles.thinkingIndicator,
|
|
202
|
+
className,
|
|
203
|
+
].filter(Boolean).join(' ');
|
|
204
|
+
|
|
205
|
+
// Map ThinkingIndicator variants to Loading variants
|
|
206
|
+
const loadingVariant = variant === 'dots' ? 'dots'
|
|
207
|
+
: variant === 'pulse' ? 'pulse'
|
|
208
|
+
: 'spinner';
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<ThinkingIndicatorContext.Provider value={contextValue}>
|
|
212
|
+
<div
|
|
213
|
+
{...htmlProps}
|
|
214
|
+
className={classes}
|
|
215
|
+
role="status"
|
|
216
|
+
aria-label={label}
|
|
217
|
+
aria-live="polite"
|
|
218
|
+
>
|
|
219
|
+
<div className={styles.main}>
|
|
220
|
+
<Loading size="sm" variant={loadingVariant} color="muted" label="" />
|
|
221
|
+
<span className={styles.label}>{label}</span>
|
|
222
|
+
{showElapsed && elapsedTime && (
|
|
223
|
+
<span className={styles.elapsed}>{elapsedTime}</span>
|
|
224
|
+
)}
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
{steps && steps.length > 0 && (
|
|
228
|
+
<ThinkingSteps>
|
|
229
|
+
{steps.map((step) => (
|
|
230
|
+
<ThinkingStep
|
|
231
|
+
key={step.id}
|
|
232
|
+
label={step.label}
|
|
233
|
+
status={step.status}
|
|
234
|
+
/>
|
|
235
|
+
))}
|
|
236
|
+
</ThinkingSteps>
|
|
237
|
+
)}
|
|
238
|
+
</div>
|
|
239
|
+
</ThinkingIndicatorContext.Provider>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ============================================
|
|
244
|
+
// Export compound component
|
|
245
|
+
// ============================================
|
|
246
|
+
|
|
247
|
+
export const ThinkingIndicator = Object.assign(ThinkingIndicatorRoot, {
|
|
248
|
+
Steps: ThinkingSteps,
|
|
249
|
+
Step: ThinkingStep,
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
export {
|
|
253
|
+
ThinkingIndicatorRoot,
|
|
254
|
+
ThinkingSteps,
|
|
255
|
+
ThinkingStep,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export { useThinkingIndicatorContext };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { defineSegment } from '@fragments/core';
|
|
3
|
-
import { Toggle } from '
|
|
3
|
+
import { Toggle } from '.';
|
|
4
4
|
|
|
5
5
|
// Stateful wrapper for interactive demos
|
|
6
6
|
function StatefulToggle(props: React.ComponentProps<typeof Toggle>) {
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { defineSegment } from '@fragments/core';
|
|
3
|
+
import { ToggleGroup } from '.';
|
|
4
|
+
|
|
5
|
+
export default defineSegment({
|
|
6
|
+
component: ToggleGroup,
|
|
7
|
+
|
|
8
|
+
meta: {
|
|
9
|
+
name: 'ToggleGroup',
|
|
10
|
+
description: 'A group of toggle buttons where only one can be selected at a time. Useful for switching between views, modes, or options.',
|
|
11
|
+
category: 'forms',
|
|
12
|
+
status: 'stable',
|
|
13
|
+
tags: ['toggle', 'group', 'segmented', 'control', 'tabs', 'switch'],
|
|
14
|
+
since: '0.2.0',
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
usage: {
|
|
18
|
+
when: [
|
|
19
|
+
'Switching between mutually exclusive views or modes',
|
|
20
|
+
'Selecting one option from a small set (2-5 options)',
|
|
21
|
+
'Segmented controls like view switchers',
|
|
22
|
+
'Filter or sort options',
|
|
23
|
+
],
|
|
24
|
+
whenNot: [
|
|
25
|
+
'Multiple selections allowed (use Checkbox group)',
|
|
26
|
+
'Many options (use Select or RadioGroup)',
|
|
27
|
+
'Navigation between pages (use Tabs)',
|
|
28
|
+
'On/off toggle (use Toggle component)',
|
|
29
|
+
],
|
|
30
|
+
guidelines: [
|
|
31
|
+
'Keep options to 2-5 items for clarity',
|
|
32
|
+
'Use clear, concise labels',
|
|
33
|
+
'Consider icons for common actions (grid/list view)',
|
|
34
|
+
'Ensure adequate touch targets on mobile',
|
|
35
|
+
],
|
|
36
|
+
accessibility: [
|
|
37
|
+
'Uses role="group" for semantic grouping',
|
|
38
|
+
'Each item has role="radio" with aria-checked',
|
|
39
|
+
'Keyboard navigable with Tab and arrow keys',
|
|
40
|
+
'Focus visible on active item',
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
props: {
|
|
45
|
+
value: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: 'Currently selected value',
|
|
48
|
+
required: true,
|
|
49
|
+
},
|
|
50
|
+
onChange: {
|
|
51
|
+
type: 'function',
|
|
52
|
+
description: 'Called with new value when selection changes',
|
|
53
|
+
required: true,
|
|
54
|
+
},
|
|
55
|
+
children: {
|
|
56
|
+
type: 'node',
|
|
57
|
+
description: 'ToggleGroup.Item components',
|
|
58
|
+
required: true,
|
|
59
|
+
},
|
|
60
|
+
variant: {
|
|
61
|
+
type: 'enum',
|
|
62
|
+
description: 'Visual style',
|
|
63
|
+
values: ['default', 'pills', 'outline'],
|
|
64
|
+
default: 'default',
|
|
65
|
+
},
|
|
66
|
+
size: {
|
|
67
|
+
type: 'enum',
|
|
68
|
+
description: 'Size variant',
|
|
69
|
+
values: ['sm', 'md'],
|
|
70
|
+
default: 'md',
|
|
71
|
+
},
|
|
72
|
+
gap: {
|
|
73
|
+
type: 'enum',
|
|
74
|
+
description: 'Gap between items (pills/outline variants)',
|
|
75
|
+
values: ['none', 'xs', 'sm'],
|
|
76
|
+
default: 'xs',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
relations: [
|
|
81
|
+
{ component: 'RadioGroup', relationship: 'alternative', note: 'RadioGroup for form-style single selection' },
|
|
82
|
+
{ component: 'Tabs', relationship: 'alternative', note: 'Tabs for content panel switching' },
|
|
83
|
+
{ component: 'Toggle', relationship: 'sibling', note: 'Toggle for single on/off control' },
|
|
84
|
+
],
|
|
85
|
+
|
|
86
|
+
contract: {
|
|
87
|
+
propsSummary: [
|
|
88
|
+
'value: string - selected value (required)',
|
|
89
|
+
'onChange: (value: string) => void - change handler (required)',
|
|
90
|
+
'children: ToggleGroup.Item[] - toggle items',
|
|
91
|
+
'variant: default|pills|outline - visual style',
|
|
92
|
+
'size: sm|md - size variant',
|
|
93
|
+
'gap: none|xs|sm - spacing',
|
|
94
|
+
],
|
|
95
|
+
scenarioTags: [
|
|
96
|
+
'forms.selection',
|
|
97
|
+
'input.toggle',
|
|
98
|
+
'control.segmented',
|
|
99
|
+
],
|
|
100
|
+
a11yRules: ['A11Y_GROUP_ROLE', 'A11Y_KEYBOARD_ACCESSIBLE'],
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
variants: [
|
|
104
|
+
{
|
|
105
|
+
name: 'Default',
|
|
106
|
+
description: 'Basic toggle group',
|
|
107
|
+
render: () => {
|
|
108
|
+
const [value, setValue] = React.useState('left');
|
|
109
|
+
return (
|
|
110
|
+
<ToggleGroup value={value} onChange={setValue}>
|
|
111
|
+
<ToggleGroup.Item value="left">Left</ToggleGroup.Item>
|
|
112
|
+
<ToggleGroup.Item value="center">Center</ToggleGroup.Item>
|
|
113
|
+
<ToggleGroup.Item value="right">Right</ToggleGroup.Item>
|
|
114
|
+
</ToggleGroup>
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'Pills Variant',
|
|
120
|
+
description: 'Pill-shaped toggle buttons',
|
|
121
|
+
render: () => {
|
|
122
|
+
const [value, setValue] = React.useState('all');
|
|
123
|
+
return (
|
|
124
|
+
<ToggleGroup value={value} onChange={setValue} variant="pills">
|
|
125
|
+
<ToggleGroup.Item value="all">All</ToggleGroup.Item>
|
|
126
|
+
<ToggleGroup.Item value="active">Active</ToggleGroup.Item>
|
|
127
|
+
<ToggleGroup.Item value="completed">Completed</ToggleGroup.Item>
|
|
128
|
+
</ToggleGroup>
|
|
129
|
+
);
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'Outline Variant',
|
|
134
|
+
description: 'Outlined toggle buttons',
|
|
135
|
+
render: () => {
|
|
136
|
+
const [value, setValue] = React.useState('day');
|
|
137
|
+
return (
|
|
138
|
+
<ToggleGroup value={value} onChange={setValue} variant="outline">
|
|
139
|
+
<ToggleGroup.Item value="day">Day</ToggleGroup.Item>
|
|
140
|
+
<ToggleGroup.Item value="week">Week</ToggleGroup.Item>
|
|
141
|
+
<ToggleGroup.Item value="month">Month</ToggleGroup.Item>
|
|
142
|
+
</ToggleGroup>
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'Sizes',
|
|
148
|
+
description: 'Different size variants',
|
|
149
|
+
render: () => {
|
|
150
|
+
const [value1, setValue1] = React.useState('a');
|
|
151
|
+
const [value2, setValue2] = React.useState('a');
|
|
152
|
+
return (
|
|
153
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
154
|
+
<ToggleGroup value={value1} onChange={setValue1} size="sm">
|
|
155
|
+
<ToggleGroup.Item value="a">Small</ToggleGroup.Item>
|
|
156
|
+
<ToggleGroup.Item value="b">Size</ToggleGroup.Item>
|
|
157
|
+
</ToggleGroup>
|
|
158
|
+
<ToggleGroup value={value2} onChange={setValue2} size="md">
|
|
159
|
+
<ToggleGroup.Item value="a">Medium</ToggleGroup.Item>
|
|
160
|
+
<ToggleGroup.Item value="b">Size</ToggleGroup.Item>
|
|
161
|
+
</ToggleGroup>
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'View Switcher',
|
|
168
|
+
description: 'Common pattern for switching between views',
|
|
169
|
+
render: () => {
|
|
170
|
+
const [view, setView] = React.useState('grid');
|
|
171
|
+
return (
|
|
172
|
+
<ToggleGroup value={view} onChange={setView} size="sm">
|
|
173
|
+
<ToggleGroup.Item value="grid">
|
|
174
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
175
|
+
<rect x="3" y="3" width="7" height="7" />
|
|
176
|
+
<rect x="14" y="3" width="7" height="7" />
|
|
177
|
+
<rect x="3" y="14" width="7" height="7" />
|
|
178
|
+
<rect x="14" y="14" width="7" height="7" />
|
|
179
|
+
</svg>
|
|
180
|
+
</ToggleGroup.Item>
|
|
181
|
+
<ToggleGroup.Item value="list">
|
|
182
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
183
|
+
<line x1="3" y1="6" x2="21" y2="6" />
|
|
184
|
+
<line x1="3" y1="12" x2="21" y2="12" />
|
|
185
|
+
<line x1="3" y1="18" x2="21" y2="18" />
|
|
186
|
+
</svg>
|
|
187
|
+
</ToggleGroup.Item>
|
|
188
|
+
</ToggleGroup>
|
|
189
|
+
);
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: 'With Disabled Item',
|
|
194
|
+
description: 'Toggle group with a disabled option',
|
|
195
|
+
render: () => {
|
|
196
|
+
const [value, setValue] = React.useState('basic');
|
|
197
|
+
return (
|
|
198
|
+
<ToggleGroup value={value} onChange={setValue}>
|
|
199
|
+
<ToggleGroup.Item value="basic">Basic</ToggleGroup.Item>
|
|
200
|
+
<ToggleGroup.Item value="pro">Pro</ToggleGroup.Item>
|
|
201
|
+
<ToggleGroup.Item value="enterprise" disabled>Enterprise</ToggleGroup.Item>
|
|
202
|
+
</ToggleGroup>
|
|
203
|
+
);
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { defineSegment } from '@fragments/core';
|
|
3
|
-
import { Tooltip, TooltipProvider } from '
|
|
4
|
-
import { Button } from '../Button
|
|
3
|
+
import { Tooltip, TooltipProvider } from '.';
|
|
4
|
+
import { Button } from '../Button';
|
|
5
5
|
|
|
6
6
|
export default defineSegment({
|
|
7
7
|
component: Tooltip,
|
|
@@ -9,7 +9,7 @@ export default defineSegment({
|
|
|
9
9
|
meta: {
|
|
10
10
|
name: 'Tooltip',
|
|
11
11
|
description: 'Contextual help text that appears on hover or focus. Perfect for explaining icons, truncated text, or providing additional context.',
|
|
12
|
-
category: '
|
|
12
|
+
category: 'feedback',
|
|
13
13
|
status: 'stable',
|
|
14
14
|
tags: ['tooltip', 'hint', 'help', 'hover', 'contextual'],
|
|
15
15
|
since: '0.1.0',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { defineSegment } from '@fragments/core';
|
|
3
|
-
import { VisuallyHidden } from '
|
|
3
|
+
import { VisuallyHidden } from '.';
|
|
4
4
|
|
|
5
5
|
export default defineSegment({
|
|
6
6
|
component: VisuallyHidden,
|
|
@@ -8,7 +8,7 @@ export default defineSegment({
|
|
|
8
8
|
meta: {
|
|
9
9
|
name: 'VisuallyHidden',
|
|
10
10
|
description: 'Hides content visually while keeping it accessible to screen readers. Essential for accessible icon-only buttons and supplementary text.',
|
|
11
|
-
category: '
|
|
11
|
+
category: 'navigation',
|
|
12
12
|
status: 'stable',
|
|
13
13
|
tags: ['accessibility', 'a11y', 'screen-reader', 'hidden', 'sr-only'],
|
|
14
14
|
since: '0.1.0',
|
package/src/index.ts
CHANGED
|
@@ -57,6 +57,19 @@ export {
|
|
|
57
57
|
type AccordionValue,
|
|
58
58
|
} from './components/Accordion';
|
|
59
59
|
|
|
60
|
+
// Collapsible
|
|
61
|
+
export {
|
|
62
|
+
Collapsible,
|
|
63
|
+
CollapsibleRoot,
|
|
64
|
+
CollapsibleTrigger,
|
|
65
|
+
CollapsibleContent,
|
|
66
|
+
useCollapsibleContext,
|
|
67
|
+
type CollapsibleProps,
|
|
68
|
+
type CollapsibleRootProps,
|
|
69
|
+
type CollapsibleTriggerProps,
|
|
70
|
+
type CollapsibleContentProps,
|
|
71
|
+
} from './components/Collapsible';
|
|
72
|
+
|
|
60
73
|
// Dialog
|
|
61
74
|
export {
|
|
62
75
|
Dialog,
|
|
@@ -143,6 +156,19 @@ export {
|
|
|
143
156
|
// Checkbox
|
|
144
157
|
export { Checkbox, type CheckboxProps } from './components/Checkbox';
|
|
145
158
|
|
|
159
|
+
// Combobox
|
|
160
|
+
export {
|
|
161
|
+
Combobox,
|
|
162
|
+
type ComboboxProps,
|
|
163
|
+
type ComboboxInputProps,
|
|
164
|
+
type ComboboxTriggerProps,
|
|
165
|
+
type ComboboxContentProps,
|
|
166
|
+
type ComboboxItemProps,
|
|
167
|
+
type ComboboxEmptyProps,
|
|
168
|
+
type ComboboxGroupProps,
|
|
169
|
+
type ComboboxGroupLabelProps,
|
|
170
|
+
} from './components/Combobox';
|
|
171
|
+
|
|
146
172
|
// RadioGroup
|
|
147
173
|
export {
|
|
148
174
|
RadioGroup,
|
|
@@ -165,6 +191,19 @@ export {
|
|
|
165
191
|
type SkeletonSize,
|
|
166
192
|
} from './components/Skeleton';
|
|
167
193
|
|
|
194
|
+
// Loading
|
|
195
|
+
export {
|
|
196
|
+
Loading,
|
|
197
|
+
LoadingRoot,
|
|
198
|
+
LoadingInline,
|
|
199
|
+
LoadingScreen,
|
|
200
|
+
type LoadingProps,
|
|
201
|
+
type LoadingSize,
|
|
202
|
+
type LoadingVariant,
|
|
203
|
+
type LoadingInlineProps,
|
|
204
|
+
type LoadingScreenProps,
|
|
205
|
+
} from './components/Loading';
|
|
206
|
+
|
|
168
207
|
// Table
|
|
169
208
|
export {
|
|
170
209
|
Table,
|
|
@@ -310,9 +349,6 @@ export { Slider, type SliderProps } from './components/Slider';
|
|
|
310
349
|
// ColorPicker
|
|
311
350
|
export { ColorPicker, type ColorPickerProps } from './components/ColorPicker';
|
|
312
351
|
|
|
313
|
-
// ColorChip
|
|
314
|
-
export { ColorChip, type ColorChipProps } from './components/ColorChip';
|
|
315
|
-
|
|
316
352
|
// Prompt
|
|
317
353
|
export {
|
|
318
354
|
Prompt,
|
|
@@ -379,6 +415,66 @@ export { VisuallyHidden, type VisuallyHiddenProps } from './components/VisuallyH
|
|
|
379
415
|
// Brand
|
|
380
416
|
export { BRAND, type Brand } from './brand';
|
|
381
417
|
|
|
418
|
+
// Message (AI Chat)
|
|
419
|
+
export {
|
|
420
|
+
Message,
|
|
421
|
+
MessageRoot,
|
|
422
|
+
MessageContent,
|
|
423
|
+
MessageActions,
|
|
424
|
+
MessageTimestamp,
|
|
425
|
+
MessageAvatar,
|
|
426
|
+
useMessageContext,
|
|
427
|
+
type MessageProps,
|
|
428
|
+
type MessageRole,
|
|
429
|
+
type MessageStatus,
|
|
430
|
+
type MessageContentProps,
|
|
431
|
+
type MessageActionsProps,
|
|
432
|
+
type MessageTimestampProps,
|
|
433
|
+
type MessageAvatarProps,
|
|
434
|
+
} from './components/Message';
|
|
435
|
+
|
|
436
|
+
// ConversationList (AI Chat)
|
|
437
|
+
export {
|
|
438
|
+
ConversationList,
|
|
439
|
+
ConversationListRoot,
|
|
440
|
+
DateSeparator,
|
|
441
|
+
TypingIndicator,
|
|
442
|
+
useConversationList,
|
|
443
|
+
type ConversationListProps,
|
|
444
|
+
type AutoScrollBehavior,
|
|
445
|
+
type DateSeparatorProps,
|
|
446
|
+
type TypingIndicatorProps,
|
|
447
|
+
} from './components/ConversationList';
|
|
448
|
+
|
|
449
|
+
// ThinkingIndicator (AI Chat)
|
|
450
|
+
export {
|
|
451
|
+
ThinkingIndicator,
|
|
452
|
+
ThinkingIndicatorRoot,
|
|
453
|
+
ThinkingSteps,
|
|
454
|
+
ThinkingStep,
|
|
455
|
+
useThinkingIndicatorContext,
|
|
456
|
+
type ThinkingIndicatorProps,
|
|
457
|
+
type ThinkingVariant,
|
|
458
|
+
type ThinkingStep as ThinkingStepType,
|
|
459
|
+
type StepStatus,
|
|
460
|
+
type ThinkingStepsProps,
|
|
461
|
+
type ThinkingStepProps,
|
|
462
|
+
} from './components/ThinkingIndicator';
|
|
463
|
+
|
|
464
|
+
// Chart
|
|
465
|
+
export {
|
|
466
|
+
ChartContainer,
|
|
467
|
+
ChartTooltip,
|
|
468
|
+
ChartTooltipContent,
|
|
469
|
+
ChartLegend,
|
|
470
|
+
ChartLegendContent,
|
|
471
|
+
useChartConfig,
|
|
472
|
+
type ChartConfig,
|
|
473
|
+
type ChartContainerProps,
|
|
474
|
+
type ChartTooltipContentProps,
|
|
475
|
+
type ChartLegendContentProps,
|
|
476
|
+
} from './components/Chart';
|
|
477
|
+
|
|
382
478
|
// Accessibility Utilities
|
|
383
479
|
export {
|
|
384
480
|
useId,
|