gridsmith-ui 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/MentionList-CoNBRFGR.d.ts +8 -0
- package/dist/charts.d.ts +42 -1
- package/dist/charts.js +320 -89
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +5 -4
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-6XAU44U4.js → chunk-CYN5O567.js} +10 -23
- package/dist/chunk-CYN5O567.js.map +1 -0
- package/dist/{chunk-SBTBMAIU.js → chunk-EX64MN2U.js} +6 -6
- package/dist/{chunk-SBTBMAIU.js.map → chunk-EX64MN2U.js.map} +1 -1
- package/dist/chunk-HP7WUZPK.js +80 -0
- package/dist/chunk-HP7WUZPK.js.map +1 -0
- package/dist/{chunk-4LDYR7QP.js → chunk-HXVXJUGV.js} +53 -13
- package/dist/chunk-HXVXJUGV.js.map +1 -0
- package/dist/{chunk-MV7JXWXK.js → chunk-KWLNEH53.js} +8 -7
- package/dist/chunk-KWLNEH53.js.map +1 -0
- package/dist/{chunk-CXMV7SXJ.js → chunk-MD2EFMES.js} +5 -77
- package/dist/chunk-MD2EFMES.js.map +1 -0
- package/dist/{chunk-SVP2IG4S.js → chunk-MYIJNVTK.js} +7 -7
- package/dist/chunk-MYIJNVTK.js.map +1 -0
- package/dist/{chunk-IVCVNAXG.js → chunk-OTCEJN64.js} +3 -3
- package/dist/{chunk-IVCVNAXG.js.map → chunk-OTCEJN64.js.map} +1 -1
- package/dist/{chunk-2PWGJ4PK.js → chunk-QM4SJKWV.js} +11 -6
- package/dist/chunk-QM4SJKWV.js.map +1 -0
- package/dist/chunk-RWKCAKN3.js +209 -0
- package/dist/chunk-RWKCAKN3.js.map +1 -0
- package/dist/{chunk-2YSEME33.js → chunk-SFY2KMHG.js} +63 -6
- package/dist/chunk-SFY2KMHG.js.map +1 -0
- package/dist/{chunk-NCIZQYXQ.js → chunk-X2HEV7FB.js} +33 -3
- package/dist/chunk-X2HEV7FB.js.map +1 -0
- package/dist/{chunk-JXANCXK6.js → chunk-ZI3OQDET.js} +18 -4
- package/dist/chunk-ZI3OQDET.js.map +1 -0
- package/dist/{chunk-7TOJ4G7S.js → chunk-ZYVXV4WC.js} +14 -9
- package/dist/chunk-ZYVXV4WC.js.map +1 -0
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +13 -12
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.d.ts +30 -0
- package/dist/editor-mentions.js +160 -0
- package/dist/editor-mentions.js.map +1 -0
- package/dist/editor.d.ts +23 -3
- package/dist/editor.js +58 -9
- package/dist/editor.js.map +1 -1
- package/dist/{feather-2JFSFLXN.js → feather-VFWLAILO.js} +12 -3
- package/dist/feather-VFWLAILO.js.map +1 -0
- package/dist/{heroicons-4AQ4YBVG.js → heroicons-H3Z7DFCF.js} +22 -7
- package/dist/heroicons-H3Z7DFCF.js.map +1 -0
- package/dist/icons.d.ts +11 -4
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +202 -31
- package/dist/index.js +1473 -1181
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +8 -8
- package/dist/kanban.js.map +1 -1
- package/dist/{lucide-RZC2FEMS.js → lucide-MR32KM4G.js} +12 -3
- package/dist/lucide-MR32KM4G.js.map +1 -0
- package/dist/{phosphor-CEN25FLM.js → phosphor-ABQQL5N5.js} +12 -3
- package/dist/phosphor-ABQQL5N5.js.map +1 -0
- package/dist/resizable.js +8 -8
- package/dist/roots.css +28 -0
- package/dist/{tabler-YXXC7Y6B.js → tabler-ANUSY4D2.js} +12 -3
- package/dist/tabler-ANUSY4D2.js.map +1 -0
- package/dist/tokens.css +6 -0
- package/dist/{use-pagination-DiJo0aW5.d.ts → use-pagination-BnKOnBdz.d.ts} +3 -0
- package/dist/virtualized.d.ts +1 -1
- package/dist/virtualized.js +7 -6
- package/dist/virtualized.js.map +1 -1
- package/dist-static/tokens.css +6 -0
- package/package.json +29 -21
- package/dist/chunk-2PWGJ4PK.js.map +0 -1
- package/dist/chunk-2YSEME33.js.map +0 -1
- package/dist/chunk-4LDYR7QP.js.map +0 -1
- package/dist/chunk-6XAU44U4.js.map +0 -1
- package/dist/chunk-7TOJ4G7S.js.map +0 -1
- package/dist/chunk-CXMV7SXJ.js.map +0 -1
- package/dist/chunk-JXANCXK6.js.map +0 -1
- package/dist/chunk-MV7JXWXK.js.map +0 -1
- package/dist/chunk-NCIZQYXQ.js.map +0 -1
- package/dist/chunk-SVP2IG4S.js.map +0 -1
- package/dist/chunk-WOVYHFUD.js +0 -50
- package/dist/chunk-WOVYHFUD.js.map +0 -1
- package/dist/feather-2JFSFLXN.js.map +0 -1
- package/dist/heroicons-4AQ4YBVG.js.map +0 -1
- package/dist/lucide-RZC2FEMS.js.map +0 -1
- package/dist/phosphor-CEN25FLM.js.map +0 -1
- package/dist/tabler-YXXC7Y6B.js.map +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useState, useRef, useCallback, useLayoutEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// ../../showcase/src/lib/use-position.ts
|
|
4
|
+
var VIEWPORT_PADDING = 8;
|
|
5
|
+
function usePosition(triggerRef, floatingRef, open, options = {}) {
|
|
6
|
+
const { side = "bottom", align = "center", offset = 8, flip = true } = options;
|
|
7
|
+
const [pos, setPos] = useState({ top: 0, left: 0, placement: side });
|
|
8
|
+
const rafId = useRef(0);
|
|
9
|
+
const compute = useCallback(() => {
|
|
10
|
+
const trigger = triggerRef.current;
|
|
11
|
+
const floating = floatingRef.current;
|
|
12
|
+
if (!trigger || !floating) return;
|
|
13
|
+
const tRect = trigger.getBoundingClientRect();
|
|
14
|
+
const fRect = floating.getBoundingClientRect();
|
|
15
|
+
const vw = window.innerWidth;
|
|
16
|
+
const vh = window.innerHeight;
|
|
17
|
+
let placement = side;
|
|
18
|
+
if (flip) {
|
|
19
|
+
if (placement === "bottom" && tRect.bottom + offset + fRect.height > vh - VIEWPORT_PADDING && tRect.top - offset - fRect.height > VIEWPORT_PADDING) {
|
|
20
|
+
placement = "top";
|
|
21
|
+
} else if (placement === "top" && tRect.top - offset - fRect.height < VIEWPORT_PADDING && tRect.bottom + offset + fRect.height < vh - VIEWPORT_PADDING) {
|
|
22
|
+
placement = "bottom";
|
|
23
|
+
} else if (placement === "right" && tRect.right + offset + fRect.width > vw - VIEWPORT_PADDING && tRect.left - offset - fRect.width > VIEWPORT_PADDING) {
|
|
24
|
+
placement = "left";
|
|
25
|
+
} else if (placement === "left" && tRect.left - offset - fRect.width < VIEWPORT_PADDING && tRect.right + offset + fRect.width < vw - VIEWPORT_PADDING) {
|
|
26
|
+
placement = "right";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let top;
|
|
30
|
+
let left;
|
|
31
|
+
if (placement === "bottom" || placement === "top") {
|
|
32
|
+
top = placement === "bottom" ? tRect.bottom + offset : tRect.top - fRect.height - offset;
|
|
33
|
+
switch (align) {
|
|
34
|
+
case "start":
|
|
35
|
+
left = tRect.left;
|
|
36
|
+
break;
|
|
37
|
+
case "end":
|
|
38
|
+
left = tRect.right - fRect.width;
|
|
39
|
+
break;
|
|
40
|
+
default:
|
|
41
|
+
left = tRect.left + (tRect.width - fRect.width) / 2;
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
left = placement === "right" ? tRect.right + offset : tRect.left - fRect.width - offset;
|
|
45
|
+
switch (align) {
|
|
46
|
+
case "start":
|
|
47
|
+
top = tRect.top;
|
|
48
|
+
break;
|
|
49
|
+
case "end":
|
|
50
|
+
top = tRect.bottom - fRect.height;
|
|
51
|
+
break;
|
|
52
|
+
default:
|
|
53
|
+
top = tRect.top + (tRect.height - fRect.height) / 2;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
left = Math.max(VIEWPORT_PADDING, Math.min(left, vw - fRect.width - VIEWPORT_PADDING));
|
|
57
|
+
top = Math.max(VIEWPORT_PADDING, Math.min(top, vh - fRect.height - VIEWPORT_PADDING));
|
|
58
|
+
setPos((cur) => cur.top === top && cur.left === left && cur.placement === placement ? cur : { top, left, placement });
|
|
59
|
+
}, [triggerRef, floatingRef, side, align, offset, flip]);
|
|
60
|
+
useLayoutEffect(() => {
|
|
61
|
+
if (!open) return;
|
|
62
|
+
compute();
|
|
63
|
+
const onUpdate = () => {
|
|
64
|
+
cancelAnimationFrame(rafId.current);
|
|
65
|
+
rafId.current = requestAnimationFrame(compute);
|
|
66
|
+
};
|
|
67
|
+
window.addEventListener("scroll", onUpdate, true);
|
|
68
|
+
window.addEventListener("resize", onUpdate);
|
|
69
|
+
return () => {
|
|
70
|
+
cancelAnimationFrame(rafId.current);
|
|
71
|
+
window.removeEventListener("scroll", onUpdate, true);
|
|
72
|
+
window.removeEventListener("resize", onUpdate);
|
|
73
|
+
};
|
|
74
|
+
}, [open, compute]);
|
|
75
|
+
return pos;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { usePosition };
|
|
79
|
+
//# sourceMappingURL=chunk-HP7WUZPK.js.map
|
|
80
|
+
//# sourceMappingURL=chunk-HP7WUZPK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/use-position.ts"],"names":[],"mappings":"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","file":"chunk-HP7WUZPK.js","sourcesContent":["import { useState, useCallback, useLayoutEffect, useRef, type RefObject } from \"react\";\n\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\nexport type Align = \"start\" | \"center\" | \"end\";\n\ninterface PositionOptions {\n side?: Side;\n align?: Align;\n offset?: number;\n flip?: boolean;\n}\n\ninterface PositionResult {\n top: number;\n left: number;\n placement: Side;\n}\n\nconst VIEWPORT_PADDING = 8;\n\nexport function usePosition(\n triggerRef: RefObject<HTMLElement | null>,\n floatingRef: RefObject<HTMLElement | null>,\n open: boolean,\n options: PositionOptions = {}\n): PositionResult {\n const { side = \"bottom\", align = \"center\", offset = 8, flip = true } = options;\n const [pos, setPos] = useState<PositionResult>({ top: 0, left: 0, placement: side });\n const rafId = useRef(0);\n\n const compute = useCallback(() => {\n const trigger = triggerRef.current;\n const floating = floatingRef.current;\n if (!trigger || !floating) return;\n\n const tRect = trigger.getBoundingClientRect();\n const fRect = floating.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n let placement = side;\n\n if (flip) {\n if (placement === \"bottom\" && tRect.bottom + offset + fRect.height > vh - VIEWPORT_PADDING && tRect.top - offset - fRect.height > VIEWPORT_PADDING) {\n placement = \"top\";\n } else if (placement === \"top\" && tRect.top - offset - fRect.height < VIEWPORT_PADDING && tRect.bottom + offset + fRect.height < vh - VIEWPORT_PADDING) {\n placement = \"bottom\";\n } else if (placement === \"right\" && tRect.right + offset + fRect.width > vw - VIEWPORT_PADDING && tRect.left - offset - fRect.width > VIEWPORT_PADDING) {\n placement = \"left\";\n } else if (placement === \"left\" && tRect.left - offset - fRect.width < VIEWPORT_PADDING && tRect.right + offset + fRect.width < vw - VIEWPORT_PADDING) {\n placement = \"right\";\n }\n }\n\n let top: number;\n let left: number;\n\n if (placement === \"bottom\" || placement === \"top\") {\n top = placement === \"bottom\" ? tRect.bottom + offset : tRect.top - fRect.height - offset;\n\n switch (align) {\n case \"start\":\n left = tRect.left;\n break;\n case \"end\":\n left = tRect.right - fRect.width;\n break;\n default:\n left = tRect.left + (tRect.width - fRect.width) / 2;\n }\n } else {\n left = placement === \"right\" ? tRect.right + offset : tRect.left - fRect.width - offset;\n\n switch (align) {\n case \"start\":\n top = tRect.top;\n break;\n case \"end\":\n top = tRect.bottom - fRect.height;\n break;\n default:\n top = tRect.top + (tRect.height - fRect.height) / 2;\n }\n }\n\n left = Math.max(VIEWPORT_PADDING, Math.min(left, vw - fRect.width - VIEWPORT_PADDING));\n top = Math.max(VIEWPORT_PADDING, Math.min(top, vh - fRect.height - VIEWPORT_PADDING));\n\n // the same place is no change: a scroll anywhere on the page, the popup's own list included, re-renders nothing (the\n // 25.17 second review: every scroll re-rendered an open list)\n setPos((cur) => (cur.top === top && cur.left === left && cur.placement === placement ? cur : { top, left, placement }));\n }, [triggerRef, floatingRef, side, align, offset, flip]);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n compute();\n\n const onUpdate = () => {\n cancelAnimationFrame(rafId.current);\n rafId.current = requestAnimationFrame(compute);\n };\n\n window.addEventListener(\"scroll\", onUpdate, true);\n window.addEventListener(\"resize\", onUpdate);\n\n return () => {\n cancelAnimationFrame(rafId.current);\n window.removeEventListener(\"scroll\", onUpdate, true);\n window.removeEventListener(\"resize\", onUpdate);\n };\n }, [open, compute]);\n\n return pos;\n}\n"]}
|
|
@@ -2,6 +2,21 @@ import { createContext, useEffect, useContext, useSyncExternalStore } from 'reac
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// ../../showcase/src/lib/icons.tsx
|
|
5
|
+
|
|
6
|
+
// ../../showcase/src/lib/dev-warn.ts
|
|
7
|
+
var warned = /* @__PURE__ */ new Set();
|
|
8
|
+
function warnOnce(component, message) {
|
|
9
|
+
let dev = false;
|
|
10
|
+
try {
|
|
11
|
+
dev = process.env.NODE_ENV !== "production";
|
|
12
|
+
} catch {
|
|
13
|
+
dev = false;
|
|
14
|
+
}
|
|
15
|
+
const text = `${component}: ${message}`;
|
|
16
|
+
if (!dev || warned.has(text)) return;
|
|
17
|
+
warned.add(text);
|
|
18
|
+
console.warn(text);
|
|
19
|
+
}
|
|
5
20
|
var subscribers = /* @__PURE__ */ new Set();
|
|
6
21
|
function notifySubscribers() {
|
|
7
22
|
subscribers.forEach((fn) => fn());
|
|
@@ -45,19 +60,19 @@ async function loadPack(pack) {
|
|
|
45
60
|
try {
|
|
46
61
|
switch (pack) {
|
|
47
62
|
case "lucide":
|
|
48
|
-
mod = await import('./lucide-
|
|
63
|
+
mod = await import('./lucide-MR32KM4G.js');
|
|
49
64
|
break;
|
|
50
65
|
case "phosphor":
|
|
51
|
-
mod = await import('./phosphor-
|
|
66
|
+
mod = await import('./phosphor-ABQQL5N5.js');
|
|
52
67
|
break;
|
|
53
68
|
case "heroicons":
|
|
54
|
-
mod = await import('./heroicons-
|
|
69
|
+
mod = await import('./heroicons-H3Z7DFCF.js');
|
|
55
70
|
break;
|
|
56
71
|
case "tabler":
|
|
57
|
-
mod = await import('./tabler-
|
|
72
|
+
mod = await import('./tabler-ANUSY4D2.js');
|
|
58
73
|
break;
|
|
59
74
|
case "feather":
|
|
60
|
-
mod = await import('./feather-
|
|
75
|
+
mod = await import('./feather-VFWLAILO.js');
|
|
61
76
|
break;
|
|
62
77
|
}
|
|
63
78
|
curated = await mod.loadCurated();
|
|
@@ -92,7 +107,10 @@ function getPhosphorWeight(numericWeight) {
|
|
|
92
107
|
if (numericWeight <= 1.75) return "regular";
|
|
93
108
|
return "bold";
|
|
94
109
|
}
|
|
95
|
-
function
|
|
110
|
+
function owns(map, name) {
|
|
111
|
+
return !!map && Object.prototype.hasOwnProperty.call(map, name);
|
|
112
|
+
}
|
|
113
|
+
function Icon({ name, size = 16, className, from }) {
|
|
96
114
|
const { pack, weight } = useContext(IconCtx);
|
|
97
115
|
const curatedMap = useCuratedMap(pack);
|
|
98
116
|
const extendedMap = useExtendedMap(pack);
|
|
@@ -103,21 +121,25 @@ function Icon({ name, size = 16, className }) {
|
|
|
103
121
|
}
|
|
104
122
|
let Comp = null;
|
|
105
123
|
let renderPack = pack;
|
|
106
|
-
if (curatedMap) {
|
|
124
|
+
if (owns(curatedMap, name)) {
|
|
107
125
|
Comp = curatedMap[name];
|
|
108
126
|
}
|
|
109
|
-
if (!Comp && extendedMap) {
|
|
127
|
+
if (!Comp && owns(extendedMap, name)) {
|
|
110
128
|
Comp = extendedMap[name];
|
|
111
129
|
}
|
|
112
130
|
if (!Comp && pack !== "lucide") {
|
|
113
|
-
const fallback = lucideCurated
|
|
131
|
+
const fallback = owns(lucideCurated, name) ? lucideCurated[name] : owns(lucideExtended, name) ? lucideExtended[name] : void 0;
|
|
114
132
|
if (fallback) {
|
|
115
133
|
Comp = fallback;
|
|
116
134
|
renderPack = "lucide";
|
|
117
135
|
}
|
|
118
136
|
}
|
|
137
|
+
const allMapsLoaded = !!(curatedMap && extendedMap && (pack === "lucide" || lucideCurated && lucideExtended));
|
|
138
|
+
const missing = !Comp && allMapsLoaded;
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
if (missing) warnOnce("Icon", `"${name}" is not an icon name in the ${pack} pack${pack === "lucide" ? "" : " or Lucide"}, so ${from ?? "it"} draws nothing. Pass an icon name, or an element.`);
|
|
141
|
+
}, [missing, name, pack, from]);
|
|
119
142
|
if (!Comp) {
|
|
120
|
-
const allMapsLoaded = curatedMap && extendedMap && (pack === "lucide" || lucideCurated && lucideExtended);
|
|
121
143
|
if (allMapsLoaded) return null;
|
|
122
144
|
return /* @__PURE__ */ jsx("span", { style: { display: "inline-block", width: size, height: size }, className });
|
|
123
145
|
}
|
|
@@ -135,7 +157,25 @@ function Icon({ name, size = 16, className }) {
|
|
|
135
157
|
}
|
|
136
158
|
return /* @__PURE__ */ jsx(Comp, { size, strokeWidth: weight, className });
|
|
137
159
|
}
|
|
160
|
+
function slotIcon(icon, size, from) {
|
|
161
|
+
if (typeof icon === "string") {
|
|
162
|
+
if (!icon) return null;
|
|
163
|
+
return ICON_NAME_SHAPE.test(icon) ? /* @__PURE__ */ jsx(Icon, { name: icon, size, from }) : /* @__PURE__ */ jsx(NotAnIcon, { text: icon, from });
|
|
164
|
+
}
|
|
165
|
+
return icon;
|
|
166
|
+
}
|
|
167
|
+
var ICON_NAME_SHAPE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
168
|
+
function slotDraws(icon) {
|
|
169
|
+
if (typeof icon === "string") return ICON_NAME_SHAPE.test(icon);
|
|
170
|
+
return icon != null && icon !== false && icon !== true;
|
|
171
|
+
}
|
|
172
|
+
function NotAnIcon({ text, from }) {
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
warnOnce("Icon", `"${text}" is not an icon name, so ${from} draws nothing. Words go in the label; pass an icon name, or an element.`);
|
|
175
|
+
}, [text, from]);
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
138
178
|
|
|
139
|
-
export { Icon, IconProvider, preloadPack };
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
export { Icon, IconProvider, preloadPack, slotDraws, slotIcon, warnOnce };
|
|
180
|
+
//# sourceMappingURL=chunk-HXVXJUGV.js.map
|
|
181
|
+
//# sourceMappingURL=chunk-HXVXJUGV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../showcase/src/lib/dev-warn.ts","../../../showcase/src/lib/icons.tsx"],"names":[],"mappings":"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","file":"chunk-HXVXJUGV.js","sourcesContent":["// Bundlers set process.env.NODE_ENV. Where none did (a page with no build step), reading it throws and warnings stay off.\ndeclare const process: { env: { NODE_ENV?: string } };\nconst warned = new Set<string>();\n\n/** A mistake in a component's props, told to the developer once a page, in a development build. */\nexport function warnOnce(component: string, message: string): void {\n let dev = false;\n try {\n dev = process.env.NODE_ENV !== \"production\";\n } catch {\n dev = false;\n }\n const text = `${component}: ${message}`;\n if (!dev || warned.has(text)) return;\n warned.add(text);\n console.warn(text);\n}\n","import { createContext, useContext, useEffect, useSyncExternalStore, type ReactElement, type ReactNode, type ComponentType } from \"react\";\nimport { warnOnce } from \"./dev-warn\";\n\n/* ── Types ────────────────────────────────────────────────────── */\n\n/**\n * Runtime list of curated icon names. The CuratedIconName type derives from\n * this array, so adding a name here extends autocomplete automatically.\n * Every name must have an alias (or auto-kebab match) in ALL five packs —\n * icon-completeness.test.tsx enforces this.\n */\nexport const CURATED_ICON_NAMES = [\n \"home\", \"folder\", \"chart\", \"settings\",\n \"chevron-right\", \"close\", \"plus\", \"search\",\n \"bell\", \"user\", \"check\", \"warning\", \"info\", \"error\",\n \"clock\", \"calendar\",\n \"bold\", \"italic\", \"underline\", \"strikethrough\",\n \"align-left\", \"align-center\", \"align-right\",\n \"list\", \"list-ordered\", \"list-checks\",\n \"link\", \"image\", \"table\", \"code\", \"quote\", \"minus\",\n \"superscript\", \"subscript\", \"highlight\", \"type\",\n \"chevron-up\", \"chevron-down\", \"chevron-left\", \"trash\",\n \"undo\", \"redo\",\n \"arrow-left\", \"grip-vertical\",\n \"mic\", \"paperclip\", \"send\",\n \"log-out\", \"edit\", \"menu\", \"more-horizontal\",\n \"star\", \"bookmark\", \"download\", \"upload\", \"sparkles\",\n \"file\", \"file-text\", \"eye\", \"eye-off\", \"copy\", \"external-link\", \"filter\", \"lock\",\n \"map-pin\",\n] as const;\n\ntype CuratedIconName = (typeof CURATED_ICON_NAMES)[number];\n\n/**\n * Curated names provide autocomplete and work identically across all 5 packs.\n * Any kebab-case string is also accepted — it resolves directly against the\n * active pack's native exports (e.g. \"clipboard-copy\" → Lucide's ClipboardCopy).\n */\nexport type IconName = CuratedIconName | (string & {});\n\nexport type IconPack = \"lucide\" | \"phosphor\" | \"heroicons\" | \"tabler\" | \"feather\";\n\ntype IconComponent = ComponentType<Record<string, unknown>>;\ntype IconMap = Record<string, IconComponent>;\n\n/* ── External store ──────────────────────────────────────────── */\n\ntype Subscriber = () => void;\nconst subscribers = new Set<Subscriber>();\nfunction notifySubscribers() {\n subscribers.forEach((fn) => fn());\n}\nfunction subscribe(cb: Subscriber): () => void {\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nconst curatedCache = new Map<IconPack, IconMap>();\nconst extendedCache = new Map<IconPack, IconMap>();\n\nfunction useCuratedMap(pack: IconPack): IconMap | null {\n return useSyncExternalStore(\n subscribe,\n () => curatedCache.get(pack) ?? null,\n () => null,\n );\n}\n\nfunction useExtendedMap(pack: IconPack): IconMap | null {\n return useSyncExternalStore(\n subscribe,\n () => extendedCache.get(pack) ?? null,\n () => null,\n );\n}\n\n/* ── Pack loading ────────────────────────────────────────────────\n Each pack is isolated in its own file under ./icon-packs/.\n Only the active pack's module is dynamically imported at runtime,\n so bundlers won't resolve unused pack dependencies at build time.\n\n Loading is two-phase:\n 1. Curated map (50 static named imports) — available as soon as\n the pack chunk loads, cached and notified immediately.\n 2. Extended map (full barrel import + kebab-case iteration) —\n loaded in the background, cached and notified when ready. */\n\nconst loadingPacks = new Set<IconPack>();\nconst failedPacks = new Set<IconPack>();\n\ntype PackModule = {\n loadCurated(): Promise<IconMap>;\n loadExtended(): Promise<IconMap>;\n};\n\n/** The npm package each pack needs — named in the error when a pack is missing. */\nconst PEER_PACKAGE: Record<IconPack, string> = {\n lucide: \"lucide-react\",\n phosphor: \"@phosphor-icons/react\",\n heroicons: \"@heroicons/react\",\n tabler: \"@tabler/icons-react\",\n feather: \"react-icons\",\n};\n\nasync function loadPack(pack: IconPack): Promise<void> {\n if (curatedCache.has(pack) || loadingPacks.has(pack) || failedPacks.has(pack)) return;\n loadingPacks.add(pack);\n\n // Each pack module reaches its peer only through a dynamic import (see\n // icon-packs/*.ts), so the chunk import below always succeeds and it is\n // loadCurated() that rejects when the pack is not installed.\n let mod: PackModule;\n let curated: IconMap;\n try {\n switch (pack) {\n case \"lucide\": mod = await import(\"./icon-packs/lucide\"); break;\n case \"phosphor\": mod = await import(\"./icon-packs/phosphor\"); break;\n case \"heroicons\": mod = await import(\"./icon-packs/heroicons\"); break;\n case \"tabler\": mod = await import(\"./icon-packs/tabler\"); break;\n case \"feather\": mod = await import(\"./icon-packs/feather\"); break;\n }\n curated = await mod!.loadCurated();\n } catch {\n loadingPacks.delete(pack);\n failedPacks.add(pack);\n console.error(`gridsmith-ui: ${PEER_PACKAGE[pack]} is not installed. Run: npm install ${PEER_PACKAGE[pack]}`);\n return;\n }\n\n curatedCache.set(pack, curated);\n notifySubscribers();\n\n mod!.loadExtended().then((extended) => {\n extendedCache.set(pack, extended);\n notifySubscribers();\n }).catch(() => {\n // Extended map failed (e.g. network error loading the full barrel).\n // Curated icons still work; extended names will not resolve.\n });\n}\n\n/** Exported for the icon-completeness test — not part of the public API. */\nexport const packLoaders: Record<IconPack, {\n curated: () => Promise<IconMap>;\n extended: () => Promise<IconMap>;\n}> = {\n lucide: { curated: () => import(\"./icon-packs/lucide\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/lucide\").then((m) => m.loadExtended()) },\n phosphor: { curated: () => import(\"./icon-packs/phosphor\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/phosphor\").then((m) => m.loadExtended()) },\n heroicons: { curated: () => import(\"./icon-packs/heroicons\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/heroicons\").then((m) => m.loadExtended()) },\n tabler: { curated: () => import(\"./icon-packs/tabler\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/tabler\").then((m) => m.loadExtended()) },\n feather: { curated: () => import(\"./icon-packs/feather\").then((m) => m.loadCurated()), extended: () => import(\"./icon-packs/feather\").then((m) => m.loadExtended()) },\n};\n\n/* ── Context ──────────────────────────────────────────────────── */\n\ninterface IconContextValue {\n pack: IconPack;\n weight: number;\n}\n\nconst IconCtx = createContext<IconContextValue>({ pack: \"lucide\", weight: 1.5 });\n\nexport function IconProvider({ pack, weight, children }: { pack: IconPack; weight: number; children: ReactNode }) {\n useEffect(() => {\n loadPack(pack);\n if (pack !== \"lucide\") loadPack(\"lucide\");\n }, [pack]);\n\n return <IconCtx.Provider value={{ pack, weight }}>{children}</IconCtx.Provider>;\n}\n\n/**\n * Start loading a pack's icon chunk before React mounts. Call this in your\n * app's entry point (e.g. main.tsx) for the fastest possible cold start:\n *\n * import { preloadPack } from 'gridsmith-ui/icons'\n * preloadPack('lucide')\n */\nexport function preloadPack(pack: IconPack): void {\n loadPack(pack);\n}\n\n/* ── Phosphor weight mapping ──────────────────────────────────── */\n\n/**\n * A stroke weight maps to a stroke weight only. `fill` and `duotone` change the\n * glyph itself (Phosphor's filled Check is a check inside a filled square), so\n * a theme's heaviest stroke must never reach them — the Sprint 22 bench found\n * every tick on a 2.5-weight theme rendered as a filled box (14 Sep 2026).\n */\nexport function getPhosphorWeight(numericWeight: number): \"thin\" | \"light\" | \"regular\" | \"bold\" {\n if (numericWeight <= 0.75) return \"thin\";\n if (numericWeight <= 1.25) return \"light\";\n if (numericWeight <= 1.75) return \"regular\";\n return \"bold\";\n}\n\n/* ── Icon component ───────────────────────────────────────────── */\n\n/**\n * `from`: the component slot that drew the icon (\"Button's iconLeft\"), named in the development warning when the theme's\n * pack has no icon by that name. A name no pack has draws nothing (Sprint 25.17 A26: an arrow or a word passed as an\n * icon was printed as text before slots took names).\n */\n/**\n * Whether a map holds an icon of its own by this name, never one its prototype lends: a slot now takes any string, and\n * \"constructor\", \"toString\" or \"__proto__\" read off a plain object drew junk or threw (Sprint 25.17's review). The icon\n * is then read off the map itself, so the compiler sees a component the map holds, not one made while rendering.\n */\nfunction owns(map: Record<string, IconComponent> | null | undefined, name: string): map is Record<string, IconComponent> {\n return !!map && Object.prototype.hasOwnProperty.call(map, name);\n}\n\nexport function Icon({ name, size = 16, className, from }: { name: IconName; size?: number; className?: string; from?: string }) {\n const { pack, weight } = useContext(IconCtx);\n\n const curatedMap = useCuratedMap(pack);\n const extendedMap = useExtendedMap(pack);\n const lucideCurated = useCuratedMap(\"lucide\");\n const lucideExtended = useExtendedMap(\"lucide\");\n\n // Ensure the active pack is loading (covers cases where Icon mounts\n // before IconProvider's useEffect fires, e.g. during SSR hydration)\n if (!curatedCache.has(pack) && !loadingPacks.has(pack)) {\n loadPack(pack);\n }\n\n let Comp: IconComponent | undefined | null = null;\n let renderPack: IconPack = pack;\n\n // Tier 1: curated map (available once pack chunk has loaded)\n if (owns(curatedMap, name)) {\n Comp = curatedMap[name];\n }\n\n // Tier 2: extended map (available after barrel import completes)\n if (!Comp && owns(extendedMap, name)) {\n Comp = extendedMap[name];\n }\n\n // Tier 3: lucide fallback (curated first, then extended)\n if (!Comp && pack !== \"lucide\") {\n const fallback = owns(lucideCurated, name) ? lucideCurated[name] : owns(lucideExtended, name) ? lucideExtended[name] : undefined;\n if (fallback) {\n Comp = fallback;\n renderPack = \"lucide\";\n }\n }\n\n const allMapsLoaded = !!(curatedMap && extendedMap && (pack === \"lucide\" || (lucideCurated && lucideExtended)));\n const missing = !Comp && allMapsLoaded;\n useEffect(() => {\n if (missing) warnOnce(\"Icon\", `\"${name}\" is not an icon name in the ${pack} pack${pack === \"lucide\" ? \"\" : \" or Lucide\"}, so ${from ?? \"it\"} draws nothing. Pass an icon name, or an element.`);\n }, [missing, name, pack, from]);\n\n if (!Comp) {\n if (allMapsLoaded) return null;\n return <span style={{ display: \"inline-block\", width: size, height: size }} className={className} />;\n }\n\n if (renderPack === \"phosphor\") {\n return <Comp size={size} weight={getPhosphorWeight(weight)} className={className} />;\n }\n\n if (renderPack === \"heroicons\") {\n return <Comp className={className} style={{ width: size, height: size, strokeWidth: weight }} />;\n }\n\n if (renderPack === \"tabler\") {\n return <Comp size={size} stroke={weight} className={className} />;\n }\n\n if (renderPack === \"feather\") {\n return <Comp size={size} className={className} strokeWidth={weight} />;\n }\n\n return <Comp size={size} strokeWidth={weight} className={className} />;\n}\n\n/* ── Icon slots ───────────────────────────────────────────────── */\n\n/**\n * What an icon slot takes (Sprint 25.17 A26): an icon name, drawn as the theme's icon at the slot's size, or an element,\n * drawn as given. `IconName` accepts any string, so text type-checks: in development a name the theme's pack lacks warns,\n * naming the slot, and draws nothing; the engine flags a literal that is no icon name (gs:icon-slot-not-an-icon).\n */\nexport type IconSlot = IconName | ReactElement | false | null | undefined;\n\n/** What an icon slot holds, drawn: a name as the theme's icon at `size`, anything else as given. */\nexport function slotIcon(icon: IconSlot | ReactNode, size: number, from: string): ReactNode {\n if (typeof icon === \"string\") {\n // \"\" is no icon (`saved ? \"check\" : \"\"`): nothing drawn, nothing warned\n if (!icon) return null;\n return ICON_NAME_SHAPE.test(icon) ? <Icon name={icon} size={size} from={from} /> : <NotAnIcon text={icon} from={from} />;\n }\n return icon;\n}\n\n/** The shape of an icon name: kebab case, as every pack's names are written (\"arrow-right\", \"file-text\"). */\nconst ICON_NAME_SHAPE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Whether a slot draws something: an element, or a string shaped as an icon name. Text (\"→\", \"Save\") draws nothing, so\n * a button keeps its even padding for it (Sprint 25.17's review); a name the pack lacks still warns, once its maps load.\n */\nexport function slotDraws(icon: IconSlot | ReactNode): boolean {\n if (typeof icon === \"string\") return ICON_NAME_SHAPE.test(icon);\n return icon != null && icon !== false && icon !== true;\n}\n\n/** Text given to an icon slot: it draws nothing, and says so in development, naming the slot. */\nfunction NotAnIcon({ text, from }: { text: string; from: string }) {\n useEffect(() => {\n warnOnce(\"Icon\", `\"${text}\" is not an icon name, so ${from} draws nothing. Words go in the label; pass an icon name, or an element.`);\n }, [text, from]);\n return null;\n}\n"]}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { PreferencesContext, Button } from './chunk-
|
|
1
|
+
import { PreferencesContext, Button } from './chunk-ZYVXV4WC.js';
|
|
2
2
|
import { useBreakpoint, readBreakpointPx } from './chunk-CRQ6KCRD.js';
|
|
3
3
|
import { FormChangeCtx } from './chunk-XVB55M3N.js';
|
|
4
|
-
import { SurfaceBoundary } from './chunk-
|
|
5
|
-
import { usePopupFocus, useOverlayLayer, useReturnFocus, useFocusTrap, focusInitial, useNonModalDialog, OVERLAY_CLOSE_ATTR } from './chunk-
|
|
6
|
-
import {
|
|
4
|
+
import { SurfaceBoundary } from './chunk-QM4SJKWV.js';
|
|
5
|
+
import { usePopupFocus, useOverlayLayer, useReturnFocus, useFocusTrap, focusInitial, useNonModalDialog, OVERLAY_CLOSE_ATTR } from './chunk-ZI3OQDET.js';
|
|
6
|
+
import { useTextOverflow, Tooltip } from './chunk-MD2EFMES.js';
|
|
7
|
+
import { Icon } from './chunk-HXVXJUGV.js';
|
|
8
|
+
import { usePosition } from './chunk-HP7WUZPK.js';
|
|
7
9
|
import { useLatest } from './chunk-WH2FUFAC.js';
|
|
8
|
-
import { Icon } from './chunk-4LDYR7QP.js';
|
|
9
10
|
import { cn, lockBodyScroll, unlockBodyScroll, OVERLAY_SURFACE, GLASS_OVERLAY } from './chunk-M2QRNBDQ.js';
|
|
10
11
|
import { createContext, version, forwardRef, useState, useCallback, useRef, useEffect, isValidElement, useContext, useMemo, useId, useLayoutEffect } from 'react';
|
|
11
12
|
import { createPortal } from 'react-dom';
|
|
@@ -1184,5 +1185,5 @@ function useElementWidth(ref) {
|
|
|
1184
1185
|
}
|
|
1185
1186
|
|
|
1186
1187
|
export { AppShell, Breadcrumbs, DiscardConfirm, Drawer, DrawerFooterCtx, DrawerPanel, OVERLAY_ROOT_ATTR, OverlayCloseCtx, OverlayMarkCtx, OverlayMarkScope, REACT_VERSION_PROBLEM, ResizeEdge, SkipLink, crumbGoes, defaultMaxWidth, insetLessScrollbar, pxOf, useAppShell, useBelow, useCloseSettle, useCompact, useCrumbFollow, useDirtyGuard, useElementWidth, useOverlayMark, useRememberedWidth, useScrollbarInset, useUnsavedChanges };
|
|
1187
|
-
//# sourceMappingURL=chunk-
|
|
1188
|
-
//# sourceMappingURL=chunk-
|
|
1188
|
+
//# sourceMappingURL=chunk-KWLNEH53.js.map
|
|
1189
|
+
//# sourceMappingURL=chunk-KWLNEH53.js.map
|