@bsuite/page-builder 2.7.1-next.4 → 2.7.1-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,6 +58,28 @@ a React transition. Initial mounting, unchanged state and abandoned transitions
58
58
  do not emit notifications. Consumers must match the page key and preserve
59
59
  focus on surviving inputs when synchronizing their header controls.
60
60
 
61
+ From `2.7.1-next.5`, a header Save & exit dispatches `PAGE_GRID_SAVE_EVENT`
62
+ with `{ pageKey }`. The canvas waits for all preference adapters, keeps its
63
+ controls and error visible on failure, and emits the existing committed editing
64
+ notification on success. Headers wait for that notification before clearing
65
+ edit mode. Existing open/close events remain available for route navigation.
66
+
67
+ Selected depths expose separate resting, light-interaction and dark-interaction
68
+ shadow variables. Light interaction adds neutral elevation; dark interaction
69
+ adds the role-bound glow while retaining the selected depth. Explicit zero
70
+ stays flat. Consumers must read all three variables; chrome-owning grid items
71
+ already do. Default painted grid cards now use neutral elevation 2, with
72
+ interaction feedback, matching the D2C card recovery.
73
+
74
+ From `2.7.1-next.6`, app Cards import `useCardPadding` and
75
+ `CardPaddingBoundary` from `@bsuite/page-builder/card-padding`. Read the
76
+ inset before rendering the Card, apply a defined value to its painted surface,
77
+ and wrap its children with a boundary without a padding prop. Inner Cards then
78
+ keep their spacing; a nested grid establishes its own independent inset.
79
+ The grid supplies no child inset when it paints chrome itself. This replaces
80
+ consumer CSS `@scope` rules, which do not cover the supported Safari/Firefox
81
+ baseline. The subpath keeps a standalone Card import separate from grid code.
82
+
61
83
  While the canvas editor is open, each grid item renders an in-flow strip
62
84
  (`[data-slot="grid-item-editor-chrome"]`) above the card content: the widget
63
85
  name and a Hide control. The strip is **not** absolutely positioned over the
@@ -2,5 +2,10 @@ 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
+ /** Ask one mounted canvas to acknowledge its preferences before closing. */
6
+ export declare const PAGE_GRID_SAVE_EVENT = "bsuite-page-grid-save";
7
+ export interface PageGridSaveEventDetail {
8
+ pageKey: string;
9
+ }
5
10
  export declare function PageGridLayout({ pageKey, defaultLayouts, defaultCols, layoutVersion, canEditPage, editorEventNames, preferenceAdapter, widgets, widgetMeta, className, isResizable, resizeHandles, tenantId, defaultAutoHeight, layoutMigrations, itemChrome, addEntityWidgetEventNames, createEntityWidget, onRegisterEntityWidget, relationshipCatalog, addRelationshipWidgetEventNames, createRelationshipWidget, onRegisterRelationshipWidget, onRelationshipWidgetRejected, }: PageGridLayoutProps): React.JSX.Element;
6
11
  //# sourceMappingURL=PageGridLayout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageGridLayout.d.ts","sourceRoot":"","sources":["../src/PageGridLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAQN,MAAM,OAAO,CAAC;AAGf,OAAO,kCAAkC,CAAC;AAC1C,OAAO,gCAAgC,CAAC;AAsBxC,OAAO,KAAK,EAAe,mBAAmB,EAA4B,MAAM,YAAY,CAAC;AAyqB7F,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,EACjB,gBAAgB,EAKhB,UAAkB,EAClB,yBAAiE,EACjE,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,+BAA6E,EAC7E,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,GAC7B,EAAE,mBAAmB,qBAmgCrB"}
