@multiplatform.one/forms 7.71.0 → 7.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Button/circleGlyph.cjs +28 -0
- package/dist/cjs/Button/circleGlyph.native.js +31 -0
- package/dist/cjs/Button/circleGlyph.native.js.map +1 -0
- package/dist/cjs/Button/index.cjs +19 -3
- package/dist/cjs/Button/index.native.js +19 -3
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/PanelHeader.cjs +49 -0
- package/dist/cjs/FloatingPanel/PanelHeader.native.js +53 -0
- package/dist/cjs/FloatingPanel/PanelHeader.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/echoContext.cjs +67 -0
- package/dist/cjs/FloatingPanel/echoContext.native.js +71 -0
- package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/iconEcho.cjs +104 -0
- package/dist/cjs/FloatingPanel/iconEcho.native.js +114 -0
- package/dist/cjs/FloatingPanel/iconEcho.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/index.cjs +371 -86
- package/dist/cjs/FloatingPanel/index.native.js +164 -20
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/paintedBox.cjs +80 -0
- package/dist/cjs/FloatingPanel/paintedBox.native.js +85 -0
- package/dist/cjs/FloatingPanel/paintedBox.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/panelWidth.cjs +92 -0
- package/dist/cjs/FloatingPanel/panelWidth.native.js +99 -0
- package/dist/cjs/FloatingPanel/panelWidth.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/pointAnchor.cjs +34 -5
- package/dist/cjs/FloatingPanel/pointAnchor.native.js +37 -8
- package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/useFloatingPanel.cjs +60 -5
- package/dist/cjs/FloatingPanel/useFloatingPanel.native.js +72 -5
- package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/cjs/InputParts/index.cjs +18 -0
- package/dist/cjs/InputParts/index.native.js +19 -1
- package/dist/cjs/InputParts/index.native.js.map +1 -1
- package/dist/cjs/Wheel/NativeWheel.native.js +1 -1
- package/dist/cjs/Wheel/NativeWheel.native.js.map +1 -1
- package/dist/cjs/Wheel/index.cjs +2 -1
- package/dist/cjs/Wheel/index.native.js +4 -1
- package/dist/cjs/Wheel/index.native.js.map +1 -1
- package/dist/cjs/Wheel/wheelShared.cjs +6 -1
- package/dist/cjs/Wheel/wheelShared.native.js +7 -1
- package/dist/cjs/Wheel/wheelShared.native.js.map +1 -1
- package/dist/cjs/fields/Combobox/index.cjs +1 -0
- package/dist/cjs/fields/Combobox/index.native.js +1 -0
- package/dist/cjs/fields/Combobox/index.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.cjs +6 -30
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
- package/dist/cjs/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/DatetimePicker.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/catalog.cjs +2 -28
- package/dist/cjs/fields/DatePicker/catalog.native.js +2 -30
- package/dist/cjs/fields/DatePicker/catalog.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/index.native.js.map +1 -1
- package/dist/cjs/fields/DatePicker/parts.cjs +11 -20
- package/dist/cjs/fields/DatePicker/parts.native.js +13 -22
- package/dist/cjs/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/cjs/fields/Select/index.cjs +65 -44
- package/dist/cjs/fields/Select/index.native.js +69 -47
- package/dist/cjs/fields/Select/index.native.js.map +1 -1
- package/dist/cjs/fields/Select/shouldInlineChoices.cjs +3 -1
- package/dist/cjs/fields/Select/shouldInlineChoices.native.js +3 -1
- package/dist/cjs/fields/Select/shouldInlineChoices.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/catalog.cjs +4 -25
- package/dist/cjs/fields/TimePicker/catalog.native.js +7 -29
- package/dist/cjs/fields/TimePicker/catalog.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/parts.cjs +8 -21
- package/dist/cjs/fields/TimePicker/parts.native.js +8 -21
- package/dist/cjs/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.native.js +2 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/shared/floatingList.cjs +13 -4
- package/dist/cjs/shared/floatingList.native.js +15 -4
- package/dist/cjs/shared/floatingList.native.js.map +1 -1
- package/dist/esm/Button/circleGlyph.mjs +3 -0
- package/dist/esm/Button/circleGlyph.mjs.map +1 -0
- package/dist/esm/Button/circleGlyph.native.js +3 -0
- package/dist/esm/Button/circleGlyph.native.js.map +1 -0
- package/dist/esm/Button/index.mjs +18 -2
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +18 -2
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/PanelHeader.mjs +24 -0
- package/dist/esm/FloatingPanel/PanelHeader.mjs.map +1 -0
- package/dist/esm/FloatingPanel/PanelHeader.native.js +25 -0
- package/dist/esm/FloatingPanel/PanelHeader.native.js.map +1 -0
- package/dist/esm/FloatingPanel/echoContext.mjs +35 -0
- package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -0
- package/dist/esm/FloatingPanel/echoContext.native.js +36 -0
- package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -0
- package/dist/esm/FloatingPanel/iconEcho.mjs +77 -0
- package/dist/esm/FloatingPanel/iconEcho.mjs.map +1 -0
- package/dist/esm/FloatingPanel/iconEcho.native.js +84 -0
- package/dist/esm/FloatingPanel/iconEcho.native.js.map +1 -0
- package/dist/esm/FloatingPanel/index.mjs +373 -90
- package/dist/esm/FloatingPanel/index.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +165 -23
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/paintedBox.mjs +52 -0
- package/dist/esm/FloatingPanel/paintedBox.mjs.map +1 -0
- package/dist/esm/FloatingPanel/paintedBox.native.js +54 -0
- package/dist/esm/FloatingPanel/paintedBox.native.js.map +1 -0
- package/dist/esm/FloatingPanel/panelWidth.mjs +63 -0
- package/dist/esm/FloatingPanel/panelWidth.mjs.map +1 -0
- package/dist/esm/FloatingPanel/panelWidth.native.js +67 -0
- package/dist/esm/FloatingPanel/panelWidth.native.js.map +1 -0
- package/dist/esm/FloatingPanel/pointAnchor.mjs +34 -5
- package/dist/esm/FloatingPanel/pointAnchor.mjs.map +1 -1
- package/dist/esm/FloatingPanel/pointAnchor.native.js +37 -8
- package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/esm/FloatingPanel/useFloatingPanel.mjs +60 -6
- package/dist/esm/FloatingPanel/useFloatingPanel.mjs.map +1 -1
- package/dist/esm/FloatingPanel/useFloatingPanel.native.js +72 -6
- package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/esm/InputParts/index.mjs +19 -1
- package/dist/esm/InputParts/index.mjs.map +1 -1
- package/dist/esm/InputParts/index.native.js +20 -2
- package/dist/esm/InputParts/index.native.js.map +1 -1
- package/dist/esm/Wheel/NativeWheel.native.js +1 -1
- package/dist/esm/Wheel/NativeWheel.native.js.map +1 -1
- package/dist/esm/Wheel/index.mjs +2 -1
- package/dist/esm/Wheel/index.mjs.map +1 -1
- package/dist/esm/Wheel/index.native.js +4 -1
- package/dist/esm/Wheel/index.native.js.map +1 -1
- package/dist/esm/Wheel/wheelShared.mjs +6 -1
- package/dist/esm/Wheel/wheelShared.mjs.map +1 -1
- package/dist/esm/Wheel/wheelShared.native.js +7 -1
- package/dist/esm/Wheel/wheelShared.native.js.map +1 -1
- package/dist/esm/fields/Combobox/index.mjs +1 -0
- package/dist/esm/fields/Combobox/index.mjs.map +1 -1
- package/dist/esm/fields/Combobox/index.native.js +1 -0
- package/dist/esm/fields/Combobox/index.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs +6 -30
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
- package/dist/esm/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/DatetimePicker.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/catalog.mjs +2 -28
- package/dist/esm/fields/DatePicker/catalog.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/catalog.native.js +2 -30
- package/dist/esm/fields/DatePicker/catalog.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/index.native.js.map +1 -1
- package/dist/esm/fields/DatePicker/parts.mjs +11 -20
- package/dist/esm/fields/DatePicker/parts.mjs.map +1 -1
- package/dist/esm/fields/DatePicker/parts.native.js +13 -22
- package/dist/esm/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/esm/fields/Select/index.mjs +66 -45
- package/dist/esm/fields/Select/index.mjs.map +1 -1
- package/dist/esm/fields/Select/index.native.js +70 -48
- package/dist/esm/fields/Select/index.native.js.map +1 -1
- package/dist/esm/fields/Select/shouldInlineChoices.mjs +3 -1
- package/dist/esm/fields/Select/shouldInlineChoices.mjs.map +1 -1
- package/dist/esm/fields/Select/shouldInlineChoices.native.js +3 -1
- package/dist/esm/fields/Select/shouldInlineChoices.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/catalog.mjs +4 -25
- package/dist/esm/fields/TimePicker/catalog.mjs.map +1 -1
- package/dist/esm/fields/TimePicker/catalog.native.js +7 -29
- package/dist/esm/fields/TimePicker/catalog.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/parts.mjs +8 -21
- package/dist/esm/fields/TimePicker/parts.mjs.map +1 -1
- package/dist/esm/fields/TimePicker/parts.native.js +8 -21
- package/dist/esm/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/shared/floatingList.mjs +14 -5
- package/dist/esm/shared/floatingList.mjs.map +1 -1
- package/dist/esm/shared/floatingList.native.js +16 -5
- package/dist/esm/shared/floatingList.native.js.map +1 -1
- package/dist/jsx/Button/circleGlyph.mjs +3 -0
- package/dist/jsx/Button/circleGlyph.mjs.map +1 -0
- package/dist/jsx/Button/circleGlyph.native.js +31 -0
- package/dist/jsx/Button/circleGlyph.native.js.map +1 -0
- package/dist/jsx/Button/index.mjs +18 -2
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +19 -3
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/PanelHeader.mjs +24 -0
- package/dist/jsx/FloatingPanel/PanelHeader.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/PanelHeader.native.js +53 -0
- package/dist/jsx/FloatingPanel/PanelHeader.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/echoContext.mjs +35 -0
- package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/echoContext.native.js +71 -0
- package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/iconEcho.mjs +77 -0
- package/dist/jsx/FloatingPanel/iconEcho.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/iconEcho.native.js +114 -0
- package/dist/jsx/FloatingPanel/iconEcho.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/index.mjs +373 -90
- package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +164 -20
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/paintedBox.mjs +52 -0
- package/dist/jsx/FloatingPanel/paintedBox.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/paintedBox.native.js +85 -0
- package/dist/jsx/FloatingPanel/paintedBox.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/panelWidth.mjs +63 -0
- package/dist/jsx/FloatingPanel/panelWidth.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/panelWidth.native.js +99 -0
- package/dist/jsx/FloatingPanel/panelWidth.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/pointAnchor.mjs +34 -5
- package/dist/jsx/FloatingPanel/pointAnchor.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/pointAnchor.native.js +37 -8
- package/dist/jsx/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/useFloatingPanel.mjs +60 -6
- package/dist/jsx/FloatingPanel/useFloatingPanel.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/useFloatingPanel.native.js +72 -5
- package/dist/jsx/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/jsx/InputParts/index.mjs +19 -1
- package/dist/jsx/InputParts/index.mjs.map +1 -1
- package/dist/jsx/InputParts/index.native.js +19 -1
- package/dist/jsx/InputParts/index.native.js.map +1 -1
- package/dist/jsx/Wheel/NativeWheel.native.js +1 -1
- package/dist/jsx/Wheel/NativeWheel.native.js.map +1 -1
- package/dist/jsx/Wheel/index.mjs +2 -1
- package/dist/jsx/Wheel/index.mjs.map +1 -1
- package/dist/jsx/Wheel/index.native.js +4 -1
- package/dist/jsx/Wheel/index.native.js.map +1 -1
- package/dist/jsx/Wheel/wheelShared.mjs +6 -1
- package/dist/jsx/Wheel/wheelShared.mjs.map +1 -1
- package/dist/jsx/Wheel/wheelShared.native.js +7 -1
- package/dist/jsx/Wheel/wheelShared.native.js.map +1 -1
- package/dist/jsx/fields/Combobox/index.mjs +1 -0
- package/dist/jsx/fields/Combobox/index.mjs.map +1 -1
- package/dist/jsx/fields/Combobox/index.native.js +1 -0
- package/dist/jsx/fields/Combobox/index.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs +6 -30
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js +11 -34
- package/dist/jsx/fields/DatePicker/DatetimePicker.catalog.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/DatetimePicker.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/catalog.mjs +2 -28
- package/dist/jsx/fields/DatePicker/catalog.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/catalog.native.js +2 -30
- package/dist/jsx/fields/DatePicker/catalog.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/index.native.js.map +1 -1
- package/dist/jsx/fields/DatePicker/parts.mjs +11 -20
- package/dist/jsx/fields/DatePicker/parts.mjs.map +1 -1
- package/dist/jsx/fields/DatePicker/parts.native.js +13 -22
- package/dist/jsx/fields/DatePicker/parts.native.js.map +1 -1
- package/dist/jsx/fields/Select/index.mjs +66 -45
- package/dist/jsx/fields/Select/index.mjs.map +1 -1
- package/dist/jsx/fields/Select/index.native.js +69 -47
- package/dist/jsx/fields/Select/index.native.js.map +1 -1
- package/dist/jsx/fields/Select/shouldInlineChoices.mjs +3 -1
- package/dist/jsx/fields/Select/shouldInlineChoices.mjs.map +1 -1
- package/dist/jsx/fields/Select/shouldInlineChoices.native.js +3 -1
- package/dist/jsx/fields/Select/shouldInlineChoices.native.js.map +1 -1
- package/dist/jsx/fields/TimePicker/catalog.mjs +4 -25
- package/dist/jsx/fields/TimePicker/catalog.mjs.map +1 -1
- package/dist/jsx/fields/TimePicker/catalog.native.js +7 -29
- package/dist/jsx/fields/TimePicker/catalog.native.js.map +1 -1
- package/dist/jsx/fields/TimePicker/index.native.js.map +1 -1
- package/dist/jsx/fields/TimePicker/parts.mjs +8 -21
- package/dist/jsx/fields/TimePicker/parts.mjs.map +1 -1
- package/dist/jsx/fields/TimePicker/parts.native.js +8 -21
- package/dist/jsx/fields/TimePicker/parts.native.js.map +1 -1
- package/dist/jsx/index.js +2 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +2 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +2 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/shared/floatingList.mjs +14 -5
- package/dist/jsx/shared/floatingList.mjs.map +1 -1
- package/dist/jsx/shared/floatingList.native.js +15 -4
- package/dist/jsx/shared/floatingList.native.js.map +1 -1
- package/package.json +8 -8
- package/src/Button/circleGlyph.ts +6 -0
- package/src/Button/index.tsx +25 -7
- package/src/FloatingPanel/FloatingPanel.echoStretch.spec.tsx +67 -0
- package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +297 -0
- package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +280 -3
- package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +237 -0
- package/src/FloatingPanel/PanelHeader.tsx +26 -0
- package/src/FloatingPanel/echoContext.ts +67 -0
- package/src/FloatingPanel/iconEcho.tsx +118 -0
- package/src/FloatingPanel/index.native.tsx +220 -12
- package/src/FloatingPanel/index.tsx +539 -109
- package/src/FloatingPanel/paintedBox.spec.ts +95 -0
- package/src/FloatingPanel/paintedBox.ts +75 -0
- package/src/FloatingPanel/panelWidth.spec.ts +158 -0
- package/src/FloatingPanel/panelWidth.ts +122 -0
- package/src/FloatingPanel/panelWidthContract.spec.ts +10 -10
- package/src/FloatingPanel/pointAnchor.spec.ts +111 -2
- package/src/FloatingPanel/pointAnchor.ts +56 -3
- package/src/FloatingPanel/useFloatingPanel.spec.tsx +124 -4
- package/src/FloatingPanel/useFloatingPanel.ts +112 -34
- package/src/InputParts/index.tsx +26 -0
- package/src/Wheel/NativeWheel.native.tsx +1 -1
- package/src/Wheel/Wheel.spec.tsx +9 -0
- package/src/Wheel/index.tsx +12 -3
- package/src/Wheel/wheelShared.ts +6 -2
- package/src/fields/Combobox/index.tsx +1 -0
- package/src/fields/DatePicker/DatePicker.stories.tsx +3 -3
- package/src/fields/DatePicker/DatetimePicker.catalog.tsx +17 -45
- package/src/fields/DatePicker/DatetimePicker.native.tsx +3 -0
- package/src/fields/DatePicker/catalog.tsx +8 -39
- package/src/fields/DatePicker/index.native.tsx +3 -0
- package/src/fields/DatePicker/parts.tsx +13 -23
- package/src/fields/DatePicker/seamlessCover.spec.tsx +180 -0
- package/src/fields/DatePicker/touchWeb.spec.tsx +109 -167
- package/src/fields/Select/Select.containingBlock.spec.tsx +191 -0
- package/src/fields/Select/Select.stories.tsx +43 -0
- package/src/fields/Select/index.tsx +109 -45
- package/src/fields/Select/shouldInlineChoices.spec.ts +13 -0
- package/src/fields/Select/shouldInlineChoices.ts +6 -0
- package/src/fields/TimePicker/catalog.tsx +12 -33
- package/src/fields/TimePicker/index.native.tsx +2 -0
- package/src/fields/TimePicker/parts.tsx +6 -20
- package/src/index.ts +3 -0
- package/src/shared/floatingList.tsx +21 -5
- package/types/Button/circleGlyph.d.ts +7 -0
- package/types/Button/circleGlyph.d.ts.map +1 -0
- package/types/Button/index.d.ts +2 -6
- package/types/Button/index.d.ts.map +1 -1
- package/types/FloatingPanel/PanelHeader.d.ts +9 -0
- package/types/FloatingPanel/PanelHeader.d.ts.map +1 -0
- package/types/FloatingPanel/echoContext.d.ts +38 -0
- package/types/FloatingPanel/echoContext.d.ts.map +1 -0
- package/types/FloatingPanel/iconEcho.d.ts +29 -0
- package/types/FloatingPanel/iconEcho.d.ts.map +1 -0
- package/types/FloatingPanel/index.d.ts +69 -0
- package/types/FloatingPanel/index.d.ts.map +1 -1
- package/types/FloatingPanel/index.native.d.ts +9 -1
- package/types/FloatingPanel/index.native.d.ts.map +1 -1
- package/types/FloatingPanel/paintedBox.d.ts +29 -0
- package/types/FloatingPanel/paintedBox.d.ts.map +1 -0
- package/types/FloatingPanel/panelWidth.d.ts +71 -0
- package/types/FloatingPanel/panelWidth.d.ts.map +1 -0
- package/types/FloatingPanel/pointAnchor.d.ts +17 -1
- package/types/FloatingPanel/pointAnchor.d.ts.map +1 -1
- package/types/FloatingPanel/useFloatingPanel.d.ts +33 -2
- package/types/FloatingPanel/useFloatingPanel.d.ts.map +1 -1
- package/types/InputParts/index.d.ts.map +1 -1
- package/types/Wheel/index.d.ts.map +1 -1
- package/types/Wheel/wheelShared.d.ts +2 -1
- package/types/Wheel/wheelShared.d.ts.map +1 -1
- package/types/fields/Combobox/index.d.ts.map +1 -1
- package/types/fields/DatePicker/DatetimePicker.catalog.d.ts +6 -0
- package/types/fields/DatePicker/DatetimePicker.catalog.d.ts.map +1 -1
- package/types/fields/DatePicker/DatetimePicker.native.d.ts +3 -0
- package/types/fields/DatePicker/DatetimePicker.native.d.ts.map +1 -1
- package/types/fields/DatePicker/catalog.d.ts +6 -0
- package/types/fields/DatePicker/catalog.d.ts.map +1 -1
- package/types/fields/DatePicker/index.native.d.ts +3 -0
- package/types/fields/DatePicker/index.native.d.ts.map +1 -1
- package/types/fields/DatePicker/parts.d.ts +5 -7
- package/types/fields/DatePicker/parts.d.ts.map +1 -1
- package/types/fields/Select/index.d.ts +8 -1
- package/types/fields/Select/index.d.ts.map +1 -1
- package/types/fields/Select/shouldInlineChoices.d.ts +5 -1
- package/types/fields/Select/shouldInlineChoices.d.ts.map +1 -1
- package/types/fields/TimePicker/catalog.d.ts +7 -1
- package/types/fields/TimePicker/catalog.d.ts.map +1 -1
- package/types/fields/TimePicker/index.native.d.ts +2 -0
- package/types/fields/TimePicker/index.native.d.ts.map +1 -1
- package/types/fields/TimePicker/parts.d.ts +1 -3
- package/types/fields/TimePicker/parts.d.ts.map +1 -1
- package/types/index.d.ts +3 -0
- package/types/index.d.ts.map +1 -1
- package/types/shared/floatingList.d.ts +5 -1
- package/types/shared/floatingList.d.ts.map +1 -1
- package/dist/cjs/shared/touchWebPicker.cjs +0 -136
- package/dist/cjs/shared/touchWebPicker.native.js +0 -154
- package/dist/cjs/shared/touchWebPicker.native.js.map +0 -1
- package/dist/esm/shared/touchWebPicker.mjs +0 -105
- package/dist/esm/shared/touchWebPicker.mjs.map +0 -1
- package/dist/esm/shared/touchWebPicker.native.js +0 -120
- package/dist/esm/shared/touchWebPicker.native.js.map +0 -1
- package/dist/jsx/shared/touchWebPicker.mjs +0 -105
- package/dist/jsx/shared/touchWebPicker.mjs.map +0 -1
- package/dist/jsx/shared/touchWebPicker.native.js +0 -154
- package/dist/jsx/shared/touchWebPicker.native.js.map +0 -1
- package/src/shared/touchWebPicker.spec.ts +0 -98
- package/src/shared/touchWebPicker.tsx +0 -158
- package/types/shared/touchWebPicker.d.ts +0 -40
- package/types/shared/touchWebPicker.d.ts.map +0 -1
|
@@ -136,6 +136,10 @@ export interface TriggerPlacement {
|
|
|
136
136
|
maxHeight: number;
|
|
137
137
|
/** The menu moved off the trigger's top start corner to stay on screen. */
|
|
138
138
|
shifted: boolean;
|
|
139
|
+
/** An `"auto"` menu took the trigger's top trailing corner instead. */
|
|
140
|
+
end: boolean;
|
|
141
|
+
/** A pinned menu opened upward: its bottom edge is the trigger's. */
|
|
142
|
+
up: boolean;
|
|
139
143
|
}
|
|
140
144
|
|
|
141
145
|
/**
|
|
@@ -151,17 +155,56 @@ export function placeOverTrigger({
|
|
|
151
155
|
height,
|
|
152
156
|
bounds,
|
|
153
157
|
rtl = false,
|
|
158
|
+
align = "start",
|
|
159
|
+
pinned = false,
|
|
154
160
|
}: {
|
|
155
161
|
trigger: TriggerRect;
|
|
156
162
|
width: number;
|
|
157
163
|
height: number;
|
|
158
164
|
bounds: PanelBounds;
|
|
159
165
|
rtl?: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* `"auto"` (a menu with no echo row) opens from the trailing top corner when
|
|
168
|
+
* the leading one would run off the end edge and the trailing one fits.
|
|
169
|
+
*/
|
|
170
|
+
align?: "start" | "auto";
|
|
171
|
+
/**
|
|
172
|
+
* The menu echoes its icon trigger in the button's own spot (LC-112,
|
|
173
|
+
* FZ-8480), so it never slides off the button vertically: it opens down
|
|
174
|
+
* from the button's top edge, or up from its bottom edge where there is
|
|
175
|
+
* more room above, and scrolls what still does not fit.
|
|
176
|
+
*/
|
|
177
|
+
pinned?: boolean;
|
|
160
178
|
}): TriggerPlacement {
|
|
161
179
|
const room = Math.max(0, bounds.right - bounds.left);
|
|
162
180
|
const w = Math.min(Math.max(width, trigger.width), room);
|
|
163
|
-
const
|
|
164
|
-
const
|
|
181
|
+
const startLeft = rtl ? trigger.x + trigger.width - w : trigger.x;
|
|
182
|
+
const endLeft = rtl ? trigger.x : trigger.x + trigger.width - w;
|
|
183
|
+
// Only the free edge has to clear the padded bounds: the aligned edge is
|
|
184
|
+
// the trigger's own, so a bar button inside the margin keeps its corner.
|
|
185
|
+
const startFree = rtl ? startLeft >= bounds.left : startLeft + w <= bounds.right;
|
|
186
|
+
const endFree = rtl ? endLeft + w <= bounds.right : endLeft >= bounds.left;
|
|
187
|
+
const auto = align === "auto";
|
|
188
|
+
const end = auto && !startFree && endFree;
|
|
189
|
+
const wantLeft = end ? endLeft : startLeft;
|
|
190
|
+
const keep = auto && (end || startFree);
|
|
191
|
+
const left = keep ? wantLeft : Math.max(bounds.left, Math.min(wantLeft, bounds.right - w));
|
|
192
|
+
if (pinned) {
|
|
193
|
+
const triggerBottom = trigger.y + trigger.height;
|
|
194
|
+
const below = Math.max(0, bounds.bottom - trigger.y);
|
|
195
|
+
const above = Math.max(0, triggerBottom - bounds.top);
|
|
196
|
+
const up = height > below && above > below;
|
|
197
|
+
const top = up ? Math.max(bounds.top, triggerBottom - height) : trigger.y;
|
|
198
|
+
return {
|
|
199
|
+
left,
|
|
200
|
+
top,
|
|
201
|
+
width: w,
|
|
202
|
+
maxHeight: up ? above : below,
|
|
203
|
+
shifted: left !== wantLeft,
|
|
204
|
+
end,
|
|
205
|
+
up,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
165
208
|
const h = Math.min(height, Math.max(0, bounds.bottom - bounds.top));
|
|
166
209
|
const top = Math.max(bounds.top, Math.min(trigger.y, bounds.bottom - h));
|
|
167
210
|
return {
|
|
@@ -170,6 +213,8 @@ export function placeOverTrigger({
|
|
|
170
213
|
width: w,
|
|
171
214
|
maxHeight: Math.max(0, bounds.bottom - top),
|
|
172
215
|
shifted: left !== wantLeft || top !== trigger.y,
|
|
216
|
+
end,
|
|
217
|
+
up: false,
|
|
173
218
|
};
|
|
174
219
|
}
|
|
175
220
|
|
|
@@ -200,5 +245,13 @@ export function placeBesideTrigger({
|
|
|
200
245
|
const opensUp = height > below && above > below;
|
|
201
246
|
const maxHeight = Math.min(height, opensUp ? above : below);
|
|
202
247
|
const top = opensUp ? trigger.y - maxHeight : trigger.y + trigger.height;
|
|
203
|
-
return {
|
|
248
|
+
return {
|
|
249
|
+
left,
|
|
250
|
+
top,
|
|
251
|
+
width: w,
|
|
252
|
+
maxHeight,
|
|
253
|
+
shifted: left !== wantLeft || opensUp,
|
|
254
|
+
end: false,
|
|
255
|
+
up: opensUp,
|
|
256
|
+
};
|
|
204
257
|
}
|
|
@@ -22,11 +22,13 @@ import { FloatingPanel } from "./index";
|
|
|
22
22
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
23
23
|
import { Preset, type Knobs } from "@multiplatform.one/theme";
|
|
24
24
|
import { afterEach, describe, expect, it } from "vitest";
|
|
25
|
+
import { type PanelWidth } from "./panelWidth";
|
|
25
26
|
import {
|
|
26
27
|
type PanelWidthMode,
|
|
27
28
|
measureDrawnRadius,
|
|
28
29
|
panelAnchorOffset,
|
|
29
30
|
panelCoverOffset,
|
|
31
|
+
panelViewportPadding,
|
|
30
32
|
resolvePanelWidthMode,
|
|
31
33
|
useFloatingPanel,
|
|
32
34
|
} from "./useFloatingPanel";
|
|
@@ -35,10 +37,14 @@ function Harness({
|
|
|
35
37
|
open,
|
|
36
38
|
fitContent,
|
|
37
39
|
widthMode,
|
|
40
|
+
panelWidth,
|
|
41
|
+
echo,
|
|
38
42
|
}: {
|
|
39
43
|
open: boolean;
|
|
40
44
|
fitContent?: boolean;
|
|
41
45
|
widthMode?: PanelWidthMode;
|
|
46
|
+
panelWidth?: PanelWidth;
|
|
47
|
+
echo?: boolean;
|
|
42
48
|
}) {
|
|
43
49
|
const panel = useFloatingPanel({
|
|
44
50
|
open,
|
|
@@ -46,6 +52,8 @@ function Harness({
|
|
|
46
52
|
useAutoUpdate: false,
|
|
47
53
|
fitContent,
|
|
48
54
|
widthMode,
|
|
55
|
+
panelWidth,
|
|
56
|
+
echo,
|
|
49
57
|
});
|
|
50
58
|
return (
|
|
51
59
|
<>
|
|
@@ -76,7 +84,12 @@ function mockRect(el: HTMLElement, rect: { x: number; y: number; width: number;
|
|
|
76
84
|
/** Open the panel against a trigger of a known geometry and hand back the
|
|
77
85
|
* floating element once floating-ui has positioned it. */
|
|
78
86
|
async function openAgainstTrigger(
|
|
79
|
-
props: {
|
|
87
|
+
props: {
|
|
88
|
+
fitContent?: boolean;
|
|
89
|
+
widthMode?: PanelWidthMode;
|
|
90
|
+
panelWidth?: PanelWidth;
|
|
91
|
+
echo?: boolean;
|
|
92
|
+
},
|
|
80
93
|
triggerRect: { x: number; y: number; width: number; height: number },
|
|
81
94
|
) {
|
|
82
95
|
const result = renderWithProviders(<Harness open={false} {...props} />);
|
|
@@ -173,6 +186,90 @@ describe("FloatingPanel and DropdownMenu open over their trigger (MPO-38 cover r
|
|
|
173
186
|
});
|
|
174
187
|
});
|
|
175
188
|
|
|
189
|
+
describe("FloatingPanel panelWidth setting (LC-112, FZ-8438 r3)", () => {
|
|
190
|
+
const room = () =>
|
|
191
|
+
(document.documentElement.clientWidth || window.innerWidth) - 2 * panelViewportPadding;
|
|
192
|
+
|
|
193
|
+
it('"content" hugs its rows but never drops below an echoed trigger', async () => {
|
|
194
|
+
const result = await openAgainstTrigger({ panelWidth: "content" }, trigger);
|
|
195
|
+
await waitFor(() => {
|
|
196
|
+
const el = result.getByTestId("anchor-floating");
|
|
197
|
+
expect(el.style.minWidth).toBe("240px");
|
|
198
|
+
expect(el.style.width).toBe("");
|
|
199
|
+
expect(el.style.maxWidth).toBe(`${room()}px`);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('"content" without an echo (an icon trigger) has no trigger floor', async () => {
|
|
204
|
+
const result = await openAgainstTrigger({ panelWidth: "content", echo: false }, trigger);
|
|
205
|
+
await waitFor(() => {
|
|
206
|
+
const el = result.getByTestId("anchor-floating");
|
|
207
|
+
expect(el.style.minWidth).toBe("0px");
|
|
208
|
+
expect(el.style.width).toBe("");
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('"trigger" is exactly the trigger\'s width', async () => {
|
|
213
|
+
const result = await openAgainstTrigger({ panelWidth: "trigger" }, trigger);
|
|
214
|
+
await waitFor(() => {
|
|
215
|
+
const el = result.getByTestId("anchor-floating");
|
|
216
|
+
expect([el.style.minWidth, el.style.width, el.style.maxWidth]).toEqual([
|
|
217
|
+
"240px",
|
|
218
|
+
"240px",
|
|
219
|
+
"240px",
|
|
220
|
+
]);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('"screen" from a trigger in the page gutter spans the gutters, both sides', async () => {
|
|
225
|
+
// The trigger sits 16 in: the panel takes that inset at each end, so its
|
|
226
|
+
// start edge is the trigger's and its rows line up under the echo.
|
|
227
|
+
const result = await openAgainstTrigger({ panelWidth: "screen" }, trigger);
|
|
228
|
+
const gutters = (document.documentElement.clientWidth || window.innerWidth) - 2 * trigger.x;
|
|
229
|
+
await waitFor(() => {
|
|
230
|
+
const el = result.getByTestId("anchor-floating");
|
|
231
|
+
expect(el.style.width).toBe(`${gutters}px`);
|
|
232
|
+
expect(el.style.maxWidth).toBe(`${gutters}px`);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('"screen" from a trigger deep in the page is the room between the safe margins', async () => {
|
|
237
|
+
const result = await openAgainstTrigger({ panelWidth: "screen" }, { ...trigger, x: 400 });
|
|
238
|
+
await waitFor(() => {
|
|
239
|
+
const el = result.getByTestId("anchor-floating");
|
|
240
|
+
expect(el.style.width).toBe(`${room()}px`);
|
|
241
|
+
expect(el.style.maxWidth).toBe(`${room()}px`);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("a number is a fixed width, wider or narrower than the trigger", async () => {
|
|
246
|
+
const wide = await openAgainstTrigger({ panelWidth: 320 }, trigger);
|
|
247
|
+
await waitFor(() => {
|
|
248
|
+
expect(wide.getByTestId("anchor-floating").style.width).toBe("320px");
|
|
249
|
+
});
|
|
250
|
+
wide.unmount();
|
|
251
|
+
const narrow = await openAgainstTrigger({ panelWidth: 180 }, trigger);
|
|
252
|
+
await waitFor(() => {
|
|
253
|
+
const el = narrow.getByTestId("anchor-floating");
|
|
254
|
+
expect([el.style.minWidth, el.style.width, el.style.maxWidth]).toEqual([
|
|
255
|
+
"180px",
|
|
256
|
+
"180px",
|
|
257
|
+
"180px",
|
|
258
|
+
]);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it("wins over widthMode when both are set", async () => {
|
|
263
|
+
const result = await openAgainstTrigger(
|
|
264
|
+
{ widthMode: "fit-content", panelWidth: "trigger" },
|
|
265
|
+
trigger,
|
|
266
|
+
);
|
|
267
|
+
await waitFor(() => {
|
|
268
|
+
expect(result.getByTestId("anchor-floating").style.width).toBe("240px");
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
176
273
|
describe("FloatingPanel width modes (MPO-38)", () => {
|
|
177
274
|
it("resolves the deprecated boolean onto the three modes", () => {
|
|
178
275
|
expect(resolvePanelWidthMode(undefined, undefined)).toBe("at-least-trigger");
|
|
@@ -441,14 +538,15 @@ describe("FloatingPanel drawn radius (MPO-129)", () => {
|
|
|
441
538
|
/**
|
|
442
539
|
* CONTAINER-CAP (MPO-56). Part 2b files floating panels under DG-RAD-04: the
|
|
443
540
|
* class value on the panel's own padding is the ceiling, and the trigger's
|
|
444
|
-
* drawn arc (above)
|
|
541
|
+
* drawn arc (above) lowers it. A covering panel takes the arc whole (FZ-8438).
|
|
445
542
|
*/
|
|
446
|
-
function RadiusHarness({ open }: { open: boolean }) {
|
|
447
|
-
const panel = useFloatingPanel({ open, onOpenChange: () => {}, useAutoUpdate: false });
|
|
543
|
+
function RadiusHarness({ open, cover = false }: { open: boolean; cover?: boolean }) {
|
|
544
|
+
const panel = useFloatingPanel({ open, onOpenChange: () => {}, useAutoUpdate: false, cover });
|
|
448
545
|
return (
|
|
449
546
|
<div
|
|
450
547
|
data-testid="radius-trigger"
|
|
451
548
|
data-radius={String(panel.dropdownRadius)}
|
|
549
|
+
data-inset={String(panel.coverCornerInset)}
|
|
452
550
|
ref={panel.setReferenceRef}
|
|
453
551
|
/>
|
|
454
552
|
);
|
|
@@ -513,4 +611,26 @@ describe("FloatingPanel radius is CONTAINER-CAP on its padding (DG-RAD-04, MPO-5
|
|
|
513
611
|
);
|
|
514
612
|
await waitFor(() => expect(anchor.getAttribute("data-radius")).toBe("18"));
|
|
515
613
|
});
|
|
614
|
+
|
|
615
|
+
it("a covering panel takes the trigger's drawn arc exactly, past the cap (LC-112, FZ-8438)", async () => {
|
|
616
|
+
const result = renderWithProviders(
|
|
617
|
+
<Preset overrides={{ borderRadius: "full" }}>
|
|
618
|
+
<RadiusHarness open={false} cover />
|
|
619
|
+
</Preset>,
|
|
620
|
+
);
|
|
621
|
+
const anchor = result.getByTestId("radius-trigger");
|
|
622
|
+
Object.assign(anchor.style, {
|
|
623
|
+
borderTopLeftRadius: "50px",
|
|
624
|
+
backgroundColor: "rgb(255, 255, 255)",
|
|
625
|
+
});
|
|
626
|
+
mockRect(anchor, { x: 0, y: 0, width: 240, height: 44 });
|
|
627
|
+
result.rerender(
|
|
628
|
+
<Preset overrides={{ borderRadius: "full" }}>
|
|
629
|
+
<RadiusHarness open cover />
|
|
630
|
+
</Preset>,
|
|
631
|
+
);
|
|
632
|
+
await waitFor(() => expect(anchor.getAttribute("data-radius")).toBe("22"));
|
|
633
|
+
// Past the cap, the bottom insets by the arc's sagitta at 45° so rows clear it.
|
|
634
|
+
expect(anchor.getAttribute("data-inset")).toBe(String(Math.ceil(22 * (1 - Math.SQRT1_2))));
|
|
635
|
+
});
|
|
516
636
|
});
|
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
import { getTokenValue, type TransitionProp } from "tamagui";
|
|
23
23
|
import { clampDropdownRadius, scrollArrowThreshold } from "../shared/floatingList";
|
|
24
24
|
import { containsAcrossPanels } from "../shared/panelPortal";
|
|
25
|
+
import { groupSurfaceOf } from "./paintedBox";
|
|
26
|
+
import { type PanelWidth, panelWidthBox, screenBounds } from "./panelWidth";
|
|
25
27
|
|
|
26
28
|
// React Native defines a `window` global without DOM event methods, so a bare
|
|
27
29
|
// `typeof window` check is not enough — the floating cores mount this hook on
|
|
@@ -43,6 +45,24 @@ function roundToDevicePixel(value: number): number {
|
|
|
43
45
|
export const panelAnimationDuration = motionDurationMs(motionFor("quick").overlay.transition);
|
|
44
46
|
export const panelGrowDuration = panelAnimationDuration;
|
|
45
47
|
export const panelViewportPadding = 10;
|
|
48
|
+
|
|
49
|
+
/** The room a `"screen"` panel spans for this trigger (see `screenBounds`). */
|
|
50
|
+
function screenRoom(
|
|
51
|
+
reference: { getBoundingClientRect(): { left: number; right: number } },
|
|
52
|
+
viewportWidth: number,
|
|
53
|
+
) {
|
|
54
|
+
const box = reference.getBoundingClientRect();
|
|
55
|
+
return screenBounds({
|
|
56
|
+
triggerLeft: box.left,
|
|
57
|
+
triggerRight: box.right,
|
|
58
|
+
boundsLeft: panelViewportPadding,
|
|
59
|
+
boundsRight: viewportWidth - panelViewportPadding,
|
|
60
|
+
rtl:
|
|
61
|
+
typeof Element !== "undefined" &&
|
|
62
|
+
reference instanceof Element &&
|
|
63
|
+
getComputedStyle(reference).direction === "rtl",
|
|
64
|
+
});
|
|
65
|
+
}
|
|
46
66
|
/** Gap between trigger and panel: ZERO for the FloatingPanel family (one
|
|
47
67
|
* source, Axiom 5); `OVERLAY_ANCHOR_GAP` still governs FREE overlays. */
|
|
48
68
|
export const panelAnchorOffset = OVERLAY_ATTACH_GAP;
|
|
@@ -127,6 +147,14 @@ export interface UseFloatingPanelOptions {
|
|
|
127
147
|
*/
|
|
128
148
|
freeOverlay?: boolean;
|
|
129
149
|
cover?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* How wide the panel opens (LC-112, FZ-8438 r3): `"content"`, `"trigger"`,
|
|
152
|
+
* `"screen"` or a fixed width. Wins over `widthMode` when set; unset keeps
|
|
153
|
+
* `widthMode`'s behaviour, so no consumer changes until it asks.
|
|
154
|
+
*/
|
|
155
|
+
panelWidth?: PanelWidth;
|
|
156
|
+
/** The panel's first row echoes the trigger. Default: a covering panel. */
|
|
157
|
+
echo?: boolean;
|
|
130
158
|
}
|
|
131
159
|
|
|
132
160
|
/** One place that resolves the deprecated boolean onto the three modes, so
|
|
@@ -168,9 +196,15 @@ export interface UseFloatingPanelReturn {
|
|
|
168
196
|
/**
|
|
169
197
|
* Panel corner radius: CONTAINER-CAP on the panel's own padding (DG-RAD-04),
|
|
170
198
|
* lowered to the trigger's measured drawn radius once open when that arc
|
|
171
|
-
* is smaller
|
|
199
|
+
* is smaller. A covering panel (LC-112 seamless cover) takes the trigger's
|
|
200
|
+
* arc whole, past the cap.
|
|
172
201
|
*/
|
|
173
202
|
dropdownRadius: string | number;
|
|
203
|
+
/**
|
|
204
|
+
* Bottom inset a covering panel adds when its arc runs past the cap, so the
|
|
205
|
+
* last row's highlight and the scroll arrow clear the rounded corners.
|
|
206
|
+
*/
|
|
207
|
+
coverCornerInset: number;
|
|
174
208
|
hasBorder: boolean;
|
|
175
209
|
panelTransition: string;
|
|
176
210
|
knobProps: ReturnType<typeof useResolvedKnobs>["knobProps"];
|
|
@@ -202,7 +236,7 @@ function paintsACorner(el: HTMLElement): boolean {
|
|
|
202
236
|
* top-left corner and actually paints one. Nothing painted → null, so the
|
|
203
237
|
* caller falls back to the clamped token rather than to zero.
|
|
204
238
|
*/
|
|
205
|
-
function paintedCornerBox(root: HTMLElement): HTMLElement | null {
|
|
239
|
+
export function paintedCornerBox(root: HTMLElement): HTMLElement | null {
|
|
206
240
|
if (paintsACorner(root)) return root;
|
|
207
241
|
const rootRect = root.getBoundingClientRect();
|
|
208
242
|
for (const el of Array.from(root.querySelectorAll<HTMLElement>("*"))) {
|
|
@@ -250,6 +284,8 @@ export function useFloatingPanel({
|
|
|
250
284
|
fitContent,
|
|
251
285
|
freeOverlay = false,
|
|
252
286
|
cover = true,
|
|
287
|
+
panelWidth,
|
|
288
|
+
echo = cover && !freeOverlay,
|
|
253
289
|
}: UseFloatingPanelOptions): UseFloatingPanelReturn {
|
|
254
290
|
const widthMode = resolvePanelWidthMode(widthModeProp, fitContent);
|
|
255
291
|
// An overlay floats over the page: it never inherits a painted ancestor.
|
|
@@ -268,10 +304,18 @@ export function useFloatingPanel({
|
|
|
268
304
|
radiusStop && typeof panelPadPx === "number"
|
|
269
305
|
? resolveRadiusClass("CONTAINER-CAP", radiusStop, { paddingPx: panelPadPx })
|
|
270
306
|
: undefined;
|
|
271
|
-
const
|
|
307
|
+
const capped =
|
|
272
308
|
radiusCap === undefined
|
|
273
309
|
? (measuredRadius ?? clampDropdownRadius(knobProps.borderRadius.borderRadius))
|
|
274
310
|
: Math.min(measuredRadius ?? radiusCap, radiusCap);
|
|
311
|
+
// LC-112 seamless cover (FZ-8438): a panel laid over its trigger IS the
|
|
312
|
+
// trigger grown open, so all four corners take the trigger's drawn arc.
|
|
313
|
+
// The container cap only governs panels that sit beside their trigger.
|
|
314
|
+
const dropdownRadius = cover && !freeOverlay && measuredRadius != null ? measuredRadius : capped;
|
|
315
|
+
const coverCornerInset =
|
|
316
|
+
typeof dropdownRadius === "number" && typeof capped === "number" && dropdownRadius > capped
|
|
317
|
+
? Math.ceil(dropdownRadius * (1 - Math.SQRT1_2))
|
|
318
|
+
: 0;
|
|
275
319
|
|
|
276
320
|
// ── State ─────────────────────────────────────────────────
|
|
277
321
|
|
|
@@ -321,7 +365,11 @@ export function useFloatingPanel({
|
|
|
321
365
|
const setupForOpen = useCallback(() => {
|
|
322
366
|
computePlacement();
|
|
323
367
|
if (canUseDom && triggerRef.current) {
|
|
324
|
-
setMeasuredRadius(
|
|
368
|
+
setMeasuredRadius(
|
|
369
|
+
freeOverlay
|
|
370
|
+
? null
|
|
371
|
+
: measureDrawnRadius(groupSurfaceOf(triggerRef.current) ?? triggerRef.current),
|
|
372
|
+
);
|
|
325
373
|
}
|
|
326
374
|
onBeforeOpenRef.current?.();
|
|
327
375
|
if (closingTimerRef.current) clearTimeout(closingTimerRef.current);
|
|
@@ -381,40 +429,69 @@ export function useFloatingPanel({
|
|
|
381
429
|
// Horizontal collision handling: panels anchored near the right viewport
|
|
382
430
|
// edge (e.g. a ColorPicker in the last table column) shift back into view
|
|
383
431
|
// instead of clipping. Vertical placement is handled by computePlacement.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
:
|
|
432
|
+
// A screen-wide panel shifts inside the same room its width was cut to,
|
|
433
|
+
// so a trigger in the page gutter keeps its start edge.
|
|
434
|
+
shift(({ elements }) => {
|
|
435
|
+
if (panelWidth !== "screen") return { padding: panelViewportPadding };
|
|
436
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth || 0;
|
|
437
|
+
const room = screenRoom(elements.reference, viewportWidth);
|
|
438
|
+
return { padding: { left: room.left, right: viewportWidth - room.right } };
|
|
439
|
+
}),
|
|
440
|
+
...(panelWidth !== undefined
|
|
441
|
+
? [
|
|
388
442
|
size({
|
|
389
|
-
apply({
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const style: Record<string, number> =
|
|
405
|
-
widthMode === "match-trigger"
|
|
406
|
-
? { minWidth: width, width, maxWidth: width }
|
|
407
|
-
: { minWidth: width };
|
|
408
|
-
Object.assign(floatingStyleRef.current, style);
|
|
409
|
-
elements.floating.style.minWidth = `${width}px`;
|
|
410
|
-
if (widthMode === "match-trigger") {
|
|
411
|
-
elements.floating.style.width = `${width}px`;
|
|
412
|
-
elements.floating.style.maxWidth = `${width}px`;
|
|
413
|
-
}
|
|
443
|
+
apply({ rects: { reference }, elements }) {
|
|
444
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth || 0;
|
|
445
|
+
const room =
|
|
446
|
+
panelWidth === "screen"
|
|
447
|
+
? screenRoom(elements.reference, viewportWidth)
|
|
448
|
+
: { left: panelViewportPadding, right: viewportWidth - panelViewportPadding };
|
|
449
|
+
const box = panelWidthBox(panelWidth, {
|
|
450
|
+
trigger: reference.width,
|
|
451
|
+
available: room.right - room.left,
|
|
452
|
+
echo,
|
|
453
|
+
});
|
|
454
|
+
Object.assign(floatingStyleRef.current, box);
|
|
455
|
+
elements.floating.style.minWidth = `${box.minWidth}px`;
|
|
456
|
+
elements.floating.style.maxWidth = `${box.maxWidth}px`;
|
|
457
|
+
elements.floating.style.width = box.width === undefined ? "" : `${box.width}px`;
|
|
414
458
|
},
|
|
415
459
|
padding: panelViewportPadding,
|
|
416
460
|
}),
|
|
417
|
-
]
|
|
461
|
+
]
|
|
462
|
+
: widthMode === "fit-content"
|
|
463
|
+
? []
|
|
464
|
+
: [
|
|
465
|
+
size({
|
|
466
|
+
apply({
|
|
467
|
+
rects: {
|
|
468
|
+
reference: { width },
|
|
469
|
+
},
|
|
470
|
+
elements,
|
|
471
|
+
}) {
|
|
472
|
+
// MPO-38 width modes. `at-least-trigger` writes only min-width,
|
|
473
|
+
// so content may still grow the panel wider; `match-trigger`
|
|
474
|
+
// pins all three so the panel is the trigger's width EXACTLY,
|
|
475
|
+
// for content narrower AND wider than it.
|
|
476
|
+
//
|
|
477
|
+
// Any oversize on an anchored listbox breaks the flush
|
|
478
|
+
// start-alignment (a wider panel near the viewport edge gets
|
|
479
|
+
// shift()ed off the trigger's x) and lets trigger decorations
|
|
480
|
+
// peek around the panel as ghosted edges.
|
|
481
|
+
const style: Record<string, number> =
|
|
482
|
+
widthMode === "match-trigger"
|
|
483
|
+
? { minWidth: width, width, maxWidth: width }
|
|
484
|
+
: { minWidth: width };
|
|
485
|
+
Object.assign(floatingStyleRef.current, style);
|
|
486
|
+
elements.floating.style.minWidth = `${width}px`;
|
|
487
|
+
if (widthMode === "match-trigger") {
|
|
488
|
+
elements.floating.style.width = `${width}px`;
|
|
489
|
+
elements.floating.style.maxWidth = `${width}px`;
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
padding: panelViewportPadding,
|
|
493
|
+
}),
|
|
494
|
+
]),
|
|
418
495
|
];
|
|
419
496
|
|
|
420
497
|
const { x, y, strategy, context, refs, update } = useFloating({
|
|
@@ -556,6 +633,7 @@ export function useFloatingPanel({
|
|
|
556
633
|
setReferenceRef,
|
|
557
634
|
setMounted,
|
|
558
635
|
dropdownRadius,
|
|
636
|
+
coverCornerInset,
|
|
559
637
|
hasBorder,
|
|
560
638
|
panelTransition: panelTransitionFor(knobProps.motion.overlay.transition),
|
|
561
639
|
knobProps,
|
package/src/InputParts/index.tsx
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
View,
|
|
29
29
|
XGroup,
|
|
30
30
|
createStyledContext,
|
|
31
|
+
getTokenValue,
|
|
31
32
|
getVariable,
|
|
32
33
|
isWeb,
|
|
33
34
|
styled,
|
|
@@ -61,6 +62,7 @@ import { useControlGroupVertical, useControlGrouped } from "../shared/groupConte
|
|
|
61
62
|
import { nativeAutoFocus } from "../shared/nativeAutoFocus";
|
|
62
63
|
import { pressSlopProps } from "../shared/pressSlopProps";
|
|
63
64
|
import { useIsInTableCell } from "../shared/tableCellContext";
|
|
65
|
+
import { useInPanelEcho, usePanelTriggerRadiusReporter } from "../FloatingPanel/echoContext";
|
|
64
66
|
import { useFieldA11y, useFieldDescribedBy } from "../fieldLayout";
|
|
65
67
|
|
|
66
68
|
/**
|
|
@@ -498,6 +500,29 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
498
500
|
(props as { width?: unknown }).width == null
|
|
499
501
|
? { minWidth: 0, maxWidth: "100%" as const }
|
|
500
502
|
: undefined;
|
|
503
|
+
// LC-112 seamless cover (FZ-8438): a covering panel repeats this frame's
|
|
504
|
+
// arc at its corners, and an echo of this frame draws no chrome of its own.
|
|
505
|
+
const inPanelEcho = useInPanelEcho();
|
|
506
|
+
const reportRadius = usePanelTriggerRadiusReporter();
|
|
507
|
+
const drawnRadiusToken = sizeTableRadius?.borderRadius ?? knobProps.borderRadius.borderRadius;
|
|
508
|
+
const drawnRadius =
|
|
509
|
+
typeof drawnRadiusToken === "number"
|
|
510
|
+
? drawnRadiusToken
|
|
511
|
+
: Number(getTokenValue(drawnRadiusToken as never, "radius"));
|
|
512
|
+
useEffect(() => {
|
|
513
|
+
if (reportRadius && !inPanelEcho && !grouped && !inTableCell && Number.isFinite(drawnRadius)) {
|
|
514
|
+
reportRadius(drawnRadius);
|
|
515
|
+
}
|
|
516
|
+
}, [reportRadius, inPanelEcho, grouped, inTableCell, drawnRadius]);
|
|
517
|
+
const echoChrome = inPanelEcho
|
|
518
|
+
? {
|
|
519
|
+
borderColor: "transparent",
|
|
520
|
+
backgroundColor: "transparent",
|
|
521
|
+
elevation: undefined,
|
|
522
|
+
shadowColor: "transparent",
|
|
523
|
+
shadowOpacity: 0,
|
|
524
|
+
}
|
|
525
|
+
: undefined;
|
|
501
526
|
|
|
502
527
|
// Chromeless rendering inside table cells
|
|
503
528
|
if (inTableCell) {
|
|
@@ -615,6 +640,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
615
640
|
hoverStyle: { ...disabledState.surfaceKnobProps },
|
|
616
641
|
}
|
|
617
642
|
: undefined)}
|
|
643
|
+
{...echoChrome}
|
|
618
644
|
overflow={boxOverflow}
|
|
619
645
|
>
|
|
620
646
|
{children}
|
|
@@ -347,7 +347,7 @@ export function NativeWheel<T = string | number>(props: WheelProps<T>) {
|
|
|
347
347
|
right={0}
|
|
348
348
|
top={padTop}
|
|
349
349
|
height={itemHeight}
|
|
350
|
-
backgroundColor=
|
|
350
|
+
backgroundColor={layout.selectedFill}
|
|
351
351
|
pointerEvents="none"
|
|
352
352
|
style={layout.highlightStyle as never}
|
|
353
353
|
data-testid="wheel-selection"
|
package/src/Wheel/Wheel.spec.tsx
CHANGED
|
@@ -209,6 +209,15 @@ describe("Wheel iOS picker contract", () => {
|
|
|
209
209
|
expect(style.borderBottomWidth === "0px" || style.borderBottomWidth === "").toBe(true);
|
|
210
210
|
});
|
|
211
211
|
|
|
212
|
+
it("does not paint the band with the dark elevated surface colour (FZ-8438)", () => {
|
|
213
|
+
renderWithProviders(
|
|
214
|
+
<Wheel items={[1, 2, 3, 4, 5]} value={3} onChange={() => {}} visibleItems={5} />,
|
|
215
|
+
);
|
|
216
|
+
const band = screen.getByTestId("wheel-selection");
|
|
217
|
+
const paint = `${band.className} ${band.getAttribute("style") ?? ""}`;
|
|
218
|
+
expect(paint).not.toMatch(/_bg-color4|--color4/);
|
|
219
|
+
});
|
|
220
|
+
|
|
212
221
|
it("seats the selected row in the highlight band", () => {
|
|
213
222
|
renderWithProviders(
|
|
214
223
|
<Wheel
|
package/src/Wheel/index.tsx
CHANGED
|
@@ -154,8 +154,15 @@ function WebWheel<T = string | number>(props: WheelProps<T>) {
|
|
|
154
154
|
onItemCross,
|
|
155
155
|
"aria-label": ariaLabel,
|
|
156
156
|
} = props;
|
|
157
|
-
const {
|
|
158
|
-
|
|
157
|
+
const {
|
|
158
|
+
knobProps,
|
|
159
|
+
selectedFill,
|
|
160
|
+
size,
|
|
161
|
+
itemHeight,
|
|
162
|
+
snapDurationMs,
|
|
163
|
+
highlightStyle,
|
|
164
|
+
highlightClassName,
|
|
165
|
+
} = useWheelLayout(props);
|
|
159
166
|
const columnWidth = widthProp ?? defaultColumnWidth;
|
|
160
167
|
ensureWheelFocusStyles();
|
|
161
168
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
@@ -672,7 +679,9 @@ function WebWheel<T = string | number>(props: WheelProps<T>) {
|
|
|
672
679
|
{/* iOS 14+ selection fill — LC-71 selected=fill, never hairline borders */}
|
|
673
680
|
<SelectionIndicator
|
|
674
681
|
className={highlightClassName}
|
|
675
|
-
|
|
682
|
+
// FZ-8438: the selection tint (FZ-8355). $color4 is the dark elevated
|
|
683
|
+
// surface itself, so the band vanished on a dark cover panel.
|
|
684
|
+
backgroundColor={selectedFill}
|
|
676
685
|
top={paddingItems * itemHeight}
|
|
677
686
|
height={itemHeight}
|
|
678
687
|
style={highlightStyle}
|
package/src/Wheel/wheelShared.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from "react";
|
|
2
2
|
import { motionDurationMs, sizeTokenStep, useResolvedKnobs } from "@multiplatform.one/theme";
|
|
3
|
-
import type { SizeTokens } from "tamagui";
|
|
3
|
+
import type { ColorTokens, SizeTokens } from "tamagui";
|
|
4
4
|
import { getConfig, getTokens } from "tamagui";
|
|
5
5
|
|
|
6
6
|
export interface WheelItem<T = string | number> {
|
|
@@ -198,7 +198,7 @@ export function useWheelLayout<T>({
|
|
|
198
198
|
size: sizeProp,
|
|
199
199
|
highlightEdges = "all",
|
|
200
200
|
}: Pick<WheelProps<T>, "visibleItems" | "itemHeight" | "size" | "highlightEdges">) {
|
|
201
|
-
const { knobProps } = useResolvedKnobs();
|
|
201
|
+
const { knobProps, state } = useResolvedKnobs();
|
|
202
202
|
const size = sizeProp ?? wheelFontByStep[sizeTokenStep(knobProps.sizeToken)];
|
|
203
203
|
const bodyFont = (knobProps.body as { fontFamily?: unknown }).fontFamily;
|
|
204
204
|
const itemHeight =
|
|
@@ -208,6 +208,10 @@ export function useWheelLayout<T>({
|
|
|
208
208
|
const radiusToken = knobProps.borderRadius.borderRadius as string | number;
|
|
209
209
|
return {
|
|
210
210
|
knobProps,
|
|
211
|
+
// The band is the selection tint (LC-131, FZ-8355) from the state recipe;
|
|
212
|
+
// a preset with no accent tint falls back one step above the elevated
|
|
213
|
+
// dark surface, so the band still shows on a cover panel (FZ-8438).
|
|
214
|
+
selectedFill: (state.selected.surfaceKnobProps.backgroundColor ?? "$color5") as ColorTokens,
|
|
211
215
|
size,
|
|
212
216
|
itemHeight,
|
|
213
217
|
frameHeight,
|
|
@@ -1502,6 +1502,7 @@ function FloatingComboboxCore({
|
|
|
1502
1502
|
{...elevatedSurfaceProps}
|
|
1503
1503
|
borderRadius={panel.dropdownRadius}
|
|
1504
1504
|
data-testid="combobox-dropdown"
|
|
1505
|
+
paddingBottom={panel.coverCornerInset || undefined}
|
|
1505
1506
|
>
|
|
1506
1507
|
{!hideSearch && (
|
|
1507
1508
|
<InputParts size={knobProps.sizeToken}>
|
|
@@ -131,9 +131,9 @@ export const StateContract: Story = {
|
|
|
131
131
|
};
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* LC-
|
|
135
|
-
*
|
|
136
|
-
*
|
|
134
|
+
* LC-112 seamless cover (FZ-8438): on a coarse-pointer browser each field
|
|
135
|
+
* opens the same MPO panel as on desktop, one surface over the field with
|
|
136
|
+
* the calendar or the wheels. The lines below show the committed value.
|
|
137
137
|
*/
|
|
138
138
|
export const TouchWeb: Story = {
|
|
139
139
|
render: () => {
|