@titan-design/react-ui 0.1.0 → 0.2.5

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 (236) hide show
  1. package/README.md +47 -1
  2. package/dist/{chunk-MGW37MPO.mjs → chunk-UXVRPOME.mjs} +173 -3
  3. package/dist/chunk-UXVRPOME.mjs.map +1 -0
  4. package/dist/index.d.mts +101 -12
  5. package/dist/index.d.ts +101 -12
  6. package/dist/index.js +1267 -468
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +734 -112
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/theme/index.d.mts +86 -1
  11. package/dist/theme/index.d.ts +86 -1
  12. package/dist/theme/index.js +166 -0
  13. package/dist/theme/index.js.map +1 -1
  14. package/dist/theme/index.mjs +1 -1
  15. package/package.json +22 -6
  16. package/src/components/custom/DateTime/DateTime.stories.tsx +180 -0
  17. package/src/components/custom/DateTime/DateTime.test.tsx +152 -0
  18. package/src/components/custom/DateTime/DateTime.tsx +235 -0
  19. package/src/components/custom/DateTime/index.ts +2 -0
  20. package/src/components/custom/EmptyState/EmptyState.stories.tsx +99 -0
  21. package/src/components/custom/EmptyState/EmptyState.test.tsx +106 -0
  22. package/src/components/custom/EmptyState/EmptyState.tsx +68 -0
  23. package/src/components/custom/EmptyState/index.ts +2 -0
  24. package/src/components/custom/Metric/Metric.stories.tsx +133 -0
  25. package/src/components/custom/Metric/Metric.test.tsx +120 -0
  26. package/src/components/custom/Metric/Metric.tsx +92 -0
  27. package/src/components/custom/Metric/index.ts +2 -0
  28. package/src/components/custom/Sidebar/Sidebar.stories.tsx +227 -0
  29. package/src/components/custom/Sidebar/Sidebar.test.tsx +185 -0
  30. package/src/components/custom/Sidebar/Sidebar.tsx +257 -0
  31. package/src/components/custom/Sidebar/index.ts +18 -0
  32. package/src/components/custom/Table/Table.stories.tsx +481 -0
  33. package/src/components/custom/Table/Table.test.tsx +531 -0
  34. package/src/components/custom/Table/Table.tsx +696 -0
  35. package/src/components/custom/Table/index.ts +22 -0
  36. package/src/components/custom/Typography/Typography.stories.tsx +153 -0
  37. package/src/components/custom/Typography/Typography.test.tsx +107 -0
  38. package/src/components/custom/Typography/Typography.tsx +218 -0
  39. package/src/components/custom/Typography/index.ts +19 -0
  40. package/src/components/custom/Workout/RestTimer.stories.tsx +71 -0
  41. package/src/components/custom/Workout/RestTimer.test.tsx +145 -0
  42. package/src/components/custom/Workout/RestTimer.tsx +172 -0
  43. package/src/components/custom/Workout/SupersetWrapper.stories.tsx +144 -0
  44. package/src/components/custom/Workout/SupersetWrapper.test.tsx +130 -0
  45. package/src/components/custom/Workout/SupersetWrapper.tsx +63 -0
  46. package/src/components/custom/Workout/index.ts +2 -0
  47. package/src/components/custom/index.ts +9 -0
  48. package/src/components/custom/stepper/Stepper.stories.tsx +245 -0
  49. package/src/components/custom/stepper/Stepper.test.tsx +230 -0
  50. package/src/components/custom/stepper/Stepper.tsx +250 -0
  51. package/src/components/custom/stepper/index.ts +10 -0
  52. package/src/components/index.ts +5 -0
  53. package/src/components/ui/alert/Alert.stories.tsx +154 -0
  54. package/src/components/ui/alert/Alert.test.tsx +202 -0
  55. package/src/components/ui/alert/Alert.tsx +170 -0
  56. package/src/components/ui/alert/index.ts +8 -0
  57. package/src/components/ui/autocomplete/Autocomplete.stories.tsx +299 -0
  58. package/src/components/ui/autocomplete/Autocomplete.test.tsx +247 -0
  59. package/src/components/ui/autocomplete/Autocomplete.tsx +332 -0
  60. package/src/components/ui/autocomplete/index.ts +2 -0
  61. package/src/components/ui/avatar/Avatar.stories.tsx +105 -0
  62. package/src/components/ui/avatar/Avatar.test.tsx +152 -0
  63. package/src/components/ui/avatar/Avatar.tsx +176 -0
  64. package/src/components/ui/avatar/index.ts +2 -0
  65. package/src/components/ui/badge/Badge.stories.tsx +100 -0
  66. package/src/components/ui/badge/Badge.test.tsx +103 -0
  67. package/src/components/ui/badge/Badge.tsx +119 -0
  68. package/src/components/ui/badge/index.ts +3 -0
  69. package/src/components/ui/breadcrumbs/Breadcrumbs.stories.tsx +70 -0
  70. package/src/components/ui/breadcrumbs/Breadcrumbs.test.tsx +156 -0
  71. package/src/components/ui/breadcrumbs/Breadcrumbs.tsx +127 -0
  72. package/src/components/ui/breadcrumbs/index.ts +2 -0
  73. package/src/components/ui/button/Button.stories.tsx +216 -0
  74. package/src/components/ui/button/Button.test.tsx +132 -0
  75. package/src/components/ui/button/Button.tsx +297 -0
  76. package/src/components/ui/button/index.ts +10 -0
  77. package/src/components/ui/card/Card.stories.tsx +443 -0
  78. package/src/components/ui/card/Card.test.tsx +294 -0
  79. package/src/components/ui/card/Card.tsx +401 -0
  80. package/src/components/ui/card/index.ts +20 -0
  81. package/src/components/ui/checkbox/Checkbox.stories.tsx +126 -0
  82. package/src/components/ui/checkbox/Checkbox.test.tsx +152 -0
  83. package/src/components/ui/checkbox/Checkbox.tsx +163 -0
  84. package/src/components/ui/checkbox/index.ts +2 -0
  85. package/src/components/ui/chip/Chip.stories.tsx +112 -0
  86. package/src/components/ui/chip/Chip.test.tsx +119 -0
  87. package/src/components/ui/chip/Chip.tsx +151 -0
  88. package/src/components/ui/chip/index.ts +2 -0
  89. package/src/components/ui/collapse/Collapse.stories.tsx +313 -0
  90. package/src/components/ui/collapse/Collapse.test.tsx +298 -0
  91. package/src/components/ui/collapse/Collapse.tsx +275 -0
  92. package/src/components/ui/collapse/index.ts +18 -0
  93. package/src/components/ui/data-row/DataRow.stories.tsx +78 -0
  94. package/src/components/ui/data-row/DataRow.test.tsx +78 -0
  95. package/src/components/ui/data-row/DataRow.tsx +29 -0
  96. package/src/components/ui/data-row/index.ts +2 -0
  97. package/src/components/ui/divider/Divider.stories.tsx +71 -0
  98. package/src/components/ui/divider/Divider.test.tsx +55 -0
  99. package/src/components/ui/divider/Divider.tsx +37 -0
  100. package/src/components/ui/divider/index.ts +2 -0
  101. package/src/components/ui/drawer/Drawer.stories.tsx +228 -0
  102. package/src/components/ui/drawer/Drawer.test.tsx +142 -0
  103. package/src/components/ui/drawer/Drawer.tsx +228 -0
  104. package/src/components/ui/drawer/index.ts +9 -0
  105. package/src/components/ui/form-field/FormField.stories.tsx +260 -0
  106. package/src/components/ui/form-field/FormField.test.tsx +280 -0
  107. package/src/components/ui/form-field/FormField.tsx +308 -0
  108. package/src/components/ui/form-field/index.ts +2 -0
  109. package/src/components/ui/help-tip/HelpTip.stories.tsx +250 -0
  110. package/src/components/ui/help-tip/HelpTip.test.tsx +198 -0
  111. package/src/components/ui/help-tip/HelpTip.tsx +229 -0
  112. package/src/components/ui/help-tip/index.ts +2 -0
  113. package/src/components/ui/icon-box/IconBox.stories.tsx +139 -0
  114. package/src/components/ui/icon-box/IconBox.test.tsx +120 -0
  115. package/src/components/ui/icon-box/IconBox.tsx +57 -0
  116. package/src/components/ui/icon-box/index.ts +1 -0
  117. package/src/components/ui/index.ts +38 -0
  118. package/src/components/ui/indicator/Indicator.stories.tsx +74 -0
  119. package/src/components/ui/indicator/Indicator.test.tsx +55 -0
  120. package/src/components/ui/indicator/Indicator.tsx +73 -0
  121. package/src/components/ui/indicator/index.ts +2 -0
  122. package/src/components/ui/input/Input.stories.tsx +192 -0
  123. package/src/components/ui/input/Input.test.tsx +86 -0
  124. package/src/components/ui/input/Input.tsx +273 -0
  125. package/src/components/ui/input/index.ts +2 -0
  126. package/src/components/ui/link/Link.stories.tsx +78 -0
  127. package/src/components/ui/link/Link.test.tsx +94 -0
  128. package/src/components/ui/link/Link.tsx +86 -0
  129. package/src/components/ui/link/index.ts +2 -0
  130. package/src/components/ui/list-item/ListItem.stories.tsx +146 -0
  131. package/src/components/ui/list-item/ListItem.test.tsx +128 -0
  132. package/src/components/ui/list-item/ListItem.tsx +89 -0
  133. package/src/components/ui/list-item/index.ts +14 -0
  134. package/src/components/ui/menu/Menu.stories.tsx +180 -0
  135. package/src/components/ui/menu/Menu.test.tsx +353 -0
  136. package/src/components/ui/menu/Menu.tsx +222 -0
  137. package/src/components/ui/menu/index.ts +2 -0
  138. package/src/components/ui/modal/Modal.stories.tsx +350 -0
  139. package/src/components/ui/modal/Modal.test.tsx +159 -0
  140. package/src/components/ui/modal/Modal.tsx +254 -0
  141. package/src/components/ui/modal/index.ts +19 -0
  142. package/src/components/ui/pill/Pill.stories.tsx +71 -0
  143. package/src/components/ui/pill/Pill.test.tsx +69 -0
  144. package/src/components/ui/pill/Pill.tsx +104 -0
  145. package/src/components/ui/pill/index.ts +2 -0
  146. package/src/components/ui/popover/Popover.stories.tsx +190 -0
  147. package/src/components/ui/popover/Popover.test.tsx +419 -0
  148. package/src/components/ui/popover/Popover.tsx +237 -0
  149. package/src/components/ui/popover/index.ts +2 -0
  150. package/src/components/ui/progress/Progress.stories.tsx +190 -0
  151. package/src/components/ui/progress/Progress.test.tsx +210 -0
  152. package/src/components/ui/progress/Progress.tsx +339 -0
  153. package/src/components/ui/progress/index.ts +9 -0
  154. package/src/components/ui/radio/Radio.stories.tsx +199 -0
  155. package/src/components/ui/radio/Radio.test.tsx +166 -0
  156. package/src/components/ui/radio/Radio.tsx +200 -0
  157. package/src/components/ui/radio/index.ts +2 -0
  158. package/src/components/ui/section/Section.stories.tsx +111 -0
  159. package/src/components/ui/section/Section.test.tsx +121 -0
  160. package/src/components/ui/section/Section.tsx +52 -0
  161. package/src/components/ui/section/index.ts +6 -0
  162. package/src/components/ui/select/Select.stories.tsx +286 -0
  163. package/src/components/ui/select/Select.test.tsx +200 -0
  164. package/src/components/ui/select/Select.tsx +243 -0
  165. package/src/components/ui/select/index.ts +2 -0
  166. package/src/components/ui/skeleton/Skeleton.stories.tsx +153 -0
  167. package/src/components/ui/skeleton/Skeleton.test.tsx +162 -0
  168. package/src/components/ui/skeleton/Skeleton.tsx +229 -0
  169. package/src/components/ui/skeleton/index.ts +16 -0
  170. package/src/components/ui/spinner/Spinner.stories.tsx +67 -0
  171. package/src/components/ui/spinner/Spinner.test.tsx +67 -0
  172. package/src/components/ui/spinner/Spinner.tsx +72 -0
  173. package/src/components/ui/spinner/index.ts +2 -0
  174. package/src/components/ui/stack/Stack.stories.tsx +127 -0
  175. package/src/components/ui/stack/Stack.test.tsx +184 -0
  176. package/src/components/ui/stack/Stack.tsx +76 -0
  177. package/src/components/ui/stack/index.ts +2 -0
  178. package/src/components/ui/surface/Surface.stories.tsx +91 -0
  179. package/src/components/ui/surface/Surface.test.tsx +63 -0
  180. package/src/components/ui/surface/Surface.tsx +51 -0
  181. package/src/components/ui/surface/index.ts +1 -0
  182. package/src/components/ui/switch/Switch.stories.tsx +111 -0
  183. package/src/components/ui/switch/Switch.test.tsx +112 -0
  184. package/src/components/ui/switch/Switch.tsx +103 -0
  185. package/src/components/ui/switch/index.ts +2 -0
  186. package/src/components/ui/tabs/Tabs.stories.tsx +213 -0
  187. package/src/components/ui/tabs/Tabs.test.tsx +192 -0
  188. package/src/components/ui/tabs/Tabs.tsx +253 -0
  189. package/src/components/ui/tabs/index.ts +16 -0
  190. package/src/components/ui/toast/Toast.stories.tsx +255 -0
  191. package/src/components/ui/toast/Toast.test.tsx +207 -0
  192. package/src/components/ui/toast/Toast.tsx +327 -0
  193. package/src/components/ui/toast/index.ts +9 -0
  194. package/src/components/ui/toolbar-button/ToolbarButton.stories.tsx +415 -0
  195. package/src/components/ui/toolbar-button/ToolbarButton.test.tsx +224 -0
  196. package/src/components/ui/toolbar-button/ToolbarButton.tsx +307 -0
  197. package/src/components/ui/toolbar-button/index.ts +7 -0
  198. package/src/components/ui/tooltip/Tooltip.stories.tsx +126 -0
  199. package/src/components/ui/tooltip/Tooltip.test.tsx +262 -0
  200. package/src/components/ui/tooltip/Tooltip.tsx +234 -0
  201. package/src/components/ui/tooltip/index.ts +2 -0
  202. package/src/index.ts +10 -0
  203. package/src/stories/PresetShowcase.stories.tsx +462 -0
  204. package/src/stories/ThemePresets.stories.tsx +85 -0
  205. package/src/test/setup.ts +19 -0
  206. package/src/theme/Colors.stories.tsx +258 -0
  207. package/src/theme/config.ts +193 -0
  208. package/src/theme/elevation.stories.tsx +346 -0
  209. package/src/theme/elevation.test.ts +27 -0
  210. package/src/theme/elevation.ts +567 -0
  211. package/src/theme/global.css +129 -1
  212. package/src/theme/index.ts +40 -0
  213. package/src/theme/presets/apply.ts +97 -0
  214. package/src/theme/presets/audiobook.ts +93 -0
  215. package/src/theme/presets/default.ts +6 -0
  216. package/src/theme/presets/index.ts +4 -0
  217. package/src/theme/presets/presets.test.ts +51 -0
  218. package/src/theme/presets/types.ts +76 -0
  219. package/src/theme/shadows.stories.tsx +523 -0
  220. package/src/theme/shadows.ts +439 -0
  221. package/src/theme/tokens/index.ts +2 -0
  222. package/src/theme/tokens/primitives.ts +354 -0
  223. package/src/theme/tokens/semantic.ts +381 -0
  224. package/src/types/jest-axe.d.ts +16 -0
  225. package/src/types/nativewind.d.ts +54 -0
  226. package/src/utils/avatar-color.test.ts +30 -0
  227. package/src/utils/avatar-color.ts +20 -0
  228. package/src/utils/cn.ts +14 -0
  229. package/src/utils/colors.ts +140 -0
  230. package/src/utils/form.ts +188 -0
  231. package/src/utils/index.ts +29 -0
  232. package/src/utils/useTheme.ts +72 -0
  233. package/src/web-jsx/jsx-dev-runtime.ts +28 -0
  234. package/src/web-jsx/jsx-runtime.ts +41 -0
  235. package/tailwind.config.js +53 -3
  236. package/dist/chunk-MGW37MPO.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,14 +1,33 @@
