@bspk/ui 1.1.21 → 1.1.23

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 (224) hide show
  1. package/dist/Avatar.d.ts +18 -2
  2. package/dist/Avatar.js +18 -2
  3. package/dist/Avatar.js.map +1 -1
  4. package/dist/AvatarGroup.d.ts +14 -0
  5. package/dist/AvatarGroup.js +14 -0
  6. package/dist/AvatarGroup.js.map +1 -1
  7. package/dist/Badge.d.ts +32 -2
  8. package/dist/Badge.js +29 -4
  9. package/dist/Badge.js.map +1 -1
  10. package/dist/BannerAlert.d.ts +17 -0
  11. package/dist/BannerAlert.js +17 -0
  12. package/dist/BannerAlert.js.map +1 -1
  13. package/dist/Button.d.ts +16 -0
  14. package/dist/Button.js +16 -0
  15. package/dist/Button.js.map +1 -1
  16. package/dist/Card.d.ts +12 -0
  17. package/dist/Card.js +12 -0
  18. package/dist/Card.js.map +1 -1
  19. package/dist/Checkbox.d.ts +21 -0
  20. package/dist/Checkbox.js +21 -0
  21. package/dist/Checkbox.js.map +1 -1
  22. package/dist/CheckboxGroup.d.ts +30 -0
  23. package/dist/CheckboxGroup.js +23 -0
  24. package/dist/CheckboxGroup.js.map +1 -1
  25. package/dist/CheckboxOption.d.ts +23 -1
  26. package/dist/CheckboxOption.js +25 -2
  27. package/dist/CheckboxOption.js.map +1 -1
  28. package/dist/Chip.d.ts +11 -0
  29. package/dist/Chip.js +11 -0
  30. package/dist/Chip.js.map +1 -1
  31. package/dist/Dialog.d.ts +19 -0
  32. package/dist/Dialog.js +19 -0
  33. package/dist/Dialog.js.map +1 -1
  34. package/dist/Divider.d.ts +13 -0
  35. package/dist/Divider.js +13 -0
  36. package/dist/Divider.js.map +1 -1
  37. package/dist/Dropdown.d.ts +30 -0
  38. package/dist/Dropdown.js +30 -0
  39. package/dist/Dropdown.js.map +1 -1
  40. package/dist/DropdownField.d.ts +22 -0
  41. package/dist/DropdownField.js +22 -0
  42. package/dist/DropdownField.js.map +1 -1
  43. package/dist/EmptyState.d.ts +11 -0
  44. package/dist/EmptyState.js +11 -0
  45. package/dist/EmptyState.js.map +1 -1
  46. package/dist/Fab.d.ts +8 -0
  47. package/dist/Fab.js +8 -0
  48. package/dist/Fab.js.map +1 -1
  49. package/dist/FormField.d.ts +25 -0
  50. package/dist/FormField.js +25 -0
  51. package/dist/FormField.js.map +1 -1
  52. package/dist/Img.d.ts +7 -0
  53. package/dist/Img.js +7 -0
  54. package/dist/Img.js.map +1 -1
  55. package/dist/InlineAlert.d.ts +7 -0
  56. package/dist/InlineAlert.js +7 -0
  57. package/dist/InlineAlert.js.map +1 -1
  58. package/dist/Layout.d.ts +7 -0
  59. package/dist/Layout.js +7 -0
  60. package/dist/Layout.js.map +1 -1
  61. package/dist/Link.d.ts +25 -4
  62. package/dist/Link.js +9 -2
  63. package/dist/Link.js.map +1 -1
  64. package/dist/ListItem.d.ts +15 -0
  65. package/dist/ListItem.js +15 -0
  66. package/dist/ListItem.js.map +1 -1
  67. package/dist/Menu.d.ts +28 -0
  68. package/dist/Menu.js +29 -1
  69. package/dist/Menu.js.map +1 -1
  70. package/dist/MenuButton.d.ts +7 -0
  71. package/dist/MenuButton.js +7 -0
  72. package/dist/MenuButton.js.map +1 -1
  73. package/dist/Modal.d.ts +23 -1
  74. package/dist/Modal.js +23 -1
  75. package/dist/Modal.js.map +1 -1
  76. package/dist/NumberField.d.ts +19 -0
  77. package/dist/NumberField.js +19 -0
  78. package/dist/NumberField.js.map +1 -1
  79. package/dist/NumberInput.d.ts +16 -0
  80. package/dist/NumberInput.js +16 -0
  81. package/dist/NumberInput.js.map +1 -1
  82. package/dist/Popover.d.ts +29 -2
  83. package/dist/Popover.js +30 -3
  84. package/dist/Popover.js.map +1 -1
  85. package/dist/ProgressBar.d.ts +8 -0
  86. package/dist/ProgressBar.js +9 -1
  87. package/dist/ProgressBar.js.map +1 -1
  88. package/dist/ProgressCircle.d.ts +8 -0
  89. package/dist/ProgressCircle.js +8 -0
  90. package/dist/ProgressCircle.js.map +1 -1
  91. package/dist/ProgressionStepper.d.ts +12 -0
  92. package/dist/ProgressionStepper.js +12 -0
  93. package/dist/ProgressionStepper.js.map +1 -1
  94. package/dist/RadioGroup.d.ts +38 -6
  95. package/dist/RadioGroup.js +34 -5
  96. package/dist/RadioGroup.js.map +1 -1
  97. package/dist/RadioOption.d.ts +3 -1
  98. package/dist/RadioOption.js +5 -2
  99. package/dist/RadioOption.js.map +1 -1
  100. package/dist/SearchBar.d.ts +34 -0
  101. package/dist/SearchBar.js +34 -0
  102. package/dist/SearchBar.js.map +1 -1
  103. package/dist/SegmentedControl.d.ts +35 -8
  104. package/dist/SegmentedControl.js +24 -2
  105. package/dist/SegmentedControl.js.map +1 -1
  106. package/dist/Skeleton.d.ts +3 -1
  107. package/dist/Skeleton.js +3 -1
  108. package/dist/Skeleton.js.map +1 -1
  109. package/dist/StylesProviderAnywhere.js +1 -1
  110. package/dist/StylesProviderBetterHomesGardens.js +1 -1
  111. package/dist/StylesProviderCartus.js +1 -1
  112. package/dist/StylesProviderCentury21.js +1 -1
  113. package/dist/StylesProviderColdwellBanker.js +1 -1
  114. package/dist/StylesProviderCorcoran.js +1 -1
  115. package/dist/StylesProviderDenaliBoss.js +1 -1
  116. package/dist/StylesProviderEra.js +1 -1
  117. package/dist/StylesProviderSothebys.js +1 -1
  118. package/dist/Switch.d.ts +18 -1
  119. package/dist/Switch.js +18 -1
  120. package/dist/Switch.js.map +1 -1
  121. package/dist/SwitchOption.d.ts +4 -2
  122. package/dist/SwitchOption.js +5 -2
  123. package/dist/SwitchOption.js.map +1 -1
  124. package/dist/TabGroup.d.ts +26 -5
  125. package/dist/TabGroup.js +20 -0
  126. package/dist/TabGroup.js.map +1 -1
  127. package/dist/Tag.d.ts +13 -1
  128. package/dist/Tag.js +13 -1
  129. package/dist/Tag.js.map +1 -1
  130. package/dist/TextField.d.ts +21 -2
  131. package/dist/TextField.js +22 -2
  132. package/dist/TextField.js.map +1 -1
  133. package/dist/TextInput.d.ts +22 -3
  134. package/dist/TextInput.js +20 -2
  135. package/dist/TextInput.js.map +1 -1
  136. package/dist/Textarea.d.ts +23 -4
  137. package/dist/Textarea.js +27 -7
  138. package/dist/Textarea.js.map +1 -1
  139. package/dist/TextareaField.d.ts +21 -1
  140. package/dist/TextareaField.js +24 -2
  141. package/dist/TextareaField.js.map +1 -1
  142. package/dist/ToggleOption.d.ts +8 -5
  143. package/dist/ToggleOption.js +3 -3
  144. package/dist/ToggleOption.js.map +1 -1
  145. package/dist/Tooltip.d.ts +15 -3
  146. package/dist/Tooltip.js +21 -7
  147. package/dist/Tooltip.js.map +1 -1
  148. package/dist/Txt.d.ts +9 -1
  149. package/dist/Txt.js +9 -1
  150. package/dist/Txt.js.map +1 -1
  151. package/dist/badge.css +1 -1
  152. package/dist/base.css +1 -1
  153. package/dist/demo/examples.js +22 -1
  154. package/dist/demo/examples.js.map +1 -1
  155. package/dist/progress-bar.css +1 -1
  156. package/dist/radio-group.css +1 -0
  157. package/dist/textarea.css +1 -1
  158. package/dist/toggle-option.css +1 -1
  159. package/dist/tooltip.css +1 -1
  160. package/meta.ts +8 -6
  161. package/package.json +1 -1
  162. package/src/Avatar.tsx +18 -2
  163. package/src/AvatarGroup.tsx +14 -0
  164. package/src/Badge.tsx +61 -8
  165. package/src/BannerAlert.tsx +17 -0
  166. package/src/Button.tsx +16 -0
  167. package/src/Card.tsx +12 -0
  168. package/src/Checkbox.tsx +21 -0
  169. package/src/CheckboxGroup.tsx +30 -0
  170. package/src/CheckboxOption.tsx +29 -4
  171. package/src/Chip.tsx +11 -0
  172. package/src/Dialog.tsx +19 -0
  173. package/src/Divider.tsx +13 -0
  174. package/src/Dropdown.tsx +30 -0
  175. package/src/DropdownField.tsx +22 -0
  176. package/src/EmptyState.tsx +11 -0
  177. package/src/Fab.tsx +8 -0
  178. package/src/FormField.tsx +25 -0
  179. package/src/Img.tsx +7 -0
  180. package/src/InlineAlert.tsx +7 -0
  181. package/src/Layout.tsx +7 -0
  182. package/src/Link.tsx +49 -30
  183. package/src/ListItem.tsx +15 -0
  184. package/src/Menu.tsx +29 -0
  185. package/src/MenuButton.tsx +7 -0
  186. package/src/Modal.tsx +23 -1
  187. package/src/NumberField.tsx +19 -0
  188. package/src/NumberInput.tsx +16 -0
  189. package/src/Popover.tsx +53 -5
  190. package/src/ProgressBar.tsx +8 -0
  191. package/src/ProgressCircle.tsx +8 -0
  192. package/src/ProgressionStepper.tsx +12 -0
  193. package/src/RadioGroup.tsx +68 -25
  194. package/src/RadioOption.tsx +9 -4
  195. package/src/SearchBar.tsx +47 -3
  196. package/src/SegmentedControl.tsx +57 -14
  197. package/src/Skeleton.tsx +3 -1
  198. package/src/Switch.tsx +18 -1
  199. package/src/SwitchOption.tsx +11 -6
  200. package/src/TabGroup.tsx +30 -6
  201. package/src/Tag.tsx +13 -1
  202. package/src/TextField.tsx +37 -6
  203. package/src/TextInput.tsx +36 -5
  204. package/src/Textarea.tsx +41 -9
  205. package/src/TextareaField.tsx +33 -4
  206. package/src/ToggleOption.tsx +9 -6
  207. package/src/Tooltip.tsx +29 -9
  208. package/src/Txt.tsx +14 -2
  209. package/src/badge.scss +36 -7
  210. package/src/base.scss +14 -2
  211. package/src/demo/examples.tsx +28 -0
  212. package/src/progress-bar.scss +0 -2
  213. package/src/radio-group.scss +5 -0
  214. package/src/textarea.scss +4 -0
  215. package/src/toggle-option.scss +1 -20
  216. package/src/tooltip.scss +4 -4
  217. package/dist/SwitchGroup.d.ts +0 -42
  218. package/dist/SwitchGroup.js +0 -16
  219. package/dist/SwitchGroup.js.map +0 -1
  220. package/dist/hooks/useSwitchGroupState.d.ts +0 -37
  221. package/dist/hooks/useSwitchGroupState.js +0 -57
  222. package/dist/hooks/useSwitchGroupState.js.map +0 -1
  223. package/src/SwitchGroup.tsx +0 -72
  224. package/src/hooks/useSwitchGroupState.ts +0 -75
