@bsuite/page-builder 1.0.7 → 2.0.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/dist/CanvasCard.d.ts +8 -1
- package/dist/CanvasCard.d.ts.map +1 -1
- package/dist/DraggableCardPage.d.ts +8 -0
- package/dist/DraggableCardPage.d.ts.map +1 -1
- package/dist/PageGridLayout.d.ts +1 -1
- package/dist/PageGridLayout.d.ts.map +1 -1
- package/dist/PageGridLayout.js +20 -4
- package/dist/canvasCardLayout.d.ts +23 -1
- package/dist/canvasCardLayout.d.ts.map +1 -1
- package/dist/canvasCardLayout.js +23 -2
- package/dist/cardSurfaces.stories.d.ts +62 -0
- package/dist/cardSurfaces.stories.d.ts.map +1 -0
- package/dist/cardSurfaces.stories.js +76 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/scanner/cardHeadingScanner.d.ts +91 -0
- package/dist/scanner/cardHeadingScanner.d.ts.map +1 -0
- package/dist/scanner/cardHeadingScanner.js +278 -0
- package/dist/scanner/cardSurfaceScanner.d.ts +101 -1
- package/dist/scanner/cardSurfaceScanner.d.ts.map +1 -1
- package/dist/scanner/cardSurfaceScanner.js +355 -6
- package/dist/scanner/index.d.ts +3 -1
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/index.js +2 -1
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/usePageGridLayout.d.ts +8 -1
- package/dist/usePageGridLayout.d.ts.map +1 -1
- package/dist/usePageGridLayout.js +8 -1
- package/package.json +1 -1
package/dist/CanvasCard.d.ts
CHANGED
|
@@ -2,7 +2,14 @@ import type { ReactNode } from 'react';
|
|
|
2
2
|
export interface CanvasCardProps {
|
|
3
3
|
/** Stable widget key used by PageGridLayout for layout persistence. Required. */
|
|
4
4
|
cardKey: string;
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Grid width in columns on the 12-column grid.
|
|
7
|
+
*
|
|
8
|
+
* Defaults to **6** — half the grid, two cards per row. It defaulted to 12
|
|
9
|
+
* up to 1.0.7, which meant every card that omitted `w` rendered full width
|
|
10
|
+
* and stacked; 1,068 of 1,729 usages across the estate omit it. Say `w={12}`
|
|
11
|
+
* when a card genuinely wants the full row.
|
|
12
|
+
*/
|
|
6
13
|
w?: 2 | 3 | 4 | 6 | 8 | 12;
|
|
7
14
|
/** Minimum width in columns when the user resizes. Defaults to 4. */
|
|
8
15
|
minW?: 2 | 3 | 4 | 6 | 8 | 12;
|
package/dist/CanvasCard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CanvasCard.d.ts","sourceRoot":"","sources":["../src/CanvasCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB
|
|
1
|
+
{"version":3,"file":"CanvasCard.d.ts","sourceRoot":"","sources":["../src/CanvasCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAC3B,qEAAqE;IACrE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAC9B,4FAA4F;IAC5F,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAExD;yBAFe,UAAU"}
|
|
@@ -105,6 +105,14 @@ export type DraggableCardPageProps = Omit<PageGridLayoutProps, 'widgets' | 'defa
|
|
|
105
105
|
* the element it toggles was never mounted.
|
|
106
106
|
*/
|
|
107
107
|
onDroppedChildren?: (dropped: string[], pageKey: string) => void;
|
|
108
|
+
/**
|
|
109
|
+
* Width, in grid columns, for cards that do not set `w` themselves.
|
|
110
|
+
*
|
|
111
|
+
* Defaults to `DEFAULT_CANVAS_CARD_WIDTH` (6 — half the grid, two cards per
|
|
112
|
+
* row) as of 2.0.0. Pass 12 to restore the pre-2.0.0 full-width stack while
|
|
113
|
+
* an app migrates its pages.
|
|
114
|
+
*/
|
|
115
|
+
defaultCardWidth?: number;
|
|
108
116
|
/**
|
|
109
117
|
* CanvasCard children. Falsy entries are ignored. Fragments are flattened so
|
|
110
118
|
* a conditional multi-card branch still registers each CanvasCard.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DraggableCardPage.d.ts","sourceRoot":"","sources":["../src/DraggableCardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH,OAAO,EAAW,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAItD,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,mBAAmB,EACnB,SAAS,GAAG,gBAAgB,CAC7B,GAAG;IACF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACnD;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAgCF,wBAAgB,iBAAiB,CAAC,EAChC,WAAe,EACf,aAAa,EACb,iBAAiB,EACjB,QAAQ,EACR,GAAG,SAAS,EACb,EAAE,sBAAsB,+BA2BxB;yBAjCe,iBAAiB"}
|
|
1
|
+
{"version":3,"file":"DraggableCardPage.d.ts","sourceRoot":"","sources":["../src/DraggableCardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH,OAAO,EAAW,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAItD,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,mBAAmB,EACnB,SAAS,GAAG,gBAAgB,CAC7B,GAAG;IACF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACnD;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAgCF,wBAAgB,iBAAiB,CAAC,EAChC,WAAe,EACf,aAAa,EACb,iBAAiB,EACjB,QAAQ,EACR,GAAG,SAAS,EACb,EAAE,sBAAsB,+BA2BxB;yBAjCe,iBAAiB"}
|
package/dist/PageGridLayout.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import React from 'react';
|
|
|
2
2
|
import 'react-grid-layout/css/styles.css';
|
|
3
3
|
import 'react-resizable/css/styles.css';
|
|
4
4
|
import type { PageGridLayoutProps } from './types.js';
|
|
5
|
-
export declare function PageGridLayout({ pageKey, defaultLayouts, defaultCols, layoutVersion, canEditPage, editorEventNames, preferenceAdapter, widgets, widgetMeta, className, isResizable, resizeHandles, tenantId, defaultAutoHeight, addEntityWidgetEventNames, createEntityWidget, onRegisterEntityWidget, relationshipCatalog, addRelationshipWidgetEventNames, createRelationshipWidget, onRegisterRelationshipWidget, onRelationshipWidgetRejected, }: PageGridLayoutProps): React.JSX.Element;
|
|
5
|
+
export declare function PageGridLayout({ pageKey, defaultLayouts, defaultCols, layoutVersion, canEditPage, editorEventNames, preferenceAdapter, widgets, widgetMeta, className, isResizable, resizeHandles, tenantId, defaultAutoHeight, itemChrome, addEntityWidgetEventNames, createEntityWidget, onRegisterEntityWidget, relationshipCatalog, addRelationshipWidgetEventNames, createRelationshipWidget, onRegisterRelationshipWidget, onRelationshipWidgetRejected, }: PageGridLayoutProps): React.JSX.Element;
|
|
6
6
|
//# sourceMappingURL=PageGridLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageGridLayout.d.ts","sourceRoot":"","sources":["../src/PageGridLayout.tsx"],"names":[],"mappings":"AACA,OAAO,KAQN,MAAM,OAAO,CAAC;AAGf,OAAO,kCAAkC,CAAC;AAC1C,OAAO,gCAAgC,CAAC;AAMxC,OAAO,KAAK,EAAe,mBAAmB,EAA4B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"PageGridLayout.d.ts","sourceRoot":"","sources":["../src/PageGridLayout.tsx"],"names":[],"mappings":"AACA,OAAO,KAQN,MAAM,OAAO,CAAC;AAGf,OAAO,kCAAkC,CAAC;AAC1C,OAAO,gCAAgC,CAAC;AAMxC,OAAO,KAAK,EAAe,mBAAmB,EAA4B,MAAM,YAAY,CAAC;AA4W7F,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,cAAc,EACd,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,EACP,UAAU,EACV,SAAS,EAMT,WAAkB,EAClB,aAAsC,EACtC,QAAQ,EACR,iBAAiB,EAKjB,UAAkB,EAClB,yBAAiE,EACjE,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,+BAA6E,EAC7E,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,GAC7B,EAAE,mBAAmB,qBAyzBrB"}
|
package/dist/PageGridLayout.js
CHANGED
|
@@ -84,7 +84,7 @@ const DEFAULT_ADD_RELATIONSHIP_WIDGET_EVENT_NAMES = [
|
|
|
84
84
|
const RGLResizeHandle = React.forwardRef(function RGLResizeHandle({ axis = 'se', className: injectedClassName, ...rest }, ref) {
|
|
85
85
|
return (_jsx("span", { ref: ref, "data-no-drag": true, className: `react-resizable-handle react-resizable-handle-${axis}${injectedClassName ? ' ' + injectedClassName : ''}`, ...rest }));
|
|
86
86
|
});
|
|
87
|
-
const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, isEditing, label, onHide, autoHeight, onAutoHeightChange, children: injectedChildren, className: injectedClassName, style: injectedStyle, ...rest }, ref) {
|
|
87
|
+
const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, isEditing, label, onHide, autoHeight, onAutoHeightChange, chrome = false, children: injectedChildren, className: injectedClassName, style: injectedStyle, ...rest }, ref) {
|
|
88
88
|
// Auto-height measurement (blueprint amendment A1). `measureRef` wraps
|
|
89
89
|
// `content` with NO height constraint of its own — its parent has
|
|
90
90
|
// `overflow-hidden` + `flex-1 min-h-0` (clips *painting* to the current
|
|
@@ -214,7 +214,18 @@ const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, is
|
|
|
214
214
|
return (_jsxs("div", { ref: ref, className: outerClass, style: injectedStyle, ...rest, children: [_jsxs("div", { className: "h-full w-full relative", children: [isEditing && (_jsx("div", { className: "absolute inset-0 z-10 pointer-events-none rounded-3xl border-2 border-transparent group-hover:border-primary/50 transition-colors bg-primary/5" })), isEditing && (_jsx("div", { className: "absolute top-2 left-2 z-30 flex items-center gap-1 pointer-events-none", children: _jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-md opacity-80 font-medium bg-muted text-muted-foreground", children: label }) })), isEditing && (_jsx("button", { className: "absolute top-2 right-2 z-30 h-6 w-6 rounded-full flex items-center justify-center bg-destructive/80 hover:bg-destructive text-destructive-foreground shadow transition-colors", "data-no-drag": true, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
215
215
|
event.stopPropagation();
|
|
216
216
|
onHide(id);
|
|
217
|
-
}, title: `Hide ${label}`, "aria-label": `Hide ${label}`, children: _jsx(EyeOff, { className: "h-3 w-3", "aria-hidden": "true" }) })), _jsx("div", {
|
|
217
|
+
}, title: `Hide ${label}`, "aria-label": `Hide ${label}`, children: _jsx(EyeOff, { className: "h-3 w-3", "aria-hidden": "true" }) })), _jsx("div", { "data-slot": "grid-item-surface", "data-chrome": chrome ? 'on' : 'off', className: chrome
|
|
218
|
+
? // ONE radius token, read by the grid item AND available to any
|
|
219
|
+
// app card that opts into the same surface. Two surfaces
|
|
220
|
+
// reading the SAME var is what makes their corners align, and
|
|
221
|
+
// it is also what keeps the radius tenant-configurable —
|
|
222
|
+
// a literal here would align them and lock white-label out.
|
|
223
|
+
// `--radius-card` defaults to today's value (1.5rem =
|
|
224
|
+
// rounded-3xl), so this is byte-identical until a tenant sets
|
|
225
|
+
// one.
|
|
226
|
+
'h-full w-full rounded-[var(--radius-card,1.5rem)] transition-all flex flex-col bg-card border border-border shadow-sm dark:shadow-[var(--glow-card,none)]'
|
|
227
|
+
: // Chrome OFF: layout only. Identical box, no paint.
|
|
228
|
+
'h-full w-full transition-all flex flex-col', style: { contain: 'layout style' }, children: _jsx("div", { className: cn('flex-1 min-h-0', autoHeight ? 'overflow-hidden' : 'overflow-auto'), children: autoHeight ? _jsx("div", { ref: measureRef, children: content }) : content }) })] }), injectedChildren] }));
|
|
218
229
|
}));
|
|
219
230
|
export function PageGridLayout({ pageKey, defaultLayouts, defaultCols, layoutVersion, canEditPage, editorEventNames, preferenceAdapter, widgets, widgetMeta, className,
|
|
220
231
|
// Resize default flipped 2026-05-12: rgl v2 dropped auto-handle rendering
|
|
@@ -222,7 +233,12 @@ export function PageGridLayout({ pageKey, defaultLayouts, defaultCols, layoutVer
|
|
|
222
233
|
// adapters then defaulted it back to true. With v2's handle gap fixed,
|
|
223
234
|
// the safe default is true so any consumer who forgets to set it still
|
|
224
235
|
// gets a usable canvas. Opt out per-page with isResizable={false}.
|
|
225
|
-
isResizable = true, resizeHandles = DEFAULT_RESIZE_HANDLES, tenantId, defaultAutoHeight,
|
|
236
|
+
isResizable = true, resizeHandles = DEFAULT_RESIZE_HANDLES, tenantId, defaultAutoHeight,
|
|
237
|
+
// CHROME OFF BY DEFAULT — the inversion. See `GridItemProps.chrome`.
|
|
238
|
+
// An app that is not ready to migrate its own card surfaces passes
|
|
239
|
+
// `itemChrome` to get the pre-2.0.0 behaviour back for every slot, and
|
|
240
|
+
// migrates page by page with the per-item `chrome` flag.
|
|
241
|
+
itemChrome = false, addEntityWidgetEventNames = DEFAULT_ADD_ENTITY_WIDGET_EVENT_NAMES, createEntityWidget, onRegisterEntityWidget, relationshipCatalog, addRelationshipWidgetEventNames = DEFAULT_ADD_RELATIONSHIP_WIDGET_EVENT_NAMES, createRelationshipWidget, onRegisterRelationshipWidget, onRelationshipWidgetRejected, }) {
|
|
226
242
|
const { currentLayouts, layoutCols, isEditing, setIsEditing, activeCols, activeCompactor, onLayoutChange, handleColumnChange, handleBreakpointChange, handleCompact, handleReset, addWidget, moveWidget, setWidgetLocked, applyAutoHeightRows, autoHeightRows, resetConfirmOpen, setResetConfirmOpen, containerRef, containerWidth, } = usePageGridLayout({
|
|
227
243
|
pageKey,
|
|
228
244
|
defaultLayouts,
|
|
@@ -693,6 +709,6 @@ isResizable = true, resizeHandles = DEFAULT_RESIZE_HANDLES, tenantId, defaultAut
|
|
|
693
709
|
const content = allWidgets[layoutItem.i];
|
|
694
710
|
if (content === undefined || content === null)
|
|
695
711
|
return null;
|
|
696
|
-
return (_jsx(GridItem, { id: layoutItem.i, content: content, isEditing: isEditing, label: layerNames[layoutItem.i] || widgetMeta?.[layoutItem.i]?.label || layoutItem.i, onHide: hideLayer, autoHeight: layoutItem.autoHeight, onAutoHeightChange: handleAutoHeightChange }, layoutItem.i));
|
|
712
|
+
return (_jsx(GridItem, { id: layoutItem.i, content: content, isEditing: isEditing, label: layerNames[layoutItem.i] || widgetMeta?.[layoutItem.i]?.label || layoutItem.i, onHide: hideLayer, autoHeight: layoutItem.autoHeight, onAutoHeightChange: handleAutoHeightChange, chrome: layoutItem.chrome ?? itemChrome }, layoutItem.i));
|
|
697
713
|
}) }) }) })] }));
|
|
698
714
|
}
|
|
@@ -12,6 +12,26 @@ import type { CanvasCardProps } from './CanvasCard.js';
|
|
|
12
12
|
import type { GridLayouts } from './types.js';
|
|
13
13
|
/** The 12-column grid every BSuite page canvas is laid out against. */
|
|
14
14
|
export declare const CANVAS_GRID_COLUMNS = 12;
|
|
15
|
+
/**
|
|
16
|
+
* The width a `CanvasCard` gets when its author does not say.
|
|
17
|
+
*
|
|
18
|
+
* SIX, i.e. half the grid — changed from twelve in 2.0.0. Twelve on a
|
|
19
|
+
* twelve-column grid means every card that omits `w` renders full width and
|
|
20
|
+
* the page becomes a single vertical stack. Measured across the estate on
|
|
21
|
+
* 2026-08-25: **1,068 of 1,729 CanvasCard usages omit `w`** (BSU and conduit
|
|
22
|
+
* omit it 100% of the time), so 62% of every card surface in BSuite was
|
|
23
|
+
* stacked by a DEFAULT, not by a layout decision. That is the operator's
|
|
24
|
+
* long-standing "the cards don't use the available space" report, and it is
|
|
25
|
+
* one number in one file rather than 1,068 page edits.
|
|
26
|
+
*
|
|
27
|
+
* Six rather than four: at a 1680px container half the grid is still ~820px,
|
|
28
|
+
* which comfortably holds a data table. Four would have traded a stacking
|
|
29
|
+
* complaint for a cramping one.
|
|
30
|
+
*
|
|
31
|
+
* A page that genuinely wants a full-width card still says `w={12}` — an
|
|
32
|
+
* explicit width always wins, and 661 usages already do exactly that.
|
|
33
|
+
*/
|
|
34
|
+
export declare const DEFAULT_CANVAS_CARD_WIDTH = 6;
|
|
15
35
|
export declare function isCanvasCardElement(node: ReactNode): node is ReactElement<CanvasCardProps>;
|
|
16
36
|
/**
|
|
17
37
|
* Best-effort display name for a node that is about to be discarded.
|
|
@@ -58,5 +78,7 @@ export interface CanvasCardLayoutResult {
|
|
|
58
78
|
* item. (This is the fact that disproves the "dynamic card lists cannot be
|
|
59
79
|
* split into static widget keys" objection recorded in several app ledgers.)
|
|
60
80
|
*/
|
|
61
|
-
export declare function buildCanvasCardLayout(children: ReactNode
|
|
81
|
+
export declare function buildCanvasCardLayout(children: ReactNode, options?: {
|
|
82
|
+
defaultWidth?: number;
|
|
83
|
+
}): CanvasCardLayoutResult;
|
|
62
84
|
//# sourceMappingURL=canvasCardLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvasCardLayout.d.ts","sourceRoot":"","sources":["../src/canvasCardLayout.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,GACd,IAAI,IAAI,YAAY,CAAC,eAAe,CAAC,CAKvC;AAQD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAQpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG;IACpD,KAAK,EAAE,YAAY,CAAC,eAAe,CAAC,EAAE,CAAC;IACvC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAqBA;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAI,EAAE,GAAG,SAAsB,UAE7E;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,yEAAyE;IACzE,OAAO,EAAE,WAAW,CAAC;IACrB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"canvasCardLayout.d.ts","sourceRoot":"","sources":["../src/canvasCardLayout.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,GACd,IAAI,IAAI,YAAY,CAAC,eAAe,CAAC,CAKvC;AAQD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAQpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG;IACpD,KAAK,EAAE,YAAY,CAAC,eAAe,CAAC,EAAE,CAAC;IACvC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAqBA;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAI,EAAE,GAAG,SAAsB,UAE7E;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,yEAAyE;IACzE,OAAO,EAAE,WAAW,CAAC;IACrB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,EACnB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,sBAAsB,CA2CxB"}
|
package/dist/canvasCardLayout.js
CHANGED
|
@@ -11,6 +11,26 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
11
11
|
import { Children, Fragment, isValidElement, } from 'react';
|
|
12
12
|
/** The 12-column grid every BSuite page canvas is laid out against. */
|
|
13
13
|
export const CANVAS_GRID_COLUMNS = 12;
|
|
14
|
+
/**
|
|
15
|
+
* The width a `CanvasCard` gets when its author does not say.
|
|
16
|
+
*
|
|
17
|
+
* SIX, i.e. half the grid — changed from twelve in 2.0.0. Twelve on a
|
|
18
|
+
* twelve-column grid means every card that omits `w` renders full width and
|
|
19
|
+
* the page becomes a single vertical stack. Measured across the estate on
|
|
20
|
+
* 2026-08-25: **1,068 of 1,729 CanvasCard usages omit `w`** (BSU and conduit
|
|
21
|
+
* omit it 100% of the time), so 62% of every card surface in BSuite was
|
|
22
|
+
* stacked by a DEFAULT, not by a layout decision. That is the operator's
|
|
23
|
+
* long-standing "the cards don't use the available space" report, and it is
|
|
24
|
+
* one number in one file rather than 1,068 page edits.
|
|
25
|
+
*
|
|
26
|
+
* Six rather than four: at a 1680px container half the grid is still ~820px,
|
|
27
|
+
* which comfortably holds a data table. Four would have traded a stacking
|
|
28
|
+
* complaint for a cramping one.
|
|
29
|
+
*
|
|
30
|
+
* A page that genuinely wants a full-width card still says `w={12}` — an
|
|
31
|
+
* explicit width always wins, and 661 usages already do exactly that.
|
|
32
|
+
*/
|
|
33
|
+
export const DEFAULT_CANVAS_CARD_WIDTH = 6;
|
|
14
34
|
export function isCanvasCardElement(node) {
|
|
15
35
|
return (isValidElement(node) &&
|
|
16
36
|
node.type.displayName === 'CanvasCard');
|
|
@@ -84,7 +104,8 @@ export function clampColumns(value, min = 1, max = CANVAS_GRID_COLUMNS) {
|
|
|
84
104
|
* item. (This is the fact that disproves the "dynamic card lists cannot be
|
|
85
105
|
* split into static widget keys" objection recorded in several app ledgers.)
|
|
86
106
|
*/
|
|
87
|
-
export function buildCanvasCardLayout(children) {
|
|
107
|
+
export function buildCanvasCardLayout(children, options = {}) {
|
|
108
|
+
const defaultWidth = clampColumns(options.defaultWidth ?? DEFAULT_CANVAS_CARD_WIDTH);
|
|
88
109
|
const widgets = {};
|
|
89
110
|
const lg = [];
|
|
90
111
|
let x = 0;
|
|
@@ -96,7 +117,7 @@ export function buildCanvasCardLayout(children) {
|
|
|
96
117
|
// a card explicitly opts out for a virtualized list. See CanvasCardProps.
|
|
97
118
|
const { cardKey, h = 6, minH = 2, minW = 4, autoHeight = true, children: body, } = child.props;
|
|
98
119
|
const normalizedMinW = clampColumns(minW);
|
|
99
|
-
const width = clampColumns(child.props.w ??
|
|
120
|
+
const width = clampColumns(child.props.w ?? defaultWidth, normalizedMinW);
|
|
100
121
|
if (x + width > CANVAS_GRID_COLUMNS) {
|
|
101
122
|
y += rowHeight;
|
|
102
123
|
x = 0;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The card-surface defect classes, made VISIBLE and DIFFABLE.
|
|
4
|
+
*
|
|
5
|
+
* `@bsuite/page-builder` 1.0.4, 1.0.5 and 1.0.6 each shipped GREEN AND BROKEN.
|
|
6
|
+
* Types, lint, unit tests and CI cannot see a 28px card sitting inside a 24px
|
|
7
|
+
* frame; only a rendered surface can. These stories exist so the chrome
|
|
8
|
+
* inversion has something to be checked against that is not a number.
|
|
9
|
+
*
|
|
10
|
+
* Read them in pairs: the story named "…(the defect)" is what shipped up to
|
|
11
|
+
* 1.0.7, and the one beside it is what 2.0.0 renders.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Plain CSF, no `Meta`/`StoryObj` type imports.
|
|
15
|
+
*
|
|
16
|
+
* `@storybook/react-vite` is a devDependency of `@bsuite/ui`, which owns the
|
|
17
|
+
* Storybook config; this package does not depend on Storybook and must not
|
|
18
|
+
* start to, or `pnpm typecheck` here fails on a type-only import for a tool
|
|
19
|
+
* that is not installed. CSF is a plain-object format — the indexer reads the
|
|
20
|
+
* default export and the named exports, and the types are optional sugar.
|
|
21
|
+
*/
|
|
22
|
+
type Story = {
|
|
23
|
+
name?: string;
|
|
24
|
+
render: () => ReactNode;
|
|
25
|
+
};
|
|
26
|
+
declare const _default: {
|
|
27
|
+
title: string;
|
|
28
|
+
parameters: {
|
|
29
|
+
layout: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export default _default;
|
|
33
|
+
/**
|
|
34
|
+
* THE DEFECT, exactly as it shipped. A card inside the grid item's card:
|
|
35
|
+
* two radii, two 1px borders, two backgrounds. 316+ files render this.
|
|
36
|
+
*/
|
|
37
|
+
export declare const NestedCardDoubleFrame: Story;
|
|
38
|
+
/** The same content on 2.0.0 defaults: ONE border, ONE radius. */
|
|
39
|
+
export declare const NestedCardSingleFrame: Story;
|
|
40
|
+
/** Bare content with chrome OFF — the regression the inversion could cause. */
|
|
41
|
+
export declare const BareContentNoChrome: Story;
|
|
42
|
+
/** The same bare content opting IN per item. This is the migration for the 10%. */
|
|
43
|
+
export declare const BareContentOptsIn: Story;
|
|
44
|
+
/**
|
|
45
|
+
* Every card width side by side. `w` defaulted to 12, so 1,068 of 1,729 usages
|
|
46
|
+
* rendered like the last row here — one card per row, the rest of the screen
|
|
47
|
+
* empty. That is the "cards don't use the available space" report.
|
|
48
|
+
*/
|
|
49
|
+
export declare const WidthLadder: Story;
|
|
50
|
+
/**
|
|
51
|
+
* Card headings. `text-gradient-accent` is on 183 of 235 crm7 h1 page titles
|
|
52
|
+
* and 0 of 310 crm7 h2/h3 CARD headings — the element the operator keeps
|
|
53
|
+
* asking about. The pairing matters: the solid `text-(--role-text-heading)`
|
|
54
|
+
* sits UNDER the gradient as the fallback layer.
|
|
55
|
+
*
|
|
56
|
+
* `width: fit-content` inside the utility is load-bearing. Anything that
|
|
57
|
+
* overrides width makes a short heading sample only the first ~15% of the
|
|
58
|
+
* gradient and render flat — indistinguishable from having no gradient at all,
|
|
59
|
+
* which is why "is the class present" is not a check.
|
|
60
|
+
*/
|
|
61
|
+
export declare const CardHeadingGradient: Story;
|
|
62
|
+
//# sourceMappingURL=cardSurfaces.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardSurfaces.stories.d.ts","sourceRoot":"","sources":["../src/cardSurfaces.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,KAAK,KAAK,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,SAAS,CAAA;CAAE,CAAA;;;;;;;AAEvD,wBAGC;AA0BD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAYnC,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,qBAAqB,EAAE,KAWnC,CAAA;AAED,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAE,KAWjC,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,EAAE,KAW/B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,KAyBzB,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAoBjC,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PageGridLayout } from './PageGridLayout.js';
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Page Builder/Card surfaces',
|
|
5
|
+
parameters: { layout: 'fullscreen' },
|
|
6
|
+
};
|
|
7
|
+
/** What an app renders inside a slot: its own card. Border, radius, background. */
|
|
8
|
+
function AppCard({ title, children }) {
|
|
9
|
+
return (_jsxs("div", { className: "h-full rounded-[var(--radius-card,1.5rem)] border border-border bg-card p-6 shadow-sm", children: [_jsx("h3", { className: "mb-2 text-lg font-semibold text-(--role-text-heading)", children: title }), _jsx("div", { className: "text-sm text-muted-foreground", children: children })] }));
|
|
10
|
+
}
|
|
11
|
+
/** Bare content: no surface of its own. This is the 10% that NEEDS the chrome. */
|
|
12
|
+
function BareContent({ title }) {
|
|
13
|
+
return (_jsxs("div", { className: "p-6", children: [_jsx("h3", { className: "mb-2 text-lg font-semibold text-(--role-text-heading)", children: title }), _jsx("p", { className: "text-sm text-muted-foreground", children: "No surface of its own \u2014 this slot is the one that should opt IN to chrome." })] }));
|
|
14
|
+
}
|
|
15
|
+
const oneSlot = { lg: [{ i: 'a', x: 0, y: 0, w: 6, h: 6 }] };
|
|
16
|
+
/**
|
|
17
|
+
* THE DEFECT, exactly as it shipped. A card inside the grid item's card:
|
|
18
|
+
* two radii, two 1px borders, two backgrounds. 316+ files render this.
|
|
19
|
+
*/
|
|
20
|
+
export const NestedCardDoubleFrame = {
|
|
21
|
+
name: 'Nested card — DOUBLE FRAME (the defect)',
|
|
22
|
+
render: () => (_jsx("div", { className: "p-8", children: _jsx(PageGridLayout, { pageKey: "sb/nested-defect", defaultLayouts: oneSlot, itemChrome: true, widgets: { a: _jsx(AppCard, { title: "Quick Actions", children: "Grid item chrome ON + app card." }) } }) })),
|
|
23
|
+
};
|
|
24
|
+
/** The same content on 2.0.0 defaults: ONE border, ONE radius. */
|
|
25
|
+
export const NestedCardSingleFrame = {
|
|
26
|
+
name: 'Nested card — ONE frame (2.0.0 default)',
|
|
27
|
+
render: () => (_jsx("div", { className: "p-8", children: _jsx(PageGridLayout, { pageKey: "sb/nested-fixed", defaultLayouts: oneSlot, widgets: { a: _jsx(AppCard, { title: "Quick Actions", children: "Grid item chrome OFF; the app card is the only surface." }) } }) })),
|
|
28
|
+
};
|
|
29
|
+
/** Bare content with chrome OFF — the regression the inversion could cause. */
|
|
30
|
+
export const BareContentNoChrome = {
|
|
31
|
+
name: 'Bare content, chrome OFF — the regression to watch for',
|
|
32
|
+
render: () => (_jsx("div", { className: "p-8", children: _jsx(PageGridLayout, { pageKey: "sb/bare-off", defaultLayouts: oneSlot, widgets: { a: _jsx(BareContent, { title: "Pipeline Overview" }) } }) })),
|
|
33
|
+
};
|
|
34
|
+
/** The same bare content opting IN per item. This is the migration for the 10%. */
|
|
35
|
+
export const BareContentOptsIn = {
|
|
36
|
+
name: 'Bare content, per-item chrome ON — the migration',
|
|
37
|
+
render: () => (_jsx("div", { className: "p-8", children: _jsx(PageGridLayout, { pageKey: "sb/bare-on", defaultLayouts: { lg: [{ i: 'a', x: 0, y: 0, w: 6, h: 6, chrome: true }] }, widgets: { a: _jsx(BareContent, { title: "Pipeline Overview" }) } }) })),
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Every card width side by side. `w` defaulted to 12, so 1,068 of 1,729 usages
|
|
41
|
+
* rendered like the last row here — one card per row, the rest of the screen
|
|
42
|
+
* empty. That is the "cards don't use the available space" report.
|
|
43
|
+
*/
|
|
44
|
+
export const WidthLadder = {
|
|
45
|
+
name: 'Width ladder — w = 2 / 3 / 4 / 6 / 12',
|
|
46
|
+
render: () => (_jsx("div", { className: "p-8", children: _jsx(PageGridLayout, { pageKey: "sb/widths", defaultLayouts: {
|
|
47
|
+
lg: [
|
|
48
|
+
{ i: 'w2', x: 0, y: 0, w: 2, h: 4 },
|
|
49
|
+
{ i: 'w3', x: 2, y: 0, w: 3, h: 4 },
|
|
50
|
+
{ i: 'w4', x: 5, y: 0, w: 4, h: 4 },
|
|
51
|
+
{ i: 'w6', x: 0, y: 4, w: 6, h: 4 },
|
|
52
|
+
{ i: 'w12', x: 0, y: 8, w: 12, h: 4 },
|
|
53
|
+
],
|
|
54
|
+
}, widgets: {
|
|
55
|
+
w2: _jsx(AppCard, { title: "w=2" }),
|
|
56
|
+
w3: _jsx(AppCard, { title: "w=3" }),
|
|
57
|
+
w4: _jsx(AppCard, { title: "w=4" }),
|
|
58
|
+
w6: _jsx(AppCard, { title: "w=6 \u2014 the new default" }),
|
|
59
|
+
w12: _jsx(AppCard, { title: "w=12 \u2014 the old default, one card per row" }),
|
|
60
|
+
} }) })),
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Card headings. `text-gradient-accent` is on 183 of 235 crm7 h1 page titles
|
|
64
|
+
* and 0 of 310 crm7 h2/h3 CARD headings — the element the operator keeps
|
|
65
|
+
* asking about. The pairing matters: the solid `text-(--role-text-heading)`
|
|
66
|
+
* sits UNDER the gradient as the fallback layer.
|
|
67
|
+
*
|
|
68
|
+
* `width: fit-content` inside the utility is load-bearing. Anything that
|
|
69
|
+
* overrides width makes a short heading sample only the first ~15% of the
|
|
70
|
+
* gradient and render flat — indistinguishable from having no gradient at all,
|
|
71
|
+
* which is why "is the class present" is not a check.
|
|
72
|
+
*/
|
|
73
|
+
export const CardHeadingGradient = {
|
|
74
|
+
name: 'Card headings — with and without the gradient',
|
|
75
|
+
render: () => (_jsxs("div", { className: "grid gap-8 p-8 md:grid-cols-2", children: [_jsxs("div", { className: "rounded-[var(--radius-card,1.5rem)] border border-border bg-card p-6", children: [_jsx("h3", { className: "mb-2 text-lg font-semibold text-(--role-text-heading)", children: "Quick Actions \u2014 flat (today, 0 of 310)" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "No gradient." })] }), _jsxs("div", { className: "rounded-[var(--radius-card,1.5rem)] border border-border bg-card p-6", children: [_jsx("h3", { className: "text-gradient-accent mb-2 text-lg font-semibold text-(--role-text-heading)", children: "Quick Actions \u2014 gradient (G2 target)" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "`text-gradient-accent` over the solid heading token." })] })] })),
|
|
76
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { CanvasCard } from './CanvasCard.js';
|
|
|
4
4
|
export type { CanvasCardProps } from './CanvasCard.js';
|
|
5
5
|
export { DraggableCardPage } from './DraggableCardPage.js';
|
|
6
6
|
export type { DraggableCardPageProps } from './DraggableCardPage.js';
|
|
7
|
-
export { buildCanvasCardLayout, flattenCanvasCards, isCanvasCardElement, describeNode, clampColumns, CANVAS_GRID_COLUMNS, } from './canvasCardLayout.js';
|
|
7
|
+
export { buildCanvasCardLayout, DEFAULT_CANVAS_CARD_WIDTH, flattenCanvasCards, isCanvasCardElement, describeNode, clampColumns, CANVAS_GRID_COLUMNS, } from './canvasCardLayout.js';
|
|
8
8
|
export type { CanvasCardLayoutResult } from './canvasCardLayout.js';
|
|
9
9
|
export type { WidgetConfig, PageEditorLauncherProps } from './PageEditorLauncher.js';
|
|
10
10
|
export { usePageGridLayout, DEFAULT_EDITOR_EVENT_NAMES, PAGE_GRID_EDITING_EVENT, } from './usePageGridLayout.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,6BAA6B,EAC7B,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EACV,kBAAkB,EAClB,0BAA0B,EAC1B,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,gCAAgC,EAChC,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,YAAY,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,6BAA6B,EAC7B,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EACV,kBAAkB,EAClB,0BAA0B,EAC1B,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,gCAAgC,EAChC,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { PageGridLayout } from './PageGridLayout.js';
|
|
|
2
2
|
export { PageEditorLauncher } from './PageEditorLauncher.js';
|
|
3
3
|
export { CanvasCard } from './CanvasCard.js';
|
|
4
4
|
export { DraggableCardPage } from './DraggableCardPage.js';
|
|
5
|
-
export { buildCanvasCardLayout, flattenCanvasCards, isCanvasCardElement, describeNode, clampColumns, CANVAS_GRID_COLUMNS, } from './canvasCardLayout.js';
|
|
5
|
+
export { buildCanvasCardLayout, DEFAULT_CANVAS_CARD_WIDTH, flattenCanvasCards, isCanvasCardElement, describeNode, clampColumns, CANVAS_GRID_COLUMNS, } from './canvasCardLayout.js';
|
|
6
6
|
export { usePageGridLayout, DEFAULT_EDITOR_EVENT_NAMES, PAGE_GRID_EDITING_EVENT, } from './usePageGridLayout.js';
|
|
7
7
|
export { rescaleLayout } from './rescaleLayout.js';
|
|
8
8
|
export { computeAutoHeightRows } from './autoHeight.js';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which headings are CARD headings, and do they carry the gradient?
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS. The estate's heading gradient was implemented as a
|
|
5
|
+
* PAGE-TITLE convention and shipped: 183 of 232 crm7 `<h1>` page titles carry
|
|
6
|
+
* `.text-gradient-accent`. Card headings were never in scope, and the numbers
|
|
7
|
+
* say so plainly — 0 of 304 crm7 `<h2>`/`<h3>`, 15 of 734 estate-wide. The work
|
|
8
|
+
* was done, declared complete, and covered a DIFFERENT ELEMENT than the one the
|
|
9
|
+
* operator keeps pointing at. On the very dashboard he screenshotted,
|
|
10
|
+
* "Dashboard" (h1) has the gradient and "Quick Actions", "Communication Center"
|
|
11
|
+
* and "Pipeline Overview" (h2/h3) do not.
|
|
12
|
+
*
|
|
13
|
+
* SO WHY NOT JUST GREP `<h2`? Because `<h2>` is not the same thing as "card
|
|
14
|
+
* heading", and a sweep that treats them as equal gradients dialog titles,
|
|
15
|
+
* empty-state titles, section labels and table captions along with the cards.
|
|
16
|
+
* The operator asked for card headings. A detector that cannot tell a card
|
|
17
|
+
* heading from any other heading would deliver 734 changes to satisfy a request
|
|
18
|
+
* about roughly 600 of them, and the excess is what gets noticed.
|
|
19
|
+
*
|
|
20
|
+
* A heading is a CARD heading here when an enclosing element paints card chrome
|
|
21
|
+
* — a card component, or a border+radius+background surface — which is the same
|
|
22
|
+
* definition `cardSurfaceScanner` already uses for nested chrome. One definition
|
|
23
|
+
* of "card", two scanners.
|
|
24
|
+
*
|
|
25
|
+
* FAIL CLOSED. A file whose JSX tags do not balance is UNKNOWN, not clean: a
|
|
26
|
+
* tag stack that has lost its place cannot say what encloses what, and
|
|
27
|
+
* "checked nothing" must not share an exit code with "found nothing" (D-92).
|
|
28
|
+
*
|
|
29
|
+
* Node-only: filesystem access, exported from `@bsuite/page-builder/scanner`.
|
|
30
|
+
*/
|
|
31
|
+
export interface CardHeadingFinding {
|
|
32
|
+
file: string;
|
|
33
|
+
/** `h2` or `h3`. */
|
|
34
|
+
tag: string;
|
|
35
|
+
/** 1-based line of the heading's opening tag. */
|
|
36
|
+
line: number;
|
|
37
|
+
/** The chrome element that makes this a card heading. */
|
|
38
|
+
enclosingSurface: string;
|
|
39
|
+
/** Does it already carry a gradient class? */
|
|
40
|
+
hasGradient: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Classes that fight `width: fit-content`.
|
|
43
|
+
*
|
|
44
|
+
* `.text-gradient-accent` sets `width: fit-content`, and that is load-bearing
|
|
45
|
+
* — `background-clip: text` paints across the ELEMENT BOX, so a block-level
|
|
46
|
+
* heading spanning its container samples only the first slice of the gradient
|
|
47
|
+
* and renders flat, which is indistinguishable from having no gradient at
|
|
48
|
+
* all. But a heading that is `truncate`, `flex-1`, `w-full` or `line-clamp-*`
|
|
49
|
+
* DEPENDS on filling its box, and shrink-wrapping it changes the layout.
|
|
50
|
+
* Those headings need a decision, not a codemod.
|
|
51
|
+
*/
|
|
52
|
+
widthDependentClasses: string[];
|
|
53
|
+
}
|
|
54
|
+
export interface CardHeadingScanResult {
|
|
55
|
+
findings: CardHeadingFinding[];
|
|
56
|
+
filesScanned: number;
|
|
57
|
+
scanRootsResolved: string[];
|
|
58
|
+
/** Files whose JSX could not be walked. UNKNOWN is not clean. */
|
|
59
|
+
unknownFiles: string[];
|
|
60
|
+
summary: string;
|
|
61
|
+
}
|
|
62
|
+
export interface CardHeadingScannerConfig {
|
|
63
|
+
projectRoot: string;
|
|
64
|
+
scanRoots: string[];
|
|
65
|
+
/** Component names that count as card chrome. */
|
|
66
|
+
cardTags: string[];
|
|
67
|
+
/** Extra chrome components, as in `cardSurfaceScanner`. */
|
|
68
|
+
nestedChromeTags?: string[];
|
|
69
|
+
/** Heading tags to consider. Defaults to h2 and h3 — h1 is the page title. */
|
|
70
|
+
headingTags?: string[];
|
|
71
|
+
/** Classes that already paint a heading gradient. */
|
|
72
|
+
gradientClasses?: string[];
|
|
73
|
+
extensions?: string[];
|
|
74
|
+
}
|
|
75
|
+
interface JsxTag {
|
|
76
|
+
kind: 'open' | 'close' | 'self';
|
|
77
|
+
tag: string;
|
|
78
|
+
attrs: string;
|
|
79
|
+
index: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Tokenise JSX tags with their kind and offset.
|
|
83
|
+
*
|
|
84
|
+
* `openingTags` in the sibling module is deliberately kind-blind — it only has
|
|
85
|
+
* to find chrome inside a known block. Ancestry needs a stack, and a stack
|
|
86
|
+
* needs to know which tags close.
|
|
87
|
+
*/
|
|
88
|
+
export declare function jsxTags(source: string): JsxTag[];
|
|
89
|
+
export declare function scanCardHeadings(config: CardHeadingScannerConfig): CardHeadingScanResult;
|
|
90
|
+
export {};
|
|
91
|
+
//# sourceMappingURL=cardHeadingScanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cardHeadingScanner.d.ts","sourceRoot":"","sources":["../../src/scanner/cardHeadingScanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAMH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;OAUG;IACH,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,iEAAiE;IACjE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAkDD,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAqDhD;AAsCD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,GAAG,qBAAqB,CA+FxF"}
|