@bettercms-ai/types 1.23.1 → 1.25.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/index.js CHANGED
@@ -150,13 +150,18 @@ function blockStyleToCss(style) {
150
150
  const top = spaceTokenCss(s.spaceTop);
151
151
  const bottom = SPACE_BOTTOM_TOKENS.includes(s.spaceBottom ?? "") ? spaceTokenCss(s.spaceBottom) : "";
152
152
  const sides = spaceTokenCss(s.spaceSides);
153
- if (top) css.paddingTop = top;
153
+ const navOverlap = s.spaceTop === "section-space-nav-overlap";
154
+ if (top && !navOverlap) css.paddingTop = top;
154
155
  if (bottom) css.paddingBottom = bottom;
155
156
  if (sides) {
156
157
  css.paddingLeft = sides;
157
158
  css.paddingRight = sides;
158
159
  }
159
160
  if (s.marginTop && SPACE_PX[s.marginTop] != null) css.marginTop = SPACE_PX[s.marginTop];
161
+ if (top && navOverlap) {
162
+ css.marginTop = top;
163
+ css.paddingTop = `calc(-1 * ${top})`;
164
+ }
160
165
  if (s.marginBottom && SPACE_PX[s.marginBottom] != null) css.marginBottom = SPACE_PX[s.marginBottom];
161
166
  if (s.background && COLOR_HEX[s.background]) css.background = COLOR_HEX[s.background];
162
167
  if (s.textColor && COLOR_HEX[s.textColor]) css.color = COLOR_HEX[s.textColor];
@@ -2151,6 +2156,451 @@ var PAGE_CONTENT_ANCHOR_ID = "page-content";
2151
2156
  var NAVIGATION_SECTION_ID = "navigation";
2152
2157
  var FOOTER_SECTION_ID = "footer";
2153
2158
 
2159
+ // src/dock-icon-names.ts
2160
+ var DOCK_ICON_NAMES = [
2161
+ "access-denied",
2162
+ "activity",
2163
+ "add",
2164
+ "add-circle",
2165
+ "add-comment",
2166
+ "add-document",
2167
+ "add-user",
2168
+ "api",
2169
+ "archive",
2170
+ "arrow-down",
2171
+ "arrow-left",
2172
+ "arrow-right",
2173
+ "arrow-top-right",
2174
+ "arrow-up",
2175
+ "asterisk",
2176
+ "bar-chart",
2177
+ "basket",
2178
+ "bell",
2179
+ "bill",
2180
+ "binary-document",
2181
+ "block-content",
2182
+ "block-element",
2183
+ "blockquote",
2184
+ "bold",
2185
+ "bolt",
2186
+ "book",
2187
+ "bookmark",
2188
+ "bookmark-filled",
2189
+ "bottle",
2190
+ "bug",
2191
+ "bulb-filled",
2192
+ "bulb-outline",
2193
+ "calendar",
2194
+ "case",
2195
+ "chart-upward",
2196
+ "checkmark",
2197
+ "checkmark-circle",
2198
+ "chevron-down",
2199
+ "chevron-left",
2200
+ "chevron-right",
2201
+ "chevron-up",
2202
+ "circle",
2203
+ "clipboard",
2204
+ "clipboard-image",
2205
+ "clock",
2206
+ "close",
2207
+ "close-circle",
2208
+ "code",
2209
+ "code-block",
2210
+ "cog",
2211
+ "collapse",
2212
+ "color-wheel",
2213
+ "comment",
2214
+ "component",
2215
+ "compose",
2216
+ "compose-sparkles",
2217
+ "confetti",
2218
+ "controls",
2219
+ "copy",
2220
+ "credit-card",
2221
+ "crop",
2222
+ "cube",
2223
+ "dashboard",
2224
+ "database",
2225
+ "desktop",
2226
+ "diamond",
2227
+ "document",
2228
+ "document-pdf",
2229
+ "document-remove",
2230
+ "document-sheet",
2231
+ "document-text",
2232
+ "document-video",
2233
+ "document-word",
2234
+ "document-zip",
2235
+ "documents",
2236
+ "dot",
2237
+ "double-chevron-down",
2238
+ "double-chevron-left",
2239
+ "double-chevron-right",
2240
+ "double-chevron-up",
2241
+ "double-quote",
2242
+ "download",
2243
+ "drag-handle",
2244
+ "drop",
2245
+ "earth-americas",
2246
+ "earth-globe",
2247
+ "edit",
2248
+ "ellipsis-horizontal",
2249
+ "ellipsis-vertical",
2250
+ "empty",
2251
+ "enter",
2252
+ "enter-right",
2253
+ "envelope",
2254
+ "equal",
2255
+ "error-filled",
2256
+ "error-outline",
2257
+ "error-screen",
2258
+ "expand",
2259
+ "eye-closed",
2260
+ "eye-open",
2261
+ "face-happy",
2262
+ "face-indifferent",
2263
+ "face-sad",
2264
+ "feedback",
2265
+ "filter",
2266
+ "folder",
2267
+ "generate",
2268
+ "github",
2269
+ "groq",
2270
+ "hash",
2271
+ "heart",
2272
+ "heart-filled",
2273
+ "help-circle",
2274
+ "highlight",
2275
+ "home",
2276
+ "ice-cream",
2277
+ "image",
2278
+ "image-remove",
2279
+ "images",
2280
+ "inbox",
2281
+ "info-filled",
2282
+ "info-outline",
2283
+ "inline",
2284
+ "inline-element",
2285
+ "insert-above",
2286
+ "insert-below",
2287
+ "italic",
2288
+ "joystick",
2289
+ "json",
2290
+ "launch",
2291
+ "leave",
2292
+ "lemon",
2293
+ "link",
2294
+ "link-removed",
2295
+ "linkedin",
2296
+ "list",
2297
+ "lock",
2298
+ "logo-js",
2299
+ "logo-ts",
2300
+ "marker",
2301
+ "marker-removed",
2302
+ "master-detail",
2303
+ "menu",
2304
+ "microphone",
2305
+ "microphone-slash",
2306
+ "mobile-device",
2307
+ "moon",
2308
+ "number",
2309
+ "ok-hand",
2310
+ "olist",
2311
+ "overage",
2312
+ "package",
2313
+ "panel-left",
2314
+ "panel-right",
2315
+ "pause",
2316
+ "pin",
2317
+ "pin-filled",
2318
+ "pin-removed",
2319
+ "play",
2320
+ "plug",
2321
+ "presentation",
2322
+ "progress-50",
2323
+ "progress-75",
2324
+ "projects",
2325
+ "publish",
2326
+ "read-only",
2327
+ "redo",
2328
+ "refresh",
2329
+ "remove",
2330
+ "remove-circle",
2331
+ "reset",
2332
+ "restore",
2333
+ "retrieve",
2334
+ "retry",
2335
+ "revert",
2336
+ "robot",
2337
+ "rocket",
2338
+ "schema",
2339
+ "search",
2340
+ "select",
2341
+ "share",
2342
+ "sort",
2343
+ "sparkle",
2344
+ "sparkles",
2345
+ "spinner",
2346
+ "split-horizontal",
2347
+ "split-vertical",
2348
+ "square",
2349
+ "stack",
2350
+ "stack-compact",
2351
+ "star",
2352
+ "star-filled",
2353
+ "stop",
2354
+ "strikethrough",
2355
+ "string",
2356
+ "sun",
2357
+ "sync",
2358
+ "tablet-device",
2359
+ "tag",
2360
+ "tags",
2361
+ "target",
2362
+ "task",
2363
+ "terminal",
2364
+ "text",
2365
+ "th-large",
2366
+ "th-list",
2367
+ "thumbs-down",
2368
+ "thumbs-up",
2369
+ "tiers",
2370
+ "timeline",
2371
+ "toggle-arrow-right",
2372
+ "token",
2373
+ "transfer",
2374
+ "translate",
2375
+ "trash",
2376
+ "trend-upward",
2377
+ "triangle-outline",
2378
+ "trolley",
2379
+ "truncate",
2380
+ "twitter",
2381
+ "ulist",
2382
+ "unarchive",
2383
+ "underline",
2384
+ "undo",
2385
+ "unknown",
2386
+ "unlink",
2387
+ "unlock",
2388
+ "unpublish",
2389
+ "upload",
2390
+ "user",
2391
+ "users",
2392
+ "versions",
2393
+ "video",
2394
+ "warning-filled",
2395
+ "warning-outline",
2396
+ "wrench"
2397
+ ];
2398
+ var DOCK_ICON_NAME_SET = new Set(DOCK_ICON_NAMES);
2399
+
2400
+ // src/dock-budget.ts
2401
+ var DOCK_BUDGET = { ungrouped: 8, group: 12, depth: 3, activations: 2 };
2402
+ function listItems(f) {
2403
+ const c = f.config ?? {};
2404
+ if (f.type === "repeater") return f.fields ?? [];
2405
+ if (f.type === "table") return c.fields ?? f.fields ?? [];
2406
+ if (f.type === "array" && c.zones?.repeatable) return c.zones.repeatable.fields ?? [];
2407
+ if (f.type === "modular") return null;
2408
+ return void 0;
2409
+ }
2410
+ function zoneFields(f) {
2411
+ const c = f.config ?? {};
2412
+ if (f.type === "group") return c.fields ?? f.fields ?? [];
2413
+ if (f.type === "array" && c.zones?.nonRepeatable) return c.zones.nonRepeatable;
2414
+ return void 0;
2415
+ }
2416
+ function layout(fields, fieldsets, root) {
2417
+ const byId = new Map(fieldsets.map((s) => [s.id, s]));
2418
+ const tabIds = root ? fieldsets.filter((s) => s.kind === "tab").map((s) => s.id) : [];
2419
+ const tabOf = (s) => s?.kind === "tab" ? s.id : s?.tab !== void 0 && byId.get(s.tab)?.kind === "tab" ? s.tab : void 0;
2420
+ const nonEmpty = new Set(
2421
+ fields.map((f) => tabOf(byId.get(f.fieldsetId ?? ""))).filter((t) => t && tabIds.includes(t))
2422
+ );
2423
+ const strip = nonEmpty.size >= 2;
2424
+ const branches = /* @__PURE__ */ new Map();
2425
+ const nodeFor = (f, path) => {
2426
+ const key = `${path}${f.key}`;
2427
+ const zone = zoneFields(f);
2428
+ if (zone) {
2429
+ return { kind: "group", id: key, collapsed: f.ui?.collapsed === true, nodes: zone.map((z) => nodeFor(z, `${key}.`)) };
2430
+ }
2431
+ const items = listItems(f);
2432
+ if (items !== void 0) {
2433
+ branches.set(key, { key, field: f, items });
2434
+ return { kind: "branch", key };
2435
+ }
2436
+ return { kind: "leaf", key };
2437
+ };
2438
+ const pinned = [];
2439
+ const panels = new Map(strip ? tabIds.filter((t) => nonEmpty.has(t)).map((t) => [t, []]) : []);
2440
+ const containers = /* @__PURE__ */ new Map();
2441
+ for (const f of fields) {
2442
+ const node = nodeFor(f, "");
2443
+ const set = byId.get(f.fieldsetId ?? "");
2444
+ const target = strip && panels.get(tabOf(set) ?? "") || pinned;
2445
+ if (set?.kind !== "group" && set?.kind !== "row") {
2446
+ target.push(node);
2447
+ continue;
2448
+ }
2449
+ let box = containers.get(set.id);
2450
+ if (!box) {
2451
+ box = set.kind === "row" ? { kind: "row", id: set.id, keys: [] } : { kind: "group", id: set.id, collapsed: set.collapsed === true, nodes: [] };
2452
+ containers.set(set.id, box);
2453
+ target.push(box);
2454
+ }
2455
+ if (box.kind === "row") box.keys.push(f.key);
2456
+ else if (box.kind === "group") box.nodes.push(node);
2457
+ }
2458
+ return { pinned, tabs: [...panels.values()], branches };
2459
+ }
2460
+ function walkCosts(screen) {
2461
+ const values = [];
2462
+ const branchCost = /* @__PURE__ */ new Map();
2463
+ const walk = (nodes, cost) => {
2464
+ for (const n of nodes) {
2465
+ if (n.kind === "group") walk(n.nodes, cost + (n.collapsed ? 1 : 0));
2466
+ else if (n.kind === "branch") branchCost.set(n.key, cost);
2467
+ else values.push(cost);
2468
+ }
2469
+ };
2470
+ walk(screen.pinned, 0);
2471
+ screen.tabs.forEach((panel, i) => walk(panel, i === 0 ? 0 : 1));
2472
+ return { values, branchCost };
2473
+ }
2474
+ function dockScreens(source, lane, props) {
2475
+ let fields = source.fields ?? [];
2476
+ let fieldsets = source.fieldsets ?? [];
2477
+ if (props) {
2478
+ fieldsets = [];
2479
+ fields = props.map((p) => {
2480
+ const g = p.ui?.group;
2481
+ if (!g) return p;
2482
+ if (!fieldsets.some((s) => s.id === g.id)) {
2483
+ fieldsets.push({ id: g.id, name: g.label, kind: g.kind ?? "group", collapsed: g.collapsed });
2484
+ }
2485
+ return { ...p, fieldsetId: g.id };
2486
+ });
2487
+ }
2488
+ const screens = [];
2489
+ const open = (id, kind, title, depth, entry, level) => {
2490
+ const laid = level ? layout(level, fieldsets, kind === "root") : null;
2491
+ const screen = {
2492
+ id,
2493
+ lane,
2494
+ kind,
2495
+ title,
2496
+ depth,
2497
+ entry,
2498
+ pinned: laid?.pinned ?? [],
2499
+ tabs: laid?.tabs ?? []
2500
+ };
2501
+ screens.push(screen);
2502
+ if (!laid) return;
2503
+ const { branchCost } = walkCosts(screen);
2504
+ for (const b of laid.branches.values()) {
2505
+ const listId = `${id}/${b.key}`;
2506
+ const listEntry = entry + (branchCost.get(b.key) ?? 0) + 1;
2507
+ const label = b.field.label ?? b.field.key;
2508
+ open(listId, "list", label, depth + 1, listEntry, null);
2509
+ if (b.items) open(`${listId}/item`, "item", `${label} item`, depth + 2, listEntry + 1, b.items);
2510
+ }
2511
+ };
2512
+ open(lane, "root", lane === "component" ? "Component" : lane === "page-fields" ? "Page fields" : "Section", 0, 0, fields);
2513
+ return screens;
2514
+ }
2515
+ function dockBudget(screen) {
2516
+ const rows = (nodes) => nodes.filter((n) => n.kind !== "group").length;
2517
+ let maxGroupLeaves = 0;
2518
+ const groups = (nodes) => {
2519
+ for (const n of nodes) {
2520
+ if (n.kind !== "group") continue;
2521
+ maxGroupLeaves = Math.max(maxGroupLeaves, rows(n.nodes));
2522
+ groups(n.nodes);
2523
+ }
2524
+ };
2525
+ groups(screen.pinned);
2526
+ screen.tabs.forEach(groups);
2527
+ const pinned = rows(screen.pinned);
2528
+ const { values } = walkCosts(screen);
2529
+ return {
2530
+ ungroupedLeaves: screen.tabs.length ? Math.max(...screen.tabs.map((p) => pinned + rows(p))) : pinned,
2531
+ maxGroupLeaves,
2532
+ depth: screen.depth,
2533
+ maxActivations: screen.entry + (values.length ? Math.max(...values) : 0)
2534
+ };
2535
+ }
2536
+
2537
+ // src/button-link-pairing.ts
2538
+ var TEXT_ROLES = /* @__PURE__ */ new Set(["label", "text", "title", "cta", "button", "btn", "name"]);
2539
+ var LINK_ROLES = /* @__PURE__ */ new Set(["href", "link", "url", "to"]);
2540
+ var BUTTON_NOUNS = /* @__PURE__ */ new Set(["cta", "button", "btn"]);
2541
+ var TEXT_TYPES = /* @__PURE__ */ new Set(["text", "string"]);
2542
+ var LINK_TYPES = /* @__PURE__ */ new Set(["link", "url"]);
2543
+ var MEDIA = /image|img|photo|video|avatar|logo|icon|thumb|poster|embed|src|og|favicon/i;
2544
+ function keyWords(key) {
2545
+ const leaf = key.split(".").pop() ?? "";
2546
+ return leaf.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[\s_-]+/).filter(Boolean).map((word) => word.toLowerCase());
2547
+ }
2548
+ function roleFromWords(candidate, words) {
2549
+ const type = (candidate.type ?? "").toLowerCase();
2550
+ const value = candidate.value;
2551
+ if (!(value === void 0 || value === null || typeof value === "string")) return null;
2552
+ if (!words.length) return null;
2553
+ const last = words[words.length - 1];
2554
+ const stem = words.slice(0, -1).join("_");
2555
+ const full = words.join("_");
2556
+ if (LINK_TYPES.has(type)) return { role: "link", stems: LINK_ROLES.has(last) ? [stem] : [stem, full] };
2557
+ if (!TEXT_TYPES.has(type)) return null;
2558
+ if (LINK_ROLES.has(last)) {
2559
+ if (MEDIA.test(candidate.key) || MEDIA.test(candidate.label ?? "")) return null;
2560
+ return { role: "link", stems: [stem] };
2561
+ }
2562
+ if (TEXT_ROLES.has(last)) return { role: "text", stems: BUTTON_NOUNS.has(last) ? [stem, full] : [stem] };
2563
+ return null;
2564
+ }
2565
+ function candidateRole(candidate) {
2566
+ const fromKey = roleFromWords(candidate, keyWords(candidate.key));
2567
+ if (fromKey) return fromKey;
2568
+ const label = candidate.label?.trim();
2569
+ if (!label) return null;
2570
+ const fromLabel = roleFromWords(candidate, keyWords(label.replace(/\s+/g, "_")));
2571
+ return fromLabel ? { role: fromLabel.role, stems: fromLabel.stems.map((stem) => `label:${stem}`) } : null;
2572
+ }
2573
+ function buttonLinkPairs(candidates) {
2574
+ const roles = candidates.map(candidateRole);
2575
+ const byStem = /* @__PURE__ */ new Map();
2576
+ roles.forEach((role, index) => {
2577
+ if (!role) return;
2578
+ for (const stem of new Set(role.stems)) {
2579
+ const bucket = byStem.get(stem) ?? { text: /* @__PURE__ */ new Set(), link: /* @__PURE__ */ new Set() };
2580
+ bucket[role.role].add(index);
2581
+ byStem.set(stem, bucket);
2582
+ }
2583
+ });
2584
+ const ambiguous = /* @__PURE__ */ new Set();
2585
+ const proposals = /* @__PURE__ */ new Map();
2586
+ for (const bucket of byStem.values()) {
2587
+ if (bucket.text.size + bucket.link.size >= 3) {
2588
+ for (const index of [...bucket.text, ...bucket.link]) ambiguous.add(index);
2589
+ continue;
2590
+ }
2591
+ if (bucket.text.size === 1 && bucket.link.size === 1) {
2592
+ const pair = [[...bucket.text][0], [...bucket.link][0]];
2593
+ proposals.set(pair.join(":"), pair);
2594
+ }
2595
+ }
2596
+ const uses = /* @__PURE__ */ new Map();
2597
+ for (const [text, link] of proposals.values()) {
2598
+ uses.set(text, (uses.get(text) ?? 0) + 1);
2599
+ uses.set(link, (uses.get(link) ?? 0) + 1);
2600
+ }
2601
+ return [...proposals.values()].filter(([t, l]) => !ambiguous.has(t) && !ambiguous.has(l) && uses.get(t) === 1 && uses.get(l) === 1).sort((a, b) => Math.min(...a) - Math.min(...b));
2602
+ }
2603
+
2154
2604
  // src/locator.ts
