@danieljoffe/shared-ui 0.0.1 → 0.1.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.
Files changed (54) hide show
  1. package/dist/index.js +110 -5358
  2. package/dist/lib/Alert.js +72 -0
  3. package/dist/lib/AspectRatio.js +31 -0
  4. package/dist/lib/Avatar.js +47 -0
  5. package/dist/lib/Badge.js +43 -0
  6. package/dist/lib/Breadcrumb.js +28 -0
  7. package/dist/lib/Button.js +82 -0
  8. package/dist/lib/CTACard.js +31 -0
  9. package/dist/lib/Card.js +91 -0
  10. package/dist/lib/Checkbox.js +75 -0
  11. package/dist/lib/Container.js +35 -0
  12. package/dist/lib/Divider.js +48 -0
  13. package/dist/lib/Dropdown.js +158 -0
  14. package/dist/lib/FormFieldError.js +8 -0
  15. package/dist/lib/Grid.js +67 -0
  16. package/dist/lib/GridBg.js +31 -0
  17. package/dist/lib/Heading.js +40 -0
  18. package/dist/lib/Input.js +55 -0
  19. package/dist/lib/Kbd.js +19 -0
  20. package/dist/lib/Loading.js +44 -0
  21. package/dist/lib/Modal.js +119 -0
  22. package/dist/lib/PageContainer.js +35 -0
  23. package/dist/lib/PageLayout.js +25 -0
  24. package/dist/lib/Pagination.js +111 -0
  25. package/dist/lib/ProgressBar.js +68 -0
  26. package/dist/lib/Section.js +58 -0
  27. package/dist/lib/SectionLabel.js +19 -0
  28. package/dist/lib/Select.js +67 -0
  29. package/dist/lib/Sidebar.js +97 -0
  30. package/dist/lib/Skeleton.js +63 -0
  31. package/dist/lib/Spacer.js +17 -0
  32. package/dist/lib/Spinner.js +39 -0
  33. package/dist/lib/Stack.js +59 -0
  34. package/dist/lib/StatsCard.js +79 -0
  35. package/dist/lib/StructuredData.js +15 -0
  36. package/dist/lib/Switch.js +69 -0
  37. package/dist/lib/Table.js +91 -0
  38. package/dist/lib/Tabs.js +101 -0
  39. package/dist/lib/Text.js +48 -0
  40. package/dist/lib/Textarea.js +50 -0
  41. package/dist/lib/ThemeProvider.js +54 -0
  42. package/dist/lib/ThemeToggle.js +29 -0
  43. package/dist/lib/Toast.js +95 -0
  44. package/dist/lib/Tooltip.js +70 -0
  45. package/dist/lib/index.js +112 -0
  46. package/dist/lib/styles/formStyles.js +24 -0
  47. package/dist/lib/styles/semanticVariants.js +27 -0
  48. package/dist/lib/types.js +1 -0
  49. package/dist/lib/utils/ErrorBoundary.js +17 -0
  50. package/dist/lib/utils/ModalErrorBoundary.js +17 -0
  51. package/dist/lib/utils/cn.js +8 -0
  52. package/dist/lib/utils/index.js +10 -0
  53. package/dist/lib/utils/validateProps.js +7 -0
  54. package/package.json +7 -4
