@civitai/blocks-react 0.22.0 → 0.23.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/README.md CHANGED
@@ -300,6 +300,7 @@ import { useBlockContext } from '@civitai/blocks-react';
300
300
  import {
301
301
  Button, TextInput, Textarea, Card, Stack, Group,
302
302
  Alert, Loader, Badge, Modal,
303
+ Slider, NumberInput, Select, Collapse,
303
304
  } from '@civitai/blocks-react/ui';
304
305
 
305
306
  export function App() {
@@ -338,6 +339,10 @@ export function App() {
338
339
  | `Loader` | CSS-keyframe spinner; `size`, `color`; `role="status"`. |
339
340
  | `Badge` | `variant`, `size`, `color`. |
340
341
  | `Modal` | `opened` + `onClose`, `title`, `size`; `role="dialog"` + `aria-modal`, Escape- and overlay-click-to-close, focuses the panel on open and restores focus on close. |
342
+ | `Slider` | controlled range (`value: number`, `onChange`, `min`/`max`/`step`, `showValue`). Native `input[type=range]` — keyboard-operable, implicit `role="slider"`; accent tracks `--ci-color-primary`. Same `label`/`description`/`error`/`required` wiring as `TextInput`. |
343
+ | `NumberInput` | controlled numeric (`value: number \| null`, `onChange`, `min`/`max`/`step`). Rejects non-numeric (never emits `NaN`), clamps to `[min,max]` on blur, empty → `null`. Same label/description/error wiring. |
344
+ | `Select` | controlled dropdown (`value: string`, `onChange`, `options: {value,label,disabled}[]` **or** `<option>` children, `placeholder`). Native `<select>`, `role="combobox"`. Same label/description/error wiring. |
345
+ | `Collapse` | controlled disclosure (`open` + `onOpenChange`, `title`, `disabled`) for the "advanced params reveal". `aria-expanded` + `aria-controls`; content region `role="region"`, `hidden` when closed. |
341
346
 
342
347
  Each component forwards `className` + `style`, forwards a `ref` to its DOM
343
348
  node (where it wraps one), and carries a `data-civitai-ui="<name>"` hook. Need
@@ -0,0 +1,24 @@
1
+ export interface CollapseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'title'> {
2
+ /** Whether the content is expanded (controlled). */
3
+ open: boolean;
4
+ /** Fires with the requested next open state when the trigger is activated. */
5
+ onOpenChange: (open: boolean) => void;
6
+ /** Trigger label (the "Advanced" toggle text). */
7
+ title: React.ReactNode;
8
+ /** Disable the trigger. */
9
+ disabled?: boolean;
10
+ /** Class on the wrapping element. */
11
+ className?: string;
12
+ /** Content revealed when `open`. */
13
+ children?: React.ReactNode;
14
+ }
15
+ /**
16
+ * Controlled disclosure — the "advanced params reveal" pattern. The `<button>`
17
+ * trigger (ref-forwarded) carries `aria-expanded` + `aria-controls` pointing at
18
+ * the content region (`role="region"` + `aria-labelledby` back to the trigger),
19
+ * so it is keyboard-operable and correctly announced. Collapsed content is
20
+ * `hidden`, so it leaves the a11y tree and the tab order. Controlled like the
21
+ * rest of the pack (`open` + `onOpenChange`). Auto-themed.
22
+ */
23
+ export declare const Collapse: import("react").ForwardRefExoticComponent<CollapseProps & import("react").RefAttributes<HTMLButtonElement>>;
24
+ //# sourceMappingURL=Collapse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collapse.d.ts","sourceRoot":"","sources":["../../src/ui/Collapse.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,aACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACxE,oDAAoD;IACpD,IAAI,EAAE,OAAO,CAAC;IACd,8EAA8E;IAC9E,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,kDAAkD;IAClD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,6GA6CpB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useId } from 'react';
3
+ import { useBlocksStyles } from './styles.js';
4
+ /**
5
+ * Controlled disclosure — the "advanced params reveal" pattern. The `<button>`
6
+ * trigger (ref-forwarded) carries `aria-expanded` + `aria-controls` pointing at
7
+ * the content region (`role="region"` + `aria-labelledby` back to the trigger),
8
+ * so it is keyboard-operable and correctly announced. Collapsed content is
9
+ * `hidden`, so it leaves the a11y tree and the tab order. Controlled like the
10
+ * rest of the pack (`open` + `onOpenChange`). Auto-themed.
11
+ */
12
+ export const Collapse = forwardRef(function Collapse({ open, onOpenChange, title, disabled = false, className, children, id, ...rest }, ref) {
13
+ useBlocksStyles();
14
+ const reactId = useId();
15
+ const rootId = id ?? `ci-collapse-${reactId}`;
16
+ const triggerId = `${rootId}-trigger`;
17
+ const regionId = `${rootId}-region`;
18
+ return (_jsxs("div", { ...rest, className: className, "data-civitai-ui": "collapse", "data-open": open ? 'true' : undefined, children: [_jsxs("button", { ref: ref, id: triggerId, type: "button", "data-civitai-ui-collapse-trigger": true, "aria-expanded": open, "aria-controls": regionId, disabled: disabled, onClick: () => onOpenChange(!open), children: [_jsx("span", { "data-civitai-ui-collapse-chevron": true, "aria-hidden": "true", children: open ? '▾' : '▸' }), _jsx("span", { children: title })] }), _jsx("div", { id: regionId, role: "region", "aria-labelledby": triggerId, "data-civitai-ui-collapse-region": true, hidden: !open, children: children })] }));
19
+ });
20
+ //# sourceMappingURL=Collapse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collapse.js","sourceRoot":"","sources":["../../src/ui/Collapse.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAkB9C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,SAAS,QAAQ,CACf,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EACjF,GAAG;IAEH,eAAe,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,EAAE,IAAI,eAAe,OAAO,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,GAAG,MAAM,UAAU,CAAC;IACtC,MAAM,QAAQ,GAAG,GAAG,MAAM,SAAS,CAAC;IAEpC,OAAO,CACL,kBACM,IAAI,EACR,SAAS,EAAE,SAAS,qBACJ,UAAU,eACf,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,aAEpC,kBACE,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,SAAS,EACb,IAAI,EAAC,QAAQ,6DAEE,IAAI,mBACJ,QAAQ,EACvB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,aAElC,wEAAmD,MAAM,YACtD,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GACZ,EACP,yBAAO,KAAK,GAAQ,IACb,EACT,cACE,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAC,QAAQ,qBACI,SAAS,2CAE1B,MAAM,EAAE,CAAC,IAAI,YAEZ,QAAQ,GACL,IACF,CACP,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -0,0 +1,39 @@
1
+ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'defaultValue' | 'type' | 'size' | 'min' | 'max' | 'step'> {
2
+ /** Current value (controlled). `null` renders an empty field. */
3
+ value: number | null;
4
+ /** Fires with the parsed number, or `null` when the field is cleared. */
5
+ onChange: (value: number | null) => void;
6
+ /** Lower bound. Enforced (clamped) on blur. */
7
+ min?: number;
8
+ /** Upper bound. Enforced (clamped) on blur. */
9
+ max?: number;
10
+ /** Step increment for the native spinner. Default `1`. */
11
+ step?: number;
12
+ /** Visible field label, rendered in a `<label>` linked to the input. */
13
+ label?: React.ReactNode;
14
+ /** Helper text under the label, linked via `aria-describedby`. */
15
+ description?: React.ReactNode;
16
+ /** Error message. Sets `aria-invalid`, announces (`role="alert"`), links it. */
17
+ error?: React.ReactNode;
18
+ /** Mark required: shows an asterisk and sets the native `required`. */
19
+ required?: boolean;
20
+ /** Class on the wrapping element. */
21
+ className?: string;
22
+ /** Class applied to the native `<input>`. */
23
+ inputClassName?: string;
24
+ }
25
+ /**
26
+ * Labeled numeric input (steps / cfg / quantity params). Wraps a native
27
+ * `input[type="number"]` (ref-forwarded).
28
+ *
29
+ * - Fully controlled by `value` (`number | null`; `null` === empty).
30
+ * - **Rejects non-numeric** input: a keystroke that does not parse to a finite
31
+ * number is ignored (no `onChange`), so the model value never goes NaN.
32
+ * - **Clamps to `[min, max]` on blur** — free typing is allowed while focused
33
+ * (so "12" survives a `min` of 10 mid-type), then the committed value is
34
+ * corrected to the nearest bound.
35
+ *
36
+ * Same label/description/error a11y wiring as `<TextInput>`. Auto-themed.
37
+ */
38
+ export declare const NumberInput: import("react").ForwardRefExoticComponent<NumberInputProps & import("react").RefAttributes<HTMLInputElement>>;
39
+ //# sourceMappingURL=NumberInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberInput.d.ts","sourceRoot":"","sources":["../../src/ui/NumberInput.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBACf,SAAQ,IAAI,CACV,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CACjF;IACD,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,yEAAyE;IACzE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,kEAAkE;IAClE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,gFAAgF;IAChF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AASD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,+GAiGvB,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useId } from 'react';
3
+ import { useBlocksStyles } from './styles.js';
4
+ function clamp(n, min, max) {
5
+ let out = n;
6
+ if (min !== undefined && out < min)
7
+ out = min;
8
+ if (max !== undefined && out > max)
9
+ out = max;
10
+ return out;
11
+ }
12
+ /**
13
+ * Labeled numeric input (steps / cfg / quantity params). Wraps a native
14
+ * `input[type="number"]` (ref-forwarded).
15
+ *
16
+ * - Fully controlled by `value` (`number | null`; `null` === empty).
17
+ * - **Rejects non-numeric** input: a keystroke that does not parse to a finite
18
+ * number is ignored (no `onChange`), so the model value never goes NaN.
19
+ * - **Clamps to `[min, max]` on blur** — free typing is allowed while focused
20
+ * (so "12" survives a `min` of 10 mid-type), then the committed value is
21
+ * corrected to the nearest bound.
22
+ *
23
+ * Same label/description/error a11y wiring as `<TextInput>`. Auto-themed.
24
+ */
25
+ export const NumberInput = forwardRef(function NumberInput({ value, onChange, min, max, step = 1, label, description, error, required, className, inputClassName, id, style, onBlur, ...rest }, ref) {
26
+ useBlocksStyles();
27
+ const reactId = useId();
28
+ const inputId = id ?? `ci-number-${reactId}`;
29
+ const descId = `${inputId}-desc`;
30
+ const errId = `${inputId}-err`;
31
+ const hasError = error != null && error !== false;
32
+ const describedBy = [description != null ? descId : null, hasError ? errId : null]
33
+ .filter(Boolean)
34
+ .join(' ') || undefined;
35
+ return (_jsxs("div", { className: className, "data-civitai-ui": "number-input", "data-invalid": hasError ? 'true' : undefined, style: style, children: [label != null ? (_jsxs("label", { htmlFor: inputId, "data-civitai-ui-label": true, children: [label, required ? (_jsx("span", { "data-civitai-ui-required": true, "aria-hidden": "true", children: "*" })) : null] })) : null, description != null ? (_jsx("span", { id: descId, "data-civitai-ui-description": true, children: description })) : null, _jsx("input", { ref: ref, ...rest, id: inputId, type: "number", inputMode: "decimal", className: inputClassName, "data-civitai-ui-control": true, min: min, max: max, step: step, required: required, value: value ?? '', "aria-invalid": hasError || undefined, "aria-describedby": describedBy, "aria-required": required || undefined, onChange: (e) => {
36
+ const raw = e.target.value;
37
+ if (raw === '') {
38
+ onChange(null);
39
+ return;
40
+ }
41
+ const parsed = Number(raw);
42
+ // Reject non-numeric — leave the model value untouched.
43
+ if (!Number.isFinite(parsed))
44
+ return;
45
+ onChange(parsed);
46
+ }, onBlur: (e) => {
47
+ if (value !== null) {
48
+ const clamped = clamp(value, min, max);
49
+ if (clamped !== value)
50
+ onChange(clamped);
51
+ }
52
+ onBlur?.(e);
53
+ } }), hasError ? (_jsx("span", { id: errId, "data-civitai-ui-error": true, role: "alert", children: error })) : null] }));
54
+ });
55
+ //# sourceMappingURL=NumberInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberInput.js","sourceRoot":"","sources":["../../src/ui/NumberInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA+B9C,SAAS,KAAK,CAAC,CAAS,EAAE,GAAY,EAAE,GAAY;IAClD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG;QAAE,GAAG,GAAG,GAAG,CAAC;IAC9C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG;QAAE,GAAG,GAAG,GAAG,CAAC;IAC9C,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CACnC,SAAS,WAAW,CAClB,EACE,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,EACH,IAAI,GAAG,CAAC,EACR,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,SAAS,EACT,cAAc,EACd,EAAE,EACF,KAAK,EACL,MAAM,EACN,GAAG,IAAI,EACR,EACD,GAAG;IAEH,eAAe,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,EAAE,IAAI,aAAa,OAAO,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC;IACjC,MAAM,KAAK,GAAG,GAAG,OAAO,MAAM,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC;IAClD,MAAM,WAAW,GACf,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;SAC3D,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;IAE5B,OAAO,CACL,eACE,SAAS,EAAE,SAAS,qBACJ,cAAc,kBAChB,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC3C,KAAK,EAAE,KAAK,aAEX,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CACf,iBAAO,OAAO,EAAE,OAAO,4CACpB,KAAK,EACL,QAAQ,CAAC,CAAC,CAAC,CACV,gEAA2C,MAAM,kBAE1C,CACR,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAC,CAAC,CAAC,IAAI,EACP,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,CACrB,eAAM,EAAE,EAAE,MAAM,iDACb,WAAW,GACP,CACR,CAAC,CAAC,CAAC,IAAI,EACR,gBACE,GAAG,EAAE,GAAG,KACJ,IAAI,EACR,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,SAAS,EACnB,SAAS,EAAE,cAAc,mCAEzB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,IAAI,EAAE,kBACJ,QAAQ,IAAI,SAAS,sBACjB,WAAW,mBACd,QAAQ,IAAI,SAAS,EACpC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;oBACd,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC3B,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;wBACf,QAAQ,CAAC,IAAI,CAAC,CAAC;wBACf,OAAO;oBACT,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC3B,wDAAwD;oBACxD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAAE,OAAO;oBACrC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACnB,CAAC,EACD,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;oBACZ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;wBACnB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;wBACvC,IAAI,OAAO,KAAK,KAAK;4BAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;oBAC3C,CAAC;oBACD,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;gBACd,CAAC,GACD,EACD,QAAQ,CAAC,CAAC,CAAC,CACV,eAAM,EAAE,EAAE,KAAK,iCAAwB,IAAI,EAAC,OAAO,YAChD,KAAK,GACD,CACR,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -0,0 +1,42 @@
1
+ /** One option for the declarative `options` prop. */
2
+ export interface SelectOption {
3
+ value: string;
4
+ label: React.ReactNode;
5
+ disabled?: boolean;
6
+ }
7
+ export interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'onChange' | 'value' | 'defaultValue' | 'size'> {
8
+ /** Current value (controlled). */
9
+ value: string;
10
+ /** Fires with the selected option's value. */
11
+ onChange: (value: string) => void;
12
+ /** Declarative options. Alternative to `<option>` `children`. */
13
+ options?: SelectOption[];
14
+ /** `<option>` children — use instead of `options` for full control. */
15
+ children?: React.ReactNode;
16
+ /**
17
+ * Placeholder shown as a disabled, empty-valued leading option. Rendered
18
+ * only alongside `options`.
19
+ */
20
+ placeholder?: string;
21
+ /** Visible field label, rendered in a `<label>` linked to the select. */
22
+ label?: React.ReactNode;
23
+ /** Helper text under the label, linked via `aria-describedby`. */
24
+ description?: React.ReactNode;
25
+ /** Error message. Sets `aria-invalid`, announces (`role="alert"`), links it. */
26
+ error?: React.ReactNode;
27
+ /** Mark required: shows an asterisk and sets the native `required`. */
28
+ required?: boolean;
29
+ /** Class on the wrapping element. */
30
+ className?: string;
31
+ /** Class applied to the native `<select>`. */
32
+ selectClassName?: string;
33
+ }
34
+ /**
35
+ * Labeled dropdown (sampler / base-model / workflow-type). Wraps a native
36
+ * `<select>` (ref-forwarded) — keyboard-operable and announced as a combobox
37
+ * with its `<label>` for free. Supply choices via `options` or `<option>`
38
+ * `children`. Same label/description/error a11y wiring as `<TextInput>`.
39
+ * Auto-themed.
40
+ */
41
+ export declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLSelectElement>>;
42
+ //# sourceMappingURL=Select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/ui/Select.tsx"],"names":[],"mappings":"AAIA,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CACV,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC7C,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,CAC/C;IACD,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,iEAAiE;IACjE,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,kEAAkE;IAClE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,gFAAgF;IAChF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,2GAyFjB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { forwardRef, useId } from 'react';
3
+ import { useBlocksStyles } from './styles.js';
4
+ /**
5
+ * Labeled dropdown (sampler / base-model / workflow-type). Wraps a native
6
+ * `<select>` (ref-forwarded) — keyboard-operable and announced as a combobox
7
+ * with its `<label>` for free. Supply choices via `options` or `<option>`
8
+ * `children`. Same label/description/error a11y wiring as `<TextInput>`.
9
+ * Auto-themed.
10
+ */
11
+ export const Select = forwardRef(function Select({ value, onChange, options, children, placeholder, label, description, error, required, className, selectClassName, id, style, ...rest }, ref) {
12
+ useBlocksStyles();
13
+ const reactId = useId();
14
+ const selectId = id ?? `ci-select-${reactId}`;
15
+ const descId = `${selectId}-desc`;
16
+ const errId = `${selectId}-err`;
17
+ const hasError = error != null && error !== false;
18
+ const describedBy = [description != null ? descId : null, hasError ? errId : null]
19
+ .filter(Boolean)
20
+ .join(' ') || undefined;
21
+ return (_jsxs("div", { className: className, "data-civitai-ui": "select", "data-invalid": hasError ? 'true' : undefined, style: style, children: [label != null ? (_jsxs("label", { htmlFor: selectId, "data-civitai-ui-label": true, children: [label, required ? (_jsx("span", { "data-civitai-ui-required": true, "aria-hidden": "true", children: "*" })) : null] })) : null, description != null ? (_jsx("span", { id: descId, "data-civitai-ui-description": true, children: description })) : null, _jsx("select", { ref: ref, ...rest, id: selectId, className: selectClassName, "data-civitai-ui-control": true, required: required, value: value, "aria-invalid": hasError || undefined, "aria-describedby": describedBy, "aria-required": required || undefined, onChange: (e) => onChange(e.target.value), children: options ? (_jsxs(_Fragment, { children: [placeholder !== undefined ? (_jsx("option", { value: "", disabled: true, children: placeholder })) : null, options.map((opt) => (_jsx("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value)))] })) : (children) }), hasError ? (_jsx("span", { id: errId, "data-civitai-ui-error": true, role: "alert", children: error })) : null] }));
22
+ });
23
+ //# sourceMappingURL=Select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.js","sourceRoot":"","sources":["../../src/ui/Select.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAyC9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CAC9E,EACE,KAAK,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,WAAW,EACX,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,SAAS,EACT,eAAe,EACf,EAAE,EACF,KAAK,EACL,GAAG,IAAI,EACR,EACD,GAAG;IAEH,eAAe,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,QAAQ,GAAG,EAAE,IAAI,aAAa,OAAO,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,GAAG,QAAQ,OAAO,CAAC;IAClC,MAAM,KAAK,GAAG,GAAG,QAAQ,MAAM,CAAC;IAChC,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC;IAClD,MAAM,WAAW,GACf,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;SAC3D,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;IAE5B,OAAO,CACL,eACE,SAAS,EAAE,SAAS,qBACJ,QAAQ,kBACV,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC3C,KAAK,EAAE,KAAK,aAEX,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CACf,iBAAO,OAAO,EAAE,QAAQ,4CACrB,KAAK,EACL,QAAQ,CAAC,CAAC,CAAC,CACV,gEAA2C,MAAM,kBAE1C,CACR,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAC,CAAC,CAAC,IAAI,EACP,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,CACrB,eAAM,EAAE,EAAE,MAAM,iDACb,WAAW,GACP,CACR,CAAC,CAAC,CAAC,IAAI,EACR,iBACE,GAAG,EAAE,GAAG,KACJ,IAAI,EACR,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,eAAe,mCAE1B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,kBACE,QAAQ,IAAI,SAAS,sBACjB,WAAW,mBACd,QAAQ,IAAI,SAAS,EACpC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,YAExC,OAAO,CAAC,CAAC,CAAC,CACT,8BACG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,iBAAQ,KAAK,EAAC,EAAE,EAAC,QAAQ,kBACtB,WAAW,GACL,CACV,CAAC,CAAC,CAAC,IAAI,EACP,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,iBAAwB,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,YAC7D,GAAG,CAAC,KAAK,IADC,GAAG,CAAC,KAAK,CAEb,CACV,CAAC,IACD,CACJ,CAAC,CAAC,CAAC,CACF,QAAQ,CACT,GACM,EACR,QAAQ,CAAC,CAAC,CAAC,CACV,eAAM,EAAE,EAAE,KAAK,iCAAwB,IAAI,EAAC,OAAO,YAChD,KAAK,GACD,CACR,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ export interface SliderProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'defaultValue' | 'type' | 'size' | 'min' | 'max' | 'step'> {
2
+ /** Current value (controlled). */
3
+ value: number;
4
+ /** Fires with the new numeric value on every input (drag / keyboard). */
5
+ onChange: (value: number) => void;
6
+ /** Minimum value. Default `0`. */
7
+ min?: number;
8
+ /** Maximum value. Default `100`. */
9
+ max?: number;
10
+ /** Step increment. Default `1`. */
11
+ step?: number;
12
+ /** Visible field label, rendered in a `<label>` linked to the input. */
13
+ label?: React.ReactNode;
14
+ /** Helper text under the label, linked via `aria-describedby`. */
15
+ description?: React.ReactNode;
16
+ /** Error message. Sets `aria-invalid`, announces (`role="alert"`), links it. */
17
+ error?: React.ReactNode;
18
+ /** Mark required: shows an asterisk and sets the native `required`. */
19
+ required?: boolean;
20
+ /** Show the current value at the end of the label row. Default `false`. */
21
+ showValue?: boolean;
22
+ /** Class on the wrapping element. */
23
+ className?: string;
24
+ /** Class applied to the native range `<input>`. */
25
+ inputClassName?: string;
26
+ }
27
+ /**
28
+ * Labeled range slider — the primitive the Custom Generators app most needed
29
+ * (LoRA weights). Wraps a native `input[type="range"]` (ref-forwarded), so it
30
+ * is keyboard-operable (arrows / Home / End / PageUp / PageDown) and exposes an
31
+ * implicit `role="slider"` with `aria-valuemin`/`max`/`now` for free. The label,
32
+ * description and error are wired via `htmlFor` / `id` / `aria-describedby` /
33
+ * `aria-invalid`. Auto-themed via `useBlocksStyles()`; the accent tracks
34
+ * `--ci-color-primary`.
35
+ */
36
+ export declare const Slider: import("react").ForwardRefExoticComponent<SliderProps & import("react").RefAttributes<HTMLInputElement>>;
37
+ //# sourceMappingURL=Slider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/ui/Slider.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,WACf,SAAQ,IAAI,CACV,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CACjF;IACD,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,kEAAkE;IAClE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,gFAAgF;IAChF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,0GAkFjB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useId } from 'react';
3
+ import { useBlocksStyles } from './styles.js';
4
+ /**
5
+ * Labeled range slider — the primitive the Custom Generators app most needed
6
+ * (LoRA weights). Wraps a native `input[type="range"]` (ref-forwarded), so it
7
+ * is keyboard-operable (arrows / Home / End / PageUp / PageDown) and exposes an
8
+ * implicit `role="slider"` with `aria-valuemin`/`max`/`now` for free. The label,
9
+ * description and error are wired via `htmlFor` / `id` / `aria-describedby` /
10
+ * `aria-invalid`. Auto-themed via `useBlocksStyles()`; the accent tracks
11
+ * `--ci-color-primary`.
12
+ */
13
+ export const Slider = forwardRef(function Slider({ value, onChange, min = 0, max = 100, step = 1, label, description, error, required, showValue = false, className, inputClassName, id, style, ...rest }, ref) {
14
+ useBlocksStyles();
15
+ const reactId = useId();
16
+ const inputId = id ?? `ci-slider-${reactId}`;
17
+ const descId = `${inputId}-desc`;
18
+ const errId = `${inputId}-err`;
19
+ const hasError = error != null && error !== false;
20
+ const describedBy = [description != null ? descId : null, hasError ? errId : null]
21
+ .filter(Boolean)
22
+ .join(' ') || undefined;
23
+ return (_jsxs("div", { className: className, "data-civitai-ui": "slider", "data-invalid": hasError ? 'true' : undefined, style: style, children: [label != null || showValue ? (_jsxs("label", { htmlFor: inputId, "data-civitai-ui-label": true, children: [_jsxs("span", { children: [label, required ? (_jsx("span", { "data-civitai-ui-required": true, "aria-hidden": "true", children: "*" })) : null] }), showValue ? (_jsx("span", { "data-civitai-ui-slider-value": true, children: value })) : null] })) : null, description != null ? (_jsx("span", { id: descId, "data-civitai-ui-description": true, children: description })) : null, _jsx("input", { ref: ref, ...rest, id: inputId, type: "range", className: inputClassName, "data-civitai-ui-range": true, min: min, max: max, step: step, value: value, required: required, "aria-invalid": hasError || undefined, "aria-describedby": describedBy, "aria-required": required || undefined, onChange: (e) => onChange(Number(e.target.value)) }), hasError ? (_jsx("span", { id: errId, "data-civitai-ui-error": true, role: "alert", children: error })) : null] }));
24
+ });
25
+ //# sourceMappingURL=Slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.js","sourceRoot":"","sources":["../../src/ui/Slider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAiC9C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAgC,SAAS,MAAM,CAC7E,EACE,KAAK,EACL,QAAQ,EACR,GAAG,GAAG,CAAC,EACP,GAAG,GAAG,GAAG,EACT,IAAI,GAAG,CAAC,EACR,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,SAAS,GAAG,KAAK,EACjB,SAAS,EACT,cAAc,EACd,EAAE,EACF,KAAK,EACL,GAAG,IAAI,EACR,EACD,GAAG;IAEH,eAAe,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,EAAE,IAAI,aAAa,OAAO,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC;IACjC,MAAM,KAAK,GAAG,GAAG,OAAO,MAAM,CAAC;IAC/B,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,CAAC;IAClD,MAAM,WAAW,GACf,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;SAC3D,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;IAE5B,OAAO,CACL,eACE,SAAS,EAAE,SAAS,qBACJ,QAAQ,kBACV,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC3C,KAAK,EAAE,KAAK,aAEX,KAAK,IAAI,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,CAC5B,iBAAO,OAAO,EAAE,OAAO,4CACrB,2BACG,KAAK,EACL,QAAQ,CAAC,CAAC,CAAC,CACV,gEAA2C,MAAM,kBAE1C,CACR,CAAC,CAAC,CAAC,IAAI,IACH,EACN,SAAS,CAAC,CAAC,CAAC,CACX,+DAAoC,KAAK,GAAQ,CAClD,CAAC,CAAC,CAAC,IAAI,IACF,CACT,CAAC,CAAC,CAAC,IAAI,EACP,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,CACrB,eAAM,EAAE,EAAE,MAAM,iDACb,WAAW,GACP,CACR,CAAC,CAAC,CAAC,IAAI,EACR,gBACE,GAAG,EAAE,GAAG,KACJ,IAAI,EACR,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,OAAO,EACZ,SAAS,EAAE,cAAc,iCAEzB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,kBACJ,QAAQ,IAAI,SAAS,sBACjB,WAAW,mBACd,QAAQ,IAAI,SAAS,EACpC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GACjD,EACD,QAAQ,CAAC,CAAC,CAAC,CACV,eAAM,EAAE,EAAE,KAAK,iCAAwB,IAAI,EAAC,OAAO,YAChD,KAAK,GACD,CACR,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -7,7 +7,8 @@
7
7
  * controls; its contract is intentionally unstyled).
8
8
  * 2. The W6 component pack — a small, Civitai-looking, self-styled component
9
9
  * set (Button, TextInput, Textarea, Card, Stack, Group, Alert, Loader,
10
- * Badge, Modal). Zero setup: rendering any of them runs `useBlocksStyles()`
10
+ * Badge, Modal, plus the form primitives Slider, NumberInput, Select,
11
+ * Collapse). Zero setup: rendering any of them runs `useBlocksStyles()`
11
12
  * which injects the pack's CSS into the block document's `<head>` once.
12
13
  * Theme via your block's `data-theme` root (gotcha #60).
13
14
  *
@@ -37,4 +38,12 @@ export { Badge } from './Badge.js';
37
38
  export type { BadgeProps, BadgeVariant, BadgeSize } from './Badge.js';
38
39
  export { Modal } from './Modal.js';
39
40
  export type { ModalProps, ModalSize } from './Modal.js';
41
+ export { Slider } from './Slider.js';
42
+ export type { SliderProps } from './Slider.js';
43
+ export { NumberInput } from './NumberInput.js';
44
+ export type { NumberInputProps } from './NumberInput.js';
45
+ export { Select } from './Select.js';
46
+ export type { SelectProps, SelectOption } from './Select.js';
47
+ export { Collapse } from './Collapse.js';
48
+ export type { CollapseProps } from './Collapse.js';
40
49
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
package/dist/ui/index.js CHANGED
@@ -7,7 +7,8 @@
7
7
  * controls; its contract is intentionally unstyled).
8
8
  * 2. The W6 component pack — a small, Civitai-looking, self-styled component
9
9
  * set (Button, TextInput, Textarea, Card, Stack, Group, Alert, Loader,
10
- * Badge, Modal). Zero setup: rendering any of them runs `useBlocksStyles()`
10
+ * Badge, Modal, plus the form primitives Slider, NumberInput, Select,
11
+ * Collapse). Zero setup: rendering any of them runs `useBlocksStyles()`
11
12
  * which injects the pack's CSS into the block document's `<head>` once.
12
13
  * Theme via your block's `data-theme` root (gotcha #60).
13
14
  *
@@ -29,4 +30,8 @@ export { Alert } from './Alert.js';
29
30
  export { Loader } from './Loader.js';
30
31
  export { Badge } from './Badge.js';
31
32
  export { Modal } from './Modal.js';
33
+ export { Slider } from './Slider.js';
34
+ export { NumberInput } from './NumberInput.js';
35
+ export { Select } from './Select.js';
36
+ export { Collapse } from './Collapse.js';
32
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,oEAAoE;AACpE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGpF,gCAAgC;AAChC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,uBAAuB;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,oEAAoE;AACpE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGpF,gCAAgC;AAChC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,uBAAuB;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /** The full stylesheet shipped by the pack. Exported for SSR/manual use. */
2
- export declare const BLOCKS_UI_STYLES = "\n:root {\n --ci-font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --ci-radius: 8px;\n --ci-color-text: #1a1a1a;\n --ci-color-text-dimmed: #6b7280;\n --ci-color-surface: #ffffff;\n --ci-color-surface-2: #f4f4f5;\n --ci-color-border: #e0e0e3;\n --ci-color-primary: #228be6;\n --ci-color-primary-hover: #1c7ed6;\n --ci-color-primary-fg: #ffffff;\n --ci-color-error: #e03131;\n --ci-color-success: #2f9e44;\n --ci-color-warning: #f08c00;\n --ci-color-info: #1971c2;\n}\n\n[data-theme='light'] {\n --ci-color-text: #1a1a1a;\n --ci-color-text-dimmed: #6b7280;\n --ci-color-surface: #ffffff;\n --ci-color-surface-2: #f4f4f5;\n --ci-color-border: #e0e0e3;\n}\n\n[data-theme='dark'] {\n --ci-color-text: #e6e6e6;\n --ci-color-text-dimmed: #909296;\n --ci-color-surface: #1a1b1e;\n --ci-color-surface-2: #25262b;\n --ci-color-border: #2c2e33;\n --ci-color-primary: #228be6;\n --ci-color-primary-hover: #339af0;\n --ci-color-primary-fg: #ffffff;\n --ci-color-error: #ff6b6b;\n --ci-color-success: #51cf66;\n --ci-color-warning: #ffa94d;\n --ci-color-info: #4dabf7;\n}\n\n\n[data-civitai-ui] {\n box-sizing: border-box;\n font-family: var(--ci-font);\n}\n[data-civitai-ui] *,\n[data-civitai-ui] *::before,\n[data-civitai-ui] *::after {\n box-sizing: border-box;\n}\n\n/* ----- Button ----- */\n[data-civitai-ui='button'] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid transparent;\n border-radius: var(--ci-radius);\n font-family: var(--ci-font);\n font-weight: 600;\n line-height: 1;\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;\n background: var(--ci-color-primary);\n color: var(--ci-color-primary-fg);\n}\n[data-civitai-ui='button'][data-size='sm'] { height: 30px; padding: 0 14px; font-size: 13px; }\n[data-civitai-ui='button'][data-size='md'] { height: 36px; padding: 0 18px; font-size: 14px; }\n[data-civitai-ui='button'][data-size='lg'] { height: 44px; padding: 0 22px; font-size: 16px; }\n[data-civitai-ui='button'][data-full-width='true'] { width: 100%; }\n[data-civitai-ui='button'][data-variant='filled'] {\n background: var(--ci-color-primary);\n color: var(--ci-color-primary-fg);\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui='button'][data-variant='filled']:hover:not(:disabled) {\n background: var(--ci-color-primary-hover);\n border-color: var(--ci-color-primary-hover);\n}\n[data-civitai-ui='button'][data-variant='light'] {\n background: color-mix(in srgb, var(--ci-color-primary) 12%, transparent);\n color: var(--ci-color-primary);\n border-color: transparent;\n}\n[data-civitai-ui='button'][data-variant='light']:hover:not(:disabled) {\n background: color-mix(in srgb, var(--ci-color-primary) 22%, transparent);\n}\n[data-civitai-ui='button'][data-variant='outline'] {\n background: transparent;\n color: var(--ci-color-primary);\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui='button'][data-variant='outline']:hover:not(:disabled) {\n background: color-mix(in srgb, var(--ci-color-primary) 10%, transparent);\n}\n[data-civitai-ui='button'][data-variant='subtle'] {\n background: transparent;\n color: var(--ci-color-primary);\n border-color: transparent;\n}\n[data-civitai-ui='button'][data-variant='subtle']:hover:not(:disabled) {\n background: color-mix(in srgb, var(--ci-color-primary) 10%, transparent);\n}\n[data-civitai-ui='button']:disabled,\n[data-civitai-ui='button'][aria-busy='true'] {\n opacity: 0.6;\n cursor: not-allowed;\n}\n[data-civitai-ui='button'] [data-civitai-ui-section] {\n display: inline-flex;\n align-items: center;\n}\n\n/* ----- TextInput / Textarea ----- */\n[data-civitai-ui='text-input'],\n[data-civitai-ui='textarea'] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n[data-civitai-ui-label] {\n font-size: 14px;\n font-weight: 600;\n color: var(--ci-color-text);\n}\n[data-civitai-ui-required] {\n color: var(--ci-color-error);\n margin-left: 2px;\n}\n[data-civitai-ui-description] {\n font-size: 12px;\n color: var(--ci-color-text-dimmed);\n}\n[data-civitai-ui-error] {\n font-size: 12px;\n color: var(--ci-color-error);\n}\n[data-civitai-ui-control] {\n width: 100%;\n font-family: var(--ci-font);\n font-size: 14px;\n color: var(--ci-color-text);\n background: var(--ci-color-surface);\n border: 1px solid var(--ci-color-border);\n border-radius: var(--ci-radius);\n padding: 8px 12px;\n transition: border-color 120ms ease;\n}\n[data-civitai-ui-control]:focus {\n outline: none;\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui-control][aria-invalid='true'] {\n border-color: var(--ci-color-error);\n}\n[data-civitai-ui-control]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\ntextarea[data-civitai-ui-control] {\n resize: vertical;\n line-height: 1.5;\n}\n\n/* ----- Card ----- */\n[data-civitai-ui='card'] {\n background: var(--ci-color-surface);\n border-radius: var(--ci-radius);\n color: var(--ci-color-text);\n}\n[data-civitai-ui='card'][data-with-border='true'] {\n border: 1px solid var(--ci-color-border);\n}\n[data-civitai-ui='card'][data-padding='sm'] { padding: 10px; }\n[data-civitai-ui='card'][data-padding='md'] { padding: 16px; }\n[data-civitai-ui='card'][data-padding='lg'] { padding: 24px; }\n\n/* ----- Stack / Group ----- */\n[data-civitai-ui='stack'] {\n display: flex;\n flex-direction: column;\n}\n[data-civitai-ui='group'] {\n display: flex;\n flex-direction: row;\n}\n\n/* ----- Alert ----- */\n[data-civitai-ui='alert'] {\n display: flex;\n gap: 10px;\n align-items: flex-start;\n padding: 12px 14px;\n border-radius: var(--ci-radius);\n border: 1px solid transparent;\n font-size: 14px;\n color: var(--ci-color-text);\n}\n[data-civitai-ui='alert'][data-color='info'] {\n background: color-mix(in srgb, var(--ci-color-info) 12%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-info) 35%, transparent);\n}\n[data-civitai-ui='alert'][data-color='success'] {\n background: color-mix(in srgb, var(--ci-color-success) 12%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-success) 35%, transparent);\n}\n[data-civitai-ui='alert'][data-color='warning'] {\n background: color-mix(in srgb, var(--ci-color-warning) 14%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-warning) 35%, transparent);\n}\n[data-civitai-ui='alert'][data-color='error'] {\n background: color-mix(in srgb, var(--ci-color-error) 12%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-error) 35%, transparent);\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-body] {\n flex: 1;\n min-width: 0;\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-title] {\n font-weight: 600;\n margin-bottom: 2px;\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-close] {\n background: transparent;\n border: none;\n cursor: pointer;\n color: inherit;\n font-size: 16px;\n line-height: 1;\n padding: 0;\n opacity: 0.7;\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-close]:hover {\n opacity: 1;\n}\n\n/* ----- Loader ----- */\n[data-civitai-ui='loader'] {\n display: inline-block;\n border-radius: 50%;\n border-style: solid;\n border-color: color-mix(in srgb, currentColor 25%, transparent);\n border-top-color: currentColor;\n color: var(--ci-color-primary);\n animation: civitai-ui-spin 0.7s linear infinite;\n}\n[data-civitai-ui='loader'][data-size='sm'] { width: 16px; height: 16px; border-width: 2px; }\n[data-civitai-ui='loader'][data-size='md'] { width: 22px; height: 22px; border-width: 3px; }\n[data-civitai-ui='loader'][data-size='lg'] { width: 32px; height: 32px; border-width: 4px; }\n@keyframes civitai-ui-spin {\n to { transform: rotate(360deg); }\n}\n[data-civitai-ui='button'] [data-civitai-ui='loader'] {\n color: currentColor;\n}\n\n/* ----- Badge ----- */\n[data-civitai-ui='badge'] {\n display: inline-flex;\n align-items: center;\n border: 1px solid transparent;\n border-radius: 999px;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n[data-civitai-ui='badge'][data-size='sm'] { height: 18px; padding: 0 8px; font-size: 10px; }\n[data-civitai-ui='badge'][data-size='md'] { height: 22px; padding: 0 10px; font-size: 11px; }\n[data-civitai-ui='badge'][data-size='lg'] { height: 26px; padding: 0 12px; font-size: 13px; }\n[data-civitai-ui='badge'][data-variant='filled'] {\n background: var(--ci-color-primary);\n color: var(--ci-color-primary-fg);\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui='badge'][data-variant='light'] {\n background: color-mix(in srgb, var(--ci-color-primary) 14%, transparent);\n color: var(--ci-color-primary);\n}\n[data-civitai-ui='badge'][data-variant='outline'] {\n background: transparent;\n color: var(--ci-color-primary);\n border-color: var(--ci-color-primary);\n}\n\n/* ----- Modal ----- */\n[data-civitai-ui='modal-overlay'] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding: 32px 16px;\n overflow-y: auto;\n z-index: 1000;\n}\n[data-civitai-ui='modal'] {\n background: var(--ci-color-surface);\n color: var(--ci-color-text);\n border: 1px solid var(--ci-color-border);\n border-radius: var(--ci-radius);\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);\n width: 100%;\n max-width: 440px;\n outline: none;\n}\n[data-civitai-ui='modal'][data-size='sm'] { max-width: 340px; }\n[data-civitai-ui='modal'][data-size='md'] { max-width: 440px; }\n[data-civitai-ui='modal'][data-size='lg'] { max-width: 620px; }\n[data-civitai-ui='modal'] [data-civitai-ui-modal-header] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 16px 18px;\n border-bottom: 1px solid var(--ci-color-border);\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-title] {\n font-size: 16px;\n font-weight: 700;\n margin: 0;\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-close] {\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--ci-color-text-dimmed);\n font-size: 20px;\n line-height: 1;\n padding: 0;\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-close]:hover {\n color: var(--ci-color-text);\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-body] {\n padding: 18px;\n}\n";
2
+ export declare const BLOCKS_UI_STYLES = "\n:root {\n --ci-font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --ci-radius: 8px;\n --ci-color-text: #1a1a1a;\n --ci-color-text-dimmed: #6b7280;\n --ci-color-surface: #ffffff;\n --ci-color-surface-2: #f4f4f5;\n --ci-color-border: #e0e0e3;\n --ci-color-primary: #228be6;\n --ci-color-primary-hover: #1c7ed6;\n --ci-color-primary-fg: #ffffff;\n --ci-color-error: #e03131;\n --ci-color-success: #2f9e44;\n --ci-color-warning: #f08c00;\n --ci-color-info: #1971c2;\n}\n\n[data-theme='light'] {\n --ci-color-text: #1a1a1a;\n --ci-color-text-dimmed: #6b7280;\n --ci-color-surface: #ffffff;\n --ci-color-surface-2: #f4f4f5;\n --ci-color-border: #e0e0e3;\n}\n\n[data-theme='dark'] {\n --ci-color-text: #e6e6e6;\n --ci-color-text-dimmed: #909296;\n --ci-color-surface: #1a1b1e;\n --ci-color-surface-2: #25262b;\n --ci-color-border: #2c2e33;\n --ci-color-primary: #228be6;\n --ci-color-primary-hover: #339af0;\n --ci-color-primary-fg: #ffffff;\n --ci-color-error: #ff6b6b;\n --ci-color-success: #51cf66;\n --ci-color-warning: #ffa94d;\n --ci-color-info: #4dabf7;\n}\n\n\n[data-civitai-ui] {\n box-sizing: border-box;\n font-family: var(--ci-font);\n}\n[data-civitai-ui] *,\n[data-civitai-ui] *::before,\n[data-civitai-ui] *::after {\n box-sizing: border-box;\n}\n\n/* ----- Button ----- */\n[data-civitai-ui='button'] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n border: 1px solid transparent;\n border-radius: var(--ci-radius);\n font-family: var(--ci-font);\n font-weight: 600;\n line-height: 1;\n cursor: pointer;\n user-select: none;\n text-decoration: none;\n transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;\n background: var(--ci-color-primary);\n color: var(--ci-color-primary-fg);\n}\n[data-civitai-ui='button'][data-size='sm'] { height: 30px; padding: 0 14px; font-size: 13px; }\n[data-civitai-ui='button'][data-size='md'] { height: 36px; padding: 0 18px; font-size: 14px; }\n[data-civitai-ui='button'][data-size='lg'] { height: 44px; padding: 0 22px; font-size: 16px; }\n[data-civitai-ui='button'][data-full-width='true'] { width: 100%; }\n[data-civitai-ui='button'][data-variant='filled'] {\n background: var(--ci-color-primary);\n color: var(--ci-color-primary-fg);\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui='button'][data-variant='filled']:hover:not(:disabled) {\n background: var(--ci-color-primary-hover);\n border-color: var(--ci-color-primary-hover);\n}\n[data-civitai-ui='button'][data-variant='light'] {\n background: color-mix(in srgb, var(--ci-color-primary) 12%, transparent);\n color: var(--ci-color-primary);\n border-color: transparent;\n}\n[data-civitai-ui='button'][data-variant='light']:hover:not(:disabled) {\n background: color-mix(in srgb, var(--ci-color-primary) 22%, transparent);\n}\n[data-civitai-ui='button'][data-variant='outline'] {\n background: transparent;\n color: var(--ci-color-primary);\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui='button'][data-variant='outline']:hover:not(:disabled) {\n background: color-mix(in srgb, var(--ci-color-primary) 10%, transparent);\n}\n[data-civitai-ui='button'][data-variant='subtle'] {\n background: transparent;\n color: var(--ci-color-primary);\n border-color: transparent;\n}\n[data-civitai-ui='button'][data-variant='subtle']:hover:not(:disabled) {\n background: color-mix(in srgb, var(--ci-color-primary) 10%, transparent);\n}\n[data-civitai-ui='button']:disabled,\n[data-civitai-ui='button'][aria-busy='true'] {\n opacity: 0.6;\n cursor: not-allowed;\n}\n[data-civitai-ui='button'] [data-civitai-ui-section] {\n display: inline-flex;\n align-items: center;\n}\n\n/* ----- TextInput / Textarea / NumberInput / Select / Slider ----- */\n[data-civitai-ui='text-input'],\n[data-civitai-ui='textarea'],\n[data-civitai-ui='number-input'],\n[data-civitai-ui='select'],\n[data-civitai-ui='slider'] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n[data-civitai-ui-label] {\n font-size: 14px;\n font-weight: 600;\n color: var(--ci-color-text);\n}\n[data-civitai-ui-required] {\n color: var(--ci-color-error);\n margin-left: 2px;\n}\n[data-civitai-ui-description] {\n font-size: 12px;\n color: var(--ci-color-text-dimmed);\n}\n[data-civitai-ui-error] {\n font-size: 12px;\n color: var(--ci-color-error);\n}\n[data-civitai-ui-control] {\n width: 100%;\n font-family: var(--ci-font);\n font-size: 14px;\n color: var(--ci-color-text);\n background: var(--ci-color-surface);\n border: 1px solid var(--ci-color-border);\n border-radius: var(--ci-radius);\n padding: 8px 12px;\n transition: border-color 120ms ease;\n}\n[data-civitai-ui-control]:focus {\n outline: none;\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui-control][aria-invalid='true'] {\n border-color: var(--ci-color-error);\n}\n[data-civitai-ui-control]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\ntextarea[data-civitai-ui-control] {\n resize: vertical;\n line-height: 1.5;\n}\n\n/* ----- Card ----- */\n[data-civitai-ui='card'] {\n background: var(--ci-color-surface);\n border-radius: var(--ci-radius);\n color: var(--ci-color-text);\n}\n[data-civitai-ui='card'][data-with-border='true'] {\n border: 1px solid var(--ci-color-border);\n}\n[data-civitai-ui='card'][data-padding='sm'] { padding: 10px; }\n[data-civitai-ui='card'][data-padding='md'] { padding: 16px; }\n[data-civitai-ui='card'][data-padding='lg'] { padding: 24px; }\n\n/* ----- Stack / Group ----- */\n[data-civitai-ui='stack'] {\n display: flex;\n flex-direction: column;\n}\n[data-civitai-ui='group'] {\n display: flex;\n flex-direction: row;\n}\n\n/* ----- Alert ----- */\n[data-civitai-ui='alert'] {\n display: flex;\n gap: 10px;\n align-items: flex-start;\n padding: 12px 14px;\n border-radius: var(--ci-radius);\n border: 1px solid transparent;\n font-size: 14px;\n color: var(--ci-color-text);\n}\n[data-civitai-ui='alert'][data-color='info'] {\n background: color-mix(in srgb, var(--ci-color-info) 12%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-info) 35%, transparent);\n}\n[data-civitai-ui='alert'][data-color='success'] {\n background: color-mix(in srgb, var(--ci-color-success) 12%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-success) 35%, transparent);\n}\n[data-civitai-ui='alert'][data-color='warning'] {\n background: color-mix(in srgb, var(--ci-color-warning) 14%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-warning) 35%, transparent);\n}\n[data-civitai-ui='alert'][data-color='error'] {\n background: color-mix(in srgb, var(--ci-color-error) 12%, transparent);\n border-color: color-mix(in srgb, var(--ci-color-error) 35%, transparent);\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-body] {\n flex: 1;\n min-width: 0;\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-title] {\n font-weight: 600;\n margin-bottom: 2px;\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-close] {\n background: transparent;\n border: none;\n cursor: pointer;\n color: inherit;\n font-size: 16px;\n line-height: 1;\n padding: 0;\n opacity: 0.7;\n}\n[data-civitai-ui='alert'] [data-civitai-ui-alert-close]:hover {\n opacity: 1;\n}\n\n/* ----- Loader ----- */\n[data-civitai-ui='loader'] {\n display: inline-block;\n border-radius: 50%;\n border-style: solid;\n border-color: color-mix(in srgb, currentColor 25%, transparent);\n border-top-color: currentColor;\n color: var(--ci-color-primary);\n animation: civitai-ui-spin 0.7s linear infinite;\n}\n[data-civitai-ui='loader'][data-size='sm'] { width: 16px; height: 16px; border-width: 2px; }\n[data-civitai-ui='loader'][data-size='md'] { width: 22px; height: 22px; border-width: 3px; }\n[data-civitai-ui='loader'][data-size='lg'] { width: 32px; height: 32px; border-width: 4px; }\n@keyframes civitai-ui-spin {\n to { transform: rotate(360deg); }\n}\n[data-civitai-ui='button'] [data-civitai-ui='loader'] {\n color: currentColor;\n}\n\n/* ----- Badge ----- */\n[data-civitai-ui='badge'] {\n display: inline-flex;\n align-items: center;\n border: 1px solid transparent;\n border-radius: 999px;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n[data-civitai-ui='badge'][data-size='sm'] { height: 18px; padding: 0 8px; font-size: 10px; }\n[data-civitai-ui='badge'][data-size='md'] { height: 22px; padding: 0 10px; font-size: 11px; }\n[data-civitai-ui='badge'][data-size='lg'] { height: 26px; padding: 0 12px; font-size: 13px; }\n[data-civitai-ui='badge'][data-variant='filled'] {\n background: var(--ci-color-primary);\n color: var(--ci-color-primary-fg);\n border-color: var(--ci-color-primary);\n}\n[data-civitai-ui='badge'][data-variant='light'] {\n background: color-mix(in srgb, var(--ci-color-primary) 14%, transparent);\n color: var(--ci-color-primary);\n}\n[data-civitai-ui='badge'][data-variant='outline'] {\n background: transparent;\n color: var(--ci-color-primary);\n border-color: var(--ci-color-primary);\n}\n\n/* ----- Modal ----- */\n[data-civitai-ui='modal-overlay'] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding: 32px 16px;\n overflow-y: auto;\n z-index: 1000;\n}\n[data-civitai-ui='modal'] {\n background: var(--ci-color-surface);\n color: var(--ci-color-text);\n border: 1px solid var(--ci-color-border);\n border-radius: var(--ci-radius);\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);\n width: 100%;\n max-width: 440px;\n outline: none;\n}\n[data-civitai-ui='modal'][data-size='sm'] { max-width: 340px; }\n[data-civitai-ui='modal'][data-size='md'] { max-width: 440px; }\n[data-civitai-ui='modal'][data-size='lg'] { max-width: 620px; }\n[data-civitai-ui='modal'] [data-civitai-ui-modal-header] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 16px 18px;\n border-bottom: 1px solid var(--ci-color-border);\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-title] {\n font-size: 16px;\n font-weight: 700;\n margin: 0;\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-close] {\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--ci-color-text-dimmed);\n font-size: 20px;\n line-height: 1;\n padding: 0;\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-close]:hover {\n color: var(--ci-color-text);\n}\n[data-civitai-ui='modal'] [data-civitai-ui-modal-body] {\n padding: 18px;\n}\n\n/* ----- Slider ----- */\n[data-civitai-ui='slider'] [data-civitai-ui-label] {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n gap: 8px;\n}\n[data-civitai-ui-slider-value] {\n font-weight: 500;\n color: var(--ci-color-text-dimmed);\n font-variant-numeric: tabular-nums;\n}\n[data-civitai-ui-range] {\n width: 100%;\n margin: 0;\n accent-color: var(--ci-color-primary);\n cursor: pointer;\n}\n[data-civitai-ui-range]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n[data-civitai-ui-range]:focus-visible {\n outline: 2px solid var(--ci-color-primary);\n outline-offset: 2px;\n}\n\n/* ----- Collapse ----- */\n[data-civitai-ui='collapse'] [data-civitai-ui-collapse-trigger] {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 6px 0;\n background: transparent;\n border: none;\n font-family: var(--ci-font);\n font-size: 14px;\n font-weight: 600;\n color: var(--ci-color-text);\n text-align: left;\n cursor: pointer;\n}\n[data-civitai-ui='collapse'] [data-civitai-ui-collapse-trigger]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n[data-civitai-ui='collapse'] [data-civitai-ui-collapse-chevron] {\n display: inline-block;\n width: 1em;\n color: var(--ci-color-text-dimmed);\n}\n[data-civitai-ui='collapse'] [data-civitai-ui-collapse-region] {\n padding-top: 4px;\n}\n";
3
3
  /**
4
4
  * Inject the pack's stylesheet into a document's `<head>` exactly once.
5
5
  * Idempotent: subsequent calls (including from other components) detect the
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AA4XA,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,uzUAAgC,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAgBvD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAubA,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,+wXAAgC,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAgBvD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC"}
package/dist/ui/styles.js CHANGED
@@ -146,9 +146,12 @@ const COMPONENT_CSS = `
146
146
  align-items: center;
147
147
  }
148
148
 
149
- /* ----- TextInput / Textarea ----- */
149
+ /* ----- TextInput / Textarea / NumberInput / Select / Slider ----- */
150
150
  [data-civitai-ui='text-input'],
151
- [data-civitai-ui='textarea'] {
151
+ [data-civitai-ui='textarea'],
152
+ [data-civitai-ui='number-input'],
153
+ [data-civitai-ui='select'],
154
+ [data-civitai-ui='slider'] {
152
155
  display: flex;
153
156
  flex-direction: column;
154
157
  gap: 4px;
@@ -372,6 +375,62 @@ textarea[data-civitai-ui-control] {
372
375
  [data-civitai-ui='modal'] [data-civitai-ui-modal-body] {
373
376
  padding: 18px;
374
377
  }
378
+
379
+ /* ----- Slider ----- */
380
+ [data-civitai-ui='slider'] [data-civitai-ui-label] {
381
+ display: flex;
382
+ justify-content: space-between;
383
+ align-items: baseline;
384
+ gap: 8px;
385
+ }
386
+ [data-civitai-ui-slider-value] {
387
+ font-weight: 500;
388
+ color: var(--ci-color-text-dimmed);
389
+ font-variant-numeric: tabular-nums;
390
+ }
391
+ [data-civitai-ui-range] {
392
+ width: 100%;
393
+ margin: 0;
394
+ accent-color: var(--ci-color-primary);
395
+ cursor: pointer;
396
+ }
397
+ [data-civitai-ui-range]:disabled {
398
+ opacity: 0.6;
399
+ cursor: not-allowed;
400
+ }
401
+ [data-civitai-ui-range]:focus-visible {
402
+ outline: 2px solid var(--ci-color-primary);
403
+ outline-offset: 2px;
404
+ }
405
+
406
+ /* ----- Collapse ----- */
407
+ [data-civitai-ui='collapse'] [data-civitai-ui-collapse-trigger] {
408
+ display: flex;
409
+ align-items: center;
410
+ gap: 6px;
411
+ width: 100%;
412
+ padding: 6px 0;
413
+ background: transparent;
414
+ border: none;
415
+ font-family: var(--ci-font);
416
+ font-size: 14px;
417
+ font-weight: 600;
418
+ color: var(--ci-color-text);
419
+ text-align: left;
420
+ cursor: pointer;
421
+ }
422
+ [data-civitai-ui='collapse'] [data-civitai-ui-collapse-trigger]:disabled {
423
+ opacity: 0.6;
424
+ cursor: not-allowed;
425
+ }
426
+ [data-civitai-ui='collapse'] [data-civitai-ui-collapse-chevron] {
427
+ display: inline-block;
428
+ width: 1em;
429
+ color: var(--ci-color-text-dimmed);
430
+ }
431
+ [data-civitai-ui='collapse'] [data-civitai-ui-collapse-region] {
432
+ padding-top: 4px;
433
+ }
375
434
  `;
376
435
  /** The full stylesheet shipped by the pack. Exported for SSR/manual use. */
377
436
  export const BLOCKS_UI_STYLES = `${TOKENS}\n${COMPONENT_CSS}`;
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;;;;;;;;;;;;;;GAgBG;AAEH,6EAA6E;AAC7E,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCd,CAAC;AAEF;;;;GAIG;AACH,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8SrB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,MAAM,KAAK,aAAa,EAAE,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAc;IAC/C,MAAM,MAAM,GACV,GAAG,IAAI,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,yCAAyC;IACzC,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,YAAY,GAAG,CAAC;QAAE,OAAO;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5C,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,WAAW,GAAG,gBAAgB,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,oEAAoE;QACpE,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,EAAE,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/ui/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;;;;;;;;;;;;;;GAgBG;AAEH,6EAA6E;AAC7E,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCd,CAAC;AAEF;;;;GAIG;AACH,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyWrB,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,MAAM,KAAK,aAAa,EAAE,CAAC;AAE9D;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAc;IAC/C,MAAM,MAAM,GACV,GAAG,IAAI,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,yCAAyC;IACzC,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,YAAY,GAAG,CAAC;QAAE,OAAO;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5C,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,WAAW,GAAG,gBAAgB,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,oEAAoE;QACpE,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,EAAE,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@civitai/blocks-react",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "description": "React hooks and iframe transport for Civitai Apps. Pairs with @civitai/app-sdk/blocks.",
5
5
  "license": "MIT",
6
6
  "type": "module",