@drawnagency/primitives 0.1.75 → 0.1.76

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.
@@ -536,6 +536,7 @@ var ChildBlockWrapper = forwardRef(
536
536
  onDuplicate,
537
537
  onColSpanChange,
538
538
  onOpenSettings,
539
+ clearSectionChrome,
539
540
  children
540
541
  }, ref) {
541
542
  return /* @__PURE__ */ jsxs4(
@@ -548,23 +549,33 @@ var ChildBlockWrapper = forwardRef(
548
549
  "hover:outline hover:outline-2 hover:outline-primary/30"
549
550
  ),
550
551
  children: [
551
- /* @__PURE__ */ jsxs4("div", { className: "absolute top-0 left-0 -translate-x-full z-20 flex flex-col items-center gap-1 opacity-0 transition-opacity group-hover/childblock:opacity-100 group-focus-within/childblock:opacity-100 pointer-events-none", children: [
552
- /* @__PURE__ */ jsx12("span", { className: "sr-only", children: label }),
553
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DragHandle, { ref: dragHandleRef }) }),
554
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(ColSpanControl, { colSpan, columns, onChange: onColSpanChange }) }),
555
- hasSettings && onOpenSettings && /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(SettingsButton, { onClick: onOpenSettings }) }),
556
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(
557
- "button",
558
- {
559
- type: "button",
560
- "aria-label": "Duplicate block",
561
- onClick: onDuplicate,
562
- className: "cursor-pointer rounded p-1 text-base-contrast-light hover:text-primary",
563
- children: /* @__PURE__ */ jsx12(CopyPlus, { size: 16 })
564
- }
565
- ) }),
566
- /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DeleteButton, { onDelete }) })
567
- ] }),
552
+ /* @__PURE__ */ jsxs4(
553
+ "div",
554
+ {
555
+ "data-testid": "child-control-rail",
556
+ className: cn(
557
+ "absolute left-0 -translate-x-full z-20 flex flex-col items-center gap-1 opacity-0 transition-opacity group-hover/childblock:opacity-100 group-focus-within/childblock:opacity-100 pointer-events-none",
558
+ clearSectionChrome ? "top-8 xl:top-0" : "top-0"
559
+ ),
560
+ children: [
561
+ /* @__PURE__ */ jsx12("span", { className: "sr-only", children: label }),
562
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DragHandle, { ref: dragHandleRef }) }),
563
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(ColSpanControl, { colSpan, columns, onChange: onColSpanChange }) }),
564
+ hasSettings && onOpenSettings && /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(SettingsButton, { onClick: onOpenSettings }) }),
565
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(
566
+ "button",
567
+ {
568
+ type: "button",
569
+ "aria-label": "Duplicate block",
570
+ onClick: onDuplicate,
571
+ className: "cursor-pointer rounded p-1 text-base-contrast-light hover:text-primary",
572
+ children: /* @__PURE__ */ jsx12(CopyPlus, { size: 16 })
573
+ }
574
+ ) }),
575
+ /* @__PURE__ */ jsx12("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx12(DeleteButton, { onDelete }) })
576
+ ]
577
+ }
578
+ ),
568
579
  closestEdge === "left" && /* @__PURE__ */ jsx12(
569
580
  "div",
570
581
  {
@@ -764,6 +775,7 @@ function ContainerChild({
764
775
  hasSettings,
765
776
  mergedOptions,
766
777
  isEditMode,
778
+ clearSectionChrome,
767
779
  ChildComp,
768
780
  onDelete,
769
781
  onDuplicate,
@@ -797,6 +809,7 @@ function ContainerChild({
797
809
  closestEdge,
798
810
  isDragging,
799
811
  hasSettings,
812
+ clearSectionChrome,
800
813
  dragHandleRef: handleRef,
801
814
  onDelete,
802
815
  onDuplicate,
@@ -956,6 +969,7 @@ function Container({ content, isEditMode, onChange, openModal }) {
956
969
  hasSettings,
957
970
  mergedOptions,
958
971
  isEditMode,
972
+ clearSectionChrome: index === 0,
959
973
  ChildComp: def.component,
960
974
  onDelete: () => emit(trimTrailingSpacers(removeChildAt(container, index).container)),
961
975
  onDuplicate: () => emit(duplicateChildAt(container, index, newId)),
@@ -969,7 +983,7 @@ function Container({ content, isEditMode, onChange, openModal }) {
969
983
  }
970
984
  const occupied = occupiedColumns(children, columns);
971
985
  const emptyCols = occupied < columns ? columns - occupied : 0;
972
- return /* @__PURE__ */ jsx13("div", { className: "@container", children: /* @__PURE__ */ jsxs5("div", { className: cn(gridClass, "pt-8 xl:pt-0"), children: [
986
+ return /* @__PURE__ */ jsx13("div", { className: "@container", children: /* @__PURE__ */ jsxs5("div", { className: gridClass, children: [
973
987
  children.map(renderEditChild),
974
988
  Array.from({ length: emptyCols }, (_, i) => /* @__PURE__ */ jsx13(
975
989
  EmptyColumnCell,
@@ -13,6 +13,13 @@ export interface ChildBlockWrapperProps {
13
13
  onDuplicate: () => void;
14
14
  onColSpanChange: (span: number) => void;
15
15
  onOpenSettings?: () => void;
16
+ /**
17
+ * Below xl the parent SECTION's "+" hangs down into the left gutter where this
18
+ * rail starts — set on the container's first cell so the rail (not the cell)
19
+ * shifts down out of the collision. Cells never move: edit-mode layout must
20
+ * match view mode exactly.
21
+ */
22
+ clearSectionChrome?: boolean;
16
23
  children: ReactNode;
17
24
  }
18
25
  export declare const ChildBlockWrapper: import("react").ForwardRefExoticComponent<ChildBlockWrapperProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"ChildBlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/editor/ChildBlockWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uDAAuD,CAAC;AAQlF,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,iBAAiB,mHAkF7B,CAAC"}
1
+ {"version":3,"file":"ChildBlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/components/editor/ChildBlockWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uDAAuD,CAAC;AAQlF,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,iBAAiB,mHAyF7B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../../../src/components/sections/Container/Container.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgB3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAqGzD,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,gBAAgB,CAAA;KAAE,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;CACzD;AAkDD,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,2CA2LrF"}
1
+ {"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../../../src/components/sections/Container/Container.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgB3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAyGzD,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,gBAAgB,CAAA;KAAE,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;CACzD;AAkDD,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,2CAyLrF"}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  allSectionDefs
3
- } from "../../chunk-U4E6S4PX.js";
3
+ } from "../../chunk-SWEVWC5K.js";
4
4
  import "../../chunk-NKVZGPR6.js";
5
5
  import "../../chunk-Y4JQGO6G.js";
6
6
  import "../../chunk-7T2WQSWF.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  allSectionDefs
3
- } from "../../chunk-U4E6S4PX.js";
3
+ } from "../../chunk-SWEVWC5K.js";
4
4
  import "../../chunk-NKVZGPR6.js";
5
5
  import "../../chunk-Y4JQGO6G.js";
6
6
  import "../../chunk-7T2WQSWF.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawnagency/primitives",
3
- "version": "0.1.75",
3
+ "version": "0.1.76",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -20,6 +20,13 @@ export interface ChildBlockWrapperProps {
20
20
  onDuplicate: () => void;
21
21
  onColSpanChange: (span: number) => void;
22
22
  onOpenSettings?: () => void;
23
+ /**
24
+ * Below xl the parent SECTION's "+" hangs down into the left gutter where this
25
+ * rail starts — set on the container's first cell so the rail (not the cell)
26
+ * shifts down out of the collision. Cells never move: edit-mode layout must
27
+ * match view mode exactly.
28
+ */
29
+ clearSectionChrome?: boolean;
23
30
  children: ReactNode;
24
31
  }
25
32
 
@@ -37,6 +44,7 @@ export const ChildBlockWrapper = forwardRef<HTMLDivElement, ChildBlockWrapperPro
37
44
  onDuplicate,
38
45
  onColSpanChange,
39
46
  onOpenSettings,
47
+ clearSectionChrome,
40
48
  children,
41
49
  },
42
50
  ref,
@@ -53,7 +61,13 @@ export const ChildBlockWrapper = forwardRef<HTMLDivElement, ChildBlockWrapperPro
53
61
  {/* Controls — vertical rail in the cell's LEFT gutter. Revealed on hover OR
54
62
  focus-within, so an open col-span popover (which traps focus) keeps the rail
55
63
  visible even when the pointer moves off the block to reach an option. */}
56
- <div className="absolute top-0 left-0 -translate-x-full z-20 flex flex-col items-center gap-1 opacity-0 transition-opacity group-hover/childblock:opacity-100 group-focus-within/childblock:opacity-100 pointer-events-none">
64
+ <div
65
+ data-testid="child-control-rail"
66
+ className={cn(
67
+ "absolute left-0 -translate-x-full z-20 flex flex-col items-center gap-1 opacity-0 transition-opacity group-hover/childblock:opacity-100 group-focus-within/childblock:opacity-100 pointer-events-none",
68
+ clearSectionChrome ? "top-8 xl:top-0" : "top-0",
69
+ )}
70
+ >
57
71
  <span className="sr-only">{label}</span>
58
72
  <div className="pointer-events-auto">
59
73
  <DragHandle ref={dragHandleRef} />
@@ -40,6 +40,8 @@ interface ContainerChildProps {
40
40
  hasSettings: boolean;
41
41
  mergedOptions: Record<string, unknown>;
42
42
  isEditMode: boolean;
43
+ /** First cell only: shift the control rail below the section's stacked "+" (below xl). */
44
+ clearSectionChrome?: boolean;
43
45
  ChildComp: ChildComponent;
44
46
  onDelete: () => void;
45
47
  onDuplicate: () => void;
@@ -65,6 +67,7 @@ function ContainerChild({
65
67
  hasSettings,
66
68
  mergedOptions,
67
69
  isEditMode,
70
+ clearSectionChrome,
68
71
  ChildComp,
69
72
  onDelete,
70
73
  onDuplicate,
@@ -97,6 +100,7 @@ function ContainerChild({
97
100
  closestEdge={closestEdge}
98
101
  isDragging={isDragging}
99
102
  hasSettings={hasSettings}
103
+ clearSectionChrome={clearSectionChrome}
100
104
  dragHandleRef={handleRef}
101
105
  onDelete={onDelete}
102
106
  onDuplicate={onDuplicate}
@@ -328,6 +332,7 @@ export function Container({ content, isEditMode, onChange, openModal }: Containe
328
332
  hasSettings={hasSettings}
329
333
  mergedOptions={mergedOptions}
330
334
  isEditMode={isEditMode}
335
+ clearSectionChrome={index === 0}
331
336
  ChildComp={def.component as ChildComponent}
332
337
  onDelete={() => emit(trimTrailingSpacers(removeChildAt(container, index).container))}
333
338
  onDuplicate={() => emit(duplicateChildAt(container, index, newId))}
@@ -348,10 +353,7 @@ export function Container({ content, isEditMode, onChange, openModal }: Containe
348
353
  const emptyCols = occupied < columns ? columns - occupied : 0;
349
354
  return (
350
355
  <div className="@container">
351
- {/* Below xl the section's "+" stacks under the drag handle and hangs down
352
- into the left gutter, where the first child's control rail would collide
353
- with it — push children down until the gutter is side-by-side again. */}
354
- <div className={cn(gridClass, "pt-8 xl:pt-0")}>
356
+ <div className={gridClass}>
355
357
  {children.map(renderEditChild)}
356
358
  {Array.from({ length: emptyCols }, (_, i) => (
357
359
  <EmptyColumnCell