@sincpro/mobile-ui 0.7.1 → 1.0.1

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 (270) hide show
  1. package/README.md +7 -5
  2. package/dist/Actions/Actions.Button.d.ts +91 -91
  3. package/dist/Actions/Actions.Button.js +36 -43
  4. package/dist/Actions/Actions.FAB.js +5 -5
  5. package/dist/Actions/Actions.FilterButton.js +3 -3
  6. package/dist/Actions/Actions.IconButton.d.ts +31 -31
  7. package/dist/Actions/Actions.IconButton.js +4 -4
  8. package/dist/Actions/index.d.ts +11 -11
  9. package/dist/Actions/index.js +5 -5
  10. package/dist/Dialog/BottomSheet/BottomSheet.Root.js +1 -1
  11. package/dist/Dialog/BottomSheet/index.d.ts +1 -1
  12. package/dist/Dialog/BottomSheet/index.js +1 -1
  13. package/dist/Dialog/Confirmation.context.js +3 -3
  14. package/dist/Dialog/Dialog.ActionSheet.js +26 -10
  15. package/dist/Dialog/Dialog.Confirmation.js +5 -5
  16. package/dist/Dialog/Dialog.EditValue.js +4 -4
  17. package/dist/Dialog/Dialog.Sheet.js +19 -8
  18. package/dist/Dialog/index.d.ts +5 -5
  19. package/dist/Dialog/index.js +5 -5
  20. package/dist/Display/Display.Accordion.js +5 -5
  21. package/dist/Display/Display.Avatar.d.ts +30 -30
  22. package/dist/Display/Display.Avatar.js +2 -2
  23. package/dist/Display/Display.AvatarGroup.js +3 -3
  24. package/dist/Display/Display.Badge.d.ts +3 -3
  25. package/dist/Display/Display.Badge.js +1 -1
  26. package/dist/Display/Display.Card.d.ts +15 -15
  27. package/dist/Display/Display.Card.js +4 -4
  28. package/dist/Display/Display.Carousel.js +2 -2
  29. package/dist/Display/Display.Chip.d.ts +3 -3
  30. package/dist/Display/Display.Chip.js +12 -12
  31. package/dist/Display/Display.CircleButton.d.ts +1 -1
  32. package/dist/Display/Display.CircleButton.js +3 -3
  33. package/dist/Display/Display.CopyableText.js +2 -2
  34. package/dist/Display/Display.CountRecords.js +2 -2
  35. package/dist/Display/Display.DataTable.js +2 -2
  36. package/dist/Display/Display.Date.d.ts +1 -1
  37. package/dist/Display/Display.Date.js +5 -5
  38. package/dist/Display/Display.Divider.d.ts +24 -24
  39. package/dist/Display/Display.Divider.js +1 -1
  40. package/dist/Display/Display.GradientSurface.d.ts +58 -39
  41. package/dist/Display/Display.GradientSurface.js +31 -15
  42. package/dist/Display/Display.Icon.d.ts +1 -1
  43. package/dist/Display/Display.Icon.js +1 -1
  44. package/dist/Display/Display.IconBadge.js +3 -3
  45. package/dist/Display/Display.Image.js +4 -4
  46. package/dist/Display/Display.KeyValue.js +2 -2
  47. package/dist/Display/Display.ListItem.js +5 -5
  48. package/dist/Display/Display.Logo.d.ts +3 -3
  49. package/dist/Display/Display.Logo.js +2 -2
  50. package/dist/Display/Display.MediaCard.js +4 -4
  51. package/dist/Display/Display.MediaEmbed.js +7 -7
  52. package/dist/Display/Display.MenuButton.d.ts +4 -4
  53. package/dist/Display/Display.MenuButton.js +6 -6
  54. package/dist/Display/Display.MenuCard.d.ts +1 -1
  55. package/dist/Display/Display.MenuCard.js +3 -3
  56. package/dist/Display/Display.MenuGrid.d.ts +1 -1
  57. package/dist/Display/Display.MenuGrid.js +1 -1
  58. package/dist/Display/Display.Monetary.d.ts +1 -1
  59. package/dist/Display/Display.Monetary.js +2 -2
  60. package/dist/Display/Display.Pattern.d.ts +33 -12
  61. package/dist/Display/Display.Pattern.js +60 -14
  62. package/dist/Display/Display.PriceTag.js +2 -2
  63. package/dist/Display/Display.ProductCard.js +7 -7
  64. package/dist/Display/Display.Rating.js +3 -3
  65. package/dist/Display/Display.SearchHistory.js +6 -6
  66. package/dist/Display/Display.SectionHeader.js +4 -4
  67. package/dist/Display/Display.Stat.js +2 -2
  68. package/dist/Display/Display.StatCard.js +4 -4
  69. package/dist/Display/Display.StatusDot.js +3 -3
  70. package/dist/Display/Display.Story.js +3 -3
  71. package/dist/Display/Display.StoryTray.js +5 -5
  72. package/dist/Display/Display.StoryViewer.js +4 -4
  73. package/dist/Display/Display.SwipeableRow.js +4 -4
  74. package/dist/Display/Display.Tag.js +2 -2
  75. package/dist/Display/Display.Timeline.js +4 -4
  76. package/dist/Display/Display.Tooltip.js +3 -3
  77. package/dist/Display/index.d.ts +45 -45
  78. package/dist/Display/index.js +42 -42
  79. package/dist/Feedback/ErrorBoundary.d.ts +1 -1
  80. package/dist/Feedback/ErrorBoundary.js +1 -1
  81. package/dist/Feedback/Feedback.Banner.d.ts +3 -3
  82. package/dist/Feedback/Feedback.Banner.js +5 -5
  83. package/dist/Feedback/Feedback.DomainSplashScreen.js +5 -4
  84. package/dist/Feedback/Feedback.Empty.js +3 -3
  85. package/dist/Feedback/Feedback.EmptyState.js +5 -5
  86. package/dist/Feedback/Feedback.Error.js +4 -4
  87. package/dist/Feedback/Feedback.Loading.d.ts +1 -1
  88. package/dist/Feedback/Feedback.Loading.js +2 -2
  89. package/dist/Feedback/Feedback.PermissionCard.js +5 -5
  90. package/dist/Feedback/Feedback.Progress.js +6 -4
  91. package/dist/Feedback/Feedback.ProgressCircle.js +1 -1
  92. package/dist/Feedback/Feedback.Skeleton.js +5 -4
  93. package/dist/Feedback/Feedback.Spinner.js +3 -3
  94. package/dist/Feedback/Feedback.Splash.d.ts +1 -1
  95. package/dist/Feedback/Feedback.Splash.js +7 -6
  96. package/dist/Feedback/Toast.context.js +7 -7
  97. package/dist/Feedback/index.d.ts +13 -13
  98. package/dist/Feedback/index.js +13 -13
  99. package/dist/Form/Form.Button.d.ts +2 -2
  100. package/dist/Form/Form.Button.js +1 -1
  101. package/dist/Form/Form.Checkbox.js +4 -4
  102. package/dist/Form/Form.ControlledCheckbox.js +1 -1
  103. package/dist/Form/Form.ControlledInput.js +1 -1
  104. package/dist/Form/Form.ControlledMonetaryInput.js +1 -1
  105. package/dist/Form/Form.ControlledRadioButton.js +1 -1
  106. package/dist/Form/Form.DatePicker.js +5 -5
  107. package/dist/Form/Form.Dropdown.js +8 -8
  108. package/dist/Form/Form.FAB.d.ts +2 -2
  109. package/dist/Form/Form.FAB.js +1 -1
  110. package/dist/Form/Form.FilterButton.d.ts +2 -2
  111. package/dist/Form/Form.FilterButton.js +1 -1
  112. package/dist/Form/Form.FractionalQuantityInput.js +4 -4
  113. package/dist/Form/Form.IconButton.d.ts +2 -2
  114. package/dist/Form/Form.IconButton.js +1 -1
  115. package/dist/Form/Form.Input.js +4 -4
  116. package/dist/Form/Form.InputField.d.ts +1 -1
  117. package/dist/Form/Form.InputField.js +3 -3
  118. package/dist/Form/Form.MonetaryInput.js +5 -4
  119. package/dist/Form/Form.PasswordInput.d.ts +1 -1
  120. package/dist/Form/Form.PasswordInput.js +3 -3
  121. package/dist/Form/Form.PinInput.js +5 -5
  122. package/dist/Form/Form.QuantitySelector.js +3 -3
  123. package/dist/Form/Form.RadioButton.js +4 -4
  124. package/dist/Form/Form.SearchBar.js +4 -4
  125. package/dist/Form/Form.Select.js +33 -18
  126. package/dist/Form/Form.Slider.js +3 -3
  127. package/dist/Form/Form.Switch.js +4 -4
  128. package/dist/Form/Form.TextInput.js +3 -3
  129. package/dist/Form/index.d.ts +27 -27
  130. package/dist/Form/index.js +25 -25
  131. package/dist/Navigation/Navigation.AppBar.d.ts +5 -4
  132. package/dist/Navigation/Navigation.AppBar.js +10 -10
  133. package/dist/Navigation/Navigation.BottomNav.d.ts +1 -1
  134. package/dist/Navigation/Navigation.BottomNav.js +25 -16
  135. package/dist/Navigation/Navigation.CollapsingHeader.d.ts +1 -1
  136. package/dist/Navigation/Navigation.CollapsingHeader.js +3 -3
  137. package/dist/Navigation/Navigation.FloatingBar.js +2 -2
  138. package/dist/Navigation/Navigation.Header.js +6 -6
  139. package/dist/Navigation/Navigation.HeaderToolbar.js +5 -5
  140. package/dist/Navigation/Navigation.Menu.js +7 -7
  141. package/dist/Navigation/Navigation.MenuSection.js +2 -2
  142. package/dist/Navigation/Navigation.RowItem.d.ts +1 -1
  143. package/dist/Navigation/Navigation.RowItem.js +2 -2
  144. package/dist/Navigation/Navigation.SearchBar.js +6 -6
  145. package/dist/Navigation/Navigation.SegmentedControl.js +4 -4
  146. package/dist/Navigation/Navigation.Steps.js +5 -5
  147. package/dist/Navigation/Navigation.TabIcon.js +2 -2
  148. package/dist/Navigation/Navigation.TabItem.js +2 -2
  149. package/dist/Navigation/Navigation.Tabs.js +5 -5
  150. package/dist/Navigation/index.d.ts +19 -19
  151. package/dist/Navigation/index.js +15 -15
  152. package/dist/Typography/Typography.Heading.d.ts +1 -1
  153. package/dist/Typography/Typography.Heading.js +1 -1
  154. package/dist/Typography/Typography.Text.d.ts +2 -2
  155. package/dist/Typography/Typography.Text.js +8 -6
  156. package/dist/Typography/index.d.ts +2 -2
  157. package/dist/Typography/index.js +2 -2
  158. package/dist/branding.d.ts +22 -0
  159. package/dist/branding.js +20 -3
  160. package/dist/icons/AddItemIcon.d.ts +1 -1
  161. package/dist/icons/ArrangeCircle.d.ts +1 -1
  162. package/dist/icons/ArrowDownIcon.d.ts +1 -1
  163. package/dist/icons/ArrowUpIcon.d.ts +1 -1
  164. package/dist/icons/BoxIcon.d.ts +1 -1
  165. package/dist/icons/BoxTimeIcon.d.ts +1 -1
  166. package/dist/icons/CalendarIcon.d.ts +1 -1
  167. package/dist/icons/CardIcon.d.ts +1 -1
  168. package/dist/icons/CashierIcon.d.ts +1 -1
  169. package/dist/icons/DuoIcon.d.ts +1 -1
  170. package/dist/icons/HomeIcon.d.ts +1 -1
  171. package/dist/icons/HomeIconOutlined.d.ts +1 -1
  172. package/dist/icons/LogoIcon.d.ts +1 -1
  173. package/dist/icons/MoneyReceiveIcon.d.ts +1 -1
  174. package/dist/icons/PinIcon.d.ts +1 -1
  175. package/dist/icons/PrinterIcon.d.ts +1 -1
  176. package/dist/icons/ProfileIcon.d.ts +1 -1
  177. package/dist/icons/SettingsIcon.d.ts +1 -1
  178. package/dist/icons/SinpeIcon.d.ts +1 -1
  179. package/dist/icons/ToggleOffIcon.d.ts +1 -1
  180. package/dist/icons/WalletMoneyIcon.d.ts +1 -1
  181. package/dist/index.d.ts +24 -23
  182. package/dist/index.js +26 -24
  183. package/dist/layouts/AuthContainer.d.ts +5 -2
  184. package/dist/layouts/AuthContainer.js +6 -6
  185. package/dist/layouts/Container.js +1 -1
  186. package/dist/layouts/GradientContainer.js +1 -1
  187. package/dist/layouts/ScrollContainer.js +1 -1
  188. package/dist/layouts/TabNavigatorLayout.js +4 -4
  189. package/dist/primitives/AspectRatio.js +1 -1
  190. package/dist/primitives/BaseButton.d.ts +85 -85
  191. package/dist/primitives/BaseButton.js +34 -50
  192. package/dist/primitives/Box.js +1 -1
  193. package/dist/primitives/Pressable.js +1 -1
  194. package/dist/primitives/Row.js +1 -1
  195. package/dist/primitives/Stack.js +1 -1
  196. package/dist/primitives/index.d.ts +6 -6
  197. package/dist/primitives/index.js +6 -6
  198. package/dist/theme/active.d.ts +1 -1
  199. package/dist/theme/active.js +14 -1
  200. package/dist/theme/build.d.ts +33 -0
  201. package/dist/theme/build.js +118 -0
  202. package/dist/theme/color.d.ts +26 -0
  203. package/dist/theme/color.js +109 -0
  204. package/dist/theme/components/index.d.ts +1 -1
  205. package/dist/theme/components/index.js +1 -1
  206. package/dist/theme/contrast.d.ts +29 -0
  207. package/dist/theme/contrast.js +57 -0
  208. package/dist/theme/css-vars.d.ts +3 -1
  209. package/dist/theme/css-vars.js +29 -3
  210. package/dist/theme/dark.d.ts +3 -4
  211. package/dist/theme/dark.js +91 -48
  212. package/dist/theme/default.d.ts +5 -1
  213. package/dist/theme/default.js +89 -41
  214. package/dist/theme/define.d.ts +4 -1
  215. package/dist/theme/define.js +4 -1
  216. package/dist/theme/globals.css +61 -46
  217. package/dist/theme/index.d.ts +14 -10
  218. package/dist/theme/index.js +13 -9
  219. package/dist/theme/theme.d.ts +1 -1
  220. package/dist/theme/theme.js +2 -2
  221. package/dist/theme/types.d.ts +77 -16
  222. package/dist/theme/types.js +13 -3
  223. package/dist/theme/typography.d.ts +4 -4
  224. package/dist/theme/typography.js +26 -28
  225. package/dist/theme/useTheme.d.ts +1 -1
  226. package/dist/theme/useTheme.js +1 -1
  227. package/dist/theme/validate.d.ts +16 -0
  228. package/dist/theme/validate.js +200 -0
  229. package/dist/tokens/index.d.ts +2 -2
  230. package/dist/tokens/index.js +2 -2
  231. package/dist/views/AppSplashView.d.ts +2 -2
  232. package/dist/views/AppSplashView.js +3 -3
  233. package/dist/views/AuthFormView.d.ts +1 -1
  234. package/dist/views/AuthFormView.js +3 -3
  235. package/dist/views/FormViewV2.d.ts +2 -2
  236. package/dist/views/FormViewV2.js +9 -9
  237. package/dist/views/ListViewV2.d.ts +3 -3
  238. package/dist/views/ListViewV2.js +16 -16
  239. package/dist/views/Wizard/Wizard.context.js +1 -1
  240. package/dist/views/Wizard/Wizard.d.ts +1 -1
  241. package/dist/views/Wizard/Wizard.js +1 -1
  242. package/dist/views/Wizard/index.d.ts +4 -4
  243. package/dist/views/Wizard/index.js +2 -2
  244. package/dist/views/types/IFormView.d.ts +1 -1
  245. package/dist/views/types/IListView.d.ts +1 -1
  246. package/dist/widgets/CircleButton.d.ts +2 -2
  247. package/dist/widgets/CircleButton.js +1 -1
  248. package/dist/widgets/GeoPermissionCard.js +3 -3
  249. package/dist/widgets/HomeHeader.js +3 -3
  250. package/dist/widgets/JSONViewer.js +2 -2
  251. package/dist/widgets/MenuCard.d.ts +2 -2
  252. package/dist/widgets/MenuCard.js +1 -1
  253. package/dist/widgets/MenuGrid.d.ts +3 -3
  254. package/dist/widgets/MenuGrid.js +1 -1
  255. package/dist/widgets/MenuSection.d.ts +2 -2
  256. package/dist/widgets/MenuSection.js +1 -1
  257. package/dist/widgets/PromoBanner.js +3 -3
  258. package/dist/widgets/PromoModal.js +4 -4
  259. package/dist/widgets/QuickActions.js +3 -3
  260. package/dist/widgets/ScreenHeader.js +2 -2
  261. package/dist/widgets/TimeZoneSelector.d.ts +1 -1
  262. package/dist/widgets/TimeZoneSelector.js +4 -4
  263. package/dist/widgets/TimeZoneSelectorModal.d.ts +1 -1
  264. package/dist/widgets/TimeZoneSelectorModal.js +5 -5
  265. package/dist/widgets/index.d.ts +16 -16
  266. package/dist/widgets/index.js +10 -10
  267. package/package.json +56 -50
  268. package/tailwind.preset.js +19 -0
  269. package/dist/icons/icon_getters.d.ts +0 -6
  270. package/dist/icons/icon_getters.js +0 -23
