@neuronection/assistant-ui 0.1.0 → 0.3.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/CHANGELOG.md +40 -0
- package/README.md +40 -9
- package/dist/badge.js +1 -1
- package/dist/button.js +1 -1
- package/dist/check-indicator.d.ts +12 -0
- package/dist/check-indicator.js +3 -0
- package/dist/check-indicator.js.map +1 -0
- package/dist/chip-input.d.ts +14 -0
- package/dist/chip-input.js +3 -0
- package/dist/chip-input.js.map +1 -0
- package/dist/chip-list.d.ts +15 -0
- package/dist/chip-list.js +3 -0
- package/dist/chip-list.js.map +1 -0
- package/dist/chunk-2KO2YIZN.js +357 -0
- package/dist/chunk-2KO2YIZN.js.map +1 -0
- package/dist/chunk-3522NABN.js +452 -0
- package/dist/chunk-3522NABN.js.map +1 -0
- package/dist/chunk-4SW3ESVI.js +111 -0
- package/dist/chunk-4SW3ESVI.js.map +1 -0
- package/dist/chunk-5AVBKEDQ.js +74 -0
- package/dist/chunk-5AVBKEDQ.js.map +1 -0
- package/dist/chunk-5X3RYDPC.js +54 -0
- package/dist/chunk-5X3RYDPC.js.map +1 -0
- package/dist/chunk-BJOY3XL7.js +27 -0
- package/dist/chunk-BJOY3XL7.js.map +1 -0
- package/dist/chunk-BPTGPF3L.js +3 -0
- package/dist/chunk-BPTGPF3L.js.map +1 -0
- package/dist/chunk-DV3MXDLN.js +46 -0
- package/dist/chunk-DV3MXDLN.js.map +1 -0
- package/dist/chunk-ESUTPQDO.js +21 -0
- package/dist/chunk-ESUTPQDO.js.map +1 -0
- package/dist/{chunk-TLTKWLMN.js → chunk-GA3XIDVX.js} +3 -3
- package/dist/{chunk-TLTKWLMN.js.map → chunk-GA3XIDVX.js.map} +1 -1
- package/dist/chunk-GPIN2ITX.js +63 -0
- package/dist/chunk-GPIN2ITX.js.map +1 -0
- package/dist/{chunk-56VRWCLJ.js → chunk-GTXGTQ6F.js} +2 -2
- package/dist/{chunk-56VRWCLJ.js.map → chunk-GTXGTQ6F.js.map} +1 -1
- package/dist/chunk-H5U4KNXF.js +63 -0
- package/dist/chunk-H5U4KNXF.js.map +1 -0
- package/dist/chunk-HSUCCANX.js +44 -0
- package/dist/chunk-HSUCCANX.js.map +1 -0
- package/dist/chunk-KXLMTAZ5.js +109 -0
- package/dist/chunk-KXLMTAZ5.js.map +1 -0
- package/dist/chunk-LEDQQBVV.js +184 -0
- package/dist/chunk-LEDQQBVV.js.map +1 -0
- package/dist/chunk-MXOBOS4Y.js +60 -0
- package/dist/chunk-MXOBOS4Y.js.map +1 -0
- package/dist/chunk-N5KQRHXU.js +107 -0
- package/dist/chunk-N5KQRHXU.js.map +1 -0
- package/dist/chunk-OAR74ML4.js +3 -0
- package/dist/chunk-OAR74ML4.js.map +1 -0
- package/dist/chunk-OUHUVACM.js +45 -0
- package/dist/chunk-OUHUVACM.js.map +1 -0
- package/dist/chunk-PPH3G7AL.js +3 -0
- package/dist/chunk-PPH3G7AL.js.map +1 -0
- package/dist/chunk-RU3DEF2O.js +186 -0
- package/dist/chunk-RU3DEF2O.js.map +1 -0
- package/dist/{chunk-NQQNTK6L.js → chunk-SKTLC2XY.js} +2 -2
- package/dist/{chunk-NQQNTK6L.js.map → chunk-SKTLC2XY.js.map} +1 -1
- package/dist/chunk-TPLQL62V.js +124 -0
- package/dist/chunk-TPLQL62V.js.map +1 -0
- package/dist/chunk-UIUALJNR.js +110 -0
- package/dist/chunk-UIUALJNR.js.map +1 -0
- package/dist/chunk-WZSAUESL.js +58 -0
- package/dist/chunk-WZSAUESL.js.map +1 -0
- package/dist/chunk-XE4TFW63.js +34 -0
- package/dist/chunk-XE4TFW63.js.map +1 -0
- package/dist/chunk-XLD2BPTT.js +82 -0
- package/dist/chunk-XLD2BPTT.js.map +1 -0
- package/dist/combobox.d.ts +54 -0
- package/dist/combobox.js +3 -0
- package/dist/combobox.js.map +1 -0
- package/dist/confirmation-modal.js +1 -1
- package/dist/context-menu.d.ts +22 -0
- package/dist/context-menu.js +3 -0
- package/dist/context-menu.js.map +1 -0
- package/dist/date-picker.d.ts +26 -0
- package/dist/date-picker.js +3 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/error-banner.d.ts +10 -0
- package/dist/error-banner.js +3 -0
- package/dist/error-banner.js.map +1 -0
- package/dist/expandable-search.d.ts +16 -0
- package/dist/expandable-search.js +3 -0
- package/dist/expandable-search.js.map +1 -0
- package/dist/field-label.d.ts +13 -0
- package/dist/field-label.js +3 -0
- package/dist/field-label.js.map +1 -0
- package/dist/form-modal.d.ts +23 -0
- package/dist/form-modal.js +3 -0
- package/dist/form-modal.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +30 -8
- package/dist/info-button.d.ts +13 -0
- package/dist/info-button.js +3 -0
- package/dist/info-button.js.map +1 -0
- package/dist/marquee.d.ts +39 -0
- package/dist/marquee.js +3 -0
- package/dist/marquee.js.map +1 -0
- package/dist/menu.d.ts +38 -0
- package/dist/menu.js +3 -0
- package/dist/menu.js.map +1 -0
- package/dist/popover-button.d.ts +23 -0
- package/dist/popover-button.js +3 -0
- package/dist/popover-button.js.map +1 -0
- package/dist/range-bar.d.ts +15 -0
- package/dist/range-bar.js +3 -0
- package/dist/range-bar.js.map +1 -0
- package/dist/scale-slider.d.ts +18 -0
- package/dist/scale-slider.js +3 -0
- package/dist/scale-slider.js.map +1 -0
- package/dist/search-input.d.ts +15 -0
- package/dist/search-input.js +3 -0
- package/dist/search-input.js.map +1 -0
- package/dist/selection-bar.d.ts +13 -0
- package/dist/selection-bar.js +3 -0
- package/dist/selection-bar.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/table.d.ts +10 -0
- package/dist/table.js +3 -0
- package/dist/table.js.map +1 -0
- package/dist/undo-notice.d.ts +14 -0
- package/dist/undo-notice.js +3 -0
- package/dist/undo-notice.js.map +1 -0
- package/dist/view-toggle.d.ts +13 -0
- package/dist/view-toggle.js +3 -0
- package/dist/view-toggle.js.map +1 -0
- package/dist/wizard.d.ts +57 -0
- package/dist/wizard.js +3 -0
- package/dist/wizard.js.map +1 -0
- package/package.json +97 -4
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/marquee/Marquee.tsx
|
|
5
|
+
function rectsIntersect(a, b) {
|
|
6
|
+
return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom;
|
|
7
|
+
}
|
|
8
|
+
function marqueeRect(startX, startY, currentX, currentY) {
|
|
9
|
+
return {
|
|
10
|
+
left: Math.min(startX, currentX),
|
|
11
|
+
top: Math.min(startY, currentY),
|
|
12
|
+
right: Math.max(startX, currentX),
|
|
13
|
+
bottom: Math.max(startY, currentY)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function hitTestIds(container, marquee) {
|
|
17
|
+
const hits = [];
|
|
18
|
+
const elements = container.querySelectorAll("[data-selectable-id]");
|
|
19
|
+
for (const element of elements) {
|
|
20
|
+
const box = element.getBoundingClientRect();
|
|
21
|
+
const itemRect = {
|
|
22
|
+
left: box.left,
|
|
23
|
+
top: box.top,
|
|
24
|
+
right: box.right,
|
|
25
|
+
bottom: box.bottom
|
|
26
|
+
};
|
|
27
|
+
if (rectsIntersect(marquee, itemRect)) {
|
|
28
|
+
const id = element.getAttribute("data-selectable-id");
|
|
29
|
+
if (id !== null) {
|
|
30
|
+
hits.push(id);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return hits;
|
|
35
|
+
}
|
|
36
|
+
var DRAG_THRESHOLD = 4;
|
|
37
|
+
var INTERACTIVE_SELECTOR = "button, input, textarea, select, a, [data-selectable-id], [data-no-marquee]";
|
|
38
|
+
function useMarquee({
|
|
39
|
+
enabled,
|
|
40
|
+
containerRef,
|
|
41
|
+
getBaseSelection,
|
|
42
|
+
onSelect
|
|
43
|
+
}) {
|
|
44
|
+
const [band, setBand] = React.useState(null);
|
|
45
|
+
const startRef = React.useRef(null);
|
|
46
|
+
const armedRef = React.useRef(false);
|
|
47
|
+
const getBaseRef = React.useRef(getBaseSelection);
|
|
48
|
+
getBaseRef.current = getBaseSelection;
|
|
49
|
+
const onSelectRef = React.useRef(onSelect);
|
|
50
|
+
onSelectRef.current = onSelect;
|
|
51
|
+
React.useEffect(() => {
|
|
52
|
+
if (!enabled) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const container = containerRef.current;
|
|
56
|
+
if (container === null) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const onMouseDown = (event) => {
|
|
60
|
+
if (event.button !== 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const target = event.target;
|
|
64
|
+
if (target !== null && target.closest(INTERACTIVE_SELECTOR) !== null) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const base = event.ctrlKey || event.metaKey ? new Set(getBaseRef.current()) : /* @__PURE__ */ new Set();
|
|
68
|
+
startRef.current = { x: event.clientX, y: event.clientY, base };
|
|
69
|
+
armedRef.current = false;
|
|
70
|
+
};
|
|
71
|
+
const onMouseMove = (event) => {
|
|
72
|
+
const start = startRef.current;
|
|
73
|
+
if (start === null) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const rect = marqueeRect(start.x, start.y, event.clientX, event.clientY);
|
|
77
|
+
if (!armedRef.current) {
|
|
78
|
+
if (rect.right - rect.left < DRAG_THRESHOLD && rect.bottom - rect.top < DRAG_THRESHOLD) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
armedRef.current = true;
|
|
82
|
+
onSelectRef.current([...start.base], "start");
|
|
83
|
+
}
|
|
84
|
+
setBand(rect);
|
|
85
|
+
const containerNow = containerRef.current;
|
|
86
|
+
if (containerNow !== null) {
|
|
87
|
+
const hits = hitTestIds(containerNow, rect);
|
|
88
|
+
onSelectRef.current([.../* @__PURE__ */ new Set([...start.base, ...hits])], "drag");
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const finish = (event) => {
|
|
92
|
+
const start = startRef.current;
|
|
93
|
+
if (start === null) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
startRef.current = null;
|
|
97
|
+
setBand(null);
|
|
98
|
+
if (armedRef.current) {
|
|
99
|
+
const containerNow = containerRef.current;
|
|
100
|
+
if (containerNow !== null) {
|
|
101
|
+
const rect = marqueeRect(start.x, start.y, event.clientX, event.clientY);
|
|
102
|
+
const hits = hitTestIds(containerNow, rect);
|
|
103
|
+
onSelectRef.current([.../* @__PURE__ */ new Set([...start.base, ...hits])], "end");
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!event.ctrlKey && !event.metaKey) {
|
|
108
|
+
onSelectRef.current([], "end");
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const onKey = (event) => {
|
|
112
|
+
if (event.key === "Escape" && startRef.current !== null) {
|
|
113
|
+
const start = startRef.current;
|
|
114
|
+
startRef.current = null;
|
|
115
|
+
setBand(null);
|
|
116
|
+
onSelectRef.current([...start.base], "end");
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
container.addEventListener("mousedown", onMouseDown);
|
|
120
|
+
window.addEventListener("mousemove", onMouseMove);
|
|
121
|
+
window.addEventListener("mouseup", finish);
|
|
122
|
+
window.addEventListener("keydown", onKey);
|
|
123
|
+
return () => {
|
|
124
|
+
container.removeEventListener("mousedown", onMouseDown);
|
|
125
|
+
window.removeEventListener("mousemove", onMouseMove);
|
|
126
|
+
window.removeEventListener("mouseup", finish);
|
|
127
|
+
window.removeEventListener("keydown", onKey);
|
|
128
|
+
};
|
|
129
|
+
}, [enabled, containerRef]);
|
|
130
|
+
return { band };
|
|
131
|
+
}
|
|
132
|
+
function MarqueeBand({ band }) {
|
|
133
|
+
if (band === null) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return /* @__PURE__ */ jsx(
|
|
137
|
+
"div",
|
|
138
|
+
{
|
|
139
|
+
"data-as": "marquee-band",
|
|
140
|
+
className: "pointer-events-none fixed z-40 rounded-[calc(var(--as-radius-sm)-2px)] border border-[var(--as-primary)] bg-[var(--as-primary)]/10",
|
|
141
|
+
style: {
|
|
142
|
+
left: band.left,
|
|
143
|
+
top: band.top,
|
|
144
|
+
width: band.right - band.left,
|
|
145
|
+
height: band.bottom - band.top
|
|
146
|
+
},
|
|
147
|
+
"aria-hidden": true
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
var MarqueeSurface = React.forwardRef(
|
|
152
|
+
function MarqueeSurface2({ children, selection, clearBlocked, className, ...props }, ref) {
|
|
153
|
+
const paneRef = React.useRef(null);
|
|
154
|
+
React.useImperativeHandle(ref, () => paneRef.current);
|
|
155
|
+
const { band } = useMarquee({
|
|
156
|
+
enabled: true,
|
|
157
|
+
containerRef: paneRef,
|
|
158
|
+
getBaseSelection: () => selection.selected,
|
|
159
|
+
onSelect: (ids) => selection.set(ids)
|
|
160
|
+
});
|
|
161
|
+
React.useEffect(() => {
|
|
162
|
+
const onKey = (event) => {
|
|
163
|
+
if (clearBlocked?.() ?? false) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const target = event.target;
|
|
167
|
+
if (target instanceof Element && target.closest('input, textarea, select, [contenteditable="true"]') !== null) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (event.key === "Escape") {
|
|
171
|
+
selection.clear();
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
window.addEventListener("keydown", onKey);
|
|
175
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
176
|
+
}, [clearBlocked, selection]);
|
|
177
|
+
return /* @__PURE__ */ jsxs("div", { ref: paneRef, "data-marquee-surface": "", "data-as": "marquee-surface", className, ...props, children: [
|
|
178
|
+
children,
|
|
179
|
+
/* @__PURE__ */ jsx(MarqueeBand, { band })
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
export { MarqueeBand, MarqueeSurface, hitTestIds, marqueeRect, rectsIntersect, useMarquee };
|
|
185
|
+
//# sourceMappingURL=chunk-RU3DEF2O.js.map
|
|
186
|
+
//# sourceMappingURL=chunk-RU3DEF2O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/marquee/Marquee.tsx"],"names":["MarqueeSurface"],"mappings":";;;;AASO,SAAS,cAAA,CAAe,GAAS,CAAA,EAAkB;AACxD,EAAA,OAAO,CAAA,CAAE,IAAA,GAAO,CAAA,CAAE,KAAA,IAAS,EAAE,IAAA,GAAO,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,GAAA,GAAM,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,MAAM,CAAA,CAAE,MAAA;AAC/E;AAEO,SAAS,WAAA,CACd,MAAA,EACA,MAAA,EACA,QAAA,EACA,QAAA,EACM;AACN,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC/B,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC9B,KAAA,EAAO,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAChC,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,QAAQ;AAAA,GACnC;AACF;AAEO,SAAS,UAAA,CAAW,WAAwB,OAAA,EAAyB;AAC1E,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,MAAM,QAAA,GAAW,SAAA,CAAU,gBAAA,CAA8B,sBAAsB,CAAA;AAC/E,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,MAAM,GAAA,GAAM,QAAQ,qBAAA,EAAsB;AAC1C,IAAA,MAAM,QAAA,GAAiB;AAAA,MACrB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,KAAK,GAAA,CAAI,GAAA;AAAA,MACT,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,QAAQ,GAAA,CAAI;AAAA,KACd;AACA,IAAA,IAAI,cAAA,CAAe,OAAA,EAAS,QAAQ,CAAA,EAAG;AACrC,MAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,YAAA,CAAa,oBAAoB,CAAA;AACpD,MAAA,IAAI,OAAO,IAAA,EAAM;AACf,QAAA,IAAA,CAAK,KAAK,EAAE,CAAA;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,IAAM,cAAA,GAAiB,CAAA;AAEvB,IAAM,oBAAA,GACJ,6EAAA;AAWK,SAAS,UAAA,CAAW;AAAA,EACzB,OAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAA,EAA6C;AAC3C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAU,eAAsB,IAAI,CAAA;AACxD,EAAA,MAAM,QAAA,GAAiB,aAA2D,IAAI,CAAA;AACtF,EAAA,MAAM,QAAA,GAAiB,aAAO,KAAK,CAAA;AACnC,EAAA,MAAM,UAAA,GAAmB,aAAO,gBAAgB,CAAA;AAChD,EAAA,UAAA,CAAW,OAAA,GAAU,gBAAA;AACrB,EAAA,MAAM,WAAA,GAAoB,aAAO,QAAQ,CAAA;AACzC,EAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AAEtB,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AACA,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,IAAI,cAAc,IAAA,EAAM;AACtB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAAsB;AACzC,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,MAAA,IAAI,WAAW,IAAA,IAAQ,MAAA,CAAO,OAAA,CAAQ,oBAAoB,MAAM,IAAA,EAAM;AACpE,QAAA;AAAA,MACF;AACA,MAAA,MAAM,IAAA,GACJ,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,OAAA,GACnB,IAAI,GAAA,CAAI,UAAA,CAAW,OAAA,EAAS,CAAA,mBAC5B,IAAI,GAAA,EAAY;AACtB,MAAA,QAAA,CAAS,OAAA,GAAU,EAAE,CAAA,EAAG,KAAA,CAAM,SAAS,CAAA,EAAG,KAAA,CAAM,SAAS,IAAA,EAAK;AAC9D,MAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAAA,IACrB,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,KAAA,KAAsB;AACzC,MAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,IAAA,GAAO,YAAY,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,EAAG,KAAA,CAAM,OAAA,EAAS,KAAA,CAAM,OAAO,CAAA;AACvE,MAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,QAAA,IACE,IAAA,CAAK,QAAQ,IAAA,CAAK,IAAA,GAAO,kBACzB,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,GAAA,GAAM,cAAA,EACzB;AACA,UAAA;AAAA,QACF;AACA,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,QAAA,WAAA,CAAY,QAAQ,CAAC,GAAG,KAAA,CAAM,IAAI,GAAG,OAAO,CAAA;AAAA,MAC9C;AACA,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,MAAM,eAAe,YAAA,CAAa,OAAA;AAClC,MAAA,IAAI,iBAAiB,IAAA,EAAM;AACzB,QAAA,MAAM,IAAA,GAAO,UAAA,CAAW,YAAA,EAAc,IAAI,CAAA;AAC1C,QAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,KAAA,CAAM,IAAA,EAAM,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAA;AAAA,MACpE;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,MAAA,GAAS,CAAC,KAAA,KAAsB;AACpC,MAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,MAAA,IAAI,UAAU,IAAA,EAAM;AAClB,QAAA;AAAA,MACF;AACA,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,MAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,MAAA,IAAI,SAAS,OAAA,EAAS;AACpB,QAAA,MAAM,eAAe,YAAA,CAAa,OAAA;AAClC,QAAA,IAAI,iBAAiB,IAAA,EAAM;AACzB,UAAA,MAAM,IAAA,GAAO,YAAY,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,EAAG,KAAA,CAAM,OAAA,EAAS,KAAA,CAAM,OAAO,CAAA;AACvE,UAAA,MAAM,IAAA,GAAO,UAAA,CAAW,YAAA,EAAc,IAAI,CAAA;AAC1C,UAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,mBAAG,IAAI,IAAI,CAAC,GAAG,KAAA,CAAM,IAAA,EAAM,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,CAAA;AAAA,QACnE;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,IAAW,CAAC,MAAM,OAAA,EAAS;AACpC,QAAA,WAAA,CAAY,OAAA,CAAQ,EAAC,EAAG,KAAK,CAAA;AAAA,MAC/B;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KAAyB;AACtC,MAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,QAAA,IAAY,QAAA,CAAS,YAAY,IAAA,EAAM;AACvD,QAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AACvB,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,QAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,QAAA,WAAA,CAAY,QAAQ,CAAC,GAAG,KAAA,CAAM,IAAI,GAAG,KAAK,CAAA;AAAA,MAC5C;AAAA,IACF,CAAA;AAEA,IAAA,SAAA,CAAU,gBAAA,CAAiB,aAAa,WAAW,CAAA;AACnD,IAAA,MAAA,CAAO,gBAAA,CAAiB,aAAa,WAAW,CAAA;AAChD,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,MAAM,CAAA;AACzC,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,KAAK,CAAA;AACxC,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,CAAU,mBAAA,CAAoB,aAAa,WAAW,CAAA;AACtD,MAAA,MAAA,CAAO,mBAAA,CAAoB,aAAa,WAAW,CAAA;AACnD,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,MAAM,CAAA;AAC5C,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,KAAK,CAAA;AAAA,IAC7C,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,YAAY,CAAC,CAAA;AAE1B,EAAA,OAAO,EAAE,IAAA,EAAK;AAChB;AAEO,SAAS,WAAA,CAAY,EAAE,IAAA,EAAK,EAA0B;AAC3D,EAAA,IAAI,SAAS,IAAA,EAAM;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAQ,cAAA;AAAA,MACR,SAAA,EAAU,oIAAA;AAAA,MACV,KAAA,EAAO;AAAA,QACL,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,KAAA,EAAO,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,IAAA;AAAA,QACzB,MAAA,EAAQ,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK;AAAA,OAC7B;AAAA,MACA,aAAA,EAAW;AAAA;AAAA,GACb;AAEJ;AAcO,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA;AAAA,EAClC,SAASA,eAAAA,CAAe,EAAE,QAAA,EAAU,SAAA,EAAW,cAAc,SAAA,EAAW,GAAG,KAAA,EAAM,EAAG,GAAA,EAAK;AACvF,IAAA,MAAM,OAAA,GAAgB,aAA8B,IAAI,CAAA;AACxD,IAAM,KAAA,CAAA,mBAAA,CAAoB,GAAA,EAAK,MAAM,OAAA,CAAQ,OAAyB,CAAA;AACtE,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,UAAA,CAAW;AAAA,MAC1B,OAAA,EAAS,IAAA;AAAA,MACT,YAAA,EAAc,OAAA;AAAA,MACd,gBAAA,EAAkB,MAAM,SAAA,CAAU,QAAA;AAAA,MAClC,QAAA,EAAU,CAAC,GAAA,KAAQ,SAAA,CAAU,IAAI,GAAG;AAAA,KACrC,CAAA;AACD,IAAM,gBAAU,MAAM;AACpB,MAAA,MAAM,KAAA,GAAQ,CAAC,KAAA,KAAyB;AACtC,QAAA,IAAI,YAAA,QAAoB,KAAA,EAAO;AAC7B,UAAA;AAAA,QACF;AACA,QAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,QAAA,IACE,kBAAkB,OAAA,IAClB,MAAA,CAAO,OAAA,CAAQ,mDAAmD,MAAM,IAAA,EACxE;AACA,UAAA;AAAA,QACF;AACA,QAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU;AAC1B,UAAA,SAAA,CAAU,KAAA,EAAM;AAAA,QAClB;AAAA,MACF,CAAA;AACA,MAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,KAAK,CAAA;AACxC,MAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AAAA,IAC1D,CAAA,EAAG,CAAC,YAAA,EAAc,SAAS,CAAC,CAAA;AAC5B,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,OAAA,EAAS,sBAAA,EAAqB,IAAG,SAAA,EAAQ,iBAAA,EAAkB,SAAA,EAAuB,GAAG,KAAA,EAC5F,QAAA,EAAA;AAAA,MAAA,QAAA;AAAA,sBACD,GAAA,CAAC,eAAY,IAAA,EAAY;AAAA,KAAA,EAC3B,CAAA;AAAA,EAEJ;AACF","file":"chunk-RU3DEF2O.js","sourcesContent":["import * as React from 'react'\n\nexport interface Rect {\n left: number\n top: number\n right: number\n bottom: number\n}\n\nexport function rectsIntersect(a: Rect, b: Rect): boolean {\n return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom\n}\n\nexport function marqueeRect(\n startX: number,\n startY: number,\n currentX: number,\n currentY: number,\n): Rect {\n return {\n left: Math.min(startX, currentX),\n top: Math.min(startY, currentY),\n right: Math.max(startX, currentX),\n bottom: Math.max(startY, currentY),\n }\n}\n\nexport function hitTestIds(container: HTMLElement, marquee: Rect): string[] {\n const hits: string[] = []\n const elements = container.querySelectorAll<HTMLElement>('[data-selectable-id]')\n for (const element of elements) {\n const box = element.getBoundingClientRect()\n const itemRect: Rect = {\n left: box.left,\n top: box.top,\n right: box.right,\n bottom: box.bottom,\n }\n if (rectsIntersect(marquee, itemRect)) {\n const id = element.getAttribute('data-selectable-id')\n if (id !== null) {\n hits.push(id)\n }\n }\n }\n return hits\n}\n\nconst DRAG_THRESHOLD = 4\n\nconst INTERACTIVE_SELECTOR =\n 'button, input, textarea, select, a, [data-selectable-id], [data-no-marquee]'\n\nexport type MarqueePhase = 'start' | 'drag' | 'end'\n\nexport interface UseMarqueeOptions {\n enabled: boolean\n containerRef: { current: HTMLElement | null }\n getBaseSelection: () => Set<string>\n onSelect: (ids: string[], phase: MarqueePhase) => void\n}\n\nexport function useMarquee({\n enabled,\n containerRef,\n getBaseSelection,\n onSelect,\n}: UseMarqueeOptions): { band: Rect | null } {\n const [band, setBand] = React.useState<Rect | null>(null)\n const startRef = React.useRef<{ x: number; y: number; base: Set<string> } | null>(null)\n const armedRef = React.useRef(false)\n const getBaseRef = React.useRef(getBaseSelection)\n getBaseRef.current = getBaseSelection\n const onSelectRef = React.useRef(onSelect)\n onSelectRef.current = onSelect\n\n React.useEffect(() => {\n if (!enabled) {\n return\n }\n const container = containerRef.current\n if (container === null) {\n return\n }\n\n const onMouseDown = (event: MouseEvent) => {\n if (event.button !== 0) {\n return\n }\n const target = event.target as Element | null\n if (target !== null && target.closest(INTERACTIVE_SELECTOR) !== null) {\n return\n }\n const base =\n event.ctrlKey || event.metaKey\n ? new Set(getBaseRef.current())\n : new Set<string>()\n startRef.current = { x: event.clientX, y: event.clientY, base }\n armedRef.current = false\n }\n\n const onMouseMove = (event: MouseEvent) => {\n const start = startRef.current\n if (start === null) {\n return\n }\n const rect = marqueeRect(start.x, start.y, event.clientX, event.clientY)\n if (!armedRef.current) {\n if (\n rect.right - rect.left < DRAG_THRESHOLD &&\n rect.bottom - rect.top < DRAG_THRESHOLD\n ) {\n return\n }\n armedRef.current = true\n onSelectRef.current([...start.base], 'start')\n }\n setBand(rect)\n const containerNow = containerRef.current\n if (containerNow !== null) {\n const hits = hitTestIds(containerNow, rect)\n onSelectRef.current([...new Set([...start.base, ...hits])], 'drag')\n }\n }\n\n const finish = (event: MouseEvent) => {\n const start = startRef.current\n if (start === null) {\n return\n }\n startRef.current = null\n setBand(null)\n if (armedRef.current) {\n const containerNow = containerRef.current\n if (containerNow !== null) {\n const rect = marqueeRect(start.x, start.y, event.clientX, event.clientY)\n const hits = hitTestIds(containerNow, rect)\n onSelectRef.current([...new Set([...start.base, ...hits])], 'end')\n }\n return\n }\n if (!event.ctrlKey && !event.metaKey) {\n onSelectRef.current([], 'end')\n }\n }\n\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && startRef.current !== null) {\n const start = startRef.current\n startRef.current = null\n setBand(null)\n onSelectRef.current([...start.base], 'end')\n }\n }\n\n container.addEventListener('mousedown', onMouseDown)\n window.addEventListener('mousemove', onMouseMove)\n window.addEventListener('mouseup', finish)\n window.addEventListener('keydown', onKey)\n return () => {\n container.removeEventListener('mousedown', onMouseDown)\n window.removeEventListener('mousemove', onMouseMove)\n window.removeEventListener('mouseup', finish)\n window.removeEventListener('keydown', onKey)\n }\n }, [enabled, containerRef])\n\n return { band }\n}\n\nexport function MarqueeBand({ band }: { band: Rect | null }) {\n if (band === null) {\n return null\n }\n return (\n <div\n data-as=\"marquee-band\"\n className=\"pointer-events-none fixed z-40 rounded-[calc(var(--as-radius-sm)-2px)] border border-[var(--as-primary)] bg-[var(--as-primary)]/10\"\n style={{\n left: band.left,\n top: band.top,\n width: band.right - band.left,\n height: band.bottom - band.top,\n }}\n aria-hidden\n />\n )\n}\n\nexport interface MarqueeSelection {\n selected: Set<string>\n set: (ids: string[]) => void\n clear: () => void\n}\n\nexport interface MarqueeSurfaceProps extends React.ComponentProps<'div'> {\n children: React.ReactNode\n selection: MarqueeSelection\n clearBlocked?: () => boolean\n}\n\nexport const MarqueeSurface = React.forwardRef<HTMLDivElement, MarqueeSurfaceProps>(\n function MarqueeSurface({ children, selection, clearBlocked, className, ...props }, ref) {\n const paneRef = React.useRef<HTMLDivElement | null>(null)\n React.useImperativeHandle(ref, () => paneRef.current as HTMLDivElement)\n const { band } = useMarquee({\n enabled: true,\n containerRef: paneRef,\n getBaseSelection: () => selection.selected,\n onSelect: (ids) => selection.set(ids),\n })\n React.useEffect(() => {\n const onKey = (event: KeyboardEvent) => {\n if (clearBlocked?.() ?? false) {\n return\n }\n const target = event.target\n if (\n target instanceof Element &&\n target.closest('input, textarea, select, [contenteditable=\"true\"]') !== null\n ) {\n return\n }\n if (event.key === 'Escape') {\n selection.clear()\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [clearBlocked, selection])\n return (\n <div ref={paneRef} data-marquee-surface=\"\" data-as=\"marquee-surface\" className={className} {...props}>\n {children}\n <MarqueeBand band={band} />\n </div>\n )\n },\n)\n"]}
|
|
@@ -35,5 +35,5 @@ var Badge = React.forwardRef(function Badge2({ className, variant, ...props }, r
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
export { Badge, badgeVariants };
|
|
38
|
-
//# sourceMappingURL=chunk-
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
38
|
+
//# sourceMappingURL=chunk-SKTLC2XY.js.map
|
|
39
|
+
//# sourceMappingURL=chunk-SKTLC2XY.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/badge/Badge.tsx"],"names":["Badge"],"mappings":";;;;;AAIA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,qGAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,uEAAA;AAAA,QACT,SAAA,EACE,2EAAA;AAAA,QACF,OAAA,EAAS,+CAAA;AAAA,QACT,OAAA,EAAS,uEAAA;AAAA,QACT,OAAA,EAAS,uEAAA;AAAA,QACT,MAAA,EAAQ,qEAAA;AAAA,QACR,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ;AAMO,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA,CAAwC,SAASA,MAAAA,CAC1E,EAAE,WAAW,OAAA,EAAS,GAAG,KAAA,EAAM,EAC/B,GAAA,EACA;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAQ,OAAA;AAAA,MACR,WAAW,EAAA,CAAG,aAAA,CAAc,EAAE,OAAA,EAAS,SAAA,EAAW,CAAC,CAAA;AAAA,MAClD,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/components/badge/Badge.tsx"],"names":["Badge"],"mappings":";;;;;AAIA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACpB,qGAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,uEAAA;AAAA,QACT,SAAA,EACE,2EAAA;AAAA,QACF,OAAA,EAAS,+CAAA;AAAA,QACT,OAAA,EAAS,uEAAA;AAAA,QACT,OAAA,EAAS,uEAAA;AAAA,QACT,MAAA,EAAQ,qEAAA;AAAA,QACR,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ;AAMO,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA,CAAwC,SAASA,MAAAA,CAC1E,EAAE,WAAW,OAAA,EAAS,GAAG,KAAA,EAAM,EAC/B,GAAA,EACA;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAQ,OAAA;AAAA,MACR,WAAW,EAAA,CAAG,aAAA,CAAc,EAAE,OAAA,EAAS,SAAA,EAAW,CAAC,CAAA;AAAA,MAClD,GAAG;AAAA;AAAA,GACN;AAEJ,CAAC","file":"chunk-SKTLC2XY.js","sourcesContent":["import * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\nconst badgeVariants = cva(\n 'inline-flex items-center gap-1 rounded-full border px-2.5 py-0.5 text-xs font-medium [&_svg]:size-3',\n {\n variants: {\n variant: {\n default: 'border-transparent bg-[var(--as-primary)] text-[var(--as-primary-fg)]',\n secondary:\n 'border-transparent bg-[var(--as-secondary)] text-[var(--as-secondary-fg)]',\n outline: 'border-[var(--as-border)] text-[var(--as-fg)]',\n success: 'border-transparent bg-[var(--as-success)] text-[var(--as-success-fg)]',\n warning: 'border-transparent bg-[var(--as-warning)] text-[var(--as-warning-fg)]',\n danger: 'border-transparent bg-[var(--as-danger)] text-[var(--as-danger-fg)]',\n ai: 'border-transparent bg-[var(--as-ai)] text-[var(--as-ai-fg)]',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nexport interface BadgeProps\n extends React.ComponentProps<'span'>,\n VariantProps<typeof badgeVariants> {}\n\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n { className, variant, ...props },\n ref,\n) {\n return (\n <span\n ref={ref}\n data-as=\"badge\"\n className={cn(badgeVariants({ variant, className }))}\n {...props}\n />\n )\n})\n\nexport { badgeVariants }\n\n\n"]}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { X } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function escapeRegex(value) {
|
|
7
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8
|
+
}
|
|
9
|
+
var ChipInput = React.forwardRef(
|
|
10
|
+
function ChipInput2({
|
|
11
|
+
value,
|
|
12
|
+
onChange,
|
|
13
|
+
placeholder,
|
|
14
|
+
separators = [","],
|
|
15
|
+
inputLabel = "Add",
|
|
16
|
+
removeLabel = "Remove",
|
|
17
|
+
disabled = false,
|
|
18
|
+
className,
|
|
19
|
+
...props
|
|
20
|
+
}, ref) {
|
|
21
|
+
const [draft, setDraft] = React.useState("");
|
|
22
|
+
const inputRef = React.useRef(null);
|
|
23
|
+
const commit = (raw) => {
|
|
24
|
+
const separatorPattern = new RegExp(
|
|
25
|
+
`[${separators.map(escapeRegex).join("")}\\n\\r]`
|
|
26
|
+
);
|
|
27
|
+
const existing = new Set(value.map((chip) => chip.toLowerCase()));
|
|
28
|
+
const next = [...value];
|
|
29
|
+
for (const part of raw.split(separatorPattern)) {
|
|
30
|
+
const trimmed = part.trim();
|
|
31
|
+
if (trimmed && !existing.has(trimmed.toLowerCase())) {
|
|
32
|
+
next.push(trimmed);
|
|
33
|
+
existing.add(trimmed.toLowerCase());
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (next.length !== value.length) {
|
|
37
|
+
onChange(next);
|
|
38
|
+
}
|
|
39
|
+
setDraft("");
|
|
40
|
+
};
|
|
41
|
+
const handleKeyDown = (event) => {
|
|
42
|
+
if (event.key === "Enter" || separators.includes(event.key)) {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
commit(draft);
|
|
45
|
+
} else if (event.key === "Backspace" && draft === "" && value.length > 0) {
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
onChange(value.slice(0, -1));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const handlePaste = (event) => {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
const text = event.clipboardData.getData("text");
|
|
53
|
+
commit(`${draft}${text}`);
|
|
54
|
+
};
|
|
55
|
+
const removeAt = (index) => {
|
|
56
|
+
onChange(value.filter((_, i) => i !== index));
|
|
57
|
+
};
|
|
58
|
+
return /* @__PURE__ */ jsxs(
|
|
59
|
+
"div",
|
|
60
|
+
{
|
|
61
|
+
ref,
|
|
62
|
+
"data-as": "chip-input",
|
|
63
|
+
role: "group",
|
|
64
|
+
onClick: () => {
|
|
65
|
+
if (!disabled) inputRef.current?.focus();
|
|
66
|
+
},
|
|
67
|
+
className: cn(
|
|
68
|
+
"flex min-h-9 w-full cursor-text flex-wrap items-center gap-1.5 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2.5 py-1.5 text-sm outline-none transition-colors focus-within:border-[var(--as-focus-ring)] focus-within:ring-2 focus-within:ring-[var(--as-focus-ring)]",
|
|
69
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
70
|
+
className
|
|
71
|
+
),
|
|
72
|
+
...props,
|
|
73
|
+
children: [
|
|
74
|
+
value.map((chip, index) => /* @__PURE__ */ jsxs(
|
|
75
|
+
"span",
|
|
76
|
+
{
|
|
77
|
+
className: "inline-flex items-center gap-1 rounded-[calc(var(--as-radius-sm)-2px)] bg-[color-mix(in_srgb,var(--as-primary)_12%,transparent)] py-0.5 pl-2.5 pr-1.5 text-xs font-medium text-[var(--as-primary)]",
|
|
78
|
+
children: [
|
|
79
|
+
chip,
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
"button",
|
|
82
|
+
{
|
|
83
|
+
type: "button",
|
|
84
|
+
disabled,
|
|
85
|
+
"aria-label": `${removeLabel} ${chip}`,
|
|
86
|
+
onClick: (event) => {
|
|
87
|
+
event.stopPropagation();
|
|
88
|
+
removeAt(index);
|
|
89
|
+
},
|
|
90
|
+
className: "cursor-pointer rounded-full opacity-70 transition-colors hover:text-[var(--as-danger)] hover:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:pointer-events-none",
|
|
91
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3", "aria-hidden": true })
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
`${chip}-${index}`
|
|
97
|
+
)),
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
"input",
|
|
100
|
+
{
|
|
101
|
+
ref: inputRef,
|
|
102
|
+
type: "text",
|
|
103
|
+
"aria-label": inputLabel,
|
|
104
|
+
disabled,
|
|
105
|
+
value: draft,
|
|
106
|
+
onChange: (event) => setDraft(event.target.value),
|
|
107
|
+
onKeyDown: handleKeyDown,
|
|
108
|
+
onPaste: handlePaste,
|
|
109
|
+
onBlur: () => {
|
|
110
|
+
if (draft.trim()) commit(draft);
|
|
111
|
+
},
|
|
112
|
+
placeholder: value.length === 0 ? placeholder : "",
|
|
113
|
+
className: "min-w-24 flex-1 bg-transparent text-sm text-[var(--as-fg)] outline-none placeholder:text-[var(--as-muted-fg)]"
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
export { ChipInput };
|
|
123
|
+
//# sourceMappingURL=chunk-TPLQL62V.js.map
|
|
124
|
+
//# sourceMappingURL=chunk-TPLQL62V.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chip-input/ChipInput.tsx"],"names":["ChipInput"],"mappings":"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","file":"chunk-TPLQL62V.js","sourcesContent":["import * as React from 'react'\nimport { X } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface ChipInputProps\n extends Omit<React.ComponentProps<'div'>, 'onChange'> {\n value: string[]\n onChange: (value: string[]) => void\n placeholder?: string\n separators?: string[]\n inputLabel?: string\n removeLabel?: string\n disabled?: boolean\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nexport const ChipInput = React.forwardRef<HTMLDivElement, ChipInputProps>(\n function ChipInput(\n {\n value,\n onChange,\n placeholder,\n separators = [','],\n inputLabel = 'Add',\n removeLabel = 'Remove',\n disabled = false,\n className,\n ...props\n },\n ref,\n ) {\n const [draft, setDraft] = React.useState('')\n const inputRef = React.useRef<HTMLInputElement>(null)\n\n const commit = (raw: string) => {\n const separatorPattern = new RegExp(\n `[${separators.map(escapeRegex).join('')}\\\\n\\\\r]`,\n )\n const existing = new Set(value.map((chip) => chip.toLowerCase()))\n const next = [...value]\n for (const part of raw.split(separatorPattern)) {\n const trimmed = part.trim()\n if (trimmed && !existing.has(trimmed.toLowerCase())) {\n next.push(trimmed)\n existing.add(trimmed.toLowerCase())\n }\n }\n if (next.length !== value.length) {\n onChange(next)\n }\n setDraft('')\n }\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' || separators.includes(event.key)) {\n event.preventDefault()\n commit(draft)\n } else if (event.key === 'Backspace' && draft === '' && value.length > 0) {\n event.preventDefault()\n onChange(value.slice(0, -1))\n }\n }\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n event.preventDefault()\n const text = event.clipboardData.getData('text')\n commit(`${draft}${text}`)\n }\n\n const removeAt = (index: number) => {\n onChange(value.filter((_, i) => i !== index))\n }\n\n return (\n <div\n ref={ref}\n data-as=\"chip-input\"\n role=\"group\"\n onClick={() => {\n if (!disabled) inputRef.current?.focus()\n }}\n className={cn(\n 'flex min-h-9 w-full cursor-text flex-wrap items-center gap-1.5 rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2.5 py-1.5 text-sm outline-none transition-colors focus-within:border-[var(--as-focus-ring)] focus-within:ring-2 focus-within:ring-[var(--as-focus-ring)]',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n >\n {value.map((chip, index) => (\n <span\n key={`${chip}-${index}`}\n className=\"inline-flex items-center gap-1 rounded-[calc(var(--as-radius-sm)-2px)] bg-[color-mix(in_srgb,var(--as-primary)_12%,transparent)] py-0.5 pl-2.5 pr-1.5 text-xs font-medium text-[var(--as-primary)]\"\n >\n {chip}\n <button\n type=\"button\"\n disabled={disabled}\n aria-label={`${removeLabel} ${chip}`}\n onClick={(event) => {\n event.stopPropagation()\n removeAt(index)\n }}\n className=\"cursor-pointer rounded-full opacity-70 transition-colors hover:text-[var(--as-danger)] hover:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:pointer-events-none\"\n >\n <X className=\"size-3\" aria-hidden />\n </button>\n </span>\n ))}\n <input\n ref={inputRef}\n type=\"text\"\n aria-label={inputLabel}\n disabled={disabled}\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onBlur={() => {\n if (draft.trim()) commit(draft)\n }}\n placeholder={value.length === 0 ? placeholder : ''}\n className=\"min-w-24 flex-1 bg-transparent text-sm text-[var(--as-fg)] outline-none placeholder:text-[var(--as-muted-fg)]\"\n />\n </div>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function scaleColorForValue(min, max, value) {
|
|
6
|
+
if (value === "" || value === null || value === void 0) {
|
|
7
|
+
return "var(--as-muted-fg)";
|
|
8
|
+
}
|
|
9
|
+
const numeric = Number(value);
|
|
10
|
+
if (Number.isNaN(numeric)) return "var(--as-muted-fg)";
|
|
11
|
+
return positionColor((numeric - min) / (max - min));
|
|
12
|
+
}
|
|
13
|
+
function positionColor(position) {
|
|
14
|
+
const clamped = Math.max(0, Math.min(1, position));
|
|
15
|
+
const hue = 142 * (1 - clamped);
|
|
16
|
+
return `hsl(${hue.toFixed(0)}, 72%, 48%)`;
|
|
17
|
+
}
|
|
18
|
+
var ScaleSlider = React.forwardRef(
|
|
19
|
+
function ScaleSlider2({
|
|
20
|
+
value,
|
|
21
|
+
onChange,
|
|
22
|
+
min,
|
|
23
|
+
max,
|
|
24
|
+
step = 1,
|
|
25
|
+
lowLabel,
|
|
26
|
+
highLabel,
|
|
27
|
+
showInput = true,
|
|
28
|
+
disabled = false,
|
|
29
|
+
ariaLabel = "Scale",
|
|
30
|
+
className,
|
|
31
|
+
...props
|
|
32
|
+
}, ref) {
|
|
33
|
+
const numericValue = value === "" || value === null || value === void 0 || Number.isNaN(value) ? null : Number(value);
|
|
34
|
+
const thumbColor = scaleColorForValue(min, max, value);
|
|
35
|
+
const sliderValue = numericValue === null ? min : numericValue;
|
|
36
|
+
const handleSlider = (event) => {
|
|
37
|
+
const numeric = Number(event.target.value);
|
|
38
|
+
onChange(Number.isNaN(numeric) ? "" : numeric);
|
|
39
|
+
};
|
|
40
|
+
const handleInputChange = (event) => {
|
|
41
|
+
const raw = event.target.value;
|
|
42
|
+
if (raw === "") {
|
|
43
|
+
onChange("");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const numeric = Number(raw);
|
|
47
|
+
onChange(Number.isNaN(numeric) ? "" : numeric);
|
|
48
|
+
};
|
|
49
|
+
const handleInputBlur = () => {
|
|
50
|
+
if (numericValue === null) return;
|
|
51
|
+
const clamped = Math.max(min, Math.min(max, numericValue));
|
|
52
|
+
if (clamped !== numericValue) onChange(clamped);
|
|
53
|
+
};
|
|
54
|
+
const showLabels = Boolean(lowLabel || highLabel);
|
|
55
|
+
return /* @__PURE__ */ jsxs(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
ref,
|
|
59
|
+
"data-as": "scale-slider",
|
|
60
|
+
className: cn("flex flex-col gap-1.5", className),
|
|
61
|
+
...props,
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
"input",
|
|
66
|
+
{
|
|
67
|
+
type: "range",
|
|
68
|
+
"aria-label": ariaLabel,
|
|
69
|
+
className: cn(
|
|
70
|
+
"h-1.5 flex-1 cursor-pointer accent-[var(--as-primary)]",
|
|
71
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
72
|
+
),
|
|
73
|
+
min,
|
|
74
|
+
max,
|
|
75
|
+
step,
|
|
76
|
+
value: sliderValue,
|
|
77
|
+
disabled,
|
|
78
|
+
onChange: handleSlider
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
showInput ? /* @__PURE__ */ jsx(
|
|
82
|
+
"input",
|
|
83
|
+
{
|
|
84
|
+
type: "number",
|
|
85
|
+
"aria-label": `${ariaLabel} value`,
|
|
86
|
+
min,
|
|
87
|
+
max,
|
|
88
|
+
step,
|
|
89
|
+
value: value ?? "",
|
|
90
|
+
disabled,
|
|
91
|
+
onChange: handleInputChange,
|
|
92
|
+
onBlur: handleInputBlur,
|
|
93
|
+
style: { borderColor: thumbColor },
|
|
94
|
+
className: "w-16 rounded-[var(--as-radius-sm)] border-2 bg-[var(--as-surface-raised)] px-2 py-1.5 text-center text-sm font-bold text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:opacity-50"
|
|
95
|
+
}
|
|
96
|
+
) : null
|
|
97
|
+
] }),
|
|
98
|
+
showLabels ? /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-[9px] font-bold uppercase tracking-wider opacity-50", children: [
|
|
99
|
+
/* @__PURE__ */ jsx("span", { style: { color: positionColor(0) }, children: lowLabel }),
|
|
100
|
+
/* @__PURE__ */ jsx("span", { style: { color: positionColor(1) }, children: highLabel })
|
|
101
|
+
] }) : null
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
export { ScaleSlider, scaleColorForValue };
|
|
109
|
+
//# sourceMappingURL=chunk-UIUALJNR.js.map
|
|
110
|
+
//# sourceMappingURL=chunk-UIUALJNR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/scale-slider/ScaleSlider.tsx"],"names":["ScaleSlider"],"mappings":"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","file":"chunk-UIUALJNR.js","sourcesContent":["import * as React from 'react'\nimport { cn } from '../../lib/utils'\n\nexport interface ScaleSliderProps\n extends Omit<React.ComponentProps<'div'>, 'onChange'> {\n value: number | '' | null | undefined\n onChange: (value: number | '') => void\n min: number\n max: number\n step?: number\n lowLabel?: string\n highLabel?: string\n showInput?: boolean\n disabled?: boolean\n ariaLabel?: string\n}\n\nexport function scaleColorForValue(\n min: number,\n max: number,\n value: number | '' | null | undefined,\n): string {\n if (value === '' || value === null || value === undefined) {\n return 'var(--as-muted-fg)'\n }\n const numeric = Number(value)\n if (Number.isNaN(numeric)) return 'var(--as-muted-fg)'\n return positionColor((numeric - min) / (max - min))\n}\n\nfunction positionColor(position: number): string {\n const clamped = Math.max(0, Math.min(1, position))\n const hue = 142 * (1 - clamped)\n return `hsl(${hue.toFixed(0)}, 72%, 48%)`\n}\n\nexport const ScaleSlider = React.forwardRef<HTMLDivElement, ScaleSliderProps>(\n function ScaleSlider(\n {\n value,\n onChange,\n min,\n max,\n step = 1,\n lowLabel,\n highLabel,\n showInput = true,\n disabled = false,\n ariaLabel = 'Scale',\n className,\n ...props\n },\n ref,\n ) {\n const numericValue =\n value === '' ||\n value === null ||\n value === undefined ||\n Number.isNaN(value as number)\n ? null\n : Number(value)\n const thumbColor = scaleColorForValue(min, max, value)\n const sliderValue = numericValue === null ? min : numericValue\n\n const handleSlider = (event: React.ChangeEvent<HTMLInputElement>) => {\n const numeric = Number(event.target.value)\n onChange(Number.isNaN(numeric) ? '' : numeric)\n }\n\n const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const raw = event.target.value\n if (raw === '') {\n onChange('')\n return\n }\n const numeric = Number(raw)\n onChange(Number.isNaN(numeric) ? '' : numeric)\n }\n\n const handleInputBlur = () => {\n if (numericValue === null) return\n const clamped = Math.max(min, Math.min(max, numericValue))\n if (clamped !== numericValue) onChange(clamped)\n }\n\n const showLabels = Boolean(lowLabel || highLabel)\n\n return (\n <div\n ref={ref}\n data-as=\"scale-slider\"\n className={cn('flex flex-col gap-1.5', className)}\n {...props}\n >\n <div className=\"flex items-center gap-3\">\n <input\n type=\"range\"\n aria-label={ariaLabel}\n className={cn(\n 'h-1.5 flex-1 cursor-pointer accent-[var(--as-primary)]',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n min={min}\n max={max}\n step={step}\n value={sliderValue}\n disabled={disabled}\n onChange={handleSlider}\n />\n {showInput ? (\n <input\n type=\"number\"\n aria-label={`${ariaLabel} value`}\n min={min}\n max={max}\n step={step}\n value={value ?? ''}\n disabled={disabled}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n style={{ borderColor: thumbColor }}\n className=\"w-16 rounded-[var(--as-radius-sm)] border-2 bg-[var(--as-surface-raised)] px-2 py-1.5 text-center text-sm font-bold text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)] disabled:opacity-50\"\n />\n ) : null}\n </div>\n {showLabels ? (\n <div className=\"flex justify-between text-[9px] font-bold uppercase tracking-wider opacity-50\">\n <span style={{ color: positionColor(0) }}>{lowLabel}</span>\n <span style={{ color: positionColor(1) }}>{highLabel}</span>\n </div>\n ) : null}\n </div>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { MenuContent, MenuItem } from './chunk-KXLMTAZ5.js';
|
|
2
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
3
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function ContextMenu({ x, y, items, onClose, className }) {
|
|
7
|
+
const open = items.length > 0;
|
|
8
|
+
return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.Root, { open, onOpenChange: (next) => !next && onClose(), modal: false, children: [
|
|
9
|
+
/* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { asChild: true, "aria-hidden": true, tabIndex: -1, children: /* @__PURE__ */ jsx(
|
|
10
|
+
"span",
|
|
11
|
+
{
|
|
12
|
+
"data-as": "context-menu-anchor",
|
|
13
|
+
style: { position: "fixed", left: x, top: y, width: 0, height: 0 }
|
|
14
|
+
}
|
|
15
|
+
) }),
|
|
16
|
+
/* @__PURE__ */ jsx(
|
|
17
|
+
MenuContent,
|
|
18
|
+
{
|
|
19
|
+
align: "start",
|
|
20
|
+
sideOffset: 2,
|
|
21
|
+
collisionPadding: 8,
|
|
22
|
+
"data-as": "context-menu",
|
|
23
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
24
|
+
className: cn("min-w-40", className),
|
|
25
|
+
children: items.map(
|
|
26
|
+
(item) => item.disabled === true ? /* @__PURE__ */ jsxs(
|
|
27
|
+
"span",
|
|
28
|
+
{
|
|
29
|
+
role: "menuitem",
|
|
30
|
+
"aria-disabled": "true",
|
|
31
|
+
title: item.hint,
|
|
32
|
+
className: "pointer-events-none flex w-full cursor-default select-none items-center gap-2 rounded-[calc(var(--as-radius-sm)-2px)] px-2 py-1.5 text-left text-sm text-[var(--as-muted-fg)] opacity-50 [&_svg]:size-4 [&_svg]:shrink-0",
|
|
33
|
+
children: [
|
|
34
|
+
item.icon ? /* @__PURE__ */ jsx(item.icon, { "aria-hidden": true }) : null,
|
|
35
|
+
item.label
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
item.key
|
|
39
|
+
) : /* @__PURE__ */ jsx(
|
|
40
|
+
MenuItem,
|
|
41
|
+
{
|
|
42
|
+
icon: item.icon,
|
|
43
|
+
danger: item.danger,
|
|
44
|
+
title: item.hint,
|
|
45
|
+
onSelect: () => item.onSelect?.(),
|
|
46
|
+
children: item.label
|
|
47
|
+
},
|
|
48
|
+
item.key
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
] });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { ContextMenu };
|
|
57
|
+
//# sourceMappingURL=chunk-WZSAUESL.js.map
|
|
58
|
+
//# sourceMappingURL=chunk-WZSAUESL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/context-menu/ContextMenu.tsx"],"names":[],"mappings":";;;;;AAwBO,SAAS,YAAY,EAAE,CAAA,EAAG,GAAG,KAAA,EAAO,OAAA,EAAS,WAAU,EAAqB;AACjF,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,GAAS,CAAA;AAC5B,EAAA,uBACE,IAAA,CAAuB,qBAAA,CAAA,IAAA,EAAtB,EAA2B,IAAA,EAAY,YAAA,EAAc,CAAC,IAAA,KAAS,CAAC,IAAA,IAAQ,OAAA,EAAQ,EAAG,KAAA,EAAO,KAAA,EACzF,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAuB,+BAAtB,EAA8B,OAAA,EAAO,MAAC,aAAA,EAAW,IAAA,EAAC,UAAU,EAAA,EAC3D,QAAA,kBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAQ,qBAAA;AAAA,QACR,KAAA,EAAO,EAAE,QAAA,EAAU,OAAA,EAAS,IAAA,EAAM,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAE;AAAA,KACnE,EACF,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,OAAA;AAAA,QACN,UAAA,EAAY,CAAA;AAAA,QACZ,gBAAA,EAAkB,CAAA;AAAA,QAClB,SAAA,EAAQ,cAAA;AAAA,QACR,gBAAA,EAAkB,CAAC,KAAA,KAAU,KAAA,CAAM,cAAA,EAAe;AAAA,QAClD,SAAA,EAAW,EAAA,CAAG,UAAA,EAAY,SAAS,CAAA;AAAA,QAElC,QAAA,EAAA,KAAA,CAAM,GAAA;AAAA,UAAI,CAAC,IAAA,KACV,IAAA,CAAK,QAAA,KAAa,IAAA,mBAChB,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cAEC,IAAA,EAAK,UAAA;AAAA,cACL,eAAA,EAAc,MAAA;AAAA,cACd,OAAO,IAAA,CAAK,IAAA;AAAA,cACZ,SAAA,EAAU,0NAAA;AAAA,cAET,QAAA,EAAA;AAAA,gBAAA,IAAA,CAAK,uBAAO,GAAA,CAAC,IAAA,CAAK,MAAL,EAAU,aAAA,EAAW,MAAC,CAAA,GAAK,IAAA;AAAA,gBACxC,IAAA,CAAK;AAAA;AAAA,aAAA;AAAA,YAPD,IAAA,CAAK;AAAA,WAQZ,mBAEA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,MAAM,IAAA,CAAK,IAAA;AAAA,cACX,QAAQ,IAAA,CAAK,MAAA;AAAA,cACb,OAAO,IAAA,CAAK,IAAA;AAAA,cACZ,QAAA,EAAU,MAAM,IAAA,CAAK,QAAA,IAAW;AAAA,cAE/B,QAAA,EAAA,IAAA,CAAK;AAAA,aAAA;AAAA,YAND,IAAA,CAAK;AAAA;AAOZ;AAEJ;AAAA;AACF,GAAA,EACF,CAAA;AAEJ","file":"chunk-WZSAUESL.js","sourcesContent":["import * as React from 'react'\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { MenuContent, MenuItem } from '../menu/Menu'\n\nexport interface ContextMenuItem {\n key: string\n label: string\n icon?: LucideIcon\n onSelect?: () => void\n danger?: boolean\n disabled?: boolean\n hint?: string\n}\n\nexport interface ContextMenuProps {\n x: number\n y: number\n items: ContextMenuItem[]\n onClose: () => void\n className?: string\n}\n\nexport function ContextMenu({ x, y, items, onClose, className }: ContextMenuProps) {\n const open = items.length > 0\n return (\n <DropdownMenuPrimitive.Root open={open} onOpenChange={(next) => !next && onClose()} modal={false}>\n <DropdownMenuPrimitive.Trigger asChild aria-hidden tabIndex={-1}>\n <span\n data-as=\"context-menu-anchor\"\n style={{ position: 'fixed', left: x, top: y, width: 0, height: 0 }}\n />\n </DropdownMenuPrimitive.Trigger>\n <MenuContent\n align=\"start\"\n sideOffset={2}\n collisionPadding={8}\n data-as=\"context-menu\"\n onCloseAutoFocus={(event) => event.preventDefault()}\n className={cn('min-w-40', className)}\n >\n {items.map((item) =>\n item.disabled === true ? (\n <span\n key={item.key}\n role=\"menuitem\"\n aria-disabled=\"true\"\n title={item.hint}\n className=\"pointer-events-none flex w-full cursor-default select-none items-center gap-2 rounded-[calc(var(--as-radius-sm)-2px)] px-2 py-1.5 text-left text-sm text-[var(--as-muted-fg)] opacity-50 [&_svg]:size-4 [&_svg]:shrink-0\"\n >\n {item.icon ? <item.icon aria-hidden /> : null}\n {item.label}\n </span>\n ) : (\n <MenuItem\n key={item.key}\n icon={item.icon}\n danger={item.danger}\n title={item.hint}\n onSelect={() => item.onSelect?.()}\n >\n {item.label}\n </MenuItem>\n ),\n )}\n </MenuContent>\n </DropdownMenuPrimitive.Root>\n )\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Minus, Check } from 'lucide-react';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var CheckIndicator = React.forwardRef(
|
|
7
|
+
function CheckIndicator2({ checked, label, onToggle, mixed = false, className }, ref) {
|
|
8
|
+
return /* @__PURE__ */ jsx(
|
|
9
|
+
"button",
|
|
10
|
+
{
|
|
11
|
+
ref,
|
|
12
|
+
type: "button",
|
|
13
|
+
role: "checkbox",
|
|
14
|
+
"data-as": "check-indicator",
|
|
15
|
+
"aria-checked": mixed ? "mixed" : checked,
|
|
16
|
+
"aria-label": label,
|
|
17
|
+
onClick: (event) => {
|
|
18
|
+
event.stopPropagation();
|
|
19
|
+
onToggle();
|
|
20
|
+
},
|
|
21
|
+
className: cn(
|
|
22
|
+
"flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-[calc(var(--as-radius-sm)-2px)] transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]",
|
|
23
|
+
checked || mixed ? "bg-[var(--as-primary)] text-[var(--as-primary-fg)]" : "border border-[var(--as-border)] text-[var(--as-muted-fg)] hover:border-[var(--as-fg)]/40",
|
|
24
|
+
className
|
|
25
|
+
),
|
|
26
|
+
children: mixed ? /* @__PURE__ */ jsx(Minus, { className: "size-3", "aria-hidden": true }) : checked ? /* @__PURE__ */ jsx(Check, { className: "size-3", "aria-hidden": true }) : null
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export { CheckIndicator };
|
|
33
|
+
//# sourceMappingURL=chunk-XE4TFW63.js.map
|
|
34
|
+
//# sourceMappingURL=chunk-XE4TFW63.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/check-indicator/CheckIndicator.tsx"],"names":["CheckIndicator"],"mappings":";;;;;AAYO,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA;AAAA,EAClC,SAASA,eAAAA,CAAe,EAAE,OAAA,EAAS,KAAA,EAAO,UAAU,KAAA,GAAQ,KAAA,EAAO,SAAA,EAAU,EAAG,GAAA,EAAK;AACnF,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,IAAA,EAAK,UAAA;AAAA,QACL,SAAA,EAAQ,iBAAA;AAAA,QACR,cAAA,EAAc,QAAQ,OAAA,GAAU,OAAA;AAAA,QAChC,YAAA,EAAY,KAAA;AAAA,QACZ,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,UAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,UAAA,QAAA,EAAS;AAAA,QACX,CAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,+NAAA;AAAA,UACA,OAAA,IAAW,QACP,oDAAA,GACA,2FAAA;AAAA,UACJ;AAAA,SACF;AAAA,QAEC,QAAA,EAAA,KAAA,mBACC,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,UAAS,aAAA,EAAW,IAAA,EAAC,CAAA,GACpC,OAAA,uBACD,KAAA,EAAA,EAAM,SAAA,EAAU,QAAA,EAAS,aAAA,EAAW,MAAC,CAAA,GACpC;AAAA;AAAA,KACN;AAAA,EAEJ;AACF","file":"chunk-XE4TFW63.js","sourcesContent":["import * as React from 'react'\nimport { Check, Minus } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface CheckIndicatorProps {\n checked: boolean\n label: string\n onToggle: () => void\n mixed?: boolean\n className?: string\n}\n\nexport const CheckIndicator = React.forwardRef<HTMLButtonElement, CheckIndicatorProps>(\n function CheckIndicator({ checked, label, onToggle, mixed = false, className }, ref) {\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"checkbox\"\n data-as=\"check-indicator\"\n aria-checked={mixed ? 'mixed' : checked}\n aria-label={label}\n onClick={(event) => {\n event.stopPropagation()\n onToggle()\n }}\n className={cn(\n 'flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-[calc(var(--as-radius-sm)-2px)] transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n checked || mixed\n ? 'bg-[var(--as-primary)] text-[var(--as-primary-fg)]'\n : 'border border-[var(--as-border)] text-[var(--as-muted-fg)] hover:border-[var(--as-fg)]/40',\n className,\n )}\n >\n {mixed ? (\n <Minus className=\"size-3\" aria-hidden />\n ) : checked ? (\n <Check className=\"size-3\" aria-hidden />\n ) : null}\n </button>\n )\n },\n)\n"]}
|