@btndprojects/loam-ui-native 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/LICENSE +21 -0
  2. package/dist/accordion/index.js +3 -0
  3. package/dist/adaptive/index.js +2 -0
  4. package/dist/alert/index.js +3 -0
  5. package/dist/analyzer/index.js +6 -0
  6. package/dist/announcement/index.js +6 -0
  7. package/dist/audio-player/index.js +3 -0
  8. package/dist/avatar/index.js +3 -0
  9. package/dist/avatar-group/index.js +3 -0
  10. package/dist/badge/index.js +5 -0
  11. package/dist/banner/index.js +2 -0
  12. package/dist/board/index.js +7 -0
  13. package/dist/button/index.js +5 -0
  14. package/dist/camera-permission/index.js +13 -0
  15. package/dist/capture-result/index.js +18 -0
  16. package/dist/card/index.js +4 -0
  17. package/dist/card-form/index.js +10 -0
  18. package/dist/carousel/index.js +2 -0
  19. package/dist/chart/index.js +6 -0
  20. package/dist/charts/index.js +7 -0
  21. package/dist/checkbox/index.js +7 -0
  22. package/dist/checklist/index.js +10 -0
  23. package/dist/checkout/index.js +13 -0
  24. package/dist/chip/index.js +7 -0
  25. package/dist/chunk-223Q2T2Q.js +229 -0
  26. package/dist/chunk-2A5NIQAK.js +254 -0
  27. package/dist/chunk-2GK6PHGE.js +363 -0
  28. package/dist/chunk-2WUTXHMU.js +1 -0
  29. package/dist/chunk-2ZZ7TDJ4.js +324 -0
  30. package/dist/chunk-35OFI3JG.js +499 -0
  31. package/dist/chunk-3ARE4TES.js +195 -0
  32. package/dist/chunk-3ECPOSKO.js +1 -0
  33. package/dist/chunk-3ENTMPQY.js +229 -0
  34. package/dist/chunk-3HJH6FF4.js +98 -0
  35. package/dist/chunk-3NMD74ZU.js +4 -0
  36. package/dist/chunk-3WPW4KUN.js +182 -0
  37. package/dist/chunk-47FWHGUN.js +394 -0
  38. package/dist/chunk-4BXMXBJO.js +141 -0
  39. package/dist/chunk-4DS5ZWVC.js +83 -0
  40. package/dist/chunk-4GBOGOTV.js +295 -0
  41. package/dist/chunk-4SZYY6AN.js +99 -0
  42. package/dist/chunk-4YIP3CWS.js +237 -0
  43. package/dist/chunk-4YQOR7JM.js +204 -0
  44. package/dist/chunk-4ZAHCY44.js +177 -0
  45. package/dist/chunk-52X2VYTD.js +228 -0
  46. package/dist/chunk-5P26LBDL.js +1 -0
  47. package/dist/chunk-5XLRYDAX.js +1 -0
  48. package/dist/chunk-5YNTNN5A.js +177 -0
  49. package/dist/chunk-66SG2H23.js +129 -0
  50. package/dist/chunk-6HT2LP62.js +504 -0
  51. package/dist/chunk-6N33LFQA.js +35 -0
  52. package/dist/chunk-6X6PQ443.js +432 -0
  53. package/dist/chunk-7CFF4HXS.js +126 -0
  54. package/dist/chunk-7O2FMUPT.js +755 -0
  55. package/dist/chunk-AI4DWZCD.js +162 -0
  56. package/dist/chunk-AWJOCGFZ.js +213 -0
  57. package/dist/chunk-AZRX6SAC.js +285 -0
  58. package/dist/chunk-B54QE2FN.js +1 -0
  59. package/dist/chunk-BC475SJH.js +1 -0
  60. package/dist/chunk-BEDBFJND.js +202 -0
  61. package/dist/chunk-BTTFCMKG.js +166 -0
  62. package/dist/chunk-BV3B2HYZ.js +1635 -0
  63. package/dist/chunk-C2NTXVWM.js +98 -0
  64. package/dist/chunk-CDRZHT42.js +424 -0
  65. package/dist/chunk-CJ5EOYZE.js +62 -0
  66. package/dist/chunk-CUMUNPXY.js +128 -0
  67. package/dist/chunk-CUS3ZSCU.js +1 -0
  68. package/dist/chunk-CYRBHQQZ.js +411 -0
  69. package/dist/chunk-DHWADYZX.js +144 -0
  70. package/dist/chunk-DKCSPATL.js +1 -0
  71. package/dist/chunk-DM5QUKKO.js +326 -0
  72. package/dist/chunk-DSJBXLUG.js +845 -0
  73. package/dist/chunk-DYBH2I6W.js +1 -0
  74. package/dist/chunk-DZ255O2F.js +1 -0
  75. package/dist/chunk-E35BPSGW.js +1 -0
  76. package/dist/chunk-EJBDRVIH.js +166 -0
  77. package/dist/chunk-F43NP42L.js +1 -0
  78. package/dist/chunk-F5XNPWS7.js +1024 -0
  79. package/dist/chunk-FIF2M24N.js +1521 -0
  80. package/dist/chunk-FOKG57CR.js +993 -0
  81. package/dist/chunk-G3HOYSF7.js +1 -0
  82. package/dist/chunk-GDKZTW34.js +395 -0
  83. package/dist/chunk-GL7B2DOW.js +134 -0
  84. package/dist/chunk-GNNJ4GCC.js +471 -0
  85. package/dist/chunk-GNZ56EUI.js +1 -0
  86. package/dist/chunk-H6NIOQHK.js +346 -0
  87. package/dist/chunk-H6PC7RDA.js +1 -0
  88. package/dist/chunk-HPPW424V.js +334 -0
  89. package/dist/chunk-HQOQIBJI.js +1 -0
  90. package/dist/chunk-HU2EQNRZ.js +44 -0
  91. package/dist/chunk-IIQTAY3J.js +715 -0
  92. package/dist/chunk-ITTYJZWX.js +271 -0
  93. package/dist/chunk-IVNRBPGC.js +1018 -0
  94. package/dist/chunk-J4KLDGI4.js +1 -0
  95. package/dist/chunk-J7Q7VCVC.js +254 -0
  96. package/dist/chunk-JDEOITQ2.js +1 -0
  97. package/dist/chunk-JNH2TYIN.js +96 -0
  98. package/dist/chunk-JRLTGLN4.js +1 -0
  99. package/dist/chunk-JTRJJLKL.js +1 -0
  100. package/dist/chunk-JUAMLEHX.js +379 -0
  101. package/dist/chunk-JXJB2X6M.js +131 -0
  102. package/dist/chunk-KMI5ML5I.js +262 -0
  103. package/dist/chunk-KTAC4MGE.js +4 -0
  104. package/dist/chunk-LAECSR4H.js +178 -0
  105. package/dist/chunk-LK4BCSGX.js +1 -0
  106. package/dist/chunk-LOE5YNN3.js +470 -0
  107. package/dist/chunk-LRJNDEIA.js +302 -0
  108. package/dist/chunk-LSS54GLJ.js +116 -0
  109. package/dist/chunk-LZLHELAG.js +137 -0
  110. package/dist/chunk-M2LUXGKZ.js +1 -0
  111. package/dist/chunk-MOUJOP55.js +425 -0
  112. package/dist/chunk-N32RGOA5.js +159 -0
  113. package/dist/chunk-N5ZNE2YE.js +1 -0
  114. package/dist/chunk-NBNCBML6.js +1 -0
  115. package/dist/chunk-NKB7BZYK.js +167 -0
  116. package/dist/chunk-NQYBUO3K.js +1795 -0
  117. package/dist/chunk-NY2U3PBI.js +59 -0
  118. package/dist/chunk-O4AEHWII.js +464 -0
  119. package/dist/chunk-O7AE6DAF.js +146 -0
  120. package/dist/chunk-OETCUXQP.js +134 -0
  121. package/dist/chunk-OOPPQH27.js +179 -0
  122. package/dist/chunk-OPXFZ4Y5.js +204 -0
  123. package/dist/chunk-P23EQNRQ.js +338 -0
  124. package/dist/chunk-PJXUJYS6.js +248 -0
  125. package/dist/chunk-PNWUWOBF.js +1 -0
  126. package/dist/chunk-PUPM2YGF.js +376 -0
  127. package/dist/chunk-PZXZJBMP.js +620 -0
  128. package/dist/chunk-Q72LJOVE.js +169 -0
  129. package/dist/chunk-QCDXZBC5.js +247 -0
  130. package/dist/chunk-QDYDBCFP.js +197 -0
  131. package/dist/chunk-QJJ6MADV.js +274 -0
  132. package/dist/chunk-QKXCPTFS.js +349 -0
  133. package/dist/chunk-QWCMU5B2.js +860 -0
  134. package/dist/chunk-RGQWWKLA.js +634 -0
  135. package/dist/chunk-RIBDXGUG.js +108 -0
  136. package/dist/chunk-RJQOOHT2.js +214 -0
  137. package/dist/chunk-RNGLIHFA.js +191 -0
  138. package/dist/chunk-RQ3HASCC.js +6 -0
  139. package/dist/chunk-RSOJT5YW.js +124 -0
  140. package/dist/chunk-RTIKSY6A.js +1 -0
  141. package/dist/chunk-RUZHTGKB.js +237 -0
  142. package/dist/chunk-RW6ZL2FQ.js +284 -0
  143. package/dist/chunk-S7F6XLTK.js +540 -0
  144. package/dist/chunk-SBMNWWBV.js +155 -0
  145. package/dist/chunk-SDTQPRRB.js +1 -0
  146. package/dist/chunk-SYNOJOQO.js +377 -0
  147. package/dist/chunk-T753XT36.js +1 -0
  148. package/dist/chunk-TKQYWZ5V.js +196 -0
  149. package/dist/chunk-TKVFVF5D.js +95 -0
  150. package/dist/chunk-TOXAGRDQ.js +144 -0
  151. package/dist/chunk-TUTI5HOZ.js +112 -0
  152. package/dist/chunk-U7TFM2JA.js +140 -0
  153. package/dist/chunk-UC2WGUP3.js +627 -0
  154. package/dist/chunk-UWFLYMAR.js +1126 -0
  155. package/dist/chunk-UWSZB7BJ.js +1 -0
  156. package/dist/chunk-UYG5L34B.js +87 -0
  157. package/dist/chunk-VBOXAEPI.js +336 -0
  158. package/dist/chunk-VCDBXW5H.js +188 -0
  159. package/dist/chunk-VCXPHHDS.js +1 -0
  160. package/dist/chunk-VEAYTRPX.js +414 -0
  161. package/dist/chunk-VFCUIDRT.js +1 -0
  162. package/dist/chunk-VQHPQEUH.js +273 -0
  163. package/dist/chunk-VXDZFJGP.js +874 -0
  164. package/dist/chunk-WS56BL3D.js +1 -0
  165. package/dist/chunk-WSW6ZFAQ.js +98 -0
  166. package/dist/chunk-WVKKJA6U.js +870 -0
  167. package/dist/chunk-XNUVB5OL.js +375 -0
  168. package/dist/chunk-XOSCY2CW.js +242 -0
  169. package/dist/chunk-XXXEFXY5.js +99 -0
  170. package/dist/chunk-Y5CSSPV4.js +1 -0
  171. package/dist/chunk-Y6DU4J47.js +1 -0
  172. package/dist/chunk-YC6WORFL.js +535 -0
  173. package/dist/chunk-YDGVJETP.js +60 -0
  174. package/dist/chunk-YF4NSSMT.js +366 -0
  175. package/dist/chunk-YG3ZJHGU.js +223 -0
  176. package/dist/chunk-YIJ55TBC.js +1 -0
  177. package/dist/chunk-YKZ4RZZF.js +1 -0
  178. package/dist/chunk-YLLCXTMC.js +37 -0
  179. package/dist/chunk-YTA74UZR.js +1 -0
  180. package/dist/chunk-Z7H7VSFZ.js +323 -0
  181. package/dist/chunk-ZK2H4O5P.js +1 -0
  182. package/dist/chunk-ZVFE5QGU.js +524 -0
  183. package/dist/coachmark/index.js +4 -0
  184. package/dist/code-block/index.js +4 -0
  185. package/dist/color-field/index.js +7 -0
  186. package/dist/commerce/index.js +20 -0
  187. package/dist/connectivity/index.js +2 -0
  188. package/dist/context-menu/index.js +5 -0
  189. package/dist/copy-button/index.js +3 -0
  190. package/dist/data-grid/index.js +24 -0
  191. package/dist/date-range-picker/index.js +13 -0
  192. package/dist/description-list/index.js +2 -0
  193. package/dist/dialog/index.js +3 -0
  194. package/dist/empty-state/index.js +3 -0
  195. package/dist/error-summary/index.js +3 -0
  196. package/dist/fab/index.js +2 -0
  197. package/dist/file-upload/index.js +9 -0
  198. package/dist/filter-bar/index.js +8 -0
  199. package/dist/flow-run/index.js +14 -0
  200. package/dist/form/index.js +3 -0
  201. package/dist/gallery/index.js +2 -0
  202. package/dist/header/index.js +5 -0
  203. package/dist/hold-to-confirm/index.js +4 -0
  204. package/dist/index.d.ts +22883 -0
  205. package/dist/index.js +158 -0
  206. package/dist/infinite-list/index.js +2 -0
  207. package/dist/inline-edit/index.js +5 -0
  208. package/dist/input/index.js +5 -0
  209. package/dist/interactions/index.js +2 -0
  210. package/dist/invoice/index.js +10 -0
  211. package/dist/kbd/index.js +1 -0
  212. package/dist/keyboard/index.js +3 -0
  213. package/dist/list-row/index.js +7 -0
  214. package/dist/log-viewer/index.js +2 -0
  215. package/dist/map-view/index.js +3 -0
  216. package/dist/markdown/index.js +6 -0
  217. package/dist/metric/index.js +4 -0
  218. package/dist/money/index.js +3 -0
  219. package/dist/nav-drawer/index.js +2 -0
  220. package/dist/navigation/index.js +2 -0
  221. package/dist/notification-center/index.js +16 -0
  222. package/dist/number-roll/index.js +3 -0
  223. package/dist/one-handed/index.js +5 -0
  224. package/dist/os-surfaces/index.js +3 -0
  225. package/dist/otp/index.js +7 -0
  226. package/dist/page-header/index.js +1 -0
  227. package/dist/payment-method/index.js +12 -0
  228. package/dist/payment-status/index.js +16 -0
  229. package/dist/permission/index.js +2 -0
  230. package/dist/picker/index.js +7 -0
  231. package/dist/progress/index.js +5 -0
  232. package/dist/pull-to-refresh/index.js +4 -0
  233. package/dist/radio-group/index.js +6 -0
  234. package/dist/rating/index.js +2 -0
  235. package/dist/receivables/index.js +20 -0
  236. package/dist/refund/index.js +16 -0
  237. package/dist/save-status/index.js +3 -0
  238. package/dist/scroll-area/index.js +1 -0
  239. package/dist/search-bar/index.js +5 -0
  240. package/dist/segmented-control/index.js +5 -0
  241. package/dist/sheet/index.js +4 -0
  242. package/dist/skeleton/index.js +2 -0
  243. package/dist/slider/index.js +5 -0
  244. package/dist/spinner/index.js +2 -0
  245. package/dist/split-button/index.js +7 -0
  246. package/dist/spotlight/index.js +2 -0
  247. package/dist/stage-timeline/index.js +4 -0
  248. package/dist/status-dot/index.js +2 -0
  249. package/dist/stepper/index.js +6 -0
  250. package/dist/streaming-text/index.js +3 -0
  251. package/dist/survey/index.js +19 -0
  252. package/dist/switch/index.js +5 -0
  253. package/dist/system-state/index.js +4 -0
  254. package/dist/tab-bar/index.js +2 -0
  255. package/dist/tabs/index.js +2 -0
  256. package/dist/textarea/index.js +6 -0
  257. package/dist/thinking/index.js +2 -0
  258. package/dist/timeline/index.js +4 -0
  259. package/dist/toast/index.js +2 -0
  260. package/dist/toolbar/index.js +2 -0
  261. package/dist/tour/index.js +11 -0
  262. package/dist/truncation-notice/index.js +2 -0
  263. package/dist/update-notice/index.js +11 -0
  264. package/dist/video-player/index.js +2 -0
  265. package/dist/viewfinder/index.js +5 -0
  266. package/dist/widget/index.js +4 -0
  267. package/dist/wizard/index.js +6 -0
  268. package/package.json +76 -3
  269. package/README.md +0 -3
