@seedgrid/fe-components 2026.3.1 → 2026.3.2-2
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/digits/roller3d-digit/SgRoller3DDigit.d.ts +9 -7
- package/dist/digits/roller3d-digit/SgRoller3DDigit.d.ts.map +1 -1
- package/dist/digits/roller3d-digit/SgRoller3DDigit.js +6 -6
- package/dist/gadgets/qr-code/SgQRCode.d.ts.map +1 -1
- package/dist/gadgets/qr-code/SgQRCode.js +22 -48
- package/dist/layout/SgMenu.d.ts +1 -0
- package/dist/layout/SgMenu.d.ts.map +1 -1
- package/dist/layout/SgMenu.js +120 -13
- package/dist/layout/SgPageControl.d.ts +1 -0
- package/dist/layout/SgPageControl.d.ts.map +1 -1
- package/dist/layout/SgPageControl.js +1 -1
- package/dist/others/SgPlayground.d.ts.map +1 -1
- package/dist/others/SgPlayground.js +44 -9
- package/package.json +2 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type SgRoller3DDigitProps = {
|
|
2
|
-
/** Current value to display
|
|
2
|
+
/** Current value to display — must be present in `items` */
|
|
3
3
|
value: string;
|
|
4
4
|
/**
|
|
5
5
|
* Ordered list of all possible values this roller can show.
|
|
@@ -7,31 +7,33 @@ export type SgRoller3DDigitProps = {
|
|
|
7
7
|
* @default ["0","1","2","3","4","5","6","7","8","9"]
|
|
8
8
|
*/
|
|
9
9
|
items?: string[];
|
|
10
|
-
/** Font size in pixels
|
|
10
|
+
/** Font size in pixels — controls overall scale */
|
|
11
11
|
fontSize?: number;
|
|
12
|
+
/** Transition duration in milliseconds */
|
|
13
|
+
transitionMs?: number;
|
|
12
14
|
/** Additional CSS classes on the outer wrapper */
|
|
13
15
|
className?: string;
|
|
14
16
|
};
|
|
15
17
|
/**
|
|
16
|
-
* SgRoller3DDigit
|
|
18
|
+
* SgRoller3DDigit — a vertical drum/roller that animates between values.
|
|
17
19
|
*
|
|
18
20
|
* Renders a scrolling strip of items and smoothly transitions to the
|
|
19
21
|
* position of `value` in the `items` list using a CSS transform.
|
|
20
22
|
* Works with digits, letters, padded numbers or any custom strings.
|
|
21
23
|
*
|
|
22
24
|
* @example
|
|
23
|
-
* // Digit roller (default 0
|
|
25
|
+
* // Digit roller (default 0–9)
|
|
24
26
|
* <SgRoller3DDigit value="7" fontSize={32} />
|
|
25
27
|
*
|
|
26
28
|
* @example
|
|
27
|
-
* // Padded time roller (e.g. minutes 00
|
|
29
|
+
* // Padded time roller (e.g. minutes 00–59)
|
|
28
30
|
* const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, "0"));
|
|
29
31
|
* <SgRoller3DDigit value="42" items={MINUTES} fontSize={22} />
|
|
30
32
|
*
|
|
31
33
|
* @example
|
|
32
|
-
* // Letter roller (A
|
|
34
|
+
* // Letter roller (A–Z) — animate names character by character
|
|
33
35
|
* const ALPHA = Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
34
36
|
* <SgRoller3DDigit value="M" items={ALPHA} fontSize={32} />
|
|
35
37
|
*/
|
|
36
|
-
export declare function SgRoller3DDigit({ value, items, fontSize, className, }: SgRoller3DDigitProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare function SgRoller3DDigit({ value, items, fontSize, transitionMs, className, }: SgRoller3DDigitProps): import("react/jsx-runtime").JSX.Element;
|
|
37
39
|
//# sourceMappingURL=SgRoller3DDigit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgRoller3DDigit.d.ts","sourceRoot":"","sources":["../../../src/digits/roller3d-digit/SgRoller3DDigit.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC,
|
|
1
|
+
{"version":3,"file":"SgRoller3DDigit.d.ts","sourceRoot":"","sources":["../../../src/digits/roller3d-digit/SgRoller3DDigit.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG;IACjC,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAqB,EACrB,QAAa,EACb,YAAkB,EAClB,SAAS,GACV,EAAE,oBAAoB,2CAoDtB"}
|
|
@@ -4,27 +4,27 @@ function cn(...parts) {
|
|
|
4
4
|
}
|
|
5
5
|
const DEFAULT_ITEMS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
6
6
|
/**
|
|
7
|
-
* SgRoller3DDigit
|
|
7
|
+
* SgRoller3DDigit — a vertical drum/roller that animates between values.
|
|
8
8
|
*
|
|
9
9
|
* Renders a scrolling strip of items and smoothly transitions to the
|
|
10
10
|
* position of `value` in the `items` list using a CSS transform.
|
|
11
11
|
* Works with digits, letters, padded numbers or any custom strings.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
|
-
* // Digit roller (default 0
|
|
14
|
+
* // Digit roller (default 0–9)
|
|
15
15
|
* <SgRoller3DDigit value="7" fontSize={32} />
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
|
-
* // Padded time roller (e.g. minutes 00
|
|
18
|
+
* // Padded time roller (e.g. minutes 00–59)
|
|
19
19
|
* const MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, "0"));
|
|
20
20
|
* <SgRoller3DDigit value="42" items={MINUTES} fontSize={22} />
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
|
-
* // Letter roller (A
|
|
23
|
+
* // Letter roller (A–Z) — animate names character by character
|
|
24
24
|
* const ALPHA = Array.from("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
|
25
25
|
* <SgRoller3DDigit value="M" items={ALPHA} fontSize={32} />
|
|
26
26
|
*/
|
|
27
|
-
export function SgRoller3DDigit({ value, items = DEFAULT_ITEMS, fontSize = 32, className, }) {
|
|
27
|
+
export function SgRoller3DDigit({ value, items = DEFAULT_ITEMS, fontSize = 32, transitionMs = 500, className, }) {
|
|
28
28
|
const idx = Math.max(0, items.indexOf(value));
|
|
29
29
|
// Dimensions are derived from fontSize so the component scales uniformly.
|
|
30
30
|
// The ratios match the original SgClock roller3d proportions exactly when
|
|
@@ -38,7 +38,7 @@ export function SgRoller3DDigit({ value, items = DEFAULT_ITEMS, fontSize = 32, c
|
|
|
38
38
|
// top fade
|
|
39
39
|
"before:absolute before:inset-0 before:z-10 before:bg-gradient-to-b before:from-black/[0.06] before:to-transparent before:content-['']",
|
|
40
40
|
// bottom fade
|
|
41
|
-
"after:absolute after:inset-0 after:z-10 after:bg-gradient-to-t after:from-black/[0.12] after:to-transparent after:content-['']", className), style: { width: w, height: h }, children: [_jsx("div", { className: "absolute left-0 right-0 top-1/2 z-20 h-px bg-red-500/70" }), _jsx("div", { className: "absolute left-0 top-0 w-full transition-transform
|
|
41
|
+
"after:absolute after:inset-0 after:z-10 after:bg-gradient-to-t after:from-black/[0.12] after:to-transparent after:content-['']", className), style: { width: w, height: h }, children: [_jsx("div", { className: "absolute left-0 right-0 top-1/2 z-20 h-px bg-red-500/70" }), _jsx("div", { className: "absolute left-0 top-0 w-full transition-transform [transition-timing-function:cubic-bezier(0.22,1,0.36,1)] [mask-image:linear-gradient(to_bottom,transparent,black_22%,black_78%,transparent)]", style: { transform: `translateY(${translateY}px)`, transitionDuration: `${transitionMs}ms` }, children: items.map((item, i) => (_jsx("div", { className: "flex select-none items-center justify-center font-medium tabular-nums", style: {
|
|
42
42
|
height: itemH,
|
|
43
43
|
fontSize,
|
|
44
44
|
lineHeight: 1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgQRCode.d.ts","sourceRoot":"","sources":["../../../src/gadgets/qr-code/SgQRCode.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SgQRCode.d.ts","sourceRoot":"","sources":["../../../src/gadgets/qr-code/SgQRCode.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAyC/B,MAAM,MAAM,4BAA4B,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,4BAA4B,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,kDA8FtD;yBA9Fe,QAAQ"}
|
|
@@ -1,70 +1,44 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import
|
|
4
|
+
import { QRCodeSVG } from "qrcode.react";
|
|
5
5
|
function cn(...parts) {
|
|
6
6
|
return parts.filter(Boolean).join(" ");
|
|
7
7
|
}
|
|
8
|
+
class QrErrorBoundary extends React.Component {
|
|
9
|
+
state = { hasError: false };
|
|
10
|
+
static getDerivedStateFromError() {
|
|
11
|
+
return { hasError: true };
|
|
12
|
+
}
|
|
13
|
+
componentDidCatch(error) {
|
|
14
|
+
this.props.onError?.(error);
|
|
15
|
+
}
|
|
16
|
+
componentDidUpdate(prevProps) {
|
|
17
|
+
if (prevProps.resetKey !== this.props.resetKey && this.state.hasError) {
|
|
18
|
+
this.setState({ hasError: false });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
render() {
|
|
22
|
+
if (this.state.hasError)
|
|
23
|
+
return this.props.fallback;
|
|
24
|
+
return this.props.children;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
8
27
|
export function SgQRCode(props) {
|
|
9
28
|
const { value, size = 220, margin = 2, fgColor = "#000000", bgColor = "#FFFFFF", errorCorrectionLevel = "H", logoSrc, logoAlt = "Logo", logoSize, logoPadding = 6, logoBackgroundColor = "#FFFFFF", logoBorderRadius = 12, imageClassName, logoClassName, emptyFallback, onGenerateError, className, style, ...rest } = props;
|
|
10
|
-
const [qrDataUrl, setQrDataUrl] = React.useState("");
|
|
11
|
-
const [hasError, setHasError] = React.useState(false);
|
|
12
29
|
const normalizedValue = value?.trim() ?? "";
|
|
13
30
|
const safeSize = Math.max(64, Math.round(size));
|
|
14
31
|
const safeMargin = Math.max(0, Math.round(margin));
|
|
15
32
|
const safeLogoPadding = Math.max(0, Math.round(logoPadding));
|
|
16
33
|
const safeLogoSize = Math.max(18, Math.min(safeSize, Math.round(logoSize ?? safeSize * 0.22)));
|
|
17
34
|
const logoContainerSize = safeLogoSize + safeLogoPadding * 2;
|
|
18
|
-
|
|
19
|
-
let active = true;
|
|
20
|
-
if (!normalizedValue) {
|
|
21
|
-
setQrDataUrl("");
|
|
22
|
-
setHasError(false);
|
|
23
|
-
return () => {
|
|
24
|
-
active = false;
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
QRCode.toDataURL(normalizedValue, {
|
|
28
|
-
width: safeSize,
|
|
29
|
-
margin: safeMargin,
|
|
30
|
-
color: {
|
|
31
|
-
dark: fgColor,
|
|
32
|
-
light: bgColor
|
|
33
|
-
},
|
|
34
|
-
errorCorrectionLevel
|
|
35
|
-
})
|
|
36
|
-
.then((dataUrl) => {
|
|
37
|
-
if (!active)
|
|
38
|
-
return;
|
|
39
|
-
setQrDataUrl(dataUrl);
|
|
40
|
-
setHasError(false);
|
|
41
|
-
})
|
|
42
|
-
.catch((cause) => {
|
|
43
|
-
if (!active)
|
|
44
|
-
return;
|
|
45
|
-
const error = cause instanceof Error ? cause : new Error("Failed to generate QR code");
|
|
46
|
-
setQrDataUrl("");
|
|
47
|
-
setHasError(true);
|
|
48
|
-
onGenerateError?.(error);
|
|
49
|
-
});
|
|
50
|
-
return () => {
|
|
51
|
-
active = false;
|
|
52
|
-
};
|
|
53
|
-
}, [
|
|
54
|
-
normalizedValue,
|
|
55
|
-
safeSize,
|
|
56
|
-
safeMargin,
|
|
57
|
-
fgColor,
|
|
58
|
-
bgColor,
|
|
59
|
-
errorCorrectionLevel,
|
|
60
|
-
onGenerateError
|
|
61
|
-
]);
|
|
35
|
+
const qrResetKey = `${normalizedValue}|${safeSize}|${safeMargin}|${fgColor}|${bgColor}|${errorCorrectionLevel}`;
|
|
62
36
|
if (!normalizedValue) {
|
|
63
37
|
if (!emptyFallback)
|
|
64
38
|
return null;
|
|
65
39
|
return (_jsx("div", { className: cn("inline-flex items-center justify-center", className), style: { width: safeSize, height: safeSize, ...style }, ...rest, children: emptyFallback }));
|
|
66
40
|
}
|
|
67
|
-
return (_jsxs("div", { className: cn("relative inline-flex items-center justify-center", className), style: { width: safeSize, height: safeSize, ...style }, ...rest, children: [
|
|
41
|
+
return (_jsxs("div", { className: cn("relative inline-flex items-center justify-center", className), style: { width: safeSize, height: safeSize, ...style }, ...rest, children: [_jsx(QrErrorBoundary, { resetKey: qrResetKey, onError: onGenerateError, fallback: _jsx("div", { className: "h-full w-full animate-pulse rounded-md bg-muted/40", "aria-hidden": "true" }), children: _jsx(QRCodeSVG, { value: normalizedValue, size: safeSize, marginSize: safeMargin, fgColor: fgColor, bgColor: bgColor, level: errorCorrectionLevel, title: "QR Code", className: cn("block h-full w-full", imageClassName) }) }), logoSrc ? (_jsx("span", { className: cn("absolute inline-flex items-center justify-center overflow-hidden", logoClassName), style: {
|
|
68
42
|
width: logoContainerSize,
|
|
69
43
|
height: logoContainerSize,
|
|
70
44
|
padding: safeLogoPadding,
|
package/dist/layout/SgMenu.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgMenu.d.ts","sourceRoot":"","sources":["../../src/layout/SgMenu.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SgMenu.d.ts","sourceRoot":"","sources":["../../src/layout/SgMenu.tsx"],"names":[],"mappings":"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"}
|
package/dist/layout/SgMenu.js
CHANGED
|
@@ -290,6 +290,8 @@ export function SgMenu(props) {
|
|
|
290
290
|
const [searchValue, setSearchValue] = React.useState("");
|
|
291
291
|
const menuRootRef = React.useRef(null);
|
|
292
292
|
const sidebarShellRef = React.useRef(null);
|
|
293
|
+
const menuHintAnchorRef = React.useRef(null);
|
|
294
|
+
const [menuHint, setMenuHint] = React.useState(null);
|
|
293
295
|
const [dockDragActive, setDockDragActive] = React.useState(false);
|
|
294
296
|
const [horizontalDockAlign, setHorizontalDockAlign] = React.useState(null);
|
|
295
297
|
const dockDragStartRef = React.useRef(null);
|
|
@@ -326,6 +328,41 @@ export function SgMenu(props) {
|
|
|
326
328
|
const isVerticalDockZone = effectiveDockZone === "left" || effectiveDockZone === "right";
|
|
327
329
|
const tieredOpenToLeft = resolvedPosition === "right" ||
|
|
328
330
|
(isHorizontalDockZone && horizontalDockAlign === "right");
|
|
331
|
+
const hideMenuHint = React.useCallback(() => {
|
|
332
|
+
menuHintAnchorRef.current = null;
|
|
333
|
+
setMenuHint(null);
|
|
334
|
+
}, []);
|
|
335
|
+
const resolveMenuHintPosition = React.useCallback((anchor) => {
|
|
336
|
+
if (!anchor.target.isConnected)
|
|
337
|
+
return null;
|
|
338
|
+
const rect = anchor.target.getBoundingClientRect();
|
|
339
|
+
if (anchor.placement === "right") {
|
|
340
|
+
return {
|
|
341
|
+
x: rect.right + 8,
|
|
342
|
+
y: rect.top + (rect.height / 2)
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
x: rect.left + (rect.width / 2),
|
|
347
|
+
y: rect.top - 8
|
|
348
|
+
};
|
|
349
|
+
}, []);
|
|
350
|
+
const showMenuHint = React.useCallback((target, text, placement = "top") => {
|
|
351
|
+
if (!text)
|
|
352
|
+
return;
|
|
353
|
+
const anchor = { target, text, placement };
|
|
354
|
+
menuHintAnchorRef.current = anchor;
|
|
355
|
+
const nextPosition = resolveMenuHintPosition(anchor);
|
|
356
|
+
if (!nextPosition) {
|
|
357
|
+
hideMenuHint();
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
setMenuHint({
|
|
361
|
+
text: anchor.text,
|
|
362
|
+
placement: anchor.placement,
|
|
363
|
+
...nextPosition
|
|
364
|
+
});
|
|
365
|
+
}, [hideMenuHint, resolveMenuHintPosition]);
|
|
329
366
|
const [localActiveId, setLocalActiveId] = React.useState(selection?.activeId);
|
|
330
367
|
const [tieredPath, setTieredPath] = React.useState([]);
|
|
331
368
|
const [megaActiveId, setMegaActiveId] = React.useState(menu[0]?.id);
|
|
@@ -431,6 +468,40 @@ export function SgMenu(props) {
|
|
|
431
468
|
document.addEventListener("pointerdown", handlePointerDown);
|
|
432
469
|
return () => document.removeEventListener("pointerdown", handlePointerDown);
|
|
433
470
|
}, [effectiveMenuStyle]);
|
|
471
|
+
const hasVisibleMenuHint = menuHint !== null;
|
|
472
|
+
React.useEffect(() => {
|
|
473
|
+
if (!hasVisibleMenuHint || !menuHintAnchorRef.current)
|
|
474
|
+
return;
|
|
475
|
+
const reposition = () => {
|
|
476
|
+
const anchor = menuHintAnchorRef.current;
|
|
477
|
+
if (!anchor)
|
|
478
|
+
return;
|
|
479
|
+
const nextPosition = resolveMenuHintPosition(anchor);
|
|
480
|
+
if (!nextPosition) {
|
|
481
|
+
hideMenuHint();
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
setMenuHint({
|
|
485
|
+
text: anchor.text,
|
|
486
|
+
placement: anchor.placement,
|
|
487
|
+
...nextPosition
|
|
488
|
+
});
|
|
489
|
+
};
|
|
490
|
+
reposition();
|
|
491
|
+
window.addEventListener("scroll", reposition, true);
|
|
492
|
+
window.addEventListener("resize", reposition);
|
|
493
|
+
return () => {
|
|
494
|
+
window.removeEventListener("scroll", reposition, true);
|
|
495
|
+
window.removeEventListener("resize", reposition);
|
|
496
|
+
};
|
|
497
|
+
}, [hasVisibleMenuHint, hideMenuHint, resolveMenuHintPosition]);
|
|
498
|
+
React.useEffect(() => {
|
|
499
|
+
const anchor = menuHintAnchorRef.current;
|
|
500
|
+
if (!anchor)
|
|
501
|
+
return;
|
|
502
|
+
if (!anchor.target.isConnected)
|
|
503
|
+
hideMenuHint();
|
|
504
|
+
}, [filteredMenu, effectiveMenuStyle, isCollapsed, drawerOpen, pinnedState, hideMenuHint]);
|
|
434
505
|
const toggleExpanded = React.useCallback((nodeId) => {
|
|
435
506
|
setExpandedIds((prev) => {
|
|
436
507
|
const next = new Set(prev);
|
|
@@ -454,6 +525,7 @@ export function SgMenu(props) {
|
|
|
454
525
|
const activateNode = React.useCallback((node) => {
|
|
455
526
|
if (node.disabled)
|
|
456
527
|
return;
|
|
528
|
+
hideMenuHint();
|
|
457
529
|
onItemClick?.(node);
|
|
458
530
|
setLocalActiveId(node.id);
|
|
459
531
|
const hasUrl = typeof node.url === "string" && node.url.length > 0;
|
|
@@ -477,7 +549,8 @@ export function SgMenu(props) {
|
|
|
477
549
|
onNavigate,
|
|
478
550
|
pinnedState,
|
|
479
551
|
setDrawerOpen,
|
|
480
|
-
variant
|
|
552
|
+
variant,
|
|
553
|
+
hideMenuHint
|
|
481
554
|
]);
|
|
482
555
|
const handleDockDragPointerDown = React.useCallback((event) => {
|
|
483
556
|
if (event.button !== 0)
|
|
@@ -654,11 +727,15 @@ export function SgMenu(props) {
|
|
|
654
727
|
const disabled = !!node.disabled;
|
|
655
728
|
const iconNode = resolveIcon(node);
|
|
656
729
|
const hideChildren = isCollapsed;
|
|
730
|
+
const nodeHint = node.hint ?? (isCollapsed ? node.label : undefined);
|
|
731
|
+
const nodeHintPlacement = "right";
|
|
657
732
|
return (_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: cn("group flex items-center rounded-md", densityCfg.row, densityCfg.gap, isExactActive
|
|
658
733
|
? "bg-primary/15 text-primary"
|
|
659
734
|
: isBranchActive
|
|
660
735
|
? "bg-muted/60 text-foreground"
|
|
661
|
-
: "text-foreground hover:bg-muted/60", disabled ? "cursor-not-allowed opacity-55" : ""), style: isCollapsed ? undefined : { paddingLeft: 8 + depth * indent },
|
|
736
|
+
: "text-foreground hover:bg-muted/60", disabled ? "cursor-not-allowed opacity-55" : ""), style: isCollapsed ? undefined : { paddingLeft: 8 + depth * indent }, onMouseEnter: nodeHint
|
|
737
|
+
? (event) => showMenuHint(event.currentTarget, nodeHint, nodeHintPlacement)
|
|
738
|
+
: undefined, onMouseLeave: nodeHint ? hideMenuHint : undefined, children: [_jsxs("button", { ref: (el) => {
|
|
662
739
|
itemRefs.current[node.id] = el;
|
|
663
740
|
}, "data-sg-menu-node": node.id, type: "button", "aria-disabled": disabled || undefined, "aria-current": isExactActive ? "page" : undefined, onFocus: () => setFocusedId(node.id), onClick: () => {
|
|
664
741
|
if (disabled)
|
|
@@ -681,6 +758,8 @@ export function SgMenu(props) {
|
|
|
681
758
|
hasSearch,
|
|
682
759
|
indent,
|
|
683
760
|
isCollapsed,
|
|
761
|
+
hideMenuHint,
|
|
762
|
+
showMenuHint,
|
|
684
763
|
toggleExpanded
|
|
685
764
|
]);
|
|
686
765
|
const renderFlatAction = React.useCallback((node, className) => {
|
|
@@ -688,7 +767,7 @@ export function SgMenu(props) {
|
|
|
688
767
|
const isBranchActive = activeSets.branch.has(node.id);
|
|
689
768
|
const hasChildren = !!node.children?.length;
|
|
690
769
|
const iconNode = resolveIcon(node);
|
|
691
|
-
return (_jsxs("button", { type: "button", disabled: node.disabled, "aria-current": isExactActive ? "page" : undefined, onClick: () => {
|
|
770
|
+
return (_jsxs("button", { type: "button", disabled: node.disabled, "aria-current": isExactActive ? "page" : undefined, onMouseEnter: node.hint ? (event) => showMenuHint(event.currentTarget, node.hint) : undefined, onMouseLeave: node.hint ? hideMenuHint : undefined, onClick: () => {
|
|
692
771
|
if (node.disabled)
|
|
693
772
|
return;
|
|
694
773
|
if (hasChildren && !node.url && !node.onClick)
|
|
@@ -699,7 +778,7 @@ export function SgMenu(props) {
|
|
|
699
778
|
: isBranchActive
|
|
700
779
|
? "bg-muted/60 text-foreground"
|
|
701
780
|
: "text-foreground hover:bg-muted/60", node.disabled ? "cursor-not-allowed opacity-55" : "", className), children: [_jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center rounded", densityCfg.icon, iconNode ? "" : "bg-muted text-[10px] font-semibold"), children: iconNode ?? firstChars(node.label, 1) }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: node.label }), hasChildren ? _jsx(ChevronRight, { className: "size-4 shrink-0 text-muted-foreground" }) : null] }, node.id));
|
|
702
|
-
}, [activateNode, activeSets.branch, activeSets.exact, densityCfg.icon]);
|
|
781
|
+
}, [activateNode, activeSets.branch, activeSets.exact, densityCfg.icon, hideMenuHint, showMenuHint]);
|
|
703
782
|
const renderTieredLevels = React.useCallback((nodes, depth) => {
|
|
704
783
|
if (!nodes.length)
|
|
705
784
|
return null;
|
|
@@ -712,7 +791,9 @@ export function SgMenu(props) {
|
|
|
712
791
|
const isOpen = activeIdAtDepth === node.id;
|
|
713
792
|
const isExactActive = activeSets.exact.has(node.id);
|
|
714
793
|
const iconNode = resolveIcon(node);
|
|
715
|
-
return (_jsxs("button", { type: "button", disabled: node.disabled, "aria-current": isExactActive ? "page" : undefined, onMouseEnter: () => {
|
|
794
|
+
return (_jsxs("button", { type: "button", disabled: node.disabled, "aria-current": isExactActive ? "page" : undefined, onMouseEnter: (event) => {
|
|
795
|
+
if (node.hint)
|
|
796
|
+
showMenuHint(event.currentTarget, node.hint);
|
|
716
797
|
if (!openSubmenuOnHover)
|
|
717
798
|
return;
|
|
718
799
|
if (!hasChildren) {
|
|
@@ -720,7 +801,7 @@ export function SgMenu(props) {
|
|
|
720
801
|
return;
|
|
721
802
|
}
|
|
722
803
|
setTieredPath((prev) => [...prev.slice(0, depth), node.id]);
|
|
723
|
-
}, onClick: () => {
|
|
804
|
+
}, onMouseLeave: node.hint ? hideMenuHint : undefined, onClick: () => {
|
|
724
805
|
if (node.disabled)
|
|
725
806
|
return;
|
|
726
807
|
if (hasChildren) {
|
|
@@ -739,7 +820,16 @@ export function SgMenu(props) {
|
|
|
739
820
|
}) }), activeNode?.children?.length
|
|
740
821
|
? renderTieredLevels(activeNode.children, depth + 1)
|
|
741
822
|
: null] }));
|
|
742
|
-
}, [
|
|
823
|
+
}, [
|
|
824
|
+
activateNode,
|
|
825
|
+
activeSets.exact,
|
|
826
|
+
densityCfg.icon,
|
|
827
|
+
hideMenuHint,
|
|
828
|
+
openSubmenuOnHover,
|
|
829
|
+
showMenuHint,
|
|
830
|
+
tieredOpenToLeft,
|
|
831
|
+
tieredPath
|
|
832
|
+
]);
|
|
743
833
|
const renderMegaColumns = React.useCallback((nodes) => {
|
|
744
834
|
if (!nodes.length) {
|
|
745
835
|
return _jsx("div", { className: "text-sm text-muted-foreground", children: "No items found." });
|
|
@@ -763,7 +853,12 @@ export function SgMenu(props) {
|
|
|
763
853
|
const hasChildren = !!node.children?.length;
|
|
764
854
|
const active = activeMegaNode?.id === node.id;
|
|
765
855
|
const iconNode = resolveIcon(node);
|
|
766
|
-
return (_jsxs("button", { type: "button", disabled: node.disabled, onMouseEnter: () =>
|
|
856
|
+
return (_jsxs("button", { type: "button", disabled: node.disabled, onMouseEnter: (event) => {
|
|
857
|
+
if (node.hint)
|
|
858
|
+
showMenuHint(event.currentTarget, node.hint);
|
|
859
|
+
if (hasChildren)
|
|
860
|
+
setMegaActiveId(node.id);
|
|
861
|
+
}, onMouseLeave: node.hint ? hideMenuHint : undefined, onClick: () => {
|
|
767
862
|
if (node.disabled)
|
|
768
863
|
return;
|
|
769
864
|
if (hasChildren) {
|
|
@@ -778,7 +873,12 @@ export function SgMenu(props) {
|
|
|
778
873
|
const hasChildren = !!node.children?.length;
|
|
779
874
|
const active = activeMegaNode?.id === node.id;
|
|
780
875
|
const iconNode = resolveIcon(node);
|
|
781
|
-
return (_jsxs("button", { type: "button", disabled: node.disabled, onMouseEnter: () =>
|
|
876
|
+
return (_jsxs("button", { type: "button", disabled: node.disabled, onMouseEnter: (event) => {
|
|
877
|
+
if (node.hint)
|
|
878
|
+
showMenuHint(event.currentTarget, node.hint);
|
|
879
|
+
if (hasChildren)
|
|
880
|
+
setMegaActiveId(node.id);
|
|
881
|
+
}, onMouseLeave: node.hint ? hideMenuHint : undefined, onClick: () => {
|
|
782
882
|
if (node.disabled)
|
|
783
883
|
return;
|
|
784
884
|
if (hasChildren) {
|
|
@@ -896,11 +996,18 @@ export function SgMenu(props) {
|
|
|
896
996
|
: undefined,
|
|
897
997
|
...style
|
|
898
998
|
}, children: [shellHeaderRow, !isCollapsed ? (_jsx("div", { className: cn("absolute z-50 flex flex-col bg-background text-foreground", effectiveMenuStyle === "tiered" ? "overflow-visible" : "overflow-auto", effectiveDockZone === "bottom" ? "bottom-full" : "top-full", horizontalDockAlign === "right" ? "right-0" : "left-0", "min-w-[240px]", effectiveMenuStyle !== "tiered" ? "max-h-[60vh]" : "", "border border-border", elevationClass(elevation === "none" ? "sm" : elevation)), children: shellContentArea })) : null] })) : (sidebarShell);
|
|
999
|
+
const menuHintNode = menuHint && typeof document !== "undefined"
|
|
1000
|
+
? createPortal(_jsx("span", { className: "pointer-events-none fixed z-[1200] max-w-[min(28rem,calc(100vw-24px))] rounded bg-foreground/90 px-2 py-1 text-[11px] text-background shadow-md whitespace-normal break-words", style: {
|
|
1001
|
+
left: menuHint.x,
|
|
1002
|
+
top: menuHint.y,
|
|
1003
|
+
transform: menuHint.placement === "right" ? "translateY(-50%)" : "translate(-50%, -100%)"
|
|
1004
|
+
}, children: menuHint.text }), document.body)
|
|
1005
|
+
: null;
|
|
899
1006
|
if (dockMode && portalTarget) {
|
|
900
|
-
return createPortal(shellForRender, portalTarget);
|
|
1007
|
+
return (_jsxs(_Fragment, { children: [createPortal(shellForRender, portalTarget), menuHintNode] }));
|
|
901
1008
|
}
|
|
902
1009
|
if (variant === "drawer") {
|
|
903
|
-
return (_jsx(SgExpandablePanel, { mode: "overlay", open: drawerOpen, onOpenChange: setDrawerOpen, expandTo: resolvedPosition === "left" ? "right" : "left", placement: "start", size: resolvedOverlaySize, animation: { type: "slide", durationMs: 180 }, border: border, elevation: elevation === "md" ? "lg" : elevation, rounded: "none", closeOnOutsideClick: !pinnedState, closeOnEsc: !pinnedState, trapFocus: true, showBackdrop: overlayBackdropResolved, ariaLabel: ariaLabel, role: "dialog", className: className, style: style, children: shellBody }));
|
|
1010
|
+
return (_jsxs(_Fragment, { children: [_jsx(SgExpandablePanel, { mode: "overlay", open: drawerOpen, onOpenChange: setDrawerOpen, expandTo: resolvedPosition === "left" ? "right" : "left", placement: "start", size: resolvedOverlaySize, animation: { type: "slide", durationMs: 180 }, border: border, elevation: elevation === "md" ? "lg" : elevation, rounded: "none", closeOnOutsideClick: !pinnedState, closeOnEsc: !pinnedState, trapFocus: true, showBackdrop: overlayBackdropResolved, ariaLabel: ariaLabel, role: "dialog", className: className, style: style, children: shellBody }), menuHintNode] }));
|
|
904
1011
|
}
|
|
905
1012
|
if (variant === "hybrid") {
|
|
906
1013
|
return (_jsxs(_Fragment, { children: [shellForRender, !pinnedState ? (_jsx(SgExpandablePanel, { mode: "overlay", open: drawerOpen, onOpenChange: setDrawerOpen, expandTo: resolvedPosition === "left" ? "right" : "left", placement: "start", size: resolvedOverlaySize, animation: { type: "slide", durationMs: 180 }, border: border, elevation: elevation === "md" ? "lg" : elevation, rounded: "none", closeOnOutsideClick: true, closeOnEsc: true, trapFocus: true, showBackdrop: overlayBackdropResolved, ariaLabel: ariaLabel, role: "dialog", children: _jsx(SgMenu, { menu: menu, selection: { activeId: effectiveActiveId, activeUrl: effectiveActiveUrl }, brand: brand, user: user, userMenu: userMenu, variant: "inline", menuStyle: menuStyle, position: position, density: density, indent: indent, collapsed: false, collapsedWidth: collapsedWidth, expandedWidth: expandedWidth, mode: mode, expandedIds: expandedIds, onExpandedIdsChange: setExpandedIds, showCollapseButton: false, showPinButton: showPinButton, pinned: pinnedState, onPinnedChange: (next) => {
|
|
@@ -918,9 +1025,9 @@ export function SgMenu(props) {
|
|
|
918
1025
|
}, onAction: onAction, onItemClick: (node) => {
|
|
919
1026
|
setLocalActiveId(node.id);
|
|
920
1027
|
onItemClick?.(node);
|
|
921
|
-
}, ariaLabel: ariaLabel, keyboardNavigation: keyboardNavigation, openSubmenuOnHover: openSubmenuOnHover, search: search, elevation: "none", border: false, footer: footer }) })) : null] }));
|
|
1028
|
+
}, ariaLabel: ariaLabel, keyboardNavigation: keyboardNavigation, openSubmenuOnHover: openSubmenuOnHover, search: search, elevation: "none", border: false, footer: footer }) })) : null, menuHintNode] }));
|
|
922
1029
|
}
|
|
923
|
-
return shellForRender;
|
|
1030
|
+
return (_jsxs(_Fragment, { children: [shellForRender, menuHintNode] }));
|
|
924
1031
|
}
|
|
925
1032
|
SgMenu.displayName = "SgMenu";
|
|
926
1033
|
function CollapseIcon(props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgPageControl.d.ts","sourceRoot":"","sources":["../../src/layout/SgPageControl.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,sBAAsB,CAAA;KAAE,KACrD,IAAI,CAAC;IACV,mBAAmB,CAAC,EAAE,CACpB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,sBAAsB,CAAA;KAAE,KACtD,IAAI,CAAC;IAEV,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAiCF,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"SgPageControl.d.ts","sourceRoot":"","sources":["../../src/layout/SgPageControl.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,sBAAsB,CAAA;KAAE,KACrD,IAAI,CAAC;IACV,mBAAmB,CAAC,EAAE,CACpB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,sBAAsB,CAAA;KAAE,KACtD,IAAI,CAAC;IAEV,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,CAAC;AAiCF,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,kBAAkB,CAAC,2CAiQhE;yBAjQe,aAAa;;;AAqQ7B,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,2CAExE;yBAFe,iBAAiB"}
|
|
@@ -137,7 +137,7 @@ export function SgPageControl(props) {
|
|
|
137
137
|
const panelId = `${rootId}-panel-${record.id}`;
|
|
138
138
|
return (_jsxs("button", { ref: (el) => {
|
|
139
139
|
tabsRef.current[index] = el;
|
|
140
|
-
}, type: "button", id: tabId, role: "tab", "aria-controls": panelId, "aria-selected": isActive, tabIndex: isActive ? 0 : -1, disabled: record.props.disabled, onClick: () => selectPage(record.id), className: cn("inline-flex shrink-0 items-center justify-center whitespace-nowrap font-medium transition-colors", sizeClasses.tab, tabStyle.base, isActive ? tabStyle.active : tabStyle.inactive, fullWidthTabs ? "w-full" : "", record.props.disabled ? "cursor-not-allowed opacity-45" : "", tabClassName, record.props.tabClassName), children: [record.props.icon ? (_jsx("span", { className: cn("inline-flex items-center justify-center", sizeClasses.icon), children: record.props.icon })) : null, _jsx("span", { className: "truncate", children: record.props.title })] }, record.id));
|
|
140
|
+
}, type: "button", id: tabId, role: "tab", "aria-controls": panelId, "aria-selected": isActive, tabIndex: isActive ? 0 : -1, title: record.props.hint, disabled: record.props.disabled, onClick: () => selectPage(record.id), className: cn("inline-flex shrink-0 items-center justify-center whitespace-nowrap font-medium transition-colors", sizeClasses.tab, tabStyle.base, isActive ? tabStyle.active : tabStyle.inactive, fullWidthTabs ? "w-full" : "", record.props.disabled ? "cursor-not-allowed opacity-45" : "", tabClassName, record.props.tabClassName), children: [record.props.icon ? (_jsx("span", { className: cn("inline-flex items-center justify-center", sizeClasses.icon), children: record.props.icon })) : null, _jsx("span", { className: "truncate", children: record.props.title })] }, record.id));
|
|
141
141
|
}) }), _jsx("div", { className: cn("rounded-b-md border border-t-0 border-border bg-background", panelClassName), children: visiblePages.length === 0 ? (_jsx("div", { className: cn(sizeClasses.panel, "text-sm text-muted-foreground"), children: emptyMessage })) : keepMounted ? (visiblePages.map((record) => {
|
|
142
142
|
const isActive = record.id === resolvedActiveId;
|
|
143
143
|
const tabId = `${rootId}-tab-${record.id}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgPlayground.d.ts","sourceRoot":"","sources":["../../src/others/SgPlayground.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"SgPlayground.d.ts","sourceRoot":"","sources":["../../src/others/SgPlayground.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAsXF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,iBAAiB,CAAC,2CAoOtE"}
|
|
@@ -7,7 +7,7 @@ import { SgCard } from "../layout/SgCard";
|
|
|
7
7
|
function cn(...parts) {
|
|
8
8
|
return parts.filter(Boolean).join(" ");
|
|
9
9
|
}
|
|
10
|
-
const DEFAULT_SEEDGRID_DEPENDENCY = "
|
|
10
|
+
const DEFAULT_SEEDGRID_DEPENDENCY = "latest";
|
|
11
11
|
const DEFAULT_SEEDGRID_PEER_DEPENDENCIES = {
|
|
12
12
|
"@codesandbox/sandpack-react": "^2.20.0",
|
|
13
13
|
"react-hook-form": "^7.0.0",
|
|
@@ -29,6 +29,30 @@ const SANDPACK_EXTERNAL_RESOURCES = [
|
|
|
29
29
|
// Prebuilt utility CSS so classes from @seedgrid/fe-components can render inside Sandpack
|
|
30
30
|
"https://unpkg.com/tailwindcss@2.2.19/dist/tailwind.min.css"
|
|
31
31
|
];
|
|
32
|
+
const SANDPACK_QRCODE_SHIM_PACKAGE_JSON = `{
|
|
33
|
+
"name": "qrcode",
|
|
34
|
+
"version": "0.0.0-sandpack-shim",
|
|
35
|
+
"type": "module",
|
|
36
|
+
"main": "./index.js",
|
|
37
|
+
"module": "./index.js",
|
|
38
|
+
"exports": {
|
|
39
|
+
".": "./index.js"
|
|
40
|
+
}
|
|
41
|
+
}`;
|
|
42
|
+
const SANDPACK_QRCODE_SHIM_INDEX_JS = `const makeError = () =>
|
|
43
|
+
new Error(
|
|
44
|
+
"qrcode (node build) is not supported in Sandpack browser runtime. Update @seedgrid/fe-components to a browser-safe QR implementation."
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const qrcodeShim = {
|
|
48
|
+
toDataURL() {
|
|
49
|
+
return Promise.reject(makeError());
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const toDataURL = (...args) => qrcodeShim.toDataURL(...args);
|
|
54
|
+
export default qrcodeShim;
|
|
55
|
+
`;
|
|
32
56
|
const SANDPACK_FALLBACK_THEME_VARS = {
|
|
33
57
|
"--background": "0 0% 100%",
|
|
34
58
|
"--foreground": "222.2 84% 4.9%",
|
|
@@ -301,15 +325,19 @@ function CopyButton() {
|
|
|
301
325
|
}, [copyState]);
|
|
302
326
|
return (_jsx(SgButton, { appearance: "outline", size: "sm", onClick: handleCopy, children: copyState === "success" ? "Copiado" : copyState === "error" ? "Erro" : "Copiar" }));
|
|
303
327
|
}
|
|
304
|
-
function RunButton() {
|
|
328
|
+
function RunButton({ onRun }) {
|
|
305
329
|
const { sandpack } = useSandpack();
|
|
306
|
-
return (_jsx(SgButton, { severity: "primary", size: "sm", onClick: () =>
|
|
330
|
+
return (_jsx(SgButton, { severity: "primary", size: "sm", onClick: () => {
|
|
331
|
+
sandpack.runSandpack();
|
|
332
|
+
onRun?.();
|
|
333
|
+
}, children: "Run" }));
|
|
307
334
|
}
|
|
308
335
|
export default function SgPlayground(props) {
|
|
309
336
|
const { code, interactive = false, codeContract = "renderBody", title, description, height = 360, expandedHeight = "70vh", expandable = true, resizable = true, resizeAxis = "vertical", previewPadding, className, dependencies, defaultImports, previewWrapperClassName = "h-[420px] rounded-xl border border-border bg-muted/30 p-3", seedgridDependency, withCard = true, collapsible = true, defaultOpen = true, cardId } = props;
|
|
310
337
|
const effectivePreviewPadding = normalizeCssSize(previewPadding ?? (codeContract === "appFile" ? 12 : 0));
|
|
311
|
-
const [sandpackStylesCss, setSandpackStylesCss] = React.useState(() => buildSandpackStylesCss(
|
|
338
|
+
const [sandpackStylesCss, setSandpackStylesCss] = React.useState(() => buildSandpackStylesCss({}, effectivePreviewPadding));
|
|
312
339
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
340
|
+
const [activePanel, setActivePanel] = React.useState("code");
|
|
313
341
|
React.useEffect(() => {
|
|
314
342
|
if (typeof window === "undefined")
|
|
315
343
|
return;
|
|
@@ -357,7 +385,10 @@ export default function SgPlayground(props) {
|
|
|
357
385
|
DEFAULT_SEEDGRID_DEPENDENCY;
|
|
358
386
|
const files = {
|
|
359
387
|
"/App.tsx": { code: appTsx, active: true },
|
|
360
|
-
"/styles.css": { code: sandpackStylesCss || buildSandpackStylesCss({}, effectivePreviewPadding) }
|
|
388
|
+
"/styles.css": { code: sandpackStylesCss || buildSandpackStylesCss({}, effectivePreviewPadding) },
|
|
389
|
+
// Compatibility shim for legacy @seedgrid/fe-components builds that still import "qrcode" (node-only path).
|
|
390
|
+
"/node_modules/qrcode/package.json": { code: SANDPACK_QRCODE_SHIM_PACKAGE_JSON, hidden: true },
|
|
391
|
+
"/node_modules/qrcode/index.js": { code: SANDPACK_QRCODE_SHIM_INDEX_JS, hidden: true }
|
|
361
392
|
};
|
|
362
393
|
const deps = {
|
|
363
394
|
react: "^19.0.0",
|
|
@@ -376,13 +407,17 @@ export default function SgPlayground(props) {
|
|
|
376
407
|
: "resize";
|
|
377
408
|
const content = interactive ? (_jsx("div", { className: cn(withCard ? "" : "rounded-lg border border-border", withCard ? undefined : className), children: _jsxs(SandpackProvider, { template: "react-ts", files: files, customSetup: { dependencies: deps }, options: {
|
|
378
409
|
autorun: false,
|
|
410
|
+
initMode: "lazy",
|
|
411
|
+
bundlerURL: "https://sandpack.seedgrid.com.br",
|
|
412
|
+
bundlerTimeOut: 60000,
|
|
379
413
|
activeFile: "/App.tsx",
|
|
380
414
|
visibleFiles: ["/App.tsx"],
|
|
381
415
|
externalResources: SANDPACK_EXTERNAL_RESOURCES
|
|
382
|
-
}, children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [withCard ? null : _jsx("span", { className: "text-sm font-medium", children: title ?? "Example" }), _jsx("span", { className: "text-xs text-muted-foreground", children: codeContract === "renderBody" ? "editable snippet" : "editable App.tsx" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [expandable ? (_jsx(SgButton, { appearance: "outline", size: "sm", onClick: () => setIsExpanded((prev) => !prev), children: isExpanded ? "Reduzir" : "Expandir" })) : null, _jsx(RunButton, {})] })] }), _jsxs("div", { className: cn("
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
416
|
+
}, children: [_jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [withCard ? null : _jsx("span", { className: "text-sm font-medium", children: title ?? "Example" }), _jsx("span", { className: "text-xs text-muted-foreground", children: codeContract === "renderBody" ? "editable snippet" : "editable App.tsx" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [expandable ? (_jsx(SgButton, { appearance: "outline", size: "sm", onClick: () => setIsExpanded((prev) => !prev), children: isExpanded ? "Reduzir" : "Expandir" })) : null, _jsx(RunButton, { onRun: () => setActivePanel("preview") })] })] }), _jsxs("div", { className: "flex md:hidden border-b border-border", children: [_jsx("button", { type: "button", className: cn("flex-1 py-2 text-sm font-medium border-b-2 -mb-px transition-colors", activePanel === "code"
|
|
417
|
+
? "border-primary text-foreground"
|
|
418
|
+
: "border-transparent text-muted-foreground hover:text-foreground"), onClick: () => setActivePanel("code"), children: "C\u00F3digo" }), _jsx("button", { type: "button", className: cn("flex-1 py-2 text-sm font-medium border-b-2 -mb-px transition-colors", activePanel === "preview"
|
|
419
|
+
? "border-primary text-foreground"
|
|
420
|
+
: "border-transparent text-muted-foreground hover:text-foreground"), onClick: () => setActivePanel("preview"), children: "Preview" })] }), _jsxs("div", { className: cn("grid overflow-auto min-h-[260px]", "grid-cols-1 md:grid-cols-2", resizeClass), style: { height: currentHeight }, children: [_jsxs("div", { className: cn("min-w-0 md:border-r border-border", activePanel !== "code" ? "hidden md:block" : ""), children: [_jsx(SandpackCodeEditor, { showLineNumbers: true, wrapContent: true, showTabs: false, showRunButton: false, style: { height: "100%" } }), _jsx("div", { className: "flex justify-end border-t border-border px-3 py-2", children: _jsx(CopyButton, {}) })] }), _jsx("div", { className: cn("min-w-0", activePanel !== "preview" ? "hidden md:block" : ""), children: _jsx(SandpackPreview, { style: { height: "100%" }, showOpenInCodeSandbox: false, showRefreshButton: false, showRestartButton: false }) })] })] }) })) : (_jsxs("div", { className: cn(withCard ? undefined : "space-y-2", withCard ? undefined : className), children: [withCard ? null : title ? _jsx("div", { className: "text-sm font-medium", children: title }) : null, _jsx(ReadonlyBlock, { code: code })] }));
|
|
386
421
|
if (!withCard)
|
|
387
422
|
return content;
|
|
388
423
|
return (_jsx(SgCard, { id: cardId, title: title ?? "Codigo", description: description, collapsible: collapsible, defaultOpen: defaultOpen, className: cn("rounded-lg", className), bodyClassName: "p-0", children: content }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seedgrid/fe-components",
|
|
3
|
-
"version": "2026.3.
|
|
3
|
+
"version": "2026.3.2-2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
"@tiptap/extension-underline": "^2.9.1",
|
|
59
59
|
"@tiptap/react": "^2.9.1",
|
|
60
60
|
"@tiptap/starter-kit": "^2.9.1",
|
|
61
|
-
"@types/qrcode": "^1.5.6",
|
|
62
61
|
"lucide-react": "^0.468.0",
|
|
63
62
|
"react": "19.0.0",
|
|
64
63
|
"react-dom": "19.0.0",
|
|
@@ -67,6 +66,6 @@
|
|
|
67
66
|
"dependencies": {
|
|
68
67
|
"@codesandbox/sandpack-react": "^2.20.0",
|
|
69
68
|
"@pqina/flip": "^1.8.4",
|
|
70
|
-
"qrcode": "^
|
|
69
|
+
"qrcode.react": "^4.2.0"
|
|
71
70
|
}
|
|
72
71
|
}
|