@westpac/ui 0.17.0 → 0.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 (75) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/component-type.json +1 -1
  3. package/dist/components/accordion/accordion.component.d.ts +2 -1
  4. package/dist/components/autocomplete/autocomplete.component.js +4 -2
  5. package/dist/components/autocomplete/components/autocomplete-list-box/components/autocomplete-list-box-option/autocomplete-list-box-option.styles.d.ts +1 -1
  6. package/dist/components/autocomplete/components/autocomplete-list-box/components/autocomplete-list-box-option/autocomplete-list-box-option.styles.js +1 -1
  7. package/dist/components/autocomplete/components/autocomplete-popover/autocomplete-popover.component.js +9 -3
  8. package/dist/components/bottom-sheet/components/bottom-sheet-dialog/bottom-sheet-dialog.styles.js +2 -2
  9. package/dist/components/bottom-sheet/components/bottom-sheet-modal/bottom-sheet-modal.component.js +7 -2
  10. package/dist/components/button-group/button-group.component.js +58 -11
  11. package/dist/components/button-group/button-group.types.d.ts +9 -1
  12. package/dist/components/button-group/components/button-group-button/button-group-button.component.js +1 -2
  13. package/dist/components/checkbox-group/checkbox-group.component.js +61 -10
  14. package/dist/components/checkbox-group/checkbox-group.types.d.ts +5 -1
  15. package/dist/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.js +1 -2
  16. package/dist/components/date-picker/date-picker.types.d.ts +1 -0
  17. package/dist/components/error-message/error-message.types.d.ts +3 -2
  18. package/dist/components/list/components/list-item/list-item.component.d.ts +1 -1
  19. package/dist/components/list/list.utils.d.ts +1 -1
  20. package/dist/components/modal/components/modal-backdrop/modal-backdrop.component.js +8 -2
  21. package/dist/components/modal/components/modal-dialog/modal-dialog.styles.js +2 -2
  22. package/dist/components/popover/components/panel/panel.component.js +7 -2
  23. package/dist/components/popover/components/panel/panel.styles.js +2 -2
  24. package/dist/components/popover/popover.hooks.js +1 -1
  25. package/dist/components/radio-group/components/radio-group-radio/radio-group-radio.component.js +1 -2
  26. package/dist/components/radio-group/radio-group.component.js +58 -11
  27. package/dist/components/radio-group/radio-group.types.d.ts +5 -1
  28. package/dist/components/selector/components/selector-button-group/selector-button-group.component.js +9 -7
  29. package/dist/components/selector/components/selector-checkbox-group/selector-checkbox-group.component.js +50 -1
  30. package/dist/components/selector/components/selector-radio-group/components/selector-radio-group-option/selector-radio-group-option.component.js +1 -1
  31. package/dist/components/selector/components/selector-radio-group/selector-radio-group.component.js +58 -11
  32. package/dist/components/selector/components/selector-radio-group/selector-radio-group.types.d.ts +5 -1
  33. package/dist/components/tabs/components/tabs-tab/tabs-tab.component.js +1 -1
  34. package/dist/components/tabs/tabs.component.d.ts +6 -2
  35. package/dist/components/tabs/tabs.component.js +7 -1
  36. package/dist/constants/message.d.ts +1 -0
  37. package/dist/constants/message.js +1 -0
  38. package/package.json +8 -8
  39. package/src/components/accordion/accordion.component.tsx +3 -3
  40. package/src/components/accordion/components/accordion-item/accordion-item.component.tsx +2 -2
  41. package/src/components/autocomplete/autocomplete.component.tsx +5 -1
  42. package/src/components/autocomplete/components/autocomplete-list-box/components/autocomplete-list-box-option/autocomplete-list-box-option.component.tsx +1 -1
  43. package/src/components/autocomplete/components/autocomplete-list-box/components/autocomplete-list-box-option/autocomplete-list-box-option.styles.ts +1 -1
  44. package/src/components/autocomplete/components/autocomplete-popover/autocomplete-popover.component.tsx +14 -3
  45. package/src/components/bottom-sheet/components/bottom-sheet-dialog/bottom-sheet-dialog.styles.ts +2 -2
  46. package/src/components/bottom-sheet/components/bottom-sheet-modal/bottom-sheet-modal.component.tsx +11 -2
  47. package/src/components/button-group/button-group.component.tsx +58 -11
  48. package/src/components/button-group/button-group.types.ts +9 -2
  49. package/src/components/button-group/components/button-group-button/button-group-button.component.tsx +1 -2
  50. package/src/components/checkbox-group/checkbox-group.component.tsx +62 -10
  51. package/src/components/checkbox-group/checkbox-group.types.ts +5 -1
  52. package/src/components/checkbox-group/components/checkbox-group-checkbox/checkbox-group-checkbox.component.tsx +1 -2
  53. package/src/components/date-picker/date-picker.types.ts +4 -0
  54. package/src/components/error-message/error-message.component.tsx +2 -2
  55. package/src/components/error-message/error-message.types.ts +2 -1
  56. package/src/components/modal/components/modal-backdrop/modal-backdrop.component.tsx +13 -2
  57. package/src/components/modal/components/modal-dialog/modal-dialog.styles.ts +2 -2
  58. package/src/components/pagination/pagination.component.tsx +6 -6
  59. package/src/components/popover/components/panel/panel.component.tsx +7 -2
  60. package/src/components/popover/components/panel/panel.styles.ts +2 -2
  61. package/src/components/popover/popover.hooks.tsx +5 -2
  62. package/src/components/radio-group/components/radio-group-radio/radio-group-radio.component.tsx +1 -2
  63. package/src/components/radio-group/radio-group.component.tsx +57 -13
  64. package/src/components/radio-group/radio-group.types.ts +5 -1
  65. package/src/components/selector/components/selector-button-group/selector-button-group.component.tsx +10 -7
  66. package/src/components/selector/components/selector-checkbox-group/selector-checkbox-group.component.tsx +49 -0
  67. package/src/components/selector/components/selector-radio-group/components/selector-radio-group-option/selector-radio-group-option.component.tsx +1 -1
  68. package/src/components/selector/components/selector-radio-group/selector-radio-group.component.tsx +58 -11
  69. package/src/components/selector/components/selector-radio-group/selector-radio-group.types.ts +5 -1
  70. package/src/components/tabs/components/tabs-tab/tabs-tab.component.tsx +1 -1
  71. package/src/components/tabs/tabs.component.tsx +26 -5
  72. package/src/constants/message.ts +1 -0
  73. package/src/tailwind/utils/create-font-sizes.ts +11 -8
  74. package/src/tailwind/utils/generate-font-components.ts +18 -15
  75. package/src/tailwind/utils/generate-form-control.ts +11 -8
