@viraui/react 2026.10.0 → 2026.11.0-next.1
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/catalog.json +12 -0
- package/dist/components/avatar/avatar.d.ts +6 -0
- package/dist/components/avatar/avatar.js +2 -2
- package/dist/components/badge/badge.css +1 -1
- package/dist/components/button/button.css +1 -1
- package/dist/components/dialog/dialog-sheet.d.ts +1 -1
- package/dist/components/gauge/arcs.d.ts +134 -0
- package/dist/components/gauge/arcs.js +145 -0
- package/dist/components/gauge/context.d.ts +134 -0
- package/dist/components/gauge/context.js +83 -0
- package/dist/components/gauge/control.d.ts +107 -0
- package/dist/components/gauge/control.js +223 -0
- package/dist/components/gauge/demos/_shared.d.ts +28 -0
- package/dist/components/gauge/demos/activity-ring.d.ts +9 -0
- package/dist/components/gauge/demos/air-quality.d.ts +9 -0
- package/dist/components/gauge/demos/analog-dial.d.ts +9 -0
- package/dist/components/gauge/demos/battery.d.ts +9 -0
- package/dist/components/gauge/demos/chronograph.d.ts +9 -0
- package/dist/components/gauge/demos/clock.d.ts +9 -0
- package/dist/components/gauge/demos/compass.d.ts +9 -0
- package/dist/components/gauge/demos/data-usage.d.ts +9 -0
- package/dist/components/gauge/demos/dimmer.d.ts +9 -0
- package/dist/components/gauge/demos/fuel.d.ts +9 -0
- package/dist/components/gauge/demos/heart-rate.d.ts +9 -0
- package/dist/components/gauge/demos/internet-speed.d.ts +9 -0
- package/dist/components/gauge/demos/nested-rings.d.ts +11 -0
- package/dist/components/gauge/demos/orrery.d.ts +12 -0
- package/dist/components/gauge/demos/power-meter.d.ts +9 -0
- package/dist/components/gauge/demos/progress-ring.d.ts +9 -0
- package/dist/components/gauge/demos/range.d.ts +10 -0
- package/dist/components/gauge/demos/saas-metric.d.ts +9 -0
- package/dist/components/gauge/demos/segments.d.ts +9 -0
- package/dist/components/gauge/demos/simple.d.ts +9 -0
- package/dist/components/gauge/demos/speed-fuel.d.ts +10 -0
- package/dist/components/gauge/demos/speedometer.d.ts +9 -0
- package/dist/components/gauge/demos/sprint.d.ts +9 -0
- package/dist/components/gauge/demos/sun-path.d.ts +9 -0
- package/dist/components/gauge/demos/system.d.ts +11 -0
- package/dist/components/gauge/demos/tachometer.d.ts +9 -0
- package/dist/components/gauge/demos/temperature.d.ts +9 -0
- package/dist/components/gauge/demos/thermostat.d.ts +9 -0
- package/dist/components/gauge/demos/timer.d.ts +9 -0
- package/dist/components/gauge/demos/volume.d.ts +10 -0
- package/dist/components/gauge/demos/wind.d.ts +9 -0
- package/dist/components/gauge/dot.d.ts +55 -0
- package/dist/components/gauge/dot.js +34 -0
- package/dist/components/gauge/gauge.css +1 -0
- package/dist/components/gauge/gauge.d.ts +84 -0
- package/dist/components/gauge/gauge.js +62 -0
- package/dist/components/gauge/gauge.module.js +24 -0
- package/dist/components/gauge/index.d.ts +15 -0
- package/dist/components/gauge/inset.d.ts +30 -0
- package/dist/components/gauge/inset.js +39 -0
- package/dist/components/gauge/math.d.ts +69 -0
- package/dist/components/gauge/math.js +135 -0
- package/dist/components/gauge/needle.d.ts +81 -0
- package/dist/components/gauge/needle.js +162 -0
- package/dist/components/gauge/scale.d.ts +44 -0
- package/dist/components/gauge/scale.js +21 -0
- package/dist/components/gauge/text.d.ts +79 -0
- package/dist/components/gauge/text.js +42 -0
- package/dist/components/gauge/ticks.d.ts +169 -0
- package/dist/components/gauge/ticks.js +124 -0
- package/dist/components/gauge/tooltip.d.ts +117 -0
- package/dist/components/gauge/tooltip.js +336 -0
- package/dist/components/gauge/transition.d.ts +60 -0
- package/dist/components/gauge/transition.js +129 -0
- package/dist/components/gauge/use-animated-value.d.ts +14 -0
- package/dist/components/gauge/use-animated-value.js +111 -0
- package/dist/components/gauge/utils.d.ts +51 -0
- package/dist/components/gauge/utils.js +80 -0
- package/dist/components/icon-meter/icon-meter.css +1 -0
- package/dist/components/icon-meter/icon-meter.d.ts +62 -0
- package/dist/components/icon-meter/icon-meter.js +105 -0
- package/dist/components/icon-meter/icon-meter.module.js +11 -0
- package/dist/components/icon-meter/index.d.ts +2 -0
- package/dist/components/icon-meter/utils.d.ts +22 -0
- package/dist/components/icon-meter/utils.js +40 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/popover/popover-sheet.d.ts +1 -2
- package/dist/components/stack/stack.d.ts +9 -2
- package/dist/components/tabs/tabs.d.ts +1 -2
- package/dist/index.js +17 -1
- package/dist/internal/chrome-icons/chrome-icons.d.ts +4 -0
- package/dist/internal/chrome-icons/chrome-icons.js +12 -4
- package/dist/preflight.css +1 -1
- package/dist/specs/components/avatar/props.xml +3 -0
- package/dist/specs/components/avatar/usage.xml +1 -0
- package/dist/specs/components/badge/a11y.xml +1 -1
- package/dist/specs/components/button/props.xml +2 -2
- package/dist/specs/components/button/usage.xml +1 -1
- package/dist/specs/components/gauge/a11y.xml +8 -0
- package/dist/specs/components/gauge/meta.xml +38 -0
- package/dist/specs/components/gauge/patterns.xml +1158 -0
- package/dist/specs/components/gauge/props.xml +452 -0
- package/dist/specs/components/gauge/usage.xml +21 -0
- package/dist/specs/components/icon-button/props.xml +2 -2
- package/dist/specs/components/icon-button/usage.xml +1 -1
- package/dist/specs/components/icon-meter/a11y.xml +9 -0
- package/dist/specs/components/icon-meter/meta.xml +21 -0
- package/dist/specs/components/icon-meter/patterns.xml +23 -0
- package/dist/specs/components/icon-meter/props.xml +44 -0
- package/dist/specs/components/icon-meter/usage.xml +13 -0
- package/dist/specs/components/linear-progress/usage.xml +1 -0
- package/dist/specs/components/meter/meta.xml +1 -0
- package/dist/specs/components/meter/props.xml +1 -0
- package/dist/specs/components/meter/usage.xml +1 -0
- package/dist/specs/components/stack/patterns.xml +21 -21
- package/dist/specs/components/stack/props.xml +6 -6
- package/dist/specs/components/stack/usage.xml +4 -2
- package/dist/specs/components/text/patterns.xml +1 -1
- package/dist/specs/components/text/usage.xml +1 -1
- package/dist/specs/components/toggle-button/props.xml +1 -1
- package/dist/specs/components/toggle-button/usage.xml +1 -1
- package/dist/specs/components/toggle-text-button/props.xml +1 -1
- package/dist/specs/foundation/attributes.xml +3 -3
- package/dist/specs/foundation/modules.xml +1 -1
- package/dist/specs/foundation/theme-topics.xml +7 -2
- package/dist/specs/index.xml +21 -1
- package/dist/specs/patterns/compose-layout-first.xml +1 -1
- package/dist/specs/patterns/settings-panel.xml +1 -1
- package/dist/specs/patterns/settings-row.xml +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { easingFunction, resolveTransition, springPhysics, stepSpring } from "./transition.js";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
//#region src/components/gauge/use-animated-value.ts
|
|
5
|
+
/** Folds a change into [-span/2, span/2), the short way round a circle. */
|
|
6
|
+
var shortestDelta = (delta, span) => {
|
|
7
|
+
const s = Math.max(span, 1e-9);
|
|
8
|
+
return ((delta + s / 2) % s + s) % s - s / 2;
|
|
9
|
+
};
|
|
10
|
+
var prefersReducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
11
|
+
/**
|
|
12
|
+
* Follows `target` with the given transition and returns the value to draw
|
|
13
|
+
* this frame. With no transition it returns `target` as is and renders
|
|
14
|
+
* nothing extra. Honours `prefers-reduced-motion` by snapping.
|
|
15
|
+
*
|
|
16
|
+
* `span` is the size of the domain and sets the rest threshold. `initial` is
|
|
17
|
+
* where the value starts on mount, for a sweep-in from the minimum. `wrap`
|
|
18
|
+
* treats the domain as circular: every change is followed the shortest way
|
|
19
|
+
* round, so a heading crossing north never swings the long way back. The
|
|
20
|
+
* returned value may then sit outside the domain mid-flight; map it back
|
|
21
|
+
* with a modulo.
|
|
22
|
+
*/
|
|
23
|
+
var useAnimatedValue = (target, transition, span, initial, wrap) => {
|
|
24
|
+
const enabled = Boolean(transition);
|
|
25
|
+
const [display, setDisplay] = useState(initial ?? target);
|
|
26
|
+
const spring = useRef({
|
|
27
|
+
value: initial ?? target,
|
|
28
|
+
velocity: 0
|
|
29
|
+
});
|
|
30
|
+
const start = initial ?? target;
|
|
31
|
+
const [series, setSeries] = useState(() => ({
|
|
32
|
+
raw: target,
|
|
33
|
+
goal: wrap ? start + shortestDelta(target - start, span) : target
|
|
34
|
+
}));
|
|
35
|
+
if (wrap && (target !== series.raw || !enabled && target !== series.goal)) setSeries(enabled ? {
|
|
36
|
+
raw: target,
|
|
37
|
+
goal: series.goal + shortestDelta(target - series.raw, span)
|
|
38
|
+
} : {
|
|
39
|
+
raw: target,
|
|
40
|
+
goal: target
|
|
41
|
+
});
|
|
42
|
+
const goal = wrap ? series.goal : target;
|
|
43
|
+
const transitionRef = useRef(transition);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
transitionRef.current = transition;
|
|
46
|
+
});
|
|
47
|
+
const configKey = JSON.stringify(transition);
|
|
48
|
+
if (!enabled && display !== target) setDisplay(target);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (!enabled) spring.current = {
|
|
51
|
+
value: target,
|
|
52
|
+
velocity: 0
|
|
53
|
+
};
|
|
54
|
+
}, [enabled, target]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const config = resolveTransition(transitionRef.current);
|
|
57
|
+
if (!config) return;
|
|
58
|
+
const precision = Math.max(span, 1e-6) * 1e-4;
|
|
59
|
+
const snap = prefersReducedMotion();
|
|
60
|
+
const restAt = target;
|
|
61
|
+
let frame = 0;
|
|
62
|
+
let last = performance.now();
|
|
63
|
+
const from = spring.current.value;
|
|
64
|
+
const startAt = last;
|
|
65
|
+
const tick = (now) => {
|
|
66
|
+
const dt = (now - last) / 1e3;
|
|
67
|
+
last = now;
|
|
68
|
+
let done;
|
|
69
|
+
if (snap) done = true;
|
|
70
|
+
else if (config.type === "spring") {
|
|
71
|
+
const physics = springPhysics(config);
|
|
72
|
+
const { state, done: springDone } = stepSpring(spring.current, goal, physics, dt, precision);
|
|
73
|
+
spring.current = state;
|
|
74
|
+
done = springDone;
|
|
75
|
+
} else {
|
|
76
|
+
const duration = Math.max(config.duration ?? .5, .001);
|
|
77
|
+
const progress = Math.min((now - startAt) / 1e3 / duration, 1);
|
|
78
|
+
const eased = easingFunction(config.ease)(progress);
|
|
79
|
+
const value = from + (goal - from) * eased;
|
|
80
|
+
spring.current = {
|
|
81
|
+
value,
|
|
82
|
+
velocity: 0
|
|
83
|
+
};
|
|
84
|
+
done = progress >= 1;
|
|
85
|
+
}
|
|
86
|
+
if (done) {
|
|
87
|
+
spring.current = {
|
|
88
|
+
value: restAt,
|
|
89
|
+
velocity: 0
|
|
90
|
+
};
|
|
91
|
+
if (wrap) setSeries((s) => s.raw === restAt && s.goal === restAt ? s : {
|
|
92
|
+
raw: restAt,
|
|
93
|
+
goal: restAt
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
setDisplay(spring.current.value);
|
|
97
|
+
if (!done) frame = requestAnimationFrame(tick);
|
|
98
|
+
};
|
|
99
|
+
frame = requestAnimationFrame(tick);
|
|
100
|
+
return () => cancelAnimationFrame(frame);
|
|
101
|
+
}, [
|
|
102
|
+
goal,
|
|
103
|
+
target,
|
|
104
|
+
configKey,
|
|
105
|
+
span,
|
|
106
|
+
wrap
|
|
107
|
+
]);
|
|
108
|
+
return enabled ? display : target;
|
|
109
|
+
};
|
|
110
|
+
//#endregion
|
|
111
|
+
export { useAnimatedValue };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared vocabulary and pure helpers for the gauge primitives: stroke and
|
|
3
|
+
* font options, zones, and the formatters that turn a value into a label.
|
|
4
|
+
* Everything here is framework-free so it can be used in generated code.
|
|
5
|
+
*/
|
|
6
|
+
export type StrokeCap = 'round' | 'butt';
|
|
7
|
+
export type FontFamily = 'sans' | 'rounded' | 'mono';
|
|
8
|
+
export type FontWeight = 'regular' | 'medium' | 'semibold' | 'bold';
|
|
9
|
+
export type NeedleStyle = 'line' | 'pointer' | 'compass' | 'arrow';
|
|
10
|
+
/**
|
|
11
|
+
* Which end of a range a part follows: `to`, the far end, which is the value
|
|
12
|
+
* itself on a single-value gauge, or `from`, where the range starts.
|
|
13
|
+
*/
|
|
14
|
+
export type GaugeEnd = 'from' | 'to';
|
|
15
|
+
/** A colour for every mark alike, or one per mark worked out from its value. */
|
|
16
|
+
export type ValueColor = string | ((value: number) => string);
|
|
17
|
+
/** Which edge of a text sits at its position: left, centre or right. */
|
|
18
|
+
export type TextAnchor = 'start' | 'middle' | 'end';
|
|
19
|
+
export type Zone = {
|
|
20
|
+
/** Upper cutoff of the zone in domain units. Ignored for the last zone. */
|
|
21
|
+
to: number;
|
|
22
|
+
color: string;
|
|
23
|
+
};
|
|
24
|
+
/** Theme font-family CSS value for SVG `fontFamily` / `style.fontFamily`. */
|
|
25
|
+
export declare const fontFamily: (family?: FontFamily) => string;
|
|
26
|
+
/** Theme font-weight CSS value for SVG `fontWeight` / `style.fontWeight`. */
|
|
27
|
+
export declare const fontWeight: (weight?: FontWeight) => number;
|
|
28
|
+
/** Colour of the zone a value falls in, or `fallback` when there are none. */
|
|
29
|
+
export declare const zoneColor: (zones: Zone[], value: number, fallback: string) => string;
|
|
30
|
+
/** Cutoff values that separate neighbouring zones. */
|
|
31
|
+
export declare const zoneCutoffs: (zones: Zone[]) => number[];
|
|
32
|
+
/**
|
|
33
|
+
* Formats a heading in degrees as a compass point when it lands on one of the
|
|
34
|
+
* sixteen, and as degrees otherwise, so a 0–360 domain reads like a bezel:
|
|
35
|
+
* N, 30°, 60°, E, and so on.
|
|
36
|
+
*/
|
|
37
|
+
export declare const compassLabel: (degrees: number) => string;
|
|
38
|
+
/** Formats a value in hours as a clock numeral, so 0 and 12 both read "12". */
|
|
39
|
+
export declare const clockLabel: (hours: number) => string;
|
|
40
|
+
/**
|
|
41
|
+
* Hours past midnight as a 24-hour clock time: 6.5 reads "06:30". Negative
|
|
42
|
+
* hours reach back into the day before, and past 24 into the day after.
|
|
43
|
+
*/
|
|
44
|
+
export declare const clockTime: (hours: number) => string;
|
|
45
|
+
/** A duration in hours as "7h 32m". */
|
|
46
|
+
export declare const durationLabel: (hours: number) => string;
|
|
47
|
+
/**
|
|
48
|
+
* `color` thinned towards transparent: the one ink of a face taken down to
|
|
49
|
+
* its quieter tones, holding apart in either theme.
|
|
50
|
+
*/
|
|
51
|
+
export declare const fadeColor: (color: string, percent: number) => string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//#region src/components/gauge/utils.ts
|
|
2
|
+
var FONT_FAMILY = {
|
|
3
|
+
sans: "var(--font-family-body)",
|
|
4
|
+
rounded: "var(--font-family-body)",
|
|
5
|
+
mono: "var(--font-family-mono)"
|
|
6
|
+
};
|
|
7
|
+
var FONT_WEIGHT = {
|
|
8
|
+
regular: 400,
|
|
9
|
+
medium: 500,
|
|
10
|
+
semibold: 600,
|
|
11
|
+
bold: 700
|
|
12
|
+
};
|
|
13
|
+
/** Theme font-family CSS value for SVG `fontFamily` / `style.fontFamily`. */
|
|
14
|
+
var fontFamily = (family = "sans") => FONT_FAMILY[family];
|
|
15
|
+
/** Theme font-weight CSS value for SVG `fontWeight` / `style.fontWeight`. */
|
|
16
|
+
var fontWeight = (weight = "regular") => FONT_WEIGHT[weight];
|
|
17
|
+
/** Colour of the zone a value falls in, or `fallback` when there are none. */
|
|
18
|
+
var zoneColor = (zones, value, fallback) => {
|
|
19
|
+
if (zones.length === 0) return fallback;
|
|
20
|
+
for (let i = 0; i < zones.length - 1; i += 1) {
|
|
21
|
+
const zone = zones[i];
|
|
22
|
+
if (zone && value < zone.to) return zone.color;
|
|
23
|
+
}
|
|
24
|
+
return zones[zones.length - 1]?.color ?? fallback;
|
|
25
|
+
};
|
|
26
|
+
/** Cutoff values that separate neighbouring zones. */
|
|
27
|
+
var zoneCutoffs = (zones) => zones.slice(0, -1).map((zone) => zone.to);
|
|
28
|
+
var compassPoints = [
|
|
29
|
+
"N",
|
|
30
|
+
"NNE",
|
|
31
|
+
"NE",
|
|
32
|
+
"ENE",
|
|
33
|
+
"E",
|
|
34
|
+
"ESE",
|
|
35
|
+
"SE",
|
|
36
|
+
"SSE",
|
|
37
|
+
"S",
|
|
38
|
+
"SSW",
|
|
39
|
+
"SW",
|
|
40
|
+
"WSW",
|
|
41
|
+
"W",
|
|
42
|
+
"WNW",
|
|
43
|
+
"NW",
|
|
44
|
+
"NNW"
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Formats a heading in degrees as a compass point when it lands on one of the
|
|
48
|
+
* sixteen, and as degrees otherwise, so a 0–360 domain reads like a bezel:
|
|
49
|
+
* N, 30°, 60°, E, and so on.
|
|
50
|
+
*/
|
|
51
|
+
var compassLabel = (degrees) => {
|
|
52
|
+
const turn = (degrees % 360 + 360) % 360;
|
|
53
|
+
const index = Math.round(turn / 22.5) % 16;
|
|
54
|
+
const exact = Math.abs(turn - index * 22.5) < .5;
|
|
55
|
+
const point = compassPoints[index];
|
|
56
|
+
return exact && point ? point : `${Math.round(turn)}°`;
|
|
57
|
+
};
|
|
58
|
+
/** Formats a value in hours as a clock numeral, so 0 and 12 both read "12". */
|
|
59
|
+
var clockLabel = (hours) => String((Math.round(hours) % 12 + 12) % 12 || 12);
|
|
60
|
+
var pad = (n) => String(n).padStart(2, "0");
|
|
61
|
+
/**
|
|
62
|
+
* Hours past midnight as a 24-hour clock time: 6.5 reads "06:30". Negative
|
|
63
|
+
* hours reach back into the day before, and past 24 into the day after.
|
|
64
|
+
*/
|
|
65
|
+
var clockTime = (hours) => {
|
|
66
|
+
const minutes = Math.round((hours % 24 + 24) % 24 * 60);
|
|
67
|
+
return `${pad(Math.floor(minutes / 60) % 24)}:${pad(minutes % 60)}`;
|
|
68
|
+
};
|
|
69
|
+
/** A duration in hours as "7h 32m". */
|
|
70
|
+
var durationLabel = (hours) => {
|
|
71
|
+
const minutes = Math.round(hours * 60);
|
|
72
|
+
return `${Math.floor(minutes / 60)}h ${pad(minutes % 60)}m`;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* `color` thinned towards transparent: the one ink of a face taken down to
|
|
76
|
+
* its quieter tones, holding apart in either theme.
|
|
77
|
+
*/
|
|
78
|
+
var fadeColor = (color, percent) => `oklch(from ${color} l c h / ${percent}%)`;
|
|
79
|
+
//#endregion
|
|
80
|
+
export { clockLabel, clockTime, compassLabel, durationLabel, fadeColor, fontFamily, fontWeight, zoneColor, zoneCutoffs };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer viraui.preflight, viraui.components, viraui.overrides;@layer viraui.components{@property --vui-icon-meter-icon-color{syntax:"<color>";inherits:true;initial-value:#0000}@property --vui-icon-meter-empty-color{syntax:"<color>";inherits:true;initial-value:#0000}@property --__icon-meter-icon-size{syntax:"<length>";inherits:true;initial-value:0}.viraui__icon-meter-module__IconMeter_2k97C{--vui-icon-meter-icon-color:var(--global-primary);--vui-icon-meter-empty-color:var(--global-contrast);--__icon-meter-icon-size:var(--space-l);position:relative;&[data-dimension=s]{--__icon-meter-icon-size:var(--space-m)}&[data-dimension=l]{--__icon-meter-icon-size:var(--space-xl)}}.viraui__icon-meter-module__Icon_ZIDLS{display:block;flex:none;inline-size:var(--__icon-meter-icon-size);block-size:var(--__icon-meter-icon-size)}.viraui__icon-meter-module__HalfDefs_LjhPl{position:absolute;inline-size:0;block-size:0;overflow:hidden;pointer-events:none}}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
type IconMeterIconProps = {
|
|
3
|
+
'aria-hidden'?: boolean | 'true';
|
|
4
|
+
className?: string;
|
|
5
|
+
fill?: string;
|
|
6
|
+
size?: number | string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Public IconMeter props.
|
|
10
|
+
*
|
|
11
|
+
* Display-only discrete icon row (APG Meter). Not a track Meter, Gauge, progress, or interactive rating.
|
|
12
|
+
*/
|
|
13
|
+
export type IconMeterProps = Omit<React.ComponentPropsWithRef<'div'>, 'children'> & {
|
|
14
|
+
/**
|
|
15
|
+
* Current reading. Clamped to `[0, iconCount]` after `iconCount` is clamped. `0` paints all empty icons.
|
|
16
|
+
*/
|
|
17
|
+
value: number;
|
|
18
|
+
/**
|
|
19
|
+
* Number of icon slots. Clamped to at least `3`.
|
|
20
|
+
*
|
|
21
|
+
* @defaultValue 5
|
|
22
|
+
*/
|
|
23
|
+
iconCount?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Recolorable icon component instantiated once per slot with `fill` / `size` / `className`.
|
|
26
|
+
*
|
|
27
|
+
* @defaultValue ChromeStar
|
|
28
|
+
*/
|
|
29
|
+
icon?: React.ComponentType<IconMeterIconProps>;
|
|
30
|
+
/**
|
|
31
|
+
* Compact size step. Maps to `data-dimension` for icon size, gap, and label text size.
|
|
32
|
+
*
|
|
33
|
+
* @defaultValue 'm'
|
|
34
|
+
*/
|
|
35
|
+
size?: 's' | 'm' | 'l';
|
|
36
|
+
/**
|
|
37
|
+
* CSS color string for full / half icons (`--vui-icon-meter-icon-color`). Pass any valid color or theme var.
|
|
38
|
+
*
|
|
39
|
+
* @defaultValue 'var(--global-primary)'
|
|
40
|
+
*/
|
|
41
|
+
highlightColor?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Custom visible label. When omitted and not hidden, the clamped value string is shown.
|
|
44
|
+
*
|
|
45
|
+
* @defaultValue Clamped value as text.
|
|
46
|
+
*/
|
|
47
|
+
label?: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Hides the visible label. Provide `aria-label` or `aria-labelledby` for the accessible name.
|
|
50
|
+
*
|
|
51
|
+
* @defaultValue false
|
|
52
|
+
*/
|
|
53
|
+
hideLabel?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Overrides the default AT value text (`"{value} of {iconCount}"`).
|
|
56
|
+
*
|
|
57
|
+
* @defaultValue Derived `"{clampedValue} of {clampedIconCount}"`.
|
|
58
|
+
*/
|
|
59
|
+
valueText?: string;
|
|
60
|
+
};
|
|
61
|
+
export declare const IconMeter: React.FC<IconMeterProps>;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import './icon-meter.css';
|
|
2
|
+
import { clsx } from "../../core/clsx.js";
|
|
3
|
+
import { ChromeStar } from "../../internal/chrome-icons/chrome-icons.js";
|
|
4
|
+
import { Text } from "../text/text.js";
|
|
5
|
+
import { Stack } from "../stack/stack.js";
|
|
6
|
+
import icon_meter_module_default from "./icon-meter.module.js";
|
|
7
|
+
import { clampIconCount, clampValue, getSlotFill, roundMeterValue } from "./utils.js";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import * as React from "react";
|
|
10
|
+
import { Meter } from "@base-ui/react";
|
|
11
|
+
//#region src/components/icon-meter/icon-meter.tsx
|
|
12
|
+
var LABEL_TEXT_SIZE = {
|
|
13
|
+
s: "s",
|
|
14
|
+
m: "m",
|
|
15
|
+
l: "l"
|
|
16
|
+
};
|
|
17
|
+
var ICON_COLUMN_GAP = {
|
|
18
|
+
s: "2xs",
|
|
19
|
+
m: "xs",
|
|
20
|
+
l: "s"
|
|
21
|
+
};
|
|
22
|
+
var EMPTY_FILL = "var(--vui-icon-meter-empty-color)";
|
|
23
|
+
var FULL_FILL = "var(--vui-icon-meter-icon-color)";
|
|
24
|
+
var IconMeter = ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className, hideLabel = false, highlightColor = "var(--global-primary)", icon: Icon = ChromeStar, iconCount = 5, label, ref, size = "m", style, value, valueText, ...otherProps }) => {
|
|
25
|
+
const halfGradientId = `IconMeter-half-${React.useId().replaceAll(":", "")}`;
|
|
26
|
+
const clampedIconCount = clampIconCount(iconCount);
|
|
27
|
+
const clampedValue = clampValue(value, clampedIconCount);
|
|
28
|
+
const roundedValue = roundMeterValue(clampedValue);
|
|
29
|
+
const resolvedValueText = valueText ?? `${clampedValue} of ${clampedIconCount}`;
|
|
30
|
+
const visibleLabel = label ?? String(clampedValue);
|
|
31
|
+
const dynamicStyle = {
|
|
32
|
+
"--vui-icon-meter-icon-color": highlightColor,
|
|
33
|
+
...style
|
|
34
|
+
};
|
|
35
|
+
const icons = Array.from({ length: clampedIconCount }, (_, slotIndex) => {
|
|
36
|
+
const fillKind = getSlotFill(slotIndex, roundedValue);
|
|
37
|
+
let fill = EMPTY_FILL;
|
|
38
|
+
if (fillKind === "full") fill = FULL_FILL;
|
|
39
|
+
else if (fillKind === "half") fill = `url(#${halfGradientId})`;
|
|
40
|
+
return /* @__PURE__ */ jsx(Icon, {
|
|
41
|
+
"aria-hidden": "true",
|
|
42
|
+
className: icon_meter_module_default.Icon,
|
|
43
|
+
fill,
|
|
44
|
+
size: "100%"
|
|
45
|
+
}, slotIndex);
|
|
46
|
+
});
|
|
47
|
+
return /* @__PURE__ */ jsxs(Meter.Root, {
|
|
48
|
+
...otherProps,
|
|
49
|
+
ref,
|
|
50
|
+
...ariaLabel != null && { "aria-label": ariaLabel },
|
|
51
|
+
...ariaLabelledby != null && { "aria-labelledby": ariaLabelledby },
|
|
52
|
+
className: clsx(icon_meter_module_default.IconMeter, className),
|
|
53
|
+
"data-dimension": size,
|
|
54
|
+
getAriaValueText: () => resolvedValueText,
|
|
55
|
+
max: clampedIconCount,
|
|
56
|
+
min: 0,
|
|
57
|
+
render: /* @__PURE__ */ jsx(Stack, {
|
|
58
|
+
direction: "row",
|
|
59
|
+
vAlign: "center",
|
|
60
|
+
columnGap: "s"
|
|
61
|
+
}),
|
|
62
|
+
style: dynamicStyle,
|
|
63
|
+
value: clampedValue,
|
|
64
|
+
children: [
|
|
65
|
+
/* @__PURE__ */ jsx("svg", {
|
|
66
|
+
"aria-hidden": "true",
|
|
67
|
+
className: icon_meter_module_default.HalfDefs,
|
|
68
|
+
focusable: "false",
|
|
69
|
+
children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", {
|
|
70
|
+
id: halfGradientId,
|
|
71
|
+
x1: "0",
|
|
72
|
+
x2: "1",
|
|
73
|
+
y1: "0",
|
|
74
|
+
y2: "0",
|
|
75
|
+
children: [/* @__PURE__ */ jsx("stop", {
|
|
76
|
+
offset: "50%",
|
|
77
|
+
stopColor: FULL_FILL
|
|
78
|
+
}), /* @__PURE__ */ jsx("stop", {
|
|
79
|
+
offset: "50%",
|
|
80
|
+
stopColor: EMPTY_FILL
|
|
81
|
+
})]
|
|
82
|
+
}) })
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ jsx(Stack, {
|
|
85
|
+
columnGap: ICON_COLUMN_GAP[size],
|
|
86
|
+
"data-testid": "icon-meter-icons",
|
|
87
|
+
direction: "row",
|
|
88
|
+
vAlign: "center",
|
|
89
|
+
children: icons
|
|
90
|
+
}),
|
|
91
|
+
!hideLabel && /* @__PURE__ */ jsx(Meter.Label, {
|
|
92
|
+
render: /* @__PURE__ */ jsx(Text, {
|
|
93
|
+
size: LABEL_TEXT_SIZE[size],
|
|
94
|
+
tone: "muted",
|
|
95
|
+
weight: "semibold",
|
|
96
|
+
whiteSpace: "nowrap",
|
|
97
|
+
selection: false
|
|
98
|
+
}),
|
|
99
|
+
children: visibleLabel
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
export { IconMeter };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/components/icon-meter/icon-meter.module.css
|
|
2
|
+
var IconMeter = "viraui__icon-meter-module__IconMeter_2k97C";
|
|
3
|
+
var Icon = "viraui__icon-meter-module__Icon_ZIDLS";
|
|
4
|
+
var HalfDefs = "viraui__icon-meter-module__HalfDefs_LjhPl";
|
|
5
|
+
var icon_meter_module_default = {
|
|
6
|
+
IconMeter,
|
|
7
|
+
Icon,
|
|
8
|
+
HalfDefs
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { HalfDefs, Icon, IconMeter, icon_meter_module_default as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Slot paint after fraction rounding. */
|
|
2
|
+
export type IconMeterSlotFill = 'empty' | 'half' | 'full';
|
|
3
|
+
/**
|
|
4
|
+
* Clamp icon slot count to at least 3. Non-finite values become 3.
|
|
5
|
+
*/
|
|
6
|
+
export declare const clampIconCount: (iconCount: number) => number;
|
|
7
|
+
/**
|
|
8
|
+
* Clamp the meter value into `[0, max]`. Non-finite values become 0.
|
|
9
|
+
*/
|
|
10
|
+
export declare const clampValue: (value: number, max: number) => number;
|
|
11
|
+
/**
|
|
12
|
+
* Round a raw value into empty / half / full bands per unit fraction.
|
|
13
|
+
*
|
|
14
|
+
* - fraction `< 0.25` → floor (empty remainder)
|
|
15
|
+
* - fraction `≥ 0.75` → ceil (full)
|
|
16
|
+
* - else → `integer + 0.5` (half)
|
|
17
|
+
*/
|
|
18
|
+
export declare const roundMeterValue: (rawValue: number) => number;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve empty / half / full for zero-based slot index against a rounded value.
|
|
21
|
+
*/
|
|
22
|
+
export declare const getSlotFill: (slotIndex: number, roundedValue: number) => IconMeterSlotFill;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/components/icon-meter/utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Clamp icon slot count to at least 3. Non-finite values become 3.
|
|
4
|
+
*/
|
|
5
|
+
var clampIconCount = (iconCount) => {
|
|
6
|
+
if (!Number.isFinite(iconCount)) return 3;
|
|
7
|
+
return Math.max(3, Math.trunc(iconCount));
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Clamp the meter value into `[0, max]`. Non-finite values become 0.
|
|
11
|
+
*/
|
|
12
|
+
var clampValue = (value, max) => {
|
|
13
|
+
if (!Number.isFinite(value)) return 0;
|
|
14
|
+
return Math.min(Math.max(value, 0), max);
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Round a raw value into empty / half / full bands per unit fraction.
|
|
18
|
+
*
|
|
19
|
+
* - fraction `< 0.25` → floor (empty remainder)
|
|
20
|
+
* - fraction `≥ 0.75` → ceil (full)
|
|
21
|
+
* - else → `integer + 0.5` (half)
|
|
22
|
+
*/
|
|
23
|
+
var roundMeterValue = (rawValue) => {
|
|
24
|
+
const integer = Math.trunc(rawValue);
|
|
25
|
+
const fraction = rawValue - integer;
|
|
26
|
+
if (fraction >= .75) return Math.ceil(rawValue);
|
|
27
|
+
if (fraction < .25) return Math.floor(rawValue);
|
|
28
|
+
return integer + .5;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Resolve empty / half / full for zero-based slot index against a rounded value.
|
|
32
|
+
*/
|
|
33
|
+
var getSlotFill = (slotIndex, roundedValue) => {
|
|
34
|
+
const iconIndex = slotIndex + 1;
|
|
35
|
+
if (roundedValue >= iconIndex) return "full";
|
|
36
|
+
if (roundedValue > iconIndex - 1) return "half";
|
|
37
|
+
return "empty";
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { clampIconCount, clampValue, getSlotFill, roundMeterValue };
|
|
@@ -18,8 +18,10 @@ export * from './elevator';
|
|
|
18
18
|
export * from './fieldset';
|
|
19
19
|
export * from './fit-text';
|
|
20
20
|
export * from './glow';
|
|
21
|
+
export * from './gauge';
|
|
21
22
|
export * from './grid';
|
|
22
23
|
export * from './icon-button';
|
|
24
|
+
export * from './icon-meter';
|
|
23
25
|
export * from './linear-progress';
|
|
24
26
|
export * from './masonry';
|
|
25
27
|
export * from './menu';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Popover as PrimitivePopover, PopoverPositioner } from '@base-ui/react/popover';
|
|
2
|
-
import { StackProps } from '..';
|
|
3
2
|
import type * as React from 'react';
|
|
4
3
|
type PopoverSheetPositionerProps = Omit<PopoverPositioner.Props, 'className' | 'style' | 'render'>;
|
|
5
4
|
type PopoverSheetContainerProps = {
|
|
@@ -41,7 +40,7 @@ type PopoverSheetStyledProps = PopoverSheetPositionerProps & PopoverSheetContain
|
|
|
41
40
|
*
|
|
42
41
|
* @defaultValue `start`
|
|
43
42
|
*/
|
|
44
|
-
headerAlign?:
|
|
43
|
+
headerAlign?: 'start' | 'center' | 'end';
|
|
45
44
|
};
|
|
46
45
|
type PopoverSheetUnstyledProps = PopoverSheetPositionerProps & PopoverSheetContainerProps & {
|
|
47
46
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useRender } from '@base-ui/react/use-render';
|
|
2
2
|
import { ThemeTypes } from '@viraui/foundation/vira/types';
|
|
3
3
|
import type * as React from 'react';
|
|
4
|
-
|
|
4
|
+
/** Flex alignment on a physical axis; maps to `justify-content` or `align-items` by `direction`. */
|
|
5
|
+
type StackAlignment = NonNullable<React.CSSProperties['justifyContent'] | React.CSSProperties['alignItems']>;
|
|
5
6
|
type StackSpace = ThemeTypes['space'];
|
|
6
7
|
type StackAxisPadding = StackSpace | [StackSpace | 0, StackSpace | 0];
|
|
7
8
|
/**
|
|
@@ -59,7 +60,7 @@ export type StackProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
|
59
60
|
*
|
|
60
61
|
* Prefer this (with cross-axis stretch) so content-sized children like Button span a panel —
|
|
61
62
|
* do not add `width: 100%` CSS on those children.
|
|
62
|
-
* Use with `maxWidth` under a parent `hAlign="center"` for a fluid, capped, centered shell.
|
|
63
|
+
* Use with `maxWidth` under a parent `hAlign="safe center"` for a fluid, capped, centered shell.
|
|
63
64
|
* Orthogonal to `expandChildren` (self size vs children grow). Pair with `fullHeight` when the
|
|
64
65
|
* root must fill both parent axes.
|
|
65
66
|
*
|
|
@@ -91,12 +92,18 @@ export type StackProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
|
91
92
|
/**
|
|
92
93
|
* Aligns content on the horizontal axis from the consumer point of view.
|
|
93
94
|
*
|
|
95
|
+
* Accepts CSS `justify-content` / `align-items` values (which property is used
|
|
96
|
+
* depends on `direction`), including overflow keywords such as `safe center`.
|
|
97
|
+
*
|
|
94
98
|
* @defaultValue 'initial'
|
|
95
99
|
*/
|
|
96
100
|
hAlign?: StackAlignment;
|
|
97
101
|
/**
|
|
98
102
|
* Aligns content on the vertical axis from the consumer point of view.
|
|
99
103
|
*
|
|
104
|
+
* Accepts CSS `justify-content` / `align-items` values (which property is used
|
|
105
|
+
* depends on `direction`), including overflow keywords such as `safe center`.
|
|
106
|
+
*
|
|
100
107
|
* @defaultValue 'initial'
|
|
101
108
|
*/
|
|
102
109
|
vAlign?: StackAlignment;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { TabsRoot } from '@base-ui/react/tabs';
|
|
2
|
-
import { StackProps } from '..';
|
|
3
2
|
import { ButtonProps } from '../button/button';
|
|
4
3
|
import { TabsListProps } from './tabs-list';
|
|
5
4
|
import { TabsPanelProps } from './tabs-panel';
|
|
@@ -20,7 +19,7 @@ export type TabsProps = TabsRoot.Props & {
|
|
|
20
19
|
*
|
|
21
20
|
* @defaultValue 'start'
|
|
22
21
|
*/
|
|
23
|
-
listAlignment?:
|
|
22
|
+
listAlignment?: 'start' | 'center' | 'end' | 'stretch';
|
|
24
23
|
/**
|
|
25
24
|
* Shared visual size for tab items (`Button`) and the active indicator footprint.
|
|
26
25
|
*
|
package/dist/index.js
CHANGED
|
@@ -32,9 +32,25 @@ import { Elevator } from "./components/elevator/elevator.js";
|
|
|
32
32
|
import { Fieldset } from "./components/fieldset/fieldset.js";
|
|
33
33
|
import { FitText } from "./components/fit-text/fit-text.js";
|
|
34
34
|
import { Glow } from "./components/glow/glow.js";
|
|
35
|
+
import { angleToValue, arcBox, arcPath, clamp, cutValues, degreesToRadians, foldValue, polar, stepValues, valueToAngle, valueToTurnedAngle } from "./components/gauge/math.js";
|
|
36
|
+
import { arcScale } from "./components/gauge/scale.js";
|
|
37
|
+
import { DEFAULT_TRANSITION, cubicBezier, easingFunction, resolveTransition, springPhysics, stepSpring } from "./components/gauge/transition.js";
|
|
38
|
+
import { useAnimatedValue } from "./components/gauge/use-animated-value.js";
|
|
39
|
+
import { useGauge, useRoundGauge } from "./components/gauge/context.js";
|
|
40
|
+
import { Gauge } from "./components/gauge/gauge.js";
|
|
41
|
+
import { GaugeInset } from "./components/gauge/inset.js";
|
|
42
|
+
import { GaugeArc, GaugeStack, GaugeTrack, GaugeZones } from "./components/gauge/arcs.js";
|
|
43
|
+
import { GaugeControl } from "./components/gauge/control.js";
|
|
44
|
+
import { clockLabel, clockTime, compassLabel, durationLabel, fadeColor, fontFamily, fontWeight, zoneColor, zoneCutoffs } from "./components/gauge/utils.js";
|
|
45
|
+
import { GaugeMarks, GaugeTickFill, GaugeTickLabels, GaugeTicks } from "./components/gauge/ticks.js";
|
|
46
|
+
import { GaugeText, GaugeValue } from "./components/gauge/text.js";
|
|
47
|
+
import { GaugeDot } from "./components/gauge/dot.js";
|
|
48
|
+
import { GaugeTooltip } from "./components/gauge/tooltip.js";
|
|
49
|
+
import { GaugeHub, GaugeNeedle } from "./components/gauge/needle.js";
|
|
35
50
|
import { Grid } from "./components/grid/grid.js";
|
|
36
51
|
import { IconButton } from "./components/icon-button/icon-button.js";
|
|
37
52
|
import { IconButtonLink } from "./components/icon-button/icon-button-link.js";
|
|
53
|
+
import { IconMeter } from "./components/icon-meter/icon-meter.js";
|
|
38
54
|
import { LinearProgress } from "./components/linear-progress/linear-progress.js";
|
|
39
55
|
import { Masonry } from "./components/masonry/masonry.js";
|
|
40
56
|
import { MenuCheckboxItem } from "./components/menu/menu-checkbox-item.js";
|
|
@@ -74,4 +90,4 @@ import { ToggleTextButton } from "./components/toggle-text-button/toggle-text-bu
|
|
|
74
90
|
import { Typewriter } from "./components/typewriter/typewriter.js";
|
|
75
91
|
import { TooltipContent } from "./components/tooltip/tooltip-content.js";
|
|
76
92
|
import { Tooltip, TooltipProvider, TooltipTrigger } from "./components/tooltip/tooltip.js";
|
|
77
|
-
export { Accordion, Annotate, Autocomplete, Avatar, AvatarGroup, Badge, Beam, Bleed, BreakpointsProvider, Button, ButtonLink, Checkbox, CheckboxGroup, Chip, ClampText, Dialog, DialogClose, DialogIndent, DialogIndentBackground, DialogSheet, DialogTrigger, DirectionProvider, Disclosure, ELEVATION_DEFAULTS, Elevator, Fieldset, FitText, Glow, Grid, IconButton, IconButtonLink, LinearProgress, Masonry, Menu, MenuCheckboxItem, MenuGroup, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger, Meter, NumberField, OTPField, Popover, PopoverClose, PopoverDescription, PopoverSheet, PopoverTitle, PopoverTrigger, ProgressiveBlur, Prose, Radio, RadioGroup, Select, Separator, Shimmer, Skeleton, Slider, Spinner, Stack, StaticNoise, Surface, Switch, Tabs, Text, Textarea, Textfield, Title, Toast, ToggleButton, ToggleGroup, ToggleTextButton, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Typewriter, getElevationProps, useBreakpoints, useDirection };
|
|
93
|
+
export { Accordion, Annotate, Autocomplete, Avatar, AvatarGroup, Badge, Beam, Bleed, BreakpointsProvider, Button, ButtonLink, Checkbox, CheckboxGroup, Chip, ClampText, DEFAULT_TRANSITION, Dialog, DialogClose, DialogIndent, DialogIndentBackground, DialogSheet, DialogTrigger, DirectionProvider, Disclosure, ELEVATION_DEFAULTS, Elevator, Fieldset, FitText, Gauge, GaugeArc, GaugeControl, GaugeDot, GaugeHub, GaugeInset, GaugeMarks, GaugeNeedle, GaugeStack, GaugeText, GaugeTickFill, GaugeTickLabels, GaugeTicks, GaugeTooltip, GaugeTrack, GaugeValue, GaugeZones, Glow, Grid, IconButton, IconButtonLink, IconMeter, LinearProgress, Masonry, Menu, MenuCheckboxItem, MenuGroup, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger, Meter, NumberField, OTPField, Popover, PopoverClose, PopoverDescription, PopoverSheet, PopoverTitle, PopoverTrigger, ProgressiveBlur, Prose, Radio, RadioGroup, Select, Separator, Shimmer, Skeleton, Slider, Spinner, Stack, StaticNoise, Surface, Switch, Tabs, Text, Textarea, Textfield, Title, Toast, ToggleButton, ToggleGroup, ToggleTextButton, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Typewriter, angleToValue, arcBox, arcPath, arcScale, clamp, clockLabel, clockTime, compassLabel, cubicBezier, cutValues, degreesToRadians, durationLabel, easingFunction, fadeColor, foldValue, fontFamily, fontWeight, getElevationProps, polar, resolveTransition, springPhysics, stepSpring, stepValues, useAnimatedValue, useBreakpoints, useDirection, useGauge, useRoundGauge, valueToAngle, valueToTurnedAngle, zoneColor, zoneCutoffs };
|
|
@@ -7,6 +7,8 @@ import type * as React from 'react';
|
|
|
7
7
|
*/
|
|
8
8
|
export type ChromeIconProps = {
|
|
9
9
|
className?: string;
|
|
10
|
+
/** Paint for the glyph; defaults to `currentColor`. */
|
|
11
|
+
fill?: string;
|
|
10
12
|
size?: number | string;
|
|
11
13
|
};
|
|
12
14
|
export declare const ChromePlus: React.FC<ChromeIconProps>;
|
|
@@ -18,3 +20,5 @@ export declare const ChromeChevronDown: React.FC<ChromeIconProps>;
|
|
|
18
20
|
/** End-edge chevron (submenu). Mirror in RTL via CSS `:dir(rtl)`, not JS. */
|
|
19
21
|
export declare const ChromeChevronEnd: React.FC<ChromeIconProps>;
|
|
20
22
|
export declare const ChromeXmark: React.FC<ChromeIconProps>;
|
|
23
|
+
/** Default IconMeter glyph — solid star; honors `fill` for empty / half / full paint. */
|
|
24
|
+
export declare const ChromeStar: React.FC<ChromeIconProps>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
//#region src/internal/chrome-icons/chrome-icons.tsx
|
|
3
|
-
var ChromeSvg = ({ children, className, size = 24 }) => /* @__PURE__ */ jsx("svg", {
|
|
3
|
+
var ChromeSvg = ({ children, className, fill = "currentColor", size = 24 }) => /* @__PURE__ */ jsx("svg", {
|
|
4
4
|
"aria-hidden": "true",
|
|
5
5
|
className,
|
|
6
|
-
fill
|
|
6
|
+
fill,
|
|
7
7
|
height: size,
|
|
8
8
|
viewBox: "0 0 18 18",
|
|
9
9
|
width: size,
|
|
@@ -46,10 +46,18 @@ var ChromeChevronEnd = ({ className, size }) => /* @__PURE__ */ jsx(ChromeSvg, {
|
|
|
46
46
|
size,
|
|
47
47
|
children: /* @__PURE__ */ jsx("path", { d: "M13.28 8.47 7.03 2.22a.75.75 0 1 0-1.061 1.061l5.72 5.72-5.72 5.72a.75.75 0 0 0 1.06 1.061l6.25-6.25a.75.75 0 0 0 0-1.061z" })
|
|
48
48
|
});
|
|
49
|
-
var ChromeXmark = ({ className, size }) => /* @__PURE__ */ jsx(ChromeSvg, {
|
|
49
|
+
var ChromeXmark = ({ className, fill, size }) => /* @__PURE__ */ jsx(ChromeSvg, {
|
|
50
50
|
className,
|
|
51
|
+
fill,
|
|
51
52
|
size,
|
|
52
53
|
children: /* @__PURE__ */ jsx("path", { d: "M13.664 3.23a.783.783 0 1 1 1.107 1.106L10.107 9l4.664 4.664a.783.783 0 0 1-1.107 1.107L9 10.107 4.336 14.77a.783.783 0 1 1-1.107-1.107L7.893 9 3.23 4.336a.782.782 0 1 1 1.107-1.107L9 7.893z" })
|
|
53
54
|
});
|
|
55
|
+
/** Default IconMeter glyph — solid star; honors `fill` for empty / half / full paint. */
|
|
56
|
+
var ChromeStar = ({ className, fill, size }) => /* @__PURE__ */ jsx(ChromeSvg, {
|
|
57
|
+
className,
|
|
58
|
+
fill,
|
|
59
|
+
size,
|
|
60
|
+
children: /* @__PURE__ */ jsx("path", { d: "M16.713 7.017A.75.75 0 0 0 16 6.5h-4.803L9.713 1.953a.75.75 0 0 0-1.426 0L6.803 6.5H2a.75.75 0 0 0-.443 1.356l3.888 2.843-1.485 4.57a.751.751 0 0 0 1.155.838L9 13.284l3.885 2.823a.75.75 0 0 0 1.155-.839l-1.485-4.57 3.888-2.843a.75.75 0 0 0 .27-.838" })
|
|
61
|
+
});
|
|
54
62
|
//#endregion
|
|
55
|
-
export { ChromeCheck, ChromeChevronDown, ChromeChevronEnd, ChromeChevronExpandY, ChromeChevronUp, ChromeMinus, ChromePlus, ChromeXmark };
|
|
63
|
+
export { ChromeCheck, ChromeChevronDown, ChromeChevronEnd, ChromeChevronExpandY, ChromeChevronUp, ChromeMinus, ChromePlus, ChromeStar, ChromeXmark };
|