@bspk/ui 1.1.20 → 1.1.22
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 +18 -2
- package/dist/Avatar.js +18 -2
- package/dist/Avatar.js.map +1 -1
- package/dist/AvatarGroup.d.ts +14 -0
- package/dist/AvatarGroup.js +14 -0
- package/dist/AvatarGroup.js.map +1 -1
- package/dist/Badge.d.ts +23 -2
- package/dist/Badge.js +12 -3
- package/dist/Badge.js.map +1 -1
- package/dist/BannerAlert.d.ts +17 -0
- package/dist/BannerAlert.js +17 -0
- package/dist/BannerAlert.js.map +1 -1
- package/dist/Button.d.ts +16 -0
- package/dist/Button.js +16 -0
- package/dist/Button.js.map +1 -1
- package/dist/Card.d.ts +12 -0
- package/dist/Card.js +12 -0
- package/dist/Card.js.map +1 -1
- package/dist/Checkbox.d.ts +21 -0
- package/dist/Checkbox.js +21 -0
- package/dist/Checkbox.js.map +1 -1
- package/dist/CheckboxGroup.d.ts +30 -0
- package/dist/CheckboxGroup.js +23 -0
- package/dist/CheckboxGroup.js.map +1 -1
- package/dist/CheckboxOption.d.ts +23 -1
- package/dist/CheckboxOption.js +25 -2
- package/dist/CheckboxOption.js.map +1 -1
- package/dist/Chip.d.ts +11 -0
- package/dist/Chip.js +11 -0
- package/dist/Chip.js.map +1 -1
- package/dist/Dialog.d.ts +19 -0
- package/dist/Dialog.js +19 -0
- package/dist/Dialog.js.map +1 -1
- package/dist/Divider.d.ts +13 -0
- package/dist/Divider.js +13 -0
- package/dist/Divider.js.map +1 -1
- package/dist/Dropdown.d.ts +30 -0
- package/dist/Dropdown.js +30 -0
- package/dist/Dropdown.js.map +1 -1
- package/dist/DropdownField.d.ts +22 -0
- package/dist/DropdownField.js +22 -0
- package/dist/DropdownField.js.map +1 -1
- package/dist/EmptyState.d.ts +11 -0
- package/dist/EmptyState.js +11 -0
- package/dist/EmptyState.js.map +1 -1
- package/dist/Fab.d.ts +8 -0
- package/dist/Fab.js +8 -0
- package/dist/Fab.js.map +1 -1
- package/dist/FormField.d.ts +25 -0
- package/dist/FormField.js +25 -0
- package/dist/FormField.js.map +1 -1
- package/dist/Img.d.ts +7 -0
- package/dist/Img.js +7 -0
- package/dist/Img.js.map +1 -1
- package/dist/InlineAlert.d.ts +7 -0
- package/dist/InlineAlert.js +7 -0
- package/dist/InlineAlert.js.map +1 -1
- package/dist/Layout.d.ts +7 -0
- package/dist/Layout.js +7 -0
- package/dist/Layout.js.map +1 -1
- package/dist/Link.d.ts +7 -0
- package/dist/Link.js +7 -0
- package/dist/Link.js.map +1 -1
- package/dist/ListItem.d.ts +15 -0
- package/dist/ListItem.js +15 -0
- package/dist/ListItem.js.map +1 -1
- package/dist/Menu.d.ts +28 -0
- package/dist/Menu.js +29 -1
- package/dist/Menu.js.map +1 -1
- package/dist/MenuButton.d.ts +7 -0
- package/dist/MenuButton.js +7 -0
- package/dist/MenuButton.js.map +1 -1
- package/dist/Modal.d.ts +23 -1
- package/dist/Modal.js +23 -1
- package/dist/Modal.js.map +1 -1
- package/dist/NumberField.d.ts +19 -0
- package/dist/NumberField.js +19 -0
- package/dist/NumberField.js.map +1 -1
- package/dist/NumberInput.d.ts +16 -0
- package/dist/NumberInput.js +16 -0
- package/dist/NumberInput.js.map +1 -1
- package/dist/Popover.d.ts +29 -2
- package/dist/Popover.js +30 -3
- package/dist/Popover.js.map +1 -1
- package/dist/ProgressBar.d.ts +8 -0
- package/dist/ProgressBar.js +9 -1
- package/dist/ProgressBar.js.map +1 -1
- package/dist/ProgressCircle.d.ts +8 -0
- package/dist/ProgressCircle.js +8 -0
- package/dist/ProgressCircle.js.map +1 -1
- package/dist/ProgressionStepper.d.ts +12 -0
- package/dist/ProgressionStepper.js +12 -0
- package/dist/ProgressionStepper.js.map +1 -1
- package/dist/RadioGroup.d.ts +38 -6
- package/dist/RadioGroup.js +34 -5
- package/dist/RadioGroup.js.map +1 -1
- package/dist/RadioOption.d.ts +3 -1
- package/dist/RadioOption.js +5 -2
- package/dist/RadioOption.js.map +1 -1
- package/dist/SearchBar.d.ts +41 -3
- package/dist/SearchBar.js +34 -0
- package/dist/SearchBar.js.map +1 -1
- package/dist/SegmentedControl.d.ts +35 -8
- package/dist/SegmentedControl.js +24 -2
- package/dist/SegmentedControl.js.map +1 -1
- package/dist/Skeleton.d.ts +3 -1
- package/dist/Skeleton.js +3 -1
- package/dist/Skeleton.js.map +1 -1
- package/dist/Switch.d.ts +18 -1
- package/dist/Switch.js +18 -1
- package/dist/Switch.js.map +1 -1
- package/dist/SwitchOption.d.ts +4 -2
- package/dist/SwitchOption.js +5 -2
- package/dist/SwitchOption.js.map +1 -1
- package/dist/TabGroup.d.ts +26 -5
- package/dist/TabGroup.js +20 -0
- package/dist/TabGroup.js.map +1 -1
- package/dist/Tag.d.ts +13 -1
- package/dist/Tag.js +13 -1
- package/dist/Tag.js.map +1 -1
- package/dist/TextField.d.ts +21 -2
- package/dist/TextField.js +22 -2
- package/dist/TextField.js.map +1 -1
- package/dist/TextInput.d.ts +22 -3
- package/dist/TextInput.js +20 -2
- package/dist/TextInput.js.map +1 -1
- package/dist/Textarea.d.ts +23 -4
- package/dist/Textarea.js +27 -7
- package/dist/Textarea.js.map +1 -1
- package/dist/TextareaField.d.ts +21 -1
- package/dist/TextareaField.js +24 -2
- package/dist/TextareaField.js.map +1 -1
- package/dist/ToggleOption.d.ts +8 -5
- package/dist/ToggleOption.js +3 -3
- package/dist/ToggleOption.js.map +1 -1
- package/dist/Tooltip.d.ts +15 -3
- package/dist/Tooltip.js +20 -3
- package/dist/Tooltip.js.map +1 -1
- package/dist/Txt.d.ts +9 -1
- package/dist/Txt.js +9 -1
- package/dist/Txt.js.map +1 -1
- package/dist/badge.css +1 -1
- package/dist/demo/examples.js +3 -0
- package/dist/demo/examples.js.map +1 -1
- package/dist/progress-bar.css +1 -1
- package/dist/radio-group.css +1 -0
- package/dist/textarea.css +1 -1
- package/dist/toggle-option.css +1 -1
- package/meta.ts +8 -6
- package/package.json +1 -1
- package/src/Avatar.tsx +18 -2
- package/src/AvatarGroup.tsx +14 -0
- package/src/Badge.tsx +30 -4
- package/src/BannerAlert.tsx +17 -0
- package/src/Button.tsx +16 -0
- package/src/Card.tsx +12 -0
- package/src/Checkbox.tsx +21 -0
- package/src/CheckboxGroup.tsx +30 -0
- package/src/CheckboxOption.tsx +29 -4
- package/src/Chip.tsx +11 -0
- package/src/Dialog.tsx +19 -0
- package/src/Divider.tsx +13 -0
- package/src/Dropdown.tsx +30 -0
- package/src/DropdownField.tsx +22 -0
- package/src/EmptyState.tsx +11 -0
- package/src/Fab.tsx +8 -0
- package/src/FormField.tsx +25 -0
- package/src/Img.tsx +7 -0
- package/src/InlineAlert.tsx +7 -0
- package/src/Layout.tsx +7 -0
- package/src/Link.tsx +7 -0
- package/src/ListItem.tsx +15 -0
- package/src/Menu.tsx +29 -0
- package/src/MenuButton.tsx +7 -0
- package/src/Modal.tsx +23 -1
- package/src/NumberField.tsx +19 -0
- package/src/NumberInput.tsx +16 -0
- package/src/Popover.tsx +53 -5
- package/src/ProgressBar.tsx +8 -0
- package/src/ProgressCircle.tsx +8 -0
- package/src/ProgressionStepper.tsx +12 -0
- package/src/RadioGroup.tsx +68 -25
- package/src/RadioOption.tsx +9 -4
- package/src/SearchBar.tsx +54 -6
- package/src/SegmentedControl.tsx +57 -14
- package/src/Skeleton.tsx +3 -1
- package/src/Switch.tsx +18 -1
- package/src/SwitchOption.tsx +11 -6
- package/src/TabGroup.tsx +30 -6
- package/src/Tag.tsx +13 -1
- package/src/TextField.tsx +37 -6
- package/src/TextInput.tsx +36 -5
- package/src/Textarea.tsx +41 -9
- package/src/TextareaField.tsx +33 -4
- package/src/ToggleOption.tsx +9 -6
- package/src/Tooltip.tsx +29 -5
- package/src/Txt.tsx +14 -2
- package/src/badge.scss +17 -4
- package/src/demo/examples.tsx +3 -0
- package/src/progress-bar.scss +0 -2
- package/src/radio-group.scss +5 -0
- package/src/textarea.scss +4 -0
- package/src/toggle-option.scss +1 -20
- package/dist/SwitchGroup.d.ts +0 -42
- package/dist/SwitchGroup.js +0 -16
- package/dist/SwitchGroup.js.map +0 -1
- package/dist/hooks/useSwitchGroupState.d.ts +0 -37
- package/dist/hooks/useSwitchGroupState.js +0 -57
- package/dist/hooks/useSwitchGroupState.js.map +0 -1
- package/src/SwitchGroup.tsx +0 -72
- package/src/hooks/useSwitchGroupState.ts +0 -75
package/src/SegmentedControl.tsx
CHANGED
|
@@ -8,18 +8,23 @@ import { ElementProps } from './';
|
|
|
8
8
|
|
|
9
9
|
export type SegmentedControlOption = {
|
|
10
10
|
/**
|
|
11
|
-
* The label of the option. This is the text that will be displayed on the
|
|
11
|
+
* The label of the option. This is the text that will be displayed on the
|
|
12
|
+
* option.
|
|
12
13
|
*
|
|
13
14
|
* @required
|
|
14
15
|
*/
|
|
15
16
|
label: string;
|
|
16
17
|
/**
|
|
17
|
-
* Determines if the element is
|
|
18
|
+
* Determines if the element is
|
|
19
|
+
* [disabled](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled).
|
|
18
20
|
*
|
|
19
21
|
* @default false
|
|
20
22
|
*/
|
|
21
23
|
disabled?: boolean;
|
|
22
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The value of the option. If not provided, the label will be used as the
|
|
26
|
+
* value.
|
|
27
|
+
*/
|
|
23
28
|
value?: string;
|
|
24
29
|
/**
|
|
25
30
|
* The the icon to display before the label.
|
|
@@ -37,7 +42,8 @@ export type SegmentedControlOption = {
|
|
|
37
42
|
|
|
38
43
|
export type SegmentedControlProps = {
|
|
39
44
|
/**
|
|
40
|
-
* The options to display. Each option has a label and an optional leading
|
|
45
|
+
* The options to display. Each option has a label and an optional leading
|
|
46
|
+
* icon.
|
|
41
47
|
*
|
|
42
48
|
* @example
|
|
43
49
|
* [
|
|
@@ -72,15 +78,16 @@ export type SegmentedControlProps = {
|
|
|
72
78
|
*/
|
|
73
79
|
size?: 'medium' | 'small';
|
|
74
80
|
/**
|
|
75
|
-
* The width of the options. If set to 'fill', the options will fill the
|
|
76
|
-
* the options will be as wide as
|
|
81
|
+
* The width of the options. If set to 'fill', the options will fill the
|
|
82
|
+
* width of the container. If set to 'hug', the options will be as wide as
|
|
83
|
+
* their content.
|
|
77
84
|
*
|
|
78
85
|
* @default hug
|
|
79
86
|
*/
|
|
80
87
|
width?: 'fill' | 'hug';
|
|
81
88
|
/**
|
|
82
|
-
* Determines if the labels of the options should be displayed. If icons are
|
|
83
|
-
* ignored and labels are shown.
|
|
89
|
+
* Determines if the labels of the options should be displayed. If icons are
|
|
90
|
+
* not provided for every option this is ignored and labels are shown.
|
|
84
91
|
*
|
|
85
92
|
* @default true
|
|
86
93
|
*/
|
|
@@ -90,6 +97,26 @@ export type SegmentedControlProps = {
|
|
|
90
97
|
/**
|
|
91
98
|
* Navigation tool that organizes content across different screens and views.
|
|
92
99
|
*
|
|
100
|
+
* @example
|
|
101
|
+
* import { useState } from 'react';
|
|
102
|
+
* import { SegmentedControl } from '@bspk/ui/SegmentedControl';
|
|
103
|
+
*
|
|
104
|
+
* export function Example() {
|
|
105
|
+
* const [selectedOption, setSelectedOption] = useState<string>();
|
|
106
|
+
*
|
|
107
|
+
* return (
|
|
108
|
+
* <SegmentedControl
|
|
109
|
+
* onChange={setSelectedOption}
|
|
110
|
+
* options={[
|
|
111
|
+
* { value: '1', label: 'Option 1' },
|
|
112
|
+
* { value: '2', label: 'Option 2' },
|
|
113
|
+
* { value: '3', label: 'Option 3' },
|
|
114
|
+
* ]}
|
|
115
|
+
* value={selectedOption}
|
|
116
|
+
* />
|
|
117
|
+
* );
|
|
118
|
+
* }
|
|
119
|
+
*
|
|
93
120
|
* @name SegmentedControl
|
|
94
121
|
*/
|
|
95
122
|
function SegmentedControl({
|
|
@@ -104,26 +131,42 @@ function SegmentedControl({
|
|
|
104
131
|
const options = Array.isArray(optionsProp) ? optionsProp : [];
|
|
105
132
|
useOptionIconsInvalid(options);
|
|
106
133
|
|
|
107
|
-
const hideLabels =
|
|
134
|
+
const hideLabels =
|
|
135
|
+
showLabelsProp === false &&
|
|
136
|
+
options.every((item) => item.icon && item.label);
|
|
108
137
|
|
|
109
138
|
return (
|
|
110
|
-
<div
|
|
139
|
+
<div
|
|
140
|
+
{...containerProps}
|
|
141
|
+
data-bspk="segmented-control"
|
|
142
|
+
data-size={size}
|
|
143
|
+
data-width={width}
|
|
144
|
+
>
|
|
111
145
|
{options.map((item, index) => {
|
|
112
146
|
const isActive = item.value === value;
|
|
113
147
|
return (
|
|
114
148
|
<Fragment key={item.value}>
|
|
115
|
-
<Tooltip
|
|
149
|
+
<Tooltip
|
|
150
|
+
disabled={!hideLabels}
|
|
151
|
+
label={item.label}
|
|
152
|
+
placement="top"
|
|
153
|
+
>
|
|
116
154
|
<button
|
|
117
155
|
aria-label={item.label}
|
|
118
156
|
data-first={index === 0 || undefined}
|
|
119
|
-
data-last={
|
|
157
|
+
data-last={
|
|
158
|
+
index === options.length - 1 || undefined
|
|
159
|
+
}
|
|
120
160
|
data-selected={isActive || undefined}
|
|
121
161
|
disabled={item.disabled || undefined}
|
|
122
|
-
onClick={() =>
|
|
162
|
+
onClick={() =>
|
|
163
|
+
onChange(item.value || item.label)
|
|
164
|
+
}
|
|
123
165
|
>
|
|
124
166
|
<span data-outer>
|
|
125
167
|
<span data-inner>
|
|
126
|
-
{(isActive && item.iconActive) ||
|
|
168
|
+
{(isActive && item.iconActive) ||
|
|
169
|
+
item.icon}
|
|
127
170
|
{!hideLabels && item.label}
|
|
128
171
|
</span>
|
|
129
172
|
</span>
|
package/src/Skeleton.tsx
CHANGED
|
@@ -44,7 +44,9 @@ export type SkeletonProps = {
|
|
|
44
44
|
* displayed on the screen.
|
|
45
45
|
*
|
|
46
46
|
* @example
|
|
47
|
-
*
|
|
47
|
+
* import { Skeleton } from '@bspk/ui/skeleton';
|
|
48
|
+
*
|
|
49
|
+
* function Example(item: { title: string; src: string } | null) {
|
|
48
50
|
* return item ? (
|
|
49
51
|
* <img
|
|
50
52
|
* style={{
|
package/src/Switch.tsx
CHANGED
|
@@ -22,7 +22,24 @@ export type SwitchProps = CommonProps<'aria-label' | 'disabled' | 'name' | 'valu
|
|
|
22
22
|
/**
|
|
23
23
|
* A control element that allows users to toggle between two states, typically representing on/off and inherits
|
|
24
24
|
* immediate reaction in each state. This is the base element and if used directly you must wrap it with a label. This
|
|
25
|
-
* will more often be used in the SwitchOption
|
|
25
|
+
* will more often be used in the SwitchOption component.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* import { useState } from 'react';
|
|
29
|
+
* import { Switch } from '@bspk/ui/Switch';
|
|
30
|
+
*
|
|
31
|
+
* export function Example() {
|
|
32
|
+
* const [isChecked, setIsChecked] = useState<boolean>(false);
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <Switch
|
|
36
|
+
* aria-label="Example aria-label"
|
|
37
|
+
* name="Example name"
|
|
38
|
+
* onChange={setIsChecked}
|
|
39
|
+
* checked={isChecked}
|
|
40
|
+
* />
|
|
41
|
+
* );
|
|
42
|
+
* }
|
|
26
43
|
*
|
|
27
44
|
* @element
|
|
28
45
|
*
|
package/src/SwitchOption.tsx
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { SwitchProps, Switch } from './Switch';
|
|
2
2
|
import { ToggleOptionProps, ToggleOption } from './ToggleOption';
|
|
3
3
|
|
|
4
|
-
export type SwitchOptionProps = Omit<SwitchProps, 'aria-label'> &
|
|
5
|
-
Pick<ToggleOptionProps, 'description' | 'label' | 'size'>;
|
|
4
|
+
export type SwitchOptionProps = Omit<SwitchProps, 'aria-label'> & Pick<ToggleOptionProps, 'description' | 'label'>;
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* A control that allows users to choose one or more items from a list or turn an feature on or off.
|
|
9
8
|
*
|
|
9
|
+
* If only a switch is needed, consider using the `Switch` component directly.
|
|
10
|
+
*
|
|
10
11
|
* @name SwitchOption
|
|
11
12
|
*/
|
|
12
|
-
function SwitchOption({ label, description,
|
|
13
|
+
function SwitchOption({ label: labelProp, description, ...checkboxProps }: SwitchOptionProps) {
|
|
14
|
+
const label = labelProp || description;
|
|
15
|
+
|
|
13
16
|
return (
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
+
label && (
|
|
18
|
+
<ToggleOption data-bspk="switch-option" description={description} label={label}>
|
|
19
|
+
<Switch {...checkboxProps} aria-label={label} />
|
|
20
|
+
</ToggleOption>
|
|
21
|
+
)
|
|
17
22
|
);
|
|
18
23
|
}
|
|
19
24
|
|
package/src/TabGroup.tsx
CHANGED
|
@@ -22,7 +22,8 @@ export type TabGroupOption = {
|
|
|
22
22
|
*/
|
|
23
23
|
label: string;
|
|
24
24
|
/**
|
|
25
|
-
* Determines if the element is
|
|
25
|
+
* Determines if the element is
|
|
26
|
+
* [disabled](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled).
|
|
26
27
|
*
|
|
27
28
|
* @default false
|
|
28
29
|
*/
|
|
@@ -86,15 +87,15 @@ export type TabGroupProps = {
|
|
|
86
87
|
*/
|
|
87
88
|
size?: TabGroupSize;
|
|
88
89
|
/**
|
|
89
|
-
* When 'fill' the options will fill the width of the container. When 'hug',
|
|
90
|
-
* content.
|
|
90
|
+
* When 'fill' the options will fill the width of the container. When 'hug',
|
|
91
|
+
* the options will be as wide as their content.
|
|
91
92
|
*
|
|
92
93
|
* @default hug
|
|
93
94
|
*/
|
|
94
95
|
width?: 'fill' | 'hug';
|
|
95
96
|
/**
|
|
96
|
-
* When width is 'hug' this determines if the trailing underline should be
|
|
97
|
-
* property isn't applicable.
|
|
97
|
+
* When width is 'hug' this determines if the trailing underline should be
|
|
98
|
+
* showing. When width is 'fill' this property isn't applicable.
|
|
98
99
|
*
|
|
99
100
|
* @default false
|
|
100
101
|
*/
|
|
@@ -104,6 +105,26 @@ export type TabGroupProps = {
|
|
|
104
105
|
/**
|
|
105
106
|
* Navigation tool that organizes content across different screens and views.
|
|
106
107
|
*
|
|
108
|
+
* @example
|
|
109
|
+
* import { useState } from 'react';
|
|
110
|
+
* import { TabGroup } from '@bspk/ui/TabGroup';
|
|
111
|
+
*
|
|
112
|
+
* export function Example() {
|
|
113
|
+
* const [selectedTab, setSelectedTab] = useState<string>();
|
|
114
|
+
*
|
|
115
|
+
* return (
|
|
116
|
+
* <TabGroup
|
|
117
|
+
* onChange={setSelectedTab}
|
|
118
|
+
* options={[
|
|
119
|
+
* { value: '1', label: 'Option 1' },
|
|
120
|
+
* { value: '2', label: 'Option 2' },
|
|
121
|
+
* { value: '3', label: 'Option 3' },
|
|
122
|
+
* ]}
|
|
123
|
+
* value={selectedTab}
|
|
124
|
+
* />
|
|
125
|
+
* );
|
|
126
|
+
* }
|
|
127
|
+
*
|
|
107
128
|
* @name TabGroup
|
|
108
129
|
*/
|
|
109
130
|
function TabGroup({
|
|
@@ -143,7 +164,10 @@ function TabGroup({
|
|
|
143
164
|
{(isActive && item.iconActive) || item.icon}
|
|
144
165
|
{item.label}
|
|
145
166
|
{item.badge && !item.disabled && !isActive && (
|
|
146
|
-
<Badge
|
|
167
|
+
<Badge
|
|
168
|
+
count={item.badge}
|
|
169
|
+
size={TAB_BADGE_SIZES[size]}
|
|
170
|
+
/>
|
|
147
171
|
)}
|
|
148
172
|
</span>
|
|
149
173
|
</button>
|
package/src/Tag.tsx
CHANGED
|
@@ -51,7 +51,19 @@ export type TagProps<As extends ElementType = 'span'> = {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
* A non-interactive visual indicators to draw attention or categorization of a
|
|
54
|
+
* A non-interactive visual indicators to draw attention or categorization of a
|
|
55
|
+
* component.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* import { Tag } from '@bspk/ui/Tag';
|
|
59
|
+
*
|
|
60
|
+
* export function Example() {
|
|
61
|
+
* return (
|
|
62
|
+
* <Tag variant="flat" color="primary">
|
|
63
|
+
* Example Tag
|
|
64
|
+
* </Tag>
|
|
65
|
+
* );
|
|
66
|
+
* }
|
|
55
67
|
*
|
|
56
68
|
* @name Tag
|
|
57
69
|
*/
|
package/src/TextField.tsx
CHANGED
|
@@ -3,7 +3,12 @@ import { TextInputProps, TextInput } from './TextInput';
|
|
|
3
3
|
|
|
4
4
|
import { InvalidPropsLibrary } from '.';
|
|
5
5
|
|
|
6
|
-
export type TextFieldProps =
|
|
6
|
+
export type TextFieldProps =
|
|
7
|
+
InvalidPropsLibrary &
|
|
8
|
+
Pick<
|
|
9
|
+
FormFieldProps,
|
|
10
|
+
'controlId' | 'errorMessage' | 'helperText' | 'label' | 'labelTrailing'
|
|
11
|
+
> &
|
|
7
12
|
Pick<
|
|
8
13
|
TextInputProps,
|
|
9
14
|
| 'autoComplete'
|
|
@@ -19,14 +24,32 @@ export type TextFieldProps = InvalidPropsLibrary &
|
|
|
19
24
|
| 'trailing'
|
|
20
25
|
| 'type'
|
|
21
26
|
| 'value'
|
|
22
|
-
|
|
23
|
-
Pick<FormFieldProps, 'controlId' | 'errorMessage' | 'helperText' | 'label' | 'labelTrailing'>;
|
|
27
|
+
>;
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
|
-
* A text input that allows users to enter text, numbers or symbols in a
|
|
30
|
+
* A text input that allows users to enter text, numbers or symbols in a
|
|
31
|
+
* singular line.
|
|
27
32
|
*
|
|
28
33
|
* This component takes properties from the FormField and TextInput components.
|
|
29
34
|
*
|
|
35
|
+
* @example
|
|
36
|
+
* import { useState } from 'react';
|
|
37
|
+
* import { TextField } from '@bspk/ui/TextField';
|
|
38
|
+
*
|
|
39
|
+
* export function Example() {
|
|
40
|
+
* const [value, setValue] = useState<string>('');
|
|
41
|
+
*
|
|
42
|
+
* return (
|
|
43
|
+
* <TextField
|
|
44
|
+
* controlId="Example controlId"
|
|
45
|
+
* label="Example label"
|
|
46
|
+
* name="Example name"
|
|
47
|
+
* onChange={setValue}
|
|
48
|
+
* value={value}
|
|
49
|
+
* />
|
|
50
|
+
* );
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
30
53
|
* @name TextField
|
|
31
54
|
*/
|
|
32
55
|
function TextField({
|
|
@@ -38,7 +61,9 @@ function TextField({
|
|
|
38
61
|
required,
|
|
39
62
|
...inputProps
|
|
40
63
|
}: TextFieldProps) {
|
|
41
|
-
const errorMessage =
|
|
64
|
+
const errorMessage =
|
|
65
|
+
(!inputProps.readOnly && !inputProps.disabled && errorMessageProp) ||
|
|
66
|
+
undefined;
|
|
42
67
|
|
|
43
68
|
return (
|
|
44
69
|
<FormField
|
|
@@ -51,7 +76,13 @@ function TextField({
|
|
|
51
76
|
required={required}
|
|
52
77
|
>
|
|
53
78
|
{(fieldProps) => (
|
|
54
|
-
<TextInput
|
|
79
|
+
<TextInput
|
|
80
|
+
{...inputProps}
|
|
81
|
+
{...fieldProps}
|
|
82
|
+
aria-label={label}
|
|
83
|
+
id={controlId}
|
|
84
|
+
required={required}
|
|
85
|
+
/>
|
|
55
86
|
)}
|
|
56
87
|
</FormField>
|
|
57
88
|
);
|
package/src/TextInput.tsx
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { SvgCancel } from '@bspk/icons/Cancel';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ChangeEvent,
|
|
4
|
+
HTMLInputAutoCompleteAttribute,
|
|
5
|
+
HTMLInputTypeAttribute,
|
|
6
|
+
ReactNode,
|
|
7
|
+
} from 'react';
|
|
3
8
|
|
|
4
9
|
import { useId } from './hooks/useId';
|
|
5
10
|
|
|
@@ -15,7 +20,14 @@ export const DEFAULT = {
|
|
|
15
20
|
} as const;
|
|
16
21
|
|
|
17
22
|
export type TextInputProps = CommonProps<
|
|
18
|
-
'aria-label'
|
|
23
|
+
| 'aria-label'
|
|
24
|
+
| 'disabled'
|
|
25
|
+
| 'id'
|
|
26
|
+
| 'name'
|
|
27
|
+
| 'readOnly'
|
|
28
|
+
| 'required'
|
|
29
|
+
| 'size'
|
|
30
|
+
| 'value'
|
|
19
31
|
> &
|
|
20
32
|
InvalidPropsLibrary & {
|
|
21
33
|
/**
|
|
@@ -41,7 +53,8 @@ export type TextInputProps = CommonProps<
|
|
|
41
53
|
*/
|
|
42
54
|
type?: Extract<HTMLInputTypeAttribute, 'number' | 'text'>;
|
|
43
55
|
/**
|
|
44
|
-
* Specifies if user agent has any permission to provide automated
|
|
56
|
+
* Specifies if user agent has any permission to provide automated
|
|
57
|
+
* assistance in filling out form field values.
|
|
45
58
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
|
|
46
59
|
*
|
|
47
60
|
* @default off
|
|
@@ -50,8 +63,26 @@ export type TextInputProps = CommonProps<
|
|
|
50
63
|
};
|
|
51
64
|
|
|
52
65
|
/**
|
|
53
|
-
* A text input that allows users to enter text, numbers or symbols in a
|
|
54
|
-
* not intended to be used
|
|
66
|
+
* A text input that allows users to enter text, numbers or symbols in a
|
|
67
|
+
* singular line. This is the base element and is not intended to be used
|
|
68
|
+
* directly. Use the TextField component.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* import { useState } from 'react';
|
|
72
|
+
* import { TextInput } from '@bspk/ui/TextInput';
|
|
73
|
+
*
|
|
74
|
+
* export function Example() {
|
|
75
|
+
* const [value, setValue] = useState<string>('');
|
|
76
|
+
*
|
|
77
|
+
* return (
|
|
78
|
+
* <TextInput
|
|
79
|
+
* aria-label="Example aria-label"
|
|
80
|
+
* name="Example name"
|
|
81
|
+
* onChange={setValue}
|
|
82
|
+
* value={value}
|
|
83
|
+
* />
|
|
84
|
+
* );
|
|
85
|
+
* }
|
|
55
86
|
*
|
|
56
87
|
* @element
|
|
57
88
|
*
|
package/src/Textarea.tsx
CHANGED
|
@@ -11,7 +11,9 @@ const DEFAULT = {
|
|
|
11
11
|
textSize: 'medium',
|
|
12
12
|
} as const;
|
|
13
13
|
|
|
14
|
-
export type TextareaProps = CommonProps<
|
|
14
|
+
export type TextareaProps = CommonProps<
|
|
15
|
+
'aria-label' | 'disabled' | 'id' | 'readOnly' | 'required'
|
|
16
|
+
> &
|
|
15
17
|
InvalidPropsLibrary & {
|
|
16
18
|
/**
|
|
17
19
|
* Callback when the value of the field changes.
|
|
@@ -19,7 +21,10 @@ export type TextareaProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'read
|
|
|
19
21
|
* @type (next: String, Event) => void
|
|
20
22
|
* @required
|
|
21
23
|
*/
|
|
22
|
-
onChange: (
|
|
24
|
+
onChange: (
|
|
25
|
+
next: string,
|
|
26
|
+
event?: ChangeEvent<HTMLTextAreaElement>,
|
|
27
|
+
) => void;
|
|
23
28
|
/**
|
|
24
29
|
* The text size of the field.
|
|
25
30
|
*
|
|
@@ -67,11 +72,30 @@ export type TextareaProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'read
|
|
|
67
72
|
};
|
|
68
73
|
|
|
69
74
|
/**
|
|
70
|
-
* A component that allows users to input large amounts of text that could span
|
|
75
|
+
* A component that allows users to input large amounts of text that could span
|
|
76
|
+
* multiple lines.
|
|
71
77
|
*
|
|
72
|
-
* This component gives you a textarea HTML element that automatically adjusts
|
|
73
|
-
*
|
|
74
|
-
*
|
|
78
|
+
* This component gives you a textarea HTML element that automatically adjusts
|
|
79
|
+
* its height to match the length of the content within maximum and minimum
|
|
80
|
+
* rows. A character counter when a maxLength is set to show the number of
|
|
81
|
+
* characters remaining below the limit.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* import { useState } from 'react';
|
|
85
|
+
* import { Textarea } from '@bspk/ui/Textarea';
|
|
86
|
+
*
|
|
87
|
+
* export function Example() {
|
|
88
|
+
* const [value, setValue] = useState<string>('');
|
|
89
|
+
*
|
|
90
|
+
* return (
|
|
91
|
+
* <Textarea
|
|
92
|
+
* aria-label="Example aria-label"
|
|
93
|
+
* name="Example name"
|
|
94
|
+
* onChange={setValue}
|
|
95
|
+
* value={value}
|
|
96
|
+
* />
|
|
97
|
+
* );
|
|
98
|
+
* }
|
|
75
99
|
*
|
|
76
100
|
* @element
|
|
77
101
|
*
|
|
@@ -95,8 +119,14 @@ function Textarea({
|
|
|
95
119
|
const id = useId(idProp);
|
|
96
120
|
const invalid = !otherProps.readOnly && !otherProps.disabled && invalidProp;
|
|
97
121
|
// ensure minRows and maxRows are within bounds
|
|
98
|
-
const minRows = Math.min(
|
|
99
|
-
|
|
122
|
+
const minRows = Math.min(
|
|
123
|
+
DEFAULT.maxRows,
|
|
124
|
+
Math.max(minRowsProp, DEFAULT.minRows),
|
|
125
|
+
);
|
|
126
|
+
const maxRows = Math.max(
|
|
127
|
+
DEFAULT.minRows,
|
|
128
|
+
Math.min(maxRowsProp, DEFAULT.maxRows),
|
|
129
|
+
);
|
|
100
130
|
|
|
101
131
|
return (
|
|
102
132
|
<div
|
|
@@ -125,11 +155,13 @@ function Textarea({
|
|
|
125
155
|
const target = event.target as HTMLTextAreaElement;
|
|
126
156
|
// we know the textarea was resized, so we don't want to auto-size it
|
|
127
157
|
if (target.style.height) return;
|
|
128
|
-
(target.nextSibling as HTMLElement).innerText =
|
|
158
|
+
(target.nextSibling as HTMLElement).innerText =
|
|
159
|
+
`${target.value}\n`;
|
|
129
160
|
}}
|
|
130
161
|
placeholder={placeholder}
|
|
131
162
|
ref={innerRef}
|
|
132
163
|
value={value}
|
|
164
|
+
wrap="hard"
|
|
133
165
|
/>
|
|
134
166
|
<div aria-hidden data-replicated-value />
|
|
135
167
|
</div>
|
package/src/TextareaField.tsx
CHANGED
|
@@ -3,13 +3,36 @@ import { TextareaProps, Textarea } from './Textarea';
|
|
|
3
3
|
import { Txt } from './Txt';
|
|
4
4
|
import { tryIntParse } from './utils/tryIntPsrse';
|
|
5
5
|
|
|
6
|
-
export type TextareaFieldProps = Pick<
|
|
6
|
+
export type TextareaFieldProps = Pick<
|
|
7
|
+
FormFieldProps,
|
|
8
|
+
'controlId' | 'errorMessage' | 'helperText' | 'label'
|
|
9
|
+
> &
|
|
7
10
|
TextareaProps;
|
|
8
11
|
/**
|
|
9
|
-
* A component that allows users to input large amounts of text that could span
|
|
12
|
+
* A component that allows users to input large amounts of text that could span
|
|
13
|
+
* multiple lines.
|
|
10
14
|
*
|
|
11
15
|
* This component takes properties from the FormField and Textarea components.
|
|
12
16
|
*
|
|
17
|
+
* @example
|
|
18
|
+
* import { useState } from 'react';
|
|
19
|
+
* import { TextareaField } from '@bspk/ui/TextareaField';
|
|
20
|
+
*
|
|
21
|
+
* export function Example() {
|
|
22
|
+
* const [value, setValue] = useState<string>();
|
|
23
|
+
*
|
|
24
|
+
* return (
|
|
25
|
+
* <TextareaField
|
|
26
|
+
* aria-label="Example aria-label"
|
|
27
|
+
* controlId="Example controlId"
|
|
28
|
+
* label="Example label"
|
|
29
|
+
* name="Example name"
|
|
30
|
+
* onChange={setValue}
|
|
31
|
+
* value={value}
|
|
32
|
+
* />
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
13
36
|
* @name TextareaField
|
|
14
37
|
*/
|
|
15
38
|
function TextareaField({
|
|
@@ -26,7 +49,8 @@ function TextareaField({
|
|
|
26
49
|
...textareaProps
|
|
27
50
|
}: TextareaFieldProps) {
|
|
28
51
|
const maxLength = tryIntParse(maxLengthProp) || -1;
|
|
29
|
-
const errorMessage =
|
|
52
|
+
const errorMessage =
|
|
53
|
+
(!readOnly && !disabled && errorMessageProp) || undefined;
|
|
30
54
|
|
|
31
55
|
if (typeof onChange !== 'function') return null;
|
|
32
56
|
|
|
@@ -38,7 +62,12 @@ function TextareaField({
|
|
|
38
62
|
helperText={helperText}
|
|
39
63
|
label={label}
|
|
40
64
|
labelTrailing={
|
|
41
|
-
<Txt
|
|
65
|
+
<Txt
|
|
66
|
+
style={{
|
|
67
|
+
color: 'var(--foreground-neutral-on-surface-variant-02)',
|
|
68
|
+
}}
|
|
69
|
+
variant="body-small"
|
|
70
|
+
>
|
|
42
71
|
{`${textareaProps?.value?.length || 0}${maxLength > 0 ? `/${maxLength}` : ''}`}
|
|
43
72
|
</Txt>
|
|
44
73
|
}
|
package/src/ToggleOption.tsx
CHANGED
|
@@ -3,17 +3,20 @@ import { ReactElement } from 'react';
|
|
|
3
3
|
|
|
4
4
|
export type ToggleOptionProps = {
|
|
5
5
|
/**
|
|
6
|
-
* The label of the
|
|
6
|
+
* The label of the option. Also used as the aria-label of the checkbox.
|
|
7
7
|
*
|
|
8
8
|
* @required
|
|
9
9
|
*/
|
|
10
10
|
label: string;
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* The description of the option.
|
|
13
|
+
*
|
|
14
|
+
* @type multiline
|
|
15
|
+
* @type multiline
|
|
16
|
+
*/
|
|
12
17
|
description?: string;
|
|
13
18
|
/** The control element to use. */
|
|
14
19
|
children?: ReactElement;
|
|
15
|
-
/** The size of the control option label. */
|
|
16
|
-
size?: 'base' | 'large' | 'small';
|
|
17
20
|
};
|
|
18
21
|
|
|
19
22
|
/**
|
|
@@ -21,9 +24,9 @@ export type ToggleOptionProps = {
|
|
|
21
24
|
*
|
|
22
25
|
* @name ToggleOption
|
|
23
26
|
*/
|
|
24
|
-
function ToggleOption({ label, description, children
|
|
27
|
+
function ToggleOption({ label, description, children }: ToggleOptionProps) {
|
|
25
28
|
return (
|
|
26
|
-
<label data-bspk="toggle-option"
|
|
29
|
+
<label data-bspk="toggle-option">
|
|
27
30
|
<span data-control>{children}</span>
|
|
28
31
|
<span data-content>
|
|
29
32
|
<span data-label>{label}</span>
|