@gryt/ui-native 0.1.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 (137) hide show
  1. package/README.md +86 -0
  2. package/dist/components/Accordion/Accordion.d.ts +35 -0
  3. package/dist/components/Accordion/Accordion.d.ts.map +1 -0
  4. package/dist/components/Accordion/Accordion.js +66 -0
  5. package/dist/components/Alert/Alert.d.ts +21 -0
  6. package/dist/components/Alert/Alert.d.ts.map +1 -0
  7. package/dist/components/Alert/Alert.js +35 -0
  8. package/dist/components/AlertDialog/AlertDialog.d.ts +38 -0
  9. package/dist/components/AlertDialog/AlertDialog.d.ts.map +1 -0
  10. package/dist/components/AlertDialog/AlertDialog.js +15 -0
  11. package/dist/components/Avatar/Avatar.d.ts +10 -0
  12. package/dist/components/Avatar/Avatar.d.ts.map +1 -0
  13. package/dist/components/Avatar/Avatar.js +57 -0
  14. package/dist/components/Badge/Badge.d.ts +13 -0
  15. package/dist/components/Badge/Badge.d.ts.map +1 -0
  16. package/dist/components/Badge/Badge.js +28 -0
  17. package/dist/components/Button/Button.d.ts +24 -0
  18. package/dist/components/Button/Button.d.ts.map +1 -0
  19. package/dist/components/Button/Button.js +61 -0
  20. package/dist/components/Card/Card.d.ts +19 -0
  21. package/dist/components/Card/Card.d.ts.map +1 -0
  22. package/dist/components/Card/Card.js +45 -0
  23. package/dist/components/Checkbox/Checkbox.d.ts +24 -0
  24. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
  25. package/dist/components/Checkbox/Checkbox.js +43 -0
  26. package/dist/components/Chip/Chip.d.ts +17 -0
  27. package/dist/components/Chip/Chip.d.ts.map +1 -0
  28. package/dist/components/Chip/Chip.js +38 -0
  29. package/dist/components/Collapsible/Collapsible.d.ts +31 -0
  30. package/dist/components/Collapsible/Collapsible.d.ts.map +1 -0
  31. package/dist/components/Collapsible/Collapsible.js +34 -0
  32. package/dist/components/Dialog/Dialog.d.ts +67 -0
  33. package/dist/components/Dialog/Dialog.d.ts.map +1 -0
  34. package/dist/components/Dialog/Dialog.js +112 -0
  35. package/dist/components/Divider/Divider.d.ts +16 -0
  36. package/dist/components/Divider/Divider.d.ts.map +1 -0
  37. package/dist/components/Divider/Divider.js +21 -0
  38. package/dist/components/Drawer/Drawer.d.ts +44 -0
  39. package/dist/components/Drawer/Drawer.d.ts.map +1 -0
  40. package/dist/components/Drawer/Drawer.js +83 -0
  41. package/dist/components/Menu/Menu.d.ts +56 -0
  42. package/dist/components/Menu/Menu.d.ts.map +1 -0
  43. package/dist/components/Menu/Menu.js +76 -0
  44. package/dist/components/Meter/Meter.d.ts +21 -0
  45. package/dist/components/Meter/Meter.d.ts.map +1 -0
  46. package/dist/components/Meter/Meter.js +32 -0
  47. package/dist/components/NumberField/NumberField.d.ts +23 -0
  48. package/dist/components/NumberField/NumberField.d.ts.map +1 -0
  49. package/dist/components/NumberField/NumberField.js +56 -0
  50. package/dist/components/OtpField/OtpField.d.ts +24 -0
  51. package/dist/components/OtpField/OtpField.d.ts.map +1 -0
  52. package/dist/components/OtpField/OtpField.js +49 -0
  53. package/dist/components/Popover/Popover.d.ts +48 -0
  54. package/dist/components/Popover/Popover.d.ts.map +1 -0
  55. package/dist/components/Popover/Popover.js +54 -0
  56. package/dist/components/Progress/Progress.d.ts +18 -0
  57. package/dist/components/Progress/Progress.d.ts.map +1 -0
  58. package/dist/components/Progress/Progress.js +30 -0
  59. package/dist/components/Radio/Radio.d.ts +28 -0
  60. package/dist/components/Radio/Radio.d.ts.map +1 -0
  61. package/dist/components/Radio/Radio.js +53 -0
  62. package/dist/components/ScrollArea/ScrollArea.d.ts +22 -0
  63. package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -0
  64. package/dist/components/ScrollArea/ScrollArea.js +17 -0
  65. package/dist/components/Select/Select.d.ts +34 -0
  66. package/dist/components/Select/Select.d.ts.map +1 -0
  67. package/dist/components/Select/Select.js +71 -0
  68. package/dist/components/Skeleton/Skeleton.d.ts +18 -0
  69. package/dist/components/Skeleton/Skeleton.d.ts.map +1 -0
  70. package/dist/components/Skeleton/Skeleton.js +28 -0
  71. package/dist/components/Slider/Slider.d.ts +29 -0
  72. package/dist/components/Slider/Slider.d.ts.map +1 -0
  73. package/dist/components/Slider/Slider.js +94 -0
  74. package/dist/components/Spinner/Spinner.d.ts +20 -0
  75. package/dist/components/Spinner/Spinner.d.ts.map +1 -0
  76. package/dist/components/Spinner/Spinner.js +18 -0
  77. package/dist/components/Surface/Surface.d.ts +17 -0
  78. package/dist/components/Surface/Surface.d.ts.map +1 -0
  79. package/dist/components/Surface/Surface.js +22 -0
  80. package/dist/components/Switch/Switch.d.ts +25 -0
  81. package/dist/components/Switch/Switch.d.ts.map +1 -0
  82. package/dist/components/Switch/Switch.js +65 -0
  83. package/dist/components/Tabs/Tabs.d.ts +51 -0
  84. package/dist/components/Tabs/Tabs.d.ts.map +1 -0
  85. package/dist/components/Tabs/Tabs.js +82 -0
  86. package/dist/components/TextField/TextField.d.ts +15 -0
  87. package/dist/components/TextField/TextField.d.ts.map +1 -0
  88. package/dist/components/TextField/TextField.js +47 -0
  89. package/dist/components/Toast/Toast.d.ts +31 -0
  90. package/dist/components/Toast/Toast.d.ts.map +1 -0
  91. package/dist/components/Toast/Toast.js +86 -0
  92. package/dist/components/Toggle/Toggle.d.ts +19 -0
  93. package/dist/components/Toggle/Toggle.d.ts.map +1 -0
  94. package/dist/components/Toggle/Toggle.js +41 -0
  95. package/dist/components/Toolbar/Toolbar.d.ts +25 -0
  96. package/dist/components/Toolbar/Toolbar.d.ts.map +1 -0
  97. package/dist/components/Toolbar/Toolbar.js +35 -0
  98. package/dist/components/Tooltip/Tooltip.d.ts +40 -0
  99. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -0
  100. package/dist/components/Tooltip/Tooltip.js +52 -0
  101. package/dist/hooks/useReducedMotion.d.ts +10 -0
  102. package/dist/hooks/useReducedMotion.d.ts.map +1 -0
  103. package/dist/hooks/useReducedMotion.js +26 -0
  104. package/dist/index.d.ts +39 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +38 -0
  107. package/dist/overlay/AnchoredPopup.d.ts +26 -0
  108. package/dist/overlay/AnchoredPopup.d.ts.map +1 -0
  109. package/dist/overlay/AnchoredPopup.js +36 -0
  110. package/dist/overlay/placePopup.d.ts +51 -0
  111. package/dist/overlay/placePopup.d.ts.map +1 -0
  112. package/dist/overlay/placePopup.js +63 -0
  113. package/dist/overlay/useAnchoredPosition.d.ts +18 -0
  114. package/dist/overlay/useAnchoredPosition.d.ts.map +1 -0
  115. package/dist/overlay/useAnchoredPosition.js +25 -0
  116. package/dist/overlay/useOpenState.d.ts +17 -0
  117. package/dist/overlay/useOpenState.d.ts.map +1 -0
  118. package/dist/overlay/useOpenState.js +12 -0
  119. package/dist/theme/ThemeProvider.d.ts +17 -0
  120. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  121. package/dist/theme/ThemeProvider.js +17 -0
  122. package/dist/theme/createNativeTheme.d.ts +82 -0
  123. package/dist/theme/createNativeTheme.d.ts.map +1 -0
  124. package/dist/theme/createNativeTheme.js +65 -0
  125. package/dist/theme/index.d.ts +6 -0
  126. package/dist/theme/index.d.ts.map +1 -0
  127. package/dist/theme/index.js +5 -0
  128. package/dist/theme/themeContext.d.ts +9 -0
  129. package/dist/theme/themeContext.d.ts.map +1 -0
  130. package/dist/theme/themeContext.js +9 -0
  131. package/dist/theme/tones.d.ts +15 -0
  132. package/dist/theme/tones.d.ts.map +1 -0
  133. package/dist/theme/tones.js +11 -0
  134. package/dist/theme/useTheme.d.ts +8 -0
  135. package/dist/theme/useTheme.d.ts.map +1 -0
  136. package/dist/theme/useTheme.js +10 -0
  137. package/package.json +46 -0
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Pressable, Text } from "react-native";
4
+ import { toneRamp, useTheme } from "../../theme/index.js";
5
+ const SIZE = 20;
6
+ /**
7
+ * The tick is a text glyph rather than an icon.
8
+ *
9
+ * `@gryt/ui` renders a Phosphor `Check`. Pulling an icon library in here would
10
+ * be the first runtime dependency this package has, for one glyph, and
11
+ * `@phosphor-icons/react` renders SVG that React Native cannot mount without
12
+ * react-native-svg on top. Both are decisions for whoever needs a full icon set,
13
+ * not for a checkbox.
14
+ */
15
+ export function Checkbox({ checked: controlled, defaultChecked = false, indeterminate = false, onCheckedChange, disabled, tone = "primary", style, accessibilityLabel, }) {
16
+ const theme = useTheme();
17
+ const [uncontrolled, setUncontrolled] = useState(defaultChecked);
18
+ const checked = controlled ?? uncontrolled;
19
+ const ramp = toneRamp(theme, tone);
20
+ const filled = checked || indeterminate;
21
+ return (_jsx(Pressable, { accessibilityRole: "checkbox", accessibilityState: {
22
+ checked: indeterminate ? "mixed" : checked,
23
+ disabled: !!disabled,
24
+ }, accessibilityLabel: accessibilityLabel, disabled: disabled, onPress: () => {
25
+ const next = !checked;
26
+ if (controlled === undefined)
27
+ setUncontrolled(next);
28
+ onCheckedChange?.(next);
29
+ }, style: [
30
+ {
31
+ width: SIZE,
32
+ height: SIZE,
33
+ borderRadius: theme.radius.sm,
34
+ alignItems: "center",
35
+ justifyContent: "center",
36
+ borderWidth: filled ? 0 : 1.5,
37
+ borderColor: theme.color.border,
38
+ backgroundColor: filled ? ramp[8] : "transparent",
39
+ opacity: disabled ? 0.5 : 1,
40
+ },
41
+ style,
42
+ ], children: filled ? (_jsx(Text, { style: { color: theme.color.bg, fontSize: 13, fontWeight: "900", lineHeight: 15 }, children: indeterminate ? "–" : "✓" })) : null }));
43
+ }
@@ -0,0 +1,17 @@
1
+ import { type StyleProp, type ViewStyle } from "react-native";
2
+ export type ChipTone = "neutral" | "accent" | "secondary" | "success" | "danger" | "warning";
3
+ export type ChipVariant = "soft" | "solid" | "outline";
4
+ export interface ChipProps {
5
+ label: string;
6
+ tone?: ChipTone;
7
+ variant?: ChipVariant;
8
+ style?: StyleProp<ViewStyle>;
9
+ }
10
+ /**
11
+ * A small status label. No interaction — that is Button's job.
12
+ *
13
+ * Steps 3, 9 and 11 are the same ones `@gryt/ui` picks: 3 is the soft fill, 9
14
+ * is the solid one, 11 is text that passes contrast against both.
15
+ */
16
+ export declare function Chip({ label, tone, variant, style, }: ChipProps): import("react").JSX.Element;
17
+ //# sourceMappingURL=Chip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../src/components/Chip/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAI1E,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC7F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,IAAgB,EAChB,OAAgB,EAChB,KAAK,GACN,EAAE,SAAS,+BA4CX"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text, View } from "react-native";
3
+ import { useTheme } from "../../theme/index.js";
4
+ /**
5
+ * A small status label. No interaction — that is Button's job.
6
+ *
7
+ * Steps 3, 9 and 11 are the same ones `@gryt/ui` picks: 3 is the soft fill, 9
8
+ * is the solid one, 11 is text that passes contrast against both.
9
+ */
10
+ export function Chip({ label, tone = "neutral", variant = "soft", style, }) {
11
+ const theme = useTheme();
12
+ const ramp = theme.scales[tone];
13
+ const background = variant === "solid" ? ramp[8] : variant === "soft" ? ramp[2] : "transparent";
14
+ const foreground = variant === "solid"
15
+ ? tone === "accent"
16
+ ? theme.color.onAccent
17
+ : tone === "secondary"
18
+ ? theme.color.onSecondary
19
+ : tone === "danger"
20
+ ? theme.color.onDanger
21
+ : theme.color.bg
22
+ : ramp[10];
23
+ return (_jsx(View, { style: [
24
+ {
25
+ alignSelf: "flex-start",
26
+ flexDirection: "row",
27
+ alignItems: "center",
28
+ backgroundColor: background,
29
+ borderRadius: theme.radius.full,
30
+ paddingHorizontal: theme.space(2.5),
31
+ paddingVertical: theme.space(1),
32
+ ...(variant === "outline"
33
+ ? { borderWidth: 1, borderColor: ramp[6] }
34
+ : null),
35
+ },
36
+ style,
37
+ ], children: _jsx(Text, { numberOfLines: 1, style: { color: foreground, fontSize: 12, fontWeight: "600" }, children: label }) }));
38
+ }
@@ -0,0 +1,31 @@
1
+ import { type ReactNode } from "react";
2
+ import { type StyleProp, type ViewStyle } from "react-native";
3
+ import { type OpenStateProps } from "../../overlay/useOpenState.js";
4
+ export interface CollapsibleRootProps extends OpenStateProps {
5
+ children?: ReactNode;
6
+ style?: StyleProp<ViewStyle>;
7
+ }
8
+ declare function Root({ children, style, ...openProps }: CollapsibleRootProps): import("react").JSX.Element;
9
+ declare function Trigger({ children, style }: {
10
+ children?: ReactNode;
11
+ style?: StyleProp<ViewStyle>;
12
+ }): import("react").JSX.Element;
13
+ /**
14
+ * Unmounted when closed, rather than animated to zero height.
15
+ *
16
+ * The web animates the panel's height, which needs the content measured first.
17
+ * React Native can do it with `onLayout` plus `Animated`, and it costs a frame
18
+ * of the content rendered at the wrong size before the measurement lands. Not
19
+ * worth it for the first pass, and it is in the exceptions table.
20
+ */
21
+ declare function Panel({ children, style }: {
22
+ children?: ReactNode;
23
+ style?: StyleProp<ViewStyle>;
24
+ }): import("react").JSX.Element | null;
25
+ export declare const Collapsible: {
26
+ Root: typeof Root;
27
+ Trigger: typeof Trigger;
28
+ Panel: typeof Panel;
29
+ };
30
+ export {};
31
+ //# sourceMappingURL=Collapsible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collapsible.d.ts","sourceRoot":"","sources":["../../../src/components/Collapsible/Collapsible.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/E,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAe/E,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,EAAE,oBAAoB,+BAOpE;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAY3F;AAED;;;;;;;GAOG;AACH,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,sCAIzF;AAED,eAAO,MAAM,WAAW;;;;CAA2B,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ import { Pressable, View } from "react-native";
4
+ import { useOpenState } from "../../overlay/useOpenState.js";
5
+ const CollapsibleContext = createContext(null);
6
+ function useCollapsible(part) {
7
+ const value = useContext(CollapsibleContext);
8
+ if (!value)
9
+ throw new Error(`Collapsible.${part} must be rendered inside Collapsible.Root.`);
10
+ return value;
11
+ }
12
+ function Root({ children, style, ...openProps }) {
13
+ const state = useOpenState(openProps);
14
+ return (_jsx(CollapsibleContext.Provider, { value: state, children: _jsx(View, { style: style, children: children }) }));
15
+ }
16
+ function Trigger({ children, style }) {
17
+ const { open, setOpen } = useCollapsible("Trigger");
18
+ return (_jsx(Pressable, { accessibilityRole: "button", accessibilityState: { expanded: open }, onPress: () => setOpen(!open), style: style, children: children }));
19
+ }
20
+ /**
21
+ * Unmounted when closed, rather than animated to zero height.
22
+ *
23
+ * The web animates the panel's height, which needs the content measured first.
24
+ * React Native can do it with `onLayout` plus `Animated`, and it costs a frame
25
+ * of the content rendered at the wrong size before the measurement lands. Not
26
+ * worth it for the first pass, and it is in the exceptions table.
27
+ */
28
+ function Panel({ children, style }) {
29
+ const { open } = useCollapsible("Panel");
30
+ if (!open)
31
+ return null;
32
+ return _jsx(View, { style: style, children: children });
33
+ }
34
+ export const Collapsible = { Root, Trigger, Panel };
@@ -0,0 +1,67 @@
1
+ import { type ReactNode } from "react";
2
+ import { type StyleProp, type TextStyle, type ViewStyle } from "react-native";
3
+ import { type OpenStateProps } from "../../overlay/useOpenState.js";
4
+ export interface DialogRootProps extends OpenStateProps {
5
+ children?: ReactNode;
6
+ }
7
+ declare function Root({ children, ...openProps }: DialogRootProps): import("react").JSX.Element;
8
+ export interface DialogTriggerProps {
9
+ children?: ReactNode;
10
+ style?: StyleProp<ViewStyle>;
11
+ }
12
+ declare function Trigger({ children, style }: DialogTriggerProps): import("react").JSX.Element;
13
+ /**
14
+ * A passthrough.
15
+ *
16
+ * On the web a portal is how the popup escapes overflow and stacking contexts.
17
+ * React Native's `Modal` already renders above everything, so there is nothing
18
+ * to escape. It exists so call sites keep the same shape.
19
+ */
20
+ declare function Portal({ children }: {
21
+ children?: ReactNode;
22
+ }): import("react").JSX.Element;
23
+ export interface DialogPopupProps {
24
+ children?: ReactNode;
25
+ style?: StyleProp<ViewStyle>;
26
+ dismissible?: boolean;
27
+ /** Long content scrolls rather than growing past the screen. */
28
+ scrollable?: boolean;
29
+ }
30
+ declare function Popup({ children, style, dismissible, scrollable, }: DialogPopupProps): import("react").JSX.Element;
31
+ /**
32
+ * Not rendered.
33
+ *
34
+ * The scrim is drawn by Popup, because React Native's Modal owns that layer and
35
+ * a separate backdrop element would have nothing to render into. Kept so call
36
+ * sites written against `@gryt/ui` do not have to drop a line.
37
+ */
38
+ declare function Backdrop(): null;
39
+ declare function Title({ children, style }: {
40
+ children?: ReactNode;
41
+ style?: StyleProp<TextStyle>;
42
+ }): import("react").JSX.Element;
43
+ declare function Description({ children, style }: {
44
+ children?: ReactNode;
45
+ style?: StyleProp<TextStyle>;
46
+ }): import("react").JSX.Element;
47
+ declare function Footer({ children, style }: {
48
+ children?: ReactNode;
49
+ style?: StyleProp<ViewStyle>;
50
+ }): import("react").JSX.Element;
51
+ declare function Close({ children, style }: {
52
+ children?: ReactNode;
53
+ style?: StyleProp<ViewStyle>;
54
+ }): import("react").JSX.Element;
55
+ export declare const Dialog: {
56
+ Root: typeof Root;
57
+ Trigger: typeof Trigger;
58
+ Portal: typeof Portal;
59
+ Backdrop: typeof Backdrop;
60
+ Popup: typeof Popup;
61
+ Title: typeof Title;
62
+ Description: typeof Description;
63
+ Footer: typeof Footer;
64
+ Close: typeof Close;
65
+ };
66
+ export {};
67
+ //# sourceMappingURL=Dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/Dialog/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAML,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AA2B/E,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,eAAe,+BAKxD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,kBAAkB,+BAOvD;AAED;;;;;;GAMG;AACH,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAErD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,iBAAS,KAAK,CAAC,EACb,QAAQ,EACR,KAAK,EACL,WAAkB,EAClB,UAAiB,GAClB,EAAE,gBAAgB,+BA+DlB;AAED;;;;;;GAMG;AACH,iBAAS,QAAQ,IAAI,IAAI,CAExB;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAUzF;AAED,iBAAS,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAO/F;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAY1F;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAOzF;AAED,eAAO,MAAM,MAAM;;;;;;;;;;CAUlB,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ import { Modal, Pressable, ScrollView, Text, View, } from "react-native";
4
+ import { useOpenState } from "../../overlay/useOpenState.js";
5
+ import { useTheme } from "../../theme/index.js";
6
+ const DialogContext = createContext(null);
7
+ function useDialog(part) {
8
+ const value = useContext(DialogContext);
9
+ if (!value) {
10
+ throw new Error(`Dialog.${part} must be rendered inside Dialog.Root.`);
11
+ }
12
+ return value;
13
+ }
14
+ function Root({ children, ...openProps }) {
15
+ const state = useOpenState(openProps);
16
+ return (_jsx(DialogContext.Provider, { value: state, children: children }));
17
+ }
18
+ function Trigger({ children, style }) {
19
+ const { setOpen } = useDialog("Trigger");
20
+ return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(true), style: style, children: children }));
21
+ }
22
+ /**
23
+ * A passthrough.
24
+ *
25
+ * On the web a portal is how the popup escapes overflow and stacking contexts.
26
+ * React Native's `Modal` already renders above everything, so there is nothing
27
+ * to escape. It exists so call sites keep the same shape.
28
+ */
29
+ function Portal({ children }) {
30
+ return _jsx(_Fragment, { children: children });
31
+ }
32
+ function Popup({ children, style, dismissible = true, scrollable = true, }) {
33
+ const { open, setOpen } = useDialog("Popup");
34
+ const theme = useTheme();
35
+ const body = (_jsx(View
36
+ // iOS hides everything behind a modal from VoiceOver with this; Android
37
+ // gets the same effect from Modal itself.
38
+ , {
39
+ // iOS hides everything behind a modal from VoiceOver with this; Android
40
+ // gets the same effect from Modal itself.
41
+ accessibilityViewIsModal: true, style: [
42
+ {
43
+ width: "100%",
44
+ maxWidth: 480,
45
+ maxHeight: "80%",
46
+ backgroundColor: theme.color.surfaceRaised,
47
+ borderRadius: theme.radius.lg,
48
+ borderWidth: 1,
49
+ borderColor: theme.color.border,
50
+ padding: theme.space(5),
51
+ gap: theme.space(3),
52
+ },
53
+ style,
54
+ ], children: scrollable ? (_jsx(ScrollView, { contentContainerStyle: { gap: theme.space(3) }, children: children })) : (children) }));
55
+ return (_jsx(Modal, { visible: open, transparent: true, animationType: "fade",
56
+ // Android's hardware back button, which is the closest thing a phone has
57
+ // to the Escape key Base UI listens for. AlertDialog turns it off for the
58
+ // same reason it turns off the scrim: neither is an answer.
59
+ onRequestClose: dismissible ? () => setOpen(false) : undefined, children: _jsx(Pressable
60
+ // The scrim doubles as the outside-press target, which is how Base UI
61
+ // dismisses too.
62
+ , {
63
+ // The scrim doubles as the outside-press target, which is how Base UI
64
+ // dismisses too.
65
+ onPress: dismissible ? () => setOpen(false) : undefined, style: {
66
+ flex: 1,
67
+ alignItems: "center",
68
+ justifyContent: "center",
69
+ padding: theme.space(5),
70
+ backgroundColor: "rgba(0,0,0,0.6)",
71
+ }, children: _jsx(Pressable, { onPress: () => { }, style: { width: "100%", alignItems: "center" }, children: body }) }) }));
72
+ }
73
+ /**
74
+ * Not rendered.
75
+ *
76
+ * The scrim is drawn by Popup, because React Native's Modal owns that layer and
77
+ * a separate backdrop element would have nothing to render into. Kept so call
78
+ * sites written against `@gryt/ui` do not have to drop a line.
79
+ */
80
+ function Backdrop() {
81
+ return null;
82
+ }
83
+ function Title({ children, style }) {
84
+ const theme = useTheme();
85
+ return (_jsx(Text, { accessibilityRole: "header", style: [{ color: theme.color.text, fontSize: 18, fontWeight: "600" }, style], children: children }));
86
+ }
87
+ function Description({ children, style }) {
88
+ const theme = useTheme();
89
+ return (_jsx(Text, { style: [{ color: theme.color.muted, fontSize: 14, lineHeight: 20 }, style], children: children }));
90
+ }
91
+ function Footer({ children, style }) {
92
+ const theme = useTheme();
93
+ return (_jsx(View, { style: [
94
+ { flexDirection: "row", justifyContent: "flex-end", gap: theme.space(3) },
95
+ style,
96
+ ], children: children }));
97
+ }
98
+ function Close({ children, style }) {
99
+ const { setOpen } = useDialog("Close");
100
+ return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(false), style: style, children: children }));
101
+ }
102
+ export const Dialog = {
103
+ Root,
104
+ Trigger,
105
+ Portal,
106
+ Backdrop,
107
+ Popup,
108
+ Title,
109
+ Description,
110
+ Footer,
111
+ Close,
112
+ };
@@ -0,0 +1,16 @@
1
+ import { type StyleProp, type ViewStyle } from "react-native";
2
+ export interface DividerProps {
3
+ orientation?: "horizontal" | "vertical";
4
+ /** Inset from both ends, in 4pt steps. */
5
+ inset?: number;
6
+ style?: StyleProp<ViewStyle>;
7
+ }
8
+ /**
9
+ * A hairline.
10
+ *
11
+ * The web uses 1px. Here it is `1` in device-independent points, which lands on
12
+ * one physical pixel on a 1x screen and stays a hairline on 2x and 3x — the same
13
+ * thing the web gets from a 1px border on a retina display.
14
+ */
15
+ export declare function Divider({ orientation, inset, style, }: DividerProps): import("react").JSX.Element;
16
+ //# sourceMappingURL=Divider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Divider.d.ts","sourceRoot":"","sources":["../../../src/components/Divider/Divider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAIpE,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EACtB,WAA0B,EAC1B,KAAS,EACT,KAAK,GACN,EAAE,YAAY,+BAgBd"}
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View } from "react-native";
3
+ import { useTheme } from "../../theme/index.js";
4
+ /**
5
+ * A hairline.
6
+ *
7
+ * The web uses 1px. Here it is `1` in device-independent points, which lands on
8
+ * one physical pixel on a 1x screen and stays a hairline on 2x and 3x — the same
9
+ * thing the web gets from a 1px border on a retina display.
10
+ */
11
+ export function Divider({ orientation = "horizontal", inset = 0, style, }) {
12
+ const theme = useTheme();
13
+ const gap = theme.space(inset);
14
+ return (_jsx(View, { accessibilityRole: "none", style: [
15
+ orientation === "horizontal"
16
+ ? { height: 1, alignSelf: "stretch", marginHorizontal: gap }
17
+ : { width: 1, alignSelf: "stretch", marginVertical: gap },
18
+ { backgroundColor: theme.color.border },
19
+ style,
20
+ ] }));
21
+ }
@@ -0,0 +1,44 @@
1
+ import { type ReactNode } from "react";
2
+ import { type StyleProp, type ViewStyle } from "react-native";
3
+ import { type OpenStateProps } from "../../overlay/useOpenState.js";
4
+ export type DrawerSide = "left" | "right" | "bottom";
5
+ export interface DrawerRootProps extends OpenStateProps {
6
+ children?: ReactNode;
7
+ }
8
+ declare function Root({ children, ...openProps }: DrawerRootProps): import("react").JSX.Element;
9
+ declare function Trigger({ children, style }: {
10
+ children?: ReactNode;
11
+ style?: StyleProp<ViewStyle>;
12
+ }): import("react").JSX.Element;
13
+ declare function Portal({ children }: {
14
+ children?: ReactNode;
15
+ }): import("react").JSX.Element;
16
+ export interface DrawerPopupProps {
17
+ children?: ReactNode;
18
+ side?: DrawerSide;
19
+ /** Fraction of the screen, 0 to 1. */
20
+ size?: number;
21
+ dismissible?: boolean;
22
+ style?: StyleProp<ViewStyle>;
23
+ }
24
+ /**
25
+ * Slides in from an edge, which is the one place an animation is not decoration.
26
+ *
27
+ * A drawer that appears without moving reads as a screen change rather than a
28
+ * panel, so this one animates even though Collapsible and Skeleton do not.
29
+ * Reduce-motion still turns it off: the drawer arrives in place instead.
30
+ */
31
+ declare function Popup({ children, side, size, dismissible, style, }: DrawerPopupProps): import("react").JSX.Element;
32
+ declare function Close({ children, style }: {
33
+ children?: ReactNode;
34
+ style?: StyleProp<ViewStyle>;
35
+ }): import("react").JSX.Element;
36
+ export declare const Drawer: {
37
+ Root: typeof Root;
38
+ Trigger: typeof Trigger;
39
+ Portal: typeof Portal;
40
+ Popup: typeof Popup;
41
+ Close: typeof Close;
42
+ };
43
+ export {};
44
+ //# sourceMappingURL=Drawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../../src/components/Drawer/Drawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG/E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAerD,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,eAAe,+BAGxD;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAO3F;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAErD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,iBAAS,KAAK,CAAC,EACb,QAAQ,EACR,IAAa,EACb,IAAU,EACV,WAAkB,EAClB,KAAK,GACN,EAAE,gBAAgB,+BAuElB;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAOzF;AAED,eAAO,MAAM,MAAM;;;;;;CAA0C,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useState } from "react";
3
+ import { Animated, Dimensions, Modal, Pressable, } from "react-native";
4
+ import { useReducedMotion } from "../../hooks/useReducedMotion.js";
5
+ import { useOpenState } from "../../overlay/useOpenState.js";
6
+ import { useTheme } from "../../theme/index.js";
7
+ const DrawerContext = createContext(null);
8
+ function useDrawer(part) {
9
+ const value = useContext(DrawerContext);
10
+ if (!value)
11
+ throw new Error(`Drawer.${part} must be rendered inside Drawer.Root.`);
12
+ return value;
13
+ }
14
+ function Root({ children, ...openProps }) {
15
+ const state = useOpenState(openProps);
16
+ return _jsx(DrawerContext.Provider, { value: state, children: children });
17
+ }
18
+ function Trigger({ children, style }) {
19
+ const { setOpen } = useDrawer("Trigger");
20
+ return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(true), style: style, children: children }));
21
+ }
22
+ function Portal({ children }) {
23
+ return _jsx(_Fragment, { children: children });
24
+ }
25
+ /**
26
+ * Slides in from an edge, which is the one place an animation is not decoration.
27
+ *
28
+ * A drawer that appears without moving reads as a screen change rather than a
29
+ * panel, so this one animates even though Collapsible and Skeleton do not.
30
+ * Reduce-motion still turns it off: the drawer arrives in place instead.
31
+ */
32
+ function Popup({ children, side = "left", size = 0.8, dismissible = true, style, }) {
33
+ const { open, setOpen } = useDrawer("Popup");
34
+ const theme = useTheme();
35
+ const reducedMotion = useReducedMotion();
36
+ const screen = Dimensions.get("window");
37
+ const vertical = side === "bottom";
38
+ const extent = vertical ? screen.height * size : screen.width * size;
39
+ const [progress] = useState(() => new Animated.Value(0));
40
+ useEffect(() => {
41
+ if (!open) {
42
+ progress.setValue(0);
43
+ return;
44
+ }
45
+ if (reducedMotion) {
46
+ progress.setValue(1);
47
+ return;
48
+ }
49
+ Animated.spring(progress, {
50
+ toValue: 1,
51
+ useNativeDriver: true,
52
+ speed: 20,
53
+ bounciness: 0,
54
+ }).start();
55
+ }, [open, progress, reducedMotion]);
56
+ const hidden = side === "right" ? extent : side === "left" ? -extent : extent;
57
+ const translate = progress.interpolate({
58
+ inputRange: [0, 1],
59
+ outputRange: [hidden, 0],
60
+ });
61
+ return (_jsx(Modal, { visible: open, transparent: true, animationType: "none", onRequestClose: dismissible ? () => setOpen(false) : undefined, children: _jsx(Pressable, { onPress: dismissible ? () => setOpen(false) : undefined, style: { flex: 1, backgroundColor: "rgba(0,0,0,0.6)" }, children: _jsx(Animated.View, { accessibilityViewIsModal: true, style: {
62
+ position: "absolute",
63
+ top: side === "bottom" ? undefined : 0,
64
+ bottom: 0,
65
+ left: side === "right" ? undefined : 0,
66
+ right: side === "left" ? undefined : 0,
67
+ width: vertical ? "100%" : extent,
68
+ height: vertical ? extent : "100%",
69
+ backgroundColor: theme.color.surface,
70
+ borderColor: theme.color.border,
71
+ borderRightWidth: side === "left" ? 1 : 0,
72
+ borderLeftWidth: side === "right" ? 1 : 0,
73
+ borderTopWidth: vertical ? 1 : 0,
74
+ borderTopLeftRadius: vertical ? theme.radius.lg : 0,
75
+ borderTopRightRadius: vertical ? theme.radius.lg : 0,
76
+ transform: [vertical ? { translateY: translate } : { translateX: translate }],
77
+ }, children: _jsx(Pressable, { onPress: () => { }, style: [{ flex: 1 }, style], children: children }) }) }) }));
78
+ }
79
+ function Close({ children, style }) {
80
+ const { setOpen } = useDrawer("Close");
81
+ return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(false), style: style, children: children }));
82
+ }
83
+ export const Drawer = { Root, Trigger, Portal, Popup, Close };
@@ -0,0 +1,56 @@
1
+ import { type ReactNode } from "react";
2
+ import { type StyleProp, type ViewStyle } from "react-native";
3
+ import type { Align, Side } from "../../overlay/placePopup.js";
4
+ import { type OpenStateProps } from "../../overlay/useOpenState.js";
5
+ export interface MenuRootProps extends OpenStateProps {
6
+ children?: ReactNode;
7
+ }
8
+ declare function Root({ children, ...openProps }: MenuRootProps): import("react").JSX.Element;
9
+ declare function Trigger({ children, style }: {
10
+ children?: ReactNode;
11
+ style?: StyleProp<ViewStyle>;
12
+ }): import("react").JSX.Element;
13
+ declare function Portal({ children }: {
14
+ children?: ReactNode;
15
+ }): import("react").JSX.Element;
16
+ /**
17
+ * Kept as a passthrough for shape.
18
+ *
19
+ * Base UI splits Positioner from Popup so the positioned box and the styled box
20
+ * are separate elements. Here AnchoredPopup is both, because there is no
21
+ * stacking context to escape and nothing gained by the extra view.
22
+ */
23
+ declare function Positioner({ children }: {
24
+ children?: ReactNode;
25
+ }): import("react").JSX.Element;
26
+ export interface MenuPopupProps {
27
+ children?: ReactNode;
28
+ side?: Side;
29
+ align?: Align;
30
+ sideOffset?: number;
31
+ style?: StyleProp<ViewStyle>;
32
+ }
33
+ declare function Popup({ children, style, ...options }: MenuPopupProps): import("react").JSX.Element;
34
+ export interface MenuItemProps {
35
+ children?: ReactNode;
36
+ onPress?: () => void;
37
+ disabled?: boolean;
38
+ /** Renders in the danger ramp, for destructive actions. */
39
+ destructive?: boolean;
40
+ style?: StyleProp<ViewStyle>;
41
+ }
42
+ declare function Item({ children, onPress, disabled, destructive, style }: MenuItemProps): import("react").JSX.Element;
43
+ declare function Separator({ style }: {
44
+ style?: StyleProp<ViewStyle>;
45
+ }): import("react").JSX.Element;
46
+ export declare const Menu: {
47
+ Root: typeof Root;
48
+ Trigger: typeof Trigger;
49
+ Portal: typeof Portal;
50
+ Positioner: typeof Positioner;
51
+ Popup: typeof Popup;
52
+ Item: typeof Item;
53
+ Separator: typeof Separator;
54
+ };
55
+ export {};
56
+ //# sourceMappingURL=Menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGrF,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAkB/E,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,aAAa,+BAQtD;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAY3F;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAErD;AAED;;;;;;GAMG;AACH,iBAAS,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAEzD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,cAAc,+BAe7D;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,aAAa,+BAuC/E;AAED,iBAAS,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAU7D;AAED,eAAO,MAAM,IAAI;;;;;;;;CAAgE,CAAC"}