@multiplatform.one/forms 7.46.0 → 7.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Button/index.cjs +14 -3
- package/dist/cjs/Button/index.native.js +18 -7
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/ErrorSummary.cjs +1 -1
- package/dist/cjs/ErrorSummary.native.js +1 -1
- package/dist/cjs/ErrorSummary.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/PanelPortal.cjs +1 -1
- package/dist/cjs/FloatingPanel/index.cjs +13 -4
- package/dist/cjs/FloatingPanel/index.native.js +9 -2
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/trailingAction.cjs +59 -0
- package/dist/cjs/FloatingPanel/trailingAction.native.js +64 -0
- package/dist/cjs/FloatingPanel/trailingAction.native.js.map +1 -0
- package/dist/cjs/FormGrid.cjs +1 -0
- package/dist/cjs/FormGrid.native.js +1 -0
- package/dist/cjs/FormGrid.native.js.map +1 -1
- package/dist/cjs/InputParts/PasswordReveal.cjs +96 -0
- package/dist/cjs/InputParts/PasswordReveal.native.js +104 -0
- package/dist/cjs/InputParts/PasswordReveal.native.js.map +1 -0
- package/dist/cjs/InputParts/index.cjs +95 -5
- package/dist/cjs/InputParts/index.native.js +99 -5
- package/dist/cjs/InputParts/index.native.js.map +1 -1
- package/dist/cjs/fields/ColorPicker/index.cjs +8 -17
- package/dist/cjs/fields/ColorPicker/index.native.js +9 -18
- package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/index.cjs +28 -44
- package/dist/cjs/fields/Combobox/index.native.js +30 -45
- package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/Calendar.cjs +3 -4
- package/dist/cjs/fields/DatePicker/Calendar.native.js +3 -4
- package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/parts.cjs +5 -9
- package/dist/cjs/fields/DatePicker/parts.native.js +5 -9
- package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/Duration/durationMath.cjs +1 -1
- package/dist/cjs/fields/Duration/durationMath.native.js +1 -1
- package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/cjs/fields/Duration/index.cjs +100 -90
- package/dist/cjs/fields/Duration/index.native.js +108 -98
- package/dist/cjs/fields/Duration/index.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload/index.cjs +134 -24
- package/dist/cjs/fields/FileUpload/index.native.js +149 -34
- package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/GeolocationMap.cjs +2 -1
- package/dist/cjs/fields/Geolocation/GeolocationMap.native.js +3 -2
- package/dist/cjs/fields/Geolocation/GeolocationMap.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/index.cjs +10 -8
- package/dist/cjs/fields/Geolocation/index.native.js +10 -8
- package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
- package/dist/cjs/fields/Icon/index.cjs +6 -13
- package/dist/cjs/fields/Icon/index.native.js +6 -13
- package/dist/cjs/fields/Icon/index.native.js.map +1 -1
- package/dist/cjs/fields/ImageField/index.cjs +5 -5
- package/dist/cjs/fields/ImageField/index.native.js +5 -5
- package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
- package/dist/cjs/fields/Input/index.cjs +27 -21
- package/dist/cjs/fields/Input/index.native.js +28 -21
- package/dist/cjs/fields/Input/index.native.js.map +1 -1
- package/dist/cjs/fields/MentionInput/index.cjs +7 -8
- package/dist/cjs/fields/MentionInput/index.native.js +7 -8
- package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
- package/dist/cjs/fields/OTPInput/index.cjs +1 -1
- package/dist/cjs/fields/OTPInput/index.native.js +1 -1
- package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
- package/dist/cjs/fields/PhoneInput/index.cjs +3 -3
- package/dist/cjs/fields/PhoneInput/index.native.js +3 -3
- package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/cjs/fields/RadioGroup/index.cjs +1 -0
- package/dist/cjs/fields/RadioGroup/index.native.js +1 -0
- package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/cjs/fields/SearchInput/index.cjs +4 -48
- package/dist/cjs/fields/SearchInput/index.native.js +4 -46
- package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
- package/dist/cjs/fields/Select/index.cjs +14 -12
- package/dist/cjs/fields/Select/index.native.js +14 -12
- package/dist/cjs/fields/Select/index.native.js.map +1 -1
- package/dist/cjs/fields/Signature/index.cjs +1 -1
- package/dist/cjs/fields/Signature/index.native.js +1 -1
- package/dist/cjs/fields/Signature/index.native.js.map +1 -1
- package/dist/cjs/fields/Slider/index.cjs +1 -1
- package/dist/cjs/fields/Slider/index.native.js +1 -1
- package/dist/cjs/fields/Slider/index.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/parts.cjs +5 -9
- package/dist/cjs/fields/TimePicker/parts.native.js +5 -9
- package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/TimeRangeScrubber/index.cjs +14 -9
- package/dist/cjs/fields/TimeRangeScrubber/index.native.js +14 -9
- package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +1 -1
- package/dist/cjs/fields/ToggleGroup/index.cjs +1 -1
- package/dist/cjs/fields/ToggleGroup/index.native.js +1 -1
- package/dist/cjs/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +5 -5
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +5 -5
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/cjs/hooks/useFocusManagement.cjs +3 -2
- package/dist/cjs/hooks/useFocusManagement.native.js +3 -2
- package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
- package/dist/cjs/index.cjs +7 -0
- package/dist/cjs/index.native.js +7 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/shared/focusManagement.cjs +1 -1
- package/dist/cjs/shared/focusManagement.native.js +1 -1
- package/dist/cjs/shared/panelPortal.cjs +1 -1
- package/dist/cjs/shared/panelPortal.native.js +1 -1
- package/dist/cjs/shared/panelPortal.native.js.map +1 -1
- package/dist/cjs/shared/useDragScroll.cjs +2 -2
- package/dist/cjs/shared/useDragScroll.native.js +2 -2
- package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
- package/dist/esm/Button/index.mjs +17 -6
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +21 -10
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/ErrorSummary.mjs +2 -2
- package/dist/esm/ErrorSummary.mjs.map +1 -1
- package/dist/esm/ErrorSummary.native.js +2 -2
- package/dist/esm/ErrorSummary.native.js.map +1 -1
- package/dist/esm/FloatingPanel/PanelPortal.mjs +1 -1
- package/dist/esm/FloatingPanel/PanelPortal.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.mjs +13 -4
- package/dist/esm/FloatingPanel/index.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +9 -2
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/trailingAction.mjs +33 -0
- package/dist/esm/FloatingPanel/trailingAction.mjs.map +1 -0
- package/dist/esm/FloatingPanel/trailingAction.native.js +35 -0
- package/dist/esm/FloatingPanel/trailingAction.native.js.map +1 -0
- package/dist/esm/FormGrid.mjs +1 -0
- package/dist/esm/FormGrid.mjs.map +1 -1
- package/dist/esm/FormGrid.native.js +1 -0
- package/dist/esm/FormGrid.native.js.map +1 -1
- package/dist/esm/InputParts/PasswordReveal.mjs +68 -0
- package/dist/esm/InputParts/PasswordReveal.mjs.map +1 -0
- package/dist/esm/InputParts/PasswordReveal.native.js +73 -0
- package/dist/esm/InputParts/PasswordReveal.native.js.map +1 -0
- package/dist/esm/InputParts/index.mjs +97 -8
- package/dist/esm/InputParts/index.mjs.map +1 -1
- package/dist/esm/InputParts/index.native.js +101 -8
- package/dist/esm/InputParts/index.native.js.map +1 -1
- package/dist/esm/fields/ColorPicker/index.mjs +8 -17
- package/dist/esm/fields/ColorPicker/index.mjs.map +1 -1
- package/dist/esm/fields/ColorPicker/index.native.js +9 -18
- package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
- package/dist/esm/fields/Combobox/index.mjs +29 -45
- package/dist/esm/fields/Combobox/index.mjs.map +1 -1
- package/dist/esm/fields/Combobox/index.native.js +31 -46
- package/dist/esm/fields/Combobox/index.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/Calendar.mjs +4 -5
- package/dist/esm/fields/DatePicker/Calendar.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/Calendar.native.js +4 -5
- package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/parts.mjs +5 -9
- package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/parts.native.js +5 -9
- package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/esm/fields/Duration/durationMath.mjs +1 -1
- package/dist/esm/fields/Duration/durationMath.mjs.map +1 -1
- package/dist/esm/fields/Duration/durationMath.native.js +1 -1
- package/dist/esm/fields/Duration/index.mjs +100 -90
- package/dist/esm/fields/Duration/index.mjs.map +1 -1
- package/dist/esm/fields/Duration/index.native.js +108 -98
- package/dist/esm/fields/Duration/index.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/index.mjs +135 -25
- package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
- package/dist/esm/fields/FileUpload/index.native.js +150 -35
- package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/GeolocationMap.mjs +2 -1
- package/dist/esm/fields/Geolocation/GeolocationMap.mjs.map +1 -1
- package/dist/esm/fields/Geolocation/GeolocationMap.native.js +2 -1
- package/dist/esm/fields/Geolocation/GeolocationMap.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/index.mjs +13 -11
- package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
- package/dist/esm/fields/Geolocation/index.native.js +13 -11
- package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
- package/dist/esm/fields/Icon/index.mjs +8 -15
- package/dist/esm/fields/Icon/index.mjs.map +1 -1
- package/dist/esm/fields/Icon/index.native.js +8 -15
- package/dist/esm/fields/Icon/index.native.js.map +1 -1
- package/dist/esm/fields/ImageField/index.mjs +7 -7
- package/dist/esm/fields/ImageField/index.mjs.map +1 -1
- package/dist/esm/fields/ImageField/index.native.js +7 -7
- package/dist/esm/fields/ImageField/index.native.js.map +1 -1
- package/dist/esm/fields/Input/index.mjs +28 -22
- package/dist/esm/fields/Input/index.mjs.map +1 -1
- package/dist/esm/fields/Input/index.native.js +29 -22
- package/dist/esm/fields/Input/index.native.js.map +1 -1
- package/dist/esm/fields/MentionInput/index.mjs +13 -14
- package/dist/esm/fields/MentionInput/index.mjs.map +1 -1
- package/dist/esm/fields/MentionInput/index.native.js +13 -14
- package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
- package/dist/esm/fields/OTPInput/index.mjs +2 -2
- package/dist/esm/fields/OTPInput/index.mjs.map +1 -1
- package/dist/esm/fields/OTPInput/index.native.js +2 -2
- package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/index.mjs +5 -5
- package/dist/esm/fields/PhoneInput/index.mjs.map +1 -1
- package/dist/esm/fields/PhoneInput/index.native.js +5 -5
- package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/esm/fields/RadioGroup/index.mjs +1 -0
- package/dist/esm/fields/RadioGroup/index.mjs.map +1 -1
- package/dist/esm/fields/RadioGroup/index.native.js +1 -0
- package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/esm/fields/SearchInput/index.mjs +5 -49
- package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
- package/dist/esm/fields/SearchInput/index.native.js +5 -47
- package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
- package/dist/esm/fields/Select/index.mjs +15 -13
- package/dist/esm/fields/Select/index.mjs.map +1 -1
- package/dist/esm/fields/Select/index.native.js +15 -13
- package/dist/esm/fields/Select/index.native.js.map +1 -1
- package/dist/esm/fields/Signature/index.mjs +2 -2
- package/dist/esm/fields/Signature/index.mjs.map +1 -1
- package/dist/esm/fields/Signature/index.native.js +2 -2
- package/dist/esm/fields/Signature/index.native.js.map +1 -1
- package/dist/esm/fields/Slider/index.mjs +2 -2
- package/dist/esm/fields/Slider/index.mjs.map +1 -1
- package/dist/esm/fields/Slider/index.native.js +2 -2
- package/dist/esm/fields/Slider/index.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/parts.mjs +5 -9
- package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
- package/dist/esm/fields/TimePicker/parts.native.js +5 -9
- package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/esm/fields/TimeRangeScrubber/index.mjs +20 -15
- package/dist/esm/fields/TimeRangeScrubber/index.mjs.map +1 -1
- package/dist/esm/fields/TimeRangeScrubber/index.native.js +20 -15
- package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
- package/dist/esm/fields/ToggleGroup/index.mjs +3 -3
- package/dist/esm/fields/ToggleGroup/index.mjs.map +1 -1
- package/dist/esm/fields/ToggleGroup/index.native.js +3 -3
- package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +2 -2
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/esm/hooks/useFocusManagement.mjs +3 -2
- package/dist/esm/hooks/useFocusManagement.mjs.map +1 -1
- package/dist/esm/hooks/useFocusManagement.native.js +3 -2
- package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +3 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/shared/focusManagement.mjs +1 -1
- package/dist/esm/shared/focusManagement.mjs.map +1 -1
- package/dist/esm/shared/focusManagement.native.js +1 -1
- package/dist/esm/shared/panelPortal.mjs +1 -1
- package/dist/esm/shared/panelPortal.mjs.map +1 -1
- package/dist/esm/shared/panelPortal.native.js +1 -1
- package/dist/esm/shared/panelPortal.native.js.map +1 -1
- package/dist/esm/shared/useDragScroll.mjs +2 -2
- package/dist/esm/shared/useDragScroll.mjs.map +1 -1
- package/dist/esm/shared/useDragScroll.native.js +2 -2
- package/dist/esm/shared/useDragScroll.native.js.map +1 -1
- package/dist/jsx/Button/index.mjs +17 -6
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +18 -7
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/ErrorSummary.mjs +2 -2
- package/dist/jsx/ErrorSummary.mjs.map +1 -1
- package/dist/jsx/ErrorSummary.native.js +1 -1
- package/dist/jsx/ErrorSummary.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/PanelPortal.mjs +1 -1
- package/dist/jsx/FloatingPanel/PanelPortal.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.mjs +13 -4
- package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +9 -2
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/trailingAction.mjs +33 -0
- package/dist/jsx/FloatingPanel/trailingAction.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/trailingAction.native.js +64 -0
- package/dist/jsx/FloatingPanel/trailingAction.native.js.map +1 -0
- package/dist/jsx/FormGrid.mjs +1 -0
- package/dist/jsx/FormGrid.mjs.map +1 -1
- package/dist/jsx/FormGrid.native.js +1 -0
- package/dist/jsx/FormGrid.native.js.map +1 -1
- package/dist/jsx/InputParts/PasswordReveal.mjs +68 -0
- package/dist/jsx/InputParts/PasswordReveal.mjs.map +1 -0
- package/dist/jsx/InputParts/PasswordReveal.native.js +104 -0
- package/dist/jsx/InputParts/PasswordReveal.native.js.map +1 -0
- package/dist/jsx/InputParts/index.mjs +97 -8
- package/dist/jsx/InputParts/index.mjs.map +1 -1
- package/dist/jsx/InputParts/index.native.js +99 -5
- package/dist/jsx/InputParts/index.native.js.map +1 -1
- package/dist/jsx/fields/ColorPicker/index.mjs +8 -17
- package/dist/jsx/fields/ColorPicker/index.mjs.map +1 -1
- package/dist/jsx/fields/ColorPicker/index.native.js +9 -18
- package/dist/jsx/fields/ColorPicker/index.native.js.map +1 -1
- package/dist/jsx/fields/Combobox/index.mjs +29 -45
- package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
- package/dist/jsx/fields/Combobox/index.native.js +30 -45
- package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/Calendar.mjs +4 -5
- package/dist/jsx/fields/DatePicker/Calendar.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/Calendar.native.js +3 -4
- package/dist/jsx/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/parts.mjs +5 -9
- package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/parts.native.js +5 -9
- package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/jsx/fields/Duration/durationMath.mjs +1 -1
- package/dist/jsx/fields/Duration/durationMath.mjs.map +1 -1
- package/dist/jsx/fields/Duration/durationMath.native.js +1 -1
- package/dist/jsx/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/jsx/fields/Duration/index.mjs +100 -90
- package/dist/jsx/fields/Duration/index.mjs.map +1 -1
- package/dist/jsx/fields/Duration/index.native.js +108 -98
- package/dist/jsx/fields/Duration/index.native.js.map +1 -1
- package/dist/jsx/fields/FileUpload/index.mjs +135 -25
- package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
- package/dist/jsx/fields/FileUpload/index.native.js +149 -34
- package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/GeolocationMap.mjs +2 -1
- package/dist/jsx/fields/Geolocation/GeolocationMap.mjs.map +1 -1
- package/dist/jsx/fields/Geolocation/GeolocationMap.native.js +3 -2
- package/dist/jsx/fields/Geolocation/GeolocationMap.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/index.mjs +13 -11
- package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
- package/dist/jsx/fields/Geolocation/index.native.js +10 -8
- package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
- package/dist/jsx/fields/Icon/index.mjs +8 -15
- package/dist/jsx/fields/Icon/index.mjs.map +1 -1
- package/dist/jsx/fields/Icon/index.native.js +6 -13
- package/dist/jsx/fields/Icon/index.native.js.map +1 -1
- package/dist/jsx/fields/ImageField/index.mjs +7 -7
- package/dist/jsx/fields/ImageField/index.mjs.map +1 -1
- package/dist/jsx/fields/ImageField/index.native.js +5 -5
- package/dist/jsx/fields/ImageField/index.native.js.map +1 -1
- package/dist/jsx/fields/Input/index.mjs +28 -22
- package/dist/jsx/fields/Input/index.mjs.map +1 -1
- package/dist/jsx/fields/Input/index.native.js +28 -21
- package/dist/jsx/fields/Input/index.native.js.map +1 -1
- package/dist/jsx/fields/MentionInput/index.mjs +13 -14
- package/dist/jsx/fields/MentionInput/index.mjs.map +1 -1
- package/dist/jsx/fields/MentionInput/index.native.js +7 -8
- package/dist/jsx/fields/MentionInput/index.native.js.map +1 -1
- package/dist/jsx/fields/OTPInput/index.mjs +2 -2
- package/dist/jsx/fields/OTPInput/index.mjs.map +1 -1
- package/dist/jsx/fields/OTPInput/index.native.js +1 -1
- package/dist/jsx/fields/OTPInput/index.native.js.map +1 -1
- package/dist/jsx/fields/PhoneInput/index.mjs +5 -5
- package/dist/jsx/fields/PhoneInput/index.mjs.map +1 -1
- package/dist/jsx/fields/PhoneInput/index.native.js +3 -3
- package/dist/jsx/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/jsx/fields/RadioGroup/index.mjs +1 -0
- package/dist/jsx/fields/RadioGroup/index.mjs.map +1 -1
- package/dist/jsx/fields/RadioGroup/index.native.js +1 -0
- package/dist/jsx/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/jsx/fields/SearchInput/index.mjs +5 -49
- package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
- package/dist/jsx/fields/SearchInput/index.native.js +4 -46
- package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
- package/dist/jsx/fields/Select/index.mjs +15 -13
- package/dist/jsx/fields/Select/index.mjs.map +1 -1
- package/dist/jsx/fields/Select/index.native.js +14 -12
- package/dist/jsx/fields/Select/index.native.js.map +1 -1
- package/dist/jsx/fields/Signature/index.mjs +2 -2
- package/dist/jsx/fields/Signature/index.mjs.map +1 -1
- package/dist/jsx/fields/Signature/index.native.js +1 -1
- package/dist/jsx/fields/Signature/index.native.js.map +1 -1
- package/dist/jsx/fields/Slider/index.mjs +2 -2
- package/dist/jsx/fields/Slider/index.mjs.map +1 -1
- package/dist/jsx/fields/Slider/index.native.js +1 -1
- package/dist/jsx/fields/Slider/index.native.js.map +1 -1
- package/dist/jsx/fields/TimePicker/parts.mjs +5 -9
- package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
- package/dist/jsx/fields/TimePicker/parts.native.js +5 -9
- package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/jsx/fields/TimeRangeScrubber/index.mjs +20 -15
- package/dist/jsx/fields/TimeRangeScrubber/index.mjs.map +1 -1
- package/dist/jsx/fields/TimeRangeScrubber/index.native.js +14 -9
- package/dist/jsx/fields/TimeRangeScrubber/index.native.js.map +1 -1
- package/dist/jsx/fields/ToggleGroup/index.mjs +3 -3
- package/dist/jsx/fields/ToggleGroup/index.mjs.map +1 -1
- package/dist/jsx/fields/ToggleGroup/index.native.js +1 -1
- package/dist/jsx/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +2 -2
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +5 -5
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/jsx/hooks/useFocusManagement.mjs +3 -2
- package/dist/jsx/hooks/useFocusManagement.mjs.map +1 -1
- package/dist/jsx/hooks/useFocusManagement.native.js +3 -2
- package/dist/jsx/hooks/useFocusManagement.native.js.map +1 -1
- package/dist/jsx/index.js +3 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +3 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +7 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/focusManagement.mjs +1 -1
- package/dist/jsx/shared/focusManagement.mjs.map +1 -1
- package/dist/jsx/shared/focusManagement.native.js +1 -1
- package/dist/jsx/shared/focusManagement.native.js.map +1 -1
- package/dist/jsx/shared/panelPortal.mjs +1 -1
- package/dist/jsx/shared/panelPortal.mjs.map +1 -1
- package/dist/jsx/shared/panelPortal.native.js +1 -1
- package/dist/jsx/shared/panelPortal.native.js.map +1 -1
- package/dist/jsx/shared/useDragScroll.mjs +2 -2
- package/dist/jsx/shared/useDragScroll.mjs.map +1 -1
- package/dist/jsx/shared/useDragScroll.native.js +2 -2
- package/dist/jsx/shared/useDragScroll.native.js.map +1 -1
- package/package.json +8 -8
- package/src/AdaptivePopup/AdaptivePopup.stories.tsx +2 -1
- package/src/Button/Button.borderLadder.spec.tsx +32 -7
- package/src/Button/Button.edge.spec.tsx +68 -0
- package/src/Button/Button.stories.tsx +2 -1
- package/src/Button/index.tsx +37 -11
- package/src/Chip/Chip.stories.tsx +2 -1
- package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +2 -1
- package/src/ContextualSaveBar/UnsavedChangesDialog.stories.tsx +2 -1
- package/src/ControlGroup/ControlGroup.stories.tsx +2 -1
- package/src/DescriptionList/DescriptionList.stories.tsx +2 -1
- package/src/ErrorSummary.stories.tsx +2 -1
- package/src/ErrorSummary.tsx +2 -2
- package/src/FieldDisplay/FieldDisplay.stories.tsx +2 -1
- package/src/FieldLayout.stories.tsx +2 -2
- package/src/FloatingPanel/FloatingPanel.stories.tsx +2 -2
- package/src/FloatingPanel/PanelPortal.tsx +1 -0
- package/src/FloatingPanel/index.native.tsx +4 -2
- package/src/FloatingPanel/index.tsx +14 -4
- package/src/FloatingPanel/trailingAction.tsx +37 -0
- package/src/Form/Form.stories.tsx +2 -1
- package/src/FormGrid.stories.tsx +2 -1
- package/src/FormGrid.tsx +1 -0
- package/src/FormsIntegration.stories.tsx +4 -18
- package/src/InputParts/InputParts.stories.tsx +11 -11
- package/src/InputParts/PasswordReveal.tsx +94 -0
- package/src/InputParts/index.tsx +144 -2
- package/src/InputParts/inputPartsStories.spec.tsx +3 -1
- package/src/Skeleton/Skeleton.stories.tsx +2 -2
- package/src/Spinner/Spinner.stories.tsx +2 -2
- package/src/Wheel/Wheel.stories.tsx +2 -2
- package/src/fieldTrailingAction.spec.tsx +188 -0
- package/src/fields/Barcode/Barcode.stories.tsx +2 -1
- package/src/fields/Barcode/BarcodePreview.stories.tsx +2 -1
- package/src/fields/Checkbox/Checkbox.stories.tsx +3 -1
- package/src/fields/Checkbox/CheckboxGroup.stories.tsx +2 -2
- package/src/fields/Checkbox/Checkboxes.stories.tsx +2 -1
- package/src/fields/ColorPicker/PresetSwatches.stories.tsx +2 -1
- package/src/fields/ColorPicker/index.tsx +6 -12
- package/src/fields/Combobox/Combobox.stories.tsx +2 -1
- package/src/fields/Combobox/index.tsx +39 -41
- package/src/fields/DatePicker/Calendar.stories.tsx +2 -1
- package/src/fields/DatePicker/Calendar.tsx +4 -5
- package/src/fields/DatePicker/DatePicker.spec.tsx +2 -2
- package/src/fields/DatePicker/DatePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/DateRangePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/DatetimePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/MonthPicker.stories.tsx +2 -1
- package/src/fields/DatePicker/MultiDatePicker.spec.tsx +1 -1
- package/src/fields/DatePicker/MultiDatePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/parts.tsx +6 -10
- package/src/fields/Duration/Duration.spec.tsx +25 -1
- package/src/fields/Duration/Duration.stories.tsx +6 -1
- package/src/fields/Duration/durationMath.spec.ts +2 -2
- package/src/fields/Duration/durationMath.ts +1 -1
- package/src/fields/Duration/index.tsx +91 -70
- package/src/fields/FileUpload/FileUpload.spec.tsx +86 -3
- package/src/fields/FileUpload/FileUpload.stories.tsx +15 -0
- package/src/fields/FileUpload/index.tsx +170 -50
- package/src/fields/Geolocation/Geolocation.stories.tsx +2 -1
- package/src/fields/Geolocation/GeolocationMap.native.tsx +2 -1
- package/src/fields/Geolocation/GeolocationMap.tsx +2 -1
- package/src/fields/Geolocation/index.tsx +39 -16
- package/src/fields/Icon/index.tsx +9 -15
- package/src/fields/ImageField/index.tsx +9 -8
- package/src/fields/Input/Input.stories.tsx +39 -1
- package/src/fields/Input/index.tsx +45 -25
- package/src/fields/MentionInput/index.tsx +17 -18
- package/src/fields/OTPInput/OtpInput.stories.tsx +2 -1
- package/src/fields/OTPInput/index.tsx +2 -2
- package/src/fields/PhoneInput/PhoneInput.stories.tsx +2 -1
- package/src/fields/PhoneInput/index.tsx +10 -6
- package/src/fields/Progress/Progress.stories.tsx +2 -1
- package/src/fields/RadioGroup/RadioGroup.stories.tsx +3 -2
- package/src/fields/RadioGroup/index.tsx +1 -0
- package/src/fields/Rating/Rating.stories.tsx +2 -1
- package/src/fields/SearchInput/SearchInput.stories.tsx +2 -1
- package/src/fields/SearchInput/index.tsx +8 -45
- package/src/fields/Select/Select.stories.tsx +2 -2
- package/src/fields/Select/index.tsx +18 -12
- package/src/fields/Signature/Signature.stories.tsx +2 -1
- package/src/fields/Signature/index.tsx +6 -1
- package/src/fields/Slider/Slider.stories.tsx +2 -1
- package/src/fields/Slider/index.tsx +6 -2
- package/src/fields/Stepper/Stepper.stories.tsx +2 -1
- package/src/fields/Switch/Switch.stories.tsx +3 -1
- package/src/fields/TextArea/TextArea.stories.tsx +2 -1
- package/src/fields/TimePicker/TimePicker.stories.tsx +2 -1
- package/src/fields/TimePicker/parts.tsx +6 -10
- package/src/fields/TimeRangeScrubber/index.tsx +20 -18
- package/src/fields/ToggleGroup/ToggleGroup.stories.tsx +2 -8
- package/src/fields/ToggleGroup/index.tsx +10 -4
- package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +2 -2
- package/src/fields/pickerActivation.spec.tsx +7 -3
- package/src/hooks/useFocusManagement.ts +3 -2
- package/src/index.ts +9 -0
- package/src/shared/focusManagement.ts +1 -1
- package/src/shared/panelPortal.ts +2 -1
- package/src/shared/useDragScroll.ts +2 -2
- package/types/Button/index.d.ts +9 -1
- package/types/Button/index.d.ts.map +1 -1
- package/types/FloatingPanel/PanelPortal.d.ts.map +1 -1
- package/types/FloatingPanel/index.d.ts.map +1 -1
- package/types/FloatingPanel/index.native.d.ts.map +1 -1
- package/types/FloatingPanel/trailingAction.d.ts +16 -0
- package/types/FloatingPanel/trailingAction.d.ts.map +1 -0
- package/types/InputParts/PasswordReveal.d.ts +28 -0
- package/types/InputParts/PasswordReveal.d.ts.map +1 -0
- package/types/InputParts/index.d.ts +34 -2
- package/types/InputParts/index.d.ts.map +1 -1
- package/types/fields/Checkbox/index.d.ts +4 -4
- package/types/fields/ColorPicker/index.d.ts.map +1 -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/parts.d.ts.map +1 -1
- package/types/fields/Duration/index.d.ts.map +1 -1
- package/types/fields/FileUpload/index.d.ts +1 -0
- package/types/fields/FileUpload/index.d.ts.map +1 -1
- package/types/fields/Geolocation/GeolocationMap.d.ts.map +1 -1
- package/types/fields/Geolocation/GeolocationMap.native.d.ts.map +1 -1
- package/types/fields/Geolocation/index.d.ts.map +1 -1
- package/types/fields/Icon/index.d.ts.map +1 -1
- package/types/fields/ImageField/index.d.ts.map +1 -1
- package/types/fields/Input/index.d.ts +9 -3
- package/types/fields/Input/index.d.ts.map +1 -1
- package/types/fields/MentionInput/index.d.ts.map +1 -1
- package/types/fields/PhoneInput/index.d.ts.map +1 -1
- package/types/fields/RadioGroup/index.d.ts +2 -2
- 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/Signature/index.d.ts.map +1 -1
- package/types/fields/Slider/index.d.ts.map +1 -1
- package/types/fields/TimePicker/parts.d.ts.map +1 -1
- package/types/fields/TimeRangeScrubber/index.d.ts.map +1 -1
- package/types/fields/ToggleGroup/index.d.ts +1 -1
- package/types/fields/ToggleGroup/index.d.ts.map +1 -1
- package/types/hooks/useFocusManagement.d.ts.map +1 -1
- package/types/index.d.ts +4 -0
- package/types/index.d.ts.map +1 -1
- package/types/shared/panelPortal.d.ts.map +1 -1
package/src/Button/index.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IconSlot } from "@multiplatform.one/theme";
|
|
2
|
-
import { transitionProps } from "@multiplatform.one/theme";
|
|
2
|
+
import { transitionProps, SizableText } from "@multiplatform.one/theme";
|
|
3
3
|
import { pressSlopProps } from "../shared/pressSlopProps";
|
|
4
4
|
import {
|
|
5
5
|
Children,
|
|
@@ -37,7 +37,7 @@ import { useFormField } from "../shared/utils";
|
|
|
37
37
|
import {
|
|
38
38
|
Button as TamaguiButton,
|
|
39
39
|
type ButtonProps as TamaguiButtonProps,
|
|
40
|
-
SizableText,
|
|
40
|
+
SizableText as TamaguiSizableText,
|
|
41
41
|
View,
|
|
42
42
|
XStack,
|
|
43
43
|
YStack,
|
|
@@ -339,6 +339,14 @@ export interface ButtonProps extends Omit<
|
|
|
339
339
|
* `control`.
|
|
340
340
|
*/
|
|
341
341
|
recipeFamily?: RecipeFamilyName;
|
|
342
|
+
/**
|
|
343
|
+
* A chromeless button at a container edge (a toolbar's back button) pulls
|
|
344
|
+
* out by its own horizontal padding, so its glyph sits on the content
|
|
345
|
+
* gutter while the press target reaches into the margin (MUI IconButton
|
|
346
|
+
* `edge`, iOS / Material top-bar navigation icon). No effect on a button
|
|
347
|
+
* that paints a frame: the frame is what aligns there.
|
|
348
|
+
*/
|
|
349
|
+
edge?: "start" | "end";
|
|
342
350
|
}
|
|
343
351
|
|
|
344
352
|
export function Button({
|
|
@@ -363,6 +371,7 @@ export function Button({
|
|
|
363
371
|
nested = false,
|
|
364
372
|
circular,
|
|
365
373
|
chromeless,
|
|
374
|
+
edge,
|
|
366
375
|
verb,
|
|
367
376
|
noun,
|
|
368
377
|
actionRole,
|
|
@@ -444,6 +453,14 @@ export function Button({
|
|
|
444
453
|
const touch = useTouchSurface();
|
|
445
454
|
const recipe = resolveButtonSizeRecipe(resolvedSize, recipeFamily, touch);
|
|
446
455
|
const padX = recipe.paddingHorizontal;
|
|
456
|
+
// `edge` cancels the padding the frame actually paints: an escaped number,
|
|
457
|
+
// a passed-through space token, or the recipe's.
|
|
458
|
+
const edgePull =
|
|
459
|
+
sizeRecipeEscaped && typeof paddingHorizontalProp === "number"
|
|
460
|
+
? -paddingHorizontalProp
|
|
461
|
+
: typeof paddingHorizontalProp === "string" && paddingHorizontalProp.startsWith("$")
|
|
462
|
+
? (`$-${paddingHorizontalProp.slice(1)}` as "$4")
|
|
463
|
+
: -padX;
|
|
447
464
|
const radiusToken = knobProps.borderRadius.borderRadius;
|
|
448
465
|
const radiusStop: SizeRecipeRadiusStop | undefined =
|
|
449
466
|
typeof radiusToken === "string"
|
|
@@ -523,6 +540,10 @@ export function Button({
|
|
|
523
540
|
const isLow = knobProps.textAccent === "low";
|
|
524
541
|
const isMedium = knobProps.textAccent === "medium";
|
|
525
542
|
const resolvedBorderWidth = knobProps.borderRadius.borderWidth;
|
|
543
|
+
// Tamagui applies props in key order, and a JSX prop that repeats a spread
|
|
544
|
+
// key keeps the spread's slot: left in, the fragment's `borderColor` would
|
|
545
|
+
// sit before `outlined`, whose `$borderColor` then beats the LC-148 hairline.
|
|
546
|
+
const { borderColor: knobBorderColor, ...radiusFragment } = knobProps.borderRadius;
|
|
526
547
|
const [hovering, setHovering] = useState(false);
|
|
527
548
|
const [pressing, setPressing] = useState(false);
|
|
528
549
|
const handlePressIn = useCallback(() => {
|
|
@@ -574,7 +595,7 @@ export function Button({
|
|
|
574
595
|
: recipe.iconSize;
|
|
575
596
|
|
|
576
597
|
const renderLabelText = (label: string | number, key?: string) => (
|
|
577
|
-
<
|
|
598
|
+
<TamaguiSizableText
|
|
578
599
|
key={key}
|
|
579
600
|
userSelect="none"
|
|
580
601
|
flexGrow={0}
|
|
@@ -602,7 +623,7 @@ export function Button({
|
|
|
602
623
|
{...transitionProps(knobProps.motion.control)}
|
|
603
624
|
>
|
|
604
625
|
{label}
|
|
605
|
-
</
|
|
626
|
+
</TamaguiSizableText>
|
|
606
627
|
);
|
|
607
628
|
// LC-82 TEXT-RIDES-TEXT: wrap ALL bare string/number children — the
|
|
608
629
|
// array path (coalesced runs), not just the singleton case.
|
|
@@ -734,16 +755,11 @@ export function Button({
|
|
|
734
755
|
aria-busy={loading || undefined}
|
|
735
756
|
opacity={1}
|
|
736
757
|
{...transitionProps(knobProps.motion.control, ["borderRadius", "borderWidth"])}
|
|
737
|
-
{...
|
|
758
|
+
{...radiusFragment}
|
|
738
759
|
{...(radiusStop === "medium" || radiusStop == null
|
|
739
760
|
? { borderRadius: paintedRadius.radius }
|
|
740
761
|
: undefined)}
|
|
741
762
|
borderWidth={resolvedBorderWidth}
|
|
742
|
-
// MPO-19 X3: the borderRadius knob fragment carries `$borderColor` for
|
|
743
|
-
// bordered chrome, but a filled Button's edge is transparent by contract
|
|
744
|
-
// (reference §6.1) — same-width invisible border keeps filled and
|
|
745
|
-
// outlined boxes identical without the filled one showing a ring.
|
|
746
|
-
borderColor={outlined ? "$borderColor" : "transparent"}
|
|
747
763
|
size={resolvedSize}
|
|
748
764
|
{...(chromeless ? undefined : knobProps.elevationChrome)}
|
|
749
765
|
elevation={knobProps.elevation}
|
|
@@ -753,6 +769,11 @@ export function Button({
|
|
|
753
769
|
// knob-driven caller passes `knobProps.outlined`, which is a real
|
|
754
770
|
// boolean, so this fired on most screens.
|
|
755
771
|
outlined={outlined || undefined}
|
|
772
|
+
// MPO-19 X3: the borderRadius knob fragment carries `$borderColor` for
|
|
773
|
+
// bordered chrome, but a filled Button's edge is transparent by contract
|
|
774
|
+
// (reference §6.1) — same-width invisible border keeps filled and
|
|
775
|
+
// outlined boxes identical without the filled one showing a ring.
|
|
776
|
+
borderColor={outlined ? knobBorderColor : "transparent"}
|
|
756
777
|
circular={!nested && isCircular ? true : undefined}
|
|
757
778
|
chromeless={selectedFill ? false : chromeless}
|
|
758
779
|
selected={selectedFill || undefined}
|
|
@@ -767,6 +788,11 @@ export function Button({
|
|
|
767
788
|
minHeight: visualPx,
|
|
768
789
|
}
|
|
769
790
|
: undefined)}
|
|
791
|
+
{...(edge && chromeless && !selectedFill && !isCircular
|
|
792
|
+
? edge === "start"
|
|
793
|
+
? { marginInlineStart: edgePull }
|
|
794
|
+
: { marginInlineEnd: edgePull }
|
|
795
|
+
: undefined)}
|
|
770
796
|
{...(restFill ? { backgroundColor: restFill } : undefined)}
|
|
771
797
|
// Solid-intent sub-themes carry the on-fill foreground as `$color`
|
|
772
798
|
// (LC-05); outlined frames sit on the page, so re-anchor inherited
|
|
@@ -940,4 +966,4 @@ export function Button({
|
|
|
940
966
|
}
|
|
941
967
|
|
|
942
968
|
Button.Icon = TamaguiButton.Icon;
|
|
943
|
-
Button.Text =
|
|
969
|
+
Button.Text = TamaguiSizableText;
|
|
@@ -2,8 +2,9 @@ import { action } from "@multiplatform.one/storybook";
|
|
|
2
2
|
import { CheckIcon, LightningIcon, TagIcon } from "@phosphor-icons/react";
|
|
3
3
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
4
4
|
import { useState } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { XStack, YStack } from "tamagui";
|
|
6
6
|
import { Chip, type ChipColor, type ChipSize, type ChipVariantProp } from "./index";
|
|
7
|
+
import { Text } from "@multiplatform.one/theme";
|
|
7
8
|
|
|
8
9
|
const meta: Meta<typeof Chip> = {
|
|
9
10
|
title: "Forms/Chip",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { action } from "@multiplatform.one/storybook";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { YStack } from "tamagui";
|
|
5
5
|
import { Button } from "../Button";
|
|
6
6
|
import { Checkbox } from "../fields/Checkbox";
|
|
7
7
|
import { Input } from "../fields/Input";
|
|
@@ -9,6 +9,7 @@ import { RadioGroup } from "../fields/RadioGroup";
|
|
|
9
9
|
import { Switch } from "../fields/Switch";
|
|
10
10
|
import { Form } from "../Form";
|
|
11
11
|
import { ContextualSaveBar } from "./index";
|
|
12
|
+
import { SizableText } from "@multiplatform.one/theme";
|
|
12
13
|
|
|
13
14
|
const fields = (
|
|
14
15
|
<YStack gap="$4" width="100%" maxWidth={640} padding="$4" minHeight={360}>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { action } from "@multiplatform.one/storybook";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { YStack } from "tamagui";
|
|
5
5
|
import { Button } from "../Button";
|
|
6
6
|
import { UnsavedChangesDialog } from "./UnsavedChangesDialog";
|
|
7
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
7
8
|
|
|
8
9
|
const meta: Meta<typeof UnsavedChangesDialog> = {
|
|
9
10
|
title: "Forms/ContextualSaveBar/UnsavedChangesDialog",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { GuardrailSpecimenParameter } from "@multiplatform.one/theme";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
3
|
-
import {
|
|
3
|
+
import { YStack } from "tamagui";
|
|
4
4
|
import { Button } from "../Button";
|
|
5
5
|
import { Input } from "../InputParts";
|
|
6
6
|
import { ControlGroup } from "./index";
|
|
7
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
7
8
|
|
|
8
9
|
const meta: Meta<typeof ControlGroup> = {
|
|
9
10
|
title: "Forms/ControlGroup",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
2
|
-
import {
|
|
2
|
+
import { YStack } from "tamagui";
|
|
3
3
|
import { FormGrid } from "../FormGrid";
|
|
4
4
|
import { FormSection, FormSectionStack } from "../FormSection";
|
|
5
5
|
import { DescriptionList, type DescriptionListItem } from "./index";
|
|
6
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
6
7
|
|
|
7
8
|
const meta: Meta<typeof DescriptionList> = {
|
|
8
9
|
title: "Forms/DescriptionList",
|
|
@@ -2,13 +2,14 @@ import { action } from "@multiplatform.one/storybook";
|
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
3
3
|
import { useForm } from "@tanstack/react-form";
|
|
4
4
|
import { useState } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { YStack } from "tamagui";
|
|
6
6
|
import { Button } from "./Button";
|
|
7
7
|
import { ErrorSummary, collectFormFieldErrors } from "./ErrorSummary";
|
|
8
8
|
import { FieldLayout } from "./fieldLayout";
|
|
9
9
|
import { Form } from "./Form";
|
|
10
10
|
import { FormSection } from "./FormSection";
|
|
11
11
|
import { Input as InputParts } from "./InputParts";
|
|
12
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
12
13
|
|
|
13
14
|
const meta: Meta<typeof ErrorSummary> = {
|
|
14
15
|
title: "Forms/ErrorSummary",
|
package/src/ErrorSummary.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FOCUS_RING_HALO_OFFSET, useResolvedKnobs } from "@multiplatform.one/theme";
|
|
1
|
+
import { FOCUS_RING_HALO_OFFSET, useResolvedKnobs, H4 } from "@multiplatform.one/theme";
|
|
2
2
|
import { WarningCircleIcon } from "@phosphor-icons/react";
|
|
3
3
|
import { type ReactNode, useEffect, useId, useRef } from "react";
|
|
4
|
-
import { Anchor,
|
|
4
|
+
import { Anchor, Paragraph, YStack, isWeb } from "tamagui";
|
|
5
5
|
import { formCommonColors } from "./shared/colorRamps";
|
|
6
6
|
import { t } from "./shared/t";
|
|
7
7
|
import { warnBannedErrorWords as warnBannedErrorWordsShared } from "./shared/devWarn";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
2
|
-
import {
|
|
2
|
+
import { XStack, YStack } from "tamagui";
|
|
3
3
|
import type { FieldDisplayType } from "./index";
|
|
4
4
|
import { FieldDisplay } from "./index";
|
|
5
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
5
6
|
|
|
6
7
|
const meta: Meta<typeof FieldDisplay> = {
|
|
7
8
|
title: "Forms/FieldDisplay",
|
|
@@ -2,8 +2,8 @@ import { action } from "@multiplatform.one/storybook";
|
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
3
3
|
import { useForm } from "@tanstack/react-form";
|
|
4
4
|
import { useState } from "react";
|
|
5
|
-
import { Preset } from "@multiplatform.one/theme";
|
|
6
|
-
import {
|
|
5
|
+
import { Preset, Paragraph } from "@multiplatform.one/theme";
|
|
6
|
+
import { YStack, XStack } from "tamagui";
|
|
7
7
|
import { Button } from "./Button";
|
|
8
8
|
import { Form } from "./Form";
|
|
9
9
|
import { Field, FieldLayout } from "./fieldLayout";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
3
|
-
import { Preset } from "@multiplatform.one/theme";
|
|
4
|
-
import {
|
|
3
|
+
import { Preset, Paragraph, H4, Text } from "@multiplatform.one/theme";
|
|
4
|
+
import { ScrollView, Separator, View, XStack, YStack } from "tamagui";
|
|
5
5
|
import { FloatingPanel } from "./index";
|
|
6
6
|
import { Button } from "../Button";
|
|
7
7
|
import { Select } from "../fields/Select";
|
|
@@ -102,6 +102,7 @@ export function PanelPortal({ anchor, children }: PanelPortalProps) {
|
|
|
102
102
|
const guard = event.currentTarget;
|
|
103
103
|
const from = event.relatedTarget;
|
|
104
104
|
const forward =
|
|
105
|
+
typeof Node === "undefined" ||
|
|
105
106
|
!(from instanceof Node) ||
|
|
106
107
|
Boolean(guard.compareDocumentPosition(from) & Node.DOCUMENT_POSITION_PRECEDING);
|
|
107
108
|
const inside = tabbablesIn(portalRef.current);
|
|
@@ -88,6 +88,7 @@ import { useKeyboardInset } from "../shared/useKeyboardInset";
|
|
|
88
88
|
import type { FloatingPanelProps } from "./index";
|
|
89
89
|
import { placeAtPoint, type PanelBounds, type PanelPoint } from "./pointAnchor";
|
|
90
90
|
import { panelViewportPadding } from "./useFloatingPanel";
|
|
91
|
+
import { TrailingActionOverlay, TriggerWithTrailingAction } from "./trailingAction";
|
|
91
92
|
|
|
92
93
|
// Re-export the hook + constants so Select / Combobox / external consumers
|
|
93
94
|
// resolve identically on native (their floating cores are unused on device
|
|
@@ -472,6 +473,7 @@ export function FloatingPanel({
|
|
|
472
473
|
style={{
|
|
473
474
|
flexDirection: "row",
|
|
474
475
|
alignItems: "center",
|
|
476
|
+
position: "relative",
|
|
475
477
|
width: triggerSizing === "content" ? undefined : "100%",
|
|
476
478
|
}}
|
|
477
479
|
>
|
|
@@ -503,10 +505,10 @@ export function FloatingPanel({
|
|
|
503
505
|
collapsable={false}
|
|
504
506
|
style={{ width: triggerSizing === "content" ? undefined : "100%" }}
|
|
505
507
|
>
|
|
506
|
-
{trigger}
|
|
508
|
+
<TriggerWithTrailingAction trigger={trigger} triggerEnd={triggerEnd} />
|
|
507
509
|
</RNView>
|
|
508
510
|
</Pressable>
|
|
509
|
-
{triggerEnd}
|
|
511
|
+
<TrailingActionOverlay>{triggerEnd}</TrailingActionOverlay>
|
|
510
512
|
</RNView>
|
|
511
513
|
<Modal
|
|
512
514
|
visible={open}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
import { isWeb, Sheet, View, YStack } from "tamagui";
|
|
24
24
|
import { useClick, useDismiss, useInteractions } from "@floating-ui/react";
|
|
25
25
|
import { ScrollArrow } from "../shared/floatingList";
|
|
26
|
+
import { TrailingActionOverlay, TriggerWithTrailingAction } from "./trailingAction";
|
|
26
27
|
import { useReturnFocusOnClose, useSheetModalFocus } from "../shared/focusManagement";
|
|
27
28
|
import { useSheetEscapeDismiss } from "../shared/useSheetEscapeDismiss";
|
|
28
29
|
import { useFloatingPanel, panelViewportPadding } from "./useFloatingPanel";
|
|
@@ -206,7 +207,14 @@ function useKeyboardFocusIntoPanel(
|
|
|
206
207
|
if (!frame) return;
|
|
207
208
|
if (!wasKeyboardFocus() && !keyboardOpenRef?.current) return;
|
|
208
209
|
const active = document.activeElement;
|
|
209
|
-
if (
|
|
210
|
+
if (
|
|
211
|
+
typeof HTMLElement !== "undefined" &&
|
|
212
|
+
active instanceof HTMLElement &&
|
|
213
|
+
frame.contains(active) &&
|
|
214
|
+
active !== frame
|
|
215
|
+
) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
210
218
|
// Initial keyboard focus belongs to an action, not the repeated close row.
|
|
211
219
|
const first = Array.from(frame.querySelectorAll<HTMLElement>(PANEL_FOCUSABLE)).find(
|
|
212
220
|
(el) => !el.closest("[data-fp-trigger-row]"),
|
|
@@ -552,6 +560,7 @@ function FloatingPanelSheet({
|
|
|
552
560
|
<View
|
|
553
561
|
flexDirection="row"
|
|
554
562
|
alignItems="center"
|
|
563
|
+
position="relative"
|
|
555
564
|
width={triggerSizing === "content" ? "auto" : "100%"}
|
|
556
565
|
>
|
|
557
566
|
<View
|
|
@@ -562,9 +571,9 @@ function FloatingPanelSheet({
|
|
|
562
571
|
opacity={disabled ? 0.5 : 1}
|
|
563
572
|
{...triggerActivation}
|
|
564
573
|
>
|
|
565
|
-
{trigger}
|
|
574
|
+
<TriggerWithTrailingAction trigger={trigger} triggerEnd={triggerEnd} />
|
|
566
575
|
</View>
|
|
567
|
-
{triggerEnd}
|
|
576
|
+
<TrailingActionOverlay>{triggerEnd}</TrailingActionOverlay>
|
|
568
577
|
</View>
|
|
569
578
|
)}
|
|
570
579
|
<Sheet
|
|
@@ -1112,7 +1121,8 @@ function FloatingPanelWeb({
|
|
|
1112
1121
|
if (open || disabled || isContextMenu || event.button !== 0 || !isWeb) return;
|
|
1113
1122
|
const reference = panel.triggerRef.current;
|
|
1114
1123
|
if (!reference) return;
|
|
1115
|
-
const target =
|
|
1124
|
+
const target =
|
|
1125
|
+
typeof Element !== "undefined" && event.target instanceof Element ? event.target : null;
|
|
1116
1126
|
const pressed = target?.closest<HTMLElement>(PANEL_FOCUSABLE);
|
|
1117
1127
|
const focusable =
|
|
1118
1128
|
pressed && reference.contains(pressed)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { View, isWeb } from "tamagui";
|
|
3
|
+
import { FieldTrailingOverlay } from "../InputParts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* LC-149 FIELD-TRAILING-ACTION for picker triggers. `triggerEnd` stays out of
|
|
7
|
+
* the trigger's press capture (Fabric steals the responder from anything
|
|
8
|
+
* inside it), so it cannot live in the Box. It is laid over the Box's
|
|
9
|
+
* trailing edge instead, and the Box keeps that end cap empty for it: the
|
|
10
|
+
* clear reads as part of the field, not a button beside it.
|
|
11
|
+
*/
|
|
12
|
+
export function TriggerWithTrailingAction({
|
|
13
|
+
trigger,
|
|
14
|
+
triggerEnd,
|
|
15
|
+
}: {
|
|
16
|
+
trigger: ReactNode;
|
|
17
|
+
triggerEnd?: ReactNode;
|
|
18
|
+
}) {
|
|
19
|
+
const active = triggerEnd != null && triggerEnd !== false;
|
|
20
|
+
return <FieldTrailingOverlay active={active}>{trigger}</FieldTrailingOverlay>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function TrailingActionOverlay({ children }: { children?: ReactNode }) {
|
|
24
|
+
if (children == null || children === false) return null;
|
|
25
|
+
return (
|
|
26
|
+
<View
|
|
27
|
+
position="absolute"
|
|
28
|
+
top={0}
|
|
29
|
+
bottom={0}
|
|
30
|
+
{...(isWeb ? { insetInlineEnd: 0 } : { end: 0 })}
|
|
31
|
+
justifyContent="center"
|
|
32
|
+
data-field-action-overlay=""
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</View>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "@phosphor-icons/react";
|
|
12
12
|
import { useForm } from "@tanstack/react-form";
|
|
13
13
|
import { useCallback, useState } from "react";
|
|
14
|
-
import {
|
|
14
|
+
import { Separator, YStack } from "tamagui";
|
|
15
15
|
import { Button } from "../Button";
|
|
16
16
|
import { FieldGroup } from "../FieldGroup";
|
|
17
17
|
import { FormGrid } from "../FormGrid";
|
|
@@ -52,6 +52,7 @@ import { ToggleGroup } from "../fields/ToggleGroup";
|
|
|
52
52
|
import { formatFieldError } from "../ErrorSummary";
|
|
53
53
|
import type { AnyFormApi } from "../types";
|
|
54
54
|
import { Form, FormActions } from "./index";
|
|
55
|
+
import { H3 } from "@multiplatform.one/theme";
|
|
55
56
|
|
|
56
57
|
const meta: Meta<typeof Form> = {
|
|
57
58
|
title: "Forms/Form",
|
package/src/FormGrid.stories.tsx
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
2
|
-
import {
|
|
2
|
+
import { YStack } from "tamagui";
|
|
3
3
|
import { FieldGroup } from "./FieldGroup";
|
|
4
4
|
import { FormGrid } from "./FormGrid";
|
|
5
5
|
import { FormSection, FormSectionStack } from "./FormSection";
|
|
6
6
|
import { Input } from "./fields/Input";
|
|
7
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
7
8
|
|
|
8
9
|
const meta: Meta<typeof FormGrid> = {
|
|
9
10
|
title: "Forms/FormGrid",
|
package/src/FormGrid.tsx
CHANGED
|
@@ -115,6 +115,7 @@ function FormGridWeb({
|
|
|
115
115
|
update(el.getBoundingClientRect().width);
|
|
116
116
|
|
|
117
117
|
if (typeof ResizeObserver === "undefined") {
|
|
118
|
+
if (typeof window === "undefined" || typeof window.addEventListener !== "function") return;
|
|
118
119
|
const onResize = () => update(el.getBoundingClientRect().width);
|
|
119
120
|
window.addEventListener("resize", onResize);
|
|
120
121
|
return () => window.removeEventListener("resize", onResize);
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { action } from "@multiplatform.one/storybook";
|
|
2
|
-
import {
|
|
3
|
-
EnvelopeIcon,
|
|
4
|
-
KeyIcon,
|
|
5
|
-
MagnifyingGlassIcon,
|
|
6
|
-
EyeIcon,
|
|
7
|
-
EyeSlashIcon,
|
|
8
|
-
} from "@phosphor-icons/react";
|
|
2
|
+
import { EnvelopeIcon, KeyIcon, MagnifyingGlassIcon } from "@phosphor-icons/react";
|
|
9
3
|
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
10
4
|
import { useForm } from "@tanstack/react-form";
|
|
11
5
|
import { useState } from "react";
|
|
12
|
-
import {
|
|
6
|
+
import { ScrollView, Separator, View, YStack } from "tamagui";
|
|
13
7
|
import {
|
|
14
8
|
Button,
|
|
15
9
|
Checkbox,
|
|
@@ -26,6 +20,7 @@ import {
|
|
|
26
20
|
useFocusManagement,
|
|
27
21
|
} from "./index";
|
|
28
22
|
import type { AnyFormApi } from "./types";
|
|
23
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
29
24
|
|
|
30
25
|
const meta: Meta<typeof Form> = {
|
|
31
26
|
title: "Forms/FormsIntegration",
|
|
@@ -266,8 +261,6 @@ export const multiStepRegistration: Story = {
|
|
|
266
261
|
|
|
267
262
|
export const inputComposition: Story = {
|
|
268
263
|
render: function InputComposition() {
|
|
269
|
-
const [showPassword, setShowPassword] = useState(false);
|
|
270
|
-
|
|
271
264
|
return (
|
|
272
265
|
<ScrollView>
|
|
273
266
|
<View padding="$4" maxWidth={600} alignSelf="center">
|
|
@@ -283,15 +276,8 @@ export const inputComposition: Story = {
|
|
|
283
276
|
<Input
|
|
284
277
|
label="Password"
|
|
285
278
|
placeholder="Enter password"
|
|
286
|
-
secureTextEntry
|
|
279
|
+
secureTextEntry
|
|
287
280
|
leftIcon={<KeyIcon />}
|
|
288
|
-
rightIcon={
|
|
289
|
-
showPassword ? (
|
|
290
|
-
<EyeSlashIcon cursor="pointer" onClick={() => setShowPassword(false)} />
|
|
291
|
-
) : (
|
|
292
|
-
<EyeIcon cursor="pointer" onClick={() => setShowPassword(true)} />
|
|
293
|
-
)
|
|
294
|
-
}
|
|
295
281
|
/>
|
|
296
282
|
|
|
297
283
|
<Input label="Required Field" placeholder="This field is required" required />
|
|
@@ -3,12 +3,14 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
3
3
|
import {
|
|
4
4
|
EnvelopeIcon,
|
|
5
5
|
EyeIcon,
|
|
6
|
+
EyeSlashIcon,
|
|
6
7
|
MagnifyingGlassIcon,
|
|
7
8
|
WarningCircleIcon,
|
|
8
9
|
} from "@phosphor-icons/react";
|
|
9
10
|
import { useState } from "react";
|
|
10
|
-
import {
|
|
11
|
+
import { YStack } from "tamagui";
|
|
11
12
|
import { Input as InputParts } from "./index";
|
|
13
|
+
import { Paragraph } from "@multiplatform.one/theme";
|
|
12
14
|
|
|
13
15
|
const meta: Meta<typeof InputParts> = {
|
|
14
16
|
title: "Forms/InputParts",
|
|
@@ -107,8 +109,9 @@ export const Adornments: Story = {
|
|
|
107
109
|
};
|
|
108
110
|
|
|
109
111
|
/**
|
|
110
|
-
* `InputParts.
|
|
111
|
-
* copy.
|
|
112
|
+
* `InputParts.Action` is the field's own action (LC-149): a reveal toggle, a
|
|
113
|
+
* clear, a copy. A chromeless glyph that squares off to the control height
|
|
114
|
+
* inside the frame, never a bordered button beside it.
|
|
112
115
|
*/
|
|
113
116
|
export const TrailingButton: Story = {
|
|
114
117
|
render: () => {
|
|
@@ -124,19 +127,16 @@ export const TrailingButton: Story = {
|
|
|
124
127
|
secureTextEntry={secure}
|
|
125
128
|
onChangeText={action("onChangeText")}
|
|
126
129
|
/>
|
|
127
|
-
<InputParts.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
aria-label={secure ? "Show password" : "Hide password"}
|
|
130
|
+
<InputParts.Action
|
|
131
|
+
label={secure ? "Show password" : "Hide password"}
|
|
132
|
+
pressed={!secure}
|
|
131
133
|
onPress={() => {
|
|
132
134
|
setSecure((prev) => !prev);
|
|
133
135
|
action("togglePasswordVisibility")(!secure);
|
|
134
136
|
}}
|
|
135
137
|
>
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
</InputParts.Icon>
|
|
139
|
-
</InputParts.Button>
|
|
138
|
+
{secure ? <EyeIcon /> : <EyeSlashIcon />}
|
|
139
|
+
</InputParts.Action>
|
|
140
140
|
</InputParts.Box>
|
|
141
141
|
<InputParts.Meta helperText={secure ? "Hidden" : "Visible"} />
|
|
142
142
|
</InputParts>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { EyeIcon, EyeSlashIcon } from "@phosphor-icons/react";
|
|
2
|
+
import type { RefObject } from "react";
|
|
3
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
4
|
+
import type { FontSizeTokens, SizeTokens } from "tamagui";
|
|
5
|
+
import { Input } from "./index";
|
|
6
|
+
|
|
7
|
+
export const SHOW_PASSWORD = "Show password";
|
|
8
|
+
export const HIDE_PASSWORD = "Hide password";
|
|
9
|
+
|
|
10
|
+
type Selection = { start: number; end: number };
|
|
11
|
+
|
|
12
|
+
function domInput(node: unknown, id?: string): HTMLInputElement | null {
|
|
13
|
+
const fromRef = node as { setSelectionRange?: unknown } | null;
|
|
14
|
+
if (fromRef && typeof fromRef.setSelectionRange === "function") {
|
|
15
|
+
return fromRef as HTMLInputElement;
|
|
16
|
+
}
|
|
17
|
+
if (typeof document === "undefined" || !id) return null;
|
|
18
|
+
return document.getElementById(id) as HTMLInputElement | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function readSelection(node: unknown, id?: string): Selection | null {
|
|
22
|
+
const el = domInput(node, id);
|
|
23
|
+
if (!el || typeof el.selectionStart !== "number") return null;
|
|
24
|
+
return { start: el.selectionStart, end: el.selectionEnd ?? el.selectionStart };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Reveal state for a masked field. Toggling keeps focus and the caret where
|
|
29
|
+
* they were (web swaps the input type, which would otherwise drop both), and
|
|
30
|
+
* an emptied field goes back to masked.
|
|
31
|
+
*/
|
|
32
|
+
export function usePasswordReveal({
|
|
33
|
+
inputRef,
|
|
34
|
+
id,
|
|
35
|
+
text,
|
|
36
|
+
}: {
|
|
37
|
+
inputRef: RefObject<unknown>;
|
|
38
|
+
id?: string;
|
|
39
|
+
text: string;
|
|
40
|
+
}) {
|
|
41
|
+
const [revealed, setRevealed] = useState(false);
|
|
42
|
+
const pendingSelection = useRef<Selection | null>(null);
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!text) setRevealed(false);
|
|
46
|
+
}, [text]);
|
|
47
|
+
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
const selection = pendingSelection.current;
|
|
50
|
+
if (!selection) return;
|
|
51
|
+
pendingSelection.current = null;
|
|
52
|
+
const el = domInput(inputRef.current, id);
|
|
53
|
+
el?.focus();
|
|
54
|
+
el?.setSelectionRange(selection.start, selection.end);
|
|
55
|
+
}, [id, inputRef, revealed]);
|
|
56
|
+
|
|
57
|
+
const toggle = useCallback(() => {
|
|
58
|
+
pendingSelection.current = readSelection(inputRef.current, id);
|
|
59
|
+
setRevealed((open) => !open);
|
|
60
|
+
}, [id, inputRef]);
|
|
61
|
+
|
|
62
|
+
return { revealed, toggle };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface PasswordRevealProps {
|
|
66
|
+
revealed: boolean;
|
|
67
|
+
onToggle: () => void;
|
|
68
|
+
/** id of the masked input. */
|
|
69
|
+
controls?: string;
|
|
70
|
+
disabled?: boolean;
|
|
71
|
+
size?: SizeTokens | FontSizeTokens;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** LC-149: the reveal is the field's trailing action, eye / eye-slash. */
|
|
75
|
+
export function PasswordReveal({
|
|
76
|
+
revealed,
|
|
77
|
+
onToggle,
|
|
78
|
+
controls,
|
|
79
|
+
disabled,
|
|
80
|
+
size,
|
|
81
|
+
}: PasswordRevealProps) {
|
|
82
|
+
return (
|
|
83
|
+
<Input.Action
|
|
84
|
+
label={revealed ? HIDE_PASSWORD : SHOW_PASSWORD}
|
|
85
|
+
pressed={revealed}
|
|
86
|
+
controls={controls}
|
|
87
|
+
disabled={disabled}
|
|
88
|
+
size={size}
|
|
89
|
+
onPress={onToggle}
|
|
90
|
+
>
|
|
91
|
+
{revealed ? <EyeSlashIcon /> : <EyeIcon />}
|
|
92
|
+
</Input.Action>
|
|
93
|
+
);
|
|
94
|
+
}
|