@@ -0,0 +1,262 @@
1
+ import { Spinner } from './chunk-O7AE6DAF.js';
2
+ import { Skeleton, SkeletonText } from './chunk-RIBDXGUG.js';
3
+ import * as React from 'react';
4
+ import { StyleSheet, Animated, View, Pressable, Text, Image } from 'react-native';
5
+ import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
+
8
+ function Card({
9
+ children,
10
+ variant = "default",
11
+ onPress,
12
+ style,
13
+ accessibilityLabel,
14
+ selected = false,
15
+ busy = false,
16
+ busyLabel = "Loading",
17
+ skeleton = false,
18
+ emphasized = false,
19
+ dragging = false,
20
+ motion = "full"
21
+ }) {
22
+ const theme = useLoamTheme();
23
+ const { styles } = useStyles(sheet, {
24
+ variant: variant === "default" ? void 0 : variant,
25
+ selected,
26
+ emphasized,
27
+ dragging
28
+ });
29
+ const scale = React.useRef(new Animated.Value(1)).current;
30
+ const spring = (to) => Animated.spring(scale, {
31
+ toValue: to,
32
+ useNativeDriver: true,
33
+ speed: 40,
34
+ bounciness: 6
35
+ }).start();
36
+ if (skeleton) {
37
+ return /* @__PURE__ */ jsx(
38
+ View,
39
+ {
40
+ style: [styles.base, style],
41
+ accessibilityElementsHidden: true,
42
+ importantForAccessibility: "no-hide-descendants",
43
+ children: /* @__PURE__ */ jsxs(View, { style: styles.skeletonBody, children: [
44
+ /* @__PURE__ */ jsxs(View, { style: styles.skeletonHead, children: [
45
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 160, height: 18 }),
46
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 100 })
47
+ ] }),
48
+ /* @__PURE__ */ jsx(SkeletonText, { lines: 3 }),
49
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rect", width: 96, height: 32, radius: "md" })
50
+ ] })
51
+ }
52
+ );
53
+ }
54
+ const tint = dragging ? theme.state.dragged : selected ? theme.state.selected : null;
55
+ const tintOverlay = tint ? /* @__PURE__ */ jsx(View, { style: [StyleSheet.absoluteFill, { backgroundColor: tint, pointerEvents: "none" }] }) : null;
56
+ const lift = dragging && motion === "full" && !theme.reduceMotion;
57
+ const dragTransform = lift ? [{ scale: 1.022 }, { rotate: theme.rtl ? "-1.2deg" : "1.2deg" }] : [];
58
+ const withBusy = (node) => busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
59
+ node,
60
+ /* @__PURE__ */ jsx(
61
+ View,
62
+ {
63
+ style: styles.busyScrim,
64
+ accessibilityElementsHidden: true,
65
+ importantForAccessibility: "no-hide-descendants"
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsx(View, { style: styles.busySpinner, children: /* @__PURE__ */ jsx(Spinner, { size: "sm", accessibilityLabel: busyLabel }) })
69
+ ] }) : node;
70
+ if (onPress) {
71
+ return /* @__PURE__ */ jsxs(Animated.View, { style: [styles.base, style, { transform: [{ scale }, ...dragTransform] }], children: [
72
+ tintOverlay,
73
+ /* @__PURE__ */ jsx(
74
+ Pressable,
75
+ {
76
+ accessibilityRole: "button",
77
+ accessibilityLabel,
78
+ accessibilityState: { selected: selected || void 0, busy: busy || void 0 },
79
+ onPress,
80
+ onPressIn: () => spring(0.98),
81
+ onPressOut: () => spring(1),
82
+ style: StyleSheet.absoluteFill
83
+ }
84
+ ),
85
+ /* @__PURE__ */ jsx(View, { style: styles.pressContent, children: withBusy(children) })
86
+ ] });
87
+ }
88
+ return /* @__PURE__ */ jsxs(
89
+ View,
90
+ {
91
+ role: "group",
92
+ accessibilityLabel,
93
+ accessibilityState: { selected: selected || void 0, busy: busy || void 0 },
94
+ style: [styles.base, style, dragTransform.length ? { transform: dragTransform } : null],
95
+ children: [
96
+ tintOverlay,
97
+ withBusy(children)
98
+ ]
99
+ }
100
+ );
101
+ }
102
+ function CardHeader({ children, style }) {
103
+ const { styles } = useStyles(sheet);
104
+ return /* @__PURE__ */ jsx(View, { style: [styles.header, style], children });
105
+ }
106
+ function CardTitle({ children, style }) {
107
+ const { styles } = useStyles(sheet);
108
+ return typeof children === "string" ? /* @__PURE__ */ jsx(Text, { style: [styles.title, style], children }) : /* @__PURE__ */ jsx(Fragment, { children });
109
+ }
110
+ function CardDescription({ children, style }) {
111
+ const { styles } = useStyles(sheet);
112
+ return typeof children === "string" ? /* @__PURE__ */ jsx(Text, { style: [styles.description, style], children }) : /* @__PURE__ */ jsx(Fragment, { children });
113
+ }
114
+ function CardContent({ children, style }) {
115
+ const { styles } = useStyles(sheet);
116
+ return /* @__PURE__ */ jsx(View, { style: [styles.content, style], children });
117
+ }
118
+ function CardFooter({ children, style }) {
119
+ const { styles } = useStyles(sheet);
120
+ return /* @__PURE__ */ jsx(View, { style: [styles.footer, style], children });
121
+ }
122
+ function CardMedia({
123
+ source,
124
+ height = 160,
125
+ style,
126
+ accessibilityLabel
127
+ }) {
128
+ const { styles } = useStyles(sheet);
129
+ return /* @__PURE__ */ jsx(
130
+ Image,
131
+ {
132
+ source,
133
+ resizeMode: "cover",
134
+ accessibilityRole: accessibilityLabel !== void 0 ? "image" : void 0,
135
+ accessibilityLabel,
136
+ accessible: accessibilityLabel !== void 0,
137
+ style: [styles.media, { height }, style]
138
+ }
139
+ );
140
+ }
141
+ var sheet = createStyleSheet((theme) => ({
142
+ // The content layer over the full-bleed press overlay. `box-none` lets taps on
143
+ // empty regions fall through to the overlay while child controls keep theirs.
144
+ pressContent: { pointerEvents: "box-none" },
145
+ // Busy: dim the live content to ~60% (content stays — never a refresh
146
+ // skeleton) and pin the spinner to the top-inline-end corner.
147
+ busyScrim: {
148
+ ...StyleSheet.absoluteFillObject,
149
+ backgroundColor: theme.color.surface,
150
+ opacity: theme.opacity[64]
151
+ },
152
+ busySpinner: {
153
+ position: "absolute",
154
+ top: theme.space.s3,
155
+ // Logical inset — RN's engine mirrors `end` under RTL.
156
+ end: theme.space.s3,
157
+ pointerEvents: "none"
158
+ },
159
+ // First-load skeleton placeholder, sized to a typical composed card so the
160
+ // layout does not jump when real content arrives.
161
+ skeletonBody: {
162
+ paddingHorizontal: theme.space.s4,
163
+ paddingVertical: theme.space.s4,
164
+ gap: theme.space.s4
165
+ },
166
+ skeletonHead: { gap: theme.space.s2 },
167
+ base: {
168
+ backgroundColor: theme.color.surface,
169
+ borderWidth: theme.borderWidth.thin,
170
+ borderColor: theme.color.border,
171
+ borderRadius: theme.radius.xl,
172
+ overflow: "hidden",
173
+ variants: {
174
+ variant: {
175
+ // Reference (buildWidgets): `box-shadow:0 12px 30px rgba(30,25,15,.14)` → md token is
176
+ // the nearest match; elevated steps up to lg for the stronger treatment.
177
+ default: { ...theme.shadow.md },
178
+ elevated: { ...theme.shadow.lg },
179
+ outline: {}
180
+ },
181
+ // Selection: an accent border. The `state-selected` tint is a translucent
182
+ // overlay View (composited in the component); the border carries the mark
183
+ // under high contrast, where the tint flattens to the plain surface.
184
+ //
185
+ // Which is exactly why it is `focus.ringColor` and not the raw accent: a
186
+ // border that is the only cue for a state is a graphical object under SC
187
+ // 1.4.11 and owes 3:1, and the raw accent misses that in four of the
188
+ // shipped palettes. See `focusRingColor()` — named for the focus ring, but
189
+ // it derives the accent at the hard-edge strength every such edge needs,
190
+ // and it is a no-op on an accent that already clears.
191
+ selected: {
192
+ true: { borderColor: theme.focus.ringColor },
193
+ false: {}
194
+ },
195
+ // Von Restorff emphasis — a 2px accent border + the stronger `lg`
196
+ // elevation, so a single card pops from a field of peers. Under high
197
+ // contrast the shadow is zero and the accent border does the work.
198
+ emphasized: {
199
+ true: {
200
+ borderColor: theme.focus.ringColor,
201
+ borderWidth: theme.borderWidth.heavy,
202
+ ...theme.shadow.lg
203
+ },
204
+ false: {}
205
+ },
206
+ // Dragging: a raised shadow + accent border over the card's own surface;
207
+ // the `state-dragged` tint and the scale/tilt are applied in the component.
208
+ dragging: {
209
+ true: { borderColor: theme.focus.ringColor, ...theme.shadow.lg },
210
+ false: {}
211
+ }
212
+ }
213
+ },
214
+ header: {
215
+ // Reference (buildWidgets small widget): `padding:16px` — s4 = 16px.
216
+ paddingHorizontal: theme.space.s4,
217
+ paddingTop: theme.space.s4,
218
+ paddingBottom: theme.space.s3,
219
+ gap: theme.space.s1
220
+ },
221
+ // Card title = the semantic "Title 3" role (HIG: grouped-list / card title),
222
+ // rendered in the brand display face.
223
+ title: {
224
+ fontFamily: theme.font.display,
225
+ fontWeight: `${theme.font.displayWeight}`,
226
+ fontSize: theme.type.title3.fontSize,
227
+ lineHeight: theme.type.title3.lineHeight,
228
+ letterSpacing: theme.type.title3.letterSpacing,
229
+ color: theme.color.text
230
+ },
231
+ // Supporting copy = the "Subheadline" role (supporting text under a title).
232
+ description: {
233
+ fontFamily: theme.font.sans,
234
+ fontSize: theme.type.subheadline.fontSize,
235
+ lineHeight: theme.type.subheadline.lineHeight,
236
+ letterSpacing: theme.type.subheadline.letterSpacing,
237
+ color: theme.color.text2
238
+ },
239
+ content: {
240
+ // Reference (buildWidgets small widget): `padding:16px` — s4 = 16px.
241
+ paddingHorizontal: theme.space.s4,
242
+ paddingBottom: theme.space.s4,
243
+ gap: theme.space.s3
244
+ },
245
+ footer: {
246
+ flexDirection: "row",
247
+ alignItems: "center",
248
+ gap: theme.space.s2,
249
+ // Reference (buildWidgets small widget): `padding:16px` — s4 = 16px.
250
+ paddingHorizontal: theme.space.s4,
251
+ paddingBottom: theme.space.s4,
252
+ paddingTop: theme.space.s3
253
+ },
254
+ media: {
255
+ width: "100%",
256
+ borderTopLeftRadius: theme.radius.xl,
257
+ borderTopRightRadius: theme.radius.xl,
258
+ backgroundColor: theme.color.surface2
259
+ }
260
+ }));
261
+
262
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardMedia, CardTitle };
@@ -0,0 +1,4 @@
1
+ // src/lib/cursor.ts
2
+ var DRAG_CURSOR = { cursor: "pointer" };
3
+
4
+ export { DRAG_CURSOR };
@@ -0,0 +1,178 @@
1
+ import { camMeta, decorativeProps } from './chunk-RW6ZL2FQ.js';
2
+ import { useReducedMotion } from './chunk-6N33LFQA.js';
3
+ import * as React from 'react';
4
+ import { Animated, View, Text, Easing } from 'react-native';
5
+ import Svg, { Defs, Pattern, Line, RadialGradient, Stop, Rect } from 'react-native-svg';
6
+ import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
7
+ import { profile } from '@btndprojects/loam-analyzer';
8
+ import { jsxs, jsx } from 'react/jsx-runtime';
9
+
10
+ var PLACEHOLDER_LABEL = "live feed \xB7 placeholder";
11
+ function PlaceholderFeed({
12
+ label = PLACEHOLDER_LABEL,
13
+ drift = true,
14
+ topInset = 0,
15
+ children
16
+ }) {
17
+ const theme = useLoamTheme();
18
+ const reduced = useReducedMotion();
19
+ const { styles } = useStyles(feedSheet);
20
+ const still = reduced || theme.reduceMotion || !drift;
21
+ const phase = React.useRef(new Animated.Value(0)).current;
22
+ React.useEffect(() => {
23
+ if (still) {
24
+ phase.setValue(0);
25
+ return;
26
+ }
27
+ const leg = (to) => Animated.timing(phase, {
28
+ toValue: to,
29
+ duration: theme.loop.beacon * 8,
30
+ easing: Easing.bezier(...theme.easing.inOut),
31
+ useNativeDriver: true
32
+ });
33
+ const loop = Animated.loop(Animated.sequence([leg(1), leg(0)]));
34
+ loop.start();
35
+ return () => loop.stop();
36
+ }, [still, phase, theme.loop.beacon, theme.easing.inOut]);
37
+ const scale = still ? 1.015 : phase.interpolate({ inputRange: [0, 1], outputRange: [1.015, 1.046] });
38
+ const translateX = still ? 0 : phase.interpolate({ inputRange: [0, 1], outputRange: [0, 8] });
39
+ const translateY = still ? 0 : phase.interpolate({ inputRange: [0, 1], outputRange: [0, -8] });
40
+ return /* @__PURE__ */ jsxs(View, { accessible: false, testID: "loam-placeholder-feed", style: styles.root, ...decorativeProps(), children: [
41
+ /* @__PURE__ */ jsx(
42
+ Animated.View,
43
+ {
44
+ testID: still ? "loam-cam-plate-static" : "loam-cam-plate",
45
+ style: [styles.plate, { transform: [{ translateX }, { translateY }, { scale }] }],
46
+ children: /* @__PURE__ */ jsxs(Svg, { width: "100%", height: "100%", children: [
47
+ /* @__PURE__ */ jsxs(Defs, { children: [
48
+ /* @__PURE__ */ jsx(
49
+ Pattern,
50
+ {
51
+ id: "loam-cam-stripe",
52
+ patternUnits: "userSpaceOnUse",
53
+ width: 11,
54
+ height: 11,
55
+ patternTransform: "rotate(52)",
56
+ children: /* @__PURE__ */ jsx(
57
+ Line,
58
+ {
59
+ x1: 0,
60
+ y1: 0,
61
+ x2: 0,
62
+ y2: 11,
63
+ stroke: theme.white.a2,
64
+ strokeWidth: theme.borderWidth.heavy
65
+ }
66
+ )
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsxs(RadialGradient, { id: "loam-cam-warm", cx: "22%", cy: "18%", rx: "62%", ry: "62%", children: [
70
+ /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: theme.white.a3 }),
71
+ /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: theme.white.a3, stopOpacity: theme.opacity[0] })
72
+ ] }),
73
+ /* @__PURE__ */ jsxs(RadialGradient, { id: "loam-cam-cool", cx: "78%", cy: "82%", rx: "64%", ry: "64%", children: [
74
+ /* @__PURE__ */ jsx(Stop, { offset: "0", stopColor: theme.black.a5 }),
75
+ /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: theme.black.a5, stopOpacity: theme.opacity[0] })
76
+ ] })
77
+ ] }),
78
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#loam-cam-stripe)" }),
79
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#loam-cam-warm)" }),
80
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#loam-cam-cool)" })
81
+ ] })
82
+ }
83
+ ),
84
+ /* @__PURE__ */ jsx(View, { testID: "loam-cam-vignette", style: styles.vignette, children: /* @__PURE__ */ jsxs(Svg, { width: "100%", height: "100%", children: [
85
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(RadialGradient, { id: "loam-cam-vignette-fill", cx: "50%", cy: "50%", rx: "50%", ry: "50%", children: [
86
+ /* @__PURE__ */ jsx(Stop, { offset: "0.42", stopColor: theme.black.a9, stopOpacity: theme.opacity[0] }),
87
+ /* @__PURE__ */ jsx(Stop, { offset: "1", stopColor: theme.black.a9 })
88
+ ] }) }),
89
+ /* @__PURE__ */ jsx(Rect, { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#loam-cam-vignette-fill)" })
90
+ ] }) }),
91
+ children,
92
+ /* @__PURE__ */ jsx(Text, { style: [styles.label, camMeta(theme), topInset ? { marginTop: topInset } : null], children: label })
93
+ ] });
94
+ }
95
+ var PLATE = {
96
+ plant: { width: "38%", height: "42%", caption: "plant subject" },
97
+ document: { width: "58%", height: "66%", caption: "document page" },
98
+ barcode: { width: "46%", height: "14%", caption: "barcode" },
99
+ car: { width: "74%", height: "34%", caption: "vehicle" },
100
+ id: { width: "66%", height: "40%", caption: "identity document" },
101
+ generic: { width: "52%", height: "42%", caption: "scene" }
102
+ };
103
+ function SubjectPlate({
104
+ profile: profileProp,
105
+ caption
106
+ }) {
107
+ const theme = useLoamTheme();
108
+ const { styles } = useStyles(feedSheet);
109
+ const p = profile(profileProp);
110
+ const plate = PLATE[p.id] ?? PLATE.generic;
111
+ return /* @__PURE__ */ jsx(
112
+ View,
113
+ {
114
+ accessible: false,
115
+ testID: `loam-subject-plate-${p.id}`,
116
+ style: [styles.subjectPlate, { width: plate.width, height: plate.height }],
117
+ ...decorativeProps(),
118
+ children: /* @__PURE__ */ jsx(Text, { style: [styles.subjectCaption, camMeta(theme)], children: (caption ?? plate.caption).toUpperCase() })
119
+ }
120
+ );
121
+ }
122
+ var feedSheet = createStyleSheet((theme) => ({
123
+ root: {
124
+ position: "absolute",
125
+ top: theme.space[0],
126
+ bottom: theme.space[0],
127
+ left: theme.space[0],
128
+ right: theme.space[0],
129
+ overflow: "hidden",
130
+ backgroundColor: theme.media.onInk
131
+ },
132
+ plate: {
133
+ position: "absolute",
134
+ top: "-20%",
135
+ bottom: "-20%",
136
+ left: "-20%",
137
+ right: "-20%"
138
+ },
139
+ vignette: {
140
+ position: "absolute",
141
+ top: theme.space[0],
142
+ bottom: theme.space[0],
143
+ left: theme.space[0],
144
+ right: theme.space[0]
145
+ },
146
+ label: {
147
+ position: "absolute",
148
+ left: theme.space[16],
149
+ // Clear of the top bar, which is where the close button and the title plate
150
+ // sit.
151
+ top: theme.layout.appbarH + theme.space[8],
152
+ fontSize: theme.fontSize[10]
153
+ },
154
+ subjectPlate: {
155
+ pointerEvents: "none",
156
+ position: "absolute",
157
+ top: theme.space[0],
158
+ bottom: theme.space[0],
159
+ left: theme.space[0],
160
+ right: theme.space[0],
161
+ // `inset 0` plus an explicit size plus `auto` margins centres in both axes
162
+ // without a half-translate, which is the version that survives an RTL flip.
163
+ marginHorizontal: "auto",
164
+ marginVertical: "auto",
165
+ alignItems: "center",
166
+ justifyContent: "center",
167
+ borderRadius: theme.radius.sm,
168
+ borderWidth: theme.borderWidth.base,
169
+ borderStyle: "dashed",
170
+ borderColor: theme.white.a6,
171
+ backgroundColor: theme.white.a2
172
+ },
173
+ subjectCaption: {
174
+ fontSize: theme.fontSize[10]
175
+ }
176
+ }));
177
+
178
+ export { PLACEHOLDER_LABEL, PlaceholderFeed, SubjectPlate };
@@ -0,0 +1 @@
1
+