@lt-three/love3 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -40
- package/dist/native/analytics/animation.d.ts +1 -1
- package/dist/native/analytics/animation.js +1 -1
- package/dist/native/analytics/chart.types.d.ts +3 -3
- package/dist/native/analytics/metric-card.d.ts +3 -3
- package/dist/native/analytics/metric-card.js +3 -3
- package/dist/native/analytics/multi-line-chart.d.ts +9 -8
- package/dist/native/analytics/multi-line-chart.js +14 -13
- package/dist/native/analytics/pie-chart.d.ts +7 -7
- package/dist/native/analytics/pie-chart.js +8 -8
- package/dist/native/analytics/single-number.d.ts +4 -4
- package/dist/native/analytics/single-number.js +2 -2
- package/dist/native/atom/avatar.d.ts +6 -6
- package/dist/native/atom/avatar.js +2 -2
- package/dist/native/atom/badge.d.ts +5 -5
- package/dist/native/atom/button.d.ts +12 -12
- package/dist/native/atom/button.js +8 -8
- package/dist/native/atom/checkbox.d.ts +4 -4
- package/dist/native/atom/checkbox.js +2 -2
- package/dist/native/atom/colored-value.d.ts +4 -4
- package/dist/native/atom/colored-value.js +4 -4
- package/dist/native/atom/image.d.ts +7 -7
- package/dist/native/atom/image.js +2 -2
- package/dist/native/atom/label.d.ts +5 -5
- package/dist/native/atom/label.js +2 -2
- package/dist/native/atom/link.d.ts +5 -5
- package/dist/native/atom/link.js +5 -5
- package/dist/native/atom/readout.d.ts +7 -7
- package/dist/native/atom/readout.js +3 -3
- package/dist/native/atom/search-input.d.ts +2 -2
- package/dist/native/atom/search-input.js +2 -2
- package/dist/native/atom/select.d.ts +14 -14
- package/dist/native/atom/select.js +8 -8
- package/dist/native/atom/separator.d.ts +2 -3
- package/dist/native/atom/separator.js +2 -3
- package/dist/native/atom/skeleton.d.ts +3 -3
- package/dist/native/atom/skeleton.js +3 -3
- package/dist/native/atom/slider.d.ts +6 -6
- package/dist/native/atom/slider.js +3 -3
- package/dist/native/atom/spinner.d.ts +4 -4
- package/dist/native/atom/spinner.js +2 -2
- package/dist/native/atom/switch.d.ts +4 -4
- package/dist/native/atom/switch.js +3 -3
- package/dist/native/atom/symbol.d.ts +7 -7
- package/dist/native/atom/symbol.js +7 -7
- package/dist/native/atom/symbol.types.d.ts +8 -8
- package/dist/native/atom/symbol.types.js +7 -7
- package/dist/native/atom/text-field.d.ts +15 -15
- package/dist/native/atom/text-field.js +5 -5
- package/dist/native/atom/theme-toggle.d.ts +7 -7
- package/dist/native/atom/theme-toggle.js +4 -4
- package/dist/native/atom/timezone-select.d.ts +5 -5
- package/dist/native/atom/timezone-select.js +4 -4
- package/dist/native/atom/typography.d.ts +2 -2
- package/dist/native/atom/typography.js +2 -2
- package/dist/native/base/button.d.ts +13 -13
- package/dist/native/base/button.js +4 -4
- package/dist/native/base/form.d.ts +15 -15
- package/dist/native/base/form.js +11 -11
- package/dist/native/base/glass-card.d.ts +3 -3
- package/dist/native/base/glass-card.js +3 -3
- package/dist/native/base/input.d.ts +8 -8
- package/dist/native/base/input.js +7 -7
- package/dist/native/base/sheet.d.ts +27 -27
- package/dist/native/base/sheet.js +15 -15
- package/dist/native/form/checkbox.d.ts +3 -3
- package/dist/native/form/checkbox.js +2 -2
- package/dist/native/form/date-picker.d.ts +9 -9
- package/dist/native/form/date-picker.js +9 -9
- package/dist/native/form/form.d.ts +5 -6
- package/dist/native/form/form.js +4 -5
- package/dist/native/form/radio-group.d.ts +5 -5
- package/dist/native/form/radio-group.js +4 -4
- package/dist/native/form/select.d.ts +2 -2
- package/dist/native/form/select.js +2 -2
- package/dist/native/form/slider.d.ts +2 -2
- package/dist/native/form/slider.js +2 -2
- package/dist/native/form/switch.d.ts +2 -2
- package/dist/native/form/switch.js +2 -2
- package/dist/native/form/text-area.d.ts +2 -2
- package/dist/native/form/text-area.js +1 -1
- package/dist/native/form/text-input.d.ts +5 -5
- package/dist/native/form/text-input.js +8 -8
- package/dist/native/layout/accordion.d.ts +5 -5
- package/dist/native/layout/accordion.js +2 -2
- package/dist/native/layout/card.d.ts +8 -8
- package/dist/native/layout/card.js +3 -3
- package/dist/native/layout/description.d.ts +2 -2
- package/dist/native/layout/description.js +2 -2
- package/dist/native/layout/error.d.ts +5 -5
- package/dist/native/layout/error.js +2 -2
- package/dist/native/layout/information.d.ts +4 -4
- package/dist/native/layout/information.js +3 -3
- package/dist/native/layout/locked.d.ts +15 -15
- package/dist/native/layout/locked.js +7 -7
- package/dist/native/layout/modal.d.ts +8 -8
- package/dist/native/layout/modal.js +5 -5
- package/dist/native/layout/not-found.d.ts +4 -4
- package/dist/native/layout/not-found.js +3 -3
- package/dist/native/layout/page-frame.d.ts +8 -8
- package/dist/native/layout/page-frame.js +3 -3
- package/dist/native/layout/panel.d.ts +5 -5
- package/dist/native/layout/panel.js +5 -5
- package/dist/native/layout/reorderable-list.d.ts +14 -14
- package/dist/native/layout/reorderable-list.js +10 -10
- package/dist/native/layout/sheet.d.ts +10 -10
- package/dist/native/layout/sheet.js +4 -4
- package/dist/native/layout/simple-dialog.d.ts +3 -3
- package/dist/native/layout/simple-dialog.js +2 -2
- package/dist/native/layout/simple-table.d.ts +18 -18
- package/dist/native/layout/simple-table.js +1 -1
- package/dist/native/layout/tab-bar.d.ts +10 -10
- package/dist/native/layout/tab-bar.js +4 -4
- package/dist/native/layout/tabs.d.ts +6 -6
- package/dist/native/layout/tabs.js +4 -4
- package/dist/native/layout/tuning-panel.d.ts +10 -10
- package/dist/native/layout/tuning-panel.js +15 -15
- package/dist/native/lib/autocomplete.d.ts +1 -1
- package/dist/native/lib/autocomplete.js +1 -1
- package/dist/native/lib/breakpoints.d.ts +3 -3
- package/dist/native/lib/breakpoints.js +3 -3
- package/dist/native/lib/chart-palette.d.ts +2 -2
- package/dist/native/lib/chart-palette.js +2 -2
- package/dist/native/lib/confirm.d.ts +15 -16
- package/dist/native/lib/confirm.js +9 -10
- package/dist/native/lib/control.d.ts +9 -9
- package/dist/native/lib/external-store.d.ts +4 -5
- package/dist/native/lib/keyboard.d.ts +7 -7
- package/dist/native/lib/keyboard.js +7 -7
- package/dist/native/lib/labels.d.ts +6 -6
- package/dist/native/lib/labels.js +6 -6
- package/dist/native/lib/loading.d.ts +3 -3
- package/dist/native/lib/loading.js +3 -3
- package/dist/native/lib/network.d.ts +5 -6
- package/dist/native/lib/network.js +5 -6
- package/dist/native/lib/scheme.d.ts +7 -7
- package/dist/native/lib/scheme.js +3 -3
- package/dist/native/lib/snackbar.d.ts +12 -13
- package/dist/native/lib/snackbar.js +7 -8
- package/dist/native/lib/theme.d.ts +15 -15
- package/dist/native/lib/theme.js +15 -15
- package/dist/native/lib/timezone.d.ts +13 -13
- package/dist/native/lib/timezone.js +13 -13
- package/dist/native/lib/token-color.d.ts +1 -1
- package/dist/native/lib/token-color.js +1 -1
- package/dist/native/lib/tuning-context.d.ts +2 -2
- package/dist/native/lib/tuning.d.ts +10 -10
- package/dist/native/lib/tuning.js +8 -8
- package/dist/native/lib/typography.d.ts +3 -3
- package/dist/native/lib/typography.js +3 -3
- package/dist/native/lib/utils.d.ts +3 -3
- package/dist/native/lib/utils.js +3 -3
- package/dist/native/once/confirm.d.ts +2 -2
- package/dist/native/once/confirm.js +2 -2
- package/dist/native/once/error-boundary.d.ts +3 -3
- package/dist/native/once/error-boundary.js +2 -2
- package/dist/native/once/loading-lock.d.ts +3 -3
- package/dist/native/once/loading-lock.js +3 -3
- package/dist/native/once/offline-banner.d.ts +6 -6
- package/dist/native/once/offline-banner.js +5 -5
- package/dist/native/once/snackbar.d.ts +7 -7
- package/dist/native/once/snackbar.js +5 -5
- package/dist/native/styles.css +21 -21
- package/dist/shared/analytics.d.ts +23 -23
- package/dist/shared/button.d.ts +1 -1
- package/dist/shared/form.d.ts +7 -7
- package/dist/shared/form.js +2 -2
- package/dist/tokens/contrast-pairs.d.ts +9 -9
- package/dist/tokens/contrast-pairs.js +10 -10
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/styles.gen.css +87 -87
- package/dist/tokens/tokens.gen.d.ts +2 -2
- package/dist/tokens/tokens.gen.js +2 -2
- package/dist/tuning/catalog.d.ts +8 -8
- package/dist/tuning/catalog.js +9 -9
- package/dist/tuning/color.d.ts +4 -4
- package/dist/tuning/color.js +5 -5
- package/dist/tuning/css.d.ts +13 -13
- package/dist/tuning/css.js +17 -17
- package/dist/tuning/model.d.ts +11 -11
- package/dist/tuning/model.js +11 -11
- package/dist/tuning/native.d.ts +18 -18
- package/dist/tuning/native.js +18 -18
- package/dist/tuning/schema.d.ts +15 -15
- package/dist/tuning/schema.js +22 -22
- package/dist/tuning/types.d.ts +25 -25
- package/dist/tuning/types.js +6 -6
- package/dist/web/analytics/line-chart.d.ts +6 -6
- package/dist/web/analytics/line-chart.js +3 -3
- package/dist/web/analytics/metric-card.d.ts +6 -6
- package/dist/web/analytics/metric-card.js +5 -5
- package/dist/web/analytics/multi-line-chart.d.ts +23 -23
- package/dist/web/analytics/multi-line-chart.js +33 -33
- package/dist/web/atom/avatar.d.ts +1 -1
- package/dist/web/atom/checkbox.d.ts +6 -6
- package/dist/web/atom/checkbox.js +2 -2
- package/dist/web/atom/colored-value.d.ts +4 -4
- package/dist/web/atom/colored-value.js +4 -4
- package/dist/web/atom/help.d.ts +1 -1
- package/dist/web/atom/segmented-control.d.ts +13 -14
- package/dist/web/atom/segmented-control.js +6 -7
- package/dist/web/atom/select.d.ts +7 -7
- package/dist/web/atom/select.js +5 -5
- package/dist/web/atom/slider.d.ts +3 -3
- package/dist/web/atom/slider.js +2 -2
- package/dist/web/atom/switch.d.ts +3 -3
- package/dist/web/atom/text-area.d.ts +9 -8
- package/dist/web/atom/text-area.js +9 -8
- package/dist/web/atom/text-field.d.ts +5 -4
- package/dist/web/atom/text-field.js +5 -4
- package/dist/web/atom/toggle-chip.d.ts +6 -6
- package/dist/web/atom/toggle-chip.js +4 -4
- package/dist/web/atom/tooltip.d.ts +6 -6
- package/dist/web/atom/tooltip.js +2 -2
- package/dist/web/base/accordion.js +1 -1
- package/dist/web/base/breadcrumb.d.ts +1 -1
- package/dist/web/base/breadcrumb.js +1 -1
- package/dist/web/base/card.d.ts +3 -3
- package/dist/web/base/card.js +2 -2
- package/dist/web/base/dialog.d.ts +1 -1
- package/dist/web/base/dialog.js +1 -1
- package/dist/web/base/form.d.ts +7 -7
- package/dist/web/base/form.js +5 -5
- package/dist/web/base/pagination.d.ts +5 -5
- package/dist/web/base/pagination.js +1 -1
- package/dist/web/base/sheet.d.ts +1 -1
- package/dist/web/base/sheet.js +1 -1
- package/dist/web/base/slider.d.ts +1 -1
- package/dist/web/base/sonner.d.ts +2 -2
- package/dist/web/base/sonner.js +2 -2
- package/dist/web/base/spinner.js +1 -1
- package/dist/web/form/checkbox.d.ts +8 -8
- package/dist/web/form/checkbox.js +3 -3
- package/dist/web/form/radio-group.js +3 -3
- package/dist/web/form/select.js +1 -1
- package/dist/web/form/slider.d.ts +3 -3
- package/dist/web/form/slider.js +3 -3
- package/dist/web/form/switch.d.ts +3 -3
- package/dist/web/form/switch.js +4 -4
- package/dist/web/form/text-area.js +1 -1
- package/dist/web/form/text-input.d.ts +1 -1
- package/dist/web/form/text-input.js +1 -1
- package/dist/web/layout/accordion.d.ts +5 -5
- package/dist/web/layout/accordion.js +2 -2
- package/dist/web/layout/alert-modal.d.ts +11 -11
- package/dist/web/layout/alert-modal.js +7 -7
- package/dist/web/layout/card.d.ts +1 -1
- package/dist/web/layout/information.d.ts +9 -9
- package/dist/web/layout/information.js +7 -7
- package/dist/web/layout/modal.d.ts +1 -1
- package/dist/web/layout/page-frame.d.ts +14 -14
- package/dist/web/layout/page-frame.js +7 -7
- package/dist/web/layout/scroll-area.d.ts +1 -1
- package/dist/web/layout/sheet.d.ts +4 -4
- package/dist/web/layout/simple-table.d.ts +18 -18
- package/dist/web/layout/simple-table.js +2 -2
- package/dist/web/layout/tabs.d.ts +4 -4
- package/dist/web/layout/titled-modal.d.ts +10 -11
- package/dist/web/layout/titled-modal.js +7 -8
- package/dist/web/lib/css-vars.d.ts +6 -6
- package/dist/web/lib/css-vars.js +5 -5
- package/dist/web/lib/dialog.d.ts +4 -4
- package/dist/web/lib/labels.d.ts +8 -8
- package/dist/web/lib/labels.js +8 -8
- package/dist/web/lib/modal-open-focus.d.ts +7 -7
- package/dist/web/lib/modal-open-focus.js +9 -9
- package/dist/web/lib/restore-focus.d.ts +4 -4
- package/dist/web/lib/restore-focus.js +4 -4
- package/dist/web/styles.css +33 -33
- package/package.json +2 -2
|
@@ -7,10 +7,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
|
|
8
8
|
//#region src/native/layout/information.tsx
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* A definition list that lays out labels and values. Corresponds to the web `layout/information`.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Web has room to split into several columns, but native lacks the width, so it
|
|
13
|
+
* **always renders a single column** (rows with the label on the left and the value on the right).
|
|
14
14
|
*/
|
|
15
15
|
function Information({ fields, highlighted, className }) {
|
|
16
16
|
return /* @__PURE__ */ jsx(View, {
|
|
@@ -2,37 +2,37 @@ import { ReactNode } from "react";
|
|
|
2
2
|
//#region src/native/layout/locked.d.ts
|
|
3
3
|
export type LockedProps = {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* The shape of what lies behind the lock. Pass a **sample that is not meant to be read**.
|
|
6
|
+
* Never pass real data (the cover is a visual treatment, not a barrier).
|
|
7
7
|
*/
|
|
8
8
|
children: ReactNode;
|
|
9
|
-
/**
|
|
9
|
+
/** Short text overlaid on the surface. Example: "Available with Pro". */
|
|
10
10
|
label: string;
|
|
11
|
-
/**
|
|
11
|
+
/** Note stating that the content is a sample. Example: "Sample". Not shown when omitted. */
|
|
12
12
|
sampleLabel?: string;
|
|
13
|
-
/**
|
|
13
|
+
/** Makes the whole surface pressable. A lock invites pressing, so pass this in most cases. */
|
|
14
14
|
onPress?: () => void;
|
|
15
15
|
accessibilityLabel?: string;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* The destination placed under the cover (an explanation and an exit button). **Keeping it inside the same surface**
|
|
18
|
+
* puts "what you can't see" and "how to unlock it" on a single card.
|
|
19
19
|
*/
|
|
20
20
|
footer?: ReactNode;
|
|
21
|
-
/**
|
|
21
|
+
/** Height of the sample. Defaults to 160. */
|
|
22
22
|
height?: number;
|
|
23
23
|
className?: string;
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* A locked surface. **Shows the shape of the content but makes it unreadable.**
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
28
|
+
* Replacing the content wholesale communicates "absence" rather than "locked", and it is unclear what is being missed.
|
|
29
|
+
* Keeping the shape and covering it shows what is there while conveying that it is out of reach.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* It is built as **distinct from the loading Skeleton**. A Skeleton means "it will appear if you wait",
|
|
32
|
+
* so the same look must not be used for a lock (waiting will not reveal anything).
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* The cover is a `GlassView` (glass that blurs what is behind it) on iOS 26 and later, and a card-colored cover where that is unsupported (below iOS 26, Android, web).
|
|
35
|
+
* **The sample is a dummy, so the strength of the cover has no confidentiality requirement.** Choose it as a visual treatment.
|
|
36
36
|
*/
|
|
37
37
|
export declare function Locked({ children, label, sampleLabel, onPress, accessibilityLabel, footer, height, className }: LockedProps): import("react").JSX.Element;
|
|
38
38
|
//#endregion
|
|
@@ -20,16 +20,16 @@ const FILL = {
|
|
|
20
20
|
padding: 16
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* A locked surface. **Shows the shape of the content but makes it unreadable.**
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* Replacing the content wholesale communicates "absence" rather than "locked", and it is unclear what is being missed.
|
|
26
|
+
* Keeping the shape and covering it shows what is there while conveying that it is out of reach.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
28
|
+
* It is built as **distinct from the loading Skeleton**. A Skeleton means "it will appear if you wait",
|
|
29
|
+
* so the same look must not be used for a lock (waiting will not reveal anything).
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* The cover is a `GlassView` (glass that blurs what is behind it) on iOS 26 and later, and a card-colored cover where that is unsupported (below iOS 26, Android, web).
|
|
32
|
+
* **The sample is a dummy, so the strength of the cover has no confidentiality requirement.** Choose it as a visual treatment.
|
|
33
33
|
*/
|
|
34
34
|
function Locked({ children, label, sampleLabel, onPress, accessibilityLabel, footer, height = 160, className }) {
|
|
35
35
|
const ink = useTokenColor("--ink-900");
|
|
@@ -3,23 +3,23 @@ import { ReactNode } from "react";
|
|
|
3
3
|
export type ModalProps = {
|
|
4
4
|
open: boolean;
|
|
5
5
|
onOpenChange: (open: boolean) => void;
|
|
6
|
-
/**
|
|
6
|
+
/** Heading. Becomes the dialog's name. */
|
|
7
7
|
title: ReactNode;
|
|
8
8
|
description?: ReactNode;
|
|
9
9
|
content: ReactNode;
|
|
10
10
|
footer?: ReactNode;
|
|
11
|
-
/**
|
|
11
|
+
/** Whether tapping the backdrop closes it (default false = require an explicit close). Esc and Android's back action close it regardless of this setting. */
|
|
12
12
|
dismissOnBackdropPress?: boolean;
|
|
13
|
-
/**
|
|
13
|
+
/** Spoken name of the close button (default "閉じる", i.e. "Close"). This is a shared package, so pass other languages here. */
|
|
14
14
|
closeLabel?: string;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* A confirmation/editing dialog shown at the center of the screen. Corresponds to the web `layout/modal`.
|
|
18
|
+
* The shell is an overlay surface (surface radius, shadow-lg; no border), and only the body scrolls.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* web
|
|
20
|
+
* The heading is the dialog's name (`aria-labelledby`), and the supplementary text is its description (`aria-describedby`).
|
|
21
|
+
* The role (`role="dialog"`, `aria-modal`), focus trapping, and Esc are handled by `Modal`.
|
|
22
|
+
* The web `layout/modal` takes open/close through `dialog` (`DialogController`), whereas native uses `open` / `onOpenChange`.
|
|
23
23
|
*/
|
|
24
24
|
export declare function Modal({ open, onOpenChange, title, description, content, footer, dismissOnBackdropPress, closeLabel }: ModalProps): import("react").JSX.Element;
|
|
25
25
|
//#endregion
|
|
@@ -8,12 +8,12 @@ import Feather from "@expo/vector-icons/Feather";
|
|
|
8
8
|
|
|
9
9
|
//#region src/native/layout/modal.tsx
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* A confirmation/editing dialog shown at the center of the screen. Corresponds to the web `layout/modal`.
|
|
12
|
+
* The shell is an overlay surface (surface radius, shadow-lg; no border), and only the body scrolls.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* web
|
|
14
|
+
* The heading is the dialog's name (`aria-labelledby`), and the supplementary text is its description (`aria-describedby`).
|
|
15
|
+
* The role (`role="dialog"`, `aria-modal`), focus trapping, and Esc are handled by `Modal`.
|
|
16
|
+
* The web `layout/modal` takes open/close through `dialog` (`DialogController`), whereas native uses `open` / `onOpenChange`.
|
|
17
17
|
*/
|
|
18
18
|
function Modal({ open, onOpenChange, title, description, content, footer, dismissOnBackdropPress = false, closeLabel = CLOSE_LABEL }) {
|
|
19
19
|
const ink = useTokenColor("--ink-500");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/native/layout/not-found.d.ts
|
|
2
2
|
export type NotFoundProps = {
|
|
3
|
-
/**
|
|
3
|
+
/** Display text. This is a shared package, so the caller owns it. */
|
|
4
4
|
labels: {
|
|
5
5
|
title: string;
|
|
6
6
|
back: string;
|
|
@@ -8,10 +8,10 @@ export type NotFoundProps = {
|
|
|
8
8
|
onBack: () => void;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* The screen shown when something is not found.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* Web calls `history.back()` with `action="previous-page"`, but native's back destination
|
|
14
|
+
* depends on the navigation stack, so it receives `onBack` (`router.back()`, etc.) from the caller.
|
|
15
15
|
*/
|
|
16
16
|
export declare function NotFound({ labels, onBack }: NotFoundProps): import("react").JSX.Element;
|
|
17
17
|
//#endregion
|
|
@@ -5,10 +5,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
|
|
6
6
|
//#region src/native/layout/not-found.tsx
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* The screen shown when something is not found.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Web calls `history.back()` with `action="previous-page"`, but native's back destination
|
|
11
|
+
* depends on the navigation stack, so it receives `onBack` (`router.back()`, etc.) from the caller.
|
|
12
12
|
*/
|
|
13
13
|
function NotFound({ labels, onBack }) {
|
|
14
14
|
return /* @__PURE__ */ jsxs(View, {
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
//#region src/native/layout/page-frame.d.ts
|
|
3
3
|
export type PageFrameProps = {
|
|
4
|
-
/**
|
|
4
|
+
/** Header heading (the screen title; `role="heading"` `aria-level=1`). */
|
|
5
5
|
title: string;
|
|
6
|
-
/**
|
|
6
|
+
/** Right end of the header (buttons such as back, settings, user). */
|
|
7
7
|
trailing?: ReactNode;
|
|
8
8
|
children: ReactNode;
|
|
9
|
-
/**
|
|
9
|
+
/** Footer below the body (copyright, links, etc.). */
|
|
10
10
|
footer?: ReactNode;
|
|
11
|
-
/**
|
|
11
|
+
/** Navigation pinned at the bottom (`layout/tab-bar`). The body scrolls above it. */
|
|
12
12
|
nav?: ReactNode;
|
|
13
|
-
/**
|
|
13
|
+
/** Extra classes for the body (the scrolling area). */
|
|
14
14
|
contentClassName?: string;
|
|
15
15
|
className?: string;
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* The screen skeleton. Corresponds to `@lt-three/love3/web/layout/page-frame.tsx` (header, main, footer, nav).
|
|
19
|
+
* A header (banner) at the top, a scrolling body (main) in the middle, a footer (contentinfo) below it, and navigation (`TabBar`) at the very bottom.
|
|
20
|
+
* The top and bottom safe areas are the app's responsibility (an outer `SafeAreaView`, or `pt-*` in `className`).
|
|
21
21
|
*/
|
|
22
22
|
export declare function PageFrame({ title, trailing, children, footer, nav, contentClassName, className }: PageFrameProps): import("react").JSX.Element;
|
|
23
23
|
//#endregion
|
|
@@ -5,9 +5,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
|
|
6
6
|
//#region src/native/layout/page-frame.tsx
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* The screen skeleton. Corresponds to `@lt-three/love3/web/layout/page-frame.tsx` (header, main, footer, nav).
|
|
9
|
+
* A header (banner) at the top, a scrolling body (main) in the middle, a footer (contentinfo) below it, and navigation (`TabBar`) at the very bottom.
|
|
10
|
+
* The top and bottom safe areas are the app's responsibility (an outer `SafeAreaView`, or `pt-*` in `className`).
|
|
11
11
|
*/
|
|
12
12
|
function PageFrame({ title, trailing, children, footer, nav, contentClassName, className }) {
|
|
13
13
|
return /* @__PURE__ */ jsxs(View, {
|
|
@@ -7,12 +7,12 @@ export type PanelProps = {
|
|
|
7
7
|
style?: ViewStyle;
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* A content surface. Same shell as the web Card (surface radius, a very faint 1px rule, raised surface; no shadow).
|
|
11
|
+
* The inner padding is up to the caller.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* The rule uses `border-line` rather than `border-border`. `--border` is declared only once
|
|
14
|
+
* in the stylesheet, so react-native-css folds it into a single value at build time
|
|
15
|
+
* and it no longer switches under `.dark`.
|
|
16
16
|
*/
|
|
17
17
|
export declare function Panel({ children, className, style }: PanelProps): import("react").JSX.Element;
|
|
18
18
|
//#endregion
|
|
@@ -4,12 +4,12 @@ import { jsx } from "react/jsx-runtime";
|
|
|
4
4
|
|
|
5
5
|
//#region src/native/layout/panel.tsx
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* A content surface. Same shell as the web Card (surface radius, a very faint 1px rule, raised surface; no shadow).
|
|
8
|
+
* The inner padding is up to the caller.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The rule uses `border-line` rather than `border-border`. `--border` is declared only once
|
|
11
|
+
* in the stylesheet, so react-native-css folds it into a single value at build time
|
|
12
|
+
* and it no longer switches under `.dark`.
|
|
13
13
|
*/
|
|
14
14
|
function Panel({ children, className, style }) {
|
|
15
15
|
return /* @__PURE__ */ jsx(View, {
|
|
@@ -4,21 +4,21 @@ export type ReorderableRenderInfo<T> = {
|
|
|
4
4
|
item: T;
|
|
5
5
|
index: number;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Grabs the row and starts dragging. **Pass it to the row's own `Pressable` `onLongPress`.**
|
|
8
|
+
* If attached to a wrapper `Pressable`, a `Pressable` inside the row (one that opens details on tap, etc.)
|
|
9
|
+
* takes the responder and the long press never reaches the outer one, so dragging does not start.
|
|
10
10
|
*/
|
|
11
11
|
drag: () => void;
|
|
12
|
-
/**
|
|
12
|
+
/** Whether the row is currently grabbed. Make the grabbed row look clearly different. */
|
|
13
13
|
active: boolean;
|
|
14
14
|
};
|
|
15
15
|
export type ReorderableListProps<T> = {
|
|
16
16
|
data: T[];
|
|
17
17
|
keyExtractor: (item: T) => string;
|
|
18
18
|
renderItem: (info: ReorderableRenderInfo<T>) => ReactNode;
|
|
19
|
-
/**
|
|
19
|
+
/** Receives the reordered array. Persistence is up to the caller. */
|
|
20
20
|
onReorder: (next: T[]) => void;
|
|
21
|
-
/** false
|
|
21
|
+
/** While false, dragging is not accepted (for example while filtering). */
|
|
22
22
|
dragEnabled?: boolean;
|
|
23
23
|
ListHeaderComponent?: ReactElement | null;
|
|
24
24
|
ListFooterComponent?: ReactElement | null;
|
|
@@ -26,17 +26,17 @@ export type ReorderableListProps<T> = {
|
|
|
26
26
|
contentContainerClassName?: string;
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* A list reordered by long-press and drag. **Runs on the same implementation for iOS and Android.**
|
|
30
30
|
*
|
|
31
|
-
* SwiftUI
|
|
32
|
-
*
|
|
33
|
-
* `react-native-reorderable-list`
|
|
31
|
+
* SwiftUI's `List.ForEach onMove` works only on iOS, which would leave
|
|
32
|
+
* "reordering works everywhere except Android". This builds on Reanimated + Gesture Handler's
|
|
33
|
+
* `react-native-reorderable-list` so the implementation does not split by platform.
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* **A `GestureHandlerRootView` is required at the app's root** (Android). Without it no exception is thrown,
|
|
36
|
+
* and dragging and swiping silently stop working.
|
|
37
37
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
38
|
+
* The reorder is committed by a single `onReorder` call. During a drag only the display moves internally,
|
|
39
|
+
* so do not hit an API with intermediate states.
|
|
40
40
|
*/
|
|
41
41
|
export declare function ReorderableList<T>({ data, keyExtractor, renderItem, onReorder, dragEnabled, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, contentContainerClassName }: ReorderableListProps<T>): import("react").JSX.Element;
|
|
42
42
|
//#endregion
|
|
@@ -3,17 +3,17 @@ import Reorderable, { reorderItems, useIsActive, useReorderableDrag } from "reac
|
|
|
3
3
|
|
|
4
4
|
//#region src/native/layout/reorderable-list.tsx
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* A list reordered by long-press and drag. **Runs on the same implementation for iOS and Android.**
|
|
7
7
|
*
|
|
8
|
-
* SwiftUI
|
|
9
|
-
*
|
|
10
|
-
* `react-native-reorderable-list`
|
|
8
|
+
* SwiftUI's `List.ForEach onMove` works only on iOS, which would leave
|
|
9
|
+
* "reordering works everywhere except Android". This builds on Reanimated + Gesture Handler's
|
|
10
|
+
* `react-native-reorderable-list` so the implementation does not split by platform.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* **A `GestureHandlerRootView` is required at the app's root** (Android). Without it no exception is thrown,
|
|
13
|
+
* and dragging and swiping silently stop working.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* The reorder is committed by a single `onReorder` call. During a drag only the display moves internally,
|
|
16
|
+
* so do not hit an API with intermediate states.
|
|
17
17
|
*/
|
|
18
18
|
function ReorderableList({ data, keyExtractor, renderItem, onReorder, dragEnabled = true, ListHeaderComponent, ListFooterComponent, ListEmptyComponent, contentContainerClassName }) {
|
|
19
19
|
return /* @__PURE__ */ jsx(Reorderable, {
|
|
@@ -34,8 +34,8 @@ function ReorderableList({ data, keyExtractor, renderItem, onReorder, dragEnable
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
* Renders a row. `useReorderableDrag` / `useIsActive` **can only be called inside a list item**,
|
|
38
|
+
* so they are called here and handed to the caller.
|
|
39
39
|
*/
|
|
40
40
|
function Cell({ item, index, render }) {
|
|
41
41
|
const drag = useReorderableDrag();
|
|
@@ -3,28 +3,28 @@ import { ReactNode } from "react";
|
|
|
3
3
|
export type SheetProps = {
|
|
4
4
|
open: boolean;
|
|
5
5
|
onOpenChange: (open: boolean) => void;
|
|
6
|
-
/**
|
|
6
|
+
/** Heading. Becomes the dialog's name (required so the dialog is never nameless; same as the web `layout/sheet`). */
|
|
7
7
|
title: ReactNode;
|
|
8
8
|
description?: ReactNode;
|
|
9
9
|
content: ReactNode;
|
|
10
10
|
footer?: ReactNode;
|
|
11
|
-
/**
|
|
11
|
+
/** Whether tapping the backdrop closes it (default true). */
|
|
12
12
|
dismissOnBackdropPress?: boolean;
|
|
13
|
-
/**
|
|
13
|
+
/** Spoken name of the close button (default "閉じる", i.e. "Close"). */
|
|
14
14
|
closeLabel?: string;
|
|
15
|
-
/**
|
|
15
|
+
/** Whether to pad the content (default true). Use false for row lists that run edge to edge. */
|
|
16
16
|
padded?: boolean;
|
|
17
|
-
/**
|
|
17
|
+
/** Maximum height as a ratio of the screen height (default 0.85). */
|
|
18
18
|
maxHeightRatio?: number;
|
|
19
|
-
/**
|
|
19
|
+
/** Called after it has fully closed. **Open the next sheet here** (see `base/sheet`). */
|
|
20
20
|
onClosed?: () => void;
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
* native
|
|
23
|
+
* A sheet that slides up from the bottom. Corresponds to the web `layout/sheet` (a panel that slides in from a screen edge).
|
|
24
|
+
* On native the standard convention is to slide up from the bottom rather than from an edge, so only the position is reinterpreted (there is no web `side`).
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* How the surface appears, the scrim, safe-area, and keyboard avoidance belong to `base/sheet`.
|
|
27
|
+
* The heading is the dialog's name (`aria-labelledby`), and the supplementary text is its description (`aria-describedby`).
|
|
28
28
|
*/
|
|
29
29
|
export declare function Sheet({ open, onOpenChange, title, description, content, footer, dismissOnBackdropPress, closeLabel, padded, maxHeightRatio, onClosed }: SheetProps): import("react").JSX.Element;
|
|
30
30
|
//#endregion
|
|
@@ -5,11 +5,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
|
|
6
6
|
//#region src/native/layout/sheet.tsx
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
* native
|
|
8
|
+
* A sheet that slides up from the bottom. Corresponds to the web `layout/sheet` (a panel that slides in from a screen edge).
|
|
9
|
+
* On native the standard convention is to slide up from the bottom rather than from an edge, so only the position is reinterpreted (there is no web `side`).
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* How the surface appears, the scrim, safe-area, and keyboard avoidance belong to `base/sheet`.
|
|
12
|
+
* The heading is the dialog's name (`aria-labelledby`), and the supplementary text is its description (`aria-describedby`).
|
|
13
13
|
*/
|
|
14
14
|
function Sheet({ open, onOpenChange, title, description, content, footer, dismissOnBackdropPress = true, closeLabel, padded = true, maxHeightRatio = .85, onClosed }) {
|
|
15
15
|
const id = useId();
|
|
@@ -5,12 +5,12 @@ export type SimpleDialogProps = {
|
|
|
5
5
|
onOpenChange: (open: boolean) => void;
|
|
6
6
|
title: ReactNode;
|
|
7
7
|
children: ReactNode;
|
|
8
|
-
/**
|
|
8
|
+
/** Spoken name of the close button (default "閉じる", i.e. "Close"). */
|
|
9
9
|
closeLabel?: string;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* A lightweight dialog with only a title and a body. Corresponds to the web `layout/simple-dialog`.
|
|
13
|
+
* Use `Modal` directly if you need a footer or a description.
|
|
14
14
|
*/
|
|
15
15
|
export declare function SimpleDialog({ open, onOpenChange, title, children, closeLabel }: SimpleDialogProps): import("react").JSX.Element;
|
|
16
16
|
//#endregion
|
|
@@ -3,8 +3,8 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
|
|
4
4
|
//#region src/native/layout/simple-dialog.tsx
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* A lightweight dialog with only a title and a body. Corresponds to the web `layout/simple-dialog`.
|
|
7
|
+
* Use `Modal` directly if you need a footer or a description.
|
|
8
8
|
*/
|
|
9
9
|
function SimpleDialog({ open, onOpenChange, title, children, closeLabel }) {
|
|
10
10
|
return /* @__PURE__ */ jsx(Modal, {
|
|
@@ -2,48 +2,48 @@ import { Breakpoint } from "../lib/breakpoints.js";
|
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
//#region src/native/layout/simple-table.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* A declarative data table with thin rules. Just pass columns / data.
|
|
6
|
+
* It takes the same column definitions and the same prop names (`onRowClick`, `hideBelow`) as the web `layout/simple-table`.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* The header is a pale frame surface, and row rules are very faint 1px lines.
|
|
9
|
+
* Numeric columns use mono + tabular + right alignment.
|
|
10
10
|
*/
|
|
11
11
|
export type SimpleColumn<T> = {
|
|
12
|
-
/**
|
|
12
|
+
/** Column key (unique within a row). */
|
|
13
13
|
key: string;
|
|
14
14
|
header: ReactNode;
|
|
15
|
-
/**
|
|
15
|
+
/** Alignment of cells / header (default left). */
|
|
16
16
|
align?: "left" | "right" | "center";
|
|
17
|
-
/**
|
|
17
|
+
/** Monospace + tabular (for numbers and IDs). */
|
|
18
18
|
mono?: boolean;
|
|
19
|
-
/**
|
|
19
|
+
/** Emphasis (font-medium). */
|
|
20
20
|
strong?: boolean;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* Hides the whole column when narrower than this width (same breakpoints as Tailwind: sm 640, md 768, lg 1024 px; judged by the **screen width**).
|
|
23
|
+
* Collapses unimportant columns (ID, notes, etc.) on narrow screens (same as web's `hideBelow`). Always shown when unspecified.
|
|
24
24
|
*/
|
|
25
25
|
hideBelow?: Breakpoint;
|
|
26
|
-
/**
|
|
26
|
+
/** Column width (px). Divided equally when omitted. */
|
|
27
27
|
width?: number;
|
|
28
|
-
/**
|
|
28
|
+
/** Extra classes for the cell (View). */
|
|
29
29
|
cellClassName?: string;
|
|
30
|
-
/**
|
|
30
|
+
/** Extra classes for the header cell (View). */
|
|
31
31
|
headClassName?: string;
|
|
32
|
-
/**
|
|
32
|
+
/** Renders the cell. Shows row[key] when unspecified. */
|
|
33
33
|
render?: (row: T) => ReactNode;
|
|
34
34
|
};
|
|
35
35
|
export type SimpleTableProps<T> = {
|
|
36
36
|
columns: SimpleColumn<T>[];
|
|
37
37
|
data: T[];
|
|
38
|
-
/**
|
|
38
|
+
/** Derives the row key. Uses the index when unspecified. */
|
|
39
39
|
getRowKey?: (row: T, index: number) => string;
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
41
|
+
* Pressing a row (same name as web's `onRowClick`). When passed, each row becomes a button (focusable, and pressable with Enter and Space),
|
|
42
|
+
* and focus is shown with an opaque outline.
|
|
43
43
|
*/
|
|
44
44
|
onRowClick?: (row: T) => void;
|
|
45
45
|
className?: string;
|
|
46
|
-
/**
|
|
46
|
+
/** Scrolls horizontally when the columns do not fit the screen width. */
|
|
47
47
|
horizontalScroll?: boolean;
|
|
48
48
|
};
|
|
49
49
|
export declare function SimpleTable<T extends object>({ columns: allColumns, data, getRowKey, onRowClick, className, horizontalScroll }: SimpleTableProps<T>): import("react").JSX.Element;
|
|
@@ -17,7 +17,7 @@ const justifyClass = {
|
|
|
17
17
|
right: "justify-end",
|
|
18
18
|
center: "justify-center"
|
|
19
19
|
};
|
|
20
|
-
/** `render
|
|
20
|
+
/** Default rendering for a column without `render`. Shows the row's `key` value only when it is text, a number, or an element. */
|
|
21
21
|
function cellValue(row, key) {
|
|
22
22
|
const value = Reflect.get(row, key);
|
|
23
23
|
if (typeof value === "string" || typeof value === "number" || isValidElement(value)) return value;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
//#region src/native/layout/tab-bar.d.ts
|
|
3
3
|
export type TabBarItem = {
|
|
4
|
-
/**
|
|
4
|
+
/** Selection value (unique). */
|
|
5
5
|
value: string;
|
|
6
|
-
/**
|
|
6
|
+
/** Text label. Never use an icon alone (for the spoken name and clarity). */
|
|
7
7
|
label: string;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Icon. It receives the color (`color`) matching the selection state, for use as `Symbol`'s `tintColor` and the like.
|
|
10
|
+
* Omit it if text alone is enough.
|
|
11
11
|
*/
|
|
12
12
|
icon?: (state: {
|
|
13
13
|
active: boolean;
|
|
@@ -16,18 +16,18 @@ export type TabBarItem = {
|
|
|
16
16
|
};
|
|
17
17
|
export type TabBarProps = {
|
|
18
18
|
items: readonly TabBarItem[];
|
|
19
|
-
/**
|
|
19
|
+
/** The selected value. */
|
|
20
20
|
value: string;
|
|
21
21
|
onValueChange: (value: string) => void;
|
|
22
|
-
/**
|
|
22
|
+
/** Spoken name (distinguishes landmarks when there are several). Defaults to "メイン" ("Main"). */
|
|
23
23
|
accessibilityLabel?: string;
|
|
24
24
|
className?: string;
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* Switcher for top-level destinations placed at the bottom of the screen (3 to 5 items). Distinct from `layout/tabs` (underlined tabs that switch the body).
|
|
28
|
+
* The selected item uses `text-action-ink` (AA even on dark surfaces), and the selected state is shown by weight (`font-semibold`) as well as color.
|
|
29
|
+
* Each item's press target is at least 56px tall (above the 44pt real-device guideline). **The bottom safe area (home indicator) is the app's responsibility**
|
|
30
|
+
* (pass `pb-*` in `className`, or place it inside an outer `SafeAreaView`).
|
|
31
31
|
*/
|
|
32
32
|
export declare function TabBar({ items, value, onValueChange, accessibilityLabel, className }: TabBarProps): import("react").JSX.Element;
|
|
33
33
|
//#endregion
|
|
@@ -6,10 +6,10 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
|
|
7
7
|
//#region src/native/layout/tab-bar.tsx
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Switcher for top-level destinations placed at the bottom of the screen (3 to 5 items). Distinct from `layout/tabs` (underlined tabs that switch the body).
|
|
10
|
+
* The selected item uses `text-action-ink` (AA even on dark surfaces), and the selected state is shown by weight (`font-semibold`) as well as color.
|
|
11
|
+
* Each item's press target is at least 56px tall (above the 44pt real-device guideline). **The bottom safe area (home indicator) is the app's responsibility**
|
|
12
|
+
* (pass `pb-*` in `className`, or place it inside an outer `SafeAreaView`).
|
|
13
13
|
*/
|
|
14
14
|
function TabBar({ items, value, onValueChange, accessibilityLabel = "メイン", className }) {
|
|
15
15
|
const activeColor = useTokenColor("--action-ink");
|