@bspk/ui 1.1.16 → 1.1.18
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/Avatar.d.ts +44 -10
- package/dist/Avatar.js +32 -13
- package/dist/Avatar.js.map +1 -1
- package/dist/AvatarGroup.d.ts +49 -0
- package/dist/AvatarGroup.js +18 -0
- package/dist/AvatarGroup.js.map +1 -0
- package/dist/Badge.js +1 -1
- package/dist/Button.d.ts +14 -4
- package/dist/Button.js +1 -1
- package/dist/Button.js.map +1 -1
- package/dist/Checkbox.d.ts +15 -2
- package/dist/Checkbox.js.map +1 -1
- package/dist/CheckboxGroup.d.ts +6 -3
- package/dist/CheckboxGroup.js.map +1 -1
- package/dist/CheckboxOption.d.ts +8 -1
- package/dist/CheckboxOption.js.map +1 -1
- package/dist/Chip.d.ts +3 -1
- package/dist/Chip.js.map +1 -1
- package/dist/Dialog.d.ts +3 -3
- package/dist/Dialog.js.map +1 -1
- package/dist/Divider.js +1 -1
- package/dist/Dropdown.d.ts +26 -6
- package/dist/Dropdown.js +2 -2
- package/dist/Dropdown.js.map +1 -1
- package/dist/ListItem.js +1 -1
- package/dist/Menu.d.ts +27 -15
- package/dist/Menu.js +1 -1
- package/dist/Menu.js.map +1 -1
- package/dist/NumberInput.d.ts +5 -1
- package/dist/NumberInput.js +7 -5
- package/dist/NumberInput.js.map +1 -1
- package/dist/Portal.d.ts +5 -1
- package/dist/Portal.js.map +1 -1
- package/dist/ProgressBar.d.ts +4 -0
- package/dist/ProgressBar.js.map +1 -1
- package/dist/ProgressionStepper.d.ts +9 -2
- package/dist/ProgressionStepper.js +1 -1
- package/dist/ProgressionStepper.js.map +1 -1
- package/dist/ProgressionStepperBar.d.ts +6 -0
- package/dist/ProgressionStepperBar.js.map +1 -1
- package/dist/Radio.d.ts +16 -2
- package/dist/Radio.js +2 -2
- package/dist/Radio.js.map +1 -1
- package/dist/RadioGroup.d.ts +26 -3
- package/dist/RadioGroup.js +3 -3
- package/dist/RadioGroup.js.map +1 -1
- package/dist/RadioOption.d.ts +9 -1
- package/dist/RadioOption.js.map +1 -1
- package/dist/SegmentedControl.d.ts +21 -2
- package/dist/SegmentedControl.js +1 -1
- package/dist/SegmentedControl.js.map +1 -1
- package/dist/Switch.d.ts +1 -1
- package/dist/SwitchGroup.d.ts +13 -6
- package/dist/SwitchGroup.js +1 -1
- package/dist/SwitchGroup.js.map +1 -1
- package/dist/TabGroup.d.ts +23 -5
- package/dist/TabGroup.js +1 -1
- package/dist/TabGroup.js.map +1 -1
- package/dist/Tag.d.ts +5 -2
- package/dist/Tag.js +1 -1
- package/dist/Tag.js.map +1 -1
- package/dist/TextInput.d.ts +15 -6
- package/dist/TextInput.js +11 -5
- package/dist/TextInput.js.map +1 -1
- package/dist/Textarea.d.ts +3 -3
- package/dist/avatar-group.css +1 -0
- package/dist/avatar.css +1 -1
- package/dist/badge.css +1 -1
- package/dist/button.css +1 -1
- package/dist/demo/ExampleModalRender.d.ts +7 -0
- package/dist/demo/ExampleModalRender.js +16 -0
- package/dist/demo/ExampleModalRender.js.map +1 -0
- package/dist/demo/ExamplePlaceholder.d.ts +7 -0
- package/dist/demo/ExamplePlaceholder.js +13 -0
- package/dist/demo/ExamplePlaceholder.js.map +1 -0
- package/dist/demo/examples.d.ts +101 -0
- package/dist/demo/examples.js +472 -0
- package/dist/demo/examples.js.map +1 -0
- package/dist/divider.css +1 -1
- package/dist/hooks/useOptionIconsInvalid.d.ts +10 -1
- package/dist/hooks/useOptionIconsInvalid.js.map +1 -1
- package/dist/index.d.ts +4 -26
- package/dist/index.js.map +1 -1
- package/dist/list-item.css +1 -1
- package/dist/menu.css +1 -1
- package/dist/segmented-control.css +1 -1
- package/dist/tab-group.css +1 -1
- package/dist/tag.css +1 -1
- package/dist/text-input.css +1 -1
- package/dist/utils/children.js.map +1 -1
- package/meta-types.ts +2 -0
- package/meta.ts +76 -42
- package/package.json +1 -1
- package/src/Avatar.tsx +80 -27
- package/src/AvatarGroup.tsx +71 -0
- package/src/Button.tsx +14 -4
- package/src/Checkbox.tsx +25 -11
- package/src/CheckboxGroup.tsx +6 -3
- package/src/CheckboxOption.tsx +9 -2
- package/src/Chip.tsx +3 -1
- package/src/Dialog.tsx +3 -3
- package/src/Dropdown.tsx +30 -10
- package/src/Menu.tsx +30 -18
- package/src/NumberInput.tsx +15 -6
- package/src/Portal.tsx +5 -1
- package/src/ProgressBar.tsx +4 -0
- package/src/ProgressionStepper.tsx +9 -2
- package/src/ProgressionStepperBar.tsx +6 -0
- package/src/Radio.tsx +21 -4
- package/src/RadioGroup.tsx +34 -6
- package/src/RadioOption.tsx +11 -2
- package/src/SegmentedControl.tsx +21 -2
- package/src/Switch.tsx +1 -1
- package/src/SwitchGroup.tsx +19 -7
- package/src/TabGroup.tsx +23 -5
- package/src/Tag.tsx +5 -2
- package/src/TextInput.tsx +25 -15
- package/src/Textarea.tsx +3 -3
- package/src/avatar-group.scss +17 -0
- package/src/avatar.scss +5 -2
- package/src/badge.scss +1 -0
- package/src/button.scss +1 -0
- package/src/demo/ExampleModalRender.tsx +37 -0
- package/src/demo/ExamplePlaceholder.tsx +40 -0
- package/src/demo/examples.tsx +683 -0
- package/src/divider.scss +2 -0
- package/src/dropdown.scss +1 -0
- package/src/hooks/useOptionIconsInvalid.ts +10 -1
- package/src/index.ts +5 -32
- package/src/list-item.scss +5 -1
- package/src/menu.scss +1 -1
- package/src/segmented-control.scss +1 -0
- package/src/tab-group.scss +1 -0
- package/src/tag.scss +1 -0
- package/src/text-input.scss +13 -18
- package/src/utils/children.ts +1 -1
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
import { SvgCircle } from '@bspk/icons/Circle';
|
|
2
|
+
import { SvgContentCopy } from '@bspk/icons/ContentCopy';
|
|
3
|
+
import { SvgDiamond } from '@bspk/icons/Diamond';
|
|
4
|
+
import { SvgDiamondFill } from '@bspk/icons/DiamondFill';
|
|
5
|
+
import { SvgSquare } from '@bspk/icons/Square';
|
|
6
|
+
import { SvgSquareFill } from '@bspk/icons/SquareFill';
|
|
7
|
+
import { CSSProperties } from 'react';
|
|
8
|
+
|
|
9
|
+
import { Avatar, AvatarProps } from '../Avatar';
|
|
10
|
+
import { BannerAlertProps } from '../BannerAlert';
|
|
11
|
+
import { Button, ButtonProps } from '../Button';
|
|
12
|
+
import { Checkbox } from '../Checkbox';
|
|
13
|
+
import { DropdownOption, DropdownProps } from '../Dropdown';
|
|
14
|
+
import { EmptyStateProps } from '../EmptyState';
|
|
15
|
+
import { Img } from '../Img';
|
|
16
|
+
import { LEADING_COMPONENTS, TRAILING_COMPONENTS, ListItem } from '../ListItem';
|
|
17
|
+
import { MenuItem } from '../Menu';
|
|
18
|
+
import { ModalProps } from '../Modal';
|
|
19
|
+
import { Popover, PopoverProps } from '../Popover';
|
|
20
|
+
import { ProgressionStepperProps } from '../ProgressionStepper';
|
|
21
|
+
import { Radio } from '../Radio';
|
|
22
|
+
import { SegmentedControlProps } from '../SegmentedControl';
|
|
23
|
+
import { Switch } from '../Switch';
|
|
24
|
+
import { TabGroupProps } from '../TabGroup';
|
|
25
|
+
import { Tag } from '../Tag';
|
|
26
|
+
import { TextInputProps } from '../TextInput';
|
|
27
|
+
import { Txt } from '../Txt';
|
|
28
|
+
import { ColorVariant } from '../utils/colorVariants';
|
|
29
|
+
|
|
30
|
+
import { ExampleModalRender } from './ExampleModalRender';
|
|
31
|
+
import { ExamplePlaceholder } from './ExamplePlaceholder';
|
|
32
|
+
|
|
33
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
34
|
+
|
|
35
|
+
export type TypeProperty = {
|
|
36
|
+
name: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
type?: string[] | string;
|
|
39
|
+
default?: unknown;
|
|
40
|
+
required?: boolean;
|
|
41
|
+
options?: number[] | string[];
|
|
42
|
+
variants?: string[];
|
|
43
|
+
properties?: TypeProperty[];
|
|
44
|
+
references?: string[];
|
|
45
|
+
minimum?: number;
|
|
46
|
+
maximum?: number;
|
|
47
|
+
example?: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type DemoAction = (...str: unknown[]) => void;
|
|
51
|
+
|
|
52
|
+
export type DemoSetState = (next: Record<string, unknown>) => void;
|
|
53
|
+
|
|
54
|
+
export type DevPhase =
|
|
55
|
+
| 'AccessibilityReview'
|
|
56
|
+
| 'Backlog'
|
|
57
|
+
| 'DesignReview'
|
|
58
|
+
| 'ProductionReady'
|
|
59
|
+
| 'Utility'
|
|
60
|
+
| 'WorkInProgress';
|
|
61
|
+
|
|
62
|
+
export type TypePropertyDemo = Omit<TypeProperty, 'example'> & {
|
|
63
|
+
properties?: TypePropertyDemo[];
|
|
64
|
+
libraryDefault?: TypeProperty['default'];
|
|
65
|
+
label?: string;
|
|
66
|
+
|
|
67
|
+
example?: any;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type TypePropertyDemoWithControls = Pick<TypeProperty, 'type'> &
|
|
71
|
+
TypePropertyDemo & {
|
|
72
|
+
haveControl: boolean;
|
|
73
|
+
typeOptions: number[] | string[] | undefined;
|
|
74
|
+
properties?: TypePropertyDemoWithControls[];
|
|
75
|
+
multiline?: boolean;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type ComponentExample<Props = Record<string, unknown>> = {
|
|
79
|
+
/**
|
|
80
|
+
* The style of the wrapping component.
|
|
81
|
+
*
|
|
82
|
+
* //
|
|
83
|
+
*/
|
|
84
|
+
containerStyle?: React.CSSProperties | ((state: Record<string, unknown>) => React.CSSProperties);
|
|
85
|
+
/**
|
|
86
|
+
* Takes the current state and returns the props to be passed to the component.
|
|
87
|
+
*
|
|
88
|
+
* This is useful for dynamically generating props based on the state and context of the component.
|
|
89
|
+
*
|
|
90
|
+
* @param state The current state of the component.
|
|
91
|
+
* @param context The context of the component, which can include the current preset.
|
|
92
|
+
* @returns The props to be passed directly into the component.
|
|
93
|
+
*/
|
|
94
|
+
propRenderOverrides?: (
|
|
95
|
+
state: Record<string, unknown>,
|
|
96
|
+
context?: {
|
|
97
|
+
[key: string]: unknown;
|
|
98
|
+
preset?: DemoPreset;
|
|
99
|
+
},
|
|
100
|
+
) => Record<string, unknown>;
|
|
101
|
+
/**
|
|
102
|
+
* True to hide all or a list of variants to hide.
|
|
103
|
+
*
|
|
104
|
+
* Helpful for hiding variants that can have unexpected collisions with the other examples.
|
|
105
|
+
*/
|
|
106
|
+
hideVariants?: string[] | true;
|
|
107
|
+
/**
|
|
108
|
+
* This is used to set the initial state of the component.
|
|
109
|
+
*
|
|
110
|
+
* Specifically to highlight certain features of the component.
|
|
111
|
+
*/
|
|
112
|
+
presets?: Preset<Props>[];
|
|
113
|
+
/**
|
|
114
|
+
* The component to render in the example.
|
|
115
|
+
*
|
|
116
|
+
* By default, this will be the component that is being documented.
|
|
117
|
+
*
|
|
118
|
+
* If you only need to update the props of the component, you can use renderProps.
|
|
119
|
+
*/
|
|
120
|
+
render?: (params: {
|
|
121
|
+
props: Props;
|
|
122
|
+
preset?: DemoPreset;
|
|
123
|
+
Component: React.ComponentType<Record<string, unknown>>;
|
|
124
|
+
}) => React.ReactNode;
|
|
125
|
+
/**
|
|
126
|
+
* Useful for overriding the default props controls in the demo.
|
|
127
|
+
*
|
|
128
|
+
* If you change the type of a prop, you will probably need to specificy how to render them in renderProps.
|
|
129
|
+
*
|
|
130
|
+
* See the ListItem example for an of how to use this.
|
|
131
|
+
*/
|
|
132
|
+
propControlsOverrides?: {
|
|
133
|
+
[key: string]: Partial<TypePropertyDemo>;
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type Preset<P> = {
|
|
138
|
+
/** The name of the preset. This is used to display the preset in the UI. */
|
|
139
|
+
label: string;
|
|
140
|
+
/** The props of the component. This is used to set props of the component. These values can't be changed in the UI. */
|
|
141
|
+
state?: Partial<P>;
|
|
142
|
+
/** Determines if the preset is the default preset. This is used to set the initial state of the component. */
|
|
143
|
+
isDefault?: boolean;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export type DemoPreset<P = Record<string, unknown>> = Preset<P> & { value: string };
|
|
147
|
+
|
|
148
|
+
export function createUid(prefix: string = 'uid'): string {
|
|
149
|
+
return `${prefix}-${Math.random().toString(36).substring(2, 9)}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const asProps = <P extends Record<string, unknown>>(p: Partial<P>): Partial<P> => p;
|
|
153
|
+
|
|
154
|
+
export const setPresets = <P extends Record<string, unknown>>(p: Preset<P>[] | (() => Preset<P>[])) =>
|
|
155
|
+
typeof p === 'function' ? p() : p;
|
|
156
|
+
|
|
157
|
+
const buttonExamplePresets = setPresets<ButtonProps>([
|
|
158
|
+
{
|
|
159
|
+
label: 'Icon & Text',
|
|
160
|
+
state: {
|
|
161
|
+
icon: 'Add',
|
|
162
|
+
label: 'Add',
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
label: 'Text only',
|
|
167
|
+
state: {
|
|
168
|
+
label: 'Add',
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
label: 'Icon only',
|
|
173
|
+
state: {
|
|
174
|
+
showLabel: false,
|
|
175
|
+
icon: 'Add',
|
|
176
|
+
label: 'Add',
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
]);
|
|
180
|
+
|
|
181
|
+
export const examples: (setState: DemoSetState, action: DemoAction) => Record<string, ComponentExample> = (
|
|
182
|
+
setState,
|
|
183
|
+
action,
|
|
184
|
+
) => ({
|
|
185
|
+
Avatar: {
|
|
186
|
+
presets: setPresets<AvatarProps>([
|
|
187
|
+
{
|
|
188
|
+
label: 'Name Only',
|
|
189
|
+
state: {
|
|
190
|
+
name: 'Andre Giant',
|
|
191
|
+
image: undefined, // Ensure no image is set
|
|
192
|
+
initials: undefined, // Ensure no initials are set
|
|
193
|
+
icon: undefined, // Ensure no icon is set
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
label: 'With Initials',
|
|
198
|
+
state: {
|
|
199
|
+
name: 'Andre Giant',
|
|
200
|
+
initials: 'GA',
|
|
201
|
+
image: undefined, // Ensure no image is set
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
label: 'With Icon',
|
|
206
|
+
state: {
|
|
207
|
+
name: 'Andre Giant',
|
|
208
|
+
icon: 'Person',
|
|
209
|
+
image: undefined, // Ensure no image is set
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
label: 'With Image',
|
|
214
|
+
state: {
|
|
215
|
+
name: 'Andre Giant',
|
|
216
|
+
image: '/profile.jpg',
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
]),
|
|
220
|
+
},
|
|
221
|
+
Button: {
|
|
222
|
+
presets: buttonExamplePresets,
|
|
223
|
+
},
|
|
224
|
+
BannerAlert: {
|
|
225
|
+
containerStyle: { width: '100%' },
|
|
226
|
+
propRenderOverrides: (state, context) => {
|
|
227
|
+
let nextHeader = state.header || 'This is a banner alert';
|
|
228
|
+
if (context?.variantName === 'variant') {
|
|
229
|
+
if (context?.variantValue === 'informational') nextHeader = 'This is informational banner';
|
|
230
|
+
if (context?.variantValue === 'success') nextHeader = 'This is success banner';
|
|
231
|
+
if (context?.variantValue === 'warning') nextHeader = 'This is warning banner';
|
|
232
|
+
if (context?.variantValue === 'error') nextHeader = 'This is error banner';
|
|
233
|
+
}
|
|
234
|
+
return { ...state, header: nextHeader };
|
|
235
|
+
},
|
|
236
|
+
presets: setPresets<BannerAlertProps>([
|
|
237
|
+
{
|
|
238
|
+
label: 'With CallToAction',
|
|
239
|
+
state: {
|
|
240
|
+
callToAction: {
|
|
241
|
+
label: 'Click me',
|
|
242
|
+
onClick: () => action('Call to action clicked!'),
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
label: 'Without OnClose',
|
|
248
|
+
state: {
|
|
249
|
+
onClose: undefined,
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
]),
|
|
253
|
+
},
|
|
254
|
+
Card: {
|
|
255
|
+
propRenderOverrides: (state) => ({
|
|
256
|
+
...state,
|
|
257
|
+
children: (
|
|
258
|
+
<ExamplePlaceholder
|
|
259
|
+
style={{
|
|
260
|
+
height: '200px',
|
|
261
|
+
width: '100%',
|
|
262
|
+
minWidth: '250px',
|
|
263
|
+
}}
|
|
264
|
+
/>
|
|
265
|
+
),
|
|
266
|
+
}),
|
|
267
|
+
},
|
|
268
|
+
Divider: {
|
|
269
|
+
render: ({ props, Component }) => {
|
|
270
|
+
const style: CSSProperties =
|
|
271
|
+
props.orientation === 'vertical' ? { height: 300, width: 100 } : { height: 100, width: '300px' };
|
|
272
|
+
return (
|
|
273
|
+
<div
|
|
274
|
+
style={{
|
|
275
|
+
display: 'flex',
|
|
276
|
+
flexDirection: props.orientation === 'vertical' ? 'row' : 'column',
|
|
277
|
+
alignItems: props.orientation === 'vertical' ? 'center' : 'stretch',
|
|
278
|
+
justifyContent: props.orientation === 'vertical' ? 'center' : 'stretch',
|
|
279
|
+
maxWidth: props.orientation !== 'vertical' ? '300px' : 'auto',
|
|
280
|
+
}}
|
|
281
|
+
>
|
|
282
|
+
<ExamplePlaceholder direction={props.orientation !== 'vertical' ? 'row' : 'column'} style={style} />
|
|
283
|
+
<Component {...props} />
|
|
284
|
+
<ExamplePlaceholder direction={props.orientation !== 'vertical' ? 'row' : 'column'} style={style} />
|
|
285
|
+
</div>
|
|
286
|
+
);
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
Dropdown: {
|
|
290
|
+
presets: setPresets<DropdownProps>(() => {
|
|
291
|
+
return [
|
|
292
|
+
{
|
|
293
|
+
label: 'Simple',
|
|
294
|
+
state: {},
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
label: 'Multi',
|
|
298
|
+
state: { isMulti: true },
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
label: 'Trailing Tags',
|
|
302
|
+
state: asProps<DropdownProps<DropdownOption & { tag?: string; tagColor?: ColorVariant }>>({
|
|
303
|
+
options: [
|
|
304
|
+
//
|
|
305
|
+
{ value: 'a', label: 'Package A', tag: 'Recommended', tagColor: 'blue' },
|
|
306
|
+
{ value: 'b', label: 'Package B', tag: 'Best Value', tagColor: 'green' },
|
|
307
|
+
{ value: 'c', label: 'Package C' },
|
|
308
|
+
{ value: 'd', label: 'Package D' },
|
|
309
|
+
],
|
|
310
|
+
renderListItem: (props) => {
|
|
311
|
+
return {
|
|
312
|
+
trailing:
|
|
313
|
+
props.item.tag && props.item.tagColor ? (
|
|
314
|
+
<Tag color={props.item.tagColor!} size="x-small">
|
|
315
|
+
{props.item.tag}
|
|
316
|
+
</Tag>
|
|
317
|
+
) : null,
|
|
318
|
+
};
|
|
319
|
+
},
|
|
320
|
+
}),
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
label: 'Trailing Text',
|
|
324
|
+
state: asProps<DropdownProps<DropdownOption & { price: number }>>({
|
|
325
|
+
options: [
|
|
326
|
+
//
|
|
327
|
+
{ value: '1', label: 'Option A', price: 400 },
|
|
328
|
+
{ value: '2', label: 'Option B', price: 1000 },
|
|
329
|
+
{ value: '3', label: 'Option C', price: 1600 },
|
|
330
|
+
{ value: '4', label: 'Option D', price: 2000 },
|
|
331
|
+
],
|
|
332
|
+
renderListItem: (props) => {
|
|
333
|
+
return {
|
|
334
|
+
trailing: (
|
|
335
|
+
<Txt>{`${new Intl.NumberFormat('en-US', {
|
|
336
|
+
style: 'currency',
|
|
337
|
+
currency: 'USD',
|
|
338
|
+
}).format(props.item.price / 100)}`}</Txt>
|
|
339
|
+
),
|
|
340
|
+
};
|
|
341
|
+
},
|
|
342
|
+
}),
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
label: 'Leading Avatar',
|
|
346
|
+
state: asProps<
|
|
347
|
+
DropdownProps<
|
|
348
|
+
MenuItem & {
|
|
349
|
+
profile: AvatarProps;
|
|
350
|
+
}
|
|
351
|
+
>
|
|
352
|
+
>({
|
|
353
|
+
options: [
|
|
354
|
+
//
|
|
355
|
+
{
|
|
356
|
+
value: 'Jessica',
|
|
357
|
+
label: 'Jessica P.',
|
|
358
|
+
profile: { name: 'Jessica P.' },
|
|
359
|
+
},
|
|
360
|
+
{ value: 'Louis', label: 'Louis L.', profile: { name: 'Louis L.' } },
|
|
361
|
+
{ value: 'Harvey', label: 'Harvey S.', profile: { name: 'Harvey S.' } },
|
|
362
|
+
{ value: 'Mike', label: 'Mike R.', profile: { name: 'Mike R.' } },
|
|
363
|
+
],
|
|
364
|
+
renderListItem: (props) => {
|
|
365
|
+
return {
|
|
366
|
+
leading: <Avatar size="small" {...props.item.profile} />,
|
|
367
|
+
};
|
|
368
|
+
},
|
|
369
|
+
}),
|
|
370
|
+
},
|
|
371
|
+
];
|
|
372
|
+
}),
|
|
373
|
+
},
|
|
374
|
+
EmptyState: {
|
|
375
|
+
containerStyle: { width: '100%' },
|
|
376
|
+
propRenderOverrides: (state, context) => {
|
|
377
|
+
return {
|
|
378
|
+
...state,
|
|
379
|
+
children:
|
|
380
|
+
context?.preset?.label === 'With Children' ? (
|
|
381
|
+
<ExamplePlaceholder
|
|
382
|
+
style={{
|
|
383
|
+
height: '200px',
|
|
384
|
+
width: '60%',
|
|
385
|
+
minWidth: '250px',
|
|
386
|
+
}}
|
|
387
|
+
/>
|
|
388
|
+
) : null,
|
|
389
|
+
};
|
|
390
|
+
},
|
|
391
|
+
presets: setPresets<EmptyStateProps>([
|
|
392
|
+
{
|
|
393
|
+
label: 'With CallToAction',
|
|
394
|
+
state: {
|
|
395
|
+
header: 'No payment methods added',
|
|
396
|
+
body: 'Add a card to your account for faster checkout.',
|
|
397
|
+
callToAction: {
|
|
398
|
+
label: 'Add payment method',
|
|
399
|
+
onClick: () => action('Add payment method clicked!'),
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
label: 'With Children',
|
|
405
|
+
state: {
|
|
406
|
+
header: 'No payment methods added',
|
|
407
|
+
body: 'Add a card to your account for faster checkout.',
|
|
408
|
+
callToAction: {
|
|
409
|
+
label: 'Add payment method',
|
|
410
|
+
onClick: () => action('Add payment method clicked!'),
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
]),
|
|
415
|
+
},
|
|
416
|
+
Fab: {
|
|
417
|
+
containerStyle: { width: '100%' },
|
|
418
|
+
presets: buttonExamplePresets,
|
|
419
|
+
},
|
|
420
|
+
ListItem: {
|
|
421
|
+
containerStyle: { width: '50%' },
|
|
422
|
+
propRenderOverrides: (state) => {
|
|
423
|
+
return {
|
|
424
|
+
...state,
|
|
425
|
+
leading: createChildrenElement(state, 'leading', setState, action),
|
|
426
|
+
trailing: createChildrenElement(state, 'trailing', setState, action),
|
|
427
|
+
};
|
|
428
|
+
},
|
|
429
|
+
propControlsOverrides: {
|
|
430
|
+
leading: {
|
|
431
|
+
options: [...LEADING_COMPONENTS],
|
|
432
|
+
type: 'select',
|
|
433
|
+
},
|
|
434
|
+
trailing: {
|
|
435
|
+
options: [...TRAILING_COMPONENTS],
|
|
436
|
+
type: 'select',
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
Modal: {
|
|
441
|
+
hideVariants: true,
|
|
442
|
+
render: ({ props, preset }) => (
|
|
443
|
+
<ExampleModalRender preset={preset} props={props as ModalProps} setState={setState} />
|
|
444
|
+
),
|
|
445
|
+
},
|
|
446
|
+
Popover: {
|
|
447
|
+
render: ({ props }) => {
|
|
448
|
+
return (
|
|
449
|
+
<>
|
|
450
|
+
<Popover {...(props as PopoverProps)}>
|
|
451
|
+
<Button label={`Click me (${props.placement})`} variant="secondary" />
|
|
452
|
+
</Popover>
|
|
453
|
+
</>
|
|
454
|
+
);
|
|
455
|
+
},
|
|
456
|
+
presets: setPresets<PopoverProps>([
|
|
457
|
+
{
|
|
458
|
+
label: 'With CallToAction',
|
|
459
|
+
state: { callToAction: { label: 'Click me', onClick: () => action('Call to action clicked!') } },
|
|
460
|
+
},
|
|
461
|
+
]),
|
|
462
|
+
},
|
|
463
|
+
Link: {
|
|
464
|
+
render: ({ props, Component }) => {
|
|
465
|
+
return (
|
|
466
|
+
<div
|
|
467
|
+
style={{
|
|
468
|
+
display: 'flex',
|
|
469
|
+
width: '100%',
|
|
470
|
+
justifyContent: 'center',
|
|
471
|
+
background: props.variant === 'subtle-inverse' ? 'black' : '',
|
|
472
|
+
minHeight: 'var(--spacing-sizing-24)',
|
|
473
|
+
}}
|
|
474
|
+
>
|
|
475
|
+
<Component {...props} />
|
|
476
|
+
</div>
|
|
477
|
+
);
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
ProgressionStepper: {
|
|
481
|
+
presets: setPresets<ProgressionStepperProps>([
|
|
482
|
+
{
|
|
483
|
+
label: 'Horizontal',
|
|
484
|
+
state: {
|
|
485
|
+
variant: 'horizontal',
|
|
486
|
+
currentStep: 2,
|
|
487
|
+
steps: [{ name: 'Name of step 1' }, { name: 'Name of step 2' }, { name: 'Name of step 3' }],
|
|
488
|
+
},
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
label: 'Vertical',
|
|
492
|
+
state: {
|
|
493
|
+
variant: 'vertical',
|
|
494
|
+
currentStep: 2,
|
|
495
|
+
steps: [
|
|
496
|
+
{
|
|
497
|
+
name: 'Name of step 1',
|
|
498
|
+
subtext: `Subtext of step 1`,
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
name: 'Name of step 2',
|
|
502
|
+
subtext: `Subtext of step 2`,
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: 'Name of step 3',
|
|
506
|
+
subtext: `Subtext of step 3`,
|
|
507
|
+
},
|
|
508
|
+
],
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
label: 'Widget',
|
|
513
|
+
state: {
|
|
514
|
+
variant: 'widget',
|
|
515
|
+
currentStep: 2,
|
|
516
|
+
steps: [
|
|
517
|
+
{ name: 'Name of step 1' },
|
|
518
|
+
{ name: 'Name of step 2' },
|
|
519
|
+
{ name: 'Name of step 3' },
|
|
520
|
+
{ name: 'Name of step 4' },
|
|
521
|
+
{ name: 'Name of step 5' },
|
|
522
|
+
{ name: 'Name of step 6' },
|
|
523
|
+
{ name: 'Name of step 7' },
|
|
524
|
+
],
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
]),
|
|
528
|
+
},
|
|
529
|
+
Radio: {
|
|
530
|
+
render: ({ props, Component }) => <Component {...props} name={createUid('radio')} />,
|
|
531
|
+
},
|
|
532
|
+
RadioGroup: {
|
|
533
|
+
render: ({ props, Component }) => <Component {...props} name={createUid('radio')} />,
|
|
534
|
+
},
|
|
535
|
+
RadioOption: {
|
|
536
|
+
render: ({ props, Component }) => <Component {...props} name={createUid('radio')} />,
|
|
537
|
+
},
|
|
538
|
+
SegmentedControl: {
|
|
539
|
+
containerStyle: { width: '100%' },
|
|
540
|
+
presets: setPresets<SegmentedControlProps>([
|
|
541
|
+
{
|
|
542
|
+
label: 'With icons',
|
|
543
|
+
state: {
|
|
544
|
+
options: [
|
|
545
|
+
{ value: '1', label: 'Option 1', icon: <SvgDiamond />, iconActive: <SvgDiamondFill /> },
|
|
546
|
+
{ value: '2', label: 'Disabled 2', disabled: true, icon: <SvgCircle /> },
|
|
547
|
+
{ value: '3', label: 'Option 3', icon: <SvgSquare />, iconActive: <SvgSquareFill /> },
|
|
548
|
+
],
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
]),
|
|
552
|
+
},
|
|
553
|
+
TextInput: {
|
|
554
|
+
containerStyle: { width: '280px' },
|
|
555
|
+
presets: setPresets<TextInputProps>([
|
|
556
|
+
{
|
|
557
|
+
label: 'Currency',
|
|
558
|
+
state: {
|
|
559
|
+
type: 'number',
|
|
560
|
+
leading: '$',
|
|
561
|
+
trailing: undefined,
|
|
562
|
+
placeholder: 'currency',
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
label: 'Percent',
|
|
567
|
+
state: {
|
|
568
|
+
type: 'number',
|
|
569
|
+
leading: undefined,
|
|
570
|
+
trailing: '%',
|
|
571
|
+
placeholder: 'percent',
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
label: 'Dimension',
|
|
576
|
+
state: {
|
|
577
|
+
type: 'number',
|
|
578
|
+
leading: undefined,
|
|
579
|
+
placeholder: 'dimensions',
|
|
580
|
+
trailing: 'ft',
|
|
581
|
+
},
|
|
582
|
+
},
|
|
583
|
+
]),
|
|
584
|
+
},
|
|
585
|
+
TabGroup: {
|
|
586
|
+
containerStyle: { width: '100%' },
|
|
587
|
+
presets: setPresets<TabGroupProps>([
|
|
588
|
+
{
|
|
589
|
+
label: 'With icons',
|
|
590
|
+
state: {
|
|
591
|
+
options: [
|
|
592
|
+
{ value: '1', label: 'Option 1', icon: <SvgDiamond />, iconActive: <SvgDiamondFill /> },
|
|
593
|
+
{ value: '2', label: 'Disabled 2', disabled: true, icon: <SvgCircle /> },
|
|
594
|
+
{ value: '3', label: 'Option 3', icon: <SvgSquare />, iconActive: <SvgSquareFill /> },
|
|
595
|
+
],
|
|
596
|
+
},
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
label: 'With badges',
|
|
600
|
+
state: {
|
|
601
|
+
options: [
|
|
602
|
+
{
|
|
603
|
+
value: '1',
|
|
604
|
+
label: 'Option 1',
|
|
605
|
+
icon: <SvgDiamond />,
|
|
606
|
+
iconActive: <SvgDiamondFill />,
|
|
607
|
+
badge: 1,
|
|
608
|
+
},
|
|
609
|
+
{ value: '2', label: 'Disabled 2', disabled: true, icon: <SvgCircle />, badge: 2 },
|
|
610
|
+
{ value: '3', label: 'Option 3', icon: <SvgSquare />, iconActive: <SvgSquare />, badge: 3 },
|
|
611
|
+
],
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
]),
|
|
615
|
+
},
|
|
616
|
+
Tooltip: {
|
|
617
|
+
render: ({ props: state, Component }) => {
|
|
618
|
+
return (
|
|
619
|
+
<>
|
|
620
|
+
<Component label="Tooltip text" {...state} placement={[state.placement].flat()[0] || 'top'}>
|
|
621
|
+
<Button
|
|
622
|
+
label={`Hover over me ${'data-variant-value' in state ? `(${state['data-variant-value']})` : ''}`}
|
|
623
|
+
variant="secondary"
|
|
624
|
+
/>
|
|
625
|
+
</Component>
|
|
626
|
+
</>
|
|
627
|
+
);
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
export const createChildrenElement = (
|
|
633
|
+
state: Record<string, any>,
|
|
634
|
+
name: string,
|
|
635
|
+
setState: DemoSetState,
|
|
636
|
+
action: DemoAction,
|
|
637
|
+
) => {
|
|
638
|
+
const componentName = state[name];
|
|
639
|
+
|
|
640
|
+
if (componentName === 'Checkbox' || componentName === 'Radio' || componentName === 'Switch') {
|
|
641
|
+
let As: typeof Checkbox | typeof Radio | typeof Switch = Checkbox;
|
|
642
|
+
if (componentName === 'Radio') As = Radio;
|
|
643
|
+
else if (componentName === 'Switch') As = Switch;
|
|
644
|
+
|
|
645
|
+
return (
|
|
646
|
+
<As
|
|
647
|
+
aria-label={`${componentName} demo`}
|
|
648
|
+
checked={state[`${name}-toggle`]}
|
|
649
|
+
name={`${name}-toggle`}
|
|
650
|
+
onChange={(checked: boolean) => {
|
|
651
|
+
setState({ [`${name}-toggle`]: checked });
|
|
652
|
+
}}
|
|
653
|
+
onClick={() => action(`${name} ${componentName} clicked`)}
|
|
654
|
+
value={`${name}-${componentName}`}
|
|
655
|
+
/>
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (componentName === 'ListItemButton')
|
|
660
|
+
return (
|
|
661
|
+
<ListItem.Button
|
|
662
|
+
icon={<SvgContentCopy />}
|
|
663
|
+
label="LI Button"
|
|
664
|
+
onClick={() => action('ListItem button clicked')}
|
|
665
|
+
/>
|
|
666
|
+
);
|
|
667
|
+
|
|
668
|
+
if (componentName === 'Img') return <Img alt="placeholder" src="/placeholder.svg" />;
|
|
669
|
+
|
|
670
|
+
if (componentName === 'Avatar') return <Avatar name="List Item" showTooltip={false} />;
|
|
671
|
+
|
|
672
|
+
if (componentName === 'Tag') {
|
|
673
|
+
return <Tag>Tag</Tag>;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
if (componentName === 'Txt') return <Txt>Text</Txt>;
|
|
677
|
+
|
|
678
|
+
if (componentName === 'Icon') return <SvgDiamond />;
|
|
679
|
+
|
|
680
|
+
return null;
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
/** Copyright 2025 Anywhere Real Estate - CC BY 4.0 */
|
package/src/divider.scss
CHANGED
package/src/dropdown.scss
CHANGED