@westpac/ui 0.42.1 → 0.42.3

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 (40) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/component-type.json +1 -1
  3. package/dist/components/accordion/accordion.component.js +13 -7
  4. package/dist/components/alert/alert.component.js +3 -1
  5. package/dist/components/alert/alert.styles.js +1 -1
  6. package/dist/components/autocomplete/autocomplete.component.d.ts +8 -1
  7. package/dist/components/autocomplete/autocomplete.component.js +6 -2
  8. package/dist/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.js +5 -5
  9. package/dist/components/date-picker/date-picker.component.js +4 -1
  10. package/dist/components/date-picker/date-picker.styles.d.ts +12 -0
  11. package/dist/components/date-picker/date-picker.styles.js +4 -0
  12. package/dist/components/error-message/error-message.styles.js +1 -1
  13. package/dist/components/filter/components/filter-buttons/filter-buttons.component.js +3 -1
  14. package/dist/components/header/header.styles.js +1 -1
  15. package/dist/components/popover/components/panel/panel.styles.js +1 -1
  16. package/dist/components/popover/popover.component.js +1 -0
  17. package/dist/components/radio-group/components/radio-group-radio/radio-group-radio.component.js +5 -5
  18. package/dist/components/selector/components/selector-radio-group/components/selector-radio-group-option/selector-radio-group-option.component.js +10 -3
  19. package/dist/components/switch/switch.component.js +3 -3
  20. package/dist/css/westpac-ui.css +309 -37
  21. package/dist/css/westpac-ui.min.css +309 -37
  22. package/dist/tailwind/utils/generate-date-picker-component.d.ts +30 -7
  23. package/dist/tailwind/utils/generate-date-picker-component.js +30 -7
  24. package/package.json +2 -2
  25. package/src/components/accordion/accordion.component.tsx +17 -9
  26. package/src/components/alert/alert.component.tsx +9 -2
  27. package/src/components/alert/alert.styles.ts +1 -1
  28. package/src/components/autocomplete/autocomplete.component.tsx +29 -16
  29. package/src/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.tsx +4 -4
  30. package/src/components/date-picker/date-picker.component.tsx +3 -1
  31. package/src/components/date-picker/date-picker.styles.ts +4 -0
  32. package/src/components/error-message/error-message.styles.ts +1 -1
  33. package/src/components/filter/components/filter-buttons/filter-buttons.component.tsx +4 -1
  34. package/src/components/header/header.styles.ts +1 -1
  35. package/src/components/popover/components/panel/panel.styles.ts +1 -1
  36. package/src/components/popover/popover.component.tsx +1 -0
  37. package/src/components/radio-group/components/radio-group-radio/radio-group-radio.component.tsx +4 -4
  38. package/src/components/selector/components/selector-radio-group/components/selector-radio-group-option/selector-radio-group-option.component.tsx +6 -3
  39. package/src/components/switch/switch.component.tsx +2 -2
  40. package/src/tailwind/utils/generate-date-picker-component.ts +32 -8
@@ -21,15 +21,21 @@ import { Item, useTreeState } from 'react-stately';
21
21
  import { styles } from './accordion.styles.js';
22
22
  import { AccordionItem as AccordionItemContent } from './components/index.js';
