@drawnagency/primitives 0.1.89 → 0.1.90

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.
Files changed (83) hide show
  1. package/dist/{chunk-75P6HWPN.js → chunk-5BM2Y3NJ.js} +5 -3
  2. package/dist/{chunk-VK5KNH73.js → chunk-AGWE2LJG.js} +2 -2
  3. package/dist/{chunk-2QXJ2KGB.js → chunk-KBQNJZUX.js} +1 -1
  4. package/dist/{chunk-WCBYXNAG.js → chunk-KMQZYORS.js} +1 -0
  5. package/dist/{chunk-Y24T75HT.js → chunk-MK7YB2A4.js} +1 -1
  6. package/dist/{chunk-QFV5TSPO.js → chunk-SIYQ37QY.js} +12 -4
  7. package/dist/{chunk-J75XGXYD.js → chunk-XKRQMTE4.js} +9 -0
  8. package/dist/{chunk-L2MAJKKC.js → chunk-XUIJHYKI.js} +2 -2
  9. package/dist/{chunk-MVX4ULYE.js → chunk-ZLG7S54V.js} +241 -82
  10. package/dist/components/editor/AudienceIndicator.d.ts +6 -0
  11. package/dist/components/editor/AudienceIndicator.d.ts.map +1 -1
  12. package/dist/components/editor/ChildBlockWrapper.d.ts.map +1 -1
  13. package/dist/components/editor/ColSpanControl.d.ts.map +1 -1
  14. package/dist/components/editor/DragHandle.d.ts +3 -1
  15. package/dist/components/editor/DragHandle.d.ts.map +1 -1
  16. package/dist/components/editor/SectionWrapper.d.ts.map +1 -1
  17. package/dist/components/editor/StatusIndicator.d.ts +7 -0
  18. package/dist/components/editor/StatusIndicator.d.ts.map +1 -1
  19. package/dist/components/editor/index.js +98 -76
  20. package/dist/components/primitives/index.js +3 -3
  21. package/dist/components/sections/Container/Container.d.ts +3 -2
  22. package/dist/components/sections/Container/Container.d.ts.map +1 -1
  23. package/dist/components/sections/Container/ContainerSettingsForm.d.ts +4 -2
  24. package/dist/components/sections/Container/ContainerSettingsForm.d.ts.map +1 -1
  25. package/dist/components/sections/Container/index.d.ts +8 -2
  26. package/dist/components/sections/Container/index.d.ts.map +1 -1
  27. package/dist/components/sections/SectionLayout.d.ts +3 -1
  28. package/dist/components/sections/SectionLayout.d.ts.map +1 -1
  29. package/dist/components/sections/ViewRenderer.d.ts +3 -1
  30. package/dist/components/sections/ViewRenderer.d.ts.map +1 -1
  31. package/dist/components/sections/all-sections.d.ts +8 -2
  32. package/dist/components/sections/all-sections.d.ts.map +1 -1
  33. package/dist/components/sections/brand-guide.js +3 -3
  34. package/dist/components/sections/core-sections.d.ts +8 -2
  35. package/dist/components/sections/core-sections.d.ts.map +1 -1
  36. package/dist/components/sections/register-schemas.js +6 -6
  37. package/dist/components/sections/register.js +6 -6
  38. package/dist/components/shared/Tooltip.d.ts +8 -1
  39. package/dist/components/shared/Tooltip.d.ts.map +1 -1
  40. package/dist/components/shell/AudiencePreviewMenu.d.ts +7 -0
  41. package/dist/components/shell/AudiencePreviewMenu.d.ts.map +1 -0
  42. package/dist/components/shell/AuthoringDefaultsMenu.d.ts +10 -0
  43. package/dist/components/shell/AuthoringDefaultsMenu.d.ts.map +1 -0
  44. package/dist/components/shell/EditorContext.d.ts +3 -0
  45. package/dist/components/shell/EditorContext.d.ts.map +1 -1
  46. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  47. package/dist/components/shell/SiteSettingsChatbot.d.ts.map +1 -1
  48. package/dist/hooks/useBuildStatus.d.ts.map +1 -1
  49. package/dist/index.js +6 -4
  50. package/dist/lib/authoring-defaults.d.ts +17 -0
  51. package/dist/lib/authoring-defaults.d.ts.map +1 -0
  52. package/dist/lib/container-grid.d.ts +6 -0
  53. package/dist/lib/container-grid.d.ts.map +1 -1
  54. package/dist/lib/index.js +3 -3
  55. package/dist/lib/migrate-sections-transform.js +1 -1
  56. package/dist/media/index.js +1 -1
  57. package/dist/schemas/index.js +4 -2
  58. package/dist/schemas/site-config.d.ts +6 -0
  59. package/dist/schemas/site-config.d.ts.map +1 -1
  60. package/package.json +1 -1
  61. package/src/components/editor/AudienceIndicator.tsx +50 -37
  62. package/src/components/editor/ChildBlockWrapper.tsx +8 -7
  63. package/src/components/editor/ColSpanControl.tsx +14 -11
  64. package/src/components/editor/DragHandle.tsx +5 -2
  65. package/src/components/editor/PagesModal.tsx +10 -10
  66. package/src/components/editor/SectionWrapper.tsx +32 -21
  67. package/src/components/editor/StatusIndicator.tsx +37 -24
  68. package/src/components/sections/Container/Container.tsx +185 -43
  69. package/src/components/sections/Container/ContainerSettingsForm.tsx +64 -24
  70. package/src/components/sections/Container/index.tsx +45 -20
  71. package/src/components/sections/SectionLayout.tsx +13 -3
  72. package/src/components/sections/ViewRenderer.tsx +11 -2
  73. package/src/components/shared/Tooltip.tsx +18 -2
  74. package/src/components/shell/AudiencePreviewMenu.tsx +73 -0
  75. package/src/components/shell/AuthoringDefaultsMenu.tsx +54 -0
  76. package/src/components/shell/EditorContext.tsx +5 -1
  77. package/src/components/shell/EditorShell.tsx +59 -12
  78. package/src/components/shell/SiteSettingsChatbot.tsx +2 -1
  79. package/src/hooks/useBuildStatus.ts +35 -4
  80. package/src/lib/authoring-defaults.ts +42 -0
  81. package/src/lib/container-grid.ts +14 -0
  82. package/src/lib/migrate-sections-transform.ts +5 -3
  83. package/src/schemas/site-config.ts +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthoringDefaultsMenu.d.ts","sourceRoot":"","sources":["../../../src/components/shell/AuthoringDefaultsMenu.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,UAAU,0BAA0B;IAClC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,0BAA0B,2CAsClG"}
