@schemavaults/ui 0.23.1 → 0.25.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.
@@ -116,3 +116,7 @@ export * from "./stat-card";
116
116
  export type * from "./stat-card";
117
117
  export * from "./timeline";
118
118
  export type * from "./timeline";
119
+ export * from "./rating";
120
+ export type * from "./rating";
121
+ export * from "./number-input";
122
+ export type * from "./number-input";
@@ -57,4 +57,6 @@ export * from "./banner";
57
57
  export * from "./empty-state";
58
58
  export * from "./stat-card";
59
59
  export * from "./timeline";
60
+ export * from "./rating";
61
+ export * from "./number-input";
60
62
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AAGzB,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,mBAAmB,CAAC;AAGlC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,UAAU,CAAC;AAGzB,cAAc,SAAS,CAAC;AAGxB,cAAc,kBAAkB,CAAC;AAGjC,cAAc,aAAa,CAAC;AAG5B,cAAc,kCAAkC,CAAC;AAGjD,cAAc,cAAc,CAAC;AAG7B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAExB,cAAc,WAAW,CAAC;AAG1B,cAAc,YAAY,CAAC;AAG3B,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,WAAW,CAAC;AAG1B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AAGxB,cAAc,aAAa,CAAC;AAG5B,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,cAAc,CAAC;AAG7B,cAAc,eAAe,CAAC;AAG9B,cAAc,YAAY,CAAC;AAG3B,cAAc,2BAA2B,CAAC;AAG1C,cAAc,kBAAkB,CAAC;AAGjC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,eAAe,CAAC;AAG9B,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC;AAG7B,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,eAAe,CAAC;AAG9B,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,UAAU,CAAC;AAGzB,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC;AAG7B,cAAc,cAAc,CAAC;AAG7B,cAAc,OAAO,CAAC;AAGtB,cAAc,eAAe,CAAC;AAG9B,cAAc,WAAW,CAAC;AAG1B,cAAc,UAAU,CAAC;AAGzB,cAAc,eAAe,CAAC;AAG9B,cAAc,aAAa,CAAC;AAG5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AAGzB,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,mBAAmB,CAAC;AAGlC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,UAAU,CAAC;AAGzB,cAAc,SAAS,CAAC;AAGxB,cAAc,kBAAkB,CAAC;AAGjC,cAAc,aAAa,CAAC;AAG5B,cAAc,kCAAkC,CAAC;AAGjD,cAAc,cAAc,CAAC;AAG7B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAExB,cAAc,WAAW,CAAC;AAG1B,cAAc,YAAY,CAAC;AAG3B,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,WAAW,CAAC;AAG1B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AAGxB,cAAc,aAAa,CAAC;AAG5B,cAAc,YAAY,CAAC;AAG3B,cAAc,YAAY,CAAC;AAG3B,cAAc,cAAc,CAAC;AAG7B,cAAc,eAAe,CAAC;AAG9B,cAAc,YAAY,CAAC;AAG3B,cAAc,2BAA2B,CAAC;AAG1C,cAAc,kBAAkB,CAAC;AAGjC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,eAAe,CAAC;AAG9B,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC;AAG7B,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,eAAe,CAAC;AAG9B,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,UAAU,CAAC;AAGzB,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC;AAG7B,cAAc,cAAc,CAAC;AAG7B,cAAc,OAAO,CAAC;AAGtB,cAAc,eAAe,CAAC;AAG9B,cAAc,WAAW,CAAC;AAG1B,cAAc,UAAU,CAAC;AAGzB,cAAc,eAAe,CAAC;AAG9B,cAAc,aAAa,CAAC;AAG5B,cAAc,YAAY,CAAC;AAG3B,cAAc,UAAU,CAAC;AAGzB,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { NumberInput, NumberInput as default, numberInputContainerVariants, } from "./number-input";
2
+ export type { NumberInputProps } from "./number-input";
3
+ export { numberInputSizeIds, numberInputVariantIds, numberInputStepperLayoutIds, } from "./number-input-variants";
4
+ export type { NumberInputSize, NumberInputVariant, NumberInputStepperLayout, } from "./number-input-variants";
@@ -0,0 +1,3 @@
1
+ export { NumberInput, NumberInput as default, numberInputContainerVariants, } from "./number-input";
2
+ export { numberInputSizeIds, numberInputVariantIds, numberInputStepperLayoutIds, } from "./number-input-variants";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/ui/number-input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,WAAW,IAAI,OAAO,EACtB,4BAA4B,GAC7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const numberInputSizeIds: readonly ["sm", "md", "lg"];
2
+ export type NumberInputSize = (typeof numberInputSizeIds)[number];
3
+ export declare const numberInputVariantIds: readonly ["default", "outline", "ghost"];
4
+ export type NumberInputVariant = (typeof numberInputVariantIds)[number];
5
+ export declare const numberInputStepperLayoutIds: readonly ["split", "stacked"];
6
+ export type NumberInputStepperLayout = (typeof numberInputStepperLayoutIds)[number];
@@ -0,0 +1,15 @@
1
+ export const numberInputSizeIds = [
2
+ "sm",
3
+ "md",
4
+ "lg",
5
+ ];
6
+ export const numberInputVariantIds = [
7
+ "default",
8
+ "outline",
9
+ "ghost",
10
+ ];
11
+ export const numberInputStepperLayoutIds = [
12
+ "split",
13
+ "stacked",
14
+ ];
15
+ //# sourceMappingURL=number-input-variants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input-variants.js","sourceRoot":"","sources":["../../../../src/components/ui/number-input/number-input-variants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI;IACJ,IAAI;IACJ,IAAI;CACgC,CAAC;AAGvC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,SAAS;IACT,SAAS;IACT,OAAO;CAC6B,CAAC;AAGvC,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,OAAO;IACP,SAAS;CAC2B,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { type VariantProps } from "class-variance-authority";
2
+ import { type ChangeEvent, type InputHTMLAttributes, type ReactElement, type ReactNode, type Ref } from "react";
3
+ import { type NumberInputStepperLayout } from "./number-input-variants";
4
+ declare const numberInputContainerVariants: (props?: ({
5
+ variant?: "default" | "ghost" | "outline" | null | undefined;
6
+ size?: "sm" | "lg" | "md" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ export interface NumberInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange" | "size" | "type" | "prefix">, VariantProps<typeof numberInputContainerVariants> {
9
+ /** Controlled numeric value. Use `null` to represent an empty input. */
10
+ value?: number | null;
11
+ /** Default uncontrolled value. */
12
+ defaultValue?: number | null;
13
+ /** Minimum allowed value. */
14
+ min?: number;
15
+ /** Maximum allowed value. */
16
+ max?: number;
17
+ /** Increment / decrement step. Defaults to 1. */
18
+ step?: number;
19
+ /** Number of decimal places to display & enforce. */
20
+ precision?: number;
21
+ /** Layout of the stepper buttons. */
22
+ stepperLayout?: NumberInputStepperLayout;
23
+ /** Hide the stepper buttons entirely. */
24
+ hideSteppers?: boolean;
25
+ /** Optional prefix shown inside the input (e.g. "$"). */
26
+ prefix?: ReactNode;
27
+ /** Optional suffix shown inside the input (e.g. "%"). */
28
+ suffix?: ReactNode;
29
+ /** Marks the input as invalid (sets aria-invalid and shows the destructive ring). */
30
+ invalid?: boolean;
31
+ /** Callback invoked with the parsed numeric value (or `null` when empty). */
32
+ onValueChange?: (value: number | null) => void;
33
+ /** Native onChange forwarded for compatibility. */
34
+ onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
35
+ /** Optional ref to the inner input element. */
36
+ inputRef?: Ref<HTMLInputElement>;
37
+ /** Optional class for the outer container. */
38
+ containerClassName?: string;
39
+ }
40
+ export declare function NumberInput({ value, defaultValue, min, max, step, precision, size, variant, stepperLayout, hideSteppers, prefix, suffix, invalid, disabled, readOnly, onValueChange, onChange, onBlur, onKeyDown, className, containerClassName, inputRef, id, name, placeholder, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }: NumberInputProps): ReactElement;
41
+ export declare namespace NumberInput {
42
+ var displayName: string;
43
+ }
44
+ export { numberInputContainerVariants };
45
+ export default NumberInput;
@@ -0,0 +1,173 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Minus, Plus, ChevronUp, ChevronDown } from "lucide-react";
4
+ import { cva } from "class-variance-authority";
5
+ import { useCallback, useEffect, useRef, useState, } from "react";
6
+ import { cn } from "../../../lib/utils";
7
+ const numberInputContainerVariants = cva("relative inline-flex items-stretch w-full rounded-md transition-colors focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 ring-offset-background aria-invalid:ring-destructive/40 aria-invalid:focus-within:ring-destructive overflow-hidden", {
8
+ variants: {
9
+ variant: {
10
+ default: "border border-input bg-background",
11
+ outline: "border border-primary/40 bg-background",
12
+ ghost: "border border-transparent bg-muted/40",
13
+ },
14
+ size: {
15
+ sm: "h-8 text-xs",
16
+ md: "h-10 text-sm",
17
+ lg: "h-12 text-base",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ variant: "default",
22
+ size: "md",
23
+ },
24
+ });
25
+ const stepperButtonSizeClasses = {
26
+ sm: "h-full w-7",
27
+ md: "h-full w-9",
28
+ lg: "h-full w-11",
29
+ };
30
+ const stackedStepperButtonSizeClasses = {
31
+ sm: "h-1/2 w-7",
32
+ md: "h-1/2 w-9",
33
+ lg: "h-1/2 w-11",
34
+ };
35
+ const stepperIconSizeClasses = {
36
+ sm: "h-3 w-3",
37
+ md: "h-4 w-4",
38
+ lg: "h-5 w-5",
39
+ };
40
+ const adornmentPaddingClasses = {
41
+ sm: "px-2 text-muted-foreground",
42
+ md: "px-3 text-muted-foreground",
43
+ lg: "px-3.5 text-muted-foreground",
44
+ };
45
+ const inputPaddingClasses = {
46
+ sm: "px-2 py-1",
47
+ md: "px-3 py-2",
48
+ lg: "px-4 py-2",
49
+ };
50
+ function clamp(value, min, max) {
51
+ let next = value;
52
+ if (typeof min === "number" && next < min)
53
+ next = min;
54
+ if (typeof max === "number" && next > max)
55
+ next = max;
56
+ return next;
57
+ }
58
+ function formatValue(value, precision) {
59
+ if (typeof precision === "number" && precision >= 0) {
60
+ return value.toFixed(precision);
61
+ }
62
+ return String(value);
63
+ }
64
+ export function NumberInput({ value, defaultValue, min, max, step = 1, precision, size, variant, stepperLayout = "split", hideSteppers = false, prefix, suffix, invalid = false, disabled = false, readOnly = false, onValueChange, onChange, onBlur, onKeyDown, className, containerClassName, inputRef, id, name, placeholder, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...rest }) {
65
+ const isControlled = value !== undefined;
66
+ const resolvedSize = size ?? "md";
67
+ const [internal, setInternal] = useState(defaultValue ?? null);
68
+ const [text, setText] = useState(() => {
69
+ const seed = isControlled ? value ?? null : defaultValue ?? null;
70
+ return seed === null || seed === undefined ? "" : formatValue(seed, precision);
71
+ });
72
+ const lastEmittedRef = useRef(undefined);
73
+ const current = isControlled ? value ?? null : internal;
74
+ useEffect(() => {
75
+ if (!isControlled)
76
+ return;
77
+ const next = value ?? null;
78
+ setText(next === null ? "" : formatValue(next, precision));
79
+ }, [isControlled, value, precision]);
80
+ const emit = useCallback((next) => {
81
+ if (lastEmittedRef.current === next)
82
+ return;
83
+ lastEmittedRef.current = next;
84
+ if (!isControlled)
85
+ setInternal(next);
86
+ onValueChange?.(next);
87
+ }, [isControlled, onValueChange]);
88
+ const applyDelta = useCallback((direction) => {
89
+ if (disabled || readOnly)
90
+ return;
91
+ const base = typeof current === "number" ? current : (min ?? 0);
92
+ const candidate = base + direction * step;
93
+ const clamped = clamp(candidate, min, max);
94
+ const rounded = typeof precision === "number"
95
+ ? Number(clamped.toFixed(precision))
96
+ : clamped;
97
+ setText(formatValue(rounded, precision));
98
+ emit(rounded);
99
+ }, [current, disabled, readOnly, min, max, step, precision, emit]);
100
+ const handleInputChange = useCallback((event) => {
101
+ const raw = event.target.value;
102
+ setText(raw);
103
+ onChange?.(event);
104
+ if (raw === "" || raw === "-") {
105
+ emit(null);
106
+ return;
107
+ }
108
+ const parsed = Number(raw);
109
+ if (!Number.isFinite(parsed))
110
+ return;
111
+ emit(parsed);
112
+ }, [emit, onChange]);
113
+ const handleBlur = useCallback((event) => {
114
+ onBlur?.(event);
115
+ if (text === "" || text === "-") {
116
+ emit(null);
117
+ setText("");
118
+ return;
119
+ }
120
+ const parsed = Number(text);
121
+ if (!Number.isFinite(parsed)) {
122
+ setText(current === null ? "" : formatValue(current, precision));
123
+ return;
124
+ }
125
+ const clamped = clamp(parsed, min, max);
126
+ const rounded = typeof precision === "number"
127
+ ? Number(clamped.toFixed(precision))
128
+ : clamped;
129
+ setText(formatValue(rounded, precision));
130
+ emit(rounded);
131
+ }, [text, onBlur, emit, min, max, precision, current]);
132
+ const handleKeyDown = useCallback((event) => {
133
+ onKeyDown?.(event);
134
+ if (event.defaultPrevented)
135
+ return;
136
+ if (event.key === "ArrowUp") {
137
+ event.preventDefault();
138
+ applyDelta(1);
139
+ }
140
+ else if (event.key === "ArrowDown") {
141
+ event.preventDefault();
142
+ applyDelta(-1);
143
+ }
144
+ }, [applyDelta, onKeyDown]);
145
+ const isAtMin = typeof min === "number" && typeof current === "number" && current <= min;
146
+ const isAtMax = typeof max === "number" && typeof current === "number" && current >= max;
147
+ const stepperDisabled = disabled || readOnly;
148
+ const renderStepperButton = (direction, layout) => {
149
+ const sizeClass = layout === "stacked"
150
+ ? stackedStepperButtonSizeClasses[resolvedSize]
151
+ : stepperButtonSizeClasses[resolvedSize];
152
+ const ariaLabel = direction === 1 ? "Increase value" : "Decrease value";
153
+ const Icon = layout === "stacked"
154
+ ? direction === 1
155
+ ? ChevronUp
156
+ : ChevronDown
157
+ : direction === 1
158
+ ? Plus
159
+ : Minus;
160
+ const disabledForDirection = stepperDisabled || (direction === 1 ? isAtMax : isAtMin);
161
+ return (_jsx("button", { type: "button", tabIndex: -1, "aria-label": ariaLabel, disabled: disabledForDirection, onClick: () => applyDelta(direction), "data-slot": "number-input-stepper", "data-direction": direction === 1 ? "up" : "down", className: cn("inline-flex items-center justify-center select-none shrink-0", "text-muted-foreground hover:text-foreground hover:bg-accent", "transition-colors", "disabled:opacity-40 disabled:pointer-events-none", "focus-visible:outline-none focus-visible:bg-accent focus-visible:text-accent-foreground", sizeClass), children: _jsx(Icon, { className: cn(layout === "stacked"
162
+ ? "h-3 w-3"
163
+ : stepperIconSizeClasses[resolvedSize]), "aria-hidden": "true" }) }));
164
+ };
165
+ const stepperDecrement = !hideSteppers ? renderStepperButton(-1, "split") : null;
166
+ const stepperIncrement = !hideSteppers ? renderStepperButton(1, "split") : null;
167
+ const stackedSteppers = !hideSteppers ? (_jsxs("div", { className: "flex flex-col items-stretch shrink-0 border-l border-input", "data-slot": "number-input-stepper-group", children: [renderStepperButton(1, "stacked"), _jsx("div", { className: "border-t border-input", "aria-hidden": "true" }), renderStepperButton(-1, "stacked")] })) : null;
168
+ return (_jsxs("div", { "data-slot": "number-input", "data-disabled": disabled || undefined, "data-readonly": readOnly || undefined, "aria-invalid": invalid || undefined, className: cn(numberInputContainerVariants({ variant, size: resolvedSize }), disabled && "opacity-50 cursor-not-allowed", containerClassName), children: [stepperLayout === "split" && stepperDecrement ? (_jsx("div", { className: "flex items-stretch border-r border-input", children: stepperDecrement })) : null, prefix !== undefined && prefix !== null ? (_jsx("span", { "data-slot": "number-input-prefix", className: cn("inline-flex items-center justify-center", adornmentPaddingClasses[resolvedSize]), children: prefix })) : null, _jsx("input", { ...rest, ref: inputRef, id: id, name: name, type: "text", inputMode: "decimal", role: "spinbutton", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": current ?? undefined, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": invalid || undefined, disabled: disabled, readOnly: readOnly, placeholder: placeholder, value: text, onChange: handleInputChange, onBlur: handleBlur, onKeyDown: handleKeyDown, className: cn("flex-1 min-w-0 bg-transparent text-center tabular-nums", "placeholder:text-muted-foreground", "focus:outline-none", "disabled:cursor-not-allowed", inputPaddingClasses[resolvedSize], className) }), suffix !== undefined && suffix !== null ? (_jsx("span", { "data-slot": "number-input-suffix", className: cn("inline-flex items-center justify-center", adornmentPaddingClasses[resolvedSize]), children: suffix })) : null, stepperLayout === "split" && stepperIncrement ? (_jsx("div", { className: "flex items-stretch border-l border-input", children: stepperIncrement })) : null, stepperLayout === "stacked" ? stackedSteppers : null] }));
169
+ }
170
+ NumberInput.displayName = "NumberInput";
171
+ export { numberInputContainerVariants };
172
+ export default NumberInput;
173
+ //# sourceMappingURL=number-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.js","sourceRoot":"","sources":["../../../../src/components/ui/number-input/number-input.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { Rating, Rating as default, ratingContainerVariants, } from "./rating";
2
+ export type { RatingProps } from "./rating";
3
+ export { ratingSizeIds, ratingColorIds } from "./rating-variants";
4
+ export type { RatingSize, RatingColor } from "./rating-variants";
@@ -0,0 +1,3 @@
1
+ export { Rating, Rating as default, ratingContainerVariants, } from "./rating";
2
+ export { ratingSizeIds, ratingColorIds } from "./rating-variants";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/ui/rating/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,MAAM,IAAI,OAAO,EACjB,uBAAuB,GACxB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const ratingSizeIds: readonly ["sm", "md", "lg", "xl"];
2
+ export type RatingSize = (typeof ratingSizeIds)[number];
3
+ export declare const ratingColorIds: readonly ["warning", "primary", "destructive", "foreground"];
4
+ export type RatingColor = (typeof ratingColorIds)[number];
@@ -0,0 +1,8 @@
1
+ export const ratingSizeIds = ["sm", "md", "lg", "xl"];
2
+ export const ratingColorIds = [
3
+ "warning",
4
+ "primary",
5
+ "destructive",
6
+ "foreground",
7
+ ];
8
+ //# sourceMappingURL=rating-variants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rating-variants.js","sourceRoot":"","sources":["../../../../src/components/ui/rating/rating-variants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAsC,CAAC;AAG3F,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS;IACT,SAAS;IACT,aAAa;IACb,YAAY;CACwB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { type VariantProps } from "class-variance-authority";
2
+ import { type ReactElement, type Ref } from "react";
3
+ import { ratingColorIds, ratingSizeIds, type RatingColor, type RatingSize } from "./rating-variants";
4
+ declare const ratingContainerVariants: (props?: ({
5
+ size?: "sm" | "lg" | "xl" | "md" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ export interface RatingProps extends VariantProps<typeof ratingContainerVariants> {
8
+ /** Current rating value (0..max). Supports fractional values when `allowHalf` is true. */
9
+ value?: number;
10
+ /** Default uncontrolled value. */
11
+ defaultValue?: number;
12
+ /** Maximum number of stars. Defaults to 5. */
13
+ max?: number;
14
+ /** Color used for filled portions of stars. */
15
+ color?: RatingColor;
16
+ /** When true, allow half-star granularity in interactive mode. */
17
+ allowHalf?: boolean;
18
+ /** Disable interaction; render as a display-only rating. */
19
+ readOnly?: boolean;
20
+ /** Disabled state — non-interactive and visually muted. */
21
+ disabled?: boolean;
22
+ /** Callback fired when the user selects a new value. */
23
+ onValueChange?: (value: number) => void;
24
+ /** Optional accessible label for the rating widget. */
25
+ "aria-label"?: string;
26
+ /** Optional id of an element labelling the rating widget. */
27
+ "aria-labelledby"?: string;
28
+ /** Custom class name forwarded to the root container. */
29
+ className?: string;
30
+ /** Optional ref to the root container. */
31
+ ref?: Ref<HTMLDivElement>;
32
+ /** Optional name to render a hidden form input (helpful for native form submission). */
33
+ name?: string;
34
+ }
35
+ export declare function Rating({ value, defaultValue, max, size, color, allowHalf, readOnly, disabled, onValueChange, className, ref, name, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: RatingProps): ReactElement;
36
+ export declare namespace Rating {
37
+ var displayName: string;
38
+ }
39
+ export { ratingContainerVariants, ratingColorIds, ratingSizeIds };
40
+ export type { RatingColor, RatingSize };
41
+ export default Rating;
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Star } from "lucide-react";
4
+ import { cva } from "class-variance-authority";
5
+ import { useCallback, useMemo, useState, } from "react";
6
+ import { cn } from "../../../lib/utils";
7
+ import { ratingColorIds, ratingSizeIds, } from "./rating-variants";
8
+ const ratingContainerVariants = cva("inline-flex items-center align-middle text-muted-foreground/40", {
9
+ variants: {
10
+ size: {
11
+ sm: "gap-0.5",
12
+ md: "gap-1",
13
+ lg: "gap-1.5",
14
+ xl: "gap-2",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ size: "md",
19
+ },
20
+ });
21
+ const starSizeClasses = {
22
+ sm: "size-3.5",
23
+ md: "size-5",
24
+ lg: "size-6",
25
+ xl: "size-8",
26
+ };
27
+ const filledColorClasses = {
28
+ warning: "text-warning",
29
+ primary: "text-primary",
30
+ destructive: "text-destructive",
31
+ foreground: "text-foreground",
32
+ };
33
+ function clampValue(value, max) {
34
+ if (Number.isNaN(value))
35
+ return 0;
36
+ if (value < 0)
37
+ return 0;
38
+ if (value > max)
39
+ return max;
40
+ return value;
41
+ }
42
+ export function Rating({ value, defaultValue, max = 5, size, color = "warning", allowHalf = false, readOnly = false, disabled = false, onValueChange, className, ref, name, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }) {
43
+ const isControlled = value !== undefined;
44
+ const [internal, setInternal] = useState(clampValue(defaultValue ?? 0, max));
45
+ const [hover, setHover] = useState(null);
46
+ const current = clampValue(isControlled ? value : internal, max);
47
+ const display = hover !== null ? hover : current;
48
+ const interactive = !readOnly && !disabled;
49
+ const updateValue = useCallback((next) => {
50
+ const clamped = clampValue(next, max);
51
+ if (!isControlled)
52
+ setInternal(clamped);
53
+ onValueChange?.(clamped);
54
+ }, [isControlled, max, onValueChange]);
55
+ const handleClick = useCallback((event, index) => {
56
+ if (!interactive)
57
+ return;
58
+ let next = index + 1;
59
+ if (allowHalf) {
60
+ const target = event.currentTarget;
61
+ const rect = target.getBoundingClientRect();
62
+ const isLeftHalf = event.clientX - rect.left < rect.width / 2;
63
+ next = index + (isLeftHalf ? 0.5 : 1);
64
+ }
65
+ // Toggle off when clicking the currently selected single-unit value.
66
+ if (!allowHalf && current === next) {
67
+ next = next - 1;
68
+ }
69
+ updateValue(next);
70
+ }, [interactive, allowHalf, current, updateValue]);
71
+ const handleKeyDown = useCallback((event) => {
72
+ if (!interactive)
73
+ return;
74
+ const step = allowHalf ? 0.5 : 1;
75
+ switch (event.key) {
76
+ case "ArrowRight":
77
+ case "ArrowUp":
78
+ event.preventDefault();
79
+ updateValue(current + step);
80
+ break;
81
+ case "ArrowLeft":
82
+ case "ArrowDown":
83
+ event.preventDefault();
84
+ updateValue(current - step);
85
+ break;
86
+ case "Home":
87
+ event.preventDefault();
88
+ updateValue(0);
89
+ break;
90
+ case "End":
91
+ event.preventDefault();
92
+ updateValue(max);
93
+ break;
94
+ default:
95
+ break;
96
+ }
97
+ }, [interactive, allowHalf, current, max, updateValue]);
98
+ const stars = useMemo(() => Array.from({ length: max }, (_, i) => i), [max]);
99
+ const starClass = size ? starSizeClasses[size] : starSizeClasses.md;
100
+ const filledClass = filledColorClasses[color];
101
+ return (_jsxs("div", { ref: ref, role: interactive ? "slider" : "img", "aria-label": ariaLabel ?? `Rating: ${current} out of ${max}`, "aria-labelledby": ariaLabelledBy, "aria-valuemin": interactive ? 0 : undefined, "aria-valuemax": interactive ? max : undefined, "aria-valuenow": interactive ? current : undefined, "aria-valuetext": `${current} out of ${max}`, "aria-readonly": readOnly || undefined, "aria-disabled": disabled || undefined, tabIndex: interactive ? 0 : -1, onKeyDown: handleKeyDown, "data-slot": "rating", className: cn(ratingContainerVariants({ size }), interactive
102
+ ? "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-md"
103
+ : "cursor-default", disabled && "opacity-50 pointer-events-none", className), children: [stars.map((index) => {
104
+ const fill = Math.max(0, Math.min(1, display - index));
105
+ const filledPct = `${Math.round(fill * 100)}%`;
106
+ return (_jsxs("button", { type: "button", tabIndex: -1, disabled: !interactive, "aria-hidden": "true", "data-slot": "rating-star", "data-index": index, "data-fill": fill, onClick: (e) => handleClick(e, index), onMouseMove: (e) => {
107
+ if (!interactive)
108
+ return;
109
+ if (allowHalf) {
110
+ const rect = e.currentTarget.getBoundingClientRect();
111
+ const isLeftHalf = e.clientX - rect.left < rect.width / 2;
112
+ setHover(index + (isLeftHalf ? 0.5 : 1));
113
+ }
114
+ else {
115
+ setHover(index + 1);
116
+ }
117
+ }, onMouseLeave: () => setHover(null), onFocus: () => undefined, className: cn("relative inline-flex items-center justify-center bg-transparent border-0 p-0 m-0", "transition-transform duration-150", interactive && "hover:scale-110 active:scale-95", !interactive && "cursor-default"), children: [_jsx(Star, { className: cn(starClass, "stroke-current fill-none"), "aria-hidden": "true" }), _jsx("span", { "aria-hidden": "true", className: cn("pointer-events-none absolute inset-0 inline-flex items-center justify-center overflow-hidden", filledClass), style: { clipPath: `inset(0 ${100 - parseInt(filledPct, 10)}% 0 0)` }, children: _jsx(Star, { className: cn(starClass, "fill-current stroke-current"), "aria-hidden": "true" }) })] }, index));
118
+ }), name ? (_jsx("input", { type: "hidden", name: name, value: current, readOnly: true })) : null] }));
119
+ }
120
+ Rating.displayName = "Rating";
121
+ export { ratingContainerVariants, ratingColorIds, ratingSizeIds };
122
+ export default Rating;
123
+ //# sourceMappingURL=rating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rating.js","sourceRoot":"","sources":["../../../../src/components/ui/rating/rating.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schemavaults/ui",
3
- "version": "0.23.1",
3
+ "version": "0.25.1",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "description": "React.js UI components for SchemaVaults frontend applications",