@westpac/ui 0.50.0 → 0.52.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.
- package/CHANGELOG.md +53 -0
- package/dist/component-type.json +1 -1
- package/dist/components/accordion/components/accordion-item/accordion-item.component.js +55 -25
- package/dist/components/accordion/components/accordion-item/accordion-item.styles.d.ts +45 -6
- package/dist/components/accordion/components/accordion-item/accordion-item.styles.js +19 -6
- package/dist/components/autocomplete/autocomplete.component.d.ts +1 -1
- package/dist/components/autocomplete/autocomplete.component.js +3 -2
- package/dist/components/autocomplete/autocomplete.types.d.ts +6 -0
- package/dist/components/badge/badge.styles.js +1 -1
- package/dist/components/bottom-sheet/components/bottom-sheet-dialog/bottom-sheet-dialog.styles.js +1 -1
- package/dist/components/footer/footer.component.js +4 -11
- package/dist/components/footer/footer.styles.d.ts +3 -21
- package/dist/components/footer/footer.styles.js +3 -9
- package/dist/components/header/header.component.d.ts +1 -1
- package/dist/components/header/header.component.js +13 -10
- package/dist/components/header/header.types.d.ts +7 -1
- package/dist/components/modal/components/modal-dialog/index.d.ts +1 -0
- package/dist/components/modal/index.d.ts +1 -0
- package/dist/components/popover/components/panel/panel.component.js +5 -4
- package/dist/components/select/components/index.d.ts +2 -0
- package/dist/components/select/components/index.js +2 -0
- package/dist/components/select/components/select-with-tooltip/select-with-tooltip.component.d.ts +13 -0
- package/dist/components/select/components/select-with-tooltip/select-with-tooltip.component.js +22 -0
- package/dist/components/select/components/select-with-tooltip/select-with-tooltip.styles.d.ts +56 -0
- package/dist/components/select/components/select-with-tooltip/select-with-tooltip.styles.js +30 -0
- package/dist/components/select/components/styled-select/styled-select.component.d.ts +13 -0
- package/dist/components/select/components/styled-select/styled-select.component.js +19 -0
- package/dist/components/select/components/styled-select/styled-select.styles.d.ts +104 -0
- package/dist/components/select/components/styled-select/styled-select.styles.js +46 -0
- package/dist/components/select/select.component.d.ts +1 -0
- package/dist/components/select/select.component.js +7 -14
- package/dist/components/select/select.styles.d.ts +180 -45
- package/dist/components/select/select.styles.js +60 -15
- package/dist/components/select/select.types.d.ts +6 -0
- package/dist/components/tooltip/components/tooltip-content/tooltip-content.component.d.ts +2 -0
- package/dist/components/tooltip/components/tooltip-content/tooltip-content.component.js +9 -0
- package/dist/components/tooltip/components/tooltip-content/tooltip-content.styles.d.ts +1 -0
- package/dist/components/tooltip/components/tooltip-content/tooltip-content.styles.js +4 -0
- package/dist/components/tooltip/components/tooltip-content/tooltip-content.types.d.ts +5 -0
- package/dist/components/tooltip/components/tooltip-content/tooltip-content.types.js +1 -0
- package/dist/components/tooltip/index.d.ts +1 -0
- package/dist/components/tooltip/index.js +1 -0
- package/dist/components/tooltip/tooltip.component.d.ts +2 -0
- package/dist/components/tooltip/tooltip.component.js +55 -0
- package/dist/components/tooltip/tooltip.styles.d.ts +1 -0
- package/dist/components/tooltip/tooltip.styles.js +4 -0
- package/dist/components/tooltip/tooltip.types.d.ts +7 -0
- package/dist/components/tooltip/tooltip.types.js +1 -0
- package/dist/css/westpac-ui.css +69 -36
- package/dist/css/westpac-ui.min.css +69 -36
- package/dist/hook/breakpoints.hook.js +59 -10
- package/dist/hook/index.d.ts +1 -0
- package/dist/hook/index.js +1 -0
- package/package.json +4 -3
- package/src/components/accordion/components/accordion-item/accordion-item.component.tsx +64 -28
- package/src/components/accordion/components/accordion-item/accordion-item.styles.ts +19 -6
- package/src/components/autocomplete/autocomplete.component.tsx +3 -1
- package/src/components/autocomplete/autocomplete.types.ts +6 -0
- package/src/components/badge/badge.styles.ts +1 -1
- package/src/components/bottom-sheet/components/bottom-sheet-dialog/bottom-sheet-dialog.styles.ts +1 -1
- package/src/components/footer/footer.component.tsx +8 -12
- package/src/components/footer/footer.styles.ts +2 -6
- package/src/components/header/header.component.tsx +17 -4
- package/src/components/header/header.types.ts +7 -1
- package/src/components/modal/components/modal-dialog/index.ts +1 -0
- package/src/components/modal/index.ts +1 -0
- package/src/components/popover/components/panel/panel.component.tsx +8 -5
- package/src/components/select/components/index.ts +2 -0
- package/src/components/select/components/select-with-tooltip/select-with-tooltip.component.tsx +31 -0
- package/src/components/select/components/select-with-tooltip/select-with-tooltip.styles.ts +26 -0
- package/src/components/select/components/styled-select/styled-select.component.tsx +25 -0
- package/src/components/select/components/styled-select/styled-select.styles.ts +42 -0
- package/src/components/select/select.component.tsx +9 -14
- package/src/components/select/select.styles.ts +18 -15
- package/src/components/select/select.types.ts +6 -0
- package/src/components/tooltip/components/tooltip-content/tooltip-content.component.tsx +12 -0
- package/src/components/tooltip/components/tooltip-content/tooltip-content.styles.ts +5 -0
- package/src/components/tooltip/components/tooltip-content/tooltip-content.types.ts +6 -0
- package/src/components/tooltip/index.ts +1 -0
- package/src/components/tooltip/tooltip.component.tsx +61 -0
- package/src/components/tooltip/tooltip.styles.ts +3 -0
- package/src/components/tooltip/tooltip.types.ts +8 -0
- package/src/hook/breakpoints.hook.ts +71 -11
- package/src/hook/index.ts +1 -0
|
@@ -1,21 +1,70 @@
|
|
|
1
|
-
import { useEffect
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { create } from 'zustand';
|
|
2
3
|
import { BREAKPOINTS } from '../tailwind/constants/index.js';
|
|
3
4
|
function checkBreakpoint() {
|
|
5
|
+
if (typeof window === 'undefined') {
|
|
6
|
+
return 'initial';
|
|
7
|
+
}
|
|
4
8
|
const breakpointsAsArray = Object.entries(BREAKPOINTS).reverse();
|
|
5
9
|
const breakpoint = breakpointsAsArray.find(([, value])=>window.matchMedia(`(min-width: ${value})`).matches);
|
|
6
10
|
return breakpoint ? breakpoint[0] : 'initial';
|
|
7
11
|
}
|
|
12
|
+
const BREAKPOINTS_ENTRIES = Object.entries(BREAKPOINTS);
|
|
13
|
+
const BREAKPOINTS_MEDIA = BREAKPOINTS_ENTRIES.reduce((acc, [key, value], index)=>{
|
|
14
|
+
const finalValue = (()=>{
|
|
15
|
+
const nextBreakpoint = BREAKPOINTS_ENTRIES[index + 1];
|
|
16
|
+
if (nextBreakpoint) {
|
|
17
|
+
return `(min-width: ${value}) and (max-width: ${+nextBreakpoint[1].replace('px', '') - 1}px)`;
|
|
18
|
+
}
|
|
19
|
+
return `(min-width: ${value})`;
|
|
20
|
+
})();
|
|
21
|
+
return {
|
|
22
|
+
...acc,
|
|
23
|
+
[key]: finalValue
|
|
24
|
+
};
|
|
25
|
+
}, {
|
|
26
|
+
initial: `(max-width: ${+BREAKPOINTS_ENTRIES[0][1].replace('px', '') - 1}px)`
|
|
27
|
+
});
|
|
28
|
+
const useBreakpointStore = create()((set, get)=>({
|
|
29
|
+
breakpoint: 'initial',
|
|
30
|
+
mediaQueryListeners: null,
|
|
31
|
+
initialised: false,
|
|
32
|
+
ensureInitialized: ()=>{
|
|
33
|
+
if (get().initialised) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const listeners = Object.entries(BREAKPOINTS_MEDIA).map(([label, query])=>{
|
|
37
|
+
const mq = window.matchMedia(query);
|
|
38
|
+
const listener = (e)=>{
|
|
39
|
+
if (e.matches) {
|
|
40
|
+
set({
|
|
41
|
+
breakpoint: label
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
mq.addEventListener('change', listener);
|
|
46
|
+
return {
|
|
47
|
+
mq,
|
|
48
|
+
listener
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
set({
|
|
52
|
+
mediaQueryListeners: listeners,
|
|
53
|
+
initialised: true,
|
|
54
|
+
breakpoint: checkBreakpoint()
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
removeListeners: ()=>{
|
|
58
|
+
var _get_mediaQueryListeners;
|
|
59
|
+
(_get_mediaQueryListeners = get().mediaQueryListeners) === null || _get_mediaQueryListeners === void 0 ? void 0 : _get_mediaQueryListeners.forEach(({ mq, listener })=>{
|
|
60
|
+
mq.removeEventListener('change', listener);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}));
|
|
8
64
|
export function useBreakpoint() {
|
|
9
|
-
const
|
|
65
|
+
const { breakpoint, ensureInitialized: initIfNotInitialised } = useBreakpointStore();
|
|
10
66
|
useEffect(()=>{
|
|
11
|
-
|
|
12
|
-
const breakpoint = checkBreakpoint();
|
|
13
|
-
setBreakpoint(breakpoint);
|
|
14
|
-
};
|
|
15
|
-
window.addEventListener('resize', listener);
|
|
16
|
-
return ()=>{
|
|
17
|
-
window.removeEventListener('resize', listener);
|
|
18
|
-
};
|
|
67
|
+
initIfNotInitialised();
|
|
19
68
|
}, []);
|
|
20
69
|
return breakpoint;
|
|
21
70
|
}
|
package/dist/hook/index.d.ts
CHANGED
package/dist/hook/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@westpac/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -255,8 +255,8 @@
|
|
|
255
255
|
"typescript": "^5.5.4",
|
|
256
256
|
"vite": "^7.0.5",
|
|
257
257
|
"vitest": "^3.2.4",
|
|
258
|
-
"@westpac/eslint-config": "~1.0.1",
|
|
259
258
|
"@westpac/test-config": "~0.0.0",
|
|
259
|
+
"@westpac/eslint-config": "~1.0.1",
|
|
260
260
|
"@westpac/ts-config": "~0.0.0"
|
|
261
261
|
},
|
|
262
262
|
"dependencies": {
|
|
@@ -270,7 +270,8 @@
|
|
|
270
270
|
"lodash.throttle": "~4.1.1",
|
|
271
271
|
"motion": "~12.23.12",
|
|
272
272
|
"react-aria": "~3.41.1",
|
|
273
|
-
"react-stately": "~3.39.0"
|
|
273
|
+
"react-stately": "~3.39.0",
|
|
274
|
+
"zustand": "~4.5.4"
|
|
274
275
|
},
|
|
275
276
|
"overrides": {
|
|
276
277
|
"react-aria": {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable sonarjs/deprecation */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
3
|
import { useAccordionItem } from '@react-aria/accordion';
|
|
4
|
-
import {
|
|
5
|
-
import React, { useRef } from 'react';
|
|
4
|
+
import { LazyMotion, m, useAnimate } from 'motion/react';
|
|
5
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
6
6
|
import { mergeProps, useFocusRing, useHover, useLocale } from 'react-aria';
|
|
7
7
|
|
|
8
8
|
import { ArrowLeftIcon, ArrowRightIcon } from '../../../icon/index.js';
|
|
@@ -23,11 +23,58 @@ export function AccordionItem<T = HTMLElement>({
|
|
|
23
23
|
const { state, item } = props;
|
|
24
24
|
const { buttonProps, regionProps } = useAccordionItem<T>(props, state, ref);
|
|
25
25
|
const { isFocusVisible, focusProps } = useFocusRing();
|
|
26
|
-
const
|
|
26
|
+
const isOpenState = state.expandedKeys.has(item.key);
|
|
27
27
|
const isDisabled = state.disabledKeys.has(item.key);
|
|
28
28
|
const { hoverProps } = useHover({ isDisabled });
|
|
29
29
|
const { direction } = useLocale();
|
|
30
|
-
|
|
30
|
+
// Open/close animation needs to be done with useAnimate as AnimatePresence will unmount component
|
|
31
|
+
const [scope, animate] = useAnimate();
|
|
32
|
+
const [enableOpenStyle, setEnableOpenStyle] = useState(isOpenState); // styles for opening accordion
|
|
33
|
+
const [enableCloseStyle, setEnableCloseStyle] = useState(!isOpenState); // styles for closing accordion
|
|
34
|
+
|
|
35
|
+
const styles = accordionItemStyles({
|
|
36
|
+
isOpen: enableOpenStyle,
|
|
37
|
+
isClosed: enableCloseStyle,
|
|
38
|
+
isOpenState,
|
|
39
|
+
isDisabled,
|
|
40
|
+
look,
|
|
41
|
+
isFocusVisible,
|
|
42
|
+
rounded,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
// setEnableStyle here as opening animation isn't working correctly if done below
|
|
47
|
+
if (isOpenState) setEnableOpenStyle(true);
|
|
48
|
+
|
|
49
|
+
// animates opening accordion
|
|
50
|
+
if (enableOpenStyle) {
|
|
51
|
+
animate(
|
|
52
|
+
scope.current,
|
|
53
|
+
{ height: 'auto' },
|
|
54
|
+
{ duration: 0.3, ease: [0.25, 0.1, 0.25, 1.0], onComplete: () => setEnableCloseStyle(false) },
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// animates closing accordion
|
|
59
|
+
if (!isOpenState) {
|
|
60
|
+
animate(
|
|
61
|
+
scope.current,
|
|
62
|
+
{ height: '0px' },
|
|
63
|
+
{
|
|
64
|
+
duration: 0.3,
|
|
65
|
+
ease: [0.25, 0.1, 0.25, 1.0],
|
|
66
|
+
// set some styles after animation completes so content doesn't disappear on close
|
|
67
|
+
onPlay: () => {
|
|
68
|
+
setEnableCloseStyle(true);
|
|
69
|
+
},
|
|
70
|
+
onComplete: () => {
|
|
71
|
+
setEnableOpenStyle(false);
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
77
|
+
}, [isOpenState, enableOpenStyle]);
|
|
31
78
|
|
|
32
79
|
return (
|
|
33
80
|
<Tag className={styles.base({ className })}>
|
|
@@ -46,34 +93,23 @@ export function AccordionItem<T = HTMLElement>({
|
|
|
46
93
|
</button>
|
|
47
94
|
</h3>
|
|
48
95
|
<div {...regionProps}>
|
|
96
|
+
{/* NOTE: Can potentially replace animation in the future with React 19.2 Activity and AnimateActivity from motion/react once fully released https://motion.dev/docs/react-animate-activity */}
|
|
49
97
|
<LazyMotion features={loadAnimations}>
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
-
className=
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
height: 'auto',
|
|
98
|
+
<m.div className={styles.motionContent()} initial={{ height: isOpenState ? 'auto' : 0 }} ref={scope}>
|
|
99
|
+
<div
|
|
100
|
+
className={styles.content()}
|
|
101
|
+
// TODO: Remove below with updated accordion that uses disclosure as the issue doesn't happen with that version
|
|
102
|
+
// Need to call stopPropagation here as some events from children are bubbling up and focusing the accordion i.e. inputs
|
|
103
|
+
onBlur={e => {
|
|
104
|
+
e.stopPropagation();
|
|
58
105
|
}}
|
|
59
|
-
|
|
60
|
-
|
|
106
|
+
onFocus={e => {
|
|
107
|
+
e.stopPropagation();
|
|
61
108
|
}}
|
|
62
|
-
transition={{ duration: 0.3, ease: [0.25, 0.1, 0.25, 1.0] }}
|
|
63
|
-
key={`${item.index}-${isOpen}`}
|
|
64
109
|
>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Need to call stopPropagation here as some events from children are bubbling up and focusing the accordion i.e. inputs
|
|
69
|
-
onBlur={e => {
|
|
70
|
-
e.stopPropagation();
|
|
71
|
-
}}
|
|
72
|
-
>
|
|
73
|
-
{item.props.children}
|
|
74
|
-
</div>
|
|
75
|
-
</m.div>
|
|
76
|
-
</AnimatePresence>
|
|
110
|
+
{item.props.children}
|
|
111
|
+
</div>
|
|
112
|
+
</m.div>
|
|
77
113
|
</LazyMotion>
|
|
78
114
|
</div>
|
|
79
115
|
</Tag>
|
|
@@ -7,7 +7,8 @@ export const styles = tv(
|
|
|
7
7
|
itemHeader: 'typography-body-9 flex w-full flex-1 items-center justify-between px-3 py-2 group-first:border-t-0',
|
|
8
8
|
headerTitleWrapper: 'flex-1 pr-2 text-left',
|
|
9
9
|
indicator: 'size-3 rotate-90',
|
|
10
|
-
content: '
|
|
10
|
+
content: '',
|
|
11
|
+
motionContent: '',
|
|
11
12
|
},
|
|
12
13
|
variants: {
|
|
13
14
|
look: {
|
|
@@ -19,13 +20,25 @@ export const styles = tv(
|
|
|
19
20
|
'mb-[-1px] border-l-[0.375rem] border-r border-border bg-light shadow-[inset_0px_1px_0_0_var(--tw-shadow-color),inset_0_-1px_0_0_var(--tw-shadow-color)] !shadow-border transition-colors',
|
|
20
21
|
},
|
|
21
22
|
},
|
|
23
|
+
isOpenState: {
|
|
24
|
+
false: {
|
|
25
|
+
itemHeader: 'background-transition hover:bg-background',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
22
28
|
isOpen: {
|
|
23
29
|
true: {
|
|
24
|
-
content: 'block border-border p-3',
|
|
30
|
+
content: 'visible block border-border p-3',
|
|
25
31
|
},
|
|
26
32
|
false: {
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
content: 'hidden',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
isClosed: {
|
|
37
|
+
true: {
|
|
38
|
+
motionContent: 'overflow-hidden',
|
|
39
|
+
},
|
|
40
|
+
false: {
|
|
41
|
+
motionContent: 'overflow-visible',
|
|
29
42
|
},
|
|
30
43
|
},
|
|
31
44
|
isDisabled: {
|
|
@@ -45,13 +58,13 @@ export const styles = tv(
|
|
|
45
58
|
compoundSlots: [
|
|
46
59
|
{
|
|
47
60
|
slots: ['indicator'],
|
|
48
|
-
|
|
61
|
+
isOpenState: true,
|
|
49
62
|
className: '-rotate-90',
|
|
50
63
|
},
|
|
51
64
|
{
|
|
52
65
|
slots: ['itemHeader'],
|
|
53
66
|
look: 'lego',
|
|
54
|
-
|
|
67
|
+
isOpenState: true,
|
|
55
68
|
className: 'border-l-hero',
|
|
56
69
|
},
|
|
57
70
|
{
|
|
@@ -41,13 +41,15 @@ function Autocomplete<T extends object>(
|
|
|
41
41
|
className,
|
|
42
42
|
width = 'full',
|
|
43
43
|
loadingState,
|
|
44
|
+
comboBoxState,
|
|
44
45
|
...props
|
|
45
46
|
}: AutocompleteProps<T>,
|
|
46
47
|
ref: ForwardedRef<HTMLInputElement>,
|
|
47
48
|
) {
|
|
48
49
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
49
50
|
const { contains } = useFilter({ sensitivity: 'base' });
|
|
50
|
-
const
|
|
51
|
+
const internalState = useComboBoxState({ isDisabled, ...props, defaultFilter: contains });
|
|
52
|
+
const state = comboBoxState ?? internalState;
|
|
51
53
|
const { isFocusVisible, focusProps } = useFocusRing();
|
|
52
54
|
const { isFocusVisible: isInputFocusVisible, focusProps: inputFocusProps } = useFocusRing();
|
|
53
55
|
const inputRef = React.useRef<HTMLInputElement>(null);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ComboBoxProps } from '@react-types/combobox';
|
|
2
2
|
import { type AriaLabelingProps } from '@react-types/shared';
|
|
3
3
|
import { type ReactNode } from 'react';
|
|
4
|
+
import { ComboBoxState } from 'react-stately';
|
|
4
5
|
import { type VariantProps } from 'tailwind-variants';
|
|
5
6
|
|
|
6
7
|
import { HintProps, InputProps } from '../index.js';
|
|
@@ -63,5 +64,10 @@ export type AutocompleteProps<T extends object> = {
|
|
|
63
64
|
* Width of autocomplete
|
|
64
65
|
*/
|
|
65
66
|
width?: InputProps['width'];
|
|
67
|
+
/**
|
|
68
|
+
* Pass through comboBox state from consuming component. If not specified,
|
|
69
|
+
* will be handled internally.
|
|
70
|
+
*/
|
|
71
|
+
comboBoxState?: ComboBoxState<T>;
|
|
66
72
|
} & ComboBoxProps<T> &
|
|
67
73
|
AriaLabelingProps;
|
|
@@ -24,7 +24,7 @@ export const styles = tv(
|
|
|
24
24
|
'warning-inverted': 'border-none bg-white text-warning',
|
|
25
25
|
},
|
|
26
26
|
type: {
|
|
27
|
-
pill: 'typography-body-10 flex h-4 w-fit items-center rounded-xl px-[0.4375rem] font-medium leading-none',
|
|
27
|
+
pill: 'typography-body-10 flex h-4 min-w-4 w-fit items-center justify-center rounded-xl px-[0.4375rem] font-medium leading-none',
|
|
28
28
|
default: 'h-[1.25rem] rounded-sm px-1 text-[0.75rem] leading-[1.125rem]',
|
|
29
29
|
},
|
|
30
30
|
soft: {
|
package/src/components/bottom-sheet/components/bottom-sheet-dialog/bottom-sheet-dialog.styles.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { tv } from 'tailwind-variants';
|
|
|
3
3
|
export const styles = tv(
|
|
4
4
|
{
|
|
5
5
|
slots: {
|
|
6
|
-
base: 'flex max-h-screen max-w-full flex-1 flex-col overflow-hidden rounded-t-md bg-white shadow-sm md:w-[37.5rem] md:rounded-md',
|
|
6
|
+
base: 'relative flex max-h-screen max-w-full flex-1 flex-col overflow-hidden rounded-t-md bg-white shadow-sm md:w-[37.5rem] md:rounded-md',
|
|
7
7
|
title: 'typography-body-7 p-7 pb-4 pt-9 font-bold text-text max-md:px-5',
|
|
8
8
|
body: 'flex-1 overflow-auto px-7 pb-7 text-text max-md:px-5',
|
|
9
9
|
closeBtn: 'absolute right-3 top-3 p-0',
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { useFocusRing } from 'react-aria';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { VisuallyHidden } from '../index.js';
|
|
7
7
|
import {
|
|
8
8
|
BOMMultibrandSmallLogo,
|
|
9
9
|
BSAMultibrandSmallLogo,
|
|
@@ -54,18 +54,14 @@ export function Footer({
|
|
|
54
54
|
return (
|
|
55
55
|
<footer className={styles.base({ className })} {...props}>
|
|
56
56
|
<div className={styles.wrapper()}>
|
|
57
|
-
<
|
|
58
|
-
<GridItem span={12}>{children}</GridItem>
|
|
59
|
-
</Grid>
|
|
57
|
+
<div>{children}</div>
|
|
60
58
|
{!hideLogo && (
|
|
61
|
-
<
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
</GridItem>
|
|
68
|
-
</Grid>
|
|
59
|
+
<div className={styles.logoWrapper()}>
|
|
60
|
+
<a href={logoLink} className={styles.link()} {...focusProps}>
|
|
61
|
+
{srOnlyText && <VisuallyHidden>{srOnlyText}</VisuallyHidden>}
|
|
62
|
+
<Logo align="right" aria-label={logoAssistiveText} />
|
|
63
|
+
</a>
|
|
64
|
+
</div>
|
|
69
65
|
)}
|
|
70
66
|
</div>
|
|
71
67
|
</footer>
|
|
@@ -4,9 +4,9 @@ export const styles = tv(
|
|
|
4
4
|
{
|
|
5
5
|
slots: {
|
|
6
6
|
base: 'relative overflow-hidden border-t border-t-border',
|
|
7
|
-
wrapper: 'pt-3 max-md:px-2 max-md:pb-3 md:px-4 md:pb-
|
|
8
|
-
topRow: '',
|
|
7
|
+
wrapper: 'pt-3 max-md:px-2 max-md:pb-3 md:px-4 md:pb-3',
|
|
9
8
|
link: 'float-right block',
|
|
9
|
+
logoWrapper: 'flex justify-end',
|
|
10
10
|
},
|
|
11
11
|
variants: {
|
|
12
12
|
offsetSidebar: {
|
|
@@ -18,10 +18,6 @@ export const styles = tv(
|
|
|
18
18
|
isFocusVisible: {
|
|
19
19
|
true: { link: 'focus-outline' },
|
|
20
20
|
},
|
|
21
|
-
hideLogo: {
|
|
22
|
-
true: '',
|
|
23
|
-
false: { topRow: 'max-md:mb-7 md:mb-4' },
|
|
24
|
-
},
|
|
25
21
|
},
|
|
26
22
|
},
|
|
27
23
|
{ responsiveVariants: ['xsl', 'sm', 'md', 'lg', 'xl'] },
|
|
@@ -56,6 +56,7 @@ export function Header({
|
|
|
56
56
|
brand,
|
|
57
57
|
className,
|
|
58
58
|
children,
|
|
59
|
+
disableLogoLink = false,
|
|
59
60
|
fixed = false,
|
|
60
61
|
fixedMaxWidth,
|
|
61
62
|
isScrolled,
|
|
@@ -97,6 +98,13 @@ export function Header({
|
|
|
97
98
|
|
|
98
99
|
const styles = headerStyles({ logoCenter, fixed, leftIcon, scrolled: isScrolled || scrolled });
|
|
99
100
|
|
|
101
|
+
const HeaderLogo = () => (
|
|
102
|
+
<>
|
|
103
|
+
<SmallLogo align={logoAlignment} aria-label={logoAssistiveText} className={styles.smallLogo()} />
|
|
104
|
+
<LargeLogo aria-label={logoAssistiveText} className={styles.largeLogo()} />
|
|
105
|
+
</>
|
|
106
|
+
);
|
|
107
|
+
|
|
100
108
|
return (
|
|
101
109
|
<header className={styles.base({ className })} {...props}>
|
|
102
110
|
<div className={styles.inner()} style={{ maxWidth: fixed ? fixedMaxWidth : undefined }}>
|
|
@@ -115,10 +123,15 @@ export function Header({
|
|
|
115
123
|
</div>
|
|
116
124
|
)}
|
|
117
125
|
{/* useFocusRing was causing this link to need two clicks to activate so focus-visible styling is used instead */}
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
{disableLogoLink ? (
|
|
127
|
+
<div className={styles.logoLink()}>
|
|
128
|
+
<HeaderLogo />
|
|
129
|
+
</div>
|
|
130
|
+
) : (
|
|
131
|
+
<a href={logoLink} target={anchorTarget} className={styles.logoLink()} onClick={logoOnClick}>
|
|
132
|
+
<HeaderLogo />
|
|
133
|
+
</a>
|
|
134
|
+
)}
|
|
122
135
|
{children && <div className={styles.rightContent()}>{children}</div>}
|
|
123
136
|
</div>
|
|
124
137
|
</header>
|
|
@@ -12,6 +12,11 @@ export type HeaderProps = {
|
|
|
12
12
|
* Icon for brand
|
|
13
13
|
*/
|
|
14
14
|
brand: Exclude<BrandKey, 'btfg'>;
|
|
15
|
+
/**
|
|
16
|
+
* Removes anchor link from logo
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
disableLogoLink?: boolean;
|
|
15
20
|
/**
|
|
16
21
|
* Enable fixed header
|
|
17
22
|
*/
|
|
@@ -46,7 +51,8 @@ export type HeaderProps = {
|
|
|
46
51
|
*/
|
|
47
52
|
logoCenter?: boolean;
|
|
48
53
|
/**
|
|
49
|
-
* Link for logo
|
|
54
|
+
* Link for logo, can be disabled with disableLogoLink
|
|
55
|
+
* @default '#'
|
|
50
56
|
*/
|
|
51
57
|
logoLink?: string;
|
|
52
58
|
/**
|
|
@@ -22,16 +22,19 @@ export function BasePanel({
|
|
|
22
22
|
const popoverRef = useRef<HTMLDivElement>(null);
|
|
23
23
|
const arrowRef = useRef<HTMLDivElement>(null);
|
|
24
24
|
const { popoverPosition, arrowPosition } = usePanel({ state, placement, triggerRef, portal });
|
|
25
|
-
|
|
26
25
|
const styles = panelStyles({ placement });
|
|
27
26
|
return (
|
|
28
27
|
<FocusScope autoFocus restoreFocus>
|
|
29
28
|
<div style={popoverPosition} className={styles.popover()} test-id="popover" id={id} ref={popoverRef}>
|
|
30
29
|
<div className={styles.content()}>
|
|
31
|
-
|
|
32
|
-
{heading}
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
{heading && (
|
|
31
|
+
<Tag className={styles.heading()} tabIndex={0}>
|
|
32
|
+
{heading}
|
|
33
|
+
</Tag>
|
|
34
|
+
)}
|
|
35
|
+
<div className={styles.body()} tabIndex={0}>
|
|
36
|
+
{content}
|
|
37
|
+
</div>
|
|
35
38
|
<Button
|
|
36
39
|
look="link"
|
|
37
40
|
size="small"
|
package/src/components/select/components/select-with-tooltip/select-with-tooltip.component.tsx
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React, { ForwardedRef, forwardRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Tooltip } from '../../../tooltip/index.js';
|
|
4
|
+
import { SelectProps } from '../../select.types.js';
|
|
5
|
+
import { StyledSelect } from '../styled-select/styled-select.component.js';
|
|
6
|
+
|
|
7
|
+
import { styles } from './select-with-tooltip.styles.js';
|
|
8
|
+
|
|
9
|
+
function BaseSelectWithTooltip(
|
|
10
|
+
{ width = 'auto', children, onChange, ...props }: SelectProps,
|
|
11
|
+
ref: ForwardedRef<HTMLSelectElement>,
|
|
12
|
+
) {
|
|
13
|
+
const [selectedOption, setSelectedOption] = useState('');
|
|
14
|
+
return (
|
|
15
|
+
<Tooltip tooltip={selectedOption} className={styles({ width })}>
|
|
16
|
+
<StyledSelect
|
|
17
|
+
ref={ref}
|
|
18
|
+
onChange={e => {
|
|
19
|
+
setSelectedOption(e.target.options[e.target.selectedIndex].text);
|
|
20
|
+
onChange?.(e);
|
|
21
|
+
}}
|
|
22
|
+
width={width}
|
|
23
|
+
{...props}
|
|
24
|
+
>
|
|
25
|
+
{children}
|
|
26
|
+
</StyledSelect>
|
|
27
|
+
</Tooltip>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const SelectWithTooltip = forwardRef<HTMLSelectElement, SelectProps>(BaseSelectWithTooltip);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
|
|
3
|
+
export const styles = tv(
|
|
4
|
+
{
|
|
5
|
+
base: '',
|
|
6
|
+
variants: {
|
|
7
|
+
width: {
|
|
8
|
+
auto: 'flex-1',
|
|
9
|
+
full: 'w-full flex-1',
|
|
10
|
+
1: 'w-[1.81ex]',
|
|
11
|
+
2: 'w-[3.62ex]',
|
|
12
|
+
3: 'w-[5.43ex]',
|
|
13
|
+
4: 'w-[7.24ex]',
|
|
14
|
+
5: 'w-[9.05ex]',
|
|
15
|
+
6: 'w-[10.86ex]',
|
|
16
|
+
7: 'w-[12.67ex]',
|
|
17
|
+
8: 'w-[14.48ex]',
|
|
18
|
+
9: 'w-[16.29ex]',
|
|
19
|
+
10: 'w-[18.1ex]',
|
|
20
|
+
20: 'w-[36.2ex]',
|
|
21
|
+
30: 'w-[54.3ex]',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{ responsiveVariants: ['xsl', 'sm', 'md', 'lg', 'xl'] },
|
|
26
|
+
);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React, { ForwardedRef, forwardRef } from 'react';
|
|
2
|
+
import { mergeProps, useFocusRing } from 'react-aria';
|
|
3
|
+
|
|
4
|
+
import { type SelectProps } from '../../select.types.js';
|
|
5
|
+
|
|
6
|
+
import { styles } from './styled-select.styles.js';
|
|
7
|
+
|
|
8
|
+
function BaseSelect(
|
|
9
|
+
{ className, size = 'medium', invalid = false, width = 'auto', children, ...props }: SelectProps,
|
|
10
|
+
ref: ForwardedRef<HTMLSelectElement>,
|
|
11
|
+
) {
|
|
12
|
+
const { isFocused, isFocusVisible, focusProps } = useFocusRing();
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<select
|
|
16
|
+
ref={ref}
|
|
17
|
+
className={styles({ className, size, invalid, isFocused, isFocusVisible, width })}
|
|
18
|
+
{...mergeProps(props, focusProps)}
|
|
19
|
+
>
|
|
20
|
+
{children}
|
|
21
|
+
</select>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const StyledSelect = forwardRef<HTMLSelectElement, SelectProps>(BaseSelect);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
|
|
3
|
+
export const styles = tv(
|
|
4
|
+
{
|
|
5
|
+
base: 'form-control overflow-hidden overflow-ellipsis whitespace-nowrap bg-no-repeat select-caret disabled:form-control-disabled group-first/add-on-before:!rounded-l group-first/add-on-before:rounded-r-none group-first/add-on-before:!border-x group-last/add-on-after:!rounded-r group-last/add-on-after:rounded-l-none group-last/add-on-after:!border-x group-[.input-group-after]:rounded-r-none group-[.input-group-before]:rounded-l-none group-[.input-group-after]:border-r-0 group-[.input-group-before]:border-l-0',
|
|
6
|
+
variants: {
|
|
7
|
+
size: {
|
|
8
|
+
small: 'form-control-small bg-[right_0.5625rem_center] pr-[calc(0.5rem+14px+0.5625rem)]',
|
|
9
|
+
medium: 'form-control-medium bg-[right_0.75rem_center] pr-[calc(0.5rem+14px+0.75rem)]',
|
|
10
|
+
large: 'form-control-large bg-[right_0.9375rem_center] pr-[calc(0.5rem+14px+0.9375rem)]',
|
|
11
|
+
xlarge: 'form-control-xlarge bg-[right_1.125rem_center] pr-[calc(0.5rem+14px+1.125rem)]',
|
|
12
|
+
},
|
|
13
|
+
invalid: {
|
|
14
|
+
true: 'border-danger',
|
|
15
|
+
false: 'border-borderDark',
|
|
16
|
+
},
|
|
17
|
+
isFocusVisible: {
|
|
18
|
+
true: 'focus-outline',
|
|
19
|
+
},
|
|
20
|
+
isFocused: {
|
|
21
|
+
true: 'outline-none',
|
|
22
|
+
},
|
|
23
|
+
width: {
|
|
24
|
+
auto: 'flex-1',
|
|
25
|
+
full: 'w-full flex-1',
|
|
26
|
+
1: 'box-content w-[1.81ex]',
|
|
27
|
+
2: 'box-content w-[3.62ex]',
|
|
28
|
+
3: 'box-content w-[5.43ex]',
|
|
29
|
+
4: 'box-content w-[7.24ex]',
|
|
30
|
+
5: 'box-content w-[9.05ex]',
|
|
31
|
+
6: 'box-content w-[10.86ex]',
|
|
32
|
+
7: 'box-content w-[12.67ex]',
|
|
33
|
+
8: 'box-content w-[14.48ex]',
|
|
34
|
+
9: 'box-content w-[16.29ex]',
|
|
35
|
+
10: 'box-content w-[18.1ex]',
|
|
36
|
+
20: 'box-content w-[36.2ex]',
|
|
37
|
+
30: 'box-content w-[54.3ex]',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{ responsiveVariants: ['xsl', 'sm', 'md', 'lg', 'xl'] },
|
|
42
|
+
);
|