@vizel/react 0.0.1-alpha.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.
package/dist/index.js ADDED
@@ -0,0 +1,60 @@
1
+ import { useVizelContext as r, useVizelContextSafe as t } from "./index2.js";
2
+ import { VizelIconProvider as l, useVizelIconContext as m } from "./index3.js";
3
+ import { VizelThemeProvider as z, useVizelTheme as f, useVizelThemeSafe as x } from "./index4.js";
4
+ import { Vizel as u } from "./index5.js";
5
+ import { VizelBubbleMenu as a } from "./index6.js";
6
+ import { VizelBubbleMenuButton as d } from "./index7.js";
7
+ import { VizelBubbleMenuColorPicker as S } from "./index8.js";
8
+ import { VizelBubbleMenuDefault as c } from "./index9.js";
9
+ import { VizelBubbleMenuDivider as v } from "./index10.js";
10
+ import { VizelColorPicker as E } from "./index11.js";
11
+ import { VizelEditor as C } from "./index12.js";
12
+ import { VizelEmbedView as k } from "./index13.js";
13
+ import { VizelIcon as w } from "./index14.js";
14
+ import { VizelLinkEditor as y } from "./index15.js";
15
+ import { VizelNodeSelector as L } from "./index16.js";
16
+ import { VizelPortal as R } from "./index17.js";
17
+ import { VizelProvider as j } from "./index18.js";
18
+ import { VizelSaveIndicator as F } from "./index19.js";
19
+ import { VizelSlashMenu as H } from "./index20.js";
20
+ import { VizelSlashMenuEmpty as K } from "./index21.js";
21
+ import { VizelSlashMenuItem as Q } from "./index22.js";
22
+ import { createVizelSlashMenuRenderer as W } from "./index23.js";
23
+ import { useVizelAutoSave as Y } from "./index24.js";
24
+ import { useVizelEditor as _ } from "./index25.js";
25
+ import { useVizelEditorState as ee } from "./index26.js";
26
+ import { useVizelMarkdown as re } from "./index27.js";
27
+ import { useVizelState as ie } from "./index28.js";
28
+ export {
29
+ u as Vizel,
30
+ a as VizelBubbleMenu,
31
+ d as VizelBubbleMenuButton,
32
+ S as VizelBubbleMenuColorPicker,
33
+ c as VizelBubbleMenuDefault,
34
+ v as VizelBubbleMenuDivider,
35
+ E as VizelColorPicker,
36
+ C as VizelEditor,
37
+ k as VizelEmbedView,
38
+ w as VizelIcon,
39
+ l as VizelIconProvider,
40
+ y as VizelLinkEditor,
41
+ L as VizelNodeSelector,
42
+ R as VizelPortal,
43
+ j as VizelProvider,
44
+ F as VizelSaveIndicator,
45
+ H as VizelSlashMenu,
46
+ K as VizelSlashMenuEmpty,
47
+ Q as VizelSlashMenuItem,
48
+ z as VizelThemeProvider,
49
+ W as createVizelSlashMenuRenderer,
50
+ Y as useVizelAutoSave,
51
+ r as useVizelContext,
52
+ t as useVizelContextSafe,
53
+ _ as useVizelEditor,
54
+ ee as useVizelEditorState,
55
+ m as useVizelIconContext,
56
+ re as useVizelMarkdown,
57
+ ie as useVizelState,
58
+ f as useVizelTheme,
59
+ x as useVizelThemeSafe
60
+ };
@@ -0,0 +1,7 @@
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ function n({ className: e }) {
3
+ return /* @__PURE__ */ i("span", { className: `vizel-bubble-menu-divider ${e ?? ""}` });
4
+ }
5
+ export {
6
+ n as VizelBubbleMenuDivider
7
+ };
@@ -0,0 +1,179 @@
1
+ import { jsxs as z, jsx as l } from "react/jsx-runtime";
2
+ import { normalizeVizelHexColor as N, isVizelValidHexColor as I } from "@vizel/core";
3
+ import { useState as K, useRef as L, useMemo as $, useEffect as y, useCallback as b } from "react";
4
+ import { VizelIcon as w } from "./index14.js";
5
+ const S = 4, j = ["transparent", "inherit"];
6
+ function q({
7
+ colors: f,
8
+ value: a,
9
+ onChange: m,
10
+ label: M = "Color palette",
11
+ className: O,
12
+ allowCustomColor: U = !0,
13
+ recentColors: s = [],
14
+ showRecentColors: h = !0,
15
+ noneValues: g = j
16
+ }) {
17
+ const [p, d] = K(""), [x, v] = K(-1), u = L([]), D = L(null), i = $(
18
+ () => [...h ? s : [], ...f.map((e) => e.color)],
19
+ [h, s, f]
20
+ );
21
+ y(() => {
22
+ u.current.length > i.length && (u.current.length = i.length);
23
+ }, [i.length]);
24
+ const H = h ? s.length : 0, o = b(
25
+ (e) => g.includes(e),
26
+ [g]
27
+ ), k = b(
28
+ (e) => {
29
+ m(e), d("");
30
+ },
31
+ [m]
32
+ ), V = b(() => {
33
+ const e = N(p);
34
+ I(e) && (m(e), d(""));
35
+ }, [p, m]), R = (e) => {
36
+ e.key === "Enter" && (e.preventDefault(), V());
37
+ }, A = b(
38
+ (e, r) => {
39
+ const t = i.length;
40
+ if (t === 0) return;
41
+ let n = r, c = !1;
42
+ switch (e.key) {
43
+ case "ArrowRight":
44
+ n = (r + 1) % t, c = !0;
45
+ break;
46
+ case "ArrowLeft":
47
+ n = (r - 1 + t) % t, c = !0;
48
+ break;
49
+ case "ArrowDown":
50
+ n = Math.min(r + S, t - 1), c = !0;
51
+ break;
52
+ case "ArrowUp":
53
+ n = Math.max(r - S, 0), c = !0;
54
+ break;
55
+ case "Home":
56
+ n = 0, c = !0;
57
+ break;
58
+ case "End":
59
+ n = t - 1, c = !0;
60
+ break;
61
+ case "Enter":
62
+ case " ": {
63
+ e.preventDefault();
64
+ const E = i[r];
65
+ E && k(E);
66
+ return;
67
+ }
68
+ }
69
+ c && (e.preventDefault(), v(n), u.current[n]?.focus());
70
+ },
71
+ [i, k]
72
+ );
73
+ y(() => {
74
+ a && !o(a) ? d(a) : d("");
75
+ }, [a, o]), y(() => {
76
+ const e = a ? i.indexOf(a) : -1;
77
+ e >= 0 ? v(e) : i.length > 0 && v(0);
78
+ }, [i, a]);
79
+ const C = I(N(p)), _ = C ? N(p) : void 0;
80
+ return /* @__PURE__ */ z(
81
+ "div",
82
+ {
83
+ className: `vizel-color-picker-content ${O ?? ""}`,
84
+ role: "listbox",
85
+ "aria-label": M,
86
+ children: [
87
+ h && s.length > 0 && /* @__PURE__ */ z("div", { className: "vizel-color-picker-section", children: [
88
+ /* @__PURE__ */ l("div", { className: "vizel-color-picker-label", children: "Recent" }),
89
+ /* @__PURE__ */ l("div", { className: "vizel-color-picker-recent", children: s.map((e, r) => /* @__PURE__ */ l(
90
+ "button",
91
+ {
92
+ ref: (t) => {
93
+ u.current[r] = t;
94
+ },
95
+ type: "button",
96
+ role: "option",
97
+ "aria-selected": a === e,
98
+ "aria-label": e,
99
+ tabIndex: x === r ? 0 : -1,
100
+ className: `vizel-color-picker-swatch ${a === e ? "is-active" : ""}`,
101
+ onClick: () => k(e),
102
+ onKeyDown: (t) => A(t, r),
103
+ style: {
104
+ backgroundColor: o(e) ? "transparent" : e
105
+ },
106
+ "data-color": e,
107
+ children: o(e) ? /* @__PURE__ */ l("span", { className: "vizel-color-picker-none", children: /* @__PURE__ */ l(w, { name: "x" }) }) : null
108
+ },
109
+ e
110
+ )) })
111
+ ] }),
112
+ /* @__PURE__ */ l("div", { className: "vizel-color-picker-section", children: /* @__PURE__ */ l("div", { className: "vizel-color-picker-grid", children: f.map((e, r) => {
113
+ const t = H + r;
114
+ return /* @__PURE__ */ l(
115
+ "button",
116
+ {
117
+ ref: (n) => {
118
+ u.current[t] = n;
119
+ },
120
+ type: "button",
121
+ role: "option",
122
+ "aria-selected": a === e.color,
123
+ "aria-label": e.name,
124
+ tabIndex: x === t ? 0 : -1,
125
+ className: `vizel-color-picker-swatch ${a === e.color ? "is-active" : ""}`,
126
+ onClick: () => k(e.color),
127
+ onKeyDown: (n) => A(n, t),
128
+ style: {
129
+ backgroundColor: o(e.color) ? "transparent" : e.color
130
+ },
131
+ "data-color": e.color,
132
+ children: o(e.color) ? /* @__PURE__ */ l("span", { className: "vizel-color-picker-none", children: /* @__PURE__ */ l(w, { name: "x" }) }) : null
133
+ },
134
+ e.color
135
+ );
136
+ }) }) }),
137
+ U && /* @__PURE__ */ z("div", { className: "vizel-color-picker-input-row", children: [
138
+ /* @__PURE__ */ l(
139
+ "span",
140
+ {
141
+ className: "vizel-color-picker-preview",
142
+ style: { backgroundColor: _ || "transparent" },
143
+ "aria-hidden": "true"
144
+ }
145
+ ),
146
+ /* @__PURE__ */ l(
147
+ "input",
148
+ {
149
+ ref: D,
150
+ type: "text",
151
+ className: "vizel-color-picker-input",
152
+ placeholder: "#000000",
153
+ value: p,
154
+ onChange: (e) => d(e.target.value),
155
+ onKeyDown: R,
156
+ maxLength: 7,
157
+ "aria-label": "Custom color hex value"
158
+ }
159
+ ),
160
+ /* @__PURE__ */ l(
161
+ "button",
162
+ {
163
+ type: "button",
164
+ className: "vizel-color-picker-apply",
165
+ onClick: V,
166
+ disabled: !C,
167
+ title: "Apply",
168
+ "aria-label": "Apply custom color",
169
+ children: /* @__PURE__ */ l(w, { name: "check" })
170
+ }
171
+ )
172
+ ] })
173
+ ]
174
+ }
175
+ );
176
+ }
177
+ export {
178
+ q as VizelColorPicker
179
+ };
@@ -0,0 +1,24 @@
1
+ import { jsx as f } from "react/jsx-runtime";
2
+ import { useRef as a, useImperativeHandle as c, useEffect as l } from "react";
3
+ import { useVizelContextSafe as s } from "./index2.js";
4
+ function v({ ref: i, editor: o, className: n }) {
5
+ const d = s(), e = o ?? d?.editor, r = a(null);
6
+ return c(
7
+ i,
8
+ () => ({
9
+ container: r.current
10
+ }),
11
+ []
12
+ ), l(() => {
13
+ const t = r.current;
14
+ if (e && t)
15
+ return t.appendChild(e.view.dom), e.view.setProps({
16
+ editable: () => e?.isEditable ?? !1
17
+ }), () => {
18
+ e.view.dom.parentNode === t && t.removeChild(e.view.dom);
19
+ };
20
+ }, [e]), e ? /* @__PURE__ */ f("div", { ref: r, className: n, "data-vizel-content": "" }) : null;
21
+ }
22
+ export {
23
+ v as VizelEditor
24
+ };
@@ -0,0 +1,79 @@
1
+ import { jsx as i, jsxs as s } from "react/jsx-runtime";
2
+ import { useRef as a, useEffect as v } from "react";
3
+ import { VizelIcon as p } from "./index14.js";
4
+ const b = (r, e, n) => `vizel-embed ${r ? "is-loading" : ""} ${e ? "ProseMirror-selectednode" : ""} ${n ?? ""}`, h = (r, e) => /* @__PURE__ */ i("div", { className: r, "data-embed-type": "loading", "data-embed-provider": e, children: /* @__PURE__ */ s("div", { className: "vizel-embed-loading", children: [
5
+ /* @__PURE__ */ i("div", { className: "vizel-embed-loading-spinner" }),
6
+ /* @__PURE__ */ i("span", { children: "Loading embed..." })
7
+ ] }) }), f = (r, e, n) => {
8
+ const l = ["youtube", "vimeo", "loom", "tiktok"].includes(e.provider ?? "");
9
+ return /* @__PURE__ */ i(
10
+ "div",
11
+ {
12
+ ref: n,
13
+ className: r,
14
+ "data-embed-type": "oembed",
15
+ "data-embed-provider": e.provider,
16
+ children: /* @__PURE__ */ i(
17
+ "div",
18
+ {
19
+ className: l ? "vizel-embed-video" : "vizel-embed-oembed",
20
+ dangerouslySetInnerHTML: { __html: e.html ?? "" }
21
+ }
22
+ )
23
+ }
24
+ );
25
+ }, u = (r, e) => {
26
+ const n = !!e.image, l = n ? "vizel-embed-card-horizontal" : "";
27
+ return /* @__PURE__ */ i("div", { className: r, "data-embed-type": "ogp", "data-embed-provider": e.provider, children: /* @__PURE__ */ s(
28
+ "a",
29
+ {
30
+ href: e.url,
31
+ target: "_blank",
32
+ rel: "noopener noreferrer",
33
+ className: `vizel-embed-card ${l}`,
34
+ children: [
35
+ n && /* @__PURE__ */ i("img", { src: e.image, alt: "", className: "vizel-embed-card-image", loading: "lazy" }),
36
+ /* @__PURE__ */ s("div", { className: "vizel-embed-card-content", children: [
37
+ (e.siteName || e.favicon) && /* @__PURE__ */ s("div", { className: "vizel-embed-card-site", children: [
38
+ e.favicon && /* @__PURE__ */ i("img", { src: e.favicon, alt: "", className: "vizel-embed-card-favicon" }),
39
+ e.siteName && /* @__PURE__ */ i("span", { children: e.siteName })
40
+ ] }),
41
+ e.title && /* @__PURE__ */ i("div", { className: "vizel-embed-card-title", children: e.title }),
42
+ e.description && /* @__PURE__ */ i("div", { className: "vizel-embed-card-description", children: e.description }),
43
+ /* @__PURE__ */ i("div", { className: "vizel-embed-card-url", children: new URL(e.url).hostname })
44
+ ] })
45
+ ]
46
+ }
47
+ ) });
48
+ }, N = (r, e, n) => /* @__PURE__ */ i("div", { className: r, "data-embed-type": "title", "data-embed-provider": e.provider, children: /* @__PURE__ */ s("a", { href: e.url, target: "_blank", rel: "noopener noreferrer", className: "vizel-embed-link", children: [
49
+ /* @__PURE__ */ i("span", { className: "vizel-embed-link-icon", children: n }),
50
+ /* @__PURE__ */ i("span", { className: "vizel-embed-link-text", children: e.title })
51
+ ] }) }), z = (r, e, n) => /* @__PURE__ */ i("div", { className: r, "data-embed-type": "link", "data-embed-provider": e.provider, children: /* @__PURE__ */ s("a", { href: e.url, target: "_blank", rel: "noopener noreferrer", className: "vizel-embed-link", children: [
52
+ /* @__PURE__ */ i("span", { className: "vizel-embed-link-icon", children: n }),
53
+ /* @__PURE__ */ i("span", { className: "vizel-embed-link-text", children: e.url })
54
+ ] }) });
55
+ function w({ data: r, className: e, selected: n }) {
56
+ const l = a(null);
57
+ v(() => {
58
+ if (r.type === "oembed" && r.html && l.current) {
59
+ const m = l.current.querySelectorAll("script");
60
+ for (const o of m) {
61
+ const d = document.createElement("script");
62
+ o.src ? d.src = o.src : d.textContent = o.textContent, o.parentNode?.replaceChild(d, o);
63
+ }
64
+ r.provider === "twitter" && "twttr" in window && window.twttr?.widgets?.load?.();
65
+ }
66
+ }, [r.type, r.html, r.provider]);
67
+ const c = b(r.loading, n, e);
68
+ if (r.loading)
69
+ return h(c, r.provider);
70
+ if (r.type === "oembed" && r.html)
71
+ return f(c, r, l);
72
+ if (r.type === "ogp")
73
+ return u(c, r);
74
+ const t = /* @__PURE__ */ i(p, { name: "link" });
75
+ return r.type === "title" && r.title ? N(c, r, t) : z(c, r, t);
76
+ }
77
+ export {
78
+ w as VizelEmbedView
79
+ };
@@ -0,0 +1,11 @@
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ import { Icon as s } from "@iconify/react";
3
+ import { vizelDefaultIconIds as I } from "@vizel/core";
4
+ import { useVizelIconContext as m } from "./index3.js";
5
+ function x({ name: o, customIcons: t, style: n, ...c }) {
6
+ const { customIcons: r } = m(), e = t?.[o] ?? r?.[o] ?? I[o];
7
+ return /* @__PURE__ */ i(s, { icon: e, style: { pointerEvents: "none", ...n }, ...c });
8
+ }
9
+ export {
10
+ x as VizelIcon
11
+ };
@@ -0,0 +1,81 @@
1
+ import { jsxs as a, jsx as i } from "react/jsx-runtime";
2
+ import { detectVizelEmbedProvider as R } from "@vizel/core";
3
+ import { useState as h, useRef as k, useMemo as v, useEffect as b, useCallback as p } from "react";
4
+ import { VizelIcon as g } from "./index14.js";
5
+ function P({
6
+ editor: e,
7
+ onClose: n,
8
+ className: E,
9
+ enableEmbed: m = !1
10
+ }) {
11
+ const d = e.getAttributes("link").href || "", [s, z] = h(d), [l, L] = h(!1), u = k(null), f = k(null), o = v(() => m ? e.extensionManager.extensions.some((r) => r.name === "embed") : !1, [e, m]), x = v(() => s.trim() ? R(s.trim()) !== null : !1, [s]);
12
+ b(() => {
13
+ f.current?.focus();
14
+ }, []), b(() => {
15
+ const t = (c) => {
16
+ u.current && !u.current.contains(c.target) && n();
17
+ }, r = (c) => {
18
+ c.key === "Escape" && (c.preventDefault(), c.stopImmediatePropagation(), n());
19
+ }, N = setTimeout(() => {
20
+ document.addEventListener("mousedown", t);
21
+ }, 0);
22
+ return document.addEventListener("keydown", r, !0), () => {
23
+ clearTimeout(N), document.removeEventListener("mousedown", t), document.removeEventListener("keydown", r, !0);
24
+ };
25
+ }, [n]);
26
+ const y = p(
27
+ (t) => {
28
+ t.preventDefault();
29
+ const r = s.trim();
30
+ if (!r) {
31
+ e.chain().focus().unsetLink().run(), n();
32
+ return;
33
+ }
34
+ l && o ? e.chain().focus().unsetLink().setEmbed({ url: r }).run() : e.chain().focus().setLink({ href: r }).run(), n();
35
+ },
36
+ [e, s, l, o, n]
37
+ ), w = p(() => {
38
+ e.chain().focus().unsetLink().run(), n();
39
+ }, [e, n]);
40
+ return /* @__PURE__ */ a("form", { ref: u, onSubmit: y, className: `vizel-link-editor ${E ?? ""}`, children: [
41
+ /* @__PURE__ */ a("div", { className: "vizel-link-editor-row", children: [
42
+ /* @__PURE__ */ i(
43
+ "input",
44
+ {
45
+ ref: f,
46
+ type: "url",
47
+ value: s,
48
+ onChange: (t) => z(t.target.value),
49
+ placeholder: "Enter URL...",
50
+ className: "vizel-link-input"
51
+ }
52
+ ),
53
+ /* @__PURE__ */ i("button", { type: "submit", className: "vizel-link-button", title: "Apply", children: /* @__PURE__ */ i(g, { name: "check" }) }),
54
+ d && /* @__PURE__ */ i(
55
+ "button",
56
+ {
57
+ type: "button",
58
+ onClick: w,
59
+ className: "vizel-link-button vizel-link-remove",
60
+ title: "Remove link",
61
+ children: /* @__PURE__ */ i(g, { name: "x" })
62
+ }
63
+ )
64
+ ] }),
65
+ o && x && /* @__PURE__ */ a("div", { className: "vizel-link-editor-embed-toggle", children: [
66
+ /* @__PURE__ */ i(
67
+ "input",
68
+ {
69
+ type: "checkbox",
70
+ id: "vizel-embed-toggle",
71
+ checked: l,
72
+ onChange: (t) => L(t.target.checked)
73
+ }
74
+ ),
75
+ /* @__PURE__ */ i("label", { htmlFor: "vizel-embed-toggle", children: "Embed as rich content" })
76
+ ] })
77
+ ] });
78
+ }
79
+ export {
80
+ P as VizelLinkEditor
81
+ };
@@ -0,0 +1,118 @@
1
+ import { jsxs as p, jsx as n } from "react/jsx-runtime";
2
+ import { getVizelActiveNodeType as x, vizelDefaultNodeTypes as E } from "@vizel/core";
3
+ import { useState as z, useRef as N, useEffect as w } from "react";
4
+ import { useVizelState as y } from "./index28.js";
5
+ import { VizelIcon as s } from "./index14.js";
6
+ function $({
7
+ editor: c,
8
+ nodeTypes: r = E,
9
+ className: D
10
+ }) {
11
+ y(() => c);
12
+ const [o, l] = z(!1), [f, a] = z(0), i = N(null), d = N(null), m = x(c, r), h = m?.label ?? "Text", g = m?.icon ?? "paragraph";
13
+ w(() => {
14
+ if (!o) return;
15
+ const e = (t) => {
16
+ i.current && !i.current.contains(t.target) && l(!1);
17
+ };
18
+ return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
19
+ }, [o]), w(() => {
20
+ o && d.current && d.current.focus();
21
+ }, [o]);
22
+ const b = (e) => {
23
+ if (!o) {
24
+ (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") && (e.preventDefault(), l(!0), a(0));
25
+ return;
26
+ }
27
+ switch (e.key) {
28
+ case "Escape":
29
+ e.preventDefault(), l(!1);
30
+ break;
31
+ case "ArrowDown":
32
+ e.preventDefault(), a((t) => (t + 1) % r.length);
33
+ break;
34
+ case "ArrowUp":
35
+ e.preventDefault(), a((t) => (t - 1 + r.length) % r.length);
36
+ break;
37
+ case "Enter":
38
+ case " ": {
39
+ e.preventDefault();
40
+ const t = r[f];
41
+ t && v(t);
42
+ break;
43
+ }
44
+ case "Home":
45
+ e.preventDefault(), a(0);
46
+ break;
47
+ case "End":
48
+ e.preventDefault(), a(r.length - 1);
49
+ break;
50
+ }
51
+ }, v = (e) => {
52
+ e.command(c), l(!1);
53
+ };
54
+ return /* @__PURE__ */ p(
55
+ "div",
56
+ {
57
+ ref: i,
58
+ className: `vizel-node-selector ${D ?? ""}`,
59
+ "data-vizel-node-selector": !0,
60
+ children: [
61
+ /* @__PURE__ */ p(
62
+ "button",
63
+ {
64
+ type: "button",
65
+ className: "vizel-node-selector-trigger",
66
+ onClick: () => l(!o),
67
+ onKeyDown: b,
68
+ "aria-haspopup": "listbox",
69
+ "aria-expanded": o,
70
+ "aria-label": `Current block type: ${h}`,
71
+ title: "Change block type",
72
+ children: [
73
+ /* @__PURE__ */ n("span", { className: "vizel-node-selector-icon", children: /* @__PURE__ */ n(s, { name: g }) }),
74
+ /* @__PURE__ */ n("span", { className: "vizel-node-selector-label", children: h }),
75
+ /* @__PURE__ */ n("span", { className: "vizel-node-selector-chevron", "aria-hidden": "true", children: /* @__PURE__ */ n(s, { name: "chevronDown" }) })
76
+ ]
77
+ }
78
+ ),
79
+ o && /* @__PURE__ */ n(
80
+ "div",
81
+ {
82
+ ref: d,
83
+ className: "vizel-node-selector-dropdown",
84
+ role: "listbox",
85
+ "aria-label": "Block types",
86
+ "data-vizel-node-selector-dropdown": !0,
87
+ tabIndex: -1,
88
+ onKeyDown: b,
89
+ children: r.map((e, t) => {
90
+ const u = e.isActive(c), k = t === f;
91
+ return /* @__PURE__ */ p(
92
+ "button",
93
+ {
94
+ type: "button",
95
+ role: "option",
96
+ "aria-selected": u,
97
+ className: `vizel-node-selector-option ${u ? "is-active" : ""} ${k ? "is-focused" : ""}`,
98
+ onClick: () => v(e),
99
+ onMouseEnter: () => a(t),
100
+ tabIndex: k ? 0 : -1,
101
+ children: [
102
+ /* @__PURE__ */ n("span", { className: "vizel-node-selector-option-icon", children: /* @__PURE__ */ n(s, { name: e.icon }) }),
103
+ /* @__PURE__ */ n("span", { className: "vizel-node-selector-option-label", children: e.label }),
104
+ u && /* @__PURE__ */ n("span", { className: "vizel-node-selector-check", "aria-hidden": "true", children: /* @__PURE__ */ n(s, { name: "check" }) })
105
+ ]
106
+ },
107
+ e.name
108
+ );
109
+ })
110
+ }
111
+ )
112
+ ]
113
+ }
114
+ );
115
+ }
116
+ export {
117
+ $ as VizelNodeSelector
118
+ };
@@ -0,0 +1,38 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { getVizelPortalContainer as s, VIZEL_PORTAL_Z_INDEX as f } from "@vizel/core";
3
+ import { useState as m, useEffect as p } from "react";
4
+ import { createPortal as u } from "react-dom";
5
+ function d({
6
+ children: t,
7
+ layer: o = "dropdown",
8
+ className: e,
9
+ disabled: r = !1
10
+ }) {
11
+ const [a, i] = m(!1);
12
+ if (p(() => {
13
+ i(!0);
14
+ }, []), !a || r)
15
+ return t;
16
+ const l = s();
17
+ return u(
18
+ /* @__PURE__ */ n(
19
+ "div",
20
+ {
21
+ "data-vizel-portal-layer": o,
22
+ className: e,
23
+ style: {
24
+ position: "absolute",
25
+ top: 0,
26
+ left: 0,
27
+ zIndex: f[o]
28
+ },
29
+ children: t
30
+ }
31
+ ),
32
+ l
33
+ );
34
+ }
35
+ d.displayName = "VizelPortal";
36
+ export {
37
+ d as VizelPortal
38
+ };
@@ -0,0 +1,8 @@
1
+ import { jsx as r } from "react/jsx-runtime";
2
+ import { VizelInternalProvider as t } from "./index2.js";
3
+ function l({ editor: i, children: o, className: e }) {
4
+ return /* @__PURE__ */ r(t, { editor: i, children: /* @__PURE__ */ r("div", { className: e, "data-vizel-root": "", children: o }) });
5
+ }
6
+ export {
7
+ l as VizelProvider
8
+ };
@@ -0,0 +1,71 @@
1
+ import { jsxs as m, jsx as e } from "react/jsx-runtime";
2
+ import { formatVizelRelativeTime as p } from "@vizel/core";
3
+ import { useState as h, useEffect as f } from "react";
4
+ import { VizelIcon as i } from "./index14.js";
5
+ function I({
6
+ status: r,
7
+ lastSaved: a,
8
+ showTimestamp: c = !0,
9
+ className: o
10
+ }) {
11
+ const [n, t] = h("");
12
+ f(() => {
13
+ if (!a) {
14
+ t("");
15
+ return;
16
+ }
17
+ const s = () => {
18
+ t(p(a));
19
+ };
20
+ s();
21
+ const u = setInterval(s, 1e4);
22
+ return () => clearInterval(u);
23
+ }, [a]);
24
+ const l = () => {
25
+ switch (r) {
26
+ case "saved":
27
+ return /* @__PURE__ */ e(i, { name: "check" });
28
+ case "saving":
29
+ return /* @__PURE__ */ e("span", { className: "vizel-save-indicator-spinner", "aria-hidden": "true", children: /* @__PURE__ */ e(i, { name: "loader" }) });
30
+ case "unsaved":
31
+ return /* @__PURE__ */ e(i, { name: "circle" });
32
+ case "error":
33
+ return /* @__PURE__ */ e(i, { name: "warning" });
34
+ default:
35
+ return null;
36
+ }
37
+ }, v = () => {
38
+ switch (r) {
39
+ case "saved":
40
+ return "Saved";
41
+ case "saving":
42
+ return "Saving...";
43
+ case "unsaved":
44
+ return "Unsaved";
45
+ case "error":
46
+ return "Error saving";
47
+ default:
48
+ return "";
49
+ }
50
+ }, d = c && a && n && r === "saved";
51
+ return (
52
+ // biome-ignore lint/a11y/useSemanticElements: role="status" is appropriate for non-form status announcements
53
+ /* @__PURE__ */ m(
54
+ "div",
55
+ {
56
+ className: `vizel-save-indicator vizel-save-indicator--${r} ${o ?? ""}`,
57
+ role: "status",
58
+ "aria-live": "polite",
59
+ "data-vizel-save-indicator": !0,
60
+ children: [
61
+ /* @__PURE__ */ e("span", { className: "vizel-save-indicator-icon", "aria-hidden": "true", children: l() }),
62
+ /* @__PURE__ */ e("span", { className: "vizel-save-indicator-text", children: v() }),
63
+ d && /* @__PURE__ */ e("span", { className: "vizel-save-indicator-timestamp", children: n })
64
+ ]
65
+ }
66
+ )
67
+ );
68
+ }
69
+ export {
70
+ I as VizelSaveIndicator
71
+ };