@multiplatform.one/forms 7.7.6 → 7.10.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/Button/index.cjs +1 -4
- package/dist/cjs/Button/index.native.js +5 -6
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/Chip/index.cjs +1 -1
- package/dist/cjs/Chip/index.native.js +1 -1
- package/dist/cjs/Chip/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/index.cjs +59 -14
- package/dist/cjs/FloatingPanel/index.native.js +16 -7
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/nestedAction.cjs +37 -0
- package/dist/cjs/FloatingPanel/nestedAction.native.js +42 -0
- package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -0
- package/dist/cjs/InputParts/index.cjs +19 -8
- package/dist/cjs/InputParts/index.native.js +20 -11
- package/dist/cjs/InputParts/index.native.js.map +1 -1
- package/dist/cjs/Wheel/index.cjs +3 -3
- package/dist/cjs/Wheel/index.native.js +3 -3
- package/dist/cjs/Wheel/index.native.js.map +1 -1
- package/dist/cjs/fieldLayout.cjs +3 -3
- package/dist/cjs/fieldLayout.native.js +3 -3
- package/dist/cjs/fieldLayout.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.cjs +9 -2
- package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
- package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/index.cjs +36 -29
- package/dist/cjs/fields/Combobox/index.native.js +38 -38
- package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/Calendar.cjs +6 -1
- package/dist/cjs/fields/DatePicker/Calendar.native.js +6 -1
- package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/DateRangePicker.cjs +2 -2
- package/dist/cjs/fields/DatePicker/DateRangePicker.native.js +2 -2
- package/dist/cjs/fields/DatePicker/DateRangePicker.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +15 -12
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +39 -14
- package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/MonthPicker.cjs +10 -3
- package/dist/cjs/fields/DatePicker/MonthPicker.native.js +10 -3
- package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/MultiDatePicker.cjs +2 -2
- package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js +2 -2
- package/dist/cjs/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/index.native.js +3 -0
- package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/parts.cjs +26 -14
- package/dist/cjs/fields/DatePicker/parts.native.js +28 -14
- package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload/index.cjs +6 -0
- package/dist/cjs/fields/FileUpload/index.native.js +6 -0
- package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/GeolocationMap.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/geocoder.cjs +63 -0
- package/dist/cjs/fields/Geolocation/geocoder.native.js +68 -0
- package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -0
- package/dist/cjs/fields/Geolocation/index.cjs +801 -152
- package/dist/cjs/fields/Geolocation/index.native.js +856 -167
- package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/nativeSearchFocus.cjs +44 -0
- package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js +47 -0
- package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
- package/dist/cjs/fields/Icon/drawnSet.cjs +16 -3
- package/dist/cjs/fields/Icon/drawnSet.native.js +20 -3
- package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
- package/dist/cjs/fields/Icon/index.cjs +102 -27
- package/dist/cjs/fields/Icon/index.native.js +115 -31
- package/dist/cjs/fields/Icon/index.native.js.map +1 -1
- package/dist/cjs/fields/Input/index.cjs +5 -12
- package/dist/cjs/fields/Input/index.native.js +5 -13
- package/dist/cjs/fields/Input/index.native.js.map +1 -1
- package/dist/cjs/fields/PhoneInput/index.cjs +2 -2
- package/dist/cjs/fields/PhoneInput/index.native.js +2 -2
- package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/cjs/fields/RadioGroup/index.cjs +34 -5
- package/dist/cjs/fields/RadioGroup/index.native.js +49 -7
- package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/cjs/fields/SearchInput/index.cjs +8 -9
- package/dist/cjs/fields/SearchInput/index.native.js +8 -9
- package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
- package/dist/cjs/fields/Select/index.cjs +42 -11
- package/dist/cjs/fields/Select/index.native.js +52 -20
- package/dist/cjs/fields/Select/index.native.js.map +1 -1
- package/dist/cjs/fields/Stepper/index.cjs +144 -31
- package/dist/cjs/fields/Stepper/index.native.js +151 -31
- package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
- package/dist/cjs/fields/ToggleGroup/index.cjs +35 -2
- package/dist/cjs/fields/ToggleGroup/index.native.js +42 -2
- package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.native.js +2 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/shared/focusManagement.cjs +24 -11
- package/dist/cjs/shared/focusManagement.native.js +24 -11
- package/dist/cjs/shared/focusManagement.native.js.map +1 -1
- package/dist/cjs/shared/nativeA11y.cjs +57 -0
- package/dist/cjs/shared/nativeA11y.native.js +61 -0
- package/dist/cjs/shared/nativeA11y.native.js.map +1 -0
- package/dist/esm/Button/index.mjs +1 -4
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +5 -6
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/Chip/index.mjs +1 -1
- package/dist/esm/Chip/index.mjs.map +1 -1
- package/dist/esm/Chip/index.native.js +1 -1
- package/dist/esm/Chip/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/index.mjs +58 -15
- package/dist/esm/FloatingPanel/index.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +15 -8
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/nestedAction.mjs +11 -0
- package/dist/esm/FloatingPanel/nestedAction.mjs.map +1 -0
- package/dist/esm/FloatingPanel/nestedAction.native.js +13 -0
- package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -0
- package/dist/esm/InputParts/index.mjs +20 -9
- package/dist/esm/InputParts/index.mjs.map +1 -1
- package/dist/esm/InputParts/index.native.js +21 -12
- package/dist/esm/InputParts/index.native.js.map +1 -1
- package/dist/esm/Wheel/index.mjs +3 -3
- package/dist/esm/Wheel/index.mjs.map +1 -1
- package/dist/esm/Wheel/index.native.js +3 -3
- package/dist/esm/Wheel/index.native.js.map +1 -1
- package/dist/esm/fieldLayout.mjs +3 -3
- package/dist/esm/fieldLayout.mjs.map +1 -1
- package/dist/esm/fieldLayout.native.js +3 -3
- package/dist/esm/fieldLayout.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
- package/dist/esm/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
- package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
- package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
- package/dist/esm/fields/Combobox/index.mjs +36 -29
- package/dist/esm/fields/Combobox/index.mjs.map +1 -1
- package/dist/esm/fields/Combobox/index.native.js +38 -38
- package/dist/esm/fields/Combobox/index.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/Calendar.mjs +6 -1
- package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/Calendar.native.js +6 -1
- package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DateRangePicker.mjs +2 -2
- package/dist/esm/fields/DatePicker/DateRangePicker.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/DateRangePicker.native.js +2 -2
- package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.native.js +39 -14
- package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/MonthPicker.mjs +10 -3
- package/dist/esm/fields/DatePicker/MonthPicker.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/MonthPicker.native.js +10 -3
- package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/MultiDatePicker.mjs +2 -2
- package/dist/esm/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/MultiDatePicker.native.js +2 -2
- package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/index.native.js +3 -0
- package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/parts.mjs +28 -16
- package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/parts.native.js +30 -16
- package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/index.mjs +6 -0
- package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
- package/dist/esm/fields/FileUpload/index.native.js +6 -0
- package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
- package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/geocoder.mjs +33 -0
- package/dist/esm/fields/Geolocation/geocoder.mjs.map +1 -0
- package/dist/esm/fields/Geolocation/geocoder.native.js +35 -0
- package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -0
- package/dist/esm/fields/Geolocation/index.mjs +792 -149
- package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
- package/dist/esm/fields/Geolocation/index.native.js +847 -164
- package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs +19 -0
- package/dist/esm/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
- package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js +19 -0
- package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
- package/dist/esm/fields/Icon/drawnSet.mjs +16 -3
- package/dist/esm/fields/Icon/drawnSet.mjs.map +1 -1
- package/dist/esm/fields/Icon/drawnSet.native.js +20 -3
- package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
- package/dist/esm/fields/Icon/index.mjs +93 -18
- package/dist/esm/fields/Icon/index.mjs.map +1 -1
- package/dist/esm/fields/Icon/index.native.js +106 -22
- package/dist/esm/fields/Icon/index.native.js.map +1 -1
- package/dist/esm/fields/Input/index.mjs +5 -12
- package/dist/esm/fields/Input/index.mjs.map +1 -1
- package/dist/esm/fields/Input/index.native.js +5 -13
- package/dist/esm/fields/Input/index.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/index.mjs +2 -2
- package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
- package/dist/esm/fields/PhoneInput/index.native.js +2 -2
- package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/esm/fields/RadioGroup/index.mjs +34 -5
- package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
- package/dist/esm/fields/RadioGroup/index.native.js +49 -7
- package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/esm/fields/SearchInput/index.mjs +9 -10
- package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
- package/dist/esm/fields/SearchInput/index.native.js +9 -10
- package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
- package/dist/esm/fields/Select/index.mjs +42 -11
- package/dist/esm/fields/Select/index.mjs.map +1 -1
- package/dist/esm/fields/Select/index.native.js +52 -20
- package/dist/esm/fields/Select/index.native.js.map +1 -1
- package/dist/esm/fields/Stepper/index.mjs +145 -32
- package/dist/esm/fields/Stepper/index.mjs.map +1 -1
- package/dist/esm/fields/Stepper/index.native.js +152 -32
- package/dist/esm/fields/Stepper/index.native.js.map +1 -1
- package/dist/esm/fields/ToggleGroup/index.mjs +35 -2
- package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
- package/dist/esm/fields/ToggleGroup/index.native.js +42 -2
- package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/shared/focusManagement.mjs +24 -11
- package/dist/esm/shared/focusManagement.mjs.map +1 -1
- package/dist/esm/shared/focusManagement.native.js +24 -11
- package/dist/esm/shared/focusManagement.native.js.map +1 -1
- package/dist/esm/shared/nativeA11y.mjs +31 -0
- package/dist/esm/shared/nativeA11y.mjs.map +1 -0
- package/dist/esm/shared/nativeA11y.native.js +32 -0
- package/dist/esm/shared/nativeA11y.native.js.map +1 -0
- package/dist/jsx/Button/index.mjs +1 -4
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +5 -6
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/Chip/index.mjs +1 -1
- package/dist/jsx/Chip/index.mjs.map +1 -1
- package/dist/jsx/Chip/index.native.js +1 -1
- package/dist/jsx/Chip/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/index.mjs +58 -15
- package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +16 -7
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/nestedAction.mjs +11 -0
- package/dist/jsx/FloatingPanel/nestedAction.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/nestedAction.native.js +42 -0
- package/dist/jsx/FloatingPanel/nestedAction.native.js.map +1 -0
- package/dist/jsx/InputParts/index.mjs +20 -9
- package/dist/jsx/InputParts/index.mjs.map +1 -1
- package/dist/jsx/InputParts/index.native.js +20 -11
- package/dist/jsx/InputParts/index.native.js.map +1 -1
- package/dist/jsx/Wheel/index.mjs +3 -3
- package/dist/jsx/Wheel/index.mjs.map +1 -1
- package/dist/jsx/Wheel/index.native.js +3 -3
- package/dist/jsx/Wheel/index.native.js.map +1 -1
- package/dist/jsx/fieldLayout.mjs +3 -3
- package/dist/jsx/fieldLayout.mjs.map +1 -1
- package/dist/jsx/fieldLayout.native.js +3 -3
- package/dist/jsx/fieldLayout.native.js.map +1 -1
- package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs +8 -1
- package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.mjs.map +1 -1
- package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js +10 -1
- package/dist/jsx/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
- package/dist/jsx/fields/Combobox/index.mjs +36 -29
- package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
- package/dist/jsx/fields/Combobox/index.native.js +38 -38
- package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/Calendar.mjs +6 -1
- package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/Calendar.native.js +6 -1
- package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/DateRangePicker.mjs +2 -2
- package/dist/jsx/fields/DatePicker/DateRangePicker.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/DateRangePicker.native.js +2 -2
- package/dist/jsx/fields/DatePicker/DateRangePicker.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +15 -12
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +16 -12
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/DatetimePicker.native.js +39 -14
- package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/MonthPicker.mjs +10 -3
- package/dist/jsx/fields/DatePicker/MonthPicker.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/MonthPicker.native.js +10 -3
- package/dist/jsx/fields/DatePicker/MonthPicker.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs +2 -2
- package/dist/jsx/fields/DatePicker/MultiDatePicker.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js +2 -2
- package/dist/jsx/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/index.native.js +3 -0
- package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/parts.mjs +28 -16
- package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/parts.native.js +28 -14
- package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/jsx/fields/FileUpload/index.mjs +6 -0
- package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
- package/dist/jsx/fields/FileUpload/index.native.js +6 -0
- package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
- package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/geocoder.mjs +33 -0
- package/dist/jsx/fields/Geolocation/geocoder.mjs.map +1 -0
- package/dist/jsx/fields/Geolocation/geocoder.native.js +68 -0
- package/dist/jsx/fields/Geolocation/geocoder.native.js.map +1 -0
- package/dist/jsx/fields/Geolocation/index.mjs +792 -149
- package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
- package/dist/jsx/fields/Geolocation/index.native.js +856 -167
- package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs +19 -0
- package/dist/jsx/fields/Geolocation/nativeSearchFocus.mjs.map +1 -0
- package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js +47 -0
- package/dist/jsx/fields/Geolocation/nativeSearchFocus.native.js.map +1 -0
- package/dist/jsx/fields/Icon/drawnSet.mjs +16 -3
- package/dist/jsx/fields/Icon/drawnSet.mjs.map +1 -1
- package/dist/jsx/fields/Icon/drawnSet.native.js +20 -3
- package/dist/jsx/fields/Icon/drawnSet.native.js.map +1 -1
- package/dist/jsx/fields/Icon/index.mjs +93 -18
- package/dist/jsx/fields/Icon/index.mjs.map +1 -1
- package/dist/jsx/fields/Icon/index.native.js +115 -31
- package/dist/jsx/fields/Icon/index.native.js.map +1 -1
- package/dist/jsx/fields/Input/index.mjs +5 -12
- package/dist/jsx/fields/Input/index.mjs.map +1 -1
- package/dist/jsx/fields/Input/index.native.js +5 -13
- package/dist/jsx/fields/Input/index.native.js.map +1 -1
- package/dist/jsx/fields/PhoneInput/index.mjs +2 -2
- package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
- package/dist/jsx/fields/PhoneInput/index.native.js +2 -2
- package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/jsx/fields/RadioGroup/index.mjs +34 -5
- package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
- package/dist/jsx/fields/RadioGroup/index.native.js +49 -7
- package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/jsx/fields/SearchInput/index.mjs +9 -10
- package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
- package/dist/jsx/fields/SearchInput/index.native.js +8 -9
- package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
- package/dist/jsx/fields/Select/index.mjs +42 -11
- package/dist/jsx/fields/Select/index.mjs.map +1 -1
- package/dist/jsx/fields/Select/index.native.js +52 -20
- package/dist/jsx/fields/Select/index.native.js.map +1 -1
- package/dist/jsx/fields/Stepper/index.mjs +145 -32
- package/dist/jsx/fields/Stepper/index.mjs.map +1 -1
- package/dist/jsx/fields/Stepper/index.native.js +151 -31
- package/dist/jsx/fields/Stepper/index.native.js.map +1 -1
- package/dist/jsx/fields/ToggleGroup/index.mjs +35 -2
- package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
- package/dist/jsx/fields/ToggleGroup/index.native.js +42 -2
- package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/jsx/index.js +2 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +2 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +2 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/focusManagement.mjs +24 -11
- package/dist/jsx/shared/focusManagement.mjs.map +1 -1
- package/dist/jsx/shared/focusManagement.native.js +24 -11
- package/dist/jsx/shared/focusManagement.native.js.map +1 -1
- package/dist/jsx/shared/nativeA11y.mjs +31 -0
- package/dist/jsx/shared/nativeA11y.mjs.map +1 -0
- package/dist/jsx/shared/nativeA11y.native.js +61 -0
- package/dist/jsx/shared/nativeA11y.native.js.map +1 -0
- package/package.json +9 -7
- package/src/Button/Button.fontWeight.spec.tsx +75 -0
- package/src/Button/Button.labelInk.spec.tsx +21 -18
- package/src/Button/Button.outlinedChannel.spec.tsx +46 -0
- package/src/Button/Button.sizeLadder.spec.tsx +4 -3
- package/src/Button/Button.stories.tsx +20 -0
- package/src/Button/index.tsx +30 -7
- package/src/Chip/Chip.spec.tsx +3 -1
- package/src/Chip/index.tsx +1 -5
- package/src/FieldGroup.stories.tsx +3 -7
- package/src/FieldLayout.stories.tsx +75 -12
- package/src/Fieldset.stories.tsx +3 -7
- package/src/FloatingPanel/FloatingPanel.native.spec.tsx +54 -0
- package/src/FloatingPanel/FloatingPanel.spec.tsx +109 -0
- package/src/FloatingPanel/index.native.tsx +24 -7
- package/src/FloatingPanel/index.tsx +80 -13
- package/src/FloatingPanel/nestedAction.spec.ts +36 -0
- package/src/FloatingPanel/nestedAction.ts +15 -0
- package/src/FloatingPanel/panelWidthContract.spec.ts +12 -15
- package/src/FormGrid.stories.tsx +5 -11
- package/src/FormsIntegration.stories.tsx +2 -6
- package/src/InputParts/InputButton.spec.tsx +16 -0
- package/src/InputParts/index.tsx +34 -7
- package/src/InputParts/layoutGap.spec.tsx +43 -0
- package/src/Wheel/Wheel.spec.tsx +16 -0
- package/src/Wheel/index.tsx +3 -3
- package/src/fieldFamilyStories.radius.spec.tsx +118 -0
- package/src/fieldLayout.spec.tsx +42 -1
- package/src/fieldLayout.tsx +9 -9
- package/src/fields/Barcode/Barcode.spec.tsx +2 -0
- package/src/fields/Checkbox/CheckboxFieldFrame.spec.tsx +18 -0
- package/src/fields/Checkbox/CheckboxFieldFrame.tsx +6 -1
- package/src/fields/Combobox/Combobox.spec.tsx +48 -1
- package/src/fields/Combobox/index.tsx +53 -39
- package/src/fields/DatePicker/Calendar.tsx +4 -1
- package/src/fields/DatePicker/DatePicker.stories.tsx +22 -1
- package/src/fields/DatePicker/DateRangePicker.tsx +4 -2
- package/src/fields/DatePicker/DatetimePicker.catalog.tsx +21 -19
- package/src/fields/DatePicker/DatetimePicker.native.spec.tsx +144 -0
- package/src/fields/DatePicker/DatetimePicker.native.tsx +57 -32
- package/src/fields/DatePicker/DatetimePicker.stories.tsx +22 -0
- package/src/fields/DatePicker/MonthPicker.tsx +8 -3
- package/src/fields/DatePicker/MultiDatePicker.tsx +4 -2
- package/src/fields/DatePicker/index.native.tsx +1 -0
- package/src/fields/DatePicker/parts.spec.tsx +56 -0
- package/src/fields/DatePicker/parts.tsx +33 -12
- package/src/fields/FileUpload/FileUpload.spec.tsx +29 -0
- package/src/fields/FileUpload/index.tsx +6 -0
- package/src/fields/Geolocation/Geolocation.spec.tsx +287 -35
- package/src/fields/Geolocation/Geolocation.stories.tsx +141 -7
- package/src/fields/Geolocation/GeolocationMap.native.tsx +3 -0
- package/src/fields/Geolocation/GeolocationMap.tsx +4 -0
- package/src/fields/Geolocation/geocoder.spec.ts +59 -0
- package/src/fields/Geolocation/geocoder.ts +84 -0
- package/src/fields/Geolocation/geocoderSeam.spec.tsx +203 -0
- package/src/fields/Geolocation/index.tsx +912 -180
- package/src/fields/Geolocation/nativeSearchFocus.spec.ts +34 -0
- package/src/fields/Geolocation/nativeSearchFocus.ts +19 -0
- package/src/fields/Geolocation/salvage.spec.tsx +398 -0
- package/src/fields/Geolocation/storyProviders.spec.tsx +44 -0
- package/src/fields/Icon/Icon.spec.tsx +215 -1
- package/src/fields/Icon/Icon.stories.tsx +9 -1
- package/src/fields/Icon/drawnSet.tsx +44 -4
- package/src/fields/Icon/index.tsx +118 -18
- package/src/fields/Input/Input.copy.spec.tsx +1 -0
- package/src/fields/Input/Input.spec.tsx +50 -0
- package/src/fields/Input/Input.stories.tsx +1 -1
- package/src/fields/Input/index.tsx +7 -13
- package/src/fields/PhoneInput/index.tsx +2 -2
- package/src/fields/RadioGroup/RadioGroup.native.spec.tsx +67 -0
- package/src/fields/RadioGroup/index.tsx +82 -8
- package/src/fields/SearchInput/SearchInput.spec.tsx +14 -0
- package/src/fields/SearchInput/index.tsx +5 -6
- package/src/fields/Select/Select.spec.tsx +54 -0
- package/src/fields/Select/index.tsx +52 -17
- package/src/fields/Stepper/Stepper.spec.tsx +34 -1
- package/src/fields/Stepper/index.tsx +193 -33
- package/src/fields/ToggleGroup/ToggleGroup.native.spec.tsx +73 -0
- package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +49 -0
- package/src/fields/ToggleGroup/index.tsx +76 -1
- package/src/index.ts +9 -0
- package/src/shared/focusManagement.spec.tsx +68 -0
- package/src/shared/focusManagement.ts +20 -10
- package/src/shared/nativeA11y.spec.ts +64 -0
- package/src/shared/nativeA11y.ts +80 -0
- package/types/Button/index.d.ts +22 -3
- package/types/Button/index.d.ts.map +1 -1
- package/types/Chip/index.d.ts.map +1 -1
- package/types/FloatingPanel/index.d.ts +11 -1
- package/types/FloatingPanel/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/FloatingPanel/nestedAction.d.ts +13 -0
- package/types/FloatingPanel/nestedAction.d.ts.map +1 -0
- package/types/InputParts/index.d.ts.map +1 -1
- package/types/fields/Checkbox/CheckboxFieldFrame.d.ts +46 -2
- package/types/fields/Checkbox/CheckboxFieldFrame.d.ts.map +1 -1
- package/types/fields/Checkbox/index.d.ts +3 -3
- package/types/fields/Combobox/index.d.ts +3 -1
- package/types/fields/Combobox/index.d.ts.map +1 -1
- package/types/fields/DatePicker/Calendar.d.ts.map +1 -1
- package/types/fields/DatePicker/DateRangePicker.d.ts.map +1 -1
- package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
- package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
- package/types/fields/DatePicker/MonthPicker.d.ts.map +1 -1
- package/types/fields/DatePicker/MultiDatePicker.d.ts.map +1 -1
- package/types/fields/DatePicker/index.native.d.ts.map +1 -1
- package/types/fields/DatePicker/parts.d.ts.map +1 -1
- package/types/fields/FileUpload/index.d.ts.map +1 -1
- package/types/fields/Geolocation/GeolocationMap.d.ts +4 -0
- package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
- package/types/fields/Geolocation/GeolocationMap.native.d.ts +3 -0
- package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
- package/types/fields/Geolocation/geocoder.d.ts +53 -0
- package/types/fields/Geolocation/geocoder.d.ts.map +1 -0
- package/types/fields/Geolocation/index.d.ts +18 -2
- package/types/fields/Geolocation/index.d.ts.map +1 -1
- package/types/fields/Geolocation/nativeSearchFocus.d.ts +8 -0
- package/types/fields/Geolocation/nativeSearchFocus.d.ts.map +1 -0
- package/types/fields/Icon/drawnSet.d.ts.map +1 -1
- package/types/fields/Icon/index.d.ts.map +1 -1
- package/types/fields/Input/index.d.ts.map +1 -1
- package/types/fields/PhoneInput/index.d.ts.map +1 -1
- package/types/fields/RadioGroup/index.d.ts +30 -3
- package/types/fields/RadioGroup/index.d.ts.map +1 -1
- package/types/fields/SearchInput/index.d.ts.map +1 -1
- package/types/fields/Select/index.d.ts.map +1 -1
- package/types/fields/Stepper/index.d.ts.map +1 -1
- package/types/fields/ToggleGroup/index.d.ts +31 -2
- package/types/fields/ToggleGroup/index.d.ts.map +1 -1
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -1
- package/types/shared/focusManagement.d.ts +2 -2
- package/types/shared/focusManagement.d.ts.map +1 -1
- package/types/shared/nativeA11y.d.ts +61 -0
- package/types/shared/nativeA11y.d.ts.map +1 -0
- package/src/router.d.ts +0 -16
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { act, fireEvent } from "@testing-library/react";
|
|
2
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
4
4
|
import { Form } from "../../Form";
|
|
5
5
|
import { Combobox } from "./index";
|
|
@@ -11,6 +11,53 @@ const options = [
|
|
|
11
11
|
];
|
|
12
12
|
|
|
13
13
|
describe("Combobox", () => {
|
|
14
|
+
describe("custom sheet trigger", () => {
|
|
15
|
+
const initialWidth = window.innerWidth;
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
window.innerWidth = initialWidth;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("keeps the same name and keyboard opener on narrow and wide screens", async () => {
|
|
21
|
+
for (const width of [500, 1200]) {
|
|
22
|
+
window.innerWidth = width;
|
|
23
|
+
const result = renderWithProviders(
|
|
24
|
+
<Combobox
|
|
25
|
+
options={options}
|
|
26
|
+
aria-label="Country code"
|
|
27
|
+
trigger={() => <span>Country</span>}
|
|
28
|
+
/>,
|
|
29
|
+
);
|
|
30
|
+
const trigger = result.container.querySelector('[role="combobox"]');
|
|
31
|
+
expect(trigger?.getAttribute("aria-label")).toBe("Country code");
|
|
32
|
+
expect(trigger?.getAttribute("tabindex")).toBe("0");
|
|
33
|
+
expect(trigger?.getAttribute("aria-expanded")).toBe("false");
|
|
34
|
+
await act(async () => fireEvent.keyDown(trigger!, { key: "Enter" }));
|
|
35
|
+
expect(trigger?.getAttribute("aria-expanded")).toBe("true");
|
|
36
|
+
result.unmount();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("lets a custom adornment hug its content while ordinary triggers keep stretching", () => {
|
|
41
|
+
for (const width of [500, 1200]) {
|
|
42
|
+
window.innerWidth = width;
|
|
43
|
+
for (const triggerSizing of [undefined, "content"] as const) {
|
|
44
|
+
const result = renderWithProviders(
|
|
45
|
+
<Combobox
|
|
46
|
+
options={options}
|
|
47
|
+
triggerSizing={triggerSizing}
|
|
48
|
+
trigger={() => <span>Country</span>}
|
|
49
|
+
/>,
|
|
50
|
+
);
|
|
51
|
+
const trigger = result.container.querySelector<HTMLElement>(
|
|
52
|
+
'[data-testid="combobox-trigger"]',
|
|
53
|
+
);
|
|
54
|
+
expect(trigger?.style.width).toBe(triggerSizing === "content" ? "auto" : "100%");
|
|
55
|
+
result.unmount();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
14
61
|
describe("without form context", () => {
|
|
15
62
|
it("renders with label", () => {
|
|
16
63
|
const result = renderWithProviders(<Combobox label="Fruit" name="fruit" options={options} />);
|
|
@@ -191,6 +191,8 @@ export interface ComboboxProps {
|
|
|
191
191
|
/** Whether more pages are available. Shows a spinner at the bottom when loading more. */
|
|
192
192
|
hasMore?: boolean;
|
|
193
193
|
trigger?: (selected: ComboboxOption | ComboboxOption[] | undefined, open: boolean) => ReactNode;
|
|
194
|
+
/** Custom triggers stretch by default; content hugs a composite-field adornment. */
|
|
195
|
+
triggerSizing?: "stretch" | "content";
|
|
194
196
|
name?: string;
|
|
195
197
|
form?: AnyFormApi;
|
|
196
198
|
validators?: Record<string, unknown>;
|
|
@@ -458,6 +460,7 @@ interface FloatingComboboxCoreProps {
|
|
|
458
460
|
tabIndexOverride?: number;
|
|
459
461
|
popoverWidth?: number;
|
|
460
462
|
trigger?: (selected: ComboboxOption | ComboboxOption[] | undefined, open: boolean) => ReactNode;
|
|
463
|
+
triggerSizing?: "stretch" | "content";
|
|
461
464
|
knobProps: KnobProps;
|
|
462
465
|
multiple?: boolean;
|
|
463
466
|
selectedOrder?: SelectedOrder;
|
|
@@ -493,6 +496,7 @@ function FloatingComboboxCore({
|
|
|
493
496
|
tabIndexOverride,
|
|
494
497
|
popoverWidth,
|
|
495
498
|
trigger: triggerRender,
|
|
499
|
+
triggerSizing = "stretch",
|
|
496
500
|
knobProps,
|
|
497
501
|
multiple,
|
|
498
502
|
selectedOrder,
|
|
@@ -1351,12 +1355,16 @@ function FloatingComboboxCore({
|
|
|
1351
1355
|
<View
|
|
1352
1356
|
{...boxEventProps}
|
|
1353
1357
|
data-testid="combobox-trigger"
|
|
1354
|
-
width="100%"
|
|
1358
|
+
width={triggerSizing === "content" ? "auto" : "100%"}
|
|
1355
1359
|
alignSelf="stretch"
|
|
1356
1360
|
flexShrink={0}
|
|
1357
1361
|
outlineWidth={0}
|
|
1358
1362
|
focusVisibleStyle={ensureFocusVisibleRing({ outlineOffset: -2 })}
|
|
1359
|
-
style={{
|
|
1363
|
+
style={{
|
|
1364
|
+
display: "flex",
|
|
1365
|
+
alignItems: "stretch",
|
|
1366
|
+
width: triggerSizing === "content" ? "auto" : "100%",
|
|
1367
|
+
}}
|
|
1360
1368
|
>
|
|
1361
1369
|
{triggerRender(multiple ? selectedOptions : selectedOption, open)}
|
|
1362
1370
|
</View>
|
|
@@ -1785,6 +1793,7 @@ function NativeComboboxCore({
|
|
|
1785
1793
|
"aria-label": ariaLabel,
|
|
1786
1794
|
hasLabel,
|
|
1787
1795
|
trigger: triggerRender,
|
|
1796
|
+
triggerSizing = "stretch",
|
|
1788
1797
|
knobProps,
|
|
1789
1798
|
multiple,
|
|
1790
1799
|
selectedOrder,
|
|
@@ -2369,15 +2378,51 @@ function NativeComboboxCore({
|
|
|
2369
2378
|
</View>
|
|
2370
2379
|
);
|
|
2371
2380
|
|
|
2381
|
+
// Both trigger shapes share one accessible control. The sheet wrapper's
|
|
2382
|
+
// capture handler also opens it, so pointer activation is idempotent.
|
|
2383
|
+
const triggerProps = {
|
|
2384
|
+
id,
|
|
2385
|
+
...(isWeb
|
|
2386
|
+
? {
|
|
2387
|
+
role: "combobox" as const,
|
|
2388
|
+
"aria-haspopup": "listbox" as const,
|
|
2389
|
+
"aria-expanded": open,
|
|
2390
|
+
"aria-controls": listboxId,
|
|
2391
|
+
"aria-activedescendant": hideSearch ? activeDescendant : undefined,
|
|
2392
|
+
"aria-autocomplete": hideSearch ? ("list" as const) : undefined,
|
|
2393
|
+
"aria-label": ariaLabel ?? (!hasLabel ? placeholder : undefined),
|
|
2394
|
+
"aria-describedby": describedBy,
|
|
2395
|
+
tabIndex: disabled ? -1 : 0,
|
|
2396
|
+
}
|
|
2397
|
+
: { importantForAccessibility: "no" as const }),
|
|
2398
|
+
onPress: isWeb && !disabled ? () => handleOpenChange(true) : undefined,
|
|
2399
|
+
onKeyDown: (event: React.KeyboardEvent) => {
|
|
2400
|
+
if (disabled) return;
|
|
2401
|
+
if (
|
|
2402
|
+
["Enter", " ", "ArrowDown", "ArrowUp", "j", "k"].includes(event.key) ||
|
|
2403
|
+
event.code === "Space"
|
|
2404
|
+
) {
|
|
2405
|
+
event.preventDefault();
|
|
2406
|
+
setKeyboardNav(true);
|
|
2407
|
+
if (!open) handleOpenChange(true);
|
|
2408
|
+
}
|
|
2409
|
+
},
|
|
2410
|
+
};
|
|
2411
|
+
|
|
2372
2412
|
const triggerContent = triggerRender ? (
|
|
2373
2413
|
<View
|
|
2374
2414
|
data-testid="combobox-trigger"
|
|
2375
|
-
width="100%"
|
|
2415
|
+
width={triggerSizing === "content" ? "auto" : "100%"}
|
|
2376
2416
|
alignSelf="stretch"
|
|
2377
2417
|
flexShrink={0}
|
|
2378
2418
|
outlineWidth={0}
|
|
2379
2419
|
focusVisibleStyle={ensureFocusVisibleRing({ outlineOffset: -2 })}
|
|
2380
|
-
style={{
|
|
2420
|
+
style={{
|
|
2421
|
+
display: "flex",
|
|
2422
|
+
alignItems: "stretch",
|
|
2423
|
+
width: triggerSizing === "content" ? "auto" : "100%",
|
|
2424
|
+
}}
|
|
2425
|
+
{...triggerProps}
|
|
2381
2426
|
>
|
|
2382
2427
|
{triggerRender(multiple ? selectedOptions : selectedOption, open)}
|
|
2383
2428
|
</View>
|
|
@@ -2402,41 +2447,7 @@ function NativeComboboxCore({
|
|
|
2402
2447
|
borderRadius: knobProps.borderRadius.borderRadius,
|
|
2403
2448
|
borderWidth: knobProps.borderRadius.borderWidth,
|
|
2404
2449
|
})}
|
|
2405
|
-
|
|
2406
|
-
// Web: the box is the combobox control (ARIA + keyboard). Native:
|
|
2407
|
-
// FloatingPanel's trigger Pressable (triggerA11y) is the single
|
|
2408
|
-
// accessible node — role/aria props here surface the box as a
|
|
2409
|
-
// duplicate TalkBack stop on Android, so exclude it from the tree
|
|
2410
|
-
// (descendants stay reachable; "no", not "no-hide-descendants").
|
|
2411
|
-
{...(isWeb
|
|
2412
|
-
? {
|
|
2413
|
-
role: "combobox" as const,
|
|
2414
|
-
"aria-haspopup": "listbox",
|
|
2415
|
-
"aria-expanded": open,
|
|
2416
|
-
"aria-controls": listboxId,
|
|
2417
|
-
"aria-activedescendant": hideSearch ? activeDescendant : undefined,
|
|
2418
|
-
"aria-autocomplete": hideSearch ? ("list" as const) : undefined,
|
|
2419
|
-
// Standalone (no label): fall back to placeholder for the name.
|
|
2420
|
-
// Labelled: the sibling Label wires `aria-labelledby` onto this id
|
|
2421
|
-
// itself — naming it here too doubles the spoken name.
|
|
2422
|
-
"aria-label": ariaLabel ?? (!hasLabel ? placeholder : undefined),
|
|
2423
|
-
"aria-describedby": describedBy,
|
|
2424
|
-
tabIndex: disabled ? -1 : 0,
|
|
2425
|
-
}
|
|
2426
|
-
: { importantForAccessibility: "no" as const })}
|
|
2427
|
-
// Sheet capture opens first on web, so this opener is idempotent.
|
|
2428
|
-
// Native delegates the gesture to FloatingPanel.
|
|
2429
|
-
onPress={isWeb && !disabled ? () => handleOpenChange(true) : undefined}
|
|
2430
|
-
onKeyDown={(e: React.KeyboardEvent) => {
|
|
2431
|
-
if (
|
|
2432
|
-
["Enter", " ", "ArrowDown", "ArrowUp", "j", "k"].includes(e.key) ||
|
|
2433
|
-
e.code === "Space"
|
|
2434
|
-
) {
|
|
2435
|
-
e.preventDefault();
|
|
2436
|
-
setKeyboardNav(true);
|
|
2437
|
-
if (!open) handleOpenChange(true);
|
|
2438
|
-
}
|
|
2439
|
-
}}
|
|
2450
|
+
{...triggerProps}
|
|
2440
2451
|
>
|
|
2441
2452
|
<View
|
|
2442
2453
|
flex={1}
|
|
@@ -2506,6 +2517,7 @@ function NativeComboboxCore({
|
|
|
2506
2517
|
// the user types, so a content-fit sheet would open as a sliver.
|
|
2507
2518
|
sheetFill={Boolean(onSearch)}
|
|
2508
2519
|
trigger={triggerContent}
|
|
2520
|
+
triggerSizing={triggerSizing}
|
|
2509
2521
|
triggerEnd={
|
|
2510
2522
|
clearable && !multiple && !disabled && typeof value === "string" && value !== "" ? (
|
|
2511
2523
|
<Button
|
|
@@ -2564,6 +2576,7 @@ export function Combobox({
|
|
|
2564
2576
|
onLoadMore,
|
|
2565
2577
|
hasMore,
|
|
2566
2578
|
trigger,
|
|
2579
|
+
triggerSizing,
|
|
2567
2580
|
name,
|
|
2568
2581
|
form: formProp,
|
|
2569
2582
|
validators,
|
|
@@ -2696,6 +2709,7 @@ export function Combobox({
|
|
|
2696
2709
|
tabIndexOverride={tabIndexProp}
|
|
2697
2710
|
popoverWidth={popoverWidth}
|
|
2698
2711
|
trigger={trigger}
|
|
2712
|
+
triggerSizing={triggerSizing}
|
|
2699
2713
|
knobProps={knobProps}
|
|
2700
2714
|
multiple={multiple}
|
|
2701
2715
|
selectedOrder={selectedOrder}
|
|
@@ -80,6 +80,7 @@ function CalendarDayGrid({
|
|
|
80
80
|
maxDate,
|
|
81
81
|
selectionCapped,
|
|
82
82
|
}: CalendarDayGridProps) {
|
|
83
|
+
const { knobProps } = useCalendarKnobs();
|
|
83
84
|
return (
|
|
84
85
|
<CalendarDays
|
|
85
86
|
calendarData={calendarData}
|
|
@@ -110,7 +111,7 @@ function CalendarDayGrid({
|
|
|
110
111
|
}
|
|
111
112
|
return (
|
|
112
113
|
<View
|
|
113
|
-
transition=
|
|
114
|
+
transition={knobProps.transition}
|
|
114
115
|
position="absolute"
|
|
115
116
|
height="100%"
|
|
116
117
|
zIndex={0}
|
|
@@ -297,6 +298,7 @@ export function Calendar({
|
|
|
297
298
|
const handleSetDisplayForPrev = useCallback(
|
|
298
299
|
(date: Date) => {
|
|
299
300
|
const next = new Date(date);
|
|
301
|
+
next.setDate(1);
|
|
300
302
|
next.setMonth(next.getMonth() + 1);
|
|
301
303
|
setDisplayDate(next);
|
|
302
304
|
},
|
|
@@ -305,6 +307,7 @@ export function Calendar({
|
|
|
305
307
|
|
|
306
308
|
const prevMonthDate = useMemo(() => {
|
|
307
309
|
const date = new Date(displayDate);
|
|
310
|
+
date.setDate(1);
|
|
308
311
|
date.setMonth(date.getMonth() - 1);
|
|
309
312
|
return date;
|
|
310
313
|
}, [displayDate]);
|
|
@@ -4,7 +4,7 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
4
4
|
import { useForm } from "@tanstack/react-form";
|
|
5
5
|
import type { ComponentProps } from "react";
|
|
6
6
|
import { useState } from "react";
|
|
7
|
-
import { YStack } from "tamagui";
|
|
7
|
+
import { Text, YStack } from "tamagui";
|
|
8
8
|
import { Button } from "../../Button";
|
|
9
9
|
import { Form } from "../../Form";
|
|
10
10
|
import { Calendar } from "./Calendar";
|
|
@@ -103,6 +103,27 @@ export const Standalone: Story = {
|
|
|
103
103
|
render: (args) => <DatePicker {...args} />,
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
+
export const StateContract: Story = {
|
|
107
|
+
render: () => {
|
|
108
|
+
const [value, setValue] = useState<string | null>(null);
|
|
109
|
+
const [edits, setEdits] = useState(0);
|
|
110
|
+
return (
|
|
111
|
+
<YStack gap="$4" maxWidth={400}>
|
|
112
|
+
<DatePicker label="Saved date" defaultValue="1990-01-01" />
|
|
113
|
+
<DatePicker
|
|
114
|
+
label="Programmatic date"
|
|
115
|
+
value={value}
|
|
116
|
+
onChange={() => setEdits((count) => count + 1)}
|
|
117
|
+
/>
|
|
118
|
+
<Button onPress={() => setValue("2026-03-05")}>Load date</Button>
|
|
119
|
+
<Text>{`User edits: ${edits}`}</Text>
|
|
120
|
+
<DatePicker label="Read-only date" value="1990-01-01" readOnly />
|
|
121
|
+
<DatePicker label="Disabled date" value="1990-01-01" disabled />
|
|
122
|
+
</YStack>
|
|
123
|
+
);
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
106
127
|
export const Basic: Story = {
|
|
107
128
|
render: (args) => <DatePicker {...args} />,
|
|
108
129
|
args: {
|
|
@@ -261,6 +261,7 @@ function DualCalendarBody({
|
|
|
261
261
|
|
|
262
262
|
const prevMonthDate = useMemo(() => {
|
|
263
263
|
const date = new Date(displayDate);
|
|
264
|
+
date.setDate(1);
|
|
264
265
|
date.setMonth(date.getMonth() - 1);
|
|
265
266
|
return date;
|
|
266
267
|
}, [displayDate]);
|
|
@@ -273,6 +274,7 @@ function DualCalendarBody({
|
|
|
273
274
|
const handleSetDisplayForPrev = useCallback(
|
|
274
275
|
(date: Date) => {
|
|
275
276
|
const next = new Date(date);
|
|
277
|
+
next.setDate(1);
|
|
276
278
|
next.setMonth(next.getMonth() + 1);
|
|
277
279
|
setDisplayDate(next);
|
|
278
280
|
},
|
|
@@ -281,7 +283,7 @@ function DualCalendarBody({
|
|
|
281
283
|
|
|
282
284
|
if (!fullWidthMode) {
|
|
283
285
|
return (
|
|
284
|
-
<View
|
|
286
|
+
<View>
|
|
285
287
|
<SingleCalendar
|
|
286
288
|
displayDate={displayDate}
|
|
287
289
|
rangeStart={rangeStart}
|
|
@@ -297,7 +299,7 @@ function DualCalendarBody({
|
|
|
297
299
|
}
|
|
298
300
|
|
|
299
301
|
return (
|
|
300
|
-
<View flexDirection="row" {...knobProps.gap}
|
|
302
|
+
<View flexDirection="row" {...knobProps.gap}>
|
|
301
303
|
<SingleCalendar
|
|
302
304
|
displayDate={prevMonthDate}
|
|
303
305
|
rangeStart={rangeStart}
|
|
@@ -246,15 +246,14 @@ function DatetimePickerBody({
|
|
|
246
246
|
);
|
|
247
247
|
|
|
248
248
|
return (
|
|
249
|
-
<View
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
<View flexDirection="row" width="100%">
|
|
249
|
+
<View flexDirection="column" alignItems="center" minWidth={px * 7} alignSelf="stretch">
|
|
250
|
+
<View
|
|
251
|
+
flexDirection="row"
|
|
252
|
+
width="100%"
|
|
253
|
+
{...knobProps.panelPadding}
|
|
254
|
+
// The active content frame owns the space below this strip.
|
|
255
|
+
paddingBottom={0}
|
|
256
|
+
>
|
|
258
257
|
{(["date", "time"] as const).map((tab) => {
|
|
259
258
|
const active = activeTab === tab;
|
|
260
259
|
const tabDisabled = tab === "time" && !selectedDatetime;
|
|
@@ -319,15 +318,17 @@ function DatetimePickerBody({
|
|
|
319
318
|
</CalendarViewSwitcher>
|
|
320
319
|
) : (
|
|
321
320
|
selectedDatetime && (
|
|
322
|
-
<
|
|
323
|
-
<
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
321
|
+
<CalendarPanelFrame>
|
|
322
|
+
<View width={px * 7}>
|
|
323
|
+
<TimeSection
|
|
324
|
+
selectedDate={selectedDatetime}
|
|
325
|
+
onTimeChange={handleTimeChange}
|
|
326
|
+
timeFormat={timeFormat}
|
|
327
|
+
minuteStep={minuteStep}
|
|
328
|
+
showSeconds={showSeconds}
|
|
329
|
+
/>
|
|
330
|
+
</View>
|
|
331
|
+
</CalendarPanelFrame>
|
|
331
332
|
)
|
|
332
333
|
)}
|
|
333
334
|
</View>
|
|
@@ -505,7 +506,8 @@ export function DatetimePicker<
|
|
|
505
506
|
}
|
|
506
507
|
disabled={disabled}
|
|
507
508
|
sizing="grow"
|
|
508
|
-
|
|
509
|
+
contentPadding="none"
|
|
510
|
+
widthMode="fit-content"
|
|
509
511
|
>
|
|
510
512
|
{pickerContent(fieldChange)}
|
|
511
513
|
</FloatingPanel>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
2
|
+
import { useForm } from "@tanstack/react-form";
|
|
3
|
+
import { act, fireEvent, waitFor } from "@testing-library/react";
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { Form } from "../../Form";
|
|
6
|
+
import { DatetimePicker } from "./DatetimePicker.native";
|
|
7
|
+
import { DatePicker } from "./index.native";
|
|
8
|
+
|
|
9
|
+
vi.mock("tamagui", async (importOriginal) => ({
|
|
10
|
+
...(await importOriginal<typeof import("tamagui")>()),
|
|
11
|
+
isWeb: false,
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
// RNW omits React Native's accessibilityValue object. Bridge that native
|
|
15
|
+
// contract for this harness; the actual iOS AX tree remains the runtime gate.
|
|
16
|
+
vi.mock("react-native-web", async (importOriginal) => {
|
|
17
|
+
const native = await importOriginal<typeof import("react-native")>();
|
|
18
|
+
return {
|
|
19
|
+
...native,
|
|
20
|
+
Pressable: ({ accessibilityValue, ...props }: import("react-native").PressableProps) => (
|
|
21
|
+
<native.Pressable {...props} aria-valuetext={accessibilityValue?.text} />
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const picked = new Date(2026, 2, 5, 14, 30);
|
|
27
|
+
vi.mock("../nativeDateTime/OsDateTimeSheet", () => ({
|
|
28
|
+
OsDateTimeSheet: ({ open, onConfirm }: { open: boolean; onConfirm: (date: Date) => void }) =>
|
|
29
|
+
open ? (
|
|
30
|
+
<div role="dialog" aria-label="OS date and time">
|
|
31
|
+
<button onClick={() => onConfirm(new Date(2026, 2, 5, 14, 30))}>
|
|
32
|
+
Confirm OS selection
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
) : null,
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
describe("native DatetimePicker ownership", () => {
|
|
39
|
+
it.each([
|
|
40
|
+
{ Control: DatePicker, name: "Date" },
|
|
41
|
+
{ Control: DatetimePicker, name: "Date and time" },
|
|
42
|
+
])(
|
|
43
|
+
"keeps $name paint inert and exposes its current value on the press owner",
|
|
44
|
+
({ Control, name }) => {
|
|
45
|
+
const result = renderWithProviders(<Control value={picked} />);
|
|
46
|
+
const trigger = result.getByRole("button", { name });
|
|
47
|
+
expect(trigger.getAttribute("aria-valuetext")).toContain("Mar 5, 2026");
|
|
48
|
+
const painted = result.getByTestId("date-picker-trigger");
|
|
49
|
+
const paintAncestors: HTMLElement[] = [];
|
|
50
|
+
for (let el = painted.parentElement; el && el !== trigger; el = el.parentElement) {
|
|
51
|
+
paintAncestors.push(el);
|
|
52
|
+
}
|
|
53
|
+
expect(paintAncestors.some((el) => getComputedStyle(el).pointerEvents === "none")).toBe(true);
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
it("opens from its full-width native target and commits exactly once", () => {
|
|
58
|
+
const onChange = vi.fn();
|
|
59
|
+
const onValueChange = vi.fn();
|
|
60
|
+
const result = renderWithProviders(
|
|
61
|
+
<DatetimePicker onChange={onChange} onValueChange={onValueChange} />,
|
|
62
|
+
);
|
|
63
|
+
const trigger = result.getByRole("button", { name: "Date and time" });
|
|
64
|
+
expect(getComputedStyle(trigger).width).toBe("100%");
|
|
65
|
+
fireEvent.click(trigger);
|
|
66
|
+
expect(result.getAllByRole("dialog")).toHaveLength(1);
|
|
67
|
+
fireEvent.click(result.getByRole("button", { name: "Confirm OS selection" }));
|
|
68
|
+
expect(result.queryByRole("dialog")).toBeNull();
|
|
69
|
+
expect(onChange).toHaveBeenCalledExactlyOnceWith(picked);
|
|
70
|
+
expect(onValueChange).toHaveBeenCalledExactlyOnceWith(picked);
|
|
71
|
+
expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("keeps native read-only text undimmed, without a picker press target", () => {
|
|
75
|
+
const result = renderWithProviders(<DatetimePicker value={picked} readOnly />);
|
|
76
|
+
const input = result.container.querySelector("input")!;
|
|
77
|
+
expect(input.value).toContain("Mar 5, 2026");
|
|
78
|
+
expect(input.disabled).toBe(false);
|
|
79
|
+
expect(input.readOnly).toBe(true);
|
|
80
|
+
expect(result.queryByRole("button")).toBeNull();
|
|
81
|
+
fireEvent.click(input);
|
|
82
|
+
expect(result.queryByRole("dialog")).toBeNull();
|
|
83
|
+
for (let el: HTMLElement | null = input; el && el !== result.container; el = el.parentElement) {
|
|
84
|
+
const opacity = getComputedStyle(el).opacity;
|
|
85
|
+
expect(opacity === "" || Number(opacity) === 1).toBe(true);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("keeps a disabled value visible while declining activation", () => {
|
|
90
|
+
const result = renderWithProviders(<DatetimePicker value={picked} disabled />);
|
|
91
|
+
const trigger = result.getByRole("button", { name: "Date and time" });
|
|
92
|
+
expect(trigger.getAttribute("aria-disabled")).toBe("true");
|
|
93
|
+
expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026");
|
|
94
|
+
fireEvent.click(trigger);
|
|
95
|
+
expect(result.queryByRole("dialog")).toBeNull();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("adopts controlled values after mount without emitting changes or opening", async () => {
|
|
99
|
+
const onChange = vi.fn();
|
|
100
|
+
const onValueChange = vi.fn();
|
|
101
|
+
const result = renderWithProviders(
|
|
102
|
+
<DatetimePicker value={null} onChange={onChange} onValueChange={onValueChange} />,
|
|
103
|
+
);
|
|
104
|
+
expect(result.container.querySelector("input")?.value).toBe("");
|
|
105
|
+
result.rerender(
|
|
106
|
+
<DatetimePicker value={picked} onChange={onChange} onValueChange={onValueChange} />,
|
|
107
|
+
);
|
|
108
|
+
await waitFor(() =>
|
|
109
|
+
expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026"),
|
|
110
|
+
);
|
|
111
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
112
|
+
expect(onValueChange).not.toHaveBeenCalled();
|
|
113
|
+
expect(result.queryByRole("dialog")).toBeNull();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("adopts form values after mount without emitting changes or opening", async () => {
|
|
117
|
+
const onChange = vi.fn();
|
|
118
|
+
let update: ((date: Date) => void) | undefined;
|
|
119
|
+
function Example() {
|
|
120
|
+
const form = useForm({ defaultValues: { when: null as Date | null } });
|
|
121
|
+
update = (date) => form.setFieldValue("when", date);
|
|
122
|
+
return (
|
|
123
|
+
<Form form={form}>
|
|
124
|
+
<DatetimePicker name="when" onChange={onChange} />
|
|
125
|
+
</Form>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
const result = renderWithProviders(<Example />);
|
|
129
|
+
expect(result.container.querySelector("input")?.value).toBe("");
|
|
130
|
+
await act(async () => update?.(picked));
|
|
131
|
+
await waitFor(() =>
|
|
132
|
+
expect(result.container.querySelector("input")?.value).toContain("Mar 5, 2026"),
|
|
133
|
+
);
|
|
134
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
135
|
+
expect(result.queryByRole("dialog")).toBeNull();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("gives the native trigger box the row width its text section needs", () => {
|
|
139
|
+
const result = renderWithProviders(<DatetimePicker value={picked} />);
|
|
140
|
+
const box = result.getByTestId("date-picker-trigger");
|
|
141
|
+
expect(getComputedStyle(box).flexGrow).toBe("1");
|
|
142
|
+
expect(getComputedStyle(box).minWidth).toBe("0px");
|
|
143
|
+
});
|
|
144
|
+
});
|
|
@@ -142,38 +142,63 @@ export function DatetimePicker<
|
|
|
142
142
|
hasError?: boolean,
|
|
143
143
|
blurHandler?: (...args: unknown[]) => void,
|
|
144
144
|
fieldChange?: (value: unknown) => void,
|
|
145
|
-
) =>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
145
|
+
) => {
|
|
146
|
+
if (readOnly) {
|
|
147
|
+
return (
|
|
148
|
+
<InputParts.Box>
|
|
149
|
+
<InputParts.Area
|
|
150
|
+
value={display}
|
|
151
|
+
readOnly
|
|
152
|
+
aria-readonly="true"
|
|
153
|
+
aria-required={required || undefined}
|
|
154
|
+
aria-invalid={hasError || undefined}
|
|
155
|
+
placeholder={placeholder}
|
|
156
|
+
/>
|
|
157
|
+
</InputParts.Box>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return (
|
|
161
|
+
<>
|
|
162
|
+
<RNPressable
|
|
163
|
+
onPress={() => !disabled && setOpen(true)}
|
|
164
|
+
disabled={disabled}
|
|
165
|
+
accessibilityRole="button"
|
|
166
|
+
accessibilityLabel={hasLabel ? undefined : t("Date and time")}
|
|
167
|
+
accessibilityValue={{ text: display || placeholder }}
|
|
168
|
+
style={{ width: "100%" }}
|
|
169
|
+
>
|
|
170
|
+
<DatePickerInputTrigger
|
|
171
|
+
value={display}
|
|
172
|
+
placeholder={placeholder}
|
|
173
|
+
disabled={disabled}
|
|
174
|
+
open={open}
|
|
175
|
+
onReset={() => commit(null, fieldChange)}
|
|
176
|
+
onButtonPress={() => {}}
|
|
177
|
+
error={!!hasError}
|
|
178
|
+
id={id}
|
|
179
|
+
aria-label={hasLabel ? undefined : t("Date and time")}
|
|
180
|
+
aria-required={required || undefined}
|
|
181
|
+
aria-invalid={hasError || undefined}
|
|
182
|
+
/>
|
|
183
|
+
</RNPressable>
|
|
184
|
+
<OsDateTimeSheet
|
|
185
|
+
open={open}
|
|
186
|
+
value={selected ?? new Date()}
|
|
187
|
+
mode="datetime"
|
|
188
|
+
minDate={minDate}
|
|
189
|
+
maxDate={maxDate}
|
|
190
|
+
onCancel={() => {
|
|
191
|
+
setOpen(false);
|
|
192
|
+
blurHandler?.();
|
|
193
|
+
}}
|
|
194
|
+
onConfirm={(date) => {
|
|
195
|
+
commit(date, fieldChange);
|
|
196
|
+
blurHandler?.();
|
|
197
|
+
}}
|
|
198
|
+
/>
|
|
199
|
+
</>
|
|
200
|
+
);
|
|
201
|
+
};
|
|
177
202
|
|
|
178
203
|
if (skeleton) {
|
|
179
204
|
return (
|
|
@@ -50,6 +50,28 @@ export const Baseline: Story = {
|
|
|
50
50
|
),
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
export const StateContract: Story = {
|
|
54
|
+
render: () => {
|
|
55
|
+
const [value, setValue] = useState<Date | null>(null);
|
|
56
|
+
const [edits, setEdits] = useState(0);
|
|
57
|
+
const saved = new Date(2026, 0, 15, 9, 30);
|
|
58
|
+
return (
|
|
59
|
+
<YStack gap="$4" maxWidth={400}>
|
|
60
|
+
<DatetimePicker label="Saved date and time" defaultValue={saved} />
|
|
61
|
+
<DatetimePicker
|
|
62
|
+
label="Programmatic date and time"
|
|
63
|
+
value={value}
|
|
64
|
+
onChange={() => setEdits((count) => count + 1)}
|
|
65
|
+
/>
|
|
66
|
+
<Button onPress={() => setValue(new Date(2026, 2, 5, 14, 30))}>Load date and time</Button>
|
|
67
|
+
<Text>{`User edits: ${edits}`}</Text>
|
|
68
|
+
<DatetimePicker label="Read-only date and time" value={saved} readOnly />
|
|
69
|
+
<DatetimePicker label="Disabled date and time" value={saved} disabled />
|
|
70
|
+
</YStack>
|
|
71
|
+
);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
53
75
|
export const TwentyFourHour: Story = {
|
|
54
76
|
args: { timeFormat: "24h", helperText: "24-hour format" },
|
|
55
77
|
};
|