@civitai/blocks-react 0.11.2 → 0.12.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.
Files changed (50) hide show
  1. package/README.md +90 -3
  2. package/dist/ui/Alert.d.ts +29 -0
  3. package/dist/ui/Alert.d.ts.map +1 -0
  4. package/dist/ui/Alert.js +16 -0
  5. package/dist/ui/Alert.js.map +1 -0
  6. package/dist/ui/Badge.d.ts +18 -0
  7. package/dist/ui/Badge.d.ts.map +1 -0
  8. package/dist/ui/Badge.js +25 -0
  9. package/dist/ui/Badge.js.map +1 -0
  10. package/dist/ui/Button.d.ts +35 -0
  11. package/dist/ui/Button.d.ts.map +1 -0
  12. package/dist/ui/Button.js +44 -0
  13. package/dist/ui/Button.js.map +1 -0
  14. package/dist/ui/Card.d.ts +14 -0
  15. package/dist/ui/Card.d.ts.map +1 -0
  16. package/dist/ui/Card.js +11 -0
  17. package/dist/ui/Card.js.map +1 -0
  18. package/dist/ui/Group.d.ts +15 -0
  19. package/dist/ui/Group.d.ts.map +1 -0
  20. package/dist/ui/Group.js +22 -0
  21. package/dist/ui/Group.js.map +1 -0
  22. package/dist/ui/Loader.d.ts +18 -0
  23. package/dist/ui/Loader.d.ts.map +1 -0
  24. package/dist/ui/Loader.js +14 -0
  25. package/dist/ui/Loader.js.map +1 -0
  26. package/dist/ui/Modal.d.ts +46 -0
  27. package/dist/ui/Modal.d.ts.map +1 -0
  28. package/dist/ui/Modal.js +67 -0
  29. package/dist/ui/Modal.js.map +1 -0
  30. package/dist/ui/Stack.d.ts +13 -0
  31. package/dist/ui/Stack.d.ts.map +1 -0
  32. package/dist/ui/Stack.js +21 -0
  33. package/dist/ui/Stack.js.map +1 -0
  34. package/dist/ui/TextInput.d.ts +26 -0
  35. package/dist/ui/TextInput.d.ts.map +1 -0
  36. package/dist/ui/TextInput.js +23 -0
  37. package/dist/ui/TextInput.js.map +1 -0
  38. package/dist/ui/Textarea.d.ts +32 -0
  39. package/dist/ui/Textarea.d.ts.map +1 -0
  40. package/dist/ui/Textarea.js +23 -0
  41. package/dist/ui/Textarea.js.map +1 -0
  42. package/dist/ui/index.d.ts +33 -4
  43. package/dist/ui/index.d.ts.map +1 -1
  44. package/dist/ui/index.js +26 -4
  45. package/dist/ui/index.js.map +1 -1
  46. package/dist/ui/styles.d.ts +19 -0
  47. package/dist/ui/styles.d.ts.map +1 -0
  48. package/dist/ui/styles.js +416 -0
  49. package/dist/ui/styles.js.map +1 -0
  50. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ export interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
