@duro-app/ui 5.11.0 → 5.12.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 (157) hide show
  1. package/dist/Table-ColfpgKV.js.map +1 -1
  2. package/dist/compiler-runtime-BuugS4D0.js.map +1 -1
  3. package/dist/components/Alert/Alert.d.ts.map +1 -1
  4. package/dist/components/Button/Button.d.ts +2 -1
  5. package/dist/components/Button/Button.d.ts.map +1 -1
  6. package/dist/components/Button/styles.css.d.ts +1 -0
  7. package/dist/components/Button/styles.css.d.ts.map +1 -1
  8. package/dist/components/Callout/Callout.d.ts.map +1 -1
  9. package/dist/components/Callout/styles.css.d.ts +3 -0
  10. package/dist/components/Callout/styles.css.d.ts.map +1 -1
  11. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  12. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -1
  13. package/dist/components/DetailPanel/DetailPanel.d.ts.map +1 -1
  14. package/dist/components/Dialog/Dialog.d.ts +2 -17
  15. package/dist/components/Dialog/Dialog.d.ts.map +1 -1
  16. package/dist/components/Dialog/Dialog.stories.d.ts +4 -0
  17. package/dist/components/Dialog/Dialog.stories.d.ts.map +1 -1
  18. package/dist/components/Dialog/native.css.d.ts +82 -0
  19. package/dist/components/Dialog/native.css.d.ts.map +1 -0
  20. package/dist/components/Dialog/parts.css.d.ts +82 -0
  21. package/dist/components/Dialog/parts.css.d.ts.map +1 -0
  22. package/dist/components/Dialog/parts.d.ts +35 -0
  23. package/dist/components/Dialog/parts.d.ts.map +1 -0
  24. package/dist/components/Dialog/styles.css.d.ts +1 -74
  25. package/dist/components/Dialog/styles.css.d.ts.map +1 -1
  26. package/dist/components/Drawer/Drawer.d.ts.map +1 -1
  27. package/dist/components/Drawer/styles.css.d.ts +2 -0
  28. package/dist/components/Drawer/styles.css.d.ts.map +1 -1
  29. package/dist/components/Grid/styles.css.d.ts +1 -0
  30. package/dist/components/Grid/styles.css.d.ts.map +1 -1
  31. package/dist/components/Icon/Icon.d.ts +3 -9
  32. package/dist/components/Icon/Icon.d.ts.map +1 -1
  33. package/dist/components/Icon/geometry.d.ts +60 -0
  34. package/dist/components/Icon/geometry.d.ts.map +1 -0
  35. package/dist/components/Icon/types.d.ts +15 -0
  36. package/dist/components/Icon/types.d.ts.map +1 -0
  37. package/dist/components/Input/Input.d.ts +5 -1
  38. package/dist/components/Input/Input.d.ts.map +1 -1
  39. package/dist/components/Input/styles.css.d.ts +1 -0
  40. package/dist/components/Input/styles.css.d.ts.map +1 -1
  41. package/dist/components/LinkButton/styles.css.d.ts +1 -0
  42. package/dist/components/LinkButton/styles.css.d.ts.map +1 -1
  43. package/dist/components/Meter/styles.css.d.ts +1 -0
  44. package/dist/components/Meter/styles.css.d.ts.map +1 -1
  45. package/dist/components/PageShell/styles.css.d.ts +2 -0
  46. package/dist/components/PageShell/styles.css.d.ts.map +1 -1
  47. package/dist/components/RadioGroup/RadioGroup.d.ts +1 -17
  48. package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  49. package/dist/components/RadioGroup/RadioGroup.stories.d.ts +3 -0
  50. package/dist/components/RadioGroup/RadioGroup.stories.d.ts.map +1 -1
  51. package/dist/components/RadioGroup/group.d.ts +31 -0
  52. package/dist/components/RadioGroup/group.d.ts.map +1 -0
  53. package/dist/components/RadioGroup/styles.css.d.ts +10 -0
  54. package/dist/components/RadioGroup/styles.css.d.ts.map +1 -1
  55. package/dist/components/ScrollArea/styles.css.d.ts +1 -0
  56. package/dist/components/ScrollArea/styles.css.d.ts.map +1 -1
  57. package/dist/components/Spinner/Spinner.d.ts +2 -6
  58. package/dist/components/Spinner/Spinner.d.ts.map +1 -1
  59. package/dist/components/Spinner/Spinner.types.d.ts +6 -0
  60. package/dist/components/Spinner/Spinner.types.d.ts.map +1 -0
  61. package/dist/components/Spinner/ring.css.d.ts +39 -0
  62. package/dist/components/Spinner/ring.css.d.ts.map +1 -0
  63. package/dist/components/Spinner/styles.css.d.ts +1 -28
  64. package/dist/components/Spinner/styles.css.d.ts.map +1 -1
  65. package/dist/components/StatusIcon/StatusIcon.d.ts.map +1 -1
  66. package/dist/components/StatusIcon/styles.css.d.ts +3 -0
  67. package/dist/components/StatusIcon/styles.css.d.ts.map +1 -1
  68. package/dist/components/Switch/Switch.d.ts +2 -18
  69. package/dist/components/Switch/Switch.d.ts.map +1 -1
  70. package/dist/components/Switch/Switch.types.d.ts +18 -0
  71. package/dist/components/Switch/Switch.types.d.ts.map +1 -0
  72. package/dist/components/TableOfContents/styles.css.d.ts +1 -0
  73. package/dist/components/TableOfContents/styles.css.d.ts.map +1 -1
  74. package/dist/components/Textarea/styles.css.d.ts +1 -0
  75. package/dist/components/Textarea/styles.css.d.ts.map +1 -1
  76. package/dist/components/Toggle/Toggle.d.ts.map +1 -1
  77. package/dist/components/Toggle/styles.css.d.ts +11 -2
  78. package/dist/components/Toggle/styles.css.d.ts.map +1 -1
  79. package/dist/components/VirtualTable/styles.css.d.ts +6 -0
  80. package/dist/components/VirtualTable/styles.css.d.ts.map +1 -1
  81. package/dist/index.css +1 -1
  82. package/dist/index.js +4299 -3566
  83. package/dist/index.js.map +1 -1
  84. package/dist/shared/portal/hostRegistry.d.ts +33 -0
  85. package/dist/shared/portal/hostRegistry.d.ts.map +1 -0
  86. package/dist/shared/useOverlayOpenState.d.ts +40 -0
  87. package/dist/shared/useOverlayOpenState.d.ts.map +1 -0
  88. package/dist/table.js +141 -135
  89. package/dist/table.js.map +1 -1
  90. package/package.json +34 -4
  91. package/src/components/Alert/Alert.tsx +14 -2
  92. package/src/components/Button/Button.tsx +3 -2
  93. package/src/components/Button/styles.css.ts +2 -0
  94. package/src/components/Callout/Callout.tsx +17 -3
  95. package/src/components/Callout/styles.css.ts +5 -0
  96. package/src/components/Checkbox/Checkbox.native.tsx +67 -0
  97. package/src/components/Checkbox/Checkbox.tsx +1 -50
  98. package/src/components/ConfirmDialog/ConfirmDialog.tsx +3 -0
  99. package/src/components/DetailPanel/DetailPanel.tsx +9 -45
  100. package/src/components/Dialog/Dialog.native.tsx +296 -0
  101. package/src/components/Dialog/Dialog.stories.tsx +71 -0
  102. package/src/components/Dialog/Dialog.tsx +41 -130
  103. package/src/components/Dialog/native.css.ts +78 -0
  104. package/src/components/Dialog/parts.css.ts +101 -0
  105. package/src/components/Dialog/parts.tsx +61 -0
  106. package/src/components/Dialog/styles.css.ts +2 -89
  107. package/src/components/Drawer/Drawer.tsx +20 -49
  108. package/src/components/Drawer/styles.css.ts +4 -0
  109. package/src/components/Grid/styles.css.ts +2 -0
  110. package/src/components/Icon/Icon.native.tsx +54 -0
  111. package/src/components/Icon/Icon.tsx +19 -430
  112. package/src/components/Icon/geometry.ts +456 -0
  113. package/src/components/Icon/types.ts +74 -0
  114. package/src/components/Input/Input.tsx +8 -0
  115. package/src/components/Input/styles.css.ts +2 -0
  116. package/src/components/LinkButton/styles.css.ts +2 -0
  117. package/src/components/Meter/styles.css.ts +2 -0
  118. package/src/components/PageShell/styles.css.ts +4 -0
  119. package/src/components/RadioGroup/RadioGroup.meta.ts +1 -1
  120. package/src/components/RadioGroup/RadioGroup.native.tsx +48 -0
  121. package/src/components/RadioGroup/RadioGroup.stories.tsx +64 -1
  122. package/src/components/RadioGroup/RadioGroup.tsx +8 -83
  123. package/src/components/RadioGroup/group.tsx +85 -0
  124. package/src/components/RadioGroup/styles.css.ts +13 -0
  125. package/src/components/ScrollArea/styles.css.ts +2 -0
  126. package/src/components/Spinner/Spinner.native.tsx +37 -0
  127. package/src/components/Spinner/Spinner.tsx +6 -15
  128. package/src/components/Spinner/Spinner.types.ts +6 -0
  129. package/src/components/Spinner/ring.css.ts +45 -0
  130. package/src/components/Spinner/styles.css.ts +2 -32
  131. package/src/components/StatusIcon/StatusIcon.tsx +13 -2
  132. package/src/components/StatusIcon/styles.css.ts +5 -0
  133. package/src/components/Switch/Switch.native.tsx +45 -0
  134. package/src/components/Switch/Switch.tsx +22 -44
  135. package/src/components/Switch/Switch.types.ts +18 -0
  136. package/src/components/TableOfContents/styles.css.ts +2 -0
  137. package/src/components/Textarea/styles.css.ts +2 -0
  138. package/src/components/ThemeProvider/ThemeProvider.native.tsx +70 -10
  139. package/src/components/Toggle/Toggle.tsx +2 -0
  140. package/src/components/Toggle/styles.css.ts +14 -2
  141. package/src/components/VirtualTable/styles.css.ts +12 -0
  142. package/src/index.native.ts +28 -1
  143. package/src/native-guard/globals.d.ts +10 -0
  144. package/src/native-guard/react-dom.d.ts +3 -0
  145. package/src/shared/accessibilityFocus.native.ts +23 -0
  146. package/src/shared/portal/OverlayModal.native.tsx +51 -0
  147. package/src/shared/portal/PortalHost.native.tsx +102 -0
  148. package/src/shared/portal/hostRegistry.ts +76 -0
  149. package/src/shared/portal/themeScope.native.ts +18 -0
  150. package/src/shared/safeArea.native.ts +22 -0
  151. package/src/shared/useOverlayOpenState.ts +128 -0
  152. package/dist/components/ThemeProvider/ThemeProvider.native.d.ts +0 -10
  153. package/dist/components/ThemeProvider/ThemeProvider.native.d.ts.map +0 -1
  154. package/dist/index.native.d.ts +0 -33
  155. package/dist/index.native.d.ts.map +0 -1
  156. package/dist/platform.native.d.ts +0 -2
  157. package/dist/platform.native.d.ts.map +0 -1