package/src/Link.tsx CHANGED
@@ -4,41 +4,61 @@ import { SvgOpenInNew } from '@bspk/icons/OpenInNew';
4
4
  import './link.scss';
5
5
  import { AnchorHTMLAttributes } from 'react';
6
6
 
7
- import { CommonPropsLibrary } from '.';
7
+ import { CommonPropsLibrary, ElementProps } from '.';
8
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
- };
9
+ export type LinkProps = Pick<CommonPropsLibrary, 'disabled'> & {
10
+ /**
11
+ * The label of the link.
12
+ *
13
+ * @required
14
+ */
15
+ label: string;
16
+ /** The variant of the link. Controls the icon that is displayed and link target. */
17
+ trailingIcon?: 'chevron' | 'external' | 'link';
18
+ /**
19
+ * The [href](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#href) of the link.
20
+ *
21
+ * @example
22
+ * https://bspk.dev
23
+ */
24
+ href: AnchorHTMLAttributes<unknown>['href'];
25
+ /**
26
+ * The size of the link.
27
+ *
28
+ * @default base
29
+ */
30
+ size?: 'base' | 'large' | 'small';
31
+ /**
32
+ * Change the color of the link to a subtle color. This is useful for links that are not primary actions, for
33
+ * example footer menus.
34
+ *
35
+ * @default default
36
+ */
37
+ variant?: 'default' | 'subtle-inverse' | 'subtle';
38
+ /**
39
+ * The [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#target) of the link. If the
40
+ * `trailingIcon` is set to `external`, this will default to `_blank`.
41
+ *
42
+ * @default _self
43
+ *
44
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target
45
+ */
46
+ target?: '_blank' | '_parent' | '_self' | '_top';
47
+ };
35
48
 