2
+ /** Visible field label, rendered in a `<label>` linked to the input. */
3
+ label?: React.ReactNode;
4
+ /** Helper text under the label, linked via `aria-describedby`. */
5
+ description?: React.ReactNode;
6
+ /**
7
+ * Error message. When set, the input gets `aria-invalid="true"`, the message
8
+ * is announced (`role="alert"`) and linked via `aria-describedby`.
9
+ */
10
+ error?: React.ReactNode;
11
+ /** Mark required: shows an asterisk and sets the native `required`. */
12
+ required?: boolean;
13
+ /** Class on the wrapping element (the `<input>` is `inputClassName`). */
14
+ className?: string;
15
+ /** Class applied to the native `<input>`. */
16
+ inputClassName?: string;
17
+ }
18
+ /**
19
+ * Labeled text input. Wraps a native `<input>` (ref-forwarded). The label,
20
+ * description and error are wired to the control via `htmlFor` / `id` /
21
+ * `aria-describedby` / `aria-invalid` so the field is announced correctly.
22
+ *
23
+ * Auto-themed via `useBlocksStyles()`.
24
+ */
25
+ export declare const TextInput: import("react").ForwardRefExoticComponent<TextInputProps & import("react").RefAttributes<HTMLInputElement>>;
26
+ //# sourceMappingURL=TextInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextInput.d.ts","sourceRoot":"","sources":["../../src/ui/TextInput.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACjE,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,kEAAkE;IAClE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,6GAmErB,CAAC"}
@@ -0,0 +1,23 @@
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 text input. Wraps a native `<input>` (ref-forwarded). The label,
6
+ * description and error are wired to the control via `htmlFor` / `id` /
7
+ * `aria-describedby` / `aria-invalid` so the field is announced correctly.
8
+ *
9
+ * Auto-themed via `useBlocksStyles()`.
10
+ */
11
+ export const TextInput = forwardRef(function TextInput({ label, description, error, required, className, inputClassName, id, style, ...rest }, ref) {
12
+ useBlocksStyles();
13
+ const reactId = useId();
14
+ const inputId = id ?? `ci-input-${reactId}`;
15
+ const descId = `${inputId}-desc`;
16
+ const errId = `${inputId}-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": "text-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, className: inputClassName, "data-civitai-ui-control": true, required: required, "aria-invalid": hasError || undefined, "aria-describedby": describedBy, "aria-required": required || undefined }), hasError ? (_jsx("span", { id: errId, "data-civitai-ui-error": true, role: "alert", children: error })) : null] }));
22
+ });
23
+ //# sourceMappingURL=TextInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../src/ui/TextInput.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqB9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CACjC,SAAS,SAAS,CAChB,EACE,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,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,YAAY,OAAO,EAAE,CAAC;IAC5C,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,YAAY,kBACd,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,SAAS,EAAE,cAAc,mCAEzB,QAAQ,EAAE,QAAQ,kBACJ,QAAQ,IAAI,SAAS,sBACjB,WAAW,mBACd,QAAQ,IAAI,SAAS,GACpC,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,32 @@
1
+ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
2
+ /** Visible field label, rendered in a `<label>` linked to the textarea. */
3
+ label?: React.ReactNode;
4
+ /** Helper text under the label, linked via `aria-describedby`. */
5
+ description?: React.ReactNode;
6
+ /**
7
+ * Error message. When set, the control gets `aria-invalid="true"`, the
8
+ * message is announced (`role="alert"`) and linked via `aria-describedby`.
9
+ */
10
+ error?: React.ReactNode;
11
+ /** Mark required: shows an asterisk and sets the native `required`. */
12
+ required?: boolean;
13
+ /**
14
+ * Initial visible rows. Alias of the native `rows`; `minRows` wins if both
15
+ * are passed (kept for parity with Mantine's `minRows`). This is a static
16
+ * minimum — v0 does not auto-grow the textarea.
17
+ */
18
+ minRows?: number;
19
+ /** Class on the wrapping element. */
20
+ className?: string;
21
+ /** Class applied to the native `<textarea>`. */
22
+ textareaClassName?: string;
23
+ }
24
+ /**
25
+ * Labeled multi-line text input. Wraps a native `<textarea>` (ref-forwarded),
26
+ * same label/description/error wiring as `<TextInput>`. Auto-themed.
27
+ *
28
+ * `minRows` is a static minimum-rows hint (maps to the native `rows`); v0 does
29
+ * not auto-grow — note this limitation in the README.
30
+ */
31
+ export declare const Textarea: import("react").ForwardRefExoticComponent<TextareaProps & import("react").RefAttributes<HTMLTextAreaElement>>;
32
+ //# sourceMappingURL=Textarea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.d.ts","sourceRoot":"","sources":["../../src/ui/Textarea.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,aACf,SAAQ,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC;IACzD,2EAA2E;IAC3E,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,kEAAkE;IAClE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,+GAsEpB,CAAC"}
@@ -0,0 +1,23 @@
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 multi-line text input. Wraps a native `<textarea>` (ref-forwarded),
6
+ * same label/description/error wiring as `<TextInput>`. Auto-themed.
7
+ *
8
+ * `minRows` is a static minimum-rows hint (maps to the native `rows`); v0 does
9
+ * not auto-grow — note this limitation in the README.
10
+ */
11
+ export const Textarea = forwardRef(function Textarea({ label, description, error, required, minRows, rows, className, textareaClassName, id, style, ...rest }, ref) {
12
+ useBlocksStyles();
13
+ const reactId = useId();
14
+ const inputId = id ?? `ci-textarea-${reactId}`;
15
+ const descId = `${inputId}-desc`;
16
+ const errId = `${inputId}-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": "textarea", "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("textarea", { ref: ref, ...rest, id: inputId, className: textareaClassName, "data-civitai-ui-control": true, rows: minRows ?? rows ?? 3, required: required, "aria-invalid": hasError || undefined, "aria-describedby": describedBy, "aria-required": required || undefined }), hasError ? (_jsx("span", { id: errId, "data-civitai-ui-error": true, role: "alert", children: error })) : null] }));
22
+ });
23
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../src/ui/Textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA2B9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,SAAS,QAAQ,CACf,EACE,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,SAAS,EACT,iBAAiB,EACjB,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,eAAe,OAAO,EAAE,CAAC;IAC/C,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,UAAU,kBACZ,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,mBACE,GAAG,EAAE,GAAG,KACJ,IAAI,EACR,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,iBAAiB,mCAE5B,IAAI,EAAE,OAAO,IAAI,IAAI,IAAI,CAAC,EAC1B,QAAQ,EAAE,QAAQ,kBACJ,QAAQ,IAAI,SAAS,sBACjB,WAAW,mBACd,QAAQ,IAAI,SAAS,GACpC,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"}
@@ -1,11 +1,40 @@
1
1
  /**
2
2
  * `@civitai/blocks-react/ui` — opinionated UI components for App Block authoring.
3
3
  *
4
- * v0 scope: just the generic, manifest-driven `SettingsForm`. The W6
5
- * component pack (Button, Input, Card, Modal, …) will land here too as
6
- * separate exports; importing from `/ui` (not the root) keeps the
7
- * transport-only consumer's bundle lean.
4
+ * Two surfaces:
5
+ *
6
+ * 1. The headless, manifest-driven `SettingsForm` (W3 host-themed native
7
+ * controls; its contract is intentionally unstyled).
8
+ * 2. The W6 component pack — a small, Civitai-looking, self-styled component
9
+ * set (Button, TextInput, Textarea, Card, Stack, Group, Alert, Loader,
10
+ * Badge, Modal). Zero setup: rendering any of them runs `useBlocksStyles()`
11
+ * which injects the pack's CSS into the block document's `<head>` once.
12
+ * Theme via your block's `data-theme` root (gotcha #60).
13
+ *
14
+ * Importing from `/ui` (not the package root) keeps a transport-only block's
15
+ * bundle lean.
8
16
  */
