@multiplatform.one/forms 7.70.0 → 7.72.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/index.cjs +16 -0
- package/dist/cjs/Button/index.native.js +16 -0
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/echoContext.cjs +39 -0
- package/dist/cjs/FloatingPanel/echoContext.native.js +42 -0
- package/dist/cjs/FloatingPanel/echoContext.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/index.cjs +212 -80
- package/dist/cjs/FloatingPanel/index.native.js +92 -17
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- 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 +15 -5
- package/dist/cjs/FloatingPanel/pointAnchor.native.js +15 -5
- package/dist/cjs/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/useFloatingPanel.cjs +58 -4
- package/dist/cjs/FloatingPanel/useFloatingPanel.native.js +69 -4
- package/dist/cjs/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/cjs/InputParts/index.cjs +20 -1
- package/dist/cjs/InputParts/index.native.js +22 -2
- 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/SearchInput/index.cjs +23 -1
- package/dist/cjs/fields/SearchInput/index.native.js +23 -1
- package/dist/cjs/fields/SearchInput/index.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.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/index.mjs +17 -1
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +17 -1
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/FloatingPanel/echoContext.mjs +11 -0
- package/dist/esm/FloatingPanel/echoContext.mjs.map +1 -0
- package/dist/esm/FloatingPanel/echoContext.native.js +11 -0
- package/dist/esm/FloatingPanel/echoContext.native.js.map +1 -0
- package/dist/esm/FloatingPanel/index.mjs +213 -83
- package/dist/esm/FloatingPanel/index.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +92 -19
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- 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 +15 -5
- package/dist/esm/FloatingPanel/pointAnchor.mjs.map +1 -1
- package/dist/esm/FloatingPanel/pointAnchor.native.js +15 -5
- package/dist/esm/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/esm/FloatingPanel/useFloatingPanel.mjs +58 -5
- package/dist/esm/FloatingPanel/useFloatingPanel.mjs.map +1 -1
- package/dist/esm/FloatingPanel/useFloatingPanel.native.js +69 -5
- package/dist/esm/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/esm/InputParts/index.mjs +21 -2
- package/dist/esm/InputParts/index.mjs.map +1 -1
- package/dist/esm/InputParts/index.native.js +23 -3
- 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/SearchInput/index.mjs +25 -3
- package/dist/esm/fields/SearchInput/index.mjs.map +1 -1
- package/dist/esm/fields/SearchInput/index.native.js +25 -3
- package/dist/esm/fields/SearchInput/index.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.map +1 -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/index.mjs +17 -1
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +16 -0
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/echoContext.mjs +11 -0
- package/dist/jsx/FloatingPanel/echoContext.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/echoContext.native.js +42 -0
- package/dist/jsx/FloatingPanel/echoContext.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/index.mjs +213 -83
- package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +92 -17
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- 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 +15 -5
- package/dist/jsx/FloatingPanel/pointAnchor.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/pointAnchor.native.js +15 -5
- package/dist/jsx/FloatingPanel/pointAnchor.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/useFloatingPanel.mjs +58 -5
- package/dist/jsx/FloatingPanel/useFloatingPanel.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/useFloatingPanel.native.js +69 -4
- package/dist/jsx/FloatingPanel/useFloatingPanel.native.js.map +1 -1
- package/dist/jsx/InputParts/index.mjs +21 -2
- package/dist/jsx/InputParts/index.mjs.map +1 -1
- package/dist/jsx/InputParts/index.native.js +22 -2
- 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/SearchInput/index.mjs +25 -3
- package/dist/jsx/fields/SearchInput/index.mjs.map +1 -1
- package/dist/jsx/fields/SearchInput/index.native.js +23 -1
- package/dist/jsx/fields/SearchInput/index.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.map +1 -1
- package/dist/jsx/index.mjs.map +1 -1
- 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/index.tsx +22 -0
- package/src/FloatingPanel/FloatingPanel.echoStretch.spec.tsx +67 -0
- package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +193 -2
- package/src/FloatingPanel/FloatingPanel.seamlessCover.spec.tsx +237 -0
- package/src/FloatingPanel/echoContext.ts +22 -0
- package/src/FloatingPanel/index.native.tsx +106 -9
- package/src/FloatingPanel/index.tsx +310 -102
- 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 +64 -2
- package/src/FloatingPanel/pointAnchor.ts +28 -3
- package/src/FloatingPanel/useFloatingPanel.spec.tsx +124 -4
- package/src/FloatingPanel/useFloatingPanel.ts +106 -33
- package/src/InputParts/index.tsx +30 -1
- 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/SearchInput/SearchInput.spec.tsx +40 -0
- package/src/fields/SearchInput/index.tsx +47 -2
- 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 +1 -0
- package/src/shared/floatingList.tsx +21 -5
- package/types/Button/index.d.ts.map +1 -1
- package/types/FloatingPanel/echoContext.d.ts +14 -0
- package/types/FloatingPanel/echoContext.d.ts.map +1 -0
- package/types/FloatingPanel/index.d.ts +59 -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/panelWidth.d.ts +71 -0
- package/types/FloatingPanel/panelWidth.d.ts.map +1 -0
- package/types/FloatingPanel/pointAnchor.d.ts +8 -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 +5 -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/Input/index.d.ts +3 -1
- package/types/fields/Input/index.d.ts.map +1 -1
- package/types/fields/SearchInput/index.d.ts +11 -0
- package/types/fields/SearchInput/index.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 +1 -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
|
@@ -22,6 +22,7 @@ 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 { type PanelWidth, panelWidthBox, screenBounds } from "./panelWidth";
|
|
25
26
|
|
|
26
27
|
// React Native defines a `window` global without DOM event methods, so a bare
|
|
27
28
|
// `typeof window` check is not enough — the floating cores mount this hook on
|
|
@@ -43,6 +44,24 @@ function roundToDevicePixel(value: number): number {
|
|
|
43
44
|
export const panelAnimationDuration = motionDurationMs(motionFor("quick").overlay.transition);
|
|
44
45
|
export const panelGrowDuration = panelAnimationDuration;
|
|
45
46
|
export const panelViewportPadding = 10;
|
|
47
|
+
|
|
48
|
+
/** The room a `"screen"` panel spans for this trigger (see `screenBounds`). */
|
|
49
|
+
function screenRoom(
|
|
50
|
+
reference: { getBoundingClientRect(): { left: number; right: number } },
|
|
51
|
+
viewportWidth: number,
|
|
52
|
+
) {
|
|
53
|
+
const box = reference.getBoundingClientRect();
|
|
54
|
+
return screenBounds({
|
|
55
|
+
triggerLeft: box.left,
|
|
56
|
+
triggerRight: box.right,
|
|
57
|
+
boundsLeft: panelViewportPadding,
|
|
58
|
+
boundsRight: viewportWidth - panelViewportPadding,
|
|
59
|
+
rtl:
|
|
60
|
+
typeof Element !== "undefined" &&
|
|
61
|
+
reference instanceof Element &&
|
|
62
|
+
getComputedStyle(reference).direction === "rtl",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
46
65
|
/** Gap between trigger and panel: ZERO for the FloatingPanel family (one
|
|
47
66
|
* source, Axiom 5); `OVERLAY_ANCHOR_GAP` still governs FREE overlays. */
|
|
48
67
|
export const panelAnchorOffset = OVERLAY_ATTACH_GAP;
|
|
@@ -127,6 +146,14 @@ export interface UseFloatingPanelOptions {
|
|
|
127
146
|
*/
|
|
128
147
|
freeOverlay?: boolean;
|
|
129
148
|
cover?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* How wide the panel opens (LC-112, FZ-8438 r3): `"content"`, `"trigger"`,
|
|
151
|
+
* `"screen"` or a fixed width. Wins over `widthMode` when set; unset keeps
|
|
152
|
+
* `widthMode`'s behaviour, so no consumer changes until it asks.
|
|
153
|
+
*/
|
|
154
|
+
panelWidth?: PanelWidth;
|
|
155
|
+
/** The panel's first row echoes the trigger. Default: a covering panel. */
|
|
156
|
+
echo?: boolean;
|
|
130
157
|
}
|
|
131
158
|
|
|
132
159
|
/** One place that resolves the deprecated boolean onto the three modes, so
|
|
@@ -168,9 +195,15 @@ export interface UseFloatingPanelReturn {
|
|
|
168
195
|
/**
|
|
169
196
|
* Panel corner radius: CONTAINER-CAP on the panel's own padding (DG-RAD-04),
|
|
170
197
|
* lowered to the trigger's measured drawn radius once open when that arc
|
|
171
|
-
* is smaller
|
|
198
|
+
* is smaller. A covering panel (LC-112 seamless cover) takes the trigger's
|
|
199
|
+
* arc whole, past the cap.
|
|
172
200
|
*/
|
|
173
201
|
dropdownRadius: string | number;
|
|
202
|
+
/**
|
|
203
|
+
* Bottom inset a covering panel adds when its arc runs past the cap, so the
|
|
204
|
+
* last row's highlight and the scroll arrow clear the rounded corners.
|
|
205
|
+
*/
|
|
206
|
+
coverCornerInset: number;
|
|
174
207
|
hasBorder: boolean;
|
|
175
208
|
panelTransition: string;
|
|
176
209
|
knobProps: ReturnType<typeof useResolvedKnobs>["knobProps"];
|
|
@@ -202,7 +235,7 @@ function paintsACorner(el: HTMLElement): boolean {
|
|
|
202
235
|
* top-left corner and actually paints one. Nothing painted → null, so the
|
|
203
236
|
* caller falls back to the clamped token rather than to zero.
|
|
204
237
|
*/
|
|
205
|
-
function paintedCornerBox(root: HTMLElement): HTMLElement | null {
|
|
238
|
+
export function paintedCornerBox(root: HTMLElement): HTMLElement | null {
|
|
206
239
|
if (paintsACorner(root)) return root;
|
|
207
240
|
const rootRect = root.getBoundingClientRect();
|
|
208
241
|
for (const el of Array.from(root.querySelectorAll<HTMLElement>("*"))) {
|
|
@@ -250,6 +283,8 @@ export function useFloatingPanel({
|
|
|
250
283
|
fitContent,
|
|
251
284
|
freeOverlay = false,
|
|
252
285
|
cover = true,
|
|
286
|
+
panelWidth,
|
|
287
|
+
echo = cover && !freeOverlay,
|
|
253
288
|
}: UseFloatingPanelOptions): UseFloatingPanelReturn {
|
|
254
289
|
const widthMode = resolvePanelWidthMode(widthModeProp, fitContent);
|
|
255
290
|
// An overlay floats over the page: it never inherits a painted ancestor.
|
|
@@ -268,10 +303,18 @@ export function useFloatingPanel({
|
|
|
268
303
|
radiusStop && typeof panelPadPx === "number"
|
|
269
304
|
? resolveRadiusClass("CONTAINER-CAP", radiusStop, { paddingPx: panelPadPx })
|
|
270
305
|
: undefined;
|
|
271
|
-
const
|
|
306
|
+
const capped =
|
|
272
307
|
radiusCap === undefined
|
|
273
308
|
? (measuredRadius ?? clampDropdownRadius(knobProps.borderRadius.borderRadius))
|
|
274
309
|
: Math.min(measuredRadius ?? radiusCap, radiusCap);
|
|
310
|
+
// LC-112 seamless cover (FZ-8438): a panel laid over its trigger IS the
|
|
311
|
+
// trigger grown open, so all four corners take the trigger's drawn arc.
|
|
312
|
+
// The container cap only governs panels that sit beside their trigger.
|
|
313
|
+
const dropdownRadius = cover && !freeOverlay && measuredRadius != null ? measuredRadius : capped;
|
|
314
|
+
const coverCornerInset =
|
|
315
|
+
typeof dropdownRadius === "number" && typeof capped === "number" && dropdownRadius > capped
|
|
316
|
+
? Math.ceil(dropdownRadius * (1 - Math.SQRT1_2))
|
|
317
|
+
: 0;
|
|
275
318
|
|
|
276
319
|
// ── State ─────────────────────────────────────────────────
|
|
277
320
|
|
|
@@ -381,40 +424,69 @@ export function useFloatingPanel({
|
|
|
381
424
|
// Horizontal collision handling: panels anchored near the right viewport
|
|
382
425
|
// edge (e.g. a ColorPicker in the last table column) shift back into view
|
|
383
426
|
// instead of clipping. Vertical placement is handled by computePlacement.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
:
|
|
427
|
+
// A screen-wide panel shifts inside the same room its width was cut to,
|
|
428
|
+
// so a trigger in the page gutter keeps its start edge.
|
|
429
|
+
shift(({ elements }) => {
|
|
430
|
+
if (panelWidth !== "screen") return { padding: panelViewportPadding };
|
|
431
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth || 0;
|
|
432
|
+
const room = screenRoom(elements.reference, viewportWidth);
|
|
433
|
+
return { padding: { left: room.left, right: viewportWidth - room.right } };
|
|
434
|
+
}),
|
|
435
|
+
...(panelWidth !== undefined
|
|
436
|
+
? [
|
|
388
437
|
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
|
-
}
|
|
438
|
+
apply({ rects: { reference }, elements }) {
|
|
439
|
+
const viewportWidth = document.documentElement.clientWidth || window.innerWidth || 0;
|
|
440
|
+
const room =
|
|
441
|
+
panelWidth === "screen"
|
|
442
|
+
? screenRoom(elements.reference, viewportWidth)
|
|
443
|
+
: { left: panelViewportPadding, right: viewportWidth - panelViewportPadding };
|
|
444
|
+
const box = panelWidthBox(panelWidth, {
|
|
445
|
+
trigger: reference.width,
|
|
446
|
+
available: room.right - room.left,
|
|
447
|
+
echo,
|
|
448
|
+
});
|
|
449
|
+
Object.assign(floatingStyleRef.current, box);
|
|
450
|
+
elements.floating.style.minWidth = `${box.minWidth}px`;
|
|
451
|
+
elements.floating.style.maxWidth = `${box.maxWidth}px`;
|
|
452
|
+
elements.floating.style.width = box.width === undefined ? "" : `${box.width}px`;
|
|
414
453
|
},
|
|
415
454
|
padding: panelViewportPadding,
|
|
416
455
|
}),
|
|
417
|
-
]
|
|
456
|
+
]
|
|
457
|
+
: widthMode === "fit-content"
|
|
458
|
+
? []
|
|
459
|
+
: [
|
|
460
|
+
size({
|
|
461
|
+
apply({
|
|
462
|
+
rects: {
|
|
463
|
+
reference: { width },
|
|
464
|
+
},
|
|
465
|
+
elements,
|
|
466
|
+
}) {
|
|
467
|
+
// MPO-38 width modes. `at-least-trigger` writes only min-width,
|
|
468
|
+
// so content may still grow the panel wider; `match-trigger`
|
|
469
|
+
// pins all three so the panel is the trigger's width EXACTLY,
|
|
470
|
+
// for content narrower AND wider than it.
|
|
471
|
+
//
|
|
472
|
+
// Any oversize on an anchored listbox breaks the flush
|
|
473
|
+
// start-alignment (a wider panel near the viewport edge gets
|
|
474
|
+
// shift()ed off the trigger's x) and lets trigger decorations
|
|
475
|
+
// peek around the panel as ghosted edges.
|
|
476
|
+
const style: Record<string, number> =
|
|
477
|
+
widthMode === "match-trigger"
|
|
478
|
+
? { minWidth: width, width, maxWidth: width }
|
|
479
|
+
: { minWidth: width };
|
|
480
|
+
Object.assign(floatingStyleRef.current, style);
|
|
481
|
+
elements.floating.style.minWidth = `${width}px`;
|
|
482
|
+
if (widthMode === "match-trigger") {
|
|
483
|
+
elements.floating.style.width = `${width}px`;
|
|
484
|
+
elements.floating.style.maxWidth = `${width}px`;
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
padding: panelViewportPadding,
|
|
488
|
+
}),
|
|
489
|
+
]),
|
|
418
490
|
];
|
|
419
491
|
|
|
420
492
|
const { x, y, strategy, context, refs, update } = useFloating({
|
|
@@ -556,6 +628,7 @@ export function useFloatingPanel({
|
|
|
556
628
|
setReferenceRef,
|
|
557
629
|
setMounted,
|
|
558
630
|
dropdownRadius,
|
|
631
|
+
coverCornerInset,
|
|
559
632
|
hasBorder,
|
|
560
633
|
panelTransition: panelTransitionFor(knobProps.motion.overlay.transition),
|
|
561
634
|
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
|
/**
|
|
@@ -361,6 +363,8 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
361
363
|
* and the size recipe still wins.
|
|
362
364
|
*/
|
|
363
365
|
sizeRecipeEscape?: string;
|
|
366
|
+
/** Glyph squares close the trailing edge (SearchInput `trailing`): no end inset. */
|
|
367
|
+
trailingFlush?: boolean;
|
|
364
368
|
}>((groupProps, forwardedRef) => {
|
|
365
369
|
const {
|
|
366
370
|
children,
|
|
@@ -371,6 +375,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
371
375
|
sizeRecipeEscape,
|
|
372
376
|
height: heightProp,
|
|
373
377
|
paddingHorizontal: paddingHorizontalProp,
|
|
378
|
+
trailingFlush = false,
|
|
374
379
|
...props
|
|
375
380
|
} = groupProps as typeof groupProps & {
|
|
376
381
|
onPress?: (e?: any) => void;
|
|
@@ -485,7 +490,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
485
490
|
pointerEvents="none"
|
|
486
491
|
/>
|
|
487
492
|
) : null;
|
|
488
|
-
const trailingPadProps = trailingOverlay ? { paddingInlineEnd: 0 } : undefined;
|
|
493
|
+
const trailingPadProps = trailingOverlay || trailingFlush ? { paddingInlineEnd: 0 } : undefined;
|
|
489
494
|
// FZ-7853 (LC-10): a Box sized by its content (a picker trigger in a row)
|
|
490
495
|
// is capped at its column, so a phone-width form never pushes the field
|
|
491
496
|
// past the card inset. A cap, not flexShrink: shrink would also act on the
|
|
@@ -495,6 +500,29 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
495
500
|
(props as { width?: unknown }).width == null
|
|
496
501
|
? { minWidth: 0, maxWidth: "100%" as const }
|
|
497
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;
|
|
498
526
|
|
|
499
527
|
// Chromeless rendering inside table cells
|
|
500
528
|
if (inTableCell) {
|
|
@@ -612,6 +640,7 @@ const InputGroupImpl = InputGroupFrame.styleable<{
|
|
|
612
640
|
hoverStyle: { ...disabledState.surfaceKnobProps },
|
|
613
641
|
}
|
|
614
642
|
: undefined)}
|
|
643
|
+
{...echoChrome}
|
|
615
644
|
overflow={boxOverflow}
|
|
616
645
|
>
|
|
617
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: () => {
|
|
@@ -7,6 +7,7 @@ import { Text, View, useProps, isWeb } from "tamagui";
|
|
|
7
7
|
|
|
8
8
|
import { Field, FieldLayout } from "../../fieldLayout";
|
|
9
9
|
import { FloatingPanel } from "../../FloatingPanel";
|
|
10
|
+
import type { PanelWidth } from "../../FloatingPanel/panelWidth";
|
|
10
11
|
import { t } from "../../shared/t";
|
|
11
12
|
import { TimeWheels } from "../../shared/TimeColumn";
|
|
12
13
|
import {
|
|
@@ -19,12 +20,6 @@ import type { FormFieldProps } from "../../fieldLayout";
|
|
|
19
20
|
import { Input as InputParts } from "../../InputParts";
|
|
20
21
|
import { Skeleton } from "../../Skeleton";
|
|
21
22
|
import type { FieldComponentProps, Validator } from "../../types";
|
|
22
|
-
import {
|
|
23
|
-
fromNativeDateValue,
|
|
24
|
-
toDatetimeLocalValue,
|
|
25
|
-
TouchWebPickerInput,
|
|
26
|
-
useCoarsePointer,
|
|
27
|
-
} from "../../shared/touchWebPicker";
|
|
28
23
|
|
|
29
24
|
import {
|
|
30
25
|
CalendarDays,
|
|
@@ -87,6 +82,11 @@ export type DatetimePickerProps<
|
|
|
87
82
|
onValueChange?: (value: Date | null) => void;
|
|
88
83
|
/** Native only. `false` keeps the catalog overlay; omit for the OS picker. */
|
|
89
84
|
native?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* How wide the open picker is (LC-112, FZ-8438 r3): `"content"`,
|
|
87
|
+
* `"trigger"`, `"screen"` or a fixed width. Unset: at least the field.
|
|
88
|
+
*/
|
|
89
|
+
panelWidth?: PanelWidth;
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
// ---------------------------------------------------------------------------
|
|
@@ -273,8 +273,10 @@ function DatetimePickerBody({
|
|
|
273
273
|
justifyContent="center"
|
|
274
274
|
cursor={tabDisabled ? "default" : "pointer"}
|
|
275
275
|
opacity={tabDisabled ? 0.5 : 1}
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
// LC-131 / FZ-8355: the chosen tab is the selection tint with a
|
|
277
|
+
// rounded arc, not an inverted accent slab (FZ-8438 critique).
|
|
278
|
+
backgroundColor={active ? "$selectedBackground" : "transparent"}
|
|
279
|
+
borderRadius={knobProps.borderRadius.borderRadius}
|
|
278
280
|
onPress={() => {
|
|
279
281
|
if (!tabDisabled) setActiveTab(tab);
|
|
280
282
|
}}
|
|
@@ -381,12 +383,12 @@ export function DatetimePicker<
|
|
|
381
383
|
showSeconds = false,
|
|
382
384
|
skeleton,
|
|
383
385
|
id: idProp,
|
|
386
|
+
panelWidth,
|
|
384
387
|
..._restProps
|
|
385
388
|
} = useProps(props);
|
|
386
389
|
|
|
387
390
|
const { resolvedForm, knobProps, id } = useFormField({ form, id: idProp });
|
|
388
391
|
const resolvedValidators = useResolvedValidators(required, validators, label, name);
|
|
389
|
-
const touchWeb = useCoarsePointer();
|
|
390
392
|
|
|
391
393
|
const [open, setOpen] = useState(false);
|
|
392
394
|
const [selectedDatetime, setSelectedDatetime] = useState<Date | null>(() =>
|
|
@@ -470,40 +472,6 @@ export function DatetimePicker<
|
|
|
470
472
|
/>
|
|
471
473
|
);
|
|
472
474
|
|
|
473
|
-
const renderTouchTrigger = (
|
|
474
|
-
hasError?: boolean,
|
|
475
|
-
blurHandler?: (...args: any[]) => void,
|
|
476
|
-
fieldChange?: (value: any) => void,
|
|
477
|
-
) => (
|
|
478
|
-
<DatePickerInputTrigger
|
|
479
|
-
value={displayValue}
|
|
480
|
-
placeholder={placeholder}
|
|
481
|
-
disabled={disabled}
|
|
482
|
-
onReset={() => handleClearDatetime(fieldChange)}
|
|
483
|
-
onButtonPress={() => {}}
|
|
484
|
-
touchInput={
|
|
485
|
-
<TouchWebPickerInput
|
|
486
|
-
kind="datetime-local"
|
|
487
|
-
id={id}
|
|
488
|
-
value={toDatetimeLocalValue(selectedDatetime, showSeconds)}
|
|
489
|
-
min={toDatetimeLocalValue(minDate, showSeconds)}
|
|
490
|
-
max={toDatetimeLocalValue(maxDate, showSeconds)}
|
|
491
|
-
showSeconds={showSeconds}
|
|
492
|
-
disabled={disabled}
|
|
493
|
-
required={required}
|
|
494
|
-
invalid={hasError}
|
|
495
|
-
aria-label={label ? undefined : t("Date and time")}
|
|
496
|
-
onValue={(next) => {
|
|
497
|
-
const date = fromNativeDateValue(next);
|
|
498
|
-
if (date) handleDatetimeSelect(date, fieldChange);
|
|
499
|
-
else handleClearDatetime(fieldChange);
|
|
500
|
-
}}
|
|
501
|
-
onBlur={blurHandler}
|
|
502
|
-
/>
|
|
503
|
-
}
|
|
504
|
-
/>
|
|
505
|
-
);
|
|
506
|
-
|
|
507
475
|
const renderPopover = (
|
|
508
476
|
hasError?: boolean,
|
|
509
477
|
blurHandler?: (...args: any[]) => void,
|
|
@@ -521,7 +489,6 @@ export function DatetimePicker<
|
|
|
521
489
|
/>
|
|
522
490
|
);
|
|
523
491
|
}
|
|
524
|
-
if (touchWeb) return renderTouchTrigger(hasError, blurHandler, fieldChange);
|
|
525
492
|
const handleOpenChange = (isOpen: boolean) => {
|
|
526
493
|
// Re-seed the visible month from the current value on every open.
|
|
527
494
|
if (isOpen && selectedDatetimeRef.current) setDisplayDate(selectedDatetimeRef.current);
|
|
@@ -544,7 +511,12 @@ export function DatetimePicker<
|
|
|
544
511
|
disabled={disabled}
|
|
545
512
|
sizing="grow"
|
|
546
513
|
contentPadding="none"
|
|
547
|
-
widthMode="
|
|
514
|
+
widthMode="at-least-trigger"
|
|
515
|
+
panelWidth={panelWidth}
|
|
516
|
+
// LC-112 seamless cover (FZ-8438): touch and narrow web open the same
|
|
517
|
+
// panel over the field, never the browser's own popover; a field too
|
|
518
|
+
// low for the panel takes MPO's bottom sheet (LC-105 collision).
|
|
519
|
+
compactFace={isWeb ? "menu" : undefined}
|
|
548
520
|
>
|
|
549
521
|
{pickerContent(fieldChange)}
|
|
550
522
|
</FloatingPanel>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Native DatetimePicker — iOS calendar then time wheel; Android date then time.
|
|
3
3
|
*/
|
|
4
4
|
import type { DeepKeys, DeepValue } from "@tanstack/form-core";
|
|
5
|
+
import type { PanelWidth } from "../../FloatingPanel/panelWidth";
|
|
5
6
|
import { formatAbsoluteDateTime } from "@multiplatform.one/theme";
|
|
6
7
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
7
8
|
import { Pressable as RNPressable } from "react-native";
|
|
@@ -56,6 +57,8 @@ export type DatetimePickerProps<
|
|
|
56
57
|
onChange?: (value: Date | null) => void;
|
|
57
58
|
onValueChange?: (value: Date | null) => void;
|
|
58
59
|
native?: boolean;
|
|
60
|
+
/** How wide the catalog picker opens (`native={false}`), LC-112. */
|
|
61
|
+
panelWidth?: PanelWidth;
|
|
59
62
|
};
|
|
60
63
|
|
|
61
64
|
function formatDatetimeDisplay(
|
|
@@ -16,12 +16,6 @@ import type { FormFieldProps } from "../../fieldLayout";
|
|
|
16
16
|
import { Input as InputParts } from "../../InputParts";
|
|
17
17
|
import { Skeleton } from "../../Skeleton";
|
|
18
18
|
import type { FieldComponentProps, Validator } from "../../types";
|
|
19
|
-
import {
|
|
20
|
-
fromNativeDateValue,
|
|
21
|
-
toDateInputValue,
|
|
22
|
-
TouchWebPickerInput,
|
|
23
|
-
useCoarsePointer,
|
|
24
|
-
} from "../../shared/touchWebPicker";
|
|
25
19
|
|
|
26
20
|
import {
|
|
27
21
|
CalendarDays,
|
|
@@ -39,6 +33,7 @@ import {
|
|
|
39
33
|
} from "./parts";
|
|
40
34
|
|
|
41
35
|
import type { ViewMode } from "./parts";
|
|
36
|
+
import type { PanelWidth } from "../../FloatingPanel/panelWidth";
|
|
42
37
|
|
|
43
38
|
export type { ViewMode } from "./parts";
|
|
44
39
|
|
|
@@ -84,6 +79,11 @@ export type DatePickerProps<
|
|
|
84
79
|
onValueChange?: (value: Date | null) => void;
|
|
85
80
|
/** Native only. `false` keeps the catalog calendar; omit for the OS picker. */
|
|
86
81
|
native?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* How wide the open picker is (LC-112, FZ-8438 r3): `"content"`,
|
|
84
|
+
* `"trigger"`, `"screen"` or a fixed width. Unset: at least the field.
|
|
85
|
+
*/
|
|
86
|
+
panelWidth?: PanelWidth;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
// ---------------------------------------------------------------------------
|
|
@@ -211,13 +211,13 @@ export function DatePicker<
|
|
|
211
211
|
onBlur,
|
|
212
212
|
skeleton,
|
|
213
213
|
id: idProp,
|
|
214
|
+
panelWidth,
|
|
214
215
|
..._restProps
|
|
215
216
|
} = useProps(props);
|
|
216
217
|
|
|
217
218
|
const { resolvedForm, knobProps, id } = useFormField({ form, id: idProp });
|
|
218
219
|
const resolvedValidators = useResolvedValidators(required, validators, label, name);
|
|
219
220
|
const hasLabel = Boolean(label);
|
|
220
|
-
const touchWeb = useCoarsePointer();
|
|
221
221
|
|
|
222
222
|
const [open, setOpen] = useState(false);
|
|
223
223
|
const [selectedDate, setSelectedDate] = useState<Date | null>(() =>
|
|
@@ -308,38 +308,6 @@ export function DatePicker<
|
|
|
308
308
|
.filter(Boolean)
|
|
309
309
|
.join(" ") || undefined;
|
|
310
310
|
|
|
311
|
-
if (touchWeb) {
|
|
312
|
-
return (
|
|
313
|
-
<DatePickerInputTrigger
|
|
314
|
-
value={formatDateDisplay(selectedDate)}
|
|
315
|
-
placeholder={placeholder}
|
|
316
|
-
disabled={disabled}
|
|
317
|
-
onReset={() => handleClearDate(fieldChange)}
|
|
318
|
-
onButtonPress={() => {}}
|
|
319
|
-
touchInput={
|
|
320
|
-
<TouchWebPickerInput
|
|
321
|
-
kind="date"
|
|
322
|
-
id={id}
|
|
323
|
-
value={toDateInputValue(selectedDate)}
|
|
324
|
-
min={toDateInputValue(minDate)}
|
|
325
|
-
max={toDateInputValue(maxDate)}
|
|
326
|
-
disabled={disabled}
|
|
327
|
-
required={required}
|
|
328
|
-
invalid={hasError}
|
|
329
|
-
aria-label={hasLabel ? undefined : t("Date")}
|
|
330
|
-
aria-describedby={describedBy}
|
|
331
|
-
onValue={(next) => {
|
|
332
|
-
const date = fromNativeDateValue(next);
|
|
333
|
-
if (date) handleDateSelect(date, fieldChange);
|
|
334
|
-
else handleClearDate(fieldChange);
|
|
335
|
-
}}
|
|
336
|
-
onBlur={blurHandler}
|
|
337
|
-
/>
|
|
338
|
-
}
|
|
339
|
-
/>
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
311
|
const handleOpenChange = (isOpen: boolean) => {
|
|
344
312
|
// Re-seed the visible month from the current value on every open —
|
|
345
313
|
// the value may have changed (externally or by a pick) since mount.
|
|
@@ -361,6 +329,7 @@ export function DatePicker<
|
|
|
361
329
|
// TimePicker already pass it.
|
|
362
330
|
disabled={disabled}
|
|
363
331
|
popoverRef={popoverRef}
|
|
332
|
+
panelWidth={panelWidth}
|
|
364
333
|
// "Date, Jul 15 2026": VO gets the field name + current value on the
|
|
365
334
|
// native trigger (the web trigger announces via aria on the Area).
|
|
366
335
|
triggerA11y={{
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* calendar) stay the catalog implementations.
|
|
6
6
|
*/
|
|
7
7
|
import type { DeepKeys, DeepValue } from "@tanstack/form-core";
|
|
8
|
+
import type { PanelWidth } from "../../FloatingPanel/panelWidth";
|
|
8
9
|
import { useCallback, useEffect, useState } from "react";
|
|
9
10
|
import { Pressable as RNPressable } from "react-native";
|
|
10
11
|
import { useProps } from "tamagui";
|
|
@@ -58,6 +59,8 @@ export type DatePickerProps<
|
|
|
58
59
|
* native is the OS picker (iOS calendar / time wheel).
|
|
59
60
|
*/
|
|
60
61
|
native?: boolean;
|
|
62
|
+
/** How wide the catalog picker opens (`native={false}`), LC-112. */
|
|
63
|
+
panelWidth?: PanelWidth;
|
|
61
64
|
};
|
|
62
65
|
|
|
63
66
|
export type { ViewMode } from "./parts";
|