@bettercms-ai/types 1.43.1 → 1.45.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.d.ts CHANGED
@@ -586,17 +586,36 @@ interface Page {
586
586
  /**
587
587
  * Section spacing as TOKEN STEPS — the ONE list of names and default sizes, shared by the save
588
588
  * schema and every renderer. A stored value is always a token (`section-space-large`), never a
589
- * pixel; it renders as `var(--bcms-section-space-large,96px)`, so a site with a token registry
589
+ * pixel; it renders as `var(--bcms-section-space-large,88px)`, so a site with a token registry
590
590
  * restyles every section at once and a site without one still gets the default rhythm.
591
591
  *
592
592
  * 🔴 The px table is twinned with the dashboard's `tokenScales.ts` preview table. Change both.
593
593
  */
594
- declare const SECTION_SPACE_TOKENS: readonly ["section-space-none", "section-space-small", "section-space-medium", "section-space-large", "section-space-xlarge", "section-space-nav-overlap"];
594
+ declare const SECTION_SPACE_TOKENS: readonly ["section-space-none", "section-space-xsmall", "section-space-small", "section-space-medium", "section-space-large", "section-space-xlarge", "section-space-nav-overlap"];
595
595
  declare const SPACE_STEP_TOKENS: readonly ["space-none", "space-s", "space-m", "space-l", "space-xl"];
596
596
  type SectionSpaceToken = (typeof SECTION_SPACE_TOKENS)[number];
597
597
  type SpaceStepToken = (typeof SPACE_STEP_TOKENS)[number];
598
598
  /** A negative band that pulls content under the nav makes sense at the TOP of a section only. */
599
- declare const SPACE_BOTTOM_TOKENS: ("section-space-none" | "section-space-small" | "section-space-medium" | "section-space-large" | "section-space-xlarge")[];
599
+ declare const SPACE_BOTTOM_TOKENS: ("section-space-none" | "section-space-xsmall" | "section-space-small" | "section-space-medium" | "section-space-large" | "section-space-xlarge")[];
600
+ /**
601
+ * What `spaceSides` accepts: the old inner `space-*` steps (still read, as they always rendered)
602
+ * and the section steps the V2 Sides handle writes — the same six as the top and bottom.
603
+ */
604
+ declare const SIDE_SPACE_TOKENS: readonly ["space-none", "space-s", "space-m", "space-l", "space-xl", ...("section-space-none" | "section-space-xsmall" | "section-space-small" | "section-space-medium" | "section-space-large" | "section-space-xlarge")[]];
605
+ /** V2: side spacing never renders under 16px (`Math.max(16, spacingPx(...))`). */
606
+ declare const SIDE_SPACE_MIN_PX = 16;
607
+ /**
608
+ * The side padding for a `spaceSides` token. A section step is floored at 16px as V2 does; an old
609
+ * `space-*` step renders exactly as before, so no stored section moves. "" for an unknown token.
610
+ */
611
+ declare function sideSpaceCss(token: unknown): string;
612
+ /**
613
+ * V2's site gutter: a band's content never touches its edge. The hosted renderer's own section
614
+ * wrapper (`div.bcms-block`) carrying the band rhythm (a top or bottom step or px — only a section
615
+ * carries one) with no side value at all gets 16px sides. Only that wrapper: a site's own section
616
+ * root keeps its own side padding, which an inline 16px would override.
617
+ */
618
+ declare function sideFloorApplies(style: Record<string, unknown>): boolean;
600
619
  /** `var(--bcms-<token>,<px>)`, or "" for anything that is not a known token (closed set). */
601
620
  declare function spaceTokenCss(token: unknown): string;
602
621
 
@@ -842,6 +861,16 @@ interface BlockStyle {
842
861
  fontSize?: FontSizeToken;
843
862
  weight?: WeightToken;
844
863
  radius?: RadiusToken;
864
+ /** A free corner radius in px (0–96), V2's Alt-drag "Custom · free" value. Wins over `radius`. */
865
+ radiusPx?: number;
866
+ /** An image cropped to this ratio, filling its column (V2's media frame). @see imageFrameCss */
867
+ aspect?: "16/9" | "16/7" | "4/3" | "4/5" | "1/1";
868
+ /** The frame's ratio on a phone (≤767px); unset keeps `aspect`. The hosted lane draws it. */
869
+ aspectMobile?: "16/9" | "16/7" | "4/3" | "4/5" | "1/1";
870
+ /** The block's top gap on a phone (≤767px), in px (0–240); unset keeps `marginTop`. The hosted lane draws it. */
871
+ marginTopMobilePx?: number;
872
+ /** A heading whose column is its measure: the hosted page's heading width limit (`type.headingMeasure`) skips it. */
873
+ measure?: "column";
845
874
  theme?: ThemeToken;
846
875
  bg?: BgToken;
847
876
  /** Only read when `bg === "custom"`. Hex only. */
@@ -855,6 +884,8 @@ interface BlockStyle {
855
884
  spaceBottom?: Exclude<SectionSpaceToken, "section-space-nav-overlap">;
856
885
  spaceSides?: SpaceStepToken;
857
886
  contentWidth?: ContentWidthToken;
887
+ /** A free content width in px (320–2400), V2's Alt-drag "Custom · free" value. Wins over `contentWidth`. */
888
+ contentWidthPx?: number;
858
889
  /**
859
890
  * Where the constrained content column sits, when `contentWidth` constrains it.
860
891
  *
@@ -879,7 +910,8 @@ interface BlockStyle {
879
910
  hover?: BlockHoverStyle;
880
911
  /**
881
912
  * Breakpoints the block is hidden on (`display:none` there only; the block stays in the HTML).
882
- * Never all three: a block hidden everywhere is a delete. Bands: see `BREAKPOINTS`.
913
+ * All three is "Hide on this page": the block is kept for the editor but no published lane
914
+ * emits it (`hiddenEverywhere`, `visibleBlocks`). Bands: see `BREAKPOINTS`.
883
915
  */
884
916
  hideOn?: Array<"mobile" | "tablet" | "desktop">;
885
917
  }
@@ -922,9 +954,15 @@ declare function windowState(item: unknown, now: Date | number): WindowState;
922
954
  /** Is the block or Section shown at `now`? No window is always shown. */
923
955
  declare const inWindow: (item: unknown, now: Date | number) => boolean;
924
956
  /**
925
- * The blocks shown at `now`: every block outside its window removed, at any depth (a section's
926
- * children, columns, slides, tab panels). What a published lane renders, collects from and
927
- * delivers.
957
+ * Is the block hidden on every breakpoint (`style.hideOn` names mobile, tablet AND desktop)? That
958
+ * is the editor's "Hide on this page": the block stays in the stored tree, so Show brings it back
959
+ * as it was, but no published lane emits it. Not a window: it does not depend on `now`.
960
+ */
961
+ declare function hiddenEverywhere(item: unknown): boolean;
962
+ /**
963
+ * The blocks shown at `now`: every block outside its window, and every block hidden on all
964
+ * breakpoints (`hiddenEverywhere`), removed at any depth (a section's children, columns, slides,
965
+ * tab panels). What a published lane renders, collects from and delivers.
928
966
  *
929
967
  * Returns the SAME array when nothing is removed, so a tree with no window costs one walk and
930
968
  * every consumer downstream is handed exactly what it was handed before windows existed.
@@ -1038,6 +1076,19 @@ interface ImageProps {
1038
1076
  width?: number;
1039
1077
  height?: number;
1040
1078
  caption?: string;
1079
+ /**
1080
+ * THIS placement's focal point (V2's `srcFocal`): 0–1 fractions of the SOURCE picture, drawn as
1081
+ * `object-position` inside the crop window `src`'s `?rect=` serves. Absent or null = centred.
1082
+ */
1083
+ focal?: {
1084
+ x: number;
1085
+ y: number;
1086
+ } | null;
1087
+ /**
1088
+ * THIS placement is decorative (V2's `srcDecorative`): rendered with `alt=""`. The page's own,
1089
+ * never the shared media asset's, so one Undo reverses it with the alt.
1090
+ */
1091
+ decorative?: boolean;
1041
1092
  }
1042
1093
  interface ImageBlock {
1043
1094
  type: "image";
@@ -1523,6 +1574,22 @@ declare function componentInstanceAddresses(instanceBlockId: string, props: read
1523
1574
  * render-page.ts. Unknown tokens are dropped — closed set, no arbitrary CSS.
1524
1575
  */
1525
1576
 
1577
+ /**
1578
+ * V2's media frame (`aspect-[16/7]` + `cs-r2` on the image wrapper, site/hero.tsx and content.tsx):
1579
+ * the picture fills its column, is cropped to the ratio (cover), and takes the theme's large media
1580
+ * corner, the card radius x 1.8 as V2's `cs-r2 = calc(var(--cs-r) * 1.8)`. A block's own `radius` /
1581
+ * `radiusPx` still wins over that corner. 🔴 Every lane reads this one function (hosted, Next, Astro).
1582
+ */
1583
+ declare const IMAGE_ASPECTS: readonly ["16/9", "16/7", "4/3", "4/5", "1/1"];
1584
+ type ImageAspect = (typeof IMAGE_ASPECTS)[number];
1585
+ declare const IMAGE_FRAME_RADIUS = "calc(var(--bcms-radius-card,14px) * 1.8)";
1586
+ declare function imageFrameCss(style: unknown): {
1587
+ display: "block";
1588
+ width: string;
1589
+ aspectRatio: string;
1590
+ objectFit: "cover";
1591
+ borderRadius?: string;
1592
+ } | null;
1526
1593
  /**
1527
1594
  * Where a block's `hideOn` bands start and end: mobile at most 767px, tablet 768-1023px, desktop
1528
1595
  * 1024px and up (the dock's 390 / 810 / 1280 canvases fall one in each band). A site's CSS
@@ -1543,6 +1610,8 @@ declare const RESPONSIVE_CSS: string;
1543
1610
  /**
1544
1611
  * The `data-bcms-hide` value for a block style (`"mobile tablet"`), or "" when it hides nowhere.
1545
1612
  * Closed set, fixed order, so a hand-edited row cannot put anything else into an attribute.
1613
+ * All three is "" too: such a block is not emitted on a published lane at all (`visibleBlocks`),
1614
+ * and the editor's lane draws it whole, marked `data-bcms-hidden`, so the author can find it.
1546
1615
  */
1547
1616
  declare function hideOnAttr(style: unknown): string;
1548
1617
  /** True when any block in the tree hides somewhere; lets a lane skip `RESPONSIVE_CSS` when unused. */
@@ -2326,9 +2395,23 @@ interface PropGroup {
2326
2395
  layout?: "stack" | "breakpoints";
2327
2396
  order?: number;
2328
2397
  }
2329
- /** A prop's `ui`: the field-lane chrome plus its inline {@link PropGroup}. */
2398
+ /**
2399
+ * A top-level prop's dock tab (V2 kit schema `groups`: Content | Design | Media | Settings | …).
2400
+ * Define-once like {@link PropGroup}: the first prop naming an `id` sets label/icon/order, later
2401
+ * props name `{ id }`. At most 8 tabs; never on a sub-field; one group's members share one tab.
2402
+ */
2403
+ interface PropTab {
2404
+ id: string;
2405
+ /** 1–20 chars, unique per component (case-insensitive). Required on the defining prop. */
2406
+ label?: string;
2407
+ icon?: DockIconName;
2408
+ /** 0–99; the tab's place among the tabs (absent = where its first prop sits). */
2409
+ order?: number;
2410
+ }
2411
+ /** A prop's `ui`: the field-lane chrome plus its inline {@link PropGroup} and {@link PropTab}. */
2330
2412
  type ComponentPropUi = ContentModelFieldUi & {
2331
2413
  group?: PropGroup;
2414
+ tab?: PropTab;
2332
2415
  };
2333
2416
  /** One field inside a `group` / `object` prop or a `table` row. Recursive, 10 levels at most counting the prop (MAX_FIELD_DEPTH). */
2334
2417
  interface ComponentSubField {
@@ -3660,4 +3743,4 @@ type SectionPlanItem<B> = {
3660
3743
  */
3661
3744
  declare function planSections<B>(slots: readonly string[], blocks: readonly B[] | null | undefined): SectionPlanItem<B>[];
3662
3745
 
3663
- export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, BREAKPOINTS, BUTTON_ACTIONS, BUTTON_FULL_WIDTH_INVALID, BUTTON_ICONS, BUTTON_ICON_NAMES, BUTTON_LOOK_KEYS, BUTTON_PLACEMENT_KEYS, BUTTON_SIZES, BUTTON_VARIANTS, type BetterCMSErrorCode, type BgToken, type BindingKind, type BlockBinding, type BlockHoverStyle, type BlockStyle, type BlockType, type ButtonAction, type ButtonBlock, type ButtonIcon, type ButtonLinkCandidate, type ButtonLookKey, type ButtonProps, type ButtonSiteLook, type ButtonSizeName, type ButtonValue, type ButtonVariant, CODE_SLOT_PREFIX, COMPONENT_PROP_TYPES, type CanonicalInputDefinition, type ChoiceOption, type CollectionBlock, type CollectionFilter, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentFormPropRef, type ComponentPropDef, type ComponentPropType, type ComponentPropUi, type ComponentProps, type ComponentSubField, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentModelFieldUi, type ContentPageResult, type ContentResponse, type ContentWidthToken, type CornerToken, DIALOG_SELECTOR, DOCK_BUDGET, DOCK_ICON_NAMES, DOCK_ICON_NAME_SET, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryEntrySeo, type DeliveryList, type DeliveryPage, type DerivedLocator, type DockBudget, type DockFieldLike, type DockFieldsetLike, type DockIconName, type DockInputRef, type DockLane, type DockNode, type DockPropGroupLike, type DockScreen, type ElementLike, type ExpandedBinding, FIELD_SIZE_ZOOM, FIELD_STYLE_KEYS, FOOTER_SECTION_ID, type FieldConfig, type FieldSize, type FieldStyle, type FieldStyleKey, type FieldStyles, type Fieldset, type FieldsetKind, type FieldsetUiBefore, type FontSizeToken, type FooterBlock, type FooterColumn, type FooterProps, type Form, type FormBlock, type FormField, type FormProps, type FormSubmission, type HeadingBlock, type HeadingProps, type ImageBlock, type ImageProps, LANDMARK_SELECTOR, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, LINK_RELS, LINK_VALUE_TYPES, type LandmarkChainElement, type LandmarkElement, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type LinkRel, type LinkValue, type LinkValueType, type LocatorGrammar, MAIN_SELECTOR, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, type NumberFieldFormat, type NumberScale, OPTION_DESCRIPTION_MAX, type OpenMode, PAGE_CONTENT_ANCHOR_ID, type Page, type PageLayoutOverrideDataDocument, type PageLayoutOverrideDocument, type PageLayoutOverrideState, type PageLayoutOverrideStructureDocument, type PageLayoutSectionOverride, type PageLayoutSectionStructureOverride, type PageMetaJson, type PageOnlyLayoutSection, type PageSectionPlacement, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type PropGroup, RESPONSIVE_CSS, type RadiusToken, type ReadButtonValue, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, SECTION_SPACE_TOKENS, SLOT_CHILD_KEYS, SLOT_ITEMS_CAP, SLOT_MAX_ITEMS, SPACE_BOTTOM_TOKENS, SPACE_STEP_TOKENS, type ScaleUnit, type SectionBlock, type SectionPlanItem, type SectionProps, type SectionSpaceToken, type ShadowToken, type ShowIf, type ShowIfRule, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SlotChild, type SlotItem, type SlotShapeOptions, type SlotShapeProblem, type SlotValue, type SpaceStepToken, type SpaceToken, type SpacerBlock, type SpacerProps, TABLE_COLUMN_TYPES, TABLE_JSONLD_TYPES, TABLE_LIMITS, TABLE_RESPONSIVE, TAG_HEADS, type TabItem, type TableCell, type TableCellObject, type TableCellValue, type TableCheckOptions, type TableColumn, type TableColumnType, type TableFieldOptions, type TableFootnote, type TableGroup, type TableLink, type TableProblem, type TableRef, type TableRefResolved, type TableRow, type TableValue, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type UiBefore, type UiOrigin, VIDEO_TRANSCRIPT_MAX, VIDEO_VALUE_KEYS, type VariantInputMapping, type VideoBlock, type VideoProps, type VideoValue, type VisibilityWindow, type WeightToken, type WindowState, type Workspace, type ZoneField, anchorTargetRel, blockStyleToColumnCss, blockStyleToCss, blockStyleToInnerCss, buttonBlockProps, buttonFullWidthProblem, buttonIconOf, buttonIconSvg, buttonLinkPairs, buttonLookValue, buttonSiteLookOf, buttonValueOfInstance, buttonValueProblem, buttonVariantOf, candidateRole, componentInstanceAddresses, componentPropTargetKey, derivedPairs, dockBudget, dockScreens, expandBlockBindings, fieldGroupOf, fieldStyleCssText, fieldStyleToCss, formatNumber, formatPropsAttribute, getBlockType, headingPaintCss, hideOnAttr, inWindow, isBlock, isButtonLookValue, isChromeLandmark, isCodeButton, isLinkObject, isScriptHref, isSlotChild, isTableValue, keyWords, landmarkRegions, linkAnchorOf, linkHref, linkRefOf, linkValueProblem, locatorFor, normalizeLinkValue, normalizeTableValue, normalizeWindow, parseNumberText, parsePropsAttribute, pickFieldStyle, placementBindOf, planSections, readButtonValue, readNumberFormat, readPath, regionOf, renderTableHtml, safeCssUrl, slotBindOf, slotChildValues, slotItems, slotPathString, slotShapeProblems, spaceTokenCss, splitButtonStyle, tableCellText, tablePathString, tableRefCells, tableSearchText, tableToMarkdown, tableValueProblems, topFieldKeyOf, usesHideOn, videoUrlOf, videoValueProblem, visibleBlocks, visibleDeliveredLayout, visibleLayoutStructure, windowState, withButtonLookProps };
3746
+ export { type AlignToken, type ApiError, type ApiKey, type ApiKeyPermission, type ApiKeyTokenType, type ArrayZoneConfig, type AssertEqual, type AuthResponse, type AuthSession, type AuthUser, BLOCK_BINDINGS, BREAKPOINTS, BUTTON_ACTIONS, BUTTON_FULL_WIDTH_INVALID, BUTTON_ICONS, BUTTON_ICON_NAMES, BUTTON_LOOK_KEYS, BUTTON_PLACEMENT_KEYS, BUTTON_SIZES, BUTTON_VARIANTS, type BetterCMSErrorCode, type BgToken, type BindingKind, type BlockBinding, type BlockHoverStyle, type BlockStyle, type BlockType, type ButtonAction, type ButtonBlock, type ButtonIcon, type ButtonLinkCandidate, type ButtonLookKey, type ButtonProps, type ButtonSiteLook, type ButtonSizeName, type ButtonValue, type ButtonVariant, CODE_SLOT_PREFIX, COMPONENT_PROP_TYPES, type CanonicalInputDefinition, type ChoiceOption, type CollectionBlock, type CollectionFilter, type CollectionProps, type ColorToken, type ColumnsBlock, type ColumnsProps, type Component, type ComponentBlock, type ComponentCategory, type ComponentFormPropRef, type ComponentPropDef, type ComponentPropType, type ComponentPropUi, type ComponentProps, type ComponentSubField, type ComponentVariantGroup, type Content, type ContentBlock, type ContentEntry, type ContentModel, type ContentModelField, type ContentModelFieldType, type ContentModelFieldUi, type ContentPageResult, type ContentResponse, type ContentWidthToken, type CornerToken, DIALOG_SELECTOR, DOCK_BUDGET, DOCK_ICON_NAMES, DOCK_ICON_NAME_SET, type DeepReadonly, type DeliveredLayout, type DeliveryComponent, type DeliveryEntry, type DeliveryEntrySeo, type DeliveryList, type DeliveryPage, type DerivedLocator, type DockBudget, type DockFieldLike, type DockFieldsetLike, type DockIconName, type DockInputRef, type DockLane, type DockNode, type DockPropGroupLike, type DockScreen, type ElementLike, type ExpandedBinding, FIELD_SIZE_ZOOM, FIELD_STYLE_KEYS, FOOTER_SECTION_ID, type FieldConfig, type FieldSize, type FieldStyle, type FieldStyleKey, type FieldStyles, type Fieldset, type FieldsetKind, type FieldsetUiBefore, type FontSizeToken, type FooterBlock, type FooterColumn, type FooterProps, type Form, type FormBlock, type FormField, type FormProps, type FormSubmission, type HeadingBlock, type HeadingProps, IMAGE_ASPECTS, IMAGE_FRAME_RADIUS, type ImageAspect, type ImageBlock, type ImageProps, LANDMARK_SELECTOR, LAYOUT_SECTION_ICONS, LAYOUT_SECTION_ICON_SET, LINK_RELS, LINK_VALUE_TYPES, type LandmarkChainElement, type LandmarkElement, type LayoutComponentItem, type LayoutDataDocument, type LayoutFieldDefinition, type LayoutFieldItem, type LayoutFieldType, type LayoutScalarFieldType, type LayoutSection, type LayoutSectionIcon, type LayoutSectionItem, type LayoutStructureDocument, type LayoutZone, type LinkRel, type LinkValue, type LinkValueType, type LocatorGrammar, MAIN_SELECTOR, type ManagementLayoutCommand, type MediaAsset, type MediaCaptionTrack, type MediaFieldValue, NAVIGATION_SECTION_ID, type NavLink, type NavbarBlock, type NavbarProps, type NumberFieldFormat, type NumberScale, OPTION_DESCRIPTION_MAX, type OpenMode, PAGE_CONTENT_ANCHOR_ID, type Page, type PageLayoutOverrideDataDocument, type PageLayoutOverrideDocument, type PageLayoutOverrideState, type PageLayoutOverrideStructureDocument, type PageLayoutSectionOverride, type PageLayoutSectionStructureOverride, type PageMetaJson, type PageOnlyLayoutSection, type PageSectionPlacement, type PaginatedResult, type Perspective, type PortableTextDocument, type PortableTextNode, type PropGroup, type PropTab, RESPONSIVE_CSS, type RadiusToken, type ReadButtonValue, type Redirect, type ReservedLayoutSection, type ResolvedLayoutNode, type RichTextBlock, type RichTextProps, SECTION_DOCTRINE, SECTION_SPACE_TOKENS, SIDE_SPACE_MIN_PX, SIDE_SPACE_TOKENS, SLOT_CHILD_KEYS, SLOT_ITEMS_CAP, SLOT_MAX_ITEMS, SPACE_BOTTOM_TOKENS, SPACE_STEP_TOKENS, type ScaleUnit, type SectionBlock, type SectionPlanItem, type SectionProps, type SectionSpaceToken, type ShadowToken, type ShowIf, type ShowIfRule, type SignInInput, type SignUpInput, type SiteSeoDefaults, type SlideItem, type SliderBlock, type SliderProps, type SlotChild, type SlotItem, type SlotShapeOptions, type SlotShapeProblem, type SlotValue, type SpaceStepToken, type SpaceToken, type SpacerBlock, type SpacerProps, TABLE_COLUMN_TYPES, TABLE_JSONLD_TYPES, TABLE_LIMITS, TABLE_RESPONSIVE, TAG_HEADS, type TabItem, type TableCell, type TableCellObject, type TableCellValue, type TableCheckOptions, type TableColumn, type TableColumnType, type TableFieldOptions, type TableFootnote, type TableGroup, type TableLink, type TableProblem, type TableRef, type TableRefResolved, type TableRow, type TableValue, type TabsBlock, type TabsProps, type TextBlock, type TextProps, type ThemeToken, type UiBefore, type UiOrigin, VIDEO_TRANSCRIPT_MAX, VIDEO_VALUE_KEYS, type VariantInputMapping, type VideoBlock, type VideoProps, type VideoValue, type VisibilityWindow, type WeightToken, type WindowState, type Workspace, type ZoneField, anchorTargetRel, blockStyleToColumnCss, blockStyleToCss, blockStyleToInnerCss, buttonBlockProps, buttonFullWidthProblem, buttonIconOf, buttonIconSvg, buttonLinkPairs, buttonLookValue, buttonSiteLookOf, buttonValueOfInstance, buttonValueProblem, buttonVariantOf, candidateRole, componentInstanceAddresses, componentPropTargetKey, derivedPairs, dockBudget, dockScreens, expandBlockBindings, fieldGroupOf, fieldStyleCssText, fieldStyleToCss, formatNumber, formatPropsAttribute, getBlockType, headingPaintCss, hiddenEverywhere, hideOnAttr, imageFrameCss, inWindow, isBlock, isButtonLookValue, isChromeLandmark, isCodeButton, isLinkObject, isScriptHref, isSlotChild, isTableValue, keyWords, landmarkRegions, linkAnchorOf, linkHref, linkRefOf, linkValueProblem, locatorFor, normalizeLinkValue, normalizeTableValue, normalizeWindow, parseNumberText, parsePropsAttribute, pickFieldStyle, placementBindOf, planSections, readButtonValue, readNumberFormat, readPath, regionOf, renderTableHtml, safeCssUrl, sideFloorApplies, sideSpaceCss, slotBindOf, slotChildValues, slotItems, slotPathString, slotShapeProblems, spaceTokenCss, splitButtonStyle, tableCellText, tablePathString, tableRefCells, tableSearchText, tableToMarkdown, tableValueProblems, topFieldKeyOf, usesHideOn, videoUrlOf, videoValueProblem, visibleBlocks, visibleDeliveredLayout, visibleLayoutStructure, windowState, withButtonLookProps };
package/dist/index.js CHANGED
@@ -29,6 +29,11 @@ function windowState(item, now) {
29
29
  return "live";
30
30
  }
31
31
  var inWindow = (item, now) => windowState(item, now) === "live";
32
+ function hiddenEverywhere(item) {
33
+ const style = item && typeof item === "object" ? item.style : void 0;
34
+ const raw = style && typeof style === "object" ? style.hideOn : void 0;
35
+ return Array.isArray(raw) && raw.includes("mobile") && raw.includes("tablet") && raw.includes("desktop");
36
+ }
32
37
  function mapSame(list, fn) {
33
38
  let changed = false;
34
39
  const out = list.map((item) => {
@@ -55,7 +60,7 @@ function withVisibleChildren(block, now) {
55
60
  }
56
61
  function visibleBlocks(blocks, now) {
57
62
  if (!Array.isArray(blocks)) return blocks;
58
- const shown = blocks.filter((block) => inWindow(block, now));
63
+ const shown = blocks.filter((block) => inWindow(block, now) && !hiddenEverywhere(block));
59
64
  const pruned = mapSame(
60
65
  shown,
61
66
  (block) => block && typeof block === "object" ? withVisibleChildren(block, now) : block
@@ -249,6 +254,8 @@ function componentInstanceAddresses(instanceBlockId, props, owner) {
249
254
  // src/sectionSpace.ts
250
255
  var SECTION_SPACE_TOKENS = [
251
256
  "section-space-none",
257
+ // V2's six-step band rhythm (None · XS · S · M · L · XL); added after the five, so nothing stored moves.
258
+ "section-space-xsmall",
252
259
  "section-space-small",
253
260
  "section-space-medium",
254
261
  "section-space-large",
@@ -261,10 +268,12 @@ var SPACE_BOTTOM_TOKENS = SECTION_SPACE_TOKENS.filter(
261
268
  );
262
269
  var SPACE_TOKEN_PX = {
263
270
  "section-space-none": "0px",
271
+ "section-space-xsmall": "16px",
264
272
  "section-space-small": "32px",
265
- "section-space-medium": "64px",
266
- "section-space-large": "96px",
267
- "section-space-xlarge": "144px",
273
+ // V2's band px (site/context.tsx PAD: none 0 · xs 16 · sm 32 · md 56 · lg 88 · xl 128).
274
+ "section-space-medium": "56px",
275
+ "section-space-large": "88px",
276
+ "section-space-xlarge": "128px",
268
277
  "section-space-nav-overlap": "-72px",
269
278
  "space-none": "0px",
270
279
  "space-s": "8px",
@@ -272,6 +281,17 @@ var SPACE_TOKEN_PX = {
272
281
  "space-l": "32px",
273
282
  "space-xl": "64px"
274
283
  };
284
+ var SIDE_SPACE_TOKENS = [...SPACE_STEP_TOKENS, ...SPACE_BOTTOM_TOKENS];
285
+ var SIDE_SPACE_MIN_PX = 16;
286
+ function sideSpaceCss(token) {
287
+ const css = spaceTokenCss(token);
288
+ if (!css || !SPACE_BOTTOM_TOKENS.includes(token)) return css;
289
+ return `max(${SIDE_SPACE_MIN_PX}px,${css})`;
290
+ }
291
+ function sideFloorApplies(style) {
292
+ const band = style.spaceTop !== void 0 || style.spaceBottom !== void 0 || typeof style.paddingTop === "number" || typeof style.paddingBottom === "number";
293
+ return band && style.spaceSides === void 0 && typeof style.paddingSides !== "number" && style.paddingX === void 0;
294
+ }
275
295
  function spaceTokenCss(token) {
276
296
  const px = typeof token === "string" ? SPACE_TOKEN_PX[token] : void 0;
277
297
  return px ? `var(--bcms-${token},${px})` : "";
@@ -291,6 +311,23 @@ var FONT_SIZE_REM = {
291
311
  };
292
312
  var WEIGHT = { normal: 400, medium: 500, semibold: 600, bold: 700 };
293
313
  var RADIUS_PX = { none: "0", sm: "4px", md: "8px", lg: "16px", full: "9999px" };
314
+ var IMAGE_ASPECTS = ["16/9", "16/7", "4/3", "4/5", "1/1"];
315
+ var IMAGE_FRAME_RADIUS = "calc(var(--bcms-radius-card,14px) * 1.8)";
316
+ function imageFrameCss(style) {
317
+ if (!style || typeof style !== "object") return null;
318
+ const s = style;
319
+ if (typeof s.aspect !== "string" || !IMAGE_ASPECTS.includes(s.aspect)) return null;
320
+ const ownRadius = typeof s.radius === "string" && RADIUS_PX[s.radius] != null || typeof s.radiusPx === "number" && Number.isFinite(s.radiusPx);
321
+ return {
322
+ // Block, as V2's preflight draws an <img>: inline, it sat on a text baseline and the box ran
323
+ // ~7px taller than the picture (445px image in a 452px box at 1280).
324
+ display: "block",
325
+ width: "100%",
326
+ aspectRatio: s.aspect.replace("/", " / "),
327
+ objectFit: "cover",
328
+ ...ownRadius ? {} : { borderRadius: IMAGE_FRAME_RADIUS }
329
+ };
330
+ }
294
331
  var COLOR_HEX = { white: "#ffffff", black: "#111111", muted: "#6b7280", mutedBg: "#f3f4f6", primary: "#111111", accent: "#4f46e5" };
295
332
  var THEME = {
296
333
  light: { colorScheme: "light", background: "#ffffff", color: "#111111" },
@@ -302,6 +339,11 @@ var BG_HEX = {
302
339
  accent: "var(--bcms-bg-accent,#4f46e5)",
303
340
  dark: "var(--bcms-bg-dark,#0b0b0d)"
304
341
  };
342
+ var DARK_BG_HEX = { surface: "#0b0b0d", muted: "#1c1c1e" };
343
+ var FILL_SCHEME = {
344
+ dark: { colorScheme: "dark", color: "#f7f8f8" },
345
+ accent: { colorScheme: "var(--bcms-accent-scheme,dark)", color: "var(--bcms-on-accent,#ffffff)" }
346
+ };
305
347
  var CORNER_PX = { "0": "0", s: "4px", m: "8px", l: "16px", xl: "24px", "2xl": "32px" };
306
348
  var SHADOW_CSS = {
307
349
  "0": "none",
@@ -354,7 +396,7 @@ function blockStyleToCss(style) {
354
396
  }
355
397
  const top = spaceTokenCss(s.spaceTop);
356
398
  const bottom = SPACE_BOTTOM_TOKENS.includes(s.spaceBottom ?? "") ? spaceTokenCss(s.spaceBottom) : "";
357
- const sides = spaceTokenCss(s.spaceSides);
399
+ const sides = sideSpaceCss(s.spaceSides);
358
400
  const navOverlap = s.spaceTop === "section-space-nav-overlap";
359
401
  if (top && !navOverlap) css.paddingTop = top;
360
402
  if (bottom) css.paddingBottom = bottom;
@@ -374,6 +416,8 @@ function blockStyleToCss(style) {
374
416
  if (s.fontSize && FONT_SIZE_REM[s.fontSize]) css.fontSize = FONT_SIZE_REM[s.fontSize];
375
417
  if (s.weight && WEIGHT[s.weight] != null) css.fontWeight = WEIGHT[s.weight];
376
418
  if (s.radius && RADIUS_PX[s.radius] != null) css.borderRadius = RADIUS_PX[s.radius];
419
+ const rpx = style.radiusPx;
420
+ if (typeof rpx === "number" && Number.isFinite(rpx)) css.borderRadius = `${clamp(Math.round(rpx), 0, 96)}px`;
377
421
  const theme = own(THEME, s.theme);
378
422
  if (theme) {
379
423
  css.colorScheme = theme.colorScheme;
@@ -382,7 +426,14 @@ function blockStyleToCss(style) {
382
426
  }
383
427
  if (s.bg === "custom") {
384
428
  if (HEX.test(s.bgCustom ?? "")) css.background = s.bgCustom;
385
- } else if (own(BG_HEX, s.bg)) css.background = own(BG_HEX, s.bg);
429
+ } else if (own(BG_HEX, s.bg)) {
430
+ css.background = s.theme === "dark" && own(DARK_BG_HEX, s.bg) || own(BG_HEX, s.bg);
431
+ const fill = own(FILL_SCHEME, s.bg);
432
+ if (fill) {
433
+ css.colorScheme = fill.colorScheme;
434
+ css.color = fill.color;
435
+ }
436
+ }
386
437
  const bgImage = safeCssUrl(s.bgImage);
387
438
  if (bgImage) {
388
439
  css.backgroundImage = `url(${bgImage})`;
@@ -417,7 +468,8 @@ function blockStyleToCss(style) {
417
468
  function blockStyleToInnerCss(style) {
418
469
  if (!style || typeof style !== "object") return void 0;
419
470
  const s = style;
420
- const max = own(CONTENT_WIDTH_PX, s.contentWidth);
471
+ const free = style.contentWidthPx;
472
+ const max = typeof free === "number" && Number.isFinite(free) ? `${clamp(Math.round(free), 320, 2400)}px` : own(CONTENT_WIDTH_PX, s.contentWidth);
421
473
  if (!max) return void 0;
422
474
  const placement = s.contentAlign ?? s.align;
423
475
  const margin = placement === "left" ? "0 auto 0 0" : placement === "right" ? "0 0 0 auto" : "0 auto";
@@ -4262,6 +4314,8 @@ export {
4262
4314
  FIELD_SIZE_ZOOM,
4263
4315
  FIELD_STYLE_KEYS,
4264
4316
  FOOTER_SECTION_ID,
4317
+ IMAGE_ASPECTS,
4318
+ IMAGE_FRAME_RADIUS,
4265
4319
  LANDMARK_SELECTOR,
4266
4320
  LAYOUT_SECTION_ICONS,
4267
4321
  LAYOUT_SECTION_ICON_SET,
@@ -4274,6 +4328,8 @@ export {
4274
4328
  RESPONSIVE_CSS,
4275
4329
  SECTION_DOCTRINE,
4276
4330
  SECTION_SPACE_TOKENS,
4331
+ SIDE_SPACE_MIN_PX,
4332
+ SIDE_SPACE_TOKENS,
4277
4333
  SLOT_CHILD_KEYS,
4278
4334
  SLOT_ITEMS_CAP,
4279
4335
  SLOT_MAX_ITEMS,
@@ -4314,7 +4370,9 @@ export {
4314
4370
  formatPropsAttribute,
4315
4371
  getBlockType,
4316
4372
  headingPaintCss,
4373
+ hiddenEverywhere,
4317
4374
  hideOnAttr,
4375
+ imageFrameCss,
4318
4376
  inWindow,
4319
4377
  isBlock,
4320
4378
  isButtonLookValue,
@@ -4345,6 +4403,8 @@ export {
4345
4403
  regionOf,
4346
4404
  renderTableHtml,
4347
4405
  safeCssUrl,
4406
+ sideFloorApplies,
4407
+ sideSpaceCss,
4348
4408
  slotBindOf,
4349
4409
  slotChildValues,
4350
4410
  slotItems,