@bspk/ui 1.1.12 → 1.1.14

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.
Files changed (62) hide show
  1. package/dist/Checkbox.d.ts +1 -1
  2. package/dist/Checkbox.js +2 -2
  3. package/dist/Checkbox.js.map +1 -1
  4. package/dist/CheckboxOption.d.ts +2 -1
  5. package/dist/Dropdown.d.ts +3 -3
  6. package/dist/Dropdown.js +2 -1
  7. package/dist/Dropdown.js.map +1 -1
  8. package/dist/FormField.d.ts +5 -4
  9. package/dist/FormField.js +3 -3
  10. package/dist/FormField.js.map +1 -1
  11. package/dist/InlineAlert.js +1 -1
  12. package/dist/ListItem.d.ts +1 -1
  13. package/dist/ListItem.js +2 -2
  14. package/dist/ListItem.js.map +1 -1
  15. package/dist/NumberField.d.ts +2 -1
  16. package/dist/NumberInput.d.ts +22 -8
  17. package/dist/NumberInput.js +5 -2
  18. package/dist/NumberInput.js.map +1 -1
  19. package/dist/Radio.d.ts +2 -2
  20. package/dist/Radio.js.map +1 -1
  21. package/dist/RadioOption.d.ts +2 -1
  22. package/dist/RadioOption.js.map +1 -1
  23. package/dist/Skeleton.d.ts +24 -2
  24. package/dist/Skeleton.js +22 -0
  25. package/dist/Skeleton.js.map +1 -1
  26. package/dist/TextField.d.ts +2 -1
  27. package/dist/TextField.js.map +1 -1
  28. package/dist/TextInput.d.ts +3 -3
  29. package/dist/TextInput.js +2 -2
  30. package/dist/TextInput.js.map +1 -1
  31. package/dist/Textarea.d.ts +7 -7
  32. package/dist/Textarea.js +2 -2
  33. package/dist/Textarea.js.map +1 -1
  34. package/dist/form-field.css +1 -1
  35. package/dist/hooks/useFloatingMenu.d.ts +3 -2
  36. package/dist/hooks/useFloatingMenu.js +1 -0
  37. package/dist/hooks/useFloatingMenu.js.map +1 -1
  38. package/dist/index.d.ts +22 -13
  39. package/dist/index.js.map +1 -1
  40. package/dist/inline-alert.css +1 -1
  41. package/dist/number-input.css +1 -1
  42. package/meta-types.ts +5 -2
  43. package/meta.ts +8 -0
  44. package/package.json +2 -2
  45. package/src/Checkbox.tsx +3 -0
  46. package/src/CheckboxOption.tsx +4 -4
  47. package/src/Dropdown.tsx +5 -2
  48. package/src/FormField.tsx +35 -24
  49. package/src/ListItem.tsx +2 -0
  50. package/src/NumberField.tsx +5 -5
  51. package/src/NumberInput.tsx +38 -24
  52. package/src/Radio.tsx +3 -5
  53. package/src/RadioOption.tsx +4 -1
  54. package/src/Skeleton.tsx +24 -2
  55. package/src/TextField.tsx +19 -17
  56. package/src/TextInput.tsx +33 -30
  57. package/src/Textarea.tsx +51 -48
  58. package/src/form-field.scss +2 -1
  59. package/src/hooks/useFloatingMenu.ts +4 -2
  60. package/src/index.ts +24 -13
  61. package/src/inline-alert.scss +1 -1
  62. package/src/number-input.scss +6 -3
