@lt-three/love3 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +86 -2
- 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 +205 -4
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/native/analytics/single-number.d.ts
|
|
2
|
+
export type SingleNumberProps = {
|
|
3
|
+
title: string;
|
|
4
|
+
subTitle?: string;
|
|
5
|
+
value: number | null;
|
|
6
|
+
unit?: string;
|
|
7
|
+
/** 比較対象の値。渡すと差分と増減率を併記する。 */
|
|
8
|
+
compareValue?: number;
|
|
9
|
+
compareTitle?: string;
|
|
10
|
+
/** 増が悪い指標(コスト等)で色を反転する。 */
|
|
11
|
+
reverseColor?: boolean;
|
|
12
|
+
className?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* raised 面(surface 角丸・1px の極薄の罫線)に大きな数値を載せる指標。
|
|
16
|
+
* `@lt-three/web` の analytics/single-number に対応する。増減は state の色(面が反転しないので、同じテーマの値でよい)。
|
|
17
|
+
*/
|
|
18
|
+
export declare function SingleNumber({ title, subTitle, value, unit, compareValue, compareTitle, reverseColor, className }: SingleNumberProps): import("react").JSX.Element;
|
|
19
|
+
//#endregion
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
4
|
+
import { tabularNums } from "../lib/typography.js";
|
|
5
|
+
import { View } from "react-native";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import Feather from "@expo/vector-icons/Feather";
|
|
8
|
+
|
|
9
|
+
//#region src/native/analytics/single-number.tsx
|
|
10
|
+
/**
|
|
11
|
+
* raised 面(surface 角丸・1px の極薄の罫線)に大きな数値を載せる指標。
|
|
12
|
+
* `@lt-three/web` の analytics/single-number に対応する。増減は state の色(面が反転しないので、同じテーマの値でよい)。
|
|
13
|
+
*/
|
|
14
|
+
function SingleNumber({ title, subTitle, value, unit, compareValue, compareTitle, reverseColor, className }) {
|
|
15
|
+
const up = useTokenColor("--state-success");
|
|
16
|
+
const down = useTokenColor("--state-error");
|
|
17
|
+
const diff = typeof compareValue === "number" ? (value ?? 0) - compareValue : 0;
|
|
18
|
+
const diffPercent = (1 - (value ?? 0) / (compareValue ?? 0)) * -100;
|
|
19
|
+
const diffColor = reverseColor ? diff < 0 ? up : down : diff < 0 ? down : up;
|
|
20
|
+
const iconName = diff < 0 ? "chevron-down" : "chevron-up";
|
|
21
|
+
const showCompare = typeof value === "number" && typeof compareValue === "number";
|
|
22
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
23
|
+
className: cn("gap-3 rounded-surface border border-line bg-card p-3", className),
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsxs(View, {
|
|
26
|
+
className: "flex-row items-end gap-2",
|
|
27
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
28
|
+
className: "text-card-foreground text-lg font-bold",
|
|
29
|
+
children: title
|
|
30
|
+
}), subTitle ? /* @__PURE__ */ jsx(Text$1, {
|
|
31
|
+
className: "text-muted-foreground text-xs",
|
|
32
|
+
children: subTitle
|
|
33
|
+
}) : null]
|
|
34
|
+
}),
|
|
35
|
+
/* @__PURE__ */ jsxs(View, {
|
|
36
|
+
className: "flex-row items-end",
|
|
37
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
38
|
+
style: tabularNums,
|
|
39
|
+
className: "text-card-foreground font-mono text-3xl leading-none",
|
|
40
|
+
children: value
|
|
41
|
+
}), unit ? /* @__PURE__ */ jsx(Text$1, {
|
|
42
|
+
className: "text-card-foreground ml-1 text-base",
|
|
43
|
+
children: unit
|
|
44
|
+
}) : null]
|
|
45
|
+
}),
|
|
46
|
+
showCompare ? /* @__PURE__ */ jsxs(View, {
|
|
47
|
+
className: "flex-row items-end gap-2",
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsxs(View, {
|
|
50
|
+
className: "flex-row items-center",
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ jsx(Feather, {
|
|
53
|
+
name: iconName,
|
|
54
|
+
size: 14,
|
|
55
|
+
color: diffColor
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ jsx(Text$1, {
|
|
58
|
+
style: [tabularNums, { color: diffColor }],
|
|
59
|
+
className: "font-mono text-lg leading-none",
|
|
60
|
+
children: diff
|
|
61
|
+
}),
|
|
62
|
+
unit ? /* @__PURE__ */ jsx(Text$1, {
|
|
63
|
+
style: { color: diffColor },
|
|
64
|
+
className: "ml-1 text-xs",
|
|
65
|
+
children: unit
|
|
66
|
+
}) : null
|
|
67
|
+
]
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ jsxs(View, {
|
|
70
|
+
className: "flex-row items-center",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(Feather, {
|
|
73
|
+
name: iconName,
|
|
74
|
+
size: 14,
|
|
75
|
+
color: diffColor
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ jsx(Text$1, {
|
|
78
|
+
style: [tabularNums, { color: diffColor }],
|
|
79
|
+
className: "font-mono text-lg leading-none",
|
|
80
|
+
children: Number.isNaN(diffPercent) ? 0 : !Number.isFinite(diffPercent) ? 100 : diffPercent.toFixed(2)
|
|
81
|
+
}),
|
|
82
|
+
/* @__PURE__ */ jsx(Text$1, {
|
|
83
|
+
style: { color: diffColor },
|
|
84
|
+
className: "ml-1 text-xs",
|
|
85
|
+
children: "%"
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}),
|
|
89
|
+
compareTitle ? /* @__PURE__ */ jsx(Text$1, {
|
|
90
|
+
style: { color: diffColor },
|
|
91
|
+
className: "text-xs",
|
|
92
|
+
children: compareTitle
|
|
93
|
+
}) : null
|
|
94
|
+
]
|
|
95
|
+
}) : null
|
|
96
|
+
]
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//#endregion
|
|
101
|
+
export { SingleNumber };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
//#region src/native/atom/avatar.d.ts
|
|
3
|
+
export type AvatarProps = {
|
|
4
|
+
src?: string;
|
|
5
|
+
/** 画像の代替テキスト。既定は空(飾り。隣に名前が出ている前提)。名前の無い単独の顔なら、人の名前を渡す(web と同じ) */
|
|
6
|
+
alt?: string;
|
|
7
|
+
/**
|
|
8
|
+
* 画像が無い / 失敗したときに出すもの(イニシャル等)。文字列は Text で包む。**省略・空文字は人物アイコン**
|
|
9
|
+
* (web は空文字だと何も出さない)。数値は受けない(RN は View の直下の文字を描けない。文字列にして渡す)。
|
|
10
|
+
*/
|
|
11
|
+
fallback?: string | ReactElement;
|
|
12
|
+
/** 一辺の px。既定は web の `size-6` と同じ 24。 */
|
|
13
|
+
size?: number;
|
|
14
|
+
className?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* `@lt-three/web` の atom/avatar と同じ構成(画像 + フォールバック)。
|
|
18
|
+
* web の Avatar と同じ円(`rounded-full`)で描く。
|
|
19
|
+
*/
|
|
20
|
+
export declare function Avatar({ src, alt, fallback, size, className }: AvatarProps): import("react").JSX.Element;
|
|
21
|
+
//#endregion
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { View } from "react-native";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import Feather from "@expo/vector-icons/Feather";
|
|
8
|
+
import { Image } from "expo-image";
|
|
9
|
+
|
|
10
|
+
//#region src/native/atom/avatar.tsx
|
|
11
|
+
/**
|
|
12
|
+
* `@lt-three/web` の atom/avatar と同じ構成(画像 + フォールバック)。
|
|
13
|
+
* web の Avatar と同じ円(`rounded-full`)で描く。
|
|
14
|
+
*/
|
|
15
|
+
function Avatar({ src, alt = "", fallback, size = 24, className }) {
|
|
16
|
+
const [failed, setFailed] = useState(false);
|
|
17
|
+
const wash = useTokenColor("--wash");
|
|
18
|
+
const showImage = !!src && !failed;
|
|
19
|
+
return /* @__PURE__ */ jsx(View, {
|
|
20
|
+
style: {
|
|
21
|
+
width: size,
|
|
22
|
+
height: size
|
|
23
|
+
},
|
|
24
|
+
className: cn("items-center justify-center overflow-hidden rounded-full bg-ink-500", className),
|
|
25
|
+
children: showImage ? /* @__PURE__ */ jsx(Image, {
|
|
26
|
+
source: { uri: src },
|
|
27
|
+
accessibilityLabel: alt,
|
|
28
|
+
style: {
|
|
29
|
+
width: size,
|
|
30
|
+
height: size
|
|
31
|
+
},
|
|
32
|
+
onError: () => setFailed(true)
|
|
33
|
+
}) : fallback === void 0 || fallback === "" ? /* @__PURE__ */ jsx(Feather, {
|
|
34
|
+
name: "user",
|
|
35
|
+
size: size * .6,
|
|
36
|
+
color: wash
|
|
37
|
+
}) : typeof fallback === "string" ? /* @__PURE__ */ jsx(Text$1, {
|
|
38
|
+
style: { fontSize: size * .45 },
|
|
39
|
+
className: "text-wash font-medium",
|
|
40
|
+
children: fallback
|
|
41
|
+
}) : fallback
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
export { Avatar };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/native/atom/badge.d.ts
|
|
4
|
+
declare const badgeVariants: (props?: ({
|
|
5
|
+
variant?: "<3" | "default" | "destructive" | "outline" | "secondary" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export type BadgeVariants = VariantProps<typeof badgeVariants>["variant"];
|
|
8
|
+
export type BadgeProps = {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
variant?: BadgeVariants;
|
|
11
|
+
/**
|
|
12
|
+
* タップ可能にする(フィルタチップ等)。web の Badge には無い native 固有の追加で、
|
|
13
|
+
* 見た目は変えずに `hitSlop` で 44pt 相当のタップ領域を確保する。
|
|
14
|
+
*/
|
|
15
|
+
onPress?: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* 読み上げ・E2E 用の名前。同じ文言のチップが軸をまたいで並ぶとき
|
|
18
|
+
* (どの軸の「すべて」なのか)に必ず渡す。
|
|
19
|
+
*/
|
|
20
|
+
accessibilityLabel?: string;
|
|
21
|
+
/** 選択中のチップであることを読み上げ・E2E に伝える。 */
|
|
22
|
+
selected?: boolean;
|
|
23
|
+
className?: string;
|
|
24
|
+
textClassName?: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function Badge({ children, variant, onPress, accessibilityLabel, selected, className, textClassName }: BadgeProps): import("react").JSX.Element;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { badgeVariants };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
3
|
+
import { tabularNums } from "../lib/typography.js";
|
|
4
|
+
import { Platform, Pressable, View } from "react-native";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import { cva } from "class-variance-authority";
|
|
7
|
+
|
|
8
|
+
//#region src/native/atom/badge.tsx
|
|
9
|
+
const badgeVariants = cva("h-5 flex-row items-center justify-center gap-1 self-start rounded-control border px-1.5", {
|
|
10
|
+
variants: { variant: {
|
|
11
|
+
default: "border-transparent bg-action",
|
|
12
|
+
secondary: "border-transparent bg-secondary",
|
|
13
|
+
destructive: "border-state-error/30 bg-state-error/5",
|
|
14
|
+
outline: "border-line-strong",
|
|
15
|
+
"<3": "border-transparent bg-lt-three"
|
|
16
|
+
} },
|
|
17
|
+
defaultVariants: { variant: "default" }
|
|
18
|
+
});
|
|
19
|
+
const badgeTextVariants = cva("font-mono text-xs font-medium tracking-[0.01em]", {
|
|
20
|
+
variants: { variant: {
|
|
21
|
+
default: "text-action-foreground",
|
|
22
|
+
secondary: "text-secondary-foreground",
|
|
23
|
+
destructive: "text-state-error",
|
|
24
|
+
outline: "text-foreground",
|
|
25
|
+
"<3": "text-lt-three-foreground"
|
|
26
|
+
} },
|
|
27
|
+
defaultVariants: { variant: "default" }
|
|
28
|
+
});
|
|
29
|
+
function Badge({ children, variant, onPress, accessibilityLabel, selected, className, textClassName }) {
|
|
30
|
+
const badge = /* @__PURE__ */ jsx(View, {
|
|
31
|
+
className: cn(badgeVariants({ variant }), className),
|
|
32
|
+
children: typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx(Text$1, {
|
|
33
|
+
style: tabularNums,
|
|
34
|
+
className: cn(badgeTextVariants({ variant }), textClassName),
|
|
35
|
+
children
|
|
36
|
+
}) : children
|
|
37
|
+
});
|
|
38
|
+
if (!onPress) return badge;
|
|
39
|
+
return /* @__PURE__ */ jsx(Pressable, {
|
|
40
|
+
accessibilityRole: "button",
|
|
41
|
+
accessibilityLabel,
|
|
42
|
+
...Platform.OS === "web" ? { "aria-pressed": selected } : { "aria-selected": selected },
|
|
43
|
+
onPress,
|
|
44
|
+
hitSlop: 12,
|
|
45
|
+
className: "self-start",
|
|
46
|
+
children: badge
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/native/atom/button.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* `@lt-three/web` の base/button と同じバリアント・同じ見た目(インディゴの主操作・raised 面+薄い枠・control 角丸)を持つボタン。
|
|
6
|
+
* 高さだけは、指で押す前提で web より大きい(既定 36)。
|
|
7
|
+
*
|
|
8
|
+
* `base/button`(`@expo/ui`)が OS ネイティブのボタン(iOS 26 の Liquid Glass 等)を出すのに対し、
|
|
9
|
+
* こちらは RN の `Pressable` なのでトークンで塗れる。**web と同じ見た目にしたい場所はこちらを使う。**
|
|
10
|
+
*
|
|
11
|
+
* web の `hover:` は RN に無いので、押下中の `pressed` に読み替えてある。
|
|
12
|
+
*
|
|
13
|
+
* web の Button は `inline-flex` なので内容幅に縮む。RN の `Pressable` は親の cross axis
|
|
14
|
+
* いっぱいに伸びるため `self-start` で同じ挙動にする。画面幅いっぱいの CTA にしたいときは
|
|
15
|
+
* 使用側で `className="self-stretch"` を渡す。
|
|
16
|
+
*/
|
|
17
|
+
declare const buttonVariants: (props?: ({
|
|
18
|
+
variant?: "<3" | "default" | "destructive" | "ghost" | "link" | "outline" | "plate" | "secondary" | null | undefined;
|
|
19
|
+
size?: "default" | "icon" | "icon-xs" | "lg" | "sm" | "xl" | "xs" | null | undefined;
|
|
20
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
21
|
+
declare const buttonTextVariants: (props?: ({
|
|
22
|
+
variant?: "<3" | "default" | "destructive" | "ghost" | "link" | "outline" | "plate" | "secondary" | null | undefined;
|
|
23
|
+
size?: "default" | "icon" | "icon-xs" | "lg" | "sm" | "xl" | "xs" | null | undefined;
|
|
24
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
25
|
+
export type ButtonVariants = VariantProps<typeof buttonVariants>;
|
|
26
|
+
export type ButtonProps = ButtonVariants & {
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
onPress?: () => void;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* ラベルの左右に置く要素。web は lucide のコンポーネント型を取るが、native は
|
|
32
|
+
* `@expo/vector-icons` / `expo-symbols` など描画系がまちまちなので描画済みの要素を受け取る。
|
|
33
|
+
*/
|
|
34
|
+
iconLeft?: ReactNode;
|
|
35
|
+
iconRight?: ReactNode;
|
|
36
|
+
/**
|
|
37
|
+
* 読み上げ・E2E 用の名前。**一覧の中で同じ文言のボタンが並ぶとき(行ごとの「削除」等)は
|
|
38
|
+
* 必ず渡す。** 付けないと VoiceOver でどの行のボタンか分からず、E2E も掴み分けられない。
|
|
39
|
+
*/
|
|
40
|
+
accessibilityLabel?: string;
|
|
41
|
+
className?: string;
|
|
42
|
+
textClassName?: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function Button({ children, onPress, disabled, variant, size, iconLeft, iconRight, accessibilityLabel, className, textClassName }: ButtonProps): import("react").JSX.Element;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { buttonTextVariants, buttonVariants };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Text as Text$1, TextClassContext } from "../base/text.js";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Pressable } from "react-native";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { cva } from "class-variance-authority";
|
|
7
|
+
|
|
8
|
+
//#region src/native/atom/button.tsx
|
|
9
|
+
/**
|
|
10
|
+
* `@lt-three/web` の base/button と同じバリアント・同じ見た目(インディゴの主操作・raised 面+薄い枠・control 角丸)を持つボタン。
|
|
11
|
+
* 高さだけは、指で押す前提で web より大きい(既定 36)。
|
|
12
|
+
*
|
|
13
|
+
* `base/button`(`@expo/ui`)が OS ネイティブのボタン(iOS 26 の Liquid Glass 等)を出すのに対し、
|
|
14
|
+
* こちらは RN の `Pressable` なのでトークンで塗れる。**web と同じ見た目にしたい場所はこちらを使う。**
|
|
15
|
+
*
|
|
16
|
+
* web の `hover:` は RN に無いので、押下中の `pressed` に読み替えてある。
|
|
17
|
+
*
|
|
18
|
+
* web の Button は `inline-flex` なので内容幅に縮む。RN の `Pressable` は親の cross axis
|
|
19
|
+
* いっぱいに伸びるため `self-start` で同じ挙動にする。画面幅いっぱいの CTA にしたいときは
|
|
20
|
+
* 使用側で `className="self-stretch"` を渡す。
|
|
21
|
+
*/
|
|
22
|
+
const buttonVariants = cva("flex-row items-center justify-center gap-2 self-start rounded-control border border-transparent", {
|
|
23
|
+
variants: {
|
|
24
|
+
variant: {
|
|
25
|
+
default: "bg-action",
|
|
26
|
+
destructive: "bg-destructive-solid",
|
|
27
|
+
outline: "border-line-strong bg-raised",
|
|
28
|
+
secondary: "border-line-strong bg-raised",
|
|
29
|
+
ghost: "",
|
|
30
|
+
link: "",
|
|
31
|
+
plate: "border-black bg-white",
|
|
32
|
+
"<3": "bg-lt-three"
|
|
33
|
+
},
|
|
34
|
+
size: {
|
|
35
|
+
default: "h-9 px-4",
|
|
36
|
+
xs: "h-7 gap-1 px-2",
|
|
37
|
+
sm: "h-8 gap-1.5 px-3",
|
|
38
|
+
lg: "h-10 px-6",
|
|
39
|
+
xl: "h-12 px-6",
|
|
40
|
+
icon: "h-8 w-8",
|
|
41
|
+
"icon-xs": "h-7 w-7"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
defaultVariants: {
|
|
45
|
+
variant: "default",
|
|
46
|
+
size: "default"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const buttonTextVariants = cva("font-medium", {
|
|
50
|
+
variants: {
|
|
51
|
+
variant: {
|
|
52
|
+
default: "text-action-foreground",
|
|
53
|
+
destructive: "text-destructive-solid-foreground",
|
|
54
|
+
outline: "text-foreground",
|
|
55
|
+
secondary: "text-secondary-foreground",
|
|
56
|
+
ghost: "text-foreground",
|
|
57
|
+
link: "text-action-ink underline",
|
|
58
|
+
plate: "font-normal text-black",
|
|
59
|
+
"<3": "text-lt-three-foreground"
|
|
60
|
+
},
|
|
61
|
+
size: {
|
|
62
|
+
default: "text-sm",
|
|
63
|
+
xs: "text-xs",
|
|
64
|
+
sm: "text-sm",
|
|
65
|
+
lg: "text-sm",
|
|
66
|
+
xl: "text-sm",
|
|
67
|
+
icon: "text-sm",
|
|
68
|
+
"icon-xs": "text-xs"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
defaultVariants: {
|
|
72
|
+
variant: "default",
|
|
73
|
+
size: "default"
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
function Button({ children, onPress, disabled, variant, size, iconLeft, iconRight, accessibilityLabel, className, textClassName }) {
|
|
77
|
+
const textClass = cn(buttonTextVariants({
|
|
78
|
+
variant,
|
|
79
|
+
size
|
|
80
|
+
}), textClassName);
|
|
81
|
+
const [pressed, setPressed] = useState(false);
|
|
82
|
+
return /* @__PURE__ */ jsx(Pressable, {
|
|
83
|
+
onPress,
|
|
84
|
+
onPressIn: () => setPressed(true),
|
|
85
|
+
onPressOut: () => setPressed(false),
|
|
86
|
+
disabled,
|
|
87
|
+
accessibilityRole: "button",
|
|
88
|
+
"aria-disabled": disabled,
|
|
89
|
+
accessibilityLabel,
|
|
90
|
+
className: cn(buttonVariants({
|
|
91
|
+
variant,
|
|
92
|
+
size
|
|
93
|
+
}), pressed && "opacity-70", disabled && "opacity-50", className),
|
|
94
|
+
children: /* @__PURE__ */ jsxs(TextClassContext.Provider, {
|
|
95
|
+
value: textClass,
|
|
96
|
+
children: [
|
|
97
|
+
iconLeft,
|
|
98
|
+
typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx(Text$1, {
|
|
99
|
+
className: textClass,
|
|
100
|
+
children
|
|
101
|
+
}) : children,
|
|
102
|
+
iconRight
|
|
103
|
+
]
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
export { Button, buttonTextVariants, buttonVariants };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NamedControlA11yProps } from "../lib/control.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/native/atom/checkbox.d.ts
|
|
4
|
+
export type CheckboxProps = NamedControlA11yProps & {
|
|
5
|
+
checked: boolean;
|
|
6
|
+
onCheckedChange: (checked: boolean) => void;
|
|
7
|
+
/** チェックボックスの右に表示するラベル。タップ領域に含まれる。 */
|
|
8
|
+
label?: ReactNode;
|
|
9
|
+
/** 読み上げ名。ラベルが文字列ならそれを使うので、ラベルが無い・文字列でないときに渡す。 */
|
|
10
|
+
accessibilityLabel?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
invalid?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
wrapperClassName?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* `@lt-three/web` の base/checkbox と同じ 16px の control 角丸の四角。
|
|
18
|
+
* 未選択は raised 面 + line-control の枠(3:1)、チェック時はインディゴ塗り + 白のチェック。
|
|
19
|
+
*/
|
|
20
|
+
export declare function Checkbox({ checked, onCheckedChange, label, accessibilityLabel, disabled, invalid, className, wrapperClassName, accessibilityHint, id, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }: CheckboxProps): import("react").JSX.Element;
|
|
21
|
+
//#endregion
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
4
|
+
import { activateOnSpace } from "../lib/keyboard.js";
|
|
5
|
+
import { Pressable, View } from "react-native";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import Feather from "@expo/vector-icons/Feather";
|
|
8
|
+
|
|
9
|
+
//#region src/native/atom/checkbox.tsx
|
|
10
|
+
/**
|
|
11
|
+
* `@lt-three/web` の base/checkbox と同じ 16px の control 角丸の四角。
|
|
12
|
+
* 未選択は raised 面 + line-control の枠(3:1)、チェック時はインディゴ塗り + 白のチェック。
|
|
13
|
+
*/
|
|
14
|
+
function Checkbox({ checked, onCheckedChange, label, accessibilityLabel, disabled, invalid, className, wrapperClassName, accessibilityHint, id, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid }) {
|
|
15
|
+
const isInvalid = invalid ?? ariaInvalid;
|
|
16
|
+
const checkColor = useTokenColor("--action-foreground");
|
|
17
|
+
const box = /* @__PURE__ */ jsx(View, {
|
|
18
|
+
className: cn("h-4 w-4 shrink-0 items-center justify-center rounded-control border", checked ? "border-action bg-action" : "border-line-control bg-raised", isInvalid && "border-destructive", disabled && "opacity-50", className),
|
|
19
|
+
children: checked ? /* @__PURE__ */ jsx(Feather, {
|
|
20
|
+
name: "check",
|
|
21
|
+
size: 12,
|
|
22
|
+
color: checkColor
|
|
23
|
+
}) : null
|
|
24
|
+
});
|
|
25
|
+
return /* @__PURE__ */ jsxs(Pressable, {
|
|
26
|
+
accessibilityRole: "checkbox",
|
|
27
|
+
accessibilityLabel: accessibilityLabel ?? (typeof label === "string" ? label : void 0),
|
|
28
|
+
"aria-checked": checked,
|
|
29
|
+
"aria-disabled": disabled,
|
|
30
|
+
"aria-invalid": isInvalid,
|
|
31
|
+
"aria-describedby": ariaDescribedBy,
|
|
32
|
+
accessibilityHint,
|
|
33
|
+
id,
|
|
34
|
+
onPress: () => onCheckedChange(!checked),
|
|
35
|
+
onKeyDown: activateOnSpace(() => onCheckedChange(!checked), disabled),
|
|
36
|
+
disabled,
|
|
37
|
+
hitSlop: 12,
|
|
38
|
+
className: cn("flex-row items-center gap-1.5 self-start", wrapperClassName),
|
|
39
|
+
children: [box, label === void 0 ? null : typeof label === "string" || typeof label === "number" ? /* @__PURE__ */ jsx(Text$1, {
|
|
40
|
+
className: "text-sm font-medium leading-none",
|
|
41
|
+
children: label
|
|
42
|
+
}) : label]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { Checkbox };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ColoredValueSharedProps } from "../../shared/analytics.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/native/atom/colored-value.d.ts
|
|
4
|
+
export type ColoredValueProps<TValue> = ColoredValueSharedProps<TValue>;
|
|
5
|
+
/**
|
|
6
|
+
* 符号で色が変わる数値。web の atom/colored-value(love3)と同じ API(`shared/analytics.ts`)。
|
|
7
|
+
* 既定色は Tailwind の固定パレット(green-500 / red-500)でなく、トークンの `state-success` / `state-error`
|
|
8
|
+
* (ダークでも 4.5:1 を保つ)。
|
|
9
|
+
* 数値なので等幅(タブラー)で描く。
|
|
10
|
+
*/
|
|
11
|
+
export declare function ColoredValue<TValue>({ value, format, isPositive, isNegative, positiveColor, negativeColor, className }: ColoredValueProps<TValue>): ReactNode;
|
|
12
|
+
//#endregion
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Text } from "../base/text.js";
|
|
3
|
+
import { tabularNums } from "../lib/typography.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/native/atom/colored-value.tsx
|
|
7
|
+
/**
|
|
8
|
+
* 符号で色が変わる数値。web の atom/colored-value(love3)と同じ API(`shared/analytics.ts`)。
|
|
9
|
+
* 既定色は Tailwind の固定パレット(green-500 / red-500)でなく、トークンの `state-success` / `state-error`
|
|
10
|
+
* (ダークでも 4.5:1 を保つ)。
|
|
11
|
+
* 数値なので等幅(タブラー)で描く。
|
|
12
|
+
*/
|
|
13
|
+
function ColoredValue({ value, format, isPositive, isNegative, positiveColor = "text-state-success", negativeColor = "text-state-error", className }) {
|
|
14
|
+
const formatted = format ? format(value) : String(value);
|
|
15
|
+
const toneClass = isPositive?.(value) ? positiveColor : isNegative?.(value) ? negativeColor : void 0;
|
|
16
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
17
|
+
style: tabularNums,
|
|
18
|
+
className: cn("font-mono", toneClass, className),
|
|
19
|
+
children: formatted
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ColoredValue };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/native/atom/image.d.ts
|
|
2
|
+
export type ImageWithLoaderProps = {
|
|
3
|
+
src: string;
|
|
4
|
+
/** スクリーンリーダー向けの説明。web の `alt` に対応する。 */
|
|
5
|
+
alt: string;
|
|
6
|
+
/** タップで全画面表示にする(既定 true)。 */
|
|
7
|
+
expandable?: boolean;
|
|
8
|
+
/** 読み込み失敗時に出す文言。共有パッケージなので文言は使用側が持つ。 */
|
|
9
|
+
errorText?: string;
|
|
10
|
+
/** 拡大するボタンの読み上げ名。 */
|
|
11
|
+
expandLabel?: string;
|
|
12
|
+
/** 拡大表示を閉じるボタンの読み上げ名。 */
|
|
13
|
+
closeLabel?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* 読み込み中はスケルトン、失敗時はプレースホルダを出す画像。
|
|
18
|
+
* `@lt-three/web` の atom/image(ImageWithLoader)に対応する。
|
|
19
|
+
*/
|
|
20
|
+
export declare function ImageWithLoader({ src, alt, expandable, errorText, expandLabel, closeLabel, className }: ImageWithLoaderProps): import("react").JSX.Element;
|
|
21
|
+
//#endregion
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
3
|
+
import { Skeleton } from "./skeleton.js";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Modal, Pressable, View } from "react-native";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Image } from "expo-image";
|
|
8
|
+
|
|
9
|
+
//#region src/native/atom/image.tsx
|
|
10
|
+
/**
|
|
11
|
+
* 読み込み中はスケルトン、失敗時はプレースホルダを出す画像。
|
|
12
|
+
* `@lt-three/web` の atom/image(ImageWithLoader)に対応する。
|
|
13
|
+
*/
|
|
14
|
+
function ImageWithLoader({ src, alt, expandable = true, errorText = "画像の読み込みに失敗しました", expandLabel = "画像を拡大する", closeLabel = "閉じる", className }) {
|
|
15
|
+
const [status, setStatus] = useState("loading");
|
|
16
|
+
const [expanded, setExpanded] = useState(false);
|
|
17
|
+
if (status === "error") return /* @__PURE__ */ jsx(View, {
|
|
18
|
+
className: cn("items-center justify-center bg-muted p-5", className),
|
|
19
|
+
children: /* @__PURE__ */ jsx(Text$1, {
|
|
20
|
+
className: "text-muted-foreground text-sm",
|
|
21
|
+
children: errorText
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
const image = /* @__PURE__ */ jsx(Image, {
|
|
25
|
+
source: { uri: src },
|
|
26
|
+
accessibilityLabel: alt,
|
|
27
|
+
contentFit: "cover",
|
|
28
|
+
style: {
|
|
29
|
+
width: "100%",
|
|
30
|
+
height: "100%"
|
|
31
|
+
},
|
|
32
|
+
onLoad: () => setStatus("loaded"),
|
|
33
|
+
onError: () => setStatus("error")
|
|
34
|
+
});
|
|
35
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
36
|
+
className: cn("overflow-hidden", className),
|
|
37
|
+
children: [
|
|
38
|
+
status === "loading" ? /* @__PURE__ */ jsx(Skeleton, { className: "absolute inset-0" }) : null,
|
|
39
|
+
expandable ? /* @__PURE__ */ jsx(Pressable, {
|
|
40
|
+
accessibilityRole: "button",
|
|
41
|
+
accessibilityLabel: alt === "" ? expandLabel : `${alt}(${expandLabel})`,
|
|
42
|
+
className: "h-full w-full",
|
|
43
|
+
onPress: () => setExpanded(true),
|
|
44
|
+
children: image
|
|
45
|
+
}) : image,
|
|
46
|
+
/* @__PURE__ */ jsx(Modal, {
|
|
47
|
+
visible: expanded,
|
|
48
|
+
transparent: true,
|
|
49
|
+
animationType: "fade",
|
|
50
|
+
onRequestClose: () => setExpanded(false),
|
|
51
|
+
children: /* @__PURE__ */ jsx(Pressable, {
|
|
52
|
+
accessibilityRole: "button",
|
|
53
|
+
accessibilityLabel: closeLabel,
|
|
54
|
+
className: "flex-1 items-center justify-center bg-scrim p-4",
|
|
55
|
+
onPress: () => setExpanded(false),
|
|
56
|
+
children: /* @__PURE__ */ jsx(Image, {
|
|
57
|
+
source: { uri: src },
|
|
58
|
+
accessibilityLabel: alt,
|
|
59
|
+
contentFit: "contain",
|
|
60
|
+
style: {
|
|
61
|
+
flex: 1,
|
|
62
|
+
width: "100%"
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
export { ImageWithLoader };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/native/atom/label.d.ts
|
|
3
|
+
export type LabelProps = {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** 必須マーク(`*`)を付ける。 */
|
|
6
|
+
required?: boolean;
|
|
7
|
+
/** ラベルの右に添える補足。 */
|
|
8
|
+
helpText?: ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
/** 文字の部分の `id`。入力の `aria-labelledby` から指す(必須の `*` と補足は名前に含めない)。 */
|
|
11
|
+
id?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* `@lt-three/web` の base/label と同じ見た目のラベル。
|
|
15
|
+
* web の `htmlFor` に相当するものは RN に無いので、タップでの入力フォーカス連動は持たない。
|
|
16
|
+
*/
|
|
17
|
+
export declare function Label({ children, required, helpText, className, id }: LabelProps): import("react").JSX.Element;
|
|
18
|
+
//#endregion
|