@krizaka/ui 3.3.0 → 3.4.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.
- package/dist/activity-feed.d.ts +199 -0
- package/dist/activity-feed.js +155 -0
- package/dist/activity-feed.js.map +1 -0
- package/dist/argument-card.js +3 -3
- package/dist/chunk-7Z4KHPFC.js +42 -0
- package/dist/chunk-7Z4KHPFC.js.map +1 -0
- package/dist/data-table.js +98 -131
- package/dist/data-table.js.map +1 -1
- package/dist/description-list.d.ts +105 -0
- package/dist/description-list.js +49 -0
- package/dist/description-list.js.map +1 -0
- package/dist/index.js +13 -66
- package/dist/index.js.map +1 -1
- package/dist/kanban.d.ts +132 -0
- package/dist/kanban.js +187 -0
- package/dist/kanban.js.map +1 -0
- package/dist/list.d.ts +153 -0
- package/dist/list.js +130 -0
- package/dist/list.js.map +1 -0
- package/dist/map.d.ts +463 -0
- package/dist/map.js +952 -0
- package/dist/map.js.map +1 -0
- package/dist/motion.css +12 -1
- package/dist/native/map.d.ts +200 -0
- package/dist/native/map.js +673 -0
- package/dist/native/map.js.map +1 -0
- package/dist/native/media-picker.d.ts +58 -0
- package/dist/native/media-picker.js +63 -0
- package/dist/native/media-picker.js.map +1 -0
- package/dist/native.d.ts +568 -6
- package/dist/native.js +1989 -868
- package/dist/native.js.map +1 -1
- package/dist/page-hero.js +3 -3
- package/dist/stat.d.ts +31 -2
- package/dist/stat.js +21 -4
- package/dist/stat.js.map +1 -1
- package/dist/tree-view.d.ts +111 -0
- package/dist/tree-view.js +154 -0
- package/dist/tree-view.js.map +1 -0
- package/package.json +147 -10
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/action-sheet.json +121 -0
- package/registry/activity-feed.json +468 -0
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +1 -1
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +58 -3
- package/registry/badge.json +1 -1
- package/registry/button.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +1 -1
- package/registry/catalogue-page.json +1 -1
- package/registry/changelog-page.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/choice-grid.json +1 -1
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +1 -1
- package/registry/command.json +1 -1
- package/registry/component-page.json +1 -1
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +1 -1
- package/registry/date-picker.json +2 -2
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +232 -0
- package/registry/detail-layout.json +1 -1
- package/registry/dialog.json +1 -1
- package/registry/docs-article-page.json +1 -1
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +1 -1
- package/registry/examples/action-sheet/native/video-actions.d.ts +4 -0
- package/registry/examples/action-sheet/native/video-actions.dark.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.js +30 -0
- package/registry/examples/action-sheet/native/video-actions.light.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.tsx +24 -0
- package/registry/examples/activity-feed/job-activity.d.ts +4 -0
- package/registry/examples/activity-feed/job-activity.js +21 -0
- package/registry/examples/activity-feed/job-activity.tsx +17 -0
- package/registry/examples/activity-feed/live.d.ts +4 -0
- package/registry/examples/activity-feed/live.js +23 -0
- package/registry/examples/activity-feed/live.tsx +24 -0
- package/registry/examples/activity-feed/native/notifications.d.ts +4 -0
- package/registry/examples/activity-feed/native/notifications.dark.png +0 -0
- package/registry/examples/activity-feed/native/notifications.js +18 -0
- package/registry/examples/activity-feed/native/notifications.light.png +0 -0
- package/registry/examples/activity-feed/native/notifications.tsx +18 -0
- package/registry/examples/activity-feed/timeline.d.ts +4 -0
- package/registry/examples/activity-feed/timeline.js +25 -0
- package/registry/examples/activity-feed/timeline.tsx +19 -0
- package/registry/examples/avatar/native/presence.d.ts +4 -0
- package/registry/examples/avatar/native/presence.dark.png +0 -0
- package/registry/examples/avatar/native/presence.js +18 -0
- package/registry/examples/avatar/native/presence.light.png +0 -0
- package/registry/examples/avatar/native/presence.tsx +15 -0
- package/registry/examples/description-list/job-details.d.ts +4 -0
- package/registry/examples/description-list/job-details.js +23 -0
- package/registry/examples/description-list/job-details.tsx +17 -0
- package/registry/examples/description-list/key-value-grid.d.ts +4 -0
- package/registry/examples/description-list/key-value-grid.js +22 -0
- package/registry/examples/description-list/key-value-grid.tsx +16 -0
- package/registry/examples/description-list/native/job-details.d.ts +4 -0
- package/registry/examples/description-list/native/job-details.dark.png +0 -0
- package/registry/examples/description-list/native/job-details.js +33 -0
- package/registry/examples/description-list/native/job-details.light.png +0 -0
- package/registry/examples/description-list/native/job-details.tsx +24 -0
- package/registry/examples/description-list/receipt.d.ts +4 -0
- package/registry/examples/description-list/receipt.js +23 -0
- package/registry/examples/description-list/receipt.tsx +17 -0
- package/registry/examples/fab/native/extended.d.ts +4 -0
- package/registry/examples/fab/native/extended.dark.png +0 -0
- package/registry/examples/fab/native/extended.js +18 -0
- package/registry/examples/fab/native/extended.light.png +0 -0
- package/registry/examples/fab/native/extended.tsx +23 -0
- package/registry/examples/header/native/large-title.d.ts +4 -0
- package/registry/examples/header/native/large-title.dark.png +0 -0
- package/registry/examples/header/native/large-title.js +23 -0
- package/registry/examples/header/native/large-title.light.png +0 -0
- package/registry/examples/header/native/large-title.tsx +31 -0
- package/registry/examples/image-viewer/native/gallery.d.ts +4 -0
- package/registry/examples/image-viewer/native/gallery.dark.png +0 -0
- package/registry/examples/image-viewer/native/gallery.js +22 -0
- package/registry/examples/image-viewer/native/gallery.light.png +0 -0
- package/registry/examples/image-viewer/native/gallery.tsx +21 -0
- package/registry/examples/kanban/moderation.d.ts +4 -0
- package/registry/examples/kanban/moderation.js +35 -0
- package/registry/examples/kanban/moderation.tsx +37 -0
- package/registry/examples/list/jobs.d.ts +4 -0
- package/registry/examples/list/jobs.js +35 -0
- package/registry/examples/list/jobs.tsx +33 -0
- package/registry/examples/list/selectable.d.ts +4 -0
- package/registry/examples/list/selectable.js +33 -0
- package/registry/examples/list/selectable.tsx +30 -0
- package/registry/examples/list/virtualized.d.ts +4 -0
- package/registry/examples/list/virtualized.js +22 -0
- package/registry/examples/list/virtualized.tsx +17 -0
- package/registry/examples/loader/native/block.d.ts +4 -0
- package/registry/examples/loader/native/block.dark.png +0 -0
- package/registry/examples/loader/native/block.js +12 -0
- package/registry/examples/loader/native/block.light.png +0 -0
- package/registry/examples/loader/native/block.tsx +11 -0
- package/registry/examples/loader/native/job-wait.d.ts +4 -0
- package/registry/examples/loader/native/job-wait.dark.png +0 -0
- package/registry/examples/loader/native/job-wait.js +17 -0
- package/registry/examples/loader/native/job-wait.light.png +0 -0
- package/registry/examples/loader/native/job-wait.tsx +14 -0
- package/registry/examples/map/cluster.d.ts +4 -0
- package/registry/examples/map/cluster.js +16 -0
- package/registry/examples/map/cluster.tsx +18 -0
- package/registry/examples/map/location-picker.d.ts +4 -0
- package/registry/examples/map/location-picker.js +24 -0
- package/registry/examples/map/location-picker.tsx +22 -0
- package/registry/examples/map/native/location-picker.d.ts +4 -0
- package/registry/examples/map/native/location-picker.dark.png +0 -0
- package/registry/examples/map/native/location-picker.js +14 -0
- package/registry/examples/map/native/location-picker.light.png +0 -0
- package/registry/examples/map/native/location-picker.tsx +13 -0
- package/registry/examples/map/native/places.d.ts +4 -0
- package/registry/examples/map/native/places.dark.png +0 -0
- package/registry/examples/map/native/places.js +25 -0
- package/registry/examples/map/native/places.light.png +0 -0
- package/registry/examples/map/native/places.tsx +27 -0
- package/registry/examples/map/places.d.ts +4 -0
- package/registry/examples/map/places.js +28 -0
- package/registry/examples/map/places.tsx +28 -0
- package/registry/examples/map/static.d.ts +4 -0
- package/registry/examples/map/static.js +22 -0
- package/registry/examples/map/static.tsx +18 -0
- package/registry/examples/media-picker/native/story.d.ts +4 -0
- package/registry/examples/media-picker/native/story.dark.png +0 -0
- package/registry/examples/media-picker/native/story.js +30 -0
- package/registry/examples/media-picker/native/story.light.png +0 -0
- package/registry/examples/media-picker/native/story.tsx +26 -0
- package/registry/examples/meter/native/credits.d.ts +4 -0
- package/registry/examples/meter/native/credits.dark.png +0 -0
- package/registry/examples/meter/native/credits.js +15 -0
- package/registry/examples/meter/native/credits.light.png +0 -0
- package/registry/examples/meter/native/credits.tsx +12 -0
- package/registry/examples/meter/native/split-ring.d.ts +4 -0
- package/registry/examples/meter/native/split-ring.dark.png +0 -0
- package/registry/examples/meter/native/split-ring.js +24 -0
- package/registry/examples/meter/native/split-ring.light.png +0 -0
- package/registry/examples/meter/native/split-ring.tsx +19 -0
- package/registry/examples/number-ticker/native/balance.d.ts +4 -0
- package/registry/examples/number-ticker/native/balance.dark.png +0 -0
- package/registry/examples/number-ticker/native/balance.js +18 -0
- package/registry/examples/number-ticker/native/balance.light.png +0 -0
- package/registry/examples/number-ticker/native/balance.tsx +17 -0
- package/registry/examples/onboarding/native/first-launch.d.ts +4 -0
- package/registry/examples/onboarding/native/first-launch.dark.png +0 -0
- package/registry/examples/onboarding/native/first-launch.js +23 -0
- package/registry/examples/onboarding/native/first-launch.light.png +0 -0
- package/registry/examples/onboarding/native/first-launch.tsx +19 -0
- package/registry/examples/otp-input/native/invalid.d.ts +4 -0
- package/registry/examples/otp-input/native/invalid.dark.png +0 -0
- package/registry/examples/otp-input/native/invalid.js +15 -0
- package/registry/examples/otp-input/native/invalid.light.png +0 -0
- package/registry/examples/otp-input/native/invalid.tsx +14 -0
- package/registry/examples/otp-input/native/verify.d.ts +4 -0
- package/registry/examples/otp-input/native/verify.dark.png +0 -0
- package/registry/examples/otp-input/native/verify.js +17 -0
- package/registry/examples/otp-input/native/verify.light.png +0 -0
- package/registry/examples/otp-input/native/verify.tsx +14 -0
- package/registry/examples/permission-prompt/native/blocked.d.ts +4 -0
- package/registry/examples/permission-prompt/native/blocked.dark.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.js +25 -0
- package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.tsx +21 -0
- package/registry/examples/permission-prompt/native/camera.d.ts +4 -0
- package/registry/examples/permission-prompt/native/camera.dark.png +0 -0
- package/registry/examples/permission-prompt/native/camera.js +25 -0
- package/registry/examples/permission-prompt/native/camera.light.png +0 -0
- package/registry/examples/permission-prompt/native/camera.tsx +21 -0
- package/registry/examples/pull-to-refresh/native/feed.d.ts +4 -0
- package/registry/examples/pull-to-refresh/native/feed.dark.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.js +14 -0
- package/registry/examples/pull-to-refresh/native/feed.light.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.tsx +19 -0
- package/registry/examples/search-field/native/cancel.d.ts +4 -0
- package/registry/examples/search-field/native/cancel.dark.png +0 -0
- package/registry/examples/search-field/native/cancel.js +14 -0
- package/registry/examples/search-field/native/cancel.light.png +0 -0
- package/registry/examples/search-field/native/cancel.tsx +13 -0
- package/registry/examples/stat/grid.d.ts +4 -0
- package/registry/examples/stat/grid.js +17 -0
- package/registry/examples/stat/grid.tsx +14 -0
- package/registry/examples/stepper/native/run.d.ts +4 -0
- package/registry/examples/stepper/native/run.dark.png +0 -0
- package/registry/examples/stepper/native/run.js +24 -0
- package/registry/examples/stepper/native/run.light.png +0 -0
- package/registry/examples/stepper/native/run.tsx +20 -0
- package/registry/examples/swipeable-row/native/conversation.d.ts +4 -0
- package/registry/examples/swipeable-row/native/conversation.dark.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.js +30 -0
- package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.tsx +27 -0
- package/registry/examples/tab-bar/native/main-sections.d.ts +4 -0
- package/registry/examples/tab-bar/native/main-sections.dark.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.js +29 -0
- package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.tsx +30 -0
- package/registry/examples/tabs/native/sections.d.ts +4 -0
- package/registry/examples/tabs/native/sections.dark.png +0 -0
- package/registry/examples/tabs/native/sections.js +23 -0
- package/registry/examples/tabs/native/sections.light.png +0 -0
- package/registry/examples/tabs/native/sections.tsx +19 -0
- package/registry/examples/tabs/native/segmented.d.ts +4 -0
- package/registry/examples/tabs/native/segmented.dark.png +0 -0
- package/registry/examples/tabs/native/segmented.js +22 -0
- package/registry/examples/tabs/native/segmented.light.png +0 -0
- package/registry/examples/tabs/native/segmented.tsx +18 -0
- package/registry/examples/toast/native/snackbar.d.ts +4 -0
- package/registry/examples/toast/native/snackbar.dark.png +0 -0
- package/registry/examples/toast/native/snackbar.js +23 -0
- package/registry/examples/toast/native/snackbar.light.png +0 -0
- package/registry/examples/toast/native/snackbar.tsx +21 -0
- package/registry/examples/tree-view/docs.d.ts +4 -0
- package/registry/examples/tree-view/docs.js +24 -0
- package/registry/examples/tree-view/docs.tsx +22 -0
- package/registry/examples/tree-view/lazy.d.ts +4 -0
- package/registry/examples/tree-view/lazy.js +21 -0
- package/registry/examples/tree-view/lazy.tsx +19 -0
- package/registry/fab.json +122 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +2 -2
- package/registry/filter-bar.json +1 -1
- package/registry/form.json +2 -2
- package/registry/gallery-page.json +1 -1
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/header.json +137 -0
- package/registry/how-it-works-page.json +1 -1
- package/registry/image-cropper.json +1 -1
- package/registry/image-viewer.json +107 -0
- package/registry/index.json +299 -25
- package/registry/iso.json +1 -1
- package/registry/kanban.json +253 -0
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/landscape.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +367 -30
- package/registry/loader.json +157 -4
- package/registry/longform-page.json +1 -1
- package/registry/map.json +1368 -0
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +1 -1
- package/registry/mascot-state.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/media-capture.json +1 -1
- package/registry/media-picker.json +129 -0
- package/registry/meter.json +136 -4
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +96 -4
- package/registry/onboarding.json +95 -0
- package/registry/otp-input.json +150 -0
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page.json +1 -1
- package/registry/pagination.json +1 -1
- package/registry/permission-prompt.json +172 -0
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +2 -2
- package/registry/promise-card.json +1 -1
- package/registry/pull-to-refresh.json +74 -0
- package/registry/radio-group.json +1 -1
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +30 -3
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +68 -5
- package/registry/status-page.json +1 -1
- package/registry/stepper.json +75 -4
- package/registry/swipeable-row.json +124 -0
- package/registry/switch.json +1 -1
- package/registry/tab-bar.json +115 -0
- package/registry/tabs.json +94 -4
- package/registry/tag-input.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +8 -1
- package/registry/toast.json +17 -3
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/tree-view.json +291 -0
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/registry/virtual.json +1 -1
- package/skills/map/SKILL.md +35 -0
package/dist/native.js
CHANGED
|
@@ -151,10 +151,24 @@ function monthGrid(month, weekStartsOn) {
|
|
|
151
151
|
return Array.from({ length: 6 }, (_, w) => days.slice(w * 7, w * 7 + 7)).filter((week, w) => w < 5 || week[0].slice(0, 7) === first.slice(0, 7));
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
// src/native/
|
|
155
|
-
import
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
// src/native/action-sheet.tsx
|
|
155
|
+
import { Modal, Pressable, StyleSheet as StyleSheet2, View } from "react-native";
|
|
156
|
+
|
|
157
|
+
// src/native/overlay.tsx
|
|
158
|
+
import * as React from "react";
|
|
159
|
+
var modalName = (label) => ({ "aria-label": label });
|
|
160
|
+
function useOpen({ open, defaultOpen = false, onOpenChange }) {
|
|
161
|
+
const [own, setOwn] = React.useState(defaultOpen);
|
|
162
|
+
const value = open ?? own;
|
|
163
|
+
const set = React.useCallback(
|
|
164
|
+
(next) => {
|
|
165
|
+
if (open === void 0) setOwn(next);
|
|
166
|
+
onOpenChange?.(next);
|
|
167
|
+
},
|
|
168
|
+
[open, onOpenChange]
|
|
169
|
+
);
|
|
170
|
+
return [value, set];
|
|
171
|
+
}
|
|
158
172
|
|
|
159
173
|
// ../tokens/dist/native.js
|
|
160
174
|
var themes = /* @__PURE__ */ Object.freeze({ dark: /* @__PURE__ */ Object.freeze({
|
|
@@ -314,24 +328,25 @@ var marks = /* @__PURE__ */ Object.freeze({
|
|
|
314
328
|
});
|
|
315
329
|
|
|
316
330
|
// src/native/theme.tsx
|
|
317
|
-
import * as
|
|
331
|
+
import * as React2 from "react";
|
|
318
332
|
import { AccessibilityInfo, useColorScheme } from "react-native";
|
|
319
333
|
import { jsx } from "react/jsx-runtime";
|
|
320
334
|
var themes2 = themes;
|
|
321
335
|
var radius2 = radius;
|
|
322
336
|
var motion2 = motion;
|
|
323
337
|
var stillMotion = { ...motion2, duration: { instant: 0, fast: 0, base: 0 } };
|
|
324
|
-
var
|
|
338
|
+
var NO_INSETS = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
339
|
+
var ThemeContext = React2.createContext(null);
|
|
325
340
|
var noop = () => void 0;
|
|
326
341
|
function resolve(mode, system) {
|
|
327
342
|
if (mode === "system") return system === "light" ? "light" : "dark";
|
|
328
343
|
return mode;
|
|
329
344
|
}
|
|
330
|
-
function ThemeProvider({ children, mode: controlled, defaultMode = "system", onModeChange, overrides, fonts, haptics }) {
|
|
345
|
+
function ThemeProvider({ children, mode: controlled, defaultMode = "system", onModeChange, overrides, fonts, haptics, insets }) {
|
|
331
346
|
const system = useColorScheme();
|
|
332
|
-
const [own, setOwn] =
|
|
347
|
+
const [own, setOwn] = React2.useState(defaultMode);
|
|
333
348
|
const mode = controlled ?? own;
|
|
334
|
-
const setMode =
|
|
349
|
+
const setMode = React2.useCallback(
|
|
335
350
|
(next) => {
|
|
336
351
|
if (controlled === void 0) setOwn(next);
|
|
337
352
|
onModeChange?.(next);
|
|
@@ -341,23 +356,23 @@ function ThemeProvider({ children, mode: controlled, defaultMode = "system", onM
|
|
|
341
356
|
const scheme = resolve(mode, system);
|
|
342
357
|
const override = overrides?.[scheme];
|
|
343
358
|
const reduce = useReducedMotion();
|
|
344
|
-
const theme =
|
|
345
|
-
const value =
|
|
346
|
-
() => ({ mode, setMode, scheme, theme, radius: radius2, motion: reduce ? stillMotion : motion2, fonts: fonts ?? {}, haptic: haptics ?? noop }),
|
|
347
|
-
[mode, setMode, scheme, theme, fonts, reduce, haptics]
|
|
359
|
+
const theme = React2.useMemo(() => override ? { ...themes2[scheme], ...override } : themes2[scheme], [scheme, override]);
|
|
360
|
+
const value = React2.useMemo(
|
|
361
|
+
() => ({ mode, setMode, scheme, theme, radius: radius2, motion: reduce ? stillMotion : motion2, fonts: fonts ?? {}, haptic: haptics ?? noop, insets: insets ?? NO_INSETS }),
|
|
362
|
+
[mode, setMode, scheme, theme, fonts, reduce, haptics, insets]
|
|
348
363
|
);
|
|
349
364
|
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
|
|
350
365
|
}
|
|
351
366
|
function useTheme() {
|
|
352
|
-
const context =
|
|
367
|
+
const context = React2.useContext(ThemeContext);
|
|
353
368
|
const system = useColorScheme();
|
|
354
369
|
if (context) return context;
|
|
355
370
|
const scheme = resolve("system", system);
|
|
356
|
-
return { mode: "system", setMode: noop, scheme, theme: themes2[scheme], radius: radius2, motion: motion2, fonts: {}, haptic: noop };
|
|
371
|
+
return { mode: "system", setMode: noop, scheme, theme: themes2[scheme], radius: radius2, motion: motion2, fonts: {}, haptic: noop, insets: NO_INSETS };
|
|
357
372
|
}
|
|
358
373
|
function useReducedMotion() {
|
|
359
|
-
const [reduce, setReduce] =
|
|
360
|
-
|
|
374
|
+
const [reduce, setReduce] = React2.useState(false);
|
|
375
|
+
React2.useEffect(() => {
|
|
361
376
|
let alive = true;
|
|
362
377
|
void AccessibilityInfo.isReduceMotionEnabled().then((value) => {
|
|
363
378
|
if (alive) setReduce(value);
|
|
@@ -377,77 +392,304 @@ function alpha(color, opacity) {
|
|
|
377
392
|
return `rgba(${r},${g},${b},${opacity})`;
|
|
378
393
|
}
|
|
379
394
|
function useSvgId(prefix) {
|
|
380
|
-
return `${prefix}${
|
|
395
|
+
return `${prefix}${React2.useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/native/txt.tsx
|
|
399
|
+
import { StyleSheet, Text } from "react-native";
|
|
400
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
401
|
+
var TONE = {
|
|
402
|
+
text: "textPrimary",
|
|
403
|
+
secondary: "textSecondary",
|
|
404
|
+
muted: "textMuted",
|
|
405
|
+
accent: "accentText",
|
|
406
|
+
success: "successText",
|
|
407
|
+
warning: "warningText",
|
|
408
|
+
danger: "dangerText",
|
|
409
|
+
onAccent: "onAccent",
|
|
410
|
+
onMedia: "textOnMedia"
|
|
411
|
+
};
|
|
412
|
+
function Txt({ variant = "body", tone: tone3 = "text", style, ...props }) {
|
|
413
|
+
const { theme, fonts } = useTheme();
|
|
414
|
+
const family = variant === "display" || variant === "title" ? fonts.display : variant === "mono" ? fonts.mono : fonts.sans;
|
|
415
|
+
return /* @__PURE__ */ jsx2(
|
|
416
|
+
Text,
|
|
417
|
+
{
|
|
418
|
+
role: variant === "display" || variant === "title" ? "heading" : void 0,
|
|
419
|
+
...props,
|
|
420
|
+
style: [styles[variant], { color: theme[TONE[tone3]] }, family ? { fontFamily: family } : null, style]
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
var textStyles = StyleSheet.create({
|
|
425
|
+
display: { fontSize: 30, lineHeight: 36, fontWeight: "900", letterSpacing: -0.5 },
|
|
426
|
+
title: { fontSize: 18, lineHeight: 24, fontWeight: "800" },
|
|
427
|
+
body: { fontSize: 15, lineHeight: 21 },
|
|
428
|
+
caption: { fontSize: 12, lineHeight: 16 },
|
|
429
|
+
label: { fontSize: 14, lineHeight: 18, fontWeight: "700" },
|
|
430
|
+
mono: { fontSize: 14, lineHeight: 18, fontWeight: "700", fontVariant: ["tabular-nums"] }
|
|
431
|
+
});
|
|
432
|
+
var styles = textStyles;
|
|
433
|
+
|
|
434
|
+
// src/native/action-sheet.tsx
|
|
435
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
436
|
+
function ActionSheet({ title, description, actions, cancelLabel, ...controlled }) {
|
|
437
|
+
const [open, setOpen] = useOpen(controlled);
|
|
438
|
+
const { theme, radius: radius3, insets, haptic } = useTheme();
|
|
439
|
+
const reduce = useReducedMotion();
|
|
440
|
+
const card = { backgroundColor: theme.glassBg, borderColor: theme.glassBorder, borderTopColor: theme.edgeLight, borderRadius: radius3.xl };
|
|
441
|
+
return /* @__PURE__ */ jsxs(Modal, { ...modalName(title), visible: open, transparent: true, animationType: reduce ? "none" : "slide", onRequestClose: () => setOpen(false), statusBarTranslucent: true, children: [
|
|
442
|
+
/* @__PURE__ */ jsx3(Pressable, { "aria-hidden": true, accessible: false, style: [StyleSheet2.absoluteFill, { backgroundColor: theme.scrim }], onPress: () => setOpen(false) }),
|
|
443
|
+
/* @__PURE__ */ jsxs(View, { style: [styles2.bottom, styles2.actionWrap, { paddingBottom: 8 + insets.bottom }], pointerEvents: "box-none", children: [
|
|
444
|
+
/* @__PURE__ */ jsxs(View, { role: "menu", "aria-label": title, style: [styles2.actionCard, card], children: [
|
|
445
|
+
/* @__PURE__ */ jsxs(View, { style: styles2.actionHead, children: [
|
|
446
|
+
/* @__PURE__ */ jsx3(Txt, { variant: "caption", tone: "secondary", style: styles2.centred, children: title }),
|
|
447
|
+
description ? /* @__PURE__ */ jsx3(Txt, { variant: "caption", tone: "muted", style: styles2.centred, children: description }) : null
|
|
448
|
+
] }),
|
|
449
|
+
actions.map((action, i) => /* @__PURE__ */ jsxs(
|
|
450
|
+
Pressable,
|
|
451
|
+
{
|
|
452
|
+
role: "menuitem",
|
|
453
|
+
"aria-disabled": action.disabled,
|
|
454
|
+
disabled: action.disabled,
|
|
455
|
+
onPress: () => {
|
|
456
|
+
haptic("selection");
|
|
457
|
+
setOpen(false);
|
|
458
|
+
action.onPress();
|
|
459
|
+
},
|
|
460
|
+
style: ({ pressed }) => [styles2.action, { borderTopColor: theme.borderSubtle, backgroundColor: pressed ? theme.surface2 : "transparent", opacity: action.disabled ? 0.4 : 1 }],
|
|
461
|
+
children: [
|
|
462
|
+
action.icon ? /* @__PURE__ */ jsx3(View, { "aria-hidden": true, children: action.icon }) : null,
|
|
463
|
+
/* @__PURE__ */ jsx3(Txt, { variant: "label", tone: action.destructive ? "danger" : "text", children: action.label })
|
|
464
|
+
]
|
|
465
|
+
},
|
|
466
|
+
i
|
|
467
|
+
))
|
|
468
|
+
] }),
|
|
469
|
+
/* @__PURE__ */ jsx3(Pressable, { role: "button", onPress: () => setOpen(false), style: ({ pressed }) => [styles2.cancel, card, { backgroundColor: pressed ? theme.surface2 : theme.surface1 }], children: /* @__PURE__ */ jsx3(Txt, { variant: "label", children: cancelLabel }) })
|
|
470
|
+
] })
|
|
471
|
+
] });
|
|
472
|
+
}
|
|
473
|
+
var styles2 = StyleSheet2.create({
|
|
474
|
+
bottom: { flex: 1, justifyContent: "flex-end" },
|
|
475
|
+
actionWrap: { paddingHorizontal: 8, gap: 8 },
|
|
476
|
+
actionCard: { borderWidth: StyleSheet2.hairlineWidth, overflow: "hidden" },
|
|
477
|
+
actionHead: { paddingVertical: 12, paddingHorizontal: 16, gap: 2 },
|
|
478
|
+
centred: { textAlign: "center" },
|
|
479
|
+
action: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 10, minHeight: 52, paddingHorizontal: 16, borderTopWidth: StyleSheet2.hairlineWidth },
|
|
480
|
+
cancel: { minHeight: 52, alignItems: "center", justifyContent: "center", borderWidth: StyleSheet2.hairlineWidth }
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// src/native/activity-feed.tsx
|
|
484
|
+
import * as React3 from "react";
|
|
485
|
+
import { AccessibilityInfo as AccessibilityInfo2, SectionList, StyleSheet as StyleSheet3, View as View2 } from "react-native";
|
|
486
|
+
|
|
487
|
+
// src/activity-feed/group.ts
|
|
488
|
+
var dayKey = (date) => `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
|
|
489
|
+
function groupActivity(events, { now = /* @__PURE__ */ new Date(), locale = "en-US", today = "Today", yesterday = "Yesterday", fold = true } = {}) {
|
|
490
|
+
const sorted = [...events].sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime());
|
|
491
|
+
const day = new Intl.DateTimeFormat(locale, { weekday: "long", month: "short", day: "numeric" });
|
|
492
|
+
const todayKey = dayKey(now);
|
|
493
|
+
const yesterdayKey = dayKey(new Date(now.getTime() - 864e5));
|
|
494
|
+
const groups = [];
|
|
495
|
+
let current = null;
|
|
496
|
+
let currentKey = "";
|
|
497
|
+
for (const event of sorted) {
|
|
498
|
+
const date = new Date(event.at);
|
|
499
|
+
const key = dayKey(date);
|
|
500
|
+
if (!current || key !== currentKey) {
|
|
501
|
+
currentKey = key;
|
|
502
|
+
current = { label: key === todayKey ? today : key === yesterdayKey ? yesterday : day.format(date), events: [] };
|
|
503
|
+
groups.push(current);
|
|
504
|
+
}
|
|
505
|
+
const last = current.events[current.events.length - 1];
|
|
506
|
+
if (fold && last && event.actor && event.kind && last.event.actor === event.actor && last.event.kind === event.kind) last.count += 1;
|
|
507
|
+
else current.events.push({ event, count: 1 });
|
|
508
|
+
}
|
|
509
|
+
return groups;
|
|
510
|
+
}
|
|
511
|
+
var UNITS = [
|
|
512
|
+
["second", 60],
|
|
513
|
+
["minute", 60],
|
|
514
|
+
["hour", 24],
|
|
515
|
+
["day", 7],
|
|
516
|
+
["week", 4.35],
|
|
517
|
+
["month", 12],
|
|
518
|
+
["year", Number.POSITIVE_INFINITY]
|
|
519
|
+
];
|
|
520
|
+
function timeAgo(at, { now = /* @__PURE__ */ new Date(), locale = "en-US", style = "short" } = {}) {
|
|
521
|
+
let value = (new Date(at).getTime() - now.getTime()) / 1e3;
|
|
522
|
+
let unit = "second";
|
|
523
|
+
for (const [name, size] of UNITS) {
|
|
524
|
+
unit = name;
|
|
525
|
+
if (Math.abs(value) < size - 0.5) break;
|
|
526
|
+
value /= size;
|
|
527
|
+
}
|
|
528
|
+
return new Intl.RelativeTimeFormat(locale, { numeric: "auto", style }).format(Math.round(value) + 0, unit);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// src/native/activity-feed.tsx
|
|
532
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
533
|
+
var LABELS = { today: "Today", yesterday: "Yesterday", times: (n) => `\xD7${n}`, newEvents: (n) => n === 1 ? "1 new event" : `${n} new events` };
|
|
534
|
+
var tone = (t, name) => ({ neutral: t.borderStrong, accent: t.accent, success: t.success, warning: t.warning, danger: t.danger, info: t.info })[name ?? "neutral"];
|
|
535
|
+
function ActivityFeed({ events, "aria-label": label, locale = "en-US", now: given, fold = true, live, leading, empty, labels: words, style }) {
|
|
536
|
+
const { theme } = useTheme();
|
|
537
|
+
const labels = { ...LABELS, ...words };
|
|
538
|
+
const [tick, setTick] = React3.useState(() => given ?? /* @__PURE__ */ new Date());
|
|
539
|
+
React3.useEffect(() => {
|
|
540
|
+
if (given) return;
|
|
541
|
+
const timer2 = setInterval(() => setTick(/* @__PURE__ */ new Date()), 6e4);
|
|
542
|
+
return () => clearInterval(timer2);
|
|
543
|
+
}, [given]);
|
|
544
|
+
const now = given ?? tick;
|
|
545
|
+
const seen = React3.useRef(events.length);
|
|
546
|
+
React3.useEffect(() => {
|
|
547
|
+
const added = events.length - seen.current;
|
|
548
|
+
seen.current = events.length;
|
|
549
|
+
if (live && added > 0) AccessibilityInfo2.announceForAccessibility(labels.newEvents(added));
|
|
550
|
+
}, [events.length, live]);
|
|
551
|
+
const sections = groupActivity(events, { now, locale, today: labels.today, yesterday: labels.yesterday, fold }).map((g) => ({ title: g.label, data: g.events }));
|
|
552
|
+
return /* @__PURE__ */ jsx4(
|
|
553
|
+
SectionList,
|
|
554
|
+
{
|
|
555
|
+
"aria-label": label,
|
|
556
|
+
style,
|
|
557
|
+
sections,
|
|
558
|
+
keyExtractor: (item) => item.event.id,
|
|
559
|
+
stickySectionHeadersEnabled: true,
|
|
560
|
+
ListEmptyComponent: empty ? /* @__PURE__ */ jsx4(Fragment, { children: empty }) : null,
|
|
561
|
+
renderSectionHeader: ({ section }) => /* @__PURE__ */ jsx4(View2, { style: [styles3.heading, { backgroundColor: theme.surface0 }], children: /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", role: "heading", style: styles3.headingText, children: section.title }) }),
|
|
562
|
+
renderItem: ({ item: { event, count } }) => /* @__PURE__ */ jsxs2(View2, { style: styles3.row, accessible: true, children: [
|
|
563
|
+
leading ? leading(event) : /* @__PURE__ */ jsx4(View2, { "aria-hidden": true, style: [styles3.marker, { backgroundColor: tone(theme, event.tone) }] }),
|
|
564
|
+
/* @__PURE__ */ jsxs2(View2, { style: styles3.body, children: [
|
|
565
|
+
/* @__PURE__ */ jsxs2(Txt, { children: [
|
|
566
|
+
event.title,
|
|
567
|
+
count > 1 ? /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", children: ` ${labels.times(count)}` }) : null
|
|
568
|
+
] }),
|
|
569
|
+
event.description ? /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", children: event.description }) : null
|
|
570
|
+
] }),
|
|
571
|
+
/* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", children: timeAgo(event.at, { now, locale }) })
|
|
572
|
+
] })
|
|
573
|
+
}
|
|
574
|
+
);
|
|
381
575
|
}
|
|
576
|
+
var styles3 = StyleSheet3.create({
|
|
577
|
+
heading: { paddingVertical: 6 },
|
|
578
|
+
headingText: { fontWeight: "700", textTransform: "uppercase", letterSpacing: 0.6 },
|
|
579
|
+
row: { flexDirection: "row", alignItems: "flex-start", gap: 12, paddingVertical: 10 },
|
|
580
|
+
marker: { width: 10, height: 10, borderRadius: 5, marginTop: 5 },
|
|
581
|
+
body: { flex: 1, gap: 2 }
|
|
582
|
+
});
|
|
382
583
|
|
|
383
584
|
// src/native/avatar.tsx
|
|
384
|
-
import
|
|
585
|
+
import * as React4 from "react";
|
|
586
|
+
import { Image, StyleSheet as StyleSheet4, Text as Text2, View as View3 } from "react-native";
|
|
587
|
+
import Svg, { Circle, Defs, LinearGradient, Stop, SvgUri } from "react-native-svg";
|
|
588
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
385
589
|
var SIDE = { xs: 20, sm: 32, md: 40, lg: 56, xl: 80 };
|
|
386
590
|
function isSvgUri(uri) {
|
|
387
591
|
return /^data:image\/svg\+xml[;,]/i.test(uri) || /\.svg(?:[?#]|$)/i.test(uri);
|
|
388
592
|
}
|
|
389
|
-
function AvatarRoot({ src, svg, alt = "", fallback, size = "md", style, ...props }) {
|
|
593
|
+
function AvatarRoot({ src, svg, alt = "", fallback, size = "md", presence, presenceLabel, ring, style, ...props }) {
|
|
390
594
|
const { theme } = useTheme();
|
|
391
|
-
const
|
|
595
|
+
const gradient = useSvgId("kz-ring-");
|
|
596
|
+
const [failedSrc, setFailedSrc] = React4.useState(null);
|
|
392
597
|
const failed = Boolean(src) && failedSrc === src;
|
|
393
598
|
const side = typeof size === "number" ? size : SIDE[size];
|
|
394
599
|
const initial = alt.trim().charAt(0).toUpperCase();
|
|
395
600
|
const content = fallback ?? initial;
|
|
396
|
-
|
|
397
|
-
|
|
601
|
+
const picture = /* @__PURE__ */ jsx5(
|
|
602
|
+
View3,
|
|
398
603
|
{
|
|
399
|
-
accessible: Boolean(alt),
|
|
400
|
-
role: alt ? "img" : void 0,
|
|
401
|
-
"aria-label": alt
|
|
402
|
-
...props,
|
|
403
|
-
style: [
|
|
404
|
-
children: src && !failed && (svg || isSvgUri(src)) ? /* @__PURE__ */
|
|
604
|
+
accessible: Boolean(alt) && !presence && !ring,
|
|
605
|
+
role: alt && !presence && !ring ? "img" : void 0,
|
|
606
|
+
"aria-label": alt && !presence && !ring ? alt : void 0,
|
|
607
|
+
...presence || ring ? {} : props,
|
|
608
|
+
style: [styles4.root, { width: side, height: side, borderRadius: side / 2, backgroundColor: theme.surface3 }, presence || ring ? null : style],
|
|
609
|
+
children: src && !failed && (svg || isSvgUri(src)) ? /* @__PURE__ */ jsx5(View3, { style: StyleSheet4.absoluteFill, pointerEvents: "none", children: /* @__PURE__ */ jsx5(SvgUri, { testID: props.testID ? `${props.testID}.svg` : void 0, uri: src, width: "100%", height: "100%", preserveAspectRatio: "xMidYMid slice", onError: () => setFailedSrc(src) }) }) : src && !failed ? /* @__PURE__ */ jsx5(Image, { testID: props.testID ? `${props.testID}.image` : void 0, source: { uri: src }, onError: () => setFailedSrc(src), resizeMode: "cover", style: StyleSheet4.absoluteFill }) : typeof content === "string" ? /* @__PURE__ */ jsx5(Text2, { style: [styles4.initial, { color: theme.textSecondary, fontSize: Math.max(9, Math.round(side * 0.4)) }], children: content }) : content
|
|
405
610
|
}
|
|
406
611
|
);
|
|
612
|
+
if (!presence && !ring) return picture;
|
|
613
|
+
const gap = ring ? Math.max(2.5, Math.round(side * 0.07)) : 0;
|
|
614
|
+
const outer = side + gap * 4;
|
|
615
|
+
const dot = Math.max(8, Math.round(side * 0.28));
|
|
616
|
+
const dotColor = presence === "online" ? theme.success : presence === "away" ? theme.warning : presence === "busy" ? theme.danger : theme.surface0;
|
|
617
|
+
const name = [alt, presence ? presenceLabel : null].filter(Boolean).join(", ");
|
|
618
|
+
return /* @__PURE__ */ jsxs3(View3, { accessible: Boolean(name), role: name ? "img" : void 0, "aria-label": name || void 0, ...props, style: [{ width: outer, height: outer, alignItems: "center", justifyContent: "center" }, style], children: [
|
|
619
|
+
ring ? /* @__PURE__ */ jsxs3(Svg, { width: outer, height: outer, style: StyleSheet4.absoluteFill, "aria-hidden": true, children: [
|
|
620
|
+
/* @__PURE__ */ jsx5(Defs, { children: /* @__PURE__ */ jsxs3(LinearGradient, { id: gradient, x1: "0", y1: "1", x2: "1", y2: "0", children: [
|
|
621
|
+
/* @__PURE__ */ jsx5(Stop, { offset: "0", stopColor: theme.accent }),
|
|
622
|
+
/* @__PURE__ */ jsx5(Stop, { offset: "1", stopColor: theme.accent2 })
|
|
623
|
+
] }) }),
|
|
624
|
+
/* @__PURE__ */ jsx5(
|
|
625
|
+
Circle,
|
|
626
|
+
{
|
|
627
|
+
cx: outer / 2,
|
|
628
|
+
cy: outer / 2,
|
|
629
|
+
r: outer / 2 - gap / 2 - 0.5,
|
|
630
|
+
fill: "none",
|
|
631
|
+
strokeWidth: gap,
|
|
632
|
+
stroke: ring === "story" ? `url(#${gradient})` : ring === "live" ? theme.danger : theme.borderStrong
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] }) : null,
|
|
636
|
+
picture,
|
|
637
|
+
presence ? /* @__PURE__ */ jsx5(
|
|
638
|
+
View3,
|
|
639
|
+
{
|
|
640
|
+
"aria-hidden": true,
|
|
641
|
+
style: [
|
|
642
|
+
styles4.dot,
|
|
643
|
+
{ width: dot, height: dot, borderRadius: dot / 2, right: gap * 2, bottom: gap * 2, backgroundColor: dotColor, borderColor: presence === "offline" ? theme.textMuted : theme.surface0 }
|
|
644
|
+
]
|
|
645
|
+
}
|
|
646
|
+
) : null
|
|
647
|
+
] });
|
|
407
648
|
}
|
|
408
649
|
function AvatarGroup({ max, size = "md", style, children, ...props }) {
|
|
409
650
|
const { theme } = useTheme();
|
|
410
|
-
const items2 =
|
|
651
|
+
const items2 = React4.Children.toArray(children);
|
|
411
652
|
const shown = max === void 0 ? items2 : items2.slice(0, max);
|
|
412
653
|
const rest = items2.length - shown.length;
|
|
413
654
|
const side = typeof size === "number" ? size : SIDE[size];
|
|
414
655
|
const ring = { borderWidth: 2, borderColor: theme.surface0, marginLeft: -side / 5 };
|
|
415
|
-
return /* @__PURE__ */
|
|
416
|
-
shown.map((child, i) => /* @__PURE__ */
|
|
417
|
-
rest > 0 ? /* @__PURE__ */
|
|
656
|
+
return /* @__PURE__ */ jsxs3(View3, { ...props, style: [styles4.group, { paddingLeft: side / 5 }, style], children: [
|
|
657
|
+
shown.map((child, i) => /* @__PURE__ */ jsx5(View3, { style: [ring, { borderRadius: side }], children: React4.isValidElement(child) ? React4.cloneElement(child, { size }) : child }, i)),
|
|
658
|
+
rest > 0 ? /* @__PURE__ */ jsx5(View3, { style: [ring, { borderRadius: side }], children: /* @__PURE__ */ jsx5(AvatarRoot, { size, fallback: `+${rest}` }) }) : null
|
|
418
659
|
] });
|
|
419
660
|
}
|
|
420
661
|
var Avatar = Object.assign(AvatarRoot, { Group: AvatarGroup });
|
|
421
|
-
var
|
|
662
|
+
var styles4 = StyleSheet4.create({
|
|
422
663
|
root: { overflow: "hidden", alignItems: "center", justifyContent: "center" },
|
|
423
664
|
initial: { fontWeight: "700" },
|
|
424
|
-
group: { flexDirection: "row", alignItems: "center" }
|
|
665
|
+
group: { flexDirection: "row", alignItems: "center" },
|
|
666
|
+
dot: { position: "absolute", borderWidth: 2 }
|
|
425
667
|
});
|
|
426
668
|
|
|
427
669
|
// src/native/badge.tsx
|
|
428
|
-
import * as
|
|
429
|
-
import { Animated, StyleSheet as
|
|
430
|
-
import { jsx as
|
|
431
|
-
function look(
|
|
432
|
-
switch (
|
|
670
|
+
import * as React5 from "react";
|
|
671
|
+
import { Animated, StyleSheet as StyleSheet5, Text as Text3 } from "react-native";
|
|
672
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
673
|
+
function look(tone3, t) {
|
|
674
|
+
switch (tone3) {
|
|
433
675
|
case "accent":
|
|
434
676
|
return { bg: t.accentSoft, fg: t.textPrimary, border: alpha(t.accent, 0.4), dot: t.accent };
|
|
435
677
|
case "success":
|
|
436
678
|
case "warning":
|
|
437
679
|
case "danger":
|
|
438
|
-
return { bg: alpha(t[
|
|
680
|
+
return { bg: alpha(t[tone3], 0.15), fg: t.textPrimary, border: alpha(t[tone3], 0.4), dot: t[tone3] };
|
|
439
681
|
case "scrim":
|
|
440
682
|
return { bg: t.scrim, fg: t.textOnMedia, border: "transparent", dot: t.textOnMedia };
|
|
441
683
|
default:
|
|
442
684
|
return { bg: t.surface3, fg: t.textSecondary, border: "transparent", dot: t.textSecondary };
|
|
443
685
|
}
|
|
444
686
|
}
|
|
445
|
-
function Badge({ tone:
|
|
687
|
+
function Badge({ tone: tone3 = "neutral", size = "sm", dot, pulse, style, children, ...props }) {
|
|
446
688
|
const { theme } = useTheme();
|
|
447
|
-
const colors = look(
|
|
689
|
+
const colors = look(tone3, theme);
|
|
448
690
|
const reduce = useReducedMotion();
|
|
449
|
-
const [opacity] =
|
|
450
|
-
|
|
691
|
+
const [opacity] = React5.useState(() => new Animated.Value(1));
|
|
692
|
+
React5.useEffect(() => {
|
|
451
693
|
if (!dot || !pulse || reduce) return;
|
|
452
694
|
const loop = Animated.loop(
|
|
453
695
|
Animated.sequence([
|
|
@@ -461,19 +703,19 @@ function Badge({ tone: tone2 = "neutral", size = "sm", dot, pulse, style, childr
|
|
|
461
703
|
opacity.setValue(1);
|
|
462
704
|
};
|
|
463
705
|
}, [dot, pulse, reduce, opacity]);
|
|
464
|
-
return /* @__PURE__ */
|
|
706
|
+
return /* @__PURE__ */ jsxs4(
|
|
465
707
|
Animated.View,
|
|
466
708
|
{
|
|
467
709
|
...props,
|
|
468
|
-
style: [
|
|
710
|
+
style: [styles5.root, size === "md" ? styles5.md : styles5.sm, { backgroundColor: colors.bg, borderColor: colors.border }, style],
|
|
469
711
|
children: [
|
|
470
|
-
dot ? /* @__PURE__ */
|
|
471
|
-
typeof children === "string" || typeof children === "number" ? /* @__PURE__ */
|
|
712
|
+
dot ? /* @__PURE__ */ jsx6(Animated.View, { "aria-hidden": true, style: [styles5.dot, { backgroundColor: colors.dot, opacity }] }) : null,
|
|
713
|
+
typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx6(Text3, { style: [styles5.text, { color: colors.fg, fontSize: size === "md" ? 11 : 10 }], children }) : children
|
|
472
714
|
]
|
|
473
715
|
}
|
|
474
716
|
);
|
|
475
717
|
}
|
|
476
|
-
var
|
|
718
|
+
var styles5 = StyleSheet5.create({
|
|
477
719
|
root: { flexDirection: "row", alignItems: "center", alignSelf: "flex-start", gap: 4, borderRadius: 9999, borderWidth: 1 },
|
|
478
720
|
sm: { paddingHorizontal: 8, paddingVertical: 2 },
|
|
479
721
|
md: { paddingHorizontal: 10, paddingVertical: 4 },
|
|
@@ -482,48 +724,10 @@ var styles2 = StyleSheet2.create({
|
|
|
482
724
|
});
|
|
483
725
|
|
|
484
726
|
// src/native/button.tsx
|
|
485
|
-
import * as
|
|
486
|
-
import { ActivityIndicator, Pressable, StyleSheet as
|
|
487
|
-
import
|
|
488
|
-
|
|
489
|
-
// src/native/txt.tsx
|
|
490
|
-
import { StyleSheet as StyleSheet3, Text as Text3 } from "react-native";
|
|
491
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
492
|
-
var TONE = {
|
|
493
|
-
text: "textPrimary",
|
|
494
|
-
secondary: "textSecondary",
|
|
495
|
-
muted: "textMuted",
|
|
496
|
-
accent: "accentText",
|
|
497
|
-
success: "successText",
|
|
498
|
-
warning: "warningText",
|
|
499
|
-
danger: "dangerText",
|
|
500
|
-
onAccent: "onAccent",
|
|
501
|
-
onMedia: "textOnMedia"
|
|
502
|
-
};
|
|
503
|
-
function Txt({ variant = "body", tone: tone2 = "text", style, ...props }) {
|
|
504
|
-
const { theme, fonts } = useTheme();
|
|
505
|
-
const family = variant === "display" || variant === "title" ? fonts.display : variant === "mono" ? fonts.mono : fonts.sans;
|
|
506
|
-
return /* @__PURE__ */ jsx4(
|
|
507
|
-
Text3,
|
|
508
|
-
{
|
|
509
|
-
role: variant === "display" || variant === "title" ? "heading" : void 0,
|
|
510
|
-
...props,
|
|
511
|
-
style: [styles3[variant], { color: theme[TONE[tone2]] }, family ? { fontFamily: family } : null, style]
|
|
512
|
-
}
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
var textStyles = StyleSheet3.create({
|
|
516
|
-
display: { fontSize: 30, lineHeight: 36, fontWeight: "900", letterSpacing: -0.5 },
|
|
517
|
-
title: { fontSize: 18, lineHeight: 24, fontWeight: "800" },
|
|
518
|
-
body: { fontSize: 15, lineHeight: 21 },
|
|
519
|
-
caption: { fontSize: 12, lineHeight: 16 },
|
|
520
|
-
label: { fontSize: 14, lineHeight: 18, fontWeight: "700" },
|
|
521
|
-
mono: { fontSize: 14, lineHeight: 18, fontWeight: "700", fontVariant: ["tabular-nums"] }
|
|
522
|
-
});
|
|
523
|
-
var styles3 = textStyles;
|
|
524
|
-
|
|
525
|
-
// src/native/button.tsx
|
|
526
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
727
|
+
import * as React6 from "react";
|
|
728
|
+
import { ActivityIndicator, Pressable as Pressable2, StyleSheet as StyleSheet6, View as View4 } from "react-native";
|
|
729
|
+
import Svg2, { Defs as Defs2, LinearGradient as LinearGradient2, Rect, Stop as Stop2 } from "react-native-svg";
|
|
730
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
527
731
|
function look2(variant, t) {
|
|
528
732
|
switch (variant) {
|
|
529
733
|
case "primary":
|
|
@@ -558,19 +762,19 @@ function useButton({ variant = "secondary", size = "md", shape = "rounded", load
|
|
|
558
762
|
}
|
|
559
763
|
function Fill({ colors, id }) {
|
|
560
764
|
if (!colors.gradient) return null;
|
|
561
|
-
return /* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
564
|
-
/* @__PURE__ */
|
|
765
|
+
return /* @__PURE__ */ jsxs5(Svg2, { "aria-hidden": true, pointerEvents: "none", style: StyleSheet6.absoluteFill, width: "100%", height: "100%", children: [
|
|
766
|
+
/* @__PURE__ */ jsx7(Defs2, { children: /* @__PURE__ */ jsxs5(LinearGradient2, { id, x1: "0", y1: "0", x2: "1", y2: "0", children: [
|
|
767
|
+
/* @__PURE__ */ jsx7(Stop2, { offset: "0", stopColor: colors.gradient[0] }),
|
|
768
|
+
/* @__PURE__ */ jsx7(Stop2, { offset: "1", stopColor: colors.gradient[1] })
|
|
565
769
|
] }) }),
|
|
566
|
-
/* @__PURE__ */
|
|
770
|
+
/* @__PURE__ */ jsx7(Rect, { width: "100%", height: "100%", fill: `url(#${id})` })
|
|
567
771
|
] });
|
|
568
772
|
}
|
|
569
773
|
function Button({ label, icon, variant, size = "md", shape, loading = false, disabled, style, ...props }) {
|
|
570
774
|
const { colors, inactive, frame } = useButton({ variant, size, shape, loading, disabled });
|
|
571
|
-
const gradientId = `kz-button-${
|
|
572
|
-
return /* @__PURE__ */
|
|
573
|
-
|
|
775
|
+
const gradientId = `kz-button-${React6.useId().replace(/:/g, "")}`;
|
|
776
|
+
return /* @__PURE__ */ jsxs5(
|
|
777
|
+
Pressable2,
|
|
574
778
|
{
|
|
575
779
|
role: "button",
|
|
576
780
|
"aria-label": label,
|
|
@@ -578,12 +782,12 @@ function Button({ label, icon, variant, size = "md", shape, loading = false, dis
|
|
|
578
782
|
"aria-busy": loading,
|
|
579
783
|
...props,
|
|
580
784
|
disabled: inactive,
|
|
581
|
-
style: ({ pressed }) => [
|
|
785
|
+
style: ({ pressed }) => [styles6.base, { paddingHorizontal: PADDING[size] }, frame(pressed), style],
|
|
582
786
|
children: [
|
|
583
|
-
/* @__PURE__ */
|
|
584
|
-
/* @__PURE__ */
|
|
585
|
-
loading ? /* @__PURE__ */
|
|
586
|
-
/* @__PURE__ */
|
|
787
|
+
/* @__PURE__ */ jsx7(Fill, { colors, id: gradientId }),
|
|
788
|
+
/* @__PURE__ */ jsxs5(View4, { style: styles6.row, children: [
|
|
789
|
+
loading ? /* @__PURE__ */ jsx7(ActivityIndicator, { "aria-hidden": true, size: "small", color: colors.fg }) : icon,
|
|
790
|
+
/* @__PURE__ */ jsx7(Txt, { variant: "label", numberOfLines: 1, style: { color: colors.fg, fontSize: size === "sm" ? 12 : 14 }, children: label })
|
|
587
791
|
] })
|
|
588
792
|
]
|
|
589
793
|
}
|
|
@@ -591,10 +795,10 @@ function Button({ label, icon, variant, size = "md", shape, loading = false, dis
|
|
|
591
795
|
}
|
|
592
796
|
function IconButton({ label, icon, variant, size = "md", shape, loading = false, disabled, style, ...props }) {
|
|
593
797
|
const { colors, inactive, frame } = useButton({ variant, size, shape, loading, disabled });
|
|
594
|
-
const gradientId = `kz-button-${
|
|
798
|
+
const gradientId = `kz-button-${React6.useId().replace(/:/g, "")}`;
|
|
595
799
|
const side = HEIGHT[size];
|
|
596
|
-
return /* @__PURE__ */
|
|
597
|
-
|
|
800
|
+
return /* @__PURE__ */ jsxs5(
|
|
801
|
+
Pressable2,
|
|
598
802
|
{
|
|
599
803
|
role: "button",
|
|
600
804
|
"aria-label": label,
|
|
@@ -603,36 +807,36 @@ function IconButton({ label, icon, variant, size = "md", shape, loading = false,
|
|
|
603
807
|
hitSlop: side < 44 ? (44 - side) / 2 : void 0,
|
|
604
808
|
...props,
|
|
605
809
|
disabled: inactive,
|
|
606
|
-
style: ({ pressed }) => [
|
|
810
|
+
style: ({ pressed }) => [styles6.base, frame(pressed), { width: side }, style],
|
|
607
811
|
children: [
|
|
608
|
-
/* @__PURE__ */
|
|
609
|
-
loading ? /* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ jsx7(Fill, { colors, id: gradientId }),
|
|
813
|
+
loading ? /* @__PURE__ */ jsx7(ActivityIndicator, { "aria-hidden": true, size: "small", color: colors.fg }) : icon
|
|
610
814
|
]
|
|
611
815
|
}
|
|
612
816
|
);
|
|
613
817
|
}
|
|
614
|
-
var
|
|
818
|
+
var styles6 = StyleSheet6.create({
|
|
615
819
|
base: { alignItems: "center", justifyContent: "center", borderWidth: 1, overflow: "hidden" },
|
|
616
820
|
row: { flexDirection: "row", alignItems: "center", gap: 8 }
|
|
617
821
|
});
|
|
618
822
|
|
|
619
823
|
// src/native/card.tsx
|
|
620
|
-
import { Image as Image2, Pressable as
|
|
621
|
-
import { jsx as
|
|
622
|
-
function CardRoot({ tone:
|
|
824
|
+
import { Image as Image2, Pressable as Pressable3, StyleSheet as StyleSheet7, View as View5 } from "react-native";
|
|
825
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
826
|
+
function CardRoot({ tone: tone3 = "default", radius: radius3 = "xl", onPress, style, ...props }) {
|
|
623
827
|
const { theme, radius: r } = useTheme();
|
|
624
828
|
const frame = [
|
|
625
|
-
|
|
829
|
+
styles7.root,
|
|
626
830
|
{
|
|
627
|
-
backgroundColor:
|
|
831
|
+
backgroundColor: tone3 === "elevated" ? theme.surface2 : theme.surface1,
|
|
628
832
|
borderColor: theme.borderDefault,
|
|
629
833
|
borderRadius: r[radius3]
|
|
630
834
|
},
|
|
631
|
-
|
|
835
|
+
tone3 === "elevated" ? [styles7.shadow, { shadowColor: theme.scrimStrong }] : null
|
|
632
836
|
];
|
|
633
|
-
if (!onPress) return /* @__PURE__ */
|
|
634
|
-
return /* @__PURE__ */
|
|
635
|
-
|
|
837
|
+
if (!onPress) return /* @__PURE__ */ jsx8(View5, { ...props, style: [frame, style] });
|
|
838
|
+
return /* @__PURE__ */ jsx8(
|
|
839
|
+
Pressable3,
|
|
636
840
|
{
|
|
637
841
|
role: "button",
|
|
638
842
|
onPress,
|
|
@@ -644,14 +848,14 @@ function CardRoot({ tone: tone2 = "default", radius: radius3 = "xl", onPress, st
|
|
|
644
848
|
var ASPECT = { video: 16 / 9, square: 1, portrait: 3 / 4 };
|
|
645
849
|
function CardMedia({ aspect = "video", style, ...props }) {
|
|
646
850
|
const { theme } = useTheme();
|
|
647
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.media, { backgroundColor: theme.media }, aspect === "auto" ? null : { aspectRatio: ASPECT[aspect] }, style] });
|
|
648
852
|
}
|
|
649
853
|
function CardImage({ src, fallback, alt, style, ...props }) {
|
|
650
854
|
const { theme } = useTheme();
|
|
651
855
|
if (!src) {
|
|
652
|
-
return /* @__PURE__ */
|
|
856
|
+
return /* @__PURE__ */ jsx8(View5, { "aria-hidden": true, style: [StyleSheet7.absoluteFill, styles7.center, { backgroundColor: theme.accentSoft }], children: fallback });
|
|
653
857
|
}
|
|
654
|
-
return /* @__PURE__ */
|
|
858
|
+
return /* @__PURE__ */ jsx8(Image2, { accessible: Boolean(alt), alt, "aria-label": alt, resizeMode: "cover", ...props, source: { uri: src }, style: [StyleSheet7.absoluteFill, style] });
|
|
655
859
|
}
|
|
656
860
|
var CORNER = {
|
|
657
861
|
"top-left": { top: 10, left: 10 },
|
|
@@ -660,21 +864,21 @@ var CORNER = {
|
|
|
660
864
|
"bottom-right": { bottom: 10, right: 10 }
|
|
661
865
|
};
|
|
662
866
|
function CardOverlay({ corner = "top-left", style, ...props }) {
|
|
663
|
-
return /* @__PURE__ */
|
|
867
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.overlay, CORNER[corner], style] });
|
|
664
868
|
}
|
|
665
869
|
var PADDING2 = { none: 0, sm: 12, md: 16, lg: 24 };
|
|
666
870
|
function CardBody({ padding = "md", style, ...props }) {
|
|
667
|
-
return /* @__PURE__ */
|
|
871
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.body, { padding: PADDING2[padding] }, style] });
|
|
668
872
|
}
|
|
669
873
|
function CardTitle({ numberOfLines = 1, ...props }) {
|
|
670
|
-
return /* @__PURE__ */
|
|
874
|
+
return /* @__PURE__ */ jsx8(Txt, { variant: "label", role: "heading", numberOfLines, ...props });
|
|
671
875
|
}
|
|
672
876
|
function CardDescription({ numberOfLines = 2, ...props }) {
|
|
673
|
-
return /* @__PURE__ */
|
|
877
|
+
return /* @__PURE__ */ jsx8(Txt, { variant: "caption", tone: "secondary", numberOfLines, ...props });
|
|
674
878
|
}
|
|
675
879
|
function CardFooter({ style, ...props }) {
|
|
676
880
|
const { theme } = useTheme();
|
|
677
|
-
return /* @__PURE__ */
|
|
881
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.footer, { borderTopColor: theme.borderSubtle }, style] });
|
|
678
882
|
}
|
|
679
883
|
var Card = {
|
|
680
884
|
Root: CardRoot,
|
|
@@ -686,37 +890,37 @@ var Card = {
|
|
|
686
890
|
Description: CardDescription,
|
|
687
891
|
Footer: CardFooter
|
|
688
892
|
};
|
|
689
|
-
var
|
|
690
|
-
root: { overflow: "hidden", borderWidth:
|
|
893
|
+
var styles7 = StyleSheet7.create({
|
|
894
|
+
root: { overflow: "hidden", borderWidth: StyleSheet7.hairlineWidth },
|
|
691
895
|
shadow: { shadowOpacity: 0.25, shadowRadius: 12, shadowOffset: { width: 0, height: 6 }, elevation: 4 },
|
|
692
896
|
media: { position: "relative", overflow: "hidden", width: "100%" },
|
|
693
897
|
center: { alignItems: "center", justifyContent: "center" },
|
|
694
898
|
overlay: { position: "absolute", zIndex: 1, flexDirection: "row", alignItems: "center", gap: 6 },
|
|
695
899
|
body: { gap: 12 },
|
|
696
|
-
footer: { flexDirection: "row", alignItems: "center", gap: 8, borderTopWidth:
|
|
900
|
+
footer: { flexDirection: "row", alignItems: "center", gap: 8, borderTopWidth: StyleSheet7.hairlineWidth, paddingTop: 12, marginTop: "auto" }
|
|
697
901
|
});
|
|
698
902
|
|
|
699
903
|
// src/native/checkbox.tsx
|
|
700
|
-
import * as
|
|
701
|
-
import { Pressable as
|
|
702
|
-
import
|
|
703
|
-
import { jsx as
|
|
904
|
+
import * as React7 from "react";
|
|
905
|
+
import { Pressable as Pressable4, StyleSheet as StyleSheet8, Text as Text4, View as View6 } from "react-native";
|
|
906
|
+
import Svg3, { Path } from "react-native-svg";
|
|
907
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
704
908
|
function Checkbox({ children, label, checked, defaultChecked = false, onCheckedChange, error, disabled, style }) {
|
|
705
909
|
const { theme, radius: radius3 } = useTheme();
|
|
706
|
-
const [own, setOwn] =
|
|
910
|
+
const [own, setOwn] = React7.useState(defaultChecked);
|
|
707
911
|
const on = checked ?? own;
|
|
708
912
|
const toggle = () => {
|
|
709
913
|
if (checked === void 0) setOwn(!on);
|
|
710
914
|
onCheckedChange?.(!on);
|
|
711
915
|
};
|
|
712
|
-
const box = /* @__PURE__ */
|
|
713
|
-
|
|
916
|
+
const box = /* @__PURE__ */ jsx9(
|
|
917
|
+
View6,
|
|
714
918
|
{
|
|
715
919
|
style: [
|
|
716
|
-
|
|
920
|
+
styles8.box,
|
|
717
921
|
{ borderRadius: radius3.xs + 2, borderColor: error ? theme.danger : on ? theme.accent : theme.borderStrong, backgroundColor: on ? theme.accent : theme.surface1 }
|
|
718
922
|
],
|
|
719
|
-
children: on ? /* @__PURE__ */
|
|
923
|
+
children: on ? /* @__PURE__ */ jsx9(Svg3, { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: theme.onAccent, strokeWidth: 3, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx9(Path, { d: "M20 6 9 17l-5-5" }) }) : null
|
|
720
924
|
}
|
|
721
925
|
);
|
|
722
926
|
const plain = children === void 0 || typeof children === "string";
|
|
@@ -729,21 +933,21 @@ function Checkbox({ children, label, checked, defaultChecked = false, onCheckedC
|
|
|
729
933
|
disabled,
|
|
730
934
|
onPress: toggle
|
|
731
935
|
};
|
|
732
|
-
return /* @__PURE__ */
|
|
733
|
-
plain ? /* @__PURE__ */
|
|
936
|
+
return /* @__PURE__ */ jsxs6(View6, { style: [styles8.root, style], children: [
|
|
937
|
+
plain ? /* @__PURE__ */ jsxs6(Pressable4, { ...a11y, hitSlop: 4, style: [styles8.row, disabled ? styles8.disabled : null], children: [
|
|
734
938
|
box,
|
|
735
|
-
children !== void 0 ? /* @__PURE__ */
|
|
939
|
+
children !== void 0 ? /* @__PURE__ */ jsx9(View6, { style: styles8.text, children: /* @__PURE__ */ jsx9(Text4, { style: [styles8.label, { color: theme.textPrimary }], children }) }) : null
|
|
736
940
|
] }) : (
|
|
737
941
|
// Words with links: the box alone is the control (a 44-pt target, named by `label`), the links stay links.
|
|
738
|
-
/* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
740
|
-
/* @__PURE__ */
|
|
942
|
+
/* @__PURE__ */ jsxs6(View6, { style: [styles8.row, disabled ? styles8.disabled : null], children: [
|
|
943
|
+
/* @__PURE__ */ jsx9(Pressable4, { ...a11y, hitSlop: 11, style: styles8.target, children: box }),
|
|
944
|
+
/* @__PURE__ */ jsx9(View6, { style: styles8.text, children })
|
|
741
945
|
] })
|
|
742
946
|
),
|
|
743
|
-
error ? /* @__PURE__ */
|
|
947
|
+
error ? /* @__PURE__ */ jsx9(Text4, { role: "alert", "aria-live": "polite", style: [styles8.error, { color: theme.dangerText }], children: error }) : null
|
|
744
948
|
] });
|
|
745
949
|
}
|
|
746
|
-
var
|
|
950
|
+
var styles8 = StyleSheet8.create({
|
|
747
951
|
root: { gap: 2, alignSelf: "stretch" },
|
|
748
952
|
row: { flexDirection: "row", alignItems: "center", gap: 12, minHeight: 44 },
|
|
749
953
|
target: { minHeight: 44, justifyContent: "center" },
|
|
@@ -755,18 +959,18 @@ var styles6 = StyleSheet6.create({
|
|
|
755
959
|
});
|
|
756
960
|
|
|
757
961
|
// src/native/chip.tsx
|
|
758
|
-
import * as
|
|
759
|
-
import { Pressable as
|
|
760
|
-
import { Fragment, jsx as
|
|
761
|
-
var ChipGroupContext =
|
|
962
|
+
import * as React8 from "react";
|
|
963
|
+
import { Pressable as Pressable5, ScrollView, StyleSheet as StyleSheet9, Text as Text5, View as View7 } from "react-native";
|
|
964
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
965
|
+
var ChipGroupContext = React8.createContext(null);
|
|
762
966
|
function Label({ children, color, size }) {
|
|
763
|
-
if (typeof children !== "string" && typeof children !== "number") return /* @__PURE__ */
|
|
764
|
-
return /* @__PURE__ */
|
|
967
|
+
if (typeof children !== "string" && typeof children !== "number") return /* @__PURE__ */ jsx10(Fragment2, { children });
|
|
968
|
+
return /* @__PURE__ */ jsx10(Text5, { style: [styles9.label, { color, fontSize: size === "sm" ? 12 : 13 }], children });
|
|
765
969
|
}
|
|
766
970
|
function ChipBase(props) {
|
|
767
|
-
const group =
|
|
971
|
+
const group = React8.useContext(ChipGroupContext);
|
|
768
972
|
const { theme, radius: radius3 } = useTheme();
|
|
769
|
-
const [own, setOwn] =
|
|
973
|
+
const [own, setOwn] = React8.useState(props.removable ? false : props.defaultSelected ?? false);
|
|
770
974
|
const size = props.size ?? group?.size ?? "md";
|
|
771
975
|
const frame = (on2, pressed) => ({
|
|
772
976
|
height: size === "sm" ? 28 : 36,
|
|
@@ -777,9 +981,9 @@ function ChipBase(props) {
|
|
|
777
981
|
});
|
|
778
982
|
if (props.removable) {
|
|
779
983
|
const { removable: _r2, removeLabel, onRemove, disabled: disabled2, size: _s2, style: style2, children: children2, ...rest2 } = props;
|
|
780
|
-
return /* @__PURE__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
984
|
+
return /* @__PURE__ */ jsxs7(View7, { ...rest2, style: [styles9.base, frame(false, false), disabled2 ? styles9.disabled : null, style2], children: [
|
|
985
|
+
/* @__PURE__ */ jsx10(Label, { color: theme.textSecondary, size, children: children2 }),
|
|
986
|
+
/* @__PURE__ */ jsx10(Pressable5, { role: "button", "aria-label": removeLabel, disabled: disabled2 ?? void 0, hitSlop: 10, onPress: onRemove, style: styles9.remove, children: /* @__PURE__ */ jsx10(Text5, { style: [styles9.cross, { color: theme.textSecondary }], children: "\xD7" }) })
|
|
783
987
|
] });
|
|
784
988
|
}
|
|
785
989
|
const { removable: _r, value, selected, defaultSelected: _d, onSelectedChange, disabled: ownDisabled, size: _s, style, children, ...rest } = props;
|
|
@@ -792,8 +996,8 @@ function ChipBase(props) {
|
|
|
792
996
|
onSelectedChange?.(!on);
|
|
793
997
|
};
|
|
794
998
|
const single = group?.type === "single";
|
|
795
|
-
return /* @__PURE__ */
|
|
796
|
-
|
|
999
|
+
return /* @__PURE__ */ jsx10(
|
|
1000
|
+
Pressable5,
|
|
797
1001
|
{
|
|
798
1002
|
role: single ? "radio" : "checkbox",
|
|
799
1003
|
"aria-checked": on,
|
|
@@ -801,17 +1005,17 @@ function ChipBase(props) {
|
|
|
801
1005
|
...rest,
|
|
802
1006
|
disabled,
|
|
803
1007
|
onPress: press,
|
|
804
|
-
style: ({ pressed }) => [
|
|
805
|
-
children: /* @__PURE__ */
|
|
1008
|
+
style: ({ pressed }) => [styles9.base, frame(on, pressed), disabled ? styles9.disabled : null, style],
|
|
1009
|
+
children: /* @__PURE__ */ jsx10(Label, { color: on ? theme.textPrimary : theme.textSecondary, size, children })
|
|
806
1010
|
}
|
|
807
1011
|
);
|
|
808
1012
|
}
|
|
809
1013
|
function ChipGroup(props) {
|
|
810
1014
|
const { size, disabled, scrollable, "aria-label": label, style, children } = props;
|
|
811
1015
|
const initial = props.type === "single" ? props.defaultValue ?? "" : props.defaultValue ?? [];
|
|
812
|
-
const [own, setOwn] =
|
|
1016
|
+
const [own, setOwn] = React8.useState(initial);
|
|
813
1017
|
const current = props.value ?? own;
|
|
814
|
-
const context =
|
|
1018
|
+
const context = React8.useMemo(() => {
|
|
815
1019
|
const list = Array.isArray(current) ? current : [current];
|
|
816
1020
|
return {
|
|
817
1021
|
type: props.type,
|
|
@@ -826,10 +1030,10 @@ function ChipGroup(props) {
|
|
|
826
1030
|
};
|
|
827
1031
|
}, [current, props.type, props.value, props.onValueChange, size, disabled]);
|
|
828
1032
|
const a11y = { role: props.type === "single" ? "radiogroup" : "group", "aria-label": label };
|
|
829
|
-
return /* @__PURE__ */
|
|
1033
|
+
return /* @__PURE__ */ jsx10(ChipGroupContext.Provider, { value: context, children: scrollable ? /* @__PURE__ */ jsx10(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, ...a11y, style, contentContainerStyle: styles9.row, children }) : /* @__PURE__ */ jsx10(View7, { ...a11y, style: [styles9.row, styles9.wrap, style], children }) });
|
|
830
1034
|
}
|
|
831
1035
|
var Chip = Object.assign(ChipBase, { Group: ChipGroup });
|
|
832
|
-
var
|
|
1036
|
+
var styles9 = StyleSheet9.create({
|
|
833
1037
|
base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 6, paddingHorizontal: 14, borderWidth: 1, alignSelf: "flex-start" },
|
|
834
1038
|
label: { fontWeight: "600" },
|
|
835
1039
|
remove: { marginRight: -6, width: 24, height: 24, alignItems: "center", justifyContent: "center" },
|
|
@@ -840,30 +1044,30 @@ var styles7 = StyleSheet7.create({
|
|
|
840
1044
|
});
|
|
841
1045
|
|
|
842
1046
|
// src/native/combobox.tsx
|
|
843
|
-
import * as
|
|
844
|
-
import { Pressable as
|
|
845
|
-
import
|
|
1047
|
+
import * as React10 from "react";
|
|
1048
|
+
import { Pressable as Pressable7, ScrollView as ScrollView2, StyleSheet as StyleSheet11, Text as Text7, TextInput, View as View9 } from "react-native";
|
|
1049
|
+
import Svg4, { Path as Path2 } from "react-native-svg";
|
|
846
1050
|
|
|
847
1051
|
// src/native/dialog.tsx
|
|
848
|
-
import * as
|
|
849
|
-
import { Animated as Animated2, Modal, Pressable as
|
|
850
|
-
import { jsx as
|
|
1052
|
+
import * as React9 from "react";
|
|
1053
|
+
import { Animated as Animated2, Modal as Modal2, Pressable as Pressable6, StyleSheet as StyleSheet10, Text as Text6, View as View8 } from "react-native";
|
|
1054
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
851
1055
|
function Sheet({ open, onOpenChange, title, closeLabel = "Close", children, style }) {
|
|
852
1056
|
const { theme, radius: radius3, motion: motion3 } = useTheme();
|
|
853
|
-
const [rise] =
|
|
854
|
-
|
|
1057
|
+
const [rise] = React9.useState(() => new Animated2.Value(0));
|
|
1058
|
+
React9.useEffect(() => {
|
|
855
1059
|
if (open) Animated2.timing(rise, { toValue: 1, duration: motion3.duration.base * 1.6, useNativeDriver: true }).start();
|
|
856
1060
|
else rise.setValue(0);
|
|
857
1061
|
}, [open, rise, motion3.duration.base]);
|
|
858
|
-
return /* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ jsx11(Modal2, { transparent: true, visible: open, animationType: "none", onRequestClose: () => onOpenChange(false), statusBarTranslucent: true, children: /* @__PURE__ */ jsxs8(View8, { style: styles10.backdrop, children: [
|
|
1063
|
+
/* @__PURE__ */ jsx11(Animated2.View, { style: [StyleSheet10.absoluteFill, { opacity: rise }], children: /* @__PURE__ */ jsx11(Pressable6, { role: "button", "aria-label": closeLabel, onPress: () => onOpenChange(false), style: [StyleSheet10.absoluteFill, { backgroundColor: theme.scrim }] }) }),
|
|
1064
|
+
/* @__PURE__ */ jsxs8(
|
|
861
1065
|
Animated2.View,
|
|
862
1066
|
{
|
|
863
1067
|
role: "dialog",
|
|
864
1068
|
"aria-label": title,
|
|
865
1069
|
style: [
|
|
866
|
-
|
|
1070
|
+
styles10.sheet,
|
|
867
1071
|
{
|
|
868
1072
|
backgroundColor: theme.surface1,
|
|
869
1073
|
borderColor: theme.borderDefault,
|
|
@@ -876,37 +1080,37 @@ function Sheet({ open, onOpenChange, title, closeLabel = "Close", children, styl
|
|
|
876
1080
|
style
|
|
877
1081
|
],
|
|
878
1082
|
children: [
|
|
879
|
-
/* @__PURE__ */
|
|
880
|
-
title ? /* @__PURE__ */
|
|
1083
|
+
/* @__PURE__ */ jsx11(View8, { "aria-hidden": true, style: [styles10.grip, { backgroundColor: theme.borderStrong }] }),
|
|
1084
|
+
title ? /* @__PURE__ */ jsx11(Text6, { role: "heading", style: [styles10.title, { color: theme.textPrimary }], children: title }) : null,
|
|
881
1085
|
children
|
|
882
1086
|
]
|
|
883
1087
|
}
|
|
884
1088
|
)
|
|
885
1089
|
] }) });
|
|
886
1090
|
}
|
|
887
|
-
var
|
|
1091
|
+
var styles10 = StyleSheet10.create({
|
|
888
1092
|
backdrop: { flex: 1, justifyContent: "flex-end" },
|
|
889
|
-
sheet: { maxHeight: "85%", paddingHorizontal: 16, paddingTop: 8, paddingBottom: 28, gap: 12, borderWidth:
|
|
1093
|
+
sheet: { maxHeight: "85%", paddingHorizontal: 16, paddingTop: 8, paddingBottom: 28, gap: 12, borderWidth: StyleSheet10.hairlineWidth, shadowOpacity: 0.3, shadowRadius: 16, shadowOffset: { width: 0, height: -4 }, elevation: 12 },
|
|
890
1094
|
grip: { alignSelf: "center", width: 40, height: 5, borderRadius: 3, marginBottom: 4 },
|
|
891
1095
|
title: { fontSize: 17, fontWeight: "700" }
|
|
892
1096
|
});
|
|
893
1097
|
|
|
894
1098
|
// src/native/combobox.tsx
|
|
895
|
-
import { Fragment as
|
|
1099
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
896
1100
|
function Chevron({ color }) {
|
|
897
|
-
return /* @__PURE__ */
|
|
1101
|
+
return /* @__PURE__ */ jsx12(Svg4, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx12(Path2, { d: "m6 9 6 6 6-6" }) });
|
|
898
1102
|
}
|
|
899
1103
|
function Tick({ color }) {
|
|
900
|
-
return /* @__PURE__ */
|
|
1104
|
+
return /* @__PURE__ */ jsx12(Svg4, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.6, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx12(Path2, { d: "M20 6 9 17l-5-5" }) });
|
|
901
1105
|
}
|
|
902
1106
|
function Trigger({ shared, text, onPress, open }) {
|
|
903
1107
|
const { theme, radius: radius3 } = useTheme();
|
|
904
1108
|
const { label, placeholder, hint, error, disabled } = shared;
|
|
905
1109
|
const caption = error ?? hint;
|
|
906
|
-
return /* @__PURE__ */
|
|
907
|
-
/* @__PURE__ */
|
|
908
|
-
/* @__PURE__ */
|
|
909
|
-
|
|
1110
|
+
return /* @__PURE__ */ jsxs9(View9, { style: [styles11.field, shared.style], children: [
|
|
1111
|
+
/* @__PURE__ */ jsx12(Text7, { style: [styles11.label, { color: theme.textSecondary }], children: label }),
|
|
1112
|
+
/* @__PURE__ */ jsxs9(
|
|
1113
|
+
Pressable7,
|
|
910
1114
|
{
|
|
911
1115
|
role: "button",
|
|
912
1116
|
"aria-label": `${label}, ${text ?? placeholder ?? ""}`.replace(/, $/, ""),
|
|
@@ -916,22 +1120,22 @@ function Trigger({ shared, text, onPress, open }) {
|
|
|
916
1120
|
accessibilityHint: caption,
|
|
917
1121
|
disabled,
|
|
918
1122
|
onPress,
|
|
919
|
-
style: [
|
|
1123
|
+
style: [styles11.trigger, { borderRadius: radius3.md, backgroundColor: theme.surface2, borderColor: error ? theme.danger : open ? theme.accent : theme.borderDefault }, disabled ? styles11.disabled : null],
|
|
920
1124
|
children: [
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
/* @__PURE__ */
|
|
1125
|
+
/* @__PURE__ */ jsx12(Text7, { numberOfLines: 1, style: [styles11.triggerText, { color: text ? theme.textPrimary : theme.textSecondary }], children: text ?? placeholder ?? "" }),
|
|
1126
|
+
/* @__PURE__ */ jsx12(Chevron, { color: theme.textSecondary })
|
|
923
1127
|
]
|
|
924
1128
|
}
|
|
925
1129
|
),
|
|
926
|
-
caption ? /* @__PURE__ */
|
|
1130
|
+
caption ? /* @__PURE__ */ jsx12(Text7, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles11.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
927
1131
|
] });
|
|
928
1132
|
}
|
|
929
1133
|
function Options({ options, isChosen, onPick, multiple }) {
|
|
930
1134
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
931
|
-
return /* @__PURE__ */
|
|
1135
|
+
return /* @__PURE__ */ jsx12(ScrollView2, { role: multiple ? "list" : "radiogroup", keyboardShouldPersistTaps: "handled", style: styles11.options, children: options.map((o) => {
|
|
932
1136
|
const chosen = isChosen(o.value);
|
|
933
|
-
return /* @__PURE__ */
|
|
934
|
-
|
|
1137
|
+
return /* @__PURE__ */ jsxs9(
|
|
1138
|
+
Pressable7,
|
|
935
1139
|
{
|
|
936
1140
|
role: multiple ? "checkbox" : "radio",
|
|
937
1141
|
"aria-checked": chosen,
|
|
@@ -942,13 +1146,13 @@ function Options({ options, isChosen, onPick, multiple }) {
|
|
|
942
1146
|
haptic("selection");
|
|
943
1147
|
onPick(o);
|
|
944
1148
|
},
|
|
945
|
-
style: ({ pressed }) => [
|
|
1149
|
+
style: ({ pressed }) => [styles11.option, { borderRadius: radius3.md, backgroundColor: chosen ? theme.accentSoft : pressed ? theme.surface3 : "transparent" }, o.disabled ? styles11.disabled : null],
|
|
946
1150
|
children: [
|
|
947
|
-
/* @__PURE__ */
|
|
948
|
-
/* @__PURE__ */
|
|
949
|
-
o.description ? /* @__PURE__ */
|
|
1151
|
+
/* @__PURE__ */ jsxs9(View9, { style: styles11.optionText, children: [
|
|
1152
|
+
/* @__PURE__ */ jsx12(Text7, { style: [styles11.optionLabel, { color: theme.textPrimary, fontWeight: chosen ? "700" : "500" }], children: o.label }),
|
|
1153
|
+
o.description ? /* @__PURE__ */ jsx12(Text7, { style: [styles11.caption, { color: theme.textSecondary }], children: o.description }) : null
|
|
950
1154
|
] }),
|
|
951
|
-
chosen ? /* @__PURE__ */
|
|
1155
|
+
chosen ? /* @__PURE__ */ jsx12(Tick, { color: theme.accentText }) : null
|
|
952
1156
|
]
|
|
953
1157
|
},
|
|
954
1158
|
o.value
|
|
@@ -956,16 +1160,16 @@ function Options({ options, isChosen, onPick, multiple }) {
|
|
|
956
1160
|
}) });
|
|
957
1161
|
}
|
|
958
1162
|
function Select({ options, value: valueProp, defaultValue = null, onValueChange, sheetTitle, ...shared }) {
|
|
959
|
-
const [own, setOwn] =
|
|
1163
|
+
const [own, setOwn] = React10.useState(defaultValue);
|
|
960
1164
|
const value = valueProp !== void 0 ? valueProp : own;
|
|
961
|
-
const [open, setOpen] =
|
|
1165
|
+
const [open, setOpen] = React10.useState(false);
|
|
962
1166
|
const close = () => {
|
|
963
1167
|
setOpen(false);
|
|
964
1168
|
shared.onBlur?.();
|
|
965
1169
|
};
|
|
966
|
-
return /* @__PURE__ */
|
|
967
|
-
/* @__PURE__ */
|
|
968
|
-
/* @__PURE__ */
|
|
1170
|
+
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1171
|
+
/* @__PURE__ */ jsx12(Trigger, { shared, text: options.find((o) => o.value === value)?.label ?? null, open, onPress: () => setOpen(true) }),
|
|
1172
|
+
/* @__PURE__ */ jsx12(Sheet, { open, onOpenChange: (o) => o ? setOpen(true) : close(), title: sheetTitle ?? shared.label, children: /* @__PURE__ */ jsx12(
|
|
969
1173
|
Options,
|
|
970
1174
|
{
|
|
971
1175
|
options,
|
|
@@ -983,13 +1187,13 @@ var comboboxLabels = { search: "Search", loading: "Searching\u2026", empty: "No
|
|
|
983
1187
|
function Combobox({ options = [], onSearch, multiple, value, onValueChange, labels: given, ...shared }) {
|
|
984
1188
|
const labels = { ...comboboxLabels, ...given };
|
|
985
1189
|
const { theme, radius: radius3 } = useTheme();
|
|
986
|
-
const [open, setOpen] =
|
|
987
|
-
const [query, setQuery] =
|
|
988
|
-
const [found, setFound] =
|
|
989
|
-
const [loading, setLoading] =
|
|
990
|
-
const [seen, setSeen] =
|
|
1190
|
+
const [open, setOpen] = React10.useState(false);
|
|
1191
|
+
const [query, setQuery] = React10.useState("");
|
|
1192
|
+
const [found, setFound] = React10.useState(null);
|
|
1193
|
+
const [loading, setLoading] = React10.useState(false);
|
|
1194
|
+
const [seen, setSeen] = React10.useState({});
|
|
991
1195
|
const chosen = value == null ? [] : typeof value === "string" ? value ? [value] : [] : [...value];
|
|
992
|
-
|
|
1196
|
+
React10.useEffect(() => {
|
|
993
1197
|
if (!onSearch || !open) return;
|
|
994
1198
|
const controller = new AbortController();
|
|
995
1199
|
const timer2 = setTimeout(() => {
|
|
@@ -1013,10 +1217,10 @@ function Combobox({ options = [], onSearch, multiple, value, onValueChange, labe
|
|
|
1013
1217
|
setQuery("");
|
|
1014
1218
|
shared.onBlur?.();
|
|
1015
1219
|
};
|
|
1016
|
-
return /* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1220
|
+
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1221
|
+
/* @__PURE__ */ jsx12(Trigger, { shared, text: chosen.length ? chosen.map(labelOf).join(", ") : null, open, onPress: () => setOpen(true) }),
|
|
1222
|
+
/* @__PURE__ */ jsxs9(Sheet, { open, onOpenChange: (o) => o ? setOpen(true) : close(), title: shared.label, children: [
|
|
1223
|
+
/* @__PURE__ */ jsx12(
|
|
1020
1224
|
TextInput,
|
|
1021
1225
|
{
|
|
1022
1226
|
"aria-label": labels.search,
|
|
@@ -1027,12 +1231,12 @@ function Combobox({ options = [], onSearch, multiple, value, onValueChange, labe
|
|
|
1027
1231
|
autoFocus: true,
|
|
1028
1232
|
autoCorrect: false,
|
|
1029
1233
|
returnKeyType: "search",
|
|
1030
|
-
style: [
|
|
1234
|
+
style: [styles11.search, { borderRadius: radius3.md, backgroundColor: theme.surface2, borderColor: theme.borderDefault, color: theme.textPrimary }]
|
|
1031
1235
|
}
|
|
1032
1236
|
),
|
|
1033
|
-
loading ? /* @__PURE__ */
|
|
1034
|
-
!loading && list.length === 0 ? /* @__PURE__ */
|
|
1035
|
-
/* @__PURE__ */
|
|
1237
|
+
loading ? /* @__PURE__ */ jsx12(Text7, { style: [styles11.caption, { color: theme.textSecondary }], children: labels.loading }) : null,
|
|
1238
|
+
!loading && list.length === 0 ? /* @__PURE__ */ jsx12(Text7, { style: [styles11.caption, { color: theme.textSecondary }], children: labels.empty }) : null,
|
|
1239
|
+
/* @__PURE__ */ jsx12(
|
|
1036
1240
|
Options,
|
|
1037
1241
|
{
|
|
1038
1242
|
options: list,
|
|
@@ -1048,11 +1252,11 @@ function Combobox({ options = [], onSearch, multiple, value, onValueChange, labe
|
|
|
1048
1252
|
}
|
|
1049
1253
|
}
|
|
1050
1254
|
),
|
|
1051
|
-
multiple ? /* @__PURE__ */
|
|
1255
|
+
multiple ? /* @__PURE__ */ jsx12(Pressable7, { role: "button", onPress: close, style: [styles11.done, { borderRadius: radius3.md, backgroundColor: theme.accent }], children: /* @__PURE__ */ jsx12(Text7, { style: [styles11.doneText, { color: theme.onAccent }], children: labels.done }) }) : null
|
|
1052
1256
|
] })
|
|
1053
1257
|
] });
|
|
1054
1258
|
}
|
|
1055
|
-
var
|
|
1259
|
+
var styles11 = StyleSheet11.create({
|
|
1056
1260
|
field: { gap: 6, alignSelf: "stretch" },
|
|
1057
1261
|
label: { fontSize: 12, lineHeight: 16, fontWeight: "600" },
|
|
1058
1262
|
trigger: { minHeight: 48, flexDirection: "row", alignItems: "center", gap: 8, paddingHorizontal: 14, borderWidth: 1 },
|
|
@@ -1069,9 +1273,9 @@ var styles9 = StyleSheet9.create({
|
|
|
1069
1273
|
});
|
|
1070
1274
|
|
|
1071
1275
|
// src/native/countdown.tsx
|
|
1072
|
-
import * as
|
|
1073
|
-
import { Animated as Animated3, StyleSheet as
|
|
1074
|
-
import { jsx as
|
|
1276
|
+
import * as React11 from "react";
|
|
1277
|
+
import { Animated as Animated3, StyleSheet as StyleSheet12, Text as Text8 } from "react-native";
|
|
1278
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1075
1279
|
var FONT = { sm: 14, md: 20, lg: 32 };
|
|
1076
1280
|
function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md", label, showLabel = false, style }) {
|
|
1077
1281
|
const { theme, fonts } = useTheme();
|
|
@@ -1079,8 +1283,8 @@ function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md"
|
|
|
1079
1283
|
const ms = useCountdown(target, skewMs);
|
|
1080
1284
|
const urgent = ms > 0 && ms < urgentBelowMs;
|
|
1081
1285
|
const parts = countdownParts(ms, units);
|
|
1082
|
-
const [opacity] =
|
|
1083
|
-
|
|
1286
|
+
const [opacity] = React11.useState(() => new Animated3.Value(1));
|
|
1287
|
+
React11.useEffect(() => {
|
|
1084
1288
|
if (!urgent || reduce) return;
|
|
1085
1289
|
const loop = Animated3.loop(
|
|
1086
1290
|
Animated3.sequence([
|
|
@@ -1096,24 +1300,24 @@ function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md"
|
|
|
1096
1300
|
}, [urgent, reduce, opacity]);
|
|
1097
1301
|
const color = urgent ? theme.dangerText : theme.textPrimary;
|
|
1098
1302
|
const text = parts.map(([value, unit]) => `${String(value).padStart(2, "0")}${unit}`).join(" ");
|
|
1099
|
-
return /* @__PURE__ */
|
|
1303
|
+
return /* @__PURE__ */ jsxs10(
|
|
1100
1304
|
Animated3.View,
|
|
1101
1305
|
{
|
|
1102
1306
|
accessible: true,
|
|
1103
1307
|
role: "timer",
|
|
1104
1308
|
"aria-label": `${label} ${text}`,
|
|
1105
|
-
style: [
|
|
1309
|
+
style: [styles12.root, style],
|
|
1106
1310
|
children: [
|
|
1107
|
-
showLabel ? /* @__PURE__ */
|
|
1108
|
-
parts.map(([value, unit], i) => /* @__PURE__ */
|
|
1109
|
-
/* @__PURE__ */
|
|
1110
|
-
/* @__PURE__ */
|
|
1311
|
+
showLabel ? /* @__PURE__ */ jsx13(Text8, { style: [styles12.label, { color: theme.textSecondary, fontSize: Math.max(11, Math.round(FONT[size] * 0.6)) }], children: label }) : null,
|
|
1312
|
+
parts.map(([value, unit], i) => /* @__PURE__ */ jsxs10(Animated3.View, { style: [styles12.segment, urgent && i === parts.length - 1 ? { opacity } : null], children: [
|
|
1313
|
+
/* @__PURE__ */ jsx13(Text8, { style: [styles12.value, { color, fontSize: FONT[size] }, fonts.display ? { fontFamily: fonts.display } : null], children: String(value).padStart(2, "0") }),
|
|
1314
|
+
/* @__PURE__ */ jsx13(Text8, { style: [styles12.unit, { color: theme.textSecondary, fontSize: Math.round(FONT[size] / 2) }], children: unit })
|
|
1111
1315
|
] }, unit))
|
|
1112
1316
|
]
|
|
1113
1317
|
}
|
|
1114
1318
|
);
|
|
1115
1319
|
}
|
|
1116
|
-
var
|
|
1320
|
+
var styles12 = StyleSheet12.create({
|
|
1117
1321
|
root: { flexDirection: "row", alignItems: "baseline", gap: 6 },
|
|
1118
1322
|
segment: { flexDirection: "row", alignItems: "baseline" },
|
|
1119
1323
|
value: { fontWeight: "900", fontVariant: ["tabular-nums"], letterSpacing: -0.3 },
|
|
@@ -1122,18 +1326,18 @@ var styles10 = StyleSheet10.create({
|
|
|
1122
1326
|
});
|
|
1123
1327
|
|
|
1124
1328
|
// src/native/date-picker.tsx
|
|
1125
|
-
import * as
|
|
1126
|
-
import { Platform, StyleSheet as
|
|
1127
|
-
import { jsx as
|
|
1329
|
+
import * as React12 from "react";
|
|
1330
|
+
import { Platform, StyleSheet as StyleSheet13, Text as Text9, TextInput as TextInput2, View as View10 } from "react-native";
|
|
1331
|
+
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1128
1332
|
var LENGTH = DATE_PART_LENGTH;
|
|
1129
1333
|
var dateFieldLabels = { day: "Day", month: "Month", year: "Year" };
|
|
1130
1334
|
function DateField({ label, hint, error, value, defaultValue, onValueChange, onBlur, locale = "en-US", labels: given, autoComplete, disabled, inputRef, onSubmitEditing, returnKeyType = "done", style }) {
|
|
1131
1335
|
const { theme, radius: radius3 } = useTheme();
|
|
1132
1336
|
const labels = { ...dateFieldLabels, ...given };
|
|
1133
|
-
const order =
|
|
1134
|
-
const [parts, setParts] =
|
|
1135
|
-
const [focused, setFocused] =
|
|
1136
|
-
const refs = { day:
|
|
1337
|
+
const order = React12.useMemo(() => datePartsOrder(locale), [locale]);
|
|
1338
|
+
const [parts, setParts] = React12.useState(() => splitDate(value ?? defaultValue));
|
|
1339
|
+
const [focused, setFocused] = React12.useState(null);
|
|
1340
|
+
const refs = { day: React12.useRef(null), month: React12.useRef(null), year: React12.useRef(null) };
|
|
1137
1341
|
if (value !== void 0 && value !== composeDate(parts) && composeDate(splitDate(value)) === value) setParts(splitDate(value));
|
|
1138
1342
|
const caption = error ?? hint;
|
|
1139
1343
|
const change = (part, text) => {
|
|
@@ -1144,11 +1348,11 @@ function DateField({ label, hint, error, value, defaultValue, onValueChange, onB
|
|
|
1144
1348
|
const following = order[order.indexOf(part) + 1];
|
|
1145
1349
|
if (digits.length === LENGTH[part] && following) refs[following].current?.focus();
|
|
1146
1350
|
};
|
|
1147
|
-
return /* @__PURE__ */
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1150
|
-
/* @__PURE__ */
|
|
1151
|
-
/* @__PURE__ */
|
|
1351
|
+
return /* @__PURE__ */ jsxs11(View10, { role: "group", "aria-label": label, style: [styles13.root, disabled ? styles13.disabled : null, style], children: [
|
|
1352
|
+
/* @__PURE__ */ jsx14(Text9, { style: [styles13.label, { color: theme.textSecondary }], children: label }),
|
|
1353
|
+
/* @__PURE__ */ jsx14(View10, { style: styles13.row, children: order.map((part, i) => /* @__PURE__ */ jsxs11(View10, { style: part === "year" ? styles13.yearBox : styles13.box, children: [
|
|
1354
|
+
/* @__PURE__ */ jsx14(Text9, { style: [styles13.part, { color: theme.textSecondary }], children: labels[part] }),
|
|
1355
|
+
/* @__PURE__ */ jsx14(
|
|
1152
1356
|
TextInput2,
|
|
1153
1357
|
{
|
|
1154
1358
|
ref: (node) => {
|
|
@@ -1180,16 +1384,16 @@ function DateField({ label, hint, error, value, defaultValue, onValueChange, onB
|
|
|
1180
1384
|
if (i === order.length - 1) onBlur?.();
|
|
1181
1385
|
},
|
|
1182
1386
|
style: [
|
|
1183
|
-
|
|
1387
|
+
styles13.input,
|
|
1184
1388
|
{ color: theme.textPrimary, backgroundColor: theme.surface2, borderRadius: radius3.md, borderColor: error ? theme.danger : focused === part ? theme.accent : theme.borderDefault }
|
|
1185
1389
|
]
|
|
1186
1390
|
}
|
|
1187
1391
|
)
|
|
1188
1392
|
] }, part)) }),
|
|
1189
|
-
caption ? /* @__PURE__ */
|
|
1393
|
+
caption ? /* @__PURE__ */ jsx14(Text9, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles13.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
1190
1394
|
] });
|
|
1191
1395
|
}
|
|
1192
|
-
var
|
|
1396
|
+
var styles13 = StyleSheet13.create({
|
|
1193
1397
|
root: { gap: 6, alignSelf: "stretch" },
|
|
1194
1398
|
label: { fontSize: 12, lineHeight: 16, fontWeight: "600" },
|
|
1195
1399
|
row: { flexDirection: "row", gap: 10 },
|
|
@@ -1202,26 +1406,26 @@ var styles11 = StyleSheet11.create({
|
|
|
1202
1406
|
});
|
|
1203
1407
|
|
|
1204
1408
|
// src/native/date-time.tsx
|
|
1205
|
-
import * as
|
|
1206
|
-
import { Pressable as
|
|
1207
|
-
import
|
|
1409
|
+
import * as React14 from "react";
|
|
1410
|
+
import { Pressable as Pressable9, ScrollView as ScrollView4, StyleSheet as StyleSheet15, Text as Text11, View as View12 } from "react-native";
|
|
1411
|
+
import Svg5, { Path as Path3 } from "react-native-svg";
|
|
1208
1412
|
|
|
1209
1413
|
// src/native/wheel.tsx
|
|
1210
|
-
import * as
|
|
1211
|
-
import { Pressable as
|
|
1212
|
-
import { jsx as
|
|
1414
|
+
import * as React13 from "react";
|
|
1415
|
+
import { Pressable as Pressable8, ScrollView as ScrollView3, StyleSheet as StyleSheet14, Text as Text10, View as View11 } from "react-native";
|
|
1416
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1213
1417
|
var ITEM = 44;
|
|
1214
|
-
var FrameContext =
|
|
1418
|
+
var FrameContext = React13.createContext({ visible: 5, unset: false });
|
|
1215
1419
|
function WheelPicker({ label, children, visible = 5, invalid, unset = false, style }) {
|
|
1216
1420
|
const { theme, radius: radius3 } = useTheme();
|
|
1217
|
-
return /* @__PURE__ */
|
|
1218
|
-
|
|
1421
|
+
return /* @__PURE__ */ jsx15(FrameContext.Provider, { value: React13.useMemo(() => ({ visible, unset }), [visible, unset]), children: /* @__PURE__ */ jsxs12(
|
|
1422
|
+
View11,
|
|
1219
1423
|
{
|
|
1220
1424
|
role: "group",
|
|
1221
1425
|
"aria-label": label,
|
|
1222
|
-
style: [
|
|
1426
|
+
style: [styles14.root, { height: ITEM * visible, borderRadius: radius3.xl, backgroundColor: theme.surface1, borderColor: invalid ? theme.danger : theme.borderDefault }, style],
|
|
1223
1427
|
children: [
|
|
1224
|
-
/* @__PURE__ */
|
|
1428
|
+
/* @__PURE__ */ jsx15(View11, { pointerEvents: "none", style: [styles14.band, { top: ITEM * (visible - 1) / 2, height: ITEM, borderRadius: radius3.lg, backgroundColor: theme.surface3, borderColor: theme.borderSubtle }] }),
|
|
1225
1429
|
children
|
|
1226
1430
|
]
|
|
1227
1431
|
}
|
|
@@ -1229,7 +1433,7 @@ function WheelPicker({ label, children, visible = 5, invalid, unset = false, sty
|
|
|
1229
1433
|
}
|
|
1230
1434
|
function WheelDivider({ children }) {
|
|
1231
1435
|
const { theme } = useTheme();
|
|
1232
|
-
return /* @__PURE__ */
|
|
1436
|
+
return /* @__PURE__ */ jsx15(Text10, { "aria-hidden": true, style: [styles14.divider, { color: theme.textSecondary }], children });
|
|
1233
1437
|
}
|
|
1234
1438
|
var nearestEnabled = (options, index) => {
|
|
1235
1439
|
for (let d = 0; d < options.length; d++) {
|
|
@@ -1240,14 +1444,14 @@ var nearestEnabled = (options, index) => {
|
|
|
1240
1444
|
};
|
|
1241
1445
|
function Wheel({ label, options, value: valueProp, defaultValue, onValueChange, disabled, style }) {
|
|
1242
1446
|
const { theme, haptic } = useTheme();
|
|
1243
|
-
const { visible, unset } =
|
|
1244
|
-
const [own, setOwn] =
|
|
1447
|
+
const { visible, unset } = React13.useContext(FrameContext);
|
|
1448
|
+
const [own, setOwn] = React13.useState(defaultValue ?? options[0]?.value ?? "");
|
|
1245
1449
|
const value = valueProp ?? own;
|
|
1246
1450
|
const index = Math.max(0, options.findIndex((o) => o.value === value));
|
|
1247
|
-
const scroller =
|
|
1248
|
-
const passing =
|
|
1249
|
-
const [shown, setShown] =
|
|
1250
|
-
const [seen, setSeen] =
|
|
1451
|
+
const scroller = React13.useRef(null);
|
|
1452
|
+
const passing = React13.useRef(index);
|
|
1453
|
+
const [shown, setShown] = React13.useState(index);
|
|
1454
|
+
const [seen, setSeen] = React13.useState(index);
|
|
1251
1455
|
if (seen !== index) {
|
|
1252
1456
|
setSeen(index);
|
|
1253
1457
|
setShown(index);
|
|
@@ -1260,7 +1464,7 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1260
1464
|
if (valueProp === void 0) setOwn(option.value);
|
|
1261
1465
|
if (option.value !== value) onValueChange?.(option.value);
|
|
1262
1466
|
};
|
|
1263
|
-
|
|
1467
|
+
React13.useEffect(() => {
|
|
1264
1468
|
passing.current = index;
|
|
1265
1469
|
scroller.current?.scrollTo({ y: index * ITEM, animated: false });
|
|
1266
1470
|
}, [index]);
|
|
@@ -1279,8 +1483,8 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1279
1483
|
if (options[i]) commit(i);
|
|
1280
1484
|
};
|
|
1281
1485
|
const pad = (visible - 1) / 2 * ITEM;
|
|
1282
|
-
return /* @__PURE__ */
|
|
1283
|
-
|
|
1486
|
+
return /* @__PURE__ */ jsx15(
|
|
1487
|
+
View11,
|
|
1284
1488
|
{
|
|
1285
1489
|
accessible: true,
|
|
1286
1490
|
role: "spinbutton",
|
|
@@ -1292,8 +1496,8 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1292
1496
|
"aria-disabled": disabled || void 0,
|
|
1293
1497
|
accessibilityActions: [{ name: "increment" }, { name: "decrement" }],
|
|
1294
1498
|
onAccessibilityAction: (e) => step(e.nativeEvent.actionName === "increment" ? 1 : -1),
|
|
1295
|
-
style: [
|
|
1296
|
-
children: /* @__PURE__ */
|
|
1499
|
+
style: [styles14.column, disabled ? styles14.disabled : null, style],
|
|
1500
|
+
children: /* @__PURE__ */ jsx15(
|
|
1297
1501
|
ScrollView3,
|
|
1298
1502
|
{
|
|
1299
1503
|
ref: scroller,
|
|
@@ -1313,12 +1517,12 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1313
1517
|
},
|
|
1314
1518
|
children: options.map((o, i) => {
|
|
1315
1519
|
const distance = Math.abs(i - shown);
|
|
1316
|
-
return /* @__PURE__ */
|
|
1520
|
+
return /* @__PURE__ */ jsx15(Pressable8, { focusable: false, tabIndex: -1, disabled: disabled || o.disabled, onPress: () => commit(i), style: [styles14.item, { height: ITEM }], children: /* @__PURE__ */ jsx15(
|
|
1317
1521
|
Text10,
|
|
1318
1522
|
{
|
|
1319
1523
|
numberOfLines: 1,
|
|
1320
1524
|
style: [
|
|
1321
|
-
|
|
1525
|
+
styles14.itemText,
|
|
1322
1526
|
{
|
|
1323
1527
|
color: o.disabled ? theme.textMuted : i === shown && !unset ? theme.textPrimary : theme.textSecondary,
|
|
1324
1528
|
fontWeight: i === shown && !unset ? "600" : "400",
|
|
@@ -1336,9 +1540,9 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1336
1540
|
}
|
|
1337
1541
|
);
|
|
1338
1542
|
}
|
|
1339
|
-
var
|
|
1340
|
-
root: { flexDirection: "row", alignItems: "stretch", borderWidth:
|
|
1341
|
-
band: { position: "absolute", left: 6, right: 6, borderWidth:
|
|
1543
|
+
var styles14 = StyleSheet14.create({
|
|
1544
|
+
root: { flexDirection: "row", alignItems: "stretch", borderWidth: StyleSheet14.hairlineWidth, paddingHorizontal: 6, gap: 4, overflow: "hidden", alignSelf: "flex-start" },
|
|
1545
|
+
band: { position: "absolute", left: 6, right: 6, borderWidth: StyleSheet14.hairlineWidth },
|
|
1342
1546
|
column: { minWidth: 56, flexGrow: 1 },
|
|
1343
1547
|
item: { alignItems: "center", justifyContent: "center", paddingHorizontal: 8 },
|
|
1344
1548
|
itemText: { fontSize: 18, fontVariant: ["tabular-nums"] },
|
|
@@ -1347,19 +1551,19 @@ var styles12 = StyleSheet12.create({
|
|
|
1347
1551
|
});
|
|
1348
1552
|
|
|
1349
1553
|
// src/native/date-time.tsx
|
|
1350
|
-
import { jsx as
|
|
1554
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1351
1555
|
var longDate = (locale, iso) => new Intl.DateTimeFormat(locale, { dateStyle: "long" }).format(toLocalDate(iso));
|
|
1352
1556
|
var useOwn = (value, initial) => {
|
|
1353
|
-
const [own, setOwn] =
|
|
1557
|
+
const [own, setOwn] = React14.useState(initial);
|
|
1354
1558
|
return [value !== void 0 ? value : own, (next) => value === void 0 && setOwn(next)];
|
|
1355
1559
|
};
|
|
1356
1560
|
function Chevron2({ direction, color }) {
|
|
1357
|
-
return /* @__PURE__ */
|
|
1561
|
+
return /* @__PURE__ */ jsx16(Svg5, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx16(Path3, { d: direction === "left" ? "m15 18-6-6 6-6" : "m9 18 6-6-6-6" }) });
|
|
1358
1562
|
}
|
|
1359
1563
|
function NavButton({ label, direction, disabled, onPress }) {
|
|
1360
1564
|
const { theme, radius: radius3 } = useTheme();
|
|
1361
|
-
return /* @__PURE__ */
|
|
1362
|
-
|
|
1565
|
+
return /* @__PURE__ */ jsx16(
|
|
1566
|
+
Pressable9,
|
|
1363
1567
|
{
|
|
1364
1568
|
role: "button",
|
|
1365
1569
|
"aria-label": label,
|
|
@@ -1367,49 +1571,49 @@ function NavButton({ label, direction, disabled, onPress }) {
|
|
|
1367
1571
|
disabled,
|
|
1368
1572
|
hitSlop: 6,
|
|
1369
1573
|
onPress,
|
|
1370
|
-
style: ({ pressed }) => [
|
|
1371
|
-
children: /* @__PURE__ */
|
|
1574
|
+
style: ({ pressed }) => [styles15.nav, { borderRadius: radius3.md, backgroundColor: pressed ? theme.surface3 : theme.surface2, borderColor: theme.borderSubtle }, disabled ? styles15.disabled : null],
|
|
1575
|
+
children: /* @__PURE__ */ jsx16(Chevron2, { direction, color: theme.textSecondary })
|
|
1372
1576
|
}
|
|
1373
1577
|
);
|
|
1374
1578
|
}
|
|
1375
1579
|
function Node({ color, style }) {
|
|
1376
|
-
return /* @__PURE__ */
|
|
1580
|
+
return /* @__PURE__ */ jsx16(View12, { "aria-hidden": true, style: [styles15.node, { backgroundColor: color }, style] });
|
|
1377
1581
|
}
|
|
1378
1582
|
var calendarLabels = { previousMonth: "Previous month", nextMonth: "Next month" };
|
|
1379
1583
|
function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDateDisabled, weekStartsOn, today: todayProp, labels: given, style }) {
|
|
1380
1584
|
const labels = { ...calendarLabels, ...given };
|
|
1381
1585
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
1382
1586
|
const today = todayProp ?? todayIso();
|
|
1383
|
-
const [month, setMonth] =
|
|
1587
|
+
const [month, setMonth] = React14.useState(`${(defaultMonth ?? value ?? range?.start ?? today).slice(0, 7)}-01`);
|
|
1384
1588
|
const start = weekStartsOn ?? weekStartOf(locale);
|
|
1385
1589
|
const weeks = monthGrid(month, start);
|
|
1386
1590
|
const weekday = new Intl.DateTimeFormat(locale, { weekday: "narrow" });
|
|
1387
1591
|
const title = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(toLocalDate(month));
|
|
1388
1592
|
const [lo, hi] = range?.end ? range.start <= range.end ? [range.start, range.end] : [range.end, range.start] : [null, null];
|
|
1389
1593
|
const off = (iso) => Boolean(min && iso < min || max && iso > max || isDateDisabled?.(iso));
|
|
1390
|
-
return /* @__PURE__ */
|
|
1391
|
-
/* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1594
|
+
return /* @__PURE__ */ jsxs13(View12, { style: [styles15.calendar, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius3.xl }, style], children: [
|
|
1595
|
+
/* @__PURE__ */ jsxs13(View12, { style: styles15.header, children: [
|
|
1596
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels.previousMonth, direction: "left", disabled: Boolean(min && addDays(month, -1) < min), onPress: () => setMonth(addMonths(month, -1)) }),
|
|
1597
|
+
/* @__PURE__ */ jsx16(Text11, { role: "heading", "aria-live": "polite", style: [styles15.title, { color: theme.textPrimary }], children: title }),
|
|
1598
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels.nextMonth, direction: "right", disabled: Boolean(max && addMonths(month, 1) > max), onPress: () => setMonth(addMonths(month, 1)) })
|
|
1395
1599
|
] }),
|
|
1396
|
-
/* @__PURE__ */
|
|
1397
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsx16(View12, { style: styles15.week, "aria-hidden": true, children: weeks[0].map((iso) => /* @__PURE__ */ jsx16(Text11, { style: [styles15.weekday, { color: theme.textSecondary }], children: weekday.format(toLocalDate(iso)) }, iso)) }),
|
|
1601
|
+
/* @__PURE__ */ jsx16(View12, { role: "radiogroup", "aria-label": title, children: weeks.map((week) => /* @__PURE__ */ jsx16(View12, { style: styles15.week, children: week.map((iso) => {
|
|
1398
1602
|
const outside = iso.slice(0, 7) !== month.slice(0, 7);
|
|
1399
1603
|
const selected = iso === value || Boolean(range && (iso === range.start || iso === range.end));
|
|
1400
1604
|
const disabled = off(iso);
|
|
1401
1605
|
const band = lo && hi && lo !== hi && iso >= lo && iso <= hi;
|
|
1402
|
-
return /* @__PURE__ */
|
|
1403
|
-
|
|
1606
|
+
return /* @__PURE__ */ jsx16(
|
|
1607
|
+
View12,
|
|
1404
1608
|
{
|
|
1405
1609
|
style: [
|
|
1406
|
-
|
|
1610
|
+
styles15.cell,
|
|
1407
1611
|
band ? { backgroundColor: theme.accentSoft } : null,
|
|
1408
1612
|
band && iso === lo ? { borderTopLeftRadius: radius3.lg, borderBottomLeftRadius: radius3.lg } : null,
|
|
1409
1613
|
band && iso === hi ? { borderTopRightRadius: radius3.lg, borderBottomRightRadius: radius3.lg } : null
|
|
1410
1614
|
],
|
|
1411
|
-
children: /* @__PURE__ */
|
|
1412
|
-
|
|
1615
|
+
children: /* @__PURE__ */ jsxs13(
|
|
1616
|
+
Pressable9,
|
|
1413
1617
|
{
|
|
1414
1618
|
role: "radio",
|
|
1415
1619
|
"aria-label": longDate(locale, iso),
|
|
@@ -1422,16 +1626,16 @@ function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDa
|
|
|
1422
1626
|
onSelect?.(iso);
|
|
1423
1627
|
},
|
|
1424
1628
|
style: ({ pressed }) => [
|
|
1425
|
-
|
|
1629
|
+
styles15.day,
|
|
1426
1630
|
{ borderRadius: radius3.lg },
|
|
1427
1631
|
selected ? { backgroundColor: theme.accent } : pressed ? { backgroundColor: theme.surface3 } : null
|
|
1428
1632
|
],
|
|
1429
1633
|
children: [
|
|
1430
|
-
/* @__PURE__ */
|
|
1634
|
+
/* @__PURE__ */ jsx16(
|
|
1431
1635
|
Text11,
|
|
1432
1636
|
{
|
|
1433
1637
|
style: [
|
|
1434
|
-
|
|
1638
|
+
styles15.dayText,
|
|
1435
1639
|
{
|
|
1436
1640
|
color: selected ? theme.onAccent : disabled ? theme.textMuted : iso === today ? theme.accentText : outside ? theme.textSecondary : theme.textPrimary,
|
|
1437
1641
|
fontWeight: selected || iso === today ? "700" : "400",
|
|
@@ -1441,7 +1645,7 @@ function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDa
|
|
|
1441
1645
|
children: Number(iso.slice(8))
|
|
1442
1646
|
}
|
|
1443
1647
|
),
|
|
1444
|
-
iso === today ? /* @__PURE__ */
|
|
1648
|
+
iso === today ? /* @__PURE__ */ jsx16(Node, { color: selected ? theme.onAccent : theme.accent, style: styles15.todayNode }) : null
|
|
1445
1649
|
]
|
|
1446
1650
|
}
|
|
1447
1651
|
)
|
|
@@ -1453,21 +1657,21 @@ function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDa
|
|
|
1453
1657
|
}
|
|
1454
1658
|
function MonthPicker({ locale, value, onValueChange, min, max, labels, style }) {
|
|
1455
1659
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
1456
|
-
const [year, setYear] =
|
|
1660
|
+
const [year, setYear] = React14.useState(Number((value ?? todayIso()).slice(0, 4)));
|
|
1457
1661
|
const names = monthNames(locale, "short").map((n) => n.replace(/\.$/, ""));
|
|
1458
1662
|
const long = monthNames(locale, "long");
|
|
1459
|
-
return /* @__PURE__ */
|
|
1460
|
-
/* @__PURE__ */
|
|
1461
|
-
/* @__PURE__ */
|
|
1462
|
-
/* @__PURE__ */
|
|
1463
|
-
/* @__PURE__ */
|
|
1663
|
+
return /* @__PURE__ */ jsxs13(View12, { style: [styles15.calendar, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius3.xl }, style], children: [
|
|
1664
|
+
/* @__PURE__ */ jsxs13(View12, { style: styles15.header, children: [
|
|
1665
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels?.previousYear ?? "Previous year", direction: "left", disabled: Boolean(min && year - 1 < Number(min.slice(0, 4))), onPress: () => setYear(year - 1) }),
|
|
1666
|
+
/* @__PURE__ */ jsx16(Text11, { role: "heading", "aria-live": "polite", style: [styles15.title, { color: theme.textPrimary }], children: year }),
|
|
1667
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels?.nextYear ?? "Next year", direction: "right", disabled: Boolean(max && year + 1 > Number(max.slice(0, 4))), onPress: () => setYear(year + 1) })
|
|
1464
1668
|
] }),
|
|
1465
|
-
/* @__PURE__ */
|
|
1669
|
+
/* @__PURE__ */ jsx16(View12, { role: "radiogroup", "aria-label": String(year), style: styles15.months, children: names.map((name, i) => {
|
|
1466
1670
|
const id = `${year}-${String(i + 1).padStart(2, "0")}`;
|
|
1467
1671
|
const selected = id === value;
|
|
1468
1672
|
const disabled = Boolean(min && id < min || max && id > max);
|
|
1469
|
-
return /* @__PURE__ */
|
|
1470
|
-
|
|
1673
|
+
return /* @__PURE__ */ jsx16(
|
|
1674
|
+
Pressable9,
|
|
1471
1675
|
{
|
|
1472
1676
|
role: "radio",
|
|
1473
1677
|
"aria-checked": selected,
|
|
@@ -1478,8 +1682,8 @@ function MonthPicker({ locale, value, onValueChange, min, max, labels, style })
|
|
|
1478
1682
|
haptic("selection");
|
|
1479
1683
|
onValueChange?.(id);
|
|
1480
1684
|
},
|
|
1481
|
-
style: ({ pressed }) => [
|
|
1482
|
-
children: /* @__PURE__ */
|
|
1685
|
+
style: ({ pressed }) => [styles15.month, { borderRadius: radius3.lg, backgroundColor: selected ? theme.accent : pressed ? theme.surface3 : "transparent" }, disabled ? styles15.disabled : null],
|
|
1686
|
+
children: /* @__PURE__ */ jsx16(Text11, { style: [styles15.monthText, { color: selected ? theme.onAccent : theme.textPrimary, fontWeight: selected ? "700" : "500" }], children: name })
|
|
1483
1687
|
},
|
|
1484
1688
|
id
|
|
1485
1689
|
);
|
|
@@ -1493,13 +1697,13 @@ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValu
|
|
|
1493
1697
|
const [value, setValue] = useOwn(valueProp, defaultValue);
|
|
1494
1698
|
const weekday = new Intl.DateTimeFormat(locale, { weekday: "short" });
|
|
1495
1699
|
const list = Array.from({ length: days }, (_, i) => addDays(first, i));
|
|
1496
|
-
return /* @__PURE__ */
|
|
1700
|
+
return /* @__PURE__ */ jsx16(ScrollView4, { horizontal: true, showsHorizontalScrollIndicator: false, role: "radiogroup", "aria-label": label, contentContainerStyle: styles15.strip, style, children: list.map((iso) => {
|
|
1497
1701
|
const selected = iso === value;
|
|
1498
1702
|
const disabled = Boolean(isDateDisabled?.(iso));
|
|
1499
1703
|
const marked = Boolean(isDateMarked?.(iso));
|
|
1500
1704
|
const name = longDate(locale, iso);
|
|
1501
|
-
return /* @__PURE__ */
|
|
1502
|
-
|
|
1705
|
+
return /* @__PURE__ */ jsxs13(
|
|
1706
|
+
Pressable9,
|
|
1503
1707
|
{
|
|
1504
1708
|
role: "radio",
|
|
1505
1709
|
"aria-checked": selected,
|
|
@@ -1513,7 +1717,7 @@ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValu
|
|
|
1513
1717
|
onValueChange?.(iso);
|
|
1514
1718
|
},
|
|
1515
1719
|
style: ({ pressed }) => [
|
|
1516
|
-
|
|
1720
|
+
styles15.stripDay,
|
|
1517
1721
|
{
|
|
1518
1722
|
borderRadius: radius3.xl,
|
|
1519
1723
|
backgroundColor: selected ? theme.accent : disabled ? "transparent" : theme.surface2,
|
|
@@ -1523,10 +1727,10 @@ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValu
|
|
|
1523
1727
|
}
|
|
1524
1728
|
],
|
|
1525
1729
|
children: [
|
|
1526
|
-
iso === today ? /* @__PURE__ */
|
|
1527
|
-
/* @__PURE__ */
|
|
1528
|
-
/* @__PURE__ */
|
|
1529
|
-
/* @__PURE__ */
|
|
1730
|
+
iso === today ? /* @__PURE__ */ jsx16(Node, { color: selected ? theme.onAccent : theme.accent, style: styles15.stripNode }) : null,
|
|
1731
|
+
/* @__PURE__ */ jsx16(Text11, { style: [styles15.stripWeekday, { color: selected ? theme.onAccent : disabled ? theme.textMuted : theme.textSecondary }], children: weekday.format(toLocalDate(iso)).replace(/\.$/, "").toUpperCase() }),
|
|
1732
|
+
/* @__PURE__ */ jsx16(Text11, { style: [styles15.stripNumber, { color: selected ? theme.onAccent : disabled ? theme.textMuted : theme.textPrimary }], children: Number(iso.slice(8)) }),
|
|
1733
|
+
/* @__PURE__ */ jsx16(View12, { style: [styles15.dot, marked ? { backgroundColor: selected ? theme.onAccent : theme.textSecondary } : null] })
|
|
1530
1734
|
]
|
|
1531
1735
|
},
|
|
1532
1736
|
iso
|
|
@@ -1541,11 +1745,11 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1541
1745
|
onValueChange?.(next);
|
|
1542
1746
|
};
|
|
1543
1747
|
if (variant === "slots")
|
|
1544
|
-
return /* @__PURE__ */
|
|
1748
|
+
return /* @__PURE__ */ jsx16(View12, { role: "radiogroup", "aria-label": label, style: [styles15.slots, style], children: slots.map((t) => {
|
|
1545
1749
|
const selected = t === value;
|
|
1546
1750
|
const off = disabled || Boolean(isTimeDisabled?.(t));
|
|
1547
|
-
return /* @__PURE__ */
|
|
1548
|
-
|
|
1751
|
+
return /* @__PURE__ */ jsx16(
|
|
1752
|
+
Pressable9,
|
|
1549
1753
|
{
|
|
1550
1754
|
role: "radio",
|
|
1551
1755
|
"aria-checked": selected,
|
|
@@ -1557,7 +1761,7 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1557
1761
|
set(t);
|
|
1558
1762
|
},
|
|
1559
1763
|
style: ({ pressed }) => [
|
|
1560
|
-
|
|
1764
|
+
styles15.slot,
|
|
1561
1765
|
{
|
|
1562
1766
|
borderRadius: radius3.lg,
|
|
1563
1767
|
backgroundColor: selected ? theme.accent : off ? "transparent" : theme.surface2,
|
|
@@ -1566,7 +1770,7 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1566
1770
|
transform: [{ scale: pressed ? 0.97 : 1 }]
|
|
1567
1771
|
}
|
|
1568
1772
|
],
|
|
1569
|
-
children: /* @__PURE__ */
|
|
1773
|
+
children: /* @__PURE__ */ jsx16(Text11, { style: [styles15.slotText, { color: selected ? theme.onAccent : off ? theme.textMuted : theme.textPrimary, textDecorationLine: off ? "line-through" : "none" }], children: formatTime(locale, t) })
|
|
1570
1774
|
},
|
|
1571
1775
|
t
|
|
1572
1776
|
);
|
|
@@ -1582,11 +1786,11 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1582
1786
|
const hours = twelve ? [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((h) => ({ value: String(h), label: String(h) })) : Array.from({ length: 24 }, (_, h) => ({ value: String(h), label: two(h) }));
|
|
1583
1787
|
const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => ({ value: String(i * minuteStep), label: two(i * minuteStep) }));
|
|
1584
1788
|
const [am, pmLabel] = dayPeriods(locale);
|
|
1585
|
-
return /* @__PURE__ */
|
|
1586
|
-
/* @__PURE__ */
|
|
1587
|
-
/* @__PURE__ */
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
twelve ? /* @__PURE__ */
|
|
1789
|
+
return /* @__PURE__ */ jsxs13(WheelPicker, { label: value ? `${label}, ${formatTime(locale, value)}` : label, style, children: [
|
|
1790
|
+
/* @__PURE__ */ jsx16(Wheel, { label: labels.hours, options: hours, disabled, value: twelve ? String(h24 % 12 === 0 ? 12 : h24 % 12) : String(h24), onValueChange: (v) => put(twelve ? Number(v) % 12 + (pm ? 12 : 0) : Number(v), minute) }),
|
|
1791
|
+
/* @__PURE__ */ jsx16(WheelDivider, { children: ":" }),
|
|
1792
|
+
/* @__PURE__ */ jsx16(Wheel, { label: labels.minutes, options: minutes, disabled, value: String(Math.min(60 - minuteStep, Math.round(minute / minuteStep) * minuteStep)), onValueChange: (v) => put(h24, Number(v)) }),
|
|
1793
|
+
twelve ? /* @__PURE__ */ jsx16(
|
|
1590
1794
|
Wheel,
|
|
1591
1795
|
{
|
|
1592
1796
|
label: labels.period,
|
|
@@ -1619,22 +1823,22 @@ function DateWheel({ label, locale, value: valueProp, defaultValue = null, onVal
|
|
|
1619
1823
|
};
|
|
1620
1824
|
const last = daysInMonth(year, month);
|
|
1621
1825
|
const columns = {
|
|
1622
|
-
day: /* @__PURE__ */
|
|
1623
|
-
month: /* @__PURE__ */
|
|
1624
|
-
year: /* @__PURE__ */
|
|
1826
|
+
day: /* @__PURE__ */ jsx16(Wheel, { label: names.day, disabled, options: Array.from({ length: last }, (_, i) => ({ value: String(i + 1), label: String(i + 1), disabled: isoOf(year, month, i + 1) > hi || isoOf(year, month, i + 1) < lo })), value: String(Math.min(day, last)), onValueChange: (v) => set(year, month, Number(v)), style: styles15.dayWheel }, "day"),
|
|
1827
|
+
month: /* @__PURE__ */ jsx16(Wheel, { label: names.month, disabled, options: months.map((n, i) => ({ value: String(i + 1), label: n, disabled: isoOf(year, i + 1, 1) > hi || isoOf(year, i + 1, daysInMonth(year, i + 1)) < lo })), value: String(month), onValueChange: (v) => set(year, Number(v), day), style: styles15.monthWheel }, "month"),
|
|
1828
|
+
year: /* @__PURE__ */ jsx16(Wheel, { label: names.year, disabled, options: yearRange(Number(hi.slice(0, 4)), Number(lo.slice(0, 4))).map((y) => ({ value: String(y), label: String(y) })), value: String(year), onValueChange: (v) => set(Number(v), month, day), style: styles15.yearWheel }, "year")
|
|
1625
1829
|
};
|
|
1626
1830
|
const caption = error ?? hint;
|
|
1627
|
-
return /* @__PURE__ */
|
|
1628
|
-
/* @__PURE__ */
|
|
1629
|
-
/* @__PURE__ */
|
|
1630
|
-
caption ? /* @__PURE__ */
|
|
1831
|
+
return /* @__PURE__ */ jsxs13(View12, { style: [styles15.field, style], children: [
|
|
1832
|
+
/* @__PURE__ */ jsx16(Text11, { "aria-hidden": true, style: [styles15.fieldLabel, { color: theme.textSecondary }], children: label }),
|
|
1833
|
+
/* @__PURE__ */ jsx16(WheelPicker, { label, invalid: Boolean(error), unset: !value, children: datePartsOrder(locale).map((part) => columns[part]) }),
|
|
1834
|
+
caption ? /* @__PURE__ */ jsx16(Text11, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles15.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
1631
1835
|
] });
|
|
1632
1836
|
}
|
|
1633
|
-
var
|
|
1634
|
-
calendar: { padding: 12, gap: 4, borderWidth:
|
|
1837
|
+
var styles15 = StyleSheet15.create({
|
|
1838
|
+
calendar: { padding: 12, gap: 4, borderWidth: StyleSheet15.hairlineWidth, alignSelf: "flex-start" },
|
|
1635
1839
|
header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 6, gap: 8 },
|
|
1636
1840
|
title: { fontSize: 15, fontWeight: "700", textTransform: "capitalize" },
|
|
1637
|
-
nav: { width: 36, height: 36, alignItems: "center", justifyContent: "center", borderWidth:
|
|
1841
|
+
nav: { width: 36, height: 36, alignItems: "center", justifyContent: "center", borderWidth: StyleSheet15.hairlineWidth },
|
|
1638
1842
|
week: { flexDirection: "row" },
|
|
1639
1843
|
weekday: { width: 44, textAlign: "center", fontSize: 11, fontWeight: "700", paddingBottom: 4 },
|
|
1640
1844
|
cell: { width: 44, height: 44, marginVertical: 1 },
|
|
@@ -1663,38 +1867,114 @@ var styles13 = StyleSheet13.create({
|
|
|
1663
1867
|
disabled: { opacity: 0.4 }
|
|
1664
1868
|
});
|
|
1665
1869
|
|
|
1870
|
+
// src/native/description-list.tsx
|
|
1871
|
+
import { StyleSheet as StyleSheet16, View as View13 } from "react-native";
|
|
1872
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1873
|
+
function DescriptionList({ items: items2, layout = "stacked", style }) {
|
|
1874
|
+
const { theme, radius: radius3 } = useTheme();
|
|
1875
|
+
return /* @__PURE__ */ jsx17(View13, { role: "list", style: [layout === "grid" ? styles16.grid : layout === "inline" ? null : styles16.stacked, style], children: items2.map((item, i) => {
|
|
1876
|
+
const value = typeof item.details === "string" || typeof item.details === "number" ? /* @__PURE__ */ jsx17(Txt, { variant: layout === "grid" ? "title" : "body", style: layout === "inline" ? styles16.right : null, children: item.details }) : item.details;
|
|
1877
|
+
return /* @__PURE__ */ jsxs14(
|
|
1878
|
+
View13,
|
|
1879
|
+
{
|
|
1880
|
+
role: "listitem",
|
|
1881
|
+
accessible: true,
|
|
1882
|
+
style: [
|
|
1883
|
+
layout === "inline" ? [styles16.inline, i > 0 ? { borderTopWidth: StyleSheet16.hairlineWidth, borderTopColor: theme.borderSubtle } : null] : null,
|
|
1884
|
+
layout === "grid" ? [styles16.card, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius3.lg }] : null
|
|
1885
|
+
],
|
|
1886
|
+
children: [
|
|
1887
|
+
/* @__PURE__ */ jsx17(Txt, { variant: "caption", tone: "secondary", style: layout === "grid" ? styles16.upper : null, children: item.term }),
|
|
1888
|
+
/* @__PURE__ */ jsxs14(View13, { style: layout === "inline" ? styles16.valueInline : styles16.value, children: [
|
|
1889
|
+
value,
|
|
1890
|
+
item.hint ? /* @__PURE__ */ jsx17(Txt, { variant: "caption", tone: "secondary", style: layout === "inline" ? styles16.right : null, children: item.hint }) : null
|
|
1891
|
+
] })
|
|
1892
|
+
]
|
|
1893
|
+
},
|
|
1894
|
+
item.id ?? item.term
|
|
1895
|
+
);
|
|
1896
|
+
}) });
|
|
1897
|
+
}
|
|
1898
|
+
var styles16 = StyleSheet16.create({
|
|
1899
|
+
stacked: { gap: 14 },
|
|
1900
|
+
inline: { flexDirection: "row", alignItems: "baseline", justifyContent: "space-between", gap: 16, paddingVertical: 10 },
|
|
1901
|
+
grid: { flexDirection: "row", flexWrap: "wrap", gap: 10 },
|
|
1902
|
+
card: { flexBasis: "47%", flexGrow: 1, padding: 12, gap: 4, borderWidth: StyleSheet16.hairlineWidth },
|
|
1903
|
+
upper: { textTransform: "uppercase", letterSpacing: 0.6, fontWeight: "700" },
|
|
1904
|
+
value: { gap: 2, marginTop: 2 },
|
|
1905
|
+
valueInline: { flexShrink: 1, alignItems: "flex-end", gap: 2 },
|
|
1906
|
+
right: { textAlign: "right" }
|
|
1907
|
+
});
|
|
1908
|
+
|
|
1666
1909
|
// src/native/empty-state.tsx
|
|
1667
|
-
import { StyleSheet as
|
|
1668
|
-
import { jsx as
|
|
1910
|
+
import { StyleSheet as StyleSheet17, View as View14 } from "react-native";
|
|
1911
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1669
1912
|
function EmptyState({ icon, title, description, action, style, ...props }) {
|
|
1670
1913
|
const { theme } = useTheme();
|
|
1671
|
-
return /* @__PURE__ */
|
|
1672
|
-
icon ? /* @__PURE__ */
|
|
1673
|
-
/* @__PURE__ */
|
|
1674
|
-
description ? /* @__PURE__ */
|
|
1675
|
-
action ? /* @__PURE__ */
|
|
1914
|
+
return /* @__PURE__ */ jsxs15(View14, { ...props, style: [styles17.root, style], children: [
|
|
1915
|
+
icon ? /* @__PURE__ */ jsx18(View14, { "aria-hidden": true, style: [styles17.icon, { backgroundColor: theme.surface2 }], children: icon }) : null,
|
|
1916
|
+
/* @__PURE__ */ jsx18(Txt, { variant: "label", role: "heading", style: styles17.center, children: title }),
|
|
1917
|
+
description ? /* @__PURE__ */ jsx18(Txt, { tone: "secondary", style: styles17.center, children: description }) : null,
|
|
1918
|
+
action ? /* @__PURE__ */ jsx18(View14, { style: styles17.action, children: action }) : null
|
|
1676
1919
|
] });
|
|
1677
1920
|
}
|
|
1678
|
-
var
|
|
1921
|
+
var styles17 = StyleSheet17.create({
|
|
1679
1922
|
root: { alignItems: "center", justifyContent: "center", gap: 8, paddingVertical: 40, paddingHorizontal: 24 },
|
|
1680
1923
|
icon: { width: 48, height: 48, borderRadius: 24, alignItems: "center", justifyContent: "center", marginBottom: 4 },
|
|
1681
1924
|
center: { textAlign: "center", maxWidth: 360 },
|
|
1682
1925
|
action: { marginTop: 8, flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: 8 }
|
|
1683
1926
|
});
|
|
1684
1927
|
|
|
1928
|
+
// src/native/fab.tsx
|
|
1929
|
+
import { Pressable as Pressable10, StyleSheet as StyleSheet18, View as View15 } from "react-native";
|
|
1930
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1931
|
+
function Fab({ label, icon, onPress, extended, placement = "end", offset = 0, style }) {
|
|
1932
|
+
const { theme, insets, haptic } = useTheme();
|
|
1933
|
+
const position = placement === "center" ? { alignSelf: "center" } : placement === "start" ? { left: 16 + insets.left } : { right: 16 + insets.right };
|
|
1934
|
+
return /* @__PURE__ */ jsx19(View15, { pointerEvents: "box-none", style: [styles18.layer, placement === "center" ? styles18.centre : null], children: /* @__PURE__ */ jsxs16(
|
|
1935
|
+
Pressable10,
|
|
1936
|
+
{
|
|
1937
|
+
role: "button",
|
|
1938
|
+
"aria-label": label,
|
|
1939
|
+
onPress: () => {
|
|
1940
|
+
haptic("impact");
|
|
1941
|
+
onPress();
|
|
1942
|
+
},
|
|
1943
|
+
style: ({ pressed }) => [
|
|
1944
|
+
styles18.fab,
|
|
1945
|
+
extended ? styles18.extended : null,
|
|
1946
|
+
position,
|
|
1947
|
+
{ bottom: 16 + insets.bottom + offset, backgroundColor: pressed ? theme.accentHover : theme.accent, borderTopColor: theme.edgeOnFill, shadowColor: theme.scrimStrong },
|
|
1948
|
+
style
|
|
1949
|
+
],
|
|
1950
|
+
children: [
|
|
1951
|
+
/* @__PURE__ */ jsx19(View15, { "aria-hidden": true, children: icon }),
|
|
1952
|
+
extended ? /* @__PURE__ */ jsx19(Txt, { variant: "label", tone: "onAccent", "aria-hidden": true, numberOfLines: 1, style: styles18.label, children: label }) : null
|
|
1953
|
+
]
|
|
1954
|
+
}
|
|
1955
|
+
) });
|
|
1956
|
+
}
|
|
1957
|
+
var styles18 = StyleSheet18.create({
|
|
1958
|
+
layer: { position: "absolute", top: 0, right: 0, bottom: 0, left: 0 },
|
|
1959
|
+
centre: { alignItems: "center" },
|
|
1960
|
+
fab: { borderTopWidth: 1, borderColor: "transparent", position: "absolute", minWidth: 56, height: 56, borderRadius: 28, alignItems: "center", justifyContent: "center", flexDirection: "row", gap: 8, shadowOpacity: 0.3, shadowRadius: 12, shadowOffset: { width: 0, height: 6 }, elevation: 6 },
|
|
1961
|
+
extended: { paddingHorizontal: 20 },
|
|
1962
|
+
label: { flexShrink: 0 }
|
|
1963
|
+
});
|
|
1964
|
+
|
|
1685
1965
|
// src/native/field.tsx
|
|
1686
|
-
import * as
|
|
1687
|
-
import { StyleSheet as
|
|
1688
|
-
import { jsx as
|
|
1966
|
+
import * as React15 from "react";
|
|
1967
|
+
import { StyleSheet as StyleSheet19, Text as Text12, TextInput as TextInput3, View as View16 } from "react-native";
|
|
1968
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1689
1969
|
function TextField({ label, hint, error, value, defaultValue, onValueChange, disabled, end, inputRef, style, multiline, onFocus, onBlur, ...props }) {
|
|
1690
1970
|
const { theme, radius: radius3 } = useTheme();
|
|
1691
|
-
const [focused, setFocused] =
|
|
1971
|
+
const [focused, setFocused] = React15.useState(false);
|
|
1692
1972
|
const caption = error ?? hint;
|
|
1693
1973
|
const border = error ? theme.danger : focused ? theme.accent : theme.borderDefault;
|
|
1694
|
-
return /* @__PURE__ */
|
|
1695
|
-
/* @__PURE__ */
|
|
1696
|
-
/* @__PURE__ */
|
|
1697
|
-
/* @__PURE__ */
|
|
1974
|
+
return /* @__PURE__ */ jsxs17(View16, { style: [styles19.root, disabled ? styles19.disabled : null, style], children: [
|
|
1975
|
+
/* @__PURE__ */ jsx20(Text12, { style: [styles19.label, { color: theme.textSecondary }], children: label }),
|
|
1976
|
+
/* @__PURE__ */ jsxs17(View16, { style: [styles19.frame, multiline ? styles19.multiline : null, { borderRadius: radius3.md, borderColor: border, backgroundColor: theme.surface2 }], children: [
|
|
1977
|
+
/* @__PURE__ */ jsx20(
|
|
1698
1978
|
TextInput3,
|
|
1699
1979
|
{
|
|
1700
1980
|
ref: inputRef,
|
|
@@ -1716,16 +1996,16 @@ function TextField({ label, hint, error, value, defaultValue, onValueChange, dis
|
|
|
1716
1996
|
setFocused(false);
|
|
1717
1997
|
onBlur?.(event);
|
|
1718
1998
|
},
|
|
1719
|
-
style: [
|
|
1999
|
+
style: [styles19.input, multiline ? styles19.inputMultiline : null, { color: theme.textPrimary }],
|
|
1720
2000
|
...props
|
|
1721
2001
|
}
|
|
1722
2002
|
),
|
|
1723
|
-
end ? /* @__PURE__ */
|
|
2003
|
+
end ? /* @__PURE__ */ jsx20(View16, { style: styles19.end, children: end }) : null
|
|
1724
2004
|
] }),
|
|
1725
|
-
caption ? /* @__PURE__ */
|
|
2005
|
+
caption ? /* @__PURE__ */ jsx20(Text12, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles19.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
1726
2006
|
] });
|
|
1727
2007
|
}
|
|
1728
|
-
var
|
|
2008
|
+
var styles19 = StyleSheet19.create({
|
|
1729
2009
|
root: { gap: 6, alignSelf: "stretch" },
|
|
1730
2010
|
label: { fontSize: 12, lineHeight: 16, fontWeight: "600" },
|
|
1731
2011
|
frame: { flexDirection: "row", alignItems: "center", minHeight: 44, paddingHorizontal: 12, borderWidth: 1 },
|
|
@@ -1738,17 +2018,17 @@ var styles15 = StyleSheet15.create({
|
|
|
1738
2018
|
});
|
|
1739
2019
|
|
|
1740
2020
|
// src/native/goal-gauge.tsx
|
|
1741
|
-
import { Animated as Animated5, StyleSheet as
|
|
2021
|
+
import { Animated as Animated5, StyleSheet as StyleSheet20, View as View17 } from "react-native";
|
|
1742
2022
|
|
|
1743
2023
|
// src/native/story-motion.ts
|
|
1744
|
-
import * as
|
|
1745
|
-
import { AccessibilityInfo as
|
|
2024
|
+
import * as React16 from "react";
|
|
2025
|
+
import { AccessibilityInfo as AccessibilityInfo3, Animated as Animated4, Easing } from "react-native";
|
|
1746
2026
|
function useEntrance(animated, delay = 0, duration = 700) {
|
|
1747
|
-
const [value] =
|
|
1748
|
-
|
|
2027
|
+
const [value] = React16.useState(() => new Animated4.Value(animated ? 0 : 1));
|
|
2028
|
+
React16.useEffect(() => {
|
|
1749
2029
|
if (!animated) return;
|
|
1750
2030
|
let cancelled = false;
|
|
1751
|
-
void
|
|
2031
|
+
void AccessibilityInfo3.isReduceMotionEnabled().then((reduce) => {
|
|
1752
2032
|
if (cancelled) return;
|
|
1753
2033
|
if (reduce) value.setValue(1);
|
|
1754
2034
|
else Animated4.timing(value, { toValue: 1, duration, delay, easing: Easing.out(Easing.cubic), useNativeDriver: true }).start();
|
|
@@ -1761,17 +2041,17 @@ function useEntrance(animated, delay = 0, duration = 700) {
|
|
|
1761
2041
|
}
|
|
1762
2042
|
|
|
1763
2043
|
// src/native/goal-gauge.tsx
|
|
1764
|
-
import { jsx as
|
|
2044
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1765
2045
|
function Cell({ lit, animate, order, animated, arcade }) {
|
|
1766
2046
|
const { theme } = useTheme();
|
|
1767
2047
|
const t = useEntrance(animated && animate, 300 + order * 100, 350);
|
|
1768
2048
|
const spentOpacity = arcade ? 0.14 : 1;
|
|
1769
2049
|
const opacity = !animate ? 1 : lit ? t.interpolate({ inputRange: [0, 1], outputRange: [0.25, 1] }) : t.interpolate({ inputRange: [0, 1], outputRange: [1, arcade ? 0.14 : 1] });
|
|
1770
2050
|
const color = lit || arcade ? theme.accent : theme.surface3;
|
|
1771
|
-
return /* @__PURE__ */
|
|
2051
|
+
return /* @__PURE__ */ jsx21(
|
|
1772
2052
|
Animated5.View,
|
|
1773
2053
|
{
|
|
1774
|
-
style: [
|
|
2054
|
+
style: [styles20.cell, arcade ? styles20.cellArcade : null, { backgroundColor: color, opacity: lit || animate ? opacity : spentOpacity }]
|
|
1775
2055
|
}
|
|
1776
2056
|
);
|
|
1777
2057
|
}
|
|
@@ -1781,8 +2061,8 @@ function GoalGauge({ label, segments, value, valueText, mode = "fill", showLabel
|
|
|
1781
2061
|
const lit = Math.min(total, Math.max(0, Math.round(value ?? total)));
|
|
1782
2062
|
const words = valueText ?? `${lit} / ${total}`;
|
|
1783
2063
|
const arcade = variant === "arcade";
|
|
1784
|
-
return /* @__PURE__ */
|
|
1785
|
-
|
|
2064
|
+
return /* @__PURE__ */ jsxs18(
|
|
2065
|
+
View17,
|
|
1786
2066
|
{
|
|
1787
2067
|
accessible: true,
|
|
1788
2068
|
role: "meter",
|
|
@@ -1792,22 +2072,22 @@ function GoalGauge({ label, segments, value, valueText, mode = "fill", showLabel
|
|
|
1792
2072
|
"aria-valuenow": lit,
|
|
1793
2073
|
"aria-valuetext": words,
|
|
1794
2074
|
...props,
|
|
1795
|
-
style: [
|
|
2075
|
+
style: [styles20.root, style],
|
|
1796
2076
|
children: [
|
|
1797
|
-
showLabel ? /* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
arcade ? null : /* @__PURE__ */
|
|
2077
|
+
showLabel ? /* @__PURE__ */ jsxs18(View17, { "aria-hidden": true, style: [styles20.head, arcade ? styles20.headArcade : null], children: [
|
|
2078
|
+
/* @__PURE__ */ jsx21(Txt, { variant: arcade ? "mono" : "caption", tone: "secondary", children: arcade ? label.toUpperCase() : label }),
|
|
2079
|
+
arcade ? null : /* @__PURE__ */ jsx21(Txt, { variant: "caption", children: words })
|
|
1800
2080
|
] }) : null,
|
|
1801
|
-
/* @__PURE__ */
|
|
2081
|
+
/* @__PURE__ */ jsx21(View17, { "aria-hidden": true, style: [styles20.cells, arcade ? [styles20.cellsArcade, { borderColor: theme.borderSubtle, backgroundColor: theme.surface1 }] : null], children: Array.from({ length: total }, (_, i) => {
|
|
1802
2082
|
const on = i < lit;
|
|
1803
2083
|
const animate = mode === "fill" ? on : !on;
|
|
1804
|
-
return /* @__PURE__ */
|
|
2084
|
+
return /* @__PURE__ */ jsx21(Cell, { lit: on, animate, order: mode === "fill" ? i : i - lit, animated, arcade }, i);
|
|
1805
2085
|
}) })
|
|
1806
2086
|
]
|
|
1807
2087
|
}
|
|
1808
2088
|
);
|
|
1809
2089
|
}
|
|
1810
|
-
var
|
|
2090
|
+
var styles20 = StyleSheet20.create({
|
|
1811
2091
|
root: { alignSelf: "stretch", gap: 8 },
|
|
1812
2092
|
head: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 },
|
|
1813
2093
|
headArcade: { justifyContent: "center" },
|
|
@@ -1817,9 +2097,190 @@ var styles16 = StyleSheet16.create({
|
|
|
1817
2097
|
cellArcade: { height: 10, borderRadius: 1 }
|
|
1818
2098
|
});
|
|
1819
2099
|
|
|
2100
|
+
// src/native/header.tsx
|
|
2101
|
+
import * as React17 from "react";
|
|
2102
|
+
import { Animated as Animated6, Pressable as Pressable11, StyleSheet as StyleSheet21, View as View18 } from "react-native";
|
|
2103
|
+
import Svg6, { Path as Path4 } from "react-native-svg";
|
|
2104
|
+
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2105
|
+
var BAR = 44;
|
|
2106
|
+
var LARGE = 52;
|
|
2107
|
+
function Header({ title, subtitle, scrollY, size = "large", backLabel, onBack, actions, children, style }) {
|
|
2108
|
+
const { theme, insets } = useTheme();
|
|
2109
|
+
const reduce = useReducedMotion();
|
|
2110
|
+
const large = size === "large";
|
|
2111
|
+
const fixed = React17.useMemo(() => new Animated6.Value(large ? 0 : 1), [large]);
|
|
2112
|
+
const progress = scrollY && large ? scrollY.interpolate({ inputRange: [0, LARGE], outputRange: [0, 1], extrapolate: "clamp" }) : fixed;
|
|
2113
|
+
const smallOpacity = progress.interpolate({ inputRange: [0.6, 1], outputRange: [0, 1], extrapolate: "clamp" });
|
|
2114
|
+
const largeOpacity = progress.interpolate({ inputRange: [0, 0.7], outputRange: [1, 0], extrapolate: "clamp" });
|
|
2115
|
+
const largeShift = reduce ? 0 : progress.interpolate({ inputRange: [0, 1], outputRange: [0, -10] });
|
|
2116
|
+
const largeHeight = progress.interpolate({ inputRange: [0, 1], outputRange: [LARGE + (subtitle ? 18 : 0), 0] });
|
|
2117
|
+
return /* @__PURE__ */ jsxs19(View18, { style: [{ paddingTop: insets.top, backgroundColor: theme.surface0 }, style], children: [
|
|
2118
|
+
/* @__PURE__ */ jsxs19(View18, { style: styles21.bar, children: [
|
|
2119
|
+
/* @__PURE__ */ jsx22(View18, { style: styles21.side, children: onBack && backLabel ? /* @__PURE__ */ jsxs19(Pressable11, { role: "button", "aria-label": backLabel, onPress: onBack, hitSlop: 8, style: styles21.back, children: [
|
|
2120
|
+
/* @__PURE__ */ jsx22(Svg6, { width: 22, height: 22, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx22(Path4, { d: "M15 5l-7 7 7 7", stroke: theme.accentText, strokeWidth: 2.4, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
2121
|
+
/* @__PURE__ */ jsx22(Txt, { variant: "label", tone: "accent", numberOfLines: 1, children: backLabel })
|
|
2122
|
+
] }) : null }),
|
|
2123
|
+
/* @__PURE__ */ jsx22(Animated6.View, { style: [styles21.middle, { opacity: smallOpacity }], "aria-hidden": large, children: /* @__PURE__ */ jsx22(Txt, { variant: "label", numberOfLines: 1, role: large ? void 0 : "heading", children: title }) }),
|
|
2124
|
+
/* @__PURE__ */ jsx22(View18, { style: [styles21.side, styles21.right], children: actions })
|
|
2125
|
+
] }),
|
|
2126
|
+
large ? /* @__PURE__ */ jsx22(Animated6.View, { style: { height: largeHeight, overflow: "hidden" }, children: /* @__PURE__ */ jsxs19(Animated6.View, { style: [styles21.large, { opacity: largeOpacity, transform: [{ translateY: largeShift }] }], children: [
|
|
2127
|
+
/* @__PURE__ */ jsx22(Txt, { variant: "display", numberOfLines: 1, role: "heading", style: styles21.largeTitle, children: title }),
|
|
2128
|
+
subtitle ? /* @__PURE__ */ jsx22(Txt, { variant: "caption", tone: "secondary", children: subtitle }) : null
|
|
2129
|
+
] }) }) : null,
|
|
2130
|
+
children ? /* @__PURE__ */ jsx22(View18, { style: styles21.children, children }) : null,
|
|
2131
|
+
/* @__PURE__ */ jsx22(Animated6.View, { "aria-hidden": true, style: [styles21.rule, { backgroundColor: theme.borderSubtle, opacity: smallOpacity }] })
|
|
2132
|
+
] });
|
|
2133
|
+
}
|
|
2134
|
+
function useCollapsingHeader() {
|
|
2135
|
+
const [scrollY] = React17.useState(() => new Animated6.Value(0));
|
|
2136
|
+
const onScroll = React17.useMemo(() => Animated6.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], { useNativeDriver: false }), [scrollY]);
|
|
2137
|
+
return { scrollY, onScroll };
|
|
2138
|
+
}
|
|
2139
|
+
var styles21 = StyleSheet21.create({
|
|
2140
|
+
bar: { height: BAR, flexDirection: "row", alignItems: "center", paddingHorizontal: 8 },
|
|
2141
|
+
side: { flex: 1, flexDirection: "row", alignItems: "center" },
|
|
2142
|
+
right: { justifyContent: "flex-end", gap: 4 },
|
|
2143
|
+
middle: { flex: 2, alignItems: "center" },
|
|
2144
|
+
back: { flexDirection: "row", alignItems: "center", gap: 2, minHeight: 44, paddingRight: 8 },
|
|
2145
|
+
large: { paddingHorizontal: 16, paddingBottom: 6 },
|
|
2146
|
+
largeTitle: { fontSize: 32, lineHeight: 40 },
|
|
2147
|
+
children: { paddingHorizontal: 16, paddingBottom: 8 },
|
|
2148
|
+
rule: { height: StyleSheet21.hairlineWidth }
|
|
2149
|
+
});
|
|
2150
|
+
|
|
2151
|
+
// src/native/image-viewer.tsx
|
|
2152
|
+
import * as React18 from "react";
|
|
2153
|
+
import { AccessibilityInfo as AccessibilityInfo4, Animated as Animated7, Image as Image3, Modal as Modal3, PanResponder, Pressable as Pressable12, StyleSheet as StyleSheet22, useWindowDimensions, View as View19 } from "react-native";
|
|
2154
|
+
import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2155
|
+
var MAX_SCALE = 4;
|
|
2156
|
+
function ImageViewer({ images, index, onIndexChange, closeLabel, positionLabel = (n, total) => `${n} / ${total}` }) {
|
|
2157
|
+
const { theme, insets, haptic } = useTheme();
|
|
2158
|
+
const reduce = useReducedMotion();
|
|
2159
|
+
const { width, height } = useWindowDimensions();
|
|
2160
|
+
const open = index !== null && images[index] !== void 0;
|
|
2161
|
+
const [scale] = React18.useState(() => new Animated7.Value(1));
|
|
2162
|
+
const [pan] = React18.useState(() => new Animated7.ValueXY({ x: 0, y: 0 }));
|
|
2163
|
+
const [dismiss2] = React18.useState(() => new Animated7.Value(0));
|
|
2164
|
+
const state = React18.useRef({ scale: 1, x: 0, y: 0, pinch: 0, base: 1, lastTap: 0 });
|
|
2165
|
+
const reset = React18.useCallback(() => {
|
|
2166
|
+
state.current = { ...state.current, scale: 1, x: 0, y: 0 };
|
|
2167
|
+
scale.setValue(1);
|
|
2168
|
+
pan.setValue({ x: 0, y: 0 });
|
|
2169
|
+
dismiss2.setValue(0);
|
|
2170
|
+
}, [scale, pan, dismiss2]);
|
|
2171
|
+
React18.useEffect(() => {
|
|
2172
|
+
reset();
|
|
2173
|
+
if (open) AccessibilityInfo4.announceForAccessibility(`${images[index].alt}, ${positionLabel(index + 1, images.length)}`);
|
|
2174
|
+
}, [index]);
|
|
2175
|
+
const go = (to) => {
|
|
2176
|
+
if (to < 0 || to >= images.length) return;
|
|
2177
|
+
haptic("selection");
|
|
2178
|
+
onIndexChange(to);
|
|
2179
|
+
};
|
|
2180
|
+
const animateTo = (value, to) => reduce ? value.setValue(to) : Animated7.spring(value, { toValue: to, useNativeDriver: true, damping: 20 }).start();
|
|
2181
|
+
const distance = (touches) => Math.hypot(touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY);
|
|
2182
|
+
const responder = React18.useMemo(
|
|
2183
|
+
() => PanResponder.create({
|
|
2184
|
+
onStartShouldSetPanResponder: () => true,
|
|
2185
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 4 || Math.abs(g.dy) > 4,
|
|
2186
|
+
onPanResponderGrant: (e) => {
|
|
2187
|
+
const now = Date.now();
|
|
2188
|
+
const s = state.current;
|
|
2189
|
+
if (e.nativeEvent.touches.length === 1 && now - s.lastTap < 280) {
|
|
2190
|
+
const next = s.scale > 1 ? 1 : 2.5;
|
|
2191
|
+
s.scale = next;
|
|
2192
|
+
s.x = 0;
|
|
2193
|
+
s.y = 0;
|
|
2194
|
+
animateTo(scale, next);
|
|
2195
|
+
pan.setValue({ x: 0, y: 0 });
|
|
2196
|
+
}
|
|
2197
|
+
s.lastTap = now;
|
|
2198
|
+
s.pinch = 0;
|
|
2199
|
+
},
|
|
2200
|
+
onPanResponderMove: (e, g) => {
|
|
2201
|
+
const s = state.current;
|
|
2202
|
+
const touches = e.nativeEvent.touches;
|
|
2203
|
+
if (touches.length === 2) {
|
|
2204
|
+
const d = distance(touches);
|
|
2205
|
+
if (!s.pinch) {
|
|
2206
|
+
s.pinch = d;
|
|
2207
|
+
s.base = s.scale;
|
|
2208
|
+
}
|
|
2209
|
+
s.scale = Math.min(MAX_SCALE, Math.max(1, s.base * (d / s.pinch)));
|
|
2210
|
+
scale.setValue(s.scale);
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
if (s.scale > 1) pan.setValue({ x: s.x + g.dx, y: s.y + g.dy });
|
|
2214
|
+
else if (Math.abs(g.dy) > Math.abs(g.dx)) dismiss2.setValue(Math.max(0, g.dy));
|
|
2215
|
+
else pan.setValue({ x: g.dx, y: 0 });
|
|
2216
|
+
},
|
|
2217
|
+
onPanResponderRelease: (_, g) => {
|
|
2218
|
+
const s = state.current;
|
|
2219
|
+
if (s.pinch) {
|
|
2220
|
+
s.pinch = 0;
|
|
2221
|
+
if (s.scale <= 1.02) reset();
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
if (s.scale > 1) {
|
|
2225
|
+
s.x += g.dx;
|
|
2226
|
+
s.y += g.dy;
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
if (g.dy > 120 || g.vy > 1.2) return onIndexChange(null);
|
|
2230
|
+
if (g.dx < -width / 4 || g.vx < -0.8) go((index ?? 0) + 1);
|
|
2231
|
+
else if (g.dx > width / 4 || g.vx > 0.8) go((index ?? 0) - 1);
|
|
2232
|
+
animateTo(dismiss2, 0);
|
|
2233
|
+
Animated7.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: true }).start();
|
|
2234
|
+
}
|
|
2235
|
+
}),
|
|
2236
|
+
[index, width, images.length]
|
|
2237
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- the gesture reads refs
|
|
2238
|
+
);
|
|
2239
|
+
if (!open) return null;
|
|
2240
|
+
const image = images[index];
|
|
2241
|
+
const backdrop = dismiss2.interpolate({ inputRange: [0, height / 2], outputRange: [1, 0.3], extrapolate: "clamp" });
|
|
2242
|
+
return /* @__PURE__ */ jsxs20(Modal3, { ...modalName(image.alt), visible: true, transparent: true, animationType: reduce ? "none" : "fade", onRequestClose: () => onIndexChange(null), statusBarTranslucent: true, children: [
|
|
2243
|
+
/* @__PURE__ */ jsx23(Animated7.View, { style: [StyleSheet22.absoluteFill, { backgroundColor: theme.media, opacity: backdrop }] }),
|
|
2244
|
+
/* @__PURE__ */ jsx23(
|
|
2245
|
+
View19,
|
|
2246
|
+
{
|
|
2247
|
+
style: StyleSheet22.absoluteFill,
|
|
2248
|
+
accessible: true,
|
|
2249
|
+
role: "img",
|
|
2250
|
+
"aria-label": `${image.alt}, ${positionLabel(index + 1, images.length)}`,
|
|
2251
|
+
accessibilityActions: [{ name: "increment" }, { name: "decrement" }, { name: "escape" }],
|
|
2252
|
+
onAccessibilityAction: (e) => {
|
|
2253
|
+
const name = e.nativeEvent.actionName;
|
|
2254
|
+
if (name === "increment") go(index + 1);
|
|
2255
|
+
if (name === "decrement") go(index - 1);
|
|
2256
|
+
if (name === "escape") onIndexChange(null);
|
|
2257
|
+
},
|
|
2258
|
+
...responder.panHandlers,
|
|
2259
|
+
children: /* @__PURE__ */ jsx23(Animated7.View, { style: { width, height, transform: [{ translateX: pan.x }, { translateY: Animated7.add(pan.y, dismiss2) }, { scale }] }, children: /* @__PURE__ */ jsx23(Image3, { source: { uri: image.uri }, resizeMode: "contain", style: { width, height }, accessibilityIgnoresInvertColors: true }) })
|
|
2260
|
+
}
|
|
2261
|
+
),
|
|
2262
|
+
/* @__PURE__ */ jsxs20(View19, { pointerEvents: "box-none", style: [styles22.top, { paddingTop: insets.top + 8 }], children: [
|
|
2263
|
+
/* @__PURE__ */ jsx23(View19, { "aria-hidden": true, style: [styles22.counter, { backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx23(Txt, { variant: "label", tone: "onMedia", children: positionLabel(index + 1, images.length) }) }),
|
|
2264
|
+
/* @__PURE__ */ jsx23(Pressable12, { role: "button", "aria-label": closeLabel, hitSlop: 12, onPress: () => onIndexChange(null), style: [styles22.close, { backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx23(Txt, { tone: "onMedia", style: styles22.cross, "aria-hidden": true, children: "\xD7" }) })
|
|
2265
|
+
] }),
|
|
2266
|
+
image.caption ? /* @__PURE__ */ jsx23(View19, { pointerEvents: "none", style: [styles22.caption, { paddingBottom: insets.bottom + 16, backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx23(Txt, { tone: "onMedia", children: image.caption }) }) : null
|
|
2267
|
+
] });
|
|
2268
|
+
}
|
|
2269
|
+
function prefetchNeighbours(images, index) {
|
|
2270
|
+
if (index === null) return;
|
|
2271
|
+
for (const i of [index - 1, index + 1]) if (images[i]) void Image3.prefetch(images[i].uri).catch(() => void 0);
|
|
2272
|
+
}
|
|
2273
|
+
var styles22 = StyleSheet22.create({
|
|
2274
|
+
top: { position: "absolute", top: 0, left: 0, right: 0, flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 },
|
|
2275
|
+
counter: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 999 },
|
|
2276
|
+
close: { width: 40, height: 40, borderRadius: 20, alignItems: "center", justifyContent: "center" },
|
|
2277
|
+
cross: { fontSize: 24, lineHeight: 26 },
|
|
2278
|
+
caption: { position: "absolute", left: 0, right: 0, bottom: 0, paddingTop: 12, paddingHorizontal: 16 }
|
|
2279
|
+
});
|
|
2280
|
+
|
|
1820
2281
|
// src/native/KrizakaMark.tsx
|
|
1821
|
-
import { View as
|
|
1822
|
-
import
|
|
2282
|
+
import { View as View20 } from "react-native";
|
|
2283
|
+
import Svg7, { Circle as Circle2, Defs as Defs3, G as Group, LinearGradient as LinearGradient3, Path as Path5, RadialGradient, Stop as Stop3 } from "react-native-svg";
|
|
1823
2284
|
|
|
1824
2285
|
// src/marks/krizaka-geometry.ts
|
|
1825
2286
|
var KRIZAKA = {
|
|
@@ -1841,24 +2302,24 @@ var KRIZAKA = {
|
|
|
1841
2302
|
};
|
|
1842
2303
|
|
|
1843
2304
|
// src/native/mark-motion.ts
|
|
1844
|
-
import { useEffect as
|
|
1845
|
-
import { AccessibilityInfo as
|
|
2305
|
+
import { useEffect as useEffect10, useState as useState18 } from "react";
|
|
2306
|
+
import { AccessibilityInfo as AccessibilityInfo5, Animated as Animated8, Easing as Easing2 } from "react-native";
|
|
1846
2307
|
var markA11y = (title) => title ? { accessible: true, accessibilityRole: "image", accessibilityLabel: title } : { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" };
|
|
1847
2308
|
function useMarkMotion(size, animated, spinMs = 3e4) {
|
|
1848
|
-
const [spin] =
|
|
1849
|
-
const [pulse] =
|
|
1850
|
-
|
|
2309
|
+
const [spin] = useState18(() => new Animated8.Value(0));
|
|
2310
|
+
const [pulse] = useState18(() => new Animated8.Value(0));
|
|
2311
|
+
useEffect10(() => {
|
|
1851
2312
|
if (!animated) return;
|
|
1852
2313
|
let loops = [];
|
|
1853
2314
|
let cancelled = false;
|
|
1854
|
-
void
|
|
2315
|
+
void AccessibilityInfo5.isReduceMotionEnabled().then((reduce) => {
|
|
1855
2316
|
if (reduce || cancelled) return;
|
|
1856
2317
|
loops = [
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
2318
|
+
Animated8.loop(Animated8.timing(spin, { toValue: 1, duration: spinMs, easing: Easing2.linear, useNativeDriver: true })),
|
|
2319
|
+
Animated8.loop(
|
|
2320
|
+
Animated8.sequence([
|
|
2321
|
+
Animated8.timing(pulse, { toValue: 1, duration: 1600, easing: Easing2.inOut(Easing2.ease), useNativeDriver: true }),
|
|
2322
|
+
Animated8.timing(pulse, { toValue: 0, duration: 1600, easing: Easing2.inOut(Easing2.ease), useNativeDriver: true })
|
|
1862
2323
|
])
|
|
1863
2324
|
)
|
|
1864
2325
|
];
|
|
@@ -1870,7 +2331,7 @@ function useMarkMotion(size, animated, spinMs = 3e4) {
|
|
|
1870
2331
|
};
|
|
1871
2332
|
}, [animated, spin, pulse, spinMs]);
|
|
1872
2333
|
return {
|
|
1873
|
-
Animated:
|
|
2334
|
+
Animated: Animated8,
|
|
1874
2335
|
layer: { position: "absolute", width: size, height: size },
|
|
1875
2336
|
spinStyle: { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] },
|
|
1876
2337
|
pulseStyle: { opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.85, 1] }) }
|
|
@@ -1878,39 +2339,39 @@ function useMarkMotion(size, animated, spinMs = 3e4) {
|
|
|
1878
2339
|
}
|
|
1879
2340
|
|
|
1880
2341
|
// src/native/KrizakaMark.tsx
|
|
1881
|
-
import { Fragment as
|
|
2342
|
+
import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1882
2343
|
function KrizakaMark({ size = 48, animated = true, title, neutral }) {
|
|
1883
2344
|
const { theme } = useTheme();
|
|
1884
|
-
const { Animated:
|
|
2345
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
|
|
1885
2346
|
const id = useSvgId("kzm");
|
|
1886
2347
|
const viewBox = size < 48 ? KRIZAKA.croppedViewBox : KRIZAKA.viewBox;
|
|
1887
2348
|
const stroke = neutral ?? theme.textMuted;
|
|
1888
|
-
const blue = /* @__PURE__ */
|
|
1889
|
-
const dot = (c) => /* @__PURE__ */
|
|
1890
|
-
/* @__PURE__ */
|
|
1891
|
-
/* @__PURE__ */
|
|
2349
|
+
const blue = /* @__PURE__ */ jsx24(LinearGradient3, { id: `${id}b`, gradientUnits: "userSpaceOnUse", x1: KRIZAKA.blue.x1 + KRIZAKA.offset, y1: KRIZAKA.blue.y1 + KRIZAKA.offset, x2: KRIZAKA.blue.x2 + KRIZAKA.offset, y2: KRIZAKA.blue.y2 + KRIZAKA.offset, children: KRIZAKA.blue.stops.map(([offset, color]) => /* @__PURE__ */ jsx24(Stop3, { offset, stopColor: color }, offset)) });
|
|
2350
|
+
const dot = (c) => /* @__PURE__ */ jsxs21(Fragment4, { children: [
|
|
2351
|
+
/* @__PURE__ */ jsx24(Circle2, { cx: c.cx, cy: c.cy, r: c.r, fill: `url(#${id}b)` }),
|
|
2352
|
+
/* @__PURE__ */ jsx24(Circle2, { cx: c.cx, cy: c.cy, r: c.inner, fill: KRIZAKA.highlight })
|
|
1892
2353
|
] });
|
|
1893
|
-
return /* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
/* @__PURE__ */
|
|
1897
|
-
/* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
2354
|
+
return /* @__PURE__ */ jsxs21(View20, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
2355
|
+
/* @__PURE__ */ jsxs21(Svg7, { viewBox, style: layer, children: [
|
|
2356
|
+
/* @__PURE__ */ jsxs21(Defs3, { children: [
|
|
2357
|
+
/* @__PURE__ */ jsxs21(RadialGradient, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
2358
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "0%", stopColor: KRIZAKA.glow.color, stopOpacity: KRIZAKA.glow.opacity }),
|
|
2359
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "100%", stopColor: KRIZAKA.glow.color, stopOpacity: 0 })
|
|
1899
2360
|
] }),
|
|
1900
|
-
/* @__PURE__ */
|
|
1901
|
-
/* @__PURE__ */
|
|
1902
|
-
/* @__PURE__ */
|
|
2361
|
+
/* @__PURE__ */ jsxs21(LinearGradient3, { id: `${id}i`, gradientUnits: "userSpaceOnUse", x1: KRIZAKA.ink.x1 + KRIZAKA.offset, y1: KRIZAKA.ink.y1 + KRIZAKA.offset, x2: KRIZAKA.ink.x2 + KRIZAKA.offset, y2: KRIZAKA.ink.y2 + KRIZAKA.offset, children: [
|
|
2362
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "0%", stopColor: theme.textSecondary }),
|
|
2363
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "100%", stopColor: theme.textPrimary })
|
|
1903
2364
|
] }),
|
|
1904
2365
|
blue
|
|
1905
2366
|
] }),
|
|
1906
|
-
size >= 48 ? /* @__PURE__ */
|
|
1907
|
-
/* @__PURE__ */
|
|
1908
|
-
/* @__PURE__ */
|
|
2367
|
+
size >= 48 ? /* @__PURE__ */ jsx24(Circle2, { cx: 200, cy: 200, r: 190, fill: `url(#${id}g)` }) : null,
|
|
2368
|
+
/* @__PURE__ */ jsx24(Circle2, { cx: 200, cy: 200, r: KRIZAKA.ring.r, stroke, strokeWidth: KRIZAKA.ring.width, opacity: 0.35, fill: "none" }),
|
|
2369
|
+
/* @__PURE__ */ jsx24(Group, { transform: `translate(${KRIZAKA.offset} ${KRIZAKA.offset})`, children: /* @__PURE__ */ jsx24(Path5, { d: KRIZAKA.shield, stroke: `url(#${id}i)`, strokeWidth: KRIZAKA.stroke, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) })
|
|
1909
2370
|
] }),
|
|
1910
|
-
/* @__PURE__ */
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
/* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
2371
|
+
/* @__PURE__ */ jsx24(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsx24(Svg7, { viewBox, style: layer, children: /* @__PURE__ */ jsx24(Circle2, { cx: 200, cy: 200, r: KRIZAKA.orbit.r, stroke, strokeWidth: KRIZAKA.orbit.width, strokeDasharray: KRIZAKA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
|
|
2372
|
+
/* @__PURE__ */ jsx24(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs21(Svg7, { viewBox, style: layer, children: [
|
|
2373
|
+
/* @__PURE__ */ jsx24(Defs3, { children: blue }),
|
|
2374
|
+
/* @__PURE__ */ jsxs21(Group, { transform: `translate(${KRIZAKA.offset} ${KRIZAKA.offset})`, children: [
|
|
1914
2375
|
dot(KRIZAKA.node),
|
|
1915
2376
|
dot(KRIZAKA.core)
|
|
1916
2377
|
] })
|
|
@@ -1918,14 +2379,115 @@ function KrizakaMark({ size = 48, animated = true, title, neutral }) {
|
|
|
1918
2379
|
] });
|
|
1919
2380
|
}
|
|
1920
2381
|
|
|
2382
|
+
// src/native/loader.tsx
|
|
2383
|
+
import * as React19 from "react";
|
|
2384
|
+
import { AccessibilityInfo as AccessibilityInfo6, Animated as Animated9, Easing as Easing3, StyleSheet as StyleSheet23, View as View21 } from "react-native";
|
|
2385
|
+
import Svg8, { Circle as Circle3, Path as Path6 } from "react-native-svg";
|
|
2386
|
+
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2387
|
+
var HEX = "M12 3 19.79 7.5 19.79 16.5 12 21 4.21 16.5 4.21 7.5Z";
|
|
2388
|
+
var PERIMETER = 54;
|
|
2389
|
+
function LoaderGlyph({ state = "loading", value, size = 20, color }) {
|
|
2390
|
+
const { theme } = useTheme();
|
|
2391
|
+
const reduce = useReducedMotion();
|
|
2392
|
+
const [spin] = React19.useState(() => new Animated9.Value(0));
|
|
2393
|
+
const known = typeof value === "number" && Number.isFinite(value);
|
|
2394
|
+
React19.useEffect(() => {
|
|
2395
|
+
if (state !== "loading" || known || reduce) return;
|
|
2396
|
+
const loop = Animated9.loop(Animated9.timing(spin, { toValue: 1, duration: 1400, easing: Easing3.linear, useNativeDriver: true }));
|
|
2397
|
+
loop.start();
|
|
2398
|
+
return () => loop.stop();
|
|
2399
|
+
}, [state, known, reduce, spin]);
|
|
2400
|
+
const stroke = color ?? (state === "success" ? theme.success : state === "error" ? theme.danger : theme.accent);
|
|
2401
|
+
const fill = state !== "loading" ? 1 : known ? Math.min(1, Math.max(0, value)) : 0.3;
|
|
2402
|
+
const rotate = spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] });
|
|
2403
|
+
return /* @__PURE__ */ jsx25(Animated9.View, { "aria-hidden": true, style: { width: size, height: size, transform: state === "loading" && !known ? [{ rotate }] : [] }, children: /* @__PURE__ */ jsxs22(Svg8, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
|
|
2404
|
+
/* @__PURE__ */ jsx25(Path6, { d: HEX, stroke, strokeOpacity: 0.22, strokeWidth: 2.2, strokeLinejoin: "round" }),
|
|
2405
|
+
/* @__PURE__ */ jsx25(Path6, { d: HEX, stroke, strokeWidth: 2.2, strokeLinejoin: "round", strokeLinecap: "round", strokeDasharray: `${fill * PERIMETER} ${PERIMETER}` }),
|
|
2406
|
+
state === "loading" ? /* @__PURE__ */ jsx25(Circle3, { cx: 12, cy: 12, r: 2.6, fill: stroke }) : null,
|
|
2407
|
+
state === "success" ? /* @__PURE__ */ jsx25(Path6, { d: "M8.3 12.3l2.6 2.6 4.9-5.3", stroke, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round" }) : null,
|
|
2408
|
+
state === "error" ? /* @__PURE__ */ jsx25(Path6, { d: "M9.4 9.4l5.2 5.2M14.6 9.4l-5.2 5.2", stroke, strokeWidth: 2.2, strokeLinecap: "round" }) : null
|
|
2409
|
+
] }) });
|
|
2410
|
+
}
|
|
2411
|
+
function useDelayedWait(active, delay = 250, minDuration = 600) {
|
|
2412
|
+
const [shown, setShown] = React19.useState(false);
|
|
2413
|
+
const since = React19.useRef(0);
|
|
2414
|
+
React19.useEffect(() => {
|
|
2415
|
+
if (active && !shown) {
|
|
2416
|
+
const timer2 = setTimeout(() => {
|
|
2417
|
+
since.current = Date.now();
|
|
2418
|
+
setShown(true);
|
|
2419
|
+
}, delay);
|
|
2420
|
+
return () => clearTimeout(timer2);
|
|
2421
|
+
}
|
|
2422
|
+
if (!active && shown) {
|
|
2423
|
+
const timer2 = setTimeout(() => setShown(false), Math.max(0, minDuration - (Date.now() - since.current)));
|
|
2424
|
+
return () => clearTimeout(timer2);
|
|
2425
|
+
}
|
|
2426
|
+
return void 0;
|
|
2427
|
+
}, [active, shown, delay, minDuration]);
|
|
2428
|
+
return shown;
|
|
2429
|
+
}
|
|
2430
|
+
var GLYPH = { inline: 20, block: 36, overlay: 36, page: 56 };
|
|
2431
|
+
function Loader({ label, status = "loading", successLabel, errorLabel, value, eta, delay = 250, minDuration = 600, endDuration = 1600, variant = "inline", style }) {
|
|
2432
|
+
const { theme, radius: radius3 } = useTheme();
|
|
2433
|
+
const waiting = useDelayedWait(status === "loading", delay, minDuration);
|
|
2434
|
+
const [ending, setEnding] = React19.useState(null);
|
|
2435
|
+
const seen = React19.useRef(false);
|
|
2436
|
+
React19.useEffect(() => {
|
|
2437
|
+
if (waiting) {
|
|
2438
|
+
seen.current = true;
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2441
|
+
if (!seen.current || status === "loading") return;
|
|
2442
|
+
seen.current = false;
|
|
2443
|
+
if (endDuration <= 0) return;
|
|
2444
|
+
const show2 = setTimeout(() => setEnding(status), 0);
|
|
2445
|
+
const hide = Number.isFinite(endDuration) ? setTimeout(() => setEnding(null), endDuration) : void 0;
|
|
2446
|
+
return () => {
|
|
2447
|
+
clearTimeout(show2);
|
|
2448
|
+
clearTimeout(hide);
|
|
2449
|
+
};
|
|
2450
|
+
}, [waiting, status, endDuration]);
|
|
2451
|
+
const phase = waiting ? "loading" : ending;
|
|
2452
|
+
const words = phase === "success" ? successLabel ?? label : phase === "error" ? errorLabel ?? label : label;
|
|
2453
|
+
React19.useEffect(() => {
|
|
2454
|
+
if (phase) AccessibilityInfo6.announceForAccessibility(words);
|
|
2455
|
+
}, [phase, words]);
|
|
2456
|
+
if (!phase) return null;
|
|
2457
|
+
const known = phase === "loading" && typeof value === "number" && Number.isFinite(value);
|
|
2458
|
+
const detail = phase === "loading" ? [known ? `${Math.round(Math.min(1, Math.max(0, value)) * 100)} %` : null, eta].filter(Boolean).join(" \xB7 ") : "";
|
|
2459
|
+
const stacked = variant !== "inline";
|
|
2460
|
+
const box = /* @__PURE__ */ jsxs22(View21, { style: [stacked ? styles23.stacked : styles23.inline, variant === "overlay" ? { backgroundColor: alpha(theme.surface1, 0.92), borderColor: theme.borderDefault, borderRadius: radius3.lg, ...styles23.card } : null], children: [
|
|
2461
|
+
/* @__PURE__ */ jsx25(LoaderGlyph, { state: phase, value: known ? value : null, size: GLYPH[variant] }),
|
|
2462
|
+
/* @__PURE__ */ jsxs22(View21, { style: stacked ? styles23.center : styles23.text, children: [
|
|
2463
|
+
/* @__PURE__ */ jsx25(Txt, { variant: variant === "page" ? "title" : "label", style: stacked ? styles23.centered : null, children: words }),
|
|
2464
|
+
detail ? /* @__PURE__ */ jsx25(Txt, { variant: "caption", tone: "secondary", style: stacked ? styles23.centered : null, children: detail }) : null
|
|
2465
|
+
] })
|
|
2466
|
+
] });
|
|
2467
|
+
const a11y = { accessible: true, role: "progressbar", "aria-label": words, "aria-busy": phase === "loading", accessibilityLiveRegion: "polite" };
|
|
2468
|
+
if (variant === "overlay" || variant === "page")
|
|
2469
|
+
return /* @__PURE__ */ jsx25(View21, { ...a11y, style: [StyleSheet23.absoluteFill, styles23.cover, variant === "page" ? { backgroundColor: alpha(theme.surface0, 0.86) } : null, style], children: box });
|
|
2470
|
+
return /* @__PURE__ */ jsx25(View21, { ...a11y, style: [variant === "block" ? styles23.block : null, style], children: box });
|
|
2471
|
+
}
|
|
2472
|
+
var styles23 = StyleSheet23.create({
|
|
2473
|
+
inline: { flexDirection: "row", alignItems: "center", gap: 10 },
|
|
2474
|
+
stacked: { alignItems: "center", gap: 10 },
|
|
2475
|
+
card: { paddingHorizontal: 24, paddingVertical: 20, borderWidth: StyleSheet23.hairlineWidth },
|
|
2476
|
+
text: { flexShrink: 1, gap: 2 },
|
|
2477
|
+
center: { alignItems: "center", gap: 2 },
|
|
2478
|
+
centered: { textAlign: "center" },
|
|
2479
|
+
block: { paddingVertical: 40, alignItems: "center" },
|
|
2480
|
+
cover: { alignItems: "center", justifyContent: "center", zIndex: 10 }
|
|
2481
|
+
});
|
|
2482
|
+
|
|
1921
2483
|
// src/native/mascot-state.tsx
|
|
1922
|
-
import * as
|
|
1923
|
-
import { AccessibilityInfo as
|
|
2484
|
+
import * as React21 from "react";
|
|
2485
|
+
import { AccessibilityInfo as AccessibilityInfo8, Animated as Animated11, Easing as Easing5, StyleSheet as StyleSheet24, View as View23 } from "react-native";
|
|
1924
2486
|
|
|
1925
2487
|
// src/native/mascots.tsx
|
|
1926
|
-
import { useEffect as
|
|
1927
|
-
import { AccessibilityInfo as
|
|
1928
|
-
import
|
|
2488
|
+
import { useEffect as useEffect12, useState as useState20 } from "react";
|
|
2489
|
+
import { AccessibilityInfo as AccessibilityInfo7, Animated as Animated10, Easing as Easing4, View as View22 } from "react-native";
|
|
2490
|
+
import Svg9, { Circle as Circle4, Defs as Defs4, Ellipse, G, LinearGradient as LinearGradient4, Path as Path7, Rect as Rect2, Stop as Stop4 } from "react-native-svg";
|
|
1929
2491
|
|
|
1930
2492
|
// src/mascots/geometry.ts
|
|
1931
2493
|
var mirror = (d) => d.replace(/(-?\d+(?:\.\d+)?) (-?\d+(?:\.\d+)?)/g, (_, x, y) => `${120 - Number(x)} ${y}`);
|
|
@@ -2083,17 +2645,17 @@ var SHADE = "#000000";
|
|
|
2083
2645
|
var PARCEL = ["#f59e0b", "#d97706", "#b45309"];
|
|
2084
2646
|
|
|
2085
2647
|
// src/native/mascots.tsx
|
|
2086
|
-
import { jsx as
|
|
2648
|
+
import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2087
2649
|
function useBob(animated) {
|
|
2088
|
-
const [y] =
|
|
2089
|
-
|
|
2650
|
+
const [y] = useState20(() => new Animated10.Value(0));
|
|
2651
|
+
useEffect12(() => {
|
|
2090
2652
|
if (!animated) return;
|
|
2091
2653
|
let loop;
|
|
2092
2654
|
let cancelled = false;
|
|
2093
|
-
void
|
|
2655
|
+
void AccessibilityInfo7.isReduceMotionEnabled().then((reduce) => {
|
|
2094
2656
|
if (reduce || cancelled) return;
|
|
2095
|
-
const step = (toValue) =>
|
|
2096
|
-
loop =
|
|
2657
|
+
const step = (toValue) => Animated10.timing(y, { toValue, duration: 1800, easing: Easing4.inOut(Easing4.ease), useNativeDriver: true });
|
|
2658
|
+
loop = Animated10.loop(Animated10.sequence([step(-2.5), step(0)]));
|
|
2097
2659
|
loop.start();
|
|
2098
2660
|
});
|
|
2099
2661
|
return () => {
|
|
@@ -2103,13 +2665,13 @@ function useBob(animated) {
|
|
|
2103
2665
|
}, [animated, y]);
|
|
2104
2666
|
return y;
|
|
2105
2667
|
}
|
|
2106
|
-
function Mascot({ bird = "owl", mood = "welcome", tone:
|
|
2668
|
+
function Mascot({ bird = "owl", mood = "welcome", tone: tone3 = "brand", size = 96, animated = true, title, style }) {
|
|
2107
2669
|
const { theme } = useTheme();
|
|
2108
2670
|
const id = useSvgId("kzb");
|
|
2109
2671
|
const bob = useBob(animated);
|
|
2110
2672
|
const g = BIRDS[bird];
|
|
2111
2673
|
const brand = { from: theme.accent2, to: theme.accent, wing: theme.accent, detail: theme.accent2, beak: theme.warning, eye: theme.textPrimary };
|
|
2112
|
-
const p =
|
|
2674
|
+
const p = tone3 === "own" ? OWN_PALETTES[bird] : brand;
|
|
2113
2675
|
const outline = theme.borderStrong;
|
|
2114
2676
|
const body = `url(#${id})`;
|
|
2115
2677
|
const line = { stroke: outline, strokeWidth: 1.4, strokeLinejoin: "round" };
|
|
@@ -2117,62 +2679,62 @@ function Mascot({ bird = "owl", mood = "welcome", tone: tone2 = "brand", size =
|
|
|
2117
2679
|
const look3 = mood === "thinking" ? 1.4 : 0;
|
|
2118
2680
|
const rot = (deg, [x, y]) => `rotate(${deg} ${x} ${y})`;
|
|
2119
2681
|
const [wl, wr] = g.wings;
|
|
2120
|
-
return /* @__PURE__ */
|
|
2121
|
-
/* @__PURE__ */
|
|
2122
|
-
/* @__PURE__ */
|
|
2123
|
-
/* @__PURE__ */
|
|
2682
|
+
return /* @__PURE__ */ jsx26(View22, { style: [{ width: size, height: size }, style], ...markA11y(title), children: /* @__PURE__ */ jsx26(Animated10.View, { style: { transform: [{ translateY: bob }] }, children: /* @__PURE__ */ jsxs23(Svg9, { width: size, height: size, viewBox: "0 0 120 120", children: [
|
|
2683
|
+
/* @__PURE__ */ jsx26(Defs4, { children: /* @__PURE__ */ jsxs23(LinearGradient4, { id, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
2684
|
+
/* @__PURE__ */ jsx26(Stop4, { offset: "0%", stopColor: p.from }),
|
|
2685
|
+
/* @__PURE__ */ jsx26(Stop4, { offset: "100%", stopColor: p.to })
|
|
2124
2686
|
] }) }),
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
mood === "empty" && /* @__PURE__ */
|
|
2127
|
-
g.legs.map((d) => /* @__PURE__ */
|
|
2128
|
-
g.back?.map((d) => d.endsWith("Z") ? /* @__PURE__ */
|
|
2129
|
-
g.parcel?.map((d, i) => /* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
/* @__PURE__ */
|
|
2687
|
+
/* @__PURE__ */ jsx26(Ellipse, { cx: g.shadow[0], cy: g.shadow[1], rx: g.shadow[2], ry: g.shadow[3], fill: SHADE, opacity: 0.14 }),
|
|
2688
|
+
mood === "empty" && /* @__PURE__ */ jsx26(Path7, { d: MOOD_PARTS.tray, stroke: outline, strokeWidth: 1.6, strokeDasharray: "3 3", fill: "none" }),
|
|
2689
|
+
g.legs.map((d) => /* @__PURE__ */ jsx26(Path7, { d, stroke: p.beak, strokeWidth: 2.6, strokeLinecap: "round", fill: "none" }, d)),
|
|
2690
|
+
g.back?.map((d) => d.endsWith("Z") ? /* @__PURE__ */ jsx26(Path7, { d, fill: p.detail, ...line }, d) : /* @__PURE__ */ jsx26(Path7, { d, stroke: outline, strokeWidth: 1.4, fill: "none" }, d)),
|
|
2691
|
+
g.parcel?.map((d, i) => /* @__PURE__ */ jsx26(Path7, { d, fill: PARCEL[i], ...line }, d)),
|
|
2692
|
+
/* @__PURE__ */ jsx26(Path7, { d: g.body, fill: body, ...line }),
|
|
2693
|
+
/* @__PURE__ */ jsx26(Path7, { d: g.belly, fill: LIGHT, opacity: 0.28 }),
|
|
2132
2694
|
[wl, wr].map((w, i) => {
|
|
2133
2695
|
const turn = mood === "success" ? i === 0 ? 28 : -28 : mood === "welcome" && i === 1 ? -20 : 0;
|
|
2134
|
-
return /* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
/* @__PURE__ */
|
|
2696
|
+
return /* @__PURE__ */ jsxs23(G, { transform: turn ? rot(turn, w.pivot) : void 0, children: [
|
|
2697
|
+
/* @__PURE__ */ jsx26(Path7, { d: w.d, fill: p.wing, ...line }),
|
|
2698
|
+
/* @__PURE__ */ jsx26(Path7, { d: w.d, fill: SHADE, opacity: 0.16 })
|
|
2137
2699
|
] }, i);
|
|
2138
2700
|
}),
|
|
2139
|
-
g.neck && /* @__PURE__ */
|
|
2140
|
-
g.head.r > 0 && /* @__PURE__ */
|
|
2141
|
-
g.details.map((d) => /* @__PURE__ */
|
|
2142
|
-
g.visor && /* @__PURE__ */
|
|
2701
|
+
g.neck && /* @__PURE__ */ jsx26(Path7, { d: g.neck.d, stroke: body, strokeWidth: g.neck.width, strokeLinecap: "round", fill: "none" }),
|
|
2702
|
+
g.head.r > 0 && /* @__PURE__ */ jsx26(Circle4, { cx: g.head.cx, cy: g.head.cy, r: g.head.r, fill: body, ...line }),
|
|
2703
|
+
g.details.map((d) => /* @__PURE__ */ jsx26(Path7, { d, fill: p.detail, ...line }, d)),
|
|
2704
|
+
g.visor && /* @__PURE__ */ jsx26(Rect2, { x: g.visor.x, y: g.visor.y, width: g.visor.w, height: g.visor.h, rx: 4, fill: theme.surface0, ...line }),
|
|
2143
2705
|
g.eyes.at.map(
|
|
2144
|
-
(at, i) => mood === "empty" && g.eyes.white > 0 ? /* @__PURE__ */
|
|
2145
|
-
/* @__PURE__ */
|
|
2146
|
-
/* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2148
|
-
] }, i) : mood === "success" || mood === "empty" ? /* @__PURE__ */
|
|
2149
|
-
g.eyes.white > 0 && /* @__PURE__ */
|
|
2150
|
-
/* @__PURE__ */
|
|
2706
|
+
(at, i) => mood === "empty" && g.eyes.white > 0 ? /* @__PURE__ */ jsxs23(G, { children: [
|
|
2707
|
+
/* @__PURE__ */ jsx26(Circle4, { cx: at[0], cy: at[1], r: g.eyes.white, fill: LIGHT, ...line }),
|
|
2708
|
+
/* @__PURE__ */ jsx26(Circle4, { cx: at[0], cy: at[1] + g.eyes.pupil * 0.7, r: g.eyes.pupil, fill: SHADE }),
|
|
2709
|
+
/* @__PURE__ */ jsx26(Path7, { d: upperLid(at, g.eyes.white), fill: p.detail, ...line })
|
|
2710
|
+
] }, i) : mood === "success" || mood === "empty" ? /* @__PURE__ */ jsx26(Path7, { d: mood === "success" ? archEye(at, eyeR * 0.85) : lidEye(at, eyeR * 0.8), stroke: g.visor ? p.eye : outline, strokeWidth: 2.2, strokeLinecap: "round", fill: "none" }, i) : /* @__PURE__ */ jsxs23(G, { children: [
|
|
2711
|
+
g.eyes.white > 0 && /* @__PURE__ */ jsx26(Circle4, { cx: at[0], cy: at[1], r: g.eyes.white, fill: LIGHT, ...line }),
|
|
2712
|
+
/* @__PURE__ */ jsx26(Circle4, { cx: at[0] + look3, cy: at[1] - look3, r: g.eyes.pupil, fill: g.visor ? p.eye : SHADE })
|
|
2151
2713
|
] }, i)
|
|
2152
2714
|
),
|
|
2153
|
-
g.glasses && g.eyes.at.map(([x, y]) => /* @__PURE__ */
|
|
2154
|
-
mood === "error" && g.eyes.at.map((at, i) => /* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2156
|
-
mood === "thinking" && MOOD_PARTS.dots.map(([cx, cy, r], i) => /* @__PURE__ */
|
|
2157
|
-
(mood === "success" || mood === "error") && /* @__PURE__ */
|
|
2158
|
-
mood === "success" && /* @__PURE__ */
|
|
2159
|
-
mood === "error" && /* @__PURE__ */
|
|
2160
|
-
mood === "error" && /* @__PURE__ */
|
|
2715
|
+
g.glasses && g.eyes.at.map(([x, y]) => /* @__PURE__ */ jsx26(Circle4, { cx: x, cy: y, r: 6.5, fill: "none", stroke: outline, strokeWidth: 1.3 }, x)),
|
|
2716
|
+
mood === "error" && g.eyes.at.map((at, i) => /* @__PURE__ */ jsx26(Path7, { d: brow(at, eyeR, g.eyes.at.length === 1 ? 1 : i === 0 ? -1 : 1), stroke: outline, strokeWidth: 2, strokeLinecap: "round" }, i)),
|
|
2717
|
+
/* @__PURE__ */ jsx26(Path7, { d: g.beak, fill: p.beak, ...line }),
|
|
2718
|
+
mood === "thinking" && MOOD_PARTS.dots.map(([cx, cy, r], i) => /* @__PURE__ */ jsx26(Circle4, { cx, cy, r, fill: theme.textSecondary, opacity: 0.5 + i * 0.25 }, cx)),
|
|
2719
|
+
(mood === "success" || mood === "error") && /* @__PURE__ */ jsx26(Circle4, { cx: MOOD_PARTS.badge.cx, cy: MOOD_PARTS.badge.cy, r: MOOD_PARTS.badge.r, fill: mood === "success" ? theme.success : theme.danger }),
|
|
2720
|
+
mood === "success" && /* @__PURE__ */ jsx26(Path7, { d: MOOD_PARTS.check, stroke: theme.surface0, strokeWidth: 2.6, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }),
|
|
2721
|
+
mood === "error" && /* @__PURE__ */ jsx26(Path7, { d: MOOD_PARTS.bang.line, stroke: theme.surface0, strokeWidth: 2.8, strokeLinecap: "round" }),
|
|
2722
|
+
mood === "error" && /* @__PURE__ */ jsx26(Circle4, { cx: MOOD_PARTS.bang.dot[0], cy: MOOD_PARTS.bang.dot[1], r: 1.6, fill: theme.surface0 })
|
|
2161
2723
|
] }) }) });
|
|
2162
2724
|
}
|
|
2163
2725
|
|
|
2164
2726
|
// src/native/mascot-state.tsx
|
|
2165
|
-
import { jsx as
|
|
2727
|
+
import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2166
2728
|
var SIZE = { sm: 64, md: 96, lg: 128 };
|
|
2167
2729
|
function useArrival(animated) {
|
|
2168
|
-
const [value] =
|
|
2169
|
-
|
|
2730
|
+
const [value] = React21.useState(() => new Animated11.Value(animated ? 0 : 1));
|
|
2731
|
+
React21.useEffect(() => {
|
|
2170
2732
|
if (!animated) return;
|
|
2171
2733
|
let cancelled = false;
|
|
2172
|
-
void
|
|
2734
|
+
void AccessibilityInfo8.isReduceMotionEnabled().then((reduce) => {
|
|
2173
2735
|
if (cancelled) return;
|
|
2174
2736
|
if (reduce) value.setValue(1);
|
|
2175
|
-
else
|
|
2737
|
+
else Animated11.timing(value, { toValue: 1, duration: 420, easing: Easing5.out(Easing5.cubic), useNativeDriver: true }).start();
|
|
2176
2738
|
});
|
|
2177
2739
|
return () => {
|
|
2178
2740
|
cancelled = true;
|
|
@@ -2180,33 +2742,33 @@ function useArrival(animated) {
|
|
|
2180
2742
|
}, [animated, value]);
|
|
2181
2743
|
return value;
|
|
2182
2744
|
}
|
|
2183
|
-
function MascotState({ bird = "owl", mood = "empty", title, description, action, size = "md", layout = "stacked", tone:
|
|
2745
|
+
function MascotState({ bird = "owl", mood = "empty", title, description, action, size = "md", layout = "stacked", tone: tone3, animated = true, style, ...props }) {
|
|
2184
2746
|
const opacity = useArrival(animated);
|
|
2185
2747
|
const inline = layout === "inline";
|
|
2186
|
-
return /* @__PURE__ */
|
|
2187
|
-
|
|
2748
|
+
return /* @__PURE__ */ jsxs24(
|
|
2749
|
+
Animated11.View,
|
|
2188
2750
|
{
|
|
2189
2751
|
role: mood === "error" ? "alert" : "status",
|
|
2190
2752
|
accessibilityLiveRegion: mood === "error" ? "assertive" : "polite",
|
|
2191
2753
|
"aria-busy": mood === "thinking" ? true : void 0,
|
|
2192
2754
|
...props,
|
|
2193
|
-
style: [inline ?
|
|
2755
|
+
style: [inline ? styles24.inline : styles24.stacked, { opacity, transform: [{ translateY: opacity.interpolate({ inputRange: [0, 1], outputRange: [6, 0] }) }] }, style],
|
|
2194
2756
|
children: [
|
|
2195
|
-
/* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2198
|
-
description ? /* @__PURE__ */
|
|
2199
|
-
action ? /* @__PURE__ */
|
|
2757
|
+
/* @__PURE__ */ jsx27(Mascot, { bird, mood, tone: tone3, size: SIZE[size], animated }),
|
|
2758
|
+
/* @__PURE__ */ jsxs24(View23, { style: inline ? styles24.wordsInline : styles24.words, children: [
|
|
2759
|
+
/* @__PURE__ */ jsx27(Txt, { variant: "label", role: "heading", style: inline ? null : styles24.center, children: title }),
|
|
2760
|
+
description ? /* @__PURE__ */ jsx27(Txt, { tone: "secondary", style: inline ? null : styles24.center, children: description }) : null,
|
|
2761
|
+
action ? /* @__PURE__ */ jsx27(View23, { style: [styles24.action, inline ? null : styles24.actionCentred], children: action }) : null
|
|
2200
2762
|
] })
|
|
2201
2763
|
]
|
|
2202
2764
|
}
|
|
2203
2765
|
);
|
|
2204
2766
|
}
|
|
2205
|
-
var ErrorState = (props) => /* @__PURE__ */
|
|
2206
|
-
var SuccessState = (props) => /* @__PURE__ */
|
|
2207
|
-
var LoadingState = (props) => /* @__PURE__ */
|
|
2208
|
-
var WelcomeState = (props) => /* @__PURE__ */
|
|
2209
|
-
var
|
|
2767
|
+
var ErrorState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "error", ...props });
|
|
2768
|
+
var SuccessState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "success", ...props });
|
|
2769
|
+
var LoadingState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "thinking", ...props });
|
|
2770
|
+
var WelcomeState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "welcome", ...props });
|
|
2771
|
+
var styles24 = StyleSheet24.create({
|
|
2210
2772
|
stacked: { alignItems: "center", justifyContent: "center", gap: 12, paddingVertical: 40, paddingHorizontal: 24 },
|
|
2211
2773
|
inline: { flexDirection: "row", alignItems: "center", gap: 16 },
|
|
2212
2774
|
words: { alignItems: "center", gap: 6 },
|
|
@@ -2216,9 +2778,150 @@ var styles17 = StyleSheet17.create({
|
|
|
2216
2778
|
actionCentred: { justifyContent: "center" }
|
|
2217
2779
|
});
|
|
2218
2780
|
|
|
2781
|
+
// src/native/meter.tsx
|
|
2782
|
+
import { StyleSheet as StyleSheet25, View as View24 } from "react-native";
|
|
2783
|
+
import Svg10, { Circle as Circle5 } from "react-native-svg";
|
|
2784
|
+
import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2785
|
+
var THICK = { sm: 6, md: 8, lg: 12 };
|
|
2786
|
+
var RING = { sm: 56, md: 96, lg: 144 };
|
|
2787
|
+
var partColor = (t, i) => [t.accent, t.warning, t.success, t.textSecondary, t.danger][i % 5];
|
|
2788
|
+
function Meter({ label, value = 0, min = 0, max = 100, valueText, thresholds, optimum = "low", parts, variant = "bar", size = "md", showLabel, children, style }) {
|
|
2789
|
+
const { theme } = useTheme();
|
|
2790
|
+
const span = max - min || 1;
|
|
2791
|
+
const ratio = Math.min(1, Math.max(0, (value - min) / span));
|
|
2792
|
+
const level = !thresholds ? "ok" : ratio >= thresholds.high ? optimum === "low" ? "danger" : "success" : ratio >= thresholds.low ? "warning" : optimum === "low" ? "success" : "danger";
|
|
2793
|
+
const tone3 = { ok: theme.accent, success: theme.success, warning: theme.warning, danger: theme.danger }[level];
|
|
2794
|
+
const words = valueText ?? `${Math.round(ratio * 100)} %`;
|
|
2795
|
+
const shares = (parts ?? []).map((p, i) => ({ ...p, color: partColor(theme, i), ratio: Math.min(1, Math.max(0, p.value / span)), words: p.valueText ?? `${Math.round(p.value / span * 100)} %` }));
|
|
2796
|
+
const a11y = parts ? { role: "group", "aria-label": `${label}: ${shares.map((p) => `${p.label} ${p.words}`).join(", ")}` } : { role: "meter", "aria-label": label, "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": Math.min(max, Math.max(min, value)), "aria-valuetext": words };
|
|
2797
|
+
const legend = parts ? /* @__PURE__ */ jsx28(View24, { style: styles25.legend, "aria-hidden": true, children: shares.map((p, i) => /* @__PURE__ */ jsxs25(View24, { style: styles25.legendItem, children: [
|
|
2798
|
+
/* @__PURE__ */ jsx28(View24, { style: [styles25.swatch, { backgroundColor: p.color }] }),
|
|
2799
|
+
/* @__PURE__ */ jsx28(Txt, { variant: "caption", children: p.label }),
|
|
2800
|
+
/* @__PURE__ */ jsx28(Txt, { variant: "caption", tone: "secondary", children: p.words })
|
|
2801
|
+
] }, i)) }) : null;
|
|
2802
|
+
if (variant === "ring") {
|
|
2803
|
+
const side = RING[size];
|
|
2804
|
+
const r = 44;
|
|
2805
|
+
const c = 2 * Math.PI * r;
|
|
2806
|
+
let offset = 0;
|
|
2807
|
+
const arcs = parts ? shares.map((p) => {
|
|
2808
|
+
const arc = { color: p.color, len: p.ratio, start: offset };
|
|
2809
|
+
offset += p.ratio;
|
|
2810
|
+
return arc;
|
|
2811
|
+
}) : [{ color: tone3, len: ratio, start: 0 }];
|
|
2812
|
+
return /* @__PURE__ */ jsxs25(View24, { accessible: true, ...a11y, style: [styles25.ringRoot, style], children: [
|
|
2813
|
+
/* @__PURE__ */ jsxs25(View24, { style: { width: side, height: side }, children: [
|
|
2814
|
+
/* @__PURE__ */ jsxs25(Svg10, { width: side, height: side, viewBox: "0 0 100 100", style: { transform: [{ rotate: "-90deg" }] }, children: [
|
|
2815
|
+
/* @__PURE__ */ jsx28(Circle5, { cx: 50, cy: 50, r, fill: "none", stroke: theme.borderDefault, strokeWidth: 9 }),
|
|
2816
|
+
arcs.map((a, i) => /* @__PURE__ */ jsx28(Circle5, { cx: 50, cy: 50, r, fill: "none", stroke: a.color, strokeWidth: 9, strokeDasharray: `${Math.max(0, a.len * c - (parts ? 2 : 0))} ${c}`, strokeDashoffset: -a.start * c, strokeLinecap: parts ? "butt" : "round" }, i))
|
|
2817
|
+
] }),
|
|
2818
|
+
children !== void 0 ? /* @__PURE__ */ jsx28(View24, { style: [StyleSheet25.absoluteFill, styles25.center], children }) : null
|
|
2819
|
+
] }),
|
|
2820
|
+
legend
|
|
2821
|
+
] });
|
|
2822
|
+
}
|
|
2823
|
+
return /* @__PURE__ */ jsxs25(View24, { accessible: true, ...a11y, style: [styles25.root, style], children: [
|
|
2824
|
+
showLabel ? /* @__PURE__ */ jsxs25(View24, { style: styles25.header, "aria-hidden": true, children: [
|
|
2825
|
+
/* @__PURE__ */ jsx28(Txt, { variant: "caption", numberOfLines: 1, style: styles25.caption, children: label }),
|
|
2826
|
+
!parts ? /* @__PURE__ */ jsx28(Txt, { variant: "caption", tone: "secondary", children: words }) : null
|
|
2827
|
+
] }) : null,
|
|
2828
|
+
/* @__PURE__ */ jsx28(View24, { style: [styles25.track, { height: THICK[size], backgroundColor: theme.surface3 }], children: parts ? shares.map((p, i) => /* @__PURE__ */ jsx28(View24, { style: { width: `${p.ratio * 100}%`, backgroundColor: p.color } }, i)) : /* @__PURE__ */ jsx28(View24, { style: [styles25.fill, { width: `${ratio * 100}%`, backgroundColor: tone3 }] }) }),
|
|
2829
|
+
legend
|
|
2830
|
+
] });
|
|
2831
|
+
}
|
|
2832
|
+
var styles25 = StyleSheet25.create({
|
|
2833
|
+
root: { width: "100%", gap: 6 },
|
|
2834
|
+
header: { flexDirection: "row", alignItems: "baseline", gap: 8 },
|
|
2835
|
+
caption: { flex: 1, fontWeight: "600" },
|
|
2836
|
+
track: { flexDirection: "row", gap: 2, borderRadius: 999, overflow: "hidden", width: "100%" },
|
|
2837
|
+
fill: { height: "100%", borderRadius: 999 },
|
|
2838
|
+
legend: { flexDirection: "row", flexWrap: "wrap", columnGap: 14, rowGap: 4, marginTop: 4 },
|
|
2839
|
+
legendItem: { flexDirection: "row", alignItems: "center", gap: 6 },
|
|
2840
|
+
swatch: { width: 8, height: 8, borderRadius: 4 },
|
|
2841
|
+
ringRoot: { alignItems: "center", gap: 8 },
|
|
2842
|
+
center: { alignItems: "center", justifyContent: "center" }
|
|
2843
|
+
});
|
|
2844
|
+
|
|
2845
|
+
// src/native/number-ticker.tsx
|
|
2846
|
+
import * as React22 from "react";
|
|
2847
|
+
import { AccessibilityInfo as AccessibilityInfo9, Animated as Animated12, Easing as Easing6, Text as Text13 } from "react-native";
|
|
2848
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
2849
|
+
function NumberTicker({ value, locale, format, trigger = "mount", duration = 1100, announce, variant = "display", tone: tone3 = "text", style }) {
|
|
2850
|
+
const reduce = useReducedMotion();
|
|
2851
|
+
const writer = React22.useMemo(() => new Intl.NumberFormat(locale, format), [locale, format]);
|
|
2852
|
+
const [shown, setShown] = React22.useState(() => reduce ? value : trigger === "mount" ? 0 : value);
|
|
2853
|
+
const [anim] = React22.useState(() => new Animated12.Value(trigger === "mount" ? 0 : value));
|
|
2854
|
+
const first = React22.useRef(true);
|
|
2855
|
+
React22.useEffect(() => {
|
|
2856
|
+
const isFirst = first.current;
|
|
2857
|
+
first.current = false;
|
|
2858
|
+
if (reduce || !isFirst && trigger === "mount" || isFirst && trigger === "change") {
|
|
2859
|
+
anim.setValue(value);
|
|
2860
|
+
setShown(value);
|
|
2861
|
+
if (!isFirst && announce) AccessibilityInfo9.announceForAccessibility(writer.format(value));
|
|
2862
|
+
return;
|
|
2863
|
+
}
|
|
2864
|
+
const id = anim.addListener(({ value: v }) => setShown(v));
|
|
2865
|
+
const run = Animated12.timing(anim, { toValue: value, duration, easing: Easing6.out(Easing6.cubic), useNativeDriver: false });
|
|
2866
|
+
run.start(({ finished }) => {
|
|
2867
|
+
if (finished) setShown(value);
|
|
2868
|
+
});
|
|
2869
|
+
if (!isFirst && announce) AccessibilityInfo9.announceForAccessibility(writer.format(value));
|
|
2870
|
+
return () => {
|
|
2871
|
+
run.stop();
|
|
2872
|
+
anim.removeListener(id);
|
|
2873
|
+
};
|
|
2874
|
+
}, [value, reduce, trigger, duration, announce, anim, writer]);
|
|
2875
|
+
const digits = Number.isInteger(value) ? Math.round(shown) : shown;
|
|
2876
|
+
return /* @__PURE__ */ jsx29(Txt, { variant, tone: tone3, "aria-label": writer.format(value), style: [{ fontVariant: ["tabular-nums"] }, style], children: /* @__PURE__ */ jsx29(Text13, { "aria-hidden": true, children: writer.format(digits) }) });
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
// src/native/onboarding.tsx
|
|
2880
|
+
import * as React23 from "react";
|
|
2881
|
+
import { ScrollView as ScrollView5, StyleSheet as StyleSheet26, View as View25 } from "react-native";
|
|
2882
|
+
import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2883
|
+
function Onboarding({ slides, labels, onDone, style }) {
|
|
2884
|
+
const { theme, insets, haptic } = useTheme();
|
|
2885
|
+
const [width, setWidth] = React23.useState(0);
|
|
2886
|
+
const [page, setPage] = React23.useState(0);
|
|
2887
|
+
const scroller = React23.useRef(null);
|
|
2888
|
+
const last = page === slides.length - 1;
|
|
2889
|
+
const go = (to) => {
|
|
2890
|
+
scroller.current?.scrollTo({ x: to * width, animated: true });
|
|
2891
|
+
setPage(to);
|
|
2892
|
+
haptic("selection");
|
|
2893
|
+
};
|
|
2894
|
+
const onScroll = (e) => {
|
|
2895
|
+
if (width > 0) setPage(Math.round(e.nativeEvent.contentOffset.x / width));
|
|
2896
|
+
};
|
|
2897
|
+
return /* @__PURE__ */ jsxs26(View25, { style: [styles26.root, { backgroundColor: theme.surface0, paddingTop: insets.top + 8, paddingBottom: insets.bottom + 16 }, style], onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
|
|
2898
|
+
/* @__PURE__ */ jsx30(View25, { style: styles26.top, children: !last ? /* @__PURE__ */ jsx30(Button, { label: labels.skip, variant: "ghost", size: "sm", onPress: onDone }) : /* @__PURE__ */ jsx30(View25, { style: styles26.spacer }) }),
|
|
2899
|
+
/* @__PURE__ */ jsx30(ScrollView5, { ref: scroller, tabIndex: 0, horizontal: true, pagingEnabled: true, showsHorizontalScrollIndicator: false, onMomentumScrollEnd: onScroll, style: styles26.flex, children: slides.map((slide, i) => /* @__PURE__ */ jsxs26(View25, { style: [styles26.slide, { width: width || void 0 }], accessible: true, "aria-label": `${labels.position(i + 1, slides.length)}. ${slide.title}. ${slide.description}`, "aria-hidden": i !== page, children: [
|
|
2900
|
+
slide.visual ? /* @__PURE__ */ jsx30(View25, { style: styles26.visual, children: slide.visual }) : null,
|
|
2901
|
+
/* @__PURE__ */ jsx30(Txt, { variant: "display", style: styles26.centred, children: slide.title }),
|
|
2902
|
+
/* @__PURE__ */ jsx30(Txt, { tone: "secondary", style: [styles26.centred, styles26.description], children: slide.description })
|
|
2903
|
+
] }, i)) }),
|
|
2904
|
+
/* @__PURE__ */ jsx30(View25, { style: styles26.dots, "aria-hidden": true, children: slides.map((_, i) => /* @__PURE__ */ jsx30(View25, { style: [styles26.dot, { width: i === page ? 22 : 8, backgroundColor: i === page ? theme.accent : theme.borderStrong }] }, i)) }),
|
|
2905
|
+
/* @__PURE__ */ jsx30(View25, { style: styles26.bottom, children: /* @__PURE__ */ jsx30(Button, { label: last ? labels.done : labels.next, variant: last ? "gradient" : "primary", size: "lg", onPress: () => last ? onDone() : go(page + 1) }) })
|
|
2906
|
+
] });
|
|
2907
|
+
}
|
|
2908
|
+
var styles26 = StyleSheet26.create({
|
|
2909
|
+
root: { flex: 1 },
|
|
2910
|
+
top: { flexDirection: "row", justifyContent: "flex-end", paddingHorizontal: 16, minHeight: 32 },
|
|
2911
|
+
spacer: { height: 32 },
|
|
2912
|
+
flex: { flex: 1 },
|
|
2913
|
+
slide: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 32, gap: 12 },
|
|
2914
|
+
visual: { marginBottom: 12 },
|
|
2915
|
+
centred: { textAlign: "center" },
|
|
2916
|
+
description: { maxWidth: 340 },
|
|
2917
|
+
dots: { flexDirection: "row", justifyContent: "center", gap: 6, marginVertical: 16 },
|
|
2918
|
+
dot: { height: 8, borderRadius: 4 },
|
|
2919
|
+
bottom: { paddingHorizontal: 24 }
|
|
2920
|
+
});
|
|
2921
|
+
|
|
2219
2922
|
// src/native/OrazakaMark.tsx
|
|
2220
|
-
import { View as
|
|
2221
|
-
import
|
|
2923
|
+
import { View as View26 } from "react-native";
|
|
2924
|
+
import Svg11, { Circle as Circle6, Defs as Defs5, LinearGradient as LinearGradient5, Path as Path8, RadialGradient as RadialGradient2, Stop as Stop5 } from "react-native-svg";
|
|
2222
2925
|
|
|
2223
2926
|
// src/marks/orazaka-geometry.ts
|
|
2224
2927
|
var orange = marks.orazaka[marks.orazaka.length - 1][1];
|
|
@@ -2247,41 +2950,41 @@ var ORAZAKA = {
|
|
|
2247
2950
|
};
|
|
2248
2951
|
|
|
2249
2952
|
// src/native/OrazakaMark.tsx
|
|
2250
|
-
import { jsx as
|
|
2953
|
+
import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2251
2954
|
function OrazakaMark({ size = 48, animated = true, title, neutral }) {
|
|
2252
2955
|
const { theme } = useTheme();
|
|
2253
|
-
const { Animated:
|
|
2956
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
|
|
2254
2957
|
const id = useSvgId("ozm");
|
|
2255
2958
|
const viewBox = size < 48 ? ORAZAKA.croppedViewBox : ORAZAKA.viewBox;
|
|
2256
2959
|
const stroke = neutral ?? theme.textMuted;
|
|
2257
|
-
const gradient = /* @__PURE__ */
|
|
2960
|
+
const gradient = /* @__PURE__ */ jsx31(LinearGradient5, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: ORAZAKA.gradient.x1, y1: ORAZAKA.gradient.y1, x2: ORAZAKA.gradient.x2, y2: ORAZAKA.gradient.y2, children: ORAZAKA.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx31(Stop5, { offset, stopColor: color }, offset)) });
|
|
2258
2961
|
const fill = `url(#${id}a)`;
|
|
2259
|
-
return /* @__PURE__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2261
|
-
/* @__PURE__ */
|
|
2262
|
-
/* @__PURE__ */
|
|
2263
|
-
/* @__PURE__ */
|
|
2962
|
+
return /* @__PURE__ */ jsxs27(View26, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
2963
|
+
/* @__PURE__ */ jsxs27(Svg11, { viewBox, style: layer, children: [
|
|
2964
|
+
/* @__PURE__ */ jsx31(Defs5, { children: /* @__PURE__ */ jsxs27(RadialGradient2, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
2965
|
+
/* @__PURE__ */ jsx31(Stop5, { offset: "0%", stopColor: ORAZAKA.glow.color, stopOpacity: ORAZAKA.glow.opacity }),
|
|
2966
|
+
/* @__PURE__ */ jsx31(Stop5, { offset: "100%", stopColor: ORAZAKA.glow.color, stopOpacity: 0 })
|
|
2264
2967
|
] }) }),
|
|
2265
|
-
size >= 48 ? /* @__PURE__ */
|
|
2266
|
-
/* @__PURE__ */
|
|
2267
|
-
/* @__PURE__ */
|
|
2968
|
+
size >= 48 ? /* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: 190, fill: `url(#${id}g)` }) : null,
|
|
2969
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.orbit.r, stroke, strokeWidth: ORAZAKA.orbit.width, strokeDasharray: ORAZAKA.orbit.dash, opacity: 0.6, fill: "none" }),
|
|
2970
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.ring.r, stroke, strokeWidth: ORAZAKA.ring.width, opacity: 0.35, fill: "none" })
|
|
2268
2971
|
] }),
|
|
2269
|
-
/* @__PURE__ */
|
|
2270
|
-
/* @__PURE__ */
|
|
2271
|
-
ORAZAKA.shards.map((d) => /* @__PURE__ */
|
|
2972
|
+
/* @__PURE__ */ jsx31(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs27(Svg11, { viewBox, style: layer, children: [
|
|
2973
|
+
/* @__PURE__ */ jsx31(Defs5, { children: gradient }),
|
|
2974
|
+
ORAZAKA.shards.map((d) => /* @__PURE__ */ jsx31(Path8, { d, fill, stroke: fill, strokeWidth: ORAZAKA.shardStroke, strokeLinejoin: "round" }, d))
|
|
2272
2975
|
] }) }),
|
|
2273
|
-
/* @__PURE__ */
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
/* @__PURE__ */
|
|
2976
|
+
/* @__PURE__ */ jsx31(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs27(Svg11, { viewBox, style: layer, children: [
|
|
2977
|
+
/* @__PURE__ */ jsx31(Defs5, { children: gradient }),
|
|
2978
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.core.r, fill }),
|
|
2979
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.core.inner, fill: ORAZAKA.highlight })
|
|
2277
2980
|
] }) })
|
|
2278
2981
|
] });
|
|
2279
2982
|
}
|
|
2280
2983
|
|
|
2281
2984
|
// src/native/OrochiaMark.tsx
|
|
2282
|
-
import { useEffect as
|
|
2283
|
-
import { AccessibilityInfo as
|
|
2284
|
-
import
|
|
2985
|
+
import { useEffect as useEffect15, useState as useState24 } from "react";
|
|
2986
|
+
import { AccessibilityInfo as AccessibilityInfo10, Animated as Animated13, Easing as Easing7, View as View27 } from "react-native";
|
|
2987
|
+
import Svg12, { Circle as Circle7, Defs as Defs6, Ellipse as Ellipse2, G as Group2, LinearGradient as LinearGradient6, Path as Path9, RadialGradient as RadialGradient3, Stop as Stop6 } from "react-native-svg";
|
|
2285
2988
|
|
|
2286
2989
|
// src/marks/orochia-geometry.ts
|
|
2287
2990
|
var OROCHIA = {
|
|
@@ -2308,25 +3011,25 @@ var OROCHIA = {
|
|
|
2308
3011
|
};
|
|
2309
3012
|
|
|
2310
3013
|
// src/native/OrochiaMark.tsx
|
|
2311
|
-
import { jsx as
|
|
3014
|
+
import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2312
3015
|
var CENTER = OROCHIA.offset + 180;
|
|
2313
3016
|
function OrochiaMark({ size = 48, animated = true, title, neutral: neutralProp }) {
|
|
2314
3017
|
const { theme } = useTheme();
|
|
2315
3018
|
const neutral = neutralProp ?? theme.textMuted;
|
|
2316
|
-
const [spin] =
|
|
2317
|
-
const [pulse] =
|
|
2318
|
-
|
|
3019
|
+
const [spin] = useState24(() => new Animated13.Value(0));
|
|
3020
|
+
const [pulse] = useState24(() => new Animated13.Value(0));
|
|
3021
|
+
useEffect15(() => {
|
|
2319
3022
|
if (!animated) return;
|
|
2320
3023
|
let loops = [];
|
|
2321
3024
|
let cancelled = false;
|
|
2322
|
-
void
|
|
3025
|
+
void AccessibilityInfo10.isReduceMotionEnabled().then((reduce) => {
|
|
2323
3026
|
if (reduce || cancelled) return;
|
|
2324
3027
|
loops = [
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
3028
|
+
Animated13.loop(Animated13.timing(spin, { toValue: 1, duration: 3e4, easing: Easing7.linear, useNativeDriver: true })),
|
|
3029
|
+
Animated13.loop(
|
|
3030
|
+
Animated13.sequence([
|
|
3031
|
+
Animated13.timing(pulse, { toValue: 1, duration: 1600, easing: Easing7.inOut(Easing7.ease), useNativeDriver: true }),
|
|
3032
|
+
Animated13.timing(pulse, { toValue: 0, duration: 1600, easing: Easing7.inOut(Easing7.ease), useNativeDriver: true })
|
|
2330
3033
|
])
|
|
2331
3034
|
)
|
|
2332
3035
|
];
|
|
@@ -2340,44 +3043,117 @@ function OrochiaMark({ size = 48, animated = true, title, neutral: neutralProp }
|
|
|
2340
3043
|
const viewBox = size < 48 ? OROCHIA.croppedViewBox : OROCHIA.viewBox;
|
|
2341
3044
|
const layer = { position: "absolute", width: size, height: size };
|
|
2342
3045
|
const a11y = title ? { accessible: true, accessibilityRole: "image", accessibilityLabel: title } : { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" };
|
|
2343
|
-
const bodyGradient = /* @__PURE__ */
|
|
2344
|
-
return /* @__PURE__ */
|
|
2345
|
-
/* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2347
|
-
/* @__PURE__ */
|
|
2348
|
-
/* @__PURE__ */
|
|
3046
|
+
const bodyGradient = /* @__PURE__ */ jsx32(LinearGradient6, { id: "body", gradientUnits: "userSpaceOnUse", x1: OROCHIA.body.x1 + OROCHIA.offset, y1: OROCHIA.body.y1 + OROCHIA.offset, x2: OROCHIA.body.x2 + OROCHIA.offset, y2: OROCHIA.body.y2 + OROCHIA.offset, children: OROCHIA.body.stops.map(([offset, color]) => /* @__PURE__ */ jsx32(Stop6, { offset, stopColor: color }, offset)) });
|
|
3047
|
+
return /* @__PURE__ */ jsxs28(View27, { style: { width: size, height: size }, ...a11y, children: [
|
|
3048
|
+
/* @__PURE__ */ jsxs28(Svg12, { viewBox, style: layer, children: [
|
|
3049
|
+
/* @__PURE__ */ jsx32(Defs6, { children: /* @__PURE__ */ jsxs28(RadialGradient3, { id: "glow", cx: "50%", cy: "50%", r: "50%", children: [
|
|
3050
|
+
/* @__PURE__ */ jsx32(Stop6, { offset: "0%", stopColor: OROCHIA.glow.color, stopOpacity: OROCHIA.glow.opacity }),
|
|
3051
|
+
/* @__PURE__ */ jsx32(Stop6, { offset: "100%", stopColor: OROCHIA.glow.color, stopOpacity: 0 })
|
|
2349
3052
|
] }) }),
|
|
2350
|
-
/* @__PURE__ */
|
|
2351
|
-
/* @__PURE__ */
|
|
3053
|
+
/* @__PURE__ */ jsx32(Circle7, { cx: CENTER, cy: CENTER, r: 170, fill: "url(#glow)" }),
|
|
3054
|
+
/* @__PURE__ */ jsx32(Circle7, { cx: CENTER, cy: CENTER, r: OROCHIA.ring.r, stroke: neutral, strokeWidth: OROCHIA.ring.width, opacity: 0.35, fill: "none" })
|
|
2352
3055
|
] }),
|
|
2353
|
-
/* @__PURE__ */
|
|
2354
|
-
/* @__PURE__ */
|
|
2355
|
-
/* @__PURE__ */
|
|
2356
|
-
/* @__PURE__ */
|
|
2357
|
-
/* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2361
|
-
/* @__PURE__ */
|
|
2362
|
-
/* @__PURE__ */
|
|
3056
|
+
/* @__PURE__ */ jsx32(Animated13.View, { style: [layer, { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] }], children: /* @__PURE__ */ jsx32(Svg12, { viewBox, style: layer, children: /* @__PURE__ */ jsx32(Circle7, { cx: CENTER, cy: CENTER, r: OROCHIA.orbit.r, stroke: neutral, strokeWidth: OROCHIA.orbit.width, strokeDasharray: OROCHIA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
|
|
3057
|
+
/* @__PURE__ */ jsxs28(Svg12, { viewBox, style: layer, children: [
|
|
3058
|
+
/* @__PURE__ */ jsx32(Defs6, { children: bodyGradient }),
|
|
3059
|
+
/* @__PURE__ */ jsxs28(Group2, { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
|
|
3060
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.arc, stroke: "url(#body)", strokeWidth: 22, strokeLinecap: "round", fill: "none" }),
|
|
3061
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.arc, stroke: OROCHIA.scales.color, strokeOpacity: OROCHIA.scales.opacity, strokeWidth: OROCHIA.scales.width, strokeLinecap: "round", strokeDasharray: OROCHIA.scales.dash, fill: "none" }),
|
|
3062
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.neck, stroke: "url(#body)", strokeWidth: 14, strokeLinecap: "round", fill: "none" }),
|
|
3063
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.tail, stroke: "url(#body)", strokeWidth: 6, strokeLinecap: "round", fill: "none" }),
|
|
3064
|
+
/* @__PURE__ */ jsx32(Ellipse2, { cx: OROCHIA.head.cx, cy: OROCHIA.head.cy, rx: OROCHIA.head.rx, ry: OROCHIA.head.ry, rotation: OROCHIA.head.rotate, origin: `${OROCHIA.head.cx}, ${OROCHIA.head.cy}`, fill: "url(#body)" }),
|
|
3065
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.tongue.d, stroke: OROCHIA.tongue.color, strokeWidth: 3, strokeLinecap: "round", fill: "none" })
|
|
2363
3066
|
] })
|
|
2364
3067
|
] }),
|
|
2365
|
-
/* @__PURE__ */
|
|
2366
|
-
/* @__PURE__ */
|
|
2367
|
-
/* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2369
|
-
/* @__PURE__ */
|
|
3068
|
+
/* @__PURE__ */ jsx32(Animated13.View, { style: [layer, { opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.85, 1] }) }], children: /* @__PURE__ */ jsxs28(Svg12, { viewBox, style: layer, children: [
|
|
3069
|
+
/* @__PURE__ */ jsx32(Defs6, { children: /* @__PURE__ */ jsx32(LinearGradient6, { id: "flame", x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: OROCHIA.flameGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx32(Stop6, { offset, stopColor: color }, offset)) }) }),
|
|
3070
|
+
/* @__PURE__ */ jsxs28(Group2, { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
|
|
3071
|
+
/* @__PURE__ */ jsx32(Circle7, { cx: OROCHIA.eye.cx, cy: OROCHIA.eye.cy, r: OROCHIA.eye.r, fill: OROCHIA.eye.color }),
|
|
3072
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.flame.d, transform: `translate(${OROCHIA.flame.translate[0]} ${OROCHIA.flame.translate[1]}) scale(${OROCHIA.flame.scale})`, fill: "url(#flame)" })
|
|
2370
3073
|
] })
|
|
2371
3074
|
] }) })
|
|
2372
3075
|
] });
|
|
2373
3076
|
}
|
|
2374
3077
|
|
|
3078
|
+
// src/native/otp-input.tsx
|
|
3079
|
+
import * as React25 from "react";
|
|
3080
|
+
import { Platform as Platform2, Pressable as Pressable13, StyleSheet as StyleSheet27, TextInput as TextInput4, View as View28 } from "react-native";
|
|
3081
|
+
import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
3082
|
+
function OtpInput({ label, length = 6, value, onValueChange, onComplete, mode = "numeric", invalid, disabled, autoFocus, style }) {
|
|
3083
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
3084
|
+
const [own, setOwn] = React25.useState("");
|
|
3085
|
+
const code = value ?? own;
|
|
3086
|
+
const [focused, setFocused] = React25.useState(false);
|
|
3087
|
+
const input = React25.useRef(null);
|
|
3088
|
+
React25.useEffect(() => {
|
|
3089
|
+
if (invalid) haptic("warning");
|
|
3090
|
+
}, [invalid, haptic]);
|
|
3091
|
+
const change = (raw) => {
|
|
3092
|
+
const next = (mode === "numeric" ? raw.replace(/\D/g, "") : raw.replace(/\s/g, "").toUpperCase()).slice(0, length);
|
|
3093
|
+
if (value === void 0) setOwn(next);
|
|
3094
|
+
onValueChange?.(next);
|
|
3095
|
+
if (next.length === length && code.length !== length) {
|
|
3096
|
+
haptic("success");
|
|
3097
|
+
onComplete?.(next);
|
|
3098
|
+
}
|
|
3099
|
+
};
|
|
3100
|
+
return /* @__PURE__ */ jsxs29(Pressable13, { onPress: () => input.current?.focus(), disabled, accessible: false, style: [styles27.root, style], children: [
|
|
3101
|
+
/* @__PURE__ */ jsx33(View28, { style: styles27.boxes, "aria-hidden": true, children: Array.from({ length }, (_, i) => {
|
|
3102
|
+
const active = focused && i === Math.min(code.length, length - 1);
|
|
3103
|
+
return /* @__PURE__ */ jsx33(
|
|
3104
|
+
View28,
|
|
3105
|
+
{
|
|
3106
|
+
style: [
|
|
3107
|
+
styles27.box,
|
|
3108
|
+
{
|
|
3109
|
+
borderRadius: radius3.md,
|
|
3110
|
+
backgroundColor: theme.surface2,
|
|
3111
|
+
borderColor: invalid ? theme.danger : active ? theme.ring : theme.borderDefault,
|
|
3112
|
+
borderWidth: invalid || active ? 2 : 1
|
|
3113
|
+
}
|
|
3114
|
+
],
|
|
3115
|
+
children: /* @__PURE__ */ jsx33(Txt, { variant: "title", children: code[i] ?? "" })
|
|
3116
|
+
},
|
|
3117
|
+
i
|
|
3118
|
+
);
|
|
3119
|
+
}) }),
|
|
3120
|
+
/* @__PURE__ */ jsx33(
|
|
3121
|
+
TextInput4,
|
|
3122
|
+
{
|
|
3123
|
+
ref: input,
|
|
3124
|
+
"aria-label": label,
|
|
3125
|
+
"aria-invalid": invalid || void 0,
|
|
3126
|
+
value: code,
|
|
3127
|
+
onChangeText: change,
|
|
3128
|
+
maxLength: length,
|
|
3129
|
+
editable: !disabled,
|
|
3130
|
+
autoFocus,
|
|
3131
|
+
keyboardType: mode === "numeric" ? "number-pad" : "default",
|
|
3132
|
+
textContentType: "oneTimeCode",
|
|
3133
|
+
autoComplete: Platform2.OS === "android" && mode === "numeric" ? "sms-otp" : "one-time-code",
|
|
3134
|
+
autoCapitalize: "characters",
|
|
3135
|
+
autoCorrect: false,
|
|
3136
|
+
caretHidden: true,
|
|
3137
|
+
onFocus: () => setFocused(true),
|
|
3138
|
+
onBlur: () => setFocused(false),
|
|
3139
|
+
style: styles27.hidden
|
|
3140
|
+
}
|
|
3141
|
+
)
|
|
3142
|
+
] });
|
|
3143
|
+
}
|
|
3144
|
+
var styles27 = StyleSheet27.create({
|
|
3145
|
+
root: { alignSelf: "flex-start" },
|
|
3146
|
+
boxes: { flexDirection: "row", gap: 8 },
|
|
3147
|
+
box: { width: 46, height: 56, alignItems: "center", justifyContent: "center" },
|
|
3148
|
+
hidden: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, opacity: 0.011, color: "transparent" }
|
|
3149
|
+
});
|
|
3150
|
+
|
|
2375
3151
|
// src/native/pagination.tsx
|
|
2376
|
-
import { Pressable as
|
|
2377
|
-
import
|
|
2378
|
-
import { jsx as
|
|
3152
|
+
import { Pressable as Pressable14, StyleSheet as StyleSheet28, Text as Text14, View as View29 } from "react-native";
|
|
3153
|
+
import Svg13, { Path as Path10 } from "react-native-svg";
|
|
3154
|
+
import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2379
3155
|
function Chevron3({ direction, color }) {
|
|
2380
|
-
return /* @__PURE__ */
|
|
3156
|
+
return /* @__PURE__ */ jsx34(Svg13, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx34(Path10, { d: direction === "left" ? "m15 6-6 6 6 6" : "m9 6 6 6-6 6" }) });
|
|
2381
3157
|
}
|
|
2382
3158
|
function Pagination({ page = 1, pageCount, onPageChange, hasPrevious, hasNext, onPrevious, onNext, status, disabled, labels, style }) {
|
|
2383
3159
|
const { theme, radius: radius3 } = useTheme();
|
|
@@ -2386,8 +3162,8 @@ function Pagination({ page = 1, pageCount, onPageChange, hasPrevious, hasNext, o
|
|
|
2386
3162
|
const current = Math.min(Math.max(1, page), count);
|
|
2387
3163
|
const canPrevious = !disabled && (paged ? current > 1 : Boolean(hasPrevious));
|
|
2388
3164
|
const canNext = !disabled && (paged ? current < count : Boolean(hasNext));
|
|
2389
|
-
const button = (direction, enabled, onPress, label) => /* @__PURE__ */
|
|
2390
|
-
|
|
3165
|
+
const button = (direction, enabled, onPress, label) => /* @__PURE__ */ jsx34(
|
|
3166
|
+
Pressable14,
|
|
2391
3167
|
{
|
|
2392
3168
|
role: "button",
|
|
2393
3169
|
"aria-label": label,
|
|
@@ -2396,29 +3172,66 @@ function Pagination({ page = 1, pageCount, onPageChange, hasPrevious, hasNext, o
|
|
|
2396
3172
|
hitSlop: 6,
|
|
2397
3173
|
onPress,
|
|
2398
3174
|
style: ({ pressed }) => [
|
|
2399
|
-
|
|
3175
|
+
styles28.button,
|
|
2400
3176
|
{ borderRadius: radius3.sm, borderColor: theme.borderDefault, backgroundColor: theme.surface1, opacity: enabled ? pressed ? 0.8 : 1 : 0.4 }
|
|
2401
3177
|
],
|
|
2402
|
-
children: /* @__PURE__ */
|
|
3178
|
+
children: /* @__PURE__ */ jsx34(Chevron3, { direction, color: theme.textPrimary })
|
|
2403
3179
|
}
|
|
2404
3180
|
);
|
|
2405
3181
|
const text = status ?? (paged ? labels.compact(current, count) : null);
|
|
2406
|
-
return /* @__PURE__ */
|
|
3182
|
+
return /* @__PURE__ */ jsxs30(View29, { role: "navigation", style: [styles28.row, style], children: [
|
|
2407
3183
|
button("left", canPrevious, paged ? () => onPageChange?.(current - 1) : onPrevious, labels.previous),
|
|
2408
|
-
text ? /* @__PURE__ */
|
|
3184
|
+
text ? /* @__PURE__ */ jsx34(Text14, { "aria-live": "polite", style: [styles28.status, { color: theme.textSecondary }], children: text }) : null,
|
|
2409
3185
|
button("right", canNext, paged ? () => onPageChange?.(current + 1) : onNext, labels.next)
|
|
2410
3186
|
] });
|
|
2411
3187
|
}
|
|
2412
|
-
var
|
|
3188
|
+
var styles28 = StyleSheet28.create({
|
|
2413
3189
|
row: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 12 },
|
|
2414
|
-
button: { width: 44, height: 44, alignItems: "center", justifyContent: "center", borderWidth:
|
|
3190
|
+
button: { width: 44, height: 44, alignItems: "center", justifyContent: "center", borderWidth: StyleSheet28.hairlineWidth },
|
|
2415
3191
|
status: { fontSize: 13, fontWeight: "600", fontVariant: ["tabular-nums"] }
|
|
2416
3192
|
});
|
|
2417
3193
|
|
|
3194
|
+
// src/native/permission-prompt.tsx
|
|
3195
|
+
import { StyleSheet as StyleSheet29, View as View30 } from "react-native";
|
|
3196
|
+
import { Fragment as Fragment5, jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3197
|
+
function PermissionPrompt({
|
|
3198
|
+
status,
|
|
3199
|
+
title,
|
|
3200
|
+
description,
|
|
3201
|
+
allowLabel,
|
|
3202
|
+
onAllow,
|
|
3203
|
+
settingsLabel,
|
|
3204
|
+
onOpenSettings,
|
|
3205
|
+
blockedDescription,
|
|
3206
|
+
dismissLabel,
|
|
3207
|
+
onDismiss,
|
|
3208
|
+
mascot = "falcon",
|
|
3209
|
+
children,
|
|
3210
|
+
style
|
|
3211
|
+
}) {
|
|
3212
|
+
const { theme, radius: radius3 } = useTheme();
|
|
3213
|
+
if (status === "granted") return /* @__PURE__ */ jsx35(Fragment5, { children: children ?? null });
|
|
3214
|
+
const blocked = status === "blocked" || status === "denied" && Boolean(onOpenSettings);
|
|
3215
|
+
return /* @__PURE__ */ jsxs31(View30, { style: [styles29.root, { backgroundColor: theme.surface1, borderColor: theme.borderSubtle, borderRadius: radius3.xl }, style], children: [
|
|
3216
|
+
/* @__PURE__ */ jsx35(Mascot, { bird: mascot, mood: blocked ? "error" : "welcome", size: 104 }),
|
|
3217
|
+
/* @__PURE__ */ jsx35(Txt, { variant: "title", style: styles29.centred, children: title }),
|
|
3218
|
+
/* @__PURE__ */ jsx35(Txt, { tone: "secondary", style: styles29.centred, children: blocked && blockedDescription ? blockedDescription : description }),
|
|
3219
|
+
/* @__PURE__ */ jsxs31(View30, { style: styles29.actions, children: [
|
|
3220
|
+
blocked && settingsLabel && onOpenSettings ? /* @__PURE__ */ jsx35(Button, { label: settingsLabel, variant: "primary", onPress: onOpenSettings }) : /* @__PURE__ */ jsx35(Button, { label: allowLabel, variant: "primary", onPress: onAllow }),
|
|
3221
|
+
dismissLabel && onDismiss ? /* @__PURE__ */ jsx35(Button, { label: dismissLabel, variant: "ghost", onPress: onDismiss }) : null
|
|
3222
|
+
] })
|
|
3223
|
+
] });
|
|
3224
|
+
}
|
|
3225
|
+
var styles29 = StyleSheet29.create({
|
|
3226
|
+
root: { alignItems: "center", gap: 10, padding: 24, borderWidth: StyleSheet29.hairlineWidth },
|
|
3227
|
+
centred: { textAlign: "center", maxWidth: 340 },
|
|
3228
|
+
actions: { marginTop: 8, gap: 8, alignSelf: "stretch" }
|
|
3229
|
+
});
|
|
3230
|
+
|
|
2418
3231
|
// src/native/phoenix.tsx
|
|
2419
|
-
import { useEffect as
|
|
2420
|
-
import { AccessibilityInfo as
|
|
2421
|
-
import
|
|
3232
|
+
import { useEffect as useEffect17, useState as useState26 } from "react";
|
|
3233
|
+
import { AccessibilityInfo as AccessibilityInfo11, Animated as Animated14, Easing as Easing8, View as View31 } from "react-native";
|
|
3234
|
+
import Svg14, { Circle as Circle8, Defs as Defs7, LinearGradient as LinearGradient7, Path as Path11, RadialGradient as RadialGradient4, Stop as Stop7 } from "react-native-svg";
|
|
2422
3235
|
|
|
2423
3236
|
// src/mascots/phoenix-geometry.ts
|
|
2424
3237
|
var PHOENIX = {
|
|
@@ -2441,17 +3254,17 @@ var PHOENIX_PALETTES = {
|
|
|
2441
3254
|
};
|
|
2442
3255
|
|
|
2443
3256
|
// src/native/phoenix.tsx
|
|
2444
|
-
import { jsx as
|
|
3257
|
+
import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2445
3258
|
function useFloat(animated) {
|
|
2446
|
-
const [y] =
|
|
2447
|
-
|
|
3259
|
+
const [y] = useState26(() => new Animated14.Value(0));
|
|
3260
|
+
useEffect17(() => {
|
|
2448
3261
|
if (!animated) return;
|
|
2449
3262
|
let loop;
|
|
2450
3263
|
let cancelled = false;
|
|
2451
|
-
void
|
|
3264
|
+
void AccessibilityInfo11.isReduceMotionEnabled().then((reduce) => {
|
|
2452
3265
|
if (reduce || cancelled) return;
|
|
2453
|
-
const step = (toValue) =>
|
|
2454
|
-
loop =
|
|
3266
|
+
const step = (toValue) => Animated14.timing(y, { toValue, duration: 2500, easing: Easing8.inOut(Easing8.ease), useNativeDriver: true });
|
|
3267
|
+
loop = Animated14.loop(Animated14.sequence([step(-6), step(0)]));
|
|
2455
3268
|
loop.start();
|
|
2456
3269
|
});
|
|
2457
3270
|
return () => {
|
|
@@ -2461,41 +3274,41 @@ function useFloat(animated) {
|
|
|
2461
3274
|
}, [animated, y]);
|
|
2462
3275
|
return y;
|
|
2463
3276
|
}
|
|
2464
|
-
function Phoenix({ tone:
|
|
3277
|
+
function Phoenix({ tone: tone3 = "own", size = 120, animated = true, title, style }) {
|
|
2465
3278
|
const { theme } = useTheme();
|
|
2466
3279
|
const id = useSvgId("kzp");
|
|
2467
3280
|
const y = useFloat(animated);
|
|
2468
|
-
const p =
|
|
2469
|
-
return /* @__PURE__ */
|
|
2470
|
-
/* @__PURE__ */
|
|
2471
|
-
/* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
3281
|
+
const p = tone3 === "brand" ? { left: [theme.accent2, theme.accent], right: [theme.accent, theme.accent2], core: ["#ffffff", theme.accent], body: theme.surface3, edge: theme.borderStrong, crest: theme.accent } : PHOENIX_PALETTES.own;
|
|
3282
|
+
return /* @__PURE__ */ jsx36(View31, { style: [{ width: size, height: size }, style], ...markA11y(title), children: /* @__PURE__ */ jsx36(Animated14.View, { style: { transform: [{ translateY: y }] }, children: /* @__PURE__ */ jsxs32(Svg14, { width: size, height: size, viewBox: "0 0 120 120", children: [
|
|
3283
|
+
/* @__PURE__ */ jsxs32(Defs7, { children: [
|
|
3284
|
+
/* @__PURE__ */ jsxs32(LinearGradient7, { id: `${id}l`, x1: "1", y1: "0", x2: "0", y2: "1", children: [
|
|
3285
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "0%", stopColor: p.left[0] }),
|
|
3286
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "100%", stopColor: p.left[1] })
|
|
2474
3287
|
] }),
|
|
2475
|
-
/* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
2477
|
-
/* @__PURE__ */
|
|
3288
|
+
/* @__PURE__ */ jsxs32(LinearGradient7, { id: `${id}r`, x1: "0", y1: "0", x2: "1", y2: "1", children: [
|
|
3289
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "0%", stopColor: p.right[0] }),
|
|
3290
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "100%", stopColor: p.right[1] })
|
|
2478
3291
|
] }),
|
|
2479
|
-
/* @__PURE__ */
|
|
2480
|
-
/* @__PURE__ */
|
|
2481
|
-
/* @__PURE__ */
|
|
3292
|
+
/* @__PURE__ */ jsxs32(RadialGradient4, { id: `${id}c`, children: [
|
|
3293
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "0%", stopColor: p.core[0] }),
|
|
3294
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "100%", stopColor: p.core[1], stopOpacity: 0 })
|
|
2482
3295
|
] })
|
|
2483
3296
|
] }),
|
|
2484
|
-
/* @__PURE__ */
|
|
2485
|
-
/* @__PURE__ */
|
|
2486
|
-
/* @__PURE__ */
|
|
2487
|
-
/* @__PURE__ */
|
|
2488
|
-
/* @__PURE__ */
|
|
2489
|
-
/* @__PURE__ */
|
|
2490
|
-
/* @__PURE__ */
|
|
2491
|
-
/* @__PURE__ */
|
|
3297
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.wingL, fill: `url(#${id}l)` }),
|
|
3298
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.wingR, fill: `url(#${id}r)` }),
|
|
3299
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.tailL, fill: `url(#${id}l)`, opacity: 0.7 }),
|
|
3300
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.tailR, fill: `url(#${id}r)`, opacity: 0.7 }),
|
|
3301
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.body, fill: p.body, stroke: p.edge, strokeOpacity: 0.5 }),
|
|
3302
|
+
/* @__PURE__ */ jsx36(Circle8, { cx: 60, cy: 58, r: 12, fill: `url(#${id}c)` }),
|
|
3303
|
+
/* @__PURE__ */ jsx36(Circle8, { cx: 60, cy: 58, r: 3.5, fill: "#ffffff" }),
|
|
3304
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.crest, stroke: p.crest, strokeWidth: 2, strokeLinecap: "round" })
|
|
2492
3305
|
] }) }) });
|
|
2493
3306
|
}
|
|
2494
3307
|
|
|
2495
3308
|
// src/native/YazakiaMark.tsx
|
|
2496
|
-
import
|
|
2497
|
-
import { View as
|
|
2498
|
-
import
|
|
3309
|
+
import React27 from "react";
|
|
3310
|
+
import { View as View32 } from "react-native";
|
|
3311
|
+
import Svg15, { Circle as Circle9, Defs as Defs8, LinearGradient as LinearGradient8, Path as Path12, RadialGradient as RadialGradient5, Stop as Stop8 } from "react-native-svg";
|
|
2499
3312
|
|
|
2500
3313
|
// src/marks/yazakia-geometry.ts
|
|
2501
3314
|
var turquoise = marks.yazakia[marks.yazakia.length - 1][1];
|
|
@@ -2525,54 +3338,54 @@ var YAZAKIA = {
|
|
|
2525
3338
|
};
|
|
2526
3339
|
|
|
2527
3340
|
// src/native/YazakiaMark.tsx
|
|
2528
|
-
import { jsx as
|
|
3341
|
+
import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2529
3342
|
function YazakiaMark({ size = 48, animated = true, title, neutral }) {
|
|
2530
3343
|
const { theme } = useTheme();
|
|
2531
|
-
const { Animated:
|
|
3344
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
|
|
2532
3345
|
const id = useSvgId("yzm");
|
|
2533
3346
|
const viewBox = size < 48 ? YAZAKIA.croppedViewBox : YAZAKIA.viewBox;
|
|
2534
3347
|
const stroke = neutral ?? theme.textMuted;
|
|
2535
|
-
const gradient = /* @__PURE__ */
|
|
3348
|
+
const gradient = /* @__PURE__ */ jsx37(LinearGradient8, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: YAZAKIA.gradient.x1, y1: YAZAKIA.gradient.y1, x2: YAZAKIA.gradient.x2, y2: YAZAKIA.gradient.y2, children: YAZAKIA.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx37(Stop8, { offset, stopColor: color }, offset)) });
|
|
2536
3349
|
const fill = `url(#${id}a)`;
|
|
2537
|
-
return /* @__PURE__ */
|
|
2538
|
-
/* @__PURE__ */
|
|
2539
|
-
/* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
/* @__PURE__ */
|
|
2542
|
-
/* @__PURE__ */
|
|
3350
|
+
return /* @__PURE__ */ jsxs33(View32, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
3351
|
+
/* @__PURE__ */ jsxs33(Svg15, { viewBox, style: layer, children: [
|
|
3352
|
+
/* @__PURE__ */ jsxs33(Defs8, { children: [
|
|
3353
|
+
/* @__PURE__ */ jsxs33(RadialGradient5, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
3354
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "0%", stopColor: YAZAKIA.glow.color, stopOpacity: YAZAKIA.glow.opacity }),
|
|
3355
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "100%", stopColor: YAZAKIA.glow.color, stopOpacity: 0 })
|
|
2543
3356
|
] }),
|
|
2544
3357
|
gradient
|
|
2545
3358
|
] }),
|
|
2546
|
-
size >= 48 ? /* @__PURE__ */
|
|
2547
|
-
/* @__PURE__ */
|
|
2548
|
-
YAZAKIA.voices.map((v, i) => /* @__PURE__ */
|
|
2549
|
-
/* @__PURE__ */
|
|
2550
|
-
/* @__PURE__ */
|
|
2551
|
-
i === 0 ? /* @__PURE__ */
|
|
3359
|
+
size >= 48 ? /* @__PURE__ */ jsx37(Circle9, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: 190, fill: `url(#${id}g)` }) : null,
|
|
3360
|
+
/* @__PURE__ */ jsx37(Circle9, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: YAZAKIA.ring.r, stroke, strokeWidth: YAZAKIA.ring.width, opacity: 0.35, fill: "none" }),
|
|
3361
|
+
YAZAKIA.voices.map((v, i) => /* @__PURE__ */ jsxs33(React27.Fragment, { children: [
|
|
3362
|
+
/* @__PURE__ */ jsx37(Path12, { d: v.body, fill }),
|
|
3363
|
+
/* @__PURE__ */ jsx37(Path12, { d: v.tail, fill }),
|
|
3364
|
+
i === 0 ? /* @__PURE__ */ jsx37(Path12, { d: `${v.body} ${v.tail}`, fill: YAZAKIA.shade.color, opacity: YAZAKIA.shade.opacity }) : null
|
|
2552
3365
|
] }, v.body))
|
|
2553
3366
|
] }),
|
|
2554
|
-
/* @__PURE__ */
|
|
2555
|
-
/* @__PURE__ */
|
|
2556
|
-
/* @__PURE__ */
|
|
2557
|
-
YAZAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */
|
|
3367
|
+
/* @__PURE__ */ jsx37(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs33(Svg15, { viewBox, style: layer, children: [
|
|
3368
|
+
/* @__PURE__ */ jsx37(Defs8, { children: gradient }),
|
|
3369
|
+
/* @__PURE__ */ jsx37(Circle9, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: YAZAKIA.orbit.r, stroke, strokeWidth: YAZAKIA.orbit.width, strokeDasharray: YAZAKIA.orbit.dash, opacity: 0.6, fill: "none" }),
|
|
3370
|
+
YAZAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */ jsx37(Circle9, { cx, cy, r: YAZAKIA.pair.r, fill }, cx))
|
|
2558
3371
|
] }) }),
|
|
2559
|
-
/* @__PURE__ */
|
|
2560
|
-
/* @__PURE__ */
|
|
3372
|
+
/* @__PURE__ */ jsx37(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs33(Svg15, { viewBox, style: layer, children: [
|
|
3373
|
+
/* @__PURE__ */ jsxs33(Defs8, { children: [
|
|
2561
3374
|
gradient,
|
|
2562
|
-
/* @__PURE__ */
|
|
2563
|
-
/* @__PURE__ */
|
|
2564
|
-
/* @__PURE__ */
|
|
3375
|
+
/* @__PURE__ */ jsxs33(LinearGradient8, { id: `${id}l`, gradientUnits: "userSpaceOnUse", x1: 0, y1: YAZAKIA.lens.y1, x2: 0, y2: YAZAKIA.lens.y2, children: [
|
|
3376
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "0%", stopColor: YAZAKIA.highlight.color, stopOpacity: YAZAKIA.highlight.from }),
|
|
3377
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "100%", stopColor: YAZAKIA.highlight.color, stopOpacity: YAZAKIA.highlight.to })
|
|
2565
3378
|
] })
|
|
2566
3379
|
] }),
|
|
2567
|
-
/* @__PURE__ */
|
|
2568
|
-
/* @__PURE__ */
|
|
3380
|
+
/* @__PURE__ */ jsx37(Path12, { d: YAZAKIA.lens.d, fill }),
|
|
3381
|
+
/* @__PURE__ */ jsx37(Path12, { d: YAZAKIA.lens.d, fill: `url(#${id}l)` })
|
|
2569
3382
|
] }) })
|
|
2570
3383
|
] });
|
|
2571
3384
|
}
|
|
2572
3385
|
|
|
2573
3386
|
// src/native/YororisMark.tsx
|
|
2574
|
-
import { View as
|
|
2575
|
-
import
|
|
3387
|
+
import { View as View33 } from "react-native";
|
|
3388
|
+
import Svg16, { Circle as Circle10, Defs as Defs9, LinearGradient as LinearGradient9, Path as Path13, RadialGradient as RadialGradient6, Stop as Stop9 } from "react-native-svg";
|
|
2576
3389
|
|
|
2577
3390
|
// src/marks/yororis-geometry.ts
|
|
2578
3391
|
var sand = marks.yororis[0][1];
|
|
@@ -2608,65 +3421,65 @@ var YORORIS = {
|
|
|
2608
3421
|
};
|
|
2609
3422
|
|
|
2610
3423
|
// src/native/YororisMark.tsx
|
|
2611
|
-
import { jsx as
|
|
3424
|
+
import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2612
3425
|
function YororisMark({ size = 48, animated = true, title, neutral }) {
|
|
2613
3426
|
const { theme } = useTheme();
|
|
2614
|
-
const { Animated:
|
|
3427
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated, 36e3);
|
|
2615
3428
|
const id = useSvgId("yrm");
|
|
2616
3429
|
const viewBox = size < 48 ? YORORIS.croppedViewBox : YORORIS.viewBox;
|
|
2617
3430
|
const stroke = neutral ?? theme.textMuted;
|
|
2618
|
-
const gradient = /* @__PURE__ */
|
|
3431
|
+
const gradient = /* @__PURE__ */ jsx38(LinearGradient9, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: YORORIS.gradient.x1, y1: YORORIS.gradient.y1, x2: YORORIS.gradient.x2, y2: YORORIS.gradient.y2, children: YORORIS.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx38(Stop9, { offset, stopColor: color }, offset)) });
|
|
2619
3432
|
const fill = `url(#${id}a)`;
|
|
2620
|
-
return /* @__PURE__ */
|
|
2621
|
-
/* @__PURE__ */
|
|
2622
|
-
/* @__PURE__ */
|
|
2623
|
-
/* @__PURE__ */
|
|
2624
|
-
/* @__PURE__ */
|
|
2625
|
-
/* @__PURE__ */
|
|
3433
|
+
return /* @__PURE__ */ jsxs34(View33, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
3434
|
+
/* @__PURE__ */ jsxs34(Svg16, { viewBox, style: layer, children: [
|
|
3435
|
+
/* @__PURE__ */ jsxs34(Defs9, { children: [
|
|
3436
|
+
/* @__PURE__ */ jsxs34(RadialGradient6, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
3437
|
+
/* @__PURE__ */ jsx38(Stop9, { offset: "0%", stopColor: YORORIS.glow.color, stopOpacity: YORORIS.glow.opacity }),
|
|
3438
|
+
/* @__PURE__ */ jsx38(Stop9, { offset: "100%", stopColor: YORORIS.glow.color, stopOpacity: 0 })
|
|
2626
3439
|
] }),
|
|
2627
3440
|
gradient
|
|
2628
3441
|
] }),
|
|
2629
|
-
size >= 48 ? /* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
/* @__PURE__ */
|
|
2632
|
-
YORORIS.leaves.map((d) => /* @__PURE__ */
|
|
2633
|
-
/* @__PURE__ */
|
|
3442
|
+
size >= 48 ? /* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.center, cy: YORORIS.center, r: 190, fill: `url(#${id}g)` }) : null,
|
|
3443
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.center, cy: YORORIS.center, r: YORORIS.ring.r, stroke, strokeWidth: YORORIS.ring.width, opacity: 0.35, fill: "none" }),
|
|
3444
|
+
/* @__PURE__ */ jsx38(Path13, { d: YORORIS.stem, stroke: fill, strokeWidth: YORORIS.stroke, strokeLinecap: "round", fill: "none" }),
|
|
3445
|
+
YORORIS.leaves.map((d) => /* @__PURE__ */ jsx38(Path13, { d, fill }, d)),
|
|
3446
|
+
/* @__PURE__ */ jsx38(Path13, { d: YORORIS.veins, stroke: YORORIS.vein.color, strokeOpacity: YORORIS.vein.opacity, strokeWidth: YORORIS.vein.width, strokeLinecap: "round", strokeDasharray: YORORIS.vein.dash, fill: "none" })
|
|
2634
3447
|
] }),
|
|
2635
|
-
/* @__PURE__ */
|
|
2636
|
-
/* @__PURE__ */
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
3448
|
+
/* @__PURE__ */ jsx38(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs34(Svg16, { viewBox, style: layer, children: [
|
|
3449
|
+
/* @__PURE__ */ jsx38(Defs9, { children: gradient }),
|
|
3450
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.center, cy: YORORIS.center, r: YORORIS.orbit.r, stroke, strokeWidth: YORORIS.orbit.width, strokeDasharray: YORORIS.orbit.dash, opacity: 0.6, fill: "none" }),
|
|
3451
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.moment.at[0], cy: YORORIS.moment.at[1], r: YORORIS.moment.r, fill })
|
|
2639
3452
|
] }) }),
|
|
2640
|
-
/* @__PURE__ */
|
|
2641
|
-
/* @__PURE__ */
|
|
2642
|
-
/* @__PURE__ */
|
|
2643
|
-
/* @__PURE__ */
|
|
3453
|
+
/* @__PURE__ */ jsx38(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs34(Svg16, { viewBox, style: layer, children: [
|
|
3454
|
+
/* @__PURE__ */ jsx38(Defs9, { children: /* @__PURE__ */ jsx38(LinearGradient9, { id: `${id}c`, x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: YORORIS.coreGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx38(Stop9, { offset, stopColor: color }, offset)) }) }),
|
|
3455
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.core.cx, cy: YORORIS.core.cy, r: YORORIS.core.r, fill: `url(#${id}c)` }),
|
|
3456
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.core.cx, cy: YORORIS.core.cy, r: YORORIS.core.inner, fill: YORORIS.highlight })
|
|
2644
3457
|
] }) })
|
|
2645
3458
|
] });
|
|
2646
3459
|
}
|
|
2647
3460
|
|
|
2648
3461
|
// src/native/ProductMark.tsx
|
|
2649
|
-
import { jsx as
|
|
3462
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
2650
3463
|
function ProductMark({ id, ...props }) {
|
|
2651
|
-
if (id === "krizaka") return /* @__PURE__ */
|
|
2652
|
-
if (id === "orazaka") return /* @__PURE__ */
|
|
2653
|
-
if (id === "yazakia") return /* @__PURE__ */
|
|
2654
|
-
if (id === "yororis") return /* @__PURE__ */
|
|
2655
|
-
return /* @__PURE__ */
|
|
3464
|
+
if (id === "krizaka") return /* @__PURE__ */ jsx39(KrizakaMark, { ...props });
|
|
3465
|
+
if (id === "orazaka") return /* @__PURE__ */ jsx39(OrazakaMark, { ...props });
|
|
3466
|
+
if (id === "yazakia") return /* @__PURE__ */ jsx39(YazakiaMark, { ...props });
|
|
3467
|
+
if (id === "yororis") return /* @__PURE__ */ jsx39(YororisMark, { ...props });
|
|
3468
|
+
return /* @__PURE__ */ jsx39(OrochiaMark, { ...props });
|
|
2656
3469
|
}
|
|
2657
3470
|
|
|
2658
3471
|
// src/native/profile-card.tsx
|
|
2659
|
-
import * as
|
|
2660
|
-
import { Animated as
|
|
2661
|
-
import { jsx as
|
|
3472
|
+
import * as React28 from "react";
|
|
3473
|
+
import { Animated as Animated15, StyleSheet as StyleSheet30, View as View34 } from "react-native";
|
|
3474
|
+
import { jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2662
3475
|
var ratioOf = (value, max = 100) => Math.min(1, Math.max(0, value / (max || 1)));
|
|
2663
3476
|
function Bar({ label, ratio, words, animated, delay }) {
|
|
2664
3477
|
const { theme } = useTheme();
|
|
2665
3478
|
const t = useEntrance(animated, delay, 900);
|
|
2666
|
-
const [width, setWidth] =
|
|
3479
|
+
const [width, setWidth] = React28.useState(0);
|
|
2667
3480
|
const translateX = t.interpolate({ inputRange: [0, 1], outputRange: [-width * ratio, 0] });
|
|
2668
|
-
return /* @__PURE__ */
|
|
2669
|
-
|
|
3481
|
+
return /* @__PURE__ */ jsx40(
|
|
3482
|
+
View34,
|
|
2670
3483
|
{
|
|
2671
3484
|
accessible: true,
|
|
2672
3485
|
role: "meter",
|
|
@@ -2676,42 +3489,42 @@ function Bar({ label, ratio, words, animated, delay }) {
|
|
|
2676
3489
|
"aria-valuenow": Math.round(ratio * 100),
|
|
2677
3490
|
"aria-valuetext": words,
|
|
2678
3491
|
onLayout: (e) => setWidth(e.nativeEvent.layout.width),
|
|
2679
|
-
style: [
|
|
2680
|
-
children: /* @__PURE__ */
|
|
3492
|
+
style: [styles30.track, { backgroundColor: theme.surface3 }],
|
|
3493
|
+
children: /* @__PURE__ */ jsx40(Animated15.View, { style: [styles30.fill, { width: `${ratio * 100}%`, backgroundColor: theme.accent, transform: [{ translateX }] }] })
|
|
2681
3494
|
}
|
|
2682
3495
|
);
|
|
2683
3496
|
}
|
|
2684
3497
|
function ProfileCard({ visual, name, statLabel, value = 100, valueText, stats, caption, children, animated = true, style, ...props }) {
|
|
2685
3498
|
const { theme, radius: radius3 } = useTheme();
|
|
2686
3499
|
const ratio = ratioOf(value);
|
|
2687
|
-
return /* @__PURE__ */
|
|
2688
|
-
/* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
/* @__PURE__ */
|
|
2691
|
-
statLabel ? /* @__PURE__ */
|
|
3500
|
+
return /* @__PURE__ */ jsxs35(View34, { ...props, style: [styles30.root, { backgroundColor: theme.surface1, borderColor: theme.borderSubtle, borderRadius: radius3.xl }, style], children: [
|
|
3501
|
+
/* @__PURE__ */ jsx40(View34, { "aria-hidden": true, style: [styles30.disc, { backgroundColor: theme.surface2, borderColor: theme.accentSoft }], children: visual }),
|
|
3502
|
+
/* @__PURE__ */ jsxs35(View34, { style: styles30.head, children: [
|
|
3503
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "title", style: styles30.name, children: name }),
|
|
3504
|
+
statLabel ? /* @__PURE__ */ jsxs35(Txt, { variant: "caption", tone: "secondary", children: [
|
|
2692
3505
|
statLabel,
|
|
2693
3506
|
" ",
|
|
2694
|
-
/* @__PURE__ */
|
|
3507
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "caption", children: valueText ?? `${Math.round(ratio * 100)} %` })
|
|
2695
3508
|
] }) : null
|
|
2696
3509
|
] }),
|
|
2697
|
-
statLabel ? /* @__PURE__ */
|
|
3510
|
+
statLabel ? /* @__PURE__ */ jsx40(Bar, { label: statLabel, ratio, words: valueText ?? `${Math.round(ratio * 100)} %`, animated, delay: 200 }) : null,
|
|
2698
3511
|
stats?.map((s, i) => {
|
|
2699
3512
|
const r = ratioOf(s.value, s.max);
|
|
2700
3513
|
const words = s.valueText ?? `${Math.round(r * 100)} %`;
|
|
2701
|
-
return /* @__PURE__ */
|
|
2702
|
-
/* @__PURE__ */
|
|
2703
|
-
/* @__PURE__ */
|
|
2704
|
-
/* @__PURE__ */
|
|
3514
|
+
return /* @__PURE__ */ jsxs35(View34, { style: styles30.stat, children: [
|
|
3515
|
+
/* @__PURE__ */ jsxs35(View34, { "aria-hidden": true, style: styles30.statHead, children: [
|
|
3516
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "caption", tone: "secondary", children: s.label }),
|
|
3517
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "caption", children: words })
|
|
2705
3518
|
] }),
|
|
2706
|
-
/* @__PURE__ */
|
|
3519
|
+
/* @__PURE__ */ jsx40(Bar, { label: s.label, ratio: r, words, animated, delay: 320 + i * 120 })
|
|
2707
3520
|
] }, s.label);
|
|
2708
3521
|
}),
|
|
2709
|
-
caption ? /* @__PURE__ */
|
|
2710
|
-
children ? /* @__PURE__ */
|
|
3522
|
+
caption ? /* @__PURE__ */ jsx40(Txt, { variant: "caption", tone: "secondary", style: styles30.caption, children: caption }) : null,
|
|
3523
|
+
children ? /* @__PURE__ */ jsx40(View34, { style: styles30.extra, children }) : null
|
|
2711
3524
|
] });
|
|
2712
3525
|
}
|
|
2713
|
-
var
|
|
2714
|
-
root: { alignItems: "center", gap: 12, padding: 20, borderWidth:
|
|
3526
|
+
var styles30 = StyleSheet30.create({
|
|
3527
|
+
root: { alignItems: "center", gap: 12, padding: 20, borderWidth: StyleSheet30.hairlineWidth },
|
|
2715
3528
|
disc: { width: 104, height: 104, borderRadius: 52, borderWidth: 1, alignItems: "center", justifyContent: "center", overflow: "hidden" },
|
|
2716
3529
|
head: { flexDirection: "row", alignSelf: "stretch", alignItems: "center", justifyContent: "space-between", gap: 8 },
|
|
2717
3530
|
name: { flexShrink: 1, fontSize: 17 },
|
|
@@ -2724,13 +3537,13 @@ var styles19 = StyleSheet19.create({
|
|
|
2724
3537
|
});
|
|
2725
3538
|
|
|
2726
3539
|
// src/native/progress.tsx
|
|
2727
|
-
import * as
|
|
2728
|
-
import { Animated as
|
|
2729
|
-
import
|
|
2730
|
-
import { jsx as
|
|
2731
|
-
var AnimatedCircle =
|
|
2732
|
-
var
|
|
2733
|
-
var
|
|
3540
|
+
import * as React29 from "react";
|
|
3541
|
+
import { Animated as Animated16, Easing as Easing9, StyleSheet as StyleSheet31, View as View35 } from "react-native";
|
|
3542
|
+
import Svg17, { Circle as Circle11, Defs as Defs10, LinearGradient as LinearGradient10, Rect as Rect3, Stop as Stop10 } from "react-native-svg";
|
|
3543
|
+
import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3544
|
+
var AnimatedCircle = Animated16.createAnimatedComponent(Circle11);
|
|
3545
|
+
var BAR2 = { sm: 4, md: 8, lg: 12 };
|
|
3546
|
+
var RING2 = { sm: 40, md: 80, lg: 144 };
|
|
2734
3547
|
var STROKE = { sm: 12, md: 9, lg: 7 };
|
|
2735
3548
|
function Progress({ variant = "bar", size = "md", value, max = 100, label, valueText, children, style }) {
|
|
2736
3549
|
const { theme } = useTheme();
|
|
@@ -2739,21 +3552,21 @@ function Progress({ variant = "bar", size = "md", value, max = 100, label, value
|
|
|
2739
3552
|
const known = typeof value === "number" && Number.isFinite(value);
|
|
2740
3553
|
const ratio = known ? Math.min(1, Math.max(0, value / (max || 1))) : 0;
|
|
2741
3554
|
const percent = Math.round(ratio * 100);
|
|
2742
|
-
const [progress] =
|
|
2743
|
-
const [spin] =
|
|
2744
|
-
const [track, setTrack] =
|
|
2745
|
-
|
|
3555
|
+
const [progress] = React29.useState(() => new Animated16.Value(ratio));
|
|
3556
|
+
const [spin] = React29.useState(() => new Animated16.Value(0));
|
|
3557
|
+
const [track, setTrack] = React29.useState(0);
|
|
3558
|
+
React29.useEffect(() => {
|
|
2746
3559
|
if (reduce) {
|
|
2747
3560
|
progress.setValue(ratio);
|
|
2748
3561
|
return;
|
|
2749
3562
|
}
|
|
2750
|
-
const animation =
|
|
3563
|
+
const animation = Animated16.timing(progress, { toValue: ratio, duration: 700, easing: Easing9.out(Easing9.cubic), useNativeDriver: false });
|
|
2751
3564
|
animation.start();
|
|
2752
3565
|
return () => animation.stop();
|
|
2753
3566
|
}, [ratio, reduce, progress]);
|
|
2754
|
-
|
|
3567
|
+
React29.useEffect(() => {
|
|
2755
3568
|
if (known || reduce) return;
|
|
2756
|
-
const loop =
|
|
3569
|
+
const loop = Animated16.loop(Animated16.timing(spin, { toValue: 1, duration: 1200, easing: Easing9.linear, useNativeDriver: true }));
|
|
2757
3570
|
loop.start();
|
|
2758
3571
|
return () => {
|
|
2759
3572
|
loop.stop();
|
|
@@ -2769,22 +3582,22 @@ function Progress({ variant = "bar", size = "md", value, max = 100, label, value
|
|
|
2769
3582
|
"aria-valuenow": known ? Math.min(max, Math.max(0, value)) : void 0,
|
|
2770
3583
|
"aria-valuetext": known ? valueText ?? `${percent}%` : valueText
|
|
2771
3584
|
};
|
|
2772
|
-
const gradient = /* @__PURE__ */
|
|
2773
|
-
/* @__PURE__ */
|
|
2774
|
-
/* @__PURE__ */
|
|
3585
|
+
const gradient = /* @__PURE__ */ jsx41(Defs10, { children: /* @__PURE__ */ jsxs36(LinearGradient10, { id, x1: "0", y1: "0", x2: "1", y2: variant === "ring" ? "1" : "0", children: [
|
|
3586
|
+
/* @__PURE__ */ jsx41(Stop10, { offset: "0", stopColor: theme.accent }),
|
|
3587
|
+
/* @__PURE__ */ jsx41(Stop10, { offset: "1", stopColor: theme.accent2 })
|
|
2775
3588
|
] }) });
|
|
2776
3589
|
if (variant === "ring") {
|
|
2777
|
-
const side =
|
|
3590
|
+
const side = RING2[size];
|
|
2778
3591
|
const stroke = STROKE[size];
|
|
2779
3592
|
const r = 50 - stroke / 2;
|
|
2780
3593
|
const circumference = 2 * Math.PI * r;
|
|
2781
3594
|
const offset = known ? progress.interpolate({ inputRange: [0, 1], outputRange: [circumference, 0] }) : circumference * 0.75;
|
|
2782
3595
|
const rotate = spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] });
|
|
2783
|
-
return /* @__PURE__ */
|
|
2784
|
-
/* @__PURE__ */
|
|
3596
|
+
return /* @__PURE__ */ jsxs36(View35, { ...a11y, style: [styles31.ring, { width: side, height: side }, style], children: [
|
|
3597
|
+
/* @__PURE__ */ jsx41(Animated16.View, { style: [StyleSheet31.absoluteFill, { transform: [{ rotate: known ? "-90deg" : rotate }] }], children: /* @__PURE__ */ jsxs36(Svg17, { width: side, height: side, viewBox: "0 0 100 100", children: [
|
|
2785
3598
|
gradient,
|
|
2786
|
-
/* @__PURE__ */
|
|
2787
|
-
/* @__PURE__ */
|
|
3599
|
+
/* @__PURE__ */ jsx41(Circle11, { cx: 50, cy: 50, r, fill: "none", stroke: theme.borderDefault, strokeWidth: stroke }),
|
|
3600
|
+
/* @__PURE__ */ jsx41(
|
|
2788
3601
|
AnimatedCircle,
|
|
2789
3602
|
{
|
|
2790
3603
|
cx: 50,
|
|
@@ -2804,43 +3617,51 @@ function Progress({ variant = "bar", size = "md", value, max = 100, label, value
|
|
|
2804
3617
|
}
|
|
2805
3618
|
const width = known ? progress.interpolate({ inputRange: [0, 1], outputRange: ["0%", "100%"] }) : "40%";
|
|
2806
3619
|
const translate = spin.interpolate({ inputRange: [0, 1], outputRange: [-0.4 * track, track] });
|
|
2807
|
-
return /* @__PURE__ */
|
|
2808
|
-
|
|
3620
|
+
return /* @__PURE__ */ jsx41(
|
|
3621
|
+
View35,
|
|
2809
3622
|
{
|
|
2810
3623
|
...a11y,
|
|
2811
3624
|
onLayout: known ? void 0 : (event) => setTrack(event.nativeEvent.layout.width),
|
|
2812
|
-
style: [
|
|
2813
|
-
children: /* @__PURE__ */
|
|
3625
|
+
style: [styles31.bar, { height: BAR2[size], backgroundColor: theme.surface3 }, style],
|
|
3626
|
+
children: /* @__PURE__ */ jsx41(Animated16.View, { style: [styles31.fill, { width }, known || reduce ? null : { transform: [{ translateX: translate }] }], children: /* @__PURE__ */ jsxs36(Svg17, { width: "100%", height: "100%", preserveAspectRatio: "none", children: [
|
|
2814
3627
|
gradient,
|
|
2815
|
-
/* @__PURE__ */
|
|
3628
|
+
/* @__PURE__ */ jsx41(Rect3, { x: 0, y: 0, width: "100%", height: "100%", fill: `url(#${id})` })
|
|
2816
3629
|
] }) })
|
|
2817
3630
|
}
|
|
2818
3631
|
);
|
|
2819
3632
|
}
|
|
2820
|
-
var
|
|
3633
|
+
var styles31 = StyleSheet31.create({
|
|
2821
3634
|
ring: { alignItems: "center", justifyContent: "center" },
|
|
2822
3635
|
bar: { width: "100%", overflow: "hidden", borderRadius: 9999 },
|
|
2823
3636
|
fill: { height: "100%", overflow: "hidden", borderRadius: 9999 }
|
|
2824
3637
|
});
|
|
2825
3638
|
|
|
3639
|
+
// src/native/pull-to-refresh.tsx
|
|
3640
|
+
import { RefreshControl } from "react-native";
|
|
3641
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
3642
|
+
function PullToRefresh({ label, ...props }) {
|
|
3643
|
+
const { theme } = useTheme();
|
|
3644
|
+
return /* @__PURE__ */ jsx42(RefreshControl, { ...props, tintColor: theme.accent, colors: [theme.accent], progressBackgroundColor: theme.surface2, title: label, titleColor: theme.textSecondary });
|
|
3645
|
+
}
|
|
3646
|
+
|
|
2826
3647
|
// src/native/radio-group.tsx
|
|
2827
|
-
import * as
|
|
2828
|
-
import { Animated as
|
|
2829
|
-
import
|
|
2830
|
-
import { jsx as
|
|
3648
|
+
import * as React30 from "react";
|
|
3649
|
+
import { Animated as Animated17, Pressable as Pressable15, StyleSheet as StyleSheet32, Text as Text15, View as View36 } from "react-native";
|
|
3650
|
+
import Svg18, { Path as Path14 } from "react-native-svg";
|
|
3651
|
+
import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2831
3652
|
function Check({ color }) {
|
|
2832
|
-
return /* @__PURE__ */
|
|
3653
|
+
return /* @__PURE__ */ jsx43(Svg18, { width: 12, height: 12, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 3.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx43(Path14, { d: "M20 6 9 17l-5-5" }) });
|
|
2833
3654
|
}
|
|
2834
3655
|
function Key({ option, checked, disabled, onPress }) {
|
|
2835
3656
|
const { theme, radius: radius3, motion: motion3 } = useTheme();
|
|
2836
|
-
const [held, setHeld] =
|
|
2837
|
-
const [sink] =
|
|
3657
|
+
const [held, setHeld] = React30.useState(false);
|
|
3658
|
+
const [sink] = React30.useState(() => new Animated17.Value(checked ? 1 : 0));
|
|
2838
3659
|
const down = checked || held;
|
|
2839
|
-
|
|
2840
|
-
|
|
3660
|
+
React30.useEffect(() => {
|
|
3661
|
+
Animated17.timing(sink, { toValue: down ? 1 : 0, duration: motion3.duration.fast, useNativeDriver: true }).start();
|
|
2841
3662
|
}, [down, sink, motion3.duration.fast]);
|
|
2842
|
-
return /* @__PURE__ */
|
|
2843
|
-
|
|
3663
|
+
return /* @__PURE__ */ jsxs37(
|
|
3664
|
+
Pressable15,
|
|
2844
3665
|
{
|
|
2845
3666
|
role: "radio",
|
|
2846
3667
|
"aria-checked": checked,
|
|
@@ -2850,14 +3671,14 @@ function Key({ option, checked, disabled, onPress }) {
|
|
|
2850
3671
|
onPress,
|
|
2851
3672
|
onPressIn: () => setHeld(true),
|
|
2852
3673
|
onPressOut: () => setHeld(false),
|
|
2853
|
-
style: [
|
|
3674
|
+
style: [styles32.keySlot, disabled ? styles32.disabled : null],
|
|
2854
3675
|
children: [
|
|
2855
|
-
/* @__PURE__ */
|
|
2856
|
-
/* @__PURE__ */
|
|
2857
|
-
|
|
3676
|
+
/* @__PURE__ */ jsx43(View36, { style: [styles32.ledge, { borderRadius: radius3.lg, backgroundColor: checked ? theme.accentHover : theme.borderStrong }] }),
|
|
3677
|
+
/* @__PURE__ */ jsxs37(
|
|
3678
|
+
Animated17.View,
|
|
2858
3679
|
{
|
|
2859
3680
|
style: [
|
|
2860
|
-
|
|
3681
|
+
styles32.key,
|
|
2861
3682
|
{
|
|
2862
3683
|
borderRadius: radius3.lg,
|
|
2863
3684
|
backgroundColor: checked ? theme.accent : theme.surface2,
|
|
@@ -2866,8 +3687,8 @@ function Key({ option, checked, disabled, onPress }) {
|
|
|
2866
3687
|
}
|
|
2867
3688
|
],
|
|
2868
3689
|
children: [
|
|
2869
|
-
/* @__PURE__ */
|
|
2870
|
-
option.hint ? /* @__PURE__ */
|
|
3690
|
+
/* @__PURE__ */ jsx43(Text15, { style: [styles32.keyLabel, { color: checked ? theme.onAccent : theme.textPrimary }], children: option.label }),
|
|
3691
|
+
option.hint ? /* @__PURE__ */ jsx43(Text15, { style: [styles32.keyHint, { color: checked ? theme.onAccent : theme.textSecondary }], children: option.hint }) : null
|
|
2871
3692
|
]
|
|
2872
3693
|
}
|
|
2873
3694
|
)
|
|
@@ -2877,7 +3698,7 @@ function Key({ option, checked, disabled, onPress }) {
|
|
|
2877
3698
|
}
|
|
2878
3699
|
function RadioGroup({ label, options, value: valueProp, defaultValue = null, onValueChange, variant = "list", error, disabled, style }) {
|
|
2879
3700
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
2880
|
-
const [own, setOwn] =
|
|
3701
|
+
const [own, setOwn] = React30.useState(defaultValue);
|
|
2881
3702
|
const value = valueProp !== void 0 ? valueProp : own;
|
|
2882
3703
|
const pick = (v) => {
|
|
2883
3704
|
haptic(variant === "buttons" ? "impact" : "selection");
|
|
@@ -2888,10 +3709,10 @@ function RadioGroup({ label, options, value: valueProp, defaultValue = null, onV
|
|
|
2888
3709
|
const checked = o.value === value;
|
|
2889
3710
|
const off = Boolean(disabled || o.disabled);
|
|
2890
3711
|
const name = o.description ? `${o.label}, ${o.description}` : o.label;
|
|
2891
|
-
if (variant === "buttons") return /* @__PURE__ */
|
|
3712
|
+
if (variant === "buttons") return /* @__PURE__ */ jsx43(Key, { option: o, checked, disabled: off, onPress: () => pick(o.value) }, o.value);
|
|
2892
3713
|
if (variant === "segmented")
|
|
2893
|
-
return /* @__PURE__ */
|
|
2894
|
-
|
|
3714
|
+
return /* @__PURE__ */ jsx43(
|
|
3715
|
+
Pressable15,
|
|
2895
3716
|
{
|
|
2896
3717
|
role: "radio",
|
|
2897
3718
|
"aria-checked": checked,
|
|
@@ -2899,14 +3720,14 @@ function RadioGroup({ label, options, value: valueProp, defaultValue = null, onV
|
|
|
2899
3720
|
"aria-disabled": off || void 0,
|
|
2900
3721
|
disabled: off,
|
|
2901
3722
|
onPress: () => pick(o.value),
|
|
2902
|
-
style: [
|
|
2903
|
-
children: /* @__PURE__ */
|
|
3723
|
+
style: [styles32.segment, { borderRadius: radius3.md }, checked ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault } : null, off ? styles32.disabled : null],
|
|
3724
|
+
children: /* @__PURE__ */ jsx43(Text15, { numberOfLines: 1, style: [styles32.segmentLabel, { color: checked ? theme.textPrimary : theme.textSecondary }], children: o.label })
|
|
2904
3725
|
},
|
|
2905
3726
|
o.value
|
|
2906
3727
|
);
|
|
2907
3728
|
if (variant === "cards")
|
|
2908
|
-
return /* @__PURE__ */
|
|
2909
|
-
|
|
3729
|
+
return /* @__PURE__ */ jsxs37(
|
|
3730
|
+
Pressable15,
|
|
2910
3731
|
{
|
|
2911
3732
|
role: "radio",
|
|
2912
3733
|
"aria-checked": checked,
|
|
@@ -2915,40 +3736,40 @@ function RadioGroup({ label, options, value: valueProp, defaultValue = null, onV
|
|
|
2915
3736
|
disabled: off,
|
|
2916
3737
|
onPress: () => pick(o.value),
|
|
2917
3738
|
style: ({ pressed }) => [
|
|
2918
|
-
|
|
3739
|
+
styles32.card,
|
|
2919
3740
|
{ borderRadius: radius3.xl, backgroundColor: checked ? theme.accentSoft : theme.surface1, borderColor: checked ? theme.accent : theme.borderDefault, transform: [{ scale: pressed ? 0.98 : 1 }] },
|
|
2920
|
-
off ?
|
|
3741
|
+
off ? styles32.disabled : null
|
|
2921
3742
|
],
|
|
2922
3743
|
children: [
|
|
2923
|
-
/* @__PURE__ */
|
|
2924
|
-
/* @__PURE__ */
|
|
2925
|
-
o.description ? /* @__PURE__ */
|
|
3744
|
+
/* @__PURE__ */ jsx43(View36, { style: [styles32.cardCheck, { borderColor: checked ? theme.accent : theme.borderStrong, backgroundColor: checked ? theme.accent : theme.surface1 }], children: checked ? /* @__PURE__ */ jsx43(Check, { color: theme.onAccent }) : null }),
|
|
3745
|
+
/* @__PURE__ */ jsx43(Text15, { style: [styles32.cardLabel, { color: theme.textPrimary }], children: o.label }),
|
|
3746
|
+
o.description ? /* @__PURE__ */ jsx43(Text15, { style: [styles32.cardDescription, { color: theme.textSecondary }], children: o.description }) : null
|
|
2926
3747
|
]
|
|
2927
3748
|
},
|
|
2928
3749
|
o.value
|
|
2929
3750
|
);
|
|
2930
|
-
return /* @__PURE__ */
|
|
2931
|
-
/* @__PURE__ */
|
|
2932
|
-
/* @__PURE__ */
|
|
2933
|
-
/* @__PURE__ */
|
|
2934
|
-
o.description ? /* @__PURE__ */
|
|
3751
|
+
return /* @__PURE__ */ jsxs37(Pressable15, { role: "radio", "aria-checked": checked, "aria-label": name, "aria-disabled": off || void 0, disabled: off, onPress: () => pick(o.value), style: [styles32.row, off ? styles32.disabled : null], children: [
|
|
3752
|
+
/* @__PURE__ */ jsx43(View36, { style: [styles32.dot, { borderColor: checked ? theme.accent : theme.borderStrong, backgroundColor: checked ? theme.accent : theme.surface1 }], children: checked ? /* @__PURE__ */ jsx43(View36, { style: [styles32.dotIn, { backgroundColor: theme.onAccent }] }) : null }),
|
|
3753
|
+
/* @__PURE__ */ jsxs37(View36, { style: styles32.rowText, children: [
|
|
3754
|
+
/* @__PURE__ */ jsx43(Text15, { style: [styles32.rowLabel, { color: theme.textPrimary }], children: o.label }),
|
|
3755
|
+
o.description ? /* @__PURE__ */ jsx43(Text15, { style: [styles32.cardDescription, { color: theme.textSecondary }], children: o.description }) : null
|
|
2935
3756
|
] })
|
|
2936
3757
|
] }, o.value);
|
|
2937
3758
|
});
|
|
2938
|
-
return /* @__PURE__ */
|
|
2939
|
-
/* @__PURE__ */
|
|
2940
|
-
|
|
3759
|
+
return /* @__PURE__ */ jsxs37(View36, { style: [styles32.root, style], children: [
|
|
3760
|
+
/* @__PURE__ */ jsx43(
|
|
3761
|
+
View36,
|
|
2941
3762
|
{
|
|
2942
3763
|
role: "radiogroup",
|
|
2943
3764
|
"aria-label": label,
|
|
2944
|
-
style: variant === "segmented" ? [
|
|
3765
|
+
style: variant === "segmented" ? [styles32.track, { borderRadius: radius3.lg, backgroundColor: theme.surface2, borderColor: error ? theme.danger : theme.borderDefault }] : variant === "buttons" ? styles32.keys : variant === "cards" ? styles32.cards : styles32.list,
|
|
2945
3766
|
children: body
|
|
2946
3767
|
}
|
|
2947
3768
|
),
|
|
2948
|
-
error ? /* @__PURE__ */
|
|
3769
|
+
error ? /* @__PURE__ */ jsx43(Text15, { role: "alert", "aria-live": "polite", style: [styles32.error, { color: theme.dangerText }], children: error }) : null
|
|
2949
3770
|
] });
|
|
2950
3771
|
}
|
|
2951
|
-
var
|
|
3772
|
+
var styles32 = StyleSheet32.create({
|
|
2952
3773
|
root: { gap: 6, alignSelf: "stretch" },
|
|
2953
3774
|
list: { gap: 2 },
|
|
2954
3775
|
row: { flexDirection: "row", alignItems: "center", gap: 12, minHeight: 44 },
|
|
@@ -2967,38 +3788,41 @@ var styles21 = StyleSheet21.create({
|
|
|
2967
3788
|
key: { minHeight: 48, paddingHorizontal: 16, paddingVertical: 8, alignItems: "center", justifyContent: "center", gap: 1, borderWidth: 1 },
|
|
2968
3789
|
keyLabel: { fontSize: 15, fontWeight: "700" },
|
|
2969
3790
|
keyHint: { fontSize: 11, fontWeight: "500" },
|
|
2970
|
-
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth:
|
|
2971
|
-
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth:
|
|
3791
|
+
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet32.hairlineWidth, height: 42 },
|
|
3792
|
+
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet32.hairlineWidth, borderColor: "transparent" },
|
|
2972
3793
|
segmentLabel: { fontSize: 13, fontWeight: "600" },
|
|
2973
3794
|
error: { fontSize: 12, lineHeight: 16 },
|
|
2974
3795
|
disabled: { opacity: 0.4 }
|
|
2975
3796
|
});
|
|
2976
3797
|
|
|
2977
3798
|
// src/native/search-field.tsx
|
|
2978
|
-
import * as
|
|
2979
|
-
import { Pressable as
|
|
2980
|
-
import
|
|
2981
|
-
import { jsx as
|
|
2982
|
-
function SearchField({ label, value, defaultValue = "", onValueChange, onSearch, debounce = 300, onSubmit, clearLabel, style, placeholder, ...props }) {
|
|
3799
|
+
import * as React31 from "react";
|
|
3800
|
+
import { Pressable as Pressable16, StyleSheet as StyleSheet33, TextInput as TextInput5, View as View37 } from "react-native";
|
|
3801
|
+
import Svg19, { Circle as Circle12, Path as Path15 } from "react-native-svg";
|
|
3802
|
+
import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3803
|
+
function SearchField({ label, value, defaultValue = "", onValueChange, onSearch, debounce = 300, onSubmit, clearLabel, cancelLabel, onCancel, style, placeholder, onFocus, onBlur, ...props }) {
|
|
3804
|
+
const [focused, setFocused] = React31.useState(false);
|
|
3805
|
+
const input = React31.useRef(null);
|
|
2983
3806
|
const { theme, radius: radius3 } = useTheme();
|
|
2984
|
-
const [own, setOwn] =
|
|
3807
|
+
const [own, setOwn] = React31.useState(defaultValue);
|
|
2985
3808
|
const query = value ?? own;
|
|
2986
|
-
const timer2 =
|
|
2987
|
-
|
|
3809
|
+
const timer2 = React31.useRef(void 0);
|
|
3810
|
+
React31.useEffect(() => () => clearTimeout(timer2.current), []);
|
|
2988
3811
|
const change = (next) => {
|
|
2989
3812
|
if (value === void 0) setOwn(next);
|
|
2990
3813
|
onValueChange?.(next);
|
|
2991
3814
|
clearTimeout(timer2.current);
|
|
2992
3815
|
if (onSearch) timer2.current = setTimeout(() => onSearch(next), debounce);
|
|
2993
3816
|
};
|
|
2994
|
-
|
|
2995
|
-
/* @__PURE__ */
|
|
2996
|
-
/* @__PURE__ */
|
|
2997
|
-
/* @__PURE__ */
|
|
3817
|
+
const field = /* @__PURE__ */ jsxs38(View37, { style: [styles33.frame, { borderRadius: radius3.md, borderColor: theme.borderDefault, backgroundColor: theme.surface2 }, style], children: [
|
|
3818
|
+
/* @__PURE__ */ jsxs38(Svg19, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: theme.textSecondary, strokeWidth: 2, strokeLinecap: "round", "aria-hidden": true, children: [
|
|
3819
|
+
/* @__PURE__ */ jsx44(Circle12, { cx: 11, cy: 11, r: 7 }),
|
|
3820
|
+
/* @__PURE__ */ jsx44(Path15, { d: "m20 20-3.5-3.5" })
|
|
2998
3821
|
] }),
|
|
2999
|
-
/* @__PURE__ */
|
|
3000
|
-
|
|
3822
|
+
/* @__PURE__ */ jsx44(
|
|
3823
|
+
TextInput5,
|
|
3001
3824
|
{
|
|
3825
|
+
ref: input,
|
|
3002
3826
|
role: "searchbox",
|
|
3003
3827
|
"aria-label": label,
|
|
3004
3828
|
value: query,
|
|
@@ -3014,34 +3838,63 @@ function SearchField({ label, value, defaultValue = "", onValueChange, onSearch,
|
|
|
3014
3838
|
onSearch?.(query);
|
|
3015
3839
|
onSubmit?.(query);
|
|
3016
3840
|
},
|
|
3017
|
-
style: [
|
|
3841
|
+
style: [styles33.input, { color: theme.textPrimary }],
|
|
3842
|
+
onFocus: (e) => {
|
|
3843
|
+
setFocused(true);
|
|
3844
|
+
onFocus?.(e);
|
|
3845
|
+
},
|
|
3846
|
+
onBlur: (e) => {
|
|
3847
|
+
setFocused(false);
|
|
3848
|
+
onBlur?.(e);
|
|
3849
|
+
},
|
|
3018
3850
|
...props
|
|
3019
3851
|
}
|
|
3020
3852
|
),
|
|
3021
|
-
query ? /* @__PURE__ */
|
|
3853
|
+
query ? /* @__PURE__ */ jsx44(Pressable16, { role: "button", "aria-label": clearLabel, hitSlop: 10, onPress: () => change(""), style: styles33.clear, children: /* @__PURE__ */ jsx44(Svg19, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: theme.textSecondary, strokeWidth: 2.4, strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx44(Path15, { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
3854
|
+
] });
|
|
3855
|
+
if (!cancelLabel || !onCancel) return field;
|
|
3856
|
+
return /* @__PURE__ */ jsxs38(View37, { style: styles33.bar, children: [
|
|
3857
|
+
/* @__PURE__ */ jsx44(View37, { style: styles33.grow, children: field }),
|
|
3858
|
+
focused || query ? /* @__PURE__ */ jsx44(
|
|
3859
|
+
Pressable16,
|
|
3860
|
+
{
|
|
3861
|
+
role: "button",
|
|
3862
|
+
onPress: () => {
|
|
3863
|
+
change("");
|
|
3864
|
+
input.current?.blur();
|
|
3865
|
+
onCancel();
|
|
3866
|
+
},
|
|
3867
|
+
hitSlop: 8,
|
|
3868
|
+
style: styles33.cancel,
|
|
3869
|
+
children: /* @__PURE__ */ jsx44(Txt, { variant: "label", tone: "accent", children: cancelLabel })
|
|
3870
|
+
}
|
|
3871
|
+
) : null
|
|
3022
3872
|
] });
|
|
3023
3873
|
}
|
|
3024
|
-
var
|
|
3025
|
-
frame: { flexDirection: "row", alignItems: "center", gap: 8, height: 44, paddingLeft: 12, paddingRight: 6, borderWidth:
|
|
3874
|
+
var styles33 = StyleSheet33.create({
|
|
3875
|
+
frame: { flexDirection: "row", alignItems: "center", gap: 8, height: 44, paddingLeft: 12, paddingRight: 6, borderWidth: StyleSheet33.hairlineWidth },
|
|
3026
3876
|
input: { flex: 1, height: "100%", fontSize: 15, paddingVertical: 0 },
|
|
3877
|
+
bar: { flexDirection: "row", alignItems: "center", gap: 10 },
|
|
3878
|
+
grow: { flex: 1 },
|
|
3879
|
+
cancel: { minHeight: 44, justifyContent: "center" },
|
|
3027
3880
|
clear: { width: 32, height: 32, alignItems: "center", justifyContent: "center" }
|
|
3028
3881
|
});
|
|
3029
3882
|
|
|
3030
3883
|
// src/native/segmented.tsx
|
|
3031
|
-
import { Pressable as
|
|
3032
|
-
import { jsx as
|
|
3884
|
+
import { Pressable as Pressable17, StyleSheet as StyleSheet34, Text as Text16, View as View38 } from "react-native";
|
|
3885
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
3033
3886
|
function Segmented({ options, value, onValueChange, size = "md", "aria-label": label, style }) {
|
|
3034
3887
|
const { theme, radius: radius3 } = useTheme();
|
|
3035
|
-
return /* @__PURE__ */
|
|
3036
|
-
|
|
3888
|
+
return /* @__PURE__ */ jsx45(
|
|
3889
|
+
View38,
|
|
3037
3890
|
{
|
|
3038
3891
|
role: "tablist",
|
|
3039
3892
|
"aria-label": label,
|
|
3040
|
-
style: [
|
|
3893
|
+
style: [styles34.track, { backgroundColor: theme.surface2, borderColor: theme.borderSubtle, borderRadius: radius3.md, height: size === "sm" ? 32 : 40 }, style],
|
|
3041
3894
|
children: options.map((option) => {
|
|
3042
3895
|
const selected = option.value === value;
|
|
3043
|
-
return /* @__PURE__ */
|
|
3044
|
-
|
|
3896
|
+
return /* @__PURE__ */ jsx45(
|
|
3897
|
+
Pressable17,
|
|
3045
3898
|
{
|
|
3046
3899
|
role: "tab",
|
|
3047
3900
|
"aria-selected": selected,
|
|
@@ -3051,12 +3904,12 @@ function Segmented({ options, value, onValueChange, size = "md", "aria-label": l
|
|
|
3051
3904
|
if (!selected) onValueChange(option.value);
|
|
3052
3905
|
},
|
|
3053
3906
|
style: [
|
|
3054
|
-
|
|
3907
|
+
styles34.segment,
|
|
3055
3908
|
{ borderRadius: radius3.sm },
|
|
3056
3909
|
selected ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault } : null,
|
|
3057
|
-
option.disabled ?
|
|
3910
|
+
option.disabled ? styles34.disabled : null
|
|
3058
3911
|
],
|
|
3059
|
-
children: /* @__PURE__ */
|
|
3912
|
+
children: /* @__PURE__ */ jsx45(Text16, { numberOfLines: 1, style: [styles34.label, { color: selected ? theme.textPrimary : theme.textSecondary, fontSize: size === "sm" ? 12 : 13 }], children: option.label })
|
|
3060
3913
|
},
|
|
3061
3914
|
option.value
|
|
3062
3915
|
);
|
|
@@ -3064,17 +3917,17 @@ function Segmented({ options, value, onValueChange, size = "md", "aria-label": l
|
|
|
3064
3917
|
}
|
|
3065
3918
|
);
|
|
3066
3919
|
}
|
|
3067
|
-
var
|
|
3068
|
-
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth:
|
|
3069
|
-
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth:
|
|
3920
|
+
var styles34 = StyleSheet34.create({
|
|
3921
|
+
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet34.hairlineWidth },
|
|
3922
|
+
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet34.hairlineWidth, borderColor: "transparent" },
|
|
3070
3923
|
label: { fontWeight: "600" },
|
|
3071
3924
|
disabled: { opacity: 0.4 }
|
|
3072
3925
|
});
|
|
3073
3926
|
|
|
3074
3927
|
// src/native/skeleton.tsx
|
|
3075
|
-
import * as
|
|
3076
|
-
import { Animated as
|
|
3077
|
-
import { jsx as
|
|
3928
|
+
import * as React32 from "react";
|
|
3929
|
+
import { Animated as Animated18 } from "react-native";
|
|
3930
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
3078
3931
|
var SHAPE = {
|
|
3079
3932
|
text: { width: "100%", height: 12, radius: 4 },
|
|
3080
3933
|
circle: { width: 40, height: 40, radius: 9999 },
|
|
@@ -3083,13 +3936,13 @@ var SHAPE = {
|
|
|
3083
3936
|
function Skeleton({ shape = "text", width, height, style, testID }) {
|
|
3084
3937
|
const { theme } = useTheme();
|
|
3085
3938
|
const reduce = useReducedMotion();
|
|
3086
|
-
const [opacity] =
|
|
3087
|
-
|
|
3939
|
+
const [opacity] = React32.useState(() => new Animated18.Value(1));
|
|
3940
|
+
React32.useEffect(() => {
|
|
3088
3941
|
if (reduce) return;
|
|
3089
|
-
const loop =
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3942
|
+
const loop = Animated18.loop(
|
|
3943
|
+
Animated18.sequence([
|
|
3944
|
+
Animated18.timing(opacity, { toValue: 0.5, duration: 900, useNativeDriver: true }),
|
|
3945
|
+
Animated18.timing(opacity, { toValue: 1, duration: 900, useNativeDriver: true })
|
|
3093
3946
|
])
|
|
3094
3947
|
);
|
|
3095
3948
|
loop.start();
|
|
@@ -3100,8 +3953,8 @@ function Skeleton({ shape = "text", width, height, style, testID }) {
|
|
|
3100
3953
|
}, [reduce, opacity]);
|
|
3101
3954
|
const s = SHAPE[shape];
|
|
3102
3955
|
const side = shape === "circle" ? width ?? height ?? s.width : void 0;
|
|
3103
|
-
return /* @__PURE__ */
|
|
3104
|
-
|
|
3956
|
+
return /* @__PURE__ */ jsx46(
|
|
3957
|
+
Animated18.View,
|
|
3105
3958
|
{
|
|
3106
3959
|
testID,
|
|
3107
3960
|
"aria-hidden": true,
|
|
@@ -3114,10 +3967,10 @@ function Skeleton({ shape = "text", width, height, style, testID }) {
|
|
|
3114
3967
|
}
|
|
3115
3968
|
|
|
3116
3969
|
// src/native/slider.tsx
|
|
3117
|
-
import * as
|
|
3118
|
-
import { PanResponder, StyleSheet as
|
|
3119
|
-
import
|
|
3120
|
-
import { jsx as
|
|
3970
|
+
import * as React33 from "react";
|
|
3971
|
+
import { PanResponder as PanResponder2, StyleSheet as StyleSheet35, Text as Text17, View as View39 } from "react-native";
|
|
3972
|
+
import Svg20, { Defs as Defs11, LinearGradient as LinearGradient11, Rect as Rect4, Stop as Stop11 } from "react-native-svg";
|
|
3973
|
+
import { jsx as jsx47, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3121
3974
|
var THUMB = 26;
|
|
3122
3975
|
var toArray = (v) => v === void 0 ? void 0 : typeof v === "number" ? [v] : [...v];
|
|
3123
3976
|
function Slider({
|
|
@@ -3135,7 +3988,7 @@ function Slider({
|
|
|
3135
3988
|
floatingValue,
|
|
3136
3989
|
ticks,
|
|
3137
3990
|
marks: marks2,
|
|
3138
|
-
tone:
|
|
3991
|
+
tone: tone3 = "gradient",
|
|
3139
3992
|
orientation = "horizontal",
|
|
3140
3993
|
disabled,
|
|
3141
3994
|
style
|
|
@@ -3143,20 +3996,20 @@ function Slider({
|
|
|
3143
3996
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
3144
3997
|
const range = Array.isArray(value ?? defaultValue);
|
|
3145
3998
|
const vertical = orientation === "vertical";
|
|
3146
|
-
const [inner, setInner] =
|
|
3999
|
+
const [inner, setInner] = React33.useState(() => toArray(defaultValue) ?? [min]);
|
|
3147
4000
|
const current = toArray(value) ?? inner;
|
|
3148
|
-
const [length, setLength] =
|
|
3149
|
-
const [dragging, setDragging] =
|
|
4001
|
+
const [length, setLength] = React33.useState(0);
|
|
4002
|
+
const [dragging, setDragging] = React33.useState(null);
|
|
3150
4003
|
const gradientId = useSvgId("kzs");
|
|
3151
4004
|
const out = (next) => range ? [next[0], next[1]] : next[0];
|
|
3152
4005
|
const snap = (v) => Math.min(max, Math.max(min, Math.round((v - min) / step) * step + min));
|
|
3153
4006
|
const pct = (v) => (v - min) / (max - min || 1);
|
|
3154
|
-
const live =
|
|
3155
|
-
|
|
4007
|
+
const live = React33.useRef({ current, length, vertical, disabled });
|
|
4008
|
+
React33.useLayoutEffect(() => {
|
|
3156
4009
|
live.current = { current, length, vertical, disabled };
|
|
3157
4010
|
});
|
|
3158
|
-
const active =
|
|
3159
|
-
const start =
|
|
4011
|
+
const active = React33.useRef(0);
|
|
4012
|
+
const start = React33.useRef(0);
|
|
3160
4013
|
const set = (next) => {
|
|
3161
4014
|
if (value === void 0) setInner(next);
|
|
3162
4015
|
onValueChange?.(out(next));
|
|
@@ -3177,12 +4030,12 @@ function Slider({
|
|
|
3177
4030
|
return min + p * (max - min);
|
|
3178
4031
|
};
|
|
3179
4032
|
const commit = () => onValueCommit?.(out(live.current.current));
|
|
3180
|
-
const handlers =
|
|
3181
|
-
|
|
4033
|
+
const handlers = React33.useRef({ move, at, commit });
|
|
4034
|
+
React33.useLayoutEffect(() => {
|
|
3182
4035
|
handlers.current = { move, at, commit };
|
|
3183
4036
|
});
|
|
3184
|
-
const [responder] =
|
|
3185
|
-
() =>
|
|
4037
|
+
const [responder] = React33.useState(
|
|
4038
|
+
() => PanResponder2.create({
|
|
3186
4039
|
onStartShouldSetPanResponder: () => !live.current.disabled,
|
|
3187
4040
|
onMoveShouldSetPanResponder: () => !live.current.disabled,
|
|
3188
4041
|
onPanResponderTerminationRequest: () => false,
|
|
@@ -3209,24 +4062,24 @@ function Slider({
|
|
|
3209
4062
|
const along = (p) => vertical ? { bottom: p * length } : { left: p * length };
|
|
3210
4063
|
const onLayout = (e) => setLength(vertical ? e.nativeEvent.layout.height : e.nativeEvent.layout.width);
|
|
3211
4064
|
const fill = vertical ? { bottom: pct(lo) * length, height: (pct(hi) - pct(lo)) * length, left: 0, right: 0 } : { left: pct(lo) * length, width: (pct(hi) - pct(lo)) * length, top: 0, bottom: 0 };
|
|
3212
|
-
return /* @__PURE__ */
|
|
3213
|
-
showLabel ? /* @__PURE__ */
|
|
3214
|
-
/* @__PURE__ */
|
|
3215
|
-
/* @__PURE__ */
|
|
4065
|
+
return /* @__PURE__ */ jsxs39(View39, { style: [styles35.root, vertical ? styles35.rootVertical : null, disabled ? styles35.disabled : null, style], children: [
|
|
4066
|
+
showLabel ? /* @__PURE__ */ jsxs39(View39, { style: styles35.header, children: [
|
|
4067
|
+
/* @__PURE__ */ jsx47(Text17, { style: [styles35.label, { color: theme.textSecondary }], children: label }),
|
|
4068
|
+
/* @__PURE__ */ jsx47(Text17, { "aria-hidden": true, style: [styles35.value, { color: theme.textSecondary }], children: current.map(formatValue).join(" \u2013 ") })
|
|
3216
4069
|
] }) : null,
|
|
3217
|
-
/* @__PURE__ */
|
|
3218
|
-
/* @__PURE__ */
|
|
3219
|
-
/* @__PURE__ */
|
|
3220
|
-
/* @__PURE__ */
|
|
3221
|
-
/* @__PURE__ */
|
|
3222
|
-
/* @__PURE__ */
|
|
4070
|
+
/* @__PURE__ */ jsxs39(View39, { ...responder.panHandlers, style: vertical ? styles35.controlVertical : styles35.control, children: [
|
|
4071
|
+
/* @__PURE__ */ jsxs39(View39, { onLayout, pointerEvents: "none", style: [vertical ? styles35.trackVertical : styles35.track, { borderRadius: radius3.full, backgroundColor: theme.surface3 }], children: [
|
|
4072
|
+
/* @__PURE__ */ jsx47(View39, { style: [styles35.fill, fill, { borderRadius: radius3.full, overflow: "hidden", backgroundColor: theme.accent }], children: tone3 === "gradient" ? /* @__PURE__ */ jsxs39(Svg20, { width: "100%", height: "100%", "aria-hidden": true, children: [
|
|
4073
|
+
/* @__PURE__ */ jsx47(Defs11, { children: /* @__PURE__ */ jsxs39(LinearGradient11, { id: gradientId, x1: "0", y1: vertical ? "1" : "0", x2: vertical ? "0" : "1", y2: "0", children: [
|
|
4074
|
+
/* @__PURE__ */ jsx47(Stop11, { offset: "0", stopColor: theme.accent }),
|
|
4075
|
+
/* @__PURE__ */ jsx47(Stop11, { offset: "1", stopColor: theme.accent2 })
|
|
3223
4076
|
] }) }),
|
|
3224
|
-
/* @__PURE__ */
|
|
4077
|
+
/* @__PURE__ */ jsx47(Rect4, { width: "100%", height: "100%", fill: `url(#${gradientId})` })
|
|
3225
4078
|
] }) : null }),
|
|
3226
|
-
tickValues.map((t) => /* @__PURE__ */
|
|
4079
|
+
tickValues.map((t) => /* @__PURE__ */ jsx47(View39, { style: [vertical ? styles35.tickVertical : styles35.tick, along(pct(t)), { backgroundColor: t > lo && t < hi ? theme.onAccent : theme.borderStrong }] }, t))
|
|
3227
4080
|
] }),
|
|
3228
|
-
current.map((v, i) => /* @__PURE__ */
|
|
3229
|
-
|
|
4081
|
+
current.map((v, i) => /* @__PURE__ */ jsx47(
|
|
4082
|
+
View39,
|
|
3230
4083
|
{
|
|
3231
4084
|
accessible: true,
|
|
3232
4085
|
role: "slider",
|
|
@@ -3245,16 +4098,16 @@ function Slider({
|
|
|
3245
4098
|
onValueCommit?.(out(values));
|
|
3246
4099
|
},
|
|
3247
4100
|
pointerEvents: "none",
|
|
3248
|
-
style: [
|
|
3249
|
-
children: floatingValue === "always" || floatingValue && dragging === i ? /* @__PURE__ */
|
|
4101
|
+
style: [styles35.thumb, vertical ? { bottom: pct(v) * length, left: (44 - THUMB) / 2, marginLeft: 0, marginTop: 0 } : { left: pct(v) * length - THUMB / 2, top: 0 }, { borderColor: theme.accent, backgroundColor: theme.textOnMedia, shadowColor: theme.scrimStrong }],
|
|
4102
|
+
children: floatingValue === "always" || floatingValue && dragging === i ? /* @__PURE__ */ jsx47(View39, { "aria-hidden": true, style: [vertical ? styles35.bubbleVertical : styles35.bubble, { backgroundColor: theme.textPrimary, borderRadius: radius3.md }], children: /* @__PURE__ */ jsx47(Text17, { style: [styles35.bubbleText, { color: theme.surface0 }], children: formatValue(v) }) }) : null
|
|
3250
4103
|
},
|
|
3251
4104
|
i
|
|
3252
4105
|
))
|
|
3253
4106
|
] }),
|
|
3254
|
-
marks2?.length && !vertical ? /* @__PURE__ */
|
|
4107
|
+
marks2?.length && !vertical ? /* @__PURE__ */ jsx47(View39, { "aria-hidden": true, style: styles35.marks, children: marks2.map((m) => /* @__PURE__ */ jsx47(Text17, { style: [styles35.mark, { left: pct(m.value) * length, color: theme.textSecondary, transform: [{ translateX: m.value === min ? 0 : m.value === max ? -40 : -20 }], textAlign: m.value === min ? "left" : m.value === max ? "right" : "center" }], children: m.label }, m.value)) }) : null
|
|
3255
4108
|
] });
|
|
3256
4109
|
}
|
|
3257
|
-
var
|
|
4110
|
+
var styles35 = StyleSheet35.create({
|
|
3258
4111
|
root: { gap: 8, alignSelf: "stretch" },
|
|
3259
4112
|
rootVertical: { alignSelf: "flex-start", alignItems: "center" },
|
|
3260
4113
|
header: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 },
|
|
@@ -3290,10 +4143,10 @@ var styles24 = StyleSheet24.create({
|
|
|
3290
4143
|
|
|
3291
4144
|
// src/native/spinner.tsx
|
|
3292
4145
|
import { ActivityIndicator as ActivityIndicator2 } from "react-native";
|
|
3293
|
-
import { jsx as
|
|
4146
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
3294
4147
|
function Spinner({ label, size = "md", ...props }) {
|
|
3295
4148
|
const { theme } = useTheme();
|
|
3296
|
-
return /* @__PURE__ */
|
|
4149
|
+
return /* @__PURE__ */ jsx48(
|
|
3297
4150
|
ActivityIndicator2,
|
|
3298
4151
|
{
|
|
3299
4152
|
accessible: true,
|
|
@@ -3307,31 +4160,162 @@ function Spinner({ label, size = "md", ...props }) {
|
|
|
3307
4160
|
);
|
|
3308
4161
|
}
|
|
3309
4162
|
|
|
4163
|
+
// src/native/stepper.tsx
|
|
4164
|
+
import { StyleSheet as StyleSheet36, View as View40 } from "react-native";
|
|
4165
|
+
import Svg21, { Circle as Circle13, Path as Path16 } from "react-native-svg";
|
|
4166
|
+
import { jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
4167
|
+
var WORDS = { done: "done", current: "in progress", upcoming: "to come", error: "failed" };
|
|
4168
|
+
function Stepper({ steps, current = 0, orientation = "vertical", statusLabels, "aria-label": label, style }) {
|
|
4169
|
+
const { theme } = useTheme();
|
|
4170
|
+
const words = { ...WORDS, ...statusLabels };
|
|
4171
|
+
const vertical = orientation === "vertical";
|
|
4172
|
+
return /* @__PURE__ */ jsx49(View40, { role: "list", "aria-label": label, style: [vertical ? styles36.column : styles36.row, style], children: steps.map((step, i) => {
|
|
4173
|
+
const status = step.status ?? (i < current ? "done" : i === current ? "current" : "upcoming");
|
|
4174
|
+
const last = i === steps.length - 1;
|
|
4175
|
+
const node = status === "current" ? /* @__PURE__ */ jsx49(LoaderGlyph, { value: step.value ?? null, size: 24 }) : status === "error" ? /* @__PURE__ */ jsx49(LoaderGlyph, { state: "error", size: 24 }) : /* @__PURE__ */ jsxs40(Svg21, { width: 24, height: 24, viewBox: "0 0 24 24", "aria-hidden": true, children: [
|
|
4176
|
+
/* @__PURE__ */ jsx49(Circle13, { cx: 12, cy: 12, r: 10, fill: status === "done" ? theme.accent : "none", stroke: status === "done" ? theme.accent : theme.borderStrong, strokeWidth: 2 }),
|
|
4177
|
+
status === "done" ? /* @__PURE__ */ jsx49(Path16, { d: "M7.5 12.3l3 3 6-6.3", stroke: theme.onAccent, strokeWidth: 2.2, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) : null
|
|
4178
|
+
] });
|
|
4179
|
+
const connector = !last ? /* @__PURE__ */ jsx49(View40, { "aria-hidden": true, style: [vertical ? styles36.vLine : styles36.hLine, { backgroundColor: status === "done" ? theme.accent : theme.borderDefault }] }) : null;
|
|
4180
|
+
return /* @__PURE__ */ jsxs40(View40, { role: "listitem", accessible: true, "aria-label": `${step.title}, ${words[status]}`, style: vertical ? styles36.vStep : styles36.hStep, children: [
|
|
4181
|
+
/* @__PURE__ */ jsxs40(View40, { style: vertical ? styles36.vRail : styles36.hRail, children: [
|
|
4182
|
+
node,
|
|
4183
|
+
connector
|
|
4184
|
+
] }),
|
|
4185
|
+
/* @__PURE__ */ jsxs40(View40, { style: [styles36.body, vertical && !last ? { paddingBottom: 20 } : null], children: [
|
|
4186
|
+
/* @__PURE__ */ jsx49(Txt, { variant: "label", tone: status === "upcoming" ? "secondary" : "text", numberOfLines: vertical ? void 0 : 2, children: step.title }),
|
|
4187
|
+
step.description ? /* @__PURE__ */ jsx49(Txt, { variant: "caption", tone: "secondary", children: step.description }) : null,
|
|
4188
|
+
step.content && (status === "current" || status === "error") ? /* @__PURE__ */ jsx49(View40, { style: styles36.content, children: step.content }) : null
|
|
4189
|
+
] })
|
|
4190
|
+
] }, i);
|
|
4191
|
+
}) });
|
|
4192
|
+
}
|
|
4193
|
+
var styles36 = StyleSheet36.create({
|
|
4194
|
+
column: { gap: 0 },
|
|
4195
|
+
row: { flexDirection: "row" },
|
|
4196
|
+
vStep: { flexDirection: "row", gap: 12 },
|
|
4197
|
+
hStep: { flex: 1, gap: 8 },
|
|
4198
|
+
vRail: { alignItems: "center", width: 24 },
|
|
4199
|
+
hRail: { flexDirection: "row", alignItems: "center" },
|
|
4200
|
+
vLine: { width: 2, flex: 1, marginVertical: 4, borderRadius: 1 },
|
|
4201
|
+
hLine: { height: 2, flex: 1, marginHorizontal: 6, borderRadius: 1 },
|
|
4202
|
+
body: { flex: 1, gap: 2, paddingTop: 2 },
|
|
4203
|
+
content: { marginTop: 8 }
|
|
4204
|
+
});
|
|
4205
|
+
|
|
4206
|
+
// src/native/swipeable-row.tsx
|
|
4207
|
+
import * as React34 from "react";
|
|
4208
|
+
import { Animated as Animated19, PanResponder as PanResponder3, Pressable as Pressable18, StyleSheet as StyleSheet37, View as View41 } from "react-native";
|
|
4209
|
+
import { jsx as jsx50, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
4210
|
+
var toneColor = (t, tone3) => ({ neutral: t.surface3, accent: t.accent, success: t.success, warning: t.warning, danger: t.danger })[tone3 ?? "neutral"];
|
|
4211
|
+
var toneText = (tone3) => tone3 === "neutral" || tone3 === void 0 ? "text" : "onAccent";
|
|
4212
|
+
function SwipeableRow({ children, trailing = [], leading = [], fullSwipe = 0.6, actionWidth = 80, onActivate, testID, style }) {
|
|
4213
|
+
const { theme, haptic } = useTheme();
|
|
4214
|
+
const reduce = useReducedMotion();
|
|
4215
|
+
const [x] = React34.useState(() => new Animated19.Value(0));
|
|
4216
|
+
const [width, setWidth] = React34.useState(0);
|
|
4217
|
+
const rest = React34.useRef(0);
|
|
4218
|
+
const armed = React34.useRef(false);
|
|
4219
|
+
const settle = (to) => {
|
|
4220
|
+
rest.current = to;
|
|
4221
|
+
if (reduce) x.setValue(to);
|
|
4222
|
+
else Animated19.spring(x, { toValue: to, useNativeDriver: true, damping: 22, stiffness: 240 }).start();
|
|
4223
|
+
};
|
|
4224
|
+
const run = (action) => {
|
|
4225
|
+
settle(0);
|
|
4226
|
+
action.onPress();
|
|
4227
|
+
};
|
|
4228
|
+
const pan = React34.useMemo(
|
|
4229
|
+
() => PanResponder3.create({
|
|
4230
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy) * 1.5,
|
|
4231
|
+
onPanResponderMove: (_, g) => {
|
|
4232
|
+
let next = rest.current + g.dx;
|
|
4233
|
+
if (next < 0 && trailing.length === 0) next = 0;
|
|
4234
|
+
if (next > 0 && leading.length === 0) next = 0;
|
|
4235
|
+
x.setValue(next);
|
|
4236
|
+
const past = fullSwipe !== false && width > 0 && Math.abs(next) > width * fullSwipe;
|
|
4237
|
+
if (past !== armed.current) {
|
|
4238
|
+
armed.current = past;
|
|
4239
|
+
if (past) haptic("impact");
|
|
4240
|
+
}
|
|
4241
|
+
},
|
|
4242
|
+
onPanResponderRelease: (_, g) => {
|
|
4243
|
+
const at = rest.current + g.dx;
|
|
4244
|
+
if (armed.current) {
|
|
4245
|
+
armed.current = false;
|
|
4246
|
+
const action = at < 0 ? trailing[0] : leading[0];
|
|
4247
|
+
if (action) return run(action);
|
|
4248
|
+
}
|
|
4249
|
+
const open = at < 0 ? -trailing.length * actionWidth : leading.length * actionWidth;
|
|
4250
|
+
settle(Math.abs(at) > actionWidth / 2 ? open : 0);
|
|
4251
|
+
},
|
|
4252
|
+
onPanResponderTerminate: () => settle(0)
|
|
4253
|
+
}),
|
|
4254
|
+
[trailing, leading, fullSwipe, width, actionWidth]
|
|
4255
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- run/settle are stable in effect
|
|
4256
|
+
);
|
|
4257
|
+
const side = (actions, edge) => /* @__PURE__ */ jsx50(View41, { "aria-hidden": true, style: [styles37.side, edge === "left" ? { left: 0 } : { right: 0, flexDirection: "row-reverse" }], children: actions.map((action, i) => (
|
|
4258
|
+
// eslint-disable-next-line react-hooks/refs -- runs on a press, never during render
|
|
4259
|
+
/* @__PURE__ */ jsxs41(Pressable18, { focusable: false, tabIndex: -1, onPress: () => run(action), style: [styles37.action, { width: actionWidth, backgroundColor: toneColor(theme, action.tone) }], children: [
|
|
4260
|
+
action.icon,
|
|
4261
|
+
/* @__PURE__ */ jsx50(Txt, { variant: "caption", tone: toneText(action.tone), style: styles37.actionText, numberOfLines: 1, children: action.label })
|
|
4262
|
+
] }, i)
|
|
4263
|
+
)) });
|
|
4264
|
+
const all = [...leading, ...trailing];
|
|
4265
|
+
return /* @__PURE__ */ jsxs41(View41, { style: [styles37.root, style], onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
|
|
4266
|
+
leading.length > 0 ? side(leading, "left") : null,
|
|
4267
|
+
trailing.length > 0 ? side(trailing, "right") : null,
|
|
4268
|
+
/* @__PURE__ */ jsx50(
|
|
4269
|
+
Animated19.View,
|
|
4270
|
+
{
|
|
4271
|
+
...pan.panHandlers,
|
|
4272
|
+
accessible: true,
|
|
4273
|
+
testID,
|
|
4274
|
+
accessibilityActions: [...onActivate ? [{ name: "activate" }] : [], ...all.map((a) => ({ name: a.label, label: a.label }))],
|
|
4275
|
+
onAccessibilityAction: (e) => {
|
|
4276
|
+
if (e.nativeEvent.actionName === "activate") return onActivate?.();
|
|
4277
|
+
const action = all.find((a) => a.label === e.nativeEvent.actionName);
|
|
4278
|
+
if (action) action.onPress();
|
|
4279
|
+
},
|
|
4280
|
+
style: [styles37.front, { backgroundColor: theme.surface0, transform: [{ translateX: x }] }],
|
|
4281
|
+
children
|
|
4282
|
+
}
|
|
4283
|
+
)
|
|
4284
|
+
] });
|
|
4285
|
+
}
|
|
4286
|
+
var styles37 = StyleSheet37.create({
|
|
4287
|
+
root: { overflow: "hidden" },
|
|
4288
|
+
side: { position: "absolute", top: 0, bottom: 0, flexDirection: "row" },
|
|
4289
|
+
action: { alignItems: "center", justifyContent: "center", gap: 4, paddingHorizontal: 6 },
|
|
4290
|
+
actionText: { fontWeight: "700" },
|
|
4291
|
+
front: {}
|
|
4292
|
+
});
|
|
4293
|
+
|
|
3310
4294
|
// src/native/switch.tsx
|
|
3311
|
-
import * as
|
|
3312
|
-
import { Animated as
|
|
3313
|
-
import { jsx as
|
|
4295
|
+
import * as React35 from "react";
|
|
4296
|
+
import { Animated as Animated20, Pressable as Pressable19, StyleSheet as StyleSheet38, Text as Text18, View as View42 } from "react-native";
|
|
4297
|
+
import { jsx as jsx51, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3314
4298
|
var SIZES = { sm: { w: 40, h: 24, knob: 18 }, md: { w: 52, h: 32, knob: 26 } };
|
|
3315
4299
|
function Switch({ label, checked, defaultChecked = false, onCheckedChange, description, showLabel, size = "md", error, disabled, style }) {
|
|
3316
4300
|
const { theme, motion: motion3, haptic } = useTheme();
|
|
3317
|
-
const [own, setOwn] =
|
|
4301
|
+
const [own, setOwn] = React35.useState(defaultChecked);
|
|
3318
4302
|
const on = checked ?? own;
|
|
3319
4303
|
const d = SIZES[size];
|
|
3320
4304
|
const travel = d.w - d.knob - (d.h - d.knob);
|
|
3321
|
-
const [x] =
|
|
3322
|
-
|
|
3323
|
-
|
|
4305
|
+
const [x] = React35.useState(() => new Animated20.Value(on ? 1 : 0));
|
|
4306
|
+
React35.useEffect(() => {
|
|
4307
|
+
Animated20.timing(x, { toValue: on ? 1 : 0, duration: motion3.duration.base, useNativeDriver: true }).start();
|
|
3324
4308
|
}, [on, x, motion3.duration.base]);
|
|
3325
4309
|
const toggle = () => {
|
|
3326
4310
|
haptic("selection");
|
|
3327
4311
|
if (checked === void 0) setOwn(!on);
|
|
3328
4312
|
onCheckedChange?.(!on);
|
|
3329
4313
|
};
|
|
3330
|
-
const track = /* @__PURE__ */
|
|
3331
|
-
|
|
4314
|
+
const track = /* @__PURE__ */ jsx51(View42, { style: [styles38.track, { width: d.w, height: d.h, borderRadius: d.h / 2, backgroundColor: on ? theme.accent : theme.surface3, borderColor: error ? theme.danger : on ? theme.accent : theme.borderDefault }], children: /* @__PURE__ */ jsx51(
|
|
4315
|
+
Animated20.View,
|
|
3332
4316
|
{
|
|
3333
4317
|
style: [
|
|
3334
|
-
|
|
4318
|
+
styles38.knob,
|
|
3335
4319
|
{
|
|
3336
4320
|
width: d.knob,
|
|
3337
4321
|
height: d.knob,
|
|
@@ -3353,19 +4337,19 @@ function Switch({ label, checked, defaultChecked = false, onCheckedChange, descr
|
|
|
3353
4337
|
onPress: toggle
|
|
3354
4338
|
};
|
|
3355
4339
|
if (!showLabel)
|
|
3356
|
-
return /* @__PURE__ */
|
|
3357
|
-
return /* @__PURE__ */
|
|
3358
|
-
/* @__PURE__ */
|
|
3359
|
-
/* @__PURE__ */
|
|
3360
|
-
/* @__PURE__ */
|
|
3361
|
-
description ? /* @__PURE__ */
|
|
4340
|
+
return /* @__PURE__ */ jsx51(Pressable19, { ...a11y, hitSlop: { top: (44 - d.h) / 2, bottom: (44 - d.h) / 2, left: Math.max(0, (44 - d.w) / 2), right: Math.max(0, (44 - d.w) / 2) }, style: [disabled ? styles38.disabled : null, style], children: track });
|
|
4341
|
+
return /* @__PURE__ */ jsxs42(View42, { style: [styles38.root, style], children: [
|
|
4342
|
+
/* @__PURE__ */ jsxs42(Pressable19, { ...a11y, style: [styles38.row, disabled ? styles38.disabled : null], children: [
|
|
4343
|
+
/* @__PURE__ */ jsxs42(View42, { style: styles38.text, children: [
|
|
4344
|
+
/* @__PURE__ */ jsx51(Text18, { style: [styles38.label, { color: theme.textPrimary }], children: label }),
|
|
4345
|
+
description ? /* @__PURE__ */ jsx51(Text18, { style: [styles38.description, { color: theme.textSecondary }], children: description }) : null
|
|
3362
4346
|
] }),
|
|
3363
4347
|
track
|
|
3364
4348
|
] }),
|
|
3365
|
-
error ? /* @__PURE__ */
|
|
4349
|
+
error ? /* @__PURE__ */ jsx51(Text18, { role: "alert", "aria-live": "polite", style: [styles38.description, { color: theme.dangerText }], children: error }) : null
|
|
3366
4350
|
] });
|
|
3367
4351
|
}
|
|
3368
|
-
var
|
|
4352
|
+
var styles38 = StyleSheet38.create({
|
|
3369
4353
|
root: { gap: 2, alignSelf: "stretch" },
|
|
3370
4354
|
row: { flexDirection: "row", alignItems: "center", gap: 16, minHeight: 48 },
|
|
3371
4355
|
text: { flex: 1, gap: 2 },
|
|
@@ -3376,10 +4360,109 @@ var styles25 = StyleSheet25.create({
|
|
|
3376
4360
|
disabled: { opacity: 0.4 }
|
|
3377
4361
|
});
|
|
3378
4362
|
|
|
4363
|
+
// src/native/tab-bar.tsx
|
|
4364
|
+
import { Pressable as Pressable20, StyleSheet as StyleSheet39, Text as Text19, View as View43 } from "react-native";
|
|
4365
|
+
import { jsx as jsx52, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
4366
|
+
function TabBar({ items: items2, value, onValueChange, onReselect, "aria-label": label, style }) {
|
|
4367
|
+
const { theme, insets, haptic } = useTheme();
|
|
4368
|
+
return /* @__PURE__ */ jsx52(View43, { role: "tablist", "aria-label": label, style: [styles39.bar, { backgroundColor: theme.glassBg, borderTopColor: theme.glassBorder, paddingBottom: Math.max(6, insets.bottom) }, style], children: items2.map((item) => {
|
|
4369
|
+
const selected = item.value === value;
|
|
4370
|
+
const color = selected ? theme.accentText : theme.textSecondary;
|
|
4371
|
+
const badge = item.badge === true ? "" : typeof item.badge === "number" && item.badge > 0 ? item.badge > 99 ? "99+" : String(item.badge) : null;
|
|
4372
|
+
return /* @__PURE__ */ jsxs43(
|
|
4373
|
+
Pressable20,
|
|
4374
|
+
{
|
|
4375
|
+
role: "tab",
|
|
4376
|
+
"aria-selected": selected,
|
|
4377
|
+
onPress: () => {
|
|
4378
|
+
haptic("selection");
|
|
4379
|
+
if (selected) onReselect?.(item.value);
|
|
4380
|
+
else onValueChange(item.value);
|
|
4381
|
+
},
|
|
4382
|
+
style: ({ pressed }) => [styles39.item, { opacity: pressed ? 0.7 : 1 }],
|
|
4383
|
+
children: [
|
|
4384
|
+
/* @__PURE__ */ jsxs43(View43, { "aria-hidden": true, style: styles39.icon, children: [
|
|
4385
|
+
item.icon(selected, color),
|
|
4386
|
+
badge !== null ? /* @__PURE__ */ jsx52(View43, { style: [badge ? styles39.count : styles39.dot, { backgroundColor: theme.danger, borderColor: theme.surface1 }], children: badge ? /* @__PURE__ */ jsx52(Text19, { style: [styles39.countText, { color: theme.onAccent }], children: badge }) : null }) : null
|
|
4387
|
+
] }),
|
|
4388
|
+
/* @__PURE__ */ jsx52(Text19, { numberOfLines: 1, style: [styles39.label, { color, fontWeight: selected ? "700" : "500" }], children: item.label }),
|
|
4389
|
+
badge !== null && item.badgeLabel ? /* @__PURE__ */ jsx52(Text19, { style: styles39.unseen, children: `, ${item.badgeLabel}` }) : null
|
|
4390
|
+
]
|
|
4391
|
+
},
|
|
4392
|
+
item.value
|
|
4393
|
+
);
|
|
4394
|
+
}) });
|
|
4395
|
+
}
|
|
4396
|
+
var styles39 = StyleSheet39.create({
|
|
4397
|
+
bar: { flexDirection: "row", borderTopWidth: StyleSheet39.hairlineWidth, paddingTop: 6 },
|
|
4398
|
+
item: { flex: 1, alignItems: "center", gap: 2, minHeight: 48, justifyContent: "center" },
|
|
4399
|
+
icon: { width: 28, height: 26, alignItems: "center", justifyContent: "center" },
|
|
4400
|
+
label: { fontSize: 11, lineHeight: 14 },
|
|
4401
|
+
unseen: { position: "absolute", width: 1, height: 1, overflow: "hidden", opacity: 0 },
|
|
4402
|
+
count: { position: "absolute", top: -4, left: 16, minWidth: 18, height: 18, borderRadius: 9, paddingHorizontal: 4, alignItems: "center", justifyContent: "center", borderWidth: 2 },
|
|
4403
|
+
countText: { fontSize: 10, fontWeight: "800", lineHeight: 12 },
|
|
4404
|
+
dot: { position: "absolute", top: 0, right: 0, width: 10, height: 10, borderRadius: 5, borderWidth: 2 }
|
|
4405
|
+
});
|
|
4406
|
+
|
|
4407
|
+
// src/native/tabs.tsx
|
|
4408
|
+
import * as React36 from "react";
|
|
4409
|
+
import { Pressable as Pressable21, ScrollView as ScrollView6, StyleSheet as StyleSheet40, View as View44 } from "react-native";
|
|
4410
|
+
import { jsx as jsx53, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4411
|
+
function Tabs({ items: items2, value, defaultValue, onValueChange, "aria-label": label, variant = "underline", style }) {
|
|
4412
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
4413
|
+
const [own, setOwn] = React36.useState(defaultValue ?? items2[0]?.value);
|
|
4414
|
+
const current = value ?? own;
|
|
4415
|
+
const select = (next) => {
|
|
4416
|
+
if (next === current) return;
|
|
4417
|
+
haptic("selection");
|
|
4418
|
+
if (value === void 0) setOwn(next);
|
|
4419
|
+
onValueChange?.(next);
|
|
4420
|
+
};
|
|
4421
|
+
const segmented = variant === "segmented";
|
|
4422
|
+
const tabs = items2.map((item) => {
|
|
4423
|
+
const selected = item.value === current;
|
|
4424
|
+
return /* @__PURE__ */ jsx53(
|
|
4425
|
+
Pressable21,
|
|
4426
|
+
{
|
|
4427
|
+
role: "tab",
|
|
4428
|
+
"aria-selected": selected,
|
|
4429
|
+
"aria-disabled": item.disabled,
|
|
4430
|
+
disabled: item.disabled,
|
|
4431
|
+
onPress: () => select(item.value),
|
|
4432
|
+
style: [
|
|
4433
|
+
segmented ? styles40.segment : styles40.tab,
|
|
4434
|
+
segmented && selected ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault, borderRadius: radius3.sm } : null,
|
|
4435
|
+
!segmented ? { borderBottomColor: selected ? theme.accent : "transparent" } : null,
|
|
4436
|
+
item.disabled ? styles40.disabled : null
|
|
4437
|
+
],
|
|
4438
|
+
children: /* @__PURE__ */ jsxs44(Txt, { variant: "label", tone: selected ? "text" : "secondary", numberOfLines: 1, children: [
|
|
4439
|
+
item.label,
|
|
4440
|
+
item.count !== void 0 ? /* @__PURE__ */ jsx53(Txt, { variant: "caption", tone: "secondary", children: ` ${item.count}` }) : null
|
|
4441
|
+
] })
|
|
4442
|
+
},
|
|
4443
|
+
item.value
|
|
4444
|
+
);
|
|
4445
|
+
});
|
|
4446
|
+
const panel = items2.find((i) => i.value === current)?.content;
|
|
4447
|
+
return /* @__PURE__ */ jsxs44(View44, { style: [styles40.root, style], children: [
|
|
4448
|
+
segmented ? /* @__PURE__ */ jsx53(View44, { role: "tablist", "aria-label": label, style: [styles40.track, { backgroundColor: theme.surface2, borderColor: theme.borderSubtle, borderRadius: radius3.md }], children: tabs }) : /* @__PURE__ */ jsx53(View44, { style: [styles40.underline, { borderBottomColor: theme.borderSubtle }], children: /* @__PURE__ */ jsx53(ScrollView6, { horizontal: true, showsHorizontalScrollIndicator: false, role: "tablist", "aria-label": label, contentContainerStyle: styles40.scroll, children: tabs }) }),
|
|
4449
|
+
panel !== void 0 ? /* @__PURE__ */ jsx53(View44, { role: "tabpanel", children: panel }) : null
|
|
4450
|
+
] });
|
|
4451
|
+
}
|
|
4452
|
+
var styles40 = StyleSheet40.create({
|
|
4453
|
+
root: { gap: 12 },
|
|
4454
|
+
underline: { borderBottomWidth: StyleSheet40.hairlineWidth },
|
|
4455
|
+
scroll: { gap: 4, paddingHorizontal: 4 },
|
|
4456
|
+
tab: { minHeight: 44, justifyContent: "center", paddingHorizontal: 12, borderBottomWidth: 2 },
|
|
4457
|
+
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet40.hairlineWidth, height: 40 },
|
|
4458
|
+
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet40.hairlineWidth, borderColor: "transparent" },
|
|
4459
|
+
disabled: { opacity: 0.4 }
|
|
4460
|
+
});
|
|
4461
|
+
|
|
3379
4462
|
// src/native/toast.tsx
|
|
3380
|
-
import * as
|
|
3381
|
-
import { AccessibilityInfo as
|
|
3382
|
-
import { Fragment as
|
|
4463
|
+
import * as React37 from "react";
|
|
4464
|
+
import { AccessibilityInfo as AccessibilityInfo12, Animated as Animated21, PanResponder as PanResponder4, Pressable as Pressable22, StyleSheet as StyleSheet41, Text as Text20, View as View45 } from "react-native";
|
|
4465
|
+
import { Fragment as Fragment6, jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
3383
4466
|
var items = [];
|
|
3384
4467
|
var listeners2 = /* @__PURE__ */ new Set();
|
|
3385
4468
|
var counter = 0;
|
|
@@ -3403,87 +4486,104 @@ function dismiss(id) {
|
|
|
3403
4486
|
emit();
|
|
3404
4487
|
gone.forEach((t) => t.onDismiss?.());
|
|
3405
4488
|
}
|
|
3406
|
-
var
|
|
4489
|
+
var tone2 = (name) => (title, options) => show(title, { ...options, tone: name });
|
|
3407
4490
|
var toast = Object.assign(show, {
|
|
3408
|
-
success:
|
|
3409
|
-
warning:
|
|
3410
|
-
error:
|
|
3411
|
-
info:
|
|
4491
|
+
success: tone2("success"),
|
|
4492
|
+
warning: tone2("warning"),
|
|
4493
|
+
error: tone2("error"),
|
|
4494
|
+
info: tone2("info"),
|
|
3412
4495
|
dismiss
|
|
3413
4496
|
});
|
|
3414
4497
|
function ToastView({ item, closeLabel, duration }) {
|
|
3415
|
-
const { theme, radius: radius3 } = useTheme();
|
|
4498
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
3416
4499
|
const reduce = useReducedMotion();
|
|
3417
|
-
const [
|
|
3418
|
-
|
|
4500
|
+
const [swipe] = React37.useState(() => new Animated21.Value(0));
|
|
4501
|
+
const drag = React37.useMemo(
|
|
4502
|
+
() => PanResponder4.create({
|
|
4503
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy),
|
|
4504
|
+
onPanResponderMove: (_, g) => swipe.setValue(g.dx),
|
|
4505
|
+
onPanResponderRelease: (_, g) => {
|
|
4506
|
+
if (Math.abs(g.dx) > 96 || Math.abs(g.vx) > 0.9) {
|
|
4507
|
+
Animated21.timing(swipe, { toValue: Math.sign(g.dx) * 480, duration: 160, useNativeDriver: true }).start(() => dismiss(item.id));
|
|
4508
|
+
} else Animated21.spring(swipe, { toValue: 0, useNativeDriver: true }).start();
|
|
4509
|
+
}
|
|
4510
|
+
}),
|
|
4511
|
+
[swipe, item.id]
|
|
4512
|
+
);
|
|
4513
|
+
React37.useEffect(() => {
|
|
4514
|
+
if (item.tone === "success" || item.tone === "warning") haptic(item.tone);
|
|
4515
|
+
if (item.tone === "error") haptic("warning");
|
|
4516
|
+
}, [item.id]);
|
|
4517
|
+
const [enter] = React37.useState(() => new Animated21.Value(reduce ? 1 : 0));
|
|
4518
|
+
React37.useEffect(() => {
|
|
3419
4519
|
if (reduce) enter.setValue(1);
|
|
3420
|
-
else
|
|
4520
|
+
else Animated21.timing(enter, { toValue: 1, duration: 220, useNativeDriver: true }).start();
|
|
3421
4521
|
}, [enter, reduce]);
|
|
3422
|
-
|
|
3423
|
-
|
|
4522
|
+
React37.useEffect(() => {
|
|
4523
|
+
AccessibilityInfo12.announceForAccessibility(item.description ? `${item.title}. ${item.description}` : item.title);
|
|
3424
4524
|
}, [item.title, item.description]);
|
|
3425
4525
|
const ms = item.duration ?? duration;
|
|
3426
|
-
|
|
4526
|
+
React37.useEffect(() => {
|
|
3427
4527
|
if (!Number.isFinite(ms)) return;
|
|
3428
4528
|
const timer2 = setTimeout(() => dismiss(item.id), ms);
|
|
3429
4529
|
return () => clearTimeout(timer2);
|
|
3430
4530
|
}, [item.id, ms]);
|
|
3431
4531
|
const edge = { success: theme.success, warning: theme.warning, error: theme.danger, info: theme.info, default: theme.borderDefault }[item.tone ?? "default"];
|
|
3432
|
-
const text = /* @__PURE__ */
|
|
3433
|
-
item.icon ? /* @__PURE__ */
|
|
3434
|
-
/* @__PURE__ */
|
|
3435
|
-
/* @__PURE__ */
|
|
3436
|
-
item.description ? /* @__PURE__ */
|
|
4532
|
+
const text = /* @__PURE__ */ jsxs45(Fragment6, { children: [
|
|
4533
|
+
item.icon ? /* @__PURE__ */ jsx54(View45, { "aria-hidden": true, children: item.icon }) : null,
|
|
4534
|
+
/* @__PURE__ */ jsxs45(View45, { style: styles41.content, children: [
|
|
4535
|
+
/* @__PURE__ */ jsx54(Txt, { variant: "label", numberOfLines: 2, children: item.title }),
|
|
4536
|
+
item.description ? /* @__PURE__ */ jsx54(Txt, { variant: "caption", tone: "secondary", numberOfLines: 3, children: item.description }) : null
|
|
3437
4537
|
] })
|
|
3438
4538
|
] });
|
|
3439
|
-
const body = /* @__PURE__ */
|
|
3440
|
-
item.onPress ? /* @__PURE__ */
|
|
3441
|
-
|
|
4539
|
+
const body = /* @__PURE__ */ jsxs45(Fragment6, { children: [
|
|
4540
|
+
item.onPress ? /* @__PURE__ */ jsx54(
|
|
4541
|
+
Pressable22,
|
|
3442
4542
|
{
|
|
3443
4543
|
role: "button",
|
|
3444
4544
|
onPress: () => {
|
|
3445
4545
|
item.onPress?.();
|
|
3446
4546
|
dismiss(item.id);
|
|
3447
4547
|
},
|
|
3448
|
-
style: ({ pressed }) => [
|
|
4548
|
+
style: ({ pressed }) => [styles41.main, { opacity: pressed ? 0.8 : 1 }],
|
|
3449
4549
|
children: text
|
|
3450
4550
|
}
|
|
3451
|
-
) : /* @__PURE__ */
|
|
3452
|
-
item.action ? /* @__PURE__ */
|
|
3453
|
-
|
|
4551
|
+
) : /* @__PURE__ */ jsx54(View45, { style: styles41.main, children: text }),
|
|
4552
|
+
item.action ? /* @__PURE__ */ jsx54(
|
|
4553
|
+
Pressable22,
|
|
3454
4554
|
{
|
|
3455
4555
|
role: "button",
|
|
3456
4556
|
onPress: () => {
|
|
3457
4557
|
item.action?.onPress();
|
|
3458
4558
|
dismiss(item.id);
|
|
3459
4559
|
},
|
|
3460
|
-
style: [
|
|
3461
|
-
children: /* @__PURE__ */
|
|
4560
|
+
style: [styles41.action, { backgroundColor: theme.accent, borderRadius: radius3.sm }],
|
|
4561
|
+
children: /* @__PURE__ */ jsx54(Text20, { style: [styles41.actionLabel, { color: theme.onAccent }], children: item.action.label })
|
|
3462
4562
|
}
|
|
3463
4563
|
) : null,
|
|
3464
|
-
/* @__PURE__ */
|
|
4564
|
+
/* @__PURE__ */ jsx54(Pressable22, { role: "button", "aria-label": closeLabel, hitSlop: 10, onPress: () => dismiss(item.id), style: styles41.close, children: /* @__PURE__ */ jsx54(Text20, { style: [styles41.cross, { color: theme.textSecondary }], children: "\xD7" }) })
|
|
3465
4565
|
] });
|
|
3466
4566
|
const frame = [
|
|
3467
|
-
|
|
4567
|
+
styles41.toast,
|
|
3468
4568
|
{ backgroundColor: theme.surface2, borderColor: theme.borderDefault, borderLeftColor: edge, borderRadius: radius3.lg, shadowColor: theme.scrimStrong }
|
|
3469
4569
|
];
|
|
3470
|
-
const motion3 = { transform: [{ translateY: enter.interpolate({ inputRange: [0, 1], outputRange: [-8, 0] }) }] };
|
|
3471
|
-
return /* @__PURE__ */
|
|
4570
|
+
const motion3 = { transform: [{ translateY: enter.interpolate({ inputRange: [0, 1], outputRange: [-8, 0] }) }, { translateX: swipe }] };
|
|
4571
|
+
return /* @__PURE__ */ jsx54(Animated21.View, { "aria-live": "polite", style: motion3, ...drag.panHandlers, children: /* @__PURE__ */ jsx54(View45, { style: frame, children: body }) });
|
|
3472
4572
|
}
|
|
3473
4573
|
function Toaster({ closeLabel, position = "top", offset = 12, duration = 6e3, max = 3 }) {
|
|
3474
|
-
const all =
|
|
4574
|
+
const all = React37.useSyncExternalStore(subscribe2, snapshot, snapshot);
|
|
3475
4575
|
const shown = all.slice(-max);
|
|
3476
4576
|
if (shown.length === 0) return null;
|
|
3477
|
-
return /* @__PURE__ */
|
|
4577
|
+
return /* @__PURE__ */ jsx54(View45, { pointerEvents: "box-none", style: [styles41.stack, position === "top" ? { top: offset } : { bottom: offset }], children: (position === "top" ? shown : [...shown].reverse()).map((item) => /* @__PURE__ */ jsx54(ToastView, { item, closeLabel, duration }, item.id)) });
|
|
3478
4578
|
}
|
|
3479
|
-
var
|
|
4579
|
+
var styles41 = StyleSheet41.create({
|
|
3480
4580
|
stack: { position: "absolute", left: 12, right: 12, gap: 8, zIndex: 100 },
|
|
3481
4581
|
toast: {
|
|
3482
4582
|
flexDirection: "row",
|
|
3483
4583
|
alignItems: "center",
|
|
3484
4584
|
gap: 10,
|
|
3485
4585
|
padding: 12,
|
|
3486
|
-
borderWidth:
|
|
4586
|
+
borderWidth: StyleSheet41.hairlineWidth,
|
|
3487
4587
|
borderLeftWidth: 4,
|
|
3488
4588
|
shadowOpacity: 0.3,
|
|
3489
4589
|
shadowRadius: 16,
|
|
@@ -3498,6 +4598,8 @@ var styles26 = StyleSheet26.create({
|
|
|
3498
4598
|
cross: { fontSize: 18, lineHeight: 20, fontWeight: "700" }
|
|
3499
4599
|
});
|
|
3500
4600
|
export {
|
|
4601
|
+
ActionSheet,
|
|
4602
|
+
ActivityFeed,
|
|
3501
4603
|
Avatar,
|
|
3502
4604
|
AvatarGroup,
|
|
3503
4605
|
AvatarRoot,
|
|
@@ -3520,22 +4622,34 @@ export {
|
|
|
3520
4622
|
DateField,
|
|
3521
4623
|
DateWheel,
|
|
3522
4624
|
DayStrip,
|
|
4625
|
+
DescriptionList,
|
|
3523
4626
|
EmptyState,
|
|
3524
4627
|
ErrorState,
|
|
4628
|
+
Fab,
|
|
3525
4629
|
GoalGauge,
|
|
4630
|
+
Header,
|
|
3526
4631
|
IconButton,
|
|
4632
|
+
ImageViewer,
|
|
3527
4633
|
KrizakaMark,
|
|
4634
|
+
Loader,
|
|
4635
|
+
LoaderGlyph,
|
|
3528
4636
|
LoadingState,
|
|
3529
4637
|
Mascot,
|
|
3530
4638
|
MascotState,
|
|
4639
|
+
Meter,
|
|
3531
4640
|
MonthPicker,
|
|
4641
|
+
NumberTicker,
|
|
4642
|
+
Onboarding,
|
|
3532
4643
|
OrazakaMark,
|
|
3533
4644
|
OrochiaMark,
|
|
4645
|
+
OtpInput,
|
|
3534
4646
|
Pagination,
|
|
4647
|
+
PermissionPrompt,
|
|
3535
4648
|
Phoenix,
|
|
3536
4649
|
ProductMark,
|
|
3537
4650
|
ProfileCard,
|
|
3538
4651
|
Progress,
|
|
4652
|
+
PullToRefresh,
|
|
3539
4653
|
RadioGroup,
|
|
3540
4654
|
SearchField,
|
|
3541
4655
|
Segmented,
|
|
@@ -3544,8 +4658,12 @@ export {
|
|
|
3544
4658
|
Skeleton,
|
|
3545
4659
|
Slider,
|
|
3546
4660
|
Spinner,
|
|
4661
|
+
Stepper,
|
|
3547
4662
|
SuccessState,
|
|
4663
|
+
SwipeableRow,
|
|
3548
4664
|
Switch,
|
|
4665
|
+
TabBar,
|
|
4666
|
+
Tabs,
|
|
3549
4667
|
TextField,
|
|
3550
4668
|
ThemeProvider,
|
|
3551
4669
|
TimePicker,
|
|
@@ -3571,13 +4689,16 @@ export {
|
|
|
3571
4689
|
isRealDate,
|
|
3572
4690
|
latestBirthDate,
|
|
3573
4691
|
monthNames,
|
|
4692
|
+
prefetchNeighbours,
|
|
3574
4693
|
splitDuration,
|
|
3575
4694
|
textStyles,
|
|
3576
4695
|
timeSlots,
|
|
3577
4696
|
timeToMinutes,
|
|
3578
4697
|
toast,
|
|
3579
4698
|
todayIso,
|
|
4699
|
+
useCollapsingHeader,
|
|
3580
4700
|
useCountdown,
|
|
4701
|
+
useDelayedWait,
|
|
3581
4702
|
useReducedMotion,
|
|
3582
4703
|
useTheme,
|
|
3583
4704
|
uses12Hours
|