1
+ {"version":3,"file":"PageGridLayout.d.ts","sourceRoot":"","sources":["../src/PageGridLayout.tsx"],"names":[],"mappings":"AAGA,OAAO,KAQN,MAAM,OAAO,CAAC;AAGf,OAAO,kCAAkC,CAAC;AAC1C,OAAO,gCAAgC,CAAC;AAsBxC,OAAO,KAAK,EAAe,mBAAmB,EAA4B,MAAM,YAAY,CAAC;AAE7F,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,0BAA0B,CAAC;AAC5D,MAAM,WAAW,uBAAuB;IAAG,OAAO,EAAE,MAAM,CAAA;CAAE;AAsqB5D,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,EACjB,gBAAgB,EAKhB,UAAkB,EAClB,yBAAiE,EACjE,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,+BAA6E,EAC7E,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,GAC7B,EAAE,mBAAmB,qBAkhCrB"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { ElementScopeProvider } from './elementScope.js';
3
+ import { CardPaddingBoundary } from './cardPadding.js';
3
4
  import { ArrowDown, ArrowUp, ChevronDown, ChevronUp, Eye, EyeOff, Layers, LayoutGrid, Lock, Plus, RotateCcw, Save, Settings2, Unlock } from 'lucide-react';
4
5
  import React, { startTransition, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
5
6
  import { Responsive } from 'react-grid-layout';
@@ -12,6 +13,8 @@ import { defaultPreferenceAdapter } from './preferences.js';
12
13
  import { isRelationshipWritable } from './relationshipCatalog.js';
13
14
  import { usePageGridLayout } from './usePageGridLayout.js';
14
15
  import { cn } from './utils.js';
16
+ /** Ask one mounted canvas to acknowledge its preferences before closing. */
17
+ export const PAGE_GRID_SAVE_EVENT = 'bsuite-page-grid-save';
15
18
  /**
16
19
  * Single source of truth for the grid's pixel geometry — read by both the
17
20
  * `<Responsive>` props below AND `GridItem`'s auto-height measurement
@@ -185,7 +188,10 @@ const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, is
185
188
  * of card overflow across 70 sites. An extra element here would have been a
186
189
  * real risk; a provider is not one.
187
190
  */
188
- const scopedContent = (_jsx(ElementScopeProvider, { scope: { pageKey, cardKey: id, cardLabel: label, isEditing }, children: content }));
191
+ const cardPadding = !chrome && cardStyleVars && '--card-padding' in cardStyleVars
192
+ && typeof cardStyleVars['--card-padding'] === 'string'
193
+ ? cardStyleVars['--card-padding'] : undefined;
194
+ const scopedContent = (_jsx(ElementScopeProvider, { scope: { pageKey, cardKey: id, cardLabel: label, isEditing }, children: _jsx(CardPaddingBoundary, { padding: cardPadding, children: content }) }));
189
195
  const measureRef = useRef(null);
190
196
  const surfaceRef = useRef(null);
191
197
  const lastReportedRowsRef = useRef(null);
@@ -330,14 +336,9 @@ const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, is
330
336
  // whose fallbacks are byte-identical to the `border
331
337
  // border-border` they replace, so an operator who has never
332
338
  // opened the card editor sees exactly the previous CSS.
333
- // The shadow deliberately keeps its ORIGINAL classes. An
334
- // elevation choice arrives as an inline `boxShadow`, which
335
- // beats the class without needing a fallback that restates
336
- // `shadow-sm`. Writing that fallback by hand was the first
337
- // attempt and it was wrong: elev-1 is CLOSE to shadow-sm
338
- // but not equal, so it would have silently restyled every
339
- // card on 305 pages the day this shipped.
340
- 'w-full rounded-[var(--radius-card,1.5rem)] transition-all flex flex-col bg-card border-[length:var(--card-border-width,1px)] border-[color:var(--card-border-color,var(--border))] [border-style:var(--card-border-style,solid)] shadow-sm dark:shadow-[var(--glow-card,none)]',
339
+ // Resting elevation and interaction feedback are separate:
340
+ // a selected depth must not suppress hover/focus feedback.
341
+ 'w-full rounded-[var(--radius-card,1.5rem)] transition-all flex flex-col bg-card border-[length:var(--card-border-width,1px)] border-[color:var(--card-border-color,var(--border))] [border-style:var(--card-border-style,solid)] shadow-[var(--card-shadow,var(--shadow-elev-2))] hover:shadow-[var(--card-shadow-interaction,var(--shadow-elev-3))] focus-within:shadow-[var(--card-shadow-interaction,var(--shadow-elev-3))] dark:hover:shadow-[var(--card-shadow-interaction-dark,var(--glow-card-hover))] dark:focus-within:shadow-[var(--card-shadow-interaction-dark,var(--glow-card-hover))]',
341
342
  // THE DOUBLED BOTTOM BORDER, AND WHY THE ARITHMETIC COULD NEVER FIX IT.
342
343
  //
343
344
  // computeAutoHeightRows uses Math.ceil to round content height up to
@@ -367,8 +368,8 @@ const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, is
367
368
  * `cardStyleVars` carries ONLY the properties the operator changed
368
369
  * (see cardStyle.ts). An untouched page spreads an empty object, so
369
370
  * this attribute is identical to what it was before the card editor
370
- * existed. A chrome-owning surface applies `boxShadow` directly
371
- * to beat its default class. Layout-only wrappers pass the token
371
+ * existed. A chrome-owning surface reads shadow tokens in its
372
+ * resting and interaction classes. Layout-only wrappers pass them
372
373
  * to the painted consumer without drawing a second shadow. The
373
374
  * padding marker lets consumer Cards distinguish an explicit page
374
375
  * inset from an app's unrelated default --card-padding token.
@@ -376,9 +377,6 @@ const GridItem = React.memo(React.forwardRef(function GridItem({ id, content, is
376
377
  style: {
377
378
  contain: 'layout style',
378
379
  ...cardStyleVars,
379
- ...(chrome && cardStyleVars && '--card-shadow' in cardStyleVars
380
- ? { boxShadow: cardStyleVars['--card-shadow'] }
381
- : null),
382
380
  ...(chrome && cardStyleVars && '--card-padding' in cardStyleVars
383
381
  ? { padding: cardStyleVars['--card-padding'] }
384
382
  : null),
@@ -411,7 +409,11 @@ itemChrome = false, addEntityWidgetEventNames = DEFAULT_ADD_ENTITY_WIDGET_EVENT_
411
409
  const isSaving = saveState?.pageKey === pageKey && saveState.status === 'saving';
412
410
  const saveFailed = saveState?.pageKey === pageKey && saveState.status === 'failed';
413
411
  const saveAttempt = useRef(0);
414
- useLayoutEffect(() => () => { saveAttempt.current += 1; }, [pageKey, isEditing]);
412
+ const savingAttempt = useRef(null);
413
+ useLayoutEffect(() => () => {
414
+ saveAttempt.current += 1;
415
+ savingAttempt.current = null;
416
+ }, [pageKey, isEditing]);
415
417
  // Auto-height dispatcher (blueprint amendment A1, hardened per quality
416
418
  // review 2026-07-14). `GridItem`'s ResizeObserver calls this per-widget
417
419
  // whenever its measured content height changes; we rAF-batch and flush ALL
@@ -493,9 +495,10 @@ itemChrome = false, addEntityWidgetEventNames = DEFAULT_ADD_ENTITY_WIDGET_EVENT_
493
495
  const cardStyleVars = useMemo(() => toCssVars(cardStyle), [cardStyle]);
494
496
  const updateCardStyle = useCallback((patch) => setStoredCardStyle((previous) => ({ ...normaliseCardStyle(previous), ...patch })), [setStoredCardStyle]);
495
497
  const saveAndExit = useCallback(async () => {
496
- if (isSaving)
498
+ if (canEditPage === false || !isEditing || savingAttempt.current !== null)
497
499
  return;
498
500
  const attempt = ++saveAttempt.current;
501
+ savingAttempt.current = attempt;
499
502
  setSaveState({ pageKey, status: 'saving' });
500
503
  try {
501
504
  await Promise.all([flushPreferences(), flushLayerNames?.(), flushHiddenLayers?.(), flushCardStyle?.()]);
@@ -508,7 +511,20 @@ itemChrome = false, addEntityWidgetEventNames = DEFAULT_ADD_ENTITY_WIDGET_EVENT_
508
511
  if (attempt === saveAttempt.current)
509
512
  setSaveState({ pageKey, status: 'failed' });
510
513
  }
511
- }, [isSaving, pageKey, flushPreferences, flushLayerNames, flushHiddenLayers, flushCardStyle, setIsEditing]);
514
+ finally {
515
+ if (savingAttempt.current === attempt)
516
+ savingAttempt.current = null;
517
+ }
518
+ }, [canEditPage, isEditing, pageKey, flushPreferences, flushLayerNames, flushHiddenLayers, flushCardStyle, setIsEditing]);
519
+ useEffect(() => {
520
+ const onSaveRequest = (event) => {
521
+ const detail = event.detail;
522
+ if (detail?.pageKey === pageKey)
523
+ void saveAndExit();
524
+ };
525
+ window.addEventListener(PAGE_GRID_SAVE_EVENT, onSaveRequest);
526
+ return () => window.removeEventListener(PAGE_GRID_SAVE_EVENT, onSaveRequest);
527
+ }, [pageKey, saveAndExit]);
512
528
  const extraWidgets = useMemo(() => {
513
529
  const rendered = {};
514
530
  if (!createEntityWidget)
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * A grid offers its inset to the first app Card. That Card places a boundary
4
+ * around its children so inner panels keep their own spacing. A nested grid
5
+ * supplies a new value, including undefined when its inset is not overridden.
6
+ * No DOM wrapper or browser-specific CSS scoping is needed.
7
+ */
8
+ export declare function CardPaddingBoundary({ padding, children }: {
9
+ padding?: string;
10
+ children: ReactNode;
11
+ }): import("react").JSX.Element;
12
+ export declare function useCardPadding(): string | undefined;
13
+ //# sourceMappingURL=cardPadding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cardPadding.d.ts","sourceRoot":"","sources":["../src/cardPadding.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlE;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAEnG;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD"}
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext } from 'react';
4
+ const CardPaddingContext = createContext(undefined);
5
+ /**
6
+ * A grid offers its inset to the first app Card. That Card places a boundary
7
+ * around its children so inner panels keep their own spacing. A nested grid
8
+ * supplies a new value, including undefined when its inset is not overridden.
9
+ * No DOM wrapper or browser-specific CSS scoping is needed.
10
+ */
11
+ export function CardPaddingBoundary({ padding, children }) {
12
+ return _jsx(CardPaddingContext.Provider, { value: padding, children: children });
13
+ }
14
+ export function useCardPadding() {
15
+ return useContext(CardPaddingContext);
16
+ }
@@ -26,9 +26,8 @@ export interface CardStyle {
26
26
  *
27
27
  * `radius: 24` is `1.5rem`, the existing `--radius-card` fallback.
28
28
  * `borderWidth: 1` + `borderTone: 'border'` is the existing `border
29
- * border-border`. `elevation: null` preserves `shadow-sm` and the dark-mode
30
- * `--glow-card` rule rather than replacing them with an elevation token that
31
- * is close but not equal.
29
+ * border-border`. `elevation: null` leaves the component's resting and
30
+ * interaction defaults in place; an explicit zero opts out of both.
32
31
  */
33
32
  export declare const DEFAULT_CARD_STYLE: CardStyle;
34
33
  export declare const RADIUS_RANGE: {
@@ -1 +1 @@
1
- {"version":3,"file":"cardStyle.d.ts","sourceRoot":"","sources":["../src/cardStyle.ts"],"names":[],"mappings":"AA0BA,4EAA4E;AAC5E,eAAO,MAAM,YAAY,iFAOf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,aAAa,gDAAiD,CAAC;AAC5E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,gEAAgE;AAChE,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB;;;OAGG;IACH,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAOhC,CAAC;AAEF,eAAO,MAAM,YAAY;;;CAA+B,CAAC;AACzD,eAAO,MAAM,kBAAkB;;;CAA8B,CAAC;AAC9D,eAAO,MAAM,aAAa;;;CAA+B,CAAC;AAO1D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CA8B5D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAS5D;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC,aAAa,CAuB/D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAc1D"}
1
+ {"version":3,"file":"cardStyle.d.ts","sourceRoot":"","sources":["../src/cardStyle.ts"],"names":[],"mappings":"AA0BA,4EAA4E;AAC5E,eAAO,MAAM,YAAY,iFAOf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,aAAa,gDAAiD,CAAC;AAC5E,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,gEAAgE;AAChE,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB;;;OAGG;IACH,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAOhC,CAAC;AAEF,eAAO,MAAM,YAAY;;;CAA+B,CAAC;AACzD,eAAO,MAAM,kBAAkB;;;CAA8B,CAAC;AAC9D,eAAO,MAAM,aAAa;;;CAA+B,CAAC;AAO1D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CA8B5D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAS5D;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC,aAAa,CA8B/D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAc1D"}
package/dist/cardStyle.js CHANGED
@@ -12,9 +12,9 @@
12
12
  * THE DEFAULT IS "DON'T EMIT ANYTHING". `toCssVars` returns only the
13
13
  * properties that DIFFER from `DEFAULT_CARD_STYLE`, and the chrome element
14
14
  * falls back to exactly the values it used before this file existed. A page
15
- * whose operator has never opened the editor therefore renders byte-identical
16
- * CSS — this is a capability, not a restyle, and it must not show up as a
17
- * visual diff on 305 pages the day it ships.
15
+ * whose operator has never opened the editor uses the component defaults.
16
+ * The September 2026 recovery intentionally makes those defaults visibly
17
+ * elevated; appearance settings do not have to be entered to enable shadows.
18
18
  *
19
19
  * TOKENS, NOT COLOURS. `borderTone` names a theme token, never a literal.
20
20
  * The estate bans hex/rgb in D2C apps (`bsuite/no-hardcoded-colours`) and the
@@ -38,9 +38,8 @@ export const BORDER_STYLES = ['solid', 'dashed', 'dotted', 'none'];
38
38
  *
39
39
  * `radius: 24` is `1.5rem`, the existing `--radius-card` fallback.
40
40
  * `borderWidth: 1` + `borderTone: 'border'` is the existing `border
41
- * border-border`. `elevation: null` preserves `shadow-sm` and the dark-mode
42
- * `--glow-card` rule rather than replacing them with an elevation token that
43
- * is close but not equal.
41
+ * border-border`. `elevation: null` leaves the component's resting and
42
+ * interaction defaults in place; an explicit zero opts out of both.
44
43
  */
45
44
  export const DEFAULT_CARD_STYLE = {
46
45
  radius: 24,
@@ -121,7 +120,14 @@ export function toCssVars(style) {
121
120
  vars['--card-border-style'] = style.borderStyle;
122
121
  }
123
122
  if (style.elevation !== null) {
124
- vars['--card-shadow'] = `var(--shadow-elev-${style.elevation})`;
123
+ const resting = `var(--shadow-elev-${style.elevation})`;
124
+ vars['--card-shadow'] = resting;
125
+ // Preserve the selected depth while adding visible feedback, including
126
+ // at the top of the ramp. Explicit zero remains flat in every state.
127
+ vars['--card-shadow-interaction'] = style.elevation === 0
128
+ ? resting : `${resting}, var(--shadow-elev-1)`;
129
+ vars['--card-shadow-interaction-dark'] = style.elevation === 0
130
+ ? resting : `${resting}, var(--glow-card-hover)`;
125
131
  }
126
132
  if (style.padding !== null) {
127
133
  vars['--card-padding'] = `${style.padding}px`;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { PageGridLayout } from './PageGridLayout.js';
1
+ export { PageGridLayout, PAGE_GRID_SAVE_EVENT } from './PageGridLayout.js';
2
+ export { CardPaddingBoundary, useCardPadding } from './cardPadding.js';
3
+ export type { PageGridSaveEventDetail } from './PageGridLayout.js';
2
4
  export { PageEditorLauncher } from './PageEditorLauncher.js';
3
5
  export { CanvasCard } from './CanvasCard.js';
4
6
  export type { CanvasCardProps } from './CanvasCard.js';
@@ -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;AAwB7C,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,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,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,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,IAAI,kBAAkB,EAC/B,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQpF,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- export { PageGridLayout } from './PageGridLayout.js';
1
+ export { PageGridLayout, PAGE_GRID_SAVE_EVENT } from './PageGridLayout.js';
2
+ export { CardPaddingBoundary, useCardPadding } from './cardPadding.js';
2
3
  export { PageEditorLauncher } from './PageEditorLauncher.js';
3
4
  export { CanvasCard } from './CanvasCard.js';
4
5
  export { DraggableCardPage } from './DraggableCardPage.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsuite/page-builder",
3
- "version": "2.7.1-next.4",
3
+ "version": "2.7.1-next.6",
4
4
  "description": "Shared BSuite responsive page-builder grid and layout persistence primitives",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -24,6 +24,10 @@
24
24
  "types": "./dist/index.d.ts"
25
25
  },
26
26
  "./styles.css": "./src/styles/react-grid-layout-overrides.css",
27
+ "./card-padding": {
28
+ "import": "./dist/cardPadding.js",
29
+ "types": "./dist/cardPadding.d.ts"
30
+ },
27
31
  "./scanner": {
28
32
  "import": "./dist/scanner/index.js",
29
33
  "types": "./dist/scanner/index.d.ts"