package/src/TextInput.tsx CHANGED
@@ -4,38 +4,39 @@ import { ChangeEvent, HTMLInputAutoCompleteAttribute, HTMLInputTypeAttribute, Re
4
4
 
5
5
  import { useId } from './hooks/useId';
6
6
 
7
- import { ElementProps, CommonProps } from '.';
7
+ import { ElementProps, CommonProps, InvalidPropsLibrary } from '.';
8
8
 
9
9
  export type TextInputProps = CommonProps<
10
- 'aria-label' | 'disabled' | 'id' | 'invalid' | 'name' | 'readOnly' | 'required' | 'size' | 'value'
11
- > & {
12
- /**
13
- * Callback when the value of the field changes.
14
- *
15
- * @type (next: String, Event) => void
16
- * @required
17
- */
18
- onChange: (next: string, event?: ChangeEvent<HTMLInputElement>) => void;
19
- /** The ref of the container. */
20
- containerRef?: (node: HTMLElement | null) => void;
21
- /** The ref of the input. */
22
- inputRef?: (node: HTMLElement | null) => void;
23
- /** The trailing element to display in the field. */
24
- trailing?: ReactNode;
25
- /** The leading element to display in the field. */
26
- leading?: ReactNode;
27
- /** The placeholder of the field. */
28
- placeholder?: string;
29
- /** The type of the input. */
30
- type?: Extract<HTMLInputTypeAttribute, 'number' | 'text'>;
31
- /**
32
- * Specifies if user agent has any permission to provide automated assistance in filling out form field values.
33
- * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
34
- *
35
- * @default off
36
- */
37
- autoComplete?: HTMLInputAutoCompleteAttribute;
38
- };
10
+ 'aria-label' | 'disabled' | 'id' | 'name' | 'readOnly' | 'required' | 'size' | 'value'
11
+ > &
12
+ InvalidPropsLibrary & {
13
+ /**
14
+ * Callback when the value of the field changes.
15
+ *
16
+ * @type (next: String, Event) => void
17
+ * @required
18
+ */
19
+ onChange: (next: string, event?: ChangeEvent<HTMLInputElement>) => void;
20
+ /** The ref of the container. */
21
+ containerRef?: (node: HTMLElement | null) => void;
22
+ /** The ref of the input. */
23
+ inputRef?: (node: HTMLElement | null) => void;
24
+ /** The trailing element to display in the field. */
25
+ trailing?: ReactNode;
26
+ /** The leading element to display in the field. */
27
+ leading?: ReactNode;
28
+ /** The placeholder of the field. */
29
+ placeholder?: string;
30
+ /** The type of the input. */
31
+ type?: Extract<HTMLInputTypeAttribute, 'number' | 'text'>;
32
+ /**
33
+ * Specifies if user agent has any permission to provide automated assistance in filling out form field values.
34
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
35
+ *
36
+ * @default off
37
+ */
38
+ autoComplete?: HTMLInputAutoCompleteAttribute;
39
+ };
39
40
 
40
41
  /**
41
42
  * A text input that allows users to enter text, numbers or symbols in a singular line. This is the base element and is
@@ -63,6 +64,7 @@ function TextInput({
63
64
  disabled,
64
65
  autoComplete = 'off',
65
66
  containerRef,
67
+ errorMessage,
66
68
  ...otherProps
67
69
  }: ElementProps<TextInputProps, 'div'>) {
68
70
  const id = useId(idProp);
@@ -82,6 +84,7 @@ function TextInput({
82
84
  >
83
85
  {leading && <span data-leading>{leading}</span>}
84
86
  <input
87
+ aria-errormessage={errorMessage || undefined}
85
88
  aria-invalid={invalid || undefined}
86
89
  aria-label={ariaLabel}
87
90
  autoComplete={autoComplete}
package/src/Textarea.tsx CHANGED
@@ -3,55 +3,56 @@ import { ChangeEvent, CSSProperties, Ref } from 'react';
3
3
 
4
4
  import { useId } from './hooks/useId';
5
5
 
6
- import { CommonProps } from './';
6
+ import { CommonProps, InvalidPropsLibrary } from './';
7
7
 
8
- export type TextareaProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'invalid' | 'readOnly' | 'required'> & {
9
- /**
10
- * Callback when the value of the field changes.
11
- *
12
- * @type (next: String, Event) => void
13
- * @required
14
- */
15
- onChange: (next: string, event?: ChangeEvent<HTMLTextAreaElement>) => void;
16
- /**
17
- * The size of the field.
18
- *
19
- * @default medium
20
- */
21
- size?: 'large' | 'medium' | 'small';
22
- /** The value of the field. */
23
- value?: string;
24
- /**
25
- * The textarea control name of the field.
26
- *
27
- * @required
28
- */
29
- name: string;
30
- /** The ref of the field. */
31
- innerRef?: Ref<HTMLTextAreaElement>;
32
- /** The placeholder of the field. */
33
- placeholder?: string;
34
- /**
35
- * The maximum number of characters that the field will accept.
36
- *
37
- * @minimum 1
38
- */
39
- maxLength?: number;
40
- /**
41
- * The minimum number of rows that the textarea should have. If set the textarea will automatically grow and shrink
42
- * to fit the content.
43
- *
44
- * @minimum 3
45
- */
46
- minRows?: number;
47
- /**
48
- * The maximum number of rows that the textarea should have. If set the textarea will automatically grow and shrink
49
- * to fit the content.
50
- *
51
- * @maximum 10
52
- */
53
- maxRows?: number;
54
- };
8
+ export type TextareaProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'readOnly' | 'required'> &
9
+ InvalidPropsLibrary & {
10
+ /**
11
+ * Callback when the value of the field changes.
12
+ *
13
+ * @type (next: String, Event) => void
14
+ * @required
15
+ */
16
+ onChange: (next: string, event?: ChangeEvent<HTMLTextAreaElement>) => void;
17
+ /**
18
+ * The size of the field.
19
+ *
20
+ * @default medium
21
+ */
22
+ size?: 'large' | 'medium' | 'small';
23
+ /** The value of the field. */
24
+ value?: string;
25
+ /**
26
+ * The textarea control name of the field.
27
+ *
28
+ * @required
29
+ */
30
+ name: string;
31
+ /** The ref of the field. */
32
+ innerRef?: Ref<HTMLTextAreaElement>;
33
+ /** The placeholder of the field. */
34
+ placeholder?: string;
35
+ /**
36
+ * The maximum number of characters that the field will accept.
37
+ *
38
+ * @minimum 1
39
+ */
40
+ maxLength?: number;
41
+ /**
42
+ * The minimum number of rows that the textarea should have. If set the textarea will automatically grow and
43
+ * shrink to fit the content.
44
+ *
45
+ * @minimum 3
46
+ */
47
+ minRows?: number;
48
+ /**
49
+ * The maximum number of rows that the textarea should have. If set the textarea will automatically grow and
50
+ * shrink to fit the content.
51
+ *
52
+ * @maximum 10
53
+ */
54
+ maxRows?: number;
55
+ };
55
56
 
