twico-ui 1.36.1 → 1.37.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 +7 -0
- package/dist/index.cjs +22 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.mjs +22 -10
- package/dist/index.mjs.map +1 -1
- package/llms.txt +3 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -2915,8 +2915,14 @@ interface DialogProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"
|
|
|
2915
2915
|
footer?: React.ReactNode;
|
|
2916
2916
|
/** `"full"` is a near-fullscreen panel (fills the viewport minus a small margin). @default "md" */
|
|
2917
2917
|
size?: "sm" | "md" | "lg" | "full";
|
|
2918
|
-
/** Keep the header + footer fixed and scroll only the body
|
|
2918
|
+
/** Keep the header + footer fixed and scroll only the body when content exceeds the viewport — so the
|
|
2919
|
+
* action buttons never scroll off-screen (#371). Set `false` for a panel that should scroll as one block
|
|
2920
|
+
* (rare; note a non-portaled child that deliberately overflows the panel would be clipped). @default true */
|
|
2919
2921
|
scrollBody?: boolean;
|
|
2922
|
+
/** Draw a rule between header/body and body/footer. Suppressed automatically where the region is empty
|
|
2923
|
+
* (no footer; a header with only a close button and no title/description). Set `false` for a panel that
|
|
2924
|
+
* should read as one continuous surface. @default true */
|
|
2925
|
+
dividers?: boolean;
|
|
2920
2926
|
/** Close when the backdrop is clicked. @default true */
|
|
2921
2927
|
closeOnBackdrop?: boolean;
|
|
2922
2928
|
children?: React.ReactNode;
|
|
@@ -2962,6 +2968,10 @@ interface DrawerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"
|
|
|
2962
2968
|
height?: "sm" | "md" | "lg" | number | string;
|
|
2963
2969
|
/** Close when the backdrop is clicked. @default true */
|
|
2964
2970
|
closeOnBackdrop?: boolean;
|
|
2971
|
+
/** Draw a rule between header/body and body/footer (matches `Dialog`). Suppressed automatically where the
|
|
2972
|
+
* region is empty (no footer; a header with only a close button and no title/description). Set `false` for a
|
|
2973
|
+
* panel that should read as one continuous surface. @default true */
|
|
2974
|
+
dividers?: boolean;
|
|
2965
2975
|
children?: React.ReactNode;
|
|
2966
2976
|
}
|
|
2967
2977
|
|
package/dist/index.d.ts
CHANGED
|
@@ -2915,8 +2915,14 @@ interface DialogProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"
|
|
|
2915
2915
|
footer?: React.ReactNode;
|
|
2916
2916
|
/** `"full"` is a near-fullscreen panel (fills the viewport minus a small margin). @default "md" */
|
|
2917
2917
|
size?: "sm" | "md" | "lg" | "full";
|
|
2918
|
-
/** Keep the header + footer fixed and scroll only the body
|
|
2918
|
+
/** Keep the header + footer fixed and scroll only the body when content exceeds the viewport — so the
|
|
2919
|
+
* action buttons never scroll off-screen (#371). Set `false` for a panel that should scroll as one block
|
|
2920
|
+
* (rare; note a non-portaled child that deliberately overflows the panel would be clipped). @default true */
|
|
2919
2921
|
scrollBody?: boolean;
|
|
2922
|
+
/** Draw a rule between header/body and body/footer. Suppressed automatically where the region is empty
|
|
2923
|
+
* (no footer; a header with only a close button and no title/description). Set `false` for a panel that
|
|
2924
|
+
* should read as one continuous surface. @default true */
|
|
2925
|
+
dividers?: boolean;
|
|
2920
2926
|
/** Close when the backdrop is clicked. @default true */
|
|
2921
2927
|
closeOnBackdrop?: boolean;
|
|
2922
2928
|
children?: React.ReactNode;
|
|
@@ -2962,6 +2968,10 @@ interface DrawerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"
|
|
|
2962
2968
|
height?: "sm" | "md" | "lg" | number | string;
|
|
2963
2969
|
/** Close when the backdrop is clicked. @default true */
|
|
2964
2970
|
closeOnBackdrop?: boolean;
|
|
2971
|
+
/** Draw a rule between header/body and body/footer (matches `Dialog`). Suppressed automatically where the
|
|
2972
|
+
* region is empty (no footer; a header with only a close button and no title/description). Set `false` for a
|
|
2973
|
+
* panel that should read as one continuous surface. @default true */
|
|
2974
|
+
dividers?: boolean;
|
|
2965
2975
|
children?: React.ReactNode;
|
|
2966
2976
|
}
|
|
2967
2977
|
|
package/dist/index.mjs
CHANGED
|
@@ -15412,6 +15412,10 @@ var DIALOG_CSS = `
|
|
|
15412
15412
|
.twc-dialog__close svg { width: 18px; height: 18px; }
|
|
15413
15413
|
.twc-dialog__body { padding: var(--space-4) var(--space-5); font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading-normal); }
|
|
15414
15414
|
.twc-dialog__footer { display: flex; gap: var(--space-2); justify-content: flex-end; padding: 0 var(--space-5) var(--space-5); }
|
|
15415
|
+
/* #372: header/body and body/footer rules (on by default). Per-region data-divider so the rule is
|
|
15416
|
+
suppressed when the region is empty (no footer; a header with only a close button and no title/description). */
|
|
15417
|
+
.twc-dialog__header[data-divider="true"] { padding-bottom: var(--space-4); border-bottom: var(--border-thin) solid var(--color-divider); }
|
|
15418
|
+
.twc-dialog__footer[data-divider="true"] { padding-top: var(--space-4); border-top: var(--border-thin) solid var(--color-divider); }
|
|
15415
15419
|
`;
|
|
15416
15420
|
function Dialog({
|
|
15417
15421
|
open,
|
|
@@ -15421,7 +15425,8 @@ function Dialog({
|
|
|
15421
15425
|
footer,
|
|
15422
15426
|
children,
|
|
15423
15427
|
size = "md",
|
|
15424
|
-
scrollBody =
|
|
15428
|
+
scrollBody = true,
|
|
15429
|
+
dividers = true,
|
|
15425
15430
|
closeOnBackdrop = true,
|
|
15426
15431
|
className = "",
|
|
15427
15432
|
...rest
|
|
@@ -15462,7 +15467,7 @@ function Dialog({
|
|
|
15462
15467
|
}, children: [
|
|
15463
15468
|
__twcStyles,
|
|
15464
15469
|
/* @__PURE__ */ jsxs("div", { ref: dialogRef, className: `twc-dialog ${className}`, "data-state": state, "data-size": size, "data-scroll-body": scrollBody ? "true" : void 0, role: "dialog", "aria-modal": "true", tabIndex: -1, "aria-labelledby": title ? titleId : void 0, "aria-label": !title ? "Dialog" : void 0, "aria-describedby": description ? descId : void 0, ...rest, children: [
|
|
15465
|
-
title || description || onClose ? /* @__PURE__ */ jsxs("div", { className: "twc-dialog__header", children: [
|
|
15470
|
+
title || description || onClose ? /* @__PURE__ */ jsxs("div", { className: "twc-dialog__header", "data-divider": dividers && (title || description) && (children || footer) ? "true" : void 0, children: [
|
|
15466
15471
|
/* @__PURE__ */ jsxs("div", { className: "twc-dialog__titles", children: [
|
|
15467
15472
|
title ? /* @__PURE__ */ jsx("div", { className: "twc-dialog__title", id: titleId, children: title }) : null,
|
|
15468
15473
|
description ? /* @__PURE__ */ jsx("div", { className: "twc-dialog__desc", id: descId, children: description }) : null
|
|
@@ -15470,7 +15475,7 @@ function Dialog({
|
|
|
15470
15475
|
onClose ? /* @__PURE__ */ jsx("button", { className: "twc-dialog__close", onClick: onClose, "aria-label": "Close", type: "button", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
15471
15476
|
] }) : null,
|
|
15472
15477
|
children ? /* @__PURE__ */ jsx("div", { className: "twc-dialog__body", children }) : null,
|
|
15473
|
-
footer ? /* @__PURE__ */ jsx("div", { className: "twc-dialog__footer", children: footer }) : null
|
|
15478
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "twc-dialog__footer", "data-divider": dividers && children ? "true" : void 0, children: footer }) : null
|
|
15474
15479
|
] })
|
|
15475
15480
|
] });
|
|
15476
15481
|
return renderPortal(overlay);
|
|
@@ -15570,7 +15575,11 @@ var DRAWER_CSS = `
|
|
|
15570
15575
|
.twc-drawer__close:hover { background: var(--color-surface-sunken); color: var(--color-text); }
|
|
15571
15576
|
.twc-drawer__close svg { width: 18px; height: 18px; }
|
|
15572
15577
|
.twc-drawer__body { flex: 1; overflow-y: auto; padding: var(--space-2) var(--space-5) var(--space-5); font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading-normal); }
|
|
15573
|
-
.twc-drawer__footer { display: flex; gap: var(--space-2); justify-content: flex-end; padding: var(--space-4) var(--space-5);
|
|
15578
|
+
.twc-drawer__footer { display: flex; gap: var(--space-2); justify-content: flex-end; padding: var(--space-4) var(--space-5); }
|
|
15579
|
+
/* #372: header/footer rules (on by default), consistent with Dialog. Per-region data-divider so an empty
|
|
15580
|
+
region grows no stray line (no footer; a header with only a close button and no title/description). */
|
|
15581
|
+
.twc-drawer__header[data-divider="true"] { border-bottom: var(--border-thin) solid var(--color-divider); }
|
|
15582
|
+
.twc-drawer__footer[data-divider="true"] { border-top: var(--border-thin) solid var(--color-divider); }
|
|
15574
15583
|
@media (prefers-reduced-motion: reduce) {
|
|
15575
15584
|
.twc-drawer__overlay[data-state], .twc-drawer[data-state] { animation-duration: 1ms; }
|
|
15576
15585
|
}
|
|
@@ -15586,6 +15595,7 @@ function Drawer({
|
|
|
15586
15595
|
width,
|
|
15587
15596
|
height,
|
|
15588
15597
|
closeOnBackdrop = true,
|
|
15598
|
+
dividers = true,
|
|
15589
15599
|
children,
|
|
15590
15600
|
className = "",
|
|
15591
15601
|
style,
|
|
@@ -15631,7 +15641,7 @@ function Drawer({
|
|
|
15631
15641
|
}, children: [
|
|
15632
15642
|
__twcStyles,
|
|
15633
15643
|
/* @__PURE__ */ jsxs("div", { ref: panelRef, className: `twc-drawer ${className}`, "data-side": side, "data-state": state, role: "dialog", "aria-modal": "true", tabIndex: -1, "aria-labelledby": title ? titleId : void 0, "aria-label": !title ? "Drawer" : void 0, "aria-describedby": description ? descId : void 0, style: { ...dim ? sizeVar : null, ...style }, ...rest, children: [
|
|
15634
|
-
title || description || onClose ? /* @__PURE__ */ jsxs("div", { className: "twc-drawer__header", children: [
|
|
15644
|
+
title || description || onClose ? /* @__PURE__ */ jsxs("div", { className: "twc-drawer__header", "data-divider": dividers && (title || description) ? "true" : void 0, children: [
|
|
15635
15645
|
/* @__PURE__ */ jsxs("div", { className: "twc-drawer__titles", children: [
|
|
15636
15646
|
title ? /* @__PURE__ */ jsx("div", { className: "twc-drawer__title", id: titleId, children: title }) : null,
|
|
15637
15647
|
description ? /* @__PURE__ */ jsx("div", { className: "twc-drawer__desc", id: descId, children: description }) : null
|
|
@@ -15639,7 +15649,7 @@ function Drawer({
|
|
|
15639
15649
|
onClose ? /* @__PURE__ */ jsx("button", { className: "twc-drawer__close", onClick: onClose, "aria-label": "Close", type: "button", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
15640
15650
|
] }) : null,
|
|
15641
15651
|
/* @__PURE__ */ jsx("div", { className: "twc-drawer__body", children }),
|
|
15642
|
-
footer ? /* @__PURE__ */ jsx("div", { className: "twc-drawer__footer", children: footer }) : null
|
|
15652
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "twc-drawer__footer", "data-divider": dividers ? "true" : void 0, children: footer }) : null
|
|
15643
15653
|
] })
|
|
15644
15654
|
] });
|
|
15645
15655
|
return renderPortal(overlay);
|
|
@@ -16340,7 +16350,9 @@ var POPOVER_CSS = `
|
|
|
16340
16350
|
.twc-popover__arrow { position: absolute; width: 11px; height: 11px; background: var(--color-surface-raised);
|
|
16341
16351
|
border-left: var(--border-thin) solid var(--color-border); border-top: var(--border-thin) solid var(--color-border);
|
|
16342
16352
|
transform: rotate(45deg); }
|
|
16343
|
-
|
|
16353
|
+
/* #373: cap the panel to the room place() measured and scroll INSIDE the inner (not the panel \u2014 the panel
|
|
16354
|
+
must keep overflow visible so the absolutely-positioned arrow isn't clipped) so a tall panel's footer stays reachable. */
|
|
16355
|
+
.twc-popover__inner { padding: var(--space-4); font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading-normal); overflow-y: auto; }
|
|
16344
16356
|
.twc-popover__title { font-size: var(--text-sm); font-weight: var(--font-bold); color: var(--color-text); margin-bottom: 4px; }
|
|
16345
16357
|
`;
|
|
16346
16358
|
function Popover({
|
|
@@ -16402,7 +16414,7 @@ function Popover({
|
|
|
16402
16414
|
l = Math.max(M, Math.min(l, vw - w - M));
|
|
16403
16415
|
left = l;
|
|
16404
16416
|
arrow = { left: Math.min(Math.max(r2.left + r2.width / 2 - l - 5.5, 10), w - 20), [flip ? "bottom" : "top"]: -6 };
|
|
16405
|
-
return setPos({ top, bottom, left, width: w, flip, arrow });
|
|
16417
|
+
return setPos({ top, bottom, left, width: w, flip, arrow, maxHeight: flip ? spaceAbove : spaceBelow });
|
|
16406
16418
|
}
|
|
16407
16419
|
const ph = popRef.current ? popRef.current.offsetHeight : 120;
|
|
16408
16420
|
let onRight = placement === "right";
|
|
@@ -16414,7 +16426,7 @@ function Popover({
|
|
|
16414
16426
|
const cy = r2.top + r2.height / 2;
|
|
16415
16427
|
top = Math.max(M, Math.min(cy - ph / 2, vh - ph - M));
|
|
16416
16428
|
arrow = { top: Math.min(Math.max(cy - top - 5.5, 8), ph - 18), [onRight ? "left" : "right"]: -6 };
|
|
16417
|
-
setPos({ top, left, width: w, flip: false, arrow });
|
|
16429
|
+
setPos({ top, left, width: w, flip: false, arrow, maxHeight: vh - 2 * M });
|
|
16418
16430
|
}, [placement, align, width]);
|
|
16419
16431
|
React51__default.useEffect(() => {
|
|
16420
16432
|
if (!open) return;
|
|
@@ -16480,7 +16492,7 @@ function Popover({
|
|
|
16480
16492
|
children: [
|
|
16481
16493
|
__twcStyles,
|
|
16482
16494
|
/* @__PURE__ */ jsx("span", { className: "twc-popover__arrow", style: pos.arrow, "aria-hidden": "true" }),
|
|
16483
|
-
/* @__PURE__ */ jsxs("div", { className: "twc-popover__inner", children: [
|
|
16495
|
+
/* @__PURE__ */ jsxs("div", { className: "twc-popover__inner", style: { maxHeight: pos.maxHeight }, children: [
|
|
16484
16496
|
title ? /* @__PURE__ */ jsx("div", { className: "twc-popover__title", id: `${popId}-title`, children: title }) : null,
|
|
16485
16497
|
children
|
|
16486
16498
|
] })
|