@wallarm-org/design-system 1.32.0 → 2.0.0-rc-fix-stepper.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/components/CodeEditor/CodeEditorRoot.d.ts +1 -1
- package/dist/components/CodeEditor/engine/SearchPanel.js +17 -3
- package/dist/components/CodeEditor/engine/completion.d.ts +3 -3
- package/dist/components/CodeEditor/engine/completion.js +142 -2
- package/dist/components/CodeEditor/engine/index.js +21 -4
- package/dist/components/FilterDropdown/FilterDropdownTrigger.js +2 -1
- package/dist/components/NumericBadge/NumericBadge.d.ts +6 -3
- package/dist/components/NumericBadge/NumericBadge.figma.js +17 -6
- package/dist/components/NumericBadge/NumericBadge.js +51 -7
- package/dist/components/NumericBadge/classes.d.ts +3 -1
- package/dist/components/NumericBadge/classes.js +138 -23
- package/dist/components/Stepper/StepperIndicator.js +12 -6
- package/dist/components/Stepper/StepperList.d.ts +2 -2
- package/dist/components/Stepper/classes.js +6 -6
- package/dist/metadata/components.json +63 -25
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@ export interface CodeEditorRootProps extends CodeEditorRootNativeProps, Testable
|
|
|
23
23
|
* document would be seeded with the previous document's text.
|
|
24
24
|
*/
|
|
25
25
|
documentId?: string;
|
|
26
|
-
/**
|
|
26
|
+
/** Non-editable and unfocusable content; text remains selectable, searchable and copyable */
|
|
27
27
|
readOnly?: boolean;
|
|
28
28
|
/** Offsets gutter numbers; `lines`, `folds`, `diagnostics` use absolute numbers */
|
|
29
29
|
startingLineNumber?: number;
|
|
@@ -41,9 +41,20 @@ const SearchPanel = ({ view, query, matchCount, readOnly, testId })=>{
|
|
|
41
41
|
]
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
|
+
const blurReadOnlyContent = ()=>{
|
|
45
|
+
if (view.state.readOnly && view.hasFocus) view.contentDOM.blur();
|
|
46
|
+
};
|
|
47
|
+
const closeSearch = ()=>{
|
|
48
|
+
closeSearchPanel(view);
|
|
49
|
+
blurReadOnlyContent();
|
|
50
|
+
};
|
|
44
51
|
const handleKeyDown = (event, onEnter)=>{
|
|
45
52
|
if (event.nativeEvent.isComposing || 229 === event.keyCode) return;
|
|
46
|
-
if (runScopeHandlers(view, event.nativeEvent, 'search-panel'))
|
|
53
|
+
if (runScopeHandlers(view, event.nativeEvent, 'search-panel')) {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
blurReadOnlyContent();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
47
58
|
if ('Enter' === event.key) {
|
|
48
59
|
event.preventDefault();
|
|
49
60
|
onEnter(event.shiftKey);
|
|
@@ -53,7 +64,10 @@ const SearchPanel = ({ view, query, matchCount, readOnly, testId })=>{
|
|
|
53
64
|
const handleReplaceKeyDown = (event)=>handleKeyDown(event, ()=>replaceNext(view));
|
|
54
65
|
const handlePanelKeyDown = (event)=>{
|
|
55
66
|
if (event.target instanceof HTMLInputElement) return;
|
|
56
|
-
if (runScopeHandlers(view, event.nativeEvent, 'search-panel'))
|
|
67
|
+
if (runScopeHandlers(view, event.nativeEvent, 'search-panel')) {
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
blurReadOnlyContent();
|
|
70
|
+
}
|
|
57
71
|
};
|
|
58
72
|
const canSearch = query.valid;
|
|
59
73
|
return /*#__PURE__*/ jsxs("div", {
|
|
@@ -154,7 +168,7 @@ const SearchPanel = ({ view, query, matchCount, readOnly, testId })=>{
|
|
|
154
168
|
className: "ml-auto",
|
|
155
169
|
"aria-label": "Close search",
|
|
156
170
|
"data-testid": slot('search-close'),
|
|
157
|
-
onClick:
|
|
171
|
+
onClick: closeSearch,
|
|
158
172
|
children: /*#__PURE__*/ jsx(X, {})
|
|
159
173
|
})
|
|
160
174
|
]
|
|
@@ -4,9 +4,9 @@ import type { CodeEditorCompletionContext, CodeEditorCompletionSource, CodeEdito
|
|
|
4
4
|
/** Public, engine-free view of a CodeMirror completion request (spec §4). */
|
|
5
5
|
export declare const buildCompletionContext: (ctx: CompletionContext, language: CodeEditorLanguage, startingLineNumber: number) => CodeEditorCompletionContext;
|
|
6
6
|
/**
|
|
7
|
-
* Autocomplete
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Autocomplete: HTTP and JSON Schema sources, consumer sources, then language keywords and
|
|
8
|
+
* document words, all through `override` (language-data sources are off).
|
|
9
|
+
* `completionKeymap` comes with `defaultKeymap: true` at `Prec.highest`, so Enter,
|
|
10
10
|
* arrows and Escape reach the open list before `indentWithTab` / fullscreen Escape.
|
|
11
11
|
*/
|
|
12
12
|
export declare const completionExtension: (config: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { autocompletion } from "@codemirror/autocomplete";
|
|
1
|
+
import { autocompletion, completeAnyWord, completeFromList } from "@codemirror/autocomplete";
|
|
2
2
|
import { EditorView } from "@codemirror/view";
|
|
3
3
|
import { cn } from "../../../utils/cn.js";
|
|
4
4
|
import { dropdownMenuItemVariants } from "../../DropdownMenu/classes.js";
|
|
@@ -106,13 +106,153 @@ const adaptSource = (source, language, startingLineNumber)=>(ctx)=>{
|
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
108
|
const reopensAfter = (completion)=>'string' == typeof completion.apply && completion.apply.endsWith(': ');
|
|
109
|
+
const LANGUAGE_KEYWORDS = {
|
|
110
|
+
json: [
|
|
111
|
+
'true',
|
|
112
|
+
'false',
|
|
113
|
+
'null'
|
|
114
|
+
],
|
|
115
|
+
yaml: [
|
|
116
|
+
'true',
|
|
117
|
+
'false',
|
|
118
|
+
'null'
|
|
119
|
+
],
|
|
120
|
+
bash: [
|
|
121
|
+
'echo',
|
|
122
|
+
'export',
|
|
123
|
+
'if',
|
|
124
|
+
'then',
|
|
125
|
+
'else',
|
|
126
|
+
'fi',
|
|
127
|
+
'for',
|
|
128
|
+
'in',
|
|
129
|
+
'do',
|
|
130
|
+
'done',
|
|
131
|
+
'function'
|
|
132
|
+
],
|
|
133
|
+
javascript: [
|
|
134
|
+
'const',
|
|
135
|
+
'let',
|
|
136
|
+
'var',
|
|
137
|
+
'function',
|
|
138
|
+
'return',
|
|
139
|
+
'if',
|
|
140
|
+
'else',
|
|
141
|
+
'for',
|
|
142
|
+
'while',
|
|
143
|
+
'class',
|
|
144
|
+
'import',
|
|
145
|
+
'export',
|
|
146
|
+
'from',
|
|
147
|
+
'async',
|
|
148
|
+
'await',
|
|
149
|
+
'true',
|
|
150
|
+
'false',
|
|
151
|
+
'null',
|
|
152
|
+
'undefined'
|
|
153
|
+
],
|
|
154
|
+
typescript: [
|
|
155
|
+
'const',
|
|
156
|
+
'let',
|
|
157
|
+
'function',
|
|
158
|
+
'return',
|
|
159
|
+
'if',
|
|
160
|
+
'else',
|
|
161
|
+
'class',
|
|
162
|
+
'import',
|
|
163
|
+
'export',
|
|
164
|
+
'from',
|
|
165
|
+
'async',
|
|
166
|
+
'await',
|
|
167
|
+
'interface',
|
|
168
|
+
'type',
|
|
169
|
+
'enum',
|
|
170
|
+
'extends',
|
|
171
|
+
'implements',
|
|
172
|
+
'public',
|
|
173
|
+
'private',
|
|
174
|
+
'readonly',
|
|
175
|
+
'true',
|
|
176
|
+
'false',
|
|
177
|
+
'null',
|
|
178
|
+
'undefined'
|
|
179
|
+
],
|
|
180
|
+
python: [
|
|
181
|
+
'def',
|
|
182
|
+
'class',
|
|
183
|
+
'return',
|
|
184
|
+
'if',
|
|
185
|
+
'elif',
|
|
186
|
+
'else',
|
|
187
|
+
'for',
|
|
188
|
+
'while',
|
|
189
|
+
'in',
|
|
190
|
+
'import',
|
|
191
|
+
'from',
|
|
192
|
+
'as',
|
|
193
|
+
'async',
|
|
194
|
+
'await',
|
|
195
|
+
'try',
|
|
196
|
+
'except',
|
|
197
|
+
'with',
|
|
198
|
+
'True',
|
|
199
|
+
'False',
|
|
200
|
+
'None'
|
|
201
|
+
],
|
|
202
|
+
lua: [
|
|
203
|
+
'function',
|
|
204
|
+
'local',
|
|
205
|
+
'return',
|
|
206
|
+
'if',
|
|
207
|
+
'then',
|
|
208
|
+
'elseif',
|
|
209
|
+
'else',
|
|
210
|
+
'end',
|
|
211
|
+
'for',
|
|
212
|
+
'while',
|
|
213
|
+
'do',
|
|
214
|
+
'repeat',
|
|
215
|
+
'until',
|
|
216
|
+
'true',
|
|
217
|
+
'false',
|
|
218
|
+
'nil'
|
|
219
|
+
]
|
|
220
|
+
};
|
|
221
|
+
const isInsideQuotedString = (text)=>{
|
|
222
|
+
let quoted = false;
|
|
223
|
+
for(let i = 0; i < text.length; i++)if ('\\' === text[i]) i++;
|
|
224
|
+
else if ('"' === text[i]) quoted = !quoted;
|
|
225
|
+
return quoted;
|
|
226
|
+
};
|
|
227
|
+
const builtInSources = (language)=>{
|
|
228
|
+
const keywords = LANGUAGE_KEYWORDS[language];
|
|
229
|
+
if (!keywords) return [
|
|
230
|
+
completeAnyWord
|
|
231
|
+
];
|
|
232
|
+
const completeKeywords = completeFromList(keywords.map((label)=>({
|
|
233
|
+
label,
|
|
234
|
+
type: 'keyword'
|
|
235
|
+
})));
|
|
236
|
+
if ('json' === language) return [
|
|
237
|
+
(ctx)=>{
|
|
238
|
+
const line = ctx.state.doc.lineAt(ctx.pos);
|
|
239
|
+
const before = line.text.slice(0, ctx.pos - line.from);
|
|
240
|
+
if (isInsideQuotedString(before)) return completeAnyWord(ctx);
|
|
241
|
+
return /(?:^|[:,\[])[\s\w]*$/.test(before) ? completeKeywords(ctx) : null;
|
|
242
|
+
}
|
|
243
|
+
];
|
|
244
|
+
return [
|
|
245
|
+
completeKeywords,
|
|
246
|
+
completeAnyWord
|
|
247
|
+
];
|
|
248
|
+
};
|
|
109
249
|
const completionExtension = (config)=>{
|
|
110
250
|
const { language, schema, sources, startingLineNumber } = config;
|
|
111
251
|
const override = [];
|
|
112
252
|
if ('http' === language) override.push(adaptSource(httpCompletions, language, startingLineNumber));
|
|
113
253
|
if (void 0 !== schema && isJsonLike(language)) override.push(schemaCompletionSource(()=>schema, (state)=>jsonRegion(state, language)));
|
|
114
254
|
for (const source of sources)override.push(adaptSource(source, language, startingLineNumber));
|
|
115
|
-
|
|
255
|
+
override.push(...builtInSources(language));
|
|
116
256
|
return [
|
|
117
257
|
autocompletion({
|
|
118
258
|
override,
|
|
@@ -79,7 +79,8 @@ const SLOT_DEPS = {
|
|
|
79
79
|
],
|
|
80
80
|
contentAttributes: [
|
|
81
81
|
'contentAttributes',
|
|
82
|
-
'testId'
|
|
82
|
+
'testId',
|
|
83
|
+
'readOnly'
|
|
83
84
|
],
|
|
84
85
|
cspNonce: [
|
|
85
86
|
'cspNonce'
|
|
@@ -184,6 +185,7 @@ const featureExtensions = (options, callbacks)=>({
|
|
|
184
185
|
});
|
|
185
186
|
const contentAttributesFor = (options)=>{
|
|
186
187
|
const attrs = sanitizeContentAttributes(options.contentAttributes);
|
|
188
|
+
if (options.readOnly) delete attrs.tabindex;
|
|
187
189
|
if (options.testId) attrs['data-testid'] = `${options.testId}--editor`;
|
|
188
190
|
return attrs;
|
|
189
191
|
};
|
|
@@ -225,7 +227,10 @@ const gutterAria = [
|
|
|
225
227
|
];
|
|
226
228
|
const slotExtensions = (options, callbacks)=>({
|
|
227
229
|
language: ()=>languageExtension(options.language),
|
|
228
|
-
readOnly: ()=>
|
|
230
|
+
readOnly: ()=>[
|
|
231
|
+
EditorState.readOnly.of(options.readOnly),
|
|
232
|
+
EditorView.editable.of(!options.readOnly)
|
|
233
|
+
],
|
|
229
234
|
wrap: ()=>options.wrapLines ? EditorView.lineWrapping : [],
|
|
230
235
|
maxHeight: ()=>maxHeightTheme(options.maxHeight),
|
|
231
236
|
contentAttributes: ()=>EditorView.contentAttributes.of(contentAttributesFor(options)),
|
|
@@ -298,6 +303,10 @@ const createEditor = (parent, initialOptions, callbacks)=>{
|
|
|
298
303
|
state: createState(initialOptions.value, initialOptions),
|
|
299
304
|
parent
|
|
300
305
|
});
|
|
306
|
+
const preventReadOnlyMouseFocus = (event)=>{
|
|
307
|
+
if (view.state.readOnly && event.target instanceof Node && view.contentDOM.contains(event.target)) event.stopPropagation();
|
|
308
|
+
};
|
|
309
|
+
view.dom.addEventListener('mousedown', preventReadOnlyMouseFocus, true);
|
|
301
310
|
const ensureLazyLanguage = (lang)=>{
|
|
302
311
|
if (!isLazyLanguage(lang)) return;
|
|
303
312
|
loadLanguageExtension(lang).then((extension)=>{
|
|
@@ -346,13 +355,20 @@ const createEditor = (parent, initialOptions, callbacks)=>{
|
|
|
346
355
|
const update = (next)=>{
|
|
347
356
|
const prev = options;
|
|
348
357
|
options = next;
|
|
349
|
-
if (next.documentId !== prev.documentId)
|
|
358
|
+
if (next.documentId !== prev.documentId) {
|
|
359
|
+
swapDocument(prev, next);
|
|
360
|
+
if (next.readOnly && view.hasFocus) view.contentDOM.blur();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
350
363
|
reconfigure(prev, next);
|
|
364
|
+
if (next.readOnly && view.hasFocus) view.contentDOM.blur();
|
|
351
365
|
if (next.language !== prev.language) ensureLazyLanguage(next.language);
|
|
352
366
|
syncValue(next.value);
|
|
353
367
|
};
|
|
354
368
|
const api = {
|
|
355
|
-
focus: ()=>
|
|
369
|
+
focus: ()=>{
|
|
370
|
+
if (!view.state.readOnly) view.focus();
|
|
371
|
+
},
|
|
356
372
|
getValue: ()=>view.state.doc.toString(),
|
|
357
373
|
insertText: (text)=>{
|
|
358
374
|
if (view.state.readOnly) return;
|
|
@@ -380,6 +396,7 @@ const createEditor = (parent, initialOptions, callbacks)=>{
|
|
|
380
396
|
destroy: ()=>{
|
|
381
397
|
destroyed = true;
|
|
382
398
|
cache.clear();
|
|
399
|
+
view.dom.removeEventListener('mousedown', preventReadOnlyMouseFocus, true);
|
|
383
400
|
view.destroy();
|
|
384
401
|
}
|
|
385
402
|
};
|
|
@@ -81,7 +81,8 @@ const FilterDropdownTrigger = ({ ref, className, children, onKeyDown, 'aria-labe
|
|
|
81
81
|
"aria-hidden": true,
|
|
82
82
|
className: "inline-flex shrink-0",
|
|
83
83
|
children: /*#__PURE__*/ jsx(NumericBadge, {
|
|
84
|
-
type: "
|
|
84
|
+
type: "secondary",
|
|
85
|
+
color: "neutral",
|
|
85
86
|
children: value.length
|
|
86
87
|
})
|
|
87
88
|
})
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FC, type HTMLAttributes, type Ref } from 'react';
|
|
2
2
|
import type { VariantProps } from 'class-variance-authority';
|
|
3
3
|
import type { TestableProps } from '../../utils/testId';
|
|
4
4
|
import { numericBadgeVariants } from './classes';
|
|
5
|
-
type NumericBadgeNativeProps = HTMLAttributes<HTMLDivElement>;
|
|
6
|
-
type NumericBadgeVariantsProps = Omit<VariantProps<typeof numericBadgeVariants>, 'clickable'>;
|
|
5
|
+
type NumericBadgeNativeProps = Omit<HTMLAttributes<HTMLDivElement>, 'color'>;
|
|
6
|
+
type NumericBadgeVariantsProps = Omit<VariantProps<typeof numericBadgeVariants>, 'clickable' | 'iconOnly'>;
|
|
7
7
|
export type NumericBadgeProps = NumericBadgeNativeProps & NumericBadgeVariantsProps & TestableProps & {
|
|
8
|
+
ref?: Ref<HTMLDivElement>;
|
|
9
|
+
/** Applies the badge to its child element, such as a span or a native button. */
|
|
10
|
+
asChild?: boolean;
|
|
8
11
|
'data-slot'?: string;
|
|
9
12
|
};
|
|
10
13
|
export declare const NumericBadge: FC<NumericBadgeProps>;
|
|
@@ -5,17 +5,28 @@ const figmaNodeUrl = 'https://www.figma.com/design/VKb5gW46uSGw0rqrhZsbXT/wip-co
|
|
|
5
5
|
code_connect.connect(NumericBadge, figmaNodeUrl, {
|
|
6
6
|
props: {
|
|
7
7
|
type: code_connect["enum"]('Type', {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Solid: 'solid',
|
|
9
|
+
Secondary: 'secondary',
|
|
10
|
+
Outline: 'outline'
|
|
11
|
+
}),
|
|
12
|
+
color: code_connect["enum"]('Color', {
|
|
13
|
+
Neutral: 'neutral',
|
|
14
|
+
'Neutral-alt': 'neutral-alt',
|
|
10
15
|
Brand: 'brand',
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
Danger: 'danger',
|
|
17
|
+
Info: 'info',
|
|
18
|
+
Success: 'success'
|
|
19
|
+
}),
|
|
20
|
+
size: code_connect["enum"]('Size', {
|
|
21
|
+
Medium: 'default',
|
|
22
|
+
Small: 'small'
|
|
14
23
|
}),
|
|
15
24
|
children: code_connect.string('#')
|
|
16
25
|
},
|
|
17
|
-
example: ({ type, children })=>/*#__PURE__*/ jsx(NumericBadge, {
|
|
26
|
+
example: ({ type, color, size, children })=>/*#__PURE__*/ jsx(NumericBadge, {
|
|
18
27
|
type: type,
|
|
28
|
+
color: color,
|
|
29
|
+
size: size,
|
|
19
30
|
children: children
|
|
20
31
|
})
|
|
21
32
|
});
|
|
@@ -1,19 +1,63 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { isValidElement, useRef } from "react";
|
|
3
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
2
4
|
import { cn } from "../../utils/cn.js";
|
|
5
|
+
import { isIconOnly } from "../../utils/isIconOnly.js";
|
|
3
6
|
import { numericBadgeVariants } from "./classes.js";
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
const hasNativeKeyboardActivation = (element)=>'BUTTON' === element.tagName || 'INPUT' === element.tagName || 'A' === element.tagName && element.hasAttribute('href');
|
|
8
|
+
const NumericBadge = ({ type = 'secondary', color = 'solid' === type ? 'brand' : 'neutral', size = 'default', asChild = false, children, className, ref, role, tabIndex, onClick, onKeyDown, onKeyUp, onBlur, 'data-slot': dataSlot, ...props })=>{
|
|
9
|
+
const child = asChild && /*#__PURE__*/ isValidElement(children) ? children : null;
|
|
10
|
+
const childProps = child?.props;
|
|
11
|
+
const nativeChild = child?.type === 'button' || child?.type === 'input' || child?.type === 'a' && childProps?.href != null;
|
|
12
|
+
const isClickable = !childProps?.disabled && !!(onClick || childProps?.onClick || nativeChild);
|
|
13
|
+
const spacePressed = useRef(false);
|
|
14
|
+
const Comp = asChild ? Slot : 'div';
|
|
15
|
+
const handleKeyDown = (event)=>{
|
|
16
|
+
onKeyDown?.(event);
|
|
17
|
+
if (event.defaultPrevented || !isClickable || event.target !== event.currentTarget || hasNativeKeyboardActivation(event.currentTarget)) return;
|
|
18
|
+
if ('Enter' === event.key) {
|
|
19
|
+
event.preventDefault();
|
|
20
|
+
event.currentTarget.click();
|
|
21
|
+
} else if (' ' === event.key) {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
spacePressed.current = true;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const handleKeyUp = (event)=>{
|
|
27
|
+
onKeyUp?.(event);
|
|
28
|
+
if (' ' !== event.key) return;
|
|
29
|
+
const activate = spacePressed.current;
|
|
30
|
+
spacePressed.current = false;
|
|
31
|
+
if (activate && !event.defaultPrevented && isClickable && event.target === event.currentTarget && !hasNativeKeyboardActivation(event.currentTarget)) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
event.currentTarget.click();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return /*#__PURE__*/ jsx(Comp, {
|
|
7
37
|
...props,
|
|
8
|
-
|
|
38
|
+
ref: ref,
|
|
39
|
+
role: role ?? (isClickable && !nativeChild ? 'button' : void 0),
|
|
40
|
+
tabIndex: tabIndex ?? (isClickable && !nativeChild ? 0 : void 0),
|
|
9
41
|
"data-slot": dataSlot ?? 'numeric-badge',
|
|
10
42
|
"data-type": type,
|
|
11
|
-
|
|
43
|
+
"data-color": color,
|
|
44
|
+
onClick: onClick ? (event)=>{
|
|
45
|
+
if (!event.defaultPrevented) onClick(event);
|
|
46
|
+
} : void 0,
|
|
47
|
+
onKeyDown: handleKeyDown,
|
|
48
|
+
onKeyUp: handleKeyUp,
|
|
49
|
+
onBlur: (event)=>{
|
|
50
|
+
spacePressed.current = false;
|
|
51
|
+
onBlur?.(event);
|
|
52
|
+
},
|
|
12
53
|
className: cn(numericBadgeVariants({
|
|
13
54
|
type,
|
|
55
|
+
color,
|
|
14
56
|
size,
|
|
15
|
-
clickable: isClickable
|
|
16
|
-
|
|
57
|
+
clickable: isClickable,
|
|
58
|
+
iconOnly: isIconOnly(child ? child.props.children : children)
|
|
59
|
+
}), className),
|
|
60
|
+
children: children
|
|
17
61
|
});
|
|
18
62
|
};
|
|
19
63
|
NumericBadge.displayName = 'NumericBadge';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare const numericBadgeVariants: (props?: ({
|
|
2
|
-
type?: "
|
|
2
|
+
type?: "outline" | "secondary" | "solid" | null | undefined;
|
|
3
|
+
color?: "brand" | "danger" | "info" | "neutral" | "neutral-alt" | "success" | null | undefined;
|
|
3
4
|
size?: "default" | "small" | null | undefined;
|
|
5
|
+
iconOnly?: boolean | null | undefined;
|
|
4
6
|
clickable?: boolean | null | undefined;
|
|
5
7
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -1,24 +1,92 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
|
-
const numericBadgeVariants = cva('inline-flex items-center rounded-full font-mono font-medium transition-colors
|
|
2
|
+
const numericBadgeVariants = cva('inline-flex w-max shrink-0 items-center justify-center whitespace-nowrap rounded-full font-mono font-medium transition-colors', {
|
|
3
3
|
variants: {
|
|
4
4
|
type: {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
solid: '',
|
|
6
|
+
secondary: '',
|
|
7
|
+
outline: 'border-1'
|
|
8
|
+
},
|
|
9
|
+
color: {
|
|
10
|
+
neutral: '',
|
|
11
|
+
'neutral-alt': '',
|
|
12
|
+
brand: '',
|
|
13
|
+
danger: '',
|
|
14
|
+
success: '',
|
|
15
|
+
info: ''
|
|
11
16
|
},
|
|
12
17
|
size: {
|
|
13
|
-
default: 'px-5 py-2 text-xs',
|
|
14
|
-
small: '
|
|
18
|
+
default: 'h-20 min-w-16 px-5 py-2 text-xs [&_svg]:icon-md',
|
|
19
|
+
small: 'h-16 min-w-12 px-3 py-2 text-2xs [&_svg]:icon-sm'
|
|
20
|
+
},
|
|
21
|
+
iconOnly: {
|
|
22
|
+
true: ''
|
|
15
23
|
},
|
|
16
24
|
clickable: {
|
|
17
|
-
true: 'cursor-pointer overlay active:outline-none active:ring-3',
|
|
25
|
+
true: 'cursor-pointer overlay active:outline-none active:ring-3 focus-visible:outline-none focus-visible:ring-3',
|
|
18
26
|
false: ''
|
|
19
27
|
}
|
|
20
28
|
},
|
|
21
29
|
compoundVariants: [
|
|
30
|
+
{
|
|
31
|
+
type: 'solid',
|
|
32
|
+
color: 'brand',
|
|
33
|
+
className: 'bg-bg-fill-brand text-text-primary-alt'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'solid',
|
|
37
|
+
color: 'danger',
|
|
38
|
+
className: 'bg-bg-fill-danger text-text-primary-alt'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'secondary',
|
|
42
|
+
color: 'neutral',
|
|
43
|
+
className: 'bg-states-primary-active text-text-primary'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: 'secondary',
|
|
47
|
+
color: 'neutral-alt',
|
|
48
|
+
className: 'bg-states-primary-alt-active text-text-primary-alt'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'secondary',
|
|
52
|
+
color: 'brand',
|
|
53
|
+
className: 'bg-states-brand-active text-text-brand'
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'secondary',
|
|
57
|
+
color: 'danger',
|
|
58
|
+
className: 'bg-states-danger-active text-text-danger'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'secondary',
|
|
62
|
+
color: 'success',
|
|
63
|
+
className: 'bg-states-success-active text-text-success'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: 'secondary',
|
|
67
|
+
color: 'info',
|
|
68
|
+
className: 'bg-states-info-active text-text-info'
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'outline',
|
|
72
|
+
color: 'neutral',
|
|
73
|
+
className: 'border-border-primary bg-component-outline-button-bg text-text-primary'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'outline',
|
|
77
|
+
color: 'brand',
|
|
78
|
+
className: 'border-border-brand bg-bg-brand text-text-brand'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: 'outline',
|
|
82
|
+
color: 'danger',
|
|
83
|
+
className: 'border-border-danger bg-bg-danger text-text-danger'
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: 'outline',
|
|
87
|
+
color: 'success',
|
|
88
|
+
className: 'border-border-success bg-bg-success text-text-success'
|
|
89
|
+
},
|
|
22
90
|
{
|
|
23
91
|
type: 'outline',
|
|
24
92
|
size: 'default',
|
|
@@ -27,37 +95,84 @@ const numericBadgeVariants = cva('inline-flex items-center rounded-full font-mon
|
|
|
27
95
|
{
|
|
28
96
|
type: 'outline',
|
|
29
97
|
size: 'small',
|
|
30
|
-
className: '
|
|
98
|
+
className: 'px-2 py-1'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
iconOnly: true,
|
|
102
|
+
className: 'px-2 py-2'
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: 'outline',
|
|
106
|
+
iconOnly: true,
|
|
107
|
+
className: 'px-1 py-1'
|
|
31
108
|
},
|
|
32
109
|
{
|
|
33
110
|
clickable: true,
|
|
34
|
-
type:
|
|
35
|
-
|
|
111
|
+
type: [
|
|
112
|
+
'secondary',
|
|
113
|
+
'outline'
|
|
114
|
+
],
|
|
115
|
+
color: 'neutral',
|
|
116
|
+
className: 'hover:overlay-states-primary-hover active:overlay-states-primary-hover'
|
|
36
117
|
},
|
|
37
118
|
{
|
|
38
119
|
clickable: true,
|
|
39
|
-
type: '
|
|
40
|
-
|
|
120
|
+
type: 'secondary',
|
|
121
|
+
color: 'neutral-alt',
|
|
122
|
+
className: 'hover:overlay-states-primary-alt-hover active:overlay-states-primary-alt-hover'
|
|
41
123
|
},
|
|
42
124
|
{
|
|
43
125
|
clickable: true,
|
|
44
|
-
type: '
|
|
45
|
-
|
|
126
|
+
type: 'solid',
|
|
127
|
+
color: 'brand',
|
|
128
|
+
className: 'hover:overlay-states-on-fill-hover active:overlay-states-on-fill-hover active:ring-focus-brand focus-visible:ring-focus-brand'
|
|
46
129
|
},
|
|
47
130
|
{
|
|
48
131
|
clickable: true,
|
|
49
|
-
type: '
|
|
50
|
-
|
|
132
|
+
type: 'solid',
|
|
133
|
+
color: 'danger',
|
|
134
|
+
className: 'hover:overlay-states-on-fill-hover active:overlay-states-on-fill-hover active:ring-focus-destructive focus-visible:ring-focus-destructive'
|
|
51
135
|
},
|
|
52
136
|
{
|
|
53
137
|
clickable: true,
|
|
54
|
-
type:
|
|
55
|
-
|
|
138
|
+
type: [
|
|
139
|
+
'secondary',
|
|
140
|
+
'outline'
|
|
141
|
+
],
|
|
142
|
+
color: 'brand',
|
|
143
|
+
className: 'hover:overlay-states-brand-hover active:overlay-states-brand-hover'
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
clickable: true,
|
|
147
|
+
type: [
|
|
148
|
+
'secondary',
|
|
149
|
+
'outline'
|
|
150
|
+
],
|
|
151
|
+
color: 'danger',
|
|
152
|
+
className: 'hover:overlay-states-danger-hover active:overlay-states-danger-hover'
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
clickable: true,
|
|
156
|
+
type: [
|
|
157
|
+
'secondary',
|
|
158
|
+
'outline'
|
|
159
|
+
],
|
|
160
|
+
color: 'success',
|
|
161
|
+
className: 'hover:overlay-states-success-hover active:overlay-states-success-hover'
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
clickable: true,
|
|
165
|
+
type: 'secondary',
|
|
166
|
+
color: 'info',
|
|
167
|
+
className: 'hover:overlay-states-info-hover active:overlay-states-info-hover'
|
|
56
168
|
},
|
|
57
169
|
{
|
|
58
170
|
clickable: true,
|
|
59
|
-
type:
|
|
60
|
-
|
|
171
|
+
type: [
|
|
172
|
+
'secondary',
|
|
173
|
+
'outline'
|
|
174
|
+
],
|
|
175
|
+
className: 'active:ring-focus-primary focus-visible:ring-focus-primary'
|
|
61
176
|
}
|
|
62
177
|
]
|
|
63
178
|
});
|
|
@@ -3,6 +3,7 @@ import { Steps } from "@ark-ui/react/steps";
|
|
|
3
3
|
import { Check } from "../../icons/index.js";
|
|
4
4
|
import { cn } from "../../utils/cn.js";
|
|
5
5
|
import { useTestId } from "../../utils/testId.js";
|
|
6
|
+
import { NumericBadge } from "../NumericBadge/index.js";
|
|
6
7
|
import { stepperIndicatorVariants } from "./classes.js";
|
|
7
8
|
import { useStepperItemContext } from "./StepperContext.js";
|
|
8
9
|
const renderDefault = (status, index)=>{
|
|
@@ -17,16 +18,21 @@ const StepperIndicator = ({ children, className, ref, 'data-testid': testIdProp,
|
|
|
17
18
|
const testId = useTestId('indicator', testIdProp);
|
|
18
19
|
return /*#__PURE__*/ jsx(Steps.Indicator, {
|
|
19
20
|
asChild: true,
|
|
20
|
-
children: /*#__PURE__*/ jsx(
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
children: /*#__PURE__*/ jsx(NumericBadge, {
|
|
22
|
+
asChild: true,
|
|
23
|
+
type: 'upcoming' === status ? 'outline' : 'secondary',
|
|
24
|
+
color: 'active' === status ? 'brand' : 'danger' === status ? 'danger' : 'neutral',
|
|
23
25
|
"data-slot": "stepper-indicator",
|
|
24
|
-
"data-status": status,
|
|
25
|
-
"data-testid": testId,
|
|
26
26
|
className: cn(stepperIndicatorVariants({
|
|
27
27
|
status
|
|
28
28
|
}), className),
|
|
29
|
-
children:
|
|
29
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
30
|
+
...rest,
|
|
31
|
+
ref: ref,
|
|
32
|
+
"data-status": status,
|
|
33
|
+
"data-testid": testId,
|
|
34
|
+
children: children ?? renderDefault(status, index)
|
|
35
|
+
})
|
|
30
36
|
})
|
|
31
37
|
});
|
|
32
38
|
};
|
|
@@ -6,7 +6,7 @@ export interface StepperListProps extends OlHTMLAttributes<HTMLOListElement>, Te
|
|
|
6
6
|
ref?: Ref<HTMLOListElement>;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* The step bar: an `<ol>` with
|
|
10
|
-
* `aria-labelledby`.
|
|
9
|
+
* The step bar: an `<ol>` with 24px side insets and 12px bottom padding, as in Figma.
|
|
10
|
+
* Name it with `aria-label` or `aria-labelledby`.
|
|
11
11
|
*/
|
|
12
12
|
export declare const StepperList: FC<StepperListProps>;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
const stepperVariants = cva('min-w-0');
|
|
4
|
-
const stepperListVariants = cva('m-0 flex min-w-0 list-none items-start
|
|
4
|
+
const stepperListVariants = cva('m-0 flex min-w-0 list-none items-start px-24 pb-12');
|
|
5
5
|
const stepperItemVariants = cva('flex min-w-0 items-start');
|
|
6
6
|
const stepperTriggerVariants = cva(cn('grid min-w-0 cursor-pointer grid-cols-[auto_minmax(0,1fr)] grid-rows-[20px] items-start gap-x-4 bg-transparent p-0 text-left', 'rounded-6 focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-focus-primary'));
|
|
7
|
-
const stepperIndicatorVariants = cva("col-start-1 row-span-2 row-start-1
|
|
7
|
+
const stepperIndicatorVariants = cva("col-start-1 row-span-2 row-start-1 min-w-16 [font-feature-settings:'liga'_0] [&_svg]:icon-sm", {
|
|
8
8
|
variants: {
|
|
9
9
|
status: {
|
|
10
|
-
active: '
|
|
11
|
-
danger: '
|
|
12
|
-
completed: '
|
|
13
|
-
upcoming: '
|
|
10
|
+
active: 'px-4 py-2',
|
|
11
|
+
danger: 'px-4 py-2',
|
|
12
|
+
completed: 'px-2 py-2 text-icon-primary',
|
|
13
|
+
upcoming: 'px-3 py-1'
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
defaultVariants: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
3
|
-
"generatedAt": "2026-10-
|
|
2
|
+
"version": "1.33.0",
|
|
3
|
+
"generatedAt": "2026-10-02T12:33:35.613Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -19208,7 +19208,7 @@
|
|
|
19208
19208
|
"name": "readOnly",
|
|
19209
19209
|
"type": "boolean | undefined",
|
|
19210
19210
|
"required": false,
|
|
19211
|
-
"description": "
|
|
19211
|
+
"description": "Non-editable and unfocusable content; text remains selectable, searchable and copyable"
|
|
19212
19212
|
},
|
|
19213
19213
|
{
|
|
19214
19214
|
"name": "startingLineNumber",
|
|
@@ -19882,7 +19882,7 @@
|
|
|
19882
19882
|
"name": "readOnly",
|
|
19883
19883
|
"type": "boolean | undefined",
|
|
19884
19884
|
"required": false,
|
|
19885
|
-
"description": "
|
|
19885
|
+
"description": "Non-editable and unfocusable content; text remains selectable, searchable and copyable",
|
|
19886
19886
|
"defaultValue": "false"
|
|
19887
19887
|
},
|
|
19888
19888
|
{
|
|
@@ -20301,7 +20301,7 @@
|
|
|
20301
20301
|
{
|
|
20302
20302
|
"name": "ReadOnly",
|
|
20303
20303
|
"code": "() => (\n <div style={{ width: '600px' }}>\n <CodeEditorRoot\n value={httpResponseCode}\n language='http'\n readOnly\n data-testid='code-editor-read-only'\n >\n <CodeSnippetHeader>\n <CodeSnippetTitle>Response</CodeSnippetTitle>\n <CodeSnippetActions>\n <CodeSnippetCopyButton />\n </CodeSnippetActions>\n </CodeSnippetHeader>\n <CodeEditorContent lineNumbers aria-label='HTTP response, read only' />\n </CodeEditorRoot>\n </div>\n)",
|
|
20304
|
-
"description": "`readOnly`
|
|
20304
|
+
"description": "`readOnly` lets you select, search and copy without focusing the code or showing a caret. Use it when the value\ncan change elsewhere but not here. If it never changes, use `CodeSnippet`."
|
|
20305
20305
|
},
|
|
20306
20306
|
{
|
|
20307
20307
|
"name": "Tabs",
|
|
@@ -20344,9 +20344,9 @@
|
|
|
20344
20344
|
"description": "Parity check for the three sizes: the same font size, line height and gutter padding per size."
|
|
20345
20345
|
},
|
|
20346
20346
|
{
|
|
20347
|
-
"name": "
|
|
20348
|
-
"code": "() => (\n <VStack gap={24}>\n <ParityPair testId='parity-
|
|
20349
|
-
"description": "Parity check for the shared
|
|
20347
|
+
"name": "ParityFrame",
|
|
20348
|
+
"code": "() => (\n <VStack gap={24}>\n <ParityPair testId='parity-frame-header' code={sampleCode} language='text'>\n {PARITY_HEADER_FRAME}\n </ParityPair>\n <ParityPair testId='parity-frame-floating' code={sampleCode} language='text'>\n {PARITY_FLOATING_FRAME}\n </ParityPair>\n </VStack>\n)",
|
|
20349
|
+
"description": "Parity check for the shared frame: a header with tabs and actions, and floating actions\nwithout a header, sit in the same place with the same spacing."
|
|
20350
20350
|
},
|
|
20351
20351
|
{
|
|
20352
20352
|
"name": "ParityShowMore",
|
|
@@ -20391,7 +20391,7 @@
|
|
|
20391
20391
|
{
|
|
20392
20392
|
"name": "LongDocument",
|
|
20393
20393
|
"code": "() => <LongDocumentDemo />",
|
|
20394
|
-
"description": "2 000 read-only lines clamped by `maxLines` — the top of the envelope the colour painter is\nbuilt for, where `readOnly` still lets the text be
|
|
20394
|
+
"description": "2 000 read-only lines clamped by `maxLines` — the top of the envelope the colour painter is\nbuilt for, where `readOnly` still lets the text be selected, searched and copied."
|
|
20395
20395
|
}
|
|
20396
20396
|
]
|
|
20397
20397
|
},
|
|
@@ -56848,11 +56848,6 @@
|
|
|
56848
56848
|
"type": "string | undefined",
|
|
56849
56849
|
"required": false
|
|
56850
56850
|
},
|
|
56851
|
-
{
|
|
56852
|
-
"name": "color",
|
|
56853
|
-
"type": "string | undefined",
|
|
56854
|
-
"required": false
|
|
56855
|
-
},
|
|
56856
56851
|
{
|
|
56857
56852
|
"name": "itemProp",
|
|
56858
56853
|
"type": "string | undefined",
|
|
@@ -56938,28 +56933,49 @@
|
|
|
56938
56933
|
"required": false,
|
|
56939
56934
|
"description": "@see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/part}"
|
|
56940
56935
|
},
|
|
56936
|
+
{
|
|
56937
|
+
"name": "color",
|
|
56938
|
+
"type": "{ neutral: string; 'neutral-alt': string; brand: string; danger: string; success: string; info: string; }",
|
|
56939
|
+
"required": false,
|
|
56940
|
+
"defaultValue": "type === 'solid' ? 'brand' : 'neutral"
|
|
56941
|
+
},
|
|
56941
56942
|
{
|
|
56942
56943
|
"name": "type",
|
|
56943
|
-
"type": "{
|
|
56944
|
+
"type": "{ solid: string; secondary: string; outline: string; }",
|
|
56944
56945
|
"required": false,
|
|
56945
|
-
"defaultValue": "
|
|
56946
|
+
"defaultValue": "secondary"
|
|
56946
56947
|
},
|
|
56947
56948
|
{
|
|
56948
56949
|
"name": "size",
|
|
56949
56950
|
"type": "{ default: string; small: string; }",
|
|
56950
56951
|
"required": false,
|
|
56951
56952
|
"defaultValue": "default"
|
|
56953
|
+
},
|
|
56954
|
+
{
|
|
56955
|
+
"name": "asChild",
|
|
56956
|
+
"type": "boolean | undefined",
|
|
56957
|
+
"required": false,
|
|
56958
|
+
"description": "Applies the badge to its child element, such as a span or a native button.",
|
|
56959
|
+
"defaultValue": "false"
|
|
56952
56960
|
}
|
|
56953
56961
|
],
|
|
56954
56962
|
"variants": [
|
|
56955
56963
|
{
|
|
56956
56964
|
"name": "type",
|
|
56957
56965
|
"options": [
|
|
56958
|
-
"
|
|
56959
|
-
"
|
|
56966
|
+
"solid",
|
|
56967
|
+
"secondary",
|
|
56968
|
+
"outline"
|
|
56969
|
+
]
|
|
56970
|
+
},
|
|
56971
|
+
{
|
|
56972
|
+
"name": "color",
|
|
56973
|
+
"options": [
|
|
56974
|
+
"neutral",
|
|
56975
|
+
"neutral-alt",
|
|
56960
56976
|
"brand",
|
|
56961
|
-
"
|
|
56962
|
-
"
|
|
56977
|
+
"danger",
|
|
56978
|
+
"success",
|
|
56963
56979
|
"info"
|
|
56964
56980
|
]
|
|
56965
56981
|
},
|
|
@@ -56970,6 +56986,12 @@
|
|
|
56970
56986
|
"small"
|
|
56971
56987
|
]
|
|
56972
56988
|
},
|
|
56989
|
+
{
|
|
56990
|
+
"name": "iconOnly",
|
|
56991
|
+
"options": [
|
|
56992
|
+
"true"
|
|
56993
|
+
]
|
|
56994
|
+
},
|
|
56973
56995
|
{
|
|
56974
56996
|
"name": "clickable",
|
|
56975
56997
|
"options": [
|
|
@@ -56982,7 +57004,7 @@
|
|
|
56982
57004
|
"examples": [
|
|
56983
57005
|
{
|
|
56984
57006
|
"name": "Basic",
|
|
56985
|
-
"code": "
|
|
57007
|
+
"code": "args => <NumericBadge {...args}>1</NumericBadge>",
|
|
56986
57008
|
"description": "The default count. Keep it to what the reader can take in at a glance; a four-digit count is\na number they need to read, not see."
|
|
56987
57009
|
},
|
|
56988
57010
|
{
|
|
@@ -56992,8 +57014,18 @@
|
|
|
56992
57014
|
},
|
|
56993
57015
|
{
|
|
56994
57016
|
"name": "Types",
|
|
56995
|
-
"code": "() => (\n // One row per type, so the label always sits beside the badges it names.\n <VStack gap={8} align='start'>\n {(
|
|
56996
|
-
"description": "
|
|
57017
|
+
"code": "() => (\n // One row per type, so the label always sits beside the badges it names.\n <VStack gap={8} align='start'>\n {combinations.map(({ type, color }) => (\n <HStack key={`${type}-${color}`} gap={12} align='center'>\n <span className='sb-annotation w-256 whitespace-nowrap text-right'>\n {type} / {color}\n </span>\n <div\n className={`inline-flex items-center gap-12 p-8 ${color === 'neutral-alt' ? 'bg-component-tooltip-bg' : ''}`}\n >\n <NumericBadge type={type} color={color} size='default'>\n 1\n </NumericBadge>\n <NumericBadge type={type} color={color} size='small'>\n 1\n </NumericBadge>\n </div>\n </HStack>\n ))}\n </VStack>\n)",
|
|
57018
|
+
"description": "Every supported Type × Color combination, in Medium and Small."
|
|
57019
|
+
},
|
|
57020
|
+
{
|
|
57021
|
+
"name": "Content",
|
|
57022
|
+
"code": "() => (\n <VStack gap={16} align='start'>\n {(['default', 'small'] as const).map(size => (\n <HStack key={size} gap={12} align='center'>\n <span className='sb-annotation w-96 text-right'>{size}</span>\n <NumericBadge size={size}>1</NumericBadge>\n <NumericBadge size={size}>99</NumericBadge>\n <NumericBadge size={size} color='danger' aria-label='Needs attention'>\n !\n </NumericBadge>\n <NumericBadge size={size} color='info' aria-label='Unknown'>\n ?\n </NumericBadge>\n <NumericBadge size={size} color='success' aria-label='Completed'>\n <Check />\n </NumericBadge>\n </HStack>\n ))}\n </VStack>\n)",
|
|
57023
|
+
"description": "Numbers, short glyphs, and icons share the same badge heights."
|
|
57024
|
+
},
|
|
57025
|
+
{
|
|
57026
|
+
"name": "Clickable",
|
|
57027
|
+
"code": "() => {\n const [activations, setActivations] = useState(0);\n\n return (\n <VStack gap={12} align='start'>\n {combinations.map(({ type, color }) => (\n <HStack key={`${type}-${color}`} gap={12} align='center'>\n <span className='sb-annotation w-256 whitespace-nowrap text-right'>\n {type} / {color}\n </span>\n <div className={color === 'neutral-alt' ? 'bg-component-tooltip-bg p-8' : 'p-8'}>\n <NumericBadge\n asChild\n type={type}\n color={color}\n onClick={() => setActivations(count => count + 1)}\n >\n <button type='button' aria-label={`${type} ${color}`}>\n 1\n </button>\n </NumericBadge>\n </div>\n </HStack>\n ))}\n <output aria-label='Activations'>{activations}</output>\n </VStack>\n );\n}",
|
|
57028
|
+
"description": "Use a native button for an action; Tab, Enter, and Space work as expected."
|
|
56997
57029
|
}
|
|
56998
57030
|
]
|
|
56999
57031
|
},
|
|
@@ -95981,7 +96013,7 @@
|
|
|
95981
96013
|
{
|
|
95982
96014
|
"name": "InDrawer",
|
|
95983
96015
|
"code": "() => {\n const { step, statuses, goTo } = usePolicyFlow();\n const { nextRef, submitRef, onBackClick, onNextClick } = useFooterFocus(step);\n const [submitted, setSubmitted] = useState(0);\n const last = step === POLICY_STEPS.length - 1;\n const onSubmit = (event: FormEvent) => {\n event.preventDefault();\n setSubmitted(n => n + 1);\n };\n return (\n <Drawer data-testid='drawer' width={640}>\n <DrawerTrigger asChild>\n <Button variant='outline' color='neutral' data-testid='drawer-open'>\n Create policy\n </Button>\n </DrawerTrigger>\n <DrawerContent>\n <DrawerHeader>\n <DrawerTitle>Create policy</DrawerTitle>\n </DrawerHeader>\n <form onSubmit={onSubmit} className='flex min-h-0 flex-1 flex-col'>\n <Stepper\n data-testid='stepper'\n count={POLICY_STEPS.length}\n step={step}\n onStepChange={details => goTo(details.step)}\n className='flex min-h-0 flex-1 flex-col'\n >\n <StepperList aria-label='Create policy steps'>\n {POLICY_STEPS.map((title, i) => (\n <StepperItem key={title} index={i} status={statuses[i]}>\n <StepperTrigger>\n <StepperIndicator />\n <StepperTitle>{title}</StepperTitle>\n </StepperTrigger>\n <StepperSeparator />\n </StepperItem>\n ))}\n </StepperList>\n <DrawerBody>\n {POLICY_STEPS.map((title, i) => (\n <StepperContent key={title} index={i} className='py-16'>\n <BodyPlaceholder label={`${title} fields`} />\n </StepperContent>\n ))}\n <span className='sb-annotation' data-testid='stepper-submitted'>\n Submitted: {submitted}\n </span>\n </DrawerBody>\n <DrawerFooter>\n {step > 0 && (\n <DrawerFooterControls placement='left'>\n <StepperPrevTrigger asChild onClick={onBackClick}>\n <Button variant='outline' color='neutral' size='large'>\n Back\n </Button>\n </StepperPrevTrigger>\n </DrawerFooterControls>\n )}\n <DrawerFooterControls placement='right'>\n {last ? (\n <Button\n ref={submitRef}\n type='submit'\n variant='primary'\n color='brand'\n size='large'\n >\n Create policy\n </Button>\n ) : (\n <StepperNextTrigger asChild onClick={onNextClick}>\n <Button ref={nextRef} variant='primary' color='brand' size='large'>\n Next: {POLICY_STEPS[step + 1]}\n </Button>\n </StepperNextTrigger>\n )}\n </DrawerFooterControls>\n </DrawerFooter>\n </Stepper>\n </form>\n </DrawerContent>\n </Drawer>\n );\n}",
|
|
95984
|
-
"description": "Inside a create drawer: the step list sits under the header, `StepperContent` shows the current\nstep's body (every body stays mounted, so fields keep their values) and the footer moves with\nBack / Next. Steps never submit the form; only the last step's own submit button does. Focus\nstays on the footer when Back or Next unmounts. Drawer parts inside the `Stepper
|
|
96016
|
+
"description": "Inside a create drawer: the step list sits under the header, `StepperContent` shows the current\nstep's body (every body stays mounted, so fields keep their values) and the footer moves with\nBack / Next. Steps never submit the form; only the last step's own submit button does. Focus\nstays on the footer when Back or Next unmounts. The list sits directly below the header,\nwith 24px side insets, 12px bottom padding and no divider. Drawer parts inside the `Stepper`\nroot take its test ids (`stepper--body`, `stepper--footer`), not the Drawer's."
|
|
95985
96017
|
},
|
|
95986
96018
|
{
|
|
95987
96019
|
"name": "LongLabel",
|
|
@@ -106837,7 +106869,7 @@
|
|
|
106837
106869
|
"props": [
|
|
106838
106870
|
{
|
|
106839
106871
|
"name": "color",
|
|
106840
|
-
"type": "string
|
|
106872
|
+
"type": "{ neutral: string; 'neutral-alt': string; brand: string; danger: string; success: string; info: string; }",
|
|
106841
106873
|
"required": false
|
|
106842
106874
|
},
|
|
106843
106875
|
{
|
|
@@ -107104,6 +107136,12 @@
|
|
|
107104
107136
|
"type": "string | undefined",
|
|
107105
107137
|
"required": false,
|
|
107106
107138
|
"description": "@see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/part}"
|
|
107139
|
+
},
|
|
107140
|
+
{
|
|
107141
|
+
"name": "asChild",
|
|
107142
|
+
"type": "boolean | undefined",
|
|
107143
|
+
"required": false,
|
|
107144
|
+
"description": "Applies the badge to its child element, such as a span or a native button."
|
|
107107
107145
|
}
|
|
107108
107146
|
]
|
|
107109
107147
|
},
|
package/package.json
CHANGED