9
17
  export { SettingsForm, SettingsFormError, isFieldVisible } from './SettingsForm.js';
10
18
  export type { SettingsFormProps } from './SettingsForm.js';
19
+ export { injectBlocksStyles, useBlocksStyles, BLOCKS_UI_STYLES, } from './styles.js';
20
+ export { Button } from './Button.js';
21
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button.js';
22
+ export { TextInput } from './TextInput.js';
23
+ export type { TextInputProps } from './TextInput.js';
24
+ export { Textarea } from './Textarea.js';
25
+ export type { TextareaProps } from './Textarea.js';
26
+ export { Card } from './Card.js';
27
+ export type { CardProps, CardPadding } from './Card.js';
28
+ export { Stack } from './Stack.js';
29
+ export type { StackProps } from './Stack.js';
30
+ export { Group } from './Group.js';
31
+ export type { GroupProps } from './Group.js';
32
+ export { Alert } from './Alert.js';
33
+ export type { AlertProps, AlertColor } from './Alert.js';
34
+ export { Loader } from './Loader.js';
35
+ export type { LoaderProps, LoaderSize } from './Loader.js';
36
+ export { Badge } from './Badge.js';
37
+ export type { BadgeProps, BadgeVariant, BadgeSize } from './Badge.js';
38
+ export { Modal } from './Modal.js';
39
+ export type { ModalProps, ModalSize } from './Modal.js';
11
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
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"}
package/dist/ui/index.js CHANGED
@@ -1,10 +1,32 @@
1
1
  /**
2
2
  * `@civitai/blocks-react/ui` — opinionated UI components for App Block authoring.
3
3
  *
4
- * v0 scope: just the generic, manifest-driven `SettingsForm`. The W6
5
- * component pack (Button, Input, Card, Modal, …) will land here too as
6
- * separate exports; importing from `/ui` (not the root) keeps the
7
- * transport-only consumer's bundle lean.
4
+ * Two surfaces:
5
+ *
6
+ * 1. The headless, manifest-driven `SettingsForm` (W3 host-themed native
7
+ * controls; its contract is intentionally unstyled).
8
+ * 2. The W6 component pack — a small, Civitai-looking, self-styled component
9
+ * set (Button, TextInput, Textarea, Card, Stack, Group, Alert, Loader,
10
+ * Badge, Modal). Zero setup: rendering any of them runs `useBlocksStyles()`
11
+ * which injects the pack's CSS into the block document's `<head>` once.
12
+ * Theme via your block's `data-theme` root (gotcha #60).
13
+ *
14
+ * Importing from `/ui` (not the package root) keeps a transport-only block's
15
+ * bundle lean.
8
16
  */
