@lt-three/love3 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -1
- package/dist/native/analytics/animation.d.ts +4 -0
- package/dist/native/analytics/animation.js +6 -0
- package/dist/native/analytics/chart.types.d.ts +25 -0
- package/dist/native/analytics/chart.types.js +0 -0
- package/dist/native/analytics/line-chart.d.ts +4 -0
- package/dist/native/analytics/line-chart.ios.d.ts +4 -0
- package/dist/native/analytics/line-chart.ios.js +24 -0
- package/dist/native/analytics/line-chart.js +33 -0
- package/dist/native/analytics/metric-card.d.ts +10 -0
- package/dist/native/analytics/metric-card.js +29 -0
- package/dist/native/analytics/multi-line-chart.d.ts +17 -0
- package/dist/native/analytics/multi-line-chart.js +215 -0
- package/dist/native/analytics/pie-chart.d.ts +15 -0
- package/dist/native/analytics/pie-chart.ios.d.ts +4 -0
- package/dist/native/analytics/pie-chart.ios.js +24 -0
- package/dist/native/analytics/pie-chart.js +92 -0
- package/dist/native/analytics/single-number.d.ts +19 -0
- package/dist/native/analytics/single-number.js +101 -0
- package/dist/native/atom/avatar.d.ts +21 -0
- package/dist/native/atom/avatar.js +46 -0
- package/dist/native/atom/badge.d.ts +28 -0
- package/dist/native/atom/badge.js +51 -0
- package/dist/native/atom/button.d.ts +46 -0
- package/dist/native/atom/button.js +109 -0
- package/dist/native/atom/checkbox.d.ts +21 -0
- package/dist/native/atom/checkbox.js +47 -0
- package/dist/native/atom/colored-value.d.ts +12 -0
- package/dist/native/atom/colored-value.js +24 -0
- package/dist/native/atom/image.d.ts +21 -0
- package/dist/native/atom/image.js +72 -0
- package/dist/native/atom/label.d.ts +18 -0
- package/dist/native/atom/label.js +33 -0
- package/dist/native/atom/link.d.ts +18 -0
- package/dist/native/atom/link.js +25 -0
- package/dist/native/atom/readout.d.ts +22 -0
- package/dist/native/atom/readout.js +39 -0
- package/dist/native/atom/search-input.d.ts +12 -0
- package/dist/native/atom/search-input.js +36 -0
- package/dist/native/atom/select.d.ts +54 -0
- package/dist/native/atom/select.js +200 -0
- package/dist/native/atom/separator.d.ts +13 -0
- package/dist/native/atom/separator.js +17 -0
- package/dist/native/atom/skeleton.d.ts +12 -0
- package/dist/native/atom/skeleton.js +39 -0
- package/dist/native/atom/slider.d.ts +32 -0
- package/dist/native/atom/slider.js +75 -0
- package/dist/native/atom/spinner.d.ts +15 -0
- package/dist/native/atom/spinner.js +25 -0
- package/dist/native/atom/switch.d.ts +18 -0
- package/dist/native/atom/switch.js +52 -0
- package/dist/native/atom/symbol.d.ts +16 -0
- package/dist/native/atom/symbol.js +38 -0
- package/dist/native/atom/symbol.types.d.ts +25 -0
- package/dist/native/atom/symbol.types.js +49 -0
- package/dist/native/atom/text-field.d.ts +49 -0
- package/dist/native/atom/text-field.js +56 -0
- package/dist/native/atom/text.d.ts +2 -0
- package/dist/native/atom/text.js +3 -0
- package/dist/native/atom/theme-toggle.d.ts +21 -0
- package/dist/native/atom/theme-toggle.js +36 -0
- package/dist/native/atom/timezone-select.d.ts +16 -0
- package/dist/native/atom/timezone-select.js +28 -0
- package/dist/native/atom/typography.d.ts +13 -0
- package/dist/native/atom/typography.js +28 -0
- package/dist/native/base/button.d.ts +61 -0
- package/dist/native/base/button.js +92 -0
- package/dist/native/base/form.d.ts +72 -0
- package/dist/native/base/form.js +113 -0
- package/dist/native/base/glass-card.d.ts +15 -0
- package/dist/native/base/glass-card.js +38 -0
- package/dist/native/base/input.d.ts +29 -0
- package/dist/native/base/input.js +27 -0
- package/dist/native/base/sheet.d.ts +71 -0
- package/dist/native/base/sheet.js +187 -0
- package/dist/native/base/text.d.ts +14 -0
- package/dist/native/base/text.js +53 -0
- package/dist/native/form/checkbox.d.ts +13 -0
- package/dist/native/form/checkbox.js +55 -0
- package/dist/native/form/date-picker.d.ts +23 -0
- package/dist/native/form/date-picker.js +119 -0
- package/dist/native/form/form.d.ts +23 -0
- package/dist/native/form/form.js +45 -0
- package/dist/native/form/radio-group.d.ts +23 -0
- package/dist/native/form/radio-group.js +88 -0
- package/dist/native/form/select.d.ts +13 -0
- package/dist/native/form/select.js +45 -0
- package/dist/native/form/slider.d.ts +14 -0
- package/dist/native/form/slider.js +42 -0
- package/dist/native/form/switch.d.ts +9 -0
- package/dist/native/form/switch.js +59 -0
- package/dist/native/form/text-area.d.ts +11 -0
- package/dist/native/form/text-area.js +50 -0
- package/dist/native/form/text-input.d.ts +18 -0
- package/dist/native/form/text-input.js +90 -0
- package/dist/native/index.d.ts +1 -0
- package/dist/native/index.js +0 -0
- package/dist/native/layout/accordion.d.ts +25 -0
- package/dist/native/layout/accordion.js +54 -0
- package/dist/native/layout/card.d.ts +47 -0
- package/dist/native/layout/card.js +57 -0
- package/dist/native/layout/description.d.ts +16 -0
- package/dist/native/layout/description.js +32 -0
- package/dist/native/layout/error.d.ts +21 -0
- package/dist/native/layout/error.js +44 -0
- package/dist/native/layout/information.d.ts +25 -0
- package/dist/native/layout/information.js +35 -0
- package/dist/native/layout/locked.d.ts +38 -0
- package/dist/native/layout/locked.js +94 -0
- package/dist/native/layout/modal.d.ts +25 -0
- package/dist/native/layout/modal.js +93 -0
- package/dist/native/layout/not-found.d.ts +17 -0
- package/dist/native/layout/not-found.js +30 -0
- package/dist/native/layout/page-frame.d.ts +23 -0
- package/dist/native/layout/page-frame.js +46 -0
- package/dist/native/layout/panel.d.ts +18 -0
- package/dist/native/layout/panel.js +23 -0
- package/dist/native/layout/reorderable-list.d.ts +42 -0
- package/dist/native/layout/reorderable-list.js +52 -0
- package/dist/native/layout/sheet.d.ts +30 -0
- package/dist/native/layout/sheet.js +46 -0
- package/dist/native/layout/simple-dialog.d.ts +16 -0
- package/dist/native/layout/simple-dialog.js +20 -0
- package/dist/native/layout/simple-table.d.ts +50 -0
- package/dist/native/layout/simple-table.js +75 -0
- package/dist/native/layout/tab-bar.d.ts +33 -0
- package/dist/native/layout/tab-bar.js +48 -0
- package/dist/native/layout/tabs.d.ts +28 -0
- package/dist/native/layout/tabs.js +54 -0
- package/dist/native/layout/tuning-panel.d.ts +24 -0
- package/dist/native/layout/tuning-panel.js +246 -0
- package/dist/native/lib/autocomplete.d.ts +7 -0
- package/dist/native/lib/autocomplete.js +34 -0
- package/dist/native/lib/breakpoints.d.ts +14 -0
- package/dist/native/lib/breakpoints.js +17 -0
- package/dist/native/lib/chart-palette.d.ts +8 -0
- package/dist/native/lib/chart-palette.js +20 -0
- package/dist/native/lib/confirm.d.ts +49 -0
- package/dist/native/lib/confirm.js +70 -0
- package/dist/native/lib/control.d.ts +24 -0
- package/dist/native/lib/control.js +0 -0
- package/dist/native/lib/external-store.d.ts +17 -0
- package/dist/native/lib/external-store.js +30 -0
- package/dist/native/lib/keyboard.d.ts +15 -0
- package/dist/native/lib/keyboard.js +24 -0
- package/dist/native/lib/labels.d.ts +15 -0
- package/dist/native/lib/labels.js +17 -0
- package/dist/native/lib/loading.d.ts +10 -0
- package/dist/native/lib/loading.js +15 -0
- package/dist/native/lib/network.d.ts +12 -0
- package/dist/native/lib/network.js +21 -0
- package/dist/native/lib/scheme.d.ts +18 -0
- package/dist/native/lib/scheme.js +22 -0
- package/dist/native/lib/snackbar.d.ts +46 -0
- package/dist/native/lib/snackbar.js +60 -0
- package/dist/native/lib/theme.d.ts +34 -0
- package/dist/native/lib/theme.js +53 -0
- package/dist/native/lib/timezone.d.ts +26 -0
- package/dist/native/lib/timezone.js +95 -0
- package/dist/native/lib/token-color.d.ts +5 -0
- package/dist/native/lib/token-color.js +13 -0
- package/dist/native/lib/token-color.web.d.ts +4 -0
- package/dist/native/lib/token-color.web.js +7 -0
- package/dist/native/lib/tuning-context.d.ts +9 -0
- package/dist/native/lib/tuning-context.js +7 -0
- package/dist/native/lib/tuning.d.ts +24 -0
- package/dist/native/lib/tuning.js +42 -0
- package/dist/native/lib/typography.d.ts +10 -0
- package/dist/native/lib/typography.js +11 -0
- package/dist/native/lib/utils.d.ts +11 -0
- package/dist/native/lib/utils.js +21 -0
- package/dist/native/once/confirm.d.ts +7 -0
- package/dist/native/once/confirm.js +60 -0
- package/dist/native/once/error-boundary.d.ts +28 -0
- package/dist/native/once/error-boundary.js +55 -0
- package/dist/native/once/loading-lock.d.ts +8 -0
- package/dist/native/once/loading-lock.js +28 -0
- package/dist/native/once/offline-banner.d.ts +15 -0
- package/dist/native/once/offline-banner.js +35 -0
- package/dist/native/once/snackbar.d.ts +17 -0
- package/dist/native/once/snackbar.js +106 -0
- package/dist/native/styles.css +46 -0
- package/dist/shared/analytics.d.ts +71 -0
- package/dist/shared/analytics.js +0 -0
- package/dist/shared/button.d.ts +7 -0
- package/dist/shared/button.js +23 -0
- package/dist/shared/form.d.ts +45 -0
- package/dist/shared/form.js +46 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/tokens/contrast-pairs.d.ts +30 -0
- package/dist/tokens/contrast-pairs.js +404 -0
- package/dist/tokens/index.d.ts +6 -0
- package/dist/tokens/index.js +10 -0
- package/dist/tokens/styles.gen.css +250 -0
- package/dist/tokens/tokens.gen.d.ts +141 -0
- package/dist/tokens/tokens.gen.js +206 -0
- package/dist/tuning/catalog.d.ts +27 -0
- package/dist/tuning/catalog.gen.d.ts +4 -0
- package/dist/tuning/catalog.gen.js +397 -0
- package/dist/tuning/catalog.js +128 -0
- package/dist/tuning/color.d.ts +20 -0
- package/dist/tuning/color.js +80 -0
- package/dist/tuning/css.d.ts +35 -0
- package/dist/tuning/css.js +147 -0
- package/dist/tuning/index.d.ts +8 -0
- package/dist/tuning/index.js +9 -0
- package/dist/tuning/model.d.ts +33 -0
- package/dist/tuning/model.js +154 -0
- package/dist/tuning/native.d.ts +35 -0
- package/dist/tuning/native.js +80 -0
- package/dist/tuning/schema.d.ts +69 -0
- package/dist/tuning/schema.js +247 -0
- package/dist/tuning/types.d.ts +75 -0
- package/dist/tuning/types.js +39 -0
- package/dist/web/analytics/line-chart.d.ts +20 -0
- package/dist/web/analytics/line-chart.js +28 -0
- package/dist/web/analytics/metric-card.d.ts +18 -0
- package/dist/web/analytics/metric-card.js +40 -0
- package/dist/web/analytics/multi-line-chart.d.ts +39 -0
- package/dist/web/analytics/multi-line-chart.js +345 -0
- package/dist/web/atom/avatar.d.ts +11 -0
- package/dist/web/atom/avatar.js +24 -0
- package/dist/web/atom/badge.d.ts +2 -0
- package/dist/web/atom/badge.js +3 -0
- package/dist/web/atom/button.d.ts +23 -0
- package/dist/web/atom/button.js +35 -0
- package/dist/web/atom/checkbox.d.ts +19 -0
- package/dist/web/atom/checkbox.js +33 -0
- package/dist/web/atom/colored-value.d.ts +13 -0
- package/dist/web/atom/colored-value.js +24 -0
- package/dist/web/atom/help.d.ts +10 -0
- package/dist/web/atom/help.js +18 -0
- package/dist/web/atom/label.d.ts +2 -0
- package/dist/web/atom/label.js +3 -0
- package/dist/web/atom/segmented-control.d.ts +40 -0
- package/dist/web/atom/segmented-control.js +43 -0
- package/dist/web/atom/select.d.ts +43 -0
- package/dist/web/atom/select.js +93 -0
- package/dist/web/atom/separator.d.ts +2 -0
- package/dist/web/atom/separator.js +3 -0
- package/dist/web/atom/skeleton.d.ts +2 -0
- package/dist/web/atom/skeleton.js +3 -0
- package/dist/web/atom/slider.d.ts +33 -0
- package/dist/web/atom/slider.js +70 -0
- package/dist/web/atom/spinner.d.ts +8 -0
- package/dist/web/atom/spinner.js +14 -0
- package/dist/web/atom/switch.d.ts +11 -0
- package/dist/web/atom/switch.js +10 -0
- package/dist/web/atom/text-area.d.ts +22 -0
- package/dist/web/atom/text-area.js +26 -0
- package/dist/web/atom/text-field.d.ts +17 -0
- package/dist/web/atom/text-field.js +21 -0
- package/dist/web/atom/toggle-chip.d.ts +22 -0
- package/dist/web/atom/toggle-chip.js +28 -0
- package/dist/web/atom/tooltip.d.ts +23 -0
- package/dist/web/atom/tooltip.js +26 -0
- package/dist/web/atom/typography.d.ts +6 -0
- package/dist/web/atom/typography.js +23 -0
- package/dist/web/base/accordion.d.ts +9 -0
- package/dist/web/base/accordion.js +44 -0
- package/dist/web/base/alert.d.ts +11 -0
- package/dist/web/base/alert.js +37 -0
- package/dist/web/base/avatar.d.ts +8 -0
- package/dist/web/base/avatar.js +29 -0
- package/dist/web/base/badge.d.ts +12 -0
- package/dist/web/base/badge.js +26 -0
- package/dist/web/base/breadcrumb.d.ts +16 -0
- package/dist/web/base/breadcrumb.js +72 -0
- package/dist/web/base/button.d.ts +12 -0
- package/dist/web/base/button.js +47 -0
- package/dist/web/base/card.d.ts +19 -0
- package/dist/web/base/card.js +74 -0
- package/dist/web/base/checkbox.d.ts +6 -0
- package/dist/web/base/checkbox.js +21 -0
- package/dist/web/base/dialog.d.ts +20 -0
- package/dist/web/base/dialog.js +92 -0
- package/dist/web/base/dropdown-menu.d.ts +29 -0
- package/dist/web/base/dropdown-menu.js +125 -0
- package/dist/web/base/field.d.ts +27 -0
- package/dist/web/base/field.js +118 -0
- package/dist/web/base/form.d.ts +38 -0
- package/dist/web/base/form.js +110 -0
- package/dist/web/base/input.d.ts +9 -0
- package/dist/web/base/input.js +23 -0
- package/dist/web/base/label.d.ts +6 -0
- package/dist/web/base/label.js +15 -0
- package/dist/web/base/pagination.d.ts +34 -0
- package/dist/web/base/pagination.js +90 -0
- package/dist/web/base/popover.d.ts +11 -0
- package/dist/web/base/popover.js +37 -0
- package/dist/web/base/radio-group.d.ts +7 -0
- package/dist/web/base/radio-group.js +27 -0
- package/dist/web/base/scroll-area.d.ts +10 -0
- package/dist/web/base/scroll-area.js +41 -0
- package/dist/web/base/select.d.ts +17 -0
- package/dist/web/base/select.js +96 -0
- package/dist/web/base/separator.d.ts +6 -0
- package/dist/web/base/separator.js +17 -0
- package/dist/web/base/sheet.d.ts +19 -0
- package/dist/web/base/sheet.js +88 -0
- package/dist/web/base/skeleton.d.ts +5 -0
- package/dist/web/base/skeleton.js +14 -0
- package/dist/web/base/slider.d.ts +9 -0
- package/dist/web/base/slider.js +39 -0
- package/dist/web/base/sonner.d.ts +9 -0
- package/dist/web/base/sonner.js +25 -0
- package/dist/web/base/spinner.d.ts +5 -0
- package/dist/web/base/spinner.js +17 -0
- package/dist/web/base/switch.d.ts +6 -0
- package/dist/web/base/switch.js +19 -0
- package/dist/web/base/table.d.ts +14 -0
- package/dist/web/base/table.js +68 -0
- package/dist/web/base/tabs.d.ts +9 -0
- package/dist/web/base/tabs.js +36 -0
- package/dist/web/base/textarea.d.ts +9 -0
- package/dist/web/base/textarea.js +23 -0
- package/dist/web/base/tooltip.d.ts +9 -0
- package/dist/web/base/tooltip.js +36 -0
- package/dist/web/form/checkbox.d.ts +35 -0
- package/dist/web/form/checkbox.js +91 -0
- package/dist/web/form/radio-group.d.ts +24 -0
- package/dist/web/form/radio-group.js +75 -0
- package/dist/web/form/select.d.ts +16 -0
- package/dist/web/form/select.js +44 -0
- package/dist/web/form/slider.d.ts +19 -0
- package/dist/web/form/slider.js +51 -0
- package/dist/web/form/switch.d.ts +11 -0
- package/dist/web/form/switch.js +50 -0
- package/dist/web/form/text-area.d.ts +10 -0
- package/dist/web/form/text-area.js +31 -0
- package/dist/web/form/text-input.d.ts +10 -0
- package/dist/web/form/text-input.js +42 -0
- package/dist/web/index.d.ts +1 -0
- package/dist/web/index.js +0 -0
- package/dist/web/layout/accordion.d.ts +26 -0
- package/dist/web/layout/accordion.js +29 -0
- package/dist/web/layout/alert-modal.d.ts +41 -0
- package/dist/web/layout/alert-modal.js +71 -0
- package/dist/web/layout/card.d.ts +17 -0
- package/dist/web/layout/card.js +35 -0
- package/dist/web/layout/description.d.ts +12 -0
- package/dist/web/layout/description.js +20 -0
- package/dist/web/layout/information.d.ts +36 -0
- package/dist/web/layout/information.js +53 -0
- package/dist/web/layout/modal.d.ts +16 -0
- package/dist/web/layout/modal.js +37 -0
- package/dist/web/layout/page-frame.d.ts +37 -0
- package/dist/web/layout/page-frame.js +79 -0
- package/dist/web/layout/scroll-area.d.ts +10 -0
- package/dist/web/layout/scroll-area.js +13 -0
- package/dist/web/layout/sheet.d.ts +32 -0
- package/dist/web/layout/sheet.js +68 -0
- package/dist/web/layout/simple-dialog.d.ts +11 -0
- package/dist/web/layout/simple-dialog.js +24 -0
- package/dist/web/layout/simple-table.d.ts +49 -0
- package/dist/web/layout/simple-table.js +58 -0
- package/dist/web/layout/tabs.d.ts +26 -0
- package/dist/web/layout/tabs.js +42 -0
- package/dist/web/layout/titled-modal.d.ts +33 -0
- package/dist/web/layout/titled-modal.js +59 -0
- package/dist/web/lib/css-vars.d.ts +14 -0
- package/dist/web/lib/css-vars.js +18 -0
- package/dist/web/lib/dialog.d.ts +13 -0
- package/dist/web/lib/dialog.js +0 -0
- package/dist/web/lib/form.d.ts +2 -0
- package/dist/web/lib/form.js +3 -0
- package/dist/web/lib/labels.d.ts +27 -0
- package/dist/web/lib/labels.js +29 -0
- package/dist/web/lib/modal-open-focus.d.ts +17 -0
- package/dist/web/lib/modal-open-focus.js +44 -0
- package/dist/web/lib/restore-focus.d.ts +12 -0
- package/dist/web/lib/restore-focus.js +32 -0
- package/dist/web/lib/utils.d.ts +4 -0
- package/dist/web/lib/utils.js +10 -0
- package/dist/web/styles.css +162 -0
- package/package.json +203 -4
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ControlA11yProps } from "../lib/control.js";
|
|
2
|
+
//#region src/native/atom/switch.d.ts
|
|
3
|
+
export type SwitchProps = ControlA11yProps & {
|
|
4
|
+
checked: boolean;
|
|
5
|
+
onCheckedChange: (checked: boolean) => void;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
/** 読み上げ用の名前。スイッチ単体には文字が無いので、隣にラベルを置く使い方では必ず渡す。 */
|
|
8
|
+
accessibilityLabel?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `@lt-three/web` の base/switch と同じ丸いスイッチ(on はインディゴ塗り、off は wash 面 + line-control の枠)。
|
|
13
|
+
*
|
|
14
|
+
* OS 標準のスイッチが要る場合は `base/` の `@expo/ui` 側を使う。ここは
|
|
15
|
+
* 「web と同じ見た目を優先する」方針に沿った RN 実装。
|
|
16
|
+
*/
|
|
17
|
+
export declare function Switch({ checked, onCheckedChange, disabled, accessibilityLabel, accessibilityHint, className, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }: SwitchProps): import("react").JSX.Element;
|
|
18
|
+
//#endregion
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { activateOnSpace } from "../lib/keyboard.js";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { Animated, Platform, Pressable } from "react-native";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/native/atom/switch.tsx
|
|
8
|
+
const TRACK_PADDING = 1;
|
|
9
|
+
const KNOB_TRAVEL = 19;
|
|
10
|
+
/**
|
|
11
|
+
* `@lt-three/web` の base/switch と同じ丸いスイッチ(on はインディゴ塗り、off は wash 面 + line-control の枠)。
|
|
12
|
+
*
|
|
13
|
+
* OS 標準のスイッチが要る場合は `base/` の `@expo/ui` 側を使う。ここは
|
|
14
|
+
* 「web と同じ見た目を優先する」方針に沿った RN 実装。
|
|
15
|
+
*/
|
|
16
|
+
function Switch({ checked, onCheckedChange, disabled, accessibilityLabel, accessibilityHint, className, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
|
|
17
|
+
const progress = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
Animated.timing(progress, {
|
|
20
|
+
toValue: checked ? 1 : 0,
|
|
21
|
+
duration: 150,
|
|
22
|
+
useNativeDriver: Platform.OS !== "web"
|
|
23
|
+
}).start();
|
|
24
|
+
}, [checked, progress]);
|
|
25
|
+
const translateX = progress.interpolate({
|
|
26
|
+
inputRange: [0, 1],
|
|
27
|
+
outputRange: [TRACK_PADDING, KNOB_TRAVEL]
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsx(Pressable, {
|
|
30
|
+
accessibilityRole: "switch",
|
|
31
|
+
accessibilityLabel,
|
|
32
|
+
accessibilityHint,
|
|
33
|
+
id,
|
|
34
|
+
"aria-labelledby": ariaLabelledBy,
|
|
35
|
+
"aria-describedby": ariaDescribedBy,
|
|
36
|
+
"aria-invalid": ariaInvalid,
|
|
37
|
+
"aria-checked": checked,
|
|
38
|
+
"aria-disabled": disabled,
|
|
39
|
+
onPress: () => onCheckedChange(!checked),
|
|
40
|
+
onKeyDown: activateOnSpace(() => onCheckedChange(!checked), disabled),
|
|
41
|
+
disabled,
|
|
42
|
+
hitSlop: 12,
|
|
43
|
+
className: cn("h-5 w-9 shrink-0 justify-center rounded-full border", checked ? "border-action bg-action" : "border-line-control bg-wash", disabled && "opacity-50", className),
|
|
44
|
+
children: /* @__PURE__ */ jsx(Animated.View, {
|
|
45
|
+
style: { transform: [{ translateX }] },
|
|
46
|
+
className: "h-3.5 w-3.5 rounded-full bg-white shadow-xs"
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
export { Switch };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SymbolProps } from "./symbol.types.js";
|
|
2
|
+
//#region src/native/atom/symbol.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* アイコン。iOS は SF Symbols、Android は Material Symbols で描く。
|
|
5
|
+
*
|
|
6
|
+
* **`SymbolView` に SF 名を文字列で渡すと Android では何も描かれない。**
|
|
7
|
+
* 例外も警告も出ないのでアイコンだけが無言で消える(実際に Android では検索欄の虫眼鏡・
|
|
8
|
+
* 設定の歯車・行の `>`・空状態のアイコンが全部消えていた)。`{ ios, android }` の形で
|
|
9
|
+
* 渡したときだけ Android 実装が動くので、**アプリからは必ずこのコンポーネントを使う**。
|
|
10
|
+
*
|
|
11
|
+
* 読み替え表は `symbol.types.ts`。表に無い SF 名は Android で描かれないため、
|
|
12
|
+
* `fallback` に薄い丸を出して「アイコンがあるべき場所」を残す(詰めた見た目にしない)。
|
|
13
|
+
*/
|
|
14
|
+
export declare function Symbol({ name, size, tintColor, accessibilityLabel, className, style }: SymbolProps): import("react").JSX.Element;
|
|
15
|
+
//#endregion
|
|
16
|
+
export type { SymbolProps };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SF_TO_ANDROID } from "./symbol.types.js";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { SymbolView } from "expo-symbols";
|
|
5
|
+
|
|
6
|
+
//#region src/native/atom/symbol.tsx
|
|
7
|
+
/**
|
|
8
|
+
* アイコン。iOS は SF Symbols、Android は Material Symbols で描く。
|
|
9
|
+
*
|
|
10
|
+
* **`SymbolView` に SF 名を文字列で渡すと Android では何も描かれない。**
|
|
11
|
+
* 例外も警告も出ないのでアイコンだけが無言で消える(実際に Android では検索欄の虫眼鏡・
|
|
12
|
+
* 設定の歯車・行の `>`・空状態のアイコンが全部消えていた)。`{ ios, android }` の形で
|
|
13
|
+
* 渡したときだけ Android 実装が動くので、**アプリからは必ずこのコンポーネントを使う**。
|
|
14
|
+
*
|
|
15
|
+
* 読み替え表は `symbol.types.ts`。表に無い SF 名は Android で描かれないため、
|
|
16
|
+
* `fallback` に薄い丸を出して「アイコンがあるべき場所」を残す(詰めた見た目にしない)。
|
|
17
|
+
*/
|
|
18
|
+
function Symbol({ name, size = 20, tintColor, accessibilityLabel, className, style }) {
|
|
19
|
+
const android = SF_TO_ANDROID[name];
|
|
20
|
+
return /* @__PURE__ */ jsx(SymbolView, {
|
|
21
|
+
name: android ? {
|
|
22
|
+
ios: name,
|
|
23
|
+
android
|
|
24
|
+
} : name,
|
|
25
|
+
size,
|
|
26
|
+
tintColor,
|
|
27
|
+
accessibilityLabel,
|
|
28
|
+
style,
|
|
29
|
+
className,
|
|
30
|
+
fallback: /* @__PURE__ */ jsx(View, { style: {
|
|
31
|
+
width: size,
|
|
32
|
+
height: size
|
|
33
|
+
} })
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Symbol };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
2
|
+
import { AndroidSymbol, SFSymbol } from "expo-symbols";
|
|
3
|
+
//#region src/native/atom/symbol.types.d.ts
|
|
4
|
+
export type SymbolProps = {
|
|
5
|
+
/** SF Symbol の名前。Android は `SF_TO_ANDROID` で Material Symbols に読み替える。 */
|
|
6
|
+
name: SFSymbol;
|
|
7
|
+
size?: number;
|
|
8
|
+
tintColor?: string;
|
|
9
|
+
accessibilityLabel?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* SF Symbol → Material Symbols(Android)の読み替え表。
|
|
15
|
+
*
|
|
16
|
+
* **`SymbolView` は `name` を文字列で渡すと Android では何も描かない。**
|
|
17
|
+
* `{ ios, android }` の形で渡したときだけ Android 実装(Material Symbols のフォント)が動く。
|
|
18
|
+
* 実際、アプリ全体が SF 名の文字列を渡していたため、Android では検索欄の虫眼鏡・設定の歯車・
|
|
19
|
+
* 行の `>`・空状態のアイコンが**例外も警告も無く全部消えていた**。
|
|
20
|
+
*
|
|
21
|
+
* **fill の有無を潰さない。** SF は `circle` / `circle.fill` の差だけで選択状態や
|
|
22
|
+
* チェック済みを表している箇所があるので、Android 側も別のアイコンに割り当てる。
|
|
23
|
+
*/
|
|
24
|
+
export declare const SF_TO_ANDROID: Record<string, AndroidSymbol>;
|
|
25
|
+
//#endregion
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/native/atom/symbol.types.ts
|
|
2
|
+
/**
|
|
3
|
+
* SF Symbol → Material Symbols(Android)の読み替え表。
|
|
4
|
+
*
|
|
5
|
+
* **`SymbolView` は `name` を文字列で渡すと Android では何も描かない。**
|
|
6
|
+
* `{ ios, android }` の形で渡したときだけ Android 実装(Material Symbols のフォント)が動く。
|
|
7
|
+
* 実際、アプリ全体が SF 名の文字列を渡していたため、Android では検索欄の虫眼鏡・設定の歯車・
|
|
8
|
+
* 行の `>`・空状態のアイコンが**例外も警告も無く全部消えていた**。
|
|
9
|
+
*
|
|
10
|
+
* **fill の有無を潰さない。** SF は `circle` / `circle.fill` の差だけで選択状態や
|
|
11
|
+
* チェック済みを表している箇所があるので、Android 側も別のアイコンに割り当てる。
|
|
12
|
+
*/
|
|
13
|
+
const SF_TO_ANDROID = {
|
|
14
|
+
archivebox: "archive",
|
|
15
|
+
book: "book",
|
|
16
|
+
"book.fill": "menu_book",
|
|
17
|
+
calendar: "calendar_month",
|
|
18
|
+
"chart.bar": "bar_chart",
|
|
19
|
+
"chart.pie": "pie_chart_outline",
|
|
20
|
+
"chart.pie.fill": "pie_chart",
|
|
21
|
+
checkmark: "check",
|
|
22
|
+
"checkmark.circle.fill": "check_circle",
|
|
23
|
+
"chevron.left": "chevron_left",
|
|
24
|
+
"chevron.right": "chevron_right",
|
|
25
|
+
circle: "circle",
|
|
26
|
+
"circle.fill": "brightness_1",
|
|
27
|
+
"doc.on.doc": "content_copy",
|
|
28
|
+
gearshape: "settings",
|
|
29
|
+
"info.circle": "info",
|
|
30
|
+
"line.3.horizontal.decrease": "filter_list",
|
|
31
|
+
"line.3.horizontal.decrease.circle.fill": "filter_alt",
|
|
32
|
+
link: "link",
|
|
33
|
+
"link.badge.plus": "add_link",
|
|
34
|
+
lock: "lock_open",
|
|
35
|
+
"lock.fill": "lock",
|
|
36
|
+
magnifyingglass: "search",
|
|
37
|
+
"note.text": "note",
|
|
38
|
+
pencil: "edit",
|
|
39
|
+
"square.and.arrow.up": "ios_share",
|
|
40
|
+
"square.stack": "stack",
|
|
41
|
+
"square.stack.3d.up": "stack_group",
|
|
42
|
+
"square.stack.fill": "layers",
|
|
43
|
+
tray: "inbox",
|
|
44
|
+
"tray.and.arrow.up": "unarchive",
|
|
45
|
+
xmark: "close"
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
export { SF_TO_ANDROID };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ControlA11yProps } from "../lib/control.js";
|
|
2
|
+
import { AutoComplete } from "../lib/autocomplete.js";
|
|
3
|
+
//#region src/native/atom/text-field.d.ts
|
|
4
|
+
export type TextFieldType = "text" | "number" | "password" | "email" | "tel";
|
|
5
|
+
export type TextFieldProps = ControlA11yProps & {
|
|
6
|
+
value: string;
|
|
7
|
+
onChangeText: (text: string) => void;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
type?: TextFieldType;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
/** エラー。罫線が destructive になり、`aria-invalid` が付く(フォームの中では `FormControl` が渡す)。 */
|
|
12
|
+
invalid?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* 自動入力の種類(web の `TextInput.autoComplete` と同じ意味の語。`email`・`current-password`・`one-time-code` など)。
|
|
15
|
+
* RN の `autoComplete` にそのまま渡り、iOS では `textContentType` にも読み替えて渡す(`lib/autocomplete.ts`)。
|
|
16
|
+
* web より型が狭い(RN が受ける語だけ)。
|
|
17
|
+
*/
|
|
18
|
+
autoComplete?: AutoComplete;
|
|
19
|
+
autoCapitalize?: "none" | "sentences" | "words" | "characters";
|
|
20
|
+
/** `false` で自動修正(スマート引用符への置き換えなど)を切る。JSON・コード・ID を打たせる欄に使う。 */
|
|
21
|
+
autoCorrect?: boolean;
|
|
22
|
+
/** フォーカスが外れたとき(入力中の文字を確定する・破棄するのに使う)。 */
|
|
23
|
+
onBlur?: () => void;
|
|
24
|
+
multiline?: boolean;
|
|
25
|
+
/** 複数行のときの行数目安(`multiline` と併用する)。 */
|
|
26
|
+
numberOfLines?: number;
|
|
27
|
+
onSubmitEditing?: () => void;
|
|
28
|
+
returnKeyType?: "done" | "go" | "next" | "search" | "send";
|
|
29
|
+
accessibilityLabel?: string;
|
|
30
|
+
/**
|
|
31
|
+
* E2E から一意に掴むための識別子(iOS では accessibilityIdentifier になる)。
|
|
32
|
+
*
|
|
33
|
+
* ラベルと入力欄が同じ文言を持つフォームでは、テキスト一致だと**見出しの方に当たって
|
|
34
|
+
* 入力が消える**(Maestro で実際に踏んだ)。掴ませたい入力欄には付けること。
|
|
35
|
+
*/
|
|
36
|
+
testID?: string;
|
|
37
|
+
className?: string;
|
|
38
|
+
};
|
|
39
|
+
export declare const textFieldClass = "min-h-9 w-full rounded-control border border-line-strong bg-raised px-3 py-1.5 text-sm text-foreground";
|
|
40
|
+
/**
|
|
41
|
+
* 素のテキスト入力。`@lt-three/web` の base/input に対応する入力枠で、
|
|
42
|
+
* TanStack Form を使わない画面(ログイン・設定・メモ欄など)から直接使う。
|
|
43
|
+
*
|
|
44
|
+
* `base/input` は `@expo/ui` の OS ネイティブ TextField なので**トークンで塗れない**。
|
|
45
|
+
* web と同じ見た目にしたい入力はこちらを使うこと。フォーム統合が要るときは
|
|
46
|
+
* `form/text-input`(これを内側で使っている)。
|
|
47
|
+
*/
|
|
48
|
+
export declare function TextField({ value, onChangeText, placeholder, type, disabled, invalid, autoComplete, autoCapitalize, autoCorrect, onBlur, multiline, numberOfLines, onSubmitEditing, returnKeyType, accessibilityLabel, accessibilityHint, testID, className, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }: TextFieldProps): import("react").JSX.Element;
|
|
49
|
+
//#endregion
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { textContentTypeOf } from "../lib/autocomplete.js";
|
|
4
|
+
import { TextInput } from "react-native";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/native/atom/text-field.tsx
|
|
8
|
+
const textFieldClass = "min-h-9 w-full rounded-control border border-line-strong bg-raised px-3 py-1.5 text-sm text-foreground";
|
|
9
|
+
const KEYBOARD = {
|
|
10
|
+
text: "default",
|
|
11
|
+
number: "decimal-pad",
|
|
12
|
+
password: "default",
|
|
13
|
+
email: "email-address",
|
|
14
|
+
tel: "phone-pad"
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* 素のテキスト入力。`@lt-three/web` の base/input に対応する入力枠で、
|
|
18
|
+
* TanStack Form を使わない画面(ログイン・設定・メモ欄など)から直接使う。
|
|
19
|
+
*
|
|
20
|
+
* `base/input` は `@expo/ui` の OS ネイティブ TextField なので**トークンで塗れない**。
|
|
21
|
+
* web と同じ見た目にしたい入力はこちらを使うこと。フォーム統合が要るときは
|
|
22
|
+
* `form/text-input`(これを内側で使っている)。
|
|
23
|
+
*/
|
|
24
|
+
function TextField({ value, onChangeText, placeholder, type = "text", disabled, invalid, autoComplete, autoCapitalize, autoCorrect, onBlur, multiline, numberOfLines, onSubmitEditing, returnKeyType, accessibilityLabel, accessibilityHint, testID, className, id, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
|
|
25
|
+
const mutedInk = useTokenColor("--ink-500");
|
|
26
|
+
const isInvalid = invalid ?? ariaInvalid;
|
|
27
|
+
return /* @__PURE__ */ jsx(TextInput, {
|
|
28
|
+
value,
|
|
29
|
+
onChangeText,
|
|
30
|
+
placeholder,
|
|
31
|
+
placeholderTextColor: mutedInk,
|
|
32
|
+
editable: !disabled,
|
|
33
|
+
secureTextEntry: type === "password",
|
|
34
|
+
keyboardType: KEYBOARD[type],
|
|
35
|
+
autoComplete,
|
|
36
|
+
textContentType: textContentTypeOf(autoComplete),
|
|
37
|
+
autoCapitalize: autoCapitalize ?? (type === "email" ? "none" : void 0),
|
|
38
|
+
autoCorrect: autoCorrect ?? (type === "email" ? false : void 0),
|
|
39
|
+
onBlur,
|
|
40
|
+
multiline,
|
|
41
|
+
numberOfLines,
|
|
42
|
+
onSubmitEditing,
|
|
43
|
+
returnKeyType,
|
|
44
|
+
accessibilityLabel,
|
|
45
|
+
accessibilityHint,
|
|
46
|
+
id,
|
|
47
|
+
"aria-labelledby": ariaLabelledBy,
|
|
48
|
+
"aria-describedby": ariaDescribedBy,
|
|
49
|
+
"aria-invalid": isInvalid,
|
|
50
|
+
testID,
|
|
51
|
+
className: cn(textFieldClass, multiline && "min-h-[72px] py-2", isInvalid && "border-destructive", disabled && "opacity-50", className)
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { TextField, textFieldClass };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ActiveScheme } from "../lib/scheme.js";
|
|
2
|
+
import "../lib/theme.js";
|
|
3
|
+
//#region src/native/atom/theme-toggle.d.ts
|
|
4
|
+
export type ThemeToggleProps = {
|
|
5
|
+
/** 切り替えたいテーマ(`light` / `dark`)を受け取る。保存先(AsyncStorage・jotai など)はアプリが持つ。 */
|
|
6
|
+
onSchemeChange: (scheme: ActiveScheme) => void;
|
|
7
|
+
/** いまのテーマ。省略すると `useActiveScheme()`(`ThemeRoot`、無ければ端末の設定)に従う。 */
|
|
8
|
+
scheme?: ActiveScheme;
|
|
9
|
+
/** スクリーンリーダー向けのラベル。 */
|
|
10
|
+
accessibilityLabel?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* ライト / ダークを 1 タップで入れ替える。
|
|
15
|
+
* 「システム追従」を含む 3 択が要るなら、アプリが `ThemeRoot` の `preference` を直接持つ。
|
|
16
|
+
*
|
|
17
|
+
* 移植元は jotai の `themePreferenceAtom` を直接書き換えていた。love3 はテーマの保存先を持たない(`ThemeRoot` は
|
|
18
|
+
* `preference` を props で受ける)ので、`onSchemeChange` で次のテーマを渡す形にした。
|
|
19
|
+
*/
|
|
20
|
+
export declare function ThemeToggle({ onSchemeChange, scheme: schemeProp, accessibilityLabel, className }: ThemeToggleProps): import("react").JSX.Element;
|
|
21
|
+
//#endregion
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useActiveScheme } from "../lib/theme.js";
|
|
2
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Platform, Pressable } from "react-native";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import Feather from "@expo/vector-icons/Feather";
|
|
7
|
+
|
|
8
|
+
//#region src/native/atom/theme-toggle.tsx
|
|
9
|
+
/**
|
|
10
|
+
* ライト / ダークを 1 タップで入れ替える。
|
|
11
|
+
* 「システム追従」を含む 3 択が要るなら、アプリが `ThemeRoot` の `preference` を直接持つ。
|
|
12
|
+
*
|
|
13
|
+
* 移植元は jotai の `themePreferenceAtom` を直接書き換えていた。love3 はテーマの保存先を持たない(`ThemeRoot` は
|
|
14
|
+
* `preference` を props で受ける)ので、`onSchemeChange` で次のテーマを渡す形にした。
|
|
15
|
+
*/
|
|
16
|
+
function ThemeToggle({ onSchemeChange, scheme: schemeProp, accessibilityLabel = "テーマ切り替え", className }) {
|
|
17
|
+
const active = useActiveScheme();
|
|
18
|
+
const scheme = schemeProp ?? active;
|
|
19
|
+
const ink = useTokenColor("--ink-500");
|
|
20
|
+
return /* @__PURE__ */ jsx(Pressable, {
|
|
21
|
+
accessibilityRole: "button",
|
|
22
|
+
accessibilityLabel,
|
|
23
|
+
onPress: () => onSchemeChange(scheme === "dark" ? "light" : "dark"),
|
|
24
|
+
...Platform.OS === "web" ? { "aria-pressed": scheme === "dark" } : { "aria-selected": scheme === "dark" },
|
|
25
|
+
hitSlop: 12,
|
|
26
|
+
className: cn("h-8 w-8 items-center justify-center rounded-control", className),
|
|
27
|
+
children: /* @__PURE__ */ jsx(Feather, {
|
|
28
|
+
name: scheme === "dark" ? "sun" : "moon",
|
|
29
|
+
size: 16,
|
|
30
|
+
color: ink
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ThemeToggle };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SelectProps } from "./select.js";
|
|
2
|
+
//#region src/native/atom/timezone-select.d.ts
|
|
3
|
+
export type TimezoneSelectProps = Pick<SelectProps, "label" | "description" | "placeholder" | "disabled" | "size" | "className" | "wrapperClassName" | "sheetTitle" | "closeLabel" | "accessibilityLabel"> & {
|
|
4
|
+
/** 選択中の IANA タイムゾーン。空文字は「まだ決まっていない」(placeholder を出す)。 */
|
|
5
|
+
value: string;
|
|
6
|
+
onValueChange: (zone: string) => void;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* タイムゾーン(IANA 文字列)を選ぶ Select。`@lt-three/web` の atom/timezone-select と同じ名前・同じ props。
|
|
10
|
+
*
|
|
11
|
+
* 選択肢は主要な都市の固定リストに、この端末のタイムゾーンと選択中の値を足したもの(`lib/timezone.ts`)。
|
|
12
|
+
* Hermes に `Intl.supportedValuesOf` が無いので固定リストにしている。
|
|
13
|
+
* 下から出るシートで選ぶので、`closeLabel` は呼び出し側の言語で渡すこと(既定は日本語)。
|
|
14
|
+
*/
|
|
15
|
+
export declare function TimezoneSelect({ value, onValueChange, ...props }: TimezoneSelectProps): import("react").JSX.Element;
|
|
16
|
+
//#endregion
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Select } from "./select.js";
|
|
2
|
+
import { formatTimeZoneLabel, getDeviceTimeZone, timeZoneOptions } from "../lib/timezone.js";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/native/atom/timezone-select.tsx
|
|
7
|
+
/**
|
|
8
|
+
* タイムゾーン(IANA 文字列)を選ぶ Select。`@lt-three/web` の atom/timezone-select と同じ名前・同じ props。
|
|
9
|
+
*
|
|
10
|
+
* 選択肢は主要な都市の固定リストに、この端末のタイムゾーンと選択中の値を足したもの(`lib/timezone.ts`)。
|
|
11
|
+
* Hermes に `Intl.supportedValuesOf` が無いので固定リストにしている。
|
|
12
|
+
* 下から出るシートで選ぶので、`closeLabel` は呼び出し側の言語で渡すこと(既定は日本語)。
|
|
13
|
+
*/
|
|
14
|
+
function TimezoneSelect({ value, onValueChange, ...props }) {
|
|
15
|
+
const options = useMemo(() => timeZoneOptions(getDeviceTimeZone(), value).map((zone) => ({
|
|
16
|
+
value: zone,
|
|
17
|
+
label: formatTimeZoneLabel(zone)
|
|
18
|
+
})), [value]);
|
|
19
|
+
return /* @__PURE__ */ jsx(Select, {
|
|
20
|
+
...props,
|
|
21
|
+
value,
|
|
22
|
+
onValueChange,
|
|
23
|
+
options
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { TimezoneSelect };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/native/atom/typography.d.ts
|
|
3
|
+
export type SectionTitleProps = {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
description?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* セクション見出し。`@lt-three/web` の atom/typography の SectionTitle に対応する。
|
|
10
|
+
* 左端の 2px インディゴのバー + 太字の見出し + 任意の説明という同じ構成。
|
|
11
|
+
*/
|
|
12
|
+
export declare function SectionTitle({ children, description, className }: SectionTitleProps): import("react").JSX.Element;
|
|
13
|
+
//#endregion
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
3
|
+
import { View } from "react-native";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/native/atom/typography.tsx
|
|
7
|
+
/**
|
|
8
|
+
* セクション見出し。`@lt-three/web` の atom/typography の SectionTitle に対応する。
|
|
9
|
+
* 左端の 2px インディゴのバー + 太字の見出し + 任意の説明という同じ構成。
|
|
10
|
+
*/
|
|
11
|
+
function SectionTitle({ children, description, className }) {
|
|
12
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
13
|
+
className: "gap-0.5",
|
|
14
|
+
children: [/* @__PURE__ */ jsxs(View, {
|
|
15
|
+
className: "flex-row items-center py-2 pl-3",
|
|
16
|
+
children: [/* @__PURE__ */ jsx(View, { className: "absolute inset-y-2 left-1 w-0.5 bg-action/70" }), /* @__PURE__ */ jsx(Text$1, {
|
|
17
|
+
className: cn("text-sm font-semibold", className),
|
|
18
|
+
children
|
|
19
|
+
})]
|
|
20
|
+
}), description ? /* @__PURE__ */ jsx(Text$1, {
|
|
21
|
+
className: "text-muted-foreground text-sm",
|
|
22
|
+
children: description
|
|
23
|
+
}) : null]
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { SectionTitle };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ButtonVariant } from "../../shared/button.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
import { ViewStyle } from "react-native";
|
|
4
|
+
//#region src/native/base/button.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* ボタンの見た目バリアント。**`atom/button`(と web の Button)と同じ名前**(`@lt-three/love3/shared` の `ButtonVariant`)に、
|
|
7
|
+
* iOS 26 の Liquid Glass だけの `glass` を足したもの。
|
|
8
|
+
* - `glass`: iOS 26 の Liquid Glass ボタン(主要アクション向け。iOS 26 未満・Android では塗りつぶしに落ちる)
|
|
9
|
+
* - ほかは `atom/button` と同じ意味。OS のコントロールが持つ 3 つの形(塗り・枠・文字だけ)に写す(下の表)
|
|
10
|
+
*/
|
|
11
|
+
export type NativeButtonVariant = ButtonVariant | "glass";
|
|
12
|
+
declare const IOS_BUTTON_STYLE: {
|
|
13
|
+
readonly default: "borderedProminent";
|
|
14
|
+
readonly destructive: "borderedProminent";
|
|
15
|
+
readonly outline: "bordered";
|
|
16
|
+
readonly secondary: "bordered";
|
|
17
|
+
readonly ghost: "plain";
|
|
18
|
+
readonly link: "plain";
|
|
19
|
+
readonly plate: "bordered";
|
|
20
|
+
readonly "<3": "borderedProminent";
|
|
21
|
+
readonly glass: "glassProminent";
|
|
22
|
+
};
|
|
23
|
+
declare const UNIVERSAL_VARIANT: {
|
|
24
|
+
readonly default: "filled";
|
|
25
|
+
readonly destructive: "filled";
|
|
26
|
+
readonly outline: "outlined";
|
|
27
|
+
readonly secondary: "filled";
|
|
28
|
+
readonly ghost: "text";
|
|
29
|
+
readonly link: "text";
|
|
30
|
+
readonly plate: "outlined";
|
|
31
|
+
readonly "<3": "filled";
|
|
32
|
+
readonly glass: "filled";
|
|
33
|
+
};
|
|
34
|
+
type ButtonProps = {
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
onPress?: () => void;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
variant?: NativeButtonVariant;
|
|
39
|
+
/**
|
|
40
|
+
* アクセント色(iOS の SwiftUI `.tint()`)。省略すると、variant に合わせたトークンの色
|
|
41
|
+
* (`default` は主操作のインディゴ、`destructive` は destructive-solid、`<3` はブランド色)。
|
|
42
|
+
*/
|
|
43
|
+
tintColor?: string;
|
|
44
|
+
/**
|
|
45
|
+
* ラベル文字色(iOS の SwiftUI `.foregroundStyle()`)。省略すると、塗りの上で読める組のトークンの色。
|
|
46
|
+
* prominent 系は既定でラベルが白のため、明るい tint と組み合わせると読めなくなる(反転する面でも同じ)。
|
|
47
|
+
*/
|
|
48
|
+
labelColor?: string;
|
|
49
|
+
/** Host コンテナ(RN View)に適用するスタイル。幅・余白の調整に使う。 */
|
|
50
|
+
style?: ViewStyle;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* ネイティブボタン(OS のコントロールの層)。iOS は SwiftUI の `Button`、Android は Jetpack Compose の
|
|
54
|
+
* `Button` を描画する(`@expo/ui` universal 経由)。iOS 26 では `glass` が Liquid Glass になる。
|
|
55
|
+
*
|
|
56
|
+
* `atom/button`(RN の `Pressable`。トークンで塗るボタン)に対する、**OS ネイティブ版の base 層**。
|
|
57
|
+
* web と同じ見た目にしたい場所は `atom/button`、OS の標準の見た目・触感がほしい場所はこちら。
|
|
58
|
+
*/
|
|
59
|
+
declare function Button({ children, onPress, disabled, variant, tintColor, labelColor, style }: ButtonProps): import("react").JSX.Element;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { Button, type ButtonProps, IOS_BUTTON_STYLE, UNIVERSAL_VARIANT };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
2
|
+
import { Platform } from "react-native";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Button as Button$1, Host } from "@expo/ui";
|
|
5
|
+
import { buttonStyle, foregroundStyle, tint } from "@expo/ui/swift-ui/modifiers";
|
|
6
|
+
|
|
7
|
+
//#region src/native/base/button.tsx
|
|
8
|
+
const IOS_BUTTON_STYLE = {
|
|
9
|
+
default: "borderedProminent",
|
|
10
|
+
destructive: "borderedProminent",
|
|
11
|
+
outline: "bordered",
|
|
12
|
+
secondary: "bordered",
|
|
13
|
+
ghost: "plain",
|
|
14
|
+
link: "plain",
|
|
15
|
+
plate: "bordered",
|
|
16
|
+
"<3": "borderedProminent",
|
|
17
|
+
glass: "glassProminent"
|
|
18
|
+
};
|
|
19
|
+
const UNIVERSAL_VARIANT = {
|
|
20
|
+
default: "filled",
|
|
21
|
+
destructive: "filled",
|
|
22
|
+
outline: "outlined",
|
|
23
|
+
secondary: "filled",
|
|
24
|
+
ghost: "text",
|
|
25
|
+
link: "text",
|
|
26
|
+
plate: "outlined",
|
|
27
|
+
"<3": "filled",
|
|
28
|
+
glass: "filled"
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* ネイティブボタン(OS のコントロールの層)。iOS は SwiftUI の `Button`、Android は Jetpack Compose の
|
|
32
|
+
* `Button` を描画する(`@expo/ui` universal 経由)。iOS 26 では `glass` が Liquid Glass になる。
|
|
33
|
+
*
|
|
34
|
+
* `atom/button`(RN の `Pressable`。トークンで塗るボタン)に対する、**OS ネイティブ版の base 層**。
|
|
35
|
+
* web と同じ見た目にしたい場所は `atom/button`、OS の標準の見た目・触感がほしい場所はこちら。
|
|
36
|
+
*/
|
|
37
|
+
function Button({ children, onPress, disabled, variant = "default", tintColor, labelColor, style }) {
|
|
38
|
+
const primary = useTokenColor("--primary");
|
|
39
|
+
const primaryForeground = useTokenColor("--primary-foreground");
|
|
40
|
+
const destructive = useTokenColor("--destructive-solid");
|
|
41
|
+
const destructiveForeground = useTokenColor("--destructive-solid-foreground");
|
|
42
|
+
const actionInk = useTokenColor("--action-ink");
|
|
43
|
+
const brand = useTokenColor("--lt-three");
|
|
44
|
+
const brandForeground = useTokenColor("--lt-three-foreground");
|
|
45
|
+
const foreground = useTokenColor("--foreground");
|
|
46
|
+
const defaults = {
|
|
47
|
+
default: {
|
|
48
|
+
tint: primary,
|
|
49
|
+
label: primaryForeground
|
|
50
|
+
},
|
|
51
|
+
destructive: {
|
|
52
|
+
tint: destructive,
|
|
53
|
+
label: destructiveForeground
|
|
54
|
+
},
|
|
55
|
+
outline: { tint: foreground },
|
|
56
|
+
secondary: { tint: foreground },
|
|
57
|
+
ghost: { tint: foreground },
|
|
58
|
+
link: { tint: actionInk },
|
|
59
|
+
plate: { tint: foreground },
|
|
60
|
+
"<3": {
|
|
61
|
+
tint: brand,
|
|
62
|
+
label: brandForeground
|
|
63
|
+
},
|
|
64
|
+
glass: {
|
|
65
|
+
tint: primary,
|
|
66
|
+
label: primaryForeground
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const label = typeof children === "string" ? children : void 0;
|
|
70
|
+
const tintValue = tintColor ?? defaults[variant].tint;
|
|
71
|
+
const labelValue = labelColor ?? defaults[variant].label;
|
|
72
|
+
const modifiers = Platform.OS === "ios" ? [
|
|
73
|
+
buttonStyle(IOS_BUTTON_STYLE[variant]),
|
|
74
|
+
...tintValue ? [tint(tintValue)] : [],
|
|
75
|
+
...labelValue ? [foregroundStyle(labelValue)] : []
|
|
76
|
+
] : void 0;
|
|
77
|
+
return /* @__PURE__ */ jsx(Host, {
|
|
78
|
+
matchContents: true,
|
|
79
|
+
style,
|
|
80
|
+
children: /* @__PURE__ */ jsx(Button$1, {
|
|
81
|
+
label,
|
|
82
|
+
onPress,
|
|
83
|
+
disabled,
|
|
84
|
+
variant: UNIVERSAL_VARIANT[variant],
|
|
85
|
+
modifiers,
|
|
86
|
+
children: label ? void 0 : children
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { Button, IOS_BUTTON_STYLE, UNIVERSAL_VARIANT };
|