@@ -0,0 +1,128 @@
1
+ import {useCallback, useEffect, useRef, useState} from 'react'
2
+ import {DURATION_MS, type DurationToken} from '@duro-app/tokens/keys'
3
+
4
+ /**
5
+ * When the owner hears that the overlay closed.
6
+ * - `after-exit`: once the exit animation has played (Dialog, Drawer): the
7
+ * overlay stays logically open while it animates out.
8
+ * - `at-once`: as soon as the close is asked for (DetailPanel); the panel
9
+ * still animates out while `present`.
10
+ */
11
+ export type CloseNotice = 'after-exit' | 'at-once'
12
+
13
+ interface Options {
14
+ /** Controlled open state. */
15
+ open: boolean | undefined
16
+ /** Initial open state when uncontrolled. */
17
+ defaultOpen: boolean
18
+ onOpenChange: ((open: boolean) => void) | undefined
19
+ /** Motion token the exit animation lasts. */
20
+ exitDuration: DurationToken
21
+ closeNotice: CloseNotice
22
+ }
23
+
24
+ export interface OverlayOpenState {
25
+ /** Logically open (what `open` / the uncontrolled state says). */
26
+ open: boolean
27
+ /** Rendered: open, or animating out. */
28
+ present: boolean
29
+ /** Playing the exit animation. */
30
+ closing: boolean
31
+ requestOpen: () => void
32
+ /** Animated close. Does nothing while a close is already playing. */
33
+ requestClose: () => void
34
+ /** Close without the exit animation (a swipe that already moved the panel out). */
35
+ closeNow: () => void
36
+ }
37
+
38
+ /**
39
+ * Open, presence and exit-animation state shared by Dialog, Drawer and
40
+ * DetailPanel on both platforms. A controlled `open` that turns false from
41
+ * outside plays the exit animation too.
42
+ */
43
+ export function useOverlayOpenState({
44
+ open: controlledOpen,
45
+ defaultOpen,
46
+ onOpenChange,
47
+ exitDuration,
48
+ closeNotice,
49
+ }: Options): OverlayOpenState {
50
+ const isControlled = controlledOpen !== undefined
51
+ const [internalOpen, setInternalOpen] = useState(defaultOpen)
52
+ const open = isControlled ? controlledOpen : internalOpen
53
+ const [present, setPresent] = useState(open)
54
+ const [closing, setClosing] = useState(false)
55
+ const closingRef = useRef(false)
56
+ // The playing exit was started by the owner's `open` turning false (not by
57
+ // requestClose), so an `open` turning true again cancels it.
58
+ const outsideExitRef = useRef(false)
59
+ const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
60
+
61
+ const cancelExit = useCallback(() => {
62
+ if (timerRef.current) clearTimeout(timerRef.current)
63
+ timerRef.current = null
64
+ closingRef.current = false
65
+ outsideExitRef.current = false
66
+ setClosing(false)
67
+ }, [])
68
+
69
+ const playExit = useCallback(
70
+ (afterExit?: () => void) => {
71
+ closingRef.current = true
72
+ outsideExitRef.current = afterExit === undefined
73
+ setClosing(true)
74
+ timerRef.current = setTimeout(() => {
75
+ timerRef.current = null
76
+ closingRef.current = false
77
+ outsideExitRef.current = false
78
+ setClosing(false)
79
+ setPresent(false)
80
+ afterExit?.()
81
+ }, DURATION_MS[exitDuration])
82
+ },
83
+ [exitDuration],
84
+ )
85
+
86
+ const notifyClosed = useCallback(() => {
87
+ if (!isControlled) setInternalOpen(false)
88
+ onOpenChange?.(false)
89
+ }, [isControlled, onOpenChange])
90
+
91
+ const requestOpen = useCallback(() => {
92
+ cancelExit()
93
+ setPresent(true)
94
+ if (!isControlled) setInternalOpen(true)
95
+ onOpenChange?.(true)
96
+ }, [cancelExit, isControlled, onOpenChange])
97
+
98
+ const requestClose = useCallback(() => {
99
+ if (closingRef.current) return
100
+ if (closeNotice === 'after-exit') playExit(notifyClosed)
101
+ else notifyClosed()
102
+ }, [closeNotice, playExit, notifyClosed])
103
+
104
+ const closeNow = useCallback(() => {
105
+ cancelExit()
106
+ setPresent(false)
107
+ notifyClosed()
108
+ }, [cancelExit, notifyClosed])
109
+
110
+ // Presence follows the logical state: an open from outside shows the
111
+ // overlay, a close from outside (or an `at-once` close) animates it out.
112
+ useEffect(() => {
113
+ if (open && outsideExitRef.current) cancelExit()
114
+ else if (open && !present && !closingRef.current) setPresent(true)
115
+ else if (!open && present && !closingRef.current) playExit()
116
+ }, [open, present, playExit, cancelExit])
117
+
118
+ useEffect(
119
+ () => () => {
120
+ if (timerRef.current) clearTimeout(timerRef.current)
121
+ },
122
+ [],
123
+ )
124
+
125
+ // An open is rendered in the same commit (a consumer's effect on `open` can
126
+ // already reach the overlay's content); the state catches up in the effect.
127
+ return {open, present: open || present, closing, requestOpen, requestClose, closeNow}
128
+ }
@@ -1,10 +0,0 @@
1
- import { ReactNode } from 'react';
2
- export type ThemeName = 'dark' | 'light' | 'high-contrast';
3
- interface ThemeProviderProps {
4
- theme?: ThemeName;
5
- children: ReactNode;
6
- }
7
- export declare function usePortalMount(): HTMLElement | null;
8
- export declare function ThemeProvider({ theme, children }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
9
- export {};
10
- //# sourceMappingURL=ThemeProvider.native.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ThemeProvider.native.d.ts","sourceRoot":"","sources":["../../../src/components/ThemeProvider/ThemeProvider.native.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAgB,KAAK,SAAS,EAAa,MAAM,OAAO,CAAA;AAM/D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,eAAe,CAAA;AAE1D,UAAU,kBAAkB;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAwBD,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED,wBAAgB,aAAa,CAAC,EAAC,KAAc,EAAE,QAAQ,EAAC,EAAE,kBAAkB,2CAI3E"}
@@ -1,33 +0,0 @@
1
- /**
2
- * Native (React Native / Expo) entry — resolved via the `react-native` export
3
- * condition (see package.json). Metro reads THIS instead of the web `index.ts`.
4
- *
5
- * Why a separate barrel: the web `index.ts` re-exports interactive/overlay
6
- * components (Dialog, Drawer, Menu, Tabs, Select, Combobox, Form, ScrollArea,
7
- * TagGroup, ThemeProvider's portal) that use web-only DOM APIs — and Combobox
8
- * imports `react-dom`, so pulling the full barrel crashes on Metro. This barrel
9
- * re-exports ONLY the components whose source is RN-safe (pure react-strict-dom
10
- * `html` + `css`, audited 2026-06-02). The rest get RN variants in a later pass.
11
- *
12
- * Tokens resolve fine on native already: @duro-app/tokens's subpath exports
13
- * (`./tokens/*.css`, `./themes/*.css`) point straight at their `.css.ts`
14
- * source, so Metro/StyleX-native compile them directly.
15
- */
16
- export { Badge, type BadgeVariant, type BadgeSize } from './components/Badge/Badge';
17
- export { Button, type ButtonVariant, type ButtonSize } from './components/Button/Button';
18
- export { Card, type CardVariant, type CardSize } from './components/Card/Card';
19
- export { Checkbox } from './components/Checkbox/Checkbox';
20
- export { Heading, type HeadingVariant } from './components/Heading/Heading';
21
- export { Input, type InputVariant } from './components/Input/Input';
22
- export { Switch } from './components/Switch/Switch';
23
- export { Text, type TextVariant, type TextColor } from './components/Text/Text';
24
- export { Textarea, type TextareaVariant } from './components/Textarea/Textarea';
25
- export { Field } from './components/Field/Field';
26
- export { InputGroup } from './components/InputGroup/InputGroup';
27
- export { Stack, type SpacingKey } from './components/Stack/Stack';
28
- export { Inline } from './components/Inline/Inline';
29
- export { Cluster } from './components/Cluster/Cluster';
30
- export { Grid } from './components/Grid/Grid';
31
- export type { GridTrack } from './shared/length';
32
- export { ThemeProvider, usePortalMount, type ThemeName, } from './components/ThemeProvider/ThemeProvider';
33
- //# sourceMappingURL=index.native.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../src/index.native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAC,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAA;AACjF,OAAO,EAAC,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAC,MAAM,4BAA4B,CAAA;AACtF,OAAO,EAAC,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAC,MAAM,wBAAwB,CAAA;AAC5E,OAAO,EAAC,QAAQ,EAAC,MAAM,gCAAgC,CAAA;AACvD,OAAO,EAAC,OAAO,EAAE,KAAK,cAAc,EAAC,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAC,KAAK,EAAE,KAAK,YAAY,EAAC,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAC,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAC,MAAM,wBAAwB,CAAA;AAC7E,OAAO,EAAC,QAAQ,EAAE,KAAK,eAAe,EAAC,MAAM,gCAAgC,CAAA;AAG7E,OAAO,EAAC,KAAK,EAAC,MAAM,0BAA0B,CAAA;AAC9C,OAAO,EAAC,UAAU,EAAC,MAAM,oCAAoC,CAAA;AAG7D,OAAO,EAAC,KAAK,EAAE,KAAK,UAAU,EAAC,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,8BAA8B,CAAA;AACpD,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAA;AAC3C,YAAY,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAA;AAI9C,OAAO,EACL,aAAa,EACb,cAAc,EACd,KAAK,SAAS,GACf,MAAM,0CAA0C,CAAA"}
@@ -1,2 +0,0 @@
1
- export declare const isNative: boolean;
2
- //# sourceMappingURL=platform.native.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"platform.native.d.ts","sourceRoot":"","sources":["../src/platform.native.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,EAAE,OAAc,CAAA"}