36
49
  /**
37
50
  * This is the standalone link component. Inline links can use the native `a` element.
38
51
  *
52
+ * @example
53
+ * import { Link } from '@bspk/ui/Link';
54
+ *
55
+ * export function Example() {
56
+ * return <Link href="https://bspk.dev" label="Example label" trailingIcon="external" />;
57
+ * }
58
+ *
39
59
  * @name Link
40
60
  */
41
- function Link({ label, trailingIcon, size, variant, ...props }: LinkProps) {
61
+ function Link({ label, trailingIcon, size, variant, target = '_self', ...props }: ElementProps<LinkProps, 'a'>) {
42
62
  return (
43
63
  <a
44
64
  {...props}
@@ -46,8 +66,7 @@ function Link({ label, trailingIcon, size, variant, ...props }: LinkProps) {
46
66
  data-size={size}
47
67
  data-subtle={variant === 'subtle' || undefined}
48
68
  data-subtle-inverse={variant === 'subtle-inverse' || undefined}
49
- rel="noreferrer"
50
- target={trailingIcon === 'external' ? '_blank' : props.target}
69
+ target={trailingIcon === 'external' ? '_blank' : target}
51
70
  >
52
71
  <span>{label}</span>
53
72
  {trailingIcon === 'external' && <SvgOpenInNew />}
package/src/ListItem.tsx CHANGED
@@ -67,6 +67,21 @@ export type ListItemProps<As extends ElementType = 'div'> = CommonProps<'active'
67
67
  *
68
68
  * The ListItemButton is a more limited Button with context specific options.
69
69
  *
70
+ * @example
71
+ * import { SvgSquare } from '@bspk/icons/Square';
72
+ * import { ListItem } from '@bspk/ui/ListItem';
73
+ *
74
+ * export function Example() {
75
+ * return (
76
+ * <ListItem
77
+ * label="Example label"
78
+ * leading={<SvgSquare />}
79
+ * subText="Example subtest"
80
+ * trailing={<ListItem.Button label="Click me" onClick={() => console.log('Hello world')} />}
81
+ * />
82
+ * );
83
+ * }
84
+ *
70
85
  * @subComponents ListItemButton
71
86
  *
72
87
  * @name ListItem
package/src/Menu.tsx CHANGED
@@ -114,6 +114,34 @@ export type MenuProps<T extends MenuItem = MenuItem> = CommonProps<'disabled' |
114
114
  /**
115
115
  * A container housing a simple list of options presented to the user to select one option at a time.
116
116
  *
117
+ * @example
118
+ * import React from 'react';
119
+ *
120
+ * import { Menu } from '@bspk/ui/Menu';
121
+ *
122
+ * export function Example() {
123
+ * const [selected, setSelected] = React.useState<string[]>([]);
124
+ *
125
+ * return (
126
+ * <Menu
127
+ * items={[
128
+ * { value: '1', label: 'Option 1' },
129
+ * { value: '2', label: 'Option 2' },
130
+ * { value: '3', label: 'Option 3' },
131
+ * { value: '4', label: 'Option 4' },
132
+ * { value: '5', label: 'Option 5' },
133
+ * { value: '6', label: 'Option 6' },
134
+ * { value: '7', label: 'Option 7' },
135
+ * { value: '8', label: 'Option 8' },
136
+ * { value: '9', label: 'Option 9' },
137
+ * { value: '10', label: 'Option 10' },
138
+ * ]}
139
+ * onChange={(selectedValues: string[]) => setSelected(selectedValues)}
140
+ * selectedValues={selected}
141
+ * />
142
+ * );
143
+ * }
144
+ *
117
145
  * @name Menu
118
146
  */
119
147
  function Menu({
@@ -185,6 +213,7 @@ function Menu({
185
213
  <Checkbox
186
214
  aria-label={selectAll}
187
215
  checked={!!allSelected}
216
+ indeterminate={!allSelected && selectedValues.length > 0}
188
217
  name=""
189
218
  onChange={(checked) => {
190
219
  onChange?.(checked ? items.map((item) => item.value) : []);
@@ -10,6 +10,13 @@ export type MenuButtonProps = Pick<ButtonProps, 'as' | 'onClick'>;
10
10
  /**
11
11
  * Utility component used within top navigation.
12
12
  *
13
+ * @example
14
+ * import { MenuButton } from '@bspk/ui/MenuButton';
15
+ *
16
+ * export function Example() {
17
+ * return <MenuButton />;
18
+ * }
19
+ *
13
20
  * @name MenuButton
14
21
  */
15
22
  function MenuButton(props: ElementProps<MenuButtonProps, 'button'>) {
package/src/Modal.tsx CHANGED
@@ -28,7 +28,29 @@ export type ModalProps = DialogProps & {
28
28
  * interactions until an action is selected. Modal is a wrapper around the Dialog component that provides a header and
29
29
  * footer for the dialog.
30
30
  *
31
- * TODO: Add support for custom header and footer
31
+ * @example
32
+ * import React from 'react';
33
+ *
34
+ * import { Button } from '@bspk/ui/Button';
35
+ * import { Modal } from '@bspk/ui/Modal';
36
+ *
37
+ * export function Example() {
38
+ * const [open, setOpen] = React.useState(false);
39
+ *
40
+ * return (
41
+ * <>
42
+ * <Button label="Open Dialog" onClick={() => setOpen(true)} />
43
+ * <Modal
44
+ * description="Example description"
45
+ * header="Example header"
46
+ * onClose={() => setOpen(false)}
47
+ * open={open}
48
+ * >
49
+ * Example Modal
50
+ * </Modal>
51
+ * </>
52
+ * );
53
+ * }
32
54
  *
33
55
  * @name Modal
34
56
  */
@@ -13,6 +13,25 @@ export type NumberFieldProps = InvalidPropsLibrary &
13
13
  *
14
14
  * This component takes properties from the FormField and NumberInput components.
15
15
  *
16
+ * @example
17
+ * import React from 'react';
18
+ *
19
+ * import { NumberField } from '@bspk/ui/NumberField';
20
+ *
21
+ * export function Example() {
22
+ * const [state, setState] = React.useState<number>();
23
+ *
24
+ * return (
25
+ * <NumberField
26
+ * controlId="Example controlId"
27
+ * label="Example label"
28
+ * name="Example name"
29
+ * onChange={(nextValue) => setState(nextValue)}
30
+ * value={state}
31
+ * />
32
+ * );
33
+ * }
34
+ *
16
35
  * @name NumberField
17
36
  */
18
37
  function NumberField({
@@ -61,6 +61,22 @@ export type NumberInputProps = CommonProps<'aria-label' | 'disabled' | 'id' | 'n
61
61
  *
62
62
  * The value of the input is a number. The value is clamped to the min and max values if they are provided.
63
63
  *
64
+ * @example
65
+ * import { NumberInput } from '@bspk/ui/NumberInput';
66
+ *
67
+ * export function Example() {
68
+ * const [state, setState] = React.useState<number>();
69
+ *
70
+ * return (
71
+ * <NumberInput
72
+ * aria-label="Example aria-label"
73
+ * name="Example name"
74
+ * onChange={(nextValue) => setState(nextValue)}
75
+ * value={state}
76
+ * />
77
+ * );
78
+ * }
79
+ *
64
80
  * @name NumberInput
65
81
  */
66
82
  function NumberInput({
package/src/Popover.tsx CHANGED
@@ -1,6 +1,13 @@
1
1
  import { SvgClose } from '@bspk/icons/Close';
2
2
  import './popover.scss';
3
- import { ReactElement, cloneElement, useId, useMemo, useRef, useState } from 'react';
3
+ import {
4
+ ReactElement,
5
+ cloneElement,
6
+ useId,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ } from 'react';
4
11
 
5
12
  import { Button } from './Button';
6
13
  import { Portal } from './Portal';
@@ -41,11 +48,45 @@ export type PopoverProps = CommonProps<'disabled'> & {
41
48
  };
42
49
 
43
50
  /**
44
- * Brief message that provide additional guidance and helps users perform an action if needed.
51
+ * Brief message that provide additional guidance and helps users perform an
52
+ * action if needed.
53
+ *
54
+ * @example
55
+ * import { useState } from 'react';
56
+ * import { Popover } from '@bspk/ui/Popover';
57
+ * import { Button } from '@bspk/ui/Button';
58
+ *
59
+ * export function Example() {
60
+ * const [showPopover, setShowPopover] = useState<boolean>(false);
61
+ *
62
+ * const togglePopover = () => setShowPopover(!showPopover);
63
+ * const onPopoverCallToActionClick = () => alert('Action clicked');
64
+ *
65
+ * return (
66
+ * <Popover
67
+ * placement="bottom"
68
+ * content="This is a popover content"
69
+ * header="Popover Header"
70
+ * callToAction={{
71
+ * label: 'Action',
72
+ * onClick: onPopoverCallToActionClick,
73
+ * }}
74
+ * >
75
+ * <Button label="Toggle popover" onClick={togglePopover} />
76
+ * </Popover>
77
+ * );
78
+ * }
45
79
  *
46
80
  * @name Popover
47
81
  */
48
- function Popover({ placement = 'top', header, content, callToAction, children, disabled = false }: PopoverProps) {
82
+ function Popover({
83
+ placement = 'top',
84
+ header,
85
+ content,
86
+ callToAction,
87
+ children,
88
+ disabled = false,
89
+ }: PopoverProps) {
49
90
  const id = useId();
50
91
  const [show, setShow] = useState(false);
51
92
  const arrowRef = useRef<HTMLElement | null>(null);
@@ -83,13 +124,20 @@ function Popover({ placement = 'top', header, content, callToAction, children, d
83
124
  id={id}
84
125
  ref={(node) => {
85
126
  elements.setFloating(node);
86
- elements.setTrigger(document.querySelector<HTMLElement>(`[aria-describedby="${id}"]`));
127
+ elements.setTrigger(
128
+ document.querySelector<HTMLElement>(
129
+ `[aria-describedby="${id}"]`,
130
+ ),
131
+ );
87
132
  }}
88
133
  style={floatingStyles}
89
134
  >
90
135
  <header>
91
136
  <Txt variant="heading-h6">{header}</Txt>
92
- <button aria-label="Close" onClick={() => setShow(false)}>
137
+ <button
138
+ aria-label="Close"
139
+ onClick={() => setShow(false)}
140
+ >
93
141
  <SvgClose />
94
142
  </button>
95
143
  </header>
@@ -36,6 +36,14 @@ export type ProgressBarProps = {
36
36
  * occurring in the background.
37
37
  *
38
38
  * @name ProgressBar
39
+ * @example
40
+ * import { ProgressBar } from '@bspk/ui/ProgressBar';
41
+ *
42
+ * export function Example() {
43
+ * return (
44
+ * <ProgressBar label="Example label" completion={50} />
45
+ * );
46
+ * }
39
47
  */
40
48
  function ProgressBar({ size = 'large', completion = 0, align = 'center', label }: ProgressBarProps) {
41
49
  const id = useId();
@@ -27,6 +27,14 @@ export type ProgressCircleProps = {
27
27
  * Rotating circle or pill that indicates the status or state of completion for a process that’s part of a user flow.
28
28
  *
29
29
  * @name ProgressCircle
30
+ * @example
31
+ * import { ProgressCircle } from '@bspk/ui/ProgressCircle';
32
+ *
33
+ * export function Example() {
34
+ * return (
35
+ * <ProgressCircle label="Example label"/>
36
+ * );
37
+ * }
30
38
  */
31
39
  function ProgressCircle({ label, labelPosition, size = 'medium' }: ProgressCircleProps) {
32
40
  let variant: TxtVariant = 'labels-base';
@@ -66,6 +66,18 @@ export type ProgressionStepperProps = {
66
66
  * A progress stepper is a horizontal visual indicator that let’s the user know the progression of the current process.
67
67
  *
68
68
  * @name ProgressionStepper
69
+ * @example
70
+ * import { ProgressionStepper } from '@bspk/ui/ProgressionStepper';
71
+ *
72
+ * export function Example() {
73
+ * return (
74
+ * <ProgressionStepper steps={[
75
+ * { name: 'Step 1' },
76
+ * { name: 'Step 2' },
77
+ * { name: 'Step 3' },
78
+ * ]} />
79
+ * );
80
+ * }
69
81
  */
70
82
  function ProgressionStepper({
71
83
  steps = [],
@@ -1,8 +1,12 @@
1
+ import { useId } from 'react';
2
+
1
3
  import { Radio } from './Radio';
2
4
  import { ToggleOptionProps, ToggleOption } from './ToggleOption';
3
5
 
4
6
  import { ElementProps, CommonProps } from './';
5
7
 
8
+ import './radio-group.scss';
9
+
6
10
  export type RadioGroupOption = Pick<ToggleOptionProps, 'description' | 'label'> & Required<CommonProps<'value'>>;
7
11
 
8
12
  export type RadioGroupProps = CommonProps<'name'> & {
@@ -29,8 +33,8 @@ export type RadioGroupProps = CommonProps<'name'> & {
29
33
  *
30
34
  * @example
31
35
  * [
32
- * { value: '1', label: 'Option 1', description: 'Description here' },
33
- * { value: '2', label: 'Option 2' },
36
+ * { value: '1', label: 'Option 1' },
37
+ * { value: '2', label: 'Option 2', description: 'Description here' },
34
38
  * { value: '3', label: 'Option 3' },
35
39
  * ];
36
40
  *
@@ -39,16 +43,47 @@ export type RadioGroupProps = CommonProps<'name'> & {
39
43
  */
40
44
  options: RadioGroupOption[];
41
45
  /**
42
- * The size of the radio group labels.
46
+ * The label of the radio group.
47
+ *
48
+ * @required
49
+ */
50
+ label: string;
51
+ /**
52
+ * Shows the RadioGroup label. When label isn't showing it is used as the aria-label prop.
43
53
  *
44
- * @default base
54
+ * @default true
45
55
  */
46
- size?: 'base' | 'large' | 'small';
56
+ showLabel?: boolean;
47
57
  };
48
58
 
49
59
  /**
50
60
  * A group of radios that allows users to choose one or more items from a list or turn an feature on or off.
51
61
  *
62
+ * @example
63
+ * import { useState } from 'react';
64
+ * import { RadioGroup } from '@bspk/ui/RadioGroup';
65
+ *
66
+ * export function Example() {
67
+ * const [selectedOption, setSelectedOption] = useState<string>('1');
68
+ *
69
+ * return (
70
+ * <RadioGroup
71
+ * name="Example name"
72
+ * onChange={(nextValue) => setSelectedOption(nextValue)}
73
+ * options={[
74
+ * {
75
+ * value: '1',
76
+ * label: 'Option 1',
77
+ * description: 'Description here',
78
+ * },
79
+ * { value: '2', label: 'Option 2' },
80
+ * { value: '3', label: 'Option 3' },
81
+ * ]}
82
+ * value={selectedOption}
83
+ * />
84
+ * );
85
+ * }
86
+ *
52
87
  * @name RadioGroup
53
88
  */
54
89
  function RadioGroup({
@@ -56,29 +91,37 @@ function RadioGroup({
56
91
  options = [],
57
92
  name,
58
93
  value: groupValue,
59
- size = 'base',
94
+ label: groupLabel,
95
+ showLabel = true,
60
96
  ...props
61
97
  }: ElementProps<RadioGroupProps, 'div'>) {
98
+ const id = `radio-group-${useId()}`;
99
+
62
100
  return (
63
- <div {...props} data-bspk="radio-group" role="radiogroup" style={{ display: 'contents' }}>
64
- {options.map(({ label, description, value }, index) => {
65
- return (
66
- <ToggleOption
67
- description={description}
68
- key={`toggle-option-${value || index}`}
69
- label={label}
70
- size={size}
71
- >
72
- <Radio
73
- aria-label={label}
74
- checked={groupValue === value}
75
- name={name}
76
- onChange={(checked) => checked && onChange(value)}
77
- value={value}
78
- />
79
- </ToggleOption>
80
- );
81
- })}
101
+ <div
102
+ {...props}
103
+ aria-label={!showLabel ? groupLabel : undefined}
104
+ aria-labelledby={showLabel ? `${id}-label` : undefined}
105
+ data-bspk="radio-group"
106
+ id={id}
107
+ role="group"
108
+ >
109
+ {showLabel && <label id={`${id}-label`}>{groupLabel}</label>}
110
+ <div role="radiogroup">
111
+ {options.map(({ label, description, value }, index) => {
112
+ return (
113
+ <ToggleOption description={description} key={`toggle-option-${value || index}`} label={label}>
114
+ <Radio
115
+ aria-label={label}
116
+ checked={groupValue === value}
117
+ name={name}
118
+ onChange={(checked) => checked && onChange(value)}
119
+ value={value}
120
+ />
121
+ </ToggleOption>
122
+ );
123
+ })}
124
+ </div>
82
125
  </div>
83
126
  );
84
127
  }
@@ -19,13 +19,18 @@ export type RadioOptionProps = InvalidPropsLibrary &
19
19
  /**
20
20
  * A control that allows users to choose one or more items from a list or turn an feature on or off.
21
21
  *
22
+ * If only a radio button is needed, consider using the `Radio` component directly.
23
+ *
22
24
  * @name RadioOption
23
25
  */
24
- function RadioOption({ label, description, ...checkboxProps }: RadioOptionProps) {
26
+ function RadioOption({ label: labelProp, description, ...checkboxProps }: RadioOptionProps) {
27
+ const label = labelProp || description;
25
28
  return (
26
- <ToggleOption data-bspk="radio-option" description={description} label={label}>
27
- <Radio {...checkboxProps} aria-label={label} />
28
- </ToggleOption>
29
+ label && (
30
+ <ToggleOption data-bspk="radio-option" description={description} label={label}>
31
+ <Radio {...checkboxProps} aria-label={label} />
32
+ </ToggleOption>
33
+ )
29
34
  );
30
35
  }
31
36
 
package/src/SearchBar.tsx CHANGED
@@ -10,7 +10,10 @@ import { useFloatingMenu } from './hooks/useFloatingMenu';
10
10
  import { useId } from './hooks/useId';
11
11
  //import { useFloatingMenu } from './hooks/useFloatingMenu';
12
12
 
13
- export type SearchBarProps<T extends MenuItem = MenuItem> = Pick<MenuProps<T>, 'itemCount' | 'noResultsMessage'> &
13
+ export type SearchBarProps<T extends MenuItem = MenuItem> = Pick<
14
+ MenuProps<T>,
15
+ 'itemCount' | 'noResultsMessage'
16
+ > &
14
17
  Pick<TextInputProps, 'aria-label' | 'id' | 'inputRef' | 'name' | 'size'> & {
15
18
  /** The current value of the search bar. */
16
19
  value?: string;
@@ -73,6 +76,40 @@ export type SearchBarProps<T extends MenuItem = MenuItem> = Pick<MenuProps<T>, '
73
76
  /**
74
77
  * Component description coming soon.
75
78
  *
79
+ * @example
80
+ * import { useState } from 'react';
81
+ * import { SearchBar } from '@bspk/ui/SearchBar';
82
+ *
83
+ * export function Example() {
84
+ * const [searchText, setSearchText] = useState<string>('');
85
+ *
86
+ * const handleItemSelect = (item) =>
87
+ * console.log('Selected item:', item);
88
+ *
89
+ * return (
90
+ * <SearchBar
91
+ * aria-label="Example aria-label"
92
+ * items={[
93
+ * { value: '1', label: 'Apple Pie' },
94
+ * { value: '2', label: 'Banana Split' },
95
+ * { value: '3', label: 'Cherry Tart' },
96
+ * { value: '4', label: 'Dragonfruit Sorbet' },
97
+ * { value: '5', label: 'Elderberry Jam' },
98
+ * { value: '6', label: 'Fig Newton' },
99
+ * { value: '7', label: 'Grape Soda' },
100
+ * { value: '8', label: 'Honeydew Smoothie' },
101
+ * { value: '9', label: 'Ice Cream Sandwich' },
102
+ * { value: '10', label: 'Jackfruit Pudding' },
103
+ * ]}
104
+ * name="Example name"
105
+ * placeholder="Search"
106
+ * value={searchText}
107
+ * onChange={setSearchText}
108
+ * onSelect={handleItemSelect}
109
+ * />
110
+ * );
111
+ * }
112
+ *
76
113
  * @name SearchBar
77
114
  */
78
115
  function SearchBar({
@@ -92,7 +129,12 @@ function SearchBar({
92
129
  }: SearchBarProps) {
93
130
  const id = useId(idProp);
94
131
  const {
95
- triggerProps: { ref: triggerRef, onClick, onKeyDownCapture, ...triggerProps },
132
+ triggerProps: {
133
+ ref: triggerRef,
134
+ onClick,
135
+ onKeyDownCapture,
136
+ ...triggerProps
137
+ },
96
138
  menuProps,
97
139
  closeMenu,
98
140
  } = useFloatingMenu({
@@ -154,7 +196,9 @@ function SearchBar({
154
196
  }
155
197
  onChange={(selectedValues, event) => {
156
198
  event?.preventDefault();
157
- const item = items?.find((i) => i.value === selectedValues[0]);
199
+ const item = items?.find(
200
+ (i) => i.value === selectedValues[0],
201
+ );
158
202
  onSelect?.(item);
159
203
  onChange(item?.label || '');
160
204
  closeMenu();