56
57
  const MIN_ROWS = 3;
57
58
  const MAX_ROWS = 10;
@@ -75,6 +76,7 @@ function Textarea({
75
76
  id: idProp,
76
77
  minRows: minRowsProp = MIN_ROWS,
77
78
  maxRows: maxRowsProp = MAX_ROWS,
79
+ errorMessage,
78
80
  ...otherProps
79
81
  }: TextareaProps) {
80
82
  const id = useId(idProp);
@@ -96,6 +98,7 @@ function Textarea({
96
98
  >
97
99
  <textarea
98
100
  {...otherProps}
101
+ aria-errormessage={errorMessage || undefined}
99
102
  aria-invalid={invalid || undefined}
100
103
  aria-label={ariaLabel}
101
104
  id={id}
@@ -1,6 +1,7 @@
1
1
  [data-bspk='form-field'] {
2
2
  box-sizing: border-box;
3
- width: 100%;
3
+ max-width: 100%;
4
+ width: fit-content;
4
5
  display: flex;
5
6
  flex-direction: column;
6
7
  gap: var(--spacing-sizing-01);
@@ -1,6 +1,6 @@
1
1
  import { AriaAttributes, useId, useState } from 'react';
2
2
 
3
- import { CommonProps } from '..';
3
+ import { CommonProps, InvalidPropsLibrary } from '..';
4
4
  import { EVENT_KEY } from '../utils/keyboard';
5
5
 
6
6
  import { Placement, useFloating } from './useFloating';
@@ -9,7 +9,7 @@ import { useOutsideClick } from './useOutsideClick';
9
9
 
10
10
  export type UseFloatingMenuProps = {
11
11
  placement: Placement;
12
- triggerProps?: CommonProps<'disabled' | 'invalid' | 'readOnly'>;
12
+ triggerProps?: CommonProps<'disabled' | 'readOnly'> & InvalidPropsLibrary;
13
13
  };
14
14
 
15
15
  export type UseFloatingMenuReturn = {
@@ -30,6 +30,7 @@ export type UseFloatingMenuReturn = {
30
30
  'aria-invalid': boolean | undefined;
31
31
  'aria-owns': string;
32
32
  'aria-readonly': boolean | undefined;
33
+ 'aria-errormessage': string | undefined;
33
34
  role: 'combobox';
34
35
  tabIndex: number;
35
36
  ref: (node: HTMLElement | null) => void;
@@ -75,6 +76,7 @@ export function useFloatingMenu({ placement, triggerProps }: UseFloatingMenuProp
75
76
  tabIndex: -1,
76
77
  },
77
78
  triggerProps: {
79
+ 'aria-errormessage': triggerProps?.errorMessage || undefined,
78
80
  'aria-activedescendant': selectedId || undefined,
79
81
  'aria-controls': menuId,
80
82
  'aria-expanded': show,
package/src/index.ts CHANGED
@@ -34,7 +34,8 @@ export type CallToActionButton = {
34
34
  size?: ButtonSize;
35
35
  };
36
36
 
37
- export type ToggleControlProps<T extends HTMLElement> = CommonProps<'aria-label' | 'disabled' | 'invalid' | 'name', T> &
37
+ export type ToggleControlProps<T extends HTMLElement> = CommonProps<'aria-label' | 'disabled' | 'name', T> &
38
+ InvalidPropsLibrary &
38
39
  Required<CommonProps<'value'>> & {
39
40
  /**
40
41
  * Marks the control as checked.
@@ -56,6 +57,28 @@ export type CommonProps<K extends keyof CommonPropsLibrary, T extends HTMLElemen
56
57
  K
57
58
  >;
58
59
 
60
+ /**
61
+ * The props that are common to input elements.
62
+ *
63
+ * If an element is invalid it must have an errorMessage.
64
+ */
65
+ export type InvalidPropsLibrary = {
66
+ /**
67
+ * Marks the element as invalid and displays error state theme.
68
+ *
69
+ * If the errorMessage is empty the error state theme will not appear.
70
+ *
71
+ * @default false
72
+ */
73
+ invalid?: boolean;
74
+ /**
75
+ * Marks the element as invalid and displays error message.
76
+ *
77
+ * When an element is invalid it must display an error message explaining why it is invalid.
78
+ */
79
+ errorMessage?: string;
80
+ };
81
+
59
82
  export type CommonPropsLibrary<T extends HTMLElement = HTMLElement> = {
60
83
  /** The id of the element. If not provided one will be generated. */
61
84
  id?: string;
@@ -89,12 +112,6 @@ export type CommonPropsLibrary<T extends HTMLElement = HTMLElement> = {
89
112
  * @default false
90
113
  */
91
114
  disabled?: boolean;
92
- /**
93
- * Marks the element as invalid and displays error state theme.
94
- *
95
- * @default false
96
- */
97
- invalid?: boolean;
98
115
  /**
99
116
  * Determines if the element is [readonly](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly).
100
117
  *
@@ -107,12 +124,6 @@ export type CommonPropsLibrary<T extends HTMLElement = HTMLElement> = {
107
124
  * @required
108
125
  */
109
126
  name: string;
110
- /**
111
- * Marks the element as invalid and displays error message.
112
- *
113
- * When an element is invalid it must display an error message explaining why it is invalid.
114
- */
115
- errorMessage?: string;
116
127
  /**
117
128
  * The value of the control.
118
129
  *
@@ -1,7 +1,7 @@
1
1
  [data-bspk='inline-alert'] {
2
2
  display: flex;
3
3
  align-items: start;
4
- justify-content: center;
4
+ justify-content: start;
5
5
  flex-direction: row;
6
6
  gap: var(--spacing-sizing-02);
7
7
 
@@ -1,5 +1,5 @@
1
1
  [data-bspk='number-input'] {
2
- // medium
2
+ // medium is the default size
3
3
  --font: var(--body-base);
4
4
  --height: var(--spacing-sizing-10);
5
5
  --svg-width: var(--spacing-sizing-05);
@@ -13,10 +13,10 @@
13
13
  border: 1px solid var(--stroke-neutral-base);
14
14
  border-radius: var(--radius-small);
15
15
  background: var(--surface-neutral-t1-base);
16
+ max-width: 280px;
16
17
 
17
18
  &:focus-within {
18
19
  border-color: var(--stroke-brand-primary);
19
- outline: 1px solid var(--stroke-brand-primary);
20
20
  }
21
21
 
22
22
  [data-divider] {
@@ -29,11 +29,13 @@
29
29
  }
30
30
 
31
31
  button {
32
- min-width: var(--height);
32
+ width: var(--height);
33
+ height: var(--height);
33
34
  background: none;
34
35
  border: none;
35
36
  cursor: pointer;
36
37
  font: var(--font);
38
+ flex-shrink: 0;
37
39
 
38
40
  svg {
39
41
  width: var(--svg-width);
@@ -59,6 +61,7 @@
59
61
  padding: 0 var(--spacing-sizing-03);
60
62
  background: transparent;
61
63
  border: none;
64
+ flex-grow: 1;
62
65
 
63
66
  &:focus {
64
67
  outline: none;