@nori-ui/core 1.0.6 → 1.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 (166) hide show
  1. package/dist/chunk-2UXKXUX2.js +286 -0
  2. package/dist/chunk-2UXKXUX2.js.map +1 -0
  3. package/dist/{chunk-DDGMLLS3.js → chunk-46OT4PA6.js} +3 -3
  4. package/dist/{chunk-DDGMLLS3.js.map → chunk-46OT4PA6.js.map} +1 -1
  5. package/dist/{chunk-SFNDR6DI.js → chunk-5BM6H2CD.js} +3 -3
  6. package/dist/{chunk-SFNDR6DI.js.map → chunk-5BM6H2CD.js.map} +1 -1
  7. package/dist/{chunk-EWWQQ5DB.js → chunk-6JVUVBZH.js} +5 -5
  8. package/dist/{chunk-EWWQQ5DB.js.map → chunk-6JVUVBZH.js.map} +1 -1
  9. package/dist/{chunk-FT2XBBQJ.js → chunk-6PO2IWB3.js} +8 -5
  10. package/dist/chunk-6PO2IWB3.js.map +1 -0
  11. package/dist/{chunk-YNKKEO2A.js → chunk-7D2BHQ6M.js} +3 -3
  12. package/dist/{chunk-YNKKEO2A.js.map → chunk-7D2BHQ6M.js.map} +1 -1
  13. package/dist/{chunk-MRJWPRCX.js → chunk-AFQIK6JI.js} +3 -3
  14. package/dist/{chunk-MRJWPRCX.js.map → chunk-AFQIK6JI.js.map} +1 -1
  15. package/dist/{chunk-IKLA2CVQ.js → chunk-C6TRLHMW.js} +21 -5
  16. package/dist/chunk-C6TRLHMW.js.map +1 -0
  17. package/dist/{chunk-NRYWNOG5.js → chunk-CGQIVFCN.js} +3 -3
  18. package/dist/{chunk-NRYWNOG5.js.map → chunk-CGQIVFCN.js.map} +1 -1
  19. package/dist/chunk-EFK7726V.js +104 -0
  20. package/dist/chunk-EFK7726V.js.map +1 -0
  21. package/dist/{chunk-3BDDPFCI.js → chunk-FDBQOQMW.js} +3 -3
  22. package/dist/{chunk-3BDDPFCI.js.map → chunk-FDBQOQMW.js.map} +1 -1
  23. package/dist/{chunk-XALU6LOT.js → chunk-GELLSU64.js} +3 -3
  24. package/dist/{chunk-XALU6LOT.js.map → chunk-GELLSU64.js.map} +1 -1
  25. package/dist/{chunk-BZLT6R62.js → chunk-GRDVE3IR.js} +3 -3
  26. package/dist/{chunk-BZLT6R62.js.map → chunk-GRDVE3IR.js.map} +1 -1
  27. package/dist/{chunk-OMU4R4Y5.js → chunk-HTF6FDB6.js} +3 -3
  28. package/dist/{chunk-OMU4R4Y5.js.map → chunk-HTF6FDB6.js.map} +1 -1
  29. package/dist/{chunk-X7APG7G2.js → chunk-HZKXPN6B.js} +154 -34
  30. package/dist/chunk-HZKXPN6B.js.map +1 -0
  31. package/dist/{chunk-WGT345SV.js → chunk-IGLMPAWE.js} +3 -3
  32. package/dist/{chunk-WGT345SV.js.map → chunk-IGLMPAWE.js.map} +1 -1
  33. package/dist/{chunk-5XEGZFG5.js → chunk-LWQZ257T.js} +3 -3
  34. package/dist/{chunk-5XEGZFG5.js.map → chunk-LWQZ257T.js.map} +1 -1
  35. package/dist/{chunk-RFW5SRZA.js → chunk-MJ4AGXS7.js} +3 -3
  36. package/dist/{chunk-RFW5SRZA.js.map → chunk-MJ4AGXS7.js.map} +1 -1
  37. package/dist/{chunk-PNP7L4TA.js → chunk-RM5TSXVE.js} +3 -3
  38. package/dist/{chunk-PNP7L4TA.js.map → chunk-RM5TSXVE.js.map} +1 -1
  39. package/dist/{chunk-MKSDYRWQ.js → chunk-SINLREQV.js} +3 -3
  40. package/dist/{chunk-MKSDYRWQ.js.map → chunk-SINLREQV.js.map} +1 -1
  41. package/dist/{chunk-TLS54G6Y.js → chunk-UF5OENHV.js} +3 -3
  42. package/dist/{chunk-TLS54G6Y.js.map → chunk-UF5OENHV.js.map} +1 -1
  43. package/dist/{chunk-ZQMNGPLE.js → chunk-UJ5KFRDE.js} +18 -6
  44. package/dist/chunk-UJ5KFRDE.js.map +1 -0
  45. package/dist/{chunk-SWC5CNKE.js → chunk-UPVNZPFV.js} +3 -3
  46. package/dist/{chunk-SWC5CNKE.js.map → chunk-UPVNZPFV.js.map} +1 -1
  47. package/dist/{chunk-3F4TXKDY.js → chunk-UUXWRDWW.js} +3 -3
  48. package/dist/chunk-UUXWRDWW.js.map +1 -0
  49. package/dist/{chunk-7GPDNQSX.js → chunk-V2AWSDDZ.js} +5 -5
  50. package/dist/{chunk-7GPDNQSX.js.map → chunk-V2AWSDDZ.js.map} +1 -1
  51. package/dist/{chunk-JQQ3FBN7.js → chunk-VCJF75T2.js} +3 -3
  52. package/dist/{chunk-JQQ3FBN7.js.map → chunk-VCJF75T2.js.map} +1 -1
  53. package/dist/{chunk-ZBW3BA5R.js → chunk-VMAGFYHG.js} +39 -4
  54. package/dist/chunk-VMAGFYHG.js.map +1 -0
  55. package/dist/{chunk-JZ774T7U.js → chunk-W3HMOOON.js} +3 -3
  56. package/dist/{chunk-JZ774T7U.js.map → chunk-W3HMOOON.js.map} +1 -1
  57. package/dist/{chunk-6AD6KCVB.js → chunk-WAKKQROH.js} +3 -3
  58. package/dist/{chunk-6AD6KCVB.js.map → chunk-WAKKQROH.js.map} +1 -1
  59. package/dist/{chunk-LVWNMQGR.js → chunk-WDNDTSNX.js} +5 -5
  60. package/dist/{chunk-LVWNMQGR.js.map → chunk-WDNDTSNX.js.map} +1 -1
  61. package/dist/chunk-WOF67PKT.js +60 -0
  62. package/dist/chunk-WOF67PKT.js.map +1 -0
  63. package/dist/{chunk-QJNV7YQP.js → chunk-WTNDPO2V.js} +39 -4
  64. package/dist/chunk-WTNDPO2V.js.map +1 -0
  65. package/dist/{chunk-FEPTH5RV.js → chunk-XP55RZ3D.js} +3 -3
  66. package/dist/{chunk-FEPTH5RV.js.map → chunk-XP55RZ3D.js.map} +1 -1
  67. package/dist/{chunk-CCUXO2HN.js → chunk-Y4ZRSW35.js} +3 -3
  68. package/dist/{chunk-CCUXO2HN.js.map → chunk-Y4ZRSW35.js.map} +1 -1
  69. package/dist/client.cjs +619 -123
  70. package/dist/client.cjs.map +1 -1
  71. package/dist/client.d.cts +2 -0
  72. package/dist/client.d.ts +2 -0
  73. package/dist/client.js +40 -38
  74. package/dist/client.js.map +1 -1
  75. package/dist/components/Accordion/index.js +2 -2
  76. package/dist/components/Alert/index.js +2 -2
  77. package/dist/components/AlertDialog/index.js +2 -2
  78. package/dist/components/Avatar/index.js +2 -2
  79. package/dist/components/Badge/index.js +2 -2
  80. package/dist/components/Box/index.js +4 -4
  81. package/dist/components/Breadcrumb/index.cjs +6 -3
  82. package/dist/components/Breadcrumb/index.cjs.map +1 -1
  83. package/dist/components/Breadcrumb/index.js +5 -5
  84. package/dist/components/Button/index.js +2 -2
  85. package/dist/components/Calendar/index.cjs +170 -35
  86. package/dist/components/Calendar/index.cjs.map +1 -1
  87. package/dist/components/Calendar/index.js +5 -5
  88. package/dist/components/Card/index.js +2 -2
  89. package/dist/components/Checkbox/index.cjs +36 -1
  90. package/dist/components/Checkbox/index.cjs.map +1 -1
  91. package/dist/components/Checkbox/index.d.cts +17 -1
  92. package/dist/components/Checkbox/index.d.ts +17 -1
  93. package/dist/components/Checkbox/index.js +2 -2
  94. package/dist/components/Dialog/index.js +2 -2
  95. package/dist/components/Field/index.cjs +703 -0
  96. package/dist/components/Field/index.cjs.map +1 -0
  97. package/dist/components/Field/index.d.cts +51 -0
  98. package/dist/components/Field/index.d.ts +51 -0
  99. package/dist/components/Field/index.js +9 -0
  100. package/dist/components/Field/index.js.map +1 -0
  101. package/dist/components/FloatButton/index.cjs +6 -3
  102. package/dist/components/FloatButton/index.cjs.map +1 -1
  103. package/dist/components/FloatButton/index.js +5 -5
  104. package/dist/components/HStack/index.js +4 -4
  105. package/dist/components/InputGroup/index.cjs.map +1 -1
  106. package/dist/components/InputGroup/index.d.cts +8 -1
  107. package/dist/components/InputGroup/index.d.ts +8 -1
  108. package/dist/components/InputGroup/index.js +2 -2
  109. package/dist/components/Label/index.cjs +458 -0
  110. package/dist/components/Label/index.cjs.map +1 -0
  111. package/dist/components/Label/index.d.cts +14 -0
  112. package/dist/components/Label/index.d.ts +14 -0
  113. package/dist/components/Label/index.js +8 -0
  114. package/dist/components/Label/index.js.map +1 -0
  115. package/dist/components/Pagination/index.cjs +21 -6
  116. package/dist/components/Pagination/index.cjs.map +1 -1
  117. package/dist/components/Pagination/index.js +5 -5
  118. package/dist/components/Popover/index.js +2 -2
  119. package/dist/components/Progress/index.js +2 -2
  120. package/dist/components/Radio/index.cjs +18 -2
  121. package/dist/components/Radio/index.cjs.map +1 -1
  122. package/dist/components/Radio/index.d.cts +17 -1
  123. package/dist/components/Radio/index.d.ts +17 -1
  124. package/dist/components/Radio/index.js +2 -2
  125. package/dist/components/SegmentedControl/index.js +2 -2
  126. package/dist/components/Select/index.cjs +15 -3
  127. package/dist/components/Select/index.cjs.map +1 -1
  128. package/dist/components/Select/index.d.cts +6 -0
  129. package/dist/components/Select/index.d.ts +6 -0
  130. package/dist/components/Select/index.js +2 -2
  131. package/dist/components/Switch/index.cjs +36 -1
  132. package/dist/components/Switch/index.cjs.map +1 -1
  133. package/dist/components/Switch/index.d.cts +17 -1
  134. package/dist/components/Switch/index.d.ts +17 -1
  135. package/dist/components/Switch/index.js +2 -2
  136. package/dist/components/Tabs/index.js +2 -2
  137. package/dist/components/Text/index.js +2 -2
  138. package/dist/components/TextArea/index.cjs +35 -84
  139. package/dist/components/TextArea/index.cjs.map +1 -1
  140. package/dist/components/TextArea/index.js +3 -3
  141. package/dist/components/TextInput/index.cjs +35 -84
  142. package/dist/components/TextInput/index.cjs.map +1 -1
  143. package/dist/components/TextInput/index.d.cts +7 -8
  144. package/dist/components/TextInput/index.d.ts +7 -8
  145. package/dist/components/TextInput/index.js +2 -2
  146. package/dist/components/Toggle/index.js +2 -2
  147. package/dist/components/Tooltip/index.js +2 -2
  148. package/dist/components/VStack/index.js +4 -4
  149. package/dist/i18n/index.cjs +6 -3
  150. package/dist/i18n/index.cjs.map +1 -1
  151. package/dist/i18n/index.js +1 -1
  152. package/dist/index.cjs +619 -123
  153. package/dist/index.cjs.map +1 -1
  154. package/dist/index.d.cts +2 -0
  155. package/dist/index.d.ts +2 -0
  156. package/dist/index.js +37 -35
  157. package/package.json +8 -1
  158. package/dist/chunk-3F4TXKDY.js.map +0 -1
  159. package/dist/chunk-FT2XBBQJ.js.map +0 -1
  160. package/dist/chunk-IKLA2CVQ.js.map +0 -1
  161. package/dist/chunk-QJNV7YQP.js.map +0 -1
  162. package/dist/chunk-X7APG7G2.js.map +0 -1
  163. package/dist/chunk-ZBW3BA5R.js.map +0 -1
  164. package/dist/chunk-ZQMNGPLE.js.map +0 -1
  165. package/dist/chunk-ZRD4FQBT.js +0 -153
  166. package/dist/chunk-ZRD4FQBT.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Dialog/Dialog.tsx"],"names":["RNText"],"mappings":"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","file":"chunk-WGT345SV.js","sourcesContent":["'use client';\n\nimport {\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport type { ViewStyle } from 'react-native';\nimport { Modal, Platform, Pressable, Text as RNText, StyleSheet, View } from 'react-native';\nimport { defaultSemanticIcons } from '../../icons/default-semantic-icons';\nimport { Slot } from '../../slot';\nimport { px } from '../../theme/px';\nimport { useColorScheme } from '../../theme/use-color-scheme';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport { BlurBackdrop } from './blur-backdrop';\n\ntype DialogContextValue = {\n open: boolean;\n setOpen: (next: boolean) => void;\n titleId: string;\n descriptionId: string;\n triggerRef: { current: HTMLElement | null };\n};\n\nconst DialogContext = createContext<DialogContextValue | null>(null);\n\nconst useDialogContext = (label: string): DialogContextValue => {\n const ctx = useContext(DialogContext);\n if (!ctx) {\n throw new Error(`<${label}> must be rendered inside a <Dialog>.`);\n }\n return ctx;\n};\n\nexport type DialogProps = {\n /** Controlled open state. */\n open?: boolean;\n /** Uncontrolled initial open state. @defaultValue false */\n defaultOpen?: boolean;\n /** Fires with the new open state. */\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n};\n\n/**\n * Modal dialog. Owns open state and provides context for `DialogTrigger`,\n * `DialogContent`, `DialogTitle`, `DialogDescription`, and `DialogClose`.\n *\n * Behavior:\n * - Click the trigger to open. Click outside the content, press Escape,\n * or click an explicit close to dismiss.\n * - Focus is trapped inside the content while open (web). On close, focus\n * returns to whatever opened the dialog.\n * - Background scrolling is locked while open (web).\n *\n * Cross-platform: uses RN `<Modal>` as the visibility/portal primitive. On\n * web, additional focus-trap / scroll-lock / Escape-key effects layer on\n * top via the platform check inside `DialogContent`.\n */\nconst DialogRoot = ({ open, defaultOpen = false, onOpenChange, children }: DialogProps) => {\n const [inner, setInner] = useState<boolean>(defaultOpen);\n const isControlled = open !== undefined;\n const current = isControlled ? open : inner;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) {\n setInner(next);\n }\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const baseId = useId();\n const triggerRef = useRef<HTMLElement | null>(null);\n\n const ctxValue: DialogContextValue = {\n open: current,\n setOpen,\n titleId: `${baseId}-title`,\n descriptionId: `${baseId}-description`,\n triggerRef,\n };\n\n return <DialogContext.Provider value={ctxValue}>{children}</DialogContext.Provider>;\n};\n\nexport type DialogTriggerProps = {\n /** Render the child as the trigger (Slot pattern). Default true — pass `false` for an inline button. */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Element that opens the dialog when activated. Uses `asChild` by default so\n * any element (Button, Link, custom Pressable) becomes the trigger.\n */\nexport const DialogTrigger = ({ asChild = true, children, className, testID }: DialogTriggerProps) => {\n const ctx = useDialogContext('DialogTrigger');\n const onPress = useCallback(() => ctx.setOpen(true), [ctx]);\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<Record<string, unknown>>;\n // Pass both onClick (web HTML buttons) AND onPress (RN Pressable /\n // our own Button) so the trigger fires regardless of which event\n // model the wrapped child speaks. The child's existing handler\n // runs first, then we open.\n const fire = (existing: ((e: unknown) => void) | undefined) => (event: unknown) => {\n existing?.(event);\n ctx.setOpen(true);\n };\n return (\n <Slot\n ref={(node: HTMLElement | null) => {\n ctx.triggerRef.current = node;\n }}\n onClick={fire(child.props.onClick as ((e: unknown) => void) | undefined)}\n onPress={fire(child.props.onPress as ((e: unknown) => void) | undefined)}\n {...(testID !== undefined ? { 'data-testid': testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {child}\n </Slot>\n );\n }\n\n return (\n <Pressable\n ref={(node) => {\n ctx.triggerRef.current = node as unknown as HTMLElement | null;\n }}\n onPress={onPress}\n {...(testID !== undefined ? { testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {wrapStringChildren(children)}\n </Pressable>\n );\n};\n\n// On native, raw strings rendered as children of a non-Text component\n// throw \"Text strings must be rendered within a <Text> component\". On\n// web, react-native-web silently tolerates it. Wrap any string/number\n// children in an RNText so the same JSX renders cleanly on both\n// platforms. Non-string children are passed through unchanged.\nfunction wrapStringChildren(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return <RNText>{children}</RNText>;\n }\n return children;\n}\n\n// Scrim + blur target values — applied at the entered state on web,\n// always on as a flat scrim on native (RN doesn't have backdrop-filter\n// and the native shim would be an extra peer dep for vanishingly little\n// visual gain on a v0 component).\n// 24% scrim + 4px blur — strong enough to push the page back but the\n// content underneath is still legible. Earlier 32%/8px felt like a frosted\n// glass slab that completely obscured the page; this lets the page show\n// through as \"behind glass, slightly out of focus.\"\nconst SCRIM_COLOR = 'rgba(0, 0, 0, 0.24)';\nconst BLUR_AMOUNT = 4;\n\n// Static overlay layout — alignment, fixed positioning. The animatable\n// bits (scrim color, backdrop-filter blur) live in a useEffect inside\n// the component that pokes them onto the DOM ref directly so rn-web's\n// style filter can't strip the non-RN keys (backdropFilter,\n// transitionProperty). On web the styles start at blur(0px) +\n// transparent and transition to the target values on the next frame.\n//\n// Why not put blur(8px) here as a constant: when blur is applied to a\n// layer that's mid-fade (e.g. RN Modal's animationType=\"fade\" fades\n// opacity from 0 → 1), Safari and Chromium GPU-composite the layer\n// without rendering backdrop-filter — so the blur appears to \"snap in\"\n// at the end of the fade. Animating blur explicitly via our own\n// transition (and disabling the Modal's fade on web) avoids the snap.\nconst OVERLAY_LAYOUT_BASE: ViewStyle = {\n position: Platform.OS === 'web' ? ('fixed' as unknown as 'absolute') : 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n alignItems: 'center',\n justifyContent: 'center',\n // On native the BlurBackdrop sibling renders BEHIND this overlay and\n // already provides dim + frosted-glass via expo-blur's `tint`/`intensity`.\n // Painting SCRIM_COLOR on top would mask the blur entirely (the user\n // sees only a flat tint), so the overlay stays transparent and the\n // BlurView is the dominant visual on native.\n ...(Platform.OS === 'web' ? ({ zIndex: 50 } as ViewStyle) : { backgroundColor: 'transparent' }),\n};\n\n// Layout / animation only — theme-driven dimensions are merged inside\n// DialogContent below.\nconst CONTENT_LAYOUT_BASE: ViewStyle = {\n width: '100%',\n maxWidth: 480, // component-density literal — not from theme\n ...(Platform.OS === 'web'\n ? ({\n boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)',\n } as ViewStyle)\n : { elevation: 24 }),\n};\n\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport type DialogContentProps = {\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * The visible dialog surface — overlay + centered card. Renders only when\n * the parent `Dialog` is open. On web: traps focus inside, locks body\n * scroll, and dismisses on Escape or overlay click.\n */\nexport const DialogContent = ({ children, className, testID }: DialogContentProps) => {\n const ctx = useDialogContext('DialogContent');\n const colors = useThemeColors();\n const scheme = useColorScheme();\n const contentRef = useRef<HTMLDivElement | null>(null);\n const overlayStyle: ViewStyle = {\n ...OVERLAY_LAYOUT_BASE,\n padding: px(colors.spacing['4']),\n };\n const contentStyle: ViewStyle = {\n ...CONTENT_LAYOUT_BASE,\n borderRadius: px(colors.radius.xl),\n padding: px(colors.spacing['6']),\n gap: px(colors.spacing['3']),\n };\n // Scale-in: render at scale(0.96) + opacity 0 first, flip to 1 in a\n // useEffect so the CSS transition has a frame to animate from. Web\n // only; native uses `Modal animationType=\"fade\"` which is enough.\n const [entered, setEntered] = useState(false);\n useEffect(() => {\n if (Platform.OS !== 'web') {\n setEntered(true);\n return;\n }\n if (!ctx.open) {\n setEntered(false);\n return;\n }\n const id = requestAnimationFrame(() => setEntered(true));\n return () => cancelAnimationFrame(id);\n }, [ctx.open]);\n const enterStyle: ViewStyle =\n Platform.OS === 'web'\n ? ({\n opacity: entered ? 1 : 0,\n transform: [{ scale: entered ? 1 : 0.96 }],\n transitionProperty: 'opacity, transform',\n transitionDuration: '150ms',\n transitionTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)',\n } as ViewStyle)\n : {};\n\n // Overlay's scrim + backdrop-filter share the same `entered` flag as\n // the content card, so the blur starts at 0 and the scrim at 0% on\n // the first paint, then both transition to their target values at the\n // next frame — same 150ms curve as the card. The blur duration is\n // bumped slightly (200ms) so it lands a hair AFTER the scrim instead\n // of slamming to full strength immediately, which reads more natural.\n //\n // We reach for a direct DOM ref + .style assignments here rather than\n // pass the styles through `<Pressable style={...}>`. Reason: rn-web's\n // style filter drops keys it doesn't recognize as RN style props —\n // and `backdropFilter`, `transitionProperty`, etc. fall through that\n // filter, taking the whole style fragment with them. Native gets a\n // flat scrim with no blur; RN doesn't have backdrop-filter and the\n // native shim would be an extra peer dep for negligible gain.\n const overlayDomRef = useRef<HTMLElement | null>(null);\n useEffect(() => {\n if (Platform.OS !== 'web') {\n return;\n }\n const node = overlayDomRef.current;\n if (!node) {\n return;\n }\n // First paint: kick off transparent + zero blur so the next\n // assignment animates from 0 to target. We only need this on\n // the very first frame — the inline style on second frame\n // overwrites these.\n node.style.transitionProperty = 'background-color, backdrop-filter, -webkit-backdrop-filter';\n node.style.transitionDuration = '150ms, 200ms, 200ms';\n node.style.transitionTimingFunction = 'ease-out';\n if (entered) {\n node.style.backgroundColor = SCRIM_COLOR;\n node.style.backdropFilter = `blur(${BLUR_AMOUNT}px)`;\n node.style.setProperty('-webkit-backdrop-filter', `blur(${BLUR_AMOUNT}px)`);\n } else {\n node.style.backgroundColor = 'rgba(0, 0, 0, 0)';\n node.style.backdropFilter = 'blur(0px)';\n node.style.setProperty('-webkit-backdrop-filter', 'blur(0px)');\n }\n }, [entered]);\n\n // Web-only side effects: focus trap, scroll lock, Escape close,\n // initial focus on the first focusable inside the dialog. RN Modal\n // handles its own focus model on native, so the platform check keeps\n // these out of the native render path.\n useEffect(() => {\n if (!ctx.open) {\n return;\n }\n if (Platform.OS !== 'web') {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n const previouslyFocused = document.activeElement as HTMLElement | null;\n\n // Lock body scroll. Preserve any previously set inline style so\n // we don't accidentally clobber a consumer's lock from elsewhere.\n const prevBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n // Move focus into the dialog. Prefer the first focusable element;\n // if there isn't one, focus the dialog container itself so it\n // receives the keydown events.\n const focusFirst = () => {\n const node = contentRef.current;\n if (!node) {\n return;\n }\n const focusable = node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR);\n const first = focusable[0];\n if (first) {\n first.focus();\n } else {\n node.setAttribute('tabindex', '-1');\n node.focus();\n }\n };\n focusFirst();\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n ctx.setOpen(false);\n return;\n }\n if (event.key !== 'Tab') {\n return;\n }\n const node = contentRef.current;\n if (!node) {\n return;\n }\n const focusable = Array.from(node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => el.offsetParent !== null || el === document.activeElement\n );\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (!first || !last) {\n return;\n }\n if (event.shiftKey) {\n if (document.activeElement === first || !node.contains(document.activeElement)) {\n event.preventDefault();\n last.focus();\n }\n } else if (document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n document.addEventListener('keydown', onKeyDown);\n\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n document.body.style.overflow = prevBodyOverflow;\n // Restore focus to whatever opened the dialog (the trigger),\n // falling back to the previously focused node if the trigger\n // is gone.\n const restoreTo = ctx.triggerRef.current ?? previouslyFocused;\n restoreTo?.focus?.();\n };\n }, [ctx.open, ctx.setOpen, ctx.triggerRef]);\n\n const onOverlayPress = useCallback(() => ctx.setOpen(false), [ctx]);\n\n return (\n <Modal\n visible={ctx.open}\n transparent\n // Web: 'none' so RN's built-in fade doesn't fight our own\n // overlay/content transitions (its layer-level fade caused\n // backdrop-filter to \"snap in\" at the end). Native: 'fade'\n // is what users expect on iOS/Android and we don't have a\n // CSS transition path there anyway.\n animationType={Platform.OS === 'web' ? 'none' : 'fade'}\n onRequestClose={() => ctx.setOpen(false)}\n >\n {/* Native blur layer. Renders nothing on web (the overlay's\n CSS backdrop-filter handles it) and renders nothing if\n expo-blur isn't installed (graceful degrade — the scrim\n Pressable below still dims the background). */}\n <BlurBackdrop intensity={60} tint={scheme === 'dark' ? 'dark' : 'light'} style={StyleSheet.absoluteFill} />\n <Pressable\n accessibilityRole=\"none\"\n aria-hidden={true}\n ref={(node) => {\n overlayDomRef.current = node as unknown as HTMLElement | null;\n }}\n style={overlayStyle}\n onPress={onOverlayPress}\n >\n <Pressable\n onPress={(event) => event.stopPropagation?.()}\n ref={(node) => {\n contentRef.current = node as unknown as HTMLDivElement | null;\n }}\n role=\"dialog\"\n accessibilityRole=\"none\"\n aria-modal={true}\n aria-labelledby={ctx.titleId}\n aria-describedby={ctx.descriptionId}\n {...(testID !== undefined ? { testID } : {})}\n className={cn('w-full max-w-md rounded-xl bg-semantic-background-elevated p-6 gap-3', className)}\n style={[contentStyle, { backgroundColor: colors.semantic.background.elevated }, enterStyle]}\n >\n <View\n className=\"flex-col gap-1.5\"\n style={{ flexDirection: 'column', gap: px(colors.spacing['2']) - 2 }}\n >\n {children}\n </View>\n </Pressable>\n </Pressable>\n </Modal>\n );\n};\n\nexport type DialogTextProps = {\n children?: ReactNode;\n className?: string;\n};\n\n/** Heading inside DialogContent. Wires `aria-labelledby`. */\nexport const DialogTitle = ({ children, className }: DialogTextProps) => {\n const ctx = useDialogContext('DialogTitle');\n const colors = useThemeColors();\n return (\n <RNText\n nativeID={ctx.titleId}\n id={ctx.titleId}\n role=\"heading\"\n aria-level={2}\n className={cn('text-lg font-semibold text-semantic-text-default', className)}\n style={{\n color: colors.semantic.text.default,\n fontFamily: colors.fontFamily.display,\n fontSize: px(colors.fontSize.lg),\n fontWeight: colors.fontWeight.semibold as '600',\n }}\n >\n {children}\n </RNText>\n );\n};\n\n/** Subtitle / description inside DialogContent. Wires `aria-describedby`. */\nexport const DialogDescription = ({ children, className }: DialogTextProps) => {\n const ctx = useDialogContext('DialogDescription');\n const colors = useThemeColors();\n return (\n <RNText\n nativeID={ctx.descriptionId}\n id={ctx.descriptionId}\n className={cn('text-sm text-semantic-text-muted', className)}\n style={{\n color: colors.semantic.text.muted,\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n lineHeight: px(colors.fontSize.sm) * Number(colors.lineHeight.normal),\n }}\n >\n {children}\n </RNText>\n );\n};\n\nexport type DialogCloseProps = {\n /** Render the child as the close button (Slot pattern). Default true. */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n testID?: string;\n accessibilityLabel?: string;\n};\n\n/**\n * Element that closes the dialog when activated. With `asChild` (default),\n * wraps the child. Without `asChild`, renders a default ✕ button — useful\n * for the canonical top-right corner close.\n */\nexport const DialogClose = ({\n asChild = true,\n children,\n className,\n testID,\n accessibilityLabel = 'Close',\n}: DialogCloseProps) => {\n const ctx = useDialogContext('DialogClose');\n const colors = useThemeColors();\n const onPress = useCallback(() => ctx.setOpen(false), [ctx]);\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<Record<string, unknown>>;\n // Same dual-event story as DialogTrigger: pass both onClick (web\n // button) and onPress (RN Pressable / our own Button) so the\n // wrapped element fires regardless of its event model.\n const fire = (existing: ((e: unknown) => void) | undefined) => (event: unknown) => {\n existing?.(event);\n ctx.setOpen(false);\n };\n return (\n <Slot\n onClick={fire(child.props.onClick as ((e: unknown) => void) | undefined)}\n onPress={fire(child.props.onPress as ((e: unknown) => void) | undefined)}\n {...(testID !== undefined ? { 'data-testid': testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {child}\n </Slot>\n );\n }\n\n if (children !== undefined) {\n return (\n <Pressable\n onPress={onPress}\n role=\"button\"\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n aria-label={accessibilityLabel}\n {...(testID !== undefined ? { testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {wrapStringChildren(children)}\n </Pressable>\n );\n }\n\n return (\n <Pressable\n onPress={onPress}\n role=\"button\"\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n aria-label={accessibilityLabel}\n {...(testID !== undefined ? { testID } : {})}\n className={cn('absolute right-3 top-3 w-8 h-8 items-center justify-center rounded-md', className)}\n style={{\n position: 'absolute',\n right: px(colors.spacing['3']),\n top: px(colors.spacing['3']),\n // 32×32 close hit target — component-density literal — not from theme\n width: 32,\n height: 32,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: px(colors.radius.md),\n }}\n >\n <defaultSemanticIcons.close size={18} color={colors.semantic.text.muted} />\n </Pressable>\n );\n};\n\nexport type DialogFooterProps = {\n children?: ReactNode;\n className?: string;\n};\n\n/** Convenience row for dialog action buttons (right-aligned). */\nexport const DialogFooter = ({ children, className }: DialogFooterProps) => {\n const colors = useThemeColors();\n return (\n <View\n className={cn('mt-4 flex-row items-center justify-end gap-2', className)}\n style={{\n marginTop: px(colors.spacing['4']),\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: px(colors.spacing['2']),\n }}\n >\n {children}\n </View>\n );\n};\n\n/**\n * Public `Dialog` value — the root function plus its `.Trigger`, `.Content`,\n * `.Title`, `.Description`, `.Footer`, and `.Close` static members. `Object.assign`\n * produces a value whose inferred type carries the static properties, so `.d.ts`\n * consumers can write `<Dialog.Content>` without a separate import.\n */\nexport const Dialog = Object.assign(DialogRoot, {\n Trigger: DialogTrigger,\n Content: DialogContent,\n Title: DialogTitle,\n Description: DialogDescription,\n Footer: DialogFooter,\n Close: DialogClose,\n});\n"]}
1
+ {"version":3,"sources":["../src/components/Dialog/Dialog.tsx"],"names":["RNText"],"mappings":"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","file":"chunk-IGLMPAWE.js","sourcesContent":["'use client';\n\nimport {\n createContext,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport type { ViewStyle } from 'react-native';\nimport { Modal, Platform, Pressable, Text as RNText, StyleSheet, View } from 'react-native';\nimport { defaultSemanticIcons } from '../../icons/default-semantic-icons';\nimport { Slot } from '../../slot';\nimport { px } from '../../theme/px';\nimport { useColorScheme } from '../../theme/use-color-scheme';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport { BlurBackdrop } from './blur-backdrop';\n\ntype DialogContextValue = {\n open: boolean;\n setOpen: (next: boolean) => void;\n titleId: string;\n descriptionId: string;\n triggerRef: { current: HTMLElement | null };\n};\n\nconst DialogContext = createContext<DialogContextValue | null>(null);\n\nconst useDialogContext = (label: string): DialogContextValue => {\n const ctx = useContext(DialogContext);\n if (!ctx) {\n throw new Error(`<${label}> must be rendered inside a <Dialog>.`);\n }\n return ctx;\n};\n\nexport type DialogProps = {\n /** Controlled open state. */\n open?: boolean;\n /** Uncontrolled initial open state. @defaultValue false */\n defaultOpen?: boolean;\n /** Fires with the new open state. */\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n};\n\n/**\n * Modal dialog. Owns open state and provides context for `DialogTrigger`,\n * `DialogContent`, `DialogTitle`, `DialogDescription`, and `DialogClose`.\n *\n * Behavior:\n * - Click the trigger to open. Click outside the content, press Escape,\n * or click an explicit close to dismiss.\n * - Focus is trapped inside the content while open (web). On close, focus\n * returns to whatever opened the dialog.\n * - Background scrolling is locked while open (web).\n *\n * Cross-platform: uses RN `<Modal>` as the visibility/portal primitive. On\n * web, additional focus-trap / scroll-lock / Escape-key effects layer on\n * top via the platform check inside `DialogContent`.\n */\nconst DialogRoot = ({ open, defaultOpen = false, onOpenChange, children }: DialogProps) => {\n const [inner, setInner] = useState<boolean>(defaultOpen);\n const isControlled = open !== undefined;\n const current = isControlled ? open : inner;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) {\n setInner(next);\n }\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const baseId = useId();\n const triggerRef = useRef<HTMLElement | null>(null);\n\n const ctxValue: DialogContextValue = {\n open: current,\n setOpen,\n titleId: `${baseId}-title`,\n descriptionId: `${baseId}-description`,\n triggerRef,\n };\n\n return <DialogContext.Provider value={ctxValue}>{children}</DialogContext.Provider>;\n};\n\nexport type DialogTriggerProps = {\n /** Render the child as the trigger (Slot pattern). Default true — pass `false` for an inline button. */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * Element that opens the dialog when activated. Uses `asChild` by default so\n * any element (Button, Link, custom Pressable) becomes the trigger.\n */\nexport const DialogTrigger = ({ asChild = true, children, className, testID }: DialogTriggerProps) => {\n const ctx = useDialogContext('DialogTrigger');\n const onPress = useCallback(() => ctx.setOpen(true), [ctx]);\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<Record<string, unknown>>;\n // Pass both onClick (web HTML buttons) AND onPress (RN Pressable /\n // our own Button) so the trigger fires regardless of which event\n // model the wrapped child speaks. The child's existing handler\n // runs first, then we open.\n const fire = (existing: ((e: unknown) => void) | undefined) => (event: unknown) => {\n existing?.(event);\n ctx.setOpen(true);\n };\n return (\n <Slot\n ref={(node: HTMLElement | null) => {\n ctx.triggerRef.current = node;\n }}\n onClick={fire(child.props.onClick as ((e: unknown) => void) | undefined)}\n onPress={fire(child.props.onPress as ((e: unknown) => void) | undefined)}\n {...(testID !== undefined ? { 'data-testid': testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {child}\n </Slot>\n );\n }\n\n return (\n <Pressable\n ref={(node) => {\n ctx.triggerRef.current = node as unknown as HTMLElement | null;\n }}\n onPress={onPress}\n {...(testID !== undefined ? { testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {wrapStringChildren(children)}\n </Pressable>\n );\n};\n\n// On native, raw strings rendered as children of a non-Text component\n// throw \"Text strings must be rendered within a <Text> component\". On\n// web, react-native-web silently tolerates it. Wrap any string/number\n// children in an RNText so the same JSX renders cleanly on both\n// platforms. Non-string children are passed through unchanged.\nfunction wrapStringChildren(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return <RNText>{children}</RNText>;\n }\n return children;\n}\n\n// Scrim + blur target values — applied at the entered state on web,\n// always on as a flat scrim on native (RN doesn't have backdrop-filter\n// and the native shim would be an extra peer dep for vanishingly little\n// visual gain on a v0 component).\n// 24% scrim + 4px blur — strong enough to push the page back but the\n// content underneath is still legible. Earlier 32%/8px felt like a frosted\n// glass slab that completely obscured the page; this lets the page show\n// through as \"behind glass, slightly out of focus.\"\nconst SCRIM_COLOR = 'rgba(0, 0, 0, 0.24)';\nconst BLUR_AMOUNT = 4;\n\n// Static overlay layout — alignment, fixed positioning. The animatable\n// bits (scrim color, backdrop-filter blur) live in a useEffect inside\n// the component that pokes them onto the DOM ref directly so rn-web's\n// style filter can't strip the non-RN keys (backdropFilter,\n// transitionProperty). On web the styles start at blur(0px) +\n// transparent and transition to the target values on the next frame.\n//\n// Why not put blur(8px) here as a constant: when blur is applied to a\n// layer that's mid-fade (e.g. RN Modal's animationType=\"fade\" fades\n// opacity from 0 → 1), Safari and Chromium GPU-composite the layer\n// without rendering backdrop-filter — so the blur appears to \"snap in\"\n// at the end of the fade. Animating blur explicitly via our own\n// transition (and disabling the Modal's fade on web) avoids the snap.\nconst OVERLAY_LAYOUT_BASE: ViewStyle = {\n position: Platform.OS === 'web' ? ('fixed' as unknown as 'absolute') : 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n alignItems: 'center',\n justifyContent: 'center',\n // On native the BlurBackdrop sibling renders BEHIND this overlay and\n // already provides dim + frosted-glass via expo-blur's `tint`/`intensity`.\n // Painting SCRIM_COLOR on top would mask the blur entirely (the user\n // sees only a flat tint), so the overlay stays transparent and the\n // BlurView is the dominant visual on native.\n ...(Platform.OS === 'web' ? ({ zIndex: 50 } as ViewStyle) : { backgroundColor: 'transparent' }),\n};\n\n// Layout / animation only — theme-driven dimensions are merged inside\n// DialogContent below.\nconst CONTENT_LAYOUT_BASE: ViewStyle = {\n width: '100%',\n maxWidth: 480, // component-density literal — not from theme\n ...(Platform.OS === 'web'\n ? ({\n boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)',\n } as ViewStyle)\n : { elevation: 24 }),\n};\n\nconst FOCUSABLE_SELECTOR =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nexport type DialogContentProps = {\n children?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n/**\n * The visible dialog surface — overlay + centered card. Renders only when\n * the parent `Dialog` is open. On web: traps focus inside, locks body\n * scroll, and dismisses on Escape or overlay click.\n */\nexport const DialogContent = ({ children, className, testID }: DialogContentProps) => {\n const ctx = useDialogContext('DialogContent');\n const colors = useThemeColors();\n const scheme = useColorScheme();\n const contentRef = useRef<HTMLDivElement | null>(null);\n const overlayStyle: ViewStyle = {\n ...OVERLAY_LAYOUT_BASE,\n padding: px(colors.spacing['4']),\n };\n const contentStyle: ViewStyle = {\n ...CONTENT_LAYOUT_BASE,\n borderRadius: px(colors.radius.xl),\n padding: px(colors.spacing['6']),\n gap: px(colors.spacing['3']),\n };\n // Scale-in: render at scale(0.96) + opacity 0 first, flip to 1 in a\n // useEffect so the CSS transition has a frame to animate from. Web\n // only; native uses `Modal animationType=\"fade\"` which is enough.\n const [entered, setEntered] = useState(false);\n useEffect(() => {\n if (Platform.OS !== 'web') {\n setEntered(true);\n return;\n }\n if (!ctx.open) {\n setEntered(false);\n return;\n }\n const id = requestAnimationFrame(() => setEntered(true));\n return () => cancelAnimationFrame(id);\n }, [ctx.open]);\n const enterStyle: ViewStyle =\n Platform.OS === 'web'\n ? ({\n opacity: entered ? 1 : 0,\n transform: [{ scale: entered ? 1 : 0.96 }],\n transitionProperty: 'opacity, transform',\n transitionDuration: '150ms',\n transitionTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)',\n } as ViewStyle)\n : {};\n\n // Overlay's scrim + backdrop-filter share the same `entered` flag as\n // the content card, so the blur starts at 0 and the scrim at 0% on\n // the first paint, then both transition to their target values at the\n // next frame — same 150ms curve as the card. The blur duration is\n // bumped slightly (200ms) so it lands a hair AFTER the scrim instead\n // of slamming to full strength immediately, which reads more natural.\n //\n // We reach for a direct DOM ref + .style assignments here rather than\n // pass the styles through `<Pressable style={...}>`. Reason: rn-web's\n // style filter drops keys it doesn't recognize as RN style props —\n // and `backdropFilter`, `transitionProperty`, etc. fall through that\n // filter, taking the whole style fragment with them. Native gets a\n // flat scrim with no blur; RN doesn't have backdrop-filter and the\n // native shim would be an extra peer dep for negligible gain.\n const overlayDomRef = useRef<HTMLElement | null>(null);\n useEffect(() => {\n if (Platform.OS !== 'web') {\n return;\n }\n const node = overlayDomRef.current;\n if (!node) {\n return;\n }\n // First paint: kick off transparent + zero blur so the next\n // assignment animates from 0 to target. We only need this on\n // the very first frame — the inline style on second frame\n // overwrites these.\n node.style.transitionProperty = 'background-color, backdrop-filter, -webkit-backdrop-filter';\n node.style.transitionDuration = '150ms, 200ms, 200ms';\n node.style.transitionTimingFunction = 'ease-out';\n if (entered) {\n node.style.backgroundColor = SCRIM_COLOR;\n node.style.backdropFilter = `blur(${BLUR_AMOUNT}px)`;\n node.style.setProperty('-webkit-backdrop-filter', `blur(${BLUR_AMOUNT}px)`);\n } else {\n node.style.backgroundColor = 'rgba(0, 0, 0, 0)';\n node.style.backdropFilter = 'blur(0px)';\n node.style.setProperty('-webkit-backdrop-filter', 'blur(0px)');\n }\n }, [entered]);\n\n // Web-only side effects: focus trap, scroll lock, Escape close,\n // initial focus on the first focusable inside the dialog. RN Modal\n // handles its own focus model on native, so the platform check keeps\n // these out of the native render path.\n useEffect(() => {\n if (!ctx.open) {\n return;\n }\n if (Platform.OS !== 'web') {\n return;\n }\n if (typeof document === 'undefined') {\n return;\n }\n\n const previouslyFocused = document.activeElement as HTMLElement | null;\n\n // Lock body scroll. Preserve any previously set inline style so\n // we don't accidentally clobber a consumer's lock from elsewhere.\n const prevBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n\n // Move focus into the dialog. Prefer the first focusable element;\n // if there isn't one, focus the dialog container itself so it\n // receives the keydown events.\n const focusFirst = () => {\n const node = contentRef.current;\n if (!node) {\n return;\n }\n const focusable = node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR);\n const first = focusable[0];\n if (first) {\n first.focus();\n } else {\n node.setAttribute('tabindex', '-1');\n node.focus();\n }\n };\n focusFirst();\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n ctx.setOpen(false);\n return;\n }\n if (event.key !== 'Tab') {\n return;\n }\n const node = contentRef.current;\n if (!node) {\n return;\n }\n const focusable = Array.from(node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) => el.offsetParent !== null || el === document.activeElement\n );\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (!first || !last) {\n return;\n }\n if (event.shiftKey) {\n if (document.activeElement === first || !node.contains(document.activeElement)) {\n event.preventDefault();\n last.focus();\n }\n } else if (document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n document.addEventListener('keydown', onKeyDown);\n\n return () => {\n document.removeEventListener('keydown', onKeyDown);\n document.body.style.overflow = prevBodyOverflow;\n // Restore focus to whatever opened the dialog (the trigger),\n // falling back to the previously focused node if the trigger\n // is gone.\n const restoreTo = ctx.triggerRef.current ?? previouslyFocused;\n restoreTo?.focus?.();\n };\n }, [ctx.open, ctx.setOpen, ctx.triggerRef]);\n\n const onOverlayPress = useCallback(() => ctx.setOpen(false), [ctx]);\n\n return (\n <Modal\n visible={ctx.open}\n transparent\n // Web: 'none' so RN's built-in fade doesn't fight our own\n // overlay/content transitions (its layer-level fade caused\n // backdrop-filter to \"snap in\" at the end). Native: 'fade'\n // is what users expect on iOS/Android and we don't have a\n // CSS transition path there anyway.\n animationType={Platform.OS === 'web' ? 'none' : 'fade'}\n onRequestClose={() => ctx.setOpen(false)}\n >\n {/* Native blur layer. Renders nothing on web (the overlay's\n CSS backdrop-filter handles it) and renders nothing if\n expo-blur isn't installed (graceful degrade — the scrim\n Pressable below still dims the background). */}\n <BlurBackdrop intensity={60} tint={scheme === 'dark' ? 'dark' : 'light'} style={StyleSheet.absoluteFill} />\n <Pressable\n accessibilityRole=\"none\"\n aria-hidden={true}\n ref={(node) => {\n overlayDomRef.current = node as unknown as HTMLElement | null;\n }}\n style={overlayStyle}\n onPress={onOverlayPress}\n >\n <Pressable\n onPress={(event) => event.stopPropagation?.()}\n ref={(node) => {\n contentRef.current = node as unknown as HTMLDivElement | null;\n }}\n role=\"dialog\"\n accessibilityRole=\"none\"\n aria-modal={true}\n aria-labelledby={ctx.titleId}\n aria-describedby={ctx.descriptionId}\n {...(testID !== undefined ? { testID } : {})}\n className={cn('w-full max-w-md rounded-xl bg-semantic-background-elevated p-6 gap-3', className)}\n style={[contentStyle, { backgroundColor: colors.semantic.background.elevated }, enterStyle]}\n >\n <View\n className=\"flex-col gap-1.5\"\n style={{ flexDirection: 'column', gap: px(colors.spacing['2']) - 2 }}\n >\n {children}\n </View>\n </Pressable>\n </Pressable>\n </Modal>\n );\n};\n\nexport type DialogTextProps = {\n children?: ReactNode;\n className?: string;\n};\n\n/** Heading inside DialogContent. Wires `aria-labelledby`. */\nexport const DialogTitle = ({ children, className }: DialogTextProps) => {\n const ctx = useDialogContext('DialogTitle');\n const colors = useThemeColors();\n return (\n <RNText\n nativeID={ctx.titleId}\n id={ctx.titleId}\n role=\"heading\"\n aria-level={2}\n className={cn('text-lg font-semibold text-semantic-text-default', className)}\n style={{\n color: colors.semantic.text.default,\n fontFamily: colors.fontFamily.display,\n fontSize: px(colors.fontSize.lg),\n fontWeight: colors.fontWeight.semibold as '600',\n }}\n >\n {children}\n </RNText>\n );\n};\n\n/** Subtitle / description inside DialogContent. Wires `aria-describedby`. */\nexport const DialogDescription = ({ children, className }: DialogTextProps) => {\n const ctx = useDialogContext('DialogDescription');\n const colors = useThemeColors();\n return (\n <RNText\n nativeID={ctx.descriptionId}\n id={ctx.descriptionId}\n className={cn('text-sm text-semantic-text-muted', className)}\n style={{\n color: colors.semantic.text.muted,\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize.sm),\n lineHeight: px(colors.fontSize.sm) * Number(colors.lineHeight.normal),\n }}\n >\n {children}\n </RNText>\n );\n};\n\nexport type DialogCloseProps = {\n /** Render the child as the close button (Slot pattern). Default true. */\n asChild?: boolean;\n children?: ReactNode;\n className?: string;\n testID?: string;\n accessibilityLabel?: string;\n};\n\n/**\n * Element that closes the dialog when activated. With `asChild` (default),\n * wraps the child. Without `asChild`, renders a default ✕ button — useful\n * for the canonical top-right corner close.\n */\nexport const DialogClose = ({\n asChild = true,\n children,\n className,\n testID,\n accessibilityLabel = 'Close',\n}: DialogCloseProps) => {\n const ctx = useDialogContext('DialogClose');\n const colors = useThemeColors();\n const onPress = useCallback(() => ctx.setOpen(false), [ctx]);\n\n if (asChild && isValidElement(children)) {\n const child = children as ReactElement<Record<string, unknown>>;\n // Same dual-event story as DialogTrigger: pass both onClick (web\n // button) and onPress (RN Pressable / our own Button) so the\n // wrapped element fires regardless of its event model.\n const fire = (existing: ((e: unknown) => void) | undefined) => (event: unknown) => {\n existing?.(event);\n ctx.setOpen(false);\n };\n return (\n <Slot\n onClick={fire(child.props.onClick as ((e: unknown) => void) | undefined)}\n onPress={fire(child.props.onPress as ((e: unknown) => void) | undefined)}\n {...(testID !== undefined ? { 'data-testid': testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {child}\n </Slot>\n );\n }\n\n if (children !== undefined) {\n return (\n <Pressable\n onPress={onPress}\n role=\"button\"\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n aria-label={accessibilityLabel}\n {...(testID !== undefined ? { testID } : {})}\n {...(className !== undefined ? { className } : {})}\n >\n {wrapStringChildren(children)}\n </Pressable>\n );\n }\n\n return (\n <Pressable\n onPress={onPress}\n role=\"button\"\n accessibilityRole=\"button\"\n accessibilityLabel={accessibilityLabel}\n aria-label={accessibilityLabel}\n {...(testID !== undefined ? { testID } : {})}\n className={cn('absolute right-3 top-3 w-8 h-8 items-center justify-center rounded-md', className)}\n style={{\n position: 'absolute',\n right: px(colors.spacing['3']),\n top: px(colors.spacing['3']),\n // 32×32 close hit target — component-density literal — not from theme\n width: 32,\n height: 32,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: px(colors.radius.md),\n }}\n >\n <defaultSemanticIcons.close size={18} color={colors.semantic.text.muted} />\n </Pressable>\n );\n};\n\nexport type DialogFooterProps = {\n children?: ReactNode;\n className?: string;\n};\n\n/** Convenience row for dialog action buttons (right-aligned). */\nexport const DialogFooter = ({ children, className }: DialogFooterProps) => {\n const colors = useThemeColors();\n return (\n <View\n className={cn('mt-4 flex-row items-center justify-end gap-2', className)}\n style={{\n marginTop: px(colors.spacing['4']),\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: px(colors.spacing['2']),\n }}\n >\n {children}\n </View>\n );\n};\n\n/**\n * Public `Dialog` value — the root function plus its `.Trigger`, `.Content`,\n * `.Title`, `.Description`, `.Footer`, and `.Close` static members. `Object.assign`\n * produces a value whose inferred type carries the static properties, so `.d.ts`\n * consumers can write `<Dialog.Content>` without a separate import.\n */\nexport const Dialog = Object.assign(DialogRoot, {\n Trigger: DialogTrigger,\n Content: DialogContent,\n Title: DialogTitle,\n Description: DialogDescription,\n Footer: DialogFooter,\n Close: DialogClose,\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  import { Spinner } from './chunk-ACLHDHX3.js';
2
2
  import { Slot } from './chunk-ZIBNLXIV.js';
3
- import { px } from './chunk-5A2QOOVN.js';
4
3
  import { cn } from './chunk-CHXHRJNZ.js';
4
+ import { px } from './chunk-5A2QOOVN.js';
5
5
  import { useThemeColors } from './chunk-R5JMDDCB.js';
6
6
  import { __name } from './chunk-WCQVDF3K.js';
7
7
  import { useState, useCallback } from 'react';
@@ -204,5 +204,5 @@ var Button = /* @__PURE__ */ __name(({
204
204
  }, "Button");
205
205
 
206
206
  export { Button };
207
- //# sourceMappingURL=chunk-5XEGZFG5.js.map
208
- //# sourceMappingURL=chunk-5XEGZFG5.js.map
207
+ //# sourceMappingURL=chunk-LWQZ257T.js.map
208
+ //# sourceMappingURL=chunk-LWQZ257T.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Button/Button.tsx"],"names":["RNText"],"mappings":"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","file":"chunk-5XEGZFG5.js","sourcesContent":["'use client';\n\nimport type { Theme } from '@nori-ui/tokens';\nimport type { ComponentType, ReactNode, Ref } from 'react';\nimport { useCallback, useState } from 'react';\nimport type { PressableProps, StyleProp, View, ViewStyle } from 'react-native';\nimport { Pressable, Text as RNText } from 'react-native';\nimport { Slot } from '../../slot';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport { Spinner } from '../Spinner';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'destructive';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\ntype IconSlot = ComponentType<{ size?: number; color?: string }>;\n\nexport type ButtonProps = Omit<PressableProps, 'disabled' | 'children'> & {\n children?: ReactNode;\n variant?: ButtonVariant;\n size?: ButtonSize;\n disabled?: boolean;\n loading?: boolean;\n leadingIcon?: IconSlot;\n trailingIcon?: IconSlot;\n /** If true, the single child becomes the interactive element (Slot pattern). */\n asChild?: boolean;\n className?: string;\n testID?: string;\n ref?: Ref<View>;\n};\n\n// NativeWind classes — the `dark:` variants flip colors when <html> carries\n// the `dark` class (or `data-theme=\"dark\"`); see the tokens Tailwind preset.\n//\n// These act as the no-NativeWind fallback (e.g. raw JSX in Expo Snack\n// without a compile step) and the dark-mode bridge. The dimensional\n// utilities (`rounded-md`, `h-10`, `px-4`, `gap-2`, `text-*`) are kept\n// because the inline `style` array always overrides them — so when a\n// `<ThemeProvider>` widens spacing/radius/fontSize, the inline values\n// win on CSS specificity and the Tailwind class is harmless.\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n 'bg-semantic-interactive-primary hover:bg-semantic-interactive-primaryHover active:bg-semantic-interactive-primaryPressed',\n secondary:\n 'bg-neutral-100 hover:bg-neutral-200 active:bg-neutral-300 dark:bg-neutral-800 dark:hover:bg-neutral-700 dark:active:bg-neutral-600',\n ghost: 'bg-transparent hover:bg-neutral-100 active:bg-neutral-200 dark:hover:bg-neutral-800 dark:active:bg-neutral-700',\n destructive: 'bg-semantic-interactive-destructive hover:opacity-90 active:opacity-80',\n};\n\nconst SIZE_CLASSES: Record<ButtonSize, string> = {\n sm: 'h-8 px-3 text-sm',\n md: 'h-10 px-4 text-md',\n lg: 'h-12 px-5 text-lg',\n};\n\nconst ICON_SIZE: Record<ButtonSize, number> = { sm: 14, md: 16, lg: 20 };\n\nconst BASE_CLASSES = 'inline-flex flex-row items-center justify-center gap-2 rounded-md select-none';\n\n// Heights are intentionally hardcoded — they're tightly coupled to the\n// button's overall density (a 48px target on lg, 32px on sm). Padding and\n// fontSize are pulled from the active theme so a custom theme that scales\n// the spacing/fontSize ramps also scales the button. If you want a\n// genuinely smaller / taller button, override `theme.spacing` /\n// `theme.fontSize` rather than reach for new size literals here.\nconst HEIGHT_BY_SIZE: Record<ButtonSize, number> = {\n sm: 32,\n md: 40,\n lg: 48,\n};\ntype SizeKeys = { padX: keyof Theme['spacing']; font: keyof Theme['fontSize'] };\nconst SIZE_KEYS: Record<ButtonSize, SizeKeys> = {\n sm: { padX: '3', font: 'sm' },\n md: { padX: '4', font: 'md' },\n lg: { padX: '5', font: 'lg' },\n};\n\n// gap and borderRadius come from the theme inside the component.\nconst BASE_STYLE: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nexport const Button = ({\n children,\n variant = 'primary',\n size = 'md',\n disabled,\n loading,\n leadingIcon: LeadingIcon,\n trailingIcon: TrailingIcon,\n asChild,\n className,\n onPress,\n testID,\n style,\n ref,\n ...rest\n}: ButtonProps) => {\n const colors = useThemeColors();\n const isInoperative = Boolean(disabled) || Boolean(loading);\n // rn-web's `Pressable` does not reliably apply a `style` callback's\n // returned values to the rendered DOM (the static portions get\n // dropped). We track hover/press via state and pass `style` as a\n // plain array — that path produces an inline `style=\"…\"` attribute\n // on the button, which beats the dimensional Tailwind utilities on\n // CSS specificity and lets a custom `<ThemeProvider>` flow padding,\n // radius, fontSize, fontFamily, and fontWeight all the way through.\n const [hovered, setHovered] = useState(false);\n const [pressed, setPressed] = useState(false);\n const handleHoverIn = useCallback(() => setHovered(true), []);\n const handleHoverOut = useCallback(() => {\n setHovered(false);\n setPressed(false);\n }, []);\n const handlePressIn = useCallback(() => setPressed(true), []);\n const handlePressOut = useCallback(() => setPressed(false), []);\n // When disabled, drop the variant's hover/active class fragments and\n // append `pointer-events-none cursor-not-allowed` so the className\n // path matches the inline-style path: no hover tint, no press tint,\n // and the cursor signals the control is inert. We still keep the\n // base variant bg class so the resting color is right.\n const variantClasses = isInoperative\n ? VARIANT_CLASSES[variant]\n .split(' ')\n .filter((cls) => !cls.startsWith('hover:') && !cls.startsWith('active:'))\n .join(' ')\n : VARIANT_CLASSES[variant];\n const classes = cn(\n BASE_CLASSES,\n variantClasses,\n SIZE_CLASSES[size],\n isInoperative ? 'opacity-60 pointer-events-none cursor-not-allowed' : undefined,\n className\n );\n\n // Inline-style palette per (variant × interaction state). The hook is the\n // source of truth — dark mode and theme overrides flow through it.\n //\n // Why inline (not className): a class-based `:hover { background-color }`\n // can never beat an inline `style={{ backgroundColor }}` — inline wins\n // by CSS specificity. So if we want hover to actually flip the surface\n // color, hover has to be applied inline too. We use Pressable's `style`\n // callback (`{ hovered, pressed }`) which on web is wired up by\n // react-native-web and on native exposes only `pressed`. The className\n // path keeps the same Tailwind variants for the no-NativeWind fallback\n // case (Expo Snack rendering raw JSX without compilation).\n const variantStateColors: Record<ButtonVariant, { rest: string; hover: string; pressed: string }> = {\n primary: {\n rest: colors.semantic.interactive.primary,\n hover: colors.semantic.interactive.primaryHover,\n pressed: colors.semantic.interactive.primaryPressed,\n },\n secondary: {\n rest: colors.semantic.background.subtle,\n // hover / pressed must be theme-aware. The previous version\n // pulled directly from `color.neutral.{200,300}`, which are\n // raw tokens that DON'T flip per scheme — in dark mode the\n // hovered state ended up light-gray on dark, ruining contrast.\n // `border.default` / `border.strong` invert correctly: in\n // light they read as light-gray washes (next step from\n // `background.subtle`); in dark they read as the darker grays\n // expected for hover/pressed on a dark surface.\n hover: colors.semantic.border.default,\n pressed: colors.semantic.border.strong,\n },\n ghost: {\n rest: 'transparent',\n hover: colors.semantic.background.subtle,\n pressed: colors.semantic.border.default,\n },\n destructive: {\n rest: colors.semantic.interactive.destructive,\n // No darker tone token for destructive yet — fall back to a 90% /\n // 80% opacity wash by mixing through rgba. Matches the className\n // hover:opacity-90 / active:opacity-80 fallback.\n hover: colors.semantic.interactive.destructive,\n pressed: colors.semantic.interactive.destructive,\n },\n };\n const variantTextColor: Record<ButtonVariant, string> = {\n primary: colors.semantic.text.inverted,\n secondary: colors.semantic.text.default,\n ghost: colors.semantic.text.default,\n destructive: colors.semantic.text.inverted,\n };\n\n const stateColors = variantStateColors[variant];\n // When disabled (or loading), force the rest state — disabled means\n // disabled. The control should NOT visually respond to hover/press,\n // even though the OS still fires those events. Pressable also gets\n // `disabled={true}` on the Pressable below which blocks onPress, but\n // the visual treatment is owned here.\n const stateBg = isInoperative\n ? stateColors.rest\n : pressed\n ? stateColors.pressed\n : hovered\n ? stateColors.hover\n : stateColors.rest;\n // Destructive uses opacity dim instead of a separate color (matches\n // existing className behavior; keeps the red recognisable on press).\n // Same disabled rule as bg: hover/press dim is suppressed when\n // disabled — the static 0.6 opacity below handles the disabled look.\n const stateInteractionOpacity = isInoperative || variant !== 'destructive' ? 1 : pressed ? 0.8 : hovered ? 0.9 : 1;\n\n // Resolve all dimensional + typographic values from the active theme\n // so a custom theme that scales spacing / fontSize / radius / fontWeight\n // also reshapes every Button on the page.\n const sizeKeys = SIZE_KEYS[size];\n const sizeContainer: ViewStyle = {\n height: HEIGHT_BY_SIZE[size],\n paddingHorizontal: px(colors.spacing[sizeKeys.padX]),\n gap: px(colors.spacing['2']),\n borderRadius: px(colors.radius.md),\n };\n const sizeFontSize = px(colors.fontSize[sizeKeys.font]);\n\n const inlineBase: ViewStyle[] = [\n BASE_STYLE,\n { backgroundColor: stateBg },\n sizeContainer,\n { opacity: isInoperative ? 0.6 : stateInteractionOpacity },\n ];\n // Resolve the consumer's `style` against the same hover/press state\n // we just computed — this preserves the historical contract where a\n // callback `style` receives the live interaction flags. The RN\n // upstream type only declares `pressed`; rn-web also passes\n // `hovered`. Cast through `unknown` to ship both without a type\n // assertion battle.\n const consumerStyle: StyleProp<ViewStyle> =\n typeof style === 'function' ? style({ pressed, ...({ hovered } as Record<string, unknown>) } as never) : style;\n const pressableStyle: StyleProp<ViewStyle> = [...inlineBase, consumerStyle];\n const slotStyle: StyleProp<ViewStyle> = [...inlineBase, consumerStyle];\n\n const textColor = variantTextColor[variant];\n const textStyle = {\n color: textColor,\n fontFamily: colors.fontFamily.body,\n fontSize: sizeFontSize,\n fontWeight: colors.fontWeight.medium as '500',\n };\n\n const handlePress: NonNullable<PressableProps['onPress']> = (ev) => {\n if (isInoperative) {\n return;\n }\n onPress?.(ev);\n };\n\n if (asChild) {\n const slotProps: Record<string, unknown> = {\n ref,\n className: classes,\n style: slotStyle,\n onClick: handlePress as unknown as (...args: unknown[]) => unknown,\n ...rest,\n };\n if (isInoperative) {\n slotProps['aria-disabled'] = true;\n }\n if (loading) {\n slotProps['aria-busy'] = true;\n }\n if (testID !== undefined) {\n slotProps['data-testid'] = testID;\n }\n return <Slot {...slotProps}>{children}</Slot>;\n }\n\n const pressableExtra: Record<string, unknown> = {};\n if (isInoperative) {\n pressableExtra['aria-disabled'] = true;\n }\n if (loading) {\n pressableExtra['aria-busy'] = true;\n }\n\n return (\n <Pressable\n ref={ref}\n {...(testID !== undefined ? { testID } : {})}\n role=\"button\"\n accessibilityRole=\"button\"\n accessibilityState={{ disabled: isInoperative, busy: Boolean(loading) }}\n disabled={isInoperative}\n onPress={handlePress}\n onHoverIn={handleHoverIn}\n onHoverOut={handleHoverOut}\n onPressIn={handlePressIn}\n onPressOut={handlePressOut}\n className={classes}\n style={pressableStyle}\n {...pressableExtra}\n {...rest}\n >\n {loading ? (\n <Spinner size={ICON_SIZE[size]} label=\"Loading\" color={textColor} />\n ) : LeadingIcon ? (\n <LeadingIcon size={ICON_SIZE[size]} color={textColor} />\n ) : null}\n <RNText\n className={cn('font-medium', SIZE_CLASSES[size].includes('text-') ? undefined : 'text-md')}\n style={textStyle}\n >\n {children}\n </RNText>\n {TrailingIcon ? <TrailingIcon size={ICON_SIZE[size]} color={textColor} /> : null}\n </Pressable>\n );\n};\n"]}
1
+ {"version":3,"sources":["../src/components/Button/Button.tsx"],"names":["RNText"],"mappings":"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","file":"chunk-LWQZ257T.js","sourcesContent":["'use client';\n\nimport type { Theme } from '@nori-ui/tokens';\nimport type { ComponentType, ReactNode, Ref } from 'react';\nimport { useCallback, useState } from 'react';\nimport type { PressableProps, StyleProp, View, ViewStyle } from 'react-native';\nimport { Pressable, Text as RNText } from 'react-native';\nimport { Slot } from '../../slot';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\nimport { Spinner } from '../Spinner';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'destructive';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\ntype IconSlot = ComponentType<{ size?: number; color?: string }>;\n\nexport type ButtonProps = Omit<PressableProps, 'disabled' | 'children'> & {\n children?: ReactNode;\n variant?: ButtonVariant;\n size?: ButtonSize;\n disabled?: boolean;\n loading?: boolean;\n leadingIcon?: IconSlot;\n trailingIcon?: IconSlot;\n /** If true, the single child becomes the interactive element (Slot pattern). */\n asChild?: boolean;\n className?: string;\n testID?: string;\n ref?: Ref<View>;\n};\n\n// NativeWind classes — the `dark:` variants flip colors when <html> carries\n// the `dark` class (or `data-theme=\"dark\"`); see the tokens Tailwind preset.\n//\n// These act as the no-NativeWind fallback (e.g. raw JSX in Expo Snack\n// without a compile step) and the dark-mode bridge. The dimensional\n// utilities (`rounded-md`, `h-10`, `px-4`, `gap-2`, `text-*`) are kept\n// because the inline `style` array always overrides them — so when a\n// `<ThemeProvider>` widens spacing/radius/fontSize, the inline values\n// win on CSS specificity and the Tailwind class is harmless.\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n 'bg-semantic-interactive-primary hover:bg-semantic-interactive-primaryHover active:bg-semantic-interactive-primaryPressed',\n secondary:\n 'bg-neutral-100 hover:bg-neutral-200 active:bg-neutral-300 dark:bg-neutral-800 dark:hover:bg-neutral-700 dark:active:bg-neutral-600',\n ghost: 'bg-transparent hover:bg-neutral-100 active:bg-neutral-200 dark:hover:bg-neutral-800 dark:active:bg-neutral-700',\n destructive: 'bg-semantic-interactive-destructive hover:opacity-90 active:opacity-80',\n};\n\nconst SIZE_CLASSES: Record<ButtonSize, string> = {\n sm: 'h-8 px-3 text-sm',\n md: 'h-10 px-4 text-md',\n lg: 'h-12 px-5 text-lg',\n};\n\nconst ICON_SIZE: Record<ButtonSize, number> = { sm: 14, md: 16, lg: 20 };\n\nconst BASE_CLASSES = 'inline-flex flex-row items-center justify-center gap-2 rounded-md select-none';\n\n// Heights are intentionally hardcoded — they're tightly coupled to the\n// button's overall density (a 48px target on lg, 32px on sm). Padding and\n// fontSize are pulled from the active theme so a custom theme that scales\n// the spacing/fontSize ramps also scales the button. If you want a\n// genuinely smaller / taller button, override `theme.spacing` /\n// `theme.fontSize` rather than reach for new size literals here.\nconst HEIGHT_BY_SIZE: Record<ButtonSize, number> = {\n sm: 32,\n md: 40,\n lg: 48,\n};\ntype SizeKeys = { padX: keyof Theme['spacing']; font: keyof Theme['fontSize'] };\nconst SIZE_KEYS: Record<ButtonSize, SizeKeys> = {\n sm: { padX: '3', font: 'sm' },\n md: { padX: '4', font: 'md' },\n lg: { padX: '5', font: 'lg' },\n};\n\n// gap and borderRadius come from the theme inside the component.\nconst BASE_STYLE: ViewStyle = {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nexport const Button = ({\n children,\n variant = 'primary',\n size = 'md',\n disabled,\n loading,\n leadingIcon: LeadingIcon,\n trailingIcon: TrailingIcon,\n asChild,\n className,\n onPress,\n testID,\n style,\n ref,\n ...rest\n}: ButtonProps) => {\n const colors = useThemeColors();\n const isInoperative = Boolean(disabled) || Boolean(loading);\n // rn-web's `Pressable` does not reliably apply a `style` callback's\n // returned values to the rendered DOM (the static portions get\n // dropped). We track hover/press via state and pass `style` as a\n // plain array — that path produces an inline `style=\"…\"` attribute\n // on the button, which beats the dimensional Tailwind utilities on\n // CSS specificity and lets a custom `<ThemeProvider>` flow padding,\n // radius, fontSize, fontFamily, and fontWeight all the way through.\n const [hovered, setHovered] = useState(false);\n const [pressed, setPressed] = useState(false);\n const handleHoverIn = useCallback(() => setHovered(true), []);\n const handleHoverOut = useCallback(() => {\n setHovered(false);\n setPressed(false);\n }, []);\n const handlePressIn = useCallback(() => setPressed(true), []);\n const handlePressOut = useCallback(() => setPressed(false), []);\n // When disabled, drop the variant's hover/active class fragments and\n // append `pointer-events-none cursor-not-allowed` so the className\n // path matches the inline-style path: no hover tint, no press tint,\n // and the cursor signals the control is inert. We still keep the\n // base variant bg class so the resting color is right.\n const variantClasses = isInoperative\n ? VARIANT_CLASSES[variant]\n .split(' ')\n .filter((cls) => !cls.startsWith('hover:') && !cls.startsWith('active:'))\n .join(' ')\n : VARIANT_CLASSES[variant];\n const classes = cn(\n BASE_CLASSES,\n variantClasses,\n SIZE_CLASSES[size],\n isInoperative ? 'opacity-60 pointer-events-none cursor-not-allowed' : undefined,\n className\n );\n\n // Inline-style palette per (variant × interaction state). The hook is the\n // source of truth — dark mode and theme overrides flow through it.\n //\n // Why inline (not className): a class-based `:hover { background-color }`\n // can never beat an inline `style={{ backgroundColor }}` — inline wins\n // by CSS specificity. So if we want hover to actually flip the surface\n // color, hover has to be applied inline too. We use Pressable's `style`\n // callback (`{ hovered, pressed }`) which on web is wired up by\n // react-native-web and on native exposes only `pressed`. The className\n // path keeps the same Tailwind variants for the no-NativeWind fallback\n // case (Expo Snack rendering raw JSX without compilation).\n const variantStateColors: Record<ButtonVariant, { rest: string; hover: string; pressed: string }> = {\n primary: {\n rest: colors.semantic.interactive.primary,\n hover: colors.semantic.interactive.primaryHover,\n pressed: colors.semantic.interactive.primaryPressed,\n },\n secondary: {\n rest: colors.semantic.background.subtle,\n // hover / pressed must be theme-aware. The previous version\n // pulled directly from `color.neutral.{200,300}`, which are\n // raw tokens that DON'T flip per scheme — in dark mode the\n // hovered state ended up light-gray on dark, ruining contrast.\n // `border.default` / `border.strong` invert correctly: in\n // light they read as light-gray washes (next step from\n // `background.subtle`); in dark they read as the darker grays\n // expected for hover/pressed on a dark surface.\n hover: colors.semantic.border.default,\n pressed: colors.semantic.border.strong,\n },\n ghost: {\n rest: 'transparent',\n hover: colors.semantic.background.subtle,\n pressed: colors.semantic.border.default,\n },\n destructive: {\n rest: colors.semantic.interactive.destructive,\n // No darker tone token for destructive yet — fall back to a 90% /\n // 80% opacity wash by mixing through rgba. Matches the className\n // hover:opacity-90 / active:opacity-80 fallback.\n hover: colors.semantic.interactive.destructive,\n pressed: colors.semantic.interactive.destructive,\n },\n };\n const variantTextColor: Record<ButtonVariant, string> = {\n primary: colors.semantic.text.inverted,\n secondary: colors.semantic.text.default,\n ghost: colors.semantic.text.default,\n destructive: colors.semantic.text.inverted,\n };\n\n const stateColors = variantStateColors[variant];\n // When disabled (or loading), force the rest state — disabled means\n // disabled. The control should NOT visually respond to hover/press,\n // even though the OS still fires those events. Pressable also gets\n // `disabled={true}` on the Pressable below which blocks onPress, but\n // the visual treatment is owned here.\n const stateBg = isInoperative\n ? stateColors.rest\n : pressed\n ? stateColors.pressed\n : hovered\n ? stateColors.hover\n : stateColors.rest;\n // Destructive uses opacity dim instead of a separate color (matches\n // existing className behavior; keeps the red recognisable on press).\n // Same disabled rule as bg: hover/press dim is suppressed when\n // disabled — the static 0.6 opacity below handles the disabled look.\n const stateInteractionOpacity = isInoperative || variant !== 'destructive' ? 1 : pressed ? 0.8 : hovered ? 0.9 : 1;\n\n // Resolve all dimensional + typographic values from the active theme\n // so a custom theme that scales spacing / fontSize / radius / fontWeight\n // also reshapes every Button on the page.\n const sizeKeys = SIZE_KEYS[size];\n const sizeContainer: ViewStyle = {\n height: HEIGHT_BY_SIZE[size],\n paddingHorizontal: px(colors.spacing[sizeKeys.padX]),\n gap: px(colors.spacing['2']),\n borderRadius: px(colors.radius.md),\n };\n const sizeFontSize = px(colors.fontSize[sizeKeys.font]);\n\n const inlineBase: ViewStyle[] = [\n BASE_STYLE,\n { backgroundColor: stateBg },\n sizeContainer,\n { opacity: isInoperative ? 0.6 : stateInteractionOpacity },\n ];\n // Resolve the consumer's `style` against the same hover/press state\n // we just computed — this preserves the historical contract where a\n // callback `style` receives the live interaction flags. The RN\n // upstream type only declares `pressed`; rn-web also passes\n // `hovered`. Cast through `unknown` to ship both without a type\n // assertion battle.\n const consumerStyle: StyleProp<ViewStyle> =\n typeof style === 'function' ? style({ pressed, ...({ hovered } as Record<string, unknown>) } as never) : style;\n const pressableStyle: StyleProp<ViewStyle> = [...inlineBase, consumerStyle];\n const slotStyle: StyleProp<ViewStyle> = [...inlineBase, consumerStyle];\n\n const textColor = variantTextColor[variant];\n const textStyle = {\n color: textColor,\n fontFamily: colors.fontFamily.body,\n fontSize: sizeFontSize,\n fontWeight: colors.fontWeight.medium as '500',\n };\n\n const handlePress: NonNullable<PressableProps['onPress']> = (ev) => {\n if (isInoperative) {\n return;\n }\n onPress?.(ev);\n };\n\n if (asChild) {\n const slotProps: Record<string, unknown> = {\n ref,\n className: classes,\n style: slotStyle,\n onClick: handlePress as unknown as (...args: unknown[]) => unknown,\n ...rest,\n };\n if (isInoperative) {\n slotProps['aria-disabled'] = true;\n }\n if (loading) {\n slotProps['aria-busy'] = true;\n }\n if (testID !== undefined) {\n slotProps['data-testid'] = testID;\n }\n return <Slot {...slotProps}>{children}</Slot>;\n }\n\n const pressableExtra: Record<string, unknown> = {};\n if (isInoperative) {\n pressableExtra['aria-disabled'] = true;\n }\n if (loading) {\n pressableExtra['aria-busy'] = true;\n }\n\n return (\n <Pressable\n ref={ref}\n {...(testID !== undefined ? { testID } : {})}\n role=\"button\"\n accessibilityRole=\"button\"\n accessibilityState={{ disabled: isInoperative, busy: Boolean(loading) }}\n disabled={isInoperative}\n onPress={handlePress}\n onHoverIn={handleHoverIn}\n onHoverOut={handleHoverOut}\n onPressIn={handlePressIn}\n onPressOut={handlePressOut}\n className={classes}\n style={pressableStyle}\n {...pressableExtra}\n {...rest}\n >\n {loading ? (\n <Spinner size={ICON_SIZE[size]} label=\"Loading\" color={textColor} />\n ) : LeadingIcon ? (\n <LeadingIcon size={ICON_SIZE[size]} color={textColor} />\n ) : null}\n <RNText\n className={cn('font-medium', SIZE_CLASSES[size].includes('text-') ? undefined : 'text-md')}\n style={textStyle}\n >\n {children}\n </RNText>\n {TrailingIcon ? <TrailingIcon size={ICON_SIZE[size]} color={textColor} /> : null}\n </Pressable>\n );\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { resolveI18n, defaultDictionary } from './chunk-FT2XBBQJ.js';
1
+ import { resolveI18n, defaultDictionary } from './chunk-6PO2IWB3.js';
2
2
  import { __name } from './chunk-WCQVDF3K.js';
3
3
  import { createContext, useMemo, useContext } from 'react';
4
4
  import { jsx } from 'nativewind/jsx-runtime';
@@ -19,5 +19,5 @@ function useTranslation() {
19
19
  __name(useTranslation, "useTranslation");
20
20
 
21
21
  export { I18nProvider, useTranslation };
22
- //# sourceMappingURL=chunk-RFW5SRZA.js.map
23
- //# sourceMappingURL=chunk-RFW5SRZA.js.map
22
+ //# sourceMappingURL=chunk-MJ4AGXS7.js.map
23
+ //# sourceMappingURL=chunk-MJ4AGXS7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/i18n/context.tsx","../src/i18n/use-translation.ts"],"names":[],"mappings":";;;;;AAcA,IAAM,YAAA,GAAiC;AAAA,EACnC,CAAA,EAAG,WAAA,CAAY,MAAA,EAAW,iBAAiB;AAC/C,CAAA;AAEO,IAAM,WAAA,GAAc,cAAgC,YAAY,CAAA;AACvE,WAAA,CAAY,WAAA,GAAc,aAAA;AAOnB,SAAS,YAAA,CAAa,EAAE,IAAA,EAAM,QAAA,EAAS,EAAsB;AAChE,EAAA,MAAM,KAAA,GAAQ,OAAA,CAA0B,OAAO,EAAE,CAAA,EAAG,WAAA,CAAY,IAAA,EAAM,iBAAiB,CAAA,EAAE,CAAA,EAAI,CAAC,IAAI,CAAC,CAAA;AACnG,EAAA,uBAAO,GAAA,CAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,OAAe,QAAA,EAAS,CAAA;AACzD;AAHgB,MAAA,CAAA,YAAA,EAAA,cAAA,CAAA;ACrBT,SAAS,cAAA,GAAmC;AAC/C,EAAA,OAAO,WAAW,WAAW,CAAA;AACjC;AAFgB,MAAA,CAAA,cAAA,EAAA,gBAAA,CAAA","file":"chunk-RFW5SRZA.js","sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { createContext, useMemo } from 'react';\nimport { defaultDictionary } from './default-dictionary';\nimport { resolveI18n } from './resolve';\nimport type { I18nInput, TranslateFn } from './types';\n\nexport type I18nContextValue = {\n t: TranslateFn;\n};\n\n// Default context value uses the built-in English dictionary; consumers without\n// a provider still get a working t().\nconst defaultValue: I18nContextValue = {\n t: resolveI18n(undefined, defaultDictionary),\n};\n\nexport const I18nContext = createContext<I18nContextValue>(defaultValue);\nI18nContext.displayName = 'I18nContext';\n\nexport type I18nProviderProps = {\n i18n?: I18nInput;\n children?: ReactNode;\n};\n\nexport function I18nProvider({ i18n, children }: I18nProviderProps) {\n const value = useMemo<I18nContextValue>(() => ({ t: resolveI18n(i18n, defaultDictionary) }), [i18n]);\n return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;\n}\n","'use client';\n\nimport { useContext } from 'react';\nimport { I18nContext, type I18nContextValue } from './context';\n\nexport function useTranslation(): I18nContextValue {\n return useContext(I18nContext);\n}\n"]}
1
+ {"version":3,"sources":["../src/i18n/context.tsx","../src/i18n/use-translation.ts"],"names":[],"mappings":";;;;;AAcA,IAAM,YAAA,GAAiC;AAAA,EACnC,CAAA,EAAG,WAAA,CAAY,MAAA,EAAW,iBAAiB;AAC/C,CAAA;AAEO,IAAM,WAAA,GAAc,cAAgC,YAAY,CAAA;AACvE,WAAA,CAAY,WAAA,GAAc,aAAA;AAOnB,SAAS,YAAA,CAAa,EAAE,IAAA,EAAM,QAAA,EAAS,EAAsB;AAChE,EAAA,MAAM,KAAA,GAAQ,OAAA,CAA0B,OAAO,EAAE,CAAA,EAAG,WAAA,CAAY,IAAA,EAAM,iBAAiB,CAAA,EAAE,CAAA,EAAI,CAAC,IAAI,CAAC,CAAA;AACnG,EAAA,uBAAO,GAAA,CAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,OAAe,QAAA,EAAS,CAAA;AACzD;AAHgB,MAAA,CAAA,YAAA,EAAA,cAAA,CAAA;ACrBT,SAAS,cAAA,GAAmC;AAC/C,EAAA,OAAO,WAAW,WAAW,CAAA;AACjC;AAFgB,MAAA,CAAA,cAAA,EAAA,gBAAA,CAAA","file":"chunk-MJ4AGXS7.js","sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { createContext, useMemo } from 'react';\nimport { defaultDictionary } from './default-dictionary';\nimport { resolveI18n } from './resolve';\nimport type { I18nInput, TranslateFn } from './types';\n\nexport type I18nContextValue = {\n t: TranslateFn;\n};\n\n// Default context value uses the built-in English dictionary; consumers without\n// a provider still get a working t().\nconst defaultValue: I18nContextValue = {\n t: resolveI18n(undefined, defaultDictionary),\n};\n\nexport const I18nContext = createContext<I18nContextValue>(defaultValue);\nI18nContext.displayName = 'I18nContext';\n\nexport type I18nProviderProps = {\n i18n?: I18nInput;\n children?: ReactNode;\n};\n\nexport function I18nProvider({ i18n, children }: I18nProviderProps) {\n const value = useMemo<I18nContextValue>(() => ({ t: resolveI18n(i18n, defaultDictionary) }), [i18n]);\n return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;\n}\n","'use client';\n\nimport { useContext } from 'react';\nimport { I18nContext, type I18nContextValue } from './context';\n\nexport function useTranslation(): I18nContextValue {\n return useContext(I18nContext);\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { px } from './chunk-5A2QOOVN.js';
2
1
  import { cn } from './chunk-CHXHRJNZ.js';
2
+ import { px } from './chunk-5A2QOOVN.js';
3
3
  import { useThemeColors } from './chunk-R5JMDDCB.js';
4
4
  import { __name } from './chunk-WCQVDF3K.js';
5
5
  import { useState } from 'react';
@@ -99,5 +99,5 @@ var Avatar = /* @__PURE__ */ __name(({ src, name, size = "md", fallback, classNa
99
99
  }, "Avatar");
100
100
 
101
101
  export { Avatar };
102
- //# sourceMappingURL=chunk-PNP7L4TA.js.map
103
- //# sourceMappingURL=chunk-PNP7L4TA.js.map
102
+ //# sourceMappingURL=chunk-RM5TSXVE.js.map
103
+ //# sourceMappingURL=chunk-RM5TSXVE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Avatar/Avatar.tsx"],"names":["RNImage","RNText"],"mappings":"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","file":"chunk-PNP7L4TA.js","sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { useState } from 'react';\nimport type { ImageStyle, ViewStyle } from 'react-native';\nimport { Image as RNImage, Text as RNText, View } from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\n\nexport type AvatarSize = 'sm' | 'md' | 'lg' | 'xl';\n\nexport type AvatarProps = {\n /** Image URL. When omitted or the load fails, the fallback renders instead. */\n src?: string;\n /**\n * Person/entity name. Used to derive initials for the fallback (first\n * letter of the first word + first letter of the last word, up to 2\n * characters). Also becomes the `alt` text on the image — set this\n * even when `src` loads cleanly.\n */\n name?: string;\n /**\n * Visual size. Maps to a fixed pixel diameter.\n * @defaultValue 'md'\n */\n size?: AvatarSize;\n /**\n * Custom fallback content shown when no `src` is provided or the image\n * fails to load. When omitted, initials derived from `name` render; if\n * `name` is also missing, a neutral placeholder shows.\n */\n fallback?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n// Diameter for each size — component-density literals — not from theme\n// (avatars have a tight visual ramp that doesn't tie to the spacing scale).\nconst SIZE_PX: Record<AvatarSize, number> = {\n sm: 32,\n md: 40,\n lg: 56,\n xl: 72,\n};\n\n// Maps each avatar size to the closest fontSize token key. Resolved to px\n// inside the component so theme overrides take effect.\nconst FALLBACK_FONT_KEY: Record<AvatarSize, 'xs' | 'sm' | 'lg' | 'xl'> = {\n sm: 'xs', // 12\n md: 'sm', // 14\n lg: 'lg', // 18\n xl: 'xl', // 20 (closest to legacy 22)\n};\n\nconst initialsFromName = (name: string | undefined): string => {\n if (!name) {\n return '';\n }\n const trimmed = name.trim();\n if (!trimmed) {\n return '';\n }\n const parts = trimmed.split(/\\s+/);\n const first = parts[0]?.[0] ?? '';\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? '') : '';\n return (first + last).toUpperCase();\n};\n\n/**\n * Circular profile picture with graceful fallback. Renders the image when\n * `src` is provided and loads cleanly; otherwise renders the supplied\n * `fallback`, derived initials from `name`, or a neutral placeholder.\n *\n * Why a single component instead of compound (`AvatarImage` + `AvatarFallback`):\n * the common case is a one-liner — `<Avatar src name />` — and the fallback\n * decision is internal state, not consumer-driven layout.\n */\nexport const Avatar = ({ src, name, size = 'md', fallback, className, testID }: AvatarProps) => {\n const colors = useThemeColors();\n const [imageFailed, setImageFailed] = useState(false);\n const dim = SIZE_PX[size];\n const showImage = src !== undefined && src.length > 0 && !imageFailed;\n\n const containerStyle: ViewStyle = {\n width: dim,\n height: dim,\n borderRadius: dim / 2,\n backgroundColor: colors.semantic.background.subtle,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n };\n\n const imageStyle: ImageStyle = {\n width: dim,\n height: dim,\n };\n\n const initials = initialsFromName(name);\n const accessibilityLabel = name ?? 'Avatar';\n\n return (\n <View\n {...(testID !== undefined ? { testID } : {})}\n accessibilityRole=\"image\"\n accessibilityLabel={accessibilityLabel}\n aria-label={accessibilityLabel}\n className={cn('rounded-full overflow-hidden bg-neutral-200 items-center justify-center', className)}\n style={containerStyle}\n >\n {showImage ? (\n <RNImage\n source={{ uri: src }}\n style={imageStyle}\n accessibilityLabel={accessibilityLabel}\n onError={() => setImageFailed(true)}\n />\n ) : fallback !== undefined ? (\n fallback\n ) : initials.length > 0 ? (\n <RNText\n style={{\n color: colors.semantic.text.muted,\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize[FALLBACK_FONT_KEY[size]]),\n fontWeight: colors.fontWeight.medium as '500',\n }}\n >\n {initials}\n </RNText>\n ) : (\n <View\n style={{\n width: dim * 0.45,\n height: dim * 0.45,\n borderRadius: dim,\n backgroundColor: colors.semantic.text.muted,\n }}\n />\n )}\n </View>\n );\n};\n"]}
1
+ {"version":3,"sources":["../src/components/Avatar/Avatar.tsx"],"names":["RNImage","RNText"],"mappings":"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","file":"chunk-RM5TSXVE.js","sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { useState } from 'react';\nimport type { ImageStyle, ViewStyle } from 'react-native';\nimport { Image as RNImage, Text as RNText, View } from 'react-native';\nimport { px } from '../../theme/px';\nimport { useThemeColors } from '../../theme/use-theme-colors';\nimport { cn } from '../../utils/cn';\n\nexport type AvatarSize = 'sm' | 'md' | 'lg' | 'xl';\n\nexport type AvatarProps = {\n /** Image URL. When omitted or the load fails, the fallback renders instead. */\n src?: string;\n /**\n * Person/entity name. Used to derive initials for the fallback (first\n * letter of the first word + first letter of the last word, up to 2\n * characters). Also becomes the `alt` text on the image — set this\n * even when `src` loads cleanly.\n */\n name?: string;\n /**\n * Visual size. Maps to a fixed pixel diameter.\n * @defaultValue 'md'\n */\n size?: AvatarSize;\n /**\n * Custom fallback content shown when no `src` is provided or the image\n * fails to load. When omitted, initials derived from `name` render; if\n * `name` is also missing, a neutral placeholder shows.\n */\n fallback?: ReactNode;\n className?: string;\n testID?: string;\n};\n\n// Diameter for each size — component-density literals — not from theme\n// (avatars have a tight visual ramp that doesn't tie to the spacing scale).\nconst SIZE_PX: Record<AvatarSize, number> = {\n sm: 32,\n md: 40,\n lg: 56,\n xl: 72,\n};\n\n// Maps each avatar size to the closest fontSize token key. Resolved to px\n// inside the component so theme overrides take effect.\nconst FALLBACK_FONT_KEY: Record<AvatarSize, 'xs' | 'sm' | 'lg' | 'xl'> = {\n sm: 'xs', // 12\n md: 'sm', // 14\n lg: 'lg', // 18\n xl: 'xl', // 20 (closest to legacy 22)\n};\n\nconst initialsFromName = (name: string | undefined): string => {\n if (!name) {\n return '';\n }\n const trimmed = name.trim();\n if (!trimmed) {\n return '';\n }\n const parts = trimmed.split(/\\s+/);\n const first = parts[0]?.[0] ?? '';\n const last = parts.length > 1 ? (parts[parts.length - 1]?.[0] ?? '') : '';\n return (first + last).toUpperCase();\n};\n\n/**\n * Circular profile picture with graceful fallback. Renders the image when\n * `src` is provided and loads cleanly; otherwise renders the supplied\n * `fallback`, derived initials from `name`, or a neutral placeholder.\n *\n * Why a single component instead of compound (`AvatarImage` + `AvatarFallback`):\n * the common case is a one-liner — `<Avatar src name />` — and the fallback\n * decision is internal state, not consumer-driven layout.\n */\nexport const Avatar = ({ src, name, size = 'md', fallback, className, testID }: AvatarProps) => {\n const colors = useThemeColors();\n const [imageFailed, setImageFailed] = useState(false);\n const dim = SIZE_PX[size];\n const showImage = src !== undefined && src.length > 0 && !imageFailed;\n\n const containerStyle: ViewStyle = {\n width: dim,\n height: dim,\n borderRadius: dim / 2,\n backgroundColor: colors.semantic.background.subtle,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n };\n\n const imageStyle: ImageStyle = {\n width: dim,\n height: dim,\n };\n\n const initials = initialsFromName(name);\n const accessibilityLabel = name ?? 'Avatar';\n\n return (\n <View\n {...(testID !== undefined ? { testID } : {})}\n accessibilityRole=\"image\"\n accessibilityLabel={accessibilityLabel}\n aria-label={accessibilityLabel}\n className={cn('rounded-full overflow-hidden bg-neutral-200 items-center justify-center', className)}\n style={containerStyle}\n >\n {showImage ? (\n <RNImage\n source={{ uri: src }}\n style={imageStyle}\n accessibilityLabel={accessibilityLabel}\n onError={() => setImageFailed(true)}\n />\n ) : fallback !== undefined ? (\n fallback\n ) : initials.length > 0 ? (\n <RNText\n style={{\n color: colors.semantic.text.muted,\n fontFamily: colors.fontFamily.body,\n fontSize: px(colors.fontSize[FALLBACK_FONT_KEY[size]]),\n fontWeight: colors.fontWeight.medium as '500',\n }}\n >\n {initials}\n </RNText>\n ) : (\n <View\n style={{\n width: dim * 0.45,\n height: dim * 0.45,\n borderRadius: dim,\n backgroundColor: colors.semantic.text.muted,\n }}\n />\n )}\n </View>\n );\n};\n"]}
@@ -1,5 +1,5 @@
1
- import { px } from './chunk-5A2QOOVN.js';
2
1
  import { cn } from './chunk-CHXHRJNZ.js';
2
+ import { px } from './chunk-5A2QOOVN.js';
3
3
  import { useThemeColors } from './chunk-R5JMDDCB.js';
4
4
  import { __name } from './chunk-WCQVDF3K.js';
5
5
  import { createContext, useState, useCallback, useRef, useEffect, useMemo, useContext } from 'react';
@@ -442,5 +442,5 @@ var Toggle = Object.assign(ToggleRoot, {
442
442
  });
443
443
 
444
444
  export { Toggle };
445
- //# sourceMappingURL=chunk-MKSDYRWQ.js.map
446
- //# sourceMappingURL=chunk-MKSDYRWQ.js.map
445
+ //# sourceMappingURL=chunk-SINLREQV.js.map
446
+ //# sourceMappingURL=chunk-SINLREQV.js.map