@lt-three/love3 0.0.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 +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 +18 -0
- package/dist/native/analytics/multi-line-chart.js +216 -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 +12 -0
- package/dist/native/atom/separator.js +16 -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 +22 -0
- package/dist/native/form/form.js +44 -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 +48 -0
- package/dist/native/lib/confirm.js +69 -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 +16 -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 +11 -0
- package/dist/native/lib/network.js +20 -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 +45 -0
- package/dist/native/lib/snackbar.js +59 -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 +39 -0
- package/dist/web/atom/segmented-control.js +42 -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 +23 -0
- package/dist/web/atom/text-area.js +27 -0
- package/dist/web/atom/text-field.d.ts +18 -0
- package/dist/web/atom/text-field.js +22 -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 +32 -0
- package/dist/web/layout/titled-modal.js +58 -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,55 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.js";
|
|
2
|
+
import { Checkbox as Checkbox$1 } from "../atom/checkbox.js";
|
|
3
|
+
import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/native/form/checkbox.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Checkbox integrated with TanStack Form. Like the web `form/checkbox`,
|
|
9
|
+
* pass `value` / `onValueChange` for controlled mode (the field is not used); omit them to read from the field context.
|
|
10
|
+
*/
|
|
11
|
+
function Checkbox(props) {
|
|
12
|
+
if (props.value !== void 0 && props.onValueChange !== void 0) return /* @__PURE__ */ jsx(Layout, {
|
|
13
|
+
...props,
|
|
14
|
+
checked: props.value,
|
|
15
|
+
onCheckedChange: props.onValueChange
|
|
16
|
+
});
|
|
17
|
+
return /* @__PURE__ */ jsx(FieldCheckbox, { ...props });
|
|
18
|
+
}
|
|
19
|
+
function FieldCheckbox(props) {
|
|
20
|
+
const [value, setValue] = useFieldValue({ debounce: props.debounce });
|
|
21
|
+
return /* @__PURE__ */ jsx(Layout, {
|
|
22
|
+
...props,
|
|
23
|
+
checked: value ?? false,
|
|
24
|
+
onCheckedChange: setValue
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function Layout({ label, required, description, helpText, disabled, className, wrapperClassName, checkboxLabel, checked, onCheckedChange }) {
|
|
28
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
29
|
+
className: wrapperClassName,
|
|
30
|
+
children: [
|
|
31
|
+
label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
32
|
+
required,
|
|
33
|
+
helpText,
|
|
34
|
+
children: label
|
|
35
|
+
}) : null,
|
|
36
|
+
/* @__PURE__ */ jsx(FormControl, {
|
|
37
|
+
described: Boolean(description),
|
|
38
|
+
children: (control) => /* @__PURE__ */ jsx(Checkbox$1, {
|
|
39
|
+
...control,
|
|
40
|
+
accessibilityHint: description,
|
|
41
|
+
checked,
|
|
42
|
+
onCheckedChange,
|
|
43
|
+
label: checkboxLabel,
|
|
44
|
+
disabled,
|
|
45
|
+
className
|
|
46
|
+
})
|
|
47
|
+
}),
|
|
48
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
49
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { Checkbox };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
2
|
+
//#region src/native/form/date-picker.d.ts
|
|
3
|
+
export type DatePickerProps = FieldInputProps & {
|
|
4
|
+
mode?: "date" | "time" | "datetime";
|
|
5
|
+
minimumDate?: Date;
|
|
6
|
+
maximumDate?: Date;
|
|
7
|
+
/** Formats the displayed value. Defaults to the locale's date notation. */
|
|
8
|
+
format?: (value: Date) => string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Date/time input integrated with TanStack Form. Corresponds to the web `form/date-picker`.
|
|
12
|
+
*
|
|
13
|
+
* The web version shows a react-day-picker calendar in a popover, whereas native uses
|
|
14
|
+
* the OS-standard picker (`@react-native-community/datetimepicker`).
|
|
15
|
+
* It follows each OS's convention: a persistent inline spinner on iOS, a dialog opened by tapping on Android.
|
|
16
|
+
* react-native-web (preview, vitest) has no web implementation in that library, so it is rendered by a
|
|
17
|
+
* substitute such as `<input type="date">` (`web/datetimepicker.tsx`), with an "OK" shown below as on iOS.
|
|
18
|
+
*
|
|
19
|
+
* The value comes from the field context (there is no controlled mode).
|
|
20
|
+
* The trigger is a **button** that opens the picker; its name is "label, current value" (same as `atom/select`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function DatePicker({ label, required, description, helpText, placeholder, disabled, debounce, className, wrapperClassName, mode, minimumDate, maximumDate, format, "data-testid": testID }: DatePickerProps): import("react").JSX.Element;
|
|
23
|
+
//#endregion
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.js";
|
|
2
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Text as Text$1 } from "../base/text.js";
|
|
5
|
+
import { tabularNums } from "../lib/typography.js";
|
|
6
|
+
import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
|
|
7
|
+
import { useId, useState } from "react";
|
|
8
|
+
import { Platform, Pressable, View } from "react-native";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import Feather from "@expo/vector-icons/Feather";
|
|
11
|
+
import DateTimePicker from "@react-native-community/datetimepicker";
|
|
12
|
+
|
|
13
|
+
//#region src/native/form/date-picker.tsx
|
|
14
|
+
/** Name given to the picker when the date/time input has none (for example when `label` is an element). */
|
|
15
|
+
const PICKER_LABEL = {
|
|
16
|
+
date: "日付",
|
|
17
|
+
time: "時刻",
|
|
18
|
+
datetime: "日時"
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Date/time input integrated with TanStack Form. Corresponds to the web `form/date-picker`.
|
|
22
|
+
*
|
|
23
|
+
* The web version shows a react-day-picker calendar in a popover, whereas native uses
|
|
24
|
+
* the OS-standard picker (`@react-native-community/datetimepicker`).
|
|
25
|
+
* It follows each OS's convention: a persistent inline spinner on iOS, a dialog opened by tapping on Android.
|
|
26
|
+
* react-native-web (preview, vitest) has no web implementation in that library, so it is rendered by a
|
|
27
|
+
* substitute such as `<input type="date">` (`web/datetimepicker.tsx`), with an "OK" shown below as on iOS.
|
|
28
|
+
*
|
|
29
|
+
* The value comes from the field context (there is no controlled mode).
|
|
30
|
+
* The trigger is a **button** that opens the picker; its name is "label, current value" (same as `atom/select`).
|
|
31
|
+
*/
|
|
32
|
+
function DatePicker({ label, required, description, helpText, placeholder, disabled, debounce, className, wrapperClassName, mode = "date", minimumDate, maximumDate, format, "data-testid": testID }) {
|
|
33
|
+
const [value, setValue] = useFieldValue({ debounce });
|
|
34
|
+
const [open, setOpen] = useState(false);
|
|
35
|
+
const valueId = `${useId()}-value`;
|
|
36
|
+
const [openedAt, setOpenedAt] = useState(null);
|
|
37
|
+
const mutedInk = useTokenColor("--ink-500");
|
|
38
|
+
const display = value ? format ? format(value) : defaultFormat(value, mode) : placeholder ?? "";
|
|
39
|
+
const nameText = typeof label === "string" ? label : void 0;
|
|
40
|
+
const triggerName = nameText !== void 0 ? `${nameText}、${display}` : label ? void 0 : display === "" ? PICKER_LABEL[mode] : `${PICKER_LABEL[mode]}、${display}`;
|
|
41
|
+
const closesOnChange = Platform.OS === "android";
|
|
42
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
43
|
+
className: wrapperClassName,
|
|
44
|
+
children: [
|
|
45
|
+
label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
46
|
+
required,
|
|
47
|
+
helpText,
|
|
48
|
+
children: label
|
|
49
|
+
}) : null,
|
|
50
|
+
/* @__PURE__ */ jsx(FormControl, {
|
|
51
|
+
labelled: Boolean(label),
|
|
52
|
+
described: Boolean(description),
|
|
53
|
+
children: (control) => /* @__PURE__ */ jsxs(Pressable, {
|
|
54
|
+
id: control.id,
|
|
55
|
+
accessibilityRole: "button",
|
|
56
|
+
accessibilityLabel: triggerName,
|
|
57
|
+
accessibilityHint: description,
|
|
58
|
+
"aria-labelledby": control["aria-labelledby"] === void 0 ? void 0 : `${control["aria-labelledby"]} ${valueId}`,
|
|
59
|
+
"aria-describedby": control["aria-describedby"],
|
|
60
|
+
"aria-invalid": control["aria-invalid"] ? true : void 0,
|
|
61
|
+
"aria-expanded": open,
|
|
62
|
+
"aria-disabled": disabled,
|
|
63
|
+
testID,
|
|
64
|
+
onPress: () => {
|
|
65
|
+
setOpenedAt(/* @__PURE__ */ new Date());
|
|
66
|
+
setOpen(true);
|
|
67
|
+
},
|
|
68
|
+
disabled,
|
|
69
|
+
className: cn("h-9 w-full flex-row items-center justify-between rounded-control border bg-raised px-3", control["aria-invalid"] ? "border-destructive" : "border-line-strong", disabled && "opacity-50", className),
|
|
70
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
71
|
+
id: valueId,
|
|
72
|
+
style: tabularNums,
|
|
73
|
+
className: cn("font-mono text-sm", value ? "text-foreground" : "text-muted-foreground"),
|
|
74
|
+
children: display
|
|
75
|
+
}), /* @__PURE__ */ jsx(Feather, {
|
|
76
|
+
name: "calendar",
|
|
77
|
+
size: 14,
|
|
78
|
+
color: mutedInk
|
|
79
|
+
})]
|
|
80
|
+
})
|
|
81
|
+
}),
|
|
82
|
+
open && openedAt !== null ? /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(DateTimePicker, {
|
|
83
|
+
value: value ?? openedAt,
|
|
84
|
+
mode,
|
|
85
|
+
display: Platform.OS === "ios" ? "inline" : "default",
|
|
86
|
+
minimumDate,
|
|
87
|
+
maximumDate,
|
|
88
|
+
accessibilityLabel: nameText ?? PICKER_LABEL[mode],
|
|
89
|
+
onChange: (event, selected) => {
|
|
90
|
+
if (closesOnChange) setOpen(false);
|
|
91
|
+
if (event.type === "dismissed") return;
|
|
92
|
+
if (selected) setValue(selected);
|
|
93
|
+
}
|
|
94
|
+
}), closesOnChange ? null : /* @__PURE__ */ jsx(Pressable, {
|
|
95
|
+
accessibilityRole: "button",
|
|
96
|
+
onPress: () => setOpen(false),
|
|
97
|
+
hitSlop: 8,
|
|
98
|
+
className: "self-end py-2",
|
|
99
|
+
children: /* @__PURE__ */ jsx(Text$1, {
|
|
100
|
+
className: "text-action-ink text-sm font-medium",
|
|
101
|
+
children: "OK"
|
|
102
|
+
})
|
|
103
|
+
})] }) : null,
|
|
104
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
105
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
106
|
+
]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function defaultFormat(value, mode) {
|
|
110
|
+
if (mode === "time") return value.toLocaleTimeString(void 0, {
|
|
111
|
+
hour: "2-digit",
|
|
112
|
+
minute: "2-digit"
|
|
113
|
+
});
|
|
114
|
+
if (mode === "datetime") return value.toLocaleString();
|
|
115
|
+
return value.toLocaleDateString();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
export { DatePicker };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ButtonProps } from "../atom/button.js";
|
|
2
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
//#region src/native/form/form.d.ts
|
|
5
|
+
export type SubmitButtonProps = Omit<ButtonProps, "onPress"> & {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
/** Allow submitting even when the value is still the initial one. */
|
|
8
|
+
allowDefaultValue?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* The form's submit button. It is disabled under the same conditions while submitting, unchanged, or failing validation
|
|
12
|
+
* (register it in `createFormHook`'s `formComponents` and use it as `form.SubmitButton`).
|
|
13
|
+
* The web side of love3 has no counterpart yet.
|
|
14
|
+
*/
|
|
15
|
+
export declare function SubmitButton({ disabled, allowDefaultValue, children, ...props }: SubmitButtonProps): import("react").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* Wrapper for array fields (label, children, supplementary text, error). Renders `description` as well.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ArrayFields({ label, required, description, children }: Pick<FieldInputProps, "label" | "required" | "description"> & {
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
//#endregion
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useFormContext } from "../../shared/form.js";
|
|
2
|
+
import { Button } from "../atom/button.js";
|
|
3
|
+
import { FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/native/form/form.tsx
|
|
7
|
+
/**
|
|
8
|
+
* The form's submit button. It is disabled under the same conditions while submitting, unchanged, or failing validation
|
|
9
|
+
* (register it in `createFormHook`'s `formComponents` and use it as `form.SubmitButton`).
|
|
10
|
+
* The web side of love3 has no counterpart yet.
|
|
11
|
+
*/
|
|
12
|
+
function SubmitButton({ disabled, allowDefaultValue = false, children, ...props }) {
|
|
13
|
+
const form = useFormContext();
|
|
14
|
+
return /* @__PURE__ */ jsx(form.Subscribe, {
|
|
15
|
+
selector: (state) => [
|
|
16
|
+
state.isSubmitting,
|
|
17
|
+
state.canSubmit,
|
|
18
|
+
state.isDefaultValue
|
|
19
|
+
],
|
|
20
|
+
children: ([isSubmitting, canSubmit, isDefaultValue]) => /* @__PURE__ */ jsx(Button, {
|
|
21
|
+
...props,
|
|
22
|
+
onPress: () => void form.handleSubmit(),
|
|
23
|
+
disabled: isSubmitting || !canSubmit || !allowDefaultValue && isDefaultValue || disabled,
|
|
24
|
+
children
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Wrapper for array fields (label, children, supplementary text, error). Renders `description` as well.
|
|
30
|
+
*/
|
|
31
|
+
function ArrayFields({ label, required, description, children }) {
|
|
32
|
+
return /* @__PURE__ */ jsxs(FormItem, { children: [
|
|
33
|
+
label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
34
|
+
required,
|
|
35
|
+
children: label
|
|
36
|
+
}) : null,
|
|
37
|
+
children,
|
|
38
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
39
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
40
|
+
] });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { ArrayFields, SubmitButton };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/native/form/radio-group.d.ts
|
|
4
|
+
export type RadioOption = {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
content?: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
export type RadioGroupProps = FieldInputProps & {
|
|
10
|
+
options: RadioOption[];
|
|
11
|
+
/** `list` stacks vertically; `box` lays out horizontally with a 1px border. The same two forms as web. */
|
|
12
|
+
type?: "list" | "box";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Radio group integrated with TanStack Form. Corresponds to the web `form/radio-group`.
|
|
16
|
+
*
|
|
17
|
+
* The knob is a 16px **circle** (same as web; `rounded-full`): unselected has a line-control border, selected has an indigo border and a center dot.
|
|
18
|
+
*
|
|
19
|
+
* The group is a `radiogroup` named by its label (`aria-labelledby`). Each option is a `radio` (named by the option's `label`),
|
|
20
|
+
* and each option points to the description and the error (one field holds several inputs, so ids are separated per option).
|
|
21
|
+
*/
|
|
22
|
+
export declare function RadioGroup({ label, required, description, helpText, wrapperClassName, ...rest }: RadioGroupProps): import("react").JSX.Element;
|
|
23
|
+
//#endregion
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.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 { FormControl, FormDescription, FormItem, FormLabel, FormMessage, useFormField } from "../base/form.js";
|
|
6
|
+
import { useId } from "react";
|
|
7
|
+
import { Pressable, View } from "react-native";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
|
|
10
|
+
//#region src/native/form/radio-group.tsx
|
|
11
|
+
/**
|
|
12
|
+
* Radio group integrated with TanStack Form. Corresponds to the web `form/radio-group`.
|
|
13
|
+
*
|
|
14
|
+
* The knob is a 16px **circle** (same as web; `rounded-full`): unselected has a line-control border, selected has an indigo border and a center dot.
|
|
15
|
+
*
|
|
16
|
+
* The group is a `radiogroup` named by its label (`aria-labelledby`). Each option is a `radio` (named by the option's `label`),
|
|
17
|
+
* and each option points to the description and the error (one field holds several inputs, so ids are separated per option).
|
|
18
|
+
*/
|
|
19
|
+
function RadioGroup({ label, required, description, helpText, wrapperClassName, ...rest }) {
|
|
20
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
21
|
+
className: wrapperClassName,
|
|
22
|
+
children: [
|
|
23
|
+
label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
24
|
+
required,
|
|
25
|
+
helpText,
|
|
26
|
+
children: label
|
|
27
|
+
}) : null,
|
|
28
|
+
/* @__PURE__ */ jsx(RadioGroupBody, {
|
|
29
|
+
hasLabel: Boolean(label),
|
|
30
|
+
description,
|
|
31
|
+
...rest
|
|
32
|
+
}),
|
|
33
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
34
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function RadioGroupBody({ hasLabel, description, options, disabled, debounce, className, type = "list" }) {
|
|
39
|
+
const [value, setValue] = useFieldValue({ debounce });
|
|
40
|
+
const { formItemId, formLabelId, errors } = useFormField();
|
|
41
|
+
return /* @__PURE__ */ jsx(View, {
|
|
42
|
+
id: formItemId,
|
|
43
|
+
accessibilityRole: "radiogroup",
|
|
44
|
+
"aria-labelledby": hasLabel ? formLabelId : void 0,
|
|
45
|
+
"aria-invalid": errors.length > 0,
|
|
46
|
+
className: cn(type === "box" ? "flex-row flex-wrap gap-2" : "gap-1", className),
|
|
47
|
+
children: options.map((option) => /* @__PURE__ */ jsx(RadioOption, {
|
|
48
|
+
option,
|
|
49
|
+
type,
|
|
50
|
+
selected: option.value === value,
|
|
51
|
+
disabled,
|
|
52
|
+
description,
|
|
53
|
+
onSelect: () => setValue(option.value)
|
|
54
|
+
}, option.value))
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function RadioOption({ option, type, selected, disabled, description, onSelect }) {
|
|
58
|
+
const id = useId();
|
|
59
|
+
return /* @__PURE__ */ jsx(FormControl, {
|
|
60
|
+
id,
|
|
61
|
+
described: Boolean(description),
|
|
62
|
+
children: (control) => /* @__PURE__ */ jsxs(Pressable, {
|
|
63
|
+
...control,
|
|
64
|
+
accessibilityRole: "radio",
|
|
65
|
+
accessibilityLabel: option.label,
|
|
66
|
+
accessibilityHint: description,
|
|
67
|
+
"aria-checked": selected,
|
|
68
|
+
"aria-disabled": disabled,
|
|
69
|
+
onPress: onSelect,
|
|
70
|
+
onKeyDown: activateOnSpace(onSelect, disabled),
|
|
71
|
+
disabled,
|
|
72
|
+
className: cn("flex-row items-center gap-2 py-1", type === "box" && "rounded-control border px-3", type === "box" && (control["aria-invalid"] ? "border-destructive" : "border-line-strong"), disabled && "opacity-50"),
|
|
73
|
+
children: [/* @__PURE__ */ jsx(View, {
|
|
74
|
+
className: cn("h-4 w-4 items-center justify-center rounded-full border bg-raised", selected ? "border-action" : "border-line-control"),
|
|
75
|
+
children: selected ? /* @__PURE__ */ jsx(View, { className: "h-2 w-2 rounded-full bg-action" }) : null
|
|
76
|
+
}), /* @__PURE__ */ jsxs(View, {
|
|
77
|
+
className: "shrink gap-1",
|
|
78
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
79
|
+
className: "text-sm font-medium leading-none",
|
|
80
|
+
children: option.label
|
|
81
|
+
}), option.content]
|
|
82
|
+
})]
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
export { RadioGroup };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SelectOption, SelectOptionGroup } from "../atom/select.js";
|
|
2
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
3
|
+
//#region src/native/form/select.d.ts
|
|
4
|
+
export type SelectProps = FieldInputProps & {
|
|
5
|
+
options: (SelectOption | SelectOptionGroup)[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Select integrated with TanStack Form. Same props as the web `form/select` (no controlled mode; use `atom/select` for a controlled version).
|
|
9
|
+
* The value comes from the field context. The default placeholder is the same as web's, "選択してください" ("Please select").
|
|
10
|
+
*/
|
|
11
|
+
export declare function Select({ label, required, description, helpText, placeholder, disabled, debounce, options, className, wrapperClassName }: SelectProps): import("react").JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
export type { SelectOption, SelectOptionGroup };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.js";
|
|
2
|
+
import { SELECT_PLACEHOLDER_LABEL } from "../lib/labels.js";
|
|
3
|
+
import { Select as Select$1 } from "../atom/select.js";
|
|
4
|
+
import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/native/form/select.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Select integrated with TanStack Form. Same props as the web `form/select` (no controlled mode; use `atom/select` for a controlled version).
|
|
10
|
+
* The value comes from the field context. The default placeholder is the same as web's, "選択してください" ("Please select").
|
|
11
|
+
*/
|
|
12
|
+
function Select({ label, required, description, helpText, placeholder = SELECT_PLACEHOLDER_LABEL, disabled, debounce, options, className, wrapperClassName }) {
|
|
13
|
+
const [value, setValue] = useFieldValue({ debounce });
|
|
14
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
15
|
+
className: wrapperClassName,
|
|
16
|
+
children: [
|
|
17
|
+
label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
18
|
+
required,
|
|
19
|
+
helpText,
|
|
20
|
+
children: label
|
|
21
|
+
}) : null,
|
|
22
|
+
/* @__PURE__ */ jsx(FormControl, {
|
|
23
|
+
labelled: Boolean(label),
|
|
24
|
+
described: Boolean(description),
|
|
25
|
+
children: (control) => /* @__PURE__ */ jsx(Select$1, {
|
|
26
|
+
...control,
|
|
27
|
+
accessibilityLabel: typeof label === "string" ? label : void 0,
|
|
28
|
+
accessibilityHint: description,
|
|
29
|
+
sheetTitle: label,
|
|
30
|
+
value: value ?? "",
|
|
31
|
+
onValueChange: setValue,
|
|
32
|
+
options,
|
|
33
|
+
placeholder,
|
|
34
|
+
disabled,
|
|
35
|
+
className
|
|
36
|
+
})
|
|
37
|
+
}),
|
|
38
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
39
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { Select };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
2
|
+
//#region src/native/form/slider.d.ts
|
|
3
|
+
export type SliderProps = FieldInputProps & {
|
|
4
|
+
min?: number;
|
|
5
|
+
max: number;
|
|
6
|
+
step?: number;
|
|
7
|
+
formattedValue?: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Slider integrated with TanStack Form. Corresponds to the web `form/slider` (single value only; ranges do not exist on native).
|
|
11
|
+
* The label and current-value row belongs to `atom/slider`. Use `atom/slider` if you need a controlled version.
|
|
12
|
+
*/
|
|
13
|
+
export declare function Slider({ label, required, description, helpText, disabled, debounce, min, max, step, formattedValue, className, wrapperClassName }: SliderProps): import("react").JSX.Element;
|
|
14
|
+
//#endregion
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.js";
|
|
2
|
+
import { Slider as Slider$1 } from "../atom/slider.js";
|
|
3
|
+
import { FormControl, FormDescription, FormItem, FormMessage } from "../base/form.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/native/form/slider.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Slider integrated with TanStack Form. Corresponds to the web `form/slider` (single value only; ranges do not exist on native).
|
|
9
|
+
* The label and current-value row belongs to `atom/slider`. Use `atom/slider` if you need a controlled version.
|
|
10
|
+
*/
|
|
11
|
+
function Slider({ label, required, description, helpText, disabled, debounce, min, max, step, formattedValue, className, wrapperClassName }) {
|
|
12
|
+
const [value, setValue] = useFieldValue({ debounce });
|
|
13
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
14
|
+
className: wrapperClassName,
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ jsx(FormControl, {
|
|
17
|
+
described: Boolean(description),
|
|
18
|
+
children: (control) => /* @__PURE__ */ jsx(Slider$1, {
|
|
19
|
+
...control,
|
|
20
|
+
accessibilityHint: description,
|
|
21
|
+
value: typeof value === "number" ? value : min ?? 0,
|
|
22
|
+
onValueChange: setValue,
|
|
23
|
+
label,
|
|
24
|
+
required,
|
|
25
|
+
helpText,
|
|
26
|
+
min,
|
|
27
|
+
max,
|
|
28
|
+
step,
|
|
29
|
+
disabled,
|
|
30
|
+
formattedValue,
|
|
31
|
+
labelClassName: control["aria-invalid"] ? "text-destructive opacity-100" : void 0,
|
|
32
|
+
className
|
|
33
|
+
})
|
|
34
|
+
}),
|
|
35
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
36
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { Slider };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseInputProps } from "../../shared/form.js";
|
|
2
|
+
//#region src/native/form/switch.d.ts
|
|
3
|
+
export type SwitchProps = BaseInputProps<boolean>;
|
|
4
|
+
/**
|
|
5
|
+
* Switch integrated with TanStack Form. Like the web `form/switch`, it lays out a single row: label on the left, switch on the right.
|
|
6
|
+
* Pass `value` / `onValueChange` for controlled mode (the field is not used); omit them to read from the field context.
|
|
7
|
+
*/
|
|
8
|
+
export declare function Switch(props: SwitchProps): import("react").JSX.Element;
|
|
9
|
+
//#endregion
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.js";
|
|
2
|
+
import { Switch as Switch$1 } from "../atom/switch.js";
|
|
3
|
+
import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
|
|
4
|
+
import { View } from "react-native";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/native/form/switch.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Switch integrated with TanStack Form. Like the web `form/switch`, it lays out a single row: label on the left, switch on the right.
|
|
10
|
+
* Pass `value` / `onValueChange` for controlled mode (the field is not used); omit them to read from the field context.
|
|
11
|
+
*/
|
|
12
|
+
function Switch(props) {
|
|
13
|
+
if (props.value !== void 0 && props.onValueChange !== void 0) return /* @__PURE__ */ jsx(Layout, {
|
|
14
|
+
...props,
|
|
15
|
+
checked: props.value,
|
|
16
|
+
onCheckedChange: props.onValueChange
|
|
17
|
+
});
|
|
18
|
+
return /* @__PURE__ */ jsx(FieldSwitch, { ...props });
|
|
19
|
+
}
|
|
20
|
+
function FieldSwitch(props) {
|
|
21
|
+
const [value, setValue] = useFieldValue({ debounce: props.debounce });
|
|
22
|
+
return /* @__PURE__ */ jsx(Layout, {
|
|
23
|
+
...props,
|
|
24
|
+
checked: value ?? false,
|
|
25
|
+
onCheckedChange: setValue
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function Layout({ label, required, description, helpText, disabled, className, wrapperClassName, checked, onCheckedChange }) {
|
|
29
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
30
|
+
className: wrapperClassName,
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ jsxs(View, {
|
|
33
|
+
className: "h-9 flex-row items-center justify-between",
|
|
34
|
+
children: [label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
35
|
+
required,
|
|
36
|
+
helpText,
|
|
37
|
+
children: label
|
|
38
|
+
}) : /* @__PURE__ */ jsx(View, {}), /* @__PURE__ */ jsx(FormControl, {
|
|
39
|
+
labelled: Boolean(label),
|
|
40
|
+
described: Boolean(description),
|
|
41
|
+
children: (control) => /* @__PURE__ */ jsx(Switch$1, {
|
|
42
|
+
...control,
|
|
43
|
+
accessibilityLabel: typeof label === "string" ? label : void 0,
|
|
44
|
+
accessibilityHint: description,
|
|
45
|
+
checked,
|
|
46
|
+
onCheckedChange,
|
|
47
|
+
disabled,
|
|
48
|
+
className
|
|
49
|
+
})
|
|
50
|
+
})]
|
|
51
|
+
}),
|
|
52
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
53
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { Switch };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
2
|
+
//#region src/native/form/text-area.d.ts
|
|
3
|
+
export type TextareaProps = FieldInputProps & {
|
|
4
|
+
/** Approximate number of visible lines (default 5 ≈ web's min-h-[200px]). */
|
|
5
|
+
numberOfLines?: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Multi-line input integrated with TanStack Form. Corresponds to the web `form/text-area`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Textarea({ label, required, description, helpText, placeholder, disabled, debounce, className, wrapperClassName, numberOfLines, "data-testid": testID }: TextareaProps): import("react").JSX.Element;
|
|
11
|
+
//#endregion
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useFieldValue } from "../../shared/form.js";
|
|
2
|
+
import { useTokenColor } from "../lib/token-color.js";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
|
|
5
|
+
import { TextInput } from "react-native";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
|
|
8
|
+
//#region src/native/form/text-area.tsx
|
|
9
|
+
/**
|
|
10
|
+
* Multi-line input integrated with TanStack Form. Corresponds to the web `form/text-area`.
|
|
11
|
+
*/
|
|
12
|
+
function Textarea({ label, required, description, helpText, placeholder, disabled, debounce, className, wrapperClassName, numberOfLines = 5, "data-testid": testID }) {
|
|
13
|
+
const [value, setValue] = useFieldValue({ debounce });
|
|
14
|
+
const mutedInk = useTokenColor("--ink-500");
|
|
15
|
+
return /* @__PURE__ */ jsxs(FormItem, {
|
|
16
|
+
className: wrapperClassName,
|
|
17
|
+
children: [
|
|
18
|
+
label ? /* @__PURE__ */ jsx(FormLabel, {
|
|
19
|
+
required,
|
|
20
|
+
helpText,
|
|
21
|
+
children: label
|
|
22
|
+
}) : null,
|
|
23
|
+
/* @__PURE__ */ jsx(FormControl, {
|
|
24
|
+
labelled: Boolean(label),
|
|
25
|
+
described: Boolean(description),
|
|
26
|
+
children: (control) => /* @__PURE__ */ jsx(TextInput, {
|
|
27
|
+
...control,
|
|
28
|
+
accessibilityLabel: typeof label === "string" ? label : void 0,
|
|
29
|
+
accessibilityHint: description,
|
|
30
|
+
value: value ?? "",
|
|
31
|
+
onChangeText: setValue,
|
|
32
|
+
placeholder,
|
|
33
|
+
placeholderTextColor: mutedInk,
|
|
34
|
+
editable: !disabled,
|
|
35
|
+
multiline: true,
|
|
36
|
+
numberOfLines,
|
|
37
|
+
textAlignVertical: "top",
|
|
38
|
+
testID,
|
|
39
|
+
style: { minHeight: numberOfLines * 22 + 16 },
|
|
40
|
+
className: cn("w-full rounded-control border border-line-strong bg-raised px-3 py-2 text-sm text-foreground", control["aria-invalid"] && "border-destructive", disabled && "opacity-50", className)
|
|
41
|
+
})
|
|
42
|
+
}),
|
|
43
|
+
description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
|
|
44
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { Textarea };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TextFieldProps, TextFieldType } from "../atom/text-field.js";
|
|
2
|
+
import { FieldInputProps } from "../../shared/form.js";
|
|
3
|
+
//#region src/native/form/text-input.d.ts
|
|
4
|
+
export type TextInputProps = FieldInputProps & {
|
|
5
|
+
/** `number` switches to the numeric keyboard and stores the value as a number (null when emptied). */
|
|
6
|
+
type?: TextFieldType;
|
|
7
|
+
/** Autofill kind (same meaning as web's `TextInput.autoComplete`; same type as `atom/text-field`). */
|
|
8
|
+
autoComplete?: TextFieldProps["autoComplete"];
|
|
9
|
+
autoCapitalize?: "none" | "sentences" | "words" | "characters";
|
|
10
|
+
multiline?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Text input integrated with TanStack Form. Corresponds to the web `form/text-input`.
|
|
14
|
+
* The value comes from the field context, and `debounce` handling is delegated to the shared `useFieldValue`.
|
|
15
|
+
* The input frame itself uses `atom/text-field` (the counterpart of web's `base/input`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function TextInput({ label, required, description, helpText, placeholder, disabled, debounce, className, wrapperClassName, type, autoComplete, autoCapitalize, multiline, "data-testid": testID }: TextInputProps): import("react").JSX.Element;
|
|
18
|
+
//#endregion
|