@@ -1,29 +1,28 @@
1
- import { FiraCode_400Regular, FiraCode_500Medium } from "@expo-google-fonts/fira-code";
2
- import { Inter_300Light, Inter_400Regular, Inter_500Medium, Inter_600SemiBold, Inter_800ExtraBold, useFonts, } from "@expo-google-fonts/inter";
1
+ import { IBMPlexMono_400Regular, IBMPlexMono_500Medium, } from "@expo-google-fonts/ibm-plex-mono";
2
+ import { IBMPlexSans_300Light, IBMPlexSans_400Regular, IBMPlexSans_500Medium, IBMPlexSans_600SemiBold, IBMPlexSans_700Bold, useFonts, } from "@expo-google-fonts/ibm-plex-sans";
3
3
  const DEFAULT_FONT_FAMILIES = {
4
- light: "Inter_300Light",
5
- regular: "Inter_400Regular",
6
- medium: "Inter_500Medium",
7
- semiBold: "Inter_600SemiBold",
8
- extraBold: "Inter_800ExtraBold",
9
- mono: "FiraCode_400Regular",
10
- monoMedium: "FiraCode_500Medium",
11
- // Title roles default to Inter until the app wires its brand typeface via configureFonts.
12
- titleRegular: "Inter_400Regular",
13
- titleMedium: "Inter_500Medium",
14
- title: "Inter_600SemiBold",
15
- titleBlack: "Inter_800ExtraBold",
4
+ light: "IBMPlexSans_300Light",
5
+ regular: "IBMPlexSans_400Regular",
6
+ medium: "IBMPlexSans_500Medium",
7
+ semiBold: "IBMPlexSans_600SemiBold",
8
+ extraBold: "IBMPlexSans_700Bold",
9
+ mono: "IBMPlexMono_400Regular",
10
+ monoMedium: "IBMPlexMono_500Medium",
11
+ titleRegular: "IBMPlexSans_400Regular",
12
+ titleMedium: "IBMPlexSans_500Medium",
13
+ title: "IBMPlexSans_600SemiBold",
14
+ titleBlack: "IBMPlexSans_700Bold",
16
15
  };
