@supatype/ui 0.1.0-alpha.9

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/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-typecheck.log +4 -0
  3. package/dist/Badge.d.ts +6 -0
  4. package/dist/Badge.d.ts.map +1 -0
  5. package/dist/Badge.js +12 -0
  6. package/dist/Badge.js.map +1 -0
  7. package/dist/Button.d.ts +7 -0
  8. package/dist/Button.d.ts.map +1 -0
  9. package/dist/Button.js +17 -0
  10. package/dist/Button.js.map +1 -0
  11. package/dist/Card.d.ts +6 -0
  12. package/dist/Card.d.ts.map +1 -0
  13. package/dist/Card.js +12 -0
  14. package/dist/Card.js.map +1 -0
  15. package/dist/Input.d.ts +7 -0
  16. package/dist/Input.d.ts.map +1 -0
  17. package/dist/Input.js +9 -0
  18. package/dist/Input.js.map +1 -0
  19. package/dist/RichTextEditor.d.ts +21 -0
  20. package/dist/RichTextEditor.d.ts.map +1 -0
  21. package/dist/RichTextEditor.js +100 -0
  22. package/dist/RichTextEditor.js.map +1 -0
  23. package/dist/Skeleton.d.ts +3 -0
  24. package/dist/Skeleton.d.ts.map +1 -0
  25. package/dist/Skeleton.js +6 -0
  26. package/dist/Skeleton.js.map +1 -0
  27. package/dist/ThemeProvider.d.ts +14 -0
  28. package/dist/ThemeProvider.d.ts.map +1 -0
  29. package/dist/ThemeProvider.js +45 -0
  30. package/dist/ThemeProvider.js.map +1 -0
  31. package/dist/index.d.ts +15 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +10 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/richtext-utils.d.ts +13 -0
  36. package/dist/richtext-utils.d.ts.map +1 -0
  37. package/dist/richtext-utils.js +109 -0
  38. package/dist/richtext-utils.js.map +1 -0
  39. package/package.json +53 -0
  40. package/src/Badge.tsx +27 -0
  41. package/src/Button.tsx +36 -0
  42. package/src/Card.tsx +29 -0
  43. package/src/Input.tsx +37 -0
  44. package/src/RichTextEditor.tsx +206 -0
  45. package/src/Skeleton.tsx +11 -0
  46. package/src/ThemeProvider.tsx +64 -0
  47. package/src/index.ts +22 -0
  48. package/src/richtext-utils.ts +112 -0
  49. package/tsconfig.json +11 -0
  50. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,4 @@