@@ -14,11 +14,14 @@ interface EditorContextValue {
14
14
  viewBranch: "saved" | "live";
15
15
  historyState: HistoryState;
16
16
  historyPageId: string | null;
17
+ /** Audience-preview mode: dim sections this audience can't access. null = off. */
18
+ previewAudience: string | null;
17
19
  toggleEditMode: () => void;
18
20
  toggleShowAllChrome: () => void;
19
21
  setViewBranch: (branch: "saved" | "live") => void;
20
22
  setHistoryState: (state: HistoryState) => void;
21
23
  setHistoryPageId: (pageId: string | null) => void;
24
+ setPreviewAudience: (audience: string | null) => void;
22
25
  }
23
26
  interface EditorProviderProps {
24
27
  children: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB,GAAG,IAAI,CAAC;AAET,UAAU,kBAAkB;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACnD;AAID,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CA4B/D;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD"}
1
+ {"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;CACxB,GAAG,IAAI,CAAC;AAET,UAAU,kBAAkB;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kFAAkF;IAClF,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACvD;AAID,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CA6B/D;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAcjD,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAuDtF,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAmCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CA2lDP;AAuED;6EAC6E;AAC7E,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,eAAe,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK/B"}
1
+ {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAcjD,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAuDtF,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAuCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CA0mDP;AAuED;6EAC6E;AAC7E,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,eAAe,EAAE,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"SiteSettingsChatbot.d.ts","sourceRoot":"","sources":["../../../src/components/shell/SiteSettingsChatbot.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA8B,MAAM,2BAA2B,CAAC;AACxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAcjD,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,kBAAkB,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACjD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAsBD,wBAAgB,mBAAmB,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,KAAK,2CA4LxG"}
1
+ {"version":3,"file":"SiteSettingsChatbot.d.ts","sourceRoot":"","sources":["../../../src/components/shell/SiteSettingsChatbot.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAA8B,MAAM,2BAA2B,CAAC;AACxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAcjD,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,kBAAkB,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACjD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAsBD,wBAAgB,mBAAmB,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,KAAK,2CA4LxG"}
@@ -1 +1 @@
1
- {"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AASrE,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAUD,wBAAgB,cAAc,IAAI,iBAAiB,CA2IlD"}
1
+ {"version":3,"file":"useBuildStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useBuildStatus.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AASrE,UAAU,iBAAiB;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAkBD,wBAAgB,cAAc,IAAI,iBAAiB,CAkKlD"}
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ import {
51
51
  AudienceNameSchema,
52
52
  MediaGridOptionsSchema,
53
53
  slugifyAudienceName
54
- } from "./chunk-Y24T75HT.js";
54
+ } from "./chunk-MK7YB2A4.js";
55
55
  import {
56
56
  AudienceSchema,
57
57
  RoleSchema,
@@ -77,7 +77,7 @@ import {
77
77
  resolveChatbotName,
78
78
  resolveThinkingPhrases,
79
79
  safeRedirect
80
- } from "./chunk-VK5KNH73.js";
80
+ } from "./chunk-AGWE2LJG.js";
81
81
  import {
82
82
  curatedIcons,
83
83
  getIcon
@@ -105,7 +105,7 @@ import {
105
105
  import {
106
106
  audiencePasses
107
107
  } from "./chunk-YBVK254P.js";
108
- import "./chunk-75P6HWPN.js";
108
+ import "./chunk-5BM2Y3NJ.js";
109
109
  import {
110
110
  getSectionContentSchema,
111
111
  getSectionSchema
@@ -127,10 +127,11 @@ import {
127
127
  SectionMetaSchema,
128
128
  SingleMediaReferenceSchema,
129
129
  SiteConfigSchema,
130
+ StatusSchema,
130
131
  TextLineSchema,
131
132
  VariantSchema,
132
133
  normalizeSiteIndex
133
- } from "./chunk-WCBYXNAG.js";
134
+ } from "./chunk-KMQZYORS.js";
134
135
  import {
135
136
  clearRegistry,
136
137
  createRegistry,
@@ -202,6 +203,7 @@ export {
202
203
  SingleMediaReferenceSchema,
203
204
  SiteConfigSchema,
204
205
  SiteUserSchema,
206
+ StatusSchema,
205
207
  StorageConflictError,
206
208
  TakeoverMessageSchema,
207
209
  TextLineSchema,
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ import type { Audience } from "../auth/types";
3
+ export declare const AuthoringDefaultsSchema: z.ZodObject<{
4
+ status: z.ZodPipe<z.ZodEnum<{
5
+ draft: "draft";
6
+ live: "live";
7
+ archived: "archived";
8
+ published: "published";
9
+ }>, z.ZodTransform<"draft" | "live" | "archived", "draft" | "live" | "archived" | "published">>;
10
+ access: z.ZodArray<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ export type AuthoringDefaults = z.infer<typeof AuthoringDefaultsSchema>;
13
+ export declare const FALLBACK_AUTHORING_DEFAULTS: AuthoringDefaults;
14
+ export declare function loadAuthoringDefaults(): AuthoringDefaults;
15
+ export declare function saveAuthoringDefaults(defaults: AuthoringDefaults): void;
16
+ export declare function filterAccessToKnown(access: string[], audiences: Audience[]): string[];
17
+ //# sourceMappingURL=authoring-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring-defaults.d.ts","sourceRoot":"","sources":["../../src/lib/authoring-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,uBAAuB;;;;;;;;iBAGlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,2BAA2B,EAAE,iBAAmD,CAAC;AAM9F,wBAAgB,qBAAqB,IAAI,iBAAiB,CASzD;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAOvE;AAID,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAErF"}
@@ -19,6 +19,12 @@ export declare const colSpanClass: Record<number, Record<number, string>>;
19
19
  /** Gap token -> Tailwind gap class. Retained as a utility; the container now uses a
20
20
  * fixed gap (the Gap setting was removed), but the map stays for general use. */
21
21
  export declare const gapClass: Record<string, string>;
22
+ /**
23
+ * Column count -> `columns-N` classes for masonry (CSS multi-column), mirroring
24
+ * `containerGridClass`'s collapse curve (`grid-cols-`→`columns-`). Full static
25
+ * strings so Tailwind's source scan generates them.
26
+ */
27
+ export declare const masonryColumnsClass: Record<number, string>;
22
28
  /**
23
29
  * Per-column-count container-query classes that HIDE a spacer cell once the container
24
30
  * collapses to a single column (mobile). Mirrors `containerGridClass`'s collapse curve:
@@ -1 +1 @@
1
- {"version":3,"file":"container-grid.d.ts","sourceRoot":"","sources":["../../src/lib/container-grid.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOrD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO/D,CAAC;AAEF;kFACkF;AAClF,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK3C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOpD,CAAC"}
1
+ {"version":3,"file":"container-grid.d.ts","sourceRoot":"","sources":["../../src/lib/container-grid.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOrD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO/D,CAAC;AAEF;kFACkF;AAClF,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK3C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOtD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOpD,CAAC"}
package/dist/lib/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  resolveChatbotName,
12
12
  resolveThinkingPhrases,
13
13
  safeRedirect
14
- } from "../chunk-VK5KNH73.js";
14
+ } from "../chunk-AGWE2LJG.js";
15
15
  import {
16
16
  curatedIcons,
17
17
  getIcon
@@ -35,9 +35,9 @@ import "../chunk-S2L3BPLS.js";
35
35
  import {
36
36
  audiencePasses
37
37
  } from "../chunk-YBVK254P.js";
38
- import "../chunk-75P6HWPN.js";
38
+ import "../chunk-5BM2Y3NJ.js";
39
39
  import "../chunk-TZQPOR5A.js";
40
- import "../chunk-WCBYXNAG.js";
40
+ import "../chunk-KMQZYORS.js";
41
41
  import {
42
42
  clearRegistry,
43
43
  createRegistry,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  upgradeLegacySection
3
- } from "../chunk-75P6HWPN.js";
3
+ } from "../chunk-5BM2Y3NJ.js";
4
4
  import "../chunk-JSBRDJBE.js";
5
5
  export {
6
6
  upgradeLegacySection
@@ -26,7 +26,7 @@ import {
26
26
  MediaFolderSchema,
27
27
  MediaItemSchema,
28
28
  VariantSchema
29
- } from "../chunk-WCBYXNAG.js";
29
+ } from "../chunk-KMQZYORS.js";
30
30
  import "../chunk-FM4M4Q2W.js";
31
31
  import "../chunk-JSBRDJBE.js";
32
32
  export {
@@ -3,7 +3,7 @@ import {
3
3
  AudienceNameSchema,
4
4
  MediaGridOptionsSchema,
5
5
  slugifyAudienceName
6
- } from "../chunk-Y24T75HT.js";
6
+ } from "../chunk-MK7YB2A4.js";
7
7
  import {
8
8
  AudienceSchema,
9
9
  RoleSchema,
@@ -37,10 +37,11 @@ import {
37
37
  SectionMetaSchema,
38
38
  SingleMediaReferenceSchema,
39
39
  SiteConfigSchema,
40
+ StatusSchema,
40
41
  TextLineSchema,
41
42
  VariantSchema,
42
43
  normalizeSiteIndex
43
- } from "../chunk-WCBYXNAG.js";
44
+ } from "../chunk-KMQZYORS.js";
44
45
  import "../chunk-VKAGMEKE.js";
45
46
  import "../chunk-FM4M4Q2W.js";
46
47
  import "../chunk-NSCT3AMV.js";
@@ -72,6 +73,7 @@ export {
72
73
  SingleMediaReferenceSchema,
73
74
  SiteConfigSchema,
74
75
  SiteUserSchema,
76
+ StatusSchema,
75
77
  TextLineSchema,
76
78
  VariantSchema,
77
79
  getSectionContentSchema,
@@ -1,4 +1,10 @@
1
1
  import { z } from "zod";
2
+ export declare const StatusSchema: z.ZodPipe<z.ZodEnum<{
3
+ draft: "draft";
4
+ live: "live";
5
+ archived: "archived";
6
+ published: "published";
7
+ }>, z.ZodTransform<"draft" | "live" | "archived", "draft" | "live" | "archived" | "published">>;
2
8
  export declare const SectionMetaSchema: z.ZodObject<{
3
9
  type: z.ZodString;
4
10
  status: z.ZodPipe<z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"site-config.d.ts","sourceRoot":"","sources":["../../src/schemas/site-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ5D,eAAO,MAAM,cAAc,8EAA+E,CAAC;AAW3G,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AA0C9C,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE7D,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAE1D;AAMD,eAAO,MAAM,iBAAiB;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;iBAiC5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyD3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"site-config.d.ts","sourceRoot":"","sources":["../../src/schemas/site-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,YAAY;;;;;+FAExB,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ5D,eAAO,MAAM,cAAc,8EAA+E,CAAC;AAW3G,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AA0C9C,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE7D,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAE1D;AAMD,eAAO,MAAM,iBAAiB;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;iBAiC5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyD3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawnagency/primitives",
3
- "version": "0.1.89",
3
+ "version": "0.1.90",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -4,6 +4,55 @@ import { IndicatorPill } from "./IndicatorPill";
4
4
  import { PopoverItem } from "../shared/PopoverItem";
5
5
  import type { Audience } from "../../auth/types";
6
6
 
7
+ interface AudienceChecklistProps {
8
+ access: string[];
9
+ audiences: Audience[];
10
+ onToggle: (name: string) => void;
11
+ }
12
+
13
+ export function AudienceChecklist({ access, audiences, onToggle }: AudienceChecklistProps) {
14
+ if (audiences.length === 0) {
15
+ return (
16
+ <div className="px-3 py-2 text-xs text-base-contrast-light whitespace-nowrap">
17
+ No audiences configured. Add audiences in Site Settings → Viewer Access.
18
+ </div>
19
+ );
20
+ }
21
+ return (
22
+ <ul role="list" className="w-full overflow-hidden py-1">
23
+ {audiences.map((a) => {
24
+ const checked = access.includes(a.name);
25
+ return (
26
+ <li key={a.name}>
27
+ <PopoverItem
28
+ role="checkbox"
29
+ aria-checked={checked}
30
+ onClick={() => onToggle(a.name)}
31
+ >
32
+ <span
33
+ aria-hidden="true"
34
+ className={cn(
35
+ "flex h-5 w-5 shrink-0 items-center justify-center rounded border transition-colors",
36
+ checked
37
+ ? "border-primary bg-primary text-primary-contrast"
38
+ : "border-base-300 bg-base",
39
+ )}
40
+ >
41
+ {checked && <Check size={14} strokeWidth={3} />}
42
+ </span>
43
+ <span
44
+ className="h-3 w-3 shrink-0 rounded-full border border-base-200"
45
+ style={{ backgroundColor: a.color ?? "#9ca3af" }}
46
+ />
47
+ <span className="font-medium text-base-contrast whitespace-nowrap">{a.displayName}</span>
48
+ </PopoverItem>
49
+ </li>
50
+ );
51
+ })}
52
+ </ul>
53
+ );
54
+ }
55
+
7
56
  interface AudienceIndicatorProps {
8
57
  access: string[];
9
58
  audiences: Audience[];
@@ -39,43 +88,7 @@ export function AudienceIndicator({ access, audiences, onChange, disabled }: Aud
39
88
  buttonClassName={selected.length === 0 ? "text-base-contrast-light" : undefined}
40
89
  disabled={disabled}
41
90
  clickContent={
42
- audiences.length === 0 ? (
43
- <div className="px-3 py-2 text-xs text-base-contrast-light whitespace-nowrap">
44
- No audiences configured. Add audiences in Site Settings → Viewer Access.
45
- </div>
46
- ) : (
47
- <ul role="list" className="w-full overflow-hidden py-1">
48
- {audiences.map((a) => {
49
- const checked = access.includes(a.name);
50
- return (
51
- <li key={a.name}>
52
- <PopoverItem
53
- role="checkbox"
54
- aria-checked={checked}
55
- onClick={() => toggle(a.name)}
56
- >
57
- <span
58
- aria-hidden="true"
59
- className={cn(
60
- "flex h-5 w-5 shrink-0 items-center justify-center rounded border transition-colors",
61
- checked
62
- ? "border-primary bg-primary text-primary-contrast"
63
- : "border-base-300 bg-base",
64
- )}
65
- >
66
- {checked && <Check size={14} strokeWidth={3} />}
67
- </span>
68
- <span
69
- className="h-3 w-3 shrink-0 rounded-full border border-base-200"
70
- style={{ backgroundColor: a.color ?? "#9ca3af" }}
71
- />
72
- <span className="font-medium text-base-contrast">{a.displayName}</span>
73
- </PopoverItem>
74
- </li>
75
- );
76
- })}
77
- </ul>
78
- )
91
+ <AudienceChecklist access={access} audiences={audiences} onToggle={toggle} />
79
92
  }
80
93
  />
81
94
  );
@@ -5,6 +5,7 @@ import { DragHandle } from "./DragHandle";
5
5
  import { DeleteButton } from "./DeleteButton";
6
6
  import { SettingsButton } from "./SettingsButton";
7
7
  import { ColSpanControl } from "./ColSpanControl";
8
+ import { Tooltip, Kbd } from "../shared/Tooltip";
8
9
  import { cn } from "../../lib/cn";
9
10
 
10
11
  export interface ChildBlockWrapperProps {
@@ -70,17 +71,17 @@ export const ChildBlockWrapper = forwardRef<HTMLDivElement, ChildBlockWrapperPro
70
71
  >
71
72
  <span className="sr-only">{label}</span>
72
73
  <div className="pointer-events-auto">
73
- <DragHandle ref={dragHandleRef} />
74
+ <DragHandle ref={dragHandleRef} tooltipSide="right" />
74
75
  </div>
75
76
  <div className="pointer-events-auto">
76
77
  <ColSpanControl colSpan={colSpan} columns={columns} onChange={onColSpanChange} />
77
78
  </div>
78
79
  {hasSettings && onOpenSettings && (
79
- <div className="pointer-events-auto">
80
+ <Tooltip side="right" className="pointer-events-auto" content={<><Kbd>Edit</Kbd> settings</>}>
80
81
  <SettingsButton onClick={onOpenSettings} />
81
- </div>
82
+ </Tooltip>
82
83
  )}
83
- <div className="pointer-events-auto">
84
+ <Tooltip side="right" className="pointer-events-auto" content={<><Kbd>Duplicate</Kbd> block</>}>
84
85
  <button
85
86
  type="button"
86
87
  aria-label="Duplicate block"
@@ -89,10 +90,10 @@ export const ChildBlockWrapper = forwardRef<HTMLDivElement, ChildBlockWrapperPro
89
90
  >
90
91
  <CopyPlus size={16} />
91
92
  </button>
92
- </div>
93
- <div className="pointer-events-auto">
93
+ </Tooltip>
94
+ <Tooltip side="right" className="pointer-events-auto" content={<><Kbd>Delete</Kbd> block</>}>
94
95
  <DeleteButton onDelete={onDelete} />
95
- </div>
96
+ </Tooltip>
96
97
  </div>
97
98
 
98
99
  {/* Drop-edge indicators */}
@@ -2,6 +2,7 @@ import { useRef, useState } from "react";
2
2
  import { Columns3 } from "lucide-react";
3
3
  import { Popover } from "../shared/Popover";
4
4
  import { PopoverItem } from "../shared/PopoverItem";
5
+ import { Tooltip, Kbd } from "../shared/Tooltip";
5
6
  import { cn } from "../../lib/cn";
6
7
 
7
8
  interface ColSpanControlProps {
@@ -21,17 +22,19 @@ export function ColSpanControl({ colSpan, columns, onChange }: ColSpanControlPro
21
22
 
22
23
  return (
23
24
  <div className="relative">
24
- <button
25
- ref={buttonRef}
26
- type="button"
27
- aria-label="Column span"
28
- aria-haspopup="true"
29
- aria-expanded={open}
30
- onClick={() => setOpen((v) => !v)}
31
- className="pointer-events-auto inline-flex cursor-pointer items-center gap-1 rounded p-1 text-xs text-base-contrast-light hover:text-primary"
32
- >
33
- <Columns3 size={14} />
34
- </button>
25
+ <Tooltip side="right" content={<><Kbd>Set</Kbd> column span</>}>
26
+ <button
27
+ ref={buttonRef}
28
+ type="button"
29
+ aria-label="Column span"
30
+ aria-haspopup="true"
31
+ aria-expanded={open}
32
+ onClick={() => setOpen((v) => !v)}
33
+ className="pointer-events-auto inline-flex cursor-pointer items-center gap-1 rounded p-1 text-xs text-base-contrast-light hover:text-primary"
34
+ >
35
+ <Columns3 size={14} />
36
+ </button>
37
+ </Tooltip>
35
38
 
36
39
  <Popover isOpen={open} onClose={() => setOpen(false)} anchorRef={buttonRef} className="min-w-28">
37
40
  <ul role="list" className="py-1">
@@ -3,9 +3,12 @@ import { DragHandle as DragHandleIcon } from "../shared/icons";
3
3
  import { IconButton } from "../shared/IconButton";
4
4
  import { Tooltip, Kbd } from "../shared/Tooltip";
5
5
 
6
- export const DragHandle = forwardRef<HTMLButtonElement>(function DragHandle(_, ref) {
6
+ export const DragHandle = forwardRef<HTMLButtonElement, { tooltipSide?: "bottom" | "right" }>(function DragHandle(
7
+ { tooltipSide },
8
+ ref,
9
+ ) {
7
10
  return (
8
- <Tooltip content={<><Kbd>Drag</Kbd> to move</>}>
11
+ <Tooltip side={tooltipSide} content={<><Kbd>Drag</Kbd> to move</>}>
9
12
  <IconButton
10
13
  ref={ref}
11
14
  icon={<DragHandleIcon size={18} />}
@@ -205,15 +205,15 @@ function PageRow({
205
205
  return (
206
206
  <div
207
207
  ref={rowRef}
208
- className={cn("relative rounded-md border border-base-200", isDragging && "opacity-50")}
208
+ className={cn("relative flex items-start gap-1", isDragging && "opacity-50")}
209
209
  >
210
210
  <DropEdgeIndicator edge={closestEdge} />
211
- <div className="flex items-stretch gap-2 pl-3">
212
- {draggable && (
213
- <div className="flex shrink-0 items-center py-2 [&_[role=tooltip]]:hidden">
214
- <DragHandle ref={handleRef} />
215
- </div>
216
- )}
211
+ {draggable && (
212
+ <div className="flex shrink-0 items-center py-2 [&_[role=tooltip]]:hidden">
213
+ <DragHandle ref={handleRef} />
214
+ </div>
215
+ )}
216
+ <div className={cn("min-w-0 flex-1 rounded-md border border-base-200 bg-base", isDragging && "outline outline-2 outline-primary/50")}>
217
217
  <button
218
218
  type="button"
219
219
  aria-label={`Edit settings for ${pageDisplayTitle(page.title)}`}
@@ -238,9 +238,8 @@ function PageRow({
238
238
  className={cn("shrink-0 text-base-contrast/50 transition-transform", expanded && "rotate-180")}
239
239
  />
240
240
  </button>
241
- </div>
242
241
 
243
- {expanded && (
242
+ {expanded && (
244
243
  <div className="flex flex-col gap-3 border-t border-base-200 px-3 py-3">
245
244
  <Input
246
245
  label="Title"
@@ -314,7 +313,8 @@ function PageRow({
314
313
  </Button>
315
314
  </div>
316
315
  </div>
317
- )}
316
+ )}
317
+ </div>
318
318
  </div>
319
319
  );
320
320
  }
@@ -5,6 +5,8 @@ import { DragHandle } from "./DragHandle";
5
5
  import { InsertButton } from "./InsertButton";
6
6
  import { DeleteButton } from "./DeleteButton";
7
7
  import { SettingsButton } from "./SettingsButton";
8
+ import { IconButton } from "../shared/IconButton";
9
+ import { Tooltip, Kbd } from "../shared/Tooltip";
8
10
  import { StatusIndicator } from "./StatusIndicator";
9
11
  import { AudienceIndicator } from "./AudienceIndicator";
10
12
  import { LockBadge } from "./LockBadge";
@@ -298,7 +300,10 @@ export function SectionWrapper({
298
300
  {/* Status + settings + delete — top-right, above content */}
299
301
  <div
300
302
  className={cn(
301
- "pointer-events-none absolute right-0 bottom-full z-30 mb-1 flex items-center gap-2 transition-opacity",
303
+ // When a selector inside this cluster is open (Popover renders role="dialog"),
304
+ // lift the whole cluster above sibling sections' chrome (z-30, hover:z-[60]) and
305
+ // the inline type picker (z-50) so the open dropdown isn't overlapped.
306
+ "pointer-events-none absolute right-0 bottom-full z-30 has-[[role=dialog]]:z-[70] mb-1 flex items-center gap-2 transition-opacity",
302
307
  // A lock is important state — keep the cluster visible without hover.
303
308
  alwaysShow || isLocked ? "opacity-100" : "opacity-0 group-hover:opacity-100",
304
309
  )}
@@ -327,32 +332,38 @@ export function SectionWrapper({
327
332
  </div>
328
333
 
329
334
  {!isLocked && onAddChild && (
330
- <button
331
- type="button"
332
- onClick={onAddChild}
333
- aria-label="Add block"
334
- className="pointer-events-auto cursor-pointer rounded p-1 text-base-contrast-light hover:text-primary"
335
- >
336
- <Plus size={16} />
337
- </button>
335
+ <Tooltip className="pointer-events-auto" content={<><Kbd>Add</Kbd> a block</>}>
336
+ <IconButton
337
+ icon={<Plus size={16} />}
338
+ label="Add block"
339
+ onClick={onAddChild}
340
+ className="pointer-events-auto hover:text-primary"
341
+ />
342
+ </Tooltip>
338
343
  )}
339
344
 
340
- {!isLocked && hasSettings && (
341
- <SettingsButton onClick={handleSettingsClick} />
345
+ {!isLocked && onMoveSection && (
346
+ <Tooltip className="pointer-events-auto" content={<><Kbd>Move</Kbd> to page</>}>
347
+ <IconButton
348
+ icon={<ArrowRightLeft size={16} />}
349
+ label="Move to page"
350
+ onClick={onMoveSection}
351
+ className="pointer-events-auto hover:text-primary"
352
+ />
353
+ </Tooltip>
342
354
  )}
343
355
 
344
- {!isLocked && onMoveSection && (
345
- <button
346
- type="button"
347
- onClick={onMoveSection}
348
- aria-label="Move to page"
349
- className="pointer-events-auto cursor-pointer rounded p-1 text-base-contrast-light hover:text-primary"
350
- >
351
- <ArrowRightLeft size={16} />
352
- </button>
356
+ {!isLocked && hasSettings && (
357
+ <Tooltip className="pointer-events-auto" content={<><Kbd>Edit</Kbd> settings</>}>
358
+ <SettingsButton onClick={handleSettingsClick} />
359
+ </Tooltip>
353
360
  )}
354
361
 
355
- {!isLocked && onDelete && <DeleteButton onDelete={onDelete} />}
362
+ {!isLocked && onDelete && (
363
+ <Tooltip className="pointer-events-auto" content={<><Kbd>Delete</Kbd> section</>}>
364
+ <DeleteButton onDelete={onDelete} />
365
+ </Tooltip>
366
+ )}
356
367
  </div>
357
368
 
358
369
  {/* Drop indicator — centered in the section's own padding-top */}
@@ -83,6 +83,42 @@ const dotColorClasses: Record<StatusColor, string> = {
83
83
 
84
84
  const STATUSES: Status[] = ["draft", "live", "archived"];
85
85
 
86
+ interface StatusRadioListProps {
87
+ status: Status;
88
+ onChange: (status: Status) => void;
89
+ onClose?: () => void;
90
+ ariaLabel?: string;
91
+ }
92
+
93
+ export function StatusRadioList({ status, onChange, onClose, ariaLabel = "Section status" }: StatusRadioListProps) {
94
+ return (
95
+ <ul role="radiogroup" aria-label={ariaLabel} className="w-full overflow-hidden py-1">
96
+ {STATUSES.map((s) => {
97
+ const checked = s === status;
98
+ return (
99
+ <li key={s}>
100
+ <PopoverItem
101
+ role="radio"
102
+ aria-checked={checked}
103
+ onClick={() => {
104
+ if (s !== status) onChange(s);
105
+ onClose?.();
106
+ }}
107
+ >
108
+ <span
109
+ aria-hidden="true"
110
+ className={cn("h-3 w-3 shrink-0 rounded-full border border-base-200", dotColorClasses[s])}
111
+ />
112
+ <span className="flex-1 font-medium capitalize text-base-contrast">{s}</span>
113
+ {checked && <Check size={14} strokeWidth={3} className="text-primary" />}
114
+ </PopoverItem>
115
+ </li>
116
+ );
117
+ })}
118
+ </ul>
119
+ );
120
+ }
121
+
86
122
  interface StatusIndicatorProps {
87
123
  mainStatus: string | null;
88
124
  savedStatus: string;
@@ -122,30 +158,7 @@ export function StatusIndicator({
122
158
  buttonClassName="text-base-contrast-light"
123
159
  disabled={disabled}
124
160
  clickContent={(onClose) => (
125
- <ul role="radiogroup" aria-label="Section status" className="w-full overflow-hidden py-1">
126
- {STATUSES.map((s) => {
127
- const checked = s === status;
128
- return (
129
- <li key={s}>
130
- <PopoverItem
131
- role="radio"
132
- aria-checked={checked}
133
- onClick={() => {
134
- if (s !== status) onChange(s);
135
- onClose();
136
- }}
137
- >
138
- <span
139
- aria-hidden="true"
140
- className={cn("h-3 w-3 shrink-0 rounded-full border border-base-200", dotColorClasses[s])}
141
- />
142
- <span className="flex-1 font-medium capitalize text-base-contrast">{s}</span>
143
- {checked && <Check size={14} strokeWidth={3} className="text-primary" />}
144
- </PopoverItem>
145
- </li>
146
- );
147
- })}
148
- </ul>
161
+ <StatusRadioList status={status} onChange={onChange} onClose={onClose} />
149
162
  )}
150
163
  />
151
164
  );