@@ -0,0 +1,72 @@
1
+ "use client";
2
+ import { jsx as e, jsxs as d } from "react/jsx-runtime";
3
+ import { AlertCircle as $, AlertTriangle as g, CheckCircle as h, Info as E, X as T } from "lucide-react";
4
+ import { useCallback as v, useEffect as I } from "react";
5
+ import { Heading as x } from "./Heading.js";
6
+ import { DISMISS_BUTTON as C } from "./styles/formStyles.js";
7
+ import { SEMANTIC_BG_LIGHT as a, SEMANTIC_BORDER as t, SEMANTIC_TEXT as s } from "./styles/semanticVariants.js";
8
+ import { cn as k } from "./utils/cn.js";
9
+ const S = {
10
+ info: E,
11
+ success: h,
12
+ warning: g,
13
+ error: $
14
+ }, A = {
15
+ info: `${a.info} ${t.info} ${s.info}`,
16
+ success: `${a.success} ${t.success} ${s.success}`,
17
+ warning: `${a.warning} ${t.warning} ${s.warning}`,
18
+ error: `${a.error} ${t.error} ${s.error}`
19
+ };
20
+ function z({
21
+ children: m,
22
+ variant: n = "info",
23
+ title: c,
24
+ dismissible: i = !1,
25
+ onDismiss: r,
26
+ className: f,
27
+ ref: u,
28
+ ...p
29
+ }) {
30
+ const w = S[n], l = n === "error" || n === "warning", o = v(
31
+ (N) => {
32
+ N.key === "Escape" && r?.();
33
+ },
34
+ [r]
35
+ );
36
+ return I(() => {
37
+ if (!(!i || !r))
38
+ return window.addEventListener("keydown", o), () => window.removeEventListener("keydown", o);
39
+ }, [i, r, o]), /* @__PURE__ */ e(
40
+ "div",
41
+ {
42
+ ref: u,
43
+ role: l ? "alert" : "status",
44
+ "aria-live": l ? "assertive" : "polite",
45
+ className: k(
46
+ "relative rounded-lg border p-4",
47
+ A[n],
48
+ f
49
+ ),
50
+ ...p,
51
+ children: /* @__PURE__ */ d("div", { className: "flex gap-3", children: [
52
+ /* @__PURE__ */ e(w, { className: "size-5 shrink-0 mt-0.5", "aria-hidden": "true" }),
53
+ /* @__PURE__ */ d("div", { className: "flex-1", children: [
54
+ c && /* @__PURE__ */ e(x, { variant: "cardTitle", as: "h5", className: "mb-1 mt-0", children: c }),
55
+ /* @__PURE__ */ e("div", { className: "text-sm text-text-primary", children: m })
56
+ ] }),
57
+ i && /* @__PURE__ */ e(
58
+ "button",
59
+ {
60
+ onClick: r,
61
+ "aria-label": "Dismiss alert",
62
+ className: C,
63
+ children: /* @__PURE__ */ e(T, { className: "size-4", "aria-hidden": "true" })
64
+ }
65
+ )
66
+ ] })
67
+ }
68
+ );
69
+ }
70
+ export {
71
+ z as Alert
72
+ };
@@ -0,0 +1,31 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { cn as p } from "./utils/cn.js";
3
+ import "react";
4
+ const r = {
5
+ "1/1": "aspect-square",
6
+ "4/3": "aspect-[4/3]",
7
+ "16/9": "aspect-video",
8
+ "21/9": "aspect-[21/9]",
9
+ "3/4": "aspect-[3/4]",
10
+ "9/16": "aspect-[9/16]"
11
+ };
12
+ function n({
13
+ children: t,
14
+ ratio: e = "16/9",
15
+ className: s,
16
+ ref: a,
17
+ ...c
18
+ }) {
19
+ return /* @__PURE__ */ o(
20
+ "div",
21
+ {
22
+ ref: a,
23
+ className: p("relative w-full", r[e], s),
24
+ ...c,
25
+ children: t
26
+ }
27
+ );
28
+ }
29
+ export {
30
+ n as AspectRatio
31
+ };
@@ -0,0 +1,47 @@
1
+ import { jsxs as i, jsx as e } from "react/jsx-runtime";
2
+ import { cn as r } from "./utils/cn.js";
3
+ const c = {
4
+ sm: "h-8 w-8 text-xs",
5
+ md: "h-10 w-10 text-sm",
6
+ lg: "h-12 w-12 text-base"
7
+ }, d = {
8
+ online: "bg-success",
9
+ offline: "bg-text-tertiary",
10
+ away: "bg-warning",
11
+ busy: "bg-error"
12
+ };
13
+ function b({
14
+ src: t,
15
+ alt: s = "",
16
+ initials: l,
17
+ size: n = "md",
18
+ status: o,
19
+ className: a
20
+ }) {
21
+ return /* @__PURE__ */ i("div", { className: r("relative inline-flex shrink-0", a), children: [
22
+ /* @__PURE__ */ e(
23
+ "div",
24
+ {
25
+ className: r(
26
+ "rounded-full flex items-center justify-center font-medium overflow-hidden",
27
+ "bg-brand-100 text-brand-700",
28
+ c[n]
29
+ ),
30
+ children: t ? /* @__PURE__ */ e("img", { src: t, alt: s, className: "h-full w-full object-cover" }) : /* @__PURE__ */ e("span", { children: l || s?.charAt(0)?.toUpperCase() || "?" })
31
+ }
32
+ ),
33
+ o && /* @__PURE__ */ e(
34
+ "span",
35
+ {
36
+ className: r(
37
+ "absolute bottom-0 right-0 rounded-full border-2 border-surface",
38
+ d[o],
39
+ n === "sm" ? "h-2 w-2" : "h-3 w-3"
40
+ )
41
+ }
42
+ )
43
+ ] });
44
+ }
45
+ export {
46
+ b as Avatar
47
+ };
@@ -0,0 +1,43 @@
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ import { SEMANTIC_BG_LIGHT as i, SEMANTIC_TEXT as m, SEMANTIC_BORDER as x } from "./styles/semanticVariants.js";
3
+ import { cn as c } from "./utils/cn.js";
4
+ import "react";
5
+ const r = (e) => `${i[e]} ${m[e]} border ${x[e]}`, p = {
6
+ default: "bg-surface-elevated text-text-secondary border border-border",
7
+ success: r("success"),
8
+ warning: r("warning"),
9
+ error: r("error"),
10
+ info: r("info"),
11
+ brand: "bg-brand-50 text-brand-700",
12
+ "brand-solid": "bg-brand-600 text-white"
13
+ }, b = {
14
+ sm: "px-1.5 py-0.5 text-[10px]",
15
+ md: "px-2.5 py-0.5 text-xs",
16
+ lg: "px-3 py-1 text-sm"
17
+ };
18
+ function y({
19
+ children: e,
20
+ variant: t = "default",
21
+ size: n = "md",
22
+ className: o,
23
+ ref: s,
24
+ ...d
25
+ }) {
26
+ return /* @__PURE__ */ a(
27
+ "span",
28
+ {
29
+ ref: s,
30
+ className: c(
31
+ "inline-flex items-center rounded-md font-medium",
32
+ b[n],
33
+ p[t],
34
+ o
35
+ ),
36
+ ...d,
37
+ children: e
38
+ }
39
+ );
40
+ }
41
+ export {
42
+ y as Badge
43
+ };
@@ -0,0 +1,28 @@
1
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
2
+ import { ChevronRight as l } from "lucide-react";
3
+ import { cn as o } from "./utils/cn.js";
4
+ function p({ items: a, className: s }) {
5
+ return /* @__PURE__ */ n("nav", { className: o("flex items-center gap-1 text-sm", s), children: a.map((e, t) => {
6
+ const c = t === a.length - 1;
7
+ return /* @__PURE__ */ r("div", { className: "flex items-center gap-1", children: [
8
+ t > 0 && /* @__PURE__ */ n(l, { className: "h-3.5 w-3.5 text-text-tertiary" }),
9
+ c ? /* @__PURE__ */ r("span", { className: "font-medium text-text-primary flex items-center gap-1.5", children: [
10
+ e.icon,
11
+ e.label
12
+ ] }) : /* @__PURE__ */ r(
13
+ "a",
14
+ {
15
+ href: e.href || "#",
16
+ className: "text-text-secondary hover:text-text-primary transition-colors flex items-center gap-1.5",
17
+ children: [
18
+ e.icon,
19
+ e.label
20
+ ]
21
+ }
22
+ )
23
+ ] }, t);
24
+ }) });
25
+ }
26
+ export {
27
+ p as Breadcrumb
28
+ };
@@ -0,0 +1,82 @@
1
+ import { jsxs as b, jsx as v } from "react/jsx-runtime";
2
+ import { Spinner as p } from "./Spinner.js";
3
+ import { FOCUS_RING as h, FOCUS_RING_OFFSET as y, DISABLED as x } from "./styles/formStyles.js";
4
+ import { cn as n } from "./utils/cn.js";
5
+ import "react";
6
+ const f = [
7
+ "inline-flex items-center justify-center gap-2 rounded-md transition",
8
+ `duration-200 ${h} ${y}`,
9
+ x,
10
+ "hover:cursor-pointer motion-reduce:transition-none motion-reduce:hover:transform-none"
11
+ ].join(" "), t = "hover:shadow-lg/12.5", g = {
12
+ bare: "",
13
+ primary: `${t} bg-brand-500 text-text-on-brand hover:bg-brand-600 active:bg-brand-700`,
14
+ secondary: `${t} bg-surface-elevated text-text-primary hover:bg-surface border border-border`,
15
+ outline: `${t} border border-border-secondary text-text-primary hover:bg-surface-elevated`
16
+ }, o = "hover:outline hover:outline-2 hover:outline-offset-2 hover:shadow-lg/12.5", I = {
17
+ bare: "",
18
+ primary: `${o} hover:outline-brand-500`,
19
+ secondary: `${o} hover:outline-border-strong`,
20
+ outline: `${o} hover:outline-border-strong`
21
+ }, S = {
22
+ sm: "px-3 py-1.5 text-sm hover:scale-[1.1]",
23
+ md: "px-4 py-3 hover:scale-[1.05]",
24
+ lg: "px-6 py-3 text-lg hover:scale-[1.025]"
25
+ }, $ = {
26
+ sm: "p-1.5 text-sm hover:scale-[1.1]",
27
+ md: "p-2.5 hover:scale-[1.05]",
28
+ lg: "p-3 text-lg hover:scale-[1.025]"
29
+ }, B = {
30
+ sm: "size-3.5",
31
+ md: "size-4",
32
+ lg: "size-5"
33
+ };
34
+ function _({
35
+ variant: s = "primary",
36
+ size: e = "md",
37
+ loading: r = !1,
38
+ iconOnly: a = !1,
39
+ as: i = "button",
40
+ children: l,
41
+ className: d,
42
+ disabled: c,
43
+ ref: u,
44
+ ...m
45
+ }) {
46
+ return /* @__PURE__ */ b(
47
+ i,
48
+ {
49
+ ref: u,
50
+ className: n(
51
+ f,
52
+ g[s],
53
+ a ? $[e] : S[e],
54
+ d
55
+ ),
56
+ disabled: c || r,
57
+ "aria-busy": r || void 0,
58
+ ...m,
59
+ children: [
60
+ r && /* @__PURE__ */ v(
61
+ p,
62
+ {
63
+ size: "sm",
64
+ className: n(
65
+ "border-current/30 border-t-current",
66
+ B[e]
67
+ ),
68
+ "aria-hidden": "true"
69
+ }
70
+ ),
71
+ l
72
+ ]
73
+ }
74
+ );
75
+ }
76
+ export {
77
+ _ as Button,
78
+ f as baseButtonStyles,
79
+ S as sizeButtonStyles,
80
+ g as variantButtonStyles,
81
+ I as variantLinkOutline
82
+ };
@@ -0,0 +1,31 @@
1
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
2
+ import { Heading as m } from "./Heading.js";
3
+ import { Text as s } from "./Text.js";
4
+ import { cn as c } from "./utils/cn.js";
5
+ import "react";
6
+ function v({
7
+ heading: e,
8
+ description: a,
9
+ children: o,
10
+ ref: t,
11
+ className: d
12
+ }) {
13
+ return /* @__PURE__ */ r(
14
+ "div",
15
+ {
16
+ ref: t,
17
+ className: c(
18
+ "relative overflow-hidden rounded-xl bg-surface-secondary border border-border p-8 sm:p-12",
19
+ d
20
+ ),
21
+ children: /* @__PURE__ */ i("div", { className: "space-y-4", children: [
22
+ /* @__PURE__ */ r(m, { variant: "section", className: "text-center", children: e }),
23
+ /* @__PURE__ */ r(s, { variant: "body", className: "max-w-md mx-auto text-center", children: a }),
24
+ /* @__PURE__ */ r("div", { className: "pt-2", children: o })
25
+ ] })
26
+ }
27
+ );
28
+ }
29
+ export {
30
+ v as CTACard
31
+ };
@@ -0,0 +1,91 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { Heading as m } from "./Heading.js";
3
+ import { cn as n } from "./utils/cn.js";
4
+ import "react";
5
+ const s = {
6
+ none: "",
7
+ sm: "p-4",
8
+ md: "p-6",
9
+ lg: "p-8"
10
+ };
11
+ function p({
12
+ children: e,
13
+ className: d,
14
+ elevated: a = !1,
15
+ padding: r = "md",
16
+ ref: o,
17
+ ...i
18
+ }) {
19
+ return /* @__PURE__ */ t(
20
+ "div",
21
+ {
22
+ ref: o,
23
+ className: n(
24
+ "rounded-lg border border-border",
25
+ a ? "bg-surface-elevated shadow-md shadow-black/10 border-border-secondary" : "bg-surface-elevated",
26
+ s[r],
27
+ d
28
+ ),
29
+ ...i,
30
+ children: e
31
+ }
32
+ );
33
+ }
34
+ function b({
35
+ children: e,
36
+ className: d,
37
+ ref: a,
38
+ ...r
39
+ }) {
40
+ return /* @__PURE__ */ t("div", { ref: a, className: n("mb-4", d), ...r, children: e });
41
+ }
42
+ function g({
43
+ children: e,
44
+ className: d,
45
+ ref: a,
46
+ as: r,
47
+ ...o
48
+ }) {
49
+ return /* @__PURE__ */ t(
50
+ m,
51
+ {
52
+ ref: a,
53
+ variant: "cardTitle",
54
+ className: d,
55
+ ...r ? { as: r } : {},
56
+ ...o,
57
+ children: e
58
+ }
59
+ );
60
+ }
61
+ function v({
62
+ children: e,
63
+ className: d,
64
+ ref: a,
65
+ ...r
66
+ }) {
67
+ return /* @__PURE__ */ t("div", { ref: a, className: n(d), ...r, children: e });
68
+ }
69
+ function C({
70
+ children: e,
71
+ className: d,
72
+ ref: a,
73
+ ...r
74
+ }) {
75
+ return /* @__PURE__ */ t(
76
+ "div",
77
+ {
78
+ ref: a,
79
+ className: n("mt-4 flex items-center gap-2", d),
80
+ ...r,
81
+ children: e
82
+ }
83
+ );
84
+ }
85
+ export {
86
+ p as Card,
87
+ v as CardContent,
88
+ C as CardFooter,
89
+ b as CardHeader,
90
+ g as CardTitle
91
+ };
@@ -0,0 +1,75 @@
1
+ import { jsxs as i, jsx as r } from "react/jsx-runtime";
2
+ import { Check as b } from "lucide-react";
3
+ import { useId as h } from "react";
4
+ import { DISABLED_PEER as u, FOCUS_RING_PEER as x } from "./styles/formStyles.js";
5
+ import { Text as f } from "./Text.js";
6
+ import { cn as n } from "./utils/cn.js";
7
+ function g({
8
+ label: o,
9
+ error: e,
10
+ className: s,
11
+ id: l,
12
+ checked: d,
13
+ ref: m,
14
+ ...c
15
+ }) {
16
+ const p = h(), t = l ?? p, a = e ? `${t}-error` : void 0;
17
+ return /* @__PURE__ */ i("div", { children: [
18
+ /* @__PURE__ */ i("div", { className: "flex items-center gap-2", children: [
19
+ /* @__PURE__ */ i("div", { className: "relative", children: [
20
+ /* @__PURE__ */ r(
21
+ "input",
22
+ {
23
+ ref: m,
24
+ type: "checkbox",
25
+ id: t,
26
+ checked: d,
27
+ "aria-invalid": e ? "true" : void 0,
28
+ "aria-describedby": a,
29
+ className: "peer sr-only",
30
+ ...c
31
+ }
32
+ ),
33
+ /* @__PURE__ */ r(
34
+ "span",
35
+ {
36
+ "aria-hidden": "true",
37
+ onClick: () => document.getElementById(t)?.click(),
38
+ className: n(
39
+ "flex items-center justify-center size-5 border-2",
40
+ "border-border-secondary rounded-xs bg-surface cursor-pointer transition-all",
41
+ "peer-checked:bg-brand-500 peer-checked:border-brand-500",
42
+ x,
43
+ u,
44
+ e && "border-error",
45
+ s
46
+ ),
47
+ children: d && /* @__PURE__ */ r(
48
+ b,
49
+ {
50
+ className: "size-3.5 text-text-inverse",
51
+ strokeWidth: 3,
52
+ "aria-hidden": "true"
53
+ }
54
+ )
55
+ }
56
+ )
57
+ ] }),
58
+ o && /* @__PURE__ */ r(
59
+ "label",
60
+ {
61
+ htmlFor: t,
62
+ className: n(
63
+ "text-text-primary select-none",
64
+ c.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"
65
+ ),
66
+ children: o
67
+ }
68
+ )
69
+ ] }),
70
+ e && /* @__PURE__ */ r(f, { variant: "error", id: a, className: "mt-1.5", role: "alert", children: e })
71
+ ] });
72
+ }
73
+ export {
74
+ g as Checkbox
75
+ };
@@ -0,0 +1,35 @@
1
+ import { jsx as s } from "react/jsx-runtime";
2
+ import { cn as r } from "./utils/cn.js";
3
+ import "react";
4
+ const t = {
5
+ sm: "max-w-3xl",
6
+ md: "max-w-4xl",
7
+ lg: "max-w-5xl",
8
+ xl: "max-w-6xl",
9
+ "2xl": "max-w-7xl",
10
+ full: "max-w-full"
11
+ };
12
+ function p({
13
+ children: l,
14
+ size: x = "full",
15
+ className: m,
16
+ ref: a,
17
+ ...o
18
+ }) {
19
+ return /* @__PURE__ */ s(
20
+ "div",
21
+ {
22
+ ref: a,
23
+ className: r(
24
+ "mx-auto w-full px-4 sm:px-6 lg:px-8",
25
+ t[x],
26
+ m
27
+ ),
28
+ ...o,
29
+ children: l
30
+ }
31
+ );
32
+ }
33
+ export {
34
+ p as Container
35
+ };
@@ -0,0 +1,48 @@
1
+ import { jsx as r, jsxs as d } from "react/jsx-runtime";
2
+ import { Text as l } from "./Text.js";
3
+ import { cn as o } from "./utils/cn.js";
4
+ import "react";
5
+ function x({
6
+ orientation: n = "horizontal",
7
+ className: i,
8
+ label: t,
9
+ ref: a,
10
+ ...e
11
+ }) {
12
+ return n === "vertical" ? /* @__PURE__ */ r(
13
+ "div",
14
+ {
15
+ ref: a,
16
+ role: "separator",
17
+ "aria-orientation": "vertical",
18
+ className: o("w-px bg-border", i),
19
+ ...e
20
+ }
21
+ ) : t ? /* @__PURE__ */ d(
22
+ "div",
23
+ {
24
+ ref: a,
25
+ role: "separator",
26
+ "aria-orientation": "horizontal",
27
+ className: o("flex items-center gap-4", i),
28
+ ...e,
29
+ children: [
30
+ /* @__PURE__ */ r("div", { className: "flex-1 h-px bg-border", "aria-hidden": "true" }),
31
+ /* @__PURE__ */ r(l, { variant: "caption", as: "span", children: t }),
32
+ /* @__PURE__ */ r("div", { className: "flex-1 h-px bg-border", "aria-hidden": "true" })
33
+ ]
34
+ }
35
+ ) : /* @__PURE__ */ r(
36
+ "div",
37
+ {
38
+ ref: a,
39
+ role: "separator",
40
+ "aria-orientation": "horizontal",
41
+ className: o("h-px bg-border", i),
42
+ ...e
43
+ }
44
+ );
45
+ }
46
+ export {
47
+ x as Divider
48
+ };