2155
2605
  var LANDMARK_SELECTOR = "header,nav,footer";
2156
2606
  var LANDMARK_TAGS = /* @__PURE__ */ new Set(["HEADER", "NAV", "FOOTER"]);
@@ -2215,6 +2665,9 @@ export {
2215
2665
  BLOCK_BINDINGS,
2216
2666
  COMPONENT_PROP_TYPES,
2217
2667
  DIALOG_SELECTOR,
2668
+ DOCK_BUDGET,
2669
+ DOCK_ICON_NAMES,
2670
+ DOCK_ICON_NAME_SET,
2218
2671
  FOOTER_SECTION_ID,
2219
2672
  LANDMARK_SELECTOR,
2220
2673
  LAYOUT_SECTION_ICONS,
@@ -2227,13 +2680,18 @@ export {
2227
2680
  SPACE_BOTTOM_TOKENS,
2228
2681
  SPACE_STEP_TOKENS,
2229
2682
  blockStyleToCss,
2683
+ buttonLinkPairs,
2684
+ candidateRole,
2230
2685
  componentInstanceAddresses,
2231
2686
  componentPropTargetKey,
2687
+ dockBudget,
2688
+ dockScreens,
2232
2689
  expandBlockBindings,
2233
2690
  formatPropsAttribute,
2234
2691
  getBlockType,
2235
2692
  isBlock,
2236
2693
  isChromeLandmark,
2694
+ keyWords,
2237
2695
  landmarkRegions,
2238
2696
  locatorFor,
2239
2697
  parsePropsAttribute,