17
16
  export const fontFamilies = { ...DEFAULT_FONT_FAMILIES };
18
17
  /**
19
18
  * Override DS font family names (role → already-loaded family name).
20
19
  * Mutates the singleton in-place so components pick up the change at render time.
21
- * Example: `configureFonts({ title: "Satoshi-Bold", titleBlack: "Satoshi-Black" })`.
20
+ * Example: `configureFonts({ title: "YourBrandTitle-Bold", titleBlack: "YourBrandDisplay-Black" })`.
22
21
  */
23
22
  export function configureFonts(overrides) {
24
23
  Object.assign(fontFamilies, overrides);
25
24
  }
26
- /** Reset all font roles to the defaults (Inter + Fira Code). Useful in tests and stories. */
25
+ /** Reset all font roles to the defaults (IBM Plex Sans + IBM Plex Mono). Useful in tests and stories. */
27
26
  export function resetFonts() {
28
27
  Object.assign(fontFamilies, DEFAULT_FONT_FAMILIES);
29
28
  }
@@ -75,7 +74,7 @@ export const letterSpacing = {
75
74
  };
76
75
  /* -------------------- Typography Variants -------------------- */
77
76
  export const typographyVariants = {
78
- // Display (Satoshi Black — brand character)
77
+ // Display (titleBlack role — typically the brand display typeface)
79
78
  display: {
80
79
  fontSize: fontSizes["7xl"],
81
80
  fontFamily: fontFamilies.titleBlack,
@@ -83,7 +82,7 @@ export const typographyVariants = {
83
82
  lineHeight: fontSizes["7xl"] * lineHeights.tight,
84
83
  letterSpacing: letterSpacing.tight,
85
84
  },
86
- // Headings (Satoshi Bold)
85
+ // Headings (title role)
87
86
  h1: {
88
87
  fontSize: fontSizes["5xl"],
89
88
  fontFamily: fontFamilies.title,
@@ -290,18 +289,17 @@ export const createCustomTextStyle = (fontSize, fontFamily, options) => {
290
289
  * depending directly on expo-font — it's already a transitive dep via this package. */
291
290
  export { useFonts };
292
291
  /* -------------------- Font Loader (optional, convenience) ------------------
293
- * Loads the recommended base fonts (Inter + Fira Code) declared as peer deps.
294
- * The "title" role (e.g. Satoshi) is loaded and wired by the app/Storybook
295
- * via `configureFonts` — the DS never bundles font files. */
292
+ * Loads IBM Plex Sans and IBM Plex Mono, the same faces web UI uses.
293
+ * An app can still point a role at another loaded family with `configureFonts`. */
296
294
  export const useAppFonts = () => {
297
295
  const [loaded] = useFonts({
298
- FiraCode_400Regular,
299
- FiraCode_500Medium,
300
- Inter_300Light,
301
- Inter_400Regular,
302
- Inter_500Medium,
303
- Inter_600SemiBold,
304
- Inter_800ExtraBold,
296
+ IBMPlexMono_400Regular,
297
+ IBMPlexMono_500Medium,
298
+ IBMPlexSans_300Light,
299
+ IBMPlexSans_400Regular,
300
+ IBMPlexSans_500Medium,
301
+ IBMPlexSans_600SemiBold,
302
+ IBMPlexSans_700Bold,
305
303
  });
306
304
  return loaded;
307
305
  };
@@ -1,3 +1,3 @@
1
- import type { ThemeTokens } from "../theme/types";
1
+ import type { ThemeTokens } from "./types.js";
2
2
  export declare function useTheme(): ThemeTokens;
3
3
  export declare const theme: ThemeTokens;
@@ -1,4 +1,4 @@
1
- import { getActiveTheme, getThemeVersion, subscribeTheme, } from "../theme/active";
1
+ import { getActiveTheme, getThemeVersion, subscribeTheme, } from "./active.js";
2
2
  import { useSyncExternalStore } from "react";
3
3
  export function useTheme() {
4
4
  useSyncExternalStore(subscribeTheme, getThemeVersion, getThemeVersion);
@@ -0,0 +1,16 @@
1
+ import type { ThemeTokens } from "./types.js";
2
+ type Issue = {
3
+ path: string;
4
+ message: string;
5
+ };
6
+ /**
7
+ * Lightweight sanity checks on a theme. Returns a list of issues; empty array means OK.
8
+ * Not a hard validator — we don't want to over-constrain creative themes — just guards
9
+ * against the common silent failures (typos in hex, negative sizes, missing primary,
10
+ * WCAG P0 contrast violations on the key on-color pairs, semantic token collisions).
11
+ *
12
+ * Triggered automatically by `setActiveTheme` in dev mode (skipped under Node, since
13
+ * tests intentionally pass partial themes). Can also be called directly.
14
+ */
15
+ export declare function validateTheme(theme: Partial<ThemeTokens>): Issue[];
16
+ export {};
@@ -0,0 +1,200 @@
1
+ import { contrastRatio, resolveOnColor } from "./contrast.js";
2
+ /**
3
+ * Lightweight sanity checks on a theme. Returns a list of issues; empty array means OK.
4
+ * Not a hard validator — we don't want to over-constrain creative themes — just guards
5
+ * against the common silent failures (typos in hex, negative sizes, missing primary,
6
+ * WCAG P0 contrast violations on the key on-color pairs, semantic token collisions).
7
+ *
8
+ * Triggered automatically by `setActiveTheme` in dev mode (skipped under Node, since
9
+ * tests intentionally pass partial themes). Can also be called directly.
10
+ */
11
+ export function validateTheme(theme) {
12
+ const issues = [];
13
+ if (typeof theme.name !== "string" || theme.name.trim() === "") {
14
+ issues.push({ path: "name", message: "Theme must have a non-empty `name`." });
15
+ }
16
+ if (!isHex(theme.primary)) {
17
+ issues.push({ path: "primary", message: `Invalid hex color: ${String(theme.primary)}` });
18
+ }
19
+ if (!isHex(theme.accent)) {
20
+ issues.push({ path: "accent", message: `Invalid hex color: ${String(theme.accent)}` });
21
+ }
22
+ if (!isHex(theme.bg?.page)) {
23
+ issues.push({ path: "bg.page", message: `Invalid hex color: ${String(theme.bg?.page)}` });
24
+ }
25
+ if (!isHex(theme.text?.primary)) {
26
+ issues.push({
27
+ path: "text.primary",
28
+ message: `Invalid hex color: ${String(theme.text?.primary)}`,
29
+ });
30
+ }
31
+ if (theme.pattern) {
32
+ if (!isFiniteSize(theme.pattern.size)) {
33
+ issues.push({
34
+ path: "pattern.size",
35
+ message: `Tile size must be > 0 (got ${String(theme.pattern.size)}).`,
36
+ });
37
+ }
38
+ }
39
+ if (theme.shadow) {
40
+ issues.push(...validateShadow("shadow.sm", theme.shadow.sm));
41
+ issues.push(...validateShadow("shadow.md", theme.shadow.md));
42
+ issues.push(...validateShadow("shadow.lg", theme.shadow.lg));
43
+ }
44
+ issues.push(...validateContrast(theme));
45
+ issues.push(...validateSemanticDistinct(theme));
46
+ return issues;
47
+ }
48
+ function isHex(value) {
49
+ return typeof value === "string" && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value.trim());
50
+ }
51
+ function isFiniteSize(n) {
52
+ return typeof n === "number" && Number.isFinite(n) && n > 0;
53
+ }
54
+ function validateShadow(path, s) {
55
+ const out = [];
56
+ if (typeof s.shadowColor !== "string" || s.shadowColor.trim() === "") {
57
+ out.push({ path: `${path}.shadowColor`, message: "shadowColor must be a string." });
58
+ }
59
+ if (typeof s.shadowOpacity !== "number" || s.shadowOpacity < 0 || s.shadowOpacity > 1) {
60
+ out.push({
61
+ path: `${path}.shadowOpacity`,
62
+ message: `shadowOpacity must be in [0, 1] (got ${s.shadowOpacity}).`,
63
+ });
64
+ }
65
+ return out;
66
+ }
67
+ /**
68
+ * WCAG 2.1 contrast validation. Checks the P0 on-color pairs that every consumer
69
+ * relies on (CTA text/bg, focus ring, body text on surfaces). Flags any pair below the
70
+ * AA minimum (3:1 for UI/non-text, 4.5:1 for body text). Returns warnings as Issue[]
71
+ * entries — never throws — so the dev-mode warning stays non-fatal.
72
+ */
73
+ function validateContrast(theme) {
74
+ const issues = [];
75
+ const checks = [
76
+ {
77
+ fg: theme.text?.onPrimary,
78
+ bg: theme.primary,
79
+ min: 4.5,
80
+ label: "text.onPrimary on primary (CTA)",
81
+ },
82
+ {
83
+ fg: theme.text?.onSecondary,
84
+ bg: theme.secondary,
85
+ min: 4.5,
86
+ label: "text.onSecondary on secondary",
87
+ },
88
+ {
89
+ fg: theme.text?.onAccent,
90
+ bg: theme.accent,
91
+ min: 4.5,
92
+ label: "text.onAccent on accent",
93
+ },
94
+ { fg: theme.border?.focus, bg: theme.bg?.page, min: 3, label: "border.focus on bg.page" },
95
+ { fg: theme.border?.focus, bg: theme.bg?.card, min: 3, label: "border.focus on bg.card" },
96
+ {
97
+ fg: theme.text?.onDanger,
98
+ bg: theme.danger,
99
+ min: 4.5,
100
+ label: "text.onDanger on danger",
101
+ },
102
+ {
103
+ fg: theme.text?.onSuccess,
104
+ bg: theme.success,
105
+ min: 4.5,
106
+ label: "text.onSuccess on success",
107
+ },
108
+ {
109
+ fg: theme.text?.accent,
110
+ bg: theme.bg?.card,
111
+ min: 4.5,
112
+ label: "text.accent on bg.card (brand text)",
113
+ },
114
+ {
115
+ fg: theme.text?.accent,
116
+ bg: theme.bg?.page,
117
+ min: 4.5,
118
+ label: "text.accent on bg.page (brand text)",
119
+ },
120
+ {
121
+ fg: theme.container?.onPrimary,
122
+ bg: theme.container?.primary,
123
+ min: 4.5,
124
+ label: "container.onPrimary on container.primary",
125
+ },
126
+ {
127
+ fg: theme.container?.onSuccess,
128
+ bg: theme.container?.success,
129
+ min: 4.5,
130
+ label: "container.onSuccess on container.success",
131
+ },
132
+ {
133
+ fg: theme.container?.onDanger,
134
+ bg: theme.container?.danger,
135
+ min: 4.5,
136
+ label: "container.onDanger on container.danger",
137
+ },
138
+ ];
139
+ for (const c of checks) {
140
+ if (!isHex(c.fg) || !isHex(c.bg))
141
+ continue;
142
+ const ratio = contrastRatio(c.fg, c.bg);
143
+ if (ratio < c.min) {
144
+ let message = `Contrast ratio ${ratio.toFixed(2)}:1 is below WCAG AA minimum ${c.min}:1 for body/UI text.`;
145
+ if (c.label.includes("onPrimary") && isHex(theme.primary)) {
146
+ const suggested = resolveOnColor(theme.primary);
147
+ message += ` Use resolveOnColor(primary) → ${suggested}.`;
148
+ }
149
+ issues.push({ path: c.label, message });
150
+ }
151
+ }
152
+ return issues;
153
+ }
154
+ /** Roles that must stay visually distinct for maintainable state semantics. */
155
+ function validateSemanticDistinct(theme) {
156
+ const issues = [];
157
+ const pairs = [
158
+ ["bg.disabled vs bg.muted", theme.bg?.disabled, theme.bg?.muted],
159
+ ["text.disabled vs text.muted", theme.text?.disabled, theme.text?.muted],
160
+ ["icon.disabled vs icon.secondary", theme.icon?.disabled, theme.icon?.secondary],
161
+ ];
162
+ for (const [label, a, b] of pairs) {
163
+ if (!isHex(a) || !isHex(b))
164
+ continue;
165
+ if (a.trim().toLowerCase() === b.trim().toLowerCase()) {
166
+ issues.push({
167
+ path: label,
168
+ message: `Tokens share the same hex (${a}). Keep roles distinct so disabled/muted states stay maintainable.`,
169
+ });
170
+ }
171
+ }
172
+ if (theme.state) {
173
+ for (const key of ["hover", "press", "focus", "drag"]) {
174
+ const v = theme.state[key];
175
+ if (typeof v !== "number" || v < 0 || v > 1) {
176
+ issues.push({
177
+ path: `state.${key}`,
178
+ message: `State layer opacity must be in [0, 1] (got ${String(v)}).`,
179
+ });
180
+ }
181
+ }
182
+ }
183
+ if (theme.material) {
184
+ if (typeof theme.material.opacity === "number" &&
185
+ (theme.material.opacity < 0 || theme.material.opacity > 1)) {
186
+ issues.push({
187
+ path: "material.opacity",
188
+ message: `material.opacity must be in [0, 1] (got ${theme.material.opacity}).`,
189
+ });
190
+ }
191
+ if (typeof theme.material.blur === "number" &&
192
+ (!Number.isFinite(theme.material.blur) || theme.material.blur < 0)) {
193
+ issues.push({
194
+ path: "material.blur",
195
+ message: `material.blur must be ≥ 0 (got ${theme.material.blur}).`,
196
+ });
197
+ }
198
+ }
199
+ return issues;
200
+ }
@@ -1,2 +1,2 @@
1
- export { motion } from "../tokens/motion";
2
- export { duration, type DurationToken, easing, type EasingToken, spring, type SpringToken, } from "../tokens/motion";
1
+ export { motion } from "./motion.js";
2
+ export { duration, type DurationToken, easing, type EasingToken, spring, type SpringToken, } from "./motion.js";
@@ -1,2 +1,2 @@
1
- export { motion } from "../tokens/motion";
2
- export { duration, easing, spring, } from "../tokens/motion";
1
+ export { motion } from "./motion.js";
2
+ export { duration, easing, spring, } from "./motion.js";
@@ -1,5 +1,5 @@
1
- import { type SpinnerVariant } from "../Feedback/Feedback.Spinner";
2
- import type { AppBarBackground } from "../Navigation/Navigation.AppBar";
1
+ import { type SpinnerVariant } from "../Feedback/Feedback.Spinner.js";
2
+ import type { AppBarBackground } from "../Navigation/Navigation.AppBar.js";
3
3
  import type { ReactNode } from "react";
4
4
  import { type ImageSourcePropType, type ViewStyle } from "react-native";
5
5
  export interface AppSplashViewProps {
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import GradientSurface from "../Display/Display.GradientSurface";
3
- import { Pattern } from "../Display/Display.Pattern";
4
- import Spinner from "../Feedback/Feedback.Spinner";
2
+ import GradientSurface from "../Display/Display.GradientSurface.js";
3
+ import { Pattern } from "../Display/Display.Pattern.js";
4
+ import Spinner from "../Feedback/Feedback.Spinner.js";
5
5
  import { Image, View } from "react-native";
6
6
  export function AppSplashView({ background, logo, loadingVariant = "dots", loader, style, }) {
7
7
  return (_jsxs(GradientSurface, { className: "flex-1", colors: background?.colors, end: background?.end, padding: "none", preset: background?.surface ?? "night-green", radius: "none", start: background?.start, style: { flex: 1, ...style }, children: [background?.pattern ? (_jsx(Pattern, { color: background.patternColor ?? "#FFFFFF", kind: background.pattern, opacity: background.patternOpacity ?? 0.18 })) : null, _jsxs(View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: [logo ? (_jsx(Image, { source: logo, style: { width: 140, height: 140, resizeMode: "contain", marginBottom: 40 } })) : null, loader ?? (_jsx(Spinner, { color: "rgba(255,255,255,0.9)", size: "large", variant: loadingVariant }))] })] }));
@@ -1,4 +1,4 @@
1
- import type { AppBarBackground } from "../Navigation/Navigation.AppBar";
1
+ import type { AppBarBackground } from "../Navigation/Navigation.AppBar.js";
2
2
  import { ReactNode } from "react";
3
3
  import { type ImageSourcePropType } from "react-native";
4
4
  interface AuthFormProps {
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
3
- import AuthContainer from "../layouts/AuthContainer";
4
- import { Typography } from "../Typography";
2
+ import { Display } from "../Display/index.js";
3
+ import AuthContainer from "../layouts/AuthContainer.js";
4
+ import { Typography } from "../Typography/index.js";
5
5
  import { View } from "react-native";
6
6
  const Logo = Display.Logo;
7
7
  const Text = Typography.Text;
@@ -1,5 +1,5 @@
1
- import type { AppBarBackground } from "../Navigation/Navigation.AppBar";
2
- import { type SegmentedControlProps } from "../Navigation/Navigation.SegmentedControl";
1
+ import type { AppBarBackground } from "../Navigation/Navigation.AppBar.js";
2
+ import { type SegmentedControlProps } from "../Navigation/Navigation.SegmentedControl.js";
3
3
  import React, { ReactNode } from "react";
4
4
  import { type ImageSourcePropType } from "react-native";
5
5
  interface FormViewProps<T> {
@@ -1,13 +1,13 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
3
- import { ErrorBoundary, Feedback } from "../Feedback";
4
- import { useBottomInset } from "../layouts/BottomInset";
5
- import Container from "../layouts/Container";
6
- import { AppBar } from "../Navigation/Navigation.AppBar";
7
- import { MenuSection } from "../Navigation/Navigation.MenuSection";
8
- import { SegmentedControl, } from "../Navigation/Navigation.SegmentedControl";
9
- import { useTheme } from "../theme";
10
- import { FormViewProvider, useFormView } from "../views/FormViewV2.context";
2
+ import { Display } from "../Display/index.js";
3
+ import { ErrorBoundary, Feedback } from "../Feedback/index.js";
4
+ import { useBottomInset } from "../layouts/BottomInset.js";
5
+ import Container from "../layouts/Container.js";
6
+ import { AppBar } from "../Navigation/Navigation.AppBar.js";
7
+ import { MenuSection } from "../Navigation/Navigation.MenuSection.js";
8
+ import { SegmentedControl, } from "../Navigation/Navigation.SegmentedControl.js";
9
+ import { useTheme } from "../theme/index.js";
10
+ import { FormViewProvider, useFormView } from "./FormViewV2.context.js";
11
11
  import React from "react";
12
12
  import { RefreshControl, View } from "react-native";
13
13
  import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
@@ -1,6 +1,6 @@
1
- import { type SearchHistoryProps } from "../Display/Display.SearchHistory";
2
- import type { AppBarBackground } from "../Navigation/Navigation.AppBar";
3
- import { type SegmentedControlProps } from "../Navigation/Navigation.SegmentedControl";
1
+ import { type SearchHistoryProps } from "../Display/Display.SearchHistory.js";
2
+ import type { AppBarBackground } from "../Navigation/Navigation.AppBar.js";
3
+ import { type SegmentedControlProps } from "../Navigation/Navigation.SegmentedControl.js";
4
4
  import React, { ReactNode } from "react";
5
5
  import { StyleProp, ViewStyle } from "react-native";
6
6
  interface ListViewProps<T> {
@@ -1,16 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
- import { Display } from "../Display";
3
- import SearchHistory from "../Display/Display.SearchHistory";
4
- import { ErrorBoundary, Feedback } from "../Feedback";
5
- import { useBottomInset } from "../layouts/BottomInset";
6
- import Container from "../layouts/Container";
7
- import { Navigation } from "../Navigation";
8
- import { SegmentedControl, } from "../Navigation/Navigation.SegmentedControl";
9
- import { useTheme } from "../theme";
10
- import { cn, tv } from "../theme/tw";
11
- import { Typography } from "../Typography";
12
- import { ListViewProvider, useListView } from "../views/ListViewV2.context";
13
- import { toRowItems } from "../views/types/IListView";
2
+ import { Display } from "../Display/index.js";
3
+ import SearchHistory from "../Display/Display.SearchHistory.js";
4
+ import { ErrorBoundary, Feedback } from "../Feedback/index.js";
5
+ import { useBottomInset } from "../layouts/BottomInset.js";
6
+ import Container from "../layouts/Container.js";
7
+ import { Navigation } from "../Navigation/index.js";
8
+ import { SegmentedControl, } from "../Navigation/Navigation.SegmentedControl.js";
9
+ import { useTheme } from "../theme/index.js";
10
+ import { cn, tv } from "../theme/tw.js";
11
+ import { Typography } from "../Typography/index.js";
12
+ import { ListViewProvider, useListView } from "./ListViewV2.context.js";
13
+ import { toRowItems } from "./types/IListView.js";
14
14
  import { useCallback, useEffect, useMemo, useState } from "react";
15
15
  import { FlatList, RefreshControl, ScrollView, TouchableOpacity, View, } from "react-native";
16
16
  function ListViewRoot({ name, description, items, isLoading = false, hasError = false, errorMessage, readonly = false, onRefresh, onRetry, onPressItem, onDeleteItem, onSearch, onBack, onLoadMore, loadingMore = false, backgroundColor, withContainer = true, children, }) {
@@ -69,12 +69,12 @@ function HeaderSearchHistory(props) {
69
69
  function HeaderFilters({ children }) {
70
70
  return _jsx(View, { className: "px-4 py-2 items-center", children: children });
71
71
  }
72
- // Modern filter pills (2026): rounded-full, active = accent (green), inactive = muted track.
72
+ // Active filter uses the action color. The capsule is a pill; the rest of the chrome is not.
73
73
  const filterChip = tv({
74
74
  base: "py-1.5 px-3.5 items-center justify-center rounded-full",
75
75
  variants: {
76
76
  active: {
77
- true: "bg-accent",
77
+ true: "bg-primary",
78
78
  false: "bg-bg-muted",
79
79
  },
80
80
  },
@@ -83,7 +83,7 @@ const filterChip = tv({
83
83
  const filterChipText = tv({
84
84
  variants: {
85
85
  active: {
86
- true: "text-text-inverse font-semibold",
86
+ true: "text-text-on-primary font-semibold",
87
87
  false: "text-text-secondary",
88
88
  },
89
89
  },
@@ -153,7 +153,7 @@ function ContentList({ children, contentWithMargin, }) {
153
153
  marginTop: 2,
154
154
  paddingHorizontal: contentWithMargin ? 4 : 0,
155
155
  backgroundColor: theme.bg.page,
156
- }, children: _jsx(FlatList, { contentContainerStyle: bottomInset ? { paddingBottom: bottomInset } : undefined, data: rowItems, keyExtractor: (item) => String(item.index), ListFooterComponent: loadingMore ? (_jsx(View, { className: "py-4", children: _jsx(Feedback.Spinner, { size: "small" }) })) : null, onEndReached: onLoadMore ? () => onLoadMore() : undefined, onEndReachedThreshold: 0.5, refreshControl: _jsx(RefreshControl, { colors: [theme.primary], onRefresh: handleRefresh, refreshing: showRefreshing }), renderItem: renderItem, scrollEnabled: true, showsVerticalScrollIndicator: false }) }));
156
+ }, children: _jsx(FlatList, { contentContainerStyle: bottomInset ? { paddingBottom: bottomInset } : undefined, data: rowItems, keyExtractor: (item) => String(item.index), ListFooterComponent: loadingMore ? (_jsx(View, { className: "py-4", children: _jsx(Feedback.Spinner, { size: "small" }) })) : undefined, onEndReached: onLoadMore ? () => onLoadMore() : undefined, onEndReachedThreshold: 0.5, refreshControl: _jsx(RefreshControl, { colors: [theme.primary], onRefresh: handleRefresh, refreshing: showRefreshing }), renderItem: renderItem, scrollEnabled: true, showsVerticalScrollIndicator: false }) }));
157
157
  }
158
158
  function Footer({ children }) {
159
159
  const { items } = useListView();
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { ErrorBoundary } from "../../Feedback";
2
+ import { ErrorBoundary } from "../../Feedback/index.js";
3
3
  import { createContext, useCallback, useContext, useMemo, useState } from "react";
4
4
  import { ActivityIndicator, Text, View } from "react-native";
5
5
  const WizardContext = createContext(null);
@@ -1,4 +1,4 @@
1
- import type { WizardContextValue, WizardProviderProps, WizardStepId } from "../../views/Wizard/Wizard.context";
1
+ import type { WizardContextValue, WizardProviderProps, WizardStepId } from "./Wizard.context.js";
2
2
  import type { FC, ReactNode } from "react";
3
3
  export interface WizardStepGuard {
4
4
  canEnter?: () => boolean | Promise<boolean>;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
- import { useWizard, WizardProvider } from "../../views/Wizard/Wizard.context";
2
+ import { useWizard, WizardProvider } from "./Wizard.context.js";
3
3
  import { useEffect } from "react";
4
4
  import { TouchableOpacity } from "react-native";
5
5
  const WizardRoot = (props) => {
@@ -1,4 +1,4 @@
1
- export type { WizardBackProps, WizardGoProps, WizardGuardProps, WizardStepGuard, WizardStepLifecycle, WizardStepProps, } from "../../views/Wizard/Wizard";
2
- export { Wizard } from "../../views/Wizard/Wizard";
3
- export type { WizardContextValue, WizardProviderProps, WizardStepId, } from "../../views/Wizard/Wizard.context";
4
- export { useWizard } from "../../views/Wizard/Wizard.context";
1
+ export type { WizardBackProps, WizardGoProps, WizardGuardProps, WizardStepGuard, WizardStepLifecycle, WizardStepProps, } from "./Wizard.js";
2
+ export { Wizard } from "./Wizard.js";
3
+ export type { WizardContextValue, WizardProviderProps, WizardStepId, } from "./Wizard.context.js";
4
+ export { useWizard } from "./Wizard.context.js";
@@ -1,2 +1,2 @@
1
- export { Wizard } from "../../views/Wizard/Wizard";
2
- export { useWizard } from "../../views/Wizard/Wizard.context";
1
+ export { Wizard } from "./Wizard.js";
2
+ export { useWizard } from "./Wizard.context.js";
@@ -1,4 +1,4 @@
1
- import { UIItem } from "../../views/types/UIItem";
1
+ import { UIItem } from "./UIItem.js";
2
2
  import { ReactNode } from "react";
3
3
  export interface IFormView<T> extends UIItem {
4
4
  name: string;
@@ -1,4 +1,4 @@
1
- import { UICollectionItem, UIItem } from "../../views/types/UIItem";
1
+ import { UICollectionItem, UIItem } from "./UIItem.js";
2
2
  import { ReactNode } from "react";
3
3
  export type IRowItem<T> = T & UIItem & {
4
4
  id: string | number;
@@ -1,3 +1,3 @@
1
1
  /** @deprecated Import from `@sincpro/mobile-ui/Display` → `Display.CircleButton` instead. */
2
- export type { CircleButtonProps } from "../Display/Display.CircleButton";
3
- export { CircleButton } from "../Display/Display.CircleButton";
2
+ export type { CircleButtonProps } from "../Display/Display.CircleButton.js";
3
+ export { CircleButton } from "../Display/Display.CircleButton.js";
@@ -1 +1 @@
1
- export { CircleButton } from "../Display/Display.CircleButton";
1
+ export { CircleButton } from "../Display/Display.CircleButton.js";
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { Display, Form } from "../index";
3
- import { theme } from "../theme";
4
- import { Typography } from "../Typography";
2
+ import { Display, Form } from "../index.js";
3
+ import { theme } from "../theme/index.js";
4
+ import { Typography } from "../Typography/index.js";
5
5
  import { View } from "react-native";
6
6
  import { tv } from "tailwind-variants";
7
7
  const statusTextVariants = tv({
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { Display, Typography } from "../index";
3
- import GradientContainer from "../layouts/GradientContainer";
4
- import { theme } from "../theme";
2
+ import { Display, Typography } from "../index.js";
3
+ import GradientContainer from "../layouts/GradientContainer.js";
4
+ import { theme } from "../theme/index.js";
5
5
  import { TouchableOpacity, View } from "react-native";
6
6
  /**
7
7
  * @deprecated Legacy style (gradient). For new top bars use `Navigation.AppBar`.
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "nativewind/jsx-runtime";
2
- import { ThemedActivityIndicator } from "../theme";
3
- import { fontFamilies } from "../theme/typography";
2
+ import { ThemedActivityIndicator } from "../theme/index.js";
3
+ import { fontFamilies } from "../theme/typography.js";
4
4
  import { useEffect, useMemo, useState } from "react";
5
5
  import { Text, View } from "react-native";
6
6
  const parseDeepJson = (value) => {
@@ -1,3 +1,3 @@
1
1
  /** @deprecated Import from `@sincpro/mobile-ui/Display` → `Display.MenuCard` instead. */
2
- export type { MenuCardProps } from "../Display/Display.MenuCard";
3
- export { MenuCard } from "../Display/Display.MenuCard";
2
+ export type { MenuCardProps } from "../Display/Display.MenuCard.js";
3
+ export { MenuCard } from "../Display/Display.MenuCard.js";
@@ -1 +1 @@
1
- export { MenuCard } from "../Display/Display.MenuCard";
1
+ export { MenuCard } from "../Display/Display.MenuCard.js";
@@ -1,5 +1,5 @@
1
1
  /** @deprecated Import from `@sincpro/mobile-ui/Display` → `Display.MenuGrid` instead. */
2
- export type { MenuGridItem, MenuGridProps, } from "../Display/Display.MenuGrid";
3
- export { MenuGrid } from "../Display/Display.MenuGrid";
2
+ export type { MenuGridItem, MenuGridProps, } from "../Display/Display.MenuGrid.js";
3
+ export { MenuGrid } from "../Display/Display.MenuGrid.js";
4
4
  /** @deprecated Renamed to `MenuGridItem`. */
5
- export type { MenuGridItem as MenuItem } from "../Display/Display.MenuGrid";
5
+ export type { MenuGridItem as MenuItem } from "../Display/Display.MenuGrid.js";
@@ -1 +1 @@
1
- export { MenuGrid } from "../Display/Display.MenuGrid";
1
+ export { MenuGrid } from "../Display/Display.MenuGrid.js";
@@ -1,3 +1,3 @@
1
1
  /** @deprecated Import from `@sincpro/mobile-ui/Navigation` → `Navigation.MenuSection` instead. */
2
- export type { MenuSectionProps } from "../Navigation/Navigation.MenuSection";
3
- export { MenuSection } from "../Navigation/Navigation.MenuSection";
2
+ export type { MenuSectionProps } from "../Navigation/Navigation.MenuSection.js";
3
+ export { MenuSection } from "../Navigation/Navigation.MenuSection.js";
@@ -1 +1 @@
1
- export { MenuSection } from "../Navigation/Navigation.MenuSection";
1
+ export { MenuSection } from "../Navigation/Navigation.MenuSection.js";