17
+ // W3 — manifest-driven settings form (host-themed native controls).
9
18
  export { SettingsForm, SettingsFormError, isFieldVisible } from './SettingsForm.js';
19
+ // W6 — runtime style injection.
20
+ export { injectBlocksStyles, useBlocksStyles, BLOCKS_UI_STYLES, } from './styles.js';
21
+ // W6 — component pack.
22
+ export { Button } from './Button.js';
23
+ export { TextInput } from './TextInput.js';
24
+ export { Textarea } from './Textarea.js';
25
+ export { Card } from './Card.js';
26
+ export { Stack } from './Stack.js';
27
+ export { Group } from './Group.js';
28
+ export { Alert } from './Alert.js';
29
+ export { Loader } from './Loader.js';
30
+ export { Badge } from './Badge.js';
31
+ export { Modal } from './Modal.js';
10
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
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"}
@@ -0,0 +1,19 @@
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";
3
+ /**
4
+ * Inject the pack's stylesheet into a document's `<head>` exactly once.
5
+ * Idempotent: subsequent calls (including from other components) detect the
6
+ * marker `<style>` and no-op. Safe to call from any component's effect.
7
+ *
8
+ * @param doc Target document. Defaults to the ambient `document`. No-op when
9
+ * no document is available (e.g. SSR) — callers in the browser get styling,
10
+ * server renders fall back to the unstyled-but-functional markup.
11
+ */
12
+ export declare function injectBlocksStyles(doc?: Document): void;
13
+ /**
14
+ * Hook that injects the pack's styles once on mount. Every `/ui` component
15
+ * calls this so rendering any of them is enough to get the styling — the
16
+ * author never imports CSS or runs a setup step.
17
+ */
18
+ export declare function useBlocksStyles(): void;
19
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +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"}