@btndprojects/loam-ui-native 0.1.0 → 0.2.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.
- package/README.md +56 -0
- package/dist/accordion/index.js +5 -3
- package/dist/adaptive/index.js +6 -2
- package/dist/alert/index.js +5 -2
- package/dist/analyzer/index.js +9 -6
- package/dist/announcement/index.js +8 -5
- package/dist/audio-player/index.js +5 -3
- package/dist/avatar/index.js +5 -2
- package/dist/avatar-group/index.js +7 -3
- package/dist/badge/index.js +7 -4
- package/dist/banner/index.js +5 -2
- package/dist/board/index.js +11 -6
- package/dist/button/index.js +6 -3
- package/dist/camera-permission/index.js +15 -12
- package/dist/capture-result/index.js +19 -16
- package/dist/card/index.js +6 -3
- package/dist/card-form/index.js +12 -8
- package/dist/carousel/index.js +4 -2
- package/dist/chart/index.js +8 -5
- package/dist/charts/index.js +8 -6
- package/dist/chat/index.js +16 -0
- package/dist/checkbox/index.js +6 -4
- package/dist/checklist/index.js +11 -8
- package/dist/checkout/index.js +16 -11
- package/dist/chip/index.js +7 -4
- package/dist/{chunk-XNUVB5OL.js → chunk-2OLKPG4E.js} +92 -28
- package/dist/{chunk-RUZHTGKB.js → chunk-2PKYGLQ6.js} +71 -40
- package/dist/{chunk-UC2WGUP3.js → chunk-2SWKL3AJ.js} +91 -252
- package/dist/{chunk-AI4DWZCD.js → chunk-2SY63FCH.js} +63 -16
- package/dist/{chunk-F5XNPWS7.js → chunk-2TXERVVA.js} +92 -35
- package/dist/chunk-36EC2T6P.js +581 -0
- package/dist/chunk-3DUWIYV5.js +437 -0
- package/dist/{chunk-RGQWWKLA.js → chunk-3QMEOFW5.js} +275 -71
- package/dist/chunk-3WEZCGHX.js +265 -0
- package/dist/chunk-46MMSDGL.js +194 -0
- package/dist/{chunk-7O2FMUPT.js → chunk-4IZXHVFJ.js} +297 -92
- package/dist/{chunk-LAECSR4H.js → chunk-5LAAAXFP.js} +14 -8
- package/dist/{chunk-2A5NIQAK.js → chunk-5RENVKBQ.js} +134 -46
- package/dist/{chunk-2ZZ7TDJ4.js → chunk-5UTRIXQ6.js} +37 -31
- package/dist/{chunk-LOE5YNN3.js → chunk-5VFZRGVD.js} +37 -10
- package/dist/{chunk-52X2VYTD.js → chunk-67IZZ2MJ.js} +115 -60
- package/dist/{chunk-UYG5L34B.js → chunk-6YAQBXB3.js} +10 -4
- package/dist/{chunk-BTTFCMKG.js → chunk-74FLKD24.js} +94 -23
- package/dist/{chunk-ITTYJZWX.js → chunk-7BUIKDD6.js} +73 -18
- package/dist/{chunk-FOKG57CR.js → chunk-7OVVSVEZ.js} +273 -109
- package/dist/chunk-AEB7KCHQ.js +287 -0
- package/dist/chunk-APCWFOZW.js +28 -0
- package/dist/chunk-AWKQIE5I.js +139 -0
- package/dist/{chunk-VCDBXW5H.js → chunk-B7N4ASYE.js} +86 -42
- package/dist/{chunk-IVNRBPGC.js → chunk-C4GTDLRC.js} +104 -20
- package/dist/{chunk-4ZAHCY44.js → chunk-C6APNDVA.js} +12 -5
- package/dist/{chunk-4SZYY6AN.js → chunk-CMTVNF3D.js} +18 -13
- package/dist/{chunk-WVKKJA6U.js → chunk-CPTOADB2.js} +151 -96
- package/dist/chunk-D5N5QWI7.js +1325 -0
- package/dist/{chunk-IIQTAY3J.js → chunk-DN7MNQIP.js} +113 -29
- package/dist/{chunk-47FWHGUN.js → chunk-DVGBZ3TX.js} +84 -23
- package/dist/chunk-DW3L54DQ.js +305 -0
- package/dist/{chunk-3ARE4TES.js → chunk-E2E3I5W2.js} +69 -18
- package/dist/{chunk-DHWADYZX.js → chunk-EDCBJV7J.js} +41 -28
- package/dist/{chunk-WSW6ZFAQ.js → chunk-ENP3BMZU.js} +4 -4
- package/dist/{chunk-OOPPQH27.js → chunk-EVOIGUBI.js} +43 -19
- package/dist/{chunk-VEAYTRPX.js → chunk-EY4DD67D.js} +165 -97
- package/dist/{chunk-223Q2T2Q.js → chunk-F3H33DQX.js} +132 -61
- package/dist/{chunk-CYRBHQQZ.js → chunk-F5B3UINI.js} +68 -35
- package/dist/{chunk-6X6PQ443.js → chunk-FAJI7BSC.js} +20 -9
- package/dist/{chunk-MOUJOP55.js → chunk-FUMHAAF3.js} +96 -29
- package/dist/{chunk-6HT2LP62.js → chunk-FV6HMP7W.js} +192 -73
- package/dist/{chunk-S7F6XLTK.js → chunk-FYWNRX4F.js} +76 -47
- package/dist/{chunk-YG3ZJHGU.js → chunk-FZGAAOKS.js} +30 -8
- package/dist/{chunk-YDGVJETP.js → chunk-G3AFC24V.js} +1 -1
- package/dist/{chunk-EJBDRVIH.js → chunk-G6UESEVN.js} +15 -8
- package/dist/chunk-GDKVKNR2.js +339 -0
- package/dist/chunk-GEIGMWNF.js +10 -0
- package/dist/{chunk-JUAMLEHX.js → chunk-H7DWSL4O.js} +24 -12
- package/dist/chunk-HJFFOOJ4.js +1 -0
- package/dist/{chunk-RW6ZL2FQ.js → chunk-HJLPZA4X.js} +106 -21
- package/dist/chunk-HYEOQWT7.js +647 -0
- package/dist/chunk-I2KLQ2HA.js +19 -0
- package/dist/{chunk-CJ5EOYZE.js → chunk-I4FHVKEC.js} +11 -5
- package/dist/{chunk-JNH2TYIN.js → chunk-IDM7JJMO.js} +19 -5
- package/dist/{chunk-O4AEHWII.js → chunk-IPUNJMAQ.js} +141 -49
- package/dist/{chunk-J7Q7VCVC.js → chunk-IT6FUXXG.js} +13 -6
- package/dist/{chunk-QJJ6MADV.js → chunk-IVKMZ7BB.js} +80 -28
- package/dist/{chunk-Z7H7VSFZ.js → chunk-IXKWIFWZ.js} +17 -6
- package/dist/chunk-J64KGCGX.js +55 -0
- package/dist/chunk-JBMLWFSJ.js +270 -0
- package/dist/{chunk-4BXMXBJO.js → chunk-JJLPBRVZ.js} +22 -11
- package/dist/chunk-JLC6PM5S.js +406 -0
- package/dist/chunk-JUYWSSKW.js +335 -0
- package/dist/{chunk-7CFF4HXS.js → chunk-JV5YOTOB.js} +49 -11
- package/dist/{chunk-LZLHELAG.js → chunk-KFJGFLMW.js} +29 -8
- package/dist/{chunk-O7AE6DAF.js → chunk-KQZ3GLHR.js} +18 -8
- package/dist/{chunk-N32RGOA5.js → chunk-LKFC4CS7.js} +80 -24
- package/dist/{chunk-YC6WORFL.js → chunk-LMPHCVJJ.js} +82 -50
- package/dist/{chunk-3WPW4KUN.js → chunk-LQP4KEXZ.js} +45 -13
- package/dist/{chunk-TKQYWZ5V.js → chunk-LUMVGO2K.js} +47 -31
- package/dist/{chunk-AWJOCGFZ.js → chunk-M656FYNH.js} +25 -13
- package/dist/{chunk-35OFI3JG.js → chunk-MKSNFG7H.js} +73 -20
- package/dist/{chunk-4GBOGOTV.js → chunk-NBEF4EPJ.js} +16 -6
- package/dist/chunk-NNCOFLNE.js +24 -0
- package/dist/{chunk-4YQOR7JM.js → chunk-NTQ2F3AU.js} +73 -20
- package/dist/{chunk-QCDXZBC5.js → chunk-O5V4TG3V.js} +126 -44
- package/dist/{chunk-U7TFM2JA.js → chunk-OJQUBQWA.js} +3 -3
- package/dist/{chunk-VQHPQEUH.js → chunk-OWAMM2DK.js} +13 -6
- package/dist/chunk-PID3NJB7.js +405 -0
- package/dist/{chunk-66SG2H23.js → chunk-PMMTGBBS.js} +27 -17
- package/dist/{chunk-RIBDXGUG.js → chunk-PNF3NKB5.js} +49 -16
- package/dist/{chunk-JXJB2X6M.js → chunk-Q6NKEPRE.js} +81 -32
- package/dist/chunk-QDZGFXQD.js +176 -0
- package/dist/{chunk-SYNOJOQO.js → chunk-QEYFDRHR.js} +60 -26
- package/dist/{chunk-VBOXAEPI.js → chunk-QHAITQIF.js} +97 -22
- package/dist/{chunk-VXDZFJGP.js → chunk-QHTVYA65.js} +230 -76
- package/dist/{chunk-TUTI5HOZ.js → chunk-QIKT7LIB.js} +14 -8
- package/dist/{chunk-3ENTMPQY.js → chunk-QP3KMOVF.js} +82 -42
- package/dist/{chunk-GNNJ4GCC.js → chunk-QPWDDJJ4.js} +62 -148
- package/dist/{chunk-QWCMU5B2.js → chunk-QRUMA22E.js} +205 -80
- package/dist/{chunk-ZVFE5QGU.js → chunk-QYPE5JX3.js} +50 -10
- package/dist/{chunk-PUPM2YGF.js → chunk-ROCUG24E.js} +76 -36
- package/dist/{chunk-NQYBUO3K.js → chunk-RU3ZPNL6.js} +333 -142
- package/dist/{chunk-TOXAGRDQ.js → chunk-RXSCIO6W.js} +14 -5
- package/dist/{chunk-FIF2M24N.js → chunk-SATMR6SG.js} +631 -203
- package/dist/{chunk-4YIP3CWS.js → chunk-SHHY5OMK.js} +7 -5
- package/dist/chunk-SKWO3SZF.js +2284 -0
- package/dist/{chunk-YF4NSSMT.js → chunk-SWS5JQIF.js} +41 -13
- package/dist/{chunk-CUMUNPXY.js → chunk-T5LTPKX6.js} +15 -7
- package/dist/{chunk-H6NIOQHK.js → chunk-TDMG26JI.js} +26 -6
- package/dist/{chunk-UWFLYMAR.js → chunk-TLCIR6RG.js} +267 -126
- package/dist/{chunk-SBMNWWBV.js → chunk-TN2ZNJUI.js} +47 -9
- package/dist/{chunk-5YNTNN5A.js → chunk-TQVAIKFD.js} +106 -41
- package/dist/chunk-TRGFFU6A.js +1456 -0
- package/dist/{chunk-2GK6PHGE.js → chunk-TY4MTKQJ.js} +100 -22
- package/dist/{chunk-AZRX6SAC.js → chunk-U23FYWME.js} +15 -7
- package/dist/{chunk-PZXZJBMP.js → chunk-U5NLHYV6.js} +26 -12
- package/dist/chunk-UQEN55EY.js +1 -0
- package/dist/chunk-UQGBTPXH.js +218 -0
- package/dist/chunk-UXGIW7OK.js +116 -0
- package/dist/{chunk-PJXUJYS6.js → chunk-UYGDJWMN.js} +55 -30
- package/dist/{chunk-QDYDBCFP.js → chunk-V2OEB75Z.js} +50 -51
- package/dist/{chunk-LSS54GLJ.js → chunk-VAOAKWUK.js} +34 -13
- package/dist/{chunk-DM5QUKKO.js → chunk-VDPK5CY4.js} +18 -6
- package/dist/chunk-W23G6JLF.js +37 -0
- package/dist/{chunk-CDRZHT42.js → chunk-W63AJTM7.js} +276 -12
- package/dist/{chunk-XXXEFXY5.js → chunk-W74TXYFB.js} +13 -5
- package/dist/{chunk-LRJNDEIA.js → chunk-WRDSPUE7.js} +144 -29
- package/dist/{chunk-C2NTXVWM.js → chunk-XBZGDDMR.js} +11 -4
- package/dist/{chunk-BV3B2HYZ.js → chunk-XIDTBCBA.js} +189 -131
- package/dist/{chunk-DSJBXLUG.js → chunk-XN4KG3P4.js} +348 -153
- package/dist/chunk-XQXMLMH3.js +211 -0
- package/dist/{chunk-HPPW424V.js → chunk-XTORZWRF.js} +19 -8
- package/dist/{chunk-P23EQNRQ.js → chunk-YAAHPATV.js} +181 -30
- package/dist/{chunk-KMI5ML5I.js → chunk-YXOAPXMU.js} +57 -18
- package/dist/{chunk-RJQOOHT2.js → chunk-ZECZOOSB.js} +59 -28
- package/dist/{chunk-QKXCPTFS.js → chunk-ZLTO5VQI.js} +121 -31
- package/dist/{chunk-BEDBFJND.js → chunk-ZVATDZOM.js} +16 -18
- package/dist/coachmark/index.js +6 -3
- package/dist/code-block/index.js +5 -3
- package/dist/color-field/index.js +6 -4
- package/dist/commerce/index.js +19 -16
- package/dist/connectivity/index.js +5 -2
- package/dist/context-menu/index.js +5 -3
- package/dist/copy-button/index.js +4 -2
- package/dist/data-grid/index.js +21 -16
- package/dist/date-range-picker/index.js +11 -8
- package/dist/description-list/index.js +3 -1
- package/dist/dialog/index.js +4 -2
- package/dist/empty-state/index.js +4 -2
- package/dist/error-summary/index.js +4 -2
- package/dist/fab/index.js +5 -2
- package/dist/file-manager/index.js +28 -0
- package/dist/file-upload/index.js +10 -7
- package/dist/filter-bar/index.js +9 -6
- package/dist/flow-run/index.js +15 -12
- package/dist/form/index.js +5 -3
- package/dist/gallery/index.js +5 -2
- package/dist/hold-to-confirm/index.js +4 -2
- package/dist/index.d.ts +9557 -2985
- package/dist/index.js +355 -122
- package/dist/infinite-list/index.js +4 -2
- package/dist/inline-edit/index.js +6 -4
- package/dist/input/index.js +5 -3
- package/dist/interactions/index.js +2 -1
- package/dist/invoice/index.js +13 -9
- package/dist/kbd/index.js +5 -1
- package/dist/keyboard/index.js +4 -2
- package/dist/list-row/index.js +6 -4
- package/dist/log-viewer/index.js +4 -2
- package/dist/map-view/index.js +5 -3
- package/dist/markdown/index.js +9 -6
- package/dist/metric/index.js +7 -4
- package/dist/money/index.js +9 -3
- package/dist/nav-drawer/index.js +4 -2
- package/dist/nav-header/index.js +9 -0
- package/dist/navigation/index.js +5 -2
- package/dist/notification-center/index.js +12 -10
- package/dist/number-roll/index.js +5 -2
- package/dist/one-handed/index.js +5 -3
- package/dist/os-surfaces/index.js +6 -3
- package/dist/otp/index.js +7 -4
- package/dist/page-header/index.js +1 -0
- package/dist/pagination/index.js +6 -0
- package/dist/payment-method/index.js +14 -10
- package/dist/payment-status/index.js +17 -14
- package/dist/permission/index.js +5 -2
- package/dist/picker/index.js +11 -6
- package/dist/progress/index.js +6 -3
- package/dist/pull-to-refresh/index.js +4 -2
- package/dist/radio-group/index.js +6 -4
- package/dist/rating/index.js +5 -2
- package/dist/receivables/index.js +21 -16
- package/dist/refund/index.js +18 -14
- package/dist/save-status/index.js +5 -3
- package/dist/scroll-area/index.js +3 -1
- package/dist/search-field/index.js +8 -0
- package/dist/segmented-control/index.js +4 -3
- package/dist/sheet/index.js +5 -3
- package/dist/skeleton/index.js +3 -1
- package/dist/slider/index.js +4 -2
- package/dist/sortable/index.js +7 -0
- package/dist/spinner/index.js +3 -1
- package/dist/split-button/index.js +9 -6
- package/dist/spotlight/index.js +3 -1
- package/dist/stage-timeline/index.js +5 -3
- package/dist/status-dot/index.js +4 -2
- package/dist/stepper/index.js +7 -4
- package/dist/streaming-text/index.js +3 -2
- package/dist/survey/index.js +18 -15
- package/dist/switch/index.js +5 -3
- package/dist/system-state/index.js +7 -4
- package/dist/tab-bar/index.js +5 -2
- package/dist/tabs/index.js +4 -2
- package/dist/tags-input/index.js +10 -0
- package/dist/textarea/index.js +6 -4
- package/dist/thinking/index.js +3 -1
- package/dist/time-field/index.js +12 -0
- package/dist/time-range-control/index.js +22 -0
- package/dist/timeline/index.js +4 -2
- package/dist/toast/index.js +4 -2
- package/dist/toolbar/index.js +4 -2
- package/dist/tour/index.js +12 -9
- package/dist/truncation-notice/index.js +5 -2
- package/dist/update-notice/index.js +12 -9
- package/dist/video-player/index.js +5 -2
- package/dist/viewfinder/index.js +6 -4
- package/dist/widget/index.js +7 -4
- package/dist/wizard/index.js +7 -4
- package/package.json +13 -12
- package/dist/chunk-6N33LFQA.js +0 -35
- package/dist/chunk-GDKZTW34.js +0 -395
- package/dist/chunk-GL7B2DOW.js +0 -134
- package/dist/chunk-NKB7BZYK.js +0 -167
- package/dist/chunk-OETCUXQP.js +0 -134
- package/dist/chunk-OPXFZ4Y5.js +0 -204
- package/dist/chunk-Q72LJOVE.js +0 -169
- package/dist/chunk-RNGLIHFA.js +0 -191
- package/dist/chunk-RQ3HASCC.js +0 -6
- package/dist/chunk-RSOJT5YW.js +0 -124
- package/dist/chunk-TKVFVF5D.js +0 -95
- package/dist/chunk-XOSCY2CW.js +0 -242
- package/dist/header/index.js +0 -5
- package/dist/search-bar/index.js +0 -5
- /package/dist/{chunk-3ECPOSKO.js → chunk-3UG6JUCV.js} +0 -0
- /package/dist/{chunk-JRLTGLN4.js → chunk-5WWRTEPS.js} +0 -0
- /package/dist/{chunk-RTIKSY6A.js → chunk-5Z5ZYMOJ.js} +0 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { useLabels } from './chunk-APCWFOZW.js';
|
|
2
|
+
import { Icon } from './chunk-UXGIW7OK.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Animated, Pressable, Text, Easing, Platform, findNodeHandle, AccessibilityInfo, Modal, View } from 'react-native';
|
|
5
|
+
import { useStyles, createStyleSheet, useLoamTheme } from '@btndprojects/loam-theme-native';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var AnimatedPressable = Animated.createAnimatedComponent(Pressable);
|
|
9
|
+
var memoryStore = /* @__PURE__ */ new Map();
|
|
10
|
+
var defaultRememberStorage = {
|
|
11
|
+
getItem: (key) => memoryStore.get(key) ?? null,
|
|
12
|
+
setItem: (key, value) => {
|
|
13
|
+
memoryStore.set(key, value);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function measureBox(node) {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
if (!node?.measureInWindow) return resolve(null);
|
|
19
|
+
node.measureInWindow((x, y, w, h) => resolve(Number.isFinite(x) && w > 0 && h > 0 ? { x, y, w, h } : null));
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
var DEFAULT_LABELS = {
|
|
23
|
+
closeDialog: "Close dialog",
|
|
24
|
+
close: "Close"
|
|
25
|
+
};
|
|
26
|
+
function Dialog({
|
|
27
|
+
open,
|
|
28
|
+
defaultOpen = false,
|
|
29
|
+
onClose,
|
|
30
|
+
onOpenChange,
|
|
31
|
+
dismissible = true,
|
|
32
|
+
remember = false,
|
|
33
|
+
rememberKey,
|
|
34
|
+
storage = defaultRememberStorage,
|
|
35
|
+
title,
|
|
36
|
+
description,
|
|
37
|
+
showClose = dismissible,
|
|
38
|
+
accessibilityLabel,
|
|
39
|
+
motion = "full",
|
|
40
|
+
morphFrom,
|
|
41
|
+
children,
|
|
42
|
+
labels: labelsProp
|
|
43
|
+
}) {
|
|
44
|
+
const labels = useLabels("dialog", DEFAULT_LABELS, labelsProp);
|
|
45
|
+
const theme = useLoamTheme("dialog");
|
|
46
|
+
const { styles } = useStyles(sheet);
|
|
47
|
+
const controlled = open !== void 0;
|
|
48
|
+
const persist = remember && rememberKey != null;
|
|
49
|
+
const reducedMotion = theme.reduceMotion || motion === "reduced";
|
|
50
|
+
const instantMotion = motion === "none";
|
|
51
|
+
const [internalOpen, setInternalOpen] = React.useState(() => {
|
|
52
|
+
if (!controlled && persist) {
|
|
53
|
+
const v = storage.getItem(rememberKey);
|
|
54
|
+
if (v === "open") return true;
|
|
55
|
+
if (v === "closed") return false;
|
|
56
|
+
}
|
|
57
|
+
return defaultOpen;
|
|
58
|
+
});
|
|
59
|
+
const actualOpen = controlled ? open : internalOpen;
|
|
60
|
+
const setOpen = React.useCallback(
|
|
61
|
+
(next) => {
|
|
62
|
+
if (persist) storage.setItem(rememberKey, next ? "open" : "closed");
|
|
63
|
+
if (!controlled) setInternalOpen(next);
|
|
64
|
+
onOpenChange?.(next);
|
|
65
|
+
},
|
|
66
|
+
[persist, rememberKey, storage, controlled, onOpenChange]
|
|
67
|
+
);
|
|
68
|
+
const requestDismiss = React.useCallback(() => {
|
|
69
|
+
if (!dismissible) return;
|
|
70
|
+
setOpen(false);
|
|
71
|
+
onClose?.();
|
|
72
|
+
}, [dismissible, setOpen, onClose]);
|
|
73
|
+
const [mounted, setMounted] = React.useState(actualOpen);
|
|
74
|
+
const progress = React.useRef(new Animated.Value(actualOpen ? 1 : 0)).current;
|
|
75
|
+
const canMorph = !!morphFrom && !reducedMotion && !instantMotion;
|
|
76
|
+
const rootRef = React.useRef(null);
|
|
77
|
+
const cardRef = React.useRef(null);
|
|
78
|
+
const fly = React.useRef(new Animated.Value(1)).current;
|
|
79
|
+
const [pending, setPending] = React.useState(false);
|
|
80
|
+
const [flight, setFlight] = React.useState(null);
|
|
81
|
+
const closingMorph = React.useRef(false);
|
|
82
|
+
const flightFor = React.useCallback(async () => {
|
|
83
|
+
const [src, dst, root] = await Promise.all([
|
|
84
|
+
measureBox(morphFrom?.current),
|
|
85
|
+
measureBox(cardRef.current),
|
|
86
|
+
measureBox(rootRef.current)
|
|
87
|
+
]);
|
|
88
|
+
if (!src || !dst) return null;
|
|
89
|
+
const ox = root?.x ?? 0;
|
|
90
|
+
const oy = root?.y ?? 0;
|
|
91
|
+
const radius = Math.abs(src.w - src.h) < 2 ? src.h / 2 : Math.min(src.h / 2, theme.radius.md);
|
|
92
|
+
return { src: { ...src, x: src.x - ox, y: src.y - oy }, dst: { ...dst, x: dst.x - ox, y: dst.y - oy }, radius };
|
|
93
|
+
}, [morphFrom, theme.radius.md]);
|
|
94
|
+
const onCardLayout = React.useCallback(() => {
|
|
95
|
+
if (!pending) return;
|
|
96
|
+
void flightFor().then((f) => {
|
|
97
|
+
setPending(false);
|
|
98
|
+
if (!f) return;
|
|
99
|
+
setFlight(f);
|
|
100
|
+
fly.setValue(0);
|
|
101
|
+
Animated.timing(fly, {
|
|
102
|
+
toValue: 1,
|
|
103
|
+
duration: theme.motion.expand.duration,
|
|
104
|
+
easing: Easing.bezier(...theme.motion.expand.easing),
|
|
105
|
+
useNativeDriver: false
|
|
106
|
+
}).start(() => setFlight(null));
|
|
107
|
+
});
|
|
108
|
+
}, [pending, flightFor, fly, theme.motion.expand]);
|
|
109
|
+
React.useEffect(() => {
|
|
110
|
+
const easing = Easing.bezier(...theme.easing.base);
|
|
111
|
+
if (actualOpen) {
|
|
112
|
+
setMounted(true);
|
|
113
|
+
closingMorph.current = false;
|
|
114
|
+
if (canMorph) setPending(true);
|
|
115
|
+
if (instantMotion) {
|
|
116
|
+
progress.setValue(1);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
Animated.timing(progress, {
|
|
120
|
+
toValue: 1,
|
|
121
|
+
duration: theme.duration.base,
|
|
122
|
+
easing,
|
|
123
|
+
useNativeDriver: true
|
|
124
|
+
}).start();
|
|
125
|
+
} else {
|
|
126
|
+
if (instantMotion) {
|
|
127
|
+
progress.setValue(0);
|
|
128
|
+
setMounted(false);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (canMorph) {
|
|
132
|
+
closingMorph.current = true;
|
|
133
|
+
setPending(false);
|
|
134
|
+
void flightFor().then((f) => {
|
|
135
|
+
if (!closingMorph.current) return;
|
|
136
|
+
if (!f) {
|
|
137
|
+
closingMorph.current = false;
|
|
138
|
+
setMounted(false);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
setFlight(f);
|
|
142
|
+
fly.setValue(1);
|
|
143
|
+
Animated.timing(fly, {
|
|
144
|
+
toValue: 0,
|
|
145
|
+
duration: theme.motion.collapse.duration,
|
|
146
|
+
easing: Easing.bezier(...theme.motion.collapse.easing),
|
|
147
|
+
useNativeDriver: false
|
|
148
|
+
}).start(() => {
|
|
149
|
+
if (!closingMorph.current) return;
|
|
150
|
+
closingMorph.current = false;
|
|
151
|
+
setFlight(null);
|
|
152
|
+
setMounted(false);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
Animated.timing(progress, {
|
|
157
|
+
toValue: 0,
|
|
158
|
+
duration: theme.motion.exit.duration,
|
|
159
|
+
easing: Easing.bezier(...theme.motion.exit.easing),
|
|
160
|
+
useNativeDriver: true
|
|
161
|
+
}).start(({ finished }) => {
|
|
162
|
+
if (finished && !closingMorph.current) setMounted(false);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}, [
|
|
166
|
+
actualOpen,
|
|
167
|
+
progress,
|
|
168
|
+
theme.duration.base,
|
|
169
|
+
theme.easing.base,
|
|
170
|
+
theme.motion.exit.duration,
|
|
171
|
+
theme.motion.exit.easing,
|
|
172
|
+
instantMotion,
|
|
173
|
+
canMorph,
|
|
174
|
+
flightFor,
|
|
175
|
+
fly,
|
|
176
|
+
theme.motion.collapse
|
|
177
|
+
]);
|
|
178
|
+
const titleRef = React.useRef(null);
|
|
179
|
+
const cardMounted = mounted;
|
|
180
|
+
React.useEffect(() => {
|
|
181
|
+
if (!actualOpen || !cardMounted || Platform.OS === "web") return;
|
|
182
|
+
const node = titleRef.current;
|
|
183
|
+
const tag = node ? findNodeHandle(node) : null;
|
|
184
|
+
if (tag !== null) AccessibilityInfo.setAccessibilityFocus(tag);
|
|
185
|
+
}, [actualOpen, cardMounted]);
|
|
186
|
+
if (!mounted) return null;
|
|
187
|
+
const cardScale = reducedMotion || canMorph ? 1 : progress.interpolate({ inputRange: [0, 1], outputRange: [0.96, 1] });
|
|
188
|
+
const lerp = (a, b) => fly.interpolate({ inputRange: [0, 1], outputRange: [a, b] });
|
|
189
|
+
const clipStyle = flight ? [
|
|
190
|
+
styles.clip,
|
|
191
|
+
{
|
|
192
|
+
left: lerp(flight.src.x, flight.dst.x),
|
|
193
|
+
top: lerp(flight.src.y, flight.dst.y),
|
|
194
|
+
width: lerp(flight.src.w, flight.dst.w),
|
|
195
|
+
height: lerp(flight.src.h, flight.dst.h),
|
|
196
|
+
borderRadius: lerp(flight.radius, theme.radius.xl)
|
|
197
|
+
}
|
|
198
|
+
] : styles.rest;
|
|
199
|
+
const innerStyle = flight ? {
|
|
200
|
+
position: "absolute",
|
|
201
|
+
left: lerp(flight.dst.x - flight.src.x, 0),
|
|
202
|
+
top: lerp(flight.dst.y - flight.src.y, 0),
|
|
203
|
+
width: flight.dst.w,
|
|
204
|
+
// The content arrives once the clip is big enough to hold it.
|
|
205
|
+
opacity: fly.interpolate({ inputRange: [0, 0.4, 1], outputRange: [0, 0, 1] })
|
|
206
|
+
} : styles.rest;
|
|
207
|
+
const cardStyle = flight ? [styles.card, styles.flat, { width: flight.dst.w, maxWidth: flight.dst.w }] : [styles.card, { opacity: pending ? 0 : progress, transform: [{ scale: cardScale }] }];
|
|
208
|
+
return /* @__PURE__ */ jsx(Modal, { transparent: true, visible: mounted, animationType: "none", onRequestClose: requestDismiss, children: /* @__PURE__ */ jsxs(View, { ref: rootRef, collapsable: false, style: styles.root, children: [
|
|
209
|
+
/* @__PURE__ */ jsx(
|
|
210
|
+
AnimatedPressable,
|
|
211
|
+
{
|
|
212
|
+
accessibilityRole: "button",
|
|
213
|
+
accessibilityLabel: labels.closeDialog,
|
|
214
|
+
accessibilityElementsHidden: !dismissible,
|
|
215
|
+
importantForAccessibility: dismissible ? "auto" : "no-hide-descendants",
|
|
216
|
+
onPress: dismissible ? requestDismiss : void 0,
|
|
217
|
+
style: [styles.scrim, { opacity: progress }]
|
|
218
|
+
}
|
|
219
|
+
),
|
|
220
|
+
/* @__PURE__ */ jsx(Animated.View, { style: clipStyle, children: /* @__PURE__ */ jsx(Animated.View, { style: innerStyle, children: /* @__PURE__ */ jsxs(
|
|
221
|
+
Animated.View,
|
|
222
|
+
{
|
|
223
|
+
ref: cardRef,
|
|
224
|
+
role: "dialog",
|
|
225
|
+
accessibilityViewIsModal: true,
|
|
226
|
+
accessibilityLabel: accessibilityLabel ?? title,
|
|
227
|
+
onLayout: onCardLayout,
|
|
228
|
+
style: cardStyle,
|
|
229
|
+
children: [
|
|
230
|
+
showClose ? /* @__PURE__ */ jsx(
|
|
231
|
+
Pressable,
|
|
232
|
+
{
|
|
233
|
+
accessibilityRole: "button",
|
|
234
|
+
accessibilityLabel: labels.close,
|
|
235
|
+
onPress: requestDismiss,
|
|
236
|
+
style: styles.close,
|
|
237
|
+
hitSlop: 8,
|
|
238
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 20, color: theme.color.text3 })
|
|
239
|
+
}
|
|
240
|
+
) : null,
|
|
241
|
+
title ? /* @__PURE__ */ jsx(DialogTitle, { ref: titleRef, children: title }) : null,
|
|
242
|
+
description ? /* @__PURE__ */ jsx(DialogDescription, { children: description }) : null,
|
|
243
|
+
children
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
) }) })
|
|
247
|
+
] }) });
|
|
248
|
+
}
|
|
249
|
+
var DialogTitle = React.forwardRef(
|
|
250
|
+
function DialogTitle2({ children }, ref) {
|
|
251
|
+
const { styles } = useStyles(sheet);
|
|
252
|
+
return /* @__PURE__ */ jsx(Text, { ref, accessibilityRole: "header", style: styles.title, children });
|
|
253
|
+
}
|
|
254
|
+
);
|
|
255
|
+
function DialogDescription({ children }) {
|
|
256
|
+
const { styles } = useStyles(sheet);
|
|
257
|
+
return /* @__PURE__ */ jsx(Text, { style: styles.description, children });
|
|
258
|
+
}
|
|
259
|
+
function DialogFooter({ children }) {
|
|
260
|
+
const { styles } = useStyles(sheet);
|
|
261
|
+
return /* @__PURE__ */ jsx(View, { style: styles.footer, children });
|
|
262
|
+
}
|
|
263
|
+
var sheet = createStyleSheet((theme) => ({
|
|
264
|
+
root: {
|
|
265
|
+
flex: 1,
|
|
266
|
+
alignItems: "center",
|
|
267
|
+
justifyContent: "center",
|
|
268
|
+
padding: theme.space.s5
|
|
269
|
+
},
|
|
270
|
+
scrim: {
|
|
271
|
+
position: "absolute",
|
|
272
|
+
top: 0,
|
|
273
|
+
left: 0,
|
|
274
|
+
right: 0,
|
|
275
|
+
bottom: 0,
|
|
276
|
+
backgroundColor: theme.color.scrim
|
|
277
|
+
},
|
|
278
|
+
// loam-contrast-ignore — the boundary here is the scrim, not the shadow.
|
|
279
|
+
// `color.scrim` is a 44% wash and is *not* re-resolved by high contrast, so
|
|
280
|
+
// this surface is still separated from the page when the elevation zeroes
|
|
281
|
+
// out. A border would put a hairline around every modal for no gain.
|
|
282
|
+
card: {
|
|
283
|
+
width: "100%",
|
|
284
|
+
// The reference width, which is now a named tier rather than a literal.
|
|
285
|
+
maxWidth: theme.panel.xl,
|
|
286
|
+
alignSelf: "center",
|
|
287
|
+
backgroundColor: theme.color.surface,
|
|
288
|
+
borderRadius: theme.radius.xl,
|
|
289
|
+
padding: theme.space.s5,
|
|
290
|
+
gap: theme.space.s3,
|
|
291
|
+
...theme.shadow.lg
|
|
292
|
+
},
|
|
293
|
+
// The pass-through wrappers around the card at rest: full width, centring it.
|
|
294
|
+
rest: {
|
|
295
|
+
width: "100%",
|
|
296
|
+
alignItems: "center"
|
|
297
|
+
},
|
|
298
|
+
// The travelling clip while the card morphs to or from its source.
|
|
299
|
+
clip: {
|
|
300
|
+
position: "absolute",
|
|
301
|
+
overflow: "hidden",
|
|
302
|
+
backgroundColor: theme.color.surface
|
|
303
|
+
},
|
|
304
|
+
// No shadow in flight: overflow clipping would cut it anyway.
|
|
305
|
+
flat: {
|
|
306
|
+
shadowOpacity: 0,
|
|
307
|
+
elevation: 0
|
|
308
|
+
},
|
|
309
|
+
close: {
|
|
310
|
+
position: "absolute",
|
|
311
|
+
top: theme.space.s3,
|
|
312
|
+
right: theme.space.s3,
|
|
313
|
+
zIndex: 1,
|
|
314
|
+
padding: theme.space.s1,
|
|
315
|
+
borderRadius: theme.radius.full
|
|
316
|
+
},
|
|
317
|
+
title: {
|
|
318
|
+
fontFamily: theme.font.display,
|
|
319
|
+
fontWeight: `${theme.font.displayWeight}`,
|
|
320
|
+
fontSize: theme.fontSize[26],
|
|
321
|
+
color: theme.color.text
|
|
322
|
+
},
|
|
323
|
+
description: {
|
|
324
|
+
fontFamily: theme.font.sans,
|
|
325
|
+
// Reference (buildOverlays, Android): font-size:14px — sm token matches exactly.
|
|
326
|
+
fontSize: theme.fontSize[14],
|
|
327
|
+
lineHeight: theme.fontSize[14] * 1.5,
|
|
328
|
+
color: theme.color.text2
|
|
329
|
+
},
|
|
330
|
+
footer: {
|
|
331
|
+
flexDirection: "row",
|
|
332
|
+
justifyContent: "flex-end",
|
|
333
|
+
alignItems: "center",
|
|
334
|
+
gap: theme.space.s2,
|
|
335
|
+
marginTop: theme.space.s2
|
|
336
|
+
}
|
|
337
|
+
}));
|
|
338
|
+
|
|
339
|
+
export { Dialog, DialogDescription, DialogFooter, DialogTitle, defaultRememberStorage };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useLabels } from './chunk-APCWFOZW.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { DEFAULT_PAY_LABELS, resolvePayLabels } from '@btndprojects/loam-pay';
|
|
4
|
+
|
|
5
|
+
function usePayLabels(own) {
|
|
6
|
+
const merged = useLabels("pay", DEFAULT_PAY_LABELS, own);
|
|
7
|
+
return React.useMemo(() => resolvePayLabels(merged), [merged]);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { usePayLabels };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { useLabels } from './chunk-APCWFOZW.js';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
import { View, Animated, Easing, Pressable, I18nManager } from 'react-native';
|
|
3
4
|
import { createStyleSheet, useLoamTheme, useStyles } from '@btndprojects/loam-theme-native';
|
|
4
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
|
-
// src/spotlight/spotlight.tsx
|
|
7
7
|
var NO_INSETS = { top: 0, bottom: 0, left: 0, right: 0 };
|
|
8
8
|
var HostContext = React.createContext(null);
|
|
9
9
|
function TourOverlay({ children }) {
|
|
@@ -179,7 +179,7 @@ function Spotlight({
|
|
|
179
179
|
radius,
|
|
180
180
|
motion = "full"
|
|
181
181
|
}) {
|
|
182
|
-
const theme = useLoamTheme();
|
|
182
|
+
const theme = useLoamTheme("spotlight");
|
|
183
183
|
const { styles } = useStyles(sheet);
|
|
184
184
|
const rect = useAnchorRect(target);
|
|
185
185
|
const fade = React.useRef(new Animated.Value(0)).current;
|
|
@@ -221,12 +221,12 @@ function HighlightRing({
|
|
|
221
221
|
pulse = false,
|
|
222
222
|
motion = "full"
|
|
223
223
|
}) {
|
|
224
|
-
const theme = useLoamTheme();
|
|
224
|
+
const theme = useLoamTheme("spotlight");
|
|
225
225
|
const { styles } = useStyles(sheet);
|
|
226
226
|
const rect = useAnchorRect(target);
|
|
227
227
|
const breathe = React.useRef(new Animated.Value(1)).current;
|
|
228
228
|
React.useEffect(() => {
|
|
229
|
-
if (!pulse || motion === "none") return;
|
|
229
|
+
if (!pulse || motion === "none" || theme.reduceMotion) return;
|
|
230
230
|
const loop = Animated.loop(
|
|
231
231
|
Animated.sequence([
|
|
232
232
|
Animated.timing(breathe, {
|
|
@@ -245,7 +245,7 @@ function HighlightRing({
|
|
|
245
245
|
);
|
|
246
246
|
loop.start();
|
|
247
247
|
return () => loop.stop();
|
|
248
|
-
}, [pulse, motion, breathe, theme.loop.pulse]);
|
|
248
|
+
}, [pulse, motion, breathe, theme.loop.pulse, theme.reduceMotion]);
|
|
249
249
|
if (!rect) return null;
|
|
250
250
|
return /* @__PURE__ */ jsx(
|
|
251
251
|
Animated.View,
|
|
@@ -265,28 +265,38 @@ function HighlightRing({
|
|
|
265
265
|
}
|
|
266
266
|
);
|
|
267
267
|
}
|
|
268
|
-
function Highlight({
|
|
268
|
+
function Highlight({
|
|
269
|
+
kind = "spotlight",
|
|
270
|
+
pulse,
|
|
271
|
+
...rest
|
|
272
|
+
}) {
|
|
269
273
|
if (kind === "none") return null;
|
|
270
274
|
if (kind === "spotlight") return /* @__PURE__ */ jsx(Spotlight, { ...rest });
|
|
271
275
|
return /* @__PURE__ */ jsx(HighlightRing, { ...rest, pulse: kind === "pulse" || pulse });
|
|
272
276
|
}
|
|
277
|
+
var DEFAULT_LABELS = {
|
|
278
|
+
whatsNew: "What\u2019s new here"
|
|
279
|
+
};
|
|
273
280
|
var DOT = 12;
|
|
274
281
|
var OVERHANG = 5;
|
|
275
282
|
function Beacon({
|
|
276
283
|
target,
|
|
277
284
|
corner = "trailing-top",
|
|
278
|
-
accessibilityLabel
|
|
285
|
+
accessibilityLabel: accessibilityLabelProp,
|
|
279
286
|
pulsing = true,
|
|
280
287
|
onPress,
|
|
281
|
-
motion = "full"
|
|
288
|
+
motion = "full",
|
|
289
|
+
labels: labelsProp
|
|
282
290
|
}) {
|
|
283
|
-
const theme = useLoamTheme();
|
|
291
|
+
const theme = useLoamTheme("spotlight");
|
|
292
|
+
const labels = useLabels("beacon", DEFAULT_LABELS, labelsProp);
|
|
293
|
+
const accessibilityLabel = accessibilityLabelProp ?? labels.whatsNew;
|
|
284
294
|
const { styles } = useStyles(sheet);
|
|
285
295
|
const rect = useAnchorRect(target ?? null);
|
|
286
296
|
const ring = React.useRef(new Animated.Value(0)).current;
|
|
287
297
|
const anchored = target != null;
|
|
288
298
|
React.useEffect(() => {
|
|
289
|
-
if (!pulsing || motion === "none") return;
|
|
299
|
+
if (!pulsing || motion === "none" || theme.reduceMotion) return;
|
|
290
300
|
const loop = Animated.loop(
|
|
291
301
|
Animated.timing(ring, {
|
|
292
302
|
toValue: 1,
|
|
@@ -298,7 +308,7 @@ function Beacon({
|
|
|
298
308
|
ring.setValue(0);
|
|
299
309
|
loop.start();
|
|
300
310
|
return () => loop.stop();
|
|
301
|
-
}, [pulsing, motion, ring, theme.loop.beacon]);
|
|
311
|
+
}, [pulsing, motion, ring, theme.loop.beacon, theme.reduceMotion]);
|
|
302
312
|
if (anchored && !rect) return null;
|
|
303
313
|
let placement;
|
|
304
314
|
if (rect) {
|
|
@@ -328,7 +338,9 @@ function Beacon({
|
|
|
328
338
|
styles.beaconRing,
|
|
329
339
|
{
|
|
330
340
|
opacity: ring.interpolate({ inputRange: [0, 0.7, 1], outputRange: [0.55, 0, 0] }),
|
|
331
|
-
transform: [
|
|
341
|
+
transform: [
|
|
342
|
+
{ scale: ring.interpolate({ inputRange: [0, 1], outputRange: [1, 2.8] }) }
|
|
343
|
+
]
|
|
332
344
|
}
|
|
333
345
|
]
|
|
334
346
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -1,10 +1,86 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { useLabels } from './chunk-APCWFOZW.js';
|
|
2
|
+
import { Icon } from './chunk-UXGIW7OK.js';
|
|
3
|
+
import * as React3 from 'react';
|
|
4
|
+
import { resolveAnalyzerLabels, localizeProfile, profile, gateHintDisplay } from '@btndprojects/loam-analyzer';
|
|
3
5
|
import { View, Text, Pressable } from 'react-native';
|
|
4
6
|
import { createStyleSheet, useStyles, useLoamTheme } from '@btndprojects/loam-theme-native';
|
|
5
|
-
import { profile, gateHintDisplay } from '@btndprojects/loam-analyzer';
|
|
6
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
8
|
|
|
9
|
+
var DEFAULT_ANALYZER_UI_LABELS = {
|
|
10
|
+
uploadPhoto: "Upload a photo",
|
|
11
|
+
expertControls: "Expert controls",
|
|
12
|
+
placeholderFeed: "live feed \xB7 placeholder",
|
|
13
|
+
webcamFront: "webcam \xB7 front",
|
|
14
|
+
rearCamera: "rear camera",
|
|
15
|
+
feedLive: (facing, ratio, zoom) => `${facing} \xB7 ${ratio} \xB7 ${zoom}x \xB7 placeholder feed`,
|
|
16
|
+
feedCaptured: (ratio) => `frozen frame \xB7 ${ratio} \xB7 placeholder`,
|
|
17
|
+
feedAnalysing: "frozen frame \xB7 analysing",
|
|
18
|
+
feedFrozen: "frozen frame",
|
|
19
|
+
feedDone: "captured frame",
|
|
20
|
+
analysing: "Analysing",
|
|
21
|
+
resultReady: "Result ready",
|
|
22
|
+
analysisFailed: "Analysis failed",
|
|
23
|
+
plate: {
|
|
24
|
+
plant: "plant subject",
|
|
25
|
+
document: "document page",
|
|
26
|
+
barcode: "barcode",
|
|
27
|
+
car: "vehicle",
|
|
28
|
+
id: "identity document",
|
|
29
|
+
generic: "scene"
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
function useAnalyzerLabels(own) {
|
|
33
|
+
const base = useLabels("analyzer", DEFAULT_ANALYZER_UI_LABELS, own);
|
|
34
|
+
return React3.useMemo(
|
|
35
|
+
() => ({ ...base, plate: { ...DEFAULT_ANALYZER_UI_LABELS.plate, ...base.plate } }),
|
|
36
|
+
[base]
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
var NO_COPY = {};
|
|
40
|
+
function useAnalyzerCopy(own) {
|
|
41
|
+
const provided = useLabels("analyzerCopy", NO_COPY);
|
|
42
|
+
const scoped = React3.useContext(AnalyzerCopyScope);
|
|
43
|
+
return React3.useMemo(() => resolveAnalyzerLabels(provided, scoped, own), [provided, scoped, own]);
|
|
44
|
+
}
|
|
45
|
+
var AnalyzerCopyScope = React3.createContext(void 0);
|
|
46
|
+
var DEFAULT_VIEWFINDER_LABELS = {
|
|
47
|
+
closeCamera: "Close camera",
|
|
48
|
+
autoCapturing: "Auto-capturing",
|
|
49
|
+
capture: "Capture",
|
|
50
|
+
torch: "Torch",
|
|
51
|
+
grid: "Grid",
|
|
52
|
+
flipCamera: "Flip camera",
|
|
53
|
+
zoom: "Zoom",
|
|
54
|
+
zoomStop: (stop) => `${stop}x`,
|
|
55
|
+
capturedPages: "Captured pages",
|
|
56
|
+
captureSequence: "Capture sequence",
|
|
57
|
+
stepCaptured: (name) => `${name} \u2014 captured, tap to redo`,
|
|
58
|
+
expertControls: "Expert controls",
|
|
59
|
+
expert: "Expert",
|
|
60
|
+
closeExpert: "Close expert controls",
|
|
61
|
+
level: "Level",
|
|
62
|
+
torchLevels: { off: "off", low: "low", high: "high" },
|
|
63
|
+
formats: { pipeline: "Pipeline-native", full: "Full sensor" },
|
|
64
|
+
uploadPhoto: "Upload a photo",
|
|
65
|
+
cameraDevice: "Camera device"
|
|
66
|
+
};
|
|
67
|
+
function useViewfinderLabels(own) {
|
|
68
|
+
const merged = useLabels("viewfinder", DEFAULT_VIEWFINDER_LABELS, own);
|
|
69
|
+
const provided = useLabels("viewfinder", NONE);
|
|
70
|
+
return React3.useMemo(
|
|
71
|
+
() => ({
|
|
72
|
+
...merged,
|
|
73
|
+
torchLevels: {
|
|
74
|
+
...DEFAULT_VIEWFINDER_LABELS.torchLevels,
|
|
75
|
+
...provided.torchLevels,
|
|
76
|
+
...own?.torchLevels
|
|
77
|
+
},
|
|
78
|
+
formats: { ...DEFAULT_VIEWFINDER_LABELS.formats, ...provided.formats, ...own?.formats }
|
|
79
|
+
}),
|
|
80
|
+
[merged, provided, own]
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
var NONE = {};
|
|
8
84
|
function camGlass(theme) {
|
|
9
85
|
return {
|
|
10
86
|
backgroundColor: theme.black.a12,
|
|
@@ -18,7 +94,9 @@ function camInk(theme) {
|
|
|
18
94
|
function camMeta(theme) {
|
|
19
95
|
return {
|
|
20
96
|
fontFamily: theme.font.mono,
|
|
21
|
-
|
|
97
|
+
// `a13`, not `a10`: at 38% the metadata measured 2:1 on the scrim over a
|
|
98
|
+
// bright feed. 70% still reads as secondary beside the full-white ink.
|
|
99
|
+
color: theme.white.a13,
|
|
22
100
|
letterSpacing: theme.tracking.wider
|
|
23
101
|
};
|
|
24
102
|
}
|
|
@@ -32,10 +110,10 @@ function decorativeProps() {
|
|
|
32
110
|
function untabbableProps() {
|
|
33
111
|
return { tabIndex: -1 };
|
|
34
112
|
}
|
|
35
|
-
var AnnounceContext =
|
|
113
|
+
var AnnounceContext = React3.createContext(null);
|
|
36
114
|
function SurfaceLiveRegion({ children }) {
|
|
37
|
-
const [message, setMessage] =
|
|
38
|
-
const announce =
|
|
115
|
+
const [message, setMessage] = React3.useState("");
|
|
116
|
+
const announce = React3.useCallback((m) => setMessage(m), []);
|
|
39
117
|
const { styles } = useStyles(chromeSheet);
|
|
40
118
|
return /* @__PURE__ */ jsxs(AnnounceContext.Provider, { value: announce, children: [
|
|
41
119
|
children,
|
|
@@ -52,7 +130,7 @@ function SurfaceLiveRegion({ children }) {
|
|
|
52
130
|
] });
|
|
53
131
|
}
|
|
54
132
|
function useSurfaceAnnounce() {
|
|
55
|
-
return
|
|
133
|
+
return React3.useContext(AnnounceContext);
|
|
56
134
|
}
|
|
57
135
|
function GlassIconButton({
|
|
58
136
|
icon,
|
|
@@ -62,7 +140,7 @@ function GlassIconButton({
|
|
|
62
140
|
radius = "full",
|
|
63
141
|
onPress
|
|
64
142
|
}) {
|
|
65
|
-
const theme = useLoamTheme();
|
|
143
|
+
const theme = useLoamTheme("viewfinder");
|
|
66
144
|
const { styles } = useStyles(chromeSheet, { size, radius, on: on === true });
|
|
67
145
|
const glyph = on ? theme.media.onInk : camInk(theme);
|
|
68
146
|
return /* @__PURE__ */ jsx(
|
|
@@ -98,7 +176,7 @@ function GuidanceChip({
|
|
|
98
176
|
tone = "neutral",
|
|
99
177
|
icon
|
|
100
178
|
}) {
|
|
101
|
-
const theme = useLoamTheme();
|
|
179
|
+
const theme = useLoamTheme("viewfinder");
|
|
102
180
|
const { styles } = useStyles(chromeSheet, { tone });
|
|
103
181
|
const { ink } = chipColours(theme, tone);
|
|
104
182
|
return (
|
|
@@ -115,17 +193,22 @@ function GateHint({
|
|
|
115
193
|
gate = { pass: true, failing: [] },
|
|
116
194
|
countdown = null,
|
|
117
195
|
live = true,
|
|
118
|
-
throttleMs = GATE_ANNOUNCE_MS
|
|
196
|
+
throttleMs = GATE_ANNOUNCE_MS,
|
|
197
|
+
copy
|
|
119
198
|
}) {
|
|
120
|
-
const
|
|
121
|
-
const
|
|
199
|
+
const words = useAnalyzerCopy(copy);
|
|
200
|
+
const resolved = React3.useMemo(
|
|
201
|
+
() => localizeProfile(profile(profileProp), words),
|
|
202
|
+
[profileProp, words]
|
|
203
|
+
);
|
|
204
|
+
const display = gateHintDisplay(resolved, gate, countdown, words);
|
|
122
205
|
const surface = useSurfaceAnnounce();
|
|
123
|
-
const [own, setOwn] =
|
|
206
|
+
const [own, setOwn] = React3.useState("");
|
|
124
207
|
const { styles } = useStyles(chromeSheet);
|
|
125
|
-
const sink =
|
|
208
|
+
const sink = React3.useRef(setOwn);
|
|
126
209
|
sink.current = surface ?? setOwn;
|
|
127
|
-
const last =
|
|
128
|
-
|
|
210
|
+
const last = React3.useRef({ text: "", at: 0 });
|
|
211
|
+
React3.useEffect(() => {
|
|
129
212
|
if (!live) return;
|
|
130
213
|
const text = display.text;
|
|
131
214
|
if (text === last.current.text) return;
|
|
@@ -159,15 +242,17 @@ function ViewfinderTopBar({
|
|
|
159
242
|
title,
|
|
160
243
|
subtitle,
|
|
161
244
|
align = "start",
|
|
162
|
-
closeLabel
|
|
245
|
+
closeLabel,
|
|
246
|
+
labels,
|
|
163
247
|
onClose,
|
|
164
248
|
children
|
|
165
249
|
}) {
|
|
166
|
-
const
|
|
250
|
+
const t = useViewfinderLabels(labels);
|
|
251
|
+
const theme = useLoamTheme("viewfinder");
|
|
167
252
|
const { styles } = useStyles(chromeSheet, { align });
|
|
168
253
|
const ink = camInk(theme);
|
|
169
254
|
return /* @__PURE__ */ jsxs(View, { style: styles.topBar, children: [
|
|
170
|
-
onClose ? /* @__PURE__ */ jsx(GlassIconButton, { icon: "x", label: closeLabel, onPress: onClose }) : null,
|
|
255
|
+
onClose ? /* @__PURE__ */ jsx(GlassIconButton, { icon: "x", label: closeLabel ?? t.closeCamera, onPress: onClose }) : null,
|
|
171
256
|
/* @__PURE__ */ jsxs(View, { style: styles.titlePlate, children: [
|
|
172
257
|
/* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.title, { color: ink }], children: title }),
|
|
173
258
|
subtitle ? /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: [styles.subtitle, { color: ink }], children: subtitle }) : null
|
|
@@ -281,4 +366,4 @@ var chromeSheet = createStyleSheet((theme) => ({
|
|
|
281
366
|
}
|
|
282
367
|
}));
|
|
283
368
|
|
|
284
|
-
export { GATE_ANNOUNCE_MS, GateHint, GlassIconButton, GuidanceChip, SurfaceLiveRegion, ViewfinderTopBar, camGlass, camInk, camMeta, decorativeProps, pressedProps, untabbableProps, useSurfaceAnnounce };
|
|
369
|
+
export { AnalyzerCopyScope, GATE_ANNOUNCE_MS, GateHint, GlassIconButton, GuidanceChip, SurfaceLiveRegion, ViewfinderTopBar, camGlass, camInk, camMeta, decorativeProps, pressedProps, untabbableProps, useAnalyzerCopy, useAnalyzerLabels, useSurfaceAnnounce, useViewfinderLabels };
|