@westpac/ui 1.18.0 → 1.19.0

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 (64) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/component-type.json +1 -1
  3. package/dist/components/button-group/button-group.component.d.ts +2 -1
  4. package/dist/components/button-group/button-group.component.js +6 -3
  5. package/dist/components/checkbox-group/checkbox-group.component.d.ts +11 -2
  6. package/dist/components/checkbox-group/checkbox-group.component.js +10 -3
  7. package/dist/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.d.ts +1 -1
  8. package/dist/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.js +5 -6
  9. package/dist/components/date-picker/components/date-field/components/date-segment/date-segment.component.d.ts +6 -5
  10. package/dist/components/date-picker/components/date-field/components/date-segment/date-segment.component.js +6 -4
  11. package/dist/components/date-picker/components/date-field/date-field.component.d.ts +5 -5
  12. package/dist/components/date-picker/components/date-field/date-field.component.js +7 -3
  13. package/dist/components/date-picker/date-picker.component.d.ts +19 -2
  14. package/dist/components/date-picker/date-picker.component.js +10 -5
  15. package/dist/components/date-picker/date-picker.styles.js +5 -5
  16. package/dist/components/multi-select/components/multi-select-list-box/components/multi-select-option/multi-select-option.component.js +3 -7
  17. package/dist/components/multi-select/components/multi-select-list-box/components/multi-select-select-all-option/multi-select-select-all-option.component.js +3 -3
  18. package/dist/components/multi-select/components/multi-select-popover/multi-select-popover.component.js +5 -2
  19. package/dist/components/multi-select/components/multi-select-searchbar/multi-select-searchbar.component.js +4 -7
  20. package/dist/components/multi-select/multi-select.component.d.ts +14 -3
  21. package/dist/components/multi-select/multi-select.component.js +10 -16
  22. package/dist/components/radio-group/components/radio-group-radio/radio-group-radio.component.d.ts +1 -1
  23. package/dist/components/radio-group/components/radio-group-radio/radio-group-radio.component.js +5 -6
  24. package/dist/components/radio-group/radio-group.component.d.ts +10 -2
  25. package/dist/components/radio-group/radio-group.component.js +10 -3
  26. package/dist/components/selector/components/selector-button-group/selector-button-group.component.d.ts +9 -2
  27. package/dist/components/selector/components/selector-button-group/selector-button-group.component.js +8 -3
  28. package/dist/components/selector/components/selector-checkbox-group/selector-checkbox-group.component.d.ts +6 -2
  29. package/dist/components/selector/components/selector-checkbox-group/selector-checkbox-group.component.js +8 -3
  30. package/dist/components/selector/components/selector-radio-group/selector-radio-group.component.d.ts +6 -2
  31. package/dist/components/selector/components/selector-radio-group/selector-radio-group.component.js +8 -3
  32. package/dist/components/selector/selector.component.d.ts +3 -1
  33. package/dist/components/selector/selector.component.js +16 -5
  34. package/dist/components/switch/switch.component.d.ts +8 -2
  35. package/dist/components/switch/switch.component.js +6 -4
  36. package/dist/css/westpac-ui.css +12 -12
  37. package/dist/css/westpac-ui.min.css +12 -12
  38. package/dist/hook/focus-manager-ref.hook.d.ts +29 -0
  39. package/dist/hook/focus-manager-ref.hook.js +23 -0
  40. package/dist/hook/index.d.ts +1 -0
  41. package/dist/index.d.ts +1 -0
  42. package/package.json +5 -4
  43. package/src/components/button-group/button-group.component.tsx +26 -16
  44. package/src/components/checkbox-group/checkbox-group.component.tsx +24 -14
  45. package/src/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.tsx +7 -7
  46. package/src/components/date-picker/components/date-field/components/date-segment/date-segment.component.tsx +10 -4
  47. package/src/components/date-picker/components/date-field/date-field.component.tsx +17 -3
  48. package/src/components/date-picker/date-picker.component.tsx +32 -21
  49. package/src/components/date-picker/date-picker.styles.ts +5 -5
  50. package/src/components/multi-select/components/multi-select-list-box/components/multi-select-option/multi-select-option.component.tsx +3 -5
  51. package/src/components/multi-select/components/multi-select-list-box/components/multi-select-select-all-option/multi-select-select-all-option.component.tsx +4 -3
  52. package/src/components/multi-select/components/multi-select-popover/multi-select-popover.component.tsx +8 -2
  53. package/src/components/multi-select/components/multi-select-searchbar/multi-select-searchbar.component.tsx +3 -6
  54. package/src/components/multi-select/multi-select.component.tsx +33 -28
  55. package/src/components/radio-group/components/radio-group-radio/radio-group-radio.component.tsx +10 -7
  56. package/src/components/radio-group/radio-group.component.tsx +24 -14
  57. package/src/components/selector/components/selector-button-group/selector-button-group.component.tsx +23 -14
  58. package/src/components/selector/components/selector-checkbox-group/selector-checkbox-group.component.tsx +12 -3
  59. package/src/components/selector/components/selector-radio-group/selector-radio-group.component.tsx +21 -11
  60. package/src/components/selector/selector.component.tsx +16 -5
  61. package/src/components/switch/switch.component.tsx +10 -12
  62. package/src/hook/focus-manager-ref.hook.ts +56 -0
  63. package/src/hook/index.ts +1 -0
  64. package/src/index.ts +1 -0
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import React, { useId, useRef } from 'react';
4
- import { VisuallyHidden, mergeProps, useCheckbox, useFocusRing } from 'react-aria';
3
+ import React, { ForwardedRef, forwardRef, useId } from 'react';
4
+ import { VisuallyHidden, mergeProps, useCheckbox, useFocusRing, useObjectRef } from 'react-aria';
5
5
  import { useToggleState } from 'react-stately';
