@flipdish/ui-library 0.37.0 → 0.39.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 (87) hide show
  1. package/README.md +9 -9
  2. package/dist/components/__internal__/selectionControl/selectionControl.styles.cjs +22 -0
  3. package/dist/components/__internal__/selectionControl/selectionControl.styles.cjs.map +1 -0
  4. package/dist/components/__internal__/selectionControl/selectionControl.styles.d.ts +17 -0
  5. package/dist/components/__internal__/selectionControl/selectionControl.styles.d.ts.map +1 -0
  6. package/dist/components/__internal__/selectionControl/selectionControl.styles.js +20 -0
  7. package/dist/components/__internal__/selectionControl/selectionControl.styles.js.map +1 -0
  8. package/dist/components/__internal__/selectionControl/selectionControl.utils.d.ts +23 -0
  9. package/dist/components/__internal__/selectionControl/selectionControl.utils.d.ts.map +1 -0
  10. package/dist/components/atoms/Checkbox/index.cjs +3 -16
  11. package/dist/components/atoms/Checkbox/index.cjs.map +1 -1
  12. package/dist/components/atoms/Checkbox/index.d.ts.map +1 -1
  13. package/dist/components/atoms/Checkbox/index.js +3 -16
  14. package/dist/components/atoms/Checkbox/index.js.map +1 -1
  15. package/dist/components/atoms/Toggle/Toggle.styles.cjs +0 -14
  16. package/dist/components/atoms/Toggle/Toggle.styles.cjs.map +1 -1
  17. package/dist/components/atoms/Toggle/Toggle.styles.d.ts +0 -14
  18. package/dist/components/atoms/Toggle/Toggle.styles.d.ts.map +1 -1
  19. package/dist/components/atoms/Toggle/Toggle.styles.js +0 -14
  20. package/dist/components/atoms/Toggle/Toggle.styles.js.map +1 -1
  21. package/dist/components/atoms/Toggle/index.cjs +3 -2
  22. package/dist/components/atoms/Toggle/index.cjs.map +1 -1
  23. package/dist/components/atoms/Toggle/index.d.ts.map +1 -1
  24. package/dist/components/atoms/Toggle/index.js +3 -2
  25. package/dist/components/atoms/Toggle/index.js.map +1 -1
  26. package/dist/components/templates/WidgetLayout/index.cjs +36 -0
  27. package/dist/components/templates/WidgetLayout/index.cjs.map +1 -0
  28. package/dist/components/templates/WidgetLayout/index.d.ts +54 -0
  29. package/dist/components/templates/WidgetLayout/index.d.ts.map +1 -0
  30. package/dist/components/templates/WidgetLayout/index.js +34 -0
  31. package/dist/components/templates/WidgetLayout/index.js.map +1 -0
  32. package/dist/native/components/__internal__/selectionControl/SelectionControlText.d.ts +1 -1
  33. package/dist/native/components/__internal__/selectionControl/SelectionControlText.d.ts.map +1 -1
  34. package/dist/native/components/__internal__/selectionControl/SelectionControlText.js +2 -1
  35. package/dist/native/components/__internal__/selectionControl/SelectionControlText.js.map +1 -1
  36. package/dist/native/components/__internal__/selectionControl/selectionControl.styles.d.ts +17 -0
  37. package/dist/native/components/__internal__/selectionControl/selectionControl.styles.d.ts.map +1 -0
  38. package/dist/native/components/__internal__/selectionControl/selectionControl.styles.js +20 -0
  39. package/dist/native/components/__internal__/selectionControl/selectionControl.styles.js.map +1 -0
  40. package/dist/native/components/__internal__/selectionControl/selectionControl.utils.d.ts +23 -0
  41. package/dist/native/components/__internal__/selectionControl/selectionControl.utils.d.ts.map +1 -0
  42. package/dist/native/components/__internal__/selectionControl/selectionControl.utils.js +20 -0
  43. package/dist/native/components/__internal__/selectionControl/selectionControl.utils.js.map +1 -0
  44. package/dist/native/components/atoms/Checkbox/index.d.ts +31 -9
  45. package/dist/native/components/atoms/Checkbox/index.d.ts.map +1 -0
  46. package/dist/native/components/atoms/Checkbox/index.js +39 -0
  47. package/dist/native/components/atoms/Checkbox/index.js.map +1 -0
  48. package/dist/native/components/atoms/Toggle/Toggle.styles.d.ts +0 -14
  49. package/dist/native/components/atoms/Toggle/Toggle.styles.d.ts.map +1 -1
  50. package/dist/native/components/atoms/Toggle/Toggle.styles.js +0 -14
  51. package/dist/native/components/atoms/Toggle/Toggle.styles.js.map +1 -1
  52. package/dist/native/components/atoms/Toggle/index.d.ts.map +1 -1
  53. package/dist/native/components/atoms/Toggle/index.js +3 -1
  54. package/dist/native/components/atoms/Toggle/index.js.map +1 -1
  55. package/dist/native/components/templates/WidgetLayout/index.d.ts +12 -0
  56. package/dist/providers/PortalContainer/index.d.ts +1 -1
  57. package/dist/providers/ThemeProvider/index.cjs +36 -14
  58. package/dist/providers/ThemeProvider/index.cjs.map +1 -1
  59. package/dist/providers/ThemeProvider/index.d.ts +19 -5
  60. package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
  61. package/dist/providers/ThemeProvider/index.js +36 -14
  62. package/dist/providers/ThemeProvider/index.js.map +1 -1
  63. package/dist/providers/UIProvider/hooks/usePortalAnchor.cjs +137 -0
  64. package/dist/providers/UIProvider/hooks/usePortalAnchor.cjs.map +1 -0
  65. package/dist/providers/UIProvider/hooks/usePortalAnchor.d.ts +60 -0
  66. package/dist/providers/UIProvider/hooks/usePortalAnchor.d.ts.map +1 -0
  67. package/dist/providers/UIProvider/hooks/usePortalAnchor.js +131 -0
  68. package/dist/providers/UIProvider/hooks/usePortalAnchor.js.map +1 -0
  69. package/dist/providers/UIProvider/index.cjs +7 -64
  70. package/dist/providers/UIProvider/index.cjs.map +1 -1
  71. package/dist/providers/UIProvider/index.d.ts +16 -11
  72. package/dist/providers/UIProvider/index.d.ts.map +1 -1
  73. package/dist/providers/UIProvider/index.js +7 -64
  74. package/dist/providers/UIProvider/index.js.map +1 -1
  75. package/dist/utilities/cssScopeUtils/index.cjs +22 -11
  76. package/dist/utilities/cssScopeUtils/index.cjs.map +1 -1
  77. package/dist/utilities/cssScopeUtils/index.d.ts +20 -9
  78. package/dist/utilities/cssScopeUtils/index.d.ts.map +1 -1
  79. package/dist/utilities/cssScopeUtils/index.js +22 -11
  80. package/dist/utilities/cssScopeUtils/index.js.map +1 -1
  81. package/dist/utilities/renderUtils/index.cjs +36 -7
  82. package/dist/utilities/renderUtils/index.cjs.map +1 -1
  83. package/dist/utilities/renderUtils/index.d.ts +23 -2
  84. package/dist/utilities/renderUtils/index.d.ts.map +1 -1
  85. package/dist/utilities/renderUtils/index.js +35 -8
  86. package/dist/utilities/renderUtils/index.js.map +1 -1
  87. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- type SelectionControlSize = 'sm' | 'md';