1
- import { semanticColorsDark, getHoverColors, getValidatedElevation, getBaseSurfaceColor, getElevationSurface, getElevationShadow, getGlowShadow, neumorphicShadows } from './chunk-MGW37MPO.mjs';
2
- export { buttonSizes, componentElevationRanges, createFlatShadow, createPressedHoverShadow, createPressedShadow, createRaisedHoverShadow, createRaisedShadow, darkThemeCSSVars, darken, discreteRainbow, elevationSystem, getBaseSurfaceColor, getDiscreteRainbowColor, getElevationConfig, getElevationShadow, getElevationSurface, getGlowShadow, getHoverColors, getSemanticColors, getThemeCSSVars, getValidatedElevation, gluestackConfig, hexToRgb, hsvToRgb, isDark, lightThemeCSSVars, lighten, neumorphicShadows, primitiveBorderRadius, primitiveBreakpoints, primitiveColors, primitiveShadows, primitiveSpacing, primitiveTypography, primitiveZIndex, rgbToHex, rgbToHsv, semanticColorsDark, semanticColorsLight, semanticTypography, shadowColors } from './chunk-MGW37MPO.mjs';
3
- import { Pressable, ActivityIndicator, Text, View, TextInput, StyleSheet, Platform, Image, Modal as Modal$1, ScrollView } from 'react-native';
1
+ import { semanticColorsDark, __require, getHoverColors, getValidatedElevation, getBaseSurfaceColor, getElevationSurface, getElevationShadow, getGlowShadow, neumorphicShadows } from './chunk-UXVRPOME.mjs';
2
+ export { applyThemePreset, audiobookPreset, buttonSizes, componentElevationRanges, createFlatShadow, createPressedHoverShadow, createPressedShadow, createRaisedHoverShadow, createRaisedShadow, darkThemeCSSVars, darken, defaultPreset, discreteRainbow, elevationSystem, getBaseSurfaceColor, getDiscreteRainbowColor, getElevationConfig, getElevationShadow, getElevationSurface, getGlowShadow, getHoverColors, getSemanticColors, getThemeCSSVars, getValidatedElevation, gluestackConfig, hexToRgb, hsvToRgb, isDark, lightThemeCSSVars, lighten, neumorphicShadows, primitiveBorderRadius, primitiveBreakpoints, primitiveColors, primitiveShadows, primitiveSpacing, primitiveTypography, primitiveZIndex, rgbToHex, rgbToHsv, semanticColorsDark, semanticColorsLight, semanticTypography, shadowColors } from './chunk-UXVRPOME.mjs';
3
+ import { Pressable, ActivityIndicator, Text, View, TextInput, Platform, StyleSheet, Image, Modal as Modal$1, ScrollView } from 'react-native';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
- import React24, { forwardRef, useState, createContext, useMemo, useContext, useRef, useCallback, useEffect, useSyncExternalStore } from 'react';
6
+ import { jsx as jsx$1, jsxs as jsxs$1, Fragment } from 'react/jsx-runtime';
7
+ import React24, { forwardRef, useState, createContext, useMemo, useContext, useRef, useEffect, useCallback, useSyncExternalStore } from 'react';
8
8
 
9
9
  function cn(...inputs) {
10
10
  return twMerge(clsx(inputs));
11
11
  }
