@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
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { isNestedPanelAction } from "./nestedAction";
|
|
3
|
+
|
|
4
|
+
describe("independent actions inside panel triggers", () => {
|
|
5
|
+
it("recognizes an SVG descendant of a marked action", () => {
|
|
6
|
+
const wrapper = document.createElement("div");
|
|
7
|
+
wrapper.innerHTML = '<button data-floating-panel-action="true"><svg><path /></svg></button>';
|
|
8
|
+
expect(
|
|
9
|
+
isNestedPanelAction({
|
|
10
|
+
nativeEvent: { target: wrapper.querySelector("path") },
|
|
11
|
+
currentTarget: wrapper,
|
|
12
|
+
}),
|
|
13
|
+
).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("does not let a marker above the wrapper suppress an ordinary opener", () => {
|
|
17
|
+
const outer = document.createElement("div");
|
|
18
|
+
outer.setAttribute("data-floating-panel-action", "true");
|
|
19
|
+
outer.innerHTML = "<div><button>Open</button></div>";
|
|
20
|
+
expect(
|
|
21
|
+
isNestedPanelAction({
|
|
22
|
+
target: outer.querySelector("button"),
|
|
23
|
+
currentTarget: outer.firstElementChild,
|
|
24
|
+
}),
|
|
25
|
+
).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("keeps unmarked buttons and non-DOM events as ordinary trigger presses", () => {
|
|
29
|
+
const wrapper = document.createElement("div");
|
|
30
|
+
wrapper.innerHTML = "<button>Open</button>";
|
|
31
|
+
expect(isNestedPanelAction({ target: wrapper.firstElementChild, currentTarget: wrapper })).toBe(
|
|
32
|
+
false,
|
|
33
|
+
);
|
|
34
|
+
expect(isNestedPanelAction({})).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const floatingPanelActionProps = { "data-floating-panel-action": "true" } as const;
|
|
2
|
+
|
|
3
|
+
export interface PanelActionEvent {
|
|
4
|
+
target?: unknown;
|
|
5
|
+
currentTarget?: unknown;
|
|
6
|
+
nativeEvent?: { target?: unknown };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Marked actions inside a trigger keep their own press and keyboard behavior. */
|
|
10
|
+
export function isNestedPanelAction(event: PanelActionEvent): boolean {
|
|
11
|
+
const target = (event.nativeEvent?.target ?? event.target) as Element | null;
|
|
12
|
+
const wrapper = event.currentTarget as Element | null;
|
|
13
|
+
const action = target?.closest?.('[data-floating-panel-action="true"]');
|
|
14
|
+
return !!action && !!wrapper?.contains?.(action);
|
|
15
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* trigger.
|
|
2
|
+
* Text listboxes match the field width; intrinsic editors size to their content.
|
|
4
3
|
*
|
|
5
4
|
* The runtime half is covered in `useFloatingPanel.spec.tsx`. This is the
|
|
6
5
|
* source half, and it exists because the defect it guards is invisible at
|
|
@@ -8,11 +7,9 @@
|
|
|
8
7
|
* DatePicker measured 262px of calendar under a 289px trigger purely because
|
|
9
8
|
* the call site said `fitContent`.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* absurd; those are listed explicitly so the exemption is a decision rather
|
|
15
|
-
* than an oversight.
|
|
10
|
+
* Calendar grids take fit-content (MPO-262): a full-width field wrapper is
|
|
11
|
+
* unrelated to seven day columns and must not create a mostly empty popup.
|
|
12
|
+
* Text listboxes retain at-least-trigger; icon/button launchers may also hug.
|
|
16
13
|
*/
|
|
17
14
|
import { readFileSync } from "node:fs";
|
|
18
15
|
import { dirname, resolve } from "node:path";
|
|
@@ -22,13 +19,9 @@ import { describe, expect, it } from "vitest";
|
|
|
22
19
|
const fieldsDir = resolve(dirname(fileURLToPath(import.meta.url)), "..", "fields");
|
|
23
20
|
|
|
24
21
|
/** Pickers whose trigger is a form FIELD: the panel may never be narrower. */
|
|
25
|
-
const fieldShapedPickers = [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"TimePicker/catalog.tsx",
|
|
29
|
-
"ColorPicker/parts.tsx",
|
|
30
|
-
"Icon/index.tsx",
|
|
31
|
-
];
|
|
22
|
+
const fieldShapedPickers = ["TimePicker/catalog.tsx", "ColorPicker/parts.tsx", "Icon/index.tsx"];
|
|
23
|
+
|
|
24
|
+
const intrinsicGridPickers = ["DatePicker/parts.tsx", "DatePicker/DatetimePicker.catalog.tsx"];
|
|
32
25
|
|
|
33
26
|
/** Panels opened from an icon/button trigger, where fit-content is correct. */
|
|
34
27
|
const buttonShapedPickers = ["Geolocation/index.tsx"];
|
|
@@ -37,7 +30,11 @@ function read(relative: string): string {
|
|
|
37
30
|
return readFileSync(resolve(fieldsDir, relative), "utf8");
|
|
38
31
|
}
|
|
39
32
|
|
|
40
|
-
describe("FloatingPanel width contract (MPO-38)", () => {
|
|
33
|
+
describe("FloatingPanel width contract (MPO-38, MPO-262)", () => {
|
|
34
|
+
it.each(intrinsicGridPickers)("%s hugs its calendar grid", (relative) => {
|
|
35
|
+
expect(read(relative)).toContain('widthMode="fit-content"');
|
|
36
|
+
});
|
|
37
|
+
|
|
41
38
|
it.each(fieldShapedPickers)("%s declares at-least-trigger", (relative) => {
|
|
42
39
|
const source = read(relative);
|
|
43
40
|
expect(source).toContain('widthMode="at-least-trigger"');
|
package/src/FormGrid.stories.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
2
|
-
import {
|
|
2
|
+
import { Paragraph, YStack } from "tamagui";
|
|
3
3
|
import { FieldGroup } from "./FieldGroup";
|
|
4
4
|
import { FormGrid } from "./FormGrid";
|
|
5
5
|
import { FormSection, FormSectionStack } from "./FormSection";
|
|
6
|
-
import {
|
|
6
|
+
import { Input } from "./fields/Input";
|
|
7
7
|
|
|
8
8
|
const meta: Meta<typeof FormGrid> = {
|
|
9
9
|
title: "Forms/FormGrid",
|
|
@@ -24,11 +24,7 @@ export default meta;
|
|
|
24
24
|
type Story = StoryObj<typeof FormGrid>;
|
|
25
25
|
|
|
26
26
|
function GridField({ id, label }: { id: string; label: string }) {
|
|
27
|
-
return
|
|
28
|
-
<FieldLayout id={id} label={label}>
|
|
29
|
-
<TamaguiInput id={id} placeholder={label} />
|
|
30
|
-
</FieldLayout>
|
|
31
|
-
);
|
|
27
|
+
return <Input id={id} label={label} placeholder={label} />;
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
export const Basic: Story = {
|
|
@@ -99,13 +95,11 @@ export const LongErrors: Story = {
|
|
|
99
95
|
render: () => (
|
|
100
96
|
<YStack maxWidth={640}>
|
|
101
97
|
<FormGrid columns={2}>
|
|
102
|
-
<
|
|
98
|
+
<Input
|
|
103
99
|
id="fge-a"
|
|
104
100
|
label="With long error"
|
|
105
101
|
error="This validation message is extremely long and should wrap inside its own grid cell without breaking the neighbouring column alignment or overflowing the grid container"
|
|
106
|
-
|
|
107
|
-
<TamaguiInput id="fge-a" />
|
|
108
|
-
</FieldLayout>
|
|
102
|
+
/>
|
|
109
103
|
<GridField id="fge-b" label="Neighbour" />
|
|
110
104
|
</FormGrid>
|
|
111
105
|
</YStack>
|
|
@@ -212,9 +212,7 @@ export const multiStepRegistration: Story = {
|
|
|
212
212
|
/>
|
|
213
213
|
|
|
214
214
|
<FormActions>
|
|
215
|
-
<Button
|
|
216
|
-
Back
|
|
217
|
-
</Button>
|
|
215
|
+
<Button onPress={() => setStep("personal")}>Back</Button>
|
|
218
216
|
<Button onPress={() => setStep("verification")}>Next: Verification</Button>
|
|
219
217
|
</FormActions>
|
|
220
218
|
</FormSection>
|
|
@@ -240,9 +238,7 @@ export const multiStepRegistration: Story = {
|
|
|
240
238
|
/>
|
|
241
239
|
|
|
242
240
|
<FormActions>
|
|
243
|
-
<Button
|
|
244
|
-
Back
|
|
245
|
-
</Button>
|
|
241
|
+
<Button onPress={() => setStep("contact")}>Back</Button>
|
|
246
242
|
<form.Subscribe selector={(state) => [state.canSubmit, state.isSubmitting]}>
|
|
247
243
|
{([canSubmit, isSubmitting]) => (
|
|
248
244
|
<Button action="submit" disabled={!canSubmit || isSubmitting}>
|
|
@@ -40,6 +40,22 @@ describe("Input.Button", () => {
|
|
|
40
40
|
expect(btn.contains(ring)).toBe(true);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
+
it("a bare string child is a LABEL, not an icon type to createElement", () => {
|
|
44
|
+
const result = renderWithProviders(
|
|
45
|
+
<Input size="$4">
|
|
46
|
+
<Input.Box size="$4">
|
|
47
|
+
<Input.Button size="$4" aria-label="cap">
|
|
48
|
+
Scan
|
|
49
|
+
</Input.Button>
|
|
50
|
+
</Input.Box>
|
|
51
|
+
</Input>,
|
|
52
|
+
);
|
|
53
|
+
const btn = result.container.querySelector("[aria-label='cap']") as HTMLElement;
|
|
54
|
+
expect(btn).not.toBeNull();
|
|
55
|
+
expect(btn.textContent).toContain("Scan");
|
|
56
|
+
expect(result.container.querySelector("scan")).toBeNull();
|
|
57
|
+
});
|
|
58
|
+
|
|
43
59
|
it("end-cap square is generated from the size recipe at every token", () => {
|
|
44
60
|
for (const token of SIZE_RECIPE_TOKENS) {
|
|
45
61
|
if (token === "$true") continue;
|
package/src/InputParts/index.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getFontSized } from "@tamagui/get-font-sized";
|
|
2
2
|
import type { SizeVariantSpreadFunction } from "@tamagui/web";
|
|
3
|
-
import { useEffect, useState, type ReactNode } from "react";
|
|
3
|
+
import { useCallback, useEffect, useState, type ReactNode } from "react";
|
|
4
4
|
import type { ComponentProps, Ref, RefObject } from "react";
|
|
5
5
|
import { Pressable as RNPressable } from "react-native";
|
|
6
6
|
import type {
|
|
@@ -1035,6 +1035,33 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
|
|
|
1035
1035
|
size: knobProps.controlIcon.width,
|
|
1036
1036
|
color: paint as never,
|
|
1037
1037
|
});
|
|
1038
|
+
// A string/number child is a LABEL, not an icon. `getThemedIcon` treats an
|
|
1039
|
+
// un-elemented child as a component TYPE and `createElement`s it, so "Scan"
|
|
1040
|
+
// becomes an invented `<scan>` element that paints nothing (MPO-208); a bare
|
|
1041
|
+
// string under the glyphRing View is the same category error on native.
|
|
1042
|
+
const textChild =
|
|
1043
|
+
typeof children === "string" || typeof children === "number" ? (
|
|
1044
|
+
<Text
|
|
1045
|
+
{...knobProps.controlType}
|
|
1046
|
+
fontFamily={knobProps.body.fontFamily}
|
|
1047
|
+
fontWeight={knobProps.body.fontWeight}
|
|
1048
|
+
color={paint as never}
|
|
1049
|
+
numberOfLines={1}
|
|
1050
|
+
userSelect="none"
|
|
1051
|
+
>
|
|
1052
|
+
{children}
|
|
1053
|
+
</Text>
|
|
1054
|
+
) : null;
|
|
1055
|
+
const decorativeRef = useCallback(
|
|
1056
|
+
(node: TamaguiElement | null) => {
|
|
1057
|
+
// Tamagui 2.7.6 Button stamps tabIndex=0 after consumer props.
|
|
1058
|
+
// Correct the host at hydration; decorative caps share the field stop.
|
|
1059
|
+
if (isWeb && node && "tabIndex" in node) node.tabIndex = tabIndexProp ?? -1;
|
|
1060
|
+
if (typeof ref === "function") ref(node);
|
|
1061
|
+
else if (ref) ref.current = node;
|
|
1062
|
+
},
|
|
1063
|
+
[ref, tabIndexProp],
|
|
1064
|
+
);
|
|
1038
1065
|
|
|
1039
1066
|
if (glyphRing) {
|
|
1040
1067
|
// A real tab stop must square off the token it was HANDED, not the
|
|
@@ -1068,7 +1095,7 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
|
|
|
1068
1095
|
alignItems="center"
|
|
1069
1096
|
justifyContent="center"
|
|
1070
1097
|
>
|
|
1071
|
-
{children}
|
|
1098
|
+
{textChild ?? children}
|
|
1072
1099
|
</View>
|
|
1073
1100
|
</InputGlyphButton>
|
|
1074
1101
|
);
|
|
@@ -1077,7 +1104,7 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
|
|
|
1077
1104
|
const square = knobProps.control.height;
|
|
1078
1105
|
return (
|
|
1079
1106
|
<InputButton
|
|
1080
|
-
ref={
|
|
1107
|
+
ref={decorativeRef}
|
|
1081
1108
|
size={size}
|
|
1082
1109
|
height={square}
|
|
1083
1110
|
width={square}
|
|
@@ -1091,7 +1118,7 @@ const InputButtonImpl = InputButton.styleable<{ glyphRing?: boolean }>((buttonPr
|
|
|
1091
1118
|
data-end-cap={square}
|
|
1092
1119
|
{...props}
|
|
1093
1120
|
>
|
|
1094
|
-
{getThemedIcon(children)}
|
|
1121
|
+
{textChild ?? getThemedIcon(children)}
|
|
1095
1122
|
</InputButton>
|
|
1096
1123
|
);
|
|
1097
1124
|
});
|
|
@@ -1166,9 +1193,8 @@ export const InputContainerFrame = styled(View, {
|
|
|
1166
1193
|
|
|
1167
1194
|
variants: {
|
|
1168
1195
|
size: {
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
}),
|
|
1196
|
+
// Size is shared with the child parts; layout spacing belongs to space.
|
|
1197
|
+
"...size": () => ({}),
|
|
1172
1198
|
},
|
|
1173
1199
|
color: {
|
|
1174
1200
|
"...color": () => ({}),
|
|
@@ -1194,6 +1220,7 @@ const InputContainerImpl = InputContainerFrame.styleable((props, forwardedRef) =
|
|
|
1194
1220
|
ref={forwardedRef}
|
|
1195
1221
|
size={knobProps.sizeToken}
|
|
1196
1222
|
{...knobProps.body}
|
|
1223
|
+
{...knobProps.gap}
|
|
1197
1224
|
// LC-06/LC-10 (UX-P12): inside a table cell the field root must adopt
|
|
1198
1225
|
// the cell width — the raw web <input> carries an intrinsic width that
|
|
1199
1226
|
// otherwise floors the whole column at ~200px and lays out past the
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createRef } from "react";
|
|
2
|
+
import { Preset } from "@multiplatform.one/theme";
|
|
3
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
4
|
+
import { cleanup } from "@testing-library/react";
|
|
5
|
+
import { afterEach, expect, it } from "vitest";
|
|
6
|
+
import { Input } from "./index";
|
|
7
|
+
|
|
8
|
+
afterEach(cleanup);
|
|
9
|
+
|
|
10
|
+
function measure(size: "small" | "medium", space: "small" | "large", gap?: number) {
|
|
11
|
+
const ref = createRef<HTMLElement>();
|
|
12
|
+
const { getByTestId } = renderWithProviders(
|
|
13
|
+
<Preset overrides={{ size, space }}>
|
|
14
|
+
<Input testID="root" ref={ref as never} {...(gap === undefined ? {} : { gap })}>
|
|
15
|
+
<Input.Label>Location</Input.Label>
|
|
16
|
+
<Input.Box>
|
|
17
|
+
<Input.Area placeholder="Location" />
|
|
18
|
+
</Input.Box>
|
|
19
|
+
</Input>
|
|
20
|
+
</Preset>,
|
|
21
|
+
);
|
|
22
|
+
const root = getByTestId("root");
|
|
23
|
+
expect(ref.current).toBe(root);
|
|
24
|
+
// Happy DOM leaves token-backed CSS gaps unresolved; browser coverage reads
|
|
25
|
+
// the actual pixels. Keep this test checking the rendered gap owner.
|
|
26
|
+
const value =
|
|
27
|
+
getComputedStyle(root).gap || [...root.classList].find((name) => name.startsWith("_gap-"));
|
|
28
|
+
expect(value).toBeTruthy();
|
|
29
|
+
cleanup();
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
it("lets space change the multi-slot layout gap at a fixed control size", () => {
|
|
34
|
+
expect(measure("medium", "small")).not.toBe(measure("medium", "large"));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("keeps the layout gap stable when only control size changes", () => {
|
|
38
|
+
expect(measure("small", "small")).toBe(measure("medium", "small"));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("preserves the consumer gap eject and forwarded root ref", () => {
|
|
42
|
+
expect(measure("medium", "large", 11)).toBe("11px");
|
|
43
|
+
});
|
package/src/Wheel/Wheel.spec.tsx
CHANGED
|
@@ -7,6 +7,22 @@ import { Wheel } from "./index";
|
|
|
7
7
|
afterEach(cleanup);
|
|
8
8
|
|
|
9
9
|
describe("Wheel contrast contract", () => {
|
|
10
|
+
it("uses the selected-text weight and keeps rounding on the selection band", () => {
|
|
11
|
+
renderWithProviders(
|
|
12
|
+
<Preset overrides={{ borderRadius: "full" }}>
|
|
13
|
+
<Wheel items={[1, 2, 3, 4, 5]} value={3} visibleItems={5} />
|
|
14
|
+
</Preset>,
|
|
15
|
+
);
|
|
16
|
+
const wheel = screen.getByTestId("wheel");
|
|
17
|
+
const selected = wheel.querySelector('[data-selected="true"]')?.firstElementChild;
|
|
18
|
+
expect(selected).toBeTruthy();
|
|
19
|
+
expect(["700", "bold"]).toContain(getComputedStyle(selected as Element).fontWeight);
|
|
20
|
+
expect(["", "0px"]).toContain(getComputedStyle(wheel).borderTopLeftRadius);
|
|
21
|
+
expect(getComputedStyle(screen.getByTestId("wheel-selection")).borderStartStartRadius).not.toBe(
|
|
22
|
+
"0px",
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
10
26
|
it("keeps inactive item text on the AA $color11 ramp (not opacity-dimmed)", () => {
|
|
11
27
|
renderWithProviders(
|
|
12
28
|
<Wheel items={[1, 2, 3, 4, 5]} value={3} onChange={() => {}} visibleItems={5} />,
|
package/src/Wheel/index.tsx
CHANGED
|
@@ -112,7 +112,7 @@ function ensureWheelFocusStyles() {
|
|
|
112
112
|
const style = document.createElement("style");
|
|
113
113
|
style.id = WHEEL_FOCUS_STYLE_ID;
|
|
114
114
|
style.textContent =
|
|
115
|
-
".mp1-wheel-wrapper:focus-visible { outline: 2px solid var(--outlineColor,
|
|
115
|
+
".mp1-wheel-wrapper:focus-visible { outline: 2px solid var(--outlineColor, var(--c-outlineColor, CanvasText)); outline-offset: -2px; }";
|
|
116
116
|
document.head.appendChild(style);
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -847,7 +847,7 @@ export function Wheel<T = string | number>({
|
|
|
847
847
|
<Text
|
|
848
848
|
{...knobProps.body}
|
|
849
849
|
fontSize={size}
|
|
850
|
-
fontWeight={isSelected && !disabled ? "
|
|
850
|
+
fontWeight={isSelected && !disabled ? "bold" : knobProps.textWeight.fontWeight}
|
|
851
851
|
color={itemColor(isSelected)}
|
|
852
852
|
numberOfLines={1}
|
|
853
853
|
ellipsizeMode="tail"
|
|
@@ -865,7 +865,7 @@ export function Wheel<T = string | number>({
|
|
|
865
865
|
width={flex ? "100%" : columnWidth}
|
|
866
866
|
minWidth={flex ? 0 : columnWidth}
|
|
867
867
|
flex={flex}
|
|
868
|
-
{
|
|
868
|
+
borderRadius={0}
|
|
869
869
|
data-testid="wheel"
|
|
870
870
|
data-disabled={disabled ? true : undefined}
|
|
871
871
|
aria-disabled={disabled || undefined}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four form LAYOUT stories must mount house field chrome, not a raw
|
|
3
|
+
* tamagui primitive.
|
|
4
|
+
*
|
|
5
|
+
* FieldLayout, FieldGroup, Fieldset and FormGrid paint no radius of their own —
|
|
6
|
+
* they are stacks, a grid and a legend. Whatever radius a probe reads off one
|
|
7
|
+
* of their stories belongs to the CONTROL the story chose to mount. A raw
|
|
8
|
+
* `Input` from "tamagui" consumes no knobs, so it pins one radius at every
|
|
9
|
+
* stop and the axis reads dead against a component that never had a say.
|
|
10
|
+
*
|
|
11
|
+
* The measurement here is therefore the STORY's, not the component's: walk the
|
|
12
|
+
* borderRadius knob and assert the control inside each story tracks it.
|
|
13
|
+
*
|
|
14
|
+
* Under jsdom the providers inject no CSS and the radius atom keeps its token
|
|
15
|
+
* reference (`_btlr-t-radius-4`) rather than resolving to `9px`, so this file
|
|
16
|
+
* gates the token ladder. The pixel ladder (0/5/9/16/50) and the dark scheme
|
|
17
|
+
* are measured for real by scripts/knob-axis-probe.mjs against a browser.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { cleanup } from "@testing-library/react";
|
|
21
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
22
|
+
import { Preset, type BorderRadius } from "@multiplatform.one/theme";
|
|
23
|
+
import type { ReactElement } from "react";
|
|
24
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
25
|
+
|
|
26
|
+
import * as fieldGroupStories from "./FieldGroup.stories";
|
|
27
|
+
import * as fieldLayoutStories from "./FieldLayout.stories";
|
|
28
|
+
import * as fieldsetStories from "./Fieldset.stories";
|
|
29
|
+
import * as formGridStories from "./FormGrid.stories";
|
|
30
|
+
|
|
31
|
+
afterEach(cleanup);
|
|
32
|
+
|
|
33
|
+
/** Knob stop -> radius token index, the `$N` the resolver hands the frame. */
|
|
34
|
+
const ladder: Record<BorderRadius, string> = {
|
|
35
|
+
none: "0",
|
|
36
|
+
small: "2",
|
|
37
|
+
medium: "4",
|
|
38
|
+
large: "6",
|
|
39
|
+
full: "12",
|
|
40
|
+
};
|
|
41
|
+
const stops = Object.keys(ladder) as BorderRadius[];
|
|
42
|
+
|
|
43
|
+
type StoryLike = { render?: (args: Record<string, unknown>) => ReactElement };
|
|
44
|
+
|
|
45
|
+
/** Every radius token present in the subtree, deduped — the probe's reading. */
|
|
46
|
+
function radiusTokens(container: HTMLElement): string[] {
|
|
47
|
+
const found = new Set<string>();
|
|
48
|
+
for (const el of container.querySelectorAll<HTMLElement>("*")) {
|
|
49
|
+
for (const cls of String(el.className || "").split(/\s+/)) {
|
|
50
|
+
const match = /^_btlr-t-radius-(\d+)$/.exec(cls);
|
|
51
|
+
if (match) found.add(match[1]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return [...found].sort();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function mountAt(story: StoryLike, meta: { args?: unknown }, stop: BorderRadius) {
|
|
58
|
+
if (!story.render) throw new Error("story has no render");
|
|
59
|
+
return renderWithProviders(
|
|
60
|
+
<Preset overrides={{ borderRadius: stop, elevation: "none" }}>
|
|
61
|
+
{story.render({ ...((meta.args ?? {}) as Record<string, unknown>) })}
|
|
62
|
+
</Preset>,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const family = [
|
|
67
|
+
{
|
|
68
|
+
name: "Forms/FieldLayout",
|
|
69
|
+
story: fieldLayoutStories.Basic as StoryLike,
|
|
70
|
+
meta: fieldLayoutStories.default,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "Forms/FieldGroup",
|
|
74
|
+
story: fieldGroupStories.Basic as StoryLike,
|
|
75
|
+
meta: fieldGroupStories.default,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "Forms/Fieldset",
|
|
79
|
+
story: fieldsetStories.Default as StoryLike,
|
|
80
|
+
meta: fieldsetStories.default,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "Forms/FormGrid",
|
|
84
|
+
story: formGridStories.Basic as StoryLike,
|
|
85
|
+
meta: formGridStories.default,
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
describe("form layout stories mount knob-consuming field chrome", () => {
|
|
90
|
+
for (const { name, story, meta } of family) {
|
|
91
|
+
describe(name, () => {
|
|
92
|
+
// A story that fails to render measures flat on every axis, which reads
|
|
93
|
+
// exactly like a dead knob. Prove there is a control before believing
|
|
94
|
+
// anything measured off it.
|
|
95
|
+
it("renders a text control at all", () => {
|
|
96
|
+
const { container } = mountAt(story, meta as { args?: unknown }, "medium");
|
|
97
|
+
expect(container.querySelectorAll("input").length).toBeGreaterThan(0);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
for (const stop of stops) {
|
|
101
|
+
it(`takes radius token $${ladder[stop]} at borderRadius:${stop}`, () => {
|
|
102
|
+
const { container } = mountAt(story, meta as { args?: unknown }, stop);
|
|
103
|
+
expect(radiusTokens(container)).toContain(ladder[stop]);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
it("moves across all five stops instead of pinning one radius", () => {
|
|
108
|
+
const signatures = stops.map((stop) => {
|
|
109
|
+
const result = mountAt(story, meta as { args?: unknown }, stop);
|
|
110
|
+
const tokens = JSON.stringify(radiusTokens(result.container));
|
|
111
|
+
cleanup();
|
|
112
|
+
return tokens;
|
|
113
|
+
});
|
|
114
|
+
expect(new Set(signatures).size).toBe(stops.length);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
package/src/fieldLayout.spec.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
2
2
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
3
3
|
import { Preset } from "@multiplatform.one/theme";
|
|
4
4
|
import { Input as TamaguiInput } from "tamagui";
|
|
5
|
-
import { FieldLayout } from "./fieldLayout";
|
|
5
|
+
import { FieldLayout, useFieldDescribedBy } from "./fieldLayout";
|
|
6
6
|
import { __resetDevWarnSeen } from "./shared/devWarn";
|
|
7
7
|
|
|
8
8
|
function classIncludes(container: HTMLElement, fragment: string): boolean {
|
|
@@ -188,6 +188,47 @@ describe("FieldLayout error precedence (Axiom 5 eject-last)", () => {
|
|
|
188
188
|
});
|
|
189
189
|
});
|
|
190
190
|
|
|
191
|
+
describe("FieldLayout message-before-control anatomy", () => {
|
|
192
|
+
function Control() {
|
|
193
|
+
return <input id="ordered" aria-describedby={useFieldDescribedBy()} />;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
for (const mode of ["top", "side", "compact"] as const) {
|
|
197
|
+
it(`${mode}: helper and replacement error precede the control and describe only the rendered slot`, () => {
|
|
198
|
+
const renderField = (error?: string) => (
|
|
199
|
+
<Preset overrides={{ fieldLabelPlacement: mode === "side" ? "side" : "top" }}>
|
|
200
|
+
<FieldLayout
|
|
201
|
+
id="ordered"
|
|
202
|
+
label="Email"
|
|
203
|
+
compactSpacing={mode === "compact"}
|
|
204
|
+
helperText="Use your work address"
|
|
205
|
+
error={error}
|
|
206
|
+
>
|
|
207
|
+
<Control />
|
|
208
|
+
</FieldLayout>
|
|
209
|
+
</Preset>
|
|
210
|
+
);
|
|
211
|
+
const result = renderWithProviders(renderField());
|
|
212
|
+
const assertSlot = (id: string, text: string) => {
|
|
213
|
+
const input = result.container.querySelector("input")!;
|
|
214
|
+
const message = result.container.querySelector(`#${id}`)!;
|
|
215
|
+
expect(message.textContent).toBe(text);
|
|
216
|
+
expect(
|
|
217
|
+
message.compareDocumentPosition(input) & Node.DOCUMENT_POSITION_FOLLOWING,
|
|
218
|
+
).toBeTruthy();
|
|
219
|
+
expect(input.getAttribute("aria-describedby")).toBe(id);
|
|
220
|
+
expect(
|
|
221
|
+
result.container.querySelectorAll("[id$='-description'], [id$='-error']"),
|
|
222
|
+
).toHaveLength(1);
|
|
223
|
+
};
|
|
224
|
+
assertSlot("ordered-description", "Use your work address");
|
|
225
|
+
result.rerender(renderField("Enter an email address"));
|
|
226
|
+
assertSlot("ordered-error", "Enter an email address");
|
|
227
|
+
expect(result.container.textContent).not.toContain("Use your work address");
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
191
232
|
describe("FieldLayout banned-error-word DEV warn", () => {
|
|
192
233
|
let warnSpy: ReturnType<typeof vi.spyOn>;
|
|
193
234
|
|
package/src/fieldLayout.tsx
CHANGED
|
@@ -218,13 +218,13 @@ export function FieldLayout({
|
|
|
218
218
|
...(width !== undefined ? { width } : {}),
|
|
219
219
|
};
|
|
220
220
|
|
|
221
|
-
const describedBy =
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
const describedBy = id
|
|
222
|
+
? errorMessage
|
|
223
|
+
? `${id}-error`
|
|
224
|
+
: helperText
|
|
225
|
+
? `${id}-description`
|
|
226
|
+
: undefined
|
|
227
|
+
: undefined;
|
|
228
228
|
|
|
229
229
|
const a11yLabel = typeof label === "string" ? `${label}${requiredSuffix}` : ariaLabel;
|
|
230
230
|
const a11yDescription = errorMessage ?? helperText;
|
|
@@ -293,9 +293,9 @@ export function FieldLayout({
|
|
|
293
293
|
|
|
294
294
|
const controlColumn = (
|
|
295
295
|
<YStack flex={sideLabel ? 1 : undefined} {...gapProps}>
|
|
296
|
-
{children}
|
|
297
296
|
{helperNode}
|
|
298
297
|
{errorNode}
|
|
298
|
+
{children}
|
|
299
299
|
</YStack>
|
|
300
300
|
);
|
|
301
301
|
|
|
@@ -330,9 +330,9 @@ export function FieldLayout({
|
|
|
330
330
|
) : (
|
|
331
331
|
<>
|
|
332
332
|
{labelNode}
|
|
333
|
-
{children}
|
|
334
333
|
{helperNode}
|
|
335
334
|
{errorNode}
|
|
335
|
+
{children}
|
|
336
336
|
</>
|
|
337
337
|
)}
|
|
338
338
|
</YStack>
|
|
@@ -102,6 +102,8 @@ describe("Barcode", () => {
|
|
|
102
102
|
const button = result.container.querySelector("[aria-label='Scan barcode']");
|
|
103
103
|
expect(button).not.toBeNull();
|
|
104
104
|
expect(button?.textContent).toContain("Scan");
|
|
105
|
+
expect(button?.querySelector("scan")).toBeNull();
|
|
106
|
+
expect(result.container.querySelector("scan")).toBeNull();
|
|
105
107
|
});
|
|
106
108
|
|
|
107
109
|
it("renders readOnly — hides scan button", () => {
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
import { cleanup } from "@testing-library/react";
|
|
12
12
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
13
13
|
import { afterEach, describe, expect, it } from "vitest";
|
|
14
|
+
import { createRef } from "react";
|
|
15
|
+
import { FieldLayout } from "../../fieldLayout";
|
|
14
16
|
import { CheckboxFieldFrame } from "./CheckboxFieldFrame";
|
|
15
17
|
|
|
16
18
|
afterEach(cleanup);
|
|
@@ -31,6 +33,22 @@ function frame(container: HTMLElement): HTMLElement {
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
describe("CheckboxFieldFrame", () => {
|
|
36
|
+
it("links the rendered field message, forwards its ref, and preserves an explicit description", () => {
|
|
37
|
+
const ref = createRef<any>();
|
|
38
|
+
const fixture = (override?: { "aria-describedby": string | undefined }) => (
|
|
39
|
+
<FieldLayout id="consent" helperText="Read the terms" error="Accept the terms">
|
|
40
|
+
<CheckboxFieldFrame id="consent" checked={false} ref={ref} {...override} />
|
|
41
|
+
</FieldLayout>
|
|
42
|
+
);
|
|
43
|
+
const result = renderWithProviders(fixture());
|
|
44
|
+
expect(frame(result.container).getAttribute("aria-describedby")).toBe("consent-error");
|
|
45
|
+
expect(ref.current).toBe(frame(result.container));
|
|
46
|
+
result.rerender(fixture({ "aria-describedby": "consumer-description" }));
|
|
47
|
+
expect(frame(result.container).getAttribute("aria-describedby")).toBe("consumer-description");
|
|
48
|
+
result.rerender(fixture({ "aria-describedby": undefined }));
|
|
49
|
+
expect(frame(result.container).getAttribute("aria-describedby")).toBeNull();
|
|
50
|
+
});
|
|
51
|
+
|
|
34
52
|
it("still renders a real role=checkbox, so the styling never costs the semantics", () => {
|
|
35
53
|
const { container } = renderWithProviders(<CheckboxFieldFrame checked={false} />);
|
|
36
54
|
expect(frame(container)).toBeTruthy();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Checkbox as TamaguiCheckbox, styled } from "tamagui";
|
|
2
|
+
import { useFieldDescribedBy } from "../../fieldLayout";
|
|
2
3
|
|
|
3
4
|
/** Hit-target frame. The painted box is CheckboxGlyphBox (LC-71). */
|
|
4
|
-
|
|
5
|
+
const CheckboxFieldFrameBase = styled(TamaguiCheckbox, {
|
|
5
6
|
backgroundColor: "transparent",
|
|
6
7
|
borderColor: "transparent",
|
|
7
8
|
borderWidth: 0,
|
|
@@ -21,3 +22,7 @@ export const CheckboxFieldFrame = styled(TamaguiCheckbox, {
|
|
|
21
22
|
},
|
|
22
23
|
activeStyle: { backgroundColor: "transparent", borderColor: "transparent" },
|
|
23
24
|
});
|
|
25
|
+
|
|
26
|
+
export const CheckboxFieldFrame = CheckboxFieldFrameBase.styleable((props, ref) => (
|
|
27
|
+
<CheckboxFieldFrameBase aria-describedby={useFieldDescribedBy()} {...props} ref={ref} />
|
|
28
|
+
));
|