23
23
  function Accordion({ className , rounded =true , look ='soft' , ...props }, ref) {
24
+ const clonedChildren = [];
25
+ Children.forEach(props.children, (child)=>{
26
+ if (isValidElement(child)) {
27
+ const cloned = {
28
+ ...cloneElement(child, {
29
+ ...child.props,
30
+ hasChildItems: false
31
+ })
32
+ };
33
+ clonedChildren.push(cloned);
34
+ }
35
+ });
24
36
  const finalProps = {
25
37
  ...props,
26
- children: Children.map(props.children, (child)=>{
27
- if (!isValidElement(child)) return child;
28
- return cloneElement(child, {
29
- ...child.props,
30
- hasChildItems: false
31
- });
32
- })
38
+ children: clonedChildren
33
39
  };
34
40
  const state = useTreeState(finalProps);
35
41
  const domRef = useDOMRef(ref);
@@ -15,6 +15,7 @@ function _extends() {
15
15
  }
16
16
  import { AnimatePresence, LazyMotion, m } from 'framer-motion';
17
17
  import React, { useCallback, useEffect, useState } from 'react';
18
+ import { Button } from '../button/button.component.js';
18
19
  import { AlertIcon, CloseIcon, InfoIcon, LimitIcon, SuccessIcon, WarningIcon } from '../icon/index.js';
19
20
  import { styles as alertStyles } from './alert.styles.js';
20
21
  const loadAnimations = ()=>import('./alert.utils.js').then((res)=>res.default);
@@ -81,7 +82,8 @@ export function Alert({ look ='info' , mode ='box' , heading , headingTag: Headi
81
82
  className: styles.body()
82
83
  }, !!heading && React.createElement(HeadingTag, {
83
84
  className: styles.heading()
84
- }, heading), children), dismissible && mode !== 'text' && React.createElement("button", {
85
+ }, heading), children), dismissible && mode !== 'text' && React.createElement(Button, {
86
+ look: "unstyled",
85
87
  type: "button",
86
88
  className: styles.close(),
87
89
  onClick: handleClose,
@@ -5,7 +5,7 @@ export const styles = tv({
5
5
  icon: 'float-left flex-none',
6
6
  body: 'relative flex-1 overflow-hidden xsl:top-[0.125rem] [&_a]:underline',
7
7
  heading: 'typography-body-9 mb-1 font-bold',
8
- close: 'absolute right-0.5 top-0.5 p-1 hover:opacity-80'
8
+ close: 'absolute right-0.5 top-0.5 h-5.5 p-1 hover:opacity-80'
9
9
  },
10
10
  variants: {
11
11
  look: {
@@ -1,2 +1,9 @@
1
+ import { ForwardedRef } from 'react';
1
2
  import { type AutocompleteProps } from './autocomplete.types.js';
2
- export declare function Autocomplete<T extends object>({ size, invalid, isDisabled, footer, portalContainer, errorMessage, hintMessage, noOptionsMessage, className, width, loadingState, ...props }: AutocompleteProps<T>): import("react/jsx-runtime").JSX.Element;
3
+ declare function Autocomplete<T extends object>({ size, invalid, isDisabled, footer, portalContainer, errorMessage, hintMessage, noOptionsMessage, className, width, loadingState, ...props }: AutocompleteProps<T>, ref: ForwardedRef<HTMLInputElement>): import("react/jsx-runtime").JSX.Element;
4
+ declare const _Autocomplete: {
5
+ displayName: string;
6
+ } & (<T extends object>(props: AutocompleteProps<T> & {
7
+ ref?: ForwardedRef<HTMLInputElement>;
8
+ }) => ReturnType<typeof Autocomplete>);
9
+ export { _Autocomplete as Autocomplete };
@@ -14,7 +14,7 @@ function _extends() {
14
14
  return _extends.apply(this, arguments);
15
15
  }
16
16
  import * as React from 'react';
17
- import { useMemo } from 'react';
17
+ import { forwardRef, useMemo } from 'react';
18
18
  import { mergeProps, useButton, useComboBox, useFilter, useFocusRing, useSearchField } from 'react-aria';
19
19
  import { useComboBoxState, useSearchFieldState } from 'react-stately';
20
20
  import { ClearIcon, SearchIcon } from '../icon/index.js';
@@ -36,7 +36,7 @@ const STATIC_IS_OPEN_STATE = {
36
36
  return;
37
37
  }
38
38
  };
39
- export function Autocomplete({ size ='medium' , invalid =false , isDisabled , footer , portalContainer , errorMessage , hintMessage , noOptionsMessage , className , width ='full' , loadingState , ...props }) {
39
+ function Autocomplete({ size ='medium' , invalid =false , isDisabled , footer , portalContainer , errorMessage , hintMessage , noOptionsMessage , className , width ='full' , loadingState , ...props }, ref) {
40
40
  const { contains } = useFilter({
41
41
  sensitivity: 'base'
42
42
  });
@@ -48,6 +48,7 @@ export function Autocomplete({ size ='medium' , invalid =false , isDisabled , fo
48
48
  const { isFocusVisible , focusProps } = useFocusRing();
49
49
  const { isFocusVisible: isInputFocusVisible , focusProps: inputFocusProps } = useFocusRing();
50
50
  const inputRef = React.useRef(null);
51
+ React.useImperativeHandle(ref, ()=>inputRef.current);
51
52
  const listBoxRef = React.useRef(null);
52
53
  const popoverRef = React.useRef(null);
53
54
  const { inputProps , listBoxProps , labelProps , descriptionProps , errorMessageProps } = useComboBox({
@@ -149,3 +150,6 @@ export function Autocomplete({ size ='medium' , invalid =false , isDisabled , fo
149
150
  className: "border-t border-t-border px-3 py-2"
150
151
  }, footer)));
151
152
  }
153
+ const _Autocomplete = forwardRef(Autocomplete);
154
+ _Autocomplete.displayName = 'Autocomplete';
155
+ export { _Autocomplete as Autocomplete };
@@ -14,7 +14,7 @@ function _extends() {
14
14
  return _extends.apply(this, arguments);
15
15
  }
16
16
  import React, { forwardRef, useContext, useRef } from 'react';
17
- import { VisuallyHidden, useCheckboxGroupItem, useFocusRing } from 'react-aria';
17
+ import { VisuallyHidden, mergeProps, useCheckboxGroupItem, useFocusRing } from 'react-aria';
18
18
  import { Icon } from '../../../icon/icon.component.js';
19
19
  import { CheckboxGroupContext } from '../../checkbox-group.component.js';
20
20
  import { styles as checkboxItemStyles } from './checkbox-group-checkbox.styles.js';
@@ -34,7 +34,7 @@ function CheckIcon({ copyrightYear ='2025' , size , ...props }) {
34
34
  function BaseCheckbox({ className , hint , label , value , ...props }, ref) {
35
35
  const { state , size , orientation } = useContext(CheckboxGroupContext);
36
36
  const localRef = useRef(null);
37
- const { inputProps , isDisabled , isSelected } = useCheckboxGroupItem({
37
+ const { inputProps , labelProps , isDisabled , isSelected } = useCheckboxGroupItem({
38
38
  ...props,
39
39
  value,
40
40
  children: label
@@ -46,14 +46,14 @@ function BaseCheckbox({ className , hint , label , value , ...props }, ref) {
46
46
  orientation,
47
47
  isFocusVisible
48
48
  });
49
- return React.createElement("label", {
49
+ return React.createElement("label", _extends({
50
50
  className: styles.base({
51
51
  className
52
52
  }),
53
53
  ref: ref
54
- }, React.createElement(VisuallyHidden, {
54
+ }, labelProps), React.createElement(VisuallyHidden, {
55
55
  elementType: "span"
56
- }, React.createElement("input", _extends({}, inputProps, focusProps, {
56
+ }, React.createElement("input", _extends({}, mergeProps(inputProps, focusProps), {
57
57
  ref: localRef
58
58
  }))), React.createElement("span", {
59
59
  className: styles.checkbox()
@@ -14,10 +14,12 @@ function _extends() {
14
14
  return _extends.apply(this, arguments);
15
15
  }
16
16
  import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
17
+ import { useFocusVisible } from 'react-aria';
17
18
  import { styles } from './date-picker.styles.js';
18
19
  import { formatDate, isDateDisabled, useListener } from './date-picker.utils.js';
19
20
  export function DatePicker({ dateFormat ='dd-MM-yyyy' , disableWeekends , disableDaysOfWeek , disableDates , placeholder , onChange , onFocus , onBlur , onOpen , onClose , min , max , value , id , size ='md' , name , block =false , invalid =false , ...props }) {
20
21
  const [initialized, setInitialized] = useState(false);
22
+ const { isFocusVisible } = useFocusVisible();
21
23
  useEffect(()=>{
22
24
  const initDatePicker = async ()=>{
23
25
  const { defineCustomElements } = await import('@duetds/date-picker/custom-element/index.js');
@@ -146,7 +148,8 @@ export function DatePicker({ dateFormat ='dd-MM-yyyy' , disableWeekends , disabl
146
148
  class: styles({
147
149
  size,
148
150
  block,
149
- invalid
151
+ invalid,
152
+ isFocusVisible
150
153
  }),
151
154
  ref: ref
152
155
  }, props));
@@ -13,6 +13,10 @@ export declare const styles: import("tailwind-variants").TVReturnType<{
13
13
  true: string;
14
14
  false: string;
15
15
  };
16
+ isFocusVisible: {
17
+ true: string;
18
+ false: string;
19
+ };
16
20
  }, undefined, "date-picker", {
17
21
  responsiveVariants: string[];
18
22
  }, {
@@ -30,6 +34,10 @@ export declare const styles: import("tailwind-variants").TVReturnType<{
30
34
  true: string;
31
35
  false: string;
32
36
  };
37
+ isFocusVisible: {
38
+ true: string;
39
+ false: string;
40
+ };
33
41
  }, undefined, import("tailwind-variants").TVReturnType<{
34
42
  size: {
35
43
  sm: string;
@@ -45,6 +53,10 @@ export declare const styles: import("tailwind-variants").TVReturnType<{
45
53
  true: string;
46
54
  false: string;
47
55
  };
56
+ isFocusVisible: {
57
+ true: string;
58
+ false: string;
59
+ };
48
60
  }, undefined, "date-picker", {
49
61
  responsiveVariants: string[];
50
62
  }, unknown, unknown, undefined>>;
@@ -15,6 +15,10 @@ export const styles = tv({
15
15
  invalid: {
16
16
  true: 'date-picker-invalid',
17
17
  false: ''
18
+ },
19
+ isFocusVisible: {
20
+ true: 'date-picker-focused',
21
+ false: ''
18
22
  }
19
23
  }
20
24
  }, {
@@ -3,6 +3,6 @@ export const styles = tv({
3
3
  slots: {
4
4
  base: 'typography-body-11 flex items-start text-danger',
5
5
  list: 'mb-2 flex flex-col gap-1',
6
- icon: 'mr-[0.5em] mt-[0.15rem] align-top'
6
+ icon: 'mr-[0.5em] mt-[0.15rem] flex-shrink-0 align-top'
7
7
  }
8
8
  });
@@ -106,7 +106,9 @@ export function FilterButtons({ filterButtons , onClick , selectedButton , tag:
106
106
  targetLeft,
107
107
  targetRight
108
108
  };
109
- }, []);
109
+ }, [
110
+ filterButtons.length
111
+ ]);
110
112
  const handleScrollTarget = useCallback((container)=>{
111
113
  let targetRight = scrollTarget.right;
112
114
  let targetLeft = scrollTarget.left;
@@ -13,7 +13,7 @@ export const styles = tv({
13
13
  variants: {
14
14
  logoCenter: {
15
15
  true: {
16
- logoLink: 'max-sm:absolute max-sm:left-1/2 max-sm:z-0 max-sm:translate-x-[-50%] max-sm:translate-y-[15%] sm:relative',
16
+ logoLink: 'max-sm:absolute max-sm:left-1/2 max-sm:z-0 max-sm:-translate-x-1/2 max-sm:translate-y-[15%] sm:relative',
17
17
  smallLogo: ''
18
18
  },
19
19
  false: {
@@ -7,7 +7,7 @@ export const styles = tv({
7
7
  before:absolute before:left-[1px] before:top-[0.5px] before:size-0 before:border-x-[7px] before:border-t-[12px] before:border-x-[transparent] before:border-t-muted after:absolute
8
8
  after:left-[1.5px] after:top-0 after:size-0 after:border-x-[6.5px] after:border-t-[11px] after:border-x-[transparent] after:border-t-white
9
9
  `,
10
- closeBtn: 'absolute right-1 h-3 top-1 p-0 hover:opacity-80',
10
+ closeBtn: 'absolute right-1 top-1 h-3 p-0 hover:opacity-80',
11
11
  content: 'w-[17.625rem] rounded-[3px] bg-white py-4 pl-3 pr-5',
12
12
  heading: 'typography-body-9 mb-2 font-medium text-text',
13
13
  body: 'typography-body-10 text-text'
@@ -43,6 +43,7 @@ export function Popover({ children , className , headingTag , content , heading
43
43
  className
44
44
  })
45
45
  }, React.createElement(Button, {
46
+ type: "button",
46
47
  look: icon && !children || linkStyling ? 'link' : look,
47
48
  iconAfter: icon,
48
49
  soft: soft,
@@ -14,13 +14,13 @@ function _extends() {
14
14
  return _extends.apply(this, arguments);
15
15
  }
16
16
  import React, { forwardRef, useContext, useRef } from 'react';
17
- import { VisuallyHidden, useFocusRing, useRadio } from 'react-aria';
17
+ import { VisuallyHidden, mergeProps, useFocusRing, useRadio } from 'react-aria';
18
18
  import { RadioGroupContext } from '../../radio-group.component.js';
19
19
  import { styles as radioStyles } from './radio-group-radio.styles.js';
20
20
  function BaseRadioGroupRadio({ className , hint , label , ...props }, ref) {
21
21
  const { state , size , orientation } = useContext(RadioGroupContext);
22
22
  const localRef = useRef(null);
23
- const { inputProps , isSelected , isDisabled } = useRadio({
23
+ const { inputProps , labelProps , isSelected , isDisabled } = useRadio({
24
24
  ...props,
25
25
  children: label
26
26
  }, state, localRef);
@@ -32,14 +32,14 @@ function BaseRadioGroupRadio({ className , hint , label , ...props }, ref) {
32
32
  size,
33
33
  orientation
34
34
  });
35
- return React.createElement("label", {
35
+ return React.createElement("label", _extends({
36
36
  className: styles.base({
37
37
  className
38
38
  }),
39
39
  ref: ref
40
- }, React.createElement(VisuallyHidden, {
40
+ }, labelProps), React.createElement(VisuallyHidden, {
41
41
  elementType: "span"
42
- }, React.createElement("input", _extends({}, inputProps, focusProps, {
42
+ }, React.createElement("input", _extends({}, mergeProps(inputProps, focusProps), {
43
43
  ref: localRef
44
44
  }))), React.createElement("span", {
45
45
  className: styles.selector()
@@ -13,7 +13,7 @@ function _extends() {
13
13
  };
14
14
  return _extends.apply(this, arguments);
15
15
  }
16
- import React, { forwardRef, useContext, useRef } from 'react';
16
+ import React, { forwardRef, useCallback, useContext, useRef } from 'react';
17
17
  import { VisuallyHidden, mergeProps, useFocusRing, useRadio } from 'react-aria';
18
18
  import { ArrowRightIcon, TickIcon } from '../../../../../../components/icon/index.js';
19
19
  import { FlexiCell } from '../../../../../index.js';
@@ -36,9 +36,16 @@ function BaseSelectorRadioGroupOption({ className , children , value , withBorde
36
36
  checkIcon
37
37
  });
38
38
  const FinalIcon = checkIcon === 'checkbox' ? TickIcon : ArrowRightIcon;
39
- const onItemClick = ()=>{
39
+ const onItemClick = useCallback(()=>{
40
+ if (isDisabled) {
41
+ return;
42
+ }
40
43
  state.setSelectedValue(value);
41
- };
44
+ }, [
45
+ isDisabled,
46
+ state,
47
+ value
48
+ ]);
42
49
  return React.createElement(FlexiCell, {
43
50
  after: React.createElement("div", {
44
51
  className: "flex gap-2"
@@ -25,7 +25,7 @@ export function Switch({ className , label , size ='medium' , block =false , che
25
25
  const labelId = useId();
26
26
  const ref = useRef(null);
27
27
  const { isSelected } = state;
28
- const { inputProps } = useCheckbox({
28
+ const { inputProps , labelProps } = useCheckbox({
29
29
  isDisabled,
30
30
  'aria-labelledby': labelId,
31
31
  defaultSelected: checked,
@@ -39,11 +39,11 @@ export function Switch({ className , label , size ='medium' , block =false , che
39
39
  isDisabled,
40
40
  size
41
41
  });
42
- return React.createElement("label", {
42
+ return React.createElement("label", _extends({
43
43
  className: styles.base({
44
44
  className
45
45
  })
46
- }, React.createElement("span", {
46
+ }, labelProps), React.createElement("span", {
47
47
  className: styles.label(),
48
48
  id: labelId
49
49
  }, label), React.createElement(VisuallyHidden, {