@westpac/ui 0.42.2 → 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.
- package/CHANGELOG.md +12 -0
- package/dist/component-type.json +1 -1
- package/dist/components/alert/alert.component.js +3 -1
- package/dist/components/alert/alert.styles.js +1 -1
- package/dist/components/autocomplete/autocomplete.component.d.ts +8 -1
- package/dist/components/autocomplete/autocomplete.component.js +6 -2
- package/dist/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.js +5 -5
- package/dist/components/date-picker/date-picker.component.js +4 -1
- package/dist/components/date-picker/date-picker.styles.d.ts +12 -0
- package/dist/components/date-picker/date-picker.styles.js +4 -0
- package/dist/components/error-message/error-message.styles.js +1 -1
- package/dist/components/filter/components/filter-buttons/filter-buttons.component.js +3 -1
- package/dist/components/header/header.styles.js +1 -1
- package/dist/components/popover/components/panel/panel.styles.js +1 -1
- package/dist/components/popover/popover.component.js +1 -0
- package/dist/components/radio-group/components/radio-group-radio/radio-group-radio.component.js +5 -5
- package/dist/components/selector/components/selector-radio-group/components/selector-radio-group-option/selector-radio-group-option.component.js +10 -3
- package/dist/components/switch/switch.component.js +3 -3
- package/dist/css/westpac-ui.css +309 -37
- package/dist/css/westpac-ui.min.css +309 -37
- package/dist/tailwind/utils/generate-date-picker-component.d.ts +30 -7
- package/dist/tailwind/utils/generate-date-picker-component.js +30 -7
- package/package.json +2 -2
- package/src/components/alert/alert.component.tsx +9 -2
- package/src/components/alert/alert.styles.ts +1 -1
- package/src/components/autocomplete/autocomplete.component.tsx +29 -16
- package/src/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.tsx +4 -4
- package/src/components/date-picker/date-picker.component.tsx +3 -1
- package/src/components/date-picker/date-picker.styles.ts +4 -0
- package/src/components/error-message/error-message.styles.ts +1 -1
- package/src/components/filter/components/filter-buttons/filter-buttons.component.tsx +4 -1
- package/src/components/header/header.styles.ts +1 -1
- package/src/components/popover/components/panel/panel.styles.ts +1 -1
- package/src/components/popover/popover.component.tsx +1 -0
- package/src/components/radio-group/components/radio-group-radio/radio-group-radio.component.tsx +4 -4
- package/src/components/selector/components/selector-radio-group/components/selector-radio-group-option/selector-radio-group-option.component.tsx +6 -3
- package/src/components/switch/switch.component.tsx +2 -2
- package/src/tailwind/utils/generate-date-picker-component.ts +32 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { useMemo } from 'react';
|
|
4
|
+
import { ForwardedRef, forwardRef, useMemo } from 'react';
|
|
5
5
|
import { mergeProps, useButton, useComboBox, useFilter, useFocusRing, useSearchField } from 'react-aria';
|
|
6
6
|
import { useComboBoxState, useSearchFieldState } from 'react-stately';
|
|
7
7
|
|
|
@@ -28,25 +28,30 @@ const STATIC_IS_OPEN_STATE = {
|
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
function Autocomplete<T extends object>(
|
|
32
|
+
{
|
|
33
|
+
size = 'medium',
|
|
34
|
+
invalid = false,
|
|
35
|
+
isDisabled,
|
|
36
|
+
footer,
|
|
37
|
+
portalContainer,
|
|
38
|
+
errorMessage,
|
|
39
|
+
hintMessage,
|
|
40
|
+
noOptionsMessage,
|
|
41
|
+
className,
|
|
42
|
+
width = 'full',
|
|
43
|
+
loadingState,
|
|
44
|
+
...props
|
|
45
|
+
}: AutocompleteProps<T>,
|
|
46
|
+
ref: ForwardedRef<HTMLInputElement>,
|
|
47
|
+
) {
|
|
45
48
|
const { contains } = useFilter({ sensitivity: 'base' });
|
|
46
49
|
const state = useComboBoxState({ isDisabled, ...props, defaultFilter: contains });
|
|
47
50
|
const { isFocusVisible, focusProps } = useFocusRing();
|
|
48
51
|
const { isFocusVisible: isInputFocusVisible, focusProps: inputFocusProps } = useFocusRing();
|
|
49
|
-
const inputRef = React.useRef(null);
|
|
52
|
+
const inputRef = React.useRef<HTMLInputElement>(null);
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
54
|
+
React.useImperativeHandle(ref, () => inputRef.current!);
|
|
50
55
|
const listBoxRef = React.useRef(null);
|
|
51
56
|
const popoverRef = React.useRef(null);
|
|
52
57
|
const { inputProps, listBoxProps, labelProps, descriptionProps, errorMessageProps } = useComboBox(
|
|
@@ -168,3 +173,11 @@ export function Autocomplete<T extends object>({
|
|
|
168
173
|
</div>
|
|
169
174
|
);
|
|
170
175
|
}
|
|
176
|
+
|
|
177
|
+
const _Autocomplete = forwardRef(Autocomplete) as unknown as { displayName: string } & (<T extends object>(
|
|
178
|
+
props: AutocompleteProps<T> & { ref?: ForwardedRef<HTMLInputElement> },
|
|
179
|
+
) => ReturnType<typeof Autocomplete>);
|
|
180
|
+
|
|
181
|
+
_Autocomplete.displayName = 'Autocomplete';
|
|
182
|
+
|
|
183
|
+
export { _Autocomplete as Autocomplete };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import React, { Ref, forwardRef, useContext, useRef } from 'react';
|
|
4
|
-
import { VisuallyHidden, useCheckboxGroupItem, useFocusRing } from 'react-aria';
|
|
4
|
+
import { VisuallyHidden, mergeProps, useCheckboxGroupItem, useFocusRing } from 'react-aria';
|
|
5
5
|
|
|
6
6
|
import { Icon } from '../../../icon/icon.component.js';
|
|
7
7
|
import { IconProps } from '../../../icon/index.js';
|
|
@@ -37,7 +37,7 @@ function BaseCheckbox(
|
|
|
37
37
|
) {
|
|
38
38
|
const { state, size, orientation } = useContext(CheckboxGroupContext);
|
|
39
39
|
const localRef = useRef(null);
|
|
40
|
-
const { inputProps, isDisabled, isSelected } = useCheckboxGroupItem(
|
|
40
|
+
const { inputProps, labelProps, isDisabled, isSelected } = useCheckboxGroupItem(
|
|
41
41
|
{ ...props, value, children: label },
|
|
42
42
|
state,
|
|
43
43
|
localRef,
|
|
@@ -46,9 +46,9 @@ function BaseCheckbox(
|
|
|
46
46
|
const styles = checkboxItemStyles({ isDisabled, size, orientation, isFocusVisible });
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
<label className={styles.base({ className })} ref={ref}>
|
|
49
|
+
<label className={styles.base({ className })} ref={ref} {...labelProps}>
|
|
50
50
|
<VisuallyHidden elementType="span">
|
|
51
|
-
<input {...inputProps
|
|
51
|
+
<input {...mergeProps(inputProps, focusProps)} ref={localRef} />
|
|
52
52
|
</VisuallyHidden>
|
|
53
53
|
<span className={styles.checkbox()}>
|
|
54
54
|
{isSelected && <CheckIcon className={styles.checkIcon()} size={size} color={isDisabled ? 'border' : 'hero'} />}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useFocusVisible } from 'react-aria';
|
|
4
5
|
|
|
5
6
|
import { styles } from './date-picker.styles.js';
|
|
6
7
|
import { type DatePickerProps, DuetDatePickerElement } from './date-picker.types.js';
|
|
@@ -28,6 +29,7 @@ export function DatePicker({
|
|
|
28
29
|
...props
|
|
29
30
|
}: DatePickerProps) {
|
|
30
31
|
const [initialized, setInitialized] = useState(false);
|
|
32
|
+
const { isFocusVisible } = useFocusVisible();
|
|
31
33
|
|
|
32
34
|
useEffect(() => {
|
|
33
35
|
const initDatePicker = async () => {
|
|
@@ -124,5 +126,5 @@ export function DatePicker({
|
|
|
124
126
|
|
|
125
127
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
126
128
|
// @ts-ignore
|
|
127
|
-
return <duet-date-picker class={styles({ size, block, invalid })} ref={ref} {...props} />;
|
|
129
|
+
return <duet-date-picker class={styles({ size, block, invalid, isFocusVisible })} ref={ref} {...props} />;
|
|
128
130
|
}
|
|
@@ -5,6 +5,6 @@ export const styles = tv({
|
|
|
5
5
|
base: 'typography-body-11 flex items-start text-danger',
|
|
6
6
|
list: 'mb-2 flex flex-col gap-1',
|
|
7
7
|
// below should be em rather than rem based on old GEL
|
|
8
|
-
icon: 'mr-[0.5em] mt-[0.15rem] align-top',
|
|
8
|
+
icon: 'mr-[0.5em] mt-[0.15rem] flex-shrink-0 align-top',
|
|
9
9
|
},
|
|
10
10
|
});
|
|
@@ -68,6 +68,7 @@ export function FilterButtons({
|
|
|
68
68
|
setScroll(scrollBy, scrollX, container);
|
|
69
69
|
}
|
|
70
70
|
},
|
|
71
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
72
|
[scrollTarget],
|
|
72
73
|
);
|
|
73
74
|
|
|
@@ -116,7 +117,7 @@ export function FilterButtons({
|
|
|
116
117
|
|
|
117
118
|
return { targetLeft, targetRight };
|
|
118
119
|
},
|
|
119
|
-
[],
|
|
120
|
+
[filterButtons.length],
|
|
120
121
|
);
|
|
121
122
|
|
|
122
123
|
const handleScrollTarget = useCallback(
|
|
@@ -141,6 +142,7 @@ export function FilterButtons({
|
|
|
141
142
|
setScrollTarget({ left: targetLeft, right: targetRight });
|
|
142
143
|
}
|
|
143
144
|
},
|
|
145
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
144
146
|
[scrollTarget, getTargetLeft, getTargetRight, adjustTargets],
|
|
145
147
|
);
|
|
146
148
|
|
|
@@ -172,6 +174,7 @@ export function FilterButtons({
|
|
|
172
174
|
container?.removeEventListener('scroll', handleScroll);
|
|
173
175
|
window.removeEventListener('resize', handleScroll);
|
|
174
176
|
};
|
|
177
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
175
178
|
}, [handleScrollTarget, handleScrollable]);
|
|
176
179
|
|
|
177
180
|
return (
|
|
@@ -18,7 +18,7 @@ export const styles = tv(
|
|
|
18
18
|
logoCenter: {
|
|
19
19
|
true: {
|
|
20
20
|
logoLink:
|
|
21
|
-
'max-sm:absolute max-sm:left-1/2 max-sm:z-0 max-sm
|
|
21
|
+
'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',
|
|
22
22
|
smallLogo: '',
|
|
23
23
|
},
|
|
24
24
|
false: {
|
|
@@ -9,7 +9,7 @@ export const styles = tv(
|
|
|
9
9
|
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
|
|
10
10
|
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
|
|
11
11
|
`,
|
|
12
|
-
closeBtn: 'absolute right-1 h-3
|
|
12
|
+
closeBtn: 'absolute right-1 top-1 h-3 p-0 hover:opacity-80',
|
|
13
13
|
content: 'w-[17.625rem] rounded-[3px] bg-white py-4 pl-3 pr-5',
|
|
14
14
|
heading: 'typography-body-9 mb-2 font-medium text-text',
|
|
15
15
|
body: 'typography-body-10 text-text',
|
package/src/components/radio-group/components/radio-group-radio/radio-group-radio.component.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import React, { Ref, forwardRef, useContext, useRef } from 'react';
|
|
4
|
-
import { VisuallyHidden, useFocusRing, useRadio } from 'react-aria';
|
|
4
|
+
import { VisuallyHidden, mergeProps, useFocusRing, useRadio } from 'react-aria';
|
|
5
5
|
|
|
6
6
|
import { RadioGroupContext } from '../../radio-group.component.js';
|
|
7
7
|
|
|
@@ -11,14 +11,14 @@ import { type RadioGroupRadioProps } from './radio-group-radio.types.js';
|
|
|
11
11
|
function BaseRadioGroupRadio({ className, hint, label, ...props }: RadioGroupRadioProps, ref: Ref<HTMLLabelElement>) {
|
|
12
12
|
const { state, size, orientation } = useContext(RadioGroupContext);
|
|
13
13
|
const localRef = useRef(null);
|
|
14
|
-
const { inputProps, isSelected, isDisabled } = useRadio({ ...props, children: label }, state, localRef);
|
|
14
|
+
const { inputProps, labelProps, isSelected, isDisabled } = useRadio({ ...props, children: label }, state, localRef);
|
|
15
15
|
const { isFocusVisible, focusProps } = useFocusRing();
|
|
16
16
|
const styles = radioStyles({ isDisabled, isSelected, isFocusVisible, size, orientation });
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
|
-
<label className={styles.base({ className })} ref={ref}>
|
|
19
|
+
<label className={styles.base({ className })} ref={ref} {...labelProps}>
|
|
20
20
|
<VisuallyHidden elementType="span">
|
|
21
|
-
<input {...inputProps
|
|
21
|
+
<input {...mergeProps(inputProps, focusProps)} ref={localRef} />
|
|
22
22
|
</VisuallyHidden>
|
|
23
23
|
<span className={styles.selector()} />
|
|
24
24
|
<span className={styles.textWrapper()}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import React, { Ref, forwardRef, useContext, useRef } from 'react';
|
|
3
|
+
import React, { Ref, forwardRef, useCallback, useContext, useRef } from 'react';
|
|
4
4
|
import { VisuallyHidden, mergeProps, useFocusRing, useRadio } from 'react-aria';
|
|
5
5
|
|
|
6
6
|
import { ArrowRightIcon, TickIcon } from '../../../../../../components/icon/index.js';
|
|
@@ -32,9 +32,12 @@ function BaseSelectorRadioGroupOption(
|
|
|
32
32
|
|
|
33
33
|
const FinalIcon = checkIcon === 'checkbox' ? TickIcon : ArrowRightIcon;
|
|
34
34
|
|
|
35
|
-
const onItemClick = () => {
|
|
35
|
+
const onItemClick = useCallback(() => {
|
|
36
|
+
if (isDisabled) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
36
39
|
state.setSelectedValue(value);
|
|
37
|
-
};
|
|
40
|
+
}, [isDisabled, state, value]);
|
|
38
41
|
|
|
39
42
|
return (
|
|
40
43
|
<FlexiCell
|
|
@@ -20,7 +20,7 @@ export function Switch({
|
|
|
20
20
|
const labelId = useId();
|
|
21
21
|
const ref = useRef(null);
|
|
22
22
|
const { isSelected } = state;
|
|
23
|
-
const { inputProps } = useCheckbox(
|
|
23
|
+
const { inputProps, labelProps } = useCheckbox(
|
|
24
24
|
{ isDisabled, 'aria-labelledby': labelId, defaultSelected: checked, ...props },
|
|
25
25
|
state,
|
|
26
26
|
ref,
|
|
@@ -29,7 +29,7 @@ export function Switch({
|
|
|
29
29
|
const styles = switchStyles({ block, isFocusVisible, isSelected, isDisabled, size });
|
|
30
30
|
|
|
31
31
|
return (
|
|
32
|
-
<label className={styles.base({ className })}>
|
|
32
|
+
<label className={styles.base({ className })} {...labelProps}>
|
|
33
33
|
<span className={styles.label()} id={labelId}>
|
|
34
34
|
{label}
|
|
35
35
|
</span>
|
|
@@ -2,16 +2,15 @@ export const generateDatePicker = () => {
|
|
|
2
2
|
return {
|
|
3
3
|
'.date-picker': {
|
|
4
4
|
'.duet-date__input': {
|
|
5
|
-
'@apply text-lg focus:!border-borderDark focus:!shadow-none
|
|
6
|
-
{},
|
|
5
|
+
'@apply text-lg focus:!border-borderDark focus:!shadow-none border border-borderDark border-solid rounded': {},
|
|
7
6
|
},
|
|
8
7
|
'.duet-date__toggle': {
|
|
9
8
|
'@apply shadow-none border-solid border-l !border-l-borderDark !bg-light touch-manipulation whitespace-nowrap transition hover:bg-white active:bg-white rounded-r':
|
|
10
9
|
{},
|
|
11
|
-
'@apply focus:shadow-none
|
|
10
|
+
'@apply focus:shadow-none': {},
|
|
12
11
|
},
|
|
13
12
|
'.duet-date__select select:focus + .duet-date__select-label': {
|
|
14
|
-
'@apply
|
|
13
|
+
'@apply rounded': {},
|
|
15
14
|
},
|
|
16
15
|
'.duet-date__toggle-icon': {
|
|
17
16
|
'@apply w-[18px] h-[18px] bg-cover flex-auto': {},
|
|
@@ -100,17 +99,17 @@ export const generateDatePicker = () => {
|
|
|
100
99
|
'@apply font-semibold': {},
|
|
101
100
|
},
|
|
102
101
|
'.duet-date__prev, .duet-date__next': {
|
|
103
|
-
'@apply bg-background
|
|
102
|
+
'@apply bg-background !outline-offset-0 text-primary': {},
|
|
104
103
|
},
|
|
105
104
|
'.duet-date-dialog-select select:focus + .duet-date-dialog-select-label': {
|
|
106
|
-
'@apply
|
|
105
|
+
'@apply !shadow-none': {},
|
|
107
106
|
'outline-offset': '0 !important',
|
|
108
107
|
},
|
|
109
108
|
|
|
110
109
|
/* Calendar days */
|
|
111
110
|
'.duet-date__day': {
|
|
112
111
|
'@apply hover:!bg-primary/5 focus:!bg-white/0 focus:!text-text': {},
|
|
113
|
-
'@apply active:shadow
|
|
112
|
+
'@apply active:shadow focus:!shadow-none !outline-offset-0': {},
|
|
114
113
|
'&.is-today': {
|
|
115
114
|
'@apply !shadow-primary !text-text !bg-primary/5 !border !border-solid !border-primary': {},
|
|
116
115
|
},
|
|
@@ -124,9 +123,34 @@ export const generateDatePicker = () => {
|
|
|
124
123
|
},
|
|
125
124
|
},
|
|
126
125
|
'.duet-date__close:focus': {
|
|
127
|
-
'@apply bg-light
|
|
126
|
+
'@apply bg-light': {},
|
|
128
127
|
'outline-offset': '0 !important',
|
|
129
128
|
},
|
|
129
|
+
|
|
130
|
+
/* Focused styles */
|
|
131
|
+
'&.date-picker-focused': {
|
|
132
|
+
'.duet-date__input': {
|
|
133
|
+
'@apply focus:focus-outline': {},
|
|
134
|
+
},
|
|
135
|
+
'.duet-date__toggle': {
|
|
136
|
+
'@apply focus:focus-outline': {},
|
|
137
|
+
},
|
|
138
|
+
'.duet-date__select select:focus + .duet-date__select-label': {
|
|
139
|
+
'@apply !focus-outline': {},
|
|
140
|
+
},
|
|
141
|
+
'.duet-date__prev, .duet-date__next': {
|
|
142
|
+
'@apply focus:focus-outline': {},
|
|
143
|
+
},
|
|
144
|
+
'.duet-date-dialog-select select:focus + .duet-date-dialog-select-label': {
|
|
145
|
+
'@apply focus-outline': {},
|
|
146
|
+
},
|
|
147
|
+
'.duet-date__day': {
|
|
148
|
+
'@apply active:focus-outline focus:focus-outline': {},
|
|
149
|
+
},
|
|
150
|
+
'.duet-date__close:focus': {
|
|
151
|
+
'@apply bg-light focus-outline': {},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
130
154
|
},
|
|
131
155
|
};
|
|
132
156
|
};
|