1
+
2
+ > @supatype/ui@0.1.0-alpha.9 build /home/runner/work/supatype/supatype/packages/ui
3
+ > tsc --project tsconfig.json
4
+
@@ -0,0 +1,4 @@
1
+
2
+ > @supatype/ui@0.1.0-alpha.9 typecheck /home/runner/work/supatype/supatype/packages/ui
3
+ > tsc --project tsconfig.json --noEmit
4
+
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
3
+ variant?: "default" | "success" | "warning" | "danger" | "purple";
4
+ }
5
+ export declare const Badge: React.FC<BadgeProps>;
6
+ //# sourceMappingURL=Badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../src/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IACvE,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAClE;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAmBtC,CAAA"}
package/dist/Badge.js ADDED
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { clsx } from "clsx";
3
+ export const Badge = ({ variant = "default", className, children, ...props }) => {
4
+ return (_jsx("span", { className: clsx("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium", {
5
+ "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300": variant === "default",
6
+ "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300": variant === "success",
7
+ "bg-yellow-100 text-yellow-700 dark:bg-yellow-900 dark:text-yellow-300": variant === "warning",
8
+ "bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300": variant === "danger",
9
+ "bg-purple-100 text-purple-700 dark:bg-purple-900 dark:text-purple-300": variant === "purple",
10
+ }, className), ...props, children: children }));
11
+ };
12
+ //# sourceMappingURL=Badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.js","sourceRoot":"","sources":["../src/Badge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAM3B,MAAM,CAAC,MAAM,KAAK,GAAyB,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE;IACpG,OAAO,CACL,eACE,SAAS,EAAE,IAAI,CACb,yEAAyE,EACzE;YACE,2EAA2E,EAAE,OAAO,KAAK,SAAS;YAClG,mEAAmE,EAAE,OAAO,KAAK,SAAS;YAC1F,uEAAuE,EAAE,OAAO,KAAK,SAAS;YAC9F,2DAA2D,EAAE,OAAO,KAAK,QAAQ;YACjF,uEAAuE,EAAE,OAAO,KAAK,QAAQ;SAC9F,EACD,SAAS,CACV,KACG,KAAK,YAER,QAAQ,GACJ,CACR,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
3
+ variant?: "primary" | "secondary" | "ghost" | "danger";
4
+ size?: "sm" | "md" | "lg";
5
+ }
6
+ export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
7
+ //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,WAAW,WAAY,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAChF,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAA;IACtD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAED,eAAO,MAAM,MAAM,uFA0BlB,CAAA"}
package/dist/Button.js ADDED
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { clsx } from "clsx";
4
+ export const Button = React.forwardRef(({ variant = "primary", size = "md", className, children, ...props }, ref) => {
5
+ return (_jsx("button", { ref: ref, className: clsx("inline-flex items-center justify-center rounded-lg font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", {
6
+ "bg-purple-600 text-white hover:bg-purple-700": variant === "primary",
7
+ "border border-neutral-300 bg-white text-neutral-900 hover:bg-neutral-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100 dark:hover:bg-neutral-800": variant === "secondary",
8
+ "text-neutral-600 hover:bg-neutral-100 dark:text-neutral-400 dark:hover:bg-neutral-800": variant === "ghost",
9
+ "bg-red-600 text-white hover:bg-red-700": variant === "danger",
10
+ }, {
11
+ "h-8 px-3 text-sm": size === "sm",
12
+ "h-10 px-4 text-sm": size === "md",
13
+ "h-12 px-6 text-base": size === "lg",
14
+ }, className), ...props, children: children }));
15
+ });
16
+ Button.displayName = "Button";
17
+ //# sourceMappingURL=Button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAO3B,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CACpC,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IAC3E,OAAO,CACL,iBACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,IAAI,CACb,+MAA+M,EAC/M;YACE,8CAA8C,EAAE,OAAO,KAAK,SAAS;YACrE,qKAAqK,EAAE,OAAO,KAAK,WAAW;YAC9L,uFAAuF,EAAE,OAAO,KAAK,OAAO;YAC5G,wCAAwC,EAAE,OAAO,KAAK,QAAQ;SAC/D,EACD;YACE,kBAAkB,EAAE,IAAI,KAAK,IAAI;YACjC,mBAAmB,EAAE,IAAI,KAAK,IAAI;YAClC,qBAAqB,EAAE,IAAI,KAAK,IAAI;SACrC,EACD,SAAS,CACV,KACG,KAAK,YAER,QAAQ,GACF,CACV,CAAA;AACH,CAAC,CACF,CAAA;AACD,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAA"}
package/dist/Card.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ padding?: "sm" | "md" | "lg";
4
+ }
5
+ export declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
6
+ //# sourceMappingURL=Card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../src/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC7B;AAED,eAAO,MAAM,IAAI,kFAoBhB,CAAA"}
package/dist/Card.js ADDED
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { clsx } from "clsx";
4
+ export const Card = React.forwardRef(({ padding = "md", className, children, ...props }, ref) => {
5
+ return (_jsx("div", { ref: ref, className: clsx("rounded-xl border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900", {
6
+ "p-4": padding === "sm",
7
+ "p-6": padding === "md",
8
+ "p-8": padding === "lg",
9
+ }, className), ...props, children: children }));
10
+ });
11
+ Card.displayName = "Card";
12
+ //# sourceMappingURL=Card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.js","sourceRoot":"","sources":["../src/Card.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAM3B,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAClC,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IACzD,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,IAAI,CACb,2FAA2F,EAC3F;YACE,KAAK,EAAE,OAAO,KAAK,IAAI;YACvB,KAAK,EAAE,OAAO,KAAK,IAAI;YACvB,KAAK,EAAE,OAAO,KAAK,IAAI;SACxB,EACD,SAAS,CACV,KACG,KAAK,YAER,QAAQ,GACL,CACP,CAAA;AACH,CAAC,CACF,CAAA;AACD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAA"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
3
+ label?: string;
4
+ error?: string;
5
+ }
6
+ export declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
7
+ //# sourceMappingURL=Input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,KAAK,qFA2BjB,CAAA"}
package/dist/Input.js ADDED
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { clsx } from "clsx";
4
+ export const Input = React.forwardRef(({ label, error, className, id, ...props }, ref) => {
5
+ const inputId = id ?? label?.toLowerCase().replace(/\s+/g, "-");
6
+ return (_jsxs("div", { className: "flex flex-col gap-1.5", children: [label && (_jsx("label", { htmlFor: inputId, className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: label })), _jsx("input", { ref: ref, id: inputId, className: clsx("h-10 rounded-lg border px-3 text-sm transition-colors", "border-neutral-300 bg-white text-neutral-900 placeholder:text-neutral-500", "dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100 dark:placeholder:text-neutral-500", "focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500", error && "border-red-500 focus:border-red-500 focus:ring-red-500", className), ...props }), error && _jsx("p", { className: "text-sm text-red-500", children: error })] }));
7
+ });
8
+ Input.displayName = "Input";
9
+ //# sourceMappingURL=Input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.js","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAO3B,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CACnC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IACjD,MAAM,OAAO,GAAG,EAAE,IAAI,KAAK,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC/D,OAAO,CACL,eAAK,SAAS,EAAC,uBAAuB,aACnC,KAAK,IAAI,CACR,gBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,4DAA4D,YAC5F,KAAK,GACA,CACT,EACD,gBACE,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,IAAI,CACb,uDAAuD,EACvD,2EAA2E,EAC3E,qGAAqG,EACrG,+EAA+E,EAC/E,KAAK,IAAI,wDAAwD,EACjE,SAAS,CACV,KACG,KAAK,GACT,EACD,KAAK,IAAI,YAAG,SAAS,EAAC,sBAAsB,YAAE,KAAK,GAAK,IACrD,CACP,CAAA;AACH,CAAC,CACF,CAAA;AACD,KAAK,CAAC,WAAW,GAAG,OAAO,CAAA"}
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import type { SerializedEditorState } from "@supatype/types/lexical";
3
+ export interface RichTextEditorProps {
4
+ /** Initial document (Lexical JSON). Updates only on mount; use `documentKey` to reload. */
5
+ value?: SerializedEditorState | null | undefined;
6
+ onChange: (json: SerializedEditorState) => void;
7
+ placeholder?: string | undefined;
8
+ className?: string | undefined;
9
+ editable?: boolean | undefined;
10
+ /** Change when switching documents so Lexical remounts with new `value`. */
11
+ documentKey?: string | undefined;
12
+ /** `id` on the editable surface (e.g. for `<label htmlFor>`). */
13
+ contentEditableId?: string | undefined;
14
+ }
15
+ /**
16
+ * Lexical-based rich text editor aligned with `@supatype/types` `RichText` / `SerializedEditorState`.
17
+ *
18
+ * Peer dependencies: `lexical`, `@lexical/react`, `@lexical/rich-text`, `@lexical/list`, `@lexical/link`, `@lexical/selection`.
19
+ */
20
+ export declare function RichTextEditor({ value, onChange, placeholder, className, editable, documentKey, contentEditableId, }: RichTextEditorProps): React.ReactElement;
21
+ //# sourceMappingURL=RichTextEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../src/RichTextEditor.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAkD,MAAM,OAAO,CAAA;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAkIpE,MAAM,WAAW,mBAAmB;IAClC,2FAA2F;IAC3F,KAAK,CAAC,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,CAAA;IAChD,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAC/C,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC9B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,iEAAiE;IACjE,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,WAAgC,EAChC,SAAS,EACT,QAAe,EACf,WAAuB,EACvB,iBAAiB,GAClB,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CA8C1C"}
@@ -0,0 +1,100 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useMemo, useRef } from "react";
4
+ import { LexicalComposer } from "@lexical/react/LexicalComposer";
5
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
6
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
7
+ import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
8
+ import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
9
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
10
+ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
11
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
12
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
13
+ import { $getSelection, $isRangeSelection, FORMAT_TEXT_COMMAND, } from "lexical";
14
+ import { $createHeadingNode, HeadingNode, QuoteNode } from "@lexical/rich-text";
15
+ import { ListNode, ListItemNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from "@lexical/list";
16
+ import { AutoLinkNode, LinkNode } from "@lexical/link";
17
+ import { $setBlocksType } from "@lexical/selection";
18
+ import { $createParagraphNode, $getRoot } from "lexical";
19
+ import clsx from "clsx";
20
+ const EDITOR_NODES = [HeadingNode, QuoteNode, ListNode, ListItemNode, LinkNode, AutoLinkNode];
21
+ const EDITOR_THEME = {
22
+ heading: { h1: "su-rt-h1", h2: "su-rt-h2", h3: "su-rt-h3" },
23
+ text: { bold: "su-rt-bold", italic: "su-rt-italic", underline: "su-rt-underline", strikethrough: "su-rt-strikethrough" },
24
+ list: { ul: "su-rt-ul", ol: "su-rt-ol", listitem: "su-rt-li" },
25
+ link: "su-rt-link",
26
+ paragraph: "su-rt-p",
27
+ };
28
+ function ToolbarPlugin() {
29
+ const [editor] = useLexicalComposerContext();
30
+ const format = useCallback((fmt) => {
31
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, fmt);
32
+ }, [editor]);
33
+ const setHeading = useCallback((tag) => {
34
+ editor.update(() => {
35
+ const selection = $getSelection();
36
+ if ($isRangeSelection(selection)) {
37
+ $setBlocksType(selection, () => $createHeadingNode(tag));
38
+ }
39
+ });
40
+ }, [editor]);
41
+ const setParagraph = useCallback(() => {
42
+ editor.update(() => {
43
+ const selection = $getSelection();
44
+ if ($isRangeSelection(selection)) {
45
+ $setBlocksType(selection, () => $createParagraphNode());
46
+ }
47
+ });
48
+ }, [editor]);
49
+ return (_jsxs("div", { className: "su-richtext-toolbar", role: "toolbar", "aria-label": "Formatting", children: [_jsx("button", { type: "button", title: "Bold", onMouseDown: (e) => { e.preventDefault(); format("bold"); }, children: "B" }), _jsx("button", { type: "button", title: "Italic", onMouseDown: (e) => { e.preventDefault(); format("italic"); }, children: "I" }), _jsx("button", { type: "button", title: "Underline", onMouseDown: (e) => { e.preventDefault(); format("underline"); }, children: "U" }), _jsx("span", { className: "su-richtext-toolbar-divider", "aria-hidden": true }), _jsx("button", { type: "button", title: "Heading 1", onMouseDown: (e) => { e.preventDefault(); setHeading("h1"); }, children: "H1" }), _jsx("button", { type: "button", title: "Heading 2", onMouseDown: (e) => { e.preventDefault(); setHeading("h2"); }, children: "H2" }), _jsx("button", { type: "button", title: "Paragraph", onMouseDown: (e) => { e.preventDefault(); setParagraph(); }, children: "\u00B6" }), _jsx("span", { className: "su-richtext-toolbar-divider", "aria-hidden": true }), _jsx("button", { type: "button", title: "Bullet list", onMouseDown: (e) => {
50
+ e.preventDefault();
51
+ editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);
52
+ }, children: "\u2022" }), _jsx("button", { type: "button", title: "Numbered list", onMouseDown: (e) => {
53
+ e.preventDefault();
54
+ editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);
55
+ }, children: "1." })] }));
56
+ }
57
+ function InitialStatePlugin({ value }) {
58
+ const [editor] = useLexicalComposerContext();
59
+ const loaded = useRef(false);
60
+ useEffect(() => {
61
+ if (loaded.current)
62
+ return;
63
+ loaded.current = true;
64
+ if (value !== null && value !== undefined && typeof value === "object") {
65
+ try {
66
+ const state = editor.parseEditorState(JSON.stringify(value));
67
+ editor.setEditorState(state);
68
+ }
69
+ catch {
70
+ editor.update(() => {
71
+ const root = $getRoot();
72
+ root.clear();
73
+ root.append($createParagraphNode());
74
+ });
75
+ }
76
+ }
77
+ }, [editor, value]);
78
+ return null;
79
+ }
80
+ /**
81
+ * Lexical-based rich text editor aligned with `@supatype/types` `RichText` / `SerializedEditorState`.
82
+ *
83
+ * Peer dependencies: `lexical`, `@lexical/react`, `@lexical/rich-text`, `@lexical/list`, `@lexical/link`, `@lexical/selection`.
84
+ */
85
+ export function RichTextEditor({ value, onChange, placeholder = "Write something…", className, editable = true, documentKey = "default", contentEditableId, }) {
86
+ const initialConfig = useMemo(() => ({
87
+ namespace: `supatype-richtext-${documentKey}`,
88
+ theme: EDITOR_THEME,
89
+ nodes: EDITOR_NODES,
90
+ editable,
91
+ onError: (err) => {
92
+ console.error("[RichTextEditor]", err);
93
+ },
94
+ }), [documentKey, editable]);
95
+ const handleChange = useCallback((editorState, _editor) => {
96
+ onChange(editorState.toJSON());
97
+ }, [onChange]);
98
+ return (_jsx("div", { className: clsx("su-richtext", className, !editable && "su-richtext-readonly"), children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [editable ? _jsx(ToolbarPlugin, {}) : null, _jsx(InitialStatePlugin, { value: value }), _jsx("div", { className: "su-richtext-surface", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { id: contentEditableId, className: "su-richtext-editable", "aria-label": placeholder }), placeholder: _jsx("div", { className: "su-richtext-placeholder", children: placeholder }), ErrorBoundary: LexicalErrorBoundary }) }), _jsx(HistoryPlugin, {}), _jsx(ListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(OnChangePlugin, { onChange: handleChange, ignoreSelectionChange: true })] }, documentKey) }));
99
+ }
100
+ //# sourceMappingURL=RichTextEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RichTextEditor.js","sourceRoot":"","sources":["../src/RichTextEditor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ export declare const Skeleton: React.FC<React.HTMLAttributes<HTMLDivElement>>;
3
+ //# sourceMappingURL=Skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../src/Skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAOnE,CAAA"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { clsx } from "clsx";
3
+ export const Skeleton = ({ className, ...props }) => {
4
+ return (_jsx("div", { className: clsx("animate-pulse rounded-md bg-neutral-200 dark:bg-neutral-800", className), ...props }));
5
+ };
6
+ //# sourceMappingURL=Skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.js","sourceRoot":"","sources":["../src/Skeleton.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,MAAM,CAAC,MAAM,QAAQ,GAAmD,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE;IAClG,OAAO,CACL,cACE,SAAS,EAAE,IAAI,CAAC,6DAA6D,EAAE,SAAS,CAAC,KACrF,KAAK,GACT,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ type Theme = "light" | "dark" | "system";
3
+ interface ThemeContextValue {
4
+ theme: Theme;
5
+ resolvedTheme: "light" | "dark";
6
+ setTheme: (theme: Theme) => void;
7
+ }
8
+ export declare function useTheme(): ThemeContextValue;
9
+ export declare const ThemeProvider: React.FC<{
10
+ defaultTheme?: Theme;
11
+ children: React.ReactNode;
12
+ }>;
13
+ export {};
14
+ //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../src/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAA;AAE7E,KAAK,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,UAAU,iBAAiB;IACzB,KAAK,EAAE,KAAK,CAAA;IACZ,aAAa,EAAE,OAAO,GAAG,MAAM,CAAA;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACjC;AAID,wBAAgB,QAAQ,IAAI,iBAAiB,CAI5C;AAOD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,YAAY,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAwCvF,CAAA"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useState } from "react";
3
+ const ThemeContext = createContext(null);
4
+ export function useTheme() {
5
+ const ctx = useContext(ThemeContext);
6
+ if (!ctx)
7
+ throw new Error("useTheme must be used within a ThemeProvider");
8
+ return ctx;
9
+ }
10
+ function getSystemTheme() {
11
+ if (typeof window === "undefined")
12
+ return "dark";
13
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
14
+ }
15
+ export const ThemeProvider = ({ defaultTheme = "system", children, }) => {
16
+ const [theme, setThemeState] = useState(() => {
17
+ if (typeof window === "undefined")
18
+ return defaultTheme;
19
+ return localStorage.getItem("supatype-theme") ?? defaultTheme;
20
+ });
21
+ const [resolvedTheme, setResolved] = useState(() => theme === "system" ? getSystemTheme() : theme);
22
+ useEffect(() => {
23
+ const resolved = theme === "system" ? getSystemTheme() : theme;
24
+ setResolved(resolved);
25
+ document.documentElement.classList.toggle("dark", resolved === "dark");
26
+ }, [theme]);
27
+ useEffect(() => {
28
+ if (theme !== "system")
29
+ return;
30
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
31
+ const handler = () => {
32
+ const resolved = getSystemTheme();
33
+ setResolved(resolved);
34
+ document.documentElement.classList.toggle("dark", resolved === "dark");
35
+ };
36
+ mq.addEventListener("change", handler);
37
+ return () => mq.removeEventListener("change", handler);
38
+ }, [theme]);
39
+ const setTheme = (t) => {
40
+ setThemeState(t);
41
+ localStorage.setItem("supatype-theme", t);
42
+ };
43
+ return (_jsx(ThemeContext.Provider, { value: { theme, resolvedTheme, setTheme }, children: children }));
44
+ };
45
+ //# sourceMappingURL=ThemeProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.js","sourceRoot":"","sources":["../src/ThemeProvider.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAU7E,MAAM,YAAY,GAAG,aAAa,CAA2B,IAAI,CAAC,CAAA;AAElE,MAAM,UAAU,QAAQ;IACtB,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAA;IACpC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACzE,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,MAAM,CAAA;IAChD,OAAO,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;AACrF,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAkE,CAAC,EAC3F,YAAY,GAAG,QAAQ,EACvB,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAQ,GAAG,EAAE;QAClD,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO,YAAY,CAAA;QACtD,OAAQ,YAAY,CAAC,OAAO,CAAC,gBAAgB,CAAW,IAAI,YAAY,CAAA;IAC1E,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,GAAG,EAAE,CACnE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,KAAK,CAC9C,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;QAC9D,WAAW,CAAC,QAAQ,CAAC,CAAA;QACrB,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAA;IACxE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAM;QAC9B,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAA;QAC5D,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;YACjC,WAAW,CAAC,QAAQ,CAAC,CAAA;YACrB,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAA;QACxE,CAAC,CAAA;QACD,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACtC,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACxD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,QAAQ,GAAG,CAAC,CAAQ,EAAE,EAAE;QAC5B,aAAa,CAAC,CAAC,CAAC,CAAA;QAChB,YAAY,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAA;IAC3C,CAAC,CAAA;IAED,OAAO,CACL,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,YAC7D,QAAQ,GACa,CACzB,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,15 @@
1
+ export { Button } from "./Button.js";
2
+ export type { ButtonProps } from "./Button.js";
3
+ export { Input } from "./Input.js";
4
+ export type { InputProps } from "./Input.js";
5
+ export { Card } from "./Card.js";
6
+ export type { CardProps } from "./Card.js";
7
+ export { Badge } from "./Badge.js";
8
+ export type { BadgeProps } from "./Badge.js";
9
+ export { Skeleton } from "./Skeleton.js";
10
+ export { ThemeProvider, useTheme } from "./ThemeProvider.js";
11
+ export { RichTextEditor } from "./RichTextEditor.js";
12
+ export type { RichTextEditorProps } from "./RichTextEditor.js";
13
+ export { emptyRichTextDocument, normalizeRichTextDefault, richTextIsEmpty, stringToRichTextDocument } from "./richtext-utils.js";
14
+ export type { SerializedEditorState, SerializedLexicalNode } from "@supatype/types/lexical";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAChI,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ // @supatype/ui — Shared component library
2
+ export { Button } from "./Button.js";
3
+ export { Input } from "./Input.js";
4
+ export { Card } from "./Card.js";
5
+ export { Badge } from "./Badge.js";
6
+ export { Skeleton } from "./Skeleton.js";
7
+ export { ThemeProvider, useTheme } from "./ThemeProvider.js";
8
+ export { RichTextEditor } from "./RichTextEditor.js";
9
+ export { emptyRichTextDocument, normalizeRichTextDefault, richTextIsEmpty, stringToRichTextDocument } from "./richtext-utils.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAGhC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { SerializedEditorState } from "@supatype/types/lexical";
2
+ /** Lexical-compatible empty document (one empty paragraph). */
3
+ export declare function emptyRichTextDocument(): SerializedEditorState;
4
+ /** Plain sentence → minimal Lexical document (single paragraph). Not HTML — literal text only. */
5
+ export declare function stringToRichTextDocument(text: string): SerializedEditorState;
6
+ /**
7
+ * Normalize a RichText default or seed value: Lexical object passthrough, JSON Lexical string, or plain string → Lexical.
8
+ * Does not parse HTML.
9
+ */
10
+ export declare function normalizeRichTextDefault(value: SerializedEditorState | string | null | undefined): SerializedEditorState | null;
11
+ /** True when the editor has no visible text (whitespace-only counts as empty). */
12
+ export declare function richTextIsEmpty(state: SerializedEditorState | null | undefined): boolean;
13
+ //# sourceMappingURL=richtext-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"richtext-utils.d.ts","sourceRoot":"","sources":["../src/richtext-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAyB,MAAM,yBAAyB,CAAA;AAE3F,+DAA+D;AAC/D,wBAAgB,qBAAqB,IAAI,qBAAqB,CA4B7D;AAED,kGAAkG;AAClG,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CA4B5E;AAWD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GACvD,qBAAqB,GAAG,IAAI,CAgB9B;AAYD,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAGxF"}
@@ -0,0 +1,109 @@
1
+ /** Lexical-compatible empty document (one empty paragraph). */
2
+ export function emptyRichTextDocument() {
3
+ return {
4
+ root: {
5
+ type: "root",
6
+ format: "",
7
+ indent: 0,
8
+ version: 1,
9
+ children: [
10
+ {
11
+ type: "paragraph",
12
+ format: "",
13
+ indent: 0,
14
+ version: 1,
15
+ children: [
16
+ {
17
+ type: "text",
18
+ text: "",
19
+ format: 0,
20
+ style: "",
21
+ mode: "normal",
22
+ detail: 0,
23
+ version: 1,
24
+ },
25
+ ],
26
+ },
27
+ ],
28
+ },
29
+ };
30
+ }
31
+ /** Plain sentence → minimal Lexical document (single paragraph). Not HTML — literal text only. */
32
+ export function stringToRichTextDocument(text) {
33
+ return {
34
+ root: {
35
+ type: "root",
36
+ format: "",
37
+ indent: 0,
38
+ version: 1,
39
+ children: [
40
+ {
41
+ type: "paragraph",
42
+ format: "",
43
+ indent: 0,
44
+ version: 1,
45
+ children: [
46
+ {
47
+ type: "text",
48
+ text,
49
+ format: 0,
50
+ style: "",
51
+ mode: "normal",
52
+ detail: 0,
53
+ version: 1,
54
+ },
55
+ ],
56
+ },
57
+ ],
58
+ },
59
+ };
60
+ }
61
+ function isLexicalDocument(value) {
62
+ return (typeof value === "object" &&
63
+ value !== null &&
64
+ "root" in value &&
65
+ typeof value.root === "object");
66
+ }
67
+ /**
68
+ * Normalize a RichText default or seed value: Lexical object passthrough, JSON Lexical string, or plain string → Lexical.
69
+ * Does not parse HTML.
70
+ */
71
+ export function normalizeRichTextDefault(value) {
72
+ if (value === null || value === undefined)
73
+ return null;
74
+ if (isLexicalDocument(value))
75
+ return value;
76
+ if (typeof value === "string") {
77
+ const trimmed = value.trim();
78
+ if (trimmed.startsWith("{")) {
79
+ try {
80
+ const parsed = JSON.parse(trimmed);
81
+ if (isLexicalDocument(parsed))
82
+ return parsed;
83
+ }
84
+ catch {
85
+ // fall through — treat as plain text
86
+ }
87
+ }
88
+ return stringToRichTextDocument(value);
89
+ }
90
+ return null;
91
+ }
92
+ function collectText(node) {
93
+ let out = "";
94
+ if (typeof node.text === "string")
95
+ out += node.text;
96
+ const children = node.children;
97
+ if (Array.isArray(children)) {
98
+ for (const c of children)
99
+ out += collectText(c);
100
+ }
101
+ return out;
102
+ }
103
+ /** True when the editor has no visible text (whitespace-only counts as empty). */
104
+ export function richTextIsEmpty(state) {
105
+ if (state === null || state === undefined)
106
+ return true;
107
+ return collectText(state.root).trim() === "";
108
+ }
109
+ //# sourceMappingURL=richtext-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"richtext-utils.js","sourceRoot":"","sources":["../src/richtext-utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@supatype/ui",
3
+ "version": "0.1.0-alpha.9",
4
+ "description": "Shared React component library — Tailwind + Radix UI primitives",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./styles.css": "./dist/styles.css"
14
+ },
15
+ "peerDependencies": {
16
+ "@lexical/link": "^0.43.0",
17
+ "@lexical/list": "^0.43.0",
18
+ "@lexical/react": "^0.43.0",
19
+ "@lexical/rich-text": "^0.43.0",
20
+ "@lexical/selection": "^0.43.0",
21
+ "lexical": "^0.43.0",
22
+ "react": "^18.0.0 || ^19.0.0",
23
+ "react-dom": "^18.0.0 || ^19.0.0"
24
+ },
25
+ "dependencies": {
26
+ "@radix-ui/react-dialog": "^1.1.0",
27
+ "@radix-ui/react-dropdown-menu": "^2.1.0",
28
+ "@radix-ui/react-select": "^2.1.0",
29
+ "@radix-ui/react-tabs": "^1.1.0",
30
+ "@radix-ui/react-toast": "^1.2.0",
31
+ "@radix-ui/react-tooltip": "^1.1.0",
32
+ "clsx": "^2.1.0",
33
+ "@supatype/types": "0.1.0-alpha.9"
34
+ },
35
+ "devDependencies": {
36
+ "@lexical/link": "^0.43.0",
37
+ "@lexical/list": "^0.43.0",
38
+ "@lexical/react": "^0.43.0",
39
+ "@lexical/rich-text": "^0.43.0",
40
+ "@lexical/selection": "^0.43.0",
41
+ "@types/react": "^19",
42
+ "@types/react-dom": "^19",
43
+ "lexical": "^0.43.0",
44
+ "react": "^19.0.0",
45
+ "react-dom": "^19.0.0",
46
+ "typescript": "^5"
47
+ },
48
+ "scripts": {
49
+ "build": "tsc --project tsconfig.json",
50
+ "typecheck": "tsc --project tsconfig.json --noEmit",
51
+ "clean": "rm -rf dist *.tsbuildinfo"
52
+ }
53
+ }