12
+ function wrapJsx(fn) {
13
+ return function(type, props, ...rest) {
14
+ if (props && typeof props.className === "string" && props.className) {
15
+ const cn2 = props.className;
16
+ const cssStyle = { $$css: true, [cn2]: cn2 };
17
+ const existing = props.style;
18
+ props = {
19
+ ...props,
20
+ style: existing ? [cssStyle, existing] : cssStyle
21
+ };
22
+ delete props.className;
23
+ }
24
+ return fn(type, props, ...rest);
25
+ };
26
+ }
27
+ var jsx = wrapJsx(jsx$1);
28
+ var jsxs = wrapJsx(jsxs$1);
29
+
30
+ // src/components/ui/alert/Alert.tsx
12
31
  var statusColors = {
13
32
  success: {
14
33
  subtle: "bg-status-success-subtle",
@@ -99,6 +118,48 @@ function AlertTitle({ children, className }) {
99
118
  function AlertDescription({ children, className }) {
100
119
  return /* @__PURE__ */ jsx(Text, { className: cn("text-sm text-text-secondary", className), children });
101
120
  }
121
+ var textColorMap = {
122
+ solid: {
123
+ primary: "#FFFFFF",
124
+ secondary: "#FFFFFF",
125
+ success: "#FFFFFF",
126
+ error: "#FFFFFF",
127
+ warning: "#FFFFFF",
128
+ info: "#FFFFFF"
129
+ },
130
+ outline: {
131
+ primary: semanticColorsDark["brand-primary"],
132
+ secondary: semanticColorsDark["brand-secondary"],
133
+ success: semanticColorsDark["status-success"],
134
+ error: semanticColorsDark["status-error"],
135
+ warning: semanticColorsDark["status-warning"],
136
+ info: semanticColorsDark["status-info"]
137
+ },
138
+ ghost: {
139
+ primary: semanticColorsDark["brand-primary"],
140
+ secondary: semanticColorsDark["brand-secondary"],
141
+ success: semanticColorsDark["status-success"],
142
+ error: semanticColorsDark["status-error"],
143
+ warning: semanticColorsDark["status-warning"],
144
+ info: semanticColorsDark["status-info"]
145
+ },
146
+ link: {
147
+ primary: semanticColorsDark["brand-primary"],
148
+ secondary: semanticColorsDark["brand-secondary"],
149
+ success: semanticColorsDark["status-success"],
150
+ error: semanticColorsDark["status-error"],
151
+ warning: semanticColorsDark["status-warning"],
152
+ info: semanticColorsDark["status-info"]
153
+ }
154
+ };
155
+ var borderColorMap = {
156
+ primary: semanticColorsDark["brand-primary"],
157
+ secondary: semanticColorsDark["brand-secondary"],
158
+ success: semanticColorsDark["status-success"],
159
+ error: semanticColorsDark["status-error"],
160
+ warning: semanticColorsDark["status-warning"],
161
+ info: semanticColorsDark["status-info"]
162
+ };
102
163
  var variantStyles = {
103
164
  solid: {
104
165
  primary: "bg-brand-primary active:bg-brand-primary-dark active:scale-[0.98] web:hover:bg-brand-primary-dark web:active:scale-[0.98]",
@@ -196,6 +257,12 @@ var Button = forwardRef(function Button2({
196
257
  ...props
197
258
  }, ref) {
198
259
  const disabled = isDisabled || isLoading;
260
+ const inlineStyle = {
261
+ color: textColorMap[variant][color]
262
+ };
263
+ if (variant === "outline") {
264
+ inlineStyle.borderColor = borderColorMap[color];
265
+ }
199
266
  return /* @__PURE__ */ jsxs(
200
267
  Pressable,
201
268
  {
@@ -218,6 +285,7 @@ var Button = forwardRef(function Button2({
218
285
  variant === "link" && "px-0 py-0 min-h-0",
219
286
  className
220
287
  ),
288
+ style: inlineStyle,
221
289
  ...props,
222
290
  children: [
223
291
  isLoading && /* @__PURE__ */ jsx(
@@ -236,6 +304,7 @@ var Button = forwardRef(function Button2({
236
304
  textSizeStyles[size],
237
305
  textStyles[variant][color]
238
306
  ),
307
+ style: { color: textColorMap[variant][color] },
239
308
  children: loadingText
240
309
  }
241
310
  ) : children
@@ -437,13 +506,17 @@ function getServerSnapshot() {
437
506
  function useTheme() {
438
507
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
439
508
  }
509
+
510
+ // src/components/ui/card/Card.tsx
440
511
  var variantStyles3 = {
441
512
  elevated: "",
442
513
  // Will be set dynamically via elevation system
443
514
  outline: "border-2 border-border-strong",
444
515
  // Thicker border with stronger contrast
445
- filled: ""
516
+ filled: "",
446
517
  // Will be set dynamically via elevation system
518
+ accent: "border border-border-default",
519
+ subtle: "border border-border-subtle"
447
520
  };
448
521
  function Card({
449
522
  variant = "elevated",
@@ -453,6 +526,8 @@ function Card({
453
526
  onPress,
454
527
  borderColor,
455
528
  bgColor,
529
+ accentColor,
530
+ accentWidth,
456
531
  className,
457
532
  children,
458
533
  style,
@@ -466,16 +541,19 @@ function Card({
466
541
  const theme = useTheme();
467
542
  const elevationLevel = useMemo(() => {
468
543
  const validated = getValidatedElevation("card", elevation);
469
- if (variant === "outline") {
544
+ if (variant === "outline" || variant === "accent" || variant === "subtle") {
470
545
  return 1;
471
546
  }
472
547
  return validated;
473
548
  }, [variant, elevation]);
474
549
  const baseColor = useMemo(() => getBaseSurfaceColor(theme), [theme]);
475
550
  const surfaceColor = useMemo(() => {
476
- if (variant === "outline" && theme === "light") {
551
+ if ((variant === "outline" || variant === "accent") && theme === "light") {
477
552
  return "#FAFAFA";
478
553
  }
554
+ if (variant === "subtle") {
555
+ return getElevationSurface(baseColor, 0, theme);
556
+ }
479
557
  return getElevationSurface(baseColor, elevationLevel, theme);
480
558
  }, [baseColor, elevationLevel, theme, variant]);
481
559
  const shadowStyle = useMemo(() => {
@@ -509,17 +587,24 @@ function Card({
509
587
  isLoading && "pointer-events-none animate-pulse",
510
588
  className
511
589
  );
590
+ const accentStyle = useMemo(() => variant === "accent" ? {
591
+ borderLeftWidth: accentWidth ?? 3,
592
+ borderLeftColor: accentColor ?? "var(--color-brand-primary)"
593
+ } : {}, [variant, accentWidth, accentColor]);
512
594
  const mergedStyle = useMemo(() => {
513
595
  const elevationStyle = {
514
596
  backgroundColor: bgColor || surfaceColor,
515
- ...shadowStyle
597
+ borderRadius: 8,
598
+ overflow: "hidden",
599
+ ...shadowStyle,
600
+ ...accentStyle
516
601
  };
517
602
  if (borderColor) {
518
603
  elevationStyle.borderColor = borderColor;
519
604
  }
520
605
  if (!style) return elevationStyle;
521
- return [style, elevationStyle];
522
- }, [style, surfaceColor, shadowStyle, borderColor, bgColor]);
606
+ return [elevationStyle, style];
607
+ }, [style, surfaceColor, shadowStyle, borderColor, bgColor, accentStyle]);
523
608
  if (isClickable) {
524
609
  return /* @__PURE__ */ jsx(
525
610
  Pressable,
@@ -583,6 +668,57 @@ function CardSkeleton({
583
668
  hasFooter && /* @__PURE__ */ jsx(CardFooter, { children: /* @__PURE__ */ jsx(View, { className: "h-9 w-24 bg-interactive-disabled rounded" }) })
584
669
  ] });
585
670
  }
671
+ var sizeStyles3 = {
672
+ xs: "w-1 h-1",
673
+ sm: "w-1.5 h-1.5",
674
+ md: "w-2 h-2",
675
+ lg: "w-2.5 h-2.5"
676
+ };
677
+ var colorStyles = {
678
+ default: "bg-text-tertiary",
679
+ primary: "bg-brand-primary",
680
+ success: "bg-status-success",
681
+ error: "bg-status-error",
682
+ warning: "bg-status-warning",
683
+ info: "bg-status-info"
684
+ };
685
+ function Indicator({
686
+ size = "sm",
687
+ color = "default",
688
+ customColor,
689
+ glow = false,
690
+ ring = false,
691
+ className,
692
+ style,
693
+ ...props
694
+ }) {
695
+ const dynamicStyle = {
696
+ ...typeof style === "object" ? style : {},
697
+ ...customColor ? { backgroundColor: customColor } : {},
698
+ ...glow && !customColor ? {} : {},
699
+ ...glow && customColor ? { boxShadow: `0 0 6px ${customColor}` } : {}
700
+ };
701
+ return /* @__PURE__ */ jsx(
702
+ View,
703
+ {
704
+ className: cn(
705
+ "rounded-full shrink-0",
706
+ sizeStyles3[size],
707
+ !customColor && colorStyles[color],
708
+ ring && "border-2 border-background-base",
709
+ glow && !customColor && color === "success" && "shadow-[0_0_6px_rgba(20,184,166,0.6)]",
710
+ glow && !customColor && color === "error" && "shadow-[0_0_6px_rgba(239,68,68,0.6)]",
711
+ glow && !customColor && color === "warning" && "shadow-[0_0_6px_rgba(245,158,11,0.6)]",
712
+ glow && !customColor && color === "primary" && "shadow-[0_0_6px_rgba(255,121,0,0.6)]",
713
+ className
714
+ ),
715
+ style: Object.keys(dynamicStyle).length > 0 ? dynamicStyle : style,
716
+ ...props
717
+ }
718
+ );
719
+ }
720
+
721
+ // src/components/ui/badge/Badge.tsx
586
722
  var variantColorStyles = {
587
723
  solid: {
588
724
  default: "bg-border-strong text-text-inverse",
@@ -612,7 +748,7 @@ var variantColorStyles = {
612
748
  info: "border border-status-info text-status-info"
613
749
  }
614
750
  };
615
- var sizeStyles3 = {
751
+ var sizeStyles4 = {
616
752
  sm: "px-1.5 py-0.5 text-xs",
617
753
  md: "px-2 py-0.5 text-xs",
618
754
  lg: "px-2.5 py-1 text-sm"
@@ -621,21 +757,33 @@ function Badge({
621
757
  variant = "subtle",
622
758
  color = "default",
623
759
  size = "md",
760
+ dot,
761
+ dotColor,
624
762
  className,
625
763
  children,
626
764
  ...props
627
765
  }) {
628
- return /* @__PURE__ */ jsx(
766
+ return /* @__PURE__ */ jsxs(
629
767
  View,
630
768
  {
631
769
  className: cn(
632
770
  "inline-flex items-center justify-center rounded-full font-medium",
633
771
  variantColorStyles[variant][color],
634
- sizeStyles3[size],
772
+ sizeStyles4[size],
635
773
  className
636
774
  ),
637
775
  ...props,
638
- children: typeof children === "string" ? /* @__PURE__ */ jsx(Text, { className: "text-inherit font-medium", children }) : children
776
+ children: [
777
+ dot && /* @__PURE__ */ jsx(
778
+ Indicator,
779
+ {
780
+ size: "xs",
781
+ color: dotColor ?? (color === "default" || color === "secondary" ? "default" : color),
782
+ className: "mr-0.5"
783
+ }
784
+ ),
785
+ typeof children === "string" ? /* @__PURE__ */ jsx(Text, { className: "text-inherit font-medium", children }) : children
786
+ ]
639
787
  }
640
788
  );
641
789
  }
@@ -684,7 +832,33 @@ function Spinner({
684
832
  }
685
833
  );
686
834
  }
687
- var sizeStyles4 = {
835
+
836
+ // src/utils/avatar-color.ts
837
+ var AVATAR_COLORS = [
838
+ "#FF6B6B",
839
+ "#4ECDC4",
840
+ "#45B7D1",
841
+ "#96CEB4",
842
+ "#FFEAA7",
843
+ "#DDA0DD",
844
+ "#98D8C8"
845
+ ];
846
+ function avatarColor(name) {
847
+ let hash = 0;
848
+ for (let i = 0; i < name.length; i++) {
849
+ hash = name.charCodeAt(i) + ((hash << 5) - hash);
850
+ }
851
+ return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
852
+ }
853
+ function getInitials(name) {
854
+ const parts = name.trim().split(/\s+/);
855
+ if (parts.length === 0) return "?";
856
+ if (parts.length === 1) return parts[0][0]?.toUpperCase() ?? "?";
857
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
858
+ }
859
+
860
+ // src/components/ui/avatar/Avatar.tsx
861
+ var sizeStyles5 = {
688
862
  xs: { container: "w-6 h-6", text: "text-xs", image: "w-6 h-6" },
689
863
  sm: { container: "w-8 h-8", text: "text-xs", image: "w-8 h-8" },
690
864
  md: { container: "w-10 h-10", text: "text-sm", image: "w-10 h-10" },
@@ -697,22 +871,26 @@ function Avatar({
697
871
  source,
698
872
  fallback,
699
873
  alt,
874
+ colorFromName,
700
875
  className,
701
876
  ...props
702
877
  }) {
703
- const styles2 = sizeStyles4[size];
878
+ const styles2 = sizeStyles5[size];
704
879
  const hasImage = source !== void 0;
880
+ const resolvedFallback = fallback ?? (colorFromName ? getInitials(colorFromName) : void 0);
881
+ const nameColor = colorFromName ? avatarColor(colorFromName) : void 0;
705
882
  return /* @__PURE__ */ jsx(
706
883
  View,
707
884
  {
708
885
  accessibilityRole: "image",
709
- accessibilityLabel: alt || fallback || "Avatar",
886
+ accessibilityLabel: alt || resolvedFallback || "Avatar",
710
887
  className: cn(
711
888
  "items-center justify-center rounded-full overflow-hidden",
712
- "bg-border-strong",
889
+ !nameColor && "bg-border-strong",
713
890
  styles2.container,
714
891
  className
715
892
  ),
893
+ style: nameColor ? { backgroundColor: nameColor } : void 0,
716
894
  ...props,
717
895
  children: hasImage ? /* @__PURE__ */ jsx(
718
896
  Image,
@@ -721,7 +899,7 @@ function Avatar({
721
899
  className: cn("rounded-full", styles2.image),
722
900
  accessibilityLabel: alt
723
901
  }
724
- ) : fallback ? /* @__PURE__ */ jsx(Text, { className: cn("font-semibold text-text-primary", styles2.text), children: fallback }) : /* @__PURE__ */ jsx(View, { className: "w-full h-full bg-surface-raised" })
902
+ ) : resolvedFallback ? /* @__PURE__ */ jsx(Text, { className: cn("font-semibold text-text-inverse", styles2.text), children: resolvedFallback }) : /* @__PURE__ */ jsx(View, { className: "w-full h-full bg-surface-raised" })
725
903
  }
726
904
  );
727
905
  }
@@ -770,9 +948,9 @@ function AvatarGroup({
770
948
  className: cn(
771
949
  "border-2 border-surface-base rounded-full -ml-2",
772
950
  "items-center justify-center bg-surface-raised",
773
- sizeStyles4[size].container
951
+ sizeStyles5[size].container
774
952
  ),
775
- children: /* @__PURE__ */ jsxs(Text, { className: cn("font-semibold text-text-secondary", sizeStyles4[size].text), children: [
953
+ children: /* @__PURE__ */ jsxs(Text, { className: cn("font-semibold text-text-secondary", sizeStyles5[size].text), children: [
776
954
  "+",
777
955
  remainingCount
778
956
  ] })
@@ -798,7 +976,7 @@ function Divider({
798
976
  }
799
977
  );
800
978
  }
801
- var sizeStyles5 = {
979
+ var sizeStyles6 = {
802
980
  sm: { box: "w-4 h-4", icon: "w-2.5 h-2.5", label: "text-sm" },
803
981
  md: { box: "w-5 h-5", icon: "w-3 h-3", label: "text-base" },
804
982
  lg: { box: "w-6 h-6", icon: "w-3.5 h-3.5", label: "text-lg" }
@@ -816,7 +994,7 @@ var Checkbox = forwardRef(function Checkbox2({
816
994
  className,
817
995
  ...props
818
996
  }, ref) {
819
- const styles2 = sizeStyles5[size];
997
+ const styles2 = sizeStyles6[size];
820
998
  const handlePress = () => {
821
999
  if (!isDisabled) {
822
1000
  onCheckedChange?.(!isChecked);
@@ -884,7 +1062,7 @@ function CheckboxGroup({
884
1062
  )
885
1063
  ] });
886
1064
  }
887
- var sizeStyles6 = {
1065
+ var sizeStyles7 = {
888
1066
  sm: { track: "w-8 h-4", thumb: "w-3 h-3", translate: "translate-x-4" },
889
1067
  md: { track: "w-10 h-5", thumb: "w-4 h-4", translate: "translate-x-5" },
890
1068
  lg: { track: "w-12 h-6", thumb: "w-5 h-5", translate: "translate-x-6" }
@@ -899,7 +1077,7 @@ var Switch = forwardRef(function Switch2({
899
1077
  className,
900
1078
  ...props
901
1079
  }, ref) {
902
- const styles2 = sizeStyles6[size];
1080
+ const styles2 = sizeStyles7[size];
903
1081
  const handlePress = () => {
904
1082
  if (!isDisabled) {
905
1083
  onCheckedChange?.(!isChecked);
@@ -949,7 +1127,7 @@ var Switch = forwardRef(function Switch2({
949
1127
  );
950
1128
  });
951
1129
  var ModalContext = createContext({ size: "md", scrollBehavior: "outside" });
952
- var sizeStyles7 = {
1130
+ var sizeStyles8 = {
953
1131
  xs: "max-w-xs",
954
1132
  sm: "max-w-sm",
955
1133
  md: "max-w-md",
@@ -1016,7 +1194,7 @@ function ModalContent({ children, className }) {
1016
1194
  {
1017
1195
  className: cn(
1018
1196
  "bg-surface-elevated rounded-lg shadow-xl w-full",
1019
- sizeStyles7[size],
1197
+ sizeStyles8[size],
1020
1198
  className
1021
1199
  ),
1022
1200
  children
@@ -1326,7 +1504,7 @@ function TabPanels({ children, className }) {
1326
1504
  function TabPanel({ children, className }) {
1327
1505
  return /* @__PURE__ */ jsx(View, { className: cn("py-4", className), children });
1328
1506
  }
1329
- var colorStyles = {
1507
+ var colorStyles2 = {
1330
1508
  default: {
1331
1509
  solid: "bg-neutral-600 text-white",
1332
1510
  subtle: "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-200",
@@ -1363,7 +1541,7 @@ var colorStyles = {
1363
1541
  outline: "border border-status-info text-status-info"
1364
1542
  }
1365
1543
  };
1366
- var sizeStyles8 = {
1544
+ var sizeStyles9 = {
1367
1545
  sm: { container: "px-2 py-0.5 rounded", text: "text-xs", deleteButton: "ml-1 -mr-0.5" },
1368
1546
  md: { container: "px-3 py-1 rounded-md", text: "text-sm", deleteButton: "ml-1.5 -mr-1" },
1369
1547
  lg: { container: "px-4 py-1.5 rounded-md", text: "text-base", deleteButton: "ml-2 -mr-1" }
@@ -1380,7 +1558,7 @@ function Chip({
1380
1558
  children,
1381
1559
  ...props
1382
1560
  }) {
1383
- const sizes = sizeStyles8[size];
1561
+ const sizes = sizeStyles9[size];
1384
1562
  const isClickable = !!onPress;
1385
1563
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [
1386
1564
  leftElement && /* @__PURE__ */ jsx(View, { className: "mr-1.5", children: leftElement }),
@@ -1406,7 +1584,7 @@ function Chip({
1406
1584
  const baseClassName = cn(
1407
1585
  "flex-row items-center",
1408
1586
  sizes.container,
1409
- colorStyles[color][variant],
1587
+ colorStyles2[color][variant],
1410
1588
  isClickable && "web:cursor-pointer web:hover:opacity-80 active:opacity-70",
1411
1589
  isDisabled && "opacity-50 cursor-not-allowed",
1412
1590
  className
@@ -1426,7 +1604,7 @@ function Chip({
1426
1604
  }
1427
1605
  return /* @__PURE__ */ jsx(View, { className: baseClassName, ...props, children: content });
1428
1606
  }
1429
- var colorStyles2 = {
1607
+ var colorStyles3 = {
1430
1608
  default: "text-text-link",
1431
1609
  primary: "text-brand-primary",
1432
1610
  secondary: "text-brand-secondary",
@@ -1464,7 +1642,7 @@ function Link({
1464
1642
  {
1465
1643
  className: cn(
1466
1644
  "font-medium",
1467
- colorStyles2[color],
1645
+ colorStyles3[color],
1468
1646
  underlineStyles[underline],
1469
1647
  isDisabled && "opacity-50 cursor-not-allowed",
1470
1648
  "web:cursor-pointer active:opacity-70",
@@ -1480,8 +1658,16 @@ function Link({
1480
1658
  }
1481
1659
  );
1482
1660
  }
1661
+ var createPortal;
1662
+ if (Platform.OS === "web") {
1663
+ try {
1664
+ createPortal = __require("react-dom").createPortal;
1665
+ } catch {
1666
+ }
1667
+ }
1483
1668
  function Tooltip({
1484
1669
  label,
1670
+ content,
1485
1671
  children,
1486
1672
  placement = "top",
1487
1673
  openDelay = 0,
@@ -1489,11 +1675,48 @@ function Tooltip({
1489
1675
  hasArrow = true,
1490
1676
  isDisabled = false,
1491
1677
  className,
1678
+ usePortal: usePortalProp = false,
1492
1679
  ...props
1493
1680
  }) {
1494
1681
  const [isVisible, setIsVisible] = useState(false);
1682
+ const [portalPos, setPortalPos] = useState(null);
1495
1683
  const openTimeoutRef = useRef(null);
1496
1684
  const closeTimeoutRef = useRef(null);
1685
+ const triggerRef = useRef(null);
1686
+ const isPortalMode = usePortalProp && Platform.OS === "web" && !!createPortal;
1687
+ useEffect(() => {
1688
+ if (!isVisible || !isPortalMode || !triggerRef.current) return;
1689
+ const node = triggerRef.current;
1690
+ const id = requestAnimationFrame(() => {
1691
+ const rect = node.getBoundingClientRect();
1692
+ const gap = 8;
1693
+ const cardinal = placement.split("-")[0];
1694
+ const positions = {
1695
+ top: {
1696
+ top: rect.top - gap,
1697
+ left: rect.left + rect.width / 2,
1698
+ transform: "translate(-50%, -100%)"
1699
+ },
1700
+ bottom: {
1701
+ top: rect.bottom + gap,
1702
+ left: rect.left + rect.width / 2,
1703
+ transform: "translate(-50%, 0%)"
1704
+ },
1705
+ left: {
1706
+ top: rect.top + rect.height / 2,
1707
+ left: rect.left - gap,
1708
+ transform: "translate(-100%, -50%)"
1709
+ },
1710
+ right: {
1711
+ top: rect.top + rect.height / 2,
1712
+ left: rect.right + gap,
1713
+ transform: "translate(0%, -50%)"
1714
+ }
1715
+ };
1716
+ setPortalPos(positions[cardinal] ?? positions.top);
1717
+ });
1718
+ return () => cancelAnimationFrame(id);
1719
+ }, [isVisible, isPortalMode, placement]);
1497
1720
  const clearTimeouts = () => {
1498
1721
  if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);
1499
1722
  if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);
@@ -1535,7 +1758,41 @@ function Tooltip({
1535
1758
  left: "right-full top-1/2 -translate-y-1/2 mr-2",
1536
1759
  right: "left-full top-1/2 -translate-y-1/2 ml-2"
1537
1760
  };
1538
- return /* @__PURE__ */ jsxs(View, { className: "relative", ...props, children: [
1761
+ const tooltipContent = /* @__PURE__ */ jsxs(View, { className: "bg-neutral-800 px-3 py-2 rounded-md shadow-lg max-w-xs", children: [
1762
+ content ?? /* @__PURE__ */ jsx(Text, { className: "text-white text-sm", children: label }),
1763
+ hasArrow && /* @__PURE__ */ jsx(
1764
+ View,
1765
+ {
1766
+ className: cn(
1767
+ "absolute w-0 h-0 border-4",
1768
+ arrowStyles2[placement]
1769
+ )
1770
+ }
1771
+ )
1772
+ ] });
1773
+ const renderPortalTooltip = () => {
1774
+ if (!isVisible || !isPortalMode || !createPortal) return null;
1775
+ return createPortal(
1776
+ /* @__PURE__ */ jsx(
1777
+ "div",
1778
+ {
1779
+ style: {
1780
+ position: "fixed",
1781
+ top: portalPos?.top ?? 0,
1782
+ left: portalPos?.left ?? 0,
1783
+ transform: portalPos?.transform ?? "translate(-50%, -100%)",
1784
+ zIndex: 1e4,
1785
+ pointerEvents: "none"
1786
+ },
1787
+ "data-testid": "tooltip-portal",
1788
+ className,
1789
+ children: tooltipContent
1790
+ }
1791
+ ),
1792
+ document.body
1793
+ );
1794
+ };
1795
+ return /* @__PURE__ */ jsxs(View, { className: "relative", ref: triggerRef, ...props, children: [
1539
1796
  /* @__PURE__ */ jsx(
1540
1797
  Pressable,
1541
1798
  {
@@ -1547,27 +1804,16 @@ function Tooltip({
1547
1804
  children
1548
1805
  }
1549
1806
  ),
1550
- isVisible && /* @__PURE__ */ jsx(
1807
+ isPortalMode ? renderPortalTooltip() : isVisible && /* @__PURE__ */ jsx(
1551
1808
  View,
1552
1809
  {
1553
1810
  className: cn(
1554
- "absolute z-50",
1811
+ "absolute z-50 web:animate-fade-in",
1555
1812
  tooltipPositionStyles[placement],
1556
1813
  className
1557
1814
  ),
1558
1815
  pointerEvents: "none",
1559
- children: /* @__PURE__ */ jsxs(View, { className: "bg-neutral-800 px-3 py-2 rounded-md shadow-lg max-w-xs", children: [
1560
- /* @__PURE__ */ jsx(Text, { className: "text-white text-sm", children: label }),
1561
- hasArrow && /* @__PURE__ */ jsx(
1562
- View,
1563
- {
1564
- className: cn(
1565
- "absolute w-0 h-0 border-4",
1566
- arrowStyles2[placement]
1567
- )
1568
- }
1569
- )
1570
- ] })
1816
+ children: tooltipContent
1571
1817
  }
1572
1818
  )
1573
1819
  ] });
@@ -1774,29 +2020,64 @@ var PopoverContext = createContext({
1774
2020
  isOpen: false,
1775
2021
  setIsOpen: () => {
1776
2022
  },
1777
- placement: "bottom"
2023
+ placement: "bottom",
2024
+ triggerMode: "click",
2025
+ handleHoverIn: () => {
2026
+ },
2027
+ handleHoverOut: () => {
2028
+ }
1778
2029
  });
1779
2030
  function Popover({
1780
2031
  placement = "bottom",
1781
2032
  isOpen: controlledIsOpen,
1782
2033
  onOpenChange,
1783
2034
  closeOnClickOutside = true,
2035
+ triggerMode = "click",
2036
+ closeDelay = 150,
1784
2037
  className,
1785
2038
  children,
1786
2039
  ...props
1787
2040
  }) {
1788
2041
  const [internalIsOpen, setInternalIsOpen] = useState(false);
1789
2042
  const isOpen = controlledIsOpen ?? internalIsOpen;
1790
- const setIsOpen = (open) => {
2043
+ const closeTimerRef = useRef(null);
2044
+ const setIsOpen = useCallback((open) => {
1791
2045
  if (controlledIsOpen === void 0) {
1792
2046
  setInternalIsOpen(open);
1793
2047
  }
1794
2048
  onOpenChange?.(open);
1795
- };
1796
- return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { isOpen, setIsOpen, placement }, children: /* @__PURE__ */ jsx(View, { className: cn("relative", className), ...props, children }) });
2049
+ }, [controlledIsOpen, onOpenChange]);
2050
+ const handleHoverIn = useCallback(() => {
2051
+ if (triggerMode !== "hover") return;
2052
+ if (closeTimerRef.current) {
2053
+ clearTimeout(closeTimerRef.current);
2054
+ closeTimerRef.current = null;
2055
+ }
2056
+ setIsOpen(true);
2057
+ }, [triggerMode, setIsOpen]);
2058
+ const handleHoverOut = useCallback(() => {
2059
+ if (triggerMode !== "hover") return;
2060
+ closeTimerRef.current = setTimeout(() => {
2061
+ setIsOpen(false);
2062
+ closeTimerRef.current = null;
2063
+ }, closeDelay);
2064
+ }, [triggerMode, closeDelay, setIsOpen]);
2065
+ return /* @__PURE__ */ jsx(
2066
+ PopoverContext.Provider,
2067
+ {
2068
+ value: { isOpen, setIsOpen, placement, triggerMode, handleHoverIn, handleHoverOut },
2069
+ children: /* @__PURE__ */ jsx(View, { className: cn("relative", className), ...props, children })
2070
+ }
2071
+ );
1797
2072
  }
1798
2073
  function PopoverTrigger({ children, className }) {
1799
- const { isOpen, setIsOpen } = useContext(PopoverContext);
2074
+ const { isOpen, setIsOpen, triggerMode, handleHoverIn, handleHoverOut } = useContext(PopoverContext);
2075
+ const hoverProps = triggerMode === "hover" ? {
2076
+ onHoverIn: handleHoverIn,
2077
+ onHoverOut: handleHoverOut,
2078
+ onMouseEnter: handleHoverIn,
2079
+ onMouseLeave: handleHoverOut
2080
+ } : {};
1800
2081
  return /* @__PURE__ */ jsx(
1801
2082
  Pressable,
1802
2083
  {
@@ -1804,12 +2085,19 @@ function PopoverTrigger({ children, className }) {
1804
2085
  accessibilityRole: "button",
1805
2086
  accessibilityState: { expanded: isOpen },
1806
2087
  className,
2088
+ ...hoverProps,
1807
2089
  children
1808
2090
  }
1809
2091
  );
1810
2092
  }
2093
+ var SPACER_STYLES = {
2094
+ top: { left: 0, right: 0, bottom: 0, height: 8, transform: "translateY(100%)" },
2095
+ bottom: { left: 0, right: 0, top: 0, height: 8, transform: "translateY(-100%)" },
2096
+ left: { top: 0, bottom: 0, right: 0, width: 8, transform: "translateX(100%)" },
2097
+ right: { top: 0, bottom: 0, left: 0, width: 8, transform: "translateX(-100%)" }
2098
+ };
1811
2099
  function PopoverContent({ children, className }) {
1812
- const { isOpen, setIsOpen, placement } = useContext(PopoverContext);
2100
+ const { isOpen, setIsOpen, placement, triggerMode, handleHoverIn, handleHoverOut } = useContext(PopoverContext);
1813
2101
  if (!isOpen) return null;
1814
2102
  const placementStyles3 = {
1815
2103
  top: "bottom-full left-0 mb-2",
@@ -1817,6 +2105,12 @@ function PopoverContent({ children, className }) {
1817
2105
  left: "right-full top-0 mr-2",
1818
2106
  right: "left-full top-0 ml-2"
1819
2107
  };
2108
+ const hoverProps = triggerMode === "hover" ? {
2109
+ onHoverIn: handleHoverIn,
2110
+ onHoverOut: handleHoverOut,
2111
+ onMouseEnter: handleHoverIn,
2112
+ onMouseLeave: handleHoverOut
2113
+ } : {};
1820
2114
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1821
2115
  /* @__PURE__ */ jsx(
1822
2116
  Pressable,
@@ -1826,7 +2120,7 @@ function PopoverContent({ children, className }) {
1826
2120
  style: { position: "absolute" }
1827
2121
  }
1828
2122
  ),
1829
- /* @__PURE__ */ jsx(
2123
+ /* @__PURE__ */ jsxs(
1830
2124
  View,
1831
2125
  {
1832
2126
  className: cn(
@@ -1836,7 +2130,23 @@ function PopoverContent({ children, className }) {
1836
2130
  placementStyles3[placement],
1837
2131
  className
1838
2132
  ),
1839
- children
2133
+ ...hoverProps,
2134
+ children: [
2135
+ triggerMode === "hover" && /* @__PURE__ */ jsx(
2136
+ "div",
2137
+ {
2138
+ style: {
2139
+ position: "absolute",
2140
+ pointerEvents: "auto",
2141
+ background: "transparent",
2142
+ ...SPACER_STYLES[placement]
2143
+ },
2144
+ onMouseEnter: handleHoverIn,
2145
+ onMouseLeave: handleHoverOut
2146
+ }
2147
+ ),
2148
+ children
2149
+ ]
1840
2150
  }
1841
2151
  )
1842
2152
  ] });
@@ -1991,6 +2301,7 @@ function Select({
1991
2301
  isDisabled = false,
1992
2302
  isInvalid = false,
1993
2303
  options,
2304
+ variant = "default",
1994
2305
  className,
1995
2306
  ...props
1996
2307
  }) {
@@ -2039,8 +2350,8 @@ function Select({
2039
2350
  accessibilityState: { expanded: isOpen, disabled: isDisabled },
2040
2351
  className: cn(
2041
2352
  "flex-row items-center justify-between px-4 py-2.5 rounded-md border",
2042
- "bg-surface-base",
2043
- isInvalid ? "border-border-input-error" : "border-border-input",
2353
+ variant === "filled" ? "bg-black/30" : "bg-surface-base",
2354
+ isInvalid ? "border-border-input-error" : variant === "filled" ? "border-border-subtle" : "border-border-input",
2044
2355
  !isDisabled && !isInvalid && "web:hover:border-border-input-hover",
2045
2356
  isOpen && "border-border-input-focus",
2046
2357
  isDisabled && "opacity-50 cursor-not-allowed"
@@ -2136,7 +2447,7 @@ var ToolbarButtonContext = createContext({
2136
2447
  var BUTTON_BG = "#3C3C3C";
2137
2448
  var MENU_BG = "#2C2C2C";
2138
2449
  var hoverColors = getHoverColors(BUTTON_BG, "medium");
2139
- var sizeStyles9 = {
2450
+ var sizeStyles10 = {
2140
2451
  sm: "px-2 py-1 min-h-[26px]",
2141
2452
  md: "px-2.5 py-1 min-h-[30px]",
2142
2453
  lg: "px-3 py-1.5 min-h-[36px]"
@@ -2213,7 +2524,7 @@ function ToolbarButton({
2213
2524
  "flex-row items-center justify-center rounded",
2214
2525
  "web:transition-all web:duration-150 web:cursor-pointer",
2215
2526
  // Size
2216
- sizeStyles9[size],
2527
+ sizeStyles10[size],
2217
2528
  // Disabled
2218
2529
  isDisabled && "opacity-40 web:cursor-default web:pointer-events-none",
2219
2530
  className
@@ -2364,7 +2675,7 @@ var sizeConfig = {
2364
2675
  md: { outer: "w-5 h-5", inner: "w-2.5 h-2.5", text: "text-base" },
2365
2676
  lg: { outer: "w-6 h-6", inner: "w-3 h-3", text: "text-lg" }
2366
2677
  };
2367
- var colorStyles3 = {
2678
+ var colorStyles4 = {
2368
2679
  primary: { checked: "border-brand-primary bg-brand-primary", unchecked: "border-border-strong" },
2369
2680
  secondary: { checked: "border-brand-secondary bg-brand-secondary", unchecked: "border-border-strong" },
2370
2681
  success: { checked: "border-status-success bg-status-success", unchecked: "border-border-strong" },
@@ -2389,7 +2700,7 @@ function Radio({
2389
2700
  const color = radioColor ?? groupColor ?? "primary";
2390
2701
  const isChecked = selectedValue === value;
2391
2702
  const { outer, inner, text } = sizeConfig[size];
2392
- const { checked, unchecked } = colorStyles3[color];
2703
+ const { checked, unchecked } = colorStyles4[color];
2393
2704
  const handlePress = () => {
2394
2705
  if (!isDisabled) {
2395
2706
  onChange(value);
@@ -2427,7 +2738,7 @@ function Radio({
2427
2738
  }
2428
2739
  );
2429
2740
  }
2430
- var sizeStyles10 = {
2741
+ var sizeStyles11 = {
2431
2742
  left: {
2432
2743
  sm: "w-64",
2433
2744
  md: "w-80",
@@ -2502,7 +2813,7 @@ function Drawer({
2502
2813
  className: cn(
2503
2814
  "absolute bg-surface-elevated shadow-2xl",
2504
2815
  placementStyles[placement],
2505
- sizeStyles10[placement][size],
2816
+ sizeStyles11[placement][size],
2506
2817
  className
2507
2818
  ),
2508
2819
  accessibilityRole: "dialog",
@@ -2573,12 +2884,12 @@ var colorVarMap = {
2573
2884
  warning: "var(--color-status-warning)",
2574
2885
  info: "var(--color-status-info)"
2575
2886
  };
2576
- var sizeStyles11 = {
2887
+ var sizeStyles12 = {
2577
2888
  sm: "h-1",
2578
2889
  md: "h-2",
2579
2890
  lg: "h-3"
2580
2891
  };
2581
- var colorStyles4 = {
2892
+ var colorStyles5 = {
2582
2893
  primary: "bg-brand-primary",
2583
2894
  secondary: "bg-brand-secondary",
2584
2895
  success: "bg-status-success",
@@ -2603,6 +2914,8 @@ function Progress({
2603
2914
  showValue = false,
2604
2915
  formatValue = (v, m) => `${Math.round(v / m * 100)}%`,
2605
2916
  label,
2917
+ trackWidth,
2918
+ customColor,
2606
2919
  className,
2607
2920
  ...props
2608
2921
  }) {
@@ -2616,10 +2929,12 @@ function Progress({
2616
2929
  View,
2617
2930
  {
2618
2931
  className: cn(
2619
- "w-full rounded-full overflow-hidden",
2932
+ "rounded-full overflow-hidden",
2933
+ trackWidth ? void 0 : "w-full",
2620
2934
  trackColorStyles[color],
2621
- sizeStyles11[size]
2935
+ sizeStyles12[size]
2622
2936
  ),
2937
+ style: trackWidth ? { width: trackWidth } : void 0,
2623
2938
  accessibilityRole: "progressbar",
2624
2939
  accessibilityValue: {
2625
2940
  min: 0,
@@ -2631,10 +2946,13 @@ function Progress({
2631
2946
  {
2632
2947
  className: cn(
2633
2948
  "h-full rounded-full",
2634
- colorStyles4[color],
2949
+ !customColor && colorStyles5[color],
2635
2950
  isIndeterminate && "animate-pulse w-1/3"
2636
2951
  ),
2637
- style: isIndeterminate ? void 0 : { width: `${percentage}%` }
2952
+ style: {
2953
+ ...isIndeterminate ? {} : { width: `${percentage}%` },
2954
+ ...customColor ? { backgroundColor: customColor } : {}
2955
+ }
2638
2956
  }
2639
2957
  )
2640
2958
  }
@@ -2654,6 +2972,10 @@ function CircularProgress({
2654
2972
  ...props
2655
2973
  }) {
2656
2974
  const percentage = Math.min(Math.max(value / max * 100, 0), 100);
2975
+ const radius = (size - strokeWidth) / 2;
2976
+ const circumference = 2 * Math.PI * radius;
2977
+ const strokeDashoffset = circumference - percentage / 100 * circumference;
2978
+ const center = size / 2;
2657
2979
  return /* @__PURE__ */ jsxs(
2658
2980
  View,
2659
2981
  {
@@ -2670,38 +2992,56 @@ function CircularProgress({
2670
2992
  /* @__PURE__ */ jsx(
2671
2993
  View,
2672
2994
  {
2673
- className: cn(
2674
- "absolute rounded-full border-4",
2675
- "border-border-default"
2676
- ),
2677
- style: {
2678
- width: size,
2679
- height: size,
2680
- borderWidth: strokeWidth
2681
- }
2995
+ className: cn(isIndeterminate && "animate-spin"),
2996
+ style: { width: size, height: size },
2997
+ children: /* @__PURE__ */ jsxs(
2998
+ "svg",
2999
+ {
3000
+ width: size,
3001
+ height: size,
3002
+ viewBox: `0 0 ${size} ${size}`,
3003
+ style: { position: "absolute" },
3004
+ children: [
3005
+ /* @__PURE__ */ jsx(
3006
+ "circle",
3007
+ {
3008
+ cx: center,
3009
+ cy: center,
3010
+ r: radius,
3011
+ fill: "none",
3012
+ stroke: "var(--color-border-default)",
3013
+ strokeWidth
3014
+ }
3015
+ ),
3016
+ /* @__PURE__ */ jsx(
3017
+ "circle",
3018
+ {
3019
+ cx: center,
3020
+ cy: center,
3021
+ r: radius,
3022
+ fill: "none",
3023
+ stroke: colorVarMap[color],
3024
+ strokeWidth,
3025
+ strokeLinecap: "round",
3026
+ strokeDasharray: circumference,
3027
+ strokeDashoffset: isIndeterminate ? circumference * 0.75 : strokeDashoffset,
3028
+ transform: `rotate(-90 ${center} ${center})`,
3029
+ style: { transition: "stroke-dashoffset 300ms cubic-bezier(0.22, 1, 0.36, 1)" }
3030
+ }
3031
+ )
3032
+ ]
3033
+ }
3034
+ )
2682
3035
  }
2683
3036
  ),
2684
- /* @__PURE__ */ jsx(
2685
- View,
3037
+ showValue && !isIndeterminate && /* @__PURE__ */ jsx(
3038
+ Text,
2686
3039
  {
2687
- className: cn(
2688
- "absolute rounded-full",
2689
- colorStyles4[color],
2690
- isIndeterminate && "animate-spin"
2691
- ),
2692
- style: {
2693
- width: size,
2694
- height: size,
2695
- borderWidth: strokeWidth,
2696
- borderColor: "transparent",
2697
- borderTopColor: colorVarMap[color],
2698
- borderRightColor: percentage > 25 ? colorVarMap[color] : "transparent",
2699
- borderBottomColor: percentage > 50 ? colorVarMap[color] : "transparent",
2700
- borderLeftColor: percentage > 75 ? colorVarMap[color] : "transparent"
2701
- }
3040
+ className: "text-xs font-semibold text-text-primary absolute",
3041
+ style: { fontSize: Math.max(size * 0.22, 10) },
3042
+ children: formatValue(value, max)
2702
3043
  }
2703
- ),
2704
- showValue && !isIndeterminate && /* @__PURE__ */ jsx(Text, { className: "text-xs font-semibold text-text-primary", children: formatValue(value, max) })
3044
+ )
2705
3045
  ]
2706
3046
  }
2707
3047
  );
@@ -2729,7 +3069,7 @@ function ProgressSteps({
2729
3069
  className: cn(
2730
3070
  "rounded-full",
2731
3071
  dot,
2732
- index <= currentStep ? colorStyles4[color] : "bg-border-strong"
3072
+ index <= currentStep ? colorStyles5[color] : "bg-border-strong"
2733
3073
  )
2734
3074
  }
2735
3075
  ),
@@ -2739,7 +3079,7 @@ function ProgressSteps({
2739
3079
  className: cn(
2740
3080
  "flex-1 mx-1",
2741
3081
  connector,
2742
- index < currentStep ? colorStyles4[color] : "bg-border-strong"
3082
+ index < currentStep ? colorStyles5[color] : "bg-border-strong"
2743
3083
  )
2744
3084
  }
2745
3085
  )
@@ -3139,12 +3479,12 @@ function Autocomplete({
3139
3479
  )
3140
3480
  ] });
3141
3481
  }
3142
- var sizeStyles12 = {
3482
+ var sizeStyles13 = {
3143
3483
  sm: { icon: "w-3.5 h-3.5 text-xs", text: "text-xs" },
3144
3484
  md: { icon: "w-4 h-4 text-sm", text: "text-sm" },
3145
3485
  lg: { icon: "w-5 h-5 text-base", text: "text-base" }
3146
3486
  };
3147
- var colorStyles5 = {
3487
+ var colorStyles6 = {
3148
3488
  default: "text-text-tertiary",
3149
3489
  primary: "text-brand-primary",
3150
3490
  secondary: "text-text-secondary",
@@ -3183,7 +3523,7 @@ function HelpTip({
3183
3523
  }) {
3184
3524
  const [internalIsOpen, setInternalIsOpen] = useState(false);
3185
3525
  const isOpen = controlledIsOpen ?? internalIsOpen;
3186
- const { icon: iconSize, text: textSize } = sizeStyles12[size];
3526
+ const { icon: iconSize, text: textSize } = sizeStyles13[size];
3187
3527
  const handlePress = () => {
3188
3528
  if (controlledIsOpen === void 0) {
3189
3529
  setInternalIsOpen((prev) => !prev);
@@ -3212,12 +3552,12 @@ function HelpTip({
3212
3552
  className: cn(
3213
3553
  "items-center justify-center rounded-full",
3214
3554
  "border border-current",
3215
- colorStyles5[color],
3555
+ colorStyles6[color],
3216
3556
  iconSize,
3217
3557
  "web:hover:opacity-80 web:cursor-help",
3218
3558
  iconClassName
3219
3559
  ),
3220
- children: /* @__PURE__ */ jsx(Text, { className: cn("font-semibold", iconSize, colorStyles5[color]), children: iconMap[icon] })
3560
+ children: /* @__PURE__ */ jsx(Text, { className: cn("font-semibold", iconSize, colorStyles6[color]), children: iconMap[icon] })
3221
3561
  }
3222
3562
  ),
3223
3563
  isOpen && /* @__PURE__ */ jsxs(
@@ -3602,6 +3942,63 @@ function ListItemDivider({ inset = true, className, ...props }) {
3602
3942
  }
3603
3943
  );
3604
3944
  }
3945
+ var variantColorStyles2 = {
3946
+ subtle: {
3947
+ default: "bg-surface-raised border-border-subtle text-text-secondary",
3948
+ primary: "bg-brand-primary/10 border-brand-primary/25 text-brand-primary",
3949
+ secondary: "bg-brand-secondary/10 border-brand-secondary/25 text-brand-secondary",
3950
+ success: "bg-status-success/10 border-status-success/25 text-status-success",
3951
+ error: "bg-status-error/10 border-status-error/25 text-status-error",
3952
+ warning: "bg-status-warning/10 border-status-warning/25 text-status-warning",
3953
+ info: "bg-status-info/10 border-status-info/25 text-status-info"
3954
+ },
3955
+ outline: {
3956
+ default: "border-border-default text-text-secondary",
3957
+ primary: "border-brand-primary text-brand-primary",
3958
+ secondary: "border-brand-secondary text-brand-secondary",
3959
+ success: "border-status-success text-status-success",
3960
+ error: "border-status-error text-status-error",
3961
+ warning: "border-status-warning text-status-warning",
3962
+ info: "border-status-info text-status-info"
3963
+ }
3964
+ };
3965
+ var sizeStyles14 = {
3966
+ xs: { container: "px-1 py-px", text: "text-[9px]" },
3967
+ sm: { container: "px-2 py-0.5", text: "text-[10px]" },
3968
+ md: { container: "px-2 py-1", text: "text-[10px]" }
3969
+ };
3970
+ function Pill({
3971
+ children,
3972
+ variant = "subtle",
3973
+ color = "default",
3974
+ size = "sm",
3975
+ rounded = true,
3976
+ leftElement,
3977
+ onPress,
3978
+ className,
3979
+ ...props
3980
+ }) {
3981
+ const containerClasses = cn(
3982
+ "flex-row items-center gap-1 border self-start shrink-0",
3983
+ rounded ? "rounded-full" : "rounded",
3984
+ variantColorStyles2[variant][color],
3985
+ sizeStyles14[size].container,
3986
+ className
3987
+ );
3988
+ const textClasses = cn(
3989
+ "font-heading font-semibold",
3990
+ sizeStyles14[size].text,
3991
+ "text-inherit"
3992
+ );
3993
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
3994
+ leftElement,
3995
+ typeof children === "string" ? /* @__PURE__ */ jsx(Text, { className: textClasses, children }) : children
3996
+ ] });
3997
+ if (onPress) {
3998
+ return /* @__PURE__ */ jsx(Pressable, { onPress, className: containerClasses, ...props, children: content });
3999
+ }
4000
+ return /* @__PURE__ */ jsx(View, { className: containerClasses, ...props, children: content });
4001
+ }
3605
4002
  var variantStyles4 = {
3606
4003
  h1: "font-heading text-5xl font-bold leading-tight",
3607
4004
  h2: "font-heading text-4xl font-bold leading-tight",
@@ -3617,7 +4014,7 @@ var variantStyles4 = {
3617
4014
  overline: "font-body text-xs font-semibold uppercase tracking-widest leading-relaxed",
3618
4015
  button: "font-sans text-sm font-semibold leading-relaxed"
3619
4016
  };
3620
- var colorStyles6 = {
4017
+ var colorStyles7 = {
3621
4018
  primary: "text-text-primary",
3622
4019
  secondary: "text-text-secondary",
3623
4020
  tertiary: "text-text-tertiary",
@@ -3674,7 +4071,7 @@ function Typography({
3674
4071
  numberOfLines: numLines,
3675
4072
  className: cn(
3676
4073
  variantStyles4[variant],
3677
- color !== "inherit" && colorStyles6[color],
4074
+ color !== "inherit" && colorStyles7[color],
3678
4075
  align && alignStyles2[align],
3679
4076
  shouldTruncate && "truncate",
3680
4077
  marginBottomStyles[mb],
@@ -4288,7 +4685,7 @@ function StepContent({ status = "upcoming", className, children }) {
4288
4685
  if (status !== "active") return null;
4289
4686
  return /* @__PURE__ */ jsx(View, { className: cn("ml-11 mt-2 pb-4", className), children });
4290
4687
  }
4291
- var colorStyles7 = {
4688
+ var colorStyles8 = {
4292
4689
  primary: "text-text-primary",
4293
4690
  secondary: "text-text-secondary",
4294
4691
  tertiary: "text-text-tertiary",
@@ -4419,10 +4816,10 @@ function DateTime({
4419
4816
  ...props
4420
4817
  }) {
4421
4818
  if (value === null || value === void 0) {
4422
- return /* @__PURE__ */ jsx(Text, { className: cn(colorStyles7[color], className), ...props, children: fallback });
4819
+ return /* @__PURE__ */ jsx(Text, { className: cn(colorStyles8[color], className), ...props, children: fallback });
4423
4820
  }
4424
4821
  const formattedDate = formatDate(value, format, isUTC);
4425
- return /* @__PURE__ */ jsx(Text, { className: cn(colorStyles7[color], className), ...props, children: formattedDate });
4822
+ return /* @__PURE__ */ jsx(Text, { className: cn(colorStyles8[color], className), ...props, children: formattedDate });
4426
4823
  }
4427
4824
  function formatDateTime(value, format = "datetime", isUTC = false, fallback = "-") {
4428
4825
  if (value === null || value === void 0) {
@@ -4481,6 +4878,231 @@ function MetricGroup({
4481
4878
  )
4482
4879
  ] }, i)) });
4483
4880
  }
4881
+ function RestTimer({
4882
+ totalSeconds,
4883
+ elapsedMs,
4884
+ onSkip,
4885
+ onAddTime,
4886
+ nextSetInfo,
4887
+ visible
4888
+ }) {
4889
+ if (!visible) return null;
4890
+ const remainingMs = Math.max(0, totalSeconds * 1e3 - elapsedMs);
4891
+ const remainingSec = Math.ceil(remainingMs / 1e3);
4892
+ const minutes = Math.floor(remainingSec / 60);
4893
+ const seconds = remainingSec % 60;
4894
+ const timeDisplay = `${minutes}:${String(seconds).padStart(2, "0")}`;
4895
+ const progressPct = Math.min(100, elapsedMs / (totalSeconds * 1e3) * 100);
4896
+ return /* @__PURE__ */ jsxs(
4897
+ View,
4898
+ {
4899
+ style: {
4900
+ width: "100%",
4901
+ backgroundColor: "#1C1C1C",
4902
+ borderTopWidth: 1,
4903
+ borderTopColor: "#1F1F1F",
4904
+ paddingVertical: 12,
4905
+ paddingHorizontal: 16
4906
+ },
4907
+ accessibilityRole: "timer",
4908
+ accessibilityLabel: `Rest timer, ${remainingSec} seconds remaining`,
4909
+ testID: "rest-timer",
4910
+ children: [
4911
+ /* @__PURE__ */ jsxs(
4912
+ View,
4913
+ {
4914
+ style: {
4915
+ flexDirection: "row",
4916
+ justifyContent: "space-between",
4917
+ alignItems: "center",
4918
+ marginBottom: 8
4919
+ },
4920
+ children: [
4921
+ /* @__PURE__ */ jsxs(View, { style: { flexDirection: "column" }, children: [
4922
+ /* @__PURE__ */ jsx(
4923
+ Text,
4924
+ {
4925
+ style: {
4926
+ fontSize: 11,
4927
+ fontFamily: "Inter, sans-serif",
4928
+ fontWeight: "600",
4929
+ textTransform: "uppercase",
4930
+ letterSpacing: 1,
4931
+ color: "#9CA3AF"
4932
+ },
4933
+ testID: "rest-timer-label",
4934
+ children: "REST"
4935
+ }
4936
+ ),
4937
+ nextSetInfo != null && /* @__PURE__ */ jsx(
4938
+ Text,
4939
+ {
4940
+ style: {
4941
+ fontSize: 11,
4942
+ fontFamily: "Inter, sans-serif",
4943
+ color: "#6B7280",
4944
+ marginTop: 2
4945
+ },
4946
+ testID: "rest-timer-next-set",
4947
+ children: nextSetInfo
4948
+ }
4949
+ )
4950
+ ] }),
4951
+ /* @__PURE__ */ jsx(
4952
+ Text,
4953
+ {
4954
+ style: {
4955
+ fontSize: 28,
4956
+ fontFamily: '"Space Grotesk", sans-serif',
4957
+ fontWeight: "700",
4958
+ color: "#F3F4F6",
4959
+ fontVariant: ["tabular-nums"],
4960
+ letterSpacing: -0.5
4961
+ },
4962
+ testID: "rest-timer-time",
4963
+ children: timeDisplay
4964
+ }
4965
+ )
4966
+ ]
4967
+ }
4968
+ ),
4969
+ /* @__PURE__ */ jsx(
4970
+ View,
4971
+ {
4972
+ style: {
4973
+ height: 3,
4974
+ backgroundColor: "#1F1F1F",
4975
+ borderRadius: 2,
4976
+ marginBottom: 12
4977
+ },
4978
+ testID: "rest-timer-progress-track",
4979
+ children: /* @__PURE__ */ jsx(
4980
+ View,
4981
+ {
4982
+ style: {
4983
+ height: "100%",
4984
+ backgroundColor: "#FF7900",
4985
+ borderRadius: 2,
4986
+ width: `${progressPct}%`
4987
+ },
4988
+ testID: "rest-timer-progress-fill"
4989
+ }
4990
+ )
4991
+ }
4992
+ ),
4993
+ /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", gap: 8 }, children: [
4994
+ /* @__PURE__ */ jsx(
4995
+ Pressable,
4996
+ {
4997
+ onPress: onAddTime,
4998
+ style: {
4999
+ backgroundColor: "rgba(255,255,255,0.06)",
5000
+ paddingVertical: 8,
5001
+ paddingHorizontal: 20,
5002
+ borderRadius: 8
5003
+ },
5004
+ accessibilityRole: "button",
5005
+ accessibilityLabel: "Add 30 seconds",
5006
+ testID: "rest-timer-add-time",
5007
+ children: /* @__PURE__ */ jsx(
5008
+ Text,
5009
+ {
5010
+ style: {
5011
+ fontSize: 11,
5012
+ fontFamily: "Inter, sans-serif",
5013
+ fontWeight: "600",
5014
+ color: "#9CA3AF"
5015
+ },
5016
+ children: "+30s"
5017
+ }
5018
+ )
5019
+ }
5020
+ ),
5021
+ /* @__PURE__ */ jsx(
5022
+ Pressable,
5023
+ {
5024
+ onPress: onSkip,
5025
+ style: {
5026
+ backgroundColor: "rgba(255,121,0,0.12)",
5027
+ paddingVertical: 8,
5028
+ paddingHorizontal: 20,
5029
+ borderRadius: 8
5030
+ },
5031
+ accessibilityRole: "button",
5032
+ accessibilityLabel: "Skip rest",
5033
+ testID: "rest-timer-skip",
5034
+ children: /* @__PURE__ */ jsx(
5035
+ Text,
5036
+ {
5037
+ style: {
5038
+ fontSize: 11,
5039
+ fontFamily: "Inter, sans-serif",
5040
+ fontWeight: "600",
5041
+ color: "#FF7900"
5042
+ },
5043
+ children: "Skip"
5044
+ }
5045
+ )
5046
+ }
5047
+ )
5048
+ ] })
5049
+ ]
5050
+ }
5051
+ );
5052
+ }
5053
+ var DEFAULTS = {
5054
+ label: "SS",
5055
+ color: "#FF7900",
5056
+ bgBase: "#101010"
5057
+ };
5058
+ function SupersetWrapper({
5059
+ label = DEFAULTS.label,
5060
+ color = DEFAULTS.color,
5061
+ children
5062
+ }) {
5063
+ return /* @__PURE__ */ jsxs(
5064
+ View,
5065
+ {
5066
+ style: {
5067
+ position: "relative",
5068
+ borderLeftWidth: 3,
5069
+ borderLeftColor: color,
5070
+ paddingLeft: 8,
5071
+ marginHorizontal: 12,
5072
+ marginBottom: 8,
5073
+ overflow: "visible"
5074
+ },
5075
+ accessibilityRole: "group",
5076
+ accessibilityLabel: `Superset: ${label}`,
5077
+ testID: "superset-wrapper",
5078
+ children: [
5079
+ /* @__PURE__ */ jsx(
5080
+ Text,
5081
+ {
5082
+ style: {
5083
+ position: "absolute",
5084
+ top: -1,
5085
+ left: -3,
5086
+ fontSize: 9,
5087
+ fontFamily: "Inter, sans-serif",
5088
+ fontWeight: "700",
5089
+ backgroundColor: color,
5090
+ color: DEFAULTS.bgBase,
5091
+ paddingVertical: 2,
5092
+ paddingHorizontal: 6,
5093
+ borderBottomRightRadius: 4,
5094
+ letterSpacing: 0.5,
5095
+ zIndex: 2
5096
+ },
5097
+ testID: "superset-label",
5098
+ children: label
5099
+ }
5100
+ ),
5101
+ /* @__PURE__ */ jsx(View, { style: { gap: 2 }, testID: "superset-children", children })
5102
+ ]
5103
+ }
5104
+ );
5105
+ }
4484
5106
 
4485
5107
  // src/utils/colors.ts
4486
5108
  function getStatusColor(status) {
@@ -4629,6 +5251,6 @@ function composeValidators(...validators) {
4629
5251
  };
4630
5252
  }
4631
5253
 
4632
- export { Accordion, AccordionButton, AccordionItem, AccordionPanel, Alert, AlertDescription, AlertTitle, Autocomplete, Avatar, AvatarBadge, AvatarGroup, Badge, BadgeText, BreadcrumbItem, Breadcrumbs, Button, ButtonIcon, ButtonSpinner, ButtonText, Caption, Card, CardContent, CardDescription, CardFooter, CardHeader, CardSkeleton, CardTitle, Checkbox, CheckboxGroup, Chip, CircularProgress, Collapse, CollapseButton, CollapseContent, DataRow, DateTime, Divider, Drawer, DrawerBody, DrawerFooter, DrawerHeader, EmptyState, FormActions, FormField, FormRow, FormSection, HStack, Heading, HelpTip, IconBox, Input, InputGroup, Label, LabelWithHelp, Link, ListItem, ListItemContent, ListItemDivider, ListItemIcon, ListItemTrailing, Menu, MenuDivider, MenuGroup, MenuItem, MenuList, MenuTrigger, Metric, MetricGroup, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalTitle, Overline, Paragraph, PasswordInput, Popover, PopoverCloseButton, PopoverContent, PopoverTrigger, Progress, ProgressSteps, Radio, RadioGroup, Section, SectionContent, SectionHeader, Select, Sidebar, SidebarContent, SidebarDivider, SidebarFooter, SidebarHeader, SidebarItem, SidebarSection, Skeleton, SkeletonCard, SkeletonCircle, SkeletonListItem, SkeletonText, Spinner, Stack, Step, StepContent, StepIndicator, StepLabel, Stepper, Surface, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TablePagination, TableRow, Tabs, Toast, ToastProvider, ToolbarButton, ToolbarButtonGroup, Tooltip, Typography, VStack, alpha, cn, composeValidators, createFieldId, formatDateTime, getContrastText, getFieldAriaProps, getFieldValidationProps, getLuminance, getResultColor, getStatusColor, hasMaxLength, hasMinLength, isEmpty, isValidEmail, useTable, useToast, useToolbarButton, validationRules };
5254
+ export { Accordion, AccordionButton, AccordionItem, AccordionPanel, Alert, AlertDescription, AlertTitle, Autocomplete, Avatar, AvatarBadge, AvatarGroup, Badge, BadgeText, BreadcrumbItem, Breadcrumbs, Button, ButtonIcon, ButtonSpinner, ButtonText, Caption, Card, CardContent, CardDescription, CardFooter, CardHeader, CardSkeleton, CardTitle, Checkbox, CheckboxGroup, Chip, CircularProgress, Collapse, CollapseButton, CollapseContent, DataRow, DateTime, Divider, Drawer, DrawerBody, DrawerFooter, DrawerHeader, EmptyState, FormActions, FormField, FormRow, FormSection, HStack, Heading, HelpTip, IconBox, Indicator, Input, InputGroup, Label, LabelWithHelp, Link, ListItem, ListItemContent, ListItemDivider, ListItemIcon, ListItemTrailing, Menu, MenuDivider, MenuGroup, MenuItem, MenuList, MenuTrigger, Metric, MetricGroup, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalTitle, Overline, Paragraph, PasswordInput, Pill, Popover, PopoverCloseButton, PopoverContent, PopoverTrigger, Progress, ProgressSteps, Radio, RadioGroup, RestTimer, Section, SectionContent, SectionHeader, Select, Sidebar, SidebarContent, SidebarDivider, SidebarFooter, SidebarHeader, SidebarItem, SidebarSection, Skeleton, SkeletonCard, SkeletonCircle, SkeletonListItem, SkeletonText, Spinner, Stack, StepContent, StepIndicator, StepLabel, Stepper, Step as StepperStep, SupersetWrapper, Surface, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TablePagination, TableRow, Tabs, Toast, ToastProvider, ToolbarButton, ToolbarButtonGroup, Tooltip, Typography, VStack, alpha, cn, composeValidators, createFieldId, formatDateTime, getContrastText, getFieldAriaProps, getFieldValidationProps, getLuminance, getResultColor, getStatusColor, hasMaxLength, hasMinLength, isEmpty, isValidEmail, useTable, useToast, useToolbarButton, validationRules };
4633
5255
  //# sourceMappingURL=index.mjs.map
4634
5256
  //# sourceMappingURL=index.mjs.map