@multiplatform.one/forms 7.67.0 → 7.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/AdaptivePopup/index.cjs +45 -5
- package/dist/cjs/AdaptivePopup/index.native.js +47 -5
- package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
- package/dist/cjs/Button/IconButtonGroup.cjs +95 -0
- package/dist/cjs/Button/IconButtonGroup.native.js +101 -0
- package/dist/cjs/Button/IconButtonGroup.native.js.map +1 -0
- package/dist/cjs/Button/glass.cjs +34 -0
- package/dist/cjs/Button/glass.native.js +55 -0
- package/dist/cjs/Button/glass.native.js.map +1 -0
- package/dist/cjs/Button/iconButtonGroupContext.cjs +33 -0
- package/dist/cjs/Button/iconButtonGroupContext.native.js +36 -0
- package/dist/cjs/Button/iconButtonGroupContext.native.js.map +1 -0
- package/dist/cjs/Button/index.cjs +174 -30
- package/dist/cjs/Button/index.native.js +174 -29
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/Button/mediaPlate.cjs +31 -0
- package/dist/cjs/Button/mediaPlate.native.js +34 -0
- package/dist/cjs/Button/mediaPlate.native.js.map +1 -0
- package/dist/cjs/ContextualSaveBar/index.cjs +6 -8
- package/dist/cjs/ContextualSaveBar/index.native.js +6 -8
- package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/cjs/DescriptionList/index.cjs +0 -1
- package/dist/cjs/DescriptionList/index.native.js +0 -1
- package/dist/cjs/DescriptionList/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/index.native.js +21 -16
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/BarcodeScanner.cjs +7 -8
- package/dist/cjs/fields/Barcode/BarcodeScanner.native.js +7 -8
- package/dist/cjs/fields/Barcode/BarcodeScanner.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload/index.cjs +86 -60
- package/dist/cjs/fields/FileUpload/index.native.js +99 -73
- package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/index.cjs +7 -8
- package/dist/cjs/fields/Geolocation/index.native.js +7 -8
- package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
- package/dist/cjs/fields/ImageField/index.cjs +4 -6
- package/dist/cjs/fields/ImageField/index.native.js +4 -6
- package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +20 -28
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +20 -28
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/cjs/index.cjs +11 -1
- package/dist/cjs/index.native.js +10 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/shared/colorRamps.cjs +0 -8
- package/dist/cjs/shared/colorRamps.native.js +0 -8
- package/dist/cjs/shared/colorRamps.native.js.map +1 -1
- package/dist/cjs/standardActions.cjs +117 -0
- package/dist/cjs/standardActions.native.js +120 -0
- package/dist/cjs/standardActions.native.js.map +1 -0
- package/dist/esm/AdaptivePopup/index.mjs +45 -5
- package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
- package/dist/esm/AdaptivePopup/index.native.js +47 -5
- package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
- package/dist/esm/Button/IconButtonGroup.mjs +69 -0
- package/dist/esm/Button/IconButtonGroup.mjs.map +1 -0
- package/dist/esm/Button/IconButtonGroup.native.js +72 -0
- package/dist/esm/Button/IconButtonGroup.native.js.map +1 -0
- package/dist/esm/Button/glass.mjs +8 -0
- package/dist/esm/Button/glass.mjs.map +1 -0
- package/dist/esm/Button/glass.native.js +26 -0
- package/dist/esm/Button/glass.native.js.map +1 -0
- package/dist/esm/Button/iconButtonGroupContext.mjs +7 -0
- package/dist/esm/Button/iconButtonGroupContext.mjs.map +1 -0
- package/dist/esm/Button/iconButtonGroupContext.native.js +7 -0
- package/dist/esm/Button/iconButtonGroupContext.native.js.map +1 -0
- package/dist/esm/Button/index.mjs +166 -30
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +167 -30
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/Button/mediaPlate.mjs +6 -0
- package/dist/esm/Button/mediaPlate.mjs.map +1 -0
- package/dist/esm/Button/mediaPlate.native.js +6 -0
- package/dist/esm/Button/mediaPlate.native.js.map +1 -0
- package/dist/esm/ContextualSaveBar/index.mjs +7 -9
- package/dist/esm/ContextualSaveBar/index.mjs.map +1 -1
- package/dist/esm/ContextualSaveBar/index.native.js +7 -9
- package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/esm/DescriptionList/index.mjs +0 -1
- package/dist/esm/DescriptionList/index.mjs.map +1 -1
- package/dist/esm/DescriptionList/index.native.js +0 -1
- package/dist/esm/DescriptionList/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +22 -17
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- package/dist/esm/fields/Barcode/BarcodeScanner.mjs +8 -9
- package/dist/esm/fields/Barcode/BarcodeScanner.mjs.map +1 -1
- package/dist/esm/fields/Barcode/BarcodeScanner.native.js +8 -9
- package/dist/esm/fields/Barcode/BarcodeScanner.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/index.mjs +87 -61
- package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
- package/dist/esm/fields/FileUpload/index.native.js +100 -74
- package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/index.mjs +8 -9
- package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
- package/dist/esm/fields/Geolocation/index.native.js +8 -9
- package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
- package/dist/esm/fields/ImageField/index.mjs +6 -8
- package/dist/esm/fields/ImageField/index.mjs.map +1 -1
- package/dist/esm/fields/ImageField/index.native.js +6 -8
- package/dist/esm/fields/ImageField/index.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +20 -28
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +20 -28
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/esm/index.mjs +3 -2
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +3 -2
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/shared/colorRamps.mjs +0 -8
- package/dist/esm/shared/colorRamps.mjs.map +1 -1
- package/dist/esm/shared/colorRamps.native.js +0 -8
- package/dist/esm/shared/colorRamps.native.js.map +1 -1
- package/dist/esm/standardActions.mjs +91 -0
- package/dist/esm/standardActions.mjs.map +1 -0
- package/dist/esm/standardActions.native.js +91 -0
- package/dist/esm/standardActions.native.js.map +1 -0
- package/dist/jsx/AdaptivePopup/index.mjs +45 -5
- package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
- package/dist/jsx/AdaptivePopup/index.native.js +47 -5
- package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
- package/dist/jsx/Button/IconButtonGroup.mjs +69 -0
- package/dist/jsx/Button/IconButtonGroup.mjs.map +1 -0
- package/dist/jsx/Button/IconButtonGroup.native.js +101 -0
- package/dist/jsx/Button/IconButtonGroup.native.js.map +1 -0
- package/dist/jsx/Button/glass.mjs +8 -0
- package/dist/jsx/Button/glass.mjs.map +1 -0
- package/dist/jsx/Button/glass.native.js +55 -0
- package/dist/jsx/Button/glass.native.js.map +1 -0
- package/dist/jsx/Button/iconButtonGroupContext.mjs +7 -0
- package/dist/jsx/Button/iconButtonGroupContext.mjs.map +1 -0
- package/dist/jsx/Button/iconButtonGroupContext.native.js +36 -0
- package/dist/jsx/Button/iconButtonGroupContext.native.js.map +1 -0
- package/dist/jsx/Button/index.mjs +166 -30
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +174 -29
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/Button/mediaPlate.mjs +6 -0
- package/dist/jsx/Button/mediaPlate.mjs.map +1 -0
- package/dist/jsx/Button/mediaPlate.native.js +34 -0
- package/dist/jsx/Button/mediaPlate.native.js.map +1 -0
- package/dist/jsx/ContextualSaveBar/index.mjs +7 -9
- package/dist/jsx/ContextualSaveBar/index.mjs.map +1 -1
- package/dist/jsx/ContextualSaveBar/index.native.js +6 -8
- package/dist/jsx/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/jsx/DescriptionList/index.mjs +0 -1
- package/dist/jsx/DescriptionList/index.mjs.map +1 -1
- package/dist/jsx/DescriptionList/index.native.js +0 -1
- package/dist/jsx/DescriptionList/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +21 -16
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- package/dist/jsx/fields/Barcode/BarcodeScanner.mjs +8 -9
- package/dist/jsx/fields/Barcode/BarcodeScanner.mjs.map +1 -1
- package/dist/jsx/fields/Barcode/BarcodeScanner.native.js +7 -8
- package/dist/jsx/fields/Barcode/BarcodeScanner.native.js.map +1 -1
- package/dist/jsx/fields/FileUpload/index.mjs +87 -61
- package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
- package/dist/jsx/fields/FileUpload/index.native.js +99 -73
- package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/index.mjs +8 -9
- package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
- package/dist/jsx/fields/Geolocation/index.native.js +7 -8
- package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
- package/dist/jsx/fields/ImageField/index.mjs +6 -8
- package/dist/jsx/fields/ImageField/index.mjs.map +1 -1
- package/dist/jsx/fields/ImageField/index.native.js +4 -6
- package/dist/jsx/fields/ImageField/index.native.js.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +20 -28
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +20 -28
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/jsx/index.js +3 -2
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +3 -2
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +10 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/colorRamps.mjs +0 -8
- package/dist/jsx/shared/colorRamps.mjs.map +1 -1
- package/dist/jsx/shared/colorRamps.native.js +0 -8
- package/dist/jsx/shared/colorRamps.native.js.map +1 -1
- package/dist/jsx/standardActions.mjs +91 -0
- package/dist/jsx/standardActions.mjs.map +1 -0
- package/dist/jsx/standardActions.native.js +120 -0
- package/dist/jsx/standardActions.native.js.map +1 -0
- package/package.json +12 -8
- package/src/AdaptivePopup/AdaptivePopup.spec.tsx +44 -0
- package/src/AdaptivePopup/AdaptivePopup.stories.tsx +12 -32
- package/src/AdaptivePopup/index.tsx +65 -13
- package/src/Button/Button.disabledGlyph.spec.tsx +111 -0
- package/src/Button/Button.iconButton.spec.tsx +341 -0
- package/src/Button/Button.stories.tsx +179 -2
- package/src/Button/IconButtonGroup.spec.tsx +126 -0
- package/src/Button/IconButtonGroup.tsx +87 -0
- package/src/Button/glass.native.ts +51 -0
- package/src/Button/glass.ts +33 -0
- package/src/Button/iconButtonGroupContext.ts +14 -0
- package/src/Button/index.tsx +314 -42
- package/src/Button/mediaPlate.ts +9 -0
- package/src/ContextualSaveBar/ContextualSaveBar.spec.tsx +3 -1
- package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +2 -2
- package/src/ContextualSaveBar/index.tsx +7 -10
- package/src/ControlGroup/ControlGroup.stories.tsx +3 -2
- package/src/DescriptionList/index.tsx +0 -1
- package/src/ErrorSummary.stories.tsx +2 -1
- package/src/FieldLayout.stories.tsx +3 -2
- package/src/FloatingPanel/FloatingPanel.pointMenu.native.spec.tsx +69 -0
- package/src/FloatingPanel/FloatingPanel.stories.tsx +6 -10
- package/src/FloatingPanel/index.native.tsx +25 -4
- package/src/Form/Form.stories.tsx +6 -5
- package/src/errorSummaryStories.spec.tsx +4 -4
- package/src/fields/Barcode/BarcodeScanner.native.tsx +10 -9
- package/src/fields/Barcode/BarcodeScanner.tsx +10 -9
- package/src/fields/Checkbox/Checkbox.stories.tsx +3 -3
- package/src/fields/Checkbox/CheckboxGroup.stories.tsx +2 -2
- package/src/fields/ColorPicker/ColorPicker.stories.tsx +2 -2
- package/src/fields/Combobox/Combobox.stories.tsx +2 -2
- package/src/fields/DatePicker/DatePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/DateRangePicker.stories.tsx +2 -2
- package/src/fields/DatePicker/DatetimePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/MonthPicker.stories.tsx +2 -2
- package/src/fields/DatePicker/MultiDatePicker.stories.tsx +2 -2
- package/src/fields/FileUpload/FileUpload.spec.tsx +14 -5
- package/src/fields/FileUpload/FileUpload.stories.tsx +2 -2
- package/src/fields/FileUpload/index.tsx +103 -77
- package/src/fields/Geolocation/index.tsx +12 -7
- package/src/fields/ImageField/ImageField.spec.tsx +5 -5
- package/src/fields/ImageField/ImageField.stories.tsx +2 -2
- package/src/fields/ImageField/index.tsx +6 -9
- package/src/fields/Input/Input.stories.tsx +2 -2
- package/src/fields/MentionInput/MentionInput.stories.tsx +2 -1
- package/src/fields/Progress/Progress.stories.tsx +2 -1
- package/src/fields/RadioGroup/RadioGroup.stories.tsx +2 -1
- package/src/fields/Signature/Signature.stories.tsx +2 -2
- package/src/fields/Stepper/Stepper.stories.tsx +2 -2
- package/src/fields/TextArea/TextArea.stories.tsx +2 -2
- package/src/fields/ToggleGroup/ToggleGroup.stories.tsx +2 -2
- package/src/fields/nativeDateTime/OsDateTimeSheet.presentation.spec.tsx +6 -5
- package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +24 -12
- package/src/index.ts +18 -2
- package/src/shared/colorRamps.ts +1 -11
- package/src/standardActions.ts +96 -0
- package/types/AdaptivePopup/index.d.ts +13 -1
- package/types/AdaptivePopup/index.d.ts.map +1 -1
- package/types/Button/IconButtonGroup.d.ts +22 -0
- package/types/Button/IconButtonGroup.d.ts.map +1 -0
- package/types/Button/glass.d.ts +26 -0
- package/types/Button/glass.d.ts.map +1 -0
- package/types/Button/glass.native.d.ts +17 -0
- package/types/Button/glass.native.d.ts.map +1 -0
- package/types/Button/iconButtonGroupContext.d.ts +9 -0
- package/types/Button/iconButtonGroupContext.d.ts.map +1 -0
- package/types/Button/index.d.ts +55 -2
- package/types/Button/index.d.ts.map +1 -1
- package/types/Button/mediaPlate.d.ts +10 -0
- package/types/Button/mediaPlate.d.ts.map +1 -0
- package/types/ContextualSaveBar/index.d.ts.map +1 -1
- package/types/DescriptionList/index.d.ts.map +1 -1
- package/types/FloatingPanel/index.native.d.ts +2 -1
- package/types/FloatingPanel/index.native.d.ts.map +1 -1
- package/types/fields/Barcode/BarcodeScanner.d.ts.map +1 -1
- package/types/fields/Barcode/BarcodeScanner.native.d.ts.map +1 -1
- package/types/fields/FileUpload/index.d.ts.map +1 -1
- package/types/fields/Geolocation/index.d.ts.map +1 -1
- package/types/fields/ImageField/index.d.ts.map +1 -1
- package/types/fields/nativeDateTime/OsDateTimeSheet.d.ts.map +1 -1
- package/types/index.d.ts +4 -2
- package/types/index.d.ts.map +1 -1
- package/types/shared/colorRamps.d.ts +1 -11
- package/types/shared/colorRamps.d.ts.map +1 -1
- package/types/standardActions.d.ts +24 -0
- package/types/standardActions.d.ts.map +1 -0
|
@@ -5,7 +5,8 @@ import type { DeepKeys, DeepValue } from "@tanstack/form-core";
|
|
|
5
5
|
import { type DragEvent, type ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
|
6
6
|
import { useMedia, useProps, type SizeTokens } from "tamagui";
|
|
7
7
|
import { Image, isWeb, Text, XStack, YStack, styled } from "tamagui";
|
|
8
|
-
import { Button } from "../../Button";
|
|
8
|
+
import { Button, IconButton, IconButtonGroup } from "../../Button";
|
|
9
|
+
import { standardActions } from "../../standardActions";
|
|
9
10
|
import { Field, FieldLayout } from "../../fieldLayout";
|
|
10
11
|
import { Skeleton } from "../../Skeleton";
|
|
11
12
|
import {
|
|
@@ -756,25 +757,16 @@ export function FileUpload<
|
|
|
756
757
|
const existingName = existing?.name || fileNameFromSrc(existing?.src ?? "");
|
|
757
758
|
const hasRows = selectedFiles.length > 0 || transfers.length > 0 || showExisting;
|
|
758
759
|
|
|
759
|
-
|
|
760
|
+
// LC-176 ICON-BUTTON: a row's remove is a bare ✕; on an image tile it
|
|
761
|
+
// floats over the picture on the media plate. Painted at nestedControl with
|
|
762
|
+
// hitSlop restoring the 44 floor via `nested` (held exception).
|
|
763
|
+
const renderRemoveDisc = (ariaLabel: string, onPress: () => void, overMedia = false) =>
|
|
760
764
|
canInteract ? (
|
|
761
765
|
<Button
|
|
762
|
-
// Bento remove: a filled $color12 disc with the inverse
|
|
763
|
-
// ✕ — painted at nestedControl (32) with hitSlop
|
|
764
|
-
// restoring the 44 floor via `nested` (held exception);
|
|
765
|
-
// the nested icon step lands the board's 14px ✕.
|
|
766
766
|
nested
|
|
767
|
-
|
|
767
|
+
{...(overMedia ? { plate: "media" as const } : undefined)}
|
|
768
768
|
icon={XIcon}
|
|
769
769
|
aria-label={ariaLabel}
|
|
770
|
-
backgroundColor={formDropzoneColors.removeDisc.background.base}
|
|
771
|
-
color={formDropzoneColors.removeDisc.ink}
|
|
772
|
-
hoverStyle={{
|
|
773
|
-
backgroundColor: formDropzoneColors.removeDisc.background.hover,
|
|
774
|
-
}}
|
|
775
|
-
pressStyle={{
|
|
776
|
-
backgroundColor: formDropzoneColors.removeDisc.background.press,
|
|
777
|
-
}}
|
|
778
770
|
onPress={(e) => {
|
|
779
771
|
e.stopPropagation();
|
|
780
772
|
onPress();
|
|
@@ -782,6 +774,61 @@ export function FileUpload<
|
|
|
782
774
|
/>
|
|
783
775
|
) : null;
|
|
784
776
|
|
|
777
|
+
// LC-260 ICONS-OVER-WORDS: the preview's Replace and Remove are their
|
|
778
|
+
// symbols; over an image they float at its top-right on the LC-176 media
|
|
779
|
+
// plate. While replacing, the one ✕ backs out of the source choices.
|
|
780
|
+
const previewActions = (overMedia: boolean, onValueChange?: (nextValue: TData) => void) => {
|
|
781
|
+
const plate = overMedia ? { plate: "media" as const } : undefined;
|
|
782
|
+
const stop = (event: { stopPropagation: () => void }) => event.stopPropagation();
|
|
783
|
+
if (replacing)
|
|
784
|
+
return (
|
|
785
|
+
<IconButton
|
|
786
|
+
{...plate}
|
|
787
|
+
icon={standardActions.cancel.icon}
|
|
788
|
+
aria-label={t("Cancel replacement")}
|
|
789
|
+
aria-expanded
|
|
790
|
+
onPress={(event) => {
|
|
791
|
+
stop(event);
|
|
792
|
+
transfersRef.current.forEach((item) => item.controller.abort());
|
|
793
|
+
setTransfersAndRef(() => []);
|
|
794
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
795
|
+
if (isWeb)
|
|
796
|
+
replaceRef.current?.querySelector<HTMLElement>('button, [role="button"]')?.focus();
|
|
797
|
+
setReplacing(false);
|
|
798
|
+
}}
|
|
799
|
+
/>
|
|
800
|
+
);
|
|
801
|
+
return (
|
|
802
|
+
<>
|
|
803
|
+
<IconButton
|
|
804
|
+
{...plate}
|
|
805
|
+
icon={standardActions.replace.icon}
|
|
806
|
+
aria-label={t("Replace")}
|
|
807
|
+
aria-expanded={false}
|
|
808
|
+
onPress={(event) => {
|
|
809
|
+
stop(event);
|
|
810
|
+
setReplacing(true);
|
|
811
|
+
}}
|
|
812
|
+
/>
|
|
813
|
+
{singleFile || onExistingRemove ? (
|
|
814
|
+
<IconButton
|
|
815
|
+
{...plate}
|
|
816
|
+
icon={standardActions.remove.icon}
|
|
817
|
+
aria-label={t("Remove {{name}}", { name: singleFile?.name ?? existingName })}
|
|
818
|
+
onPress={(event) => {
|
|
819
|
+
stop(event);
|
|
820
|
+
transfersRef.current.forEach((item) => item.controller.abort());
|
|
821
|
+
setTransfersAndRef(() => []);
|
|
822
|
+
if (singleFile) handleFileRemove(singleFile, onValueChange);
|
|
823
|
+
else onExistingRemove?.();
|
|
824
|
+
setReplacing(false);
|
|
825
|
+
}}
|
|
826
|
+
/>
|
|
827
|
+
) : null}
|
|
828
|
+
</>
|
|
829
|
+
);
|
|
830
|
+
};
|
|
831
|
+
|
|
785
832
|
const renderFileMeta = (file: File, preview: string | null, extra?: ReactNode) => (
|
|
786
833
|
<XStack flex={1} gap="$2" alignItems="center">
|
|
787
834
|
{preview ? (
|
|
@@ -846,8 +893,10 @@ export function FileUpload<
|
|
|
846
893
|
right={tileRemoveInset}
|
|
847
894
|
zIndex={1}
|
|
848
895
|
>
|
|
849
|
-
{renderRemoveDisc(
|
|
850
|
-
|
|
896
|
+
{renderRemoveDisc(
|
|
897
|
+
t("Remove {{name}}", { name: file.name }),
|
|
898
|
+
() => handleFileRemove(file, onValueChange),
|
|
899
|
+
true,
|
|
851
900
|
)}
|
|
852
901
|
</YStack>
|
|
853
902
|
) : null}
|
|
@@ -1016,22 +1065,39 @@ export function FileUpload<
|
|
|
1016
1065
|
width="100%"
|
|
1017
1066
|
>
|
|
1018
1067
|
{singlePreview ? (
|
|
1019
|
-
<
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1068
|
+
<YStack position="relative" maxWidth="100%">
|
|
1069
|
+
<Image
|
|
1070
|
+
src={singlePreview}
|
|
1071
|
+
alt={singleFile?.name ?? existingName}
|
|
1072
|
+
width="$14"
|
|
1073
|
+
height="$14"
|
|
1074
|
+
maxWidth="100%"
|
|
1075
|
+
objectFit="contain"
|
|
1076
|
+
onLoad={(event) => {
|
|
1077
|
+
if (!isWeb) return;
|
|
1078
|
+
const image = event.currentTarget as unknown as HTMLImageElement;
|
|
1079
|
+
setPixelated(image.naturalWidth > 0 && image.naturalWidth < image.width);
|
|
1080
|
+
}}
|
|
1081
|
+
{...(isWeb && pixelated
|
|
1082
|
+
? { style: { imageRendering: "pixelated" } as any }
|
|
1083
|
+
: {})}
|
|
1084
|
+
/>
|
|
1085
|
+
{canInteract ? (
|
|
1086
|
+
<XStack
|
|
1087
|
+
ref={replaceRef as any}
|
|
1088
|
+
data-file-upload="preview-actions"
|
|
1089
|
+
position="absolute"
|
|
1090
|
+
top={-tileRemoveInset}
|
|
1091
|
+
right={-tileRemoveInset}
|
|
1092
|
+
zIndex={1}
|
|
1093
|
+
{...knobProps.gap}
|
|
1094
|
+
>
|
|
1095
|
+
<IconButtonGroup plate="media">
|
|
1096
|
+
{previewActions(true, onValueChange)}
|
|
1097
|
+
</IconButtonGroup>
|
|
1098
|
+
</XStack>
|
|
1099
|
+
) : null}
|
|
1100
|
+
</YStack>
|
|
1035
1101
|
) : (
|
|
1036
1102
|
<YStack alignItems="center" {...knobProps.gap}>
|
|
1037
1103
|
<FileIcon size={rowGlyphSize} />
|
|
@@ -1041,50 +1107,9 @@ export function FileUpload<
|
|
|
1041
1107
|
</YStack>
|
|
1042
1108
|
)}
|
|
1043
1109
|
</YStack>
|
|
1044
|
-
{canInteract ? (
|
|
1045
|
-
<XStack
|
|
1046
|
-
|
|
1047
|
-
{...knobProps.gap}
|
|
1048
|
-
justifyContent="center"
|
|
1049
|
-
flexWrap="wrap"
|
|
1050
|
-
>
|
|
1051
|
-
<Button
|
|
1052
|
-
size={knobProps.sizeToken}
|
|
1053
|
-
aria-label={replacing ? t("Cancel replacement") : t("Replace")}
|
|
1054
|
-
aria-expanded={replacing}
|
|
1055
|
-
onPress={(event) => {
|
|
1056
|
-
event.stopPropagation();
|
|
1057
|
-
if (replacing) {
|
|
1058
|
-
transfersRef.current.forEach((item) => item.controller.abort());
|
|
1059
|
-
setTransfersAndRef(() => []);
|
|
1060
|
-
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
1061
|
-
if (isWeb)
|
|
1062
|
-
replaceRef.current
|
|
1063
|
-
?.querySelector<HTMLElement>('button, [role="button"]')
|
|
1064
|
-
?.focus();
|
|
1065
|
-
}
|
|
1066
|
-
setReplacing(!replacing);
|
|
1067
|
-
}}
|
|
1068
|
-
>
|
|
1069
|
-
{replacing ? t("Cancel") : t("Replace")}
|
|
1070
|
-
</Button>
|
|
1071
|
-
{singleFile || onExistingRemove ? (
|
|
1072
|
-
<Button
|
|
1073
|
-
size={knobProps.sizeToken}
|
|
1074
|
-
outlined
|
|
1075
|
-
aria-label={t("Remove {{name}}", { name: singleFile?.name ?? existingName })}
|
|
1076
|
-
onPress={(event) => {
|
|
1077
|
-
event.stopPropagation();
|
|
1078
|
-
transfersRef.current.forEach((item) => item.controller.abort());
|
|
1079
|
-
setTransfersAndRef(() => []);
|
|
1080
|
-
if (singleFile) handleFileRemove(singleFile, onValueChange);
|
|
1081
|
-
else onExistingRemove?.();
|
|
1082
|
-
setReplacing(false);
|
|
1083
|
-
}}
|
|
1084
|
-
>
|
|
1085
|
-
{t("Remove")}
|
|
1086
|
-
</Button>
|
|
1087
|
-
) : null}
|
|
1110
|
+
{canInteract && !singlePreview ? (
|
|
1111
|
+
<XStack ref={replaceRef as any} {...knobProps.gap} justifyContent="center">
|
|
1112
|
+
{previewActions(false, onValueChange)}
|
|
1088
1113
|
</XStack>
|
|
1089
1114
|
) : null}
|
|
1090
1115
|
</YStack>
|
|
@@ -1175,6 +1200,7 @@ export function FileUpload<
|
|
|
1175
1200
|
{renderRemoveDisc(
|
|
1176
1201
|
t("Remove {{name}}", { name: existingName }),
|
|
1177
1202
|
onExistingRemove,
|
|
1203
|
+
true,
|
|
1178
1204
|
)}
|
|
1179
1205
|
</YStack>
|
|
1180
1206
|
) : null}
|
|
@@ -15,7 +15,8 @@ import { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
|
15
15
|
import type { LabelProps, SizeTokens } from "tamagui";
|
|
16
16
|
import { ScrollView, Spinner, Text as TamaguiText, View, XStack, YStack, isWeb } from "tamagui";
|
|
17
17
|
import { AdaptivePopup } from "../../AdaptivePopup";
|
|
18
|
-
import { Button } from "../../Button";
|
|
18
|
+
import { Button, IconButton } from "../../Button";
|
|
19
|
+
import { standardActions } from "../../standardActions";
|
|
19
20
|
import { Field, FieldLayout } from "../../fieldLayout";
|
|
20
21
|
import { FloatingPanel, useViewportGtSm } from "../../FloatingPanel";
|
|
21
22
|
import { Input as InputParts } from "../../InputParts";
|
|
@@ -699,12 +700,16 @@ function GeoMapSurface({
|
|
|
699
700
|
{locateError}
|
|
700
701
|
</TamaguiText>
|
|
701
702
|
<XStack gap="$2">
|
|
702
|
-
<
|
|
703
|
-
{
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
703
|
+
<IconButton
|
|
704
|
+
icon={standardActions.retry.icon}
|
|
705
|
+
onPress={onRetryLocate}
|
|
706
|
+
aria-label={t("Retry location")}
|
|
707
|
+
/>
|
|
708
|
+
<IconButton
|
|
709
|
+
icon={standardActions.close.icon}
|
|
710
|
+
onPress={onCloseLocate}
|
|
711
|
+
aria-label={t("Close location")}
|
|
712
|
+
/>
|
|
708
713
|
</XStack>
|
|
709
714
|
</YStack>
|
|
710
715
|
) : null}
|
|
@@ -106,7 +106,7 @@ describe("ImageField", () => {
|
|
|
106
106
|
if (img) fireEvent.error(img);
|
|
107
107
|
});
|
|
108
108
|
expect(result.findTextElement("Image failed to load")).toBeDefined();
|
|
109
|
-
expect(result.
|
|
109
|
+
expect(result.container.querySelector('[aria-label="Remove image"]')).toBeTruthy();
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
it("clears the value from the Remove action", async () => {
|
|
@@ -121,7 +121,7 @@ describe("ImageField", () => {
|
|
|
121
121
|
imageHeight={96}
|
|
122
122
|
/>,
|
|
123
123
|
);
|
|
124
|
-
const remove = result.
|
|
124
|
+
const remove = result.container.querySelector('[aria-label="Remove image"]');
|
|
125
125
|
expect(remove).toBeDefined();
|
|
126
126
|
await act(async () => {
|
|
127
127
|
if (remove) fireEvent.click(remove);
|
|
@@ -197,8 +197,8 @@ describe("ImageField", () => {
|
|
|
197
197
|
);
|
|
198
198
|
const tile = mediaTile(result.container);
|
|
199
199
|
expect(tile).not.toBeNull();
|
|
200
|
-
expect(tile?.
|
|
201
|
-
expect(result.
|
|
200
|
+
expect(tile?.querySelector('[aria-label="Remove image"]')).toBeNull();
|
|
201
|
+
expect(result.container.querySelector('[aria-label="Remove image"]')).toBeTruthy();
|
|
202
202
|
});
|
|
203
203
|
|
|
204
204
|
it("rides the unclamped radius knob including full", () => {
|
|
@@ -231,7 +231,7 @@ describe("ImageField", () => {
|
|
|
231
231
|
</TableCellContext.Provider>,
|
|
232
232
|
);
|
|
233
233
|
expect(mediaTile(result.container)).not.toBeNull();
|
|
234
|
-
expect(result.
|
|
234
|
+
expect(result.container.querySelector('[aria-label="Remove image"]')).toBeFalsy();
|
|
235
235
|
});
|
|
236
236
|
});
|
|
237
237
|
});
|
|
@@ -4,9 +4,9 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
4
4
|
import { useForm } from "@tanstack/react-form";
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
import { YStack, XStack } from "tamagui";
|
|
7
|
-
import { Button } from "../../Button";
|
|
8
7
|
import { Form } from "../../Form";
|
|
9
8
|
import { ImageField } from "./index";
|
|
9
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
10
10
|
|
|
11
11
|
const ATTACHED = `data:image/svg+xml;utf8,${encodeURIComponent(
|
|
12
12
|
'<svg xmlns="http://www.w3.org/2000/svg" width="240" height="120"><rect width="240" height="120" fill="#4a90d9"/><circle cx="120" cy="60" r="36" fill="#fff"/></svg>',
|
|
@@ -77,7 +77,7 @@ export const Main: Story = {
|
|
|
77
77
|
objectFit: "contain",
|
|
78
78
|
} as any)}
|
|
79
79
|
/>
|
|
80
|
-
<
|
|
80
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
81
81
|
</YStack>
|
|
82
82
|
</Form>
|
|
83
83
|
);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { edgeColorAt, transitionProps, Text } from "@multiplatform.one/theme";
|
|
13
|
-
import { ImageSquareIcon
|
|
13
|
+
import { ImageSquareIcon } from "@phosphor-icons/react";
|
|
14
14
|
import {
|
|
15
15
|
ensureFocusVisibleRing,
|
|
16
16
|
ensureKeyboardModalityTracking,
|
|
@@ -22,7 +22,8 @@ import type { DragEvent, ReactNode } from "react";
|
|
|
22
22
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
23
23
|
import type { LabelProps, SizeTokens } from "tamagui";
|
|
24
24
|
import { Image, Text as TamaguiText, View, YStack, isWeb, styled } from "tamagui";
|
|
25
|
-
import {
|
|
25
|
+
import { IconButton } from "../../Button";
|
|
26
|
+
import { standardActions } from "../../standardActions";
|
|
26
27
|
import { Field, FieldLayout, useFieldA11y, useFieldDescribedBy } from "../../fieldLayout";
|
|
27
28
|
import { Skeleton } from "../../Skeleton";
|
|
28
29
|
import { t } from "../../shared/t";
|
|
@@ -422,15 +423,11 @@ function ImageControl({
|
|
|
422
423
|
</ImageFrame>
|
|
423
424
|
|
|
424
425
|
{showRemove && hasValue && canInteract && !inTableCell && (
|
|
425
|
-
<
|
|
426
|
-
|
|
427
|
-
size="$2"
|
|
428
|
-
icon={XIcon}
|
|
426
|
+
<IconButton
|
|
427
|
+
icon={standardActions.remove.icon}
|
|
429
428
|
aria-label={t("Remove image")}
|
|
430
429
|
onPress={() => handleRemove()}
|
|
431
|
-
|
|
432
|
-
{t("Remove")}
|
|
433
|
-
</Button>
|
|
430
|
+
/>
|
|
434
431
|
)}
|
|
435
432
|
</YStack>
|
|
436
433
|
);
|
|
@@ -5,11 +5,11 @@ import { MagnifyingGlassIcon, XIcon } from "@phosphor-icons/react";
|
|
|
5
5
|
import { useForm } from "@tanstack/react-form";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { Input as TamaguiInput, XStack, YStack } from "tamagui";
|
|
8
|
-
import { Button } from "../../Button";
|
|
9
8
|
import { Form } from "../../Form";
|
|
10
9
|
import { SearchInput } from "../SearchInput";
|
|
11
10
|
import { Input } from "./index";
|
|
12
11
|
import { Paragraph } from "@multiplatform.one/theme";
|
|
12
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
13
13
|
|
|
14
14
|
const meta: Meta<typeof Input> = {
|
|
15
15
|
title: "Forms/Input",
|
|
@@ -64,7 +64,7 @@ export const Main: Story = {
|
|
|
64
64
|
},
|
|
65
65
|
}}
|
|
66
66
|
/>
|
|
67
|
-
<
|
|
67
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
68
68
|
</YStack>
|
|
69
69
|
</Form>
|
|
70
70
|
);
|
|
@@ -8,6 +8,7 @@ import { Button } from "../../Button";
|
|
|
8
8
|
import { Form } from "../../Form";
|
|
9
9
|
import { MentionInput } from "./index";
|
|
10
10
|
import type { MentionConfig } from "./index";
|
|
11
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
11
12
|
|
|
12
13
|
const meta: Meta<typeof MentionInput> = {
|
|
13
14
|
title: "Forms/MentionInput",
|
|
@@ -120,7 +121,7 @@ export const Main: Story = {
|
|
|
120
121
|
helperText="Write a message to your team"
|
|
121
122
|
placeholder="Type @ to mention someone"
|
|
122
123
|
/>
|
|
123
|
-
<
|
|
124
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
124
125
|
</YStack>
|
|
125
126
|
</Form>
|
|
126
127
|
);
|
|
@@ -8,6 +8,7 @@ import { Button } from "../../Button";
|
|
|
8
8
|
import { Form } from "../../Form";
|
|
9
9
|
import { Progress } from "./index";
|
|
10
10
|
import { Paragraph } from "@multiplatform.one/theme";
|
|
11
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
11
12
|
|
|
12
13
|
const meta: Meta<typeof Progress> = {
|
|
13
14
|
title: "Forms/Progress",
|
|
@@ -59,7 +60,7 @@ export const Main: Story = {
|
|
|
59
60
|
name="completion"
|
|
60
61
|
helperText="Read from form state"
|
|
61
62
|
/>
|
|
62
|
-
<
|
|
63
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
63
64
|
</YStack>
|
|
64
65
|
</Form>
|
|
65
66
|
);
|
|
@@ -12,6 +12,7 @@ import { Form } from "../../Form";
|
|
|
12
12
|
import { Checkbox } from "../Checkbox";
|
|
13
13
|
import { Switch } from "../Switch";
|
|
14
14
|
import { RadioGroup } from "./index";
|
|
15
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
15
16
|
|
|
16
17
|
const meta: Meta<typeof RadioGroup> = {
|
|
17
18
|
title: "Forms/RadioGroup",
|
|
@@ -395,7 +396,7 @@ export const RowPressInSheet: Story = {
|
|
|
395
396
|
return (
|
|
396
397
|
<YStack gap="$3">
|
|
397
398
|
<Text>{summary}</Text>
|
|
398
|
-
<
|
|
399
|
+
<ActionButton kind="filter" onPress={() => setOpen(true)} />
|
|
399
400
|
<AdaptivePopup open={open} onOpenChange={setOpen} title="Filter">
|
|
400
401
|
<YStack gap="$4">
|
|
401
402
|
<RadioGroup
|
|
@@ -5,10 +5,10 @@ import { EraserIcon } from "@phosphor-icons/react";
|
|
|
5
5
|
import { useForm } from "@tanstack/react-form";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { YStack } from "tamagui";
|
|
8
|
-
import { Button } from "../../Button";
|
|
9
8
|
import { Form } from "../../Form";
|
|
10
9
|
import { Signature } from "./index";
|
|
11
10
|
import { Text } from "@multiplatform.one/theme";
|
|
11
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
12
12
|
|
|
13
13
|
const meta: Meta<typeof Signature> = {
|
|
14
14
|
title: "Forms/Signature",
|
|
@@ -61,7 +61,7 @@ export const Main: Story = {
|
|
|
61
61
|
required
|
|
62
62
|
clearIcon={<EraserIcon size={16} />}
|
|
63
63
|
/>
|
|
64
|
-
<
|
|
64
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
65
65
|
</YStack>
|
|
66
66
|
</Form>
|
|
67
67
|
);
|
|
@@ -5,10 +5,10 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
5
5
|
import { useForm } from "@tanstack/react-form";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import { YStack } from "tamagui";
|
|
8
|
-
import { Button } from "../../Button";
|
|
9
8
|
import { Form } from "../../Form";
|
|
10
9
|
import { Stepper } from "./index";
|
|
11
10
|
import { Paragraph } from "@multiplatform.one/theme";
|
|
11
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
12
12
|
|
|
13
13
|
const meta: Meta<typeof Stepper> = {
|
|
14
14
|
title: "Forms/Stepper",
|
|
@@ -60,7 +60,7 @@ export const Main: Story = {
|
|
|
60
60
|
<Stepper label="Quantity" name="quantity" min={1} max={100} buttonPosition="both" />
|
|
61
61
|
<Stepper label="Price" name="price" step={0.01} precision={2} min={0} />
|
|
62
62
|
<Stepper label="Discount (%)" name="discount" min={0} max={50} step={5} />
|
|
63
|
-
<
|
|
63
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
64
64
|
</YStack>
|
|
65
65
|
</Form>
|
|
66
66
|
);
|
|
@@ -4,10 +4,10 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
4
4
|
import { useForm } from "@tanstack/react-form";
|
|
5
5
|
import { useState } from "react";
|
|
6
6
|
import { TextArea as TamaguiTextArea, XStack, YStack } from "tamagui";
|
|
7
|
-
import { Button } from "../../Button";
|
|
8
7
|
import { Form } from "../../Form";
|
|
9
8
|
import { TextArea } from "./index";
|
|
10
9
|
import { Paragraph } from "@multiplatform.one/theme";
|
|
10
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
11
11
|
|
|
12
12
|
const meta: Meta<typeof TextArea> = {
|
|
13
13
|
title: "Forms/TextArea",
|
|
@@ -82,7 +82,7 @@ export const Main: Story = {
|
|
|
82
82
|
}}
|
|
83
83
|
/>
|
|
84
84
|
|
|
85
|
-
<
|
|
85
|
+
<ActionButton kind="save" formAction="submit" />
|
|
86
86
|
</YStack>
|
|
87
87
|
</Form>
|
|
88
88
|
);
|
|
@@ -3,10 +3,10 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
3
3
|
import { useForm } from "@tanstack/react-form";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { ToggleGroup as TamaguiToggleGroup, XStack, YStack } from "tamagui";
|
|
6
|
-
import { Button } from "../../Button";
|
|
7
6
|
import { Form } from "../../Form";
|
|
8
7
|
import { ToggleGroup } from "./index";
|
|
9
8
|
import { Paragraph, SizableText, Text } from "@multiplatform.one/theme";
|
|
9
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
10
10
|
|
|
11
11
|
const meta: Meta<typeof ToggleGroup> = {
|
|
12
12
|
title: "Forms/ToggleGroup",
|
|
@@ -99,7 +99,7 @@ export const Main: Story = {
|
|
|
99
99
|
{ label: "Attachments", value: "attachments" },
|
|
100
100
|
]}
|
|
101
101
|
/>
|
|
102
|
-
<
|
|
102
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
103
103
|
</YStack>
|
|
104
104
|
</Form>
|
|
105
105
|
);
|
|
@@ -70,10 +70,11 @@ const norm = (value: string) => value.replace(/\s+/gu, " ").trim();
|
|
|
70
70
|
async function press(text: string) {
|
|
71
71
|
let target: Element | null = null;
|
|
72
72
|
await waitFor(() => {
|
|
73
|
-
const node =
|
|
74
|
-
(
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
const node =
|
|
74
|
+
Array.from(document.body.querySelectorAll("*")).find(
|
|
75
|
+
(el) => el.children.length === 0 && norm(el.textContent ?? "") === norm(text),
|
|
76
|
+
) ?? document.body.querySelector(`[aria-label="${text}"]`);
|
|
77
|
+
if (!node) throw new Error(`no element with text or label "${text}"`);
|
|
77
78
|
target = node.closest('button, [role="button"]') ?? node;
|
|
78
79
|
});
|
|
79
80
|
fireEvent.click(target!);
|
|
@@ -142,7 +143,7 @@ describe("OS date/time sheet — Android presentation", () => {
|
|
|
142
143
|
open("date", new Date(2026, 2, 15));
|
|
143
144
|
expect(lastPick().mode).toBe("date");
|
|
144
145
|
expect(lastPick().display).toBe("default");
|
|
145
|
-
expect(document.
|
|
146
|
+
expect(document.querySelector('[aria-label="Done"]')).toBeNull();
|
|
146
147
|
});
|
|
147
148
|
|
|
148
149
|
it("a datetime advances from date to time after the first commit", async () => {
|
|
@@ -23,6 +23,9 @@ import { platform } from "@multiplatform.one/platform";
|
|
|
23
23
|
import { SafeAreaInsetsContext, initialWindowMetrics } from "react-native-safe-area-context";
|
|
24
24
|
import { useResolvedKnobs, Text } from "@multiplatform.one/theme";
|
|
25
25
|
import { View, XStack, YStack, useTheme, useThemeName } from "tamagui";
|
|
26
|
+
import { ArrowRightIcon } from "@phosphor-icons/react";
|
|
27
|
+
import { IconButton } from "../../Button";
|
|
28
|
+
import { standardActions } from "../../standardActions";
|
|
26
29
|
import { formCommonColors } from "../../shared/colorRamps";
|
|
27
30
|
import { t } from "../../shared/t";
|
|
28
31
|
import { type DateTimePickerEvent, loadDateTimePicker } from "./dateTimePickerLoader";
|
|
@@ -164,9 +167,11 @@ export function OsDateTimeSheet({
|
|
|
164
167
|
<Text color={formCommonColors.muted}>
|
|
165
168
|
{t("Date picker unavailable — requires @react-native-community/datetimepicker")}
|
|
166
169
|
</Text>
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
+
<IconButton
|
|
171
|
+
icon={standardActions.cancel.icon}
|
|
172
|
+
aria-label={t(standardActions.cancel.label)}
|
|
173
|
+
onPress={onCancel}
|
|
174
|
+
/>
|
|
170
175
|
</YStack>
|
|
171
176
|
</Pressable>
|
|
172
177
|
</Modal>
|
|
@@ -209,17 +214,24 @@ export function OsDateTimeSheet({
|
|
|
209
214
|
paddingBottom={dateSheetBottomPadding(keyboardInset, isIOS)}
|
|
210
215
|
>
|
|
211
216
|
<XStack justifyContent="space-between" {...knobProps.panelPadding}>
|
|
212
|
-
<
|
|
213
|
-
|
|
214
|
-
|
|
217
|
+
<IconButton
|
|
218
|
+
icon={standardActions.cancel.icon}
|
|
219
|
+
aria-label={t(standardActions.cancel.label)}
|
|
220
|
+
onPress={onCancel}
|
|
221
|
+
/>
|
|
215
222
|
{mode === "datetime" && !showTimePicker ? (
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
223
|
+
<IconButton
|
|
224
|
+
icon={ArrowRightIcon}
|
|
225
|
+
aria-label={t("Next")}
|
|
226
|
+
onPress={() => setShowTimePicker(true)}
|
|
227
|
+
/>
|
|
219
228
|
) : (
|
|
220
|
-
<
|
|
221
|
-
|
|
222
|
-
|
|
229
|
+
<IconButton
|
|
230
|
+
icon={standardActions.done.icon}
|
|
231
|
+
plate="primary"
|
|
232
|
+
aria-label={t(standardActions.done.label)}
|
|
233
|
+
onPress={confirm}
|
|
234
|
+
/>
|
|
223
235
|
)}
|
|
224
236
|
</XStack>
|
|
225
237
|
<YStack {...knobProps.panelPadding} flexShrink={1} minHeight={0}>
|
package/src/index.ts
CHANGED
|
@@ -112,8 +112,22 @@ export { formatActionLabel } from "./actionLabel";
|
|
|
112
112
|
export type { ActionLabelParts } from "./actionLabel";
|
|
113
113
|
|
|
114
114
|
// ── Core Primitives ──────────────────────────────────────────
|
|
115
|
-
export {
|
|
116
|
-
|
|
115
|
+
export {
|
|
116
|
+
Button,
|
|
117
|
+
IconButton,
|
|
118
|
+
IconButtonGroup,
|
|
119
|
+
iconButtonGlyphPx,
|
|
120
|
+
ICON_BUTTON_GLASS_MERGE_PX,
|
|
121
|
+
ICON_BUTTON_GLYPH_PX,
|
|
122
|
+
ICON_BUTTON_NEUTRAL_GLYPH_PX,
|
|
123
|
+
ICON_BUTTON_PRESS_OPACITY,
|
|
124
|
+
} from "./Button";
|
|
125
|
+
export type {
|
|
126
|
+
ButtonProps,
|
|
127
|
+
ButtonActionRole,
|
|
128
|
+
IconButtonGroupProps,
|
|
129
|
+
IconButtonProps,
|
|
130
|
+
} from "./Button";
|
|
117
131
|
|
|
118
132
|
export { Input } from "./fields/Input";
|
|
119
133
|
export type { InputProps } from "./fields/Input";
|
|
@@ -460,3 +474,5 @@ export type {
|
|
|
460
474
|
PickedMedia,
|
|
461
475
|
MediaPickerErrorCode,
|
|
462
476
|
} from "./MediaPicker/types";
|
|
477
|
+
export { standardActions, standardActionWords } from "./standardActions";
|
|
478
|
+
export type { StandardAction, StandardActionKind } from "./standardActions";
|