2
+ import { type SelectionControlSize } from './selectionControl.styles';
3
3
  interface SelectionControlTextProps {
4
4
  size: SelectionControlSize;
5
5
  label?: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionControlText.d.ts","sourceRoot":"","sources":["../../../../../src/components/__internal__/selectionControl/SelectionControlText.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,KAAK,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AAaxC,UAAU,yBAAyB;IACjC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,yHAAyH;AACzH,eAAO,MAAM,oBAAoB,GAAI,uBAAuB,yBAAyB,uCASpF,CAAC"}
1
+ {"version":3,"file":"SelectionControlText.d.ts","sourceRoot":"","sources":["../../../../../src/components/__internal__/selectionControl/SelectionControlText.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,oBAAoB,EAAyB,MAAM,2BAA2B,CAAC;AAa7F,UAAU,yBAAyB;IACjC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,yHAAyH;AACzH,eAAO,MAAM,oBAAoB,GAAI,uBAAuB,yBAAyB,uCASpF,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { cx } from '../../../utilities/cx/index.js';
3
3
  import { View, Text } from 'react-native';
4
+ import { selectionControlSizes } from './selectionControl.styles.js';
4
5
 
5
6
  // `Text` className is ignored by the current `react-native-css` preview (see Avatar), so label
6
7
  // typography goes through `style`. Mirrors `text-sm`/`text-md` + `font-medium`.
@@ -15,7 +16,7 @@ const HINT_COLOR = '#525252';
15
16
  const SelectionControlText = ({ size, label, hint }) => {
16
17
  if (!label && !hint)
17
18
  return null;
18
- return (jsxs(View, { className: cx('shrink flex-col', size === 'md' && 'gap-0.5'), children: [label ? jsx(Text, { style: { ...TEXT_SIZE[size], fontWeight: '500', color: LABEL_COLOR }, children: label }) : null, hint ? jsx(Text, { style: { ...TEXT_SIZE[size], color: HINT_COLOR }, children: hint }) : null] }));
19
+ return (jsxs(View, { className: cx('shrink flex-col', selectionControlSizes[size].textWrapper), children: [label ? jsx(Text, { style: { ...TEXT_SIZE[size], fontWeight: '500', color: LABEL_COLOR }, children: label }) : null, hint ? jsx(Text, { style: { ...TEXT_SIZE[size], color: HINT_COLOR }, children: hint }) : null] }));
19
20
  };
20
21
 
21
22
  export { SelectionControlText };
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionControlText.js","sources":["../../../../../../src/components/__internal__/selectionControl/SelectionControlText.native.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":";;;;AAMA;AACA;AACA,MAAM,SAAS,GAA2E;IACxF,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IACpC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;CACrC;AAED;AACA,MAAM,WAAW,GAAG,SAAS;AAC7B,MAAM,UAAU,GAAG,SAAS;AAQ5B;AACO,MAAM,oBAAoB,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAA6B,KAAI;AACvF,IAAA,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AAEhC,IAAA,QACEA,IAAA,CAAC,IAAI,EAAA,EAAC,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,IAAI,KAAK,IAAI,IAAI,SAAS,CAAC,EAAA,QAAA,EAAA,CAC/D,KAAK,GAAGC,GAAA,CAAC,IAAI,EAAA,EAAC,KAAK,EAAE,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,YAAG,KAAK,EAAA,CAAQ,GAAG,IAAI,EACzG,IAAI,GAAGA,GAAA,CAAC,IAAI,EAAA,EAAC,KAAK,EAAE,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAA,QAAA,EAAG,IAAI,GAAQ,GAAG,IAAI,CAAA,EAAA,CAC/E;AAEX;;"}
1
+ {"version":3,"file":"SelectionControlText.js","sources":["../../../../../../src/components/__internal__/selectionControl/SelectionControlText.native.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":";;;;;AAKA;AACA;AACA,MAAM,SAAS,GAA2E;IACxF,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IACpC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;CACrC;AAED;AACA,MAAM,WAAW,GAAG,SAAS;AAC7B,MAAM,UAAU,GAAG,SAAS;AAQ5B;AACO,MAAM,oBAAoB,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAA6B,KAAI;AACvF,IAAA,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AAEhC,IAAA,QACEA,IAAA,CAAC,IAAI,EAAA,EAAC,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,EAAA,QAAA,EAAA,CAC5E,KAAK,GAAGC,GAAA,CAAC,IAAI,EAAA,EAAC,KAAK,EAAE,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAA,QAAA,EAAG,KAAK,EAAA,CAAQ,GAAG,IAAI,EACzG,IAAI,GAAGA,IAAC,IAAI,EAAA,EAAC,KAAK,EAAE,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAA,QAAA,EAAG,IAAI,GAAQ,GAAG,IAAI,CAAA,EAAA,CAC/E;AAEX;;"}
@@ -0,0 +1,17 @@
1
+ export type SelectionControlSize = 'sm' | 'md';
2
+ /** Root gap and label/hint typography shared by `Toggle`, `Checkbox` and `RadioButton` on web and React Native. */
3
+ export declare const selectionControlSizes: {
4
+ sm: {
5
+ root: string;
6
+ textWrapper: string;
7
+ label: string;
8
+ hint: string;
9
+ };
10
+ md: {
11
+ root: string;
12
+ textWrapper: string;
13
+ label: string;
14
+ hint: string;
15
+ };
16
+ };
17
+ //# sourceMappingURL=selectionControl.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionControl.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/__internal__/selectionControl/selectionControl.styles.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,mHAAmH;AACnH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;CAakE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { sortCx } from '../../../utilities/cx/index.js';
2
+
3
+ /** Root gap and label/hint typography shared by `Toggle`, `Checkbox` and `RadioButton` on web and React Native. */
4
+ const selectionControlSizes = sortCx({
5
+ sm: {
6
+ root: 'gap-2',
7
+ textWrapper: '',
8
+ label: 'text-sm font-medium',
9
+ hint: 'text-sm',
10
+ },
11
+ md: {
12
+ root: 'gap-3',
13
+ textWrapper: 'gap-0.5',
14
+ label: 'text-md font-medium',
15
+ hint: 'text-md',
16
+ },
17
+ });
18
+
19
+ export { selectionControlSizes };
20
+ //# sourceMappingURL=selectionControl.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionControl.styles.js","sources":["../../../../../../src/components/__internal__/selectionControl/selectionControl.styles.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAIA;AACO,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC1C,IAAA,EAAE,EAAE;AACF,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,WAAW,EAAE,EAAE;AACf,QAAA,KAAK,EAAE,qBAAqB;AAC5B,QAAA,IAAI,EAAE,SAAS;AAChB,KAAA;AACD,IAAA,EAAE,EAAE;AACF,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,WAAW,EAAE,SAAS;AACtB,QAAA,KAAK,EAAE,qBAAqB;AAC5B,QAAA,IAAI,EAAE,SAAS;AAChB,KAAA;AACgG,CAAA;;"}
@@ -0,0 +1,23 @@
1
+ import type { ReactNode } from 'react';
2
+ /**
3
+ * Accessible name for a native selection control, since RN's `accessibilityLabel` takes only a string.
4
+ *
5
+ * @param ariaLabel Explicit name from the web-style `aria-label` prop; always wins when set.
6
+ * @param label The visible label, used only when it is plain text.
7
+ * @returns The name to announce, or `undefined` when neither gives a string.
8
+ */
9
+ export declare const getAccessibleName: (ariaLabel: string | undefined, label: ReactNode) => string | undefined;
10
+ /**
11
+ * Screen-reader hint for a native selection control, since RN's `accessibilityHint` takes only a string.
12
+ *
13
+ * @param hint The visible hint, announced after the name only when it is plain text.
14
+ * @returns The hint to announce, or `undefined` for a non-string or missing hint.
15
+ */
16
+ export declare const getAccessibleHint: (hint: ReactNode) => string | undefined;
17
+ export declare const SELECTION_CONTROL_HIT_SLOP: {
18
+ top: number;
19
+ bottom: number;
20
+ left: number;
21
+ right: number;
22
+ };
23
+ //# sourceMappingURL=selectionControl.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionControl.utils.d.ts","sourceRoot":"","sources":["../../../../../src/components/__internal__/selectionControl/selectionControl.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,GAAG,SAAS,EAAE,OAAO,SAAS,KAAG,MAAM,GAAG,SAC/B,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,SAAS,KAAG,MAAM,GAAG,SAA0D,CAAC;AAGxH,eAAO,MAAM,0BAA0B;;;;;CAA6C,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Accessible name for a native selection control, since RN's `accessibilityLabel` takes only a string.
3
+ *
4
+ * @param ariaLabel Explicit name from the web-style `aria-label` prop; always wins when set.
5
+ * @param label The visible label, used only when it is plain text.
6
+ * @returns The name to announce, or `undefined` when neither gives a string.
7
+ */
8
+ const getAccessibleName = (ariaLabel, label) => ariaLabel ?? (typeof label === 'string' ? label : undefined);
9
+ /**
10
+ * Screen-reader hint for a native selection control, since RN's `accessibilityHint` takes only a string.
11
+ *
12
+ * @param hint The visible hint, announced after the name only when it is plain text.
13
+ * @returns The hint to announce, or `undefined` for a non-string or missing hint.
14
+ */
15
+ const getAccessibleHint = (hint) => (typeof hint === 'string' ? hint : undefined);
16
+ // Widens the 16–24px controls toward the 44pt minimum; vertical stops at 8 so options in a `gap-4` stack never overlap.
17
+ const SELECTION_CONTROL_HIT_SLOP = { top: 8, bottom: 8, left: 12, right: 12 };
18
+
19
+ export { SELECTION_CONTROL_HIT_SLOP, getAccessibleHint, getAccessibleName };
20
+ //# sourceMappingURL=selectionControl.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectionControl.utils.js","sources":["../../../../../../src/components/__internal__/selectionControl/selectionControl.utils.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEA;;;;;;AAMG;AACI,MAAM,iBAAiB,GAAG,CAAC,SAA6B,EAAE,KAAgB,KAC/E,SAAS,KAAK,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,SAAS;AAE7D;;;;;AAKG;MACU,iBAAiB,GAAG,CAAC,IAAe,MAA0B,OAAO,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,SAAS;AAEtH;MACa,0BAA0B,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE;;"}
@@ -1,12 +1,34 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface CheckboxProps {
3
+ /** Sets the box size and the label and hint text size. */
4
+ size?: 'sm' | 'md';
5
+ /** Text shown beside the box; pressing it toggles the checkbox. */
6
+ label?: ReactNode;
7
+ /** Supporting text shown below the label. */
8
+ hint?: ReactNode;
9
+ /** Controlled checked state — the checkbox is checked when true. */
10
+ isSelected?: boolean;
11
+ /** Initial checked state for uncontrolled usage. */
12
+ defaultSelected?: boolean;
13
+ /** Shows a dash instead of a check, for a parent whose children are partly checked. */
14
+ isIndeterminate?: boolean;
15
+ /** Disables interaction and shows a reduced-opacity state. */
16
+ isDisabled?: boolean;
17
+ /** Called with the new checked state whenever the user toggles it. */
18
+ onChange?: (isSelected: boolean) => void;
19
+ /** Extra classes merged onto the root `Pressable`. */
20
+ className?: string;
21
+ /** Web-style accessible name, used as `accessibilityLabel` so shared call sites work on both platforms. */
22
+ 'aria-label'?: string;
23
+ /** Overrides the generated `testID` (defaults to `fd-checkbox`). */
24
+ 'data-testid'?: string;
25
+ }
1
26
  /**
2
- * `Checkbox` has no React Native implementation.
27
+ * React Native `Checkbox` — the same box, check, dash, label and hint as web, built from
28
+ * `Pressable` and `View` instead of a react-aria `Checkbox`. The web `ring-inset` becomes a
29
+ * 1px border, which takes no extra space inside the fixed-size box.
3
30
  *
4
- * This is a generated types-only stub (scripts/emit-native-stubs.mjs). It exists so
5
- * that importing `@flipdish/ui-library/components/atoms/Checkbox` from React Native fails at
6
- * compile time rather than resolving to the web build's types. There is no
7
- * matching `index.js`, so Metro cannot bundle this module either.
8
- *
9
- * To make `Checkbox` available on React Native, add an `index.native.tsx` beside
10
- * its `index.tsx` — the build picks it up automatically and this stub disappears.
31
+ * @summary checkbox for selecting one or more options (React Native)
11
32
  */
12
- export declare const __NO_REACT_NATIVE_IMPLEMENTATION__: never;
33
+ export declare const Checkbox: ({ label, hint, size, className, isSelected: isSelectedProp, defaultSelected, isIndeterminate, isDisabled, onChange, "aria-label": ariaLabel, "data-testid": dataTestId, }: CheckboxProps) => import("react").JSX.Element;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/atoms/Checkbox/index.native.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAMjD,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,mEAAmE;IACnE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uFAAuF;IACvF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AASD;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,2KAYtB,aAAa,gCA4Cf,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Minus, Check } from '@flipdish/ui-icons';
3
+ import { cx } from '../../../utilities/cx/index.js';
4
+ import { useResolvedTestId } from '../../../utilities/testIdUtils/index.js';
5
+ import { useState } from 'react';
6
+ import { Pressable, View } from 'react-native';
7
+ import { SelectionControlText } from '../../__internal__/selectionControl/SelectionControlText.js';
8
+ import { selectionControlSizes } from '../../__internal__/selectionControl/selectionControl.styles.js';
9
+ import { SELECTION_CONTROL_HIT_SLOP, getAccessibleHint, getAccessibleName } from '../../__internal__/selectionControl/selectionControl.utils.js';
10
+
11
+ // Web draws both glyphs in a 14px viewBox with a 2px stroke; the ported 24px icons need 24/7 for the same weight.
12
+ const GLYPH_STROKE = 24 / 7;
13
+ const CHECK_SIZE = { sm: 12, md: 14 };
14
+ const DASH_SIZE = { sm: 10, md: 14 };
15
+ // `text-fg-white` — icons take a colour value, not a class.
16
+ const GLYPH_COLOR = '#ffffff';
17
+ /**
18
+ * React Native `Checkbox` — the same box, check, dash, label and hint as web, built from
19
+ * `Pressable` and `View` instead of a react-aria `Checkbox`. The web `ring-inset` becomes a
20
+ * 1px border, which takes no extra space inside the fixed-size box.
21
+ *
22
+ * @summary checkbox for selecting one or more options (React Native)
23
+ */
24
+ const Checkbox = ({ label, hint, size = 'sm', className, isSelected: isSelectedProp, defaultSelected = false, isIndeterminate, isDisabled, onChange, 'aria-label': ariaLabel, 'data-testid': dataTestId, }) => {
25
+ const checkboxTestId = useResolvedTestId({ testId: dataTestId, segment: 'checkbox', rootName: 'checkbox' });
26
+ const [uncontrolledSelected, setUncontrolledSelected] = useState(defaultSelected);
27
+ const isSelected = isSelectedProp ?? uncontrolledSelected;
28
+ const isFilled = isSelected || isIndeterminate;
29
+ const handlePress = () => {
30
+ const next = !isSelected;
31
+ if (isSelectedProp === undefined)
32
+ setUncontrolledSelected(next);
33
+ onChange?.(next);
34
+ };
35
+ return (jsxs(Pressable, { testID: checkboxTestId, disabled: isDisabled, onPress: handlePress, accessibilityRole: "checkbox", hitSlop: SELECTION_CONTROL_HIT_SLOP, accessibilityLabel: getAccessibleName(ariaLabel, label), accessibilityHint: getAccessibleHint(hint), accessibilityState: { checked: isIndeterminate ? 'mixed' : isSelected, disabled: Boolean(isDisabled) }, className: cx('relative flex flex-row items-start self-start', selectionControlSizes[size].root, className), children: [jsx(View, { className: cx('size-4 shrink-0 items-center justify-center rounded border border-primary bg-primary', size === 'md' && 'size-5 rounded-md', isFilled && 'border-brand-solid bg-brand-solid', isDisabled && 'opacity-50', isDisabled && !isFilled && 'bg-tertiary', (label || hint) && 'mt-0.5'), children: isIndeterminate ? (jsx(Minus, { size: DASH_SIZE[size], color: GLYPH_COLOR, strokeWidth: GLYPH_STROKE })) : isSelected ? (jsx(Check, { size: CHECK_SIZE[size], color: GLYPH_COLOR, strokeWidth: GLYPH_STROKE })) : null }), jsx(SelectionControlText, { size: size, label: label, hint: hint })] }));
36
+ };
37
+
38
+ export { Checkbox };
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../../../src/components/atoms/Checkbox/index.native.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;;;AAkCA;AACA,MAAM,YAAY,GAAG,EAAE,GAAG,CAAC;AAC3B,MAAM,UAAU,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAW;AAC9C,MAAM,SAAS,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAW;AAC7C;AACA,MAAM,WAAW,GAAG,SAAS;AAE7B;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,CAAC,EACvB,KAAK,EACL,IAAI,EACJ,IAAI,GAAG,IAAI,EACX,SAAS,EACT,UAAU,EAAE,cAAc,EAC1B,eAAe,GAAG,KAAK,EACvB,eAAe,EACf,UAAU,EACV,QAAQ,EACR,YAAY,EAAE,SAAS,EACvB,aAAa,EAAE,UAAU,GACX,KAAI;AAClB,IAAA,MAAM,cAAc,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAC3G,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC;AACjF,IAAA,MAAM,UAAU,GAAG,cAAc,IAAI,oBAAoB;AACzD,IAAA,MAAM,QAAQ,GAAG,UAAU,IAAI,eAAe;IAE9C,MAAM,WAAW,GAAG,MAAK;AACvB,QAAA,MAAM,IAAI,GAAG,CAAC,UAAU;QACxB,IAAI,cAAc,KAAK,SAAS;YAAE,uBAAuB,CAAC,IAAI,CAAC;AAC/D,QAAA,QAAQ,GAAG,IAAI,CAAC;AAClB,IAAA,CAAC;IAED,QACEA,KAAC,SAAS,EAAA,EACR,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,UAAU,EACpB,OAAO,EAAE,WAAW,EACpB,iBAAiB,EAAC,UAAU,EAC5B,OAAO,EAAE,0BAA0B,EACnC,kBAAkB,EAAE,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,EACvD,iBAAiB,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAC1C,kBAAkB,EAAE,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,GAAG,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,EACtG,SAAS,EAAE,EAAE,CAAC,+CAA+C,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAA,QAAA,EAAA,CAE3GC,GAAA,CAAC,IAAI,EAAA,EACH,SAAS,EAAE,EAAE,CACX,sFAAsF,EACtF,IAAI,KAAK,IAAI,IAAI,mBAAmB,EACpC,QAAQ,IAAI,mCAAmC,EAC/C,UAAU,IAAI,YAAY,EAC1B,UAAU,IAAI,CAAC,QAAQ,IAAI,aAAa,EACxC,CAAC,KAAK,IAAI,IAAI,KAAK,QAAQ,CAC5B,YAEA,eAAe,IACdA,IAAC,KAAK,EAAA,EAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAA,CAAI,IAC7E,UAAU,IACZA,GAAA,CAAC,KAAK,EAAA,EAAC,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAA,CAAI,IAC9E,IAAI,EAAA,CACH,EAEPA,IAAC,oBAAoB,EAAA,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAA,CAAI,CAAA,EAAA,CACpD;AAEhB;;"}
@@ -17,19 +17,5 @@ export declare const styles: {
17
17
  sm: string;
18
18
  md: string;
19
19
  };
20
- sizes: {
21
- sm: {
22
- root: string;
23
- textWrapper: string;
24
- label: string;
25
- hint: string;
26
- };
27
- md: {
28
- root: string;
29
- textWrapper: string;
30
- label: string;
31
- hint: string;
32
- };
33
- };
34
20
  };
35
21
  //# sourceMappingURL=Toggle.styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toggle.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/atoms/Toggle/Toggle.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCjB,CAAC"}
1
+ {"version":3,"file":"Toggle.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/atoms/Toggle/Toggle.styles.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;CAmBjB,CAAC"}
@@ -19,20 +19,6 @@ const styles = sortCx({
19
19
  sm: 'translate-x-4',
20
20
  md: 'translate-x-5',
21
21
  },
22
- sizes: {
23
- sm: {
24
- root: 'gap-2',
25
- textWrapper: '',
26
- label: 'text-sm font-medium',
27
- hint: 'text-sm',
28
- },
29
- md: {
30
- root: 'gap-3',
31
- textWrapper: 'gap-0.5',
32
- label: 'text-md font-medium',
33
- hint: 'text-md',
34
- },
35
- },
36
22
  });
37
23
 
38
24
  export { styles };
@@ -1 +1 @@
1
- {"version":3,"file":"Toggle.styles.js","sources":["../../../../../../src/components/atoms/Toggle/Toggle.styles.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAGO,MAAM,MAAM,GAAG,MAAM,CAAC;AAC3B,IAAA,KAAK,EAAE;AACL,QAAA,OAAO,EAAE;AACP,YAAA,EAAE,EAAE,eAAe;AACnB,YAAA,EAAE,EAAE,gBAAgB;AACrB,SAAA;AACD,QAAA,IAAI,EAAE;AACJ,YAAA,EAAE,EAAE,SAAS;AACb,YAAA,EAAE,EAAE,UAAU;AACf,SAAA;AAC+D,KAAA;AAClE,IAAA,IAAI,EAAE;AACJ,QAAA,EAAE,EAAE,QAAQ;AACZ,QAAA,EAAE,EAAE,QAAQ;AACwB,KAAA;AACtC,IAAA,YAAY,EAAE;AACZ,QAAA,EAAE,EAAE,eAAe;AACnB,QAAA,EAAE,EAAE,eAAe;AACiB,KAAA;AACtC,IAAA,KAAK,EAAE;AACL,QAAA,EAAE,EAAE;AACF,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,WAAW,EAAE,EAAE;AACf,YAAA,KAAK,EAAE,qBAAqB;AAC5B,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACD,QAAA,EAAE,EAAE;AACF,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,WAAW,EAAE,SAAS;AACtB,YAAA,KAAK,EAAE,qBAAqB;AAC5B,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACsF,KAAA;AAC1F,CAAA;;"}
1
+ {"version":3,"file":"Toggle.styles.js","sources":["../../../../../../src/components/atoms/Toggle/Toggle.styles.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAGO,MAAM,MAAM,GAAG,MAAM,CAAC;AAC3B,IAAA,KAAK,EAAE;AACL,QAAA,OAAO,EAAE;AACP,YAAA,EAAE,EAAE,eAAe;AACnB,YAAA,EAAE,EAAE,gBAAgB;AACrB,SAAA;AACD,QAAA,IAAI,EAAE;AACJ,YAAA,EAAE,EAAE,SAAS;AACb,YAAA,EAAE,EAAE,UAAU;AACf,SAAA;AAC+D,KAAA;AAClE,IAAA,IAAI,EAAE;AACJ,QAAA,EAAE,EAAE,QAAQ;AACZ,QAAA,EAAE,EAAE,QAAQ;AACwB,KAAA;AACtC,IAAA,YAAY,EAAE;AACZ,QAAA,EAAE,EAAE,eAAe;AACnB,QAAA,EAAE,EAAE,eAAe;AACiB,KAAA;AACvC,CAAA;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/atoms/Toggle/index.native.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAIpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,qFAAqF;IACrF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,GAAI,gKAYpB,WAAW,gCAyEb,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/atoms/Toggle/index.native.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AAMpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,qFAAqF;IACrF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,GAAI,gKAYpB,WAAW,gCA2Eb,CAAC"}
@@ -4,6 +4,8 @@ import { useResolvedTestId } from '../../../utilities/testIdUtils/index.js';
4
4
  import { useState, useRef, useEffect } from 'react';
5
5
  import { Animated, Easing, Pressable, View } from 'react-native';
6
6
  import { SelectionControlText } from '../../__internal__/selectionControl/SelectionControlText.js';
7
+ import { selectionControlSizes } from '../../__internal__/selectionControl/selectionControl.styles.js';
8
+ import { SELECTION_CONTROL_HIT_SLOP, getAccessibleHint } from '../../__internal__/selectionControl/selectionControl.utils.js';
7
9
  import { styles } from './Toggle.styles.js';
8
10
 
9
11
  // Matches the web knob's 150ms ease-in-out slide.
@@ -42,7 +44,7 @@ const Toggle = ({ label, hint, className, size = 'sm', slim, isSelected: isSelec
42
44
  setUncontrolledSelected(next);
43
45
  onChange?.(next);
44
46
  };
45
- return (jsxs(Pressable, { testID: toggleTestId, disabled: isDisabled, onPress: handlePress, onPressIn: () => setPressed(true), onPressOut: () => setPressed(false), accessibilityRole: "switch", accessibilityLabel: ariaLabel ?? label, accessibilityState: { checked: isSelected, disabled: Boolean(isDisabled) }, className: cx('relative flex flex-row items-start self-start', styles.sizes[size].root, className), children: [jsxs(View, { className: cx('flex-row rounded-full bg-tertiary', isDisabled && 'opacity-50', slim && 'mt-0.5', styles.track[slim ? 'slim' : 'default'][size]), children: [jsx(Animated.View, { pointerEvents: "none", style: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, opacity: progress }, children: jsx(View, { className: cx('flex-1 rounded-full bg-brand-solid', pressed && 'bg-brand-solid_hover') }) }), jsx(View, { pointerEvents: "none", className: cx('absolute inset-0 rounded-full border-secondary', slim && isSelected && 'border-transparent'), style: { borderWidth: slim ? 1 : 0.5 } }), jsx(View, { className: "flex-1 flex-row", onLayout: handleKnobAreaLayout, children: jsx(Animated.View, { style: { transform: [{ translateX }] }, children: jsx(View, { className: cx('rounded-full bg-fg-white shadow-sm', slim && 'border border-toggle-border shadow-xs', slim && isSelected && 'border-toggle-slim-border_pressed', slim && isSelected && pressed && 'border-toggle-slim-border_pressed-hover', styles.knob[size]) }) }) })] }), jsx(SelectionControlText, { size: size, label: label, hint: hint })] }));
47
+ return (jsxs(Pressable, { testID: toggleTestId, disabled: isDisabled, onPress: handlePress, onPressIn: () => setPressed(true), onPressOut: () => setPressed(false), accessibilityRole: "switch", hitSlop: SELECTION_CONTROL_HIT_SLOP, accessibilityLabel: ariaLabel ?? label, accessibilityHint: getAccessibleHint(hint), accessibilityState: { checked: isSelected, disabled: Boolean(isDisabled) }, className: cx('relative flex flex-row items-start self-start', selectionControlSizes[size].root, className), children: [jsxs(View, { className: cx('flex-row rounded-full bg-tertiary', isDisabled && 'opacity-50', slim && 'mt-0.5', styles.track[slim ? 'slim' : 'default'][size]), children: [jsx(Animated.View, { pointerEvents: "none", style: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, opacity: progress }, children: jsx(View, { className: cx('flex-1 rounded-full bg-brand-solid', pressed && 'bg-brand-solid_hover') }) }), jsx(View, { pointerEvents: "none", className: cx('absolute inset-0 rounded-full border-secondary', slim && isSelected && 'border-transparent'), style: { borderWidth: slim ? 1 : 0.5 } }), jsx(View, { className: "flex-1 flex-row", onLayout: handleKnobAreaLayout, children: jsx(Animated.View, { style: { transform: [{ translateX }] }, children: jsx(View, { className: cx('rounded-full bg-fg-white shadow-sm', slim && 'border border-toggle-border shadow-xs', slim && isSelected && 'border-toggle-slim-border_pressed', slim && isSelected && pressed && 'border-toggle-slim-border_pressed-hover', styles.knob[size]) }) }) })] }), jsx(SelectionControlText, { size: size, label: label, hint: hint })] }));
46
48
  };
47
49
 
48
50
  export { Toggle };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../../src/components/atoms/Toggle/index.native.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../../src/components/atoms/Toggle/index.native.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `WidgetLayout` has no React Native implementation.
3
+ *
4
+ * This is a generated types-only stub (scripts/emit-native-stubs.mjs). It exists so
5
+ * that importing `@flipdish/ui-library/components/templates/WidgetLayout` from React Native fails at
6
+ * compile time rather than resolving to the web build's types. There is no
7
+ * matching `index.js`, so Metro cannot bundle this module either.
8
+ *
9
+ * To make `WidgetLayout` available on React Native, add an `index.native.tsx` beside
10
+ * its `index.tsx` — the build picks it up automatically and this stub disappears.
11
+ */
12
+ export declare const __NO_REACT_NATIVE_IMPLEMENTATION__: never;
@@ -19,7 +19,7 @@ export interface PortalContainerProps {
19
19
  * and is out of scope.
20
20
  *
21
21
  * @example
22
- * <PortalContainer getContainer={() => document.getElementById('flipdish-micro-frontend')}>
22
+ * <PortalContainer getContainer={() => document.getElementById('my-overlay-host')}>
23
23
  * <App />
24
24
  * </PortalContainer>
25
25
  */
@@ -17,6 +17,9 @@ const useTheme = () => {
17
17
  }
18
18
  return context;
19
19
  };
20
+ // Providers currently mirroring onto <html>, so a page with several (a Storybook docs page mounts one per
21
+ // story) only loses the attribute when the last one unmounts.
22
+ let documentThemeWriters = 0;
20
23
  const resolveSystemPreference = () => {
21
24
  if (typeof window === 'undefined')
22
25
  return 'light';
@@ -24,15 +27,20 @@ const resolveSystemPreference = () => {
24
27
  };
25
28
  /**
26
29
  * Provides light/dark/system theme context, persisted to `localStorage` and following the OS
27
- * when set to `system`. Renders a `display: contents` wrapper carrying `data-theme` so tokens
28
- * and the Tailwind `dark:` variant cascade, including inside CSS-scoped micro-frontends.
30
+ * when set to `system`. Renders a `display: contents` wrapper carrying `data-theme` (and
31
+ * `data-mfe-scope` when `scopeId` is set) so tokens and the Tailwind `dark:` variant cascade,
32
+ * including inside CSS-scoped micro-frontends.
29
33
  *
30
34
  * @summary light/dark/system theme provider carrying data-theme
31
35
  */
32
- const ThemeProvider = ({ children, defaultTheme = 'system', storageKey = 'ui-theme', themeModeOverride }) => {
36
+ const ThemeProvider = ({ children, defaultTheme = 'system', storageKey, themeModeOverride, scopeId: scopeIdProp, syncDocumentTheme: syncDocumentThemeProp, }) => {
37
+ // An empty scopeId is unset: it would stamp `data-mfe-scope=""` and switch the <html> mirror off for nothing.
38
+ const scopeId = scopeIdProp || undefined;
39
+ const syncDocumentTheme = syncDocumentThemeProp ?? (themeModeOverride === undefined && scopeId === undefined);
40
+ const resolvedStorageKey = storageKey ?? (scopeId ? `ui-theme:${scopeId}` : 'ui-theme');
33
41
  const [theme, setTheme] = React.useState(() => {
34
42
  if (typeof window !== 'undefined') {
35
- const savedTheme = localStorage.getItem(storageKey);
43
+ const savedTheme = localStorage.getItem(resolvedStorageKey);
36
44
  return savedTheme || defaultTheme;
37
45
  }
38
46
  return defaultTheme;
@@ -41,24 +49,38 @@ const ThemeProvider = ({ children, defaultTheme = 'system', storageKey = 'ui-the
41
49
  const [themeRoot, setThemeRoot] = React.useState(null);
42
50
  const activeTheme = themeModeOverride ?? theme;
43
51
  const resolvedMode = activeTheme === 'system' ? systemPreference : activeTheme;
52
+ // The cleanup removes the attribute, so a host document is left as it was found when the mirror
53
+ // turns off or the provider unmounts.
44
54
  React.useEffect(() => {
55
+ if (!syncDocumentTheme)
56
+ return;
57
+ documentThemeWriters += 1;
45
58
  document.documentElement.setAttribute('data-theme', resolvedMode);
46
- // Only persist the theme if it's not overridden
47
- if (!themeModeOverride) {
48
- if (activeTheme === 'system') {
49
- localStorage.removeItem(storageKey);
50
- }
51
- else {
52
- localStorage.setItem(storageKey, activeTheme);
53
- }
59
+ return () => {
60
+ documentThemeWriters -= 1;
61
+ if (documentThemeWriters === 0)
62
+ document.documentElement.removeAttribute('data-theme');
63
+ };
64
+ }, [syncDocumentTheme, resolvedMode]);
65
+ // Only persist the theme if it's not overridden
66
+ React.useEffect(() => {
67
+ if (themeModeOverride)
68
+ return;
69
+ if (activeTheme === 'system') {
70
+ localStorage.removeItem(resolvedStorageKey);
71
+ }
72
+ else {
73
+ localStorage.setItem(resolvedStorageKey, activeTheme);
54
74
  }
75
+ }, [activeTheme, themeModeOverride, resolvedStorageKey]);
76
+ React.useEffect(() => {
55
77
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
56
78
  const handleChange = () => setSystemPreference(mediaQuery.matches ? 'dark' : 'light');
57
79
  mediaQuery.addEventListener('change', handleChange);
58
80
  return () => mediaQuery.removeEventListener('change', handleChange);
59
- }, [resolvedMode, activeTheme, themeModeOverride, storageKey]);
81
+ }, []);
60
82
  const contextValue = React.useMemo(() => ({ theme: activeTheme, setTheme, themeRoot, resolvedMode }), [activeTheme, themeRoot, resolvedMode]);
61
- return (jsxRuntime.jsx(ThemeContext.Provider, { value: contextValue, children: jsxRuntime.jsx("div", { ref: setThemeRoot, "data-theme": resolvedMode, style: { display: 'contents' }, children: children }) }));
83
+ return (jsxRuntime.jsx(ThemeContext.Provider, { value: contextValue, children: jsxRuntime.jsx("div", { ref: setThemeRoot, "data-theme": resolvedMode, "data-mfe-scope": scopeId, style: { display: 'contents' }, children: children }) }));
62
84
  };
63
85
 
64
86
  exports.ThemeProvider = ThemeProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/providers/ThemeProvider/index.tsx"],"sourcesContent":[null],"names":["createContext","useContext","useState","useEffect","useMemo","_jsx"],"mappings":";;;;;AAcA,MAAM,YAAY,GAAGA,mBAAa,CAA+B,SAAS,CAAC;AAE3E;;;;;AAKG;AACI,MAAM,QAAQ,GAAG,MAAuB;AAC7C,IAAA,MAAM,OAAO,GAAGC,gBAAU,CAAC,YAAY,CAAC;AAExC,IAAA,IAAI,OAAO,KAAK,SAAS,EAAE;AACzB,QAAA,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC;IACjE;AAEA,IAAA,OAAO,OAAO;AAChB;AAEA,MAAM,uBAAuB,GAAG,MAAuB;IACrD,IAAI,OAAO,MAAM,KAAK,WAAW;AAAE,QAAA,OAAO,OAAO;AACjD,IAAA,OAAO,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO;AACrF,CAAC;AAqBD;;;;;;AAMG;AACI,MAAM,aAAa,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,GAAG,QAAQ,EAAE,UAAU,GAAG,UAAU,EAAE,iBAAiB,EAAsB,KAAI;IACrI,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAGC,cAAQ,CAAQ,MAAK;AAC7C,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAiB;YACnE,OAAO,UAAU,IAAI,YAAY;QACnC;AACA,QAAA,OAAO,YAAY;AACrB,IAAA,CAAC,CAAC;IAEF,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAGA,cAAQ,CAAmB,uBAAuB,CAAC;IACnG,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAGA,cAAQ,CAAqB,IAAI,CAAC;AAEpE,IAAA,MAAM,WAAW,GAAU,iBAAiB,IAAI,KAAK;AACrD,IAAA,MAAM,YAAY,GAAqB,WAAW,KAAK,QAAQ,GAAG,gBAAgB,GAAG,WAAW;IAEhGC,eAAS,CAAC,MAAK;QACb,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,YAAY,EAAE,YAAY,CAAC;;QAGjE,IAAI,CAAC,iBAAiB,EAAE;AACtB,YAAA,IAAI,WAAW,KAAK,QAAQ,EAAE;AAC5B,gBAAA,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC;YACrC;iBAAO;AACL,gBAAA,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC;YAC/C;QACF;QAEA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC;AACpE,QAAA,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,UAAU,CAAC,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AACrF,QAAA,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC;QACnD,OAAO,MAAM,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC;IACrE,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC;AAE9D,IAAA,MAAM,YAAY,GAAGC,aAAO,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAEvI,IAAA,QACEC,cAAA,CAAC,YAAY,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,QAAA,EACxCA,cAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,YAAY,EAAA,YAAA,EAAc,YAAY,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAA,QAAA,EAC7E,QAAQ,EAAA,CACL,EAAA,CACgB;AAE5B;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/providers/ThemeProvider/index.tsx"],"sourcesContent":[null],"names":["createContext","useContext","useState","useEffect","useMemo","_jsx"],"mappings":"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"}
@@ -21,8 +21,9 @@ interface ThemeProviderProps {
21
21
  */
22
22
  defaultTheme?: Theme;
23
23
  /**
24
- * The key to use to store the theme in localStorage
25
- * @default "ui-theme"
24
+ * The key to use to store the theme in localStorage. With `scopeId` the default is namespaced so
25
+ * sibling MFEs on one host do not share a key; an explicit key is used as given.
26
+ * @default "ui-theme", or "ui-theme:<scopeId>" when `scopeId` is set
26
27
  */
27
28
  storageKey?: string;
28
29
  /**
@@ -30,14 +31,27 @@ interface ThemeProviderProps {
30
31
  * internal state and skips localStorage persistence — useful for controlled MFE's or tests.
31
32
  */
32
33
  themeModeOverride?: 'light' | 'dark';
34
+ /**
35
+ * Stamps `data-mfe-scope={scopeId}` on the themed root so a scoped CSS build
36
+ * (`[data-mfe-scope="sale-service"]`) matches this tree and nothing else on the page.
37
+ */
38
+ scopeId?: string;
39
+ /**
40
+ * Mirrors `data-theme` onto `<html>` as well as the themed root, and removes it again on unmount or
41
+ * when turned off. An embedded app must not mutate the host document, so this is off whenever
42
+ * `themeModeOverride` or `scopeId` is set.
43
+ * @default true when neither `themeModeOverride` nor `scopeId` is set
44
+ */
45
+ syncDocumentTheme?: boolean;
33
46
  }
34
47
  /**
35
48
  * Provides light/dark/system theme context, persisted to `localStorage` and following the OS
36
- * when set to `system`. Renders a `display: contents` wrapper carrying `data-theme` so tokens
37
- * and the Tailwind `dark:` variant cascade, including inside CSS-scoped micro-frontends.
49
+ * when set to `system`. Renders a `display: contents` wrapper carrying `data-theme` (and
50
+ * `data-mfe-scope` when `scopeId` is set) so tokens and the Tailwind `dark:` variant cascade,
51
+ * including inside CSS-scoped micro-frontends.
38
52
  *
39
53
  * @summary light/dark/system theme provider carrying data-theme
40
54
  */
41
- export declare const ThemeProvider: ({ children, defaultTheme, storageKey, themeModeOverride }: ThemeProviderProps) => import("react").JSX.Element;
55
+ export declare const ThemeProvider: ({ children, defaultTheme, storageKey, themeModeOverride, scopeId: scopeIdProp, syncDocumentTheme: syncDocumentThemeProp, }: ThemeProviderProps) => import("react").JSX.Element;
42
56
  export {};
43
57
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/ThemeProvider/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,KAAK,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzC,UAAU,gBAAgB;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC;AAID;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,gBAQ3B,CAAC;AAOF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACtC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,2DAAmF,kBAAkB,gCA0ClI,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/ThemeProvider/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,KAAK,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzC,UAAU,gBAAgB;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC;AAID;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,gBAQ3B,CAAC;AAWF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,4HAO3B,kBAAkB,gCA0DpB,CAAC"}
@@ -15,6 +15,9 @@ const useTheme = () => {
15
15
  }
16
16
  return context;
17
17
  };
18
+ // Providers currently mirroring onto <html>, so a page with several (a Storybook docs page mounts one per
19
+ // story) only loses the attribute when the last one unmounts.
20
+ let documentThemeWriters = 0;
18
21
  const resolveSystemPreference = () => {
19
22
  if (typeof window === 'undefined')
20
23
  return 'light';
@@ -22,15 +25,20 @@ const resolveSystemPreference = () => {
22
25
  };
23
26
  /**
24
27
  * Provides light/dark/system theme context, persisted to `localStorage` and following the OS
25
- * when set to `system`. Renders a `display: contents` wrapper carrying `data-theme` so tokens
26
- * and the Tailwind `dark:` variant cascade, including inside CSS-scoped micro-frontends.
28
+ * when set to `system`. Renders a `display: contents` wrapper carrying `data-theme` (and
29
+ * `data-mfe-scope` when `scopeId` is set) so tokens and the Tailwind `dark:` variant cascade,
30
+ * including inside CSS-scoped micro-frontends.
27
31
  *
28
32
  * @summary light/dark/system theme provider carrying data-theme
29
33
  */
30
- const ThemeProvider = ({ children, defaultTheme = 'system', storageKey = 'ui-theme', themeModeOverride }) => {
34
+ const ThemeProvider = ({ children, defaultTheme = 'system', storageKey, themeModeOverride, scopeId: scopeIdProp, syncDocumentTheme: syncDocumentThemeProp, }) => {
35
+ // An empty scopeId is unset: it would stamp `data-mfe-scope=""` and switch the <html> mirror off for nothing.
36
+ const scopeId = scopeIdProp || undefined;
37
+ const syncDocumentTheme = syncDocumentThemeProp ?? (themeModeOverride === undefined && scopeId === undefined);
38
+ const resolvedStorageKey = storageKey ?? (scopeId ? `ui-theme:${scopeId}` : 'ui-theme');
31
39
  const [theme, setTheme] = useState(() => {
32
40
  if (typeof window !== 'undefined') {
33
- const savedTheme = localStorage.getItem(storageKey);
41
+ const savedTheme = localStorage.getItem(resolvedStorageKey);
34
42
  return savedTheme || defaultTheme;
35
43
  }
36
44
  return defaultTheme;
@@ -39,24 +47,38 @@ const ThemeProvider = ({ children, defaultTheme = 'system', storageKey = 'ui-the
39
47
  const [themeRoot, setThemeRoot] = useState(null);
40
48
  const activeTheme = themeModeOverride ?? theme;
41
49
  const resolvedMode = activeTheme === 'system' ? systemPreference : activeTheme;
50
+ // The cleanup removes the attribute, so a host document is left as it was found when the mirror
51
+ // turns off or the provider unmounts.
42
52
  useEffect(() => {
53
+ if (!syncDocumentTheme)
54
+ return;
55
+ documentThemeWriters += 1;
43
56
  document.documentElement.setAttribute('data-theme', resolvedMode);
44
- // Only persist the theme if it's not overridden
45
- if (!themeModeOverride) {
46
- if (activeTheme === 'system') {
47
- localStorage.removeItem(storageKey);
48
- }
49
- else {
50
- localStorage.setItem(storageKey, activeTheme);
51
- }
57
+ return () => {
58
+ documentThemeWriters -= 1;
59
+ if (documentThemeWriters === 0)
60
+ document.documentElement.removeAttribute('data-theme');
61
+ };
62
+ }, [syncDocumentTheme, resolvedMode]);
63
+ // Only persist the theme if it's not overridden
64
+ useEffect(() => {
65
+ if (themeModeOverride)
66
+ return;
67
+ if (activeTheme === 'system') {
68
+ localStorage.removeItem(resolvedStorageKey);
69
+ }
70
+ else {
71
+ localStorage.setItem(resolvedStorageKey, activeTheme);
52
72
  }
73
+ }, [activeTheme, themeModeOverride, resolvedStorageKey]);
74
+ useEffect(() => {
53
75
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
54
76
  const handleChange = () => setSystemPreference(mediaQuery.matches ? 'dark' : 'light');
55
77
  mediaQuery.addEventListener('change', handleChange);
56
78
  return () => mediaQuery.removeEventListener('change', handleChange);
57
- }, [resolvedMode, activeTheme, themeModeOverride, storageKey]);
79
+ }, []);
58
80
  const contextValue = useMemo(() => ({ theme: activeTheme, setTheme, themeRoot, resolvedMode }), [activeTheme, themeRoot, resolvedMode]);
59
- return (jsx(ThemeContext.Provider, { value: contextValue, children: jsx("div", { ref: setThemeRoot, "data-theme": resolvedMode, style: { display: 'contents' }, children: children }) }));
81
+ return (jsx(ThemeContext.Provider, { value: contextValue, children: jsx("div", { ref: setThemeRoot, "data-theme": resolvedMode, "data-mfe-scope": scopeId, style: { display: 'contents' }, children: children }) }));
60
82
  };
61
83
 
62
84
  export { ThemeProvider, useTheme };