@multiplatform.one/forms 7.67.0 → 7.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/AdaptivePopup/index.cjs +45 -5
- package/dist/cjs/AdaptivePopup/index.native.js +48 -6
- package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
- package/dist/cjs/Button/glass.cjs +30 -0
- package/dist/cjs/Button/glass.native.js +47 -0
- package/dist/cjs/Button/glass.native.js.map +1 -0
- package/dist/cjs/Button/index.cjs +157 -28
- package/dist/cjs/Button/index.native.js +158 -29
- package/dist/cjs/Button/index.native.js.map +1 -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.cjs +6 -8
- package/dist/cjs/ContextualSaveBar/index.native.js +9 -11
- 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.cjs +0 -1
- package/dist/cjs/DescriptionList/index.native.js +2 -3
- 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/RegularPanel.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/compactFace.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/containingBlock.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/regularPlacement.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/trailingAction.native.js +1 -1
- package/dist/cjs/FloatingPanel/trailingAction.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/PasswordReveal.native.js.map +1 -1
- 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.cjs +7 -8
- package/dist/cjs/fields/Barcode/BarcodeScanner.native.js +8 -9
- package/dist/cjs/fields/Barcode/BarcodeScanner.native.js.map +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/SystemColorField.native.js.map +1 -1
- package/dist/cjs/fields/ColorPicker/index.native.js +2 -2
- 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/ColorPicker/systemColorWell.gnome.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/authorOptions.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/index.native.js +5 -5
- 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.cjs +83 -60
- package/dist/cjs/fields/FileUpload/index.native.js +98 -75
- 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.cjs +7 -8
- package/dist/cjs/fields/Geolocation/index.native.js +12 -13
- 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.cjs +4 -6
- package/dist/cjs/fields/ImageField/index.native.js +6 -8
- package/dist/cjs/fields/ImageField/index.native.js.map +1 -1
- package/dist/cjs/fields/Input/index.native.js +3 -3
- 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.native.js +3 -3
- package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
- 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.native.js +3 -3
- 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.native.js +2 -2
- package/dist/cjs/fields/SearchInput/index.native.js.map +1 -1
- package/dist/cjs/fields/Select/InlineChoices.native.js.map +1 -1
- package/dist/cjs/fields/Select/SheetPickerRow.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/Select/shouldInlineChoices.native.js.map +1 -1
- package/dist/cjs/fields/Signature/index.native.js +2 -2
- 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.cjs +20 -28
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +20 -28
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/sheetKeyboard.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.cjs +8 -1
- package/dist/cjs/index.native.js +52 -45
- 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/choiceRowPress.native.js.map +1 -1
- package/dist/cjs/shared/colorRamps.cjs +0 -8
- package/dist/cjs/shared/colorRamps.native.js +0 -8
- package/dist/cjs/shared/colorRamps.native.js.map +1 -1
- package/dist/cjs/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.native.js.map +1 -1
- package/dist/cjs/shared/overlaySizeClass.native.js.map +1 -1
- package/dist/cjs/shared/overlayStack.native.js.map +1 -1
- 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/restoreRetries.native.js.map +1 -1
- package/dist/cjs/shared/sheetNavigation.native.js.map +1 -1
- package/dist/cjs/shared/systemControlModules.gnome.native.js.map +1 -1
- package/dist/cjs/shared/systemControls.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/touchWebPicker.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/standardActions.cjs +117 -0
- package/dist/cjs/standardActions.native.js +120 -0
- package/dist/cjs/standardActions.native.js.map +1 -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/AdaptivePopup/index.mjs +45 -5
- package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
- package/dist/esm/AdaptivePopup/index.native.js +47 -5
- package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
- package/dist/esm/Button/glass.mjs +5 -0
- package/dist/esm/Button/glass.mjs.map +1 -0
- package/dist/esm/Button/glass.native.js +19 -0
- package/dist/esm/Button/glass.native.js.map +1 -0
- package/dist/esm/Button/index.mjs +153 -28
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +153 -28
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/ContextualSaveBar/index.mjs +7 -9
- package/dist/esm/ContextualSaveBar/index.mjs.map +1 -1
- package/dist/esm/ContextualSaveBar/index.native.js +7 -9
- package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/esm/DescriptionList/index.mjs +0 -1
- package/dist/esm/DescriptionList/index.mjs.map +1 -1
- package/dist/esm/DescriptionList/index.native.js +0 -1
- package/dist/esm/DescriptionList/index.native.js.map +1 -1
- package/dist/esm/fields/Barcode/BarcodeScanner.mjs +8 -9
- package/dist/esm/fields/Barcode/BarcodeScanner.mjs.map +1 -1
- package/dist/esm/fields/Barcode/BarcodeScanner.native.js +8 -9
- package/dist/esm/fields/Barcode/BarcodeScanner.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/index.mjs +84 -61
- package/dist/esm/fields/FileUpload/index.mjs.map +1 -1
- package/dist/esm/fields/FileUpload/index.native.js +97 -74
- package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/index.mjs +8 -9
- package/dist/esm/fields/Geolocation/index.mjs.map +1 -1
- package/dist/esm/fields/Geolocation/index.native.js +8 -9
- package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
- package/dist/esm/fields/ImageField/index.mjs +6 -8
- package/dist/esm/fields/ImageField/index.mjs.map +1 -1
- package/dist/esm/fields/ImageField/index.native.js +6 -8
- package/dist/esm/fields/ImageField/index.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +20 -28
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +20 -28
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/esm/index.mjs +3 -2
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +3 -2
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/shared/colorRamps.mjs +0 -8
- package/dist/esm/shared/colorRamps.mjs.map +1 -1
- package/dist/esm/shared/colorRamps.native.js +0 -8
- package/dist/esm/shared/colorRamps.native.js.map +1 -1
- package/dist/esm/standardActions.mjs +91 -0
- package/dist/esm/standardActions.mjs.map +1 -0
- package/dist/esm/standardActions.native.js +91 -0
- package/dist/esm/standardActions.native.js.map +1 -0
- package/dist/jsx/AdaptivePopup/index.mjs +45 -5
- package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
- package/dist/jsx/AdaptivePopup/index.native.js +47 -5
- package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
- package/dist/jsx/Button/glass.mjs +5 -0
- package/dist/jsx/Button/glass.mjs.map +1 -0
- package/dist/jsx/Button/glass.native.js +47 -0
- package/dist/jsx/Button/glass.native.js.map +1 -0
- package/dist/jsx/Button/index.mjs +153 -28
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +156 -27
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/ContextualSaveBar/index.mjs +7 -9
- package/dist/jsx/ContextualSaveBar/index.mjs.map +1 -1
- package/dist/jsx/ContextualSaveBar/index.native.js +6 -8
- package/dist/jsx/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/jsx/DescriptionList/index.mjs +0 -1
- package/dist/jsx/DescriptionList/index.mjs.map +1 -1
- package/dist/jsx/DescriptionList/index.native.js +0 -1
- package/dist/jsx/DescriptionList/index.native.js.map +1 -1
- package/dist/jsx/fields/Barcode/BarcodeScanner.mjs +8 -9
- package/dist/jsx/fields/Barcode/BarcodeScanner.mjs.map +1 -1
- package/dist/jsx/fields/Barcode/BarcodeScanner.native.js +7 -8
- package/dist/jsx/fields/Barcode/BarcodeScanner.native.js.map +1 -1
- package/dist/jsx/fields/FileUpload/index.mjs +84 -61
- package/dist/jsx/fields/FileUpload/index.mjs.map +1 -1
- package/dist/jsx/fields/FileUpload/index.native.js +96 -73
- package/dist/jsx/fields/FileUpload/index.native.js.map +1 -1
- package/dist/jsx/fields/Geolocation/index.mjs +8 -9
- package/dist/jsx/fields/Geolocation/index.mjs.map +1 -1
- package/dist/jsx/fields/Geolocation/index.native.js +7 -8
- package/dist/jsx/fields/Geolocation/index.native.js.map +1 -1
- package/dist/jsx/fields/ImageField/index.mjs +6 -8
- package/dist/jsx/fields/ImageField/index.mjs.map +1 -1
- package/dist/jsx/fields/ImageField/index.native.js +4 -6
- package/dist/jsx/fields/ImageField/index.native.js.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +20 -28
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +20 -28
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/jsx/index.js +3 -2
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +3 -2
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +7 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/colorRamps.mjs +0 -8
- package/dist/jsx/shared/colorRamps.mjs.map +1 -1
- package/dist/jsx/shared/colorRamps.native.js +0 -8
- package/dist/jsx/shared/colorRamps.native.js.map +1 -1
- package/dist/jsx/standardActions.mjs +91 -0
- package/dist/jsx/standardActions.mjs.map +1 -0
- package/dist/jsx/standardActions.native.js +120 -0
- package/dist/jsx/standardActions.native.js.map +1 -0
- package/package.json +12 -8
- package/src/AdaptivePopup/AdaptivePopup.spec.tsx +44 -0
- package/src/AdaptivePopup/AdaptivePopup.stories.tsx +12 -32
- package/src/AdaptivePopup/index.tsx +65 -13
- package/src/Button/Button.disabledGlyph.spec.tsx +111 -0
- package/src/Button/Button.iconButton.spec.tsx +279 -0
- package/src/Button/Button.stories.tsx +59 -3
- package/src/Button/glass.native.ts +38 -0
- package/src/Button/glass.ts +18 -0
- package/src/Button/index.tsx +272 -40
- package/src/ContextualSaveBar/ContextualSaveBar.spec.tsx +3 -1
- package/src/ContextualSaveBar/ContextualSaveBar.stories.tsx +2 -2
- package/src/ContextualSaveBar/index.tsx +7 -10
- package/src/ControlGroup/ControlGroup.stories.tsx +3 -2
- package/src/DescriptionList/index.tsx +0 -1
- package/src/ErrorSummary.stories.tsx +2 -1
- package/src/FieldLayout.stories.tsx +3 -2
- package/src/FloatingPanel/FloatingPanel.stories.tsx +6 -10
- package/src/Form/Form.stories.tsx +6 -5
- package/src/errorSummaryStories.spec.tsx +4 -4
- package/src/fields/Barcode/BarcodeScanner.native.tsx +10 -9
- package/src/fields/Barcode/BarcodeScanner.tsx +10 -9
- package/src/fields/Checkbox/Checkbox.stories.tsx +3 -3
- package/src/fields/Checkbox/CheckboxGroup.stories.tsx +2 -2
- package/src/fields/ColorPicker/ColorPicker.stories.tsx +2 -2
- package/src/fields/Combobox/Combobox.stories.tsx +2 -2
- package/src/fields/DatePicker/DatePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/DateRangePicker.stories.tsx +2 -2
- package/src/fields/DatePicker/DatetimePicker.stories.tsx +2 -1
- package/src/fields/DatePicker/MonthPicker.stories.tsx +2 -2
- package/src/fields/DatePicker/MultiDatePicker.stories.tsx +2 -2
- package/src/fields/FileUpload/FileUpload.spec.tsx +11 -6
- package/src/fields/FileUpload/FileUpload.stories.tsx +2 -2
- package/src/fields/FileUpload/index.tsx +101 -77
- package/src/fields/Geolocation/index.tsx +12 -7
- package/src/fields/ImageField/ImageField.spec.tsx +5 -5
- package/src/fields/ImageField/ImageField.stories.tsx +2 -2
- package/src/fields/ImageField/index.tsx +6 -9
- package/src/fields/Input/Input.stories.tsx +2 -2
- package/src/fields/MentionInput/MentionInput.stories.tsx +2 -1
- package/src/fields/Progress/Progress.stories.tsx +2 -1
- package/src/fields/RadioGroup/RadioGroup.stories.tsx +2 -1
- package/src/fields/Signature/Signature.stories.tsx +2 -2
- package/src/fields/Stepper/Stepper.stories.tsx +2 -2
- package/src/fields/TextArea/TextArea.stories.tsx +2 -2
- package/src/fields/ToggleGroup/ToggleGroup.stories.tsx +2 -2
- package/src/fields/nativeDateTime/OsDateTimeSheet.presentation.spec.tsx +6 -5
- package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +24 -12
- package/src/index.ts +10 -2
- package/src/shared/colorRamps.ts +1 -11
- package/src/standardActions.ts +96 -0
- package/types/AdaptivePopup/index.d.ts +13 -1
- package/types/AdaptivePopup/index.d.ts.map +1 -1
- package/types/Button/glass.d.ts +15 -0
- package/types/Button/glass.d.ts.map +1 -0
- package/types/Button/glass.native.d.ts +11 -0
- package/types/Button/glass.native.d.ts.map +1 -0
- package/types/Button/index.d.ts +45 -1
- package/types/Button/index.d.ts.map +1 -1
- package/types/ContextualSaveBar/index.d.ts.map +1 -1
- package/types/DescriptionList/index.d.ts.map +1 -1
- package/types/fields/Barcode/BarcodeScanner.d.ts.map +1 -1
- package/types/fields/Barcode/BarcodeScanner.native.d.ts.map +1 -1
- package/types/fields/FileUpload/index.d.ts.map +1 -1
- package/types/fields/Geolocation/index.d.ts.map +1 -1
- package/types/fields/ImageField/index.d.ts.map +1 -1
- package/types/fields/nativeDateTime/OsDateTimeSheet.d.ts.map +1 -1
- package/types/index.d.ts +4 -2
- package/types/index.d.ts.map +1 -1
- package/types/shared/colorRamps.d.ts +1 -11
- package/types/shared/colorRamps.d.ts.map +1 -1
- package/types/standardActions.d.ts +24 -0
- package/types/standardActions.d.ts.map +1 -0
package/src/Button/index.tsx
CHANGED
|
@@ -72,6 +72,7 @@ import { formatActionLabel } from "../actionLabel";
|
|
|
72
72
|
import { formButtonColors, formCommonColors } from "../shared/colorRamps";
|
|
73
73
|
import { warnBareDisabled, warnPositiveTabIndex, warnSizeRecipeEscape } from "../shared/devWarn";
|
|
74
74
|
import { useControlGrouped } from "../shared/groupContext";
|
|
75
|
+
import { loadGlassView } from "./glass";
|
|
75
76
|
|
|
76
77
|
/**
|
|
77
78
|
* Coordinated size recipe (Polaris slim/medium/large, Primer s/m/l, Linear
|
|
@@ -382,6 +383,66 @@ export interface ButtonProps extends Omit<
|
|
|
382
383
|
* button that paints a frame, while selected, or disabled.
|
|
383
384
|
*/
|
|
384
385
|
accentInk?: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* LC-176 ICON-BUTTON: an icon-only button is a bare glyph in the bar tint,
|
|
388
|
+
* no fill and no border, on a 44pt target. `plate="media"` is the one
|
|
389
|
+
* plated case: a translucent material circle for a control floating over
|
|
390
|
+
* an image or video, where a bare glyph would be lost on the picture.
|
|
391
|
+
* `plate="primary"` is the overlay's one confirm (LC-260): an accent-filled
|
|
392
|
+
* circle with an on-fill glyph, the iOS 26 sheet's checkmark.
|
|
393
|
+
*/
|
|
394
|
+
plate?: "media" | "primary";
|
|
395
|
+
/**
|
|
396
|
+
* LC-176: an icon button inline with a value (copy beside an address): the
|
|
397
|
+
* glyph is sized to the text, tinted, 8pt after it, and keeps the 44pt
|
|
398
|
+
* target through slop rather than a box that would grow the line.
|
|
399
|
+
*/
|
|
400
|
+
inline?: boolean;
|
|
401
|
+
/**
|
|
402
|
+
* LC-176: the glyph's stroke weight, matched to the text beside it. Phosphor
|
|
403
|
+
* regular for a tinted glyph, bold for a neutral one; never thin or light.
|
|
404
|
+
*/
|
|
405
|
+
glyphWeight?: "regular" | "bold";
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** LC-176: a pressed icon button dims on native, the iOS bar-button highlight. */
|
|
409
|
+
export const ICON_BUTTON_PRESS_OPACITY = 0.35;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* LC-176: a bar or row icon button's glyph floor (HIG 22-24pt in a 44pt
|
|
413
|
+
* target). A bare glyph carries its own weight, so it never shrinks to the
|
|
414
|
+
* label-icon size of a small control.
|
|
415
|
+
*/
|
|
416
|
+
export const ICON_BUTTON_GLYPH_PX = 22;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* LC-176: a neutral icon button (content, no intent: no tint to carry it) is
|
|
420
|
+
* a bold monochrome glyph at 24pt or more, the Instagram / Threads weight.
|
|
421
|
+
*/
|
|
422
|
+
export const ICON_BUTTON_NEUTRAL_GLYPH_PX = 24;
|
|
423
|
+
|
|
424
|
+
/** LC-176: an inline glyph is the text's size; Phosphor's 256 grid pads ~12%. */
|
|
425
|
+
const INLINE_GLYPH_RATIO = 1.2;
|
|
426
|
+
|
|
427
|
+
function withGlyphWeight(
|
|
428
|
+
icon: IconLike | undefined,
|
|
429
|
+
size: number,
|
|
430
|
+
weight: "regular" | "bold",
|
|
431
|
+
): IconLike | undefined {
|
|
432
|
+
if (icon == null || icon === false) return icon;
|
|
433
|
+
if (isValidElement<{ size?: number; weight?: string }>(icon)) {
|
|
434
|
+
return cloneElement(icon, {
|
|
435
|
+
...(icon.props.size == null ? { size } : undefined),
|
|
436
|
+
...(icon.props.weight == null ? { weight } : undefined),
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
if (typeof icon === "function" || (typeof icon === "object" && "$$typeof" in icon)) {
|
|
440
|
+
return createElement(icon as ComponentType<{ size?: number; weight?: string }>, {
|
|
441
|
+
size,
|
|
442
|
+
weight,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
return icon;
|
|
385
446
|
}
|
|
386
447
|
|
|
387
448
|
export function Button({
|
|
@@ -408,6 +469,9 @@ export function Button({
|
|
|
408
469
|
chromeless,
|
|
409
470
|
edge,
|
|
410
471
|
accentInk,
|
|
472
|
+
plate,
|
|
473
|
+
inline,
|
|
474
|
+
glyphWeight,
|
|
411
475
|
verb,
|
|
412
476
|
noun,
|
|
413
477
|
actionRole,
|
|
@@ -465,8 +529,9 @@ export function Button({
|
|
|
465
529
|
(s) => ({ isValid: s.isValid ?? true }),
|
|
466
530
|
);
|
|
467
531
|
|
|
532
|
+
const primaryPlate = plate === "primary";
|
|
468
533
|
const intent =
|
|
469
|
-
(accent && "accent") ||
|
|
534
|
+
((accent || primaryPlate) && "accent") ||
|
|
470
535
|
(error && "error") ||
|
|
471
536
|
(warning && "warning") ||
|
|
472
537
|
(success && "success") ||
|
|
@@ -486,12 +551,36 @@ export function Button({
|
|
|
486
551
|
const hostAccentInk = useAccentOnSurface();
|
|
487
552
|
const hostIdentityInk = useIdentityInkOnSurface();
|
|
488
553
|
const grouped = useControlGrouped();
|
|
554
|
+
// LC-176 ICON-BUTTON: with no label, the button is its glyph. It paints no
|
|
555
|
+
// plate at rest and takes the bar tint, unless the caller asked for a frame
|
|
556
|
+
// (`outlined`, `circular`, `chromeless={false}`) or a segment owns it.
|
|
557
|
+
const labelled = verb != null || (children != null && children !== false && children !== "");
|
|
558
|
+
const iconOnly = !labelled && Boolean(icon || iconAfter);
|
|
559
|
+
const mediaPlate = iconOnly && plate === "media";
|
|
560
|
+
const confirmPlate = iconOnly && primaryPlate;
|
|
561
|
+
const iconButton =
|
|
562
|
+
iconOnly &&
|
|
563
|
+
!mediaPlate &&
|
|
564
|
+
!confirmPlate &&
|
|
565
|
+
!grouped &&
|
|
566
|
+
chromeless !== false &&
|
|
567
|
+
outlined !== true &&
|
|
568
|
+
!circular;
|
|
489
569
|
// LC-153 CONTROL-TIERS: a bar paints its neutral buttons plain; content
|
|
490
570
|
// paints them tinted. The scheme picks the wash step.
|
|
491
571
|
// A Button is most overlays' trigger: the modality must be known before its
|
|
492
572
|
// opening key press, or the open focus cannot tell keyboard from pointer.
|
|
493
573
|
if (isWeb) ensureKeyboardModalityTracking();
|
|
494
574
|
const barSurface = useBarSurface();
|
|
575
|
+
// LC-176: the context picks the icon button's treatment, never the app. In a
|
|
576
|
+
// bar it takes the bar tint (the accent, on Liquid Glass where iOS draws
|
|
577
|
+
// it); in content, with no intent, it is a bold glyph in the text colour.
|
|
578
|
+
const neutralGlyph = iconButton && !(theme ?? intent) && !barSurface && accentInk == null;
|
|
579
|
+
if (iconButton) {
|
|
580
|
+
chromeless = true;
|
|
581
|
+
accentInk = accentInk ?? (!(theme ?? intent) && barSurface);
|
|
582
|
+
}
|
|
583
|
+
const resolvedGlyphWeight = glyphWeight ?? (neutralGlyph ? "bold" : "regular");
|
|
495
584
|
const elevatedGround = useElevatedSurface();
|
|
496
585
|
const darkScheme = isDarkThemeName(useThemeName());
|
|
497
586
|
const resolvedSize = typeof sizeProp === "number" ? sizeProp : knobProps.sizeToken;
|
|
@@ -590,25 +679,34 @@ export function Button({
|
|
|
590
679
|
const washOnHost = Boolean(
|
|
591
680
|
unavailable && activeThemeName && solidPaletteThemes.has(activeThemeName),
|
|
592
681
|
);
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
:
|
|
600
|
-
?
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
682
|
+
// LC-40: a chromeless button has no chrome to wash. A fill would make the
|
|
683
|
+
// disabled twin (a pager's first-page chevron) read as more prominent than
|
|
684
|
+
// the enabled one, so it keeps its frameless look and its ink dims.
|
|
685
|
+
const frameless = Boolean(chromeless);
|
|
686
|
+
const disabledSurface = frameless
|
|
687
|
+
? disabledState.glyphKnobProps
|
|
688
|
+
: tierDisabled
|
|
689
|
+
? {
|
|
690
|
+
...disabledState.surfaceKnobProps,
|
|
691
|
+
backgroundColor: tierDisabled.backgroundColor,
|
|
692
|
+
borderColor: tierDisabled.borderColor,
|
|
693
|
+
}
|
|
694
|
+
: washOnHost
|
|
695
|
+
? hostScoped(disabledState.surfaceKnobProps)
|
|
696
|
+
: disabledState.surfaceKnobProps;
|
|
697
|
+
const disabledText: { color?: string } = frameless
|
|
698
|
+
? {}
|
|
699
|
+
: tierDisabled
|
|
700
|
+
? { ...disabledState.textKnobProps, color: tierDisabled.color }
|
|
701
|
+
: washOnHost
|
|
702
|
+
? hostScoped(disabledState.textKnobProps)
|
|
703
|
+
: activeThemeName &&
|
|
704
|
+
solidButtonIntents.has(activeThemeName) &&
|
|
705
|
+
disabledState.textKnobProps.color
|
|
706
|
+
? { ...disabledState.textKnobProps, color: "$color12" }
|
|
707
|
+
: disabledState.textKnobProps;
|
|
708
|
+
outlined =
|
|
709
|
+
tier || iconButton || mediaPlate || confirmPlate ? false : (outlined ?? knobProps.outlined);
|
|
612
710
|
const isLow = knobProps.textAccent === "low";
|
|
613
711
|
const isMedium = knobProps.textAccent === "medium";
|
|
614
712
|
const resolvedBorderWidth = knobProps.borderRadius.borderWidth;
|
|
@@ -641,18 +739,22 @@ export function Button({
|
|
|
641
739
|
// (measured 1.02–1.06:1 on the page in both schemes). At the default
|
|
642
740
|
// textAccent (`high`, textColor undefined) the label must re-anchor to the
|
|
643
741
|
// same readable text tier the frame uses.
|
|
742
|
+
// LC-176: an intent icon button is a glyph on the page too, so it takes
|
|
743
|
+
// the outlined button's on-page ink.
|
|
744
|
+
const onPage = outlined || iconButton;
|
|
644
745
|
const outlinedIntentInk = Boolean(
|
|
645
|
-
|
|
746
|
+
onPage && activeThemeName && solidButtonIntents.has(activeThemeName),
|
|
646
747
|
);
|
|
647
748
|
// MPO-447: a solid-palette theme (accent) has no readable-on-page step at
|
|
648
749
|
// all, `$color11` included, so an outlined one takes its ink from the host:
|
|
649
750
|
// the accent that clears AA there, or host-scoped text under a textAccent.
|
|
650
751
|
const outlinedOnHost = Boolean(
|
|
651
|
-
|
|
752
|
+
onPage && activeThemeName && solidPaletteThemes.has(activeThemeName),
|
|
652
753
|
);
|
|
653
754
|
const outlinedInk = outlinedOnHost ? hostAccentInk : outlinedIntentInk ? "$color11" : undefined;
|
|
654
755
|
|
|
655
|
-
const resolvedRole: ButtonActionRole | undefined =
|
|
756
|
+
const resolvedRole: ButtonActionRole | undefined =
|
|
757
|
+
actionRole ?? (accent || confirmPlate ? "primary" : undefined);
|
|
656
758
|
const labelFromParts =
|
|
657
759
|
children == null && verb != null ? formatActionLabel({ verb, noun }) : null;
|
|
658
760
|
const resolvedChildren = children ?? labelFromParts;
|
|
@@ -661,11 +763,38 @@ export function Button({
|
|
|
661
763
|
];
|
|
662
764
|
const isSelected =
|
|
663
765
|
selected ?? (ariaPressedProp === true || ariaPressedProp === "true" ? true : undefined);
|
|
664
|
-
|
|
766
|
+
// The media plate is its own state ground; a toggle over media shows its
|
|
767
|
+
// state in the glyph.
|
|
768
|
+
const selectedFill = Boolean(isSelected) && !unavailable && !mediaPlate;
|
|
665
769
|
const barInk = accentInk && chromeless && !selectedFill && !unavailable ? hostIdentityInk : null;
|
|
770
|
+
const inlineGlyph = iconButton && inline === true && !nested;
|
|
771
|
+
// LC-176: back's caret beside its label is a bar glyph too, and so is the
|
|
772
|
+
// glyph on a plate (media, or the overlay's confirm).
|
|
773
|
+
const barGlyph =
|
|
774
|
+
((iconButton || mediaPlate || confirmPlate) && !nested) ||
|
|
775
|
+
(labelled && chromeless && accentInk === true && edge === "start");
|
|
776
|
+
const glyphFloor =
|
|
777
|
+
neutralGlyph && !inlineGlyph ? ICON_BUTTON_NEUTRAL_GLYPH_PX : ICON_BUTTON_GLYPH_PX;
|
|
778
|
+
// LC-176: on iOS 26 a bar's icon button floats on Liquid Glass, the native
|
|
779
|
+
// bar button. Elsewhere, and on a binary without the module, it stays the
|
|
780
|
+
// bare tinted glyph.
|
|
781
|
+
const GlassView =
|
|
782
|
+
iconButton && !inlineGlyph && !nested && accentInk && barSurface && !selectedFill
|
|
783
|
+
? loadGlassView()
|
|
784
|
+
: null;
|
|
666
785
|
const iconSize = nested
|
|
667
786
|
? Math.min(recipe.iconSize, Math.max(12, Math.round(knobProps.nestedControl.px * 0.45)))
|
|
668
|
-
:
|
|
787
|
+
: inlineGlyph
|
|
788
|
+
? Math.round(recipe.fontSize * INLINE_GLYPH_RATIO)
|
|
789
|
+
: barGlyph
|
|
790
|
+
? touch
|
|
791
|
+
? Math.max(glyphFloor, resolveButtonSizeRecipe("$6", recipeFamily, touch).iconSize)
|
|
792
|
+
: // A pointer toolbar keeps its token box (LC-54); the glyph fills it
|
|
793
|
+
// up to the same floor.
|
|
794
|
+
Math.max(recipe.iconSize, Math.min(glyphFloor, recipe.height - 8))
|
|
795
|
+
: recipe.iconSize;
|
|
796
|
+
const glyph =
|
|
797
|
+
barGlyph || inlineGlyph ? withGlyphWeight(icon, iconSize, resolvedGlyphWeight) : icon;
|
|
669
798
|
|
|
670
799
|
// LC-158: the frame keeps its recipe height under Dynamic Type, so the
|
|
671
800
|
// label grows only as far as that height holds: its em and its line, which
|
|
@@ -740,21 +869,25 @@ export function Button({
|
|
|
740
869
|
<View flexShrink={0} data-button-loading="" aria-hidden>
|
|
741
870
|
<Spinner px={iconSize} color={nativeIconColor as string} aria-hidden />
|
|
742
871
|
</View>
|
|
743
|
-
) :
|
|
872
|
+
) : glyph ? (
|
|
744
873
|
<View flexShrink={0}>
|
|
745
874
|
{isWeb ? (
|
|
746
|
-
normalizeButtonIcon(
|
|
875
|
+
normalizeButtonIcon(glyph, iconSize)
|
|
747
876
|
) : (
|
|
748
|
-
<NativeButtonIcon icon={
|
|
877
|
+
<NativeButtonIcon icon={glyph} size={iconSize} color={nativeIconColor} />
|
|
749
878
|
)}
|
|
750
879
|
</View>
|
|
751
880
|
) : null;
|
|
752
|
-
const
|
|
881
|
+
const glyphAfter =
|
|
882
|
+
iconAfter && (barGlyph || inlineGlyph)
|
|
883
|
+
? withGlyphWeight(iconAfter, iconSize, resolvedGlyphWeight)
|
|
884
|
+
: iconAfter;
|
|
885
|
+
const iconAfterElement = glyphAfter ? (
|
|
753
886
|
<View flexShrink={0}>
|
|
754
887
|
{isWeb ? (
|
|
755
|
-
normalizeButtonIcon(
|
|
888
|
+
normalizeButtonIcon(glyphAfter, iconSize)
|
|
756
889
|
) : (
|
|
757
|
-
<NativeButtonIcon icon={
|
|
890
|
+
<NativeButtonIcon icon={glyphAfter} size={iconSize} color={nativeIconColor} />
|
|
758
891
|
)}
|
|
759
892
|
</View>
|
|
760
893
|
) : null;
|
|
@@ -766,7 +899,13 @@ export function Button({
|
|
|
766
899
|
: undefined;
|
|
767
900
|
const isCircular = Boolean(circular);
|
|
768
901
|
const circularTokenPx = sizeTokenPx(resolvedSize);
|
|
769
|
-
const visualPx = nested
|
|
902
|
+
const visualPx = nested
|
|
903
|
+
? knobProps.nestedControl.px
|
|
904
|
+
: inlineGlyph
|
|
905
|
+
? iconSize
|
|
906
|
+
: iconButton
|
|
907
|
+
? Math.max(recipe.height, iconSize)
|
|
908
|
+
: recipe.height;
|
|
770
909
|
// Touch circular tokens below 44 need an explicit box floor (circular variant also
|
|
771
910
|
// sets maxWidth/maxHeight to the token). hitSlop covers native/touch leftovers.
|
|
772
911
|
// Nested circulars skip this — they paint nestedControl and restore press
|
|
@@ -836,6 +975,30 @@ export function Button({
|
|
|
836
975
|
const restFill = selectedFill ? (outlined ? "$background" : "$backgroundPress") : tierPaint?.rest;
|
|
837
976
|
// A plain button is ink on the bar: no shadow at rest (E-FLAT).
|
|
838
977
|
const plainTier = tier === "plain";
|
|
978
|
+
// LC-176: hover and press light a soft plate on web; on native the glyph
|
|
979
|
+
// dims, as an iOS bar button does. The media plate deepens instead.
|
|
980
|
+
const glyphState = iconButton && !selectedFill;
|
|
981
|
+
const iconHover = glyphState
|
|
982
|
+
? isWeb
|
|
983
|
+
? hostScoped({ backgroundColor: "$backgroundHover" })
|
|
984
|
+
: { backgroundColor: "transparent" }
|
|
985
|
+
: mediaPlate
|
|
986
|
+
? { backgroundColor: "$shadow5" }
|
|
987
|
+
: undefined;
|
|
988
|
+
const iconPress = glyphState
|
|
989
|
+
? isWeb
|
|
990
|
+
? hostScoped({ backgroundColor: "$backgroundPress" })
|
|
991
|
+
: { backgroundColor: "transparent", opacity: ICON_BUTTON_PRESS_OPACITY }
|
|
992
|
+
: mediaPlate
|
|
993
|
+
? { backgroundColor: "$shadow5" }
|
|
994
|
+
: undefined;
|
|
995
|
+
// A square box, so an `edge` pull puts the glyph itself on the gutter.
|
|
996
|
+
// On glass the circle, not the glyph, sits on the margin.
|
|
997
|
+
const glyphEdgePull = GlassView
|
|
998
|
+
? 0
|
|
999
|
+
: iconButton
|
|
1000
|
+
? -Math.max(0, (visualPx - iconSize) / 2)
|
|
1001
|
+
: edgePull;
|
|
839
1002
|
const buttonElement = (
|
|
840
1003
|
<ButtonFrame
|
|
841
1004
|
// DG-ST-03: an explained disable is aria-disabled (focusable, press
|
|
@@ -850,8 +1013,10 @@ export function Button({
|
|
|
850
1013
|
: undefined)}
|
|
851
1014
|
borderWidth={resolvedBorderWidth}
|
|
852
1015
|
size={resolvedSize}
|
|
853
|
-
{...(chromeless || plainTier
|
|
854
|
-
|
|
1016
|
+
{...(chromeless || plainTier || mediaPlate || confirmPlate
|
|
1017
|
+
? undefined
|
|
1018
|
+
: knobProps.elevationChrome)}
|
|
1019
|
+
elevation={plainTier || confirmPlate ? undefined : knobProps.elevation}
|
|
855
1020
|
// The frame's `outlined` variant declares only a `true` branch, so a
|
|
856
1021
|
// literal `false` is not consumed and React receives it as a DOM
|
|
857
1022
|
// attribute ("Received `false` for a non-boolean attribute"). Every
|
|
@@ -877,10 +1042,30 @@ export function Button({
|
|
|
877
1042
|
minHeight: visualPx,
|
|
878
1043
|
}
|
|
879
1044
|
: undefined)}
|
|
880
|
-
{...(
|
|
1045
|
+
{...(iconButton || mediaPlate || confirmPlate
|
|
1046
|
+
? { width: visualPx, minWidth: visualPx, paddingHorizontal: 0 }
|
|
1047
|
+
: undefined)}
|
|
1048
|
+
{...(inlineGlyph ? { marginInlineStart: "$2" as const } : undefined)}
|
|
1049
|
+
{...(GlassView ? { borderRadius: 100000, overflow: "hidden" as const } : undefined)}
|
|
1050
|
+
{...(confirmPlate ? { borderRadius: 100000 } : undefined)}
|
|
1051
|
+
{...(mediaPlate
|
|
1052
|
+
? {
|
|
1053
|
+
borderRadius: 100000,
|
|
1054
|
+
backgroundColor: "$shadow4",
|
|
1055
|
+
...(isWeb
|
|
1056
|
+
? {
|
|
1057
|
+
style: {
|
|
1058
|
+
backdropFilter: "blur(16px) saturate(180%)",
|
|
1059
|
+
WebkitBackdropFilter: "blur(16px) saturate(180%)",
|
|
1060
|
+
},
|
|
1061
|
+
}
|
|
1062
|
+
: undefined),
|
|
1063
|
+
}
|
|
1064
|
+
: undefined)}
|
|
1065
|
+
{...(edge && !inlineGlyph && chromeless && !selectedFill && !isCircular
|
|
881
1066
|
? edge === "start"
|
|
882
|
-
? { marginInlineStart:
|
|
883
|
-
: { marginInlineEnd:
|
|
1067
|
+
? { marginInlineStart: glyphEdgePull }
|
|
1068
|
+
: { marginInlineEnd: glyphEdgePull }
|
|
884
1069
|
: undefined)}
|
|
885
1070
|
{...(restFill ? { backgroundColor: restFill } : undefined)}
|
|
886
1071
|
// Solid-intent sub-themes carry the on-fill foreground as `$color`
|
|
@@ -915,6 +1100,7 @@ export function Button({
|
|
|
915
1100
|
...text.hoverKnobProps,
|
|
916
1101
|
// A selected fill, or the LC-153 tier's wash, beats the knob state fill.
|
|
917
1102
|
...(selectedFill || tierPaint ? { backgroundColor: selectedHoverFill } : undefined),
|
|
1103
|
+
...iconHover,
|
|
918
1104
|
}}
|
|
919
1105
|
pressStyle={{
|
|
920
1106
|
backgroundColor: selectedPressFill,
|
|
@@ -923,6 +1109,7 @@ export function Button({
|
|
|
923
1109
|
...text.pressKnobProps,
|
|
924
1110
|
// A selected fill, or the LC-153 tier's wash, beats the knob state fill.
|
|
925
1111
|
...(selectedFill || tierPaint ? { backgroundColor: selectedPressFill } : undefined),
|
|
1112
|
+
...iconPress,
|
|
926
1113
|
}}
|
|
927
1114
|
focusStyle={{ outlineWidth: 0 }}
|
|
928
1115
|
// DG-A11Y-01 / LC-71: house keyboard ring (≥2px `$outlineColor`) on the
|
|
@@ -971,6 +1158,9 @@ export function Button({
|
|
|
971
1158
|
}
|
|
972
1159
|
: undefined)}
|
|
973
1160
|
{...(isCircular && !grouped ? radiusClassProps("R-IDENTITY", "circular Button") : undefined)}
|
|
1161
|
+
{...(!isCircular && (GlassView || confirmPlate || mediaPlate)
|
|
1162
|
+
? radiusClassProps("R-IDENTITY", "icon button plate")
|
|
1163
|
+
: undefined)}
|
|
974
1164
|
{...(explainedDisable
|
|
975
1165
|
? {
|
|
976
1166
|
// No `title`: hover-only reveals are banned on disabled controls
|
|
@@ -981,11 +1171,11 @@ export function Button({
|
|
|
981
1171
|
// Hover/press keep the LC-40 washed chrome — an aria-disabled
|
|
982
1172
|
// control must not light up like a pressable one.
|
|
983
1173
|
hoverStyle: {
|
|
984
|
-
backgroundColor: outlined ? "transparent" : "$background",
|
|
1174
|
+
backgroundColor: outlined || frameless ? "transparent" : "$background",
|
|
985
1175
|
...disabledSurface,
|
|
986
1176
|
},
|
|
987
1177
|
pressStyle: {
|
|
988
|
-
backgroundColor: outlined ? "transparent" : "$background",
|
|
1178
|
+
backgroundColor: outlined || frameless ? "transparent" : "$background",
|
|
989
1179
|
...disabledSurface,
|
|
990
1180
|
},
|
|
991
1181
|
"data-mp-disabled-explained": "true",
|
|
@@ -1001,6 +1191,19 @@ export function Button({
|
|
|
1001
1191
|
: undefined)}
|
|
1002
1192
|
{...(resolvedRole ? { "data-mp-action-role": resolvedRole } : undefined)}
|
|
1003
1193
|
{...(tier ? { "data-mp-tier": tier } : undefined)}
|
|
1194
|
+
{...(iconButton
|
|
1195
|
+
? {
|
|
1196
|
+
"data-mp-icon-button": GlassView
|
|
1197
|
+
? "glass"
|
|
1198
|
+
: inlineGlyph
|
|
1199
|
+
? "inline"
|
|
1200
|
+
: neutralGlyph
|
|
1201
|
+
? "neutral"
|
|
1202
|
+
: "glyph",
|
|
1203
|
+
}
|
|
1204
|
+
: undefined)}
|
|
1205
|
+
{...(mediaPlate ? { "data-mp-icon-button": "media" } : undefined)}
|
|
1206
|
+
{...(confirmPlate ? { "data-mp-icon-button": "primary" } : undefined)}
|
|
1004
1207
|
data-mp-button-height={String(
|
|
1005
1208
|
nested
|
|
1006
1209
|
? visualPx
|
|
@@ -1013,17 +1216,28 @@ export function Button({
|
|
|
1013
1216
|
data-size-token={knobProps.sizeToken}
|
|
1014
1217
|
{...(selectedFill ? { "aria-pressed": true, "data-mp-selected": "true" } : undefined)}
|
|
1015
1218
|
>
|
|
1219
|
+
{GlassView ? (
|
|
1220
|
+
<GlassView
|
|
1221
|
+
glassEffectStyle="regular"
|
|
1222
|
+
isInteractive
|
|
1223
|
+
pointerEvents="none"
|
|
1224
|
+
style={{ position: "absolute", top: 0, right: 0, bottom: 0, left: 0 }}
|
|
1225
|
+
/>
|
|
1226
|
+
) : null}
|
|
1016
1227
|
{iconElement}
|
|
1017
1228
|
{labelContent}
|
|
1018
1229
|
{iconAfterElement}
|
|
1019
1230
|
</ButtonFrame>
|
|
1020
1231
|
);
|
|
1021
1232
|
|
|
1022
|
-
const
|
|
1233
|
+
const intentButton = activeThemeName ? (
|
|
1023
1234
|
<Theme name={activeThemeName as ThemeName}>{buttonElement}</Theme>
|
|
1024
1235
|
) : (
|
|
1025
1236
|
buttonElement
|
|
1026
1237
|
);
|
|
1238
|
+
// The media plate reads the same over any picture in either scheme: a dark
|
|
1239
|
+
// material with a light glyph.
|
|
1240
|
+
const themedButton = mediaPlate ? <Theme name="dark">{intentButton}</Theme> : intentButton;
|
|
1027
1241
|
|
|
1028
1242
|
// DG-ST-03 explain affordance: visible reason adjacent to the control —
|
|
1029
1243
|
// discoverable by pointer, touch, keyboard, and SR (aria-describedby)
|
|
@@ -1060,3 +1274,21 @@ export function Button({
|
|
|
1060
1274
|
|
|
1061
1275
|
Button.Icon = TamaguiButton.Icon;
|
|
1062
1276
|
Button.Text = TamaguiSizableText;
|
|
1277
|
+
|
|
1278
|
+
export interface IconButtonProps extends Omit<
|
|
1279
|
+
ButtonProps,
|
|
1280
|
+
"children" | "icon" | "verb" | "noun" | "outlined" | "circular"
|
|
1281
|
+
> {
|
|
1282
|
+
icon: NonNullable<ButtonProps["icon"]>;
|
|
1283
|
+
/** The action's name, read by assistive tech: the button shows only its glyph. */
|
|
1284
|
+
"aria-label": string;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* LC-176 ICON-BUTTON: a toolbar, nav-bar, row or field-accessory action drawn
|
|
1289
|
+
* as its glyph alone (HIG bar buttons, Material's standard icon button).
|
|
1290
|
+
* `plate="media"` floats it over imagery on a material circle.
|
|
1291
|
+
*/
|
|
1292
|
+
export function IconButton(props: IconButtonProps) {
|
|
1293
|
+
return <Button {...props} />;
|
|
1294
|
+
}
|
|
@@ -16,7 +16,9 @@ function savebar(root: ParentNode = document.body): HTMLElement | null {
|
|
|
16
16
|
|
|
17
17
|
function barButton(label: string, root: ParentNode = document.body): HTMLElement {
|
|
18
18
|
const buttons = Array.from(root.querySelectorAll('[role="button"], button'));
|
|
19
|
-
const match = buttons.find(
|
|
19
|
+
const match = buttons.find(
|
|
20
|
+
(b) => b.textContent?.includes(label) || b.getAttribute("aria-label") === label,
|
|
21
|
+
);
|
|
20
22
|
if (!match) throw new Error(`No button labelled "${label}"`);
|
|
21
23
|
return match as HTMLElement;
|
|
22
24
|
}
|
|
@@ -2,7 +2,6 @@ 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
4
|
import { YStack } from "tamagui";
|
|
5
|
-
import { Button } from "../Button";
|
|
6
5
|
import { Checkbox } from "../fields/Checkbox";
|
|
7
6
|
import { Input } from "../fields/Input";
|
|
8
7
|
import { RadioGroup } from "../fields/RadioGroup";
|
|
@@ -10,6 +9,7 @@ import { Switch } from "../fields/Switch";
|
|
|
10
9
|
import { Form } from "../Form";
|
|
11
10
|
import { ContextualSaveBar } from "./index";
|
|
12
11
|
import { SizableText } from "@multiplatform.one/theme";
|
|
12
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
13
13
|
|
|
14
14
|
const fields = (
|
|
15
15
|
<YStack gap="$4" width="100%" maxWidth={640} padding="$4" minHeight={360}>
|
|
@@ -127,7 +127,7 @@ function SubmissionPathsFixture() {
|
|
|
127
127
|
}}
|
|
128
128
|
>
|
|
129
129
|
<Input name="name" label="Service name" />
|
|
130
|
-
<
|
|
130
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
131
131
|
</Form>
|
|
132
132
|
</YStack>
|
|
133
133
|
);
|
|
@@ -3,7 +3,8 @@ import { useResolvedKnobs, warnCancelDisabled, type KnobProps } from "@multiplat
|
|
|
3
3
|
import { Store, useStore } from "@tanstack/react-store";
|
|
4
4
|
import { useCallback, useEffect, useState, useSyncExternalStore } from "react";
|
|
5
5
|
import { AnimatePresence, Text, XStack, isWeb } from "tamagui";
|
|
6
|
-
import { Button } from "../Button";
|
|
6
|
+
import { Button, IconButton } from "../Button";
|
|
7
|
+
import { standardActions } from "../standardActions";
|
|
7
8
|
import { collectFormFieldErrors } from "../ErrorSummary";
|
|
8
9
|
import { useFormContext } from "../Form";
|
|
9
10
|
import { getFormSubmission } from "../Form/submissionController";
|
|
@@ -321,21 +322,17 @@ export function ContextualSaveBar({
|
|
|
321
322
|
>
|
|
322
323
|
{t("Discard")}
|
|
323
324
|
</Button>
|
|
324
|
-
<
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
size="$4"
|
|
329
|
-
icon={snap.isSubmitting ? <Spinner size="small" /> : undefined}
|
|
325
|
+
<IconButton
|
|
326
|
+
plate="primary"
|
|
327
|
+
icon={snap.isSubmitting ? <Spinner size="small" /> : standardActions.save.icon}
|
|
328
|
+
aria-label={t("Save")}
|
|
330
329
|
disabled={snap.isSubmitting || undefined}
|
|
331
330
|
disabledReason={snap.isSubmitting ? t("Saving") : undefined}
|
|
332
331
|
data-mp-savebar-save=""
|
|
333
332
|
onPress={() => {
|
|
334
333
|
void handleSave();
|
|
335
334
|
}}
|
|
336
|
-
|
|
337
|
-
{t("Save")}
|
|
338
|
-
</Button>
|
|
335
|
+
/>
|
|
339
336
|
</XStack>
|
|
340
337
|
</XStack>
|
|
341
338
|
) : null}
|
|
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
3
3
|
import { YStack } from "tamagui";
|
|
4
4
|
import { Button } from "../Button";
|
|
5
5
|
import { Input } from "../InputParts";
|
|
6
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
6
7
|
import { ControlGroup } from "./index";
|
|
7
8
|
import { Paragraph } from "@multiplatform.one/theme";
|
|
8
9
|
|
|
@@ -130,11 +131,11 @@ export const Connected: Story = {
|
|
|
130
131
|
<Button>Go</Button>
|
|
131
132
|
</ControlGroup>
|
|
132
133
|
<ControlGroup>
|
|
133
|
-
<
|
|
134
|
+
<ActionButton kind="search" />
|
|
134
135
|
<Input.Box>
|
|
135
136
|
<Input.Area placeholder="query" flex={1} />
|
|
136
137
|
</Input.Box>
|
|
137
|
-
<
|
|
138
|
+
<ActionButton kind="filter" />
|
|
138
139
|
</ControlGroup>
|
|
139
140
|
</YStack>
|
|
140
141
|
),
|
|
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
|
3
3
|
import { useForm } from "@tanstack/react-form";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { YStack } from "tamagui";
|
|
6
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
6
7
|
import { Button } from "./Button";
|
|
7
8
|
import { ErrorSummary, collectFormFieldErrors } from "./ErrorSummary";
|
|
8
9
|
import { FieldLayout } from "./fieldLayout";
|
|
@@ -168,7 +169,7 @@ export const FocusesTheFieldOnPress: Story = {
|
|
|
168
169
|
</InputParts>
|
|
169
170
|
</FieldLayout>
|
|
170
171
|
</FormSection>
|
|
171
|
-
<
|
|
172
|
+
<ActionButton kind="submit" onPress={submit} />
|
|
172
173
|
</YStack>
|
|
173
174
|
</Form>
|
|
174
175
|
);
|
|
@@ -10,6 +10,7 @@ import { Field, FieldLayout } from "./fieldLayout";
|
|
|
10
10
|
import { Input } from "./fields/Input";
|
|
11
11
|
import { Input as InputParts } from "./InputParts";
|
|
12
12
|
import { Checkbox } from "./fields/Checkbox";
|
|
13
|
+
import { ActionButton } from "@multiplatform.one/components";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* FieldLayout wraps a CONTROL, so these stories cannot mount the house `Input`
|
|
@@ -196,7 +197,7 @@ export const FieldWrapper: Story = {
|
|
|
196
197
|
)}
|
|
197
198
|
</Field>
|
|
198
199
|
<XStack gap="$2">
|
|
199
|
-
<
|
|
200
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
200
201
|
<Button onPress={() => form.reset()}>Reset</Button>
|
|
201
202
|
</XStack>
|
|
202
203
|
</YStack>
|
|
@@ -237,7 +238,7 @@ export const FieldRequiredValidator: Story = {
|
|
|
237
238
|
</FieldLayout>
|
|
238
239
|
)}
|
|
239
240
|
</Field>
|
|
240
|
-
<
|
|
241
|
+
<ActionButton kind="submit" formAction="submit" />
|
|
241
242
|
</YStack>
|
|
242
243
|
</Form>
|
|
243
244
|
);
|