@multiplatform.one/forms 7.79.0 → 7.81.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 +1 -1
- package/dist/cjs/AdaptivePopup/index.native.js +3 -3
- package/dist/cjs/AdaptivePopup/index.native.js.map +1 -1
- package/dist/cjs/Button/IconButtonGroup.native.js.map +1 -1
- package/dist/cjs/Button/circleGlyph.native.js.map +1 -1
- package/dist/cjs/Button/glass.cjs +1 -2
- package/dist/cjs/Button/iconButtonGroupContext.native.js.map +1 -1
- package/dist/cjs/Button/index.cjs +12 -5
- package/dist/cjs/Button/index.native.js +16 -8
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/Button/webGlass.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.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/PanelHeader.cjs +3 -8
- package/dist/cjs/FloatingPanel/PanelHeader.native.js +3 -8
- package/dist/cjs/FloatingPanel/PanelHeader.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/coverRect.cjs +0 -8
- package/dist/cjs/FloatingPanel/coverRect.native.js +0 -8
- package/dist/cjs/FloatingPanel/coverRect.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/echoContext.cjs +5 -27
- package/dist/cjs/FloatingPanel/echoContext.native.js +5 -28
- package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/index.cjs +49 -131
- package/dist/cjs/FloatingPanel/index.native.js +26 -91
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/nestedAction.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/paintedBox.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/panelWidth.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/InputParts/keyboardAppearance.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/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.cjs +3 -10
- package/dist/cjs/fields/Combobox/index.native.js +8 -15
- 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/DurationWheel.native.js +1 -1
- package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/cjs/fields/Duration/durationWheelTypes.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.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.cjs +4 -8
- package/dist/cjs/fields/Select/InlineChoices.native.js +4 -8
- 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.cjs +46 -199
- package/dist/cjs/fields/Select/index.native.js +56 -211
- 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 +2 -2
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
- 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 +4 -0
- package/dist/cjs/index.native.js +49 -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/CheckGlyph.cjs +40 -0
- package/dist/cjs/shared/CheckGlyph.native.js +44 -0
- package/dist/cjs/shared/CheckGlyph.native.js.map +1 -0
- 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.native.js.map +1 -1
- package/dist/cjs/shared/devWarn.native.js.map +1 -1
- package/dist/cjs/shared/fieldRowContext.native.js.map +1 -1
- package/dist/cjs/shared/floatingList.cjs +82 -3
- package/dist/cjs/shared/floatingList.native.js +96 -6
- 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/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.native.js.map +1 -1
- 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 +2 -2
- package/dist/esm/AdaptivePopup/index.mjs.map +1 -1
- package/dist/esm/AdaptivePopup/index.native.js +2 -2
- package/dist/esm/AdaptivePopup/index.native.js.map +1 -1
- package/dist/esm/Button/IconButtonGroup.native.js.map +1 -1
- package/dist/esm/Button/circleGlyph.native.js.map +1 -1
- package/dist/esm/Button/glass.mjs +1 -2
- package/dist/esm/Button/glass.mjs.map +1 -1
- package/dist/esm/Button/iconButtonGroupContext.native.js.map +1 -1
- package/dist/esm/Button/index.mjs +12 -5
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +14 -6
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/Button/webGlass.mjs.map +1 -1
- package/dist/esm/Button/webGlass.native.js.map +1 -1
- package/dist/esm/Chip/index.native.js.map +1 -1
- package/dist/esm/ContextualSaveBar/UnsavedChangesDialog.native.js.map +1 -1
- package/dist/esm/ContextualSaveBar/clientKnownIdentity.native.js.map +1 -1
- package/dist/esm/ContextualSaveBar/commitImmediateField.native.js.map +1 -1
- package/dist/esm/ContextualSaveBar/index.native.js.map +1 -1
- package/dist/esm/ContextualSaveBar/useUnsavedChangesGuard.native.js.map +1 -1
- package/dist/esm/ControlGroup/index.native.js.map +1 -1
- package/dist/esm/DescriptionList/index.native.js.map +1 -1
- package/dist/esm/ErrorSummary.native.js.map +1 -1
- package/dist/esm/FieldDisplay/editMode.native.js.map +1 -1
- package/dist/esm/FieldDisplay/formatters.native.js.map +1 -1
- package/dist/esm/FieldDisplay/index.native.js.map +1 -1
- package/dist/esm/FieldGroup.native.js.map +1 -1
- package/dist/esm/FloatingPanel/PanelHeader.mjs +3 -8
- package/dist/esm/FloatingPanel/PanelHeader.mjs.map +1 -1
- package/dist/esm/FloatingPanel/PanelHeader.native.js +3 -8
- package/dist/esm/FloatingPanel/PanelHeader.native.js.map +1 -1
- package/dist/esm/FloatingPanel/RegularPanel.native.js.map +1 -1
- package/dist/esm/FloatingPanel/compactFace.native.js.map +1 -1
- package/dist/esm/FloatingPanel/containingBlock.native.js.map +1 -1
- package/dist/esm/FloatingPanel/coverRect.mjs +1 -8
- package/dist/esm/FloatingPanel/coverRect.mjs.map +1 -1
- package/dist/esm/FloatingPanel/coverRect.native.js +1 -8
- package/dist/esm/FloatingPanel/coverRect.native.js.map +1 -1
- package/dist/esm/FloatingPanel/echoContext.mjs +4 -24
- package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -1
- package/dist/esm/FloatingPanel/echoContext.native.js +4 -25
- package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -1
- package/dist/esm/FloatingPanel/index.mjs +53 -135
- package/dist/esm/FloatingPanel/index.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +30 -95
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/nestedAction.native.js.map +1 -1
- package/dist/esm/FloatingPanel/paintedBox.native.js.map +1 -1
- package/dist/esm/FloatingPanel/panelWidth.native.js.map +1 -1
- package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/esm/FloatingPanel/regularPlacement.native.js.map +1 -1
- package/dist/esm/FloatingPanel/trailingAction.native.js.map +1 -1
- package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/esm/Form/index.native.js.map +1 -1
- package/dist/esm/Form/submissionController.native.js.map +1 -1
- package/dist/esm/Form/validateOn.native.js.map +1 -1
- package/dist/esm/FormGrid.native.js.map +1 -1
- package/dist/esm/FormSection.native.js.map +1 -1
- package/dist/esm/InputParts/PasswordReveal.native.js.map +1 -1
- package/dist/esm/InputParts/index.native.js.map +1 -1
- package/dist/esm/InputParts/keyboardAppearance.native.js.map +1 -1
- package/dist/esm/Label/index.native.js.map +1 -1
- package/dist/esm/MediaPicker/base64.native.js.map +1 -1
- package/dist/esm/MediaPicker/payload.native.js.map +1 -1
- package/dist/esm/MediaPicker/types.native.js.map +1 -1
- package/dist/esm/MediaPicker/useMediaPicker.native.js.map +1 -1
- package/dist/esm/Skeleton/index.native.js.map +1 -1
- package/dist/esm/Spinner/SpinnerGlyph.native.js.map +1 -1
- package/dist/esm/Spinner/spinnerSize.native.js.map +1 -1
- package/dist/esm/Table/index.native.js.map +1 -1
- package/dist/esm/Wheel/haptic.native.js.map +1 -1
- package/dist/esm/Wheel/index.native.js.map +1 -1
- package/dist/esm/Wheel/wheelShared.native.js.map +1 -1
- package/dist/esm/actionLabel.native.js.map +1 -1
- package/dist/esm/fieldDefaults.native.js.map +1 -1
- package/dist/esm/fieldLayout.native.js.map +1 -1
- package/dist/esm/fields/Barcode/BarcodePreview.native.js.map +1 -1
- package/dist/esm/fields/Barcode/code128.native.js.map +1 -1
- package/dist/esm/fields/Barcode/index.native.js.map +1 -1
- package/dist/esm/fields/Barcode/qr.native.js.map +1 -1
- package/dist/esm/fields/Barcode/scannerTypes.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/Checkbox.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/CheckboxBox.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/CheckboxCard.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/CheckboxFieldFrame.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/CheckboxGroup.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/checkboxGroupContext.native.js.map +1 -1
- package/dist/esm/fields/Checkbox/index.native.js.map +1 -1
- package/dist/esm/fields/ColorPicker/SystemColorField.native.js.map +1 -1
- package/dist/esm/fields/ColorPicker/index.native.js.map +1 -1
- package/dist/esm/fields/ColorPicker/parts.native.js.map +1 -1
- package/dist/esm/fields/ColorPicker/systemColorWell.gnome.native.js.map +1 -1
- package/dist/esm/fields/Combobox/authorOptions.native.js.map +1 -1
- package/dist/esm/fields/Combobox/index.mjs +4 -11
- package/dist/esm/fields/Combobox/index.mjs.map +1 -1
- package/dist/esm/fields/Combobox/index.native.js +4 -11
- package/dist/esm/fields/Combobox/index.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/Calendar.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DateRangePicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/MonthPicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/MultiDatePicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/fieldValueSync.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/utils.native.js.map +1 -1
- package/dist/esm/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/esm/fields/Duration/durationWheelTypes.native.js.map +1 -1
- package/dist/esm/fields/Duration/index.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/filePickerTypes.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/index.native.js.map +1 -1
- package/dist/esm/fields/FileUpload/nativePickerLoader.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/expoMapsLoader.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/geoValue.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/geocoder.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/geocoderContext.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/mapMath.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/mapTypes.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/nativeSearchFocus.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/photonGeocoder.native.js.map +1 -1
- package/dist/esm/fields/Icon/drawnSet.native.js.map +1 -1
- package/dist/esm/fields/Icon/index.native.js.map +1 -1
- package/dist/esm/fields/ImageField/index.native.js.map +1 -1
- package/dist/esm/fields/Input/index.native.js.map +1 -1
- package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
- package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
- package/dist/esm/fields/OTPInput/otpCellCss.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/dialCodes.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/index.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/phone.native.js.map +1 -1
- package/dist/esm/fields/PhoneInput/regionNames.native.js.map +1 -1
- package/dist/esm/fields/Progress/index.native.js.map +1 -1
- package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/esm/fields/Rating/index.native.js.map +1 -1
- package/dist/esm/fields/Rating/ratingMath.native.js.map +1 -1
- package/dist/esm/fields/Rating/types.native.js.map +1 -1
- package/dist/esm/fields/SearchInput/index.native.js.map +1 -1
- package/dist/esm/fields/Select/InlineChoices.mjs +2 -6
- package/dist/esm/fields/Select/InlineChoices.mjs.map +1 -1
- package/dist/esm/fields/Select/InlineChoices.native.js +2 -6
- package/dist/esm/fields/Select/InlineChoices.native.js.map +1 -1
- package/dist/esm/fields/Select/SheetPickerRow.native.js.map +1 -1
- package/dist/esm/fields/Select/index.mjs +49 -202
- package/dist/esm/fields/Select/index.mjs.map +1 -1
- package/dist/esm/fields/Select/index.native.js +55 -210
- package/dist/esm/fields/Select/index.native.js.map +1 -1
- package/dist/esm/fields/Select/shouldInlineChoices.native.js.map +1 -1
- package/dist/esm/fields/Signature/index.native.js.map +1 -1
- package/dist/esm/fields/Slider/index.native.js.map +1 -1
- package/dist/esm/fields/Slider/jumpMotion.native.js.map +1 -1
- package/dist/esm/fields/Stepper/index.native.js.map +1 -1
- package/dist/esm/fields/Stepper/resolveStepperPlacement.native.js.map +1 -1
- package/dist/esm/fields/Switch/footprint.native.js.map +1 -1
- package/dist/esm/fields/Switch/index.native.js.map +1 -1
- package/dist/esm/fields/TextArea/index.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/esm/fields/TimeRangeScrubber/geometry.native.js.map +1 -1
- package/dist/esm/fields/TimeRangeScrubber/index.native.js.map +1 -1
- package/dist/esm/fields/ToggleGroup/index.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +3 -3
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/dateTimePickerLoader.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
- package/dist/esm/fields/nativeSelect.native.js.map +1 -1
- package/dist/esm/fields/selectedOrder.native.js.map +1 -1
- package/dist/esm/formSpacing.native.js.map +1 -1
- package/dist/esm/hooks/useFocusManagement.native.js.map +1 -1
- package/dist/esm/index.mjs +3 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +3 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/keyboard/chain.native.js.map +1 -1
- package/dist/esm/keyboard/index.native.js.map +1 -1
- package/dist/esm/keyboard/types.native.js.map +1 -1
- package/dist/esm/requiredMarking.native.js.map +1 -1
- package/dist/esm/shared/CheckGlyph.mjs +15 -0
- package/dist/esm/shared/CheckGlyph.mjs.map +1 -0
- package/dist/esm/shared/CheckGlyph.native.js +16 -0
- package/dist/esm/shared/CheckGlyph.native.js.map +1 -0
- package/dist/esm/shared/TimeColumn.native.js.map +1 -1
- package/dist/esm/shared/capabilityPreflight.native.js.map +1 -1
- package/dist/esm/shared/choiceRowPress.native.js.map +1 -1
- package/dist/esm/shared/colorRamps.native.js.map +1 -1
- package/dist/esm/shared/devWarn.native.js.map +1 -1
- package/dist/esm/shared/fieldRowContext.native.js.map +1 -1
- package/dist/esm/shared/floatingList.mjs +80 -4
- package/dist/esm/shared/floatingList.mjs.map +1 -1
- package/dist/esm/shared/floatingList.native.js +93 -6
- package/dist/esm/shared/floatingList.native.js.map +1 -1
- package/dist/esm/shared/focusManagement.native.js.map +1 -1
- package/dist/esm/shared/groupContext.native.js.map +1 -1
- package/dist/esm/shared/i18n.native.js.map +1 -1
- package/dist/esm/shared/instantMotion.native.js.map +1 -1
- package/dist/esm/shared/nativeA11y.native.js.map +1 -1
- package/dist/esm/shared/nativeAutoFocus.native.js.map +1 -1
- package/dist/esm/shared/overlaySizeClass.native.js.map +1 -1
- package/dist/esm/shared/overlayStack.native.js.map +1 -1
- package/dist/esm/shared/panelPortal.native.js.map +1 -1
- package/dist/esm/shared/pickerTriggerContract.native.js.map +1 -1
- package/dist/esm/shared/pressSlopProps.native.js.map +1 -1
- package/dist/esm/shared/restoreRetries.native.js.map +1 -1
- package/dist/esm/shared/sheetNavigation.native.js.map +1 -1
- package/dist/esm/shared/systemControlModules.gnome.native.js.map +1 -1
- package/dist/esm/shared/systemControls.native.js.map +1 -1
- package/dist/esm/shared/t.native.js.map +1 -1
- package/dist/esm/shared/tableCellContext.native.js.map +1 -1
- package/dist/esm/shared/useDragScroll.native.js.map +1 -1
- package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/esm/shared/useSheetEscapeDismiss.native.js.map +1 -1
- package/dist/esm/shared/useWheelIncrement.native.js.map +1 -1
- package/dist/esm/shared/utils.native.js.map +1 -1
- package/dist/esm/shared/zIndex.native.js.map +1 -1
- package/dist/esm/standardActions.native.js.map +1 -1
- package/dist/esm/themedPrimitives.native.js.map +1 -1
- package/dist/esm/types.native.js.map +1 -1
- package/dist/esm/utils/LinkCell.native.js.map +1 -1
- package/dist/jsx/AdaptivePopup/index.mjs +2 -2
- package/dist/jsx/AdaptivePopup/index.mjs.map +1 -1
- package/dist/jsx/AdaptivePopup/index.native.js +1 -1
- package/dist/jsx/AdaptivePopup/index.native.js.map +1 -1
- package/dist/jsx/Button/glass.mjs +1 -2
- package/dist/jsx/Button/glass.mjs.map +1 -1
- package/dist/jsx/Button/index.mjs +12 -5
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +14 -6
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/Button/webGlass.mjs.map +1 -1
- package/dist/jsx/Button/webGlass.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/PanelHeader.mjs +3 -8
- package/dist/jsx/FloatingPanel/PanelHeader.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/PanelHeader.native.js +3 -8
- package/dist/jsx/FloatingPanel/PanelHeader.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/coverRect.mjs +1 -8
- package/dist/jsx/FloatingPanel/coverRect.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/coverRect.native.js +0 -8
- package/dist/jsx/FloatingPanel/coverRect.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/echoContext.mjs +4 -24
- package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/echoContext.native.js +5 -28
- package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/index.mjs +53 -135
- package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +26 -91
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- package/dist/jsx/fields/Combobox/index.mjs +4 -11
- package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
- package/dist/jsx/fields/Combobox/index.native.js +3 -10
- package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
- package/dist/jsx/fields/Select/InlineChoices.mjs +2 -6
- package/dist/jsx/fields/Select/InlineChoices.mjs.map +1 -1
- package/dist/jsx/fields/Select/InlineChoices.native.js +4 -8
- package/dist/jsx/fields/Select/InlineChoices.native.js.map +1 -1
- package/dist/jsx/fields/Select/index.mjs +49 -202
- package/dist/jsx/fields/Select/index.mjs.map +1 -1
- package/dist/jsx/fields/Select/index.native.js +52 -207
- package/dist/jsx/fields/Select/index.native.js.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +3 -3
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +2 -2
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/jsx/index.js +3 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +3 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +4 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/CheckGlyph.mjs +15 -0
- package/dist/jsx/shared/CheckGlyph.mjs.map +1 -0
- package/dist/jsx/shared/CheckGlyph.native.js +44 -0
- package/dist/jsx/shared/CheckGlyph.native.js.map +1 -0
- package/dist/jsx/shared/floatingList.mjs +80 -4
- package/dist/jsx/shared/floatingList.mjs.map +1 -1
- package/dist/jsx/shared/floatingList.native.js +95 -5
- package/dist/jsx/shared/floatingList.native.js.map +1 -1
- package/package.json +8 -8
- package/src/AdaptivePopup/index.tsx +2 -2
- package/src/Button/Button.glassPress.spec.tsx +117 -0
- package/src/Button/Button.iconButton.spec.tsx +39 -0
- package/src/Button/IconButtonGroup.spec.tsx +1 -1
- package/src/Button/glass.spec.ts +48 -18
- package/src/Button/glass.ts +5 -12
- package/src/Button/index.tsx +22 -10
- package/src/Button/webGlass.ts +5 -4
- package/src/FloatingPanel/FloatingPanel.iconCover.spec.tsx +279 -0
- package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +78 -69
- package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +12 -0
- package/src/FloatingPanel/PanelHeader.tsx +4 -12
- package/src/FloatingPanel/coverRect.ts +2 -15
- package/src/FloatingPanel/echoContext.ts +6 -40
- package/src/FloatingPanel/index.native.tsx +36 -145
- package/src/FloatingPanel/index.tsx +61 -187
- package/src/FloatingPanel/pointAnchor.spec.ts +1 -1
- package/src/FloatingPanel/pointAnchor.ts +4 -4
- package/src/fields/Combobox/index.tsx +4 -9
- package/src/fields/Select/InlineChoices.tsx +2 -2
- package/src/fields/Select/Select.containingBlock.spec.tsx +131 -130
- package/src/fields/Select/Select.stories.tsx +10 -0
- package/src/fields/Select/index.tsx +66 -253
- package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +3 -3
- package/src/index.ts +2 -1
- package/src/shared/CheckGlyph.tsx +12 -0
- package/src/shared/floatingList.spec.tsx +154 -1
- package/src/shared/floatingList.tsx +125 -8
- package/types/Button/glass.d.ts +4 -3
- package/types/Button/glass.d.ts.map +1 -1
- package/types/Button/index.d.ts.map +1 -1
- package/types/Button/webGlass.d.ts +5 -4
- package/types/Button/webGlass.d.ts.map +1 -1
- package/types/FloatingPanel/PanelHeader.d.ts +1 -6
- package/types/FloatingPanel/PanelHeader.d.ts.map +1 -1
- package/types/FloatingPanel/coverRect.d.ts +2 -11
- package/types/FloatingPanel/coverRect.d.ts.map +1 -1
- package/types/FloatingPanel/echoContext.d.ts +5 -22
- package/types/FloatingPanel/echoContext.d.ts.map +1 -1
- package/types/FloatingPanel/index.d.ts +6 -8
- package/types/FloatingPanel/index.d.ts.map +1 -1
- package/types/FloatingPanel/index.native.d.ts +1 -1
- package/types/FloatingPanel/index.native.d.ts.map +1 -1
- package/types/FloatingPanel/pointAnchor.d.ts +4 -4
- package/types/fields/Combobox/index.d.ts.map +1 -1
- package/types/fields/Select/index.d.ts.map +1 -1
- package/types/index.d.ts +2 -1
- package/types/index.d.ts.map +1 -1
- package/types/shared/CheckGlyph.d.ts +10 -0
- package/types/shared/CheckGlyph.d.ts.map +1 -0
- package/types/shared/floatingList.d.ts +55 -1
- package/types/shared/floatingList.d.ts.map +1 -1
- package/dist/cjs/FloatingPanel/iconEcho.cjs +0 -106
- package/dist/cjs/FloatingPanel/iconEcho.native.js +0 -116
- package/dist/cjs/FloatingPanel/iconEcho.native.js.map +0 -1
- package/dist/esm/FloatingPanel/iconEcho.mjs +0 -79
- package/dist/esm/FloatingPanel/iconEcho.mjs.map +0 -1
- package/dist/esm/FloatingPanel/iconEcho.native.js +0 -86
- package/dist/esm/FloatingPanel/iconEcho.native.js.map +0 -1
- package/dist/jsx/FloatingPanel/iconEcho.mjs +0 -79
- package/dist/jsx/FloatingPanel/iconEcho.mjs.map +0 -1
- package/dist/jsx/FloatingPanel/iconEcho.native.js +0 -116
- package/dist/jsx/FloatingPanel/iconEcho.native.js.map +0 -1
- package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +0 -357
- package/src/FloatingPanel/iconEcho.tsx +0 -124
- package/types/FloatingPanel/iconEcho.d.ts +0 -29
- package/types/FloatingPanel/iconEcho.d.ts.map +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*
|
|
4
|
+
* LC-176 (FZ-8666): on native iOS a bar button's press is the system's. Clay
|
|
5
|
+
* on rv_c6369c2bab2ffea0: "Like actually use liquid glass it should have the
|
|
6
|
+
* same animated you know when you push it resizes like don't try to
|
|
7
|
+
* re-implement that let the native API do it." The glass is interactive and
|
|
8
|
+
* holds the glyph, and MPO layers no press fade, scale or resize on it. A bar
|
|
9
|
+
* glyph with no glass keeps MPO's press dim, which proves the instrument.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { createDefaultThemeConfig, Surface } from "@multiplatform.one/theme";
|
|
13
|
+
import { cleanup, render, screen } from "@testing-library/react";
|
|
14
|
+
import type { ReactElement } from "react";
|
|
15
|
+
import { TamaguiProvider } from "tamagui";
|
|
16
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
17
|
+
import { IconButton, IconButtonGroup } from "./index";
|
|
18
|
+
|
|
19
|
+
const platform = vi.hoisted(() => ({ web: false }));
|
|
20
|
+
vi.mock("tamagui", async (importOriginal) => ({
|
|
21
|
+
...(await importOriginal<typeof import("tamagui")>()),
|
|
22
|
+
get isWeb() {
|
|
23
|
+
return platform.web;
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
const glass = vi.hoisted(() => ({ available: true }));
|
|
28
|
+
vi.mock("./glass", () => {
|
|
29
|
+
function FakeGlassView({
|
|
30
|
+
glassEffectStyle,
|
|
31
|
+
isInteractive,
|
|
32
|
+
colorScheme: _colorScheme,
|
|
33
|
+
children,
|
|
34
|
+
...props
|
|
35
|
+
}: Record<string, unknown>) {
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
data-glass=""
|
|
39
|
+
data-effect={glassEffectStyle as string}
|
|
40
|
+
data-interactive={String(isInteractive)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{children as never}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function FakeGlassContainer({ children }: { children?: unknown }) {
|
|
48
|
+
return <div data-glass-container="">{children as never}</div>;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
loadGlassView: () => (glass.available ? FakeGlassView : null),
|
|
52
|
+
loadGlassContainer: () => (glass.available ? FakeGlassContainer : null),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
afterEach(() => {
|
|
57
|
+
cleanup();
|
|
58
|
+
glass.available = true;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const houseConfig = createDefaultThemeConfig();
|
|
62
|
+
|
|
63
|
+
/** A press class that fades, scales or resizes the button. */
|
|
64
|
+
const PRESS_MOTION = /^_(o|opacity|transform|scale|w|width|h|height)-0active-/;
|
|
65
|
+
|
|
66
|
+
function Glyph({ size }: { size?: number }) {
|
|
67
|
+
return <svg data-glyph="" width={size} height={size} />;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function barRender(ui: ReactElement) {
|
|
71
|
+
return render(
|
|
72
|
+
<TamaguiProvider config={houseConfig.tamagui} defaultTheme="light" disableInjectCSS>
|
|
73
|
+
<Surface bar>{ui}</Surface>
|
|
74
|
+
</TamaguiProvider>,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function pressMotion(el: Element): string[] {
|
|
79
|
+
return Array.from(el.classList).filter((c) => PRESS_MOTION.test(c));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
describe("LC-176: native glass answers its own press (FZ-8666)", () => {
|
|
83
|
+
it("a lone bar button sits in interactive glass with no MPO press motion", () => {
|
|
84
|
+
barRender(<IconButton icon={Glyph} aria-label="Search" />);
|
|
85
|
+
const button = screen.getByLabelText("Search");
|
|
86
|
+
expect(button.getAttribute("data-mp-icon-button")).toBe("glass");
|
|
87
|
+
const glassView = button.querySelector("[data-glass]")!;
|
|
88
|
+
expect(glassView.getAttribute("data-interactive")).toBe("true");
|
|
89
|
+
expect(glassView.querySelector("[data-glyph]")).not.toBeNull();
|
|
90
|
+
expect(pressMotion(button)).toEqual([]);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("a bar group's buttons sit in one interactive capsule with no MPO press motion", () => {
|
|
94
|
+
barRender(
|
|
95
|
+
<IconButtonGroup>
|
|
96
|
+
<IconButton icon={Glyph} aria-label="Archive" />
|
|
97
|
+
<IconButton icon={Glyph} aria-label="Delete" />
|
|
98
|
+
</IconButtonGroup>,
|
|
99
|
+
);
|
|
100
|
+
const capsule = document.querySelector("[data-glass-container] [data-glass]")!;
|
|
101
|
+
expect(capsule.getAttribute("data-effect")).toBe("regular");
|
|
102
|
+
expect(capsule.getAttribute("data-interactive")).toBe("true");
|
|
103
|
+
for (const name of ["Archive", "Delete"]) {
|
|
104
|
+
const button = screen.getByLabelText(name);
|
|
105
|
+
expect(capsule.contains(button)).toBe(true);
|
|
106
|
+
expect(pressMotion(button)).toEqual([]);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("without the glass module the bar glyph keeps MPO's press dim", () => {
|
|
111
|
+
glass.available = false;
|
|
112
|
+
barRender(<IconButton icon={Glyph} aria-label="Search" />);
|
|
113
|
+
const button = screen.getByLabelText("Search");
|
|
114
|
+
expect(button.getAttribute("data-mp-icon-button")).not.toBe("glass");
|
|
115
|
+
expect(pressMotion(button).some((c) => /^_(o|opacity)-0active-/.test(c))).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -112,6 +112,45 @@ function rest(el: Element, prefix: string): string[] {
|
|
|
112
112
|
.sort();
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
describe("LC-176: one ink on a bold glyph (FZ-8649)", () => {
|
|
116
|
+
function Inked({ color, stroke }: { color?: string; stroke?: string }) {
|
|
117
|
+
return <svg data-glyph="" data-color={color} data-stroke={stroke} />;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
it.each(SCHEMES)("%s: a bar glyph takes the bar tint on its fill and its stroke", (scheme) => {
|
|
121
|
+
houseRender(
|
|
122
|
+
<Surface bar>
|
|
123
|
+
<Button chromeless icon={Inked} aria-label="Menu" />
|
|
124
|
+
<Button chromeless icon={<Inked />} aria-label="Bell" />
|
|
125
|
+
</Surface>,
|
|
126
|
+
scheme,
|
|
127
|
+
);
|
|
128
|
+
for (const label of ["Menu", "Bell"]) {
|
|
129
|
+
const ink = glyphOf(label).getAttribute("data-color");
|
|
130
|
+
expect(ink).toBeTruthy();
|
|
131
|
+
expect(ink).not.toBe("currentColor");
|
|
132
|
+
expect(glyphOf(label).getAttribute("data-stroke")).toBe(ink);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("a caller's colour stays on the fill and the stroke", () => {
|
|
137
|
+
houseRender(
|
|
138
|
+
<Surface bar>
|
|
139
|
+
<Button chromeless icon={<Inked color="red" />} aria-label="Bell" />
|
|
140
|
+
</Surface>,
|
|
141
|
+
"light",
|
|
142
|
+
);
|
|
143
|
+
expect(glyphOf("Bell").getAttribute("data-color")).toBe("red");
|
|
144
|
+
expect(glyphOf("Bell").getAttribute("data-stroke")).toBe("red");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("a content glyph has no bar tint to pass, so it keeps currentColor", () => {
|
|
148
|
+
houseRender(<Button icon={Inked} aria-label="More" />, "light");
|
|
149
|
+
expect(glyphOf("More").hasAttribute("data-color")).toBe(false);
|
|
150
|
+
expect(glyphOf("More").getAttribute("data-stroke")).toBe("currentColor");
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
115
154
|
describe("LC-176: an icon-only Button is a bare glyph", () => {
|
|
116
155
|
it.each(SCHEMES)("%s: in a bar, no fill and no border at rest, the bar tint as ink", (scheme) => {
|
|
117
156
|
houseRender(
|
|
@@ -76,7 +76,7 @@ function houseRender(ui: ReactElement) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
describe("LC-176: IconButtonGroup", () => {
|
|
79
|
-
it("
|
|
79
|
+
it("iOS Safari's bar group is one capsule behind bare glyphs", () => {
|
|
80
80
|
vi.stubGlobal("navigator", { userAgent: IPHONE, platform: "iPhone", maxTouchPoints: 5 });
|
|
81
81
|
glass.available = true;
|
|
82
82
|
houseRender(
|
package/src/Button/glass.spec.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @vitest-environment jsdom
|
|
3
3
|
*
|
|
4
|
-
* LC-176 / LC-266 (FZ-8666):
|
|
5
|
-
*
|
|
6
|
-
* `glass.ts` until Clay answers the compare.
|
|
4
|
+
* LC-176 / LC-266 (FZ-8666): iOS Safari keeps the drawn glass face (Clay's
|
|
5
|
+
* pick A on rv_c6369c2bab2ffea0); every other browser draws plain glyphs.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
import { createDefaultThemeConfig, Surface } from "@multiplatform.one/theme";
|
|
@@ -20,6 +19,8 @@ const IPHONE =
|
|
|
20
19
|
const MAC_SAFARI =
|
|
21
20
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15";
|
|
22
21
|
const houseConfig = createDefaultThemeConfig();
|
|
22
|
+
/** A press class that fades, scales or resizes the button. */
|
|
23
|
+
const PRESS_MOTION = /^_(o|opacity|transform|scale|w|width|h|height)-0active-/;
|
|
23
24
|
const PIXEL =
|
|
24
25
|
"Mozilla/5.0 (Linux; Android 15; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Mobile Safari/537.36";
|
|
25
26
|
|
|
@@ -61,7 +62,23 @@ function renderBar(ui: ReturnType<typeof createElement>) {
|
|
|
61
62
|
);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
function renderBarRow() {
|
|
66
|
+
renderBar(
|
|
67
|
+
createElement(
|
|
68
|
+
"div",
|
|
69
|
+
null,
|
|
70
|
+
createElement(
|
|
71
|
+
IconButtonGroup,
|
|
72
|
+
null,
|
|
73
|
+
createElement(IconButton, { icon: Glyph, "aria-label": "Search" }),
|
|
74
|
+
createElement(IconButton, { icon: Glyph, "aria-label": "More" }),
|
|
75
|
+
),
|
|
76
|
+
createElement(IconButton, { icon: Glyph, "aria-label": "Back" }),
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
describe("glass on the web (LC-176)", () => {
|
|
65
82
|
afterEach(() => {
|
|
66
83
|
cleanup();
|
|
67
84
|
vi.unstubAllGlobals();
|
|
@@ -70,25 +87,38 @@ describe("no glass on the web (LC-176)", () => {
|
|
|
70
87
|
it.each([
|
|
71
88
|
["iOS Safari", { userAgent: IPHONE, platform: "iPhone", maxTouchPoints: 5 }],
|
|
72
89
|
["iPadOS Safari", { userAgent: MAC_SAFARI, platform: "MacIntel", maxTouchPoints: 5 }],
|
|
90
|
+
])(
|
|
91
|
+
"%s draws the glass face: one capsule for a bar group, a circle for a lone button",
|
|
92
|
+
(_browser, nav) => {
|
|
93
|
+
vi.stubGlobal("navigator", nav);
|
|
94
|
+
expect(loadGlassView()).toBe(WebGlassFace);
|
|
95
|
+
expect(loadGlassContainer()).toBeNull();
|
|
96
|
+
renderBarRow();
|
|
97
|
+
const capsule = document.querySelector("[data-mp-glass-capsule]");
|
|
98
|
+
expect(capsule).not.toBeNull();
|
|
99
|
+
expect(capsule!.querySelectorAll('[data-mp-glass="web"]')).toHaveLength(1);
|
|
100
|
+
expect(document.querySelectorAll('[data-mp-glass="web"]')).toHaveLength(2);
|
|
101
|
+
for (const name of ["Search", "More"])
|
|
102
|
+
expect(screen.getByLabelText(name).getAttribute("data-mp-icon-button")).not.toBe("glass");
|
|
103
|
+
const back = screen.getByLabelText("Back");
|
|
104
|
+
expect(back.getAttribute("data-mp-icon-button")).toBe("glass");
|
|
105
|
+
expect(back.querySelector('[data-mp-glass="web"]')).not.toBeNull();
|
|
106
|
+
// WebKit gives web content no system press: the face takes the web press
|
|
107
|
+
// plate, and nothing resizes or fades it.
|
|
108
|
+
const pressed = Array.from(back.classList).filter((c) => c.includes("0active-"));
|
|
109
|
+
expect(pressed.some((c) => c.startsWith("_bg-0active-"))).toBe(true);
|
|
110
|
+
expect(pressed.filter((c) => PRESS_MOTION.test(c))).toEqual([]);
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
it.each([
|
|
73
115
|
["desktop Safari", { userAgent: MAC_SAFARI, platform: "MacIntel", maxTouchPoints: 0 }],
|
|
74
116
|
["Android Chrome", { userAgent: PIXEL, platform: "Linux armv8l", maxTouchPoints: 5 }],
|
|
75
117
|
])("%s loads no glass and draws the plain glyph", (_browser, nav) => {
|
|
76
118
|
vi.stubGlobal("navigator", nav);
|
|
77
119
|
expect(loadGlassView()).toBeNull();
|
|
78
120
|
expect(loadGlassContainer()).toBeNull();
|
|
79
|
-
|
|
80
|
-
createElement(
|
|
81
|
-
"div",
|
|
82
|
-
null,
|
|
83
|
-
createElement(
|
|
84
|
-
IconButtonGroup,
|
|
85
|
-
null,
|
|
86
|
-
createElement(IconButton, { icon: Glyph, "aria-label": "Search" }),
|
|
87
|
-
createElement(IconButton, { icon: Glyph, "aria-label": "More" }),
|
|
88
|
-
),
|
|
89
|
-
createElement(IconButton, { icon: Glyph, "aria-label": "Back" }),
|
|
90
|
-
),
|
|
91
|
-
);
|
|
121
|
+
renderBarRow();
|
|
92
122
|
expect(document.querySelector("[data-mp-glass]")).toBeNull();
|
|
93
123
|
expect(document.querySelector("[data-mp-glass-capsule]")).toBeNull();
|
|
94
124
|
expect(document.querySelector('[data-mp-icon-button-group="bar"]')).not.toBeNull();
|
|
@@ -97,7 +127,7 @@ describe("no glass on the web (LC-176)", () => {
|
|
|
97
127
|
});
|
|
98
128
|
});
|
|
99
129
|
|
|
100
|
-
describe("the drawn web face
|
|
130
|
+
describe("the drawn web face", () => {
|
|
101
131
|
afterEach(cleanup);
|
|
102
132
|
|
|
103
133
|
it("sits under the glyph it backs, which stays its sibling", () => {
|
package/src/Button/glass.ts
CHANGED
|
@@ -20,20 +20,13 @@ export type GlassContainerComponent = ComponentType<{
|
|
|
20
20
|
export { isAppleTouchWeb } from "./webGlass";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* LC-176
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*/
|
|
28
|
-
const iosSafariGlassFace = false;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* LC-176: the system Liquid Glass an icon button sits in on a bar. Only native
|
|
32
|
-
* iOS 26 has it, from expo-glass-effect (`glass.native.ts`; Android probes
|
|
33
|
-
* null), so the web draws the plain glyph.
|
|
23
|
+
* LC-176: the Liquid Glass an icon button sits in on a bar. Native iOS 26 has
|
|
24
|
+
* the system's, from expo-glass-effect (`glass.native.ts`; Android probes
|
|
25
|
+
* null). On the web only iOS Safari takes the drawn glass face (Clay's pick A
|
|
26
|
+
* on rv_c6369c2bab2ffea0, FZ-8666); every other browser draws the plain glyph.
|
|
34
27
|
*/
|
|
35
28
|
export function loadGlassView(): GlassViewComponent | null {
|
|
36
|
-
return
|
|
29
|
+
return isAppleTouchWeb() ? (WebGlassFace as GlassViewComponent) : null;
|
|
37
30
|
}
|
|
38
31
|
|
|
39
32
|
/** LC-176: the system's Liquid Glass container. Only iOS has it. */
|
package/src/Button/index.tsx
CHANGED
|
@@ -465,28 +465,40 @@ export function iconButtonGlyphPx(rowLinePx: number | undefined): number {
|
|
|
465
465
|
/** LC-176: an inline glyph is the text's size; Phosphor's 256 grid pads ~12%. */
|
|
466
466
|
const INLINE_GLYPH_RATIO = 1.2;
|
|
467
467
|
|
|
468
|
+
/**
|
|
469
|
+
* `ink` is the bar tint. It goes to the glyph as well as to its stroke, because
|
|
470
|
+
* a `themed` glyph fills with the theme's text colour unless told otherwise and
|
|
471
|
+
* the stroke would then outline it in a second colour (FZ-8649).
|
|
472
|
+
*/
|
|
468
473
|
function withGlyphWeight(
|
|
469
474
|
icon: IconLike | undefined,
|
|
470
475
|
size: number,
|
|
471
476
|
weight: "regular" | "bold",
|
|
472
477
|
floor = false,
|
|
478
|
+
ink?: string | null,
|
|
473
479
|
): IconLike | undefined {
|
|
474
480
|
if (icon == null || icon === false) return icon;
|
|
481
|
+
const tint = ink ?? undefined;
|
|
475
482
|
if (isValidElement<{ size?: number; weight?: string; color?: string }>(icon)) {
|
|
476
483
|
const resolved = (icon.props.weight ?? weight) as "regular" | "bold";
|
|
477
484
|
const own = icon.props.size;
|
|
478
485
|
return cloneElement(icon, {
|
|
479
486
|
...(own == null || (floor && typeof own === "number" && own < size) ? { size } : undefined),
|
|
480
487
|
...(icon.props.weight == null ? { weight } : undefined),
|
|
481
|
-
...
|
|
488
|
+
...(icon.props.color == null && tint ? { color: tint } : undefined),
|
|
489
|
+
...boldStroke(resolved, icon.props.color ?? tint),
|
|
482
490
|
});
|
|
483
491
|
}
|
|
484
492
|
if (typeof icon === "function" || (typeof icon === "object" && "$$typeof" in icon)) {
|
|
485
|
-
return createElement(
|
|
486
|
-
size
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
493
|
+
return createElement(
|
|
494
|
+
icon as ComponentType<{ size?: number; weight?: string; color?: string }>,
|
|
495
|
+
{
|
|
496
|
+
size,
|
|
497
|
+
weight,
|
|
498
|
+
...(tint ? { color: tint } : undefined),
|
|
499
|
+
...boldStroke(weight, tint),
|
|
500
|
+
},
|
|
501
|
+
);
|
|
490
502
|
}
|
|
491
503
|
return icon;
|
|
492
504
|
}
|
|
@@ -850,8 +862,8 @@ export function Button({
|
|
|
850
862
|
const labelLine = labelLinePx(knobProps.body.fontFamily);
|
|
851
863
|
const glyphFloor = iconButtonGlyphPx(labelLine);
|
|
852
864
|
// LC-176: on iOS 26 a bar's icon button sits in system Liquid Glass, the
|
|
853
|
-
// native bar button
|
|
854
|
-
//
|
|
865
|
+
// native bar button, and iOS Safari draws its web face. Elsewhere, and on a
|
|
866
|
+
// binary without the module, it stays the bare tinted glyph (FZ-8666).
|
|
855
867
|
const glassGroup = groupGround === "glass";
|
|
856
868
|
const GlassView =
|
|
857
869
|
iconButton && !inlineGlyph && !nested && accentInk && barSurface && !selectedFill && !glassGroup
|
|
@@ -911,7 +923,7 @@ export function Button({
|
|
|
911
923
|
const barGlyphFloor = barGlyph && !framedCircle && !inlineGlyph && !nested;
|
|
912
924
|
const glyph =
|
|
913
925
|
barGlyph || inlineGlyph || framedCircle
|
|
914
|
-
? withGlyphWeight(icon, iconSize, resolvedGlyphWeight, barGlyphFloor)
|
|
926
|
+
? withGlyphWeight(icon, iconSize, resolvedGlyphWeight, barGlyphFloor, barInk)
|
|
915
927
|
: icon;
|
|
916
928
|
|
|
917
929
|
// LC-158: the frame keeps its recipe height under Dynamic Type, so the
|
|
@@ -998,7 +1010,7 @@ export function Button({
|
|
|
998
1010
|
) : null;
|
|
999
1011
|
const glyphAfter =
|
|
1000
1012
|
iconAfter && (barGlyph || inlineGlyph || framedCircle)
|
|
1001
|
-
? withGlyphWeight(iconAfter, iconSize, resolvedGlyphWeight, barGlyphFloor)
|
|
1013
|
+
? withGlyphWeight(iconAfter, iconSize, resolvedGlyphWeight, barGlyphFloor, barInk)
|
|
1002
1014
|
: iconAfter;
|
|
1003
1015
|
const iconAfterElement = glyphAfter ? (
|
|
1004
1016
|
<View flexShrink={0}>
|
package/src/Button/webGlass.ts
CHANGED
|
@@ -24,10 +24,11 @@ const webGlassBlur = {
|
|
|
24
24
|
} as const;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* LC-176: the drawn face `loadGlassView`
|
|
28
|
-
* lone button or one capsule for an `IconButtonGroup`.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* LC-176: the drawn face `loadGlassView` gives iOS Safari, one circle for a
|
|
28
|
+
* lone button or one capsule for an `IconButtonGroup`. WebKit gives web content
|
|
29
|
+
* no system glass and no system press, so it takes the web press plate and
|
|
30
|
+
* nothing animates its size. Its children stay siblings above the layer
|
|
31
|
+
* (absolute, z -1 in the button's stacking context).
|
|
31
32
|
*/
|
|
32
33
|
export function WebGlassFace({ style, children }: { style?: unknown; children?: ReactNode }) {
|
|
33
34
|
const dark = isDarkThemeName(useThemeName());
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC-112 icon trigger cover (FZ-8665 Round 45, reversing Round 37's X): a
|
|
3
|
+
* panel that covers the icon button it opened from sits exactly over the
|
|
4
|
+
* surface that button is seen on and repeats nothing. Its content starts at
|
|
5
|
+
* its top edge, a press outside closes it, and Escape closes it on the web.
|
|
6
|
+
*/
|
|
7
|
+
import { PlusIcon } from "@phosphor-icons/react";
|
|
8
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
9
|
+
import { fireEvent, waitFor, within } from "@testing-library/react";
|
|
10
|
+
import { useState } from "react";
|
|
11
|
+
import { MIN_PRESS_TARGET } from "@multiplatform.one/theme";
|
|
12
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
13
|
+
import { Text, XStack } from "tamagui";
|
|
14
|
+
import { Button } from "../Button";
|
|
15
|
+
import { FloatingPanel } from "./index";
|
|
16
|
+
import { PanelHeader } from "./PanelHeader";
|
|
17
|
+
|
|
18
|
+
type Rect = { x: number; y: number; width: number; height: number };
|
|
19
|
+
|
|
20
|
+
function measure(trigger: Rect, panelWidth = 240, panelHeight = 160, surface?: Rect) {
|
|
21
|
+
const original = HTMLElement.prototype.getBoundingClientRect;
|
|
22
|
+
const rect = {
|
|
23
|
+
...trigger,
|
|
24
|
+
top: trigger.y,
|
|
25
|
+
left: trigger.x,
|
|
26
|
+
right: trigger.x + trigger.width,
|
|
27
|
+
bottom: trigger.y + trigger.height,
|
|
28
|
+
toJSON: () => ({}),
|
|
29
|
+
};
|
|
30
|
+
vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(
|
|
31
|
+
function (this: HTMLElement) {
|
|
32
|
+
if (this.hasAttribute("data-fp-reference")) return rect;
|
|
33
|
+
if (surface && this.hasAttribute("data-fp-cover-surface")) {
|
|
34
|
+
return {
|
|
35
|
+
...surface,
|
|
36
|
+
top: surface.y,
|
|
37
|
+
left: surface.x,
|
|
38
|
+
right: surface.x + surface.width,
|
|
39
|
+
bottom: surface.y + surface.height,
|
|
40
|
+
toJSON: () => ({}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return original.call(this);
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
vi.spyOn(HTMLElement.prototype, "offsetWidth", "get").mockImplementation(
|
|
47
|
+
function (this: HTMLElement) {
|
|
48
|
+
return this.hasAttribute("data-fp-panel") ? panelWidth : 0;
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
vi.spyOn(HTMLElement.prototype, "scrollHeight", "get").mockImplementation(
|
|
52
|
+
function (this: HTMLElement) {
|
|
53
|
+
return this.hasAttribute("data-fp-panel") ? panelHeight : 0;
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function AddPanel({ header = false }: { header?: boolean }) {
|
|
59
|
+
const [open, setOpen] = useState(false);
|
|
60
|
+
return (
|
|
61
|
+
<FloatingPanel
|
|
62
|
+
open={open}
|
|
63
|
+
onOpenChange={setOpen}
|
|
64
|
+
anchorMode="cover-trigger"
|
|
65
|
+
compactFace="menu"
|
|
66
|
+
triggerEcho={false}
|
|
67
|
+
iconCover
|
|
68
|
+
coverAlign="auto"
|
|
69
|
+
widthMode="fit-content"
|
|
70
|
+
triggerSizing="content"
|
|
71
|
+
contentPadding="none"
|
|
72
|
+
trigger={<Button icon={PlusIcon} aria-label="Add node" />}
|
|
73
|
+
>
|
|
74
|
+
{header ? (
|
|
75
|
+
<PanelHeader>
|
|
76
|
+
<Text>Add a node</Text>
|
|
77
|
+
</PanelHeader>
|
|
78
|
+
) : (
|
|
79
|
+
<Text>Add a node</Text>
|
|
80
|
+
)}
|
|
81
|
+
<Button>Copy</Button>
|
|
82
|
+
</FloatingPanel>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** An account menu opened from a 32pt avatar: a trigger with no `icon`. */
|
|
87
|
+
function AvatarPanel() {
|
|
88
|
+
return (
|
|
89
|
+
<FloatingPanel
|
|
90
|
+
open
|
|
91
|
+
onOpenChange={() => {}}
|
|
92
|
+
anchorMode="cover-trigger"
|
|
93
|
+
compactFace="menu"
|
|
94
|
+
triggerEcho={false}
|
|
95
|
+
iconCover
|
|
96
|
+
coverAlign="auto"
|
|
97
|
+
widthMode="fit-content"
|
|
98
|
+
triggerSizing="content"
|
|
99
|
+
contentPadding="none"
|
|
100
|
+
trigger={
|
|
101
|
+
<span role="button" aria-label="Account">
|
|
102
|
+
AD
|
|
103
|
+
</span>
|
|
104
|
+
}
|
|
105
|
+
>
|
|
106
|
+
<Text>Sign out</Text>
|
|
107
|
+
</FloatingPanel>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function open(result: ReturnType<typeof renderWithProviders>) {
|
|
112
|
+
fireEvent.click(result.getByRole("button", { name: "Add node" }), { detail: 0 });
|
|
113
|
+
const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
|
|
114
|
+
await waitFor(() => expect(panel.style.visibility).toBe("visible"));
|
|
115
|
+
return panel;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
afterEach(() => {
|
|
119
|
+
vi.restoreAllMocks();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const buttonsIn = (panel: HTMLElement) =>
|
|
123
|
+
within(panel)
|
|
124
|
+
.getAllByRole("button")
|
|
125
|
+
.map((button) => button.textContent || button.getAttribute("aria-label"));
|
|
126
|
+
|
|
127
|
+
/** Whatever sits above the content in the panel: a hidden scroll arrow at most. */
|
|
128
|
+
const aboveContent = (panel: HTMLElement) => {
|
|
129
|
+
const children = [...panel.children] as HTMLElement[];
|
|
130
|
+
const content = children.findIndex((child) => child.textContent?.includes("Add a node"));
|
|
131
|
+
expect(content).toBeGreaterThanOrEqual(0);
|
|
132
|
+
return children.slice(0, content);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
describe("LC-112 icon trigger cover on the web (FZ-8665)", () => {
|
|
136
|
+
const viewportWidth = () => document.documentElement.clientWidth || window.innerWidth;
|
|
137
|
+
|
|
138
|
+
it("covers the + from the button's top trailing corner and repeats nothing", async () => {
|
|
139
|
+
const button = { x: viewportWidth() - 16 - 44, y: 12, width: 44, height: 44 };
|
|
140
|
+
measure(button, 240);
|
|
141
|
+
const result = renderWithProviders(<AddPanel />);
|
|
142
|
+
const panel = await open(result);
|
|
143
|
+
expect(panel.style.top).toBe(`${button.y}px`);
|
|
144
|
+
expect(panel.style.left).toBe(`${button.x + button.width - 240}px`);
|
|
145
|
+
expect(within(panel).queryByRole("button", { name: "Close" })).toBeNull();
|
|
146
|
+
expect(within(panel).queryByRole("button", { name: "Add node" })).toBeNull();
|
|
147
|
+
expect(panel.querySelector("[data-fp-trigger-row]")).toBeNull();
|
|
148
|
+
expect(panel.querySelector("[data-fp-icon-echo]")).toBeNull();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("starts the content at the panel's top edge, with no band above it", async () => {
|
|
152
|
+
measure({ x: 16, y: 12, width: 44, height: 44 });
|
|
153
|
+
const result = renderWithProviders(<AddPanel />);
|
|
154
|
+
const panel = await open(result);
|
|
155
|
+
for (const element of aboveContent(panel)) {
|
|
156
|
+
expect(element.textContent).toBe("");
|
|
157
|
+
expect(element.querySelector("button, [role='button']")).toBeNull();
|
|
158
|
+
expect(element.style.height).toBe("");
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("covers a grouped trigger's whole plate, with both edges, and shows none of its buttons", async () => {
|
|
163
|
+
const button = { x: viewportWidth() - 16 - 44, y: 12, width: 44, height: 44 };
|
|
164
|
+
const plate = { x: button.x - 100, y: 12, width: 144, height: 44 };
|
|
165
|
+
measure(button, 120, 160, plate);
|
|
166
|
+
const result = renderWithProviders(
|
|
167
|
+
<div data-fp-cover-surface="">
|
|
168
|
+
<Button icon={PlusIcon} aria-label="Search" />
|
|
169
|
+
<AddPanel />
|
|
170
|
+
</div>,
|
|
171
|
+
);
|
|
172
|
+
const panel = await open(result);
|
|
173
|
+
// The plate is wider than the menu, so the menu takes the plate's width
|
|
174
|
+
// and both edges.
|
|
175
|
+
expect(panel.style.left).toBe(`${plate.x}px`);
|
|
176
|
+
expect(panel.style.top).toBe(`${plate.y}px`);
|
|
177
|
+
expect(panel.style.minWidth).toBe(`${plate.width}px`);
|
|
178
|
+
expect(buttonsIn(panel)).toEqual(["Copy"]);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("closes on a press outside the panel", async () => {
|
|
182
|
+
measure({ x: 16, y: 12, width: 44, height: 44 });
|
|
183
|
+
const result = renderWithProviders(<AddPanel />);
|
|
184
|
+
await open(result);
|
|
185
|
+
fireEvent.click(document.body);
|
|
186
|
+
await waitFor(() => expect(result.queryByTestId("floating-panel-viewport")).toBeNull());
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("closes on Escape and hands focus back to the button", async () => {
|
|
190
|
+
measure({ x: 16, y: 12, width: 44, height: 44 });
|
|
191
|
+
const result = renderWithProviders(<AddPanel />);
|
|
192
|
+
const trigger = result.getByRole("button", { name: "Add node" });
|
|
193
|
+
trigger.focus();
|
|
194
|
+
await open(result);
|
|
195
|
+
fireEvent.keyDown(document, { key: "Escape" });
|
|
196
|
+
await waitFor(() => expect(result.queryByTestId("floating-panel-viewport")).toBeNull());
|
|
197
|
+
await waitFor(() => expect(document.activeElement).toBe(trigger));
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("puts a panel's title on the panel's normal padding, keeping clear of nothing", async () => {
|
|
201
|
+
const button = { x: viewportWidth() - 16 - 44, y: 12, width: 44, height: 44 };
|
|
202
|
+
measure(button, 240);
|
|
203
|
+
const result = renderWithProviders(
|
|
204
|
+
<>
|
|
205
|
+
<AddPanel header />
|
|
206
|
+
<XStack
|
|
207
|
+
data-testid="normal-padding"
|
|
208
|
+
alignItems="center"
|
|
209
|
+
gap="$2"
|
|
210
|
+
paddingLeft="$4"
|
|
211
|
+
paddingRight="$4"
|
|
212
|
+
paddingTop="$4"
|
|
213
|
+
/>
|
|
214
|
+
</>,
|
|
215
|
+
);
|
|
216
|
+
const panel = await open(result);
|
|
217
|
+
const header = panel.querySelector<HTMLElement>("[data-fp-panel-header]") as HTMLElement;
|
|
218
|
+
expect(header.className).toBe(result.getByTestId("normal-padding").className);
|
|
219
|
+
expect(header.style.minHeight).toBe("");
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("keeps a content-sized trigger on a centring row's line", async () => {
|
|
223
|
+
measure({ x: 16, y: 12, width: 44, height: 44 });
|
|
224
|
+
const centred = renderWithProviders(
|
|
225
|
+
<div style={{ display: "flex", flexDirection: "row", alignItems: "center", height: 60 }}>
|
|
226
|
+
<AddPanel />
|
|
227
|
+
</div>,
|
|
228
|
+
);
|
|
229
|
+
const inRow = centred.container.querySelector<HTMLElement>(
|
|
230
|
+
"[data-fp-reference]",
|
|
231
|
+
) as HTMLElement;
|
|
232
|
+
await waitFor(() => expect(getComputedStyle(inRow).alignSelf).not.toBe("flex-start"));
|
|
233
|
+
centred.unmount();
|
|
234
|
+
const column = renderWithProviders(
|
|
235
|
+
<div style={{ display: "flex", flexDirection: "column", alignItems: "stretch" }}>
|
|
236
|
+
<AddPanel />
|
|
237
|
+
</div>,
|
|
238
|
+
);
|
|
239
|
+
const inColumn = column.container.querySelector<HTMLElement>(
|
|
240
|
+
"[data-fp-reference]",
|
|
241
|
+
) as HTMLElement;
|
|
242
|
+
expect(getComputedStyle(inColumn).alignSelf).toBe("flex-start");
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("gives a keyboard its content and no extra stop", async () => {
|
|
246
|
+
measure({ x: 16, y: 12, width: 44, height: 44 });
|
|
247
|
+
const result = renderWithProviders(<AddPanel />);
|
|
248
|
+
const panel = await open(result);
|
|
249
|
+
expect(buttonsIn(panel)).toEqual(["Copy"]);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("opens up from the button's bottom edge near the bottom, still covering it", async () => {
|
|
253
|
+
const button = { x: 16, y: window.innerHeight - 60, width: 44, height: 44 };
|
|
254
|
+
measure(button, 240, 300);
|
|
255
|
+
const result = renderWithProviders(<AddPanel />);
|
|
256
|
+
const panel = await open(result);
|
|
257
|
+
const frame = getComputedStyle(panel);
|
|
258
|
+
const borders =
|
|
259
|
+
(parseFloat(frame.borderTopWidth) || 0) + (parseFloat(frame.borderBottomWidth) || 0);
|
|
260
|
+
expect(parseFloat(panel.style.top) + 300 + borders).toBe(button.y + button.height);
|
|
261
|
+
expect(panel.style.left).toBe(`${button.x}px`);
|
|
262
|
+
expect(panel.style.transformOrigin).toBe("bottom left");
|
|
263
|
+
expect(result.queryByTestId("floating-panel-sheet")).toBeNull();
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("covers a 32pt avatar at its 44pt target, its centre on the row-icon column (FZ-8480 GAP)", async () => {
|
|
267
|
+
const avatar = { x: 100, y: 18, width: 32, height: 32 };
|
|
268
|
+
measure(avatar, 240);
|
|
269
|
+
const result = renderWithProviders(<AvatarPanel />);
|
|
270
|
+
const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
|
|
271
|
+
await waitFor(() => expect(panel.style.visibility).toBe("visible"));
|
|
272
|
+
const inset = (MIN_PRESS_TARGET - avatar.width) / 2;
|
|
273
|
+
expect(panel.style.left).toBe(`${avatar.x - inset}px`);
|
|
274
|
+
expect(panel.style.top).toBe(`${avatar.y - inset}px`);
|
|
275
|
+
// The avatar's centre sits half a press target in, the centre of a menu
|
|
276
|
+
// row's leading glyph slot.
|
|
277
|
+
expect(inset + avatar.width / 2).toBe(MIN_PRESS_TARGET / 2);
|
|
278
|
+
});
|
|
279
|
+
});
|