@bspk/ui 1.1.13 → 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 (56) 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/TextField.d.ts +2 -1
  24. package/dist/TextField.js.map +1 -1
  25. package/dist/TextInput.d.ts +3 -3
  26. package/dist/TextInput.js +2 -2
  27. package/dist/TextInput.js.map +1 -1
  28. package/dist/Textarea.d.ts +7 -7
  29. package/dist/Textarea.js +2 -2
  30. package/dist/Textarea.js.map +1 -1
  31. package/dist/form-field.css +1 -1
  32. package/dist/hooks/useFloatingMenu.d.ts +3 -2
  33. package/dist/hooks/useFloatingMenu.js +1 -0
  34. package/dist/hooks/useFloatingMenu.js.map +1 -1
  35. package/dist/index.d.ts +22 -13
  36. package/dist/index.js.map +1 -1
  37. package/dist/inline-alert.css +1 -1
  38. package/dist/number-input.css +1 -1
  39. package/package.json +2 -2
  40. package/src/Checkbox.tsx +3 -0
  41. package/src/CheckboxOption.tsx +4 -4
  42. package/src/Dropdown.tsx +5 -2
  43. package/src/FormField.tsx +35 -24
  44. package/src/ListItem.tsx +2 -0
  45. package/src/NumberField.tsx +5 -5
  46. package/src/NumberInput.tsx +38 -24
  47. package/src/Radio.tsx +3 -5
  48. package/src/RadioOption.tsx +4 -1
  49. package/src/TextField.tsx +19 -17
  50. package/src/TextInput.tsx +33 -30
  51. package/src/Textarea.tsx +51 -48
  52. package/src/form-field.scss +2 -1
  53. package/src/hooks/useFloatingMenu.ts +4 -2
  54. package/src/index.ts +24 -13
  55. package/src/inline-alert.scss +1 -1
  56. package/src/number-input.scss +6 -3
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;