@multiplatform.one/forms 7.42.0 → 7.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/AdaptivePopup/index.native.js +1 -1
- package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
- package/dist/cjs/Button/index.native.js +1 -1
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/Chip/index.cjs +5 -2
- package/dist/cjs/Chip/index.native.js +2 -1
- package/dist/cjs/Chip/index.native.js.map +1 -1
- package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js +1 -1
- package/dist/cjs/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
- package/dist/cjs/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
- package/dist/cjs/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
- package/dist/cjs/ContextualSaveBar/index.native.js +3 -3
- package/dist/cjs/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/cjs/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
- package/dist/cjs/ControlGroup/index.native.js +1 -1
- package/dist/cjs/ControlGroup/index.native.js.map +1 -1
- package/dist/cjs/DescriptionList/index.native.js +2 -2
- package/dist/cjs/DescriptionList/index.native.js.map +1 -1
- package/dist/cjs/ErrorSummary.native.js.map +1 -1
- package/dist/cjs/FieldDisplay/editMode.native.js.map +1 -1
- package/dist/cjs/FieldDisplay/formatters.native.js.map +1 -1
- package/dist/cjs/FieldDisplay/index.native.js +1 -1
- package/dist/cjs/FieldDisplay/index.native.js.map +1 -1
- package/dist/cjs/FieldGroup.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/cjs/Form/index.native.js +1 -1
- package/dist/cjs/Form/index.native.js.map +1 -1
- package/dist/cjs/Form/submissionController.native.js.map +1 -1
- package/dist/cjs/Form/validateOn.native.js.map +1 -1
- package/dist/cjs/FormGrid.native.js.map +1 -1
- package/dist/cjs/FormSection.native.js.map +1 -1
- package/dist/cjs/InputParts/index.cjs +22 -116
- package/dist/cjs/InputParts/index.native.js +25 -121
- package/dist/cjs/InputParts/index.native.js.map +1 -1
- package/dist/cjs/Label/index.native.js.map +1 -1
- package/dist/cjs/MediaPicker/base64.native.js.map +1 -1
- package/dist/cjs/MediaPicker/payload.native.js.map +1 -1
- package/dist/cjs/MediaPicker/types.native.js.map +1 -1
- package/dist/cjs/MediaPicker/useMediaPicker.native.js.map +1 -1
- package/dist/cjs/Skeleton/index.native.js.map +1 -1
- package/dist/cjs/Spinner/SpinnerGlyph.native.js.map +1 -1
- package/dist/cjs/Spinner/spinnerSize.native.js.map +1 -1
- package/dist/cjs/Table/index.native.js.map +1 -1
- package/dist/cjs/Wheel/haptic.native.js.map +1 -1
- package/dist/cjs/Wheel/index.native.js.map +1 -1
- package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
- package/dist/cjs/actionLabel.native.js.map +1 -1
- package/dist/cjs/fieldDefaults.native.js.map +1 -1
- package/dist/cjs/fieldLayout.native.js +1 -1
- package/dist/cjs/fieldLayout.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/BarcodePreview.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/BarcodeScanner.native.js +1 -1
- package/dist/cjs/fields/Barcode/code128.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/index.native.js +2 -2
- package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/qr.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/scannerTypes.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/Checkbox.native.js +1 -1
- package/dist/cjs/fields/Checkbox/Checkbox.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/CheckboxBox.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/CheckboxCard.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js +1 -1
- package/dist/cjs/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
- package/dist/cjs/fields/Checkbox/index.native.js.map +1 -1
- package/dist/cjs/fields/ColorPicker/index.native.js +3 -3
- package/dist/cjs/fields/ColorPicker/index.native.js.map +1 -1
- package/dist/cjs/fields/ColorPicker/parts.native.js +2 -2
- package/dist/cjs/fields/ColorPicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/authorOptions.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/index.native.js +6 -6
- package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/Calendar.native.js.map +1 -1
- 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.native.js +3 -3
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/DatetimePicker.native.js +2 -2
- package/dist/cjs/fields/DatePicker/MonthPicker.native.js +2 -2
- package/dist/cjs/fields/DatePicker/MonthPicker.native.js.map +1 -1
- 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/catalog.native.js +2 -2
- package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/fieldValueSync.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/index.native.js +2 -2
- package/dist/cjs/fields/DatePicker/parts.native.js +2 -2
- package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/utils.native.js.map +1 -1
- package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/cjs/fields/Duration/index.native.js +3 -3
- package/dist/cjs/fields/Duration/index.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload/filePickerTypes.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload/index.native.js +2 -2
- package/dist/cjs/fields/FileUpload/index.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/geoValue.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/geocoder.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/geocoderContext.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/index.native.js +5 -5
- package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/mapMath.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/mapTypes.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/photonGeocoder.native.js.map +1 -1
- package/dist/cjs/fields/Icon/drawnSet.native.js.map +1 -1
- package/dist/cjs/fields/Icon/index.native.js +3 -3
- package/dist/cjs/fields/Icon/index.native.js.map +1 -1
- package/dist/cjs/fields/ImageField/index.native.js +2 -2
- package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
- package/dist/cjs/fields/Input/index.cjs +1 -18
- package/dist/cjs/fields/Input/index.native.js +4 -21
- package/dist/cjs/fields/Input/index.native.js.map +1 -1
- package/dist/cjs/fields/MentionInput/index.native.js +3 -3
- package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
- package/dist/cjs/fields/OTPInput/index.cjs +65 -82
- package/dist/cjs/fields/OTPInput/index.native.js +70 -87
- package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
- package/dist/cjs/fields/OTPInput/otpCellCss.cjs +1 -3
- package/dist/cjs/fields/OTPInput/otpCellCss.native.js +1 -3
- package/dist/cjs/fields/OTPInput/otpCellCss.native.js.map +1 -1
- package/dist/cjs/fields/PhoneInput/dialCodes.native.js.map +1 -1
- package/dist/cjs/fields/PhoneInput/index.cjs +1 -1
- package/dist/cjs/fields/PhoneInput/index.native.js +4 -4
- package/dist/cjs/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/cjs/fields/PhoneInput/phone.native.js.map +1 -1
- package/dist/cjs/fields/PhoneInput/regionNames.native.js.map +1 -1
- package/dist/cjs/fields/Progress/index.native.js +1 -1
- package/dist/cjs/fields/Progress/index.native.js.map +1 -1
- package/dist/cjs/fields/RadioGroup/index.native.js +1 -1
- package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/cjs/fields/Rating/index.native.js +1 -1
- package/dist/cjs/fields/Rating/index.native.js.map +1 -1
- package/dist/cjs/fields/Rating/ratingMath.native.js.map +1 -1
- package/dist/cjs/fields/Rating/types.native.js.map +1 -1
- package/dist/cjs/fields/SearchInput/index.cjs +5 -2
- package/dist/cjs/fields/SearchInput/index.native.js +4 -3
- package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
- package/dist/cjs/fields/Select/index.native.js +4 -4
- package/dist/cjs/fields/Select/index.native.js.map +1 -1
- package/dist/cjs/fields/Signature/index.cjs +3 -11
- package/dist/cjs/fields/Signature/index.native.js +5 -13
- package/dist/cjs/fields/Signature/index.native.js.map +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/Slider/jumpMotion.native.js.map +1 -1
- package/dist/cjs/fields/Stepper/index.native.js +2 -2
- package/dist/cjs/fields/Stepper/index.native.js.map +1 -1
- package/dist/cjs/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
- package/dist/cjs/fields/Switch/footprint.native.js.map +1 -1
- package/dist/cjs/fields/Switch/index.native.js +2 -2
- package/dist/cjs/fields/Switch/index.native.js.map +1 -1
- package/dist/cjs/fields/TextArea/index.native.js +2 -2
- package/dist/cjs/fields/TextArea/index.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/catalog.native.js +3 -3
- package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/index.native.js +2 -2
- package/dist/cjs/fields/TimePicker/parts.native.js +1 -1
- package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
- package/dist/cjs/fields/TimeRangeScrubber/index.native.js +2 -2
- package/dist/cjs/fields/TimeRangeScrubber/index.native.js.map +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.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
- package/dist/cjs/fields/nativeSelect.native.js.map +1 -1
- package/dist/cjs/fields/selectedOrder.native.js.map +1 -1
- package/dist/cjs/formSpacing.native.js.map +1 -1
- package/dist/cjs/hooks/useFocusManagement.native.js.map +1 -1
- package/dist/cjs/index.native.js +44 -44
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/keyboard/KeyboardDoneBar.native.js +1 -1
- package/dist/cjs/keyboard/chain.native.js.map +1 -1
- package/dist/cjs/keyboard/index.native.js.map +1 -1
- package/dist/cjs/keyboard/types.native.js.map +1 -1
- package/dist/cjs/requiredMarking.native.js.map +1 -1
- package/dist/cjs/shared/TimeColumn.native.js +1 -1
- package/dist/cjs/shared/TimeColumn.native.js.map +1 -1
- package/dist/cjs/shared/capabilityPreflight.native.js.map +1 -1
- package/dist/cjs/shared/colorRamps.native.js.map +1 -1
- package/dist/cjs/shared/devWarn.native.js.map +1 -1
- package/dist/cjs/shared/floatingList.native.js +1 -1
- package/dist/cjs/shared/floatingList.native.js.map +1 -1
- package/dist/cjs/shared/focusManagement.native.js.map +1 -1
- package/dist/cjs/shared/groupContext.native.js.map +1 -1
- package/dist/cjs/shared/i18n.native.js.map +1 -1
- package/dist/cjs/shared/instantMotion.native.js.map +1 -1
- package/dist/cjs/shared/nativeA11y.native.js.map +1 -1
- package/dist/cjs/shared/nativeAutoFocus.cjs +37 -0
- package/dist/cjs/shared/nativeAutoFocus.native.js +41 -0
- package/dist/cjs/shared/nativeAutoFocus.native.js.map +1 -0
- package/dist/cjs/shared/panelPortal.native.js.map +1 -1
- package/dist/cjs/shared/pickerTriggerContract.native.js.map +1 -1
- package/dist/cjs/shared/pressSlopProps.native.js.map +1 -1
- package/dist/cjs/shared/t.native.js.map +1 -1
- package/dist/cjs/shared/tableCellContext.native.js.map +1 -1
- package/dist/cjs/shared/useDragScroll.native.js.map +1 -1
- package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/cjs/shared/useSheetEscapeDismiss.native.js.map +1 -1
- package/dist/cjs/shared/useWheelIncrement.native.js.map +1 -1
- package/dist/cjs/shared/utils.native.js +1 -1
- package/dist/cjs/shared/utils.native.js.map +1 -1
- package/dist/cjs/shared/zIndex.native.js.map +1 -1
- package/dist/cjs/themedPrimitives.cjs +2 -0
- package/dist/cjs/themedPrimitives.native.js +2 -0
- package/dist/cjs/themedPrimitives.native.js.map +1 -1
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/cjs/utils/LinkCell.native.js.map +1 -1
- package/dist/esm/Chip/index.mjs +5 -2
- package/dist/esm/Chip/index.mjs.map +1 -1
- package/dist/esm/Chip/index.native.js +2 -1
- package/dist/esm/Chip/index.native.js.map +1 -1
- package/dist/esm/InputParts/index.mjs +24 -116
- package/dist/esm/InputParts/index.mjs.map +1 -1
- package/dist/esm/InputParts/index.native.js +27 -121
- package/dist/esm/InputParts/index.native.js.map +1 -1
- package/dist/esm/fields/Input/index.mjs +2 -18
- package/dist/esm/fields/Input/index.mjs.map +1 -1
- package/dist/esm/fields/Input/index.native.js +2 -18
- package/dist/esm/fields/Input/index.native.js.map +1 -1
- package/dist/esm/fields/OTPInput/index.mjs +67 -84
- package/dist/esm/fields/OTPInput/index.mjs.map +1 -1
- package/dist/esm/fields/OTPInput/index.native.js +69 -86
- package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
- package/dist/esm/fields/OTPInput/otpCellCss.mjs +1 -3
- package/dist/esm/fields/OTPInput/otpCellCss.mjs.map +1 -1
- package/dist/esm/fields/OTPInput/otpCellCss.native.js +1 -3
- package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/index.mjs +1 -1
- package/dist/esm/fields/PhoneInput/index.native.js +1 -1
- package/dist/esm/fields/SearchInput/index.mjs +5 -2
- package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
- package/dist/esm/fields/SearchInput/index.native.js +2 -1
- package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
- package/dist/esm/fields/Signature/index.mjs +4 -12
- package/dist/esm/fields/Signature/index.mjs.map +1 -1
- package/dist/esm/fields/Signature/index.native.js +4 -12
- package/dist/esm/fields/Signature/index.native.js.map +1 -1
- package/dist/esm/shared/nativeAutoFocus.mjs +12 -0
- package/dist/esm/shared/nativeAutoFocus.mjs.map +1 -0
- package/dist/esm/shared/nativeAutoFocus.native.js +13 -0
- package/dist/esm/shared/nativeAutoFocus.native.js.map +1 -0
- package/dist/esm/themedPrimitives.mjs +2 -0
- package/dist/esm/themedPrimitives.mjs.map +1 -1
- package/dist/esm/themedPrimitives.native.js +2 -0
- package/dist/esm/themedPrimitives.native.js.map +1 -1
- package/dist/jsx/Chip/index.mjs +5 -2
- package/dist/jsx/Chip/index.mjs.map +1 -1
- package/dist/jsx/Chip/index.native.js +2 -1
- package/dist/jsx/Chip/index.native.js.map +1 -1
- package/dist/jsx/InputParts/index.mjs +24 -116
- package/dist/jsx/InputParts/index.mjs.map +1 -1
- package/dist/jsx/InputParts/index.native.js +25 -121
- package/dist/jsx/InputParts/index.native.js.map +1 -1
- package/dist/jsx/fields/Input/index.mjs +2 -18
- package/dist/jsx/fields/Input/index.mjs.map +1 -1
- package/dist/jsx/fields/Input/index.native.js +1 -18
- package/dist/jsx/fields/Input/index.native.js.map +1 -1
- package/dist/jsx/fields/OTPInput/index.mjs +67 -84
- package/dist/jsx/fields/OTPInput/index.mjs.map +1 -1
- package/dist/jsx/fields/OTPInput/index.native.js +67 -84
- package/dist/jsx/fields/OTPInput/index.native.js.map +1 -1
- package/dist/jsx/fields/OTPInput/otpCellCss.mjs +1 -3
- package/dist/jsx/fields/OTPInput/otpCellCss.mjs.map +1 -1
- package/dist/jsx/fields/OTPInput/otpCellCss.native.js +1 -3
- package/dist/jsx/fields/OTPInput/otpCellCss.native.js.map +1 -1
- package/dist/jsx/fields/PhoneInput/index.mjs +1 -1
- package/dist/jsx/fields/PhoneInput/index.native.js +1 -1
- package/dist/jsx/fields/SearchInput/index.mjs +5 -2
- package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
- package/dist/jsx/fields/SearchInput/index.native.js +2 -1
- package/dist/jsx/fields/SearchInput/index.native.js.map +1 -1
- package/dist/jsx/fields/Signature/index.mjs +4 -12
- package/dist/jsx/fields/Signature/index.mjs.map +1 -1
- package/dist/jsx/fields/Signature/index.native.js +3 -11
- package/dist/jsx/fields/Signature/index.native.js.map +1 -1
- package/dist/jsx/shared/nativeAutoFocus.mjs +12 -0
- package/dist/jsx/shared/nativeAutoFocus.mjs.map +1 -0
- package/dist/jsx/shared/nativeAutoFocus.native.js +41 -0
- package/dist/jsx/shared/nativeAutoFocus.native.js.map +1 -0
- package/dist/jsx/themedPrimitives.mjs +2 -0
- package/dist/jsx/themedPrimitives.mjs.map +1 -1
- package/dist/jsx/themedPrimitives.native.js +2 -0
- package/dist/jsx/themedPrimitives.native.js.map +1 -1
- package/package.json +8 -8
- package/src/Button/Button.disabledReasonInk.spec.tsx +7 -1
- package/src/Chip/index.tsx +2 -1
- package/src/InputParts/index.spec.tsx +11 -17
- package/src/InputParts/index.tsx +27 -147
- package/src/fieldFocus.spec.ts +44 -0
- package/src/fields/DatePicker/DatePicker.spec.tsx +1 -1
- package/src/fields/DatePicker/DateRangePicker.spec.tsx +1 -1
- package/src/fields/DatePicker/MultiDatePicker.spec.tsx +1 -1
- package/src/fields/Duration/Duration.spec.tsx +2 -2
- package/src/fields/Input/Input.copy.spec.tsx +1 -1
- package/src/fields/Input/Input.spec.tsx +7 -8
- package/src/fields/Input/index.tsx +1 -20
- package/src/fields/OTPInput/index.tsx +79 -98
- package/src/fields/OTPInput/otpCellCss.ts +4 -8
- package/src/fields/PhoneInput/PhoneInput.spec.tsx +3 -3
- package/src/fields/PhoneInput/index.tsx +1 -1
- package/src/fields/SearchInput/SearchInput.focusHold.native.spec.tsx +81 -0
- package/src/fields/SearchInput/SearchInput.spec.tsx +1 -1
- package/src/fields/SearchInput/index.tsx +2 -1
- package/src/fields/Signature/index.tsx +4 -10
- package/src/fields/TextArea/TextArea.spec.tsx +3 -3
- package/src/fields/TimePicker/TimePicker.spec.tsx +1 -1
- package/src/shared/nativeAutoFocus.ts +20 -0
- package/src/themedPrimitives.tsx +9 -1
- package/types/Chip/index.d.ts.map +1 -1
- package/types/InputParts/index.d.ts +29 -32
- package/types/InputParts/index.d.ts.map +1 -1
- package/types/fields/Input/index.d.ts +0 -1
- package/types/fields/Input/index.d.ts.map +1 -1
- package/types/fields/OTPInput/index.d.ts.map +1 -1
- package/types/fields/OTPInput/otpCellCss.d.ts.map +1 -1
- package/types/fields/SearchInput/index.d.ts.map +1 -1
- package/types/fields/Signature/index.d.ts.map +1 -1
- package/types/shared/nativeAutoFocus.d.ts +13 -0
- package/types/shared/nativeAutoFocus.d.ts.map +1 -0
- package/types/themedPrimitives.d.ts.map +1 -1
package/src/InputParts/index.tsx
CHANGED
|
@@ -28,9 +28,9 @@ import {
|
|
|
28
28
|
} from "tamagui";
|
|
29
29
|
import {
|
|
30
30
|
ensureCompositeFocusRing,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
FIELD_FOCUS_REST,
|
|
32
|
+
FIELD_FOCUS_STYLE,
|
|
33
|
+
fieldFocusCss,
|
|
34
34
|
useTouchSurface,
|
|
35
35
|
isTouchSurface,
|
|
36
36
|
recipeFamilies,
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
} from "@multiplatform.one/theme";
|
|
51
51
|
import { formButtonColors, formCommonColors, formInputColors } from "../shared/colorRamps";
|
|
52
52
|
import { useControlGrouped } from "../shared/groupContext";
|
|
53
|
+
import { nativeAutoFocus } from "../shared/nativeAutoFocus";
|
|
53
54
|
import { useIsInTableCell } from "../shared/tableCellContext";
|
|
54
55
|
import { useFieldA11y, useFieldDescribedBy } from "../fieldLayout";
|
|
55
56
|
|
|
@@ -159,22 +160,6 @@ export const useForwardFocus = (target: RefObject<TamaguiElement | null>) => {
|
|
|
159
160
|
// Default group styles
|
|
160
161
|
// ---------------------------------------------------------------------------
|
|
161
162
|
|
|
162
|
-
/** Resting outline: transparent + 0 width so blur never lands on theme `$outlineColor`. */
|
|
163
|
-
const inputOutlineRest = {
|
|
164
|
-
outlineWidth: 0,
|
|
165
|
-
outlineColor: "transparent",
|
|
166
|
-
outlineStyle: "solid" as any,
|
|
167
|
-
} as const;
|
|
168
|
-
|
|
169
|
-
const inputOutlineFocus = {
|
|
170
|
-
outlineColor: "$outlineColor",
|
|
171
|
-
outlineWidth: 2,
|
|
172
|
-
outlineStyle: "solid" as any,
|
|
173
|
-
// Inset: Input.Box clips children with overflow:hidden; an outer +2px
|
|
174
|
-
// ring is severed (LC-71 clipping carve-out).
|
|
175
|
-
outlineOffset: -2,
|
|
176
|
-
} as const;
|
|
177
|
-
|
|
178
163
|
/**
|
|
179
164
|
* LC-71 field anatomy (Polaris Connected / Primer TextInputWrapper / Spectrum):
|
|
180
165
|
* one painted Box owns border + radius + ring; Icon/prefix/suffix live inside
|
|
@@ -191,37 +176,9 @@ const AREA_NO_OUTLINE = {
|
|
|
191
176
|
|
|
192
177
|
type BoxOverflow = "hidden" | "visible";
|
|
193
178
|
|
|
194
|
-
export
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
): "inset" | "outset" | undefined {
|
|
198
|
-
if (!paintsRing) return undefined;
|
|
199
|
-
return overflow === "hidden" ? "inset" : "outset";
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export function boxRingOffset(mode: "inset" | "outset" | undefined): number {
|
|
203
|
-
// Both branches are LC-71 §4 sanctioned offsets: the clipping inset when the
|
|
204
|
-
// Box clips its adornments, the shape halo when it does not (MPO-92).
|
|
205
|
-
return mode === "outset" ? FOCUS_RING_HALO_OFFSET : FOCUS_RING_CLIPPED_OFFSET;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export const inputPartsRingCss = `/* LC-71: ring on Box (adornments inside); Area never outlines.
|
|
209
|
-
Inset iff the Box clips (overflow:hidden). Do not :has(:focus-visible) on
|
|
210
|
-
every descendant — SearchInput clear ✕ is a second focusable. */
|
|
211
|
-
[data-mp-input-box][data-mp-ring="inset"]:has(input:focus),
|
|
212
|
-
[data-mp-input-box][data-mp-ring="inset"]:has(textarea:focus),
|
|
213
|
-
[data-mp-input-box][data-mp-ring="inset"]:has([data-mp-input-area]:focus),
|
|
214
|
-
[data-mp-input-box][data-mp-ring="inset"]:focus-visible {
|
|
215
|
-
outline: 2px solid var(--outlineColor, var(--c-outlineColor, CanvasText)) !important;
|
|
216
|
-
outline-offset: -2px !important;
|
|
217
|
-
}
|
|
218
|
-
[data-mp-input-box][data-mp-ring="outset"]:has(input:focus),
|
|
219
|
-
[data-mp-input-box][data-mp-ring="outset"]:has(textarea:focus),
|
|
220
|
-
[data-mp-input-box][data-mp-ring="outset"]:has([data-mp-input-area]:focus),
|
|
221
|
-
[data-mp-input-box][data-mp-ring="outset"]:focus-visible {
|
|
222
|
-
outline: 2px solid var(--outlineColor, var(--c-outlineColor, CanvasText)) !important;
|
|
223
|
-
outline-offset: 2px !important;
|
|
224
|
-
}
|
|
179
|
+
export const inputPartsRingCss = `/* FZ-7717: a focused Box takes the shared field focus look; Area never outlines. */
|
|
180
|
+
${fieldFocusCss("[data-mp-input-box][data-mp-field-focus]")}
|
|
181
|
+
${fieldFocusCss("[data-mp-input-box][data-mp-field-focus].mp-field-focus-deep", { deep: true })}
|
|
225
182
|
[data-mp-input-area],
|
|
226
183
|
[data-mp-input-area]:focus,
|
|
227
184
|
[data-mp-input-area]:focus-visible,
|
|
@@ -249,19 +206,14 @@ export function ensureInputPartsFocusRing(): void {
|
|
|
249
206
|
}
|
|
250
207
|
|
|
251
208
|
function webBoxRingAttrs(
|
|
252
|
-
|
|
253
|
-
paintsRing: boolean,
|
|
209
|
+
paintsFocus: boolean,
|
|
254
210
|
extraClass?: string,
|
|
255
211
|
): Record<string, unknown> | undefined {
|
|
256
212
|
if (!isWeb) return undefined;
|
|
257
|
-
const mode = boxRingMode(overflow, paintsRing);
|
|
258
|
-
const className = [paintsRing ? "mp-composite-ring" : undefined, extraClass]
|
|
259
|
-
.filter(Boolean)
|
|
260
|
-
.join(" ");
|
|
261
213
|
return {
|
|
262
|
-
...(
|
|
214
|
+
...(extraClass ? { className: extraClass } : undefined),
|
|
263
215
|
"data-mp-input-box": "true",
|
|
264
|
-
...(
|
|
216
|
+
...(paintsFocus ? { "data-mp-field-focus": "true" } : undefined),
|
|
265
217
|
};
|
|
266
218
|
}
|
|
267
219
|
|
|
@@ -292,23 +244,14 @@ export const defaultInputGroupStyles = {
|
|
|
292
244
|
backgroundColor: formInputColors.background.base,
|
|
293
245
|
|
|
294
246
|
minWidth: 0,
|
|
295
|
-
...
|
|
247
|
+
...FIELD_FOCUS_REST,
|
|
296
248
|
|
|
297
249
|
hoverStyle: {
|
|
298
250
|
borderColor: formInputColors.border.hover,
|
|
299
251
|
},
|
|
300
252
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// button-like Boxes (Select, pagination) do not ring on mouse click.
|
|
304
|
-
focusStyle: {
|
|
305
|
-
borderColor: formInputColors.border.focus,
|
|
306
|
-
},
|
|
307
|
-
|
|
308
|
-
focusVisibleStyle: {
|
|
309
|
-
borderColor: formInputColors.border.focus,
|
|
310
|
-
...inputOutlineFocus,
|
|
311
|
-
},
|
|
253
|
+
focusStyle: FIELD_FOCUS_STYLE,
|
|
254
|
+
focusVisibleStyle: FIELD_FOCUS_STYLE,
|
|
312
255
|
} as const;
|
|
313
256
|
|
|
314
257
|
// ---------------------------------------------------------------------------
|
|
@@ -324,9 +267,6 @@ const InputGroupFrame = styled(XGroup, {
|
|
|
324
267
|
alignItems: "center",
|
|
325
268
|
context: InputContext,
|
|
326
269
|
overflow: "hidden",
|
|
327
|
-
// LC-71: className on XGroup is best-effort (often dropped). The styleable
|
|
328
|
-
// spread stamps data-mp-input-box / data-mp-ring; CSS keys off those.
|
|
329
|
-
...(isWeb ? { className: "mp-composite-ring" } : {}),
|
|
330
270
|
|
|
331
271
|
variants: {
|
|
332
272
|
touch: { true: {}, false: {} },
|
|
@@ -375,11 +315,9 @@ function wrapNativePressable(
|
|
|
375
315
|
|
|
376
316
|
const InputGroupImpl = InputGroupFrame.styleable<{
|
|
377
317
|
/**
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
* sits outside the border box (outline + offset), so a covering panel can
|
|
382
|
-
* never hide it — it ghosts around the panel's corners as a doubled edge.
|
|
318
|
+
* Kept for callers. Since FZ-7717 the field focus look is the Box's own
|
|
319
|
+
* accent border, which a covering panel hides, so there is no ring left to
|
|
320
|
+
* suppress.
|
|
383
321
|
*/
|
|
384
322
|
suppressFocusRing?: boolean;
|
|
385
323
|
/**
|
|
@@ -398,7 +336,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
398
336
|
children,
|
|
399
337
|
onPress,
|
|
400
338
|
disabled,
|
|
401
|
-
suppressFocusRing,
|
|
339
|
+
suppressFocusRing: _suppressFocusRing,
|
|
402
340
|
recipeFamily = "control",
|
|
403
341
|
sizeRecipeEscape,
|
|
404
342
|
height: heightProp,
|
|
@@ -417,27 +355,21 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
417
355
|
const inTableCell = useIsInTableCell();
|
|
418
356
|
// Native Pressable owns onPress; do not also pass it to XGroup (double-fire).
|
|
419
357
|
const framePressProps = isWeb ? { onPress, disabled } : { disabled };
|
|
420
|
-
// Standalone Box clips children to radius
|
|
421
|
-
//
|
|
358
|
+
// Standalone Box clips children to radius. Grouped / in-cell frames leave
|
|
359
|
+
// overflow visible and leave focus to their container.
|
|
422
360
|
// LC-85: on native, an elevation token must not share a clipsToBounds layer
|
|
423
|
-
// with the shadow (iOS masks the layer's own drop shadow).
|
|
424
|
-
|
|
425
|
-
const paintsRing = !grouped && !inTableCell;
|
|
361
|
+
// with the shadow (iOS masks the layer's own drop shadow).
|
|
362
|
+
const paintsFocus = !grouped && !inTableCell;
|
|
426
363
|
const hasElevation = knobProps.elevation != null;
|
|
427
364
|
const hasWebPressSlop =
|
|
428
365
|
isWeb && (props as { "data-mp-press-slop"?: string })["data-mp-press-slop"] != null;
|
|
429
366
|
const boxOverflow: BoxOverflow =
|
|
430
|
-
|
|
431
|
-
const ringMode = boxRingMode(boxOverflow, paintsRing);
|
|
367
|
+
paintsFocus && !(hasElevation && !isWeb) && !hasWebPressSlop ? "hidden" : "visible";
|
|
432
368
|
if (isWeb) {
|
|
433
369
|
ensureCompositeFocusRing();
|
|
434
370
|
ensureInputPartsFocusRing();
|
|
435
371
|
}
|
|
436
|
-
const boxRingAttrs = webBoxRingAttrs(
|
|
437
|
-
boxOverflow,
|
|
438
|
-
paintsRing,
|
|
439
|
-
(props as { className?: string }).className,
|
|
440
|
-
);
|
|
372
|
+
const boxRingAttrs = webBoxRingAttrs(paintsFocus, (props as { className?: string }).className);
|
|
441
373
|
|
|
442
374
|
// DG-A11Y-01 / DG-A11Y-03 — DEV guardrails (tree-shaken in production).
|
|
443
375
|
warnPositiveTabIndex({
|
|
@@ -577,29 +509,6 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
577
509
|
);
|
|
578
510
|
}
|
|
579
511
|
|
|
580
|
-
// Covered by an overlay panel (see prop doc): keep the focus border color
|
|
581
|
-
// but draw no ring on either focus path. This is an intentional a11y
|
|
582
|
-
// exception — the open panel is the focus affordance while it covers this
|
|
583
|
-
// box. Hoisted (with `undefined` in the union) so the JSX spread does not
|
|
584
|
-
// re-specify focusStyle/focusVisibleStyle literally (TS2783 under the
|
|
585
|
-
// build tsconfig).
|
|
586
|
-
const suppressedRingProps = suppressFocusRing
|
|
587
|
-
? {
|
|
588
|
-
focusStyle: { borderColor: formInputColors.border.focus, ...inputOutlineRest },
|
|
589
|
-
focusVisibleStyle: {
|
|
590
|
-
borderColor: formInputColors.border.focus,
|
|
591
|
-
...inputOutlineRest,
|
|
592
|
-
},
|
|
593
|
-
}
|
|
594
|
-
: undefined;
|
|
595
|
-
|
|
596
|
-
const focusRing = ensureFocusVisibleRing({
|
|
597
|
-
...inputOutlineFocus,
|
|
598
|
-
...control.focusKnobProps,
|
|
599
|
-
...control.focusVisibleKnobProps,
|
|
600
|
-
outlineOffset: boxRingOffset(ringMode),
|
|
601
|
-
});
|
|
602
|
-
|
|
603
512
|
return (
|
|
604
513
|
<FocusContext.Provider focused={focused} setFocused={setFocused}>
|
|
605
514
|
{wrapNativePressable(
|
|
@@ -623,45 +532,15 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
623
532
|
pressStyle={{
|
|
624
533
|
...control.pressKnobProps,
|
|
625
534
|
}}
|
|
626
|
-
focusStyle={
|
|
627
|
-
|
|
628
|
-
...control.focusKnobProps,
|
|
629
|
-
}}
|
|
630
|
-
focusVisibleStyle={ensureFocusVisibleRing({
|
|
631
|
-
borderColor: formInputColors.border.focus,
|
|
632
|
-
...inputOutlineFocus,
|
|
633
|
-
...control.focusVisibleKnobProps,
|
|
634
|
-
outlineOffset: boxRingOffset(ringMode),
|
|
635
|
-
})}
|
|
535
|
+
focusStyle={FIELD_FOCUS_STYLE}
|
|
536
|
+
focusVisibleStyle={FIELD_FOCUS_STYLE}
|
|
636
537
|
{...props}
|
|
637
538
|
{...passthroughSizeProps}
|
|
638
539
|
{...insetPadProps}
|
|
639
540
|
{...sizeRecipeEscapeOverride}
|
|
640
541
|
{...framePressProps}
|
|
641
542
|
{...boxRingAttrs}
|
|
642
|
-
{...(focused
|
|
643
|
-
? {
|
|
644
|
-
// Text-entry carve-out (LC-71): inner Area focus means typing
|
|
645
|
-
// is next, so the Box rings on any focus — including click.
|
|
646
|
-
// CSS `[data-mp-ring]` is the sync path; this is the token-
|
|
647
|
-
// resolved backup (and the native path). Button-like Boxes
|
|
648
|
-
// (Select) do not set `focused` (no Area onFocus).
|
|
649
|
-
borderColor: formInputColors.border.focus,
|
|
650
|
-
...focusRing,
|
|
651
|
-
}
|
|
652
|
-
: isWeb
|
|
653
|
-
? {
|
|
654
|
-
// Explicit rest — avoid leaving theme `$outlineColor` (near-white in
|
|
655
|
-
// dark) as the computed outline-color while width settles.
|
|
656
|
-
// Keep outline-transparent rest (border-flicker fix); do not warn.
|
|
657
|
-
...inputOutlineRest,
|
|
658
|
-
}
|
|
659
|
-
: // FZ-7718: on iOS the outline's width and offset changing as
|
|
660
|
-
// the field takes focus makes it resign first responder, so a
|
|
661
|
-
// programmatic focus (Return to the next field) never sticks.
|
|
662
|
-
// Native keeps the ring's geometry at rest and fades its color.
|
|
663
|
-
{ ...focusRing, outlineColor: "transparent" })}
|
|
664
|
-
{...suppressedRingProps}
|
|
543
|
+
{...(focused ? FIELD_FOCUS_STYLE : FIELD_FOCUS_REST)}
|
|
665
544
|
// LC-40 DISABLED-VISIBLE: the input frame is text-bearing chrome —
|
|
666
545
|
// keepLabel washes fill/border (value text keeps >= AA) and
|
|
667
546
|
// dimWhole leaves the dim to the FieldLayout assembly. Read-only
|
|
@@ -894,6 +773,7 @@ const InputAreaImpl = InputFrame.styleable<{
|
|
|
894
773
|
: undefined
|
|
895
774
|
}
|
|
896
775
|
{...props}
|
|
776
|
+
{...nativeAutoFocus(props as { autoFocus?: boolean; autoFocusNative?: boolean })}
|
|
897
777
|
{...(flexProp != null ? { flex: flexProp } : undefined)}
|
|
898
778
|
{...(widthProp != null
|
|
899
779
|
? { width: widthProp, minWidth: minWidthProp, maxWidth: maxWidthProp }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { inspectDesign } from "@multiplatform.one/config/design-lint";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
|
|
6
|
+
const src = join(process.cwd(), "src");
|
|
7
|
+
|
|
8
|
+
function sources(dir: string): string[] {
|
|
9
|
+
return readdirSync(dir).flatMap((entry) => {
|
|
10
|
+
const path = join(dir, entry);
|
|
11
|
+
if (statSync(path).isDirectory()) return sources(path);
|
|
12
|
+
return /\.tsx?$/.test(entry) && !/\.(spec|stories|test)\./.test(entry) ? [path] : [];
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe("FZ-7717: every MPO field takes its focus look from FIELD_FOCUS_STYLE", () => {
|
|
17
|
+
const files = [...sources(join(src, "fields")), ...sources(join(src, "InputParts"))];
|
|
18
|
+
|
|
19
|
+
it("no field paints its own focus ring or shadow", () => {
|
|
20
|
+
const hits = files.flatMap((file) =>
|
|
21
|
+
(inspectDesign(readFileSync(file, "utf8"), file) as string[]).filter((error) =>
|
|
22
|
+
error.includes("[field-focus]"),
|
|
23
|
+
),
|
|
24
|
+
);
|
|
25
|
+
expect(hits).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("Input.Box, the Box every text field renders, uses the shared look", () => {
|
|
29
|
+
const box = readFileSync(join(src, "InputParts", "index.tsx"), "utf8");
|
|
30
|
+
expect(box).toContain("focusStyle={FIELD_FOCUS_STYLE}");
|
|
31
|
+
expect(box).toContain("focusVisibleStyle={FIELD_FOCUS_STYLE}");
|
|
32
|
+
expect(box).not.toMatch(
|
|
33
|
+
/outlineOffset|FOCUS_RING_(?:HALO|CLIPPED)_OFFSET|ensureFocusVisibleRing/,
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("the detector catches a field that forks the look", () => {
|
|
38
|
+
const forked = inspectDesign(
|
|
39
|
+
"const x = <Input.Box focusStyle={{ outlineWidth: 2, outlineOffset: 2 }} />;",
|
|
40
|
+
"Forked.tsx",
|
|
41
|
+
) as string[];
|
|
42
|
+
expect(forked.join("\n")).toMatch(/\[field-focus\]/);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -51,7 +51,7 @@ describe("DatePicker", () => {
|
|
|
51
51
|
const label = result.container.querySelector("label") as HTMLLabelElement;
|
|
52
52
|
expect(trigger).toBeTruthy();
|
|
53
53
|
expect(trigger.contains(input)).toBe(true);
|
|
54
|
-
expect(trigger.
|
|
54
|
+
expect(trigger.getAttribute("data-mp-field-focus")).toBe("true");
|
|
55
55
|
expect(trigger.getAttribute("tabindex")).toBe("0");
|
|
56
56
|
expect(trigger.getAttribute("role")).toBe("combobox");
|
|
57
57
|
expect(input.tabIndex).toBe(-1);
|
|
@@ -197,7 +197,7 @@ describe("DateRangePicker", () => {
|
|
|
197
197
|
const result = renderWithProviders(<DateRangePicker label="Range" name="range" />);
|
|
198
198
|
const input = result.container.querySelector("input");
|
|
199
199
|
expect(input?.className).toMatch(/mp-input-area/);
|
|
200
|
-
const box = result.container.querySelector("
|
|
200
|
+
const box = result.container.querySelector("[data-mp-field-focus]");
|
|
201
201
|
expect(box).toBeTruthy();
|
|
202
202
|
expect(box?.contains(input)).toBe(true);
|
|
203
203
|
});
|
|
@@ -162,7 +162,7 @@ describe("MultiDatePicker", () => {
|
|
|
162
162
|
const result = renderWithProviders(<MultiDatePicker label="Dates" name="dates" />);
|
|
163
163
|
const input = result.container.querySelector("input");
|
|
164
164
|
expect(input?.className).toMatch(/mp-input-area/);
|
|
165
|
-
const box = result.container.querySelector("
|
|
165
|
+
const box = result.container.querySelector("[data-mp-field-focus]");
|
|
166
166
|
expect(box).toBeTruthy();
|
|
167
167
|
expect(box?.contains(input)).toBe(true);
|
|
168
168
|
});
|
|
@@ -207,12 +207,12 @@ describe("Duration", () => {
|
|
|
207
207
|
expect(sSize).not.toBe(lSize);
|
|
208
208
|
});
|
|
209
209
|
|
|
210
|
-
it("
|
|
210
|
+
it("focuses the outer box, never the inner segments (FZ-7717)", () => {
|
|
211
211
|
const result = renderWithProviders(<Duration label="Ring" value={3600} />);
|
|
212
212
|
const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
|
|
213
213
|
const hours = result.container.querySelector('input[aria-label="Hours"]') as HTMLInputElement;
|
|
214
214
|
expect(box).toBeTruthy();
|
|
215
|
-
expect(box.
|
|
215
|
+
expect(box.getAttribute("data-mp-field-focus")).toBe("true");
|
|
216
216
|
expect(box.contains(hours)).toBe(true);
|
|
217
217
|
expect(hours.className).toMatch(/mp-input-area/);
|
|
218
218
|
});
|
|
@@ -30,7 +30,7 @@ describe("Input copy (CopyField slot)", () => {
|
|
|
30
30
|
(el) => el !== input && el !== copy,
|
|
31
31
|
);
|
|
32
32
|
expect(extraStops).toHaveLength(0);
|
|
33
|
-
expect(result.container.querySelector("
|
|
33
|
+
expect(result.container.querySelector("[data-mp-field-focus]")).toBeTruthy();
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("empty omits the cap so there is one tab stop", () => {
|
|
@@ -250,7 +250,7 @@ describe("Input", () => {
|
|
|
250
250
|
});
|
|
251
251
|
|
|
252
252
|
describe("LC-71 RING-ANATOMY", () => {
|
|
253
|
-
it("
|
|
253
|
+
it("focuses the Box (icons included), never the inner input", () => {
|
|
254
254
|
const result = renderWithProviders(
|
|
255
255
|
<Input
|
|
256
256
|
label="Search"
|
|
@@ -262,7 +262,7 @@ describe("Input", () => {
|
|
|
262
262
|
const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
|
|
263
263
|
const input = result.container.querySelector("input") as HTMLInputElement;
|
|
264
264
|
expect(box).toBeTruthy();
|
|
265
|
-
expect(box.
|
|
265
|
+
expect(box.getAttribute("data-mp-field-focus")).toBe("true");
|
|
266
266
|
expect(box.contains(result.getByTestId("leading"))).toBe(true);
|
|
267
267
|
expect(box.contains(result.getByTestId("trailing"))).toBe(true);
|
|
268
268
|
expect(box.contains(input)).toBe(true);
|
|
@@ -282,7 +282,7 @@ describe("Input", () => {
|
|
|
282
282
|
);
|
|
283
283
|
const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
|
|
284
284
|
const input = result.container.querySelector("input") as HTMLInputElement;
|
|
285
|
-
expect(box.
|
|
285
|
+
expect(box.getAttribute("data-mp-field-focus")).toBe("true");
|
|
286
286
|
expect(box.contains(result.getByTestId("leading"))).toBe(true);
|
|
287
287
|
expect(input.className).toMatch(/mp-input-area/);
|
|
288
288
|
});
|
|
@@ -451,13 +451,12 @@ describe("Input", () => {
|
|
|
451
451
|
expect(box.className).toContain("_h-48px");
|
|
452
452
|
});
|
|
453
453
|
|
|
454
|
-
it("focus
|
|
454
|
+
it("focus is the shared accent border, not an offset ring (FZ-7717)", () => {
|
|
455
455
|
const result = renderWithProviders(<Input label="Name" name="n" />);
|
|
456
456
|
const box = result.container.querySelector("[data-ring-target='box']") as HTMLElement;
|
|
457
|
-
expect(box.getAttribute("data-
|
|
458
|
-
expect(
|
|
459
|
-
|
|
460
|
-
);
|
|
457
|
+
expect(box.getAttribute("data-mp-field-focus")).toBe("true");
|
|
458
|
+
expect(box.getAttribute("data-ring-offset")).toBeNull();
|
|
459
|
+
expect(document.getElementById("mp-input-field-ring-offset")).toBeNull();
|
|
461
460
|
});
|
|
462
461
|
|
|
463
462
|
it("paints the field label at weight 400 (R7 / §6.1)", () => {
|
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
SizeTokens,
|
|
12
12
|
TamaguiElement,
|
|
13
13
|
} from "tamagui";
|
|
14
|
-
import {
|
|
14
|
+
import { Text } from "tamagui";
|
|
15
15
|
import { Skeleton } from "../../Skeleton";
|
|
16
16
|
import { resolveFieldInputProps } from "../../fieldDefaults";
|
|
17
17
|
import { Field, FieldLayout } from "../../fieldLayout";
|
|
@@ -31,23 +31,6 @@ import { useKeyboardChain } from "../../keyboard";
|
|
|
31
31
|
|
|
32
32
|
type InputAreaProps = ComponentProps<typeof InputParts.Area>;
|
|
33
33
|
|
|
34
|
-
/** F1 / reference §10: standalone Input rings at offset 0, not the inset −2. */
|
|
35
|
-
const INPUT_FIELD_RING_STYLE_ID = "mp-input-field-ring-offset";
|
|
36
|
-
|
|
37
|
-
export function ensureInputFieldRingOffset(): void {
|
|
38
|
-
if (typeof document === "undefined") return;
|
|
39
|
-
if (document.getElementById(INPUT_FIELD_RING_STYLE_ID)) return;
|
|
40
|
-
const tag = document.createElement("style");
|
|
41
|
-
tag.id = INPUT_FIELD_RING_STYLE_ID;
|
|
42
|
-
tag.textContent = `[data-mp-input-field][data-mp-ring="inset"]:has(input:focus),
|
|
43
|
-
[data-mp-input-field][data-mp-ring="inset"]:has(textarea:focus),
|
|
44
|
-
[data-mp-input-field][data-mp-ring="inset"]:has([data-mp-input-area]:focus),
|
|
45
|
-
[data-mp-input-field][data-mp-ring="inset"]:focus-visible {
|
|
46
|
-
outline-offset: 0px !important;
|
|
47
|
-
}`;
|
|
48
|
-
document.head.appendChild(tag);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
34
|
export interface InputProps {
|
|
52
35
|
name?: string;
|
|
53
36
|
form?: AnyFormApi;
|
|
@@ -165,7 +148,6 @@ export function Input({
|
|
|
165
148
|
});
|
|
166
149
|
const inputRef = useRef<TamaguiElement>(null);
|
|
167
150
|
const focusTrigger = useForwardFocus(inputRef);
|
|
168
|
-
if (isWeb) ensureInputFieldRingOffset();
|
|
169
151
|
|
|
170
152
|
const resolvedValidators = useResolvedValidators(required, validators, label, name);
|
|
171
153
|
|
|
@@ -199,7 +181,6 @@ export function Input({
|
|
|
199
181
|
"data-ring-target": "box",
|
|
200
182
|
"data-radius-class": "DEFAULT",
|
|
201
183
|
"data-radius-part": "Input",
|
|
202
|
-
"data-ring-offset": "0",
|
|
203
184
|
"data-mp-input-field": "true",
|
|
204
185
|
...(belowFloor ? { hitSlop: pressTargetHitSlop(visualHeight) } : undefined),
|
|
205
186
|
} as const;
|