6
6
 
7
7
  import { useBreakpoint } from '../../hook/breakpoints.hook.js';
@@ -10,18 +10,13 @@ import { resolveResponsiveVariant } from '../../utils/breakpoint.util.js';
10
10
  import { styles as switchStyles } from './switch.styles.js';
11
11
  import { type SwitchProps } from './switch.types.js';
12
12
 
13
- export function Switch({
14
- className,
15
- label,
16
- size = 'medium',
17
- block = false,
18
- checked = false,
19
- isDisabled,
20
- ...props
21
- }: SwitchProps) {
13
+ function BaseSwitch(
14
+ { className, label, size = 'medium', block = false, checked = false, isDisabled, ...props }: SwitchProps,
15
+ forwardedRef: ForwardedRef<HTMLInputElement>,
16
+ ) {
22
17
  const state = useToggleState({ ...props, defaultSelected: checked });
23
18
  const labelId = useId();
24
- const ref = useRef(null);
19
+ const ref = useObjectRef(forwardedRef);
25
20
  const { isSelected } = state;
26
21
  const { inputProps, labelProps } = useCheckbox(
27
22
  { isDisabled, 'aria-labelledby': labelId, defaultSelected: checked, ...props },
@@ -50,3 +45,6 @@ export function Switch({
50
45
  </label>
51
46
  );
52
47
  }
48
+
49
+ export const Switch = forwardRef(BaseSwitch);
50
+ Switch.displayName = 'Switch';
@@ -0,0 +1,56 @@
1
+ 'use client';
2
+
3
+ import { createFocusManager } from '@react-aria/focus';
4
+ import { ForwardedRef, RefObject, useImperativeHandle, useRef } from 'react';
5
+
6
+ /**
7
+ * Imperative handle exposed by group fields (`RadioGroup`, `CheckboxGroup`, `Selector`, `ButtonGroup`) whose
8
+ * focusable control is not a single element the group can point a DOM ref at.
9
+ *
10
+ * `focus()` moves focus to the group's first tabbable option at call time, which is what form libraries
11
+ * such as react-hook-form need (`field.ref` → `ref.focus()` on validation error).
12
+ */
13
+ export type FocusHandle = {
14
+ focus: () => void;
15
+ };
16
+
17
+ export type UseFocusManagerRefOptions = {
18
+ /**
19
+ * Restricts which descendants of the wrapper may receive focus, e.g. only `<input>`s when the wrapper also
20
+ * contains other controls (such as a "show more" button).
21
+ */
22
+ accept?: (node: Element) => boolean;
23
+ };
24
+
25
+ /**
26
+ * Bridges a forwarded {@link FocusHandle} ref to a wrapper element. Returns the ref to attach to the
27
+ * wrapper; `focus()` on the forwarded handle focuses the first tabbable descendant via react-aria's
28
+ * focus manager. Resolution happens when `focus()` is called, so options that render, enable or
29
+ * disable after mount are handled, and roving-tabindex groups (radios) focus their tab stop
30
+ * (the selected option) rather than the first option. When no option is tabbable (e.g. a radio
31
+ * group whose `value` matches no radio, such as `''`), the first focusable option is used instead.
32
+ */
33
+ export function useFocusManagerRef<T extends HTMLElement = HTMLDivElement>(
34
+ forwardedRef: ForwardedRef<FocusHandle>,
35
+ { accept }: UseFocusManagerRefOptions = {},
36
+ ): RefObject<T> {
37
+ const wrapperRef = useRef<T>(null);
38
+
39
+ useImperativeHandle(
40
+ forwardedRef,
41
+ () => ({
42
+ focus: () => {
43
+ const focusManager = createFocusManager(wrapperRef);
44
+ if (!focusManager.focusFirst({ tabbable: true, accept })) {
45
+ focusManager.focusFirst({ accept });
46
+ }
47
+ },
48
+ }),
49
+ [accept],
50
+ );
51
+
52
+ return wrapperRef;
53
+ }
54
+
55
+ /** `accept` predicate for groups whose options are `<input>` elements. */
56
+ export const acceptInputs = (node: Element) => node.tagName === 'INPUT';
package/src/hook/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './dark-mode.hook.js';
2
2
  export * from './breakpoints.hook.js';
3
+ export { type FocusHandle } from './focus-manager-ref.hook.js';
3
4
  export * from '../components/pagination/pagination.hooks.js';
4
5
  export * from './breakpoints.hook.js';
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './components/index.js';
2
2
  export * from './types/index.js';
3
+ export { type FocusHandle } from './hook/focus-manager-ref.hook.js';