@bspk/ui 1.1.13 → 1.1.15
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/Checkbox.d.ts +1 -1
- package/dist/Checkbox.js +2 -2
- package/dist/Checkbox.js.map +1 -1
- package/dist/CheckboxOption.d.ts +2 -1
- package/dist/Dropdown.d.ts +3 -3
- package/dist/Dropdown.js +2 -1
- package/dist/Dropdown.js.map +1 -1
- package/dist/FormField.d.ts +5 -4
- package/dist/FormField.js +3 -3
- package/dist/FormField.js.map +1 -1
- package/dist/InlineAlert.js +1 -1
- package/dist/Link.d.ts +2 -1
- package/dist/Link.js.map +1 -1
- package/dist/ListItem.d.ts +1 -1
- package/dist/ListItem.js +2 -2
- package/dist/ListItem.js.map +1 -1
- package/dist/NumberField.d.ts +2 -1
- package/dist/NumberInput.d.ts +23 -13
- package/dist/NumberInput.js +15 -4
- package/dist/NumberInput.js.map +1 -1
- package/dist/Radio.d.ts +2 -2
- package/dist/Radio.js.map +1 -1
- package/dist/RadioOption.d.ts +2 -1
- package/dist/RadioOption.js.map +1 -1
- package/dist/SegmentedControl.d.ts +11 -7
- package/dist/SegmentedControl.js +7 -6
- package/dist/SegmentedControl.js.map +1 -1
- package/dist/StylesProviderAnywhere.js +1 -1
- package/dist/StylesProviderBetterHomesGardens.js +1 -1
- package/dist/StylesProviderCartus.js +1 -1
- package/dist/StylesProviderCentury21.js +1 -1
- package/dist/StylesProviderColdwellBanker.js +1 -1
- package/dist/StylesProviderCorcoran.js +1 -1
- package/dist/StylesProviderDenaliBoss.js +1 -1
- package/dist/StylesProviderEra.js +1 -1
- package/dist/StylesProviderSothebys.js +1 -1
- package/dist/TabGroup.d.ts +15 -6
- package/dist/TabGroup.js +13 -5
- package/dist/TabGroup.js.map +1 -1
- package/dist/TextField.d.ts +2 -1
- package/dist/TextField.js.map +1 -1
- package/dist/TextInput.d.ts +3 -3
- package/dist/TextInput.js +2 -2
- package/dist/TextInput.js.map +1 -1
- package/dist/Textarea.d.ts +20 -10
- package/dist/Textarea.js +15 -8
- package/dist/Textarea.js.map +1 -1
- package/dist/base.css +1 -1
- package/dist/form-field.css +1 -1
- package/dist/hooks/useFloatingMenu.d.ts +3 -2
- package/dist/hooks/useFloatingMenu.js +1 -0
- package/dist/hooks/useFloatingMenu.js.map +1 -1
- package/dist/hooks/{useNavOptions.d.ts → useOptionIconsInvalid.d.ts} +4 -5
- package/dist/hooks/useOptionIconsInvalid.js +21 -0
- package/dist/hooks/useOptionIconsInvalid.js.map +1 -0
- package/dist/index.d.ts +22 -13
- package/dist/index.js.map +1 -1
- package/dist/inline-alert.css +1 -1
- package/dist/number-input.css +1 -1
- package/dist/textarea.css +1 -1
- package/package.json +2 -2
- package/src/Checkbox.tsx +3 -0
- package/src/CheckboxOption.tsx +4 -4
- package/src/Dropdown.tsx +5 -2
- package/src/FormField.tsx +35 -24
- package/src/Link.tsx +28 -25
- package/src/ListItem.tsx +2 -0
- package/src/NumberField.tsx +5 -5
- package/src/NumberInput.tsx +51 -30
- package/src/Radio.tsx +3 -5
- package/src/RadioOption.tsx +4 -1
- package/src/SegmentedControl.tsx +18 -13
- package/src/TabGroup.tsx +33 -12
- package/src/TextField.tsx +19 -17
- package/src/TextInput.tsx +33 -30
- package/src/Textarea.tsx +72 -56
- package/src/base.scss +4 -3
- package/src/form-field.scss +2 -1
- package/src/hooks/useFloatingMenu.ts +4 -2
- package/src/hooks/useOptionIconsInvalid.ts +49 -0
- package/src/index.ts +24 -13
- package/src/inline-alert.scss +1 -1
- package/src/number-input.scss +6 -3
- package/src/textarea.scss +5 -2
- package/dist/hooks/useNavOptions.js +0 -43
- package/dist/hooks/useNavOptions.js.map +0 -1
- package/src/hooks/useNavOptions.ts +0 -76
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOptionIconsInvalid.js","sourceRoot":"","sources":["../../src/hooks/useOptionIconsInvalid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAsB,OAAwB;IAC/E,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC;IAEtC,OAAO,OAAO,CAAC,GAAG,EAAE;QAChB,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAErD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAEzG,QAAQ,CACJ,YAAY,EACZ,+FAA+F,CAClG,CAAC;QAEF,OAAO,YAAY,CAAC;IACxB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5B,CAAC;AAsBD,sDAAsD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type CallToActionButton = {
|
|
|
24
24
|
/** The size of the call to action button. */
|
|
25
25
|
size?: ButtonSize;
|
|
26
26
|
};
|
|
27
|
-
export type ToggleControlProps<T extends HTMLElement> = CommonProps<'aria-label' | 'disabled' | '
|
|
27
|
+
export type ToggleControlProps<T extends HTMLElement> = CommonProps<'aria-label' | 'disabled' | 'name', T> & InvalidPropsLibrary & Required<CommonProps<'value'>> & {
|
|
28
28
|
/**
|
|
29
29
|
* Marks the control as checked.
|
|
30
30
|
*
|
|
@@ -40,6 +40,27 @@ export type ToggleControlProps<T extends HTMLElement> = CommonProps<'aria-label'
|
|
|
40
40
|
onChange: (checked: boolean, event: ChangeEvent<T>) => void;
|
|
41
41
|
};
|
|
42
42
|
export type CommonProps<K extends keyof CommonPropsLibrary, T extends HTMLElement = HTMLElement> = Pick<CommonPropsLibrary<T>, K>;
|
|
43
|
+
/**
|
|
44
|
+
* The props that are common to input elements.
|
|
45
|
+
*
|
|
46
|
+
* If an element is invalid it must have an errorMessage.
|
|
47
|
+
*/
|
|
48
|
+
export type InvalidPropsLibrary = {
|
|
49
|
+
/**
|
|
50
|
+
* Marks the element as invalid and displays error state theme.
|
|
51
|
+
*
|
|
52
|
+
* If the errorMessage is empty the error state theme will not appear.
|
|
53
|
+
*
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
invalid?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Marks the element as invalid and displays error message.
|
|
59
|
+
*
|
|
60
|
+
* When an element is invalid it must display an error message explaining why it is invalid.
|
|
61
|
+
*/
|
|
62
|
+
errorMessage?: string;
|
|
63
|
+
};
|
|
43
64
|
export type CommonPropsLibrary<T extends HTMLElement = HTMLElement> = {
|
|
44
65
|
/** The id of the element. If not provided one will be generated. */
|
|
45
66
|
id?: string;
|
|
@@ -73,12 +94,6 @@ export type CommonPropsLibrary<T extends HTMLElement = HTMLElement> = {
|
|
|
73
94
|
* @default false
|
|
74
95
|
*/
|
|
75
96
|
disabled?: boolean;
|
|
76
|
-
/**
|
|
77
|
-
* Marks the element as invalid and displays error state theme.
|
|
78
|
-
*
|
|
79
|
-
* @default false
|
|
80
|
-
*/
|
|
81
|
-
invalid?: boolean;
|
|
82
97
|
/**
|
|
83
98
|
* Determines if the element is [readonly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly).
|
|
84
99
|
*
|
|
@@ -91,12 +106,6 @@ export type CommonPropsLibrary<T extends HTMLElement = HTMLElement> = {
|
|
|
91
106
|
* @required
|
|
92
107
|
*/
|
|
93
108
|
name: string;
|
|
94
|
-
/**
|
|
95
|
-
* Marks the element as invalid and displays error message.
|
|
96
|
-
*
|
|
97
|
-
* When an element is invalid it must display an error message explaining why it is invalid.
|
|
98
|
-
*/
|
|
99
|
-
errorMessage?: string;
|
|
100
109
|
/**
|
|
101
110
|
* The value of the control.
|
|
102
111
|
*
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0JH,MAAM,CAAC,MAAM,MAAM,GAAqC;IACpD,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;IACvC,EAAE,KAAK,EAAE,wBAAwB,EAAE,IAAI,EAAE,sBAAsB,EAAE;IACjE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;IACnC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE;IAC3C,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,EAAE;IACrD,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;IACvC,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE;IAC7C,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;IAC7B,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE;CAClC,CAAC;AAEX,sDAAsD"}
|
package/dist/inline-alert.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[data-bspk=inline-alert]{display:flex;align-items:start;justify-content:
|
|
1
|
+
[data-bspk=inline-alert]{display:flex;align-items:start;justify-content:start;flex-direction:row;gap:var(--spacing-sizing-02)}[data-bspk=inline-alert] [data-txt]{flex:1}[data-bspk=inline-alert][data-variant=error]{color:var(--status-error);--first-tone: var(--status-error);--second-tone: var(--status-on-information)}[data-bspk=inline-alert][data-variant=success]{color:var(--status-success);--first-tone: var(--status-success);--second-tone: var(--status-on-success)}[data-bspk=inline-alert][data-variant=warning]{color:var(--foreground-neutral-on-surface);--first-tone: var(--status-warning);--second-tone: var(--status-on-warning)}[data-bspk=inline-alert][data-variant=informational]{color:var(--status-information);--first-tone: var(--status-information);--second-tone: var(--status-on-information)}[data-bspk=inline-alert] svg{color:var(--first-tone);width:var(--spacing-sizing-05);height:var(--spacing-sizing-05)}[data-bspk=inline-alert] svg [data-second-tone]{fill:var(--second-tone)}
|
package/dist/number-input.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[data-bspk=number-input]{--font: var(--body-base);--height: var(--spacing-sizing-10);--svg-width: var(--spacing-sizing-05);--color: var(--foreground-neutral-on-surface);width:100%;display:flex;flex-flow:row nowrap;font:var(--font);height:var(--height);border:1px solid var(--stroke-neutral-base);border-radius:var(--radius-small);background:var(--surface-neutral-t1-base)}[data-bspk=number-input]:focus-within{border-color:var(--stroke-brand-primary)
|
|
1
|
+
[data-bspk=number-input]{--font: var(--body-base);--height: var(--spacing-sizing-10);--svg-width: var(--spacing-sizing-05);--color: var(--foreground-neutral-on-surface);width:100%;display:flex;flex-flow:row nowrap;font:var(--font);height:var(--height);border:1px solid var(--stroke-neutral-base);border-radius:var(--radius-small);background:var(--surface-neutral-t1-base);max-width:280px}[data-bspk=number-input]:focus-within{border-color:var(--stroke-brand-primary)}[data-bspk=number-input] [data-divider]{width:4px;border-right:1px solid var(--stroke-neutral-base);height:calc(var(--height) - 8px);margin:3px 0}[data-bspk=number-input] button{width:var(--height);height:var(--height);background:none;border:none;cursor:pointer;font:var(--font);flex-shrink:0;display:flex;justify-content:center;align-items:center;color:var(--color)}[data-bspk=number-input] button svg{width:var(--svg-width)}[data-bspk=number-input] button:disabled{cursor:not-allowed;color:var(--foreground-neutral-disabled-on-surface)}[data-bspk=number-input] input{color:var(--color);min-width:0;display:block;font:var(--font);text-align:center;padding:0 var(--spacing-sizing-03);background:rgba(0,0,0,0);border:none;flex-grow:1}[data-bspk=number-input] input:focus{outline:none}[data-bspk=number-input] input::-webkit-outer-spin-button,[data-bspk=number-input] input::-webkit-inner-spin-button{appearance:none;margin:0}[data-bspk=number-input] input[type=number]{appearance:textfield}[data-bspk=number-input]:not([data-disabled],[data-readonly]) input:hover,[data-bspk=number-input]:not([data-disabled],[data-readonly]) button:not(:disabled):hover{background-color:var(--interactions-hover-opacity)}[data-bspk=number-input]:not([data-disabled],[data-readonly]) input:active,[data-bspk=number-input]:not([data-disabled],[data-readonly]) button:not(:disabled):active{background-color:var(--interactions-press-opacity)}[data-bspk=number-input]:not([data-disabled],[data-readonly])[data-invalid]{border-color:var(--status-error);outline-color:var(--status-error)}[data-bspk=number-input][data-disabled],[data-bspk=number-input][data-readonly]{--color: var(--foreground-neutral-disabled-on-surface);border-color:var(--stroke-neutral-disabled-light);background:linear-gradient(var(--interactions-disabled-opacity), var(--interactions-disabled-opacity)),linear-gradient(var(--surface-neutral-t1-base), var(--surface-neutral-t1-base))}[data-bspk=number-input][data-disabled] [data-divider],[data-bspk=number-input][data-readonly] [data-divider]{border-color:var(--stroke-neutral-disabled-light)}[data-bspk=number-input][data-readonly] input{color:var(--foreground-neutral-on-surface) !important}[data-bspk=number-input][data-size=small]{--font: var(--body-small);--height: var(--spacing-sizing-08)}[data-bspk=number-input][data-size=large]{--font: var(--body-large);--height: var(--spacing-sizing-12);--svg-width: var(--spacing-sizing-06)}
|
package/dist/textarea.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[data-bspk=textarea]{/*!
|
|
2
2
|
--min-rows: is set via inline style
|
|
3
3
|
--max-rows: is set via inline style
|
|
4
|
-
*/display:grid;width:100%;--font: var(--body-base);--line-height: 20px;--padding: var(--spacing-sizing-03)}[data-bspk=textarea][data-size=small]{--font: var(--body-small);--line-height: 20px;--padding: var(--spacing-sizing-02)}[data-bspk=textarea][data-size=large]{--font: var(--body-large);--line-height: 24px;--padding: var(--spacing-sizing-03)}[data-bspk=textarea] [data-replicated-value]{white-space:pre-wrap;visibility:hidden}[data-bspk=textarea] textarea,[data-bspk=textarea] [data-replicated-value]{width:100%;font:var(--font);border:1px solid var(--border-color);padding:var(--padding);grid-area:1/1/2/2;min-height:calc(var(--line-height)*var(--min-rows) + var(--padding)*2);max-height:calc(var(--line-height)*var(--max-rows) + var(--padding)*2)}[data-bspk=textarea] textarea{--border-color: var(--stroke-neutral-base);resize:
|
|
4
|
+
*/display:grid;width:100%;--font: var(--body-base);--line-height: 20px;--padding: var(--spacing-sizing-03)}[data-bspk=textarea][data-size=small]{--font: var(--body-small);--line-height: 20px;--padding: var(--spacing-sizing-02)}[data-bspk=textarea][data-size=large]{--font: var(--body-large);--line-height: 24px;--padding: var(--spacing-sizing-03)}[data-bspk=textarea] [data-replicated-value]{white-space:pre-wrap;visibility:hidden}[data-bspk=textarea] textarea,[data-bspk=textarea] [data-replicated-value]{width:100%;font:var(--font);border:1px solid var(--border-color);padding:var(--padding);grid-area:1/1/2/2;min-height:calc(var(--line-height)*var(--min-rows) + var(--padding)*2);max-height:calc(var(--line-height)*var(--max-rows) + var(--padding)*2)}[data-bspk=textarea] textarea{--border-color: var(--stroke-neutral-base);resize:none;color:var(--foreground-neutral-on-surface);background-color:var(--surface-neutral-t1-base);border-radius:var(--radius-small)}[data-bspk=textarea] textarea::placeholder{color:var(--foreground-neutral-on-surface-variant-03)}[data-bspk=textarea] textarea:focus-within{--border-color: var(--stroke-neutral-focus);outline:none;color:var(--foreground-neutral-on-surface)}[data-bspk=textarea] textarea:disabled{pointer-events:none;background:linear-gradient(var(--interactions-disabled-opacity), var(--interactions-disabled-opacity)),linear-gradient(var(--surface-neutral-t1-base), var(--surface-neutral-t1-base));color:var(--foreground-neutral-disabled-on-surface)}[data-bspk=textarea] textarea:read-only{background:linear-gradient(var(--interactions-disabled-opacity), var(--interactions-disabled-opacity)),linear-gradient(var(--surface-neutral-t1-base), var(--surface-neutral-t1-base));cursor:not-allowed}[data-bspk=textarea] textarea[aria-invalid]{--border-color: var(--status-error)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bspk/ui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"license": "CC-BY-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"sass": "sass --style=compressed --no-source-map src:dist",
|
|
20
20
|
"build": "tsx build.ts",
|
|
21
21
|
"lint:css": "npx stylelint '**/*.scss'",
|
|
22
|
-
"lint": "eslint",
|
|
22
|
+
"lint": "eslint && tsc --noEmit && stylelint '**/*.scss'",
|
|
23
23
|
"lint:fix": "eslint --fix",
|
|
24
24
|
"semantic-release": "semantic-release",
|
|
25
25
|
"test": "jest",
|
package/src/Checkbox.tsx
CHANGED
|
@@ -27,6 +27,8 @@ function Checkbox({
|
|
|
27
27
|
indeterminate: indeterminateProp,
|
|
28
28
|
invalid,
|
|
29
29
|
disabled,
|
|
30
|
+
errorMessage,
|
|
31
|
+
|
|
30
32
|
...props
|
|
31
33
|
}: ElementProps<CheckboxProps, 'input'>) {
|
|
32
34
|
const indeterminate = !!indeterminateProp;
|
|
@@ -46,6 +48,7 @@ function Checkbox({
|
|
|
46
48
|
>
|
|
47
49
|
<input
|
|
48
50
|
{...props}
|
|
51
|
+
aria-errormessage={errorMessage || undefined}
|
|
49
52
|
aria-invalid={invalid || undefined}
|
|
50
53
|
checked={checked}
|
|
51
54
|
disabled={disabled || undefined}
|
package/src/CheckboxOption.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CheckboxProps, Checkbox } from './Checkbox';
|
|
2
2
|
import { ToggleOptionProps, ToggleOption } from './ToggleOption';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
> &
|
|
4
|
+
import { InvalidPropsLibrary } from '.';
|
|
5
|
+
|
|
6
|
+
export type CheckboxOptionProps = InvalidPropsLibrary &
|
|
7
|
+
Pick<CheckboxProps, 'checked' | 'disabled' | 'indeterminate' | 'name' | 'onChange' | 'value'> &
|
|
8
8
|
Pick<ToggleOptionProps, 'description' | 'label'>;
|
|
9
9
|
|
|
10
10
|
/**
|
package/src/Dropdown.tsx
CHANGED
|
@@ -8,7 +8,7 @@ import { Placement } from './hooks/useFloating';
|
|
|
8
8
|
import { useFloatingMenu } from './hooks/useFloatingMenu';
|
|
9
9
|
import { useId } from './hooks/useId';
|
|
10
10
|
|
|
11
|
-
import { CommonProps } from './';
|
|
11
|
+
import { CommonProps, InvalidPropsLibrary } from './';
|
|
12
12
|
|
|
13
13
|
export type DropdownOption = {
|
|
14
14
|
/** The value of the option. */
|
|
@@ -18,8 +18,9 @@ export type DropdownOption = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
export type DropdownProps<O extends DropdownOption = DropdownOption> = CommonProps<
|
|
21
|
-
'aria-label' | 'disabled' | 'id' | '
|
|
21
|
+
'aria-label' | 'disabled' | 'id' | 'name' | 'readOnly' | 'size'
|
|
22
22
|
> &
|
|
23
|
+
InvalidPropsLibrary &
|
|
23
24
|
Pick<MenuProps<O>, 'isMulti' | 'itemCount' | 'onChange' | 'renderListItem'> & {
|
|
24
25
|
/**
|
|
25
26
|
* Array of options to display in the dropdown
|
|
@@ -66,6 +67,7 @@ function Dropdown<O extends DropdownOption = DropdownOption>({
|
|
|
66
67
|
disabled,
|
|
67
68
|
id: propId,
|
|
68
69
|
invalid,
|
|
70
|
+
errorMessage,
|
|
69
71
|
readOnly,
|
|
70
72
|
placement = 'bottom',
|
|
71
73
|
name,
|
|
@@ -81,6 +83,7 @@ function Dropdown<O extends DropdownOption = DropdownOption>({
|
|
|
81
83
|
disabled,
|
|
82
84
|
invalid,
|
|
83
85
|
readOnly,
|
|
86
|
+
errorMessage,
|
|
84
87
|
},
|
|
85
88
|
});
|
|
86
89
|
|
package/src/FormField.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { InlineAlert } from './InlineAlert';
|
|
|
3
3
|
import { Layout } from './Layout';
|
|
4
4
|
import { Txt } from './Txt';
|
|
5
5
|
|
|
6
|
-
import { CommonProps } from './';
|
|
6
|
+
import { CommonProps, InvalidPropsLibrary } from './';
|
|
7
7
|
|
|
8
8
|
export type FieldControlProps = {
|
|
9
9
|
/**
|
|
@@ -18,27 +18,29 @@ export type FieldControlProps = {
|
|
|
18
18
|
'aria-errormessage'?: string;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
export type FormFieldProps = CommonProps<'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
21
|
+
export type FormFieldProps = CommonProps<'required'> &
|
|
22
|
+
InvalidPropsLibrary & {
|
|
23
|
+
/**
|
|
24
|
+
* The label of the field.
|
|
25
|
+
*
|
|
26
|
+
* @required
|
|
27
|
+
*/
|
|
28
|
+
label: string;
|
|
29
|
+
/** The id of the control. */
|
|
30
|
+
controlId: string;
|
|
31
|
+
/**
|
|
32
|
+
* The children of the form field. This should be a control such as TextInput, Dropdown, DatePicker, or
|
|
33
|
+
* TimePicker.
|
|
34
|
+
*
|
|
35
|
+
* @type (childProps: FieldControlProps) => JSX.Element
|
|
36
|
+
* @required
|
|
37
|
+
*/
|
|
38
|
+
children: (childProps: FieldControlProps) => JSX.Element;
|
|
39
|
+
/** The helperText of the field. */
|
|
40
|
+
helperText?: string;
|
|
41
|
+
/** The trailing element of the label. */
|
|
42
|
+
labelTrailing?: React.ReactNode;
|
|
43
|
+
};
|
|
42
44
|
|
|
43
45
|
/**
|
|
44
46
|
* Wrapper component for form controls.
|
|
@@ -47,14 +49,23 @@ export type FormFieldProps = CommonProps<'errorMessage' | 'required'> & {
|
|
|
47
49
|
*
|
|
48
50
|
* @name FormField
|
|
49
51
|
*/
|
|
50
|
-
function FormField({
|
|
52
|
+
function FormField({
|
|
53
|
+
label,
|
|
54
|
+
invalid,
|
|
55
|
+
errorMessage,
|
|
56
|
+
helperText,
|
|
57
|
+
children,
|
|
58
|
+
labelTrailing,
|
|
59
|
+
controlId,
|
|
60
|
+
required,
|
|
61
|
+
}: FormFieldProps) {
|
|
51
62
|
const errorMessageId = errorMessage && `${controlId}-error-message`;
|
|
52
63
|
const helperTextId = helperText && `${controlId}-helper-text`;
|
|
53
64
|
|
|
54
65
|
if (typeof children !== 'function') return null;
|
|
55
66
|
|
|
56
67
|
return (
|
|
57
|
-
<div data-bspk="form-field">
|
|
68
|
+
<div data-bspk="form-field" data-invalid={invalid || undefined}>
|
|
58
69
|
<Layout as="header">
|
|
59
70
|
<label htmlFor={controlId}>
|
|
60
71
|
<Txt as="span" variant="labels-small">
|
package/src/Link.tsx
CHANGED
|
@@ -4,31 +4,34 @@ import { SvgOpenInNew } from '@bspk/icons/OpenInNew';
|
|
|
4
4
|
import './link.scss';
|
|
5
5
|
import { AnchorHTMLAttributes } from 'react';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
7
|
+
import { CommonPropsLibrary } from '.';
|
|
8
|
+
|
|
9
|
+
export type LinkProps = Pick<AnchorHTMLAttributes<unknown>, 'target'> &
|
|
10
|
+
Pick<CommonPropsLibrary, 'disabled'> & {
|
|
11
|
+
/**
|
|
12
|
+
* The label of the link.
|
|
13
|
+
*
|
|
14
|
+
* @required
|
|
15
|
+
*/
|
|
16
|
+
label: string;
|
|
17
|
+
/** The variant of the link. Controls the icon that is displayed and link target. */
|
|
18
|
+
trailingIcon?: 'chevron' | 'external' | 'link';
|
|
19
|
+
/** The [href](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#href) of the link. */
|
|
20
|
+
href: AnchorHTMLAttributes<unknown>['href'];
|
|
21
|
+
/**
|
|
22
|
+
* The size of the link.
|
|
23
|
+
*
|
|
24
|
+
* @default base
|
|
25
|
+
*/
|
|
26
|
+
size?: 'base' | 'large' | 'small';
|
|
27
|
+
/**
|
|
28
|
+
* Change the color of the link to a subtle color. This is useful for links that are not primary actions, for
|
|
29
|
+
* example footer menus.
|
|
30
|
+
*
|
|
31
|
+
* @default default
|
|
32
|
+
*/
|
|
33
|
+
variant?: 'default' | 'subtle-inverse' | 'subtle';
|
|
34
|
+
};
|
|
32
35
|
|
|
33
36
|
/**
|
|
34
37
|
* This is the standalone link component. Inline links can use the native `a` element.
|
package/src/ListItem.tsx
CHANGED
|
@@ -81,6 +81,7 @@ function ListItem<As extends ElementType = 'div'>({
|
|
|
81
81
|
subText,
|
|
82
82
|
active,
|
|
83
83
|
readOnly,
|
|
84
|
+
errorMessage,
|
|
84
85
|
...props
|
|
85
86
|
}: ElementProps<ListItemProps<As>, As>) {
|
|
86
87
|
let As: ElementType = as || 'div';
|
|
@@ -120,6 +121,7 @@ function ListItem<As extends ElementType = 'div'>({
|
|
|
120
121
|
<As
|
|
121
122
|
{...props}
|
|
122
123
|
aria-disabled={disabled || undefined}
|
|
124
|
+
aria-errormessage={errorMessage || undefined}
|
|
123
125
|
aria-invalid={invalid || undefined}
|
|
124
126
|
data-action={actionable || undefined}
|
|
125
127
|
data-active={active || undefined}
|
package/src/NumberField.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { FormFieldProps, FormField } from './FormField';
|
|
2
2
|
import { NumberInputProps, NumberInput } from './NumberInput';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
> &
|
|
8
|
-
Pick<
|
|
4
|
+
import { InvalidPropsLibrary } from '.';
|
|
5
|
+
|
|
6
|
+
export type NumberFieldProps = InvalidPropsLibrary &
|
|
7
|
+
Pick<FormFieldProps, 'controlId' | 'errorMessage' | 'helperText' | 'label' | 'labelTrailing' | 'required'> &
|
|
8
|
+
Pick<NumberInputProps, 'align' | 'disabled' | 'id' | 'name' | 'onChange' | 'readOnly' | 'size' | 'value'>;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A input element that allows users to either input a numerical value or singularly increase or decrease the values by
|
package/src/NumberInput.tsx
CHANGED
|
@@ -5,7 +5,14 @@ import './number-input.scss';
|
|
|
5
5
|
import { useId } from './hooks/useId';
|
|
6
6
|
import { useLongPress } from './hooks/useLongPress';
|
|
7
7
|
|
|
8
|
-
import { CommonProps } from '.';
|
|
8
|
+
import { CommonProps, InvalidPropsLibrary } from '.';
|
|
9
|
+
|
|
10
|
+
const DEFAULT = {
|
|
11
|
+
align: 'center',
|
|
12
|
+
size: 'medium',
|
|
13
|
+
disabled: false,
|
|
14
|
+
readOnly: false,
|
|
15
|
+
} as const;
|
|
9
16
|
|
|
10
17
|
function isNumber(value: unknown): number | undefined {
|
|
11
18
|
if (typeof value === 'number') return value;
|
|
@@ -14,43 +21,51 @@ function isNumber(value: unknown): number | undefined {
|
|
|
14
21
|
return isNaN(num) ? undefined : num;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
export type NumberInputProps = CommonProps<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
export type NumberInputProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'name' | 'readOnly' | 'size'> &
|
|
25
|
+
InvalidPropsLibrary & {
|
|
26
|
+
/** The value of the control. */
|
|
27
|
+
value?: number;
|
|
28
|
+
/** Callback when the value changes. */
|
|
29
|
+
onChange: (value: number | undefined) => void;
|
|
30
|
+
/**
|
|
31
|
+
* The alignment of the input box. Centered between the plus and minus buttons or to the left of the buttons.
|
|
32
|
+
*
|
|
33
|
+
* @default center
|
|
34
|
+
*/
|
|
35
|
+
align?: 'center' | 'left';
|
|
36
|
+
/**
|
|
37
|
+
* Defines the [maximum](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/max) value that is
|
|
38
|
+
* accepted.
|
|
39
|
+
*
|
|
40
|
+
* @default 99
|
|
41
|
+
* @maximum 99
|
|
42
|
+
* @minimum 1
|
|
43
|
+
*/
|
|
44
|
+
max?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Defines the [minimum](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/min) value that is
|
|
47
|
+
* accepted.
|
|
48
|
+
*
|
|
49
|
+
* @minimum 0
|
|
50
|
+
*/
|
|
51
|
+
min?: number;
|
|
52
|
+
};
|
|
39
53
|
|
|
40
54
|
/**
|
|
41
55
|
* A input element that allows users to either input a numerical value or singularly increase or decrease the values by
|
|
42
56
|
* pressing the (+) or (-).
|
|
43
57
|
*
|
|
58
|
+
* The value of the input is a number. The value is clamped to the min and max values if they are provided.
|
|
59
|
+
*
|
|
44
60
|
* @name NumberInput
|
|
45
61
|
*/
|
|
46
62
|
function NumberInput({
|
|
47
|
-
|
|
48
|
-
value = 1,
|
|
63
|
+
value,
|
|
49
64
|
onChange,
|
|
50
|
-
|
|
51
|
-
size =
|
|
52
|
-
disabled =
|
|
53
|
-
readOnly =
|
|
65
|
+
align = DEFAULT.align,
|
|
66
|
+
size = DEFAULT.size,
|
|
67
|
+
disabled = DEFAULT.disabled,
|
|
68
|
+
readOnly = DEFAULT.readOnly,
|
|
54
69
|
name,
|
|
55
70
|
id: inputIdProp,
|
|
56
71
|
invalid,
|
|
@@ -58,11 +73,17 @@ function NumberInput({
|
|
|
58
73
|
max: maxProp,
|
|
59
74
|
min: minProp,
|
|
60
75
|
}: NumberInputProps) {
|
|
76
|
+
const centered = align !== 'left';
|
|
61
77
|
const inputId = useId(inputIdProp);
|
|
62
78
|
const max = isNumber(maxProp);
|
|
63
79
|
const min = isNumber(minProp);
|
|
64
80
|
|
|
65
|
-
const fix = (next: number = value) => {
|
|
81
|
+
const fix = (next: number | undefined = value) => {
|
|
82
|
+
if (typeof next !== 'number') {
|
|
83
|
+
onChange(undefined);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
66
87
|
let fixValue = next;
|
|
67
88
|
if (typeof min !== 'undefined' && next < min) fixValue = min;
|
|
68
89
|
if (typeof max !== 'undefined' && next > max) fixValue = max;
|
package/src/Radio.tsx
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import './radio.scss';
|
|
2
|
-
import { ToggleControlProps, ElementProps } from './';
|
|
2
|
+
import { ToggleControlProps, ElementProps, InvalidPropsLibrary } from './';
|
|
3
3
|
|
|
4
|
-
export type RadioProps =
|
|
5
|
-
ToggleControlProps<HTMLInputElement>,
|
|
6
|
-
'aria-label' | 'checked' | 'disabled' | 'invalid' | 'name' | 'onChange' | 'value'
|
|
7
|
-
>;
|
|
4
|
+
export type RadioProps = InvalidPropsLibrary &
|
|
5
|
+
Pick<ToggleControlProps<HTMLInputElement>, 'aria-label' | 'checked' | 'disabled' | 'name' | 'onChange' | 'value'>;
|
|
8
6
|
|
|
9
7
|
/**
|
|
10
8
|
* A round control that allows user to choose one option from a set. This is the base element and if used directly you
|
package/src/RadioOption.tsx
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { RadioProps, Radio } from './Radio';
|
|
2
2
|
import { ToggleOptionProps, ToggleOption } from './ToggleOption';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import { InvalidPropsLibrary } from '.';
|
|
5
|
+
|
|
6
|
+
export type RadioOptionProps = InvalidPropsLibrary &
|
|
7
|
+
Pick<RadioProps, 'checked' | 'disabled' | 'name' | 'onChange' | 'value'> &
|
|
5
8
|
Pick<ToggleOptionProps, 'description' | 'label'>;
|
|
6
9
|
|
|
7
10
|
/**
|
package/src/SegmentedControl.tsx
CHANGED
|
@@ -2,11 +2,11 @@ import './segmented-control.scss';
|
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
3
|
|
|
4
4
|
import { Tooltip } from './Tooltip';
|
|
5
|
-
import {
|
|
5
|
+
import { useOptionIconsInvalid } from './hooks/useOptionIconsInvalid';
|
|
6
6
|
|
|
7
7
|
import { ElementProps } from './';
|
|
8
8
|
|
|
9
|
-
export type
|
|
9
|
+
export type SegmentedControlOption = {
|
|
10
10
|
/**
|
|
11
11
|
* The label of the option. This is the text that will be displayed on the option.
|
|
12
12
|
*
|
|
@@ -30,18 +30,22 @@ export type SegmentedControlProps = {
|
|
|
30
30
|
/**
|
|
31
31
|
* The options to display. Each option has a label and an optional leading icon.
|
|
32
32
|
*
|
|
33
|
-
* @type
|
|
33
|
+
* @type SegmentedControlOption[]
|
|
34
34
|
* @required
|
|
35
35
|
*/
|
|
36
|
-
options:
|
|
37
|
-
/**
|
|
38
|
-
|
|
36
|
+
options: SegmentedControlOption[];
|
|
37
|
+
/**
|
|
38
|
+
* The id of the selected option.
|
|
39
|
+
*
|
|
40
|
+
* @required
|
|
41
|
+
*/
|
|
42
|
+
value: SegmentedControlOption['value'];
|
|
39
43
|
/**
|
|
40
44
|
* The function to call when the option is clicked.
|
|
41
45
|
*
|
|
42
46
|
* @required
|
|
43
47
|
*/
|
|
44
|
-
onChange: (value:
|
|
48
|
+
onChange: (value: SegmentedControlOption['value']) => void;
|
|
45
49
|
/**
|
|
46
50
|
* The size of the options.
|
|
47
51
|
*
|
|
@@ -73,18 +77,19 @@ function SegmentedControl({
|
|
|
73
77
|
onChange,
|
|
74
78
|
value,
|
|
75
79
|
size = 'medium',
|
|
76
|
-
options,
|
|
80
|
+
options: optionsProp,
|
|
77
81
|
width = 'hug',
|
|
78
82
|
showLabels: showLabelsProp = true,
|
|
79
83
|
...containerProps
|
|
80
84
|
}: ElementProps<SegmentedControlProps, 'div'>) {
|
|
81
|
-
const
|
|
85
|
+
const options = Array.isArray(optionsProp) ? optionsProp : [];
|
|
86
|
+
useOptionIconsInvalid(options);
|
|
82
87
|
|
|
83
|
-
const hideLabels = showLabelsProp === false &&
|
|
88
|
+
const hideLabels = showLabelsProp === false && options.every((item) => item.icon && item.label);
|
|
84
89
|
|
|
85
90
|
return (
|
|
86
91
|
<div {...containerProps} data-bspk="segmented-control" data-size={size} data-width={width}>
|
|
87
|
-
{
|
|
92
|
+
{options.map((item, index) => {
|
|
88
93
|
const isActive = item.value === value;
|
|
89
94
|
return (
|
|
90
95
|
<Fragment key={item.value}>
|
|
@@ -92,10 +97,10 @@ function SegmentedControl({
|
|
|
92
97
|
<button
|
|
93
98
|
aria-label={item.label}
|
|
94
99
|
data-first={index === 0 || undefined}
|
|
95
|
-
data-last={index ===
|
|
100
|
+
data-last={index === options.length - 1 || undefined}
|
|
96
101
|
data-selected={isActive || undefined}
|
|
97
102
|
disabled={item.disabled || undefined}
|
|
98
|
-
onClick={() => onChange(item.value)}
|
|
103
|
+
onClick={() => onChange(item.value || item.label)}
|
|
99
104
|
>
|
|
100
105
|
<span data-outer>
|
|
101
106
|
<span data-inner>
|