@fragments-sdk/ui 0.16.1 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/ui.css +2021 -1606
- package/dist/components/Accordion/Accordion.module.scss.cjs +8 -8
- package/dist/components/Accordion/Accordion.module.scss.js +8 -8
- package/dist/components/Alert/Alert.module.scss.cjs +12 -12
- package/dist/components/Alert/Alert.module.scss.js +12 -12
- package/dist/components/Alert/index.cjs +2 -1
- package/dist/components/Alert/index.d.ts.map +1 -1
- package/dist/components/Alert/index.js +2 -1
- package/dist/components/Avatar/index.cjs +12 -4
- package/dist/components/Avatar/index.d.ts.map +1 -1
- package/dist/components/Avatar/index.js +12 -4
- package/dist/components/Badge/Badge.module.scss.cjs +13 -13
- package/dist/components/Badge/Badge.module.scss.js +13 -13
- package/dist/components/Button/Button.module.scss.cjs +11 -11
- package/dist/components/Button/Button.module.scss.js +11 -11
- package/dist/components/Button/index.cjs +51 -4
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +51 -4
- package/dist/components/Card/Card.module.scss.cjs +14 -14
- package/dist/components/Card/Card.module.scss.js +14 -14
- package/dist/components/Card/index.cjs +35 -2
- package/dist/components/Card/index.d.ts.map +1 -1
- package/dist/components/Card/index.js +35 -2
- package/dist/components/Checkbox/Checkbox.module.scss.cjs +10 -10
- package/dist/components/Checkbox/Checkbox.module.scss.js +10 -10
- package/dist/components/Chip/Chip.module.scss.cjs +15 -15
- package/dist/components/Chip/Chip.module.scss.js +15 -15
- package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +21 -21
- package/dist/components/CodeBlock/CodeBlock.module.scss.js +21 -21
- package/dist/components/Collapsible/Collapsible.module.scss.cjs +10 -10
- package/dist/components/Collapsible/Collapsible.module.scss.js +10 -10
- package/dist/components/ColorPicker/ColorPicker.module.scss.cjs +14 -14
- package/dist/components/ColorPicker/ColorPicker.module.scss.js +14 -14
- package/dist/components/Combobox/Combobox.module.scss.cjs +24 -24
- package/dist/components/Combobox/Combobox.module.scss.js +24 -24
- package/dist/components/DataTable/DataTable.module.scss.cjs +26 -26
- package/dist/components/DataTable/DataTable.module.scss.js +26 -26
- package/dist/components/DatePicker/DatePicker.module.scss.cjs +31 -31
- package/dist/components/DatePicker/DatePicker.module.scss.js +31 -31
- package/dist/components/Dialog/Dialog.module.scss.cjs +14 -14
- package/dist/components/Dialog/Dialog.module.scss.js +14 -14
- package/dist/components/Drawer/Drawer.module.scss.cjs +26 -26
- package/dist/components/Drawer/Drawer.module.scss.js +26 -26
- package/dist/components/Editor/Editor.module.scss.cjs +17 -17
- package/dist/components/Editor/Editor.module.scss.js +17 -17
- package/dist/components/Fieldset/Fieldset.module.scss.cjs +6 -3
- package/dist/components/Fieldset/Fieldset.module.scss.js +6 -3
- package/dist/components/Fieldset/index.cjs +7 -1
- package/dist/components/Fieldset/index.d.ts +6 -1
- package/dist/components/Fieldset/index.d.ts.map +1 -1
- package/dist/components/Fieldset/index.js +7 -1
- package/dist/components/Header/Header.module.scss.cjs +42 -21
- package/dist/components/Header/Header.module.scss.js +42 -21
- package/dist/components/Header/index.cjs +121 -3
- package/dist/components/Header/index.d.ts +26 -3
- package/dist/components/Header/index.d.ts.map +1 -1
- package/dist/components/Header/index.js +122 -4
- package/dist/components/Input/Input.module.scss.cjs +27 -15
- package/dist/components/Input/Input.module.scss.js +27 -15
- package/dist/components/Input/index.cjs +20 -7
- package/dist/components/Input/index.d.ts +8 -2
- package/dist/components/Input/index.d.ts.map +1 -1
- package/dist/components/Input/index.js +20 -7
- package/dist/components/Link/Link.module.scss.cjs +10 -10
- package/dist/components/Link/Link.module.scss.js +10 -10
- package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
- package/dist/components/Listbox/Listbox.module.scss.js +8 -8
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +28 -28
- package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +28 -28
- package/dist/components/Pagination/Pagination.module.scss.cjs +7 -7
- package/dist/components/Pagination/Pagination.module.scss.js +7 -7
- package/dist/components/Popover/Popover.module.scss.cjs +10 -10
- package/dist/components/Popover/Popover.module.scss.js +10 -10
- package/dist/components/Prompt/Prompt.module.scss.cjs +14 -14
- package/dist/components/Prompt/Prompt.module.scss.js +14 -14
- package/dist/components/RadioGroup/RadioGroup.module.scss.cjs +16 -16
- package/dist/components/RadioGroup/RadioGroup.module.scss.js +16 -16
- package/dist/components/Select/Select.module.scss.cjs +17 -17
- package/dist/components/Select/Select.module.scss.js +17 -17
- package/dist/components/Sidebar/Sidebar.module.scss.cjs +42 -42
- package/dist/components/Sidebar/Sidebar.module.scss.js +42 -42
- package/dist/components/Slider/Slider.module.scss.cjs +12 -12
- package/dist/components/Slider/Slider.module.scss.js +12 -12
- package/dist/components/Tabs/Tabs.module.scss.cjs +9 -9
- package/dist/components/Tabs/Tabs.module.scss.js +9 -9
- package/dist/components/Textarea/Textarea.module.scss.cjs +34 -19
- package/dist/components/Textarea/Textarea.module.scss.js +34 -19
- package/dist/components/Textarea/index.cjs +36 -6
- package/dist/components/Textarea/index.d.ts +6 -2
- package/dist/components/Textarea/index.d.ts.map +1 -1
- package/dist/components/Textarea/index.js +36 -6
- package/dist/components/Theme/ThemeToggle.module.scss.cjs +6 -6
- package/dist/components/Theme/ThemeToggle.module.scss.js +6 -6
- package/dist/components/Toast/Toast.module.scss.cjs +22 -22
- package/dist/components/Toast/Toast.module.scss.js +22 -22
- package/dist/components/Toggle/Toggle.module.scss.cjs +13 -13
- package/dist/components/Toggle/Toggle.module.scss.js +13 -13
- package/dist/components/Toggle/index.cjs +7 -3
- package/dist/components/Toggle/index.d.ts.map +1 -1
- package/dist/components/Toggle/index.js +7 -3
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.cjs +17 -17
- package/dist/components/ToggleGroup/ToggleGroup.module.scss.js +17 -17
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/fragments.json +1 -1
- package/package.json +1 -1
- package/src/components/Alert/Alert.module.scss +8 -8
- package/src/components/Alert/index.tsx +2 -1
- package/src/components/Avatar/index.tsx +6 -2
- package/src/components/Badge/Badge.module.scss +17 -11
- package/src/components/Button/Button.module.scss +6 -5
- package/src/components/Button/index.tsx +60 -4
- package/src/components/Card/index.tsx +48 -3
- package/src/components/Checkbox/Checkbox.module.scss +16 -9
- package/src/components/ColorPicker/ColorPicker.module.scss +5 -13
- package/src/components/Combobox/Combobox.module.scss +30 -25
- package/src/components/DatePicker/DatePicker.module.scss +18 -28
- package/src/components/Editor/Editor.module.scss +23 -15
- package/src/components/Fieldset/Fieldset.module.scss +12 -6
- package/src/components/Fieldset/index.tsx +11 -1
- package/src/components/Header/Header.module.scss +99 -0
- package/src/components/Header/index.tsx +191 -10
- package/src/components/Input/Input.module.scss +97 -26
- package/src/components/Input/index.tsx +31 -12
- package/src/components/Listbox/Listbox.module.scss +9 -2
- package/src/components/RadioGroup/RadioGroup.module.scss +8 -6
- package/src/components/Select/Select.module.scss +10 -24
- package/src/components/Sidebar/Sidebar.module.scss +6 -4
- package/src/components/Slider/Slider.module.scss +12 -22
- package/src/components/Textarea/Textarea.module.scss +49 -18
- package/src/components/Textarea/index.tsx +43 -12
- package/src/components/Toast/Toast.module.scss +48 -8
- package/src/components/Toggle/Toggle.module.scss +21 -35
- package/src/components/Toggle/index.tsx +11 -3
- package/src/components/ToggleGroup/ToggleGroup.module.scss +23 -19
- package/src/index.ts +2 -0
- package/src/styles/globals.scss +4 -1
- package/src/tokens/_mixins.scss +57 -4
- package/src/tokens/_variables.scss +20 -1
|
@@ -7,30 +7,17 @@
|
|
|
7
7
|
.input {
|
|
8
8
|
@include text-base;
|
|
9
9
|
@include interactive-base;
|
|
10
|
+
@include field-shell;
|
|
10
11
|
|
|
11
12
|
display: block;
|
|
12
13
|
width: 100%;
|
|
13
|
-
background-color: var(--fui-bg-elevated, $fui-bg-elevated);
|
|
14
|
-
border: 1px solid var(--fui-border-strong, $fui-border-strong);
|
|
15
|
-
border-radius: var(--fui-radius-md, $fui-radius-md);
|
|
16
14
|
|
|
17
15
|
&::placeholder {
|
|
18
16
|
color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
&:hover:not(:disabled):not(:focus-visible) {
|
|
22
|
-
border-color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
19
|
&:focus-visible {
|
|
26
|
-
@include focus
|
|
27
|
-
border-color: var(--fui-color-accent, $fui-color-accent);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
&:disabled,
|
|
31
|
-
&[data-disabled] {
|
|
32
|
-
background-color: var(--fui-bg-tertiary, $fui-bg-tertiary);
|
|
33
|
-
color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
20
|
+
@include field-shell-focus;
|
|
34
21
|
}
|
|
35
22
|
}
|
|
36
23
|
|
|
@@ -66,9 +53,17 @@
|
|
|
66
53
|
|
|
67
54
|
&:focus-visible {
|
|
68
55
|
border-color: var(--fui-color-danger, $fui-color-danger);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
56
|
+
@include focus-ring-error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Success state — green border for validated fields (DoorDash/Stocksy pattern)
|
|
61
|
+
.success {
|
|
62
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
63
|
+
|
|
64
|
+
&:focus-visible {
|
|
65
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
66
|
+
@include focus-ring-success;
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
69
|
|
|
@@ -77,8 +72,14 @@
|
|
|
77
72
|
color: var(--fui-color-danger, $fui-color-danger);
|
|
78
73
|
}
|
|
79
74
|
|
|
75
|
+
// Auto-detect success state via :has() — applies success color to helper
|
|
76
|
+
.wrapper[data-success] .helper,
|
|
77
|
+
.helperSuccess {
|
|
78
|
+
color: var(--fui-color-success, $fui-color-success);
|
|
79
|
+
}
|
|
80
|
+
|
|
80
81
|
// ============================================
|
|
81
|
-
// Input with shortcut indicator
|
|
82
|
+
// Input with adornments or shortcut indicator
|
|
82
83
|
// ============================================
|
|
83
84
|
|
|
84
85
|
.inputContainer {
|
|
@@ -92,6 +93,64 @@
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
// Adornment container — wraps input with start/end adornments inside field-shell border
|
|
97
|
+
.hasAdornment {
|
|
98
|
+
@include field-shell;
|
|
99
|
+
|
|
100
|
+
gap: var(--fui-space-2, $fui-space-2);
|
|
101
|
+
padding: 0 var(--fui-space-3, $fui-space-3);
|
|
102
|
+
border-radius: var(--fui-radius-md, $fui-radius-md);
|
|
103
|
+
|
|
104
|
+
&:focus-within {
|
|
105
|
+
@include field-shell-focus;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Strip the input's own shell when inside adornment container
|
|
109
|
+
.input {
|
|
110
|
+
border: none;
|
|
111
|
+
background: transparent;
|
|
112
|
+
padding: 0;
|
|
113
|
+
box-shadow: none;
|
|
114
|
+
|
|
115
|
+
&:focus-visible {
|
|
116
|
+
outline: none;
|
|
117
|
+
box-shadow: none;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Error state on adornment container
|
|
122
|
+
&:has(.error) {
|
|
123
|
+
border-color: var(--fui-color-danger, $fui-color-danger);
|
|
124
|
+
|
|
125
|
+
&:focus-within {
|
|
126
|
+
border-color: var(--fui-color-danger, $fui-color-danger);
|
|
127
|
+
@include focus-ring-error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Success state on adornment container
|
|
132
|
+
&:has(.success) {
|
|
133
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
134
|
+
|
|
135
|
+
&:focus-within {
|
|
136
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
137
|
+
@include focus-ring-success;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.adornment {
|
|
143
|
+
display: flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
flex-shrink: 0;
|
|
146
|
+
color: var(--fui-text-secondary, $fui-text-secondary);
|
|
147
|
+
|
|
148
|
+
svg {
|
|
149
|
+
width: 1rem;
|
|
150
|
+
height: 1rem;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
95
154
|
// Kept as fallback for direct usage
|
|
96
155
|
.hasShortcut {
|
|
97
156
|
padding-right: var(--fui-space-12, 3rem);
|
|
@@ -104,18 +163,26 @@
|
|
|
104
163
|
transform: translateY(-50%);
|
|
105
164
|
display: inline-flex;
|
|
106
165
|
align-items: center;
|
|
166
|
+
justify-content: center;
|
|
107
167
|
gap: calc(var(--fui-space-px, $fui-space-px) * 2);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
font-size: var(--fui-font-size-
|
|
112
|
-
font-family: var(--fui-font-
|
|
113
|
-
|
|
114
|
-
|
|
168
|
+
min-width: 1.25rem;
|
|
169
|
+
height: 1.25rem;
|
|
170
|
+
padding: 0 var(--fui-space-1, $fui-space-1);
|
|
171
|
+
font-size: var(--fui-font-size-2xs, $fui-font-size-2xs);
|
|
172
|
+
font-family: var(--fui-font-sans, $fui-font-sans);
|
|
173
|
+
font-weight: var(--fui-font-weight-medium, $fui-font-weight-medium);
|
|
174
|
+
line-height: 1;
|
|
175
|
+
letter-spacing: 0.02em;
|
|
176
|
+
color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
177
|
+
background: var(--fui-bg-elevated, $fui-bg-elevated);
|
|
115
178
|
border: 1px solid var(--fui-border-default, $fui-border-default);
|
|
179
|
+
border-bottom-width: 2px;
|
|
116
180
|
border-radius: var(--fui-radius-sm, $fui-radius-sm);
|
|
181
|
+
box-shadow:
|
|
182
|
+
inset 0 0.5px 0 color-mix(in srgb, white 6%, transparent);
|
|
117
183
|
pointer-events: none;
|
|
118
184
|
white-space: nowrap;
|
|
185
|
+
user-select: none;
|
|
119
186
|
}
|
|
120
187
|
|
|
121
188
|
// ============================================
|
|
@@ -136,6 +203,10 @@
|
|
|
136
203
|
.input[aria-invalid] {
|
|
137
204
|
border-color: var(--fui-color-danger, $fui-color-danger);
|
|
138
205
|
}
|
|
206
|
+
|
|
207
|
+
.success {
|
|
208
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
209
|
+
}
|
|
139
210
|
}
|
|
140
211
|
|
|
141
212
|
// ============================================
|
|
@@ -29,12 +29,18 @@ export interface InputProps extends Omit<
|
|
|
29
29
|
disabled?: boolean;
|
|
30
30
|
/** Show error styling */
|
|
31
31
|
error?: boolean;
|
|
32
|
+
/** Show success styling */
|
|
33
|
+
success?: boolean;
|
|
32
34
|
/** Visible label text */
|
|
33
35
|
label?: string;
|
|
34
36
|
/** Whether the field is required */
|
|
35
37
|
required?: boolean;
|
|
36
38
|
/** Helper text shown below the input */
|
|
37
39
|
helperText?: string;
|
|
40
|
+
/** Content rendered before the input (e.g., icon or prefix text) */
|
|
41
|
+
startAdornment?: React.ReactNode;
|
|
42
|
+
/** Content rendered after the input (e.g., icon or suffix text) */
|
|
43
|
+
endAdornment?: React.ReactNode;
|
|
38
44
|
/** Keyboard shortcut hint displayed inside the input (e.g., "⌘K"). */
|
|
39
45
|
shortcut?: string;
|
|
40
46
|
/** Whether the shortcut should also register a global focus hotkey.
|
|
@@ -44,8 +50,8 @@ export interface InputProps extends Omit<
|
|
|
44
50
|
onChange?: (value: string) => void;
|
|
45
51
|
/** Alias for onChange (value-first callback) */
|
|
46
52
|
onValueChange?: (value: string) => void;
|
|
47
|
-
onBlur?:
|
|
48
|
-
onFocus?:
|
|
53
|
+
onBlur?: React.FocusEventHandler<HTMLInputElement>;
|
|
54
|
+
onFocus?: React.FocusEventHandler<HTMLInputElement>;
|
|
49
55
|
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
50
56
|
/** Props applied to the wrapper element */
|
|
51
57
|
rootProps?: React.HTMLAttributes<HTMLDivElement>;
|
|
@@ -86,9 +92,12 @@ const InputRoot = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
86
92
|
size = 'md',
|
|
87
93
|
disabled = false,
|
|
88
94
|
error = false,
|
|
95
|
+
success = false,
|
|
89
96
|
required = false,
|
|
90
97
|
label,
|
|
91
98
|
helperText,
|
|
99
|
+
startAdornment,
|
|
100
|
+
endAdornment,
|
|
92
101
|
shortcut,
|
|
93
102
|
shortcutBehavior = 'display-only',
|
|
94
103
|
onChange,
|
|
@@ -149,17 +158,24 @@ const InputRoot = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
149
158
|
return () => document.removeEventListener('keydown', handler);
|
|
150
159
|
}, [shortcut, shortcutBehavior]);
|
|
151
160
|
|
|
161
|
+
const hasAdornment = !!(startAdornment || endAdornment);
|
|
162
|
+
|
|
152
163
|
const inputClasses = [
|
|
153
164
|
styles.input,
|
|
154
165
|
styles[size],
|
|
155
166
|
error && styles.error,
|
|
167
|
+
success && styles.success,
|
|
156
168
|
shortcut && styles.hasShortcut,
|
|
157
169
|
inputClassName,
|
|
158
170
|
]
|
|
159
171
|
.filter(Boolean)
|
|
160
172
|
.join(' ');
|
|
161
173
|
|
|
162
|
-
const helperClasses = [
|
|
174
|
+
const helperClasses = [
|
|
175
|
+
styles.helper,
|
|
176
|
+
error && styles.helperError,
|
|
177
|
+
success && styles.helperSuccess,
|
|
178
|
+
]
|
|
163
179
|
.filter(Boolean)
|
|
164
180
|
.join(' ');
|
|
165
181
|
|
|
@@ -180,8 +196,8 @@ const InputRoot = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
180
196
|
onChange?.(e.target.value);
|
|
181
197
|
onValueChange?.(e.target.value);
|
|
182
198
|
},
|
|
183
|
-
onBlur: () => onBlur?.(),
|
|
184
|
-
onFocus: () => onFocus?.(),
|
|
199
|
+
onBlur: (e: React.FocusEvent<HTMLInputElement>) => onBlur?.(e),
|
|
200
|
+
onFocus: (e: React.FocusEvent<HTMLInputElement>) => onFocus?.(e),
|
|
185
201
|
onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => onKeyDown?.(e),
|
|
186
202
|
'aria-label': ariaLabel,
|
|
187
203
|
'aria-labelledby': ariaLabelledBy,
|
|
@@ -206,14 +222,16 @@ const InputRoot = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
206
222
|
/>
|
|
207
223
|
);
|
|
208
224
|
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
225
|
+
const rawInput = withFieldWrapper ? inputElement : fieldlessInputElement;
|
|
226
|
+
|
|
227
|
+
const content = (hasAdornment || shortcut) ? (
|
|
228
|
+
<div className={[styles.inputContainer, hasAdornment && styles.hasAdornment].filter(Boolean).join(' ')}>
|
|
229
|
+
{startAdornment && <span className={styles.adornment}>{startAdornment}</span>}
|
|
230
|
+
{rawInput}
|
|
231
|
+
{endAdornment && <span className={styles.adornment}>{endAdornment}</span>}
|
|
232
|
+
{shortcut && <kbd className={styles.shortcut}>{shortcut}</kbd>}
|
|
213
233
|
</div>
|
|
214
|
-
) :
|
|
215
|
-
withFieldWrapper ? inputElement : fieldlessInputElement
|
|
216
|
-
);
|
|
234
|
+
) : rawInput;
|
|
217
235
|
|
|
218
236
|
if (!withFieldWrapper) {
|
|
219
237
|
return (
|
|
@@ -243,6 +261,7 @@ const InputRoot = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
243
261
|
{...rootProps}
|
|
244
262
|
disabled={disabled}
|
|
245
263
|
invalid={error}
|
|
264
|
+
data-success={success || undefined}
|
|
246
265
|
className={[wrapperClasses, rootProps?.className].filter(Boolean).join(' ')}
|
|
247
266
|
style={{ ...(rootProps?.style ?? {}), ...(style ?? {}) }}
|
|
248
267
|
>
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
min-width: 12rem;
|
|
13
13
|
max-height: 320px;
|
|
14
14
|
overflow-y: auto;
|
|
15
|
+
border-color: var(--fui-form-group-border, $fui-border);
|
|
15
16
|
|
|
16
17
|
&:focus-visible {
|
|
17
18
|
@include focus-ring;
|
|
@@ -38,11 +39,17 @@
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
.itemSelected {
|
|
41
|
-
|
|
42
|
+
@include popup-item-selected;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
.itemActive {
|
|
45
|
-
|
|
46
|
+
&:not(.itemSelected) {
|
|
47
|
+
background-color: var(--fui-bg-hover, $fui-bg-hover);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.itemActive.itemSelected {
|
|
52
|
+
@include popup-item-selected;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
.itemDisabled {
|
|
@@ -55,22 +55,24 @@
|
|
|
55
55
|
width: 1rem;
|
|
56
56
|
height: 1rem;
|
|
57
57
|
margin-top: 0;
|
|
58
|
-
background-color: var(--fui-bg
|
|
59
|
-
border: 1px solid var(--fui-border
|
|
58
|
+
background-color: var(--fui-field-bg, $fui-bg-elevated);
|
|
59
|
+
border: 1px solid var(--fui-field-border, $fui-border-strong);
|
|
60
60
|
border-radius: var(--fui-radius-full, $fui-radius-full);
|
|
61
61
|
cursor: inherit;
|
|
62
62
|
|
|
63
63
|
&:hover:not([data-disabled]) {
|
|
64
|
-
border-color: var(--fui-
|
|
64
|
+
border-color: var(--fui-field-border-hover, $fui-text-tertiary);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
&[data-checked] {
|
|
68
|
-
background-color: var(--fui-bg
|
|
69
|
-
border-color: var(--fui-
|
|
68
|
+
background-color: var(--fui-field-selection-bg, $fui-bg-hover);
|
|
69
|
+
border-color: var(--fui-field-selection-border, $fui-color-accent);
|
|
70
|
+
box-shadow: inset 0 0 0 1px var(--fui-field-selection-border, $fui-color-accent);
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
&[data-checked]:hover:not([data-disabled]) {
|
|
73
|
-
|
|
74
|
+
background-color: var(--fui-field-selection-bg-hover, $fui-bg-hover);
|
|
75
|
+
border-color: var(--fui-field-selection-border, $fui-color-accent);
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
&[data-invalid] {
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
@include button-reset;
|
|
10
10
|
@include interactive-base;
|
|
11
11
|
@include text-base;
|
|
12
|
+
@include field-shell;
|
|
13
|
+
@include control-size('md', 'input');
|
|
12
14
|
|
|
13
15
|
display: inline-flex;
|
|
14
16
|
align-items: center;
|
|
@@ -16,38 +18,20 @@
|
|
|
16
18
|
gap: var(--fui-space-2, $fui-space-2);
|
|
17
19
|
width: 100%;
|
|
18
20
|
min-width: 10rem;
|
|
19
|
-
height: var(--fui-input-height, $fui-input-height);
|
|
20
|
-
padding: 0 var(--fui-space-3, $fui-space-3);
|
|
21
|
-
background-color: var(--fui-bg-elevated, $fui-bg-elevated);
|
|
22
|
-
border: 1px solid var(--fui-border-strong, $fui-border-strong);
|
|
23
|
-
border-radius: var(--fui-radius-md, $fui-radius-md);
|
|
24
21
|
text-align: left;
|
|
25
22
|
|
|
26
|
-
&:hover:not([data-disabled]) {
|
|
27
|
-
border-color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
23
|
&[data-popup-open] {
|
|
31
|
-
border-color: var(--fui-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
&[data-disabled] {
|
|
35
|
-
background-color: var(--fui-bg-tertiary, $fui-bg-tertiary);
|
|
36
|
-
color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
24
|
+
border-color: var(--fui-field-border-focus, $fui-color-accent);
|
|
37
25
|
}
|
|
38
26
|
}
|
|
39
27
|
|
|
40
28
|
// Trigger size variants
|
|
41
29
|
.triggerSm {
|
|
42
|
-
|
|
43
|
-
padding: 0 var(--fui-space-2, $fui-space-2);
|
|
44
|
-
font-size: var(--fui-font-size-xs, $fui-font-size-xs);
|
|
30
|
+
@include control-size('sm', 'input');
|
|
45
31
|
}
|
|
46
32
|
|
|
47
33
|
.triggerLg {
|
|
48
|
-
|
|
49
|
-
padding: 0 var(--fui-space-4, $fui-space-4);
|
|
50
|
-
font-size: var(--fui-font-size-base, $fui-font-size-base);
|
|
34
|
+
@include control-size('lg', 'input');
|
|
51
35
|
}
|
|
52
36
|
|
|
53
37
|
// Value display
|
|
@@ -99,6 +83,8 @@
|
|
|
99
83
|
@include surface-elevated;
|
|
100
84
|
@include popup-container;
|
|
101
85
|
|
|
86
|
+
border-color: var(--fui-form-group-border, $fui-border);
|
|
87
|
+
|
|
102
88
|
// Item height derived from text-base font + vertical padding
|
|
103
89
|
--_item-h: calc(
|
|
104
90
|
var(--fui-font-size-sm, #{$fui-font-size-sm}) * var(--fui-line-height-normal, #{$fui-line-height-normal}) +
|
|
@@ -143,11 +129,10 @@
|
|
|
143
129
|
}
|
|
144
130
|
|
|
145
131
|
&[data-selected] {
|
|
146
|
-
|
|
147
|
-
color: var(--fui-text-inverse, $fui-text-inverse);
|
|
132
|
+
@include popup-item-selected;
|
|
148
133
|
|
|
149
134
|
&[data-highlighted] {
|
|
150
|
-
background-color: var(--fui-
|
|
135
|
+
background-color: var(--fui-field-selection-bg-hover, $fui-bg-hover);
|
|
151
136
|
}
|
|
152
137
|
}
|
|
153
138
|
|
|
@@ -165,6 +150,7 @@
|
|
|
165
150
|
width: 1rem;
|
|
166
151
|
height: 1rem;
|
|
167
152
|
margin-left: auto;
|
|
153
|
+
color: var(--fui-color-accent, $fui-color-accent);
|
|
168
154
|
|
|
169
155
|
svg {
|
|
170
156
|
width: 0.875rem;
|
|
@@ -226,6 +226,7 @@
|
|
|
226
226
|
|
|
227
227
|
.itemWrapper {
|
|
228
228
|
list-style: none;
|
|
229
|
+
width: 100%;
|
|
229
230
|
}
|
|
230
231
|
|
|
231
232
|
.item {
|
|
@@ -235,8 +236,9 @@
|
|
|
235
236
|
|
|
236
237
|
display: flex;
|
|
237
238
|
align-items: center;
|
|
238
|
-
|
|
239
|
-
|
|
239
|
+
width: 100%;
|
|
240
|
+
gap: var(--fui-sidebar-item-gap, var(--fui-space-2, $fui-space-2));
|
|
241
|
+
padding: var(--fui-sidebar-item-padding-y, var(--fui-space-1, $fui-space-1)) var(--fui-sidebar-item-padding-x, var(--fui-space-2, $fui-space-2));
|
|
240
242
|
border-radius: var(--fui-radius-md, $fui-radius-md);
|
|
241
243
|
color: var(--fui-text-secondary, $fui-text-secondary);
|
|
242
244
|
text-decoration: none;
|
|
@@ -635,8 +637,8 @@
|
|
|
635
637
|
.skeletonItem {
|
|
636
638
|
display: flex;
|
|
637
639
|
align-items: center;
|
|
638
|
-
gap: var(--fui-space-
|
|
639
|
-
padding: var(--fui-space-1, $fui-space-1) var(--fui-space-2, $fui-space-2);
|
|
640
|
+
gap: var(--fui-sidebar-item-gap, var(--fui-space-2, $fui-space-2));
|
|
641
|
+
padding: var(--fui-sidebar-item-padding-y, var(--fui-space-1, $fui-space-1)) var(--fui-sidebar-item-padding-x, var(--fui-space-2, $fui-space-2));
|
|
640
642
|
min-height: var(--fui-sidebar-item-height, $fui-sidebar-item-height);
|
|
641
643
|
}
|
|
642
644
|
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
position: relative;
|
|
40
40
|
height: var(--fui-slider-track-height, $fui-slider-track-height);
|
|
41
41
|
width: 100%;
|
|
42
|
-
background-color: var(--fui-bg
|
|
42
|
+
background-color: var(--fui-form-group-bg, $fui-bg-secondary);
|
|
43
|
+
box-shadow: inset 0 0 0 1px var(--fui-form-group-border, $fui-border);
|
|
43
44
|
border-radius: var(--fui-radius-full, $fui-radius-full);
|
|
44
45
|
cursor: pointer;
|
|
45
46
|
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
.indicator {
|
|
53
54
|
position: absolute;
|
|
54
55
|
height: 100%;
|
|
55
|
-
background-color: var(--fui-
|
|
56
|
+
background-color: var(--fui-field-selection-border, $fui-color-accent);
|
|
56
57
|
border-radius: var(--fui-radius-full, $fui-radius-full);
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -63,20 +64,21 @@
|
|
|
63
64
|
width: var(--fui-slider-thumb-size, $fui-slider-thumb-size);
|
|
64
65
|
height: var(--fui-slider-thumb-size, $fui-slider-thumb-size);
|
|
65
66
|
background-color: var(--fui-bg-primary, $fui-bg-primary);
|
|
66
|
-
border:
|
|
67
|
+
border: 1px solid var(--fui-field-selection-border, $fui-color-accent);
|
|
67
68
|
border-radius: var(--fui-radius-full, $fui-radius-full);
|
|
69
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.14);
|
|
68
70
|
cursor: grab;
|
|
69
71
|
transition:
|
|
70
|
-
|
|
72
|
+
border-color var(--fui-transition-fast, $fui-transition-fast),
|
|
71
73
|
box-shadow var(--fui-transition-fast, $fui-transition-fast);
|
|
72
74
|
|
|
73
75
|
&:hover {
|
|
74
|
-
|
|
76
|
+
border-color: color-mix(in srgb, var(--fui-color-accent, $fui-color-accent) 58%, transparent);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
&:active {
|
|
78
80
|
cursor: grabbing;
|
|
79
|
-
|
|
81
|
+
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.18);
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
&:focus-visible {
|
|
@@ -107,25 +109,13 @@
|
|
|
107
109
|
white-space: nowrap;
|
|
108
110
|
padding: var(--fui-space-1, $fui-space-1) var(--fui-space-2, $fui-space-2);
|
|
109
111
|
border-radius: var(--fui-radius-md, $fui-radius-md);
|
|
110
|
-
background: var(--fui-
|
|
111
|
-
color: var(--fui-
|
|
112
|
+
background: var(--fui-form-group-bg, $fui-bg-secondary);
|
|
113
|
+
color: var(--fui-text-secondary, $fui-text-secondary);
|
|
114
|
+
border: 1px solid var(--fui-form-group-border, $fui-border);
|
|
112
115
|
font-family: var(--fui-font-mono, $fui-font-mono);
|
|
113
116
|
font-size: var(--fui-font-size-xs, $fui-font-size-xs);
|
|
114
117
|
line-height: 1;
|
|
115
|
-
box-shadow: var(--fui-
|
|
116
|
-
|
|
117
|
-
&::after {
|
|
118
|
-
content: '';
|
|
119
|
-
position: absolute;
|
|
120
|
-
top: 100%;
|
|
121
|
-
left: 50%;
|
|
122
|
-
transform: translateX(-50%);
|
|
123
|
-
width: 0;
|
|
124
|
-
height: 0;
|
|
125
|
-
border-left: 5px solid transparent;
|
|
126
|
-
border-right: 5px solid transparent;
|
|
127
|
-
border-top: 5px solid var(--fui-tooltip-bg, $fui-tooltip-bg);
|
|
128
|
-
}
|
|
118
|
+
box-shadow: var(--fui-shadow-sm, $fui-shadow-sm);
|
|
129
119
|
}
|
|
130
120
|
|
|
131
121
|
// ============================================
|
|
@@ -7,14 +7,12 @@
|
|
|
7
7
|
.textarea {
|
|
8
8
|
@include text-base;
|
|
9
9
|
@include interactive-base;
|
|
10
|
+
@include field-shell;
|
|
10
11
|
|
|
11
12
|
display: block;
|
|
12
13
|
width: 100%;
|
|
13
14
|
min-height: var(--fui-input-height, $fui-input-height);
|
|
14
15
|
padding: var(--fui-space-2, $fui-space-2) var(--fui-space-3, $fui-space-3);
|
|
15
|
-
background-color: var(--fui-bg-elevated, $fui-bg-elevated);
|
|
16
|
-
border: 1px solid var(--fui-border-strong, $fui-border-strong);
|
|
17
|
-
border-radius: var(--fui-radius-md, $fui-radius-md);
|
|
18
16
|
line-height: var(--fui-line-height-normal, $fui-line-height-normal);
|
|
19
17
|
font-family: inherit;
|
|
20
18
|
|
|
@@ -22,19 +20,8 @@
|
|
|
22
20
|
color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
&:hover:not(:disabled):not(:focus-visible) {
|
|
26
|
-
border-color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
23
|
&:focus-visible {
|
|
30
|
-
@include focus
|
|
31
|
-
border-color: var(--fui-color-accent, $fui-color-accent);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
&:disabled,
|
|
35
|
-
&[data-disabled] {
|
|
36
|
-
background-color: var(--fui-bg-tertiary, $fui-bg-tertiary);
|
|
37
|
-
color: var(--fui-text-tertiary, $fui-text-tertiary);
|
|
24
|
+
@include field-shell-focus;
|
|
38
25
|
}
|
|
39
26
|
}
|
|
40
27
|
|
|
@@ -77,9 +64,17 @@
|
|
|
77
64
|
|
|
78
65
|
&:focus-visible {
|
|
79
66
|
border-color: var(--fui-color-danger, $fui-color-danger);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
@include focus-ring-error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Success state — green border for validated fields
|
|
72
|
+
.success {
|
|
73
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
74
|
+
|
|
75
|
+
&:focus-visible {
|
|
76
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
77
|
+
@include focus-ring-success;
|
|
83
78
|
}
|
|
84
79
|
}
|
|
85
80
|
|
|
@@ -88,6 +83,38 @@
|
|
|
88
83
|
color: var(--fui-color-danger, $fui-color-danger);
|
|
89
84
|
}
|
|
90
85
|
|
|
86
|
+
// Auto-detect success state
|
|
87
|
+
.wrapper[data-success] .helper,
|
|
88
|
+
.helperSuccess {
|
|
89
|
+
color: var(--fui-color-success, $fui-color-success);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Footer row — helper + character counter side by side
|
|
93
|
+
.footer {
|
|
94
|
+
display: flex;
|
|
95
|
+
justify-content: space-between;
|
|
96
|
+
align-items: baseline;
|
|
97
|
+
gap: var(--fui-space-2, $fui-space-2);
|
|
98
|
+
min-height: calc(var(--fui-font-size-xs, #{$fui-font-size-xs}) * var(--fui-line-height-normal, #{$fui-line-height-normal}) + var(--fui-space-1, #{$fui-space-1}));
|
|
99
|
+
|
|
100
|
+
&:empty {
|
|
101
|
+
display: none;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Character counter
|
|
106
|
+
.charCount {
|
|
107
|
+
@include helper-text;
|
|
108
|
+
margin-top: var(--fui-space-1, $fui-space-1);
|
|
109
|
+
margin-left: auto;
|
|
110
|
+
font-family: var(--fui-font-mono, $fui-font-mono);
|
|
111
|
+
white-space: nowrap;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.charCountOver {
|
|
115
|
+
color: var(--fui-color-danger, $fui-color-danger);
|
|
116
|
+
}
|
|
117
|
+
|
|
91
118
|
// ============================================
|
|
92
119
|
// Accessibility: High Contrast Mode
|
|
93
120
|
// ============================================
|
|
@@ -106,6 +133,10 @@
|
|
|
106
133
|
.textarea[aria-invalid] {
|
|
107
134
|
border-color: var(--fui-color-danger, $fui-color-danger);
|
|
108
135
|
}
|
|
136
|
+
|
|
137
|
+
.success {
|
|
138
|
+
border-color: var(--fui-color-success, $fui-color-success);
|
|
139
|
+
}
|
|
109
140
|
}
|
|
110
141
|
|
|
111
142
|
// ============================================
|