@mkbabb/glass-ui 8.0.0 → 10.0.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/MIGRATION.md +4768 -0
- package/README.md +57 -13
- package/dist/DialogContent-CwIBvou_.js +157 -0
- package/dist/{DropdownMenuTrigger-8UZsBtZ8.js → DropdownMenuTrigger-CKRnhDSQ.js} +1 -1
- package/dist/{Surface-i1tWC-Ga.js → Surface-1nPoabc3.js} +1 -1
- package/dist/{accent-tone-solve-Cw7WkRD9.js → accent-tone-solve-5H6FY2QO.js} +1 -1
- package/dist/aurora.js +386 -355
- package/dist/{badge-owUOaaba.js → badge-BO6BC4G5.js} +1 -1
- package/dist/badge.js +1 -1
- package/dist/blob.js +44 -44
- package/dist/{button-yvGPb0Bx.js → button-BOFTUPyU.js} +1 -1
- package/dist/button.js +1 -1
- package/dist/{card-3HFFpC7_.js → card-ByyqRBvK.js} +2 -2
- package/dist/card.js +1 -1
- package/dist/carousel.js +3 -3
- package/dist/{checkbox-BnXuGgJ3.js → checkbox-B1qn65se.js} +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/chip.js +8 -3
- package/dist/{class-names-q-UGOkHH.js → class-names-FlXcvRRT.js} +65 -18
- package/dist/{collapsible-B7O6m-Ch.js → collapsible-DFzK29Oh.js} +5 -2
- package/dist/collapsible.js +1 -1
- package/dist/color.glsl-DTJhdekG.js +34 -0
- package/dist/color.js +11 -11
- package/dist/color.wgsl-BTszLY39.js +398 -0
- package/dist/{command-BuBnYpxF.js → command-C-5xSEJ2.js} +8 -8
- package/dist/command.js +1 -1
- package/dist/component-styles.css +1 -0
- package/dist/components/_shared/class-names.d.ts +10 -1
- package/dist/components/_shared/control.d.ts +0 -1
- package/dist/components/_shared/index.d.ts +0 -1
- package/dist/components/_shared/menu/menu.css +1 -1
- package/dist/components/_shared/overlay/index.d.ts +1 -0
- package/dist/components/_shared/overlay/shortcuts.d.ts +12 -0
- package/dist/components/aurora/Aurora.vue.d.ts +1 -0
- package/dist/components/aurora/composables/atoms.d.ts +22 -6
- package/dist/components/aurora/composables/frameLoop.d.ts +6 -5
- package/dist/components/aurora/composables/runtime.d.ts +28 -1
- package/dist/components/aurora/composables/useAurora.d.ts +28 -0
- package/dist/components/aurora/composables/wgpuSetup.d.ts +1 -1
- package/dist/components/aurora/constants/presets.d.ts +62 -5
- package/dist/components/aurora/index.d.ts +1 -1
- package/dist/components/blob/Blob.vue.d.ts +3 -3
- package/dist/components/card/Card.vue.d.ts +8 -2
- package/dist/components/chip/Chip.vue.d.ts +1 -7
- package/dist/components/chip/chipVariants.d.ts +1 -0
- package/dist/components/collapsible/Collapsible.vue.d.ts +1 -0
- package/dist/components/command/CommandDialog.vue.d.ts +1 -1
- package/dist/components/configurator/Configurator.vue.d.ts +25 -2
- package/dist/components/configurator/ConfiguratorRow.vue.d.ts +4 -2
- package/dist/components/configurator/styles.css +1 -1
- package/dist/components/dark-mode-toggle/dark-mode-toggle.css +1 -1
- package/dist/components/deck/styles/capture.css +1 -1
- package/dist/components/dialog/styles.css +1 -1
- package/dist/components/dock/DockSeparator.vue.d.ts +2 -3
- package/dist/components/dock/GlassDock.vue.d.ts +1 -0
- package/dist/components/dock/composables/dockContext.d.ts +1 -8
- package/dist/components/dock/composables/dockCrossfadeContext.d.ts +0 -2
- package/dist/components/dock/composables/index.d.ts +1 -1
- package/dist/components/dock/composables/useDockHold.d.ts +16 -12
- package/dist/components/dock/composables/useDockRun.d.ts +20 -0
- package/dist/components/dock/composables/useDockSearch.d.ts +1 -1
- package/dist/components/dock/composables/useDockShellProps.d.ts +18 -101
- package/dist/components/dock/composables/useDockState.d.ts +2 -9
- package/dist/components/dock/constants.d.ts +15 -0
- package/dist/components/dock/index.d.ts +2 -2
- package/dist/components/dock/styles/controls/icon-button.css +1 -1
- package/dist/components/dock/styles/controls/tab-button.css +1 -1
- package/dist/components/dock/styles/controls/triggers.css +1 -1
- package/dist/components/dock/styles/controls.css +1 -1
- package/dist/components/dock/styles/density.css +1 -1
- package/dist/components/dock/styles/index.css +1 -1
- package/dist/components/dock/styles/layer-group.css +1 -1
- package/dist/components/dock/styles/layers.css +1 -1
- package/dist/components/dock/styles/morph.css +1 -1
- package/dist/components/dock/styles/run.css +1 -0
- package/dist/components/dock/styles/search.css +1 -1
- package/dist/components/dock/styles/shape.css +1 -1
- package/dist/components/dock/styles/shell-regions.css +1 -1
- package/dist/components/dock/styles/shell.css +1 -1
- package/dist/components/fourier-field/FourierField.vue.d.ts +29 -26
- package/dist/components/fourier-field/clock.d.ts +35 -0
- package/dist/components/fourier-field/constants.d.ts +80 -104
- package/dist/components/fourier-field/index.d.ts +3 -28
- package/dist/components/fourier-field/math.d.ts +69 -77
- package/dist/components/fourier-field/renderer/mint.d.ts +50 -0
- package/dist/components/fourier-field/renderer/uniforms.d.ts +84 -0
- package/dist/components/fourier-field/renderer/wgpu.d.ts +28 -0
- package/dist/components/fourier-field/shaders/compute.wgsl.d.ts +1 -0
- package/dist/components/fourier-field/shaders/render.wgsl.d.ts +1 -0
- package/dist/components/fourier-field/useFourierField.d.ts +49 -0
- package/dist/components/handmark/HandMark.vue.d.ts +18 -14
- package/dist/components/handmark/index.d.ts +4 -23
- package/dist/components/handmark/stroke.d.ts +92 -0
- package/dist/components/labeled-field/LabeledSwitch.vue.d.ts +3 -1
- package/dist/components/labeled-field/types.d.ts +1 -1
- package/dist/components/menu/DropdownMenu.vue.d.ts +1 -1
- package/dist/components/metric/coalesce-metric.d.ts +6 -1
- package/dist/components/metric/styles.css +1 -1
- package/dist/components/popover/Popover.vue.d.ts +1 -1
- package/dist/components/scroll-progress-rim/styles.css +1 -1
- package/dist/components/sheet/styles.css +1 -1
- package/dist/components/slider/styles.css +1 -1
- package/dist/components/tabs/SegmentedTabs.vue.d.ts +25 -112
- package/dist/components/tabs/composables/useTabDragMorph.d.ts +1 -1
- package/dist/components/tabs/composables/useTabResponsive.d.ts +11 -11
- package/dist/components/tabs/index.d.ts +1 -1
- package/dist/components/tabs/styles/drag.css +1 -1
- package/dist/components/tabs/styles/segmented.css +1 -1
- package/dist/components/tabs/types.d.ts +85 -0
- package/dist/components/timeline/index.d.ts +2 -0
- package/dist/components/toast/Toast.vue.d.ts +2 -2
- package/dist/composables/color/index.d.ts +0 -15
- package/dist/composables/dark/darkModeSyncScript.d.ts +42 -0
- package/dist/composables/dom/useResolveTokenColor.d.ts +1 -1
- package/dist/composables/glass/index.d.ts +2 -0
- package/dist/composables/keyboard/useKeyboardShortcuts.d.ts +47 -1
- package/dist/composables/motion/pointer/pointerFieldMappings.d.ts +0 -41
- package/dist/{components/search/composables → composables/search}/index.d.ts +2 -2
- package/dist/{components/search/composables/fuzzySearchIndex.d.ts → composables/search/match.d.ts} +8 -3
- package/dist/composables/sidebar/types.d.ts +5 -1
- package/dist/configurator-DiwVN573.js +339 -0
- package/dist/configurator.js +1 -1
- package/dist/constellation.js +5 -5
- package/dist/{content-CWO-XL7o.js → content-So3j6SOe.js} +1 -1
- package/dist/control-DJp15L4U.js +7 -0
- package/dist/dark-mode-toggle.js +2 -2
- package/dist/{dark-z_P5QwqI.js → dark-pONY3x93.js} +2 -2
- package/dist/dark.js +1 -1
- package/dist/{data-table-_RrOEdiw.js → data-table-Ba_uTfPc.js} +3 -3
- package/dist/data-table.js +1 -1
- package/dist/{deck-Ci6YjB5e.js → deck-Cm_VmyNL.js} +1 -1
- package/dist/deck.js +1 -1
- package/dist/{dialog-CbRnTRtg.js → dialog-BZoFG0j8.js} +1 -1
- package/dist/dialog.js +2 -2
- package/dist/dock.js +718 -496
- package/dist/dom.js +90 -8
- package/dist/easing.js +5 -5
- package/dist/expandable-container-CZUj9BzY.js +142 -0
- package/dist/expandable-container.js +2 -142
- package/dist/fourier-field.js +638 -855
- package/dist/fourier-math.js +6 -6
- package/dist/glass-ui.css +1 -1
- package/dist/glass-ui.js +88 -75
- package/dist/handmark.js +330 -718
- package/dist/index.d.ts +2 -2
- package/dist/infinite-scroll.js +16 -17
- package/dist/{input-Bls2A4Tt.js → input-eLZ_AU7l.js} +1 -1
- package/dist/input.js +1 -1
- package/dist/keyboard.js +64 -21
- package/dist/{label-BQEZhnK_.js → label-CE03H1KL.js} +2 -2
- package/dist/label.js +1 -1
- package/dist/labeled-field.js +9 -6
- package/dist/{menu-wLu1XGKn.js → menu-BnmCOa3y.js} +93 -90
- package/dist/menu.js +2 -2
- package/dist/metric.js +12 -7
- package/dist/{motion-D4uYE0UM.js → motion-BvV1_24p.js} +1 -1
- package/dist/motion-core.js +35 -35
- package/dist/{number-field-NFAwQ0HK.js → number-field-RP89046a.js} +2 -2
- package/dist/number-field.js +1 -1
- package/dist/pager-dots.js +3 -3
- package/dist/{participation-B0hdsIRo.js → participation-Di4UHbzk.js} +8 -8
- package/dist/{pointerFieldMappings-DP5tla5z.js → pointerFieldMappings-DXwlU5uj.js} +7 -23
- package/dist/popover-DA87hFBx.js +184 -0
- package/dist/popover.js +1 -1
- package/dist/{progress-DF8dWZIX.js → progress-eVa-mc7J.js} +1 -1
- package/dist/progress.js +1 -1
- package/dist/{radio-group-Ci8o-pDx.js → radio-group-B58Bz16F.js} +2 -2
- package/dist/radio-group.js +1 -1
- package/dist/{select-CDgwGH_P.js → select-fy3vtArm.js} +13 -13
- package/dist/select.js +1 -1
- package/dist/{separator-CN11t406.js → separator-D4EZM10u.js} +2 -2
- package/dist/separator.js +1 -1
- package/dist/{sheet-BEFvnO_u.js → sheet-BQJyER59.js} +120 -115
- package/dist/sheet.js +2 -2
- package/dist/shortcuts-DGGWNRNe.js +13 -0
- package/dist/sidebar.js +4 -4
- package/dist/{slider-gsc8jDIo.js → slider-5ChjjWSR.js} +1 -1
- package/dist/slider.js +1 -1
- package/dist/{status-dot-BpnqOP5N.js → status-dot-W4LFiJps.js} +2 -2
- package/dist/status-dot.js +1 -1
- package/dist/styles/accessibility.css +1 -1
- package/dist/styles/animations.css +1 -1
- package/dist/styles/components.css +1 -1
- package/dist/styles/glass/a11y-fallback.css +1 -1
- package/dist/styles/glass/dissolve.css +1 -1
- package/dist/styles/glass/focus-veil.css +1 -1
- package/dist/styles/glass/ladder.css +1 -1
- package/dist/styles/glass/material.css +1 -1
- package/dist/styles/glass/overlay-plate.css +1 -1
- package/dist/styles/glass/reveal.css +1 -1
- package/dist/styles/glass-specular-track.css +1 -1
- package/dist/styles/paper.css +1 -1
- package/dist/styles/scroll-choreography.css +1 -1
- package/dist/styles/scroll-chrome.css +1 -1
- package/dist/styles/scroll-driven.css +1 -1
- package/dist/styles/theme/literals.css +1 -1
- package/dist/styles/tokens/color-radius.css +1 -1
- package/dist/styles/tokens/dark-arm-glass.css +1 -1
- package/dist/styles/tokens/light-dark.css +1 -1
- package/dist/styles/tokens/offsets.css +1 -1
- package/dist/styles/tokens/scheme-motion.css +1 -1
- package/dist/styles/tokens/sizing.css +1 -1
- package/dist/styles/typography/semantic.css +1 -1
- package/dist/styles/typography/utilities.css +1 -1
- package/dist/styles/utilities/a11y-overrides.css +1 -1
- package/dist/styles/utilities/responsive.css +1 -1
- package/dist/styles/view-transition.css +1 -1
- package/dist/styles/viz-reveal.css +1 -1
- package/dist/surface.js +1 -1
- package/dist/{switch-DxZzDrmV.js → switch-BYUZ6g9G.js} +2 -2
- package/dist/switch.js +1 -1
- package/dist/{tabs-CYscnq5H.js → tabs-rdRXKXxd.js} +4 -3
- package/dist/tabs.js +1 -1
- package/dist/textarea.js +1 -1
- package/dist/timeline.js +44 -42
- package/dist/{toast-9c6Kp58L.js → toast-DVOwo6GB.js} +1 -1
- package/dist/toast.js +1 -1
- package/dist/{toggle-group-11aPGMfE.js → toggle-group-CC5b3o1R.js} +2 -2
- package/dist/toggle-group.js +1 -1
- package/dist/{tooltip-DqKMZ4dn.js → tooltip-DhTHhtJN.js} +2 -2
- package/dist/tooltip.js +1 -1
- package/dist/typewriter.js +1 -1
- package/dist/{useAccentTone-DFAh1osB.js → useAccentTone-DitmKfGL.js} +1 -1
- package/dist/{resolveCanvasColor-6MCrswTB.js → useCanvas2D-CQRElMyE.js} +1 -11
- package/dist/{usePointerVelocityField-DsIf7yyq.js → usePointerVelocityField-Lx26_Yap.js} +1 -1
- package/dist/useResolveTokenColor-B2FfJnd9.js +24 -0
- package/package.json +5 -21
- package/dist/DialogContent-4hzLiaCQ.js +0 -152
- package/dist/canvas.d.ts +0 -1
- package/dist/canvas.js +0 -2
- package/dist/color.wgsl-B0N3mKMb.js +0 -412
- package/dist/compile-D7VYG3gi.js +0 -19
- package/dist/components/dock/composables/useDockOverflowFit.d.ts +0 -20
- package/dist/components/dock/composables/useDockTouchGate.d.ts +0 -42
- package/dist/components/dock/styles/overflow.css +0 -1
- package/dist/components/fourier-field/composables/fourierFieldGLSetup.d.ts +0 -24
- package/dist/components/fourier-field/composables/fourierFieldWGPUSetup.d.ts +0 -31
- package/dist/components/fourier-field/composables/uniformBridgeWGPU.d.ts +0 -39
- package/dist/components/fourier-field/composables/useFourierField.d.ts +0 -56
- package/dist/components/fourier-field/shaders/fourier-field.compute.wgsl.d.ts +0 -1
- package/dist/components/fourier-field/shaders/fourier-field.glsl.d.ts +0 -4
- package/dist/components/fourier-field/shaders/fourier-field.render.wgsl.d.ts +0 -1
- package/dist/components/fourier-field/shaders/fourier-field.ribbon.d.ts +0 -51
- package/dist/components/handmark/brush.d.ts +0 -269
- package/dist/components/handmark/composables/useHandMark.d.ts +0 -99
- package/dist/components/handmark/constants.d.ts +0 -69
- package/dist/components/handmark/freehand.d.ts +0 -69
- package/dist/components/handmark/geometry.d.ts +0 -62
- package/dist/components/handmark/ink.d.ts +0 -11
- package/dist/components/handmark/noise.d.ts +0 -30
- package/dist/components/handmark/texture.d.ts +0 -39
- package/dist/components/handmark/types.d.ts +0 -70
- package/dist/components/search/SearchBar.vue.d.ts +0 -38
- package/dist/components/search/index.d.ts +0 -8
- package/dist/components/search/searchVariants.d.ts +0 -16
- package/dist/configurator-BoeScnDL.js +0 -311
- package/dist/control-Da4XeT43.js +0 -11
- package/dist/popover-DBMKTPkL.js +0 -181
- package/dist/search.d.ts +0 -1
- package/dist/search.js +0 -61
- package/dist/useFuzzySearch-CUnZknpm.js +0 -177
- package/dist/useResolveTokenColor-CspQv_ik.js +0 -107
- /package/dist/{components/search/composables → composables/search}/types.d.ts +0 -0
- /package/dist/{components/search/composables → composables/search}/useFuzzySearch.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const FOURIER_FIELD_RENDER_WGSL = "\n// 0 chain \u00B7 1 trail \u00B7 2 head \u2014 a pipeline-overridable constant, three pipelines, one module.\noverride LAYER: i32 = 0;\n\n// THE SPLICE CONTRACT, honoured. OKLCH_MATRICES_WGSL states it at color.wgsl.ts:52-53 \u2014\n// \"PI must be in scope (the consumer defines it first, as the GLSL chunk requires)\" \u2014 and\n// spends it at :105 folding the OKLCh hue to [0, 2pi). This module splices that chunk\n// below and defined PI nowhere, so every CreateShaderModule on this source failed\n// validation with \"unresolved value 'PI'\" and the stage painted NOTHING. The two other\n// WGSL primaries carry the same line for the same reason (aurora.wgsl.ts:49,\n// metaball.wgsl.ts:53); this is that house idiom, not a local patch. The CLASS is gated\n// by tests/components/fourier-field/wgsl-splice-contract.test.ts, which resolves every\n// assembled module against the chunks it splices.\nconst PI: f32 = 3.141592653589793;\n\nconst TANGENT_EPS: f32 = 1e-4;\nconst SPEED_REF_HALFWIDTHS: f32 = 6.0;\n// The trail's taper: the mark keeps this fraction of its width at the oldest tail.\nconst TAIL_TAPER: f32 = 0.55;\n\nstruct RenderUniforms {\n // r0: (centerX, centerY, scale, aspect)\n r0: vec4<f32>,\n // r1: (markHalf, inkOffsetStrokes, scaffoldFrac, edgeMargin)\n r1: vec4<f32>,\n // r2: (peakAlpha, glow, squash, trailFadeExp)\n r2: vec4<f32>,\n // r3: (trailFloor, hueSweep, ringStrokeModel, showMachine)\n r3: vec4<f32>,\n // ink: (linear rgb, rainbowChain)\n ink: vec4<f32>,\n // head: (linear rgb, _pad)\n head: vec4<f32>,\n // ints: (sampleCount, lutSize, chainCount, _pad)\n ints: vec4<i32>,\n // the CPU-resolved linear-sRGB ramp \u2014 the length is the TS constant, not a second copy\n lut: array<vec4<f32>, 16>,\n};\n\n@group(0) @binding(0) var<uniform> u: RenderUniforms;\n@group(0) @binding(1) var<storage, read> curveSamples: array<vec4<f32>>;\n@group(0) @binding(2) var<storage, read> chainTips: array<vec4<f32>>;\n\n\nfn srgbToLinearCh(c: f32) -> f32 {\n if (c <= 0.04045) { return c / 12.92; }\n return pow((c + 0.055) / 1.055, 2.4);\n}\nfn srgbToLinear(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(srgbToLinearCh(c.r), srgbToLinearCh(c.g), srgbToLinearCh(c.b));\n}\n\nfn linearToSrgbCh(c: f32) -> f32 {\n if (c <= 0.0031308) { return c * 12.92; }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\nfn linearToSrgb(c: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(linearToSrgbCh(c.r), linearToSrgbCh(c.g), linearToSrgbCh(c.b));\n}\n\n// value.js LINEAR_SRGB_TO_LMS, row-major \u2192 WGSL columns (= the transpose).\nconst LINEAR_SRGB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 0.4122214708, 0.2119034982, 0.0883024619,\n 0.5363325363, 0.6806995451, 0.2817188376,\n 0.0514459929, 0.1073969566, 0.6299787005\n);\n\n// value.js srgbToOKLab's INLINE LMS\u2192OKLab coefficients, row-major \u2192 WGSL columns.\nconst LMS_TO_OKLAB: mat3x3<f32> = mat3x3<f32>(\n 0.2104542553, 1.9779984951, 0.0259040371,\n 0.7936177850, -2.4285922050, 0.7827717662,\n -0.0040720468, 0.4505937099, -0.8086757660\n);\n\n// value.js OKLAB_TO_LMS_COEFF, row-major \u2192 WGSL columns.\nconst OKLAB_TO_LMS: mat3x3<f32> = mat3x3<f32>(\n 1.0, 1.0, 1.0,\n 0.3963377774, -0.1055613458, -0.0894841775,\n 0.2158037573, -0.0638541728, -1.2914855480\n);\n\n// value.js LMS_TO_LINEAR_SRGB, row-major \u2192 WGSL columns.\nconst LMS_TO_LINEAR_SRGB: mat3x3<f32> = mat3x3<f32>(\n 4.0767416621, -1.2684380046, -0.0041960863,\n -3.3077115913, 2.6097574011, -0.7034186147,\n 0.2309699292, -0.3413193965, 1.7076147010\n);\n\nfn cbrt3(v: vec3<f32>) -> vec3<f32> {\n return sign(v) * pow(abs(v), vec3<f32>(1.0 / 3.0));\n}\n\n// Gamma sRGB \u2192 raw OKLab (L, a, b). Mirrors value.js srgbToOKLab.\nfn srgbToOklab(c: vec3<f32>) -> vec3<f32> {\n let lin = srgbToLinear(c);\n let lms = LINEAR_SRGB_TO_LMS * lin;\n return LMS_TO_OKLAB * cbrt3(lms);\n}\n\n// Raw OKLab (L, a, b) \u2192 linear sRGB. Mirrors value.js oklabToLinearSRGB.\nfn oklabToLinearSrgb(lab: vec3<f32>) -> vec3<f32> {\n let lms_ = OKLAB_TO_LMS * lab;\n let lms = lms_ * lms_ * lms_;\n return LMS_TO_LINEAR_SRGB * lms;\n}\n\n// OKLab \u2192 OKLCh: H in RADIANS, folded to [0, 2pi). Mirrors value.js rawOklabToOklch.\nfn oklabToOklch(lab: vec3<f32>) -> vec3<f32> {\n let C = length(lab.yz);\n var H = atan2(lab.z, lab.y);\n if (H < 0.0) { H = H + 2.0 * PI; }\n return vec3<f32>(lab.x, C, H);\n}\n\n// OKLCh (H radians) \u2192 OKLab. Mirrors value.js rawOklchToOklab.\nfn oklchToOklab(lch: vec3<f32>) -> vec3<f32> {\n return vec3<f32>(lch.x, lch.y * cos(lch.z), lch.y * sin(lch.z));\n}\n\n// Read the CPU-resolved ramp. No colour-space conversion happens here \u2014 the LUT already\n// carries the chroma floor and the gamut map.\nfn sampleRamp(t: f32) -> vec3<f32> {\n let n = u.ints.y;\n let ft = clamp(t, 0.0, 1.0) * f32(n - 1);\n let i0 = i32(floor(ft));\n let i1 = min(i0 + 1, n - 1);\n return mix(u.lut[i0].rgb, u.lut[i1].rgb, ft - f32(i0));\n}\n\n// The chain's hue sweep, taken ONCE PER INSTANCE in the vertex stage: the ramp entry for\n// this arm, rotated about the palette anchor by \u00B1hueSweep. Anchored warm, the sweep is\n// bounded by its own arithmetic \u2014 it cannot arrive anywhere the palette is not.\nfn chainTint(seg: f32) -> vec3<f32> {\n let base = sampleRamp(seg * 0.6);\n if (u.ink.w < 0.5) { return base; }\n let lab = LMS_TO_OKLAB * cbrt3(LINEAR_SRGB_TO_LMS * base);\n let lch = oklabToOklch(lab);\n let swept = vec3<f32>(lch.x, lch.y, lch.z + mix(-u.r3.y, u.r3.y, clamp(seg, 0.0, 1.0)));\n return oklabToLinearSrgb(oklchToOklab(swept));\n}\n\nfn segDist(p: vec2<f32>, a: vec2<f32>, b: vec2<f32>) -> f32 {\n let pa = p - a;\n let ba = b - a;\n let h = clamp(dot(pa, ba) / max(dot(ba, ba), 1e-8), 0.0, 1.0);\n return length(pa - ba * h);\n}\n\n// The head's travel frame + its volume-preserving anisotropic metric.\nstruct HeadFrame { T: vec2<f32>, sHat: f32, };\nfn headFrame(head: vec2<f32>, back: vec2<f32>, halfW: f32) -> HeadFrame {\n let d = head - back;\n let s = length(d);\n var out: HeadFrame;\n if (s <= TANGENT_EPS) {\n out.T = vec2<f32>(1.0, 0.0);\n out.sHat = 0.0;\n return out;\n }\n out.T = d / s;\n out.sHat = clamp(s / max(halfW * SPEED_REF_HALFWIDTHS, 1e-6), 0.0, 1.0);\n return out;\n}\n\nfn headAniso(p: vec2<f32>, head: vec2<f32>, fr: HeadFrame, k: f32) -> f32 {\n let g = 1.0 + k * fr.sHat;\n let n = vec2<f32>(-fr.T.y, fr.T.x);\n let rel = p - head;\n return length(vec2<f32>(dot(rel, fr.T) / g, dot(rel, n) * g));\n}\n\nfn quadCorner(vi: u32) -> vec2<f32> {\n var c = array<vec2<f32>, 6>(\n vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 0.0), vec2<f32>(0.0, 1.0),\n vec2<f32>(0.0, 1.0), vec2<f32>(1.0, 0.0), vec2<f32>(1.0, 1.0),\n );\n return c[vi];\n}\n\nstruct VSOut {\n @builtin(position) pos: vec4<f32>,\n @location(0) p: vec2<f32>,\n @location(1) a: vec2<f32>,\n @location(2) b: vec2<f32>,\n // (age, strokeHalf, drawRing)\n @location(3) seg: vec3<f32>,\n @location(4) @interpolate(flat) tint: vec3<f32>,\n};\n\n@vertex\nfn vs_main(@builtin(vertex_index) vi: u32, @builtin(instance_index) inst: u32) -> VSOut {\n let corner = quadCorner(vi);\n let center = u.r0.xy;\n let scale = max(u.r0.z, 1e-6);\n let aspect = max(u.r0.w, 1e-4);\n let markHalf = u.r1.x;\n let margin = u.r1.w;\n\n var a = vec2<f32>(0.0);\n var b = vec2<f32>(0.0);\n var strokeHalf = markHalf;\n var age = 0.0;\n var drawRing = 0.0;\n var tint = vec3<f32>(0.0);\n var isCapsule = true;\n var ext = markHalf;\n\n if (LAYER == 0) {\n // CHAIN \u2014 the AABB around this arm's own orbit (radius = |b \u2212 a| = |c_k|).\n a = chainTips[inst].xy;\n b = chainTips[inst + 1u].xy;\n let radius = length(b - a);\n // THE RING LAW, asked of the live stage: a circle narrower than its own line is a blob.\n if (2.0 * radius >= u.r3.z) { drawRing = 1.0; }\n strokeHalf = markHalf * u.r1.z;\n tint = chainTint(f32(inst) / max(f32(u.ints.z) - 1.0, 1.0));\n ext = radius + strokeHalf * 2.0;\n isCapsule = false;\n } else if (LAYER == 1) {\n // TRAIL \u2014 the curve capsule, padded for the ink's own offset.\n a = curveSamples[inst].xy;\n b = curveSamples[inst + 1u].xy;\n age = max(curveSamples[inst].z, curveSamples[inst + 1u].z);\n tint = sampleRamp(1.0 - age);\n ext = markHalf * (1.0 + 2.0 * max(u.r1.y, 0.0));\n isCapsule = true;\n } else {\n // HEAD \u2014 centred on the newest curve sample; the AABB is the halo.\n a = curveSamples[0].xy;\n b = curveSamples[1].xy;\n tint = u.head.rgb;\n ext = markHalf * 5.0;\n isCapsule = false;\n }\n ext = ext + margin;\n\n var pos: vec2<f32>;\n if (isCapsule) {\n let d = b - a;\n let len = length(d);\n var dir = vec2<f32>(1.0, 0.0);\n if (len > 1e-6) { dir = d / len; }\n let perp = vec2<f32>(-dir.y, dir.x);\n pos = mix(a - dir * ext, b + dir * ext, corner.x) + perp * (corner.y * 2.0 - 1.0) * ext;\n } else {\n pos = a + (corner * 2.0 - vec2<f32>(1.0)) * ext;\n }\n\n var out: VSOut;\n out.pos = vec4<f32>((pos.x - center.x) * scale / aspect, (pos.y - center.y) * scale, 0.0, 1.0);\n out.p = pos;\n out.a = a;\n out.b = b;\n out.seg = vec3<f32>(age, strokeHalf, drawRing);\n out.tint = tint;\n return out;\n}\n\n@fragment\nfn fs_main(in: VSOut) -> @location(0) vec4<f32> {\n let p = in.p;\n let aa = max(fwidth(p.x) + fwidth(p.y), 1e-5) * 0.75;\n let peak = u.r2.x;\n let glow = u.r2.y;\n let squash = u.r2.z;\n let fadeExp = u.r2.w;\n let trailFloor = u.r3.x;\n let markHalf = u.r1.x;\n let strokeHalf = in.seg.y;\n let age = in.seg.x;\n let a = in.a;\n let b = in.b;\n\n if (LAYER == 0) {\n // \u2500\u2500 THE MACHINE \u2014 ring (conditionally), arm, joint dot; one scaffold rung \u2500\u2500\n let radius = length(b - a);\n var m = 0.0;\n if (in.seg.z > 0.5) {\n let dRing = abs(length(p - a) - radius);\n m = max(m, 1.0 - smoothstep(strokeHalf, strokeHalf + aa, dRing));\n }\n m = max(m, 1.0 - smoothstep(strokeHalf, strokeHalf + aa, segDist(p, a, b)));\n // The joint dot is the mark's own diameter \u2014 the machine's one solid rung.\n m = max(m, 1.0 - smoothstep(markHalf, markHalf + aa, length(p - a)));\n let alpha = clamp(m, 0.0, 1.0) * peak;\n let rgb = clamp(linearToSrgb(in.tint), vec3<f32>(0.0), vec3<f32>(1.0));\n return vec4<f32>(rgb * alpha, alpha);\n } else if (LAYER == 1) {\n // \u2500\u2500 THE CURVE \u2014 ink under mark, composited at \u03B11, then ONE envelope \u2500\u2500\n let taper = TAIL_TAPER + (1.0 - TAIL_TAPER) * age;\n let half = markHalf * taper;\n // The ink rides THIS segment's own tangent, opposite the travel: the head runs from\n // b toward a, so the ink lands behind at (b \u2212 a).\n var dir = vec2<f32>(1.0, 0.0);\n let d = b - a;\n let len = length(d);\n if (len > 1e-6) { dir = d / len; }\n let off = dir * (markHalf * 2.0 * u.r1.y);\n\n let aMark = 1.0 - smoothstep(half, half + aa, segDist(p, a, b));\n let aInk = 1.0 - smoothstep(half, half + aa, segDist(p, a + off, b + off));\n\n let markRgb = clamp(linearToSrgb(in.tint), vec3<f32>(0.0), vec3<f32>(1.0));\n let inkRgb = clamp(linearToSrgb(u.ink.rgb), vec3<f32>(0.0), vec3<f32>(1.0));\n\n // Mark OVER ink, both fully opaque where they cover \u2014 the pair, then the envelope.\n let aPair = aMark + aInk * (1.0 - aMark);\n let rgbPair = markRgb * aMark + inkRgb * aInk * (1.0 - aMark);\n let env = peak * max(pow(max(age, 0.0), fadeExp), trailFloor);\n return vec4<f32>(rgbPair * env, aPair * env);\n } else {\n // \u2500\u2500 THE HEAD \u2014 palette-lifted core over its own halo. Light-led, never white. \u2500\u2500\n let fr = headFrame(a, b, markHalf);\n let dHead = headAniso(p, a, fr, squash);\n let coreR = markHalf * 1.5;\n let haloR = coreR * 3.0;\n let rgb = clamp(linearToSrgb(in.tint), vec3<f32>(0.0), vec3<f32>(1.0));\n let halo = (1.0 - smoothstep(0.0, haloR, dHead)) * glow;\n let core = (1.0 - smoothstep(coreR, coreR + aa, dHead)) * peak;\n let alpha = clamp(max(core, halo), 0.0, 1.0);\n return vec4<f32>(rgb * alpha, alpha);\n }\n}\n";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import { type GpuBackend, type RendererStatus } from "../../composables/glass/webgpu/useGpuSubstrate.js";
|
|
3
|
+
import type { OklchStop } from "../../composables/color/index.js";
|
|
4
|
+
import { type FourierFieldConfig } from "./constants.js";
|
|
5
|
+
import type { MintedSpectrum } from "./renderer/mint.js";
|
|
6
|
+
export interface UseFourierFieldOptions {
|
|
7
|
+
config: FourierFieldConfig;
|
|
8
|
+
/** The minted spectrum (identity-stable until the source or seed changes). */
|
|
9
|
+
getSpectrum: () => MintedSpectrum;
|
|
10
|
+
/** The resolved palette stops as OKLCh. */
|
|
11
|
+
getPalette: () => OklchStop[];
|
|
12
|
+
/**
|
|
13
|
+
* Whether the pointer drives the clock. ONE authority — the component's own
|
|
14
|
+
* `interactive` prop — read live rather than copied into the config.
|
|
15
|
+
*/
|
|
16
|
+
interactive: () => boolean;
|
|
17
|
+
/** Hold the clock at its current parameter and never advance. */
|
|
18
|
+
freeze?: () => boolean;
|
|
19
|
+
/** `"capture"` → renderAt-only (the deterministic capture path). Default `"live"`. */
|
|
20
|
+
mode?: "live" | "capture";
|
|
21
|
+
}
|
|
22
|
+
/** The handle a consumer wires its lifecycle and its transport against. */
|
|
23
|
+
export interface FourierFieldHandle {
|
|
24
|
+
/** The resolved backend. Always `"webgpu"` where the field paints at all. */
|
|
25
|
+
readonly backend: GpuBackend;
|
|
26
|
+
/** Park the loop (the pause seam). */
|
|
27
|
+
pause: () => void;
|
|
28
|
+
/** Re-arm the loop. */
|
|
29
|
+
resume: () => void;
|
|
30
|
+
/** Re-arm a parked loop on demand. */
|
|
31
|
+
wake: () => void;
|
|
32
|
+
/** The live `prefers-reduced-motion: reduce` state. */
|
|
33
|
+
readonly reducedMotion: boolean;
|
|
34
|
+
/** The current loop parameter `head_t ∈ [0,1)`. */
|
|
35
|
+
readonly headT: number;
|
|
36
|
+
/**
|
|
37
|
+
* The same parameter as a REACTIVE read, refreshed off the one clock at a rate a
|
|
38
|
+
* reader (or a screen reader) can follow. It is a sample of the frame loop, never a
|
|
39
|
+
* second one.
|
|
40
|
+
*/
|
|
41
|
+
readonly headTLive: Readonly<Ref<number>>;
|
|
42
|
+
readonly rendererStatus: Readonly<Ref<RendererStatus>>;
|
|
43
|
+
/** Scrub the clock directly. Takes no spring — a hand's position is not a physics event. */
|
|
44
|
+
setHeadT: (t: number) => void;
|
|
45
|
+
/** Inject one flick impulse, in turns per second. Capped and floored like any other. */
|
|
46
|
+
flick: (turnsPerSec: number) => void;
|
|
47
|
+
dispose: () => void;
|
|
48
|
+
}
|
|
49
|
+
export declare function useFourierField(canvasRef: Ref<HTMLCanvasElement | null>, options: UseFourierFieldOptions): FourierFieldHandle;
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HandShape } from "./stroke.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
shape?: HandShape;
|
|
4
|
+
color?: string;
|
|
5
|
+
weight?: number;
|
|
6
|
+
seed?: number;
|
|
7
|
+
draw?: boolean;
|
|
8
|
+
};
|
|
2
9
|
declare function play(): void;
|
|
3
|
-
declare var __VLS_1: {};
|
|
10
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
|
|
4
11
|
type __VLS_Slots = {} & {
|
|
5
12
|
default?: (props: typeof __VLS_1) => any;
|
|
13
|
+
} & {
|
|
14
|
+
default?: (props: typeof __VLS_3) => any;
|
|
15
|
+
} & {
|
|
16
|
+
default?: (props: typeof __VLS_5) => any;
|
|
6
17
|
};
|
|
7
|
-
declare const __VLS_base: import("vue").DefineComponent<
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
8
19
|
play: typeof play;
|
|
9
|
-
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<
|
|
20
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
10
21
|
color: string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
brush: import("./brush.js").BrushName | Partial<import("./brush.js").Brush>;
|
|
15
|
-
drawMs: number;
|
|
16
|
-
drawDelayMs: number;
|
|
17
|
-
appear: "mount" | "visible" | "manual";
|
|
18
|
-
boilFps: number;
|
|
19
|
-
boilFrames: number;
|
|
20
|
-
jagged: boolean;
|
|
22
|
+
shape: HandShape;
|
|
23
|
+
weight: number;
|
|
24
|
+
draw: boolean;
|
|
21
25
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
26
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
23
27
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HandMark public barrel.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* too — they are framework-free, directly usable in slides decks, D3 charts
|
|
6
|
-
* (call `shapeGeom`/`ellipsePoints` to ink a path), even canvas.
|
|
7
|
-
*
|
|
8
|
-
* The DEFAULT is `pen` (clean ink, grain:0 ⇒ no filter, zero extra dep). The
|
|
9
|
-
* `@mkbabb/pencil-boil` geometry is an OPTIONAL PEER. The perfect-freehand body
|
|
10
|
-
* is vendored; only `ribbon:'hull'` (the highlighter) touches that core
|
|
11
|
-
* (treeshaken otherwise).
|
|
12
|
-
*
|
|
13
|
-
* The editorial draw-on underline is
|
|
14
|
-
* `<HandMark shape="underline" animation="draw-on">`; the natural pencil-boil
|
|
15
|
-
* morphology is the `boil` brush.
|
|
2
|
+
* HandMark public barrel. The component is the surface; the pure functions ship with
|
|
3
|
+
* it so a caller who owns its own path can ink it with the same pen — `strokeRibbon`
|
|
4
|
+
* takes any polyline.
|
|
16
5
|
*/
|
|
17
6
|
export { default as HandMark } from "./HandMark.vue.js";
|
|
18
|
-
export {
|
|
19
|
-
export { shapeGeom, serialize, boilLines, type ShapeGeom } from "./geometry.js";
|
|
20
|
-
export { naturalUnderlinePoints } from "./noise.js";
|
|
21
|
-
export { VB_W, VB_H, UNDERLINE_GAP } from "./constants.js";
|
|
22
|
-
export { ink, type SVGFragment } from "./ink.js";
|
|
23
|
-
export { grainFilter, hasGrain } from "./texture.js";
|
|
24
|
-
export { getStroke, getStrokePoints, getSvgPathFromStroke, type StrokeOptions, type InputPoint, } from "./freehand.js";
|
|
25
|
-
export { useHandMark, normalizeProps, type UseHandMarkInput, type HandMarkCore, type BoilClock, } from "./composables/useHandMark.js";
|
|
26
|
-
export type { HandMarkProps, HandShape, HandAnimation, MarkBox, } from "./types.js";
|
|
7
|
+
export { SHAPES, handBand, handLine, handRing, markDuration, minJerk, serialize, strokeRibbon, type Frame, type HandShape, type Point, } from "./stroke.js";
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hand voice — one pen, five laws, no framework.
|
|
3
|
+
*
|
|
4
|
+
* Every function here is pure and framework-free: a caller with a rect and a font
|
|
5
|
+
* size gets the same geometry the component draws, in 1:1 CSS pixels. `strokeRibbon`
|
|
6
|
+
* takes ANY polyline, so a consumer that owns its own path (a chart leader, a route)
|
|
7
|
+
* inks it with this pen rather than re-deriving one.
|
|
8
|
+
*/
|
|
9
|
+
/** The four gestures, enumerated at runtime so a member change breaks compile-visibly. */
|
|
10
|
+
export declare const SHAPES: readonly ["underline", "strike", "circle", "highlight"];
|
|
11
|
+
export type HandShape = (typeof SHAPES)[number];
|
|
12
|
+
export interface Point {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
}
|
|
16
|
+
/** A measured text rect, in CSS px, already expressed in the frame that draws it. */
|
|
17
|
+
export interface Frame {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
}
|
|
23
|
+
export declare const CAP_HEIGHT = 0.7515;
|
|
24
|
+
/** L4 — x-height plus a 0.04em bleed at each end. */
|
|
25
|
+
export declare const BAND_HEIGHT: number;
|
|
26
|
+
/**
|
|
27
|
+
* The hand's outer envelope for the ring, in em: the declared vertical run 2b carried
|
|
28
|
+
* out by the largest radial creep and the largest wobble crest it admits.
|
|
29
|
+
*/
|
|
30
|
+
export declare const RING_ENVELOPE: number;
|
|
31
|
+
/** L1 — the clampless allometric nib. `weight` is a dimensionless multiple. */
|
|
32
|
+
export declare function nib(weight: number, fs: number): number;
|
|
33
|
+
/** L3 — floorless, ceilingless pace over the path length of ONE line rect. */
|
|
34
|
+
export declare function markDuration(length: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* The minimum-jerk draw profile as a CSS `linear()` easing.
|
|
37
|
+
*
|
|
38
|
+
* Every stop is emitted the same way — the PROFILE'S OWN VALUE at its own input — so
|
|
39
|
+
* `easing(0) = 0` and `easing(1) = 1` hold by construction: `10t³ − 15t⁴ + 6t⁵` is
|
|
40
|
+
* exactly 0 and exactly 1 at those ends. There is no endpoint special case, because an
|
|
41
|
+
* endpoint special case is a second expression for a quantity the loop already has,
|
|
42
|
+
* and the two can disagree. (They did: the branch it replaces emitted the loop INDEX,
|
|
43
|
+
* so `easing(1)` was `samples` and a draw animating `stroke-dashoffset` to 0 with
|
|
44
|
+
* `fill: both` came to rest at −23 dash periods — a mark inside its own gap.)
|
|
45
|
+
*/
|
|
46
|
+
export declare function minJerk(samples?: number): string;
|
|
47
|
+
export interface LineOpts {
|
|
48
|
+
fs: number;
|
|
49
|
+
seed: number;
|
|
50
|
+
kind: "underline" | "strike";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* L2 — the centreline. `d(u) = S·[4u(1−u) + B·4u(1−u)(1−2u)]` with |B| ≤ 0.4: both
|
|
54
|
+
* modes vanish at the endpoints and `d′` is a quadratic, so the commit carries at most
|
|
55
|
+
* two extrema in closed form for every seed. The lift-off hook is monotone in t over
|
|
56
|
+
* the last 6% and belongs to the release, never to the calm reading. Tilt is a shear,
|
|
57
|
+
* not a rotation, so the per-end reach stays exactly what the run-out declares.
|
|
58
|
+
*/
|
|
59
|
+
export declare function handLine(rect: Frame, o: LineOpts): Point[];
|
|
60
|
+
/** The ring's semi-axes: the exact curve through the padded box corner on BOTH axes. */
|
|
61
|
+
export declare function ringAxes(rect: Frame, fs: number): {
|
|
62
|
+
a: number;
|
|
63
|
+
b: number;
|
|
64
|
+
};
|
|
65
|
+
/** The horizontal overshoot a ring reserves with `padding-inline` on its wrapper. */
|
|
66
|
+
export declare function ringReserve(rect: Frame, fs: number): number;
|
|
67
|
+
/** L2-RING — an n=3 superellipse, overswept so the tail closes outside the head. */
|
|
68
|
+
export declare function handRing(rect: Frame, o: {
|
|
69
|
+
fs: number;
|
|
70
|
+
seed: number;
|
|
71
|
+
}): Point[];
|
|
72
|
+
/**
|
|
73
|
+
* L4 — the band: one chisel per line rect, raked at both ends, sagging like a swipe,
|
|
74
|
+
* overrunning its word by 1–2% a side. Opaque, and it carries no ink colour: the page's
|
|
75
|
+
* own foreground reads on it in both themes.
|
|
76
|
+
*/
|
|
77
|
+
export declare function handBand(rect: Frame, o: {
|
|
78
|
+
fs: number;
|
|
79
|
+
seed: number;
|
|
80
|
+
}): Point[];
|
|
81
|
+
/** `M x y L x y …` over an open polyline. */
|
|
82
|
+
export declare function serialize(points: Point[]): string;
|
|
83
|
+
/**
|
|
84
|
+
* The pen, over an arbitrary polyline: the ribbon is the outline of a stroke of
|
|
85
|
+
* maximum width `w`, emitted left side forward then right side back, so the minor axis
|
|
86
|
+
* at any sample is the nib the eye reads there.
|
|
87
|
+
*/
|
|
88
|
+
export declare function strokeRibbon(points: Point[], w: number): string;
|
|
89
|
+
/** A closed polygon — the band's own emission, which is a fill and not a stroke. */
|
|
90
|
+
export declare function fillPolygon(points: Point[]): string;
|
|
91
|
+
/** The default seed: the marked text, salted by the mark's position among its siblings. */
|
|
92
|
+
export declare function markSeed(text: string, instanceIndex: number): number;
|
|
@@ -7,7 +7,9 @@ declare const __VLS_base: import("vue").DefineComponent<LabeledSwitchProps, {},
|
|
|
7
7
|
"update:modelValue": (value: boolean) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<LabeledSwitchProps> & Readonly<{
|
|
9
9
|
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
|
|
10
|
-
}>, {
|
|
10
|
+
}>, {
|
|
11
|
+
modelValue: boolean;
|
|
12
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
13
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
12
14
|
declare const _default: typeof __VLS_export;
|
|
13
15
|
export default _default;
|
|
@@ -37,5 +37,5 @@ export type LabeledSliderProps = Omit<SliderProps, "class" | "modelValue"> & Lab
|
|
|
37
37
|
modelValue: number;
|
|
38
38
|
};
|
|
39
39
|
export type LabeledSwitchProps = Omit<SwitchProps, "class" | "modelValue"> & LabeledFieldCommonProps & {
|
|
40
|
-
modelValue
|
|
40
|
+
modelValue?: boolean;
|
|
41
41
|
};
|
|
@@ -37,9 +37,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Dropdo
|
|
|
37
37
|
}, string, import("vue").PublicProps, Readonly<DropdownMenuComponentProps> & Readonly<{
|
|
38
38
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
39
39
|
}>, {
|
|
40
|
+
modal: boolean;
|
|
40
41
|
open: boolean;
|
|
41
42
|
defaultOpen: boolean;
|
|
42
|
-
modal: boolean;
|
|
43
43
|
trigger: MenuTrigger;
|
|
44
44
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
45
45
|
default?: () => unknown;
|
|
@@ -10,11 +10,16 @@ export interface CoalesceMetricOptions {
|
|
|
10
10
|
/** `12400` → `12.4K`. `Intl.NumberFormat` compact notation, never a hand ladder. */
|
|
11
11
|
compact?: boolean;
|
|
12
12
|
locale?: string;
|
|
13
|
+
/** A positive number takes a leading `+`—the delta, whose number and sign carry
|
|
14
|
+
its polarity (O-32 §2.1). A negative already carries its sign; zero takes none. */
|
|
15
|
+
signed?: boolean;
|
|
13
16
|
}
|
|
14
17
|
/**
|
|
15
18
|
* The family's ONE data-shaping seam. Every readout in the family — the atom's
|
|
16
19
|
* value, its unit-bearing reading, its delta — passes through this and nothing
|
|
17
|
-
* else, which is why "what counts as empty" has exactly one answer.
|
|
20
|
+
* else, which is why "what counts as empty" has exactly one answer. [2026-09-22 ·
|
|
21
|
+
* O-32 §2.1: the delta's `+` is part of its reading, so `signed` is shaped here on
|
|
22
|
+
* both the compact and the plain path—never a prefix at the call site.]
|
|
18
23
|
*
|
|
19
24
|
* Finite numbers (including `0` and `-0`) and nonblank strings are readings.
|
|
20
25
|
* Blank strings, non-finite numbers, `null` and `undefined` take the placeholder.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer components{.metric{display: inline-grid;grid-template-columns: minmax(0,auto) minmax(0,1fr);min-inline-size: 0;align-items: baseline;color: var(--foreground);gap: 0.125rem 0.5rem;}.metric[data-posture="stacked"],.metric[data-posture="cell"]{grid-template-columns: minmax(0,1fr);}.metric__label,.metric__context{min-inline-size: 0;overflow-wrap: anywhere;color: var(--muted-foreground);}.metric__label{font-size: var(--control-label);font-weight: 550;letter-spacing: var(--type-tracking-wide);text-transform: uppercase;}.metric__context{grid-column: 1 / -1;font-size: var(--type-caption);line-height: 1.35;}.metric__reading{display: inline-flex;min-inline-size: 0;align-items: baseline;gap: 0.3em;}.metric__value{min-inline-size: 3ch;overflow-wrap: anywhere;font-family: var(--font-mono);font-size: var(--type-prose);font-weight: 650;font-variant-numeric: tabular-nums lining-nums;letter-spacing: var(--type-tracking-tight);line-height: 1;}.metric__unit{flex: none;color: var(--muted-foreground);font-family: var(--font-mono);font-size: var(--type-caption);line-height: 1;}.metric__delta{flex: none;color: var(--
|
|
1
|
+
@layer components{.metric{display: inline-grid;grid-template-columns: minmax(0,auto) minmax(0,1fr);min-inline-size: 0;align-items: baseline;color: var(--foreground);gap: 0.125rem 0.5rem;}.metric[data-posture="stacked"],.metric[data-posture="cell"]{grid-template-columns: minmax(0,1fr);}.metric__label,.metric__context{min-inline-size: 0;overflow-wrap: anywhere;color: var(--muted-foreground);}.metric__label{font-size: var(--control-label);font-weight: 550;letter-spacing: var(--type-tracking-wide);text-transform: uppercase;}.metric__context{grid-column: 1 / -1;font-size: var(--type-caption);line-height: 1.35;}.metric__reading{display: inline-flex;min-inline-size: 0;align-items: baseline;gap: 0.3em;}.metric__value{min-inline-size: 3ch;overflow-wrap: anywhere;font-family: var(--font-mono);font-size: var(--type-prose);font-weight: 650;font-variant-numeric: tabular-nums lining-nums;letter-spacing: var(--type-tracking-tight);line-height: 1;}.metric__unit{flex: none;color: var(--muted-foreground);font-family: var(--font-mono);font-size: var(--type-caption);line-height: 1;}.metric__delta{flex: none;color: var(--foreground);font-family: var(--font-mono);font-size: var(--type-caption);font-variant-numeric: tabular-nums lining-nums;line-height: 1;}.metric[data-size="sm"] .metric__value{font-size: var(--type-small);}.metric[data-size="lg"] .metric__value,.metric[data-posture="cell"] .metric__value{font-size: var(--type-title);}.metric[data-size="xl"] .metric__value{font-size: var(--type-display-3);}.metric[data-empty] .metric__value{color: var(--muted-foreground);}.metric[data-loading] .metric__value{color: transparent;border-radius: var(--radius-sm);background: color-mix( in oklab,var(--foreground) calc(var(--ink-seam) * 100%),transparent );}.metric[data-loading] .metric__unit,.metric[data-loading] .metric__delta{visibility: hidden;}.metric[data-posture="cell"]{display: grid;align-content: start;padding: clamp(0.75rem,2cqi,1rem);border: 1px solid oklch(from var(--foreground) l c h / var(--ink-edge));border-radius: var(--radius-card);background: var(--glass-plate-wash);gap: 0.375rem;}.metric-stack{container: metric-stack / inline-size;display: grid;grid-template-columns: minmax(7rem,1fr) minmax(0,auto);inline-size: 100%;gap: 0.75rem 1.25rem;}.metric-stack[data-density="compact"]{gap: 0.5rem 1rem;}.metric-row{display: grid;grid-column: 1 / -1;grid-template-columns: subgrid;align-items: baseline;padding-block: 0.25rem;}.metric-row > .metric[data-posture="row"]{display: grid;grid-column: 1 / -1;grid-template-columns: subgrid;}.metric[data-posture="row"] > .metric__reading{justify-self: end;}.metric[data-posture="row"] > .metric__context{grid-column: 1;}@container metric-stack (max-width: 24rem){.metric-row,.metric-row > .metric[data-posture="row"]{grid-template-columns: minmax(0,1fr);gap: 0.25rem;}.metric[data-posture="row"] > .metric__reading{justify-self: start;}}}
|
|
@@ -46,9 +46,9 @@ declare const __VLS_base: import("vue").DefineComponent<PopoverProps, {}, {}, {}
|
|
|
46
46
|
}, string, import("vue").PublicProps, Readonly<PopoverProps> & Readonly<{
|
|
47
47
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
48
48
|
}>, {
|
|
49
|
+
modal: boolean;
|
|
49
50
|
open: boolean;
|
|
50
51
|
defaultOpen: boolean;
|
|
51
|
-
modal: boolean;
|
|
52
52
|
trigger: PopoverTriggerMode;
|
|
53
53
|
openDelay: number;
|
|
54
54
|
closeDelay: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.scroll-progress-rim{--scroll-progress-rim-width: 3px;--scroll-progress-rim-inset: 2px;--scroll-progress-rim-margin: 8px;position: absolute;inset: 0;z-index: 2;isolation: isolate;pointer-events: none;}.scroll-progress-rim__track{position: absolute;border-radius: var(--radius-pill);background: var(--track-well-recess);}.scroll-progress-rim[data-orientation="horizontal"] .scroll-progress-rim__track{inset-inline: var(--scroll-progress-rim-margin);inset-block-end: var(--scroll-progress-rim-inset);block-size: var(--scroll-progress-rim-width);}.scroll-progress-rim[data-orientation="vertical"] .scroll-progress-rim__track{inset-block: var(--scroll-progress-rim-margin);inset-inline-end: var(--scroll-progress-rim-inset);inline-size: var(--scroll-progress-rim-width);}.scroll-progress-rim__fill{position: absolute;inset: 0;border-radius: inherit;background: var(--scroll-progress-rim-spectrum,var(--rainbow-violet));clip-path: inset(0 100% 0 0 round var(--radius-pill));transition: clip-path var(--spring-dock-duration) var(--spring-dock);}.scroll-progress-rim[data-orientation="horizontal"] .scroll-progress-rim__fill{clip-path: inset( 0 calc(100% - var(--scroll-progress-rim-fill,0%)) 0 0 round var(--radius-pill) );}.scroll-progress-rim[data-orientation="horizontal"]:dir(rtl) .scroll-progress-rim__fill{clip-path: inset( 0 0 0 calc(100% - var(--scroll-progress-rim-fill,0%)) round var(--radius-pill) );}.scroll-progress-rim[data-orientation="vertical"] .scroll-progress-rim__fill{clip-path: inset( calc(100% - var(--scroll-progress-rim-fill,0%)) 0 0 0 round var(--radius-pill) );}@media (prefers-reduced-motion: reduce){.scroll-progress-rim__fill{transition: none;}}
|
|
1
|
+
@layer components{.scroll-progress-rim{--scroll-progress-rim-width: 3px;--scroll-progress-rim-inset: 2px;--scroll-progress-rim-margin: 8px;position: absolute;inset: 0;z-index: 2;isolation: isolate;pointer-events: none;}.scroll-progress-rim__track{position: absolute;border-radius: var(--radius-pill);background: var(--track-well-recess);}.scroll-progress-rim[data-orientation="horizontal"] .scroll-progress-rim__track{inset-inline: var(--scroll-progress-rim-margin);inset-block-end: var(--scroll-progress-rim-inset);block-size: var(--scroll-progress-rim-width);}.scroll-progress-rim[data-orientation="vertical"] .scroll-progress-rim__track{inset-block: var(--scroll-progress-rim-margin);inset-inline-end: var(--scroll-progress-rim-inset);inline-size: var(--scroll-progress-rim-width);}.scroll-progress-rim__fill{position: absolute;inset: 0;border-radius: inherit;background: var(--scroll-progress-rim-spectrum,var(--rainbow-violet));clip-path: inset(0 100% 0 0 round var(--radius-pill));transition: clip-path var(--spring-dock-duration) var(--spring-dock);}.scroll-progress-rim[data-orientation="horizontal"] .scroll-progress-rim__fill{clip-path: inset( 0 calc(100% - var(--scroll-progress-rim-fill,0%)) 0 0 round var(--radius-pill) );}.scroll-progress-rim[data-orientation="horizontal"]:dir(rtl) .scroll-progress-rim__fill{clip-path: inset( 0 0 0 calc(100% - var(--scroll-progress-rim-fill,0%)) round var(--radius-pill) );}.scroll-progress-rim[data-orientation="vertical"] .scroll-progress-rim__fill{clip-path: inset( calc(100% - var(--scroll-progress-rim-fill,0%)) 0 0 0 round var(--radius-pill) );}@media (prefers-reduced-motion: reduce){.scroll-progress-rim__fill{transition: none;}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:where([data-slot="sheet-content"]){position: fixed;z-index: var(--z-modal);}@property --detent-t{syntax: "<number>";inherits: false;initial-value: 0;}:where([data-slot="sheet-content"][data-detents]){--sheet-seam-width: 1px;contain: layout paint;display: grid;grid-template-rows: auto minmax(0,1fr);}:where([data-slot="sheet-content"][data-modal="false"]){z-index: calc(var(--z-dock) - 1);}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-detent-handle"],[data-slot="sheet-content"][data-detents] [data-slot="dialog-header"] ){touch-action: none;}:where([data-slot="sheet-content"][data-dragging]){cursor: grabbing;user-select: none;}:where([data-slot="sheet-content"] > [data-slot="sheet-content-region"]){display: grid;align-content: start;gap: var(--space-body);}:where([data-slot="sheet-content"][data-scroll] > [data-slot="sheet-content-region"]){min-block-size: 0;max-block-size: calc(100dvh - 2 * var(--space-family));overflow-y: auto;}:where( [data-slot="sheet-content"][data-side="left"]:not([data-detents]) > [data-slot="sheet-content-region"],[data-slot="sheet-content"][data-side="right"]:not([data-detents]) > [data-slot="sheet-content-region"] ){display: flex;flex-direction: column;block-size: 100%;min-block-size: 0;}:where( [data-slot="sheet-content"][data-side="left"] > [data-slot="sheet-content-region"] > :only-child,[data-slot="sheet-content"][data-side="right"] > [data-slot="sheet-content-region"] > :only-child ){min-block-size: 0;}:where([data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"]){display: grid;grid-template-rows: minmax(0,auto) minmax(1lh,1fr) auto;align-content: end;min-block-size: 0;gap: var(--space-body);}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"] > :not([data-slot="dialog-header"]):not([data-slot="dialog-footer"]) ){min-block-size: 0;overflow-y: auto;overscroll-behavior: contain;}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"] > [data-slot="dialog-header"] ){overflow: hidden;padding-block-end: var(--space-body);border-block-end: var(--sheet-seam-width) solid oklch(from var(--glass-veil-ink) l c h / calc(var(--glass-veil-step) * 2));}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"] > [data-slot="dialog-footer"] ){padding-block-start: var(--space-body);border-block-start: var(--sheet-seam-width) solid oklch(from var(--glass-veil-ink) l c h / calc(var(--glass-veil-step) * 2));}:where([data-slot="sheet-content"]:not([data-detents]):has([data-slot="dialog-close"])) :where([data-slot="dialog-header"]){padding-inline-end: calc(var(--touch-target) + var(--space-atom));}:where([data-slot="sheet-content"][data-detents] > [data-slot="sheet-detent-handle"]){display: flex;align-items: center;justify-content: center;min-block-size: var(--touch-target);cursor: grab;}:where([data-slot="sheet-detent-handle"] > [data-slot="sheet-detent-grip"]){display: block;inline-size: calc( var(--space-section) + var(--space-family) * clamp(0,var(--detent-t),1) );block-size: calc(var(--space-atom) / 2);border-radius: var(--radius-pill);background-color: currentcolor;opacity: calc(0.45 + ((0.85 - 0.45) / 2) * clamp(0,var(--detent-t),1));transition: opacity var(--spring-dock-duration) var(--spring-dock),inline-size var(--spring-dock-duration) var(--spring-dock);}@media (hover: hover){:where([data-slot="sheet-detent-handle"]:hover > [data-slot="sheet-detent-grip"]){opacity: 0.85;}}:where([data-slot="sheet-detent-handle"]:focus-visible){outline: none;}:where( [data-slot="sheet-detent-handle"]:focus-visible > [data-slot="sheet-detent-grip"],[data-slot="sheet-content"][data-dragging] [data-slot="sheet-detent-grip"] ){opacity: 0.85;}:where( [data-slot="sheet-detent-handle"]:focus-visible > [data-slot="sheet-detent-grip"] ){box-shadow: 0 0 0 3px var(--focus-ring-color);}@media (prefers-reduced-motion: reduce){:where([data-slot="sheet-detent-grip"]){transition: none;}}:where([data-slot="sheet-content"]){anchor-name: --glass-sheet-edge;}:where([data-slot="sheet-content"][data-surface="glass"]){-webkit-backdrop-filter: none;backdrop-filter: none;}:where([data-slot="glass-graded-halo"]){position: fixed;position-anchor: --glass-sheet-edge;top: anchor(top);right: anchor(right);bottom: anchor(bottom);left: anchor(left);z-index: calc(var(--z-modal) - 1);pointer-events: none;background: linear-gradient( var(--sheet-edge-direction),color-mix(in oklab,var(--glass-plate-overlay) 10%,transparent) 0,color-mix(in oklab,var(--glass-plate-overlay) 16%,transparent) 40px,color-mix(in oklab,var(--glass-plate-overlay) 34%,transparent) 120px,color-mix(in oklab,var(--glass-plate-overlay) 34%,transparent) 100% );-webkit-backdrop-filter: blur(calc(34px * var(--glass-level))) saturate(var(--glass-saturate));backdrop-filter: blur(calc(34px * var(--glass-level))) saturate(var(--glass-saturate));mask-image: linear-gradient( var(--sheet-edge-direction),rgb(0 0 0 / 0.325) 0,rgb(0 0 0 / 0.45) 40px,black 120px,black 100% );}:where([data-slot="glass-graded-halo"][data-modal="false"]){z-index: calc(var(--z-dock) - 2);}:where([data-slot="glass-graded-halo"][data-side="top"]){--sheet-edge-direction: to top;border-end-start-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-side="bottom"]){--sheet-edge-direction: to bottom;border-start-start-radius: var(--radius-3xl);border-start-end-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-side="left"]){--sheet-edge-direction: to left;border-start-end-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-side="right"]){--sheet-edge-direction: to right;border-start-start-radius: var(--radius-3xl);border-end-start-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-detents][data-side="bottom"]){height: 100dvh;bottom: auto;}:where([data-slot="glass-graded-halo"][data-detents][data-side="top"]){height: 100dvh;top: auto;}:where([data-slot="glass-graded-halo"][data-detents][data-side="left"]){width: 100dvw;left: auto;}:where([data-slot="glass-graded-halo"][data-detents][data-side="right"]){width: 100dvw;right: auto;}@media (prefers-reduced-transparency: reduce),(forced-colors: active){:where([data-slot="glass-graded-halo"]){display: none;}}:where([data-slot="sheet-content"][data-side="top"]){left: 0;right: 0;top: 0;}:where([data-slot="sheet-content"][data-side="bottom"]){left: 0;right: 0;bottom: 0;}:where([data-slot="sheet-content"][data-side="left"]){top: 0;bottom: 0;left: 0;height: 100%;width: 75%;}:where([data-slot="sheet-content"][data-side="right"]){top: 0;bottom: 0;right: 0;height: 100%;width: 75%;}@media (min-width: 40rem){:where([data-slot="sheet-content"][data-side="left"]),:where([data-slot="sheet-content"][data-side="right"]){max-width: 24rem;}}:where( [data-slot="sheet-content"][data-detents][data-side="bottom"],[data-slot="sheet-content"][data-detents][data-side="top"] ){block-size: calc(clamp(0,var(--detent-t),1) * 100dvh);min-block-size: calc( 2 * var(--space-family) + var(--sheet-seam-width) + var(--touch-target) + 2 * var(--space-body) + var(--space-body) + var(--sheet-seam-width) + 1lh + var(--space-body) + var(--sheet-seam-width) + var(--touch-target) );max-block-size: 100dvh;}:where( [data-slot="sheet-content"][data-detents][data-side="left"],[data-slot="sheet-content"][data-detents][data-side="right"] ){width: calc(clamp(0,var(--detent-t),1) * 100dvw);max-width: 100dvw;height: 100%;}:where([data-slot="sheet-content"]){padding-inline: var(--space-family);padding-block: var(--space-family);}:where([data-slot="sheet-content"][data-side="top"]){border-end-start-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="sheet-content"][data-side="bottom"]){border-start-start-radius: var(--radius-3xl);border-start-end-radius: var(--radius-3xl);}:where([data-slot="sheet-content"][data-side="left"]){border-start-end-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="sheet-content"][data-side="right"]){border-start-start-radius: var(--radius-3xl);border-end-start-radius: var(--radius-3xl);}
|
|
1
|
+
@layer components{:where([data-slot="sheet-content"]){position: fixed;z-index: var(--z-modal);}}@property --detent-t{syntax: "<number>";inherits: false;initial-value: 0;}@layer components{:where([data-slot="sheet-content"][data-detents]){--sheet-seam-width: 1px;contain: layout paint;display: grid;grid-template-rows: auto minmax(0,1fr);}:where([data-slot="sheet-content"][data-modal="false"]){z-index: calc(var(--z-dock) - 1);}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-detent-handle"],[data-slot="sheet-content"][data-detents] [data-slot="dialog-header"] ){touch-action: none;}:where([data-slot="sheet-content"][data-dragging]){cursor: grabbing;user-select: none;}:where([data-slot="sheet-content"] > [data-slot="sheet-content-region"]){display: grid;align-content: start;gap: var(--space-body);}:where([data-slot="sheet-content"][data-scroll] > [data-slot="sheet-content-region"]){min-block-size: 0;max-block-size: calc(100dvh - 2 * var(--space-family));overflow-y: auto;}:where( [data-slot="sheet-content"][data-side="left"]:not([data-detents]) > [data-slot="sheet-content-region"],[data-slot="sheet-content"][data-side="right"]:not([data-detents]) > [data-slot="sheet-content-region"] ){display: flex;flex-direction: column;block-size: 100%;min-block-size: 0;}:where( [data-slot="sheet-content"][data-side="left"] > [data-slot="sheet-content-region"] > :only-child,[data-slot="sheet-content"][data-side="right"] > [data-slot="sheet-content-region"] > :only-child ){min-block-size: 0;}:where([data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"]){display: grid;grid-template-rows: minmax(0,auto) minmax(1lh,1fr) auto;align-content: end;min-block-size: 0;gap: var(--space-body);}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"] > :not([data-slot="dialog-header"]):not([data-slot="dialog-footer"]) ){min-block-size: 0;overflow-y: auto;overscroll-behavior: contain;}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"] > [data-slot="dialog-header"] ){overflow: hidden;padding-block-end: var(--space-body);border-block-end: var(--sheet-seam-width) solid oklch(from var(--glass-veil-ink) l c h / calc(var(--glass-veil-step) * 2));}:where( [data-slot="sheet-content"][data-detents] > [data-slot="sheet-content-region"] > [data-slot="dialog-footer"] ){padding-block-start: var(--space-body);border-block-start: var(--sheet-seam-width) solid oklch(from var(--glass-veil-ink) l c h / calc(var(--glass-veil-step) * 2));}:where([data-slot="sheet-content"]:not([data-detents]):has([data-slot="dialog-close"])) :where([data-slot="dialog-header"]){padding-inline-end: calc(var(--touch-target) + var(--space-atom));}:where([data-slot="sheet-content"][data-detents] > [data-slot="sheet-detent-handle"]){display: flex;align-items: center;justify-content: center;min-block-size: var(--touch-target);cursor: grab;}:where([data-slot="sheet-detent-handle"] > [data-slot="sheet-detent-grip"]){display: block;inline-size: calc( var(--space-section) + var(--space-family) * clamp(0,var(--detent-t),1) );block-size: calc(var(--space-atom) / 2);border-radius: var(--radius-pill);background-color: currentcolor;opacity: calc(0.45 + ((0.85 - 0.45) / 2) * clamp(0,var(--detent-t),1));transition: opacity var(--spring-dock-duration) var(--spring-dock),inline-size var(--spring-dock-duration) var(--spring-dock);}@media (hover: hover){:where([data-slot="sheet-detent-handle"]:hover > [data-slot="sheet-detent-grip"]){opacity: 0.85;}}:where([data-slot="sheet-detent-handle"]:focus-visible){outline: none;}:where( [data-slot="sheet-detent-handle"]:focus-visible > [data-slot="sheet-detent-grip"],[data-slot="sheet-content"][data-dragging] [data-slot="sheet-detent-grip"] ){opacity: 0.85;}:where( [data-slot="sheet-detent-handle"]:focus-visible > [data-slot="sheet-detent-grip"] ){box-shadow: 0 0 0 3px var(--focus-ring-color);}@media (prefers-reduced-motion: reduce){:where([data-slot="sheet-detent-grip"]){transition: none;}}:where([data-slot="sheet-content"]){anchor-name: --glass-sheet-edge;}:where([data-slot="sheet-content"][data-surface="glass"]){-webkit-backdrop-filter: none;backdrop-filter: none;}:where([data-slot="glass-graded-halo"]){position: fixed;position-anchor: --glass-sheet-edge;top: anchor(top);right: anchor(right);bottom: anchor(bottom);left: anchor(left);z-index: calc(var(--z-modal) - 1);pointer-events: none;background: linear-gradient( var(--sheet-edge-direction),color-mix(in oklab,var(--glass-plate-overlay) 10%,transparent) 0,color-mix(in oklab,var(--glass-plate-overlay) 16%,transparent) 40px,color-mix(in oklab,var(--glass-plate-overlay) 34%,transparent) 120px,color-mix(in oklab,var(--glass-plate-overlay) 34%,transparent) 100% );-webkit-backdrop-filter: blur(calc(34px * var(--glass-level))) saturate(var(--glass-saturate));backdrop-filter: blur(calc(34px * var(--glass-level))) saturate(var(--glass-saturate));mask-image: linear-gradient( var(--sheet-edge-direction),rgb(0 0 0 / 0.325) 0,rgb(0 0 0 / 0.45) 40px,black 120px,black 100% );}:where([data-slot="glass-graded-halo"][data-modal="false"]){z-index: calc(var(--z-dock) - 2);}:where([data-slot="glass-graded-halo"][data-side="top"]){--sheet-edge-direction: to top;border-end-start-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-side="bottom"]){--sheet-edge-direction: to bottom;border-start-start-radius: var(--radius-3xl);border-start-end-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-side="left"]){--sheet-edge-direction: to left;border-start-end-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-side="right"]){--sheet-edge-direction: to right;border-start-start-radius: var(--radius-3xl);border-end-start-radius: var(--radius-3xl);}:where([data-slot="glass-graded-halo"][data-detents][data-side="bottom"]){height: 100dvh;bottom: auto;}:where([data-slot="glass-graded-halo"][data-detents][data-side="top"]){height: 100dvh;top: auto;}:where([data-slot="glass-graded-halo"][data-detents][data-side="left"]){width: 100dvw;left: auto;}:where([data-slot="glass-graded-halo"][data-detents][data-side="right"]){width: 100dvw;right: auto;}@media (prefers-reduced-transparency: reduce),(forced-colors: active){:where([data-slot="glass-graded-halo"]){display: none;}}:where([data-slot="sheet-content"][data-side="top"]){left: 0;right: 0;top: 0;}:where([data-slot="sheet-content"][data-side="bottom"]){left: 0;right: 0;bottom: 0;}:where([data-slot="sheet-content"][data-side="left"]){top: 0;bottom: 0;left: 0;height: 100%;width: 75%;}:where([data-slot="sheet-content"][data-side="right"]){top: 0;bottom: 0;right: 0;height: 100%;width: 75%;}@media (min-width: 40rem){:where([data-slot="sheet-content"][data-side="left"]),:where([data-slot="sheet-content"][data-side="right"]){max-width: 24rem;}}:where( [data-slot="sheet-content"][data-detents][data-side="bottom"],[data-slot="sheet-content"][data-detents][data-side="top"] ){block-size: calc(clamp(0,var(--detent-t),1) * 100dvh);min-block-size: calc( 2 * var(--space-family) + var(--sheet-seam-width) + var(--touch-target) + 2 * var(--space-body) + var(--space-body) + var(--sheet-seam-width) + 1lh + var(--space-body) + var(--sheet-seam-width) + var(--touch-target) );max-block-size: 100dvh;}:where( [data-slot="sheet-content"][data-detents][data-side="left"],[data-slot="sheet-content"][data-detents][data-side="right"] ){width: calc(clamp(0,var(--detent-t),1) * 100dvw);max-width: 100dvw;height: 100%;}:where([data-slot="sheet-content"]){padding-inline: var(--space-family);padding-block: var(--space-family);}:where([data-slot="sheet-content"][data-side="top"]){border-end-start-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="sheet-content"][data-side="bottom"]){border-start-start-radius: var(--radius-3xl);border-start-end-radius: var(--radius-3xl);}:where([data-slot="sheet-content"][data-side="left"]){border-start-end-radius: var(--radius-3xl);border-end-end-radius: var(--radius-3xl);}:where([data-slot="sheet-content"][data-side="right"]){border-start-start-radius: var(--radius-3xl);border-end-start-radius: var(--radius-3xl);}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@property --glass-slider-track-background{syntax: "*";inherits: true;}.glass-slider{--slider-range-origin: left center;position: relative;display: flex;inline-size: 100%;align-items: center;touch-action: none;user-select: none;transition: color var(--duration-fast) var(--ease-standard);}.glass-slider[data-inverted],.glass-slider:dir(rtl){--slider-range-origin: right center;}.glass-slider:dir(rtl)[data-inverted]{--slider-range-origin: left center;}.glass-slider[data-size="sm"]{--slider-track-height:
|
|
1
|
+
@property --glass-slider-track-background{syntax: "*";inherits: true;}.glass-slider{--slider-range-origin: left center;position: relative;display: flex;inline-size: 100%;align-items: center;touch-action: none;user-select: none;transition: color var(--duration-fast) var(--ease-standard);}.glass-slider{cursor: grab;}.glass-slider[data-held],.glass-slider:active{cursor: grabbing;}.glass-slider[data-disabled]{cursor: not-allowed;}.glass-slider[data-inverted],.glass-slider:dir(rtl){--slider-range-origin: right center;}.glass-slider:dir(rtl)[data-inverted]{--slider-range-origin: left center;}.glass-slider[data-size="sm"]{--slider-track-height: var(--slider-track-height-sm);--slider-thumb-size: min(var(--slider-thumb-size-sm),var(--slider-track-height-sm));}.glass-slider[data-size="md"]{--slider-track-height: var(--slider-track-height-md);--slider-thumb-size: min(var(--slider-thumb-size-md),var(--slider-track-height-md));}.glass-slider[data-size="lg"]{--slider-track-height: var(--slider-track-height-lg);--slider-thumb-size: min(var(--slider-thumb-size-lg),var(--slider-track-height-lg));}.glass-slider[data-variant="spectrum"]{--slider-track-height: calc(var(--slider-thumb-size,1rem) * 1.5);}@media (pointer: coarse){.glass-slider{--slider-target-floor: max( var(--slider-track-height,0.375rem),var(--slider-touch-target,1.5rem) );min-block-size: var(--slider-target-floor);min-inline-size: var(--slider-target-floor);}}.slider-track{width: 100%;flex-grow: 1;height: var(--slider-track-height,0.375rem);background: var(--glass-slider-track-background,var(--muted-medium));transition: background var(--duration-fast) var(--ease-standard),border-color var(--duration-fast) var(--ease-standard);}.slider-range{position: absolute;height: 100%;--liquid-fill-tint: var(--slider-range-bg,var(--glass-capsule-warm));}.slider-thumb{display: block;width: 0;height: var(--slider-track-height,0.375rem);opacity: 0;background: transparent;border: none;box-shadow: none;transition: transform var(--spring-press-duration) var(--spring-press);}.glass-slider:not([data-variant="spectrum"]):hover .slider-range{--liquid-fill-strength: 100%;}.glass-slider:not([data-variant="spectrum"]):has(:focus-visible) .slider-track{box-shadow: var(--focus-ring-shadow);}.glass-slider[data-held] .slider-range,.glass-slider:active .slider-range{--smear: calc(var(--atom-drag-v,0) * var(--motion-weight,0.618));transform: scale( calc(1.02 + 0.16 * var(--smear)),calc(0.94 - 0.06 * var(--smear)) );transform-origin: var(--slider-range-origin);transition: transform var(--spring-press-duration) var(--spring-press);}.glass-slider:not(:active):not([data-held]) .slider-range{transition: transform var(--duration-normal) var(--ease-cartoon-punch),--glass-veil-rung var(--spring-dock-duration) var(--ease-standard),box-shadow var(--duration-fast) var(--ease-standard);}@media (prefers-reduced-motion: reduce){.glass-slider:active .slider-range,.glass-slider[data-held] .slider-range{--motion-weight: 0;transform: scale(1,0.97);}}.glass-slider[data-disabled] .slider-range{opacity: var(--opacity-disabled);}.glass-slider[data-invalid] .slider-track{box-shadow: inset 0 0 0 1px var(--destructive);}.glass-slider[data-invalid]:has(:focus-visible) .slider-track{box-shadow: var(--focus-ring-shadow),inset 0 0 0 1px var(--destructive);}.glass-slider[data-variant="spectrum"][data-held] .slider-thumb{box-shadow: 0 0 0 6px var(--surface-tint-15),var(--shadow-sm);}.glass-slider[data-variant="spectrum"] .slider-track{background: var(--glass-slider-track-background,var(--secondary));}.glass-slider[data-variant="spectrum"] .slider-thumb{width: calc(var(--slider-thumb-size,1rem) * 0.75);height: var(--slider-track-height,0.375rem);opacity: 1;background: transparent;border: 2px solid var(--background);border-radius: calc(var(--slider-thumb-size,1rem) * 0.4);box-shadow: var(--shadow-sm);}@supports (corner-shape: superellipse(2)){.glass-slider[data-variant="spectrum"] .slider-thumb{corner-shape: var(--corner-shape-thumb);}}.glass-slider[data-variant="spectrum"]:hover .slider-thumb{box-shadow: 0 0 0 4px var(--surface-tint-8),var(--shadow-sm);}.glass-slider[data-variant="spectrum"] .slider-thumb:focus-visible{outline: none;box-shadow: var(--focus-ring-shadow),var(--shadow-sm);}.glass-slider[data-orientation="vertical"]{flex-direction: column;width: var(--slider-track-height,0.375rem);height: 12rem;}.glass-slider[data-orientation="vertical"] .slider-track{width: var(--slider-track-height,0.375rem);height: 100%;}.glass-slider[data-orientation="vertical"] .slider-range{width: 100%;height: auto;}.glass-slider[data-orientation="vertical"]:active .slider-range,.glass-slider[data-orientation="vertical"][data-held] .slider-range{--smear: calc(var(--atom-drag-v,0) * var(--motion-weight,0.618));transform: scale( calc(0.94 - 0.06 * var(--smear)),calc(1.02 + 0.16 * var(--smear)) );transform-origin: center bottom;}.glass-slider[data-orientation="vertical"][data-inverted] .slider-range{transform-origin: center top;}.glass-slider[data-orientation="vertical"][data-variant="spectrum"] .slider-thumb{width: var(--slider-track-height,0.375rem);height: calc(var(--slider-thumb-size,1rem) * 0.75);}@media (prefers-reduced-motion: reduce){.glass-slider[data-orientation="vertical"]:active .slider-range,.glass-slider[data-orientation="vertical"][data-held] .slider-range{transform: scale(0.97,1);}}@media (forced-colors: active){.slider-track{background: Canvas;border: 1px solid CanvasText;}.slider-range{background: Highlight;}.glass-slider[data-variant="spectrum"] .slider-thumb{border-color: CanvasText;forced-color-adjust: none;background: Highlight;}.glass-loupe{background: Canvas;border: 1px solid CanvasText;}}.glass-loupe{--loupe-k-max: 2.6;--loupe-k-min: 1.15;--loupe-k: calc( var(--loupe-k-max) - (var(--loupe-k-max) - var(--loupe-k-min)) * var(--flex-vel,0) );--loupe-vel: var(--flex-vel,0);--loupe-span: calc(var(--slider-track-height,1.25rem) * 6);position: fixed;z-index: calc(var(--z-overlay) - 1);inline-size: var(--loupe-span);block-size: calc(var(--slider-track-height,1.25rem) * var(--loupe-k-max));inset-block-start: var(--loupe-top,0);inset-inline-start: var(--loupe-left,0);translate: -50% -100%;scale: 0.13;transform-origin: 50% 100%;transition: scale var(--spring-present-duration) var(--spring-present),opacity var(--spring-present-duration) var(--ease-standard);opacity: 0;overflow: hidden;border-radius: var(--radius-pill);pointer-events: none;box-shadow: var(--glass-material-rim),var(--glass-under-shadow-quiet);}.glass-loupe[data-engaged]{scale: 1;opacity: 1;}.glass-loupe:not([data-engaged]){transition: scale var(--spring-present-exit-duration) var(--ease-standard),opacity var(--spring-present-exit-duration) var(--ease-standard);}.glass-loupe-clone{--s: 3;position: absolute;inset-block-start: 50%;inset-inline-start: 0;inline-size: calc(var(--loupe-track-w,0px) * var(--s));block-size: calc(var(--slider-track-height,1.25rem) * var(--s));border-radius: calc(var(--radius-pill) * var(--s));overflow: hidden;background: var(--glass-slider-track-background,var(--muted-medium));transform: translate( calc(var(--loupe-span) / 2 - var(--loupe-k) * var(--loupe-x,0px)),-50% ) scale(calc(var(--loupe-k) / var(--s)));transform-origin: 0 50%;filter: blur(calc(var(--loupe-vel,0) * 0.75px));transition: filter var(--duration-normal) var(--ease-standard);}.glass-loupe-fill{position: absolute;inset-block: 0;inset-inline-start: 0;inline-size: var(--loupe-fill-w,0px);background: var(--slider-range-bg,var(--glass-capsule-warm));}.glass-loupe-mark{position: absolute;inset-block: 0;inset-inline-start: 50%;inline-size: 2px;translate: -50% 0;background: var(--foreground);opacity: 0.24;}@media (prefers-reduced-motion: reduce){.glass-loupe{transition-duration: 0.01ms;}.glass-loupe-clone{filter: none;}}
|
|
@@ -1,115 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* group of pressed buttons; `tabs` exposes a tablist with selected tabs. */
|
|
22
|
-
export type SegmentedTabsSemantics = "toggle" | "tabs";
|
|
23
|
-
/** Whether focus movement also selects. Manual activation waits for Enter/Space. */
|
|
24
|
-
export type SegmentedTabsActivation = TabActivation;
|
|
25
|
-
/** The orientation axis — `horizontal` (default) lays children in a row + tracks
|
|
26
|
-
* the indicator on the inline axis; `vertical` stacks a column + tracks the
|
|
27
|
-
* block axis (the vertical underline is the leading-edge ink rail). */
|
|
28
|
-
export type SegmentedTabsOrientation = "horizontal" | "vertical";
|
|
29
|
-
export interface SegmentedTabsResponsive {
|
|
30
|
-
/**
|
|
31
|
-
* CSS length consumed inside `(min-width: <breakpoint>)`. BELOW it the
|
|
32
|
-
* strip collapses to a `<Select>`; at/above it renders the tab strip.
|
|
33
|
-
* Defaults to `"640px"` (Tailwind `sm:`).
|
|
34
|
-
*/
|
|
35
|
-
breakpoint?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Optional subset shown in the desktop strip (the mobile Select keeps the
|
|
38
|
-
* full option list). Falls back to `options`.
|
|
39
|
-
*/
|
|
40
|
-
desktopOptions?: SegmentedTabOption[] | null;
|
|
41
|
-
/** Accessible name for the mobile `<SelectTrigger>`. */
|
|
42
|
-
ariaLabel?: string;
|
|
43
|
-
/** Class merged onto the mobile `<SelectTrigger>` only. */
|
|
44
|
-
triggerClass?: HTMLAttributes["class"];
|
|
45
|
-
}
|
|
46
|
-
export interface SegmentedTabsProps {
|
|
47
|
-
options: SegmentedTabOption[];
|
|
48
|
-
/** Accessible name shared by the desktop strip and responsive Select. */
|
|
49
|
-
ariaLabel?: string;
|
|
50
|
-
/**
|
|
51
|
-
* The material — `pill` (DEFAULT, the glass eyeglass) or `underline` (the paper
|
|
52
|
-
* ink-hairline rule). TWO, and the eyeglass is not a third: it is what `pill`
|
|
53
|
-
* IS. A "million variants that are essentially the same thing" is the failure
|
|
54
|
-
* mode this axis exists to refuse.
|
|
55
|
-
*/
|
|
56
|
-
variant?: SegmentedTabsVariant;
|
|
57
|
-
/**
|
|
58
|
-
* Interaction semantics, independent of `variant`. When omitted, preserves the
|
|
59
|
-
* historical mapping: `pill` → `toggle`, `underline` → `tabs`.
|
|
60
|
-
*/
|
|
61
|
-
semantics?: SegmentedTabsSemantics;
|
|
62
|
-
/** Selection follows focus by default; manual mode activates with Enter/Space. */
|
|
63
|
-
activation?: SegmentedTabsActivation;
|
|
64
|
-
/**
|
|
65
|
-
* Orientation — `horizontal` (default) or `vertical`. Axis-derived on the
|
|
66
|
-
* one indicator engine.
|
|
67
|
-
*/
|
|
68
|
-
orientation?: SegmentedTabsOrientation;
|
|
69
|
-
/**
|
|
70
|
-
* Responsive collapse — below the breakpoint the strip becomes a `<Select>`.
|
|
71
|
-
* `true` uses defaults; an object tunes the breakpoint, desktop subset, and
|
|
72
|
-
* accessible name.
|
|
73
|
-
*/
|
|
74
|
-
responsive?: boolean | SegmentedTabsResponsive;
|
|
75
|
-
/**
|
|
76
|
-
* Motion weight. `full` (default) lets the pill indicator follow a pointer,
|
|
77
|
-
* squash with drag velocity, and settle to the nearest tab. Drag supplements the
|
|
78
|
-
* fully operable click and keyboard path; it is never the sole selection method.
|
|
79
|
-
* `reduced` and `off` use the click-only strip while preserving roving focus.
|
|
80
|
-
* Underline has no deformable indicator. Reduced-motion preference forces
|
|
81
|
-
* `full → reduced`.
|
|
82
|
-
*/
|
|
83
|
-
motion?: Motion;
|
|
84
|
-
class?: HTMLAttributes["class"];
|
|
85
|
-
}
|
|
86
|
-
type __VLS_Props = SegmentedTabsProps;
|
|
87
|
-
type __VLS_ModelProps = {
|
|
88
|
-
modelValue: string;
|
|
89
|
-
};
|
|
90
|
-
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
91
|
-
declare var __VLS_32: {
|
|
92
|
-
option: SegmentedTabOption;
|
|
93
|
-
active: boolean;
|
|
94
|
-
};
|
|
95
|
-
type __VLS_Slots = {} & {
|
|
96
|
-
option?: (props: typeof __VLS_32) => any;
|
|
1
|
+
import type { SegmentedTabOption, SegmentedTabsProps } from "./types.js";
|
|
2
|
+
declare const __VLS_export: <T extends string = string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<(SegmentedTabsProps<T> & {
|
|
4
|
+
modelValue: T;
|
|
5
|
+
}) & {
|
|
6
|
+
"onUpdate:modelValue"?: ((value: T) => any) | undefined;
|
|
7
|
+
}> & (typeof globalThis extends {
|
|
8
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
9
|
+
} ? P : {});
|
|
10
|
+
expose: (exposed: {}) => void;
|
|
11
|
+
attrs: any;
|
|
12
|
+
slots: {
|
|
13
|
+
option?: (props: {
|
|
14
|
+
option: SegmentedTabOption<T>;
|
|
15
|
+
active: boolean;
|
|
16
|
+
}) => any;
|
|
17
|
+
};
|
|
18
|
+
emit: (event: "update:modelValue", value: T) => void;
|
|
19
|
+
}>) => import("vue").VNode & {
|
|
20
|
+
__ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
|
|
97
21
|
};
|
|
98
|
-
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
99
|
-
"update:modelValue": (value: string) => any;
|
|
100
|
-
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
101
|
-
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
102
|
-
}>, {
|
|
103
|
-
orientation: SegmentedTabsOrientation;
|
|
104
|
-
variant: SegmentedTabsVariant;
|
|
105
|
-
responsive: boolean | SegmentedTabsResponsive;
|
|
106
|
-
activation: SegmentedTabsActivation;
|
|
107
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
108
|
-
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
109
22
|
declare const _default: typeof __VLS_export;
|
|
110
23
|
export default _default;
|
|
111
|
-
type
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
};
|
|
24
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
25
|
+
[K in keyof T]: T[K];
|
|
26
|
+
} : {
|
|
27
|
+
[K in keyof T as K]: T[K];
|
|
28
|
+
}) & {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ComputedRef, Ref } from "vue";
|
|
2
2
|
import { type UseDragMorphReturn } from "../../../composables/motion/morph/useDragMorph.js";
|
|
3
|
-
import type { SegmentedTabOption } from "../
|
|
3
|
+
import type { SegmentedTabOption } from "../types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Package-private composable for `SegmentedTabs.vue` — the LIQUID
|
|
6
6
|
* TAB (the `:draggable` axis). A composable held under the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComputedRef, Ref } from "vue";
|
|
2
|
-
import type { SegmentedTabOption, SegmentedTabsResponsive } from "../
|
|
2
|
+
import type { SegmentedTabOption, SegmentedTabsResponsive } from "../types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Package-private composable for `SegmentedTabs.vue` (the
|
|
5
5
|
* roving-focus/responsive carve). The responsive-collapse concern
|
|
@@ -13,30 +13,30 @@ import type { SegmentedTabOption, SegmentedTabsResponsive } from "../SegmentedTa
|
|
|
13
13
|
* lifecycle-hook owner), so the SFC never re-declares the `mql` listener. It owns the SSR/desktop-first
|
|
14
14
|
* default, the mobile-only model fall-back, and the accessible name resolution.
|
|
15
15
|
*/
|
|
16
|
-
export interface UseTabResponsiveParams {
|
|
16
|
+
export interface UseTabResponsiveParams<V extends string = string> {
|
|
17
17
|
/** The `:responsive` prop — `false` | `true` | a tuning object. */
|
|
18
|
-
responsive: () => boolean | SegmentedTabsResponsive
|
|
18
|
+
responsive: () => boolean | SegmentedTabsResponsive<V>;
|
|
19
19
|
/** The full option list (the mobile `<Select>` keeps ALL options). */
|
|
20
|
-
options: ComputedRef<SegmentedTabOption[]>;
|
|
20
|
+
options: ComputedRef<SegmentedTabOption<V>[]>;
|
|
21
21
|
/** The single-select model (the strip value the collapse falls back off). */
|
|
22
|
-
model: Ref<
|
|
22
|
+
model: Ref<V | undefined>;
|
|
23
23
|
}
|
|
24
|
-
export interface UseTabResponsiveReturn {
|
|
24
|
+
export interface UseTabResponsiveReturn<V extends string = string> {
|
|
25
25
|
/** The resolved responsive config, or `null` when `:responsive` is off. */
|
|
26
|
-
responsiveCfg: ComputedRef<SegmentedTabsResponsive | null>;
|
|
26
|
+
responsiveCfg: ComputedRef<SegmentedTabsResponsive<V> | null>;
|
|
27
27
|
/** The collapse breakpoint CSS length (default `"640px"`). */
|
|
28
28
|
breakpoint: ComputedRef<string>;
|
|
29
29
|
/** The desktop-strip option subset (falls back to the full list). */
|
|
30
|
-
desktopOptions: ComputedRef<SegmentedTabOption[]>;
|
|
30
|
+
desktopOptions: ComputedRef<SegmentedTabOption<V>[]>;
|
|
31
31
|
/** `true` at/above the breakpoint (the matchMedia state; SSR-default `true`). */
|
|
32
32
|
isDesktop: Ref<boolean>;
|
|
33
33
|
/** The value the STRIP renders (falls back off a mobile-only model). */
|
|
34
|
-
stripValue: ComputedRef<
|
|
34
|
+
stripValue: ComputedRef<V | undefined>;
|
|
35
35
|
/** The options the STRIP renders (desktop subset when responsive, else full). */
|
|
36
|
-
stripOptions: ComputedRef<SegmentedTabOption[]>;
|
|
36
|
+
stripOptions: ComputedRef<SegmentedTabOption<V>[]>;
|
|
37
37
|
/** The accessible name for the mobile `<SelectTrigger>`. */
|
|
38
38
|
mobileAriaLabel: ComputedRef<string>;
|
|
39
39
|
/** `true` when the mobile `<Select>` should render (responsive + below breakpoint). */
|
|
40
40
|
showMobileSelect: ComputedRef<boolean>;
|
|
41
41
|
}
|
|
42
|
-
export declare function useTabResponsive(params: UseTabResponsiveParams): UseTabResponsiveReturn
|
|
42
|
+
export declare function useTabResponsive<V extends string = string>(params: UseTabResponsiveParams<V>): UseTabResponsiveReturn<V>;
|