@@ -16,6 +16,7 @@ function _extends() {
16
16
  import React, { createContext } from 'react';
17
17
  import { useCheckboxGroup } from 'react-aria';
18
18
  import { useCheckboxGroupState } from 'react-stately';
19
+ import { FUNCTION_NOT_IMPLEMENTED } from '../../../../constants/message.js';
19
20
  import { ErrorMessage, Hint, Label } from '../../../index.js';
20
21
  import { styles } from './selector-checkbox-group.styles.js';
21
22
  export const SelectorCheckboxGroupContext = createContext({
@@ -27,7 +28,55 @@ export const SelectorCheckboxGroupContext = createContext({
27
28
  addValue: ()=>null,
28
29
  removeValue: ()=>null,
29
30
  toggleValue: ()=>null,
30
- validationState: 'valid'
31
+ validationState: 'valid',
32
+ isInvalid: false,
33
+ isRequired: false,
34
+ setInvalid: function() {
35
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
36
+ },
37
+ realtimeValidation: {
38
+ isInvalid: false,
39
+ validationErrors: [],
40
+ validationDetails: {
41
+ badInput: false,
42
+ customError: false,
43
+ patternMismatch: false,
44
+ rangeOverflow: false,
45
+ rangeUnderflow: false,
46
+ stepMismatch: false,
47
+ tooLong: false,
48
+ tooShort: false,
49
+ typeMismatch: false,
50
+ valid: false,
51
+ valueMissing: false
52
+ }
53
+ },
54
+ displayValidation: {
55
+ isInvalid: false,
56
+ validationErrors: [],
57
+ validationDetails: {
58
+ badInput: false,
59
+ customError: false,
60
+ patternMismatch: false,
61
+ rangeOverflow: false,
62
+ rangeUnderflow: false,
63
+ stepMismatch: false,
64
+ tooLong: false,
65
+ tooShort: false,
66
+ typeMismatch: false,
67
+ valid: false,
68
+ valueMissing: false
69
+ }
70
+ },
71
+ updateValidation: function() {
72
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
73
+ },
74
+ resetValidation: function() {
75
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
76
+ },
77
+ commitValidation: function() {
78
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
79
+ }
31
80
  });
32
81
  export function SelectorCheckboxGroup(props) {
33
82
  const { children , label , description , errorMessage } = props;
@@ -20,7 +20,7 @@ import { FlexiCell } from '../../../../../index.js';
20
20
  import { SelectorRadioGroupContext } from '../../selector-radio-group.component.js';
21
21
  import { styles as selectorRadioGroupOptionStyles } from './selector-radio-group-option.styles.js';
22
22
  function BaseSelectorRadioGroupOption({ className , children , value , withBorder =true , withArrow , after , before , checkIcon ='checkbox' , ...props }, ref) {
23
- const state = useContext(SelectorRadioGroupContext);
23
+ const { state } = useContext(SelectorRadioGroupContext);
24
24
  const localRef = useRef(null);
25
25
  const { inputProps , isSelected , isDisabled } = useRadio({
26
26
  ...props,
@@ -16,19 +16,66 @@ function _extends() {
16
16
  import React, { createContext } from 'react';
17
17
  import { useRadioGroup } from 'react-aria';
18
18
  import { useRadioGroupState } from 'react-stately';
19
+ import { FUNCTION_NOT_IMPLEMENTED } from '../../../../constants/message.js';
19
20
  import { ErrorMessage, Hint, Label } from '../../../index.js';
20
21
  import { styles } from './selector-radio-group.styles.js';
21
22
  export const SelectorRadioGroupContext = createContext({
22
- name: '',
23
- isDisabled: false,
24
- isReadOnly: false,
25
- isRequired: false,
26
- validationState: null,
27
- selectedValue: null,
28
- setSelectedValue: ()=>null,
29
- lastFocusedValue: null,
30
- setLastFocusedValue: ()=>null,
31
- orientation: 'vertical'
23
+ orientation: 'vertical',
24
+ state: {
25
+ name: '',
26
+ isDisabled: false,
27
+ isReadOnly: false,
28
+ isRequired: false,
29
+ validationState: null,
30
+ selectedValue: null,
31
+ setSelectedValue: ()=>null,
32
+ lastFocusedValue: null,
33
+ setLastFocusedValue: ()=>null,
34
+ isInvalid: false,
35
+ realtimeValidation: {
36
+ isInvalid: false,
37
+ validationErrors: [],
38
+ validationDetails: {
39
+ badInput: false,
40
+ customError: false,
41
+ patternMismatch: false,
42
+ rangeOverflow: false,
43
+ rangeUnderflow: false,
44
+ stepMismatch: false,
45
+ tooLong: false,
46
+ tooShort: false,
47
+ typeMismatch: false,
48
+ valid: false,
49
+ valueMissing: false
50
+ }
51
+ },
52
+ displayValidation: {
53
+ isInvalid: false,
54
+ validationErrors: [],
55
+ validationDetails: {
56
+ badInput: false,
57
+ customError: false,
58
+ patternMismatch: false,
59
+ rangeOverflow: false,
60
+ rangeUnderflow: false,
61
+ stepMismatch: false,
62
+ tooLong: false,
63
+ tooShort: false,
64
+ typeMismatch: false,
65
+ valid: false,
66
+ valueMissing: false
67
+ }
68
+ },
69
+ updateValidation: function() {
70
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
71
+ },
72
+ resetValidation: function() {
73
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
74
+ },
75
+ commitValidation: function() {
76
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
77
+ }
78
+ }
32
79
  });
33
80
  export function SelectorRadioGroup({ className , children , label , orientation ='vertical' , errorMessage , description , ...props }) {
34
81
  const state = useRadioGroupState({
@@ -51,7 +98,7 @@ export function SelectorRadioGroup({ className , children , label , orientation
51
98
  })
52
99
  }, radioGroupProps), React.createElement(SelectorRadioGroupContext.Provider, {
53
100
  value: {
54
- ...state,
101
+ state,
55
102
  orientation
56
103
  }
57
104
  }, children)));
@@ -19,5 +19,9 @@ export type SelectorRadioGroupContextState = {
19
19
  * Controls orientation of `Radio` components, can't be applied directly on `Radio`
20
20
  */
21
21
  orientation: 'vertical' | 'horizontal';
22
- } & RadioGroupState;
22
+ /**
23
+ * Radio group state
24
+ */
25
+ state: RadioGroupState;
26
+ };
23
27
  export {};
@@ -18,7 +18,7 @@ import { styles } from './tabs-tab.styles.js';
18
18
  export function TabsTab({ item: { key , rendered } , state , orientation , justify , color , look }) {
19
19
  const ref = useRef(null);
20
20
  const { tabProps } = useTab({
21
- key
21
+ key: key
22
22
  }, state, ref);
23
23
  const { isFocusVisible , focusProps } = useFocusRing();
24
24
  return React.createElement("div", _extends({}, mergeProps(tabProps, focusProps), {
@@ -1,4 +1,8 @@
1
1
  /// <reference types="react" resolution-mode="require"/>
2
+ import { AriaLinkOptions } from 'react-aria';
3
+ import { ItemProps } from 'react-stately';
2
4
  import { type TabsProps } from './tabs.types.js';
3
- export declare function Tabs({ className, orientation, justify, children, color, look, sticky, stickyOffset, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
4
- export declare const TabsPanel: <T>(props: import("react-stately").ItemProps<T>) => JSX.Element;
5
+ export declare function Tabs({ className, orientation, justify, children, color, look, sticky, stickyOffset, disabledKeys, selectedKey, defaultSelectedKey, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare const TabsPanel: (props: ItemProps<AriaLinkOptions> & AriaLinkOptions & {
7
+ href?: string;
8
+ }) => JSX.Element;
@@ -18,10 +18,13 @@ import { useTabList } from 'react-aria';
18
18
  import { Item, useTabListState } from 'react-stately';
19
19
  import { TabsTab, TabsTabPanel } from './components/index.js';
20
20
  import { styles as tabStyles } from './tabs.styles.js';
21
- export function Tabs({ className , orientation ='horizontal' , justify , children , color , look ='default' , sticky =false , stickyOffset ={} , ...props }) {
21
+ export function Tabs({ className , orientation ='horizontal' , justify , children , color , look ='default' , sticky =false , stickyOffset ={} , disabledKeys , selectedKey , defaultSelectedKey , ...props }) {
22
22
  var _state_selectedItem;
23
23
  const state = useTabListState({
24
24
  ...props,
25
+ disabledKeys: disabledKeys,
26
+ selectedKey: selectedKey,
27
+ defaultSelectedKey: defaultSelectedKey,
25
28
  children
26
29
  });
27
30
  const styles = tabStyles({
@@ -32,6 +35,9 @@ export function Tabs({ className , orientation ='horizontal' , justify , childre
32
35
  const ref = useRef(null);
33
36
  const { tabListProps } = useTabList({
34
37
  ...props,
38
+ disabledKeys: disabledKeys,
39
+ selectedKey: selectedKey,
40
+ defaultSelectedKey: defaultSelectedKey,
35
41
  orientation
36
42
  }, state, ref);
37
43
  return React.createElement("div", {
@@ -0,0 +1 @@
1
+ export declare const FUNCTION_NOT_IMPLEMENTED = "Function not implemented";
@@ -0,0 +1 @@
1
+ export const FUNCTION_NOT_IMPLEMENTED = 'Function not implemented';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@westpac/ui",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -241,7 +241,7 @@
241
241
  "plop": "~3.1.2",
242
242
  "postcss": "~8.4.31",
243
243
  "postcss-cli": "~10.1.0",
244
- "prettier": "^2.8.4",
244
+ "prettier": "^3.2.5",
245
245
  "prop-types": "^15.8.1",
246
246
  "react": "^18.2.0",
247
247
  "react-docgen-typescript": "~2.2.2",
@@ -255,20 +255,20 @@
255
255
  "typescript": "^5.1.6",
256
256
  "vite": "^4.3.9",
257
257
  "vitest": "^0.30.1",
258
- "@westpac/eslint-config": "~0.1.0",
258
+ "@westpac/eslint-config": "~0.2.1",
259
259
  "@westpac/test-config": "~0.0.0",
260
260
  "@westpac/ts-config": "~0.0.0"
261
261
  },
262
262
  "dependencies": {
263
263
  "@duetds/date-picker": "~1.4.0",
264
- "@react-aria/accordion": "3.0.0-alpha.19",
265
- "@react-aria/utils": "~3.18.0",
266
- "@react-spectrum/utils": "~3.10.0",
264
+ "@react-aria/accordion": "3.0.0-alpha.27",
265
+ "@react-aria/utils": "~3.23.2",
266
+ "@react-spectrum/utils": "~3.11.5",
267
267
  "clsx": "^1.2.1",
268
268
  "framer-motion": "~10.12.16",
269
269
  "lodash.throttle": "~4.1.1",
270
- "react-aria": "~3.25.0",
271
- "react-stately": "~3.23.0"
270
+ "react-aria": "~3.32.1",
271
+ "react-stately": "~3.30.1"
272
272
  },
273
273
  "overrides": {
274
274
  "react-aria": {
@@ -4,7 +4,7 @@ import { useAccordion } from '@react-aria/accordion';
4
4
  import { filterDOMProps } from '@react-aria/utils';
5
5
  import { useDOMRef } from '@react-spectrum/utils';
6
6
  import React, { Children, cloneElement, forwardRef, isValidElement } from 'react';
7
- import { Item, useTreeState } from 'react-stately';
7
+ import { Item, type ItemProps, useTreeState } from 'react-stately';
8
8
 
9
9
  import { styles } from './accordion.styles.js';
10
10
  import { type AccordionProps } from './accordion.types.js';
@@ -24,7 +24,7 @@ function Accordion<T extends object>(
24
24
  // equal to (if (child == null || typeof child == 'string'))
25
25
  if (!isValidElement(child)) return child;
26
26
  return cloneElement(child, {
27
- ...child.props,
27
+ ...(child.props as any),
28
28
  // Adding hasChildItems false by default
29
29
  hasChildItems: false,
30
30
  });
@@ -52,4 +52,4 @@ const _Accordion = forwardRef(Accordion) as unknown as { displayName: string } &
52
52
  _Accordion.displayName = 'Accordion';
53
53
 
54
54
  export { _Accordion as Accordion };
55
- export const AccordionItem = Item;
55
+ export const AccordionItem: <T>(props: ItemProps<T>) => JSX.Element = Item;
@@ -20,8 +20,8 @@ export function AccordionItem<T = any>({
20
20
  const { state, item } = props;
21
21
  const { buttonProps, regionProps } = useAccordionItem<T>(props, state, ref);
22
22
  const { isFocusVisible, focusProps } = useFocusRing();
23
- const isOpen = state.expandedKeys.has(item.key);
24
- const isDisabled = state.disabledKeys.has(item.key);
23
+ const isOpen = state.expandedKeys.has(item.key as any);
24
+ const isDisabled = state.disabledKeys.has(item.key as any);
25
25
  const { hoverProps } = useHover({ isDisabled });
26
26
  const { direction } = useLocale();
27
27
  const styles = accordionItemStyles({ isOpen, isDisabled, look, isFocusVisible });
@@ -112,7 +112,11 @@ export function Autocomplete<T extends object>({
112
112
 
113
113
  <div ref={outerRef} className={styles.outerWrapper()}>
114
114
  <div className={styles.iconWrapper()}>
115
- {loadingState ? <ProgressIndicator size={iconSize} /> : <SearchIcon aria-hidden size={iconSize} />}
115
+ {loadingState ? (
116
+ <ProgressIndicator size={iconSize} color="muted" />
117
+ ) : (
118
+ <SearchIcon aria-hidden size={iconSize} color="muted" />
119
+ )}
116
120
  </div>
117
121
  <input
118
122
  {...mergeProps(inputProps, inputFocusProps)}
@@ -18,7 +18,7 @@ export function AutocompleteListBoxOption({ item, state }: AutocompleteListBoxOp
18
18
 
19
19
  const { optionProps, isDisabled, isSelected, isFocused } = useOption(
20
20
  {
21
- key: item.key,
21
+ key: item.key as any,
22
22
  },
23
23
  state,
24
24
  ref,
@@ -2,7 +2,7 @@ import { tv } from 'tailwind-variants';
2
2
 
3
3
  export const styles = tv(
4
4
  {
5
- base: 'flex cursor-pointer items-center justify-between border-t border-t-border bg-white p-2 px-3 text-sm transition-colors first:border-t-0 hover:bg-hero hover:text-white focus:bg-hero focus:text-white',
5
+ base: 'flex cursor-pointer items-center justify-between border-t border-t-border bg-white p-2 px-3 text-sm text-text transition-colors first:border-t-0 hover:bg-hero hover:text-white focus:bg-hero focus:text-white',
6
6
  variants: {
7
7
  isFocused: {
8
8
  true: 'bg-hero !text-white',
@@ -1,5 +1,7 @@
1
+ 'use client';
2
+
1
3
  import { clsx } from 'clsx';
2
- import * as React from 'react';
4
+ import React, { useMemo, useRef } from 'react';
3
5
  import { DismissButton, Overlay, usePopover } from 'react-aria';
4
6
 
5
7
  import { AutocompletePopoverProps } from './autocomplete-popover.types.js';
@@ -7,7 +9,7 @@ import { AutocompletePopoverProps } from './autocomplete-popover.types.js';
7
9
  * @private
8
10
  */
9
11
  export function AutocompletePopover(props: AutocompletePopoverProps) {
10
- const ref = React.useRef<HTMLDivElement>(null);
12
+ const ref = useRef<HTMLDivElement>(null);
11
13
  const { popoverRef = ref, state, children, className, isNonModal, portalContainer } = props;
12
14
  const { popoverProps, underlayProps } = usePopover(
13
15
  {
@@ -17,9 +19,18 @@ export function AutocompletePopover(props: AutocompletePopoverProps) {
17
19
  state,
18
20
  );
19
21
 
22
+ // This is required so branding applies correctly by default due to portal location, can be overridden with portalContainer prop
23
+ const brandContainer = useMemo(() => {
24
+ if (typeof window !== 'undefined') {
25
+ return (
26
+ document.querySelector('[data-theme]') || document.querySelector('[className="data-theme"]') || document.body
27
+ );
28
+ }
29
+ }, []);
30
+
20
31
  const width = props.triggerRef.current?.getBoundingClientRect().width;
21
32
  return (
22
- <Overlay portalContainer={portalContainer}>
33
+ <Overlay portalContainer={portalContainer || brandContainer}>
23
34
  {!isNonModal && <div {...underlayProps} className="fixed inset-0" />}
24
35
 
25
36
  <div
@@ -4,8 +4,8 @@ export const styles = tv(
4
4
  {
5
5
  slots: {
6
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',
7
- title: 'typography-body-7 p-7 pb-4 pt-9 font-bold max-md:px-5',
8
- body: 'flex-1 overflow-auto px-7 pb-7 max-md:px-5',
7
+ title: 'typography-body-7 p-7 pb-4 pt-9 font-bold text-text max-md:px-5',
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',
10
10
  buttonWrapper: '-mt-2 flex gap-1 px-7 pb-7 max-md:flex-col max-md:px-5 max-md:pb-5',
11
11
  primaryBtn: '',
@@ -1,6 +1,6 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { PanInfo, motion, useAnimation } from 'framer-motion';
3
- import React, { useCallback, useEffect, useRef, useState } from 'react';
3
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { Overlay, useModalOverlay } from 'react-aria';
5
5
 
6
6
  import { BREAKPOINTS } from '../../../../tailwind/constants/index.js';
@@ -29,6 +29,15 @@ export function BottomSheetModal({ state, height, width, children, portalContain
29
29
  const controls = useAnimation();
30
30
  const [isMobile, setIsMobile] = useState(checkIfItIsMobile(MEDIUM_BREAKPOINT_AS_NUMBER));
31
31
 
32
+ // This is required so branding applies correctly by default due to portal location, can be overridden with portalContainer prop
33
+ const brandContainer = useMemo(() => {
34
+ if (isBrowser) {
35
+ return (
36
+ document.querySelector('[data-theme]') || document.querySelector('[className="data-theme"]') || document.body
37
+ );
38
+ }
39
+ }, []);
40
+
32
41
  useEffect(() => {
33
42
  function handleResize() {
34
43
  setIsMobile(checkIfItIsMobile(MEDIUM_BREAKPOINT_AS_NUMBER));
@@ -65,7 +74,7 @@ export function BottomSheetModal({ state, height, width, children, portalContain
65
74
  }
66
75
 
67
76
  return (
68
- <Overlay portalContainer={portalContainer}>
77
+ <Overlay portalContainer={portalContainer || brandContainer}>
69
78
  <div className={styles.underlay()} {...underlayProps}>
70
79
  <motion.div
71
80
  animate={controls}
@@ -4,25 +4,72 @@ import React, { createContext } from 'react';
4
4
  import { useRadioGroup } from 'react-aria';
5
5
  import { useRadioGroupState } from 'react-stately';
6
6
 
7
+ import { FUNCTION_NOT_IMPLEMENTED } from '../../constants/message.js';
7
8
  import { ButtonGroupButton, ErrorMessage, Hint, Label } from '../index.js';
8
9
 
9
10
  import { styles as buttonGroupStyles } from './button-group.styles.js';
10
11
  import { ButtonGroupContextState, type ButtonGroupProps } from './button-group.types.js';
11
12
 
12
13
  export const ButtonGroupContext = createContext<ButtonGroupContextState>({
13
- // TODO: Remove deprecated name prop once React Aria removes it from RadioGroupState
14
- name: '',
15
- isDisabled: false,
16
- isReadOnly: false,
17
- isRequired: false,
18
- validationState: null,
19
- selectedValue: null,
20
- setSelectedValue: () => null,
21
- lastFocusedValue: null,
22
- setLastFocusedValue: () => null,
23
14
  block: false,
24
15
  look: 'hero',
25
16
  size: 'medium',
17
+ state: {
18
+ // TODO: Remove deprecated name prop once React Aria removes it from RadioGroupState
19
+ name: '',
20
+ isDisabled: false,
21
+ isReadOnly: false,
22
+ isRequired: false,
23
+ validationState: null,
24
+ selectedValue: null,
25
+ setSelectedValue: () => null,
26
+ lastFocusedValue: null,
27
+ setLastFocusedValue: () => null,
28
+ isInvalid: false,
29
+ realtimeValidation: {
30
+ isInvalid: false,
31
+ validationErrors: [],
32
+ validationDetails: {
33
+ badInput: false,
34
+ customError: false,
35
+ patternMismatch: false,
36
+ rangeOverflow: false,
37
+ rangeUnderflow: false,
38
+ stepMismatch: false,
39
+ tooLong: false,
40
+ tooShort: false,
41
+ typeMismatch: false,
42
+ valid: false,
43
+ valueMissing: false,
44
+ },
45
+ },
46
+ displayValidation: {
47
+ isInvalid: false,
48
+ validationErrors: [],
49
+ validationDetails: {
50
+ badInput: false,
51
+ customError: false,
52
+ patternMismatch: false,
53
+ rangeOverflow: false,
54
+ rangeUnderflow: false,
55
+ stepMismatch: false,
56
+ tooLong: false,
57
+ tooShort: false,
58
+ typeMismatch: false,
59
+ valid: false,
60
+ valueMissing: false,
61
+ },
62
+ },
63
+ updateValidation: function (): void {
64
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
65
+ },
66
+ resetValidation: function (): void {
67
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
68
+ },
69
+ commitValidation: function (): void {
70
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
71
+ },
72
+ },
26
73
  });
27
74
 
28
75
  export function ButtonGroup({
@@ -56,7 +103,7 @@ export function ButtonGroup({
56
103
  <ErrorMessage {...errorMessageProps} message={errorMessage} />
57
104
  )}
58
105
  <div className={styles.buttonWrapper()}>
59
- <ButtonGroupContext.Provider value={{ ...state, size, look, block }}>
106
+ <ButtonGroupContext.Provider value={{ state, size, look, block }}>
60
107
  {buttons.map((button, index) => (
61
108
  <ButtonGroupButton key={index} className="group/buttons" {...button} />
62
109
  ))}
@@ -46,5 +46,12 @@ export type ButtonGroupContextState = {
46
46
  * Controls look of `Button` components, can't be applied directly to `Button`
47
47
  */
48
48
  look?: 'hero' | 'primary';
49
- } & RadioGroupState &
50
- Pick<ButtonProps, 'size'>;
49
+ /**
50
+ * Controls look of `Button` components, can't be applied directly to `Button`
51
+ */
52
+ size: ButtonProps['size'];
53
+ /**
54
+ * Radio group state
55
+ */
56
+ state: RadioGroupState;
57
+ };
@@ -10,8 +10,7 @@ import { styles as buttonStyles } from './button-group-button.styles.js';
10
10
  import { type ButtonGroupButtonProps } from './button-group-button.types.js';
11
11
 
12
12
  export function ButtonGroupButton({ className, label, ...props }: ButtonGroupButtonProps) {
13
- const state = useContext(ButtonGroupContext);
14
- const { size, look, block } = state;
13
+ const { state, size, look, block } = useContext(ButtonGroupContext);
15
14
  const ref = useRef(null);
16
15
  const { inputProps, isSelected, isDisabled } = useRadio({ ...props, children: label }, state, ref);
17
16
  const { isFocusVisible, focusProps } = useFocusRing();
@@ -4,6 +4,7 @@ import React, { createContext, useEffect, useId, useMemo, useRef, useState } fro
4
4
  import { useCheckboxGroup, useFocusRing } from 'react-aria';
5
5
  import { useCheckboxGroupState } from 'react-stately';
6
6
 
7
+ import { FUNCTION_NOT_IMPLEMENTED } from '../../constants/message.js';
7
8
  import { Button } from '../button/index.js';
8
9
  import { ExpandMoreIcon } from '../icon/index.js';
9
10
  import { CheckboxGroupCheckbox, ErrorMessage, Hint, Label } from '../index.js';
@@ -14,15 +15,66 @@ import { type CheckboxGroupContextState, type CheckboxGroupProps } from './check
14
15
  export const CheckboxGroupContext = createContext<CheckboxGroupContextState>({
15
16
  orientation: 'vertical',
16
17
  size: 'medium',
17
- value: [],
18
- isDisabled: false,
19
- isReadOnly: false,
20
- isSelected: () => false,
21
- setValue: () => null,
22
- addValue: () => null,
23
- removeValue: () => null,
24
- toggleValue: () => null,
25
- validationState: 'valid',
18
+ state: {
19
+ value: [],
20
+ isDisabled: false,
21
+ isReadOnly: false,
22
+ isSelected: () => false,
23
+ setValue: () => null,
24
+ addValue: () => null,
25
+ removeValue: () => null,
26
+ toggleValue: () => null,
27
+ validationState: 'valid',
28
+ isInvalid: false,
29
+ isRequired: false,
30
+ setInvalid: () =>
31
+ function (): void {
32
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
33
+ },
34
+ realtimeValidation: {
35
+ isInvalid: false,
36
+ validationErrors: [],
37
+ validationDetails: {
38
+ badInput: false,
39
+ customError: false,
40
+ patternMismatch: false,
41
+ rangeOverflow: false,
42
+ rangeUnderflow: false,
43
+ stepMismatch: false,
44
+ tooLong: false,
45
+ tooShort: false,
46
+ typeMismatch: false,
47
+ valid: false,
48
+ valueMissing: false,
49
+ },
50
+ },
51
+ displayValidation: {
52
+ isInvalid: false,
53
+ validationErrors: [],
54
+ validationDetails: {
55
+ badInput: false,
56
+ customError: false,
57
+ patternMismatch: false,
58
+ rangeOverflow: false,
59
+ rangeUnderflow: false,
60
+ stepMismatch: false,
61
+ tooLong: false,
62
+ tooShort: false,
63
+ typeMismatch: false,
64
+ valid: false,
65
+ valueMissing: false,
66
+ },
67
+ },
68
+ updateValidation: function (): void {
69
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
70
+ },
71
+ resetValidation: function (): void {
72
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
73
+ },
74
+ commitValidation: function (): void {
75
+ throw new Error(FUNCTION_NOT_IMPLEMENTED);
76
+ },
77
+ },
26
78
  });
27
79
  export function CheckboxGroup({
28
80
  className,
@@ -65,7 +117,7 @@ export function CheckboxGroup({
65
117
  <ErrorMessage {...errorMessageProps} message={errorMessage} />
66
118
  )}
67
119
  <div className={styles.itemWrapper()} id={panelId}>
68
- <CheckboxGroupContext.Provider value={{ ...state, orientation, size }}>
120
+ <CheckboxGroupContext.Provider value={{ state, orientation, size }}>
69
121
  {childrenToRender}
70
122
  </CheckboxGroupContext.Provider>
71
123
  {hiddenOptions && (
@@ -45,4 +45,8 @@ export type CheckboxGroupContextState = {
45
45
  * Controls size of `CheckboxItem` components, can't be applied directly on `CheckboxItem`
46
46
  */
47
47
  size: 'medium' | 'large';
48
- } & CheckboxGroupState;
48
+ /**
49
+ * State
50
+ */
51
+ state: CheckboxGroupState;
52
+ };
@@ -32,8 +32,7 @@ function CheckIcon({ copyrightYear = '2024', size, ...props }: IconProps) {
32
32
  }
33
33
 
34
34
  function BaseCheckbox({ className, hint, label, value, ...props }: CheckboxGroupCheckboxProps, ref: any) {
35
- const state = useContext(CheckboxGroupContext);
36
- const { size, orientation } = state;
35
+ const { state, size, orientation } = useContext(CheckboxGroupContext);
37
36
  const localRef = useRef(null);
38
37
  const { inputProps, isDisabled, isSelected } = useCheckboxGroupItem(
39
38
  { ...props, value, children: label },