@kobalte/core
Version:
Unstyled components and primitives for building accessible web apps and design systems with SolidJS.
148 lines (143 loc) • 4.41 kB
JavaScript
import { createNumberFormatter } from './XHJPQEZP.js';
import { createRegisterId } from './E4R2EMM4.js';
import { Polymorphic } from './6Y7B2NEO.js';
import { createComponent, mergeProps, memo } from 'solid-js/web';
import { createContext, useContext, splitProps, createEffect, onCleanup, createUniqueId, createSignal, createMemo } from 'solid-js';
import { combineStyle } from '@solid-primitives/props';
import { mergeDefaultProps, createGenerateId, clamp } from '@kobalte/utils';
var MeterContext = createContext();
function useMeterContext() {
const context = useContext(MeterContext);
if (context === void 0) {
throw new Error("[kobalte]: `useMeterContext` must be used within a `Meter.Root` component");
}
return context;
}
// src/meter/meter-fill.tsx
function MeterFill(props) {
const context = useMeterContext();
const [local, others] = splitProps(props, ["style"]);
return createComponent(Polymorphic, mergeProps({
as: "div",
get style() {
return combineStyle({
"--kb-meter-fill-width": context.meterFillWidth()
}, local.style);
}
}, () => context.dataset(), others));
}
function MeterLabel(props) {
const context = useMeterContext();
const mergedProps = mergeDefaultProps({
id: context.generateId("label")
}, props);
const [local, others] = splitProps(mergedProps, ["id"]);
createEffect(() => onCleanup(context.registerLabelId(local.id)));
return createComponent(Polymorphic, mergeProps({
as: "span",
get id() {
return local.id;
}
}, () => context.dataset(), others));
}
function MeterRoot(props) {
const defaultId = `meter-${createUniqueId()}`;
const mergedProps = mergeDefaultProps({
id: defaultId,
value: 0,
minValue: 0,
maxValue: 100,
role: "meter",
indeterminate: false
}, props);
const [local, others] = splitProps(mergedProps, ["value", "minValue", "maxValue", "getValueLabel", "role", "aria-valuetext", "aria-labelledby", "aria-valuemax", "aria-valuemin", "aria-valuenow", "indeterminate"]);
const [labelId, setLabelId] = createSignal();
const defaultFormatter = createNumberFormatter(() => ({
style: "percent"
}));
const value = () => {
return clamp(local.value, local.minValue, local.maxValue);
};
const valuePercent = () => {
return (value() - local.minValue) / (local.maxValue - local.minValue);
};
const valueLabel = () => {
if (local.indeterminate) {
return void 0;
}
if (local.getValueLabel) {
return local.getValueLabel({
value: value(),
min: local.minValue,
max: local.maxValue
});
}
return defaultFormatter().format(valuePercent());
};
const meterFillWidth = () => {
return `${valuePercent() * 100}%`;
};
const dataset = createMemo(() => {
return {};
});
const context = {
dataset,
value,
valuePercent,
valueLabel,
labelId,
meterFillWidth,
generateId: createGenerateId(() => others.id),
registerLabelId: createRegisterId(setLabelId)
};
return createComponent(MeterContext.Provider, {
value: context,
get children() {
return createComponent(Polymorphic, mergeProps({
as: "div",
get role() {
return local.role || "meter";
},
get ["aria-valuenow"]() {
return memo(() => !!local.indeterminate)() ? void 0 : value();
},
get ["aria-valuemin"]() {
return local.minValue;
},
get ["aria-valuemax"]() {
return local.maxValue;
},
get ["aria-valuetext"]() {
return valueLabel();
},
get ["aria-labelledby"]() {
return labelId();
}
}, dataset, others));
}
});
}
function MeterTrack(props) {
const context = useMeterContext();
return createComponent(Polymorphic, mergeProps({
as: "div"
}, () => context.dataset(), props));
}
function MeterValueLabel(props) {
const context = useMeterContext();
return createComponent(Polymorphic, mergeProps({
as: "div"
}, () => context.dataset(), props, {
get children() {
return context.valueLabel();
}
}));
}
// src/meter/index.tsx
var Meter = Object.assign(MeterRoot, {
Fill: MeterFill,
Label: MeterLabel,
Track: MeterTrack,
ValueLabel: MeterValueLabel
});
export { Meter, MeterFill, MeterLabel, MeterRoot, MeterTrack, MeterValueLabel, useMeterContext };