@multiplatform.one/forms 7.77.1 → 7.78.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/IconButtonGroup.cjs +58 -27
- package/dist/cjs/Button/IconButtonGroup.native.js +64 -29
- package/dist/cjs/Button/IconButtonGroup.native.js.map +1 -1
- package/dist/cjs/Button/circleGlyph.cjs +12 -2
- package/dist/cjs/Button/circleGlyph.native.js +12 -1
- package/dist/cjs/Button/circleGlyph.native.js.map +1 -1
- package/dist/cjs/Button/glass.cjs +2 -1
- package/dist/cjs/Button/glass.native.js +44 -19
- package/dist/cjs/Button/glass.native.js.map +1 -1
- package/dist/cjs/Button/iconButtonGroupContext.cjs +7 -1
- package/dist/cjs/Button/iconButtonGroupContext.native.js +7 -1
- package/dist/cjs/Button/iconButtonGroupContext.native.js.map +1 -1
- package/dist/cjs/Button/index.cjs +15 -23
- package/dist/cjs/Button/index.native.js +15 -24
- package/dist/cjs/Button/index.native.js.map +1 -1
- package/dist/cjs/Button/webGlass.cjs +9 -5
- package/dist/cjs/Button/webGlass.native.js +9 -5
- package/dist/cjs/Button/webGlass.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/coverRect.cjs +50 -0
- package/dist/cjs/FloatingPanel/coverRect.native.js +54 -0
- package/dist/cjs/FloatingPanel/coverRect.native.js.map +1 -0
- package/dist/cjs/FloatingPanel/iconEcho.cjs +3 -1
- package/dist/cjs/FloatingPanel/iconEcho.native.js +3 -1
- package/dist/cjs/FloatingPanel/iconEcho.native.js.map +1 -1
- package/dist/cjs/FloatingPanel/index.cjs +23 -13
- package/dist/cjs/FloatingPanel/index.native.js +41 -15
- package/dist/cjs/FloatingPanel/index.native.js.map +1 -1
- package/dist/cjs/InputParts/index.cjs +5 -0
- package/dist/cjs/InputParts/index.native.js +7 -0
- package/dist/cjs/InputParts/index.native.js.map +1 -1
- package/dist/cjs/{Button/mediaPlate.cjs → InputParts/keyboardAppearance.cjs} +7 -8
- package/dist/{jsx/Button/mediaPlate.native.js → cjs/InputParts/keyboardAppearance.native.js} +8 -9
- package/dist/cjs/InputParts/keyboardAppearance.native.js.map +1 -0
- package/dist/cjs/{Button/mediaPlate.native.js → fields/Duration/DurationWheel.cjs} +11 -11
- package/dist/cjs/fields/Duration/DurationWheel.native.js +132 -0
- package/dist/cjs/fields/Duration/DurationWheel.native.js.map +1 -0
- package/dist/cjs/fields/Duration/durationMath.cjs +19 -1
- package/dist/cjs/fields/Duration/durationMath.native.js +19 -1
- package/dist/cjs/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/cjs/fields/Duration/durationWheelTypes.cjs +18 -0
- package/dist/cjs/fields/Duration/durationWheelTypes.native.js +21 -0
- package/dist/cjs/fields/Duration/durationWheelTypes.native.js.map +1 -0
- package/dist/cjs/fields/Duration/index.cjs +30 -10
- package/dist/cjs/fields/Duration/index.native.js +32 -12
- package/dist/cjs/fields/Duration/index.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.cjs +8 -7
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js +8 -7
- package/dist/cjs/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.cjs +1 -1
- package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js +1 -1
- package/dist/cjs/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
- package/dist/cjs/fields/nativeDateTime/sheetKeyboard.cjs +1 -1
- package/dist/cjs/fields/nativeDateTime/sheetKeyboard.native.js +1 -1
- package/dist/cjs/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
- package/dist/cjs/index.cjs +0 -1
- package/dist/cjs/index.native.js +0 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/Button/IconButtonGroup.mjs +65 -33
- package/dist/esm/Button/IconButtonGroup.mjs.map +1 -1
- package/dist/esm/Button/IconButtonGroup.native.js +71 -35
- package/dist/esm/Button/IconButtonGroup.native.js.map +1 -1
- package/dist/esm/Button/circleGlyph.mjs +9 -1
- package/dist/esm/Button/circleGlyph.mjs.map +1 -1
- package/dist/esm/Button/circleGlyph.native.js +10 -1
- package/dist/esm/Button/circleGlyph.native.js.map +1 -1
- package/dist/esm/Button/glass.mjs +2 -1
- package/dist/esm/Button/glass.mjs.map +1 -1
- package/dist/esm/Button/glass.native.js +43 -19
- package/dist/esm/Button/glass.native.js.map +1 -1
- package/dist/esm/Button/iconButtonGroupContext.mjs +5 -1
- package/dist/esm/Button/iconButtonGroupContext.mjs.map +1 -1
- package/dist/esm/Button/iconButtonGroupContext.native.js +5 -1
- package/dist/esm/Button/iconButtonGroupContext.native.js.map +1 -1
- package/dist/esm/Button/index.mjs +15 -22
- package/dist/esm/Button/index.mjs.map +1 -1
- package/dist/esm/Button/index.native.js +15 -23
- package/dist/esm/Button/index.native.js.map +1 -1
- package/dist/esm/Button/webGlass.mjs +10 -6
- package/dist/esm/Button/webGlass.mjs.map +1 -1
- package/dist/esm/Button/webGlass.native.js +10 -6
- package/dist/esm/Button/webGlass.native.js.map +1 -1
- package/dist/esm/FloatingPanel/coverRect.mjs +23 -0
- package/dist/esm/FloatingPanel/coverRect.mjs.map +1 -0
- package/dist/esm/FloatingPanel/coverRect.native.js +24 -0
- package/dist/esm/FloatingPanel/coverRect.native.js.map +1 -0
- package/dist/esm/FloatingPanel/iconEcho.mjs +4 -2
- package/dist/esm/FloatingPanel/iconEcho.mjs.map +1 -1
- package/dist/esm/FloatingPanel/iconEcho.native.js +4 -2
- package/dist/esm/FloatingPanel/iconEcho.native.js.map +1 -1
- package/dist/esm/FloatingPanel/index.mjs +23 -13
- package/dist/esm/FloatingPanel/index.mjs.map +1 -1
- package/dist/esm/FloatingPanel/index.native.js +41 -15
- package/dist/esm/FloatingPanel/index.native.js.map +1 -1
- package/dist/esm/InputParts/index.mjs +6 -1
- package/dist/esm/InputParts/index.mjs.map +1 -1
- package/dist/esm/InputParts/index.native.js +8 -1
- package/dist/esm/InputParts/index.native.js.map +1 -1
- package/dist/esm/InputParts/keyboardAppearance.mjs +5 -0
- package/dist/esm/InputParts/keyboardAppearance.mjs.map +1 -0
- package/dist/esm/InputParts/keyboardAppearance.native.js +5 -0
- package/dist/esm/InputParts/keyboardAppearance.native.js.map +1 -0
- package/dist/esm/fields/Duration/DurationWheel.mjs +8 -0
- package/dist/esm/fields/Duration/DurationWheel.mjs.map +1 -0
- package/dist/esm/fields/Duration/DurationWheel.native.js +103 -0
- package/dist/esm/fields/Duration/DurationWheel.native.js.map +1 -0
- package/dist/esm/fields/Duration/durationMath.mjs +16 -1
- package/dist/esm/fields/Duration/durationMath.mjs.map +1 -1
- package/dist/esm/fields/Duration/durationMath.native.js +16 -1
- package/dist/esm/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/esm/fields/Duration/durationWheelTypes.mjs +2 -0
- package/dist/esm/fields/Duration/durationWheelTypes.mjs.map +1 -0
- package/dist/esm/fields/Duration/durationWheelTypes.native.js +2 -0
- package/dist/esm/fields/Duration/durationWheelTypes.native.js.map +1 -0
- package/dist/esm/fields/Duration/index.mjs +28 -11
- package/dist/esm/fields/Duration/index.mjs.map +1 -1
- package/dist/esm/fields/Duration/index.native.js +30 -13
- package/dist/esm/fields/Duration/index.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs +8 -7
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js +8 -7
- package/dist/esm/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.mjs +1 -1
- package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js +1 -1
- package/dist/esm/fields/nativeDateTime/osDateTimeIosDisplay.native.js.map +1 -1
- package/dist/esm/fields/nativeDateTime/sheetKeyboard.mjs +1 -1
- package/dist/esm/fields/nativeDateTime/sheetKeyboard.mjs.map +1 -1
- package/dist/esm/fields/nativeDateTime/sheetKeyboard.native.js +1 -1
- package/dist/esm/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
- package/dist/esm/index.mjs +2 -2
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -2
- package/dist/esm/index.native.js.map +1 -1
- package/dist/jsx/Button/IconButtonGroup.mjs +65 -33
- package/dist/jsx/Button/IconButtonGroup.mjs.map +1 -1
- package/dist/jsx/Button/IconButtonGroup.native.js +64 -29
- package/dist/jsx/Button/IconButtonGroup.native.js.map +1 -1
- package/dist/jsx/Button/circleGlyph.mjs +9 -1
- package/dist/jsx/Button/circleGlyph.mjs.map +1 -1
- package/dist/jsx/Button/circleGlyph.native.js +12 -1
- package/dist/jsx/Button/circleGlyph.native.js.map +1 -1
- package/dist/jsx/Button/glass.mjs +2 -1
- package/dist/jsx/Button/glass.mjs.map +1 -1
- package/dist/jsx/Button/glass.native.js +44 -19
- package/dist/jsx/Button/glass.native.js.map +1 -1
- package/dist/jsx/Button/iconButtonGroupContext.mjs +5 -1
- package/dist/jsx/Button/iconButtonGroupContext.mjs.map +1 -1
- package/dist/jsx/Button/iconButtonGroupContext.native.js +7 -1
- package/dist/jsx/Button/iconButtonGroupContext.native.js.map +1 -1
- package/dist/jsx/Button/index.mjs +15 -22
- package/dist/jsx/Button/index.mjs.map +1 -1
- package/dist/jsx/Button/index.native.js +15 -24
- package/dist/jsx/Button/index.native.js.map +1 -1
- package/dist/jsx/Button/webGlass.mjs +10 -6
- package/dist/jsx/Button/webGlass.mjs.map +1 -1
- package/dist/jsx/Button/webGlass.native.js +9 -5
- package/dist/jsx/Button/webGlass.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/coverRect.mjs +23 -0
- package/dist/jsx/FloatingPanel/coverRect.mjs.map +1 -0
- package/dist/jsx/FloatingPanel/coverRect.native.js +54 -0
- package/dist/jsx/FloatingPanel/coverRect.native.js.map +1 -0
- package/dist/jsx/FloatingPanel/iconEcho.mjs +4 -2
- package/dist/jsx/FloatingPanel/iconEcho.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/iconEcho.native.js +3 -1
- package/dist/jsx/FloatingPanel/iconEcho.native.js.map +1 -1
- package/dist/jsx/FloatingPanel/index.mjs +23 -13
- package/dist/jsx/FloatingPanel/index.mjs.map +1 -1
- package/dist/jsx/FloatingPanel/index.native.js +41 -15
- package/dist/jsx/FloatingPanel/index.native.js.map +1 -1
- package/dist/jsx/InputParts/index.mjs +6 -1
- package/dist/jsx/InputParts/index.mjs.map +1 -1
- package/dist/jsx/InputParts/index.native.js +7 -0
- package/dist/jsx/InputParts/index.native.js.map +1 -1
- package/dist/jsx/InputParts/keyboardAppearance.mjs +5 -0
- package/dist/jsx/InputParts/keyboardAppearance.mjs.map +1 -0
- package/dist/jsx/InputParts/keyboardAppearance.native.js +33 -0
- package/dist/jsx/InputParts/keyboardAppearance.native.js.map +1 -0
- package/dist/jsx/fields/Duration/DurationWheel.mjs +8 -0
- package/dist/jsx/fields/Duration/DurationWheel.mjs.map +1 -0
- package/dist/jsx/fields/Duration/DurationWheel.native.js +132 -0
- package/dist/jsx/fields/Duration/DurationWheel.native.js.map +1 -0
- package/dist/jsx/fields/Duration/durationMath.mjs +16 -1
- package/dist/jsx/fields/Duration/durationMath.mjs.map +1 -1
- package/dist/jsx/fields/Duration/durationMath.native.js +19 -1
- package/dist/jsx/fields/Duration/durationMath.native.js.map +1 -1
- package/dist/jsx/fields/Duration/durationWheelTypes.mjs +2 -0
- package/dist/jsx/fields/Duration/durationWheelTypes.mjs.map +1 -0
- package/dist/jsx/fields/Duration/durationWheelTypes.native.js +21 -0
- package/dist/jsx/fields/Duration/durationWheelTypes.native.js.map +1 -0
- package/dist/jsx/fields/Duration/index.mjs +28 -11
- package/dist/jsx/fields/Duration/index.mjs.map +1 -1
- package/dist/jsx/fields/Duration/index.native.js +32 -12
- package/dist/jsx/fields/Duration/index.native.js.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs +8 -7
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js +8 -7
- package/dist/jsx/fields/nativeDateTime/OsDateTimeSheet.native.js.map +1 -1
- package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.mjs +1 -1
- package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/osDateTimeIosDisplay.native.js +1 -1
- package/dist/jsx/fields/nativeDateTime/sheetKeyboard.mjs +1 -1
- package/dist/jsx/fields/nativeDateTime/sheetKeyboard.mjs.map +1 -1
- package/dist/jsx/fields/nativeDateTime/sheetKeyboard.native.js +1 -1
- package/dist/jsx/fields/nativeDateTime/sheetKeyboard.native.js.map +1 -1
- package/dist/jsx/index.js +2 -2
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +2 -2
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +0 -1
- package/dist/jsx/index.native.js.map +1 -1
- package/package.json +8 -8
- package/src/Button/Button.iconButton.spec.tsx +47 -7
- package/src/Button/IconButtonGroup.spec.tsx +103 -19
- package/src/Button/IconButtonGroup.tsx +84 -46
- package/src/Button/circleGlyph.ts +18 -0
- package/src/Button/glass.native.spec.ts +62 -0
- package/src/Button/glass.native.ts +58 -37
- package/src/Button/glass.spec.ts +64 -16
- package/src/Button/glass.ts +16 -12
- package/src/Button/iconButtonGroupContext.ts +27 -3
- package/src/Button/index.tsx +21 -33
- package/src/Button/webGlass.ts +25 -18
- package/src/FloatingPanel/FloatingPanel.iconEcho.spec.tsx +61 -1
- package/src/FloatingPanel/FloatingPanel.menuFace.native.spec.tsx +104 -0
- package/src/FloatingPanel/coverRect.ts +42 -0
- package/src/FloatingPanel/iconEcho.tsx +9 -3
- package/src/FloatingPanel/index.native.tsx +63 -18
- package/src/FloatingPanel/index.tsx +35 -15
- package/src/InputParts/index.tsx +6 -0
- package/src/InputParts/keyboardAppearance.spec.ts +12 -0
- package/src/InputParts/keyboardAppearance.ts +4 -0
- package/src/fields/Duration/Duration.spec.tsx +19 -10
- package/src/fields/Duration/Duration.wheel.native.spec.tsx +98 -0
- package/src/fields/Duration/DurationWheel.native.tsx +101 -0
- package/src/fields/Duration/DurationWheel.tsx +11 -0
- package/src/fields/Duration/durationMath.spec.ts +43 -0
- package/src/fields/Duration/durationMath.ts +31 -0
- package/src/fields/Duration/durationWheelTypes.ts +18 -0
- package/src/fields/Duration/index.tsx +58 -27
- package/src/fields/nativeDateTime/OsDateTimeSheet.countdown.native.spec.tsx +121 -0
- package/src/fields/nativeDateTime/OsDateTimeSheet.spec.ts +4 -0
- package/src/fields/nativeDateTime/OsDateTimeSheet.tsx +14 -9
- package/src/fields/nativeDateTime/osDateTimeIosDisplay.ts +3 -3
- package/src/fields/nativeDateTime/sheetKeyboard.spec.ts +6 -0
- package/src/fields/nativeDateTime/sheetKeyboard.ts +2 -2
- package/src/index.ts +0 -1
- package/types/Button/IconButtonGroup.d.ts +7 -12
- package/types/Button/IconButtonGroup.d.ts.map +1 -1
- package/types/Button/circleGlyph.d.ts +12 -0
- package/types/Button/circleGlyph.d.ts.map +1 -1
- package/types/Button/glass.d.ts +7 -11
- package/types/Button/glass.d.ts.map +1 -1
- package/types/Button/glass.native.d.ts +22 -10
- package/types/Button/glass.native.d.ts.map +1 -1
- package/types/Button/iconButtonGroupContext.d.ts +21 -3
- package/types/Button/iconButtonGroupContext.d.ts.map +1 -1
- package/types/Button/index.d.ts +3 -10
- package/types/Button/index.d.ts.map +1 -1
- package/types/Button/webGlass.d.ts +8 -16
- package/types/Button/webGlass.d.ts.map +1 -1
- package/types/FloatingPanel/coverRect.d.ts +25 -0
- package/types/FloatingPanel/coverRect.d.ts.map +1 -0
- package/types/FloatingPanel/index.d.ts.map +1 -1
- package/types/FloatingPanel/index.native.d.ts.map +1 -1
- package/types/InputParts/index.d.ts.map +1 -1
- package/types/InputParts/keyboardAppearance.d.ts +3 -0
- package/types/InputParts/keyboardAppearance.d.ts.map +1 -0
- package/types/fields/Duration/DurationWheel.d.ts +5 -0
- package/types/fields/Duration/DurationWheel.d.ts.map +1 -0
- package/types/fields/Duration/DurationWheel.native.d.ts +5 -0
- package/types/fields/Duration/DurationWheel.native.d.ts.map +1 -0
- package/types/fields/Duration/durationMath.d.ts +13 -0
- package/types/fields/Duration/durationMath.d.ts.map +1 -1
- package/types/fields/Duration/durationWheelTypes.d.ts +18 -0
- package/types/fields/Duration/durationWheelTypes.d.ts.map +1 -0
- package/types/fields/Duration/index.d.ts +8 -3
- package/types/fields/Duration/index.d.ts.map +1 -1
- package/types/fields/nativeDateTime/OsDateTimeSheet.d.ts +1 -1
- package/types/fields/nativeDateTime/OsDateTimeSheet.d.ts.map +1 -1
- package/types/fields/nativeDateTime/osDateTimeIosDisplay.d.ts +2 -2
- package/types/fields/nativeDateTime/osDateTimeIosDisplay.d.ts.map +1 -1
- package/types/fields/nativeDateTime/sheetKeyboard.d.ts +1 -1
- package/types/fields/nativeDateTime/sheetKeyboard.d.ts.map +1 -1
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +1 -1
- package/dist/cjs/Button/mediaPlate.native.js.map +0 -1
- package/dist/esm/Button/mediaPlate.mjs +0 -6
- package/dist/esm/Button/mediaPlate.mjs.map +0 -1
- package/dist/esm/Button/mediaPlate.native.js +0 -6
- package/dist/esm/Button/mediaPlate.native.js.map +0 -1
- package/dist/jsx/Button/mediaPlate.mjs +0 -6
- package/dist/jsx/Button/mediaPlate.mjs.map +0 -1
- package/dist/jsx/Button/mediaPlate.native.js.map +0 -1
- package/src/Button/mediaPlate.ts +0 -9
- package/types/Button/mediaPlate.d.ts +0 -10
- package/types/Button/mediaPlate.d.ts.map +0 -1
package/src/Button/index.tsx
CHANGED
|
@@ -79,11 +79,10 @@ import { warnBareDisabled, warnPositiveTabIndex, warnSizeRecipeEscape } from "..
|
|
|
79
79
|
import { useControlGrouped } from "../shared/groupContext";
|
|
80
80
|
import { useInPanelEcho, usePanelTriggerRadiusReporter } from "../FloatingPanel/echoContext";
|
|
81
81
|
import { loadGlassView } from "./glass";
|
|
82
|
-
import {
|
|
83
|
-
import { ICON_BUTTON_CIRCLE_GLYPH_RATIO } from "./circleGlyph";
|
|
82
|
+
import { boldStroke, GLYPH_BOLD_STROKE_UNITS, ICON_BUTTON_CIRCLE_GLYPH_RATIO } from "./circleGlyph";
|
|
84
83
|
import { useIconButtonGroupGround, useIconButtonGroupMember } from "./iconButtonGroupContext";
|
|
85
84
|
|
|
86
|
-
export { ICON_BUTTON_CIRCLE_GLYPH_RATIO };
|
|
85
|
+
export { GLYPH_BOLD_STROKE_UNITS, ICON_BUTTON_CIRCLE_GLYPH_RATIO };
|
|
87
86
|
|
|
88
87
|
/**
|
|
89
88
|
* Coordinated size recipe (Polaris slim/medium/large, Primer s/m/l, Linear
|
|
@@ -466,24 +465,6 @@ export function iconButtonGlyphPx(rowLinePx: number | undefined): number {
|
|
|
466
465
|
/** LC-176: an inline glyph is the text's size; Phosphor's 256 grid pads ~12%. */
|
|
467
466
|
const INLINE_GLYPH_RATIO = 1.2;
|
|
468
467
|
|
|
469
|
-
/**
|
|
470
|
-
* LC-176: Phosphor bold's stem is 0.12 of its ink, an SF Symbols bold plus's
|
|
471
|
-
* 0.18 (measured at 17 and 24pt). An outline stroke this wide, in the 256-unit
|
|
472
|
-
* grid, brings a bold glyph to SF semibold-bold (0.154); a wider one closes
|
|
473
|
-
* Phosphor bold's 16-unit counters (the trash lid, copy's overlap).
|
|
474
|
-
*/
|
|
475
|
-
export const GLYPH_BOLD_STROKE_UNITS = 8;
|
|
476
|
-
|
|
477
|
-
function boldStroke(weight: "regular" | "bold", color = "currentColor") {
|
|
478
|
-
return weight === "bold"
|
|
479
|
-
? {
|
|
480
|
-
stroke: color,
|
|
481
|
-
strokeWidth: GLYPH_BOLD_STROKE_UNITS,
|
|
482
|
-
strokeLinejoin: "round" as const,
|
|
483
|
-
}
|
|
484
|
-
: undefined;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
468
|
function withGlyphWeight(
|
|
488
469
|
icon: IconLike | undefined,
|
|
489
470
|
size: number,
|
|
@@ -868,9 +849,9 @@ export function Button({
|
|
|
868
849
|
(labelled && chromeless && accentInk === true && edge === "start");
|
|
869
850
|
const labelLine = labelLinePx(knobProps.body.fontFamily);
|
|
870
851
|
const glyphFloor = iconButtonGlyphPx(labelLine);
|
|
871
|
-
// LC-176: on iOS 26 a bar's icon button
|
|
872
|
-
// bar button. Elsewhere, and on a binary without the module, it stays
|
|
873
|
-
// bare tinted glyph.
|
|
852
|
+
// LC-176: on iOS 26 a bar's icon button sits in system Liquid Glass, the
|
|
853
|
+
// native bar button. Elsewhere, and on a binary without the module, it stays
|
|
854
|
+
// the bare tinted glyph; nothing re-creates the glass (FZ-8666).
|
|
874
855
|
const glassGroup = groupGround === "glass";
|
|
875
856
|
const GlassView =
|
|
876
857
|
iconButton && !inlineGlyph && !nested && accentInk && barSurface && !selectedFill && !glassGroup
|
|
@@ -1113,7 +1094,8 @@ export function Button({
|
|
|
1113
1094
|
// A plain button is ink on the bar: no shadow at rest (E-FLAT).
|
|
1114
1095
|
const plainTier = tier === "plain";
|
|
1115
1096
|
// LC-176: hover and press light a soft plate on web; on native the glyph
|
|
1116
|
-
// dims,
|
|
1097
|
+
// dims, and on glass the system answers the press instead. The media plate
|
|
1098
|
+
// deepens instead.
|
|
1117
1099
|
const glyphState = iconButton && !selectedFill;
|
|
1118
1100
|
const iconHover = glyphState
|
|
1119
1101
|
? isWeb
|
|
@@ -1125,7 +1107,9 @@ export function Button({
|
|
|
1125
1107
|
const iconPress = glyphState
|
|
1126
1108
|
? isWeb
|
|
1127
1109
|
? hostScoped({ backgroundColor: "$backgroundPress" })
|
|
1128
|
-
:
|
|
1110
|
+
: GlassView || glassGroup
|
|
1111
|
+
? { backgroundColor: "transparent" }
|
|
1112
|
+
: { backgroundColor: "transparent", opacity: ICON_BUTTON_PRESS_OPACITY }
|
|
1129
1113
|
: mediaPlate
|
|
1130
1114
|
? { backgroundColor: "$shadow5" }
|
|
1131
1115
|
: undefined;
|
|
@@ -1192,7 +1176,6 @@ export function Button({
|
|
|
1192
1176
|
? {
|
|
1193
1177
|
borderRadius: 100000,
|
|
1194
1178
|
backgroundColor: "$shadow4",
|
|
1195
|
-
...(isWeb ? { style: MEDIA_PLATE_WEB_STYLE } : undefined),
|
|
1196
1179
|
}
|
|
1197
1180
|
: undefined)}
|
|
1198
1181
|
{...(edge && !inlineGlyph && chromeless && !selectedFill && !isCircular
|
|
@@ -1363,8 +1346,8 @@ export function Button({
|
|
|
1363
1346
|
{GlassView ? (
|
|
1364
1347
|
<GlassView
|
|
1365
1348
|
glassEffectStyle="regular"
|
|
1366
|
-
isInteractive
|
|
1367
|
-
|
|
1349
|
+
isInteractive={!unavailable}
|
|
1350
|
+
colorScheme={darkScheme ? "dark" : "light"}
|
|
1368
1351
|
style={{
|
|
1369
1352
|
position: "absolute",
|
|
1370
1353
|
top: glassInset,
|
|
@@ -1372,10 +1355,15 @@ export function Button({
|
|
|
1372
1355
|
bottom: glassInset,
|
|
1373
1356
|
left: glassInset,
|
|
1374
1357
|
borderRadius: visualPx / 2,
|
|
1358
|
+
alignItems: "center",
|
|
1359
|
+
justifyContent: "center",
|
|
1375
1360
|
}}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1361
|
+
>
|
|
1362
|
+
{iconElement}
|
|
1363
|
+
</GlassView>
|
|
1364
|
+
) : (
|
|
1365
|
+
iconElement
|
|
1366
|
+
)}
|
|
1379
1367
|
{labelContent}
|
|
1380
1368
|
{iconAfterElement}
|
|
1381
1369
|
</ButtonFrame>
|
|
@@ -1444,5 +1432,5 @@ export function IconButton(props: IconButtonProps) {
|
|
|
1444
1432
|
return <Button {...props} />;
|
|
1445
1433
|
}
|
|
1446
1434
|
|
|
1447
|
-
export { IconButtonGroup
|
|
1435
|
+
export { IconButtonGroup } from "./IconButtonGroup";
|
|
1448
1436
|
export type { IconButtonGroupProps } from "./IconButtonGroup";
|
package/src/Button/webGlass.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { isDarkThemeName } from "@multiplatform.one/theme";
|
|
2
|
-
import { createElement } from "react";
|
|
2
|
+
import { createElement, Fragment, type ReactNode } from "react";
|
|
3
3
|
import { useThemeName, YStack } from "tamagui";
|
|
4
|
-
import { MEDIA_PLATE_WEB_STYLE } from "./mediaPlate";
|
|
5
4
|
|
|
6
5
|
type GlassNavigator = { userAgent?: string; platform?: string; maxTouchPoints?: number };
|
|
7
6
|
|
|
@@ -19,24 +18,32 @@ export function isAppleTouchWeb(
|
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
const webGlassMarker = { "data-mp-glass": "web" };
|
|
21
|
+
const webGlassBlur = {
|
|
22
|
+
backdropFilter: "blur(16px) saturate(180%)",
|
|
23
|
+
WebkitBackdropFilter: "blur(16px) saturate(180%)",
|
|
24
|
+
} as const;
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
|
-
* LC-176: the
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* drop shadow alone, with the media plate's blur.
|
|
27
|
+
* LC-176: the drawn face `loadGlassView` can give iOS Safari, one circle for a
|
|
28
|
+
* lone button or one capsule for an `IconButtonGroup`. Off by default: the
|
|
29
|
+
* compare in `glass.ts` decides whether it stays. Its children stay siblings
|
|
30
|
+
* above the layer (absolute, z -1 in the button's stacking context).
|
|
29
31
|
*/
|
|
30
|
-
export function WebGlassFace({ style }: { style?: unknown }) {
|
|
32
|
+
export function WebGlassFace({ style, children }: { style?: unknown; children?: ReactNode }) {
|
|
31
33
|
const dark = isDarkThemeName(useThemeName());
|
|
32
|
-
return createElement(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
return createElement(
|
|
35
|
+
Fragment,
|
|
36
|
+
null,
|
|
37
|
+
createElement(YStack, {
|
|
38
|
+
pointerEvents: "none",
|
|
39
|
+
backgroundColor: dark ? "$color4" : "$color1",
|
|
40
|
+
opacity: 0.92,
|
|
41
|
+
shadowColor: "$shadowColor",
|
|
42
|
+
shadowRadius: 10,
|
|
43
|
+
shadowOffset: { width: 0, height: 3 },
|
|
44
|
+
...webGlassMarker,
|
|
45
|
+
style: { ...(style as object), zIndex: -1, ...webGlassBlur },
|
|
46
|
+
}),
|
|
47
|
+
children,
|
|
48
|
+
);
|
|
42
49
|
}
|
|
@@ -8,10 +8,11 @@ import { PlusIcon, XIcon } from "@phosphor-icons/react";
|
|
|
8
8
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
9
9
|
import { fireEvent, render, waitFor, within } from "@testing-library/react";
|
|
10
10
|
import { useState } from "react";
|
|
11
|
-
import { Surface, useBarSurface } from "@multiplatform.one/theme";
|
|
11
|
+
import { MIN_PRESS_TARGET, Surface, useBarSurface } from "@multiplatform.one/theme";
|
|
12
12
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
13
13
|
import { Text } from "tamagui";
|
|
14
14
|
import { Button } from "../Button";
|
|
15
|
+
import { GLYPH_BOLD_STROKE_UNITS } from "../Button/circleGlyph";
|
|
15
16
|
import { FloatingPanel } from "./index";
|
|
16
17
|
import { usePanelIconEchoBox } from "./echoContext";
|
|
17
18
|
import { PanelHeader } from "./PanelHeader";
|
|
@@ -98,6 +99,31 @@ function AddPanel({ kind = "close", header = false }: { kind?: IconEcho; header?
|
|
|
98
99
|
);
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
/** An account menu opened from a 32pt avatar (no `icon`, so its X is a circle). */
|
|
103
|
+
function AvatarPanel() {
|
|
104
|
+
return (
|
|
105
|
+
<FloatingPanel
|
|
106
|
+
open
|
|
107
|
+
onOpenChange={() => {}}
|
|
108
|
+
anchorMode="cover-trigger"
|
|
109
|
+
compactFace="menu"
|
|
110
|
+
triggerEcho={false}
|
|
111
|
+
iconEcho="menu"
|
|
112
|
+
coverAlign="auto"
|
|
113
|
+
widthMode="fit-content"
|
|
114
|
+
triggerSizing="content"
|
|
115
|
+
contentPadding="none"
|
|
116
|
+
trigger={
|
|
117
|
+
<span role="button" aria-label="Account">
|
|
118
|
+
AD
|
|
119
|
+
</span>
|
|
120
|
+
}
|
|
121
|
+
>
|
|
122
|
+
<Text>Sign out</Text>
|
|
123
|
+
</FloatingPanel>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
101
127
|
const glyphPath = (node: Element | null | undefined) =>
|
|
102
128
|
node?.querySelector("svg path")?.getAttribute("d");
|
|
103
129
|
|
|
@@ -294,4 +320,38 @@ describe("LC-112 icon trigger echo on the web (FZ-8480)", () => {
|
|
|
294
320
|
expect(panel.style.transformOrigin).toBe("bottom left");
|
|
295
321
|
expect(result.queryByTestId("floating-panel-sheet")).toBeNull();
|
|
296
322
|
});
|
|
323
|
+
|
|
324
|
+
it("strokes the avatar's X to the bar buttons' bold stem (FZ-8480 follow-up)", async () => {
|
|
325
|
+
measure({ x: 100, y: 12, width: 44, height: 44 });
|
|
326
|
+
const bar = renderWithProviders(<AddPanel kind="menu" />);
|
|
327
|
+
const barPanel = await open(bar);
|
|
328
|
+
const barX = within(barPanel).getByRole("button", { name: "Close" }).querySelector("svg");
|
|
329
|
+
expect(barX?.getAttribute("stroke-width")).toBe(String(GLYPH_BOLD_STROKE_UNITS));
|
|
330
|
+
bar.unmount();
|
|
331
|
+
const result = renderWithProviders(<AvatarPanel />);
|
|
332
|
+
const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
|
|
333
|
+
const avatarX = within(panel).getByRole("button", { name: "Close" }).querySelector("svg");
|
|
334
|
+
expect(avatarX?.getAttribute("stroke-width")).toBe(barX?.getAttribute("stroke-width"));
|
|
335
|
+
expect(avatarX?.getAttribute("stroke-linejoin")).toBe("round");
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it("covers a 32pt avatar at its 44pt target, its centre on the row-icon column (FZ-8480 GAP)", async () => {
|
|
339
|
+
const avatar = { x: 100, y: 18, width: 32, height: 32 };
|
|
340
|
+
measure(avatar, 240);
|
|
341
|
+
const result = renderWithProviders(<AvatarPanel />);
|
|
342
|
+
const panel = (await result.findByTestId("floating-panel-viewport")) as HTMLElement;
|
|
343
|
+
await waitFor(() => expect(panel.style.visibility).toBe("visible"));
|
|
344
|
+
const inset = (MIN_PRESS_TARGET - avatar.width) / 2;
|
|
345
|
+
expect(panel.style.left).toBe(`${avatar.x - inset}px`);
|
|
346
|
+
expect(panel.style.top).toBe(`${avatar.y - inset}px`);
|
|
347
|
+
const row = panel.querySelector<HTMLElement>("[data-fp-icon-echo]") as HTMLElement;
|
|
348
|
+
expect(row.style.height).toBe(`${MIN_PRESS_TARGET}px`);
|
|
349
|
+
const box = row.querySelector<HTMLElement>("[data-fp-icon-echo-box]") as HTMLElement;
|
|
350
|
+
expect(box.style.width).toBe(`${avatar.width}px`);
|
|
351
|
+
expect(box.style.marginLeft).toBe(`${inset}px`);
|
|
352
|
+
expect(box.style.marginTop).toBe(`${inset}px`);
|
|
353
|
+
// The X's centre sits half a press target in, the centre of a menu row's
|
|
354
|
+
// leading glyph slot.
|
|
355
|
+
expect(inset + avatar.width / 2).toBe(MIN_PRESS_TARGET / 2);
|
|
356
|
+
});
|
|
297
357
|
});
|
|
@@ -9,7 +9,13 @@ import { PlusIcon, XIcon } from "@phosphor-icons/react";
|
|
|
9
9
|
import { useState, type ReactNode } from "react";
|
|
10
10
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
11
11
|
import { Text, XStack, YStack, getTokens, getVariableValue } from "tamagui";
|
|
12
|
+
import { MIN_PRESS_TARGET } from "@multiplatform.one/theme";
|
|
12
13
|
import { Button } from "../Button";
|
|
14
|
+
import {
|
|
15
|
+
IconButtonGroupSurfaceContext,
|
|
16
|
+
type IconButtonGroupPlate,
|
|
17
|
+
type IconButtonGroupSurface,
|
|
18
|
+
} from "../Button/iconButtonGroupContext";
|
|
13
19
|
import { Input as InputParts } from "../InputParts";
|
|
14
20
|
import { OverlayStackProvider } from "../shared/overlayStack";
|
|
15
21
|
import { MENU_MIN_WIDTH, type CompactFace } from "./compactFace";
|
|
@@ -540,3 +546,101 @@ describe("LC-112 icon trigger echo on native (FZ-8480, rv_2607879d3bdaf9bf)", ()
|
|
|
540
546
|
expect(glyphPath(iconEcho())).not.toBe(glyphPath(live));
|
|
541
547
|
});
|
|
542
548
|
});
|
|
549
|
+
|
|
550
|
+
const capsuleSurface = (plate: IconButtonGroupPlate): IconButtonGroupSurface => ({
|
|
551
|
+
measure: (callback) => callback(plate),
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
describe("LC-112 grouped glass capsule on native (FZ-8550, Round 37 second pass)", () => {
|
|
555
|
+
const plate = { x: 200, y: 50, width: 174, height: 44, radius: 22 };
|
|
556
|
+
|
|
557
|
+
it("covers the whole capsule from context at its radius; only the pressed trigger shows, as its X", () => {
|
|
558
|
+
trigger = { x: 330, y: 50, width: 44, height: 44 };
|
|
559
|
+
const result = renderWithProviders(
|
|
560
|
+
<IconButtonGroupSurfaceContext.Provider value={capsuleSurface(plate)}>
|
|
561
|
+
<EchoMenu kind="menu" />
|
|
562
|
+
</IconButtonGroupSurfaceContext.Provider>,
|
|
563
|
+
);
|
|
564
|
+
tap(result.getAllByRole("button", { name: "Add node" })[0]!);
|
|
565
|
+
const panel = menu() as HTMLElement;
|
|
566
|
+
layout(panel, MENU_MIN_WIDTH, 180);
|
|
567
|
+
const left = parseFloat(panel.style.left);
|
|
568
|
+
const top = parseFloat(panel.style.top);
|
|
569
|
+
// The panel's frame contains the capsule's: same top edge, both ends.
|
|
570
|
+
expect(top).toBe(plate.y);
|
|
571
|
+
expect(left).toBeLessThanOrEqual(plate.x);
|
|
572
|
+
expect(left + MENU_MIN_WIDTH).toBeGreaterThanOrEqual(plate.x + plate.width);
|
|
573
|
+
expect(left).toBe(plate.x + plate.width - MENU_MIN_WIDTH);
|
|
574
|
+
expect(corners(frame() as HTMLElement)).toEqual(radiusAtoms(plate.radius));
|
|
575
|
+
// The band is the capsule's height; the X keeps the trigger's own box.
|
|
576
|
+
const band = iconBand() as HTMLElement;
|
|
577
|
+
expect(band.style.height).toBe(`${plate.height}px`);
|
|
578
|
+
const box = band.firstElementChild as HTMLElement;
|
|
579
|
+
expect(box.style.width).toBe(`${trigger.width}px`);
|
|
580
|
+
expect(box.style.marginInlineStart || box.style.marginLeft).toBe(`${trigger.x - left}px`);
|
|
581
|
+
// Only the pressed trigger shows, as an X; nothing else of the group.
|
|
582
|
+
const echoes = document.querySelectorAll('[data-testid="floating-panel-icon-echo"]');
|
|
583
|
+
expect(echoes).toHaveLength(1);
|
|
584
|
+
const x = render(<XIcon weight="bold" />);
|
|
585
|
+
expect(glyphPath(echoes[0] as Element)).toBe(glyphPath(x.container));
|
|
586
|
+
x.unmount();
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
it("takes the capsule's width as its floor when the capsule is wider than the menu", () => {
|
|
590
|
+
const wide = { x: 16, y: 50, width: 358, height: 44, radius: 22 };
|
|
591
|
+
trigger = { x: 330, y: 50, width: 44, height: 44 };
|
|
592
|
+
const result = renderWithProviders(
|
|
593
|
+
<IconButtonGroupSurfaceContext.Provider value={capsuleSurface(wide)}>
|
|
594
|
+
<EchoMenu kind="menu" />
|
|
595
|
+
</IconButtonGroupSurfaceContext.Provider>,
|
|
596
|
+
);
|
|
597
|
+
tap(result.getAllByRole("button", { name: "Add node" })[0]!);
|
|
598
|
+
const panel = menu() as HTMLElement;
|
|
599
|
+
expect(panel.style.minWidth).toBe(`${wide.width}px`);
|
|
600
|
+
layout(panel, wide.width, 180);
|
|
601
|
+
expect(panel.style.left).toBe(`${wide.x}px`);
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
it("waits for the capsule before it shows, so it never opens on the button alone first", () => {
|
|
605
|
+
trigger = { x: 330, y: 50, width: 44, height: 44 };
|
|
606
|
+
let answer: ((plate: IconButtonGroupPlate | null) => void) | null = null;
|
|
607
|
+
const result = renderWithProviders(
|
|
608
|
+
<IconButtonGroupSurfaceContext.Provider
|
|
609
|
+
value={{
|
|
610
|
+
measure: (callback) => {
|
|
611
|
+
answer = callback;
|
|
612
|
+
},
|
|
613
|
+
}}
|
|
614
|
+
>
|
|
615
|
+
<EchoMenu kind="menu" />
|
|
616
|
+
</IconButtonGroupSurfaceContext.Provider>,
|
|
617
|
+
);
|
|
618
|
+
tap(result.getAllByRole("button", { name: "Add node" })[0]!);
|
|
619
|
+
const panel = menu() as HTMLElement;
|
|
620
|
+
layout(panel, MENU_MIN_WIDTH, 180);
|
|
621
|
+
expect(panel.style.opacity).toBe("0");
|
|
622
|
+
act(() => answer?.(plate));
|
|
623
|
+
expect(panel.style.opacity).toBe("1");
|
|
624
|
+
expect(panel.style.left).toBe(`${plate.x + plate.width - MENU_MIN_WIDTH}px`);
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
it("covers a 32pt avatar at its 44pt target, so its centre is the row-icon column (FZ-8480)", () => {
|
|
628
|
+
trigger = { x: 100, y: 56, width: 32, height: 32 };
|
|
629
|
+
const result = renderWithProviders(<EchoMenu kind="menu" />);
|
|
630
|
+
tap(result.getAllByRole("button", { name: "Add node" })[0]!);
|
|
631
|
+
const panel = menu() as HTMLElement;
|
|
632
|
+
layout(panel, MENU_MIN_WIDTH, 180);
|
|
633
|
+
const inset = (MIN_PRESS_TARGET - trigger.width) / 2;
|
|
634
|
+
expect(panel.style.left).toBe(`${trigger.x - inset}px`);
|
|
635
|
+
expect(panel.style.top).toBe(`${trigger.y - inset}px`);
|
|
636
|
+
const band = iconBand() as HTMLElement;
|
|
637
|
+
expect(band.style.height).toBe(`${MIN_PRESS_TARGET}px`);
|
|
638
|
+
const box = band.firstElementChild as HTMLElement;
|
|
639
|
+
expect(box.style.width).toBe(`${trigger.width}px`);
|
|
640
|
+
expect(box.style.marginTop).toBe(`${inset}px`);
|
|
641
|
+
expect(box.style.marginInlineStart || box.style.marginLeft).toBe(`${inset}px`);
|
|
642
|
+
// The X's centre sits half a press target in: where a row's leading
|
|
643
|
+
// glyph centres (row inset plus half its 18pt slot, on the frame border).
|
|
644
|
+
expect(inset + trigger.width / 2).toBe(MIN_PRESS_TARGET / 2);
|
|
645
|
+
});
|
|
646
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MIN_PRESS_TARGET } from "@multiplatform.one/theme";
|
|
2
|
+
import type { TriggerRect } from "./pointAnchor";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The 44pt box an icon trigger is pressed in, centred on the trigger
|
|
6
|
+
* (LC-176). A trigger drawn smaller than its target (a 32pt avatar) is
|
|
7
|
+
* covered at its target, so the panel's row-icon column, which centres on
|
|
8
|
+
* a 44pt start inset, runs through the trigger's centre and the X drawn on
|
|
9
|
+
* it (FZ-8480 GAP). A trigger at least that big is its own box.
|
|
10
|
+
*/
|
|
11
|
+
export function pressTargetRect(trigger: TriggerRect, min = MIN_PRESS_TARGET): TriggerRect {
|
|
12
|
+
const width = Math.max(trigger.width, min);
|
|
13
|
+
const height = Math.max(trigger.height, min);
|
|
14
|
+
return {
|
|
15
|
+
x: trigger.x - (width - trigger.width) / 2,
|
|
16
|
+
y: trigger.y - (height - trigger.height) / 2,
|
|
17
|
+
width,
|
|
18
|
+
height,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The surface a panel opened from an icon trigger covers (LC-112, FZ-8480
|
|
24
|
+
* Round 37): the plate the trigger sits on. In a grouped glass capsule
|
|
25
|
+
* that is the capsule (FZ-8550); a lone trigger is its press target.
|
|
26
|
+
*/
|
|
27
|
+
export function iconCoverRect(trigger: TriggerRect, group: TriggerRect | null): TriggerRect {
|
|
28
|
+
return group ?? pressTargetRect(trigger);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Where the trigger sits inside the surface its panel covers: the X box's
|
|
33
|
+
* offset from the cover's top, and the band's height. Null when the cover is
|
|
34
|
+
* the trigger itself.
|
|
35
|
+
*/
|
|
36
|
+
export function echoInCover(
|
|
37
|
+
trigger: TriggerRect,
|
|
38
|
+
cover: TriggerRect,
|
|
39
|
+
): { top: number; height: number } | null {
|
|
40
|
+
if (cover.y === trigger.y && cover.height === trigger.height) return null;
|
|
41
|
+
return { top: trigger.y - cover.y, height: cover.height };
|
|
42
|
+
}
|
|
@@ -2,7 +2,7 @@ import { XIcon } from "@phosphor-icons/react";
|
|
|
2
2
|
import { cloneElement, isValidElement, useState, type ReactElement, type ReactNode } from "react";
|
|
3
3
|
import { SurfaceContext, type SurfaceIntent } from "@multiplatform.one/theme";
|
|
4
4
|
import { useTheme, View } from "tamagui";
|
|
5
|
-
import { ICON_BUTTON_CIRCLE_GLYPH_RATIO } from "../Button/circleGlyph";
|
|
5
|
+
import { boldStroke, ICON_BUTTON_CIRCLE_GLYPH_RATIO } from "../Button/circleGlyph";
|
|
6
6
|
import { t } from "../shared/t";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -83,10 +83,15 @@ const avatarPlate = "$selectedBackground";
|
|
|
83
83
|
/** The X's glyph before the circle has measured itself. */
|
|
84
84
|
const circleGlyphFallbackPx = 18;
|
|
85
85
|
|
|
86
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* An X in a circle the size of the trigger it replaces (an avatar), stroked
|
|
88
|
+
* to the bar buttons' bold stem (LC-176), so every X in a bar reads at one
|
|
89
|
+
* weight.
|
|
90
|
+
*/
|
|
87
91
|
function CircleClose({ label, onClose }: { label: string; onClose: () => void }) {
|
|
88
92
|
const theme = useTheme();
|
|
89
93
|
const [side, setSide] = useState(0);
|
|
94
|
+
const ink = theme.selectedColor?.val ?? theme.color?.val;
|
|
90
95
|
return (
|
|
91
96
|
<View
|
|
92
97
|
role="button"
|
|
@@ -110,7 +115,8 @@ function CircleClose({ label, onClose }: { label: string; onClose: () => void })
|
|
|
110
115
|
<XIcon
|
|
111
116
|
size={side > 0 ? Math.round(side * ICON_BUTTON_CIRCLE_GLYPH_RATIO) : circleGlyphFallbackPx}
|
|
112
117
|
weight="bold"
|
|
113
|
-
color={
|
|
118
|
+
color={ink}
|
|
119
|
+
{...boldStroke("bold", typeof ink === "string" ? ink : undefined)}
|
|
114
120
|
aria-hidden
|
|
115
121
|
/>
|
|
116
122
|
</View>
|