@riverbankcms/sdk 0.78.2 → 0.79.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.
Files changed (159) hide show
  1. package/README.md +80 -0
  2. package/dist/{PreviewEditorSidebar-4DXLYX2V.mjs → PreviewEditorSidebar-56NMJMIK.mjs} +724 -47
  3. package/dist/{PreviewEditorUI-CS5P4N3P.mjs → PreviewEditorUI-27KJVEET.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-H4BSP6E7.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +36 -0
  6. package/dist/_dts/api/src/endpoints.d.ts +55 -0
  7. package/dist/_dts/api/src/index.d.ts +5 -3
  8. package/dist/_dts/api/src/media.d.ts +8 -1
  9. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  10. package/dist/_dts/api/src/navigation/dashboardSiteNav.d.ts +8 -8
  11. package/dist/_dts/api/src/navigation/identity.d.ts +59 -0
  12. package/dist/_dts/api/src/navigation.d.ts +2 -0
  13. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +4 -0
  14. package/dist/_dts/api/src/sdkContracts.d.ts +1 -0
  15. package/dist/_dts/api/src/siteIcons.d.ts +128 -0
  16. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +16 -0
  17. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +7 -0
  18. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +6 -1
  19. package/dist/_dts/api/src/types.d.ts +1 -1
  20. package/dist/_dts/api/src/webhooks.d.ts +239 -0
  21. package/dist/_dts/blocks/src/index.d.ts +4 -0
  22. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +288 -288
  23. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +288 -288
  24. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +288 -288
  25. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +288 -288
  26. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +288 -288
  27. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +294 -289
  28. package/dist/_dts/blocks/src/system/blocks/feature-card-icons.d.ts +57 -0
  29. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +4 -0
  30. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +288 -288
  31. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  32. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -1
  33. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +22 -22
  34. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +288 -288
  35. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +288 -288
  36. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +288 -288
  37. package/dist/_dts/blocks/src/system/blocks/testimonials.d.ts +7 -1
  38. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +170 -0
  39. package/dist/_dts/blocks/src/system/fragments/library/testimonialsCarousel.d.ts +5 -0
  40. package/dist/_dts/blocks/src/system/helpers/resolveBackground.d.ts +3 -1
  41. package/dist/_dts/blocks/src/system/icons/ids.d.ts +13 -0
  42. package/dist/_dts/blocks/src/system/icons/index.d.ts +6 -0
  43. package/dist/_dts/blocks/src/system/icons/presets.d.ts +4 -0
  44. package/dist/_dts/blocks/src/system/icons/registry.d.ts +18 -0
  45. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +239 -0
  46. package/dist/_dts/blocks/src/system/icons/value.d.ts +94 -0
  47. package/dist/_dts/blocks/src/system/index.d.ts +1 -0
  48. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +4 -1
  49. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +23 -0
  50. package/dist/_dts/blocks/src/system/runtime/nodes/feature-card-icon.d.ts +13 -0
  51. package/dist/_dts/content-model/src/contentManifest.d.ts +3 -1
  52. package/dist/_dts/core/src/branded.d.ts +6 -0
  53. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +191 -0
  54. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +12 -1
  55. package/dist/_dts/editor-blocks/src/block-editor/BlockCardBody.d.ts +12 -1
  56. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +12 -2
  57. package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +21 -0
  58. package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +40 -0
  59. package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +11 -1
  60. package/dist/_dts/editor-blocks/src/block-editor/featureCardIconActions.d.ts +82 -0
  61. package/dist/_dts/editor-blocks/src/widgets/icon-picker/IconPickerField.d.ts +1 -1
  62. package/dist/_dts/media-core/src/fileDomain.d.ts +8 -1
  63. package/dist/_dts/media-editor/src/MediaEditor.d.ts +3 -2
  64. package/dist/_dts/media-react/src/components/MediaLibrary.d.ts +2 -1
  65. package/dist/_dts/media-react/src/components/MediaPickerMini.d.ts +2 -1
  66. package/dist/_dts/preview-next/src/client/blocks/previewCustomizeActions.d.ts +17 -0
  67. package/dist/_dts/preview-next/src/client/preview/PageDesignEditorStateContext.d.ts +4 -0
  68. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +3 -2
  69. package/dist/_dts/preview-next/src/client/preview/previewCustomizeHistory.d.ts +6 -0
  70. package/dist/_dts/sdk/src/cli/navigationIdentity.d.ts +11 -0
  71. package/dist/_dts/sdk/src/cli/site-commands/navigationCommands.d.ts +4 -0
  72. package/dist/_dts/sdk/src/cli/site-commands/oneOffCommands.d.ts +1 -0
  73. package/dist/_dts/sdk/src/cli/sync/diff.d.ts +9 -0
  74. package/dist/_dts/sdk/src/client/management/types.d.ts +2 -0
  75. package/dist/_dts/sdk/src/config/field-definitions.d.ts +3 -1
  76. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  77. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +19 -2
  78. package/dist/_dts/sdk/src/next/index.d.ts +1 -1
  79. package/dist/_dts/sdk/src/next/revalidate.d.ts +26 -5
  80. package/dist/_dts/sdk/src/next/static-params.d.ts +28 -3
  81. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -1
  82. package/dist/_dts/sdk/src/public-api/runtime.d.ts +1 -1
  83. package/dist/_dts/sdk/src/version.d.ts +1 -1
  84. package/dist/_dts/sdk/src/webhooks/index.d.ts +1 -1
  85. package/dist/_dts/sdk/src/webhooks/verify.d.ts +6 -102
  86. package/dist/_dts/site-commands/src/commands.d.ts +3 -0
  87. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  88. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +3 -3
  89. package/dist/_dts/theme-core/src/schema.d.ts +5 -5
  90. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +25 -2
  91. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +5 -5
  92. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  93. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +4 -4
  94. package/dist/_dts/theme-core/src/tokens/themeColorTokens.d.ts +2 -0
  95. package/dist/_dts/ui/src/combobox.d.ts +1 -0
  96. package/dist/{chunk-RGTOD4AJ.mjs → chunk-4HCW7FHJ.mjs} +491 -56
  97. package/dist/{chunk-OKMBEAXY.mjs → chunk-A3HHFKVT.mjs} +1 -1
  98. package/dist/{chunk-6HYXHRAI.mjs → chunk-GP555I66.mjs} +177 -7
  99. package/dist/{chunk-CR5HKAGU.mjs → chunk-K2IIF34C.mjs} +55 -0
  100. package/dist/{chunk-4QEGTLK6.mjs → chunk-LCY32PXF.mjs} +1 -1
  101. package/dist/{chunk-MCRQMPET.mjs → chunk-V47ZU33I.mjs} +1745 -157
  102. package/dist/cli/index.mjs +1169 -171
  103. package/dist/cli/init-docs/content/workflow-editor-workflows.md +2 -0
  104. package/dist/cli/init-docs/content/workflow-isr-revalidation.md +138 -0
  105. package/dist/client/{accordion-PLYNJIIM.mjs → accordion-QLA7KBYO.mjs} +1 -1
  106. package/dist/client/{bookingForm-BXAP6AO7.mjs → bookingForm-PYZIPA5G.mjs} +3 -3
  107. package/dist/client/bookings.mjs +110 -2
  108. package/dist/client/{carousel-TRBXDHGF.mjs → carousel-5EIULWBI.mjs} +2 -2
  109. package/dist/client/{cart-Z7H3HJRS.mjs → cart-DOP3FNI4.mjs} +5 -5
  110. package/dist/client/{checkout-WAFCUBIX.mjs → checkout-BVMF6FBV.mjs} +5 -5
  111. package/dist/client/{chunk-JRDUHZCT.mjs → chunk-44K2U3QI.mjs} +4 -4
  112. package/dist/client/{chunk-UVQEJJTN.mjs → chunk-CCNTDRCF.mjs} +1 -1
  113. package/dist/client/{chunk-ZI3LLBPZ.mjs → chunk-GG4M2NP6.mjs} +1 -1
  114. package/dist/client/{chunk-JGXPTEI2.mjs → chunk-R5ESWNKX.mjs} +6 -3
  115. package/dist/client/{chunk-CWGTG37I.mjs → chunk-TYONZMST.mjs} +1 -1
  116. package/dist/client/{chunk-75OUS5MT.mjs → chunk-UDS3NTWA.mjs} +1 -1
  117. package/dist/client/{chunk-DNRGY432.mjs → chunk-V6M5FCR5.mjs} +1 -1
  118. package/dist/client/{chunk-FUXW6VW2.mjs → chunk-YLDYVRZL.mjs} +4 -4
  119. package/dist/client/client.mjs +21329 -19729
  120. package/dist/client/{courseRegistration-AHFQHWIJ.mjs → courseRegistration-E6EAA6NL.mjs} +3 -3
  121. package/dist/client/{eventCalendar-LDXTV5R7.mjs → eventCalendar-HBG3HAK6.mjs} +5 -5
  122. package/dist/client/{eventCombined-A4JGTNJO.mjs → eventCombined-6K5ZZWAK.mjs} +5 -5
  123. package/dist/client/{eventDetails-4YXTZ7EG.mjs → eventDetails-Q75ICXLT.mjs} +5 -5
  124. package/dist/client/{eventListing-P72TPFFM.mjs → eventListing-27P5F7DZ.mjs} +5 -5
  125. package/dist/client/{eventRegistration-LSYJHGMT.mjs → eventRegistration-IQ7AMASR.mjs} +5 -5
  126. package/dist/client/{form-AOPYOKOW.mjs → form-JRTD65FN.mjs} +1 -1
  127. package/dist/client/{headerSection-5TFYDFVQ.mjs → headerSection-7FPSSZHS.mjs} +2 -2
  128. package/dist/client/hooks.mjs +350 -35
  129. package/dist/client/{locationMap-QSZ3ZVAZ.mjs → locationMap-7NGFNYBH.mjs} +1 -1
  130. package/dist/client/{newsletterForm-KTRHZY52.mjs → newsletterForm-F3BADCI2.mjs} +1 -1
  131. package/dist/client/{productDetail-N4E775RG.mjs → productDetail-V3HP7ITJ.mjs} +5 -5
  132. package/dist/client/{productList-UGUQ2S45.mjs → productList-L3EGJUF2.mjs} +5 -5
  133. package/dist/client/rendering/client.mjs +2713 -1382
  134. package/dist/client/rendering/islands.mjs +18 -18
  135. package/dist/client/rendering.mjs +2014 -414
  136. package/dist/client/{shop-VHSZEEQ2.mjs → shop-DQUB5E2C.mjs} +5 -5
  137. package/dist/preview-next/before-render.mjs +55 -0
  138. package/dist/preview-next/client/runtime.mjs +5 -5
  139. package/dist/preview-next/middleware.mjs +55 -0
  140. package/dist/{sdk-runtime-WHPJEF5G.mjs → sdk-runtime-AF6KXJU4.mjs} +6 -6
  141. package/dist/server/components.mjs +2169 -781
  142. package/dist/server/config-validation.mjs +350 -35
  143. package/dist/server/config.mjs +350 -35
  144. package/dist/server/data.mjs +350 -35
  145. package/dist/server/index.mjs +64 -1
  146. package/dist/server/next/revalidate.mjs +229 -34
  147. package/dist/server/next.mjs +2307 -818
  148. package/dist/server/page-converter.mjs +275 -34
  149. package/dist/server/prebuild.mjs +1 -1
  150. package/dist/server/rendering/server.mjs +2174 -786
  151. package/dist/server/rendering.mjs +2187 -799
  152. package/dist/server/routing.mjs +767 -50
  153. package/dist/server/server.mjs +351 -36
  154. package/dist/server/theme-bridge.mjs +164 -2
  155. package/dist/server/theme.mjs +2 -2
  156. package/dist/server/webhooks.mjs +129 -25
  157. package/dist/styles/index.css +55 -0
  158. package/package.json +2 -1
  159. package/dist/SdkPreviewModeRuntime-IJDHTW4W.mjs +0 -8
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { resolvePreviewDashboardSetupHandoff, buildPreviewDashboardSetupUrl, resolvePreviewSidebarChromeModel, resolvePreviewEditorGuidanceModel, canInspectSiteStyle, usePreviewDesignCoordinator, resolveStyleConfiguratorInitialSnapshot, createStyleConfiguratorState, createOptimisticActionRunner, syncStyleConfiguratorState, isPreviewingChange, planSiteStylePreviewChange, openRow, previewSiteStyle, applyResolvedSelections, previewButtonPersonality, previewHeaderLayout, previewHeaderStyle, planSiteChromeLookSelection, previewFooterLook, previewPaletteVariant, previewTypographyPreset, setTypographyBodyFontOverride, setTypographyHeadingFontOverride, clearTypographyFontOverrides, setPaletteOverrides, toggleRow, cancelPreview, dismissWarnings, dismissNotices, markApplyFailed, markApplySaved, markApplySaving, canApplySiteStyle, buildSiteChromeLookModels, cycleSiteChromeLookId, cycleableSiteChromeOptions } from './chunk-4QEGTLK6.mjs';
3
- import { KeyboardCode, getBlockDefinition, CSS, useSdkConfig, listBlockDescriptors, useSensor, PointerSensor, useSensors, deleteBlock, createEditorRemoveBlockCommand, unsafeAsEditorBlockId, DndContext, closestCenter, Button, Plus, useDroppable, useDraggable, useCombinedRefs, isKeyboardEvent, createCustomBlockRegistry, Card, cn, Collapsible, CollapsibleContent, listContentTypes, mergeBlockDescriptorsWithRegistry, createBlock, createEditorReorderBlocksCommand, reorderBlocks, mutateBlockContent, useDndContext, useUniqueId, useIsomorphicLayoutEffect, EmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Search, getClientRect, resolveBlockTitle, CardHeader, GripVertical, ChevronRight, CardTitle, ArrowUp, ArrowDown, DropdownMenu, DropdownMenuTrigger, EllipsisVertical, DropdownMenuContent, DropdownMenuItem, Settings, DropdownMenuSeparator, Copy, Trash2, DialogFooter, DialogClose, CardContent, createEditorInsertBlockCommand, LoaderCircle, ChevronDown, normalEditorCuratedPromotedFieldPaths, resolveVisiblePromotedFieldPathsForEditorBlock, createStoreBackend, validateBlockManifestIssues, Callout, CalloutTitle, unfinishedBlockCopy, CalloutDescription, recoveryConflictCopy, ManifestForm, unsafeAsEditorBlockValues, Box, createManifestFormAdapter, getModalConfig, isNonEmptyValue, ScrollableDialogContent, FormRenderer, Tabs, TabsList, TabsTrigger, TabsContent, mergeManifestWithSdkOptions, augmentManifestWithStyleGroups, lucide_react_exports, isThemeV2NormalEditorRawStylePath, getFieldIntent, isHeaderField, isThemeV2NormalEditorRawStyleFieldName, unwrapResponse, useEntryController, useEditorUiStoreInstance, useUISelector, resolvePreviewSidebarTab, BackgroundGradientField, BackgroundColorField, X, omitRouteTitleFieldFromManifest, getRouteMetadataManifestForType, createManifestValidation, previewAssistantEnabled, useField, FieldFrame, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, isCtaIconName, Combobox, CTA_ICON_OPTIONS, getCtaIconComponent, useBackendWatch, useAsyncPickerOptions, shouldShowPickerSearch, normalizePickerSearchThreshold, Badge, resolvePickerSelectionLabel, useMediaEditorOptional, useRichTextEditor, RichTextEditorSurface, ThemeScope, useBlockContext, resolveMediaSlotContract, asRecord, parseAspectRatioValue, MediaEditor, PUBLIC_FILE_FIELD_KINDS, CollapsibleTrigger, ContentFieldsForm, getCuratedSiteStyle, paletteOverridesSchema, findButtonPersonality, findPaletteVariant, findTypographyPreset, getHeaderLayout, getHeaderStyle, findFooterLook, footerLookCatalog, isObjectRecord, EMPTY_DOC, getRichTextImagePositionFromTarget, insertOrReplaceRichTextImage, resolveVideoSelectionIntentForMediaField, emitMediaCropDebug, Pencil, foldSubroute, SUBROUTE_KINDS, Smartphone, Tablet, Monitor, Maximize2, DropdownMenuLabel, expectParsedBrandedId, parseSiteId, buildThemeRuntime, PaletteProvider, MediaEditorProvider, curatedSiteStyles, ChevronLeft, requireEntriesForCuratedChoices, buttonPersonalities, typographyPresets, paletteVariants, resolveImageUrlWithContext, Root2, List, Trigger, Content, Input, Check, Label, isInternalResolvedLinkValue, evaluateTypographyFontSlot, Separator, classifyKnownMimeType, toRoutableLinkPayload, useMediaEditor, MediaPickerMini, MediaPickerDialog, Surface, ColorPicker, getDirectImageUrlForMediaAsset, isSvgMimeType } from './chunk-MCRQMPET.mjs';
4
- import { usePreviewAuth, getDashboardUrl } from './chunk-CR5HKAGU.mjs';
2
+ import { resolvePreviewDashboardSetupHandoff, buildPreviewDashboardSetupUrl, resolvePreviewSidebarChromeModel, resolvePreviewEditorGuidanceModel, canInspectSiteStyle, usePreviewDesignCoordinator, resolveStyleConfiguratorInitialSnapshot, createStyleConfiguratorState, createOptimisticActionRunner, syncStyleConfiguratorState, isPreviewingChange, planSiteStylePreviewChange, openRow, previewSiteStyle, applyResolvedSelections, previewButtonPersonality, previewHeaderLayout, previewHeaderStyle, planSiteChromeLookSelection, previewFooterLook, previewPaletteVariant, previewTypographyPreset, setTypographyBodyFontOverride, setTypographyHeadingFontOverride, clearTypographyFontOverrides, setPaletteOverrides, toggleRow, cancelPreview, dismissWarnings, dismissNotices, markApplyFailed, markApplySaved, markApplySaving, canApplySiteStyle, buildSiteChromeLookModels, cycleSiteChromeLookId, cycleableSiteChromeOptions } from './chunk-LCY32PXF.mjs';
3
+ import { KeyboardCode, getBlockDefinition, CSS, useSdkConfig, unwrapResponse, parseSiteIconStyleGuideVersionId, parseBlockIconValue, listBlockDescriptors, useSensor, PointerSensor, useSensors, deleteBlock, createEditorRemoveBlockCommand, unsafeAsEditorBlockId, DndContext, closestCenter, Button, Plus, useDroppable, useDraggable, useCombinedRefs, isKeyboardEvent, createCustomBlockRegistry, Card, cn, Collapsible, CollapsibleContent, listContentTypes, mergeBlockDescriptorsWithRegistry, createBlock, createEditorReorderBlocksCommand, reorderBlocks, mutateBlockContent, useDndContext, useUniqueId, useIsomorphicLayoutEffect, EmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Search, getClientRect, resolveBlockTitle, CardHeader, GripVertical, ChevronRight, CardTitle, ArrowUp, ArrowDown, DropdownMenu, DropdownMenuTrigger, EllipsisVertical, DropdownMenuContent, DropdownMenuItem, Settings, DropdownMenuSeparator, Sparkles, RotateCcw, ImagePlus, Copy, Trash2, DialogFooter, DialogClose, CardContent, createEditorInsertBlockCommand, LoaderCircle, ChevronDown, getFeatureCardIconCompletion, toFeatureCardIconSuggestionInputs, getBlockIconSemanticFallbackId, suggestSemanticIconForFeatureCard, getGeneratedBlockIconStyleState, assertNever, suggestFeatureCardSemanticIcons, applyFeatureCardIconSuggestions, createFeatureCardIconKey, Textarea, Callout, CalloutDescription, normalEditorCuratedPromotedFieldPaths, resolveVisiblePromotedFieldPathsForEditorBlock, createStoreBackend, validateBlockManifestIssues, CalloutTitle, unfinishedBlockCopy, recoveryConflictCopy, ManifestForm, unsafeAsEditorBlockValues, Box, createManifestFormAdapter, getModalConfig, isNonEmptyValue, ScrollableDialogContent, FormRenderer, Tabs, TabsList, TabsTrigger, TabsContent, mergeManifestWithSdkOptions, augmentManifestWithStyleGroups, lucide_react_exports, isThemeV2NormalEditorRawStylePath, getFieldIntent, isHeaderField, isThemeV2NormalEditorRawStyleFieldName, useEntryController, useEditorUiStoreInstance, useUISelector, resolvePreviewSidebarTab, BackgroundGradientField, BackgroundColorField, X, omitRouteTitleFieldFromManifest, getRouteMetadataManifestForType, createManifestValidation, previewAssistantEnabled, useField, FieldFrame, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, resolveIconPickerPreset, isIconPickerPreset, getIconPickerOptionsForPreset, isKnownIconName, Combobox, getIconComponent, useBackendWatch, useAsyncPickerOptions, shouldShowPickerSearch, normalizePickerSearchThreshold, Badge, resolvePickerSelectionLabel, useMediaEditorOptional, useRichTextEditor, RichTextEditorSurface, ThemeScope, useBlockContext, resolveMediaSlotContract, asRecord, parseAspectRatioValue, MediaEditor, PUBLIC_FILE_FIELD_KINDS, CollapsibleTrigger, ContentFieldsForm, getCuratedSiteStyle, paletteOverridesSchema, findButtonPersonality, findPaletteVariant, findTypographyPreset, getHeaderLayout, getHeaderStyle, findFooterLook, footerLookCatalog, isObjectRecord, EMPTY_DOC, getRichTextImagePositionFromTarget, insertOrReplaceRichTextImage, resolveVideoSelectionIntentForMediaField, emitMediaCropDebug, Pencil, foldSubroute, SUBROUTE_KINDS, Smartphone, Tablet, Monitor, Maximize2, DropdownMenuLabel, expectParsedBrandedId, parseSiteId, buildThemeRuntime, PaletteProvider, MediaEditorProvider, curatedSiteStyles, ChevronLeft, requireEntriesForCuratedChoices, buttonPersonalities, typographyPresets, paletteVariants, resolveImageUrlWithContext, Root2, List, Trigger, Content, Input, Check, Label, isInternalResolvedLinkValue, evaluateTypographyFontSlot, Separator, classifyKnownMimeType, toRoutableLinkPayload, useMediaEditor, MediaPickerMini, MediaPickerDialog, Surface, ColorPicker, getDirectImageUrlForMediaAsset, isSvgMimeType } from './chunk-V47ZU33I.mjs';
4
+ import { usePreviewAuth, getDashboardUrl } from './chunk-K2IIF34C.mjs';
5
5
  import './chunk-R7POPVJR.mjs';
6
- import React, { createContext, memo, useMemo, useState, useRef, useEffect, forwardRef, useCallback, useImperativeHandle, useContext, useSyncExternalStore, useLayoutEffect, useTransition, useId } from 'react';
6
+ import React, { createContext, memo, useMemo, useState, useRef, useEffect, forwardRef, useCallback, useImperativeHandle, useContext, useSyncExternalStore, useLayoutEffect, useReducer, useTransition, useId } from 'react';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { useRouter } from 'next/navigation';
9
9
 
@@ -47,7 +47,7 @@ function parseReferenceKind(referenceKind) {
47
47
  }
48
48
 
49
49
  // ../content-model/src/contentManifest.ts
50
- function assertNever(value) {
50
+ function assertNever2(value) {
51
51
  throw new Error(`Unhandled content field mapping decision: ${JSON.stringify(value)}`);
52
52
  }
53
53
  function resolveContentReferenceKind(field) {
@@ -178,7 +178,7 @@ function toFieldDefinition(field, context = {}) {
178
178
  valueFrom: mapping.valueFrom
179
179
  };
180
180
  default:
181
- return assertNever(mapping);
181
+ return assertNever2(mapping);
182
182
  }
183
183
  }
184
184
  case "link":
@@ -2301,6 +2301,451 @@ function blockSaveabilityEqual(left, right) {
2301
2301
  return nextIssue?.fieldPath === issue.fieldPath && nextIssue.message === issue.message;
2302
2302
  });
2303
2303
  }
2304
+
2305
+ // ../editor-blocks/src/block-editor/featureCardIconActions.ts
2306
+ function getFeatureCards(content) {
2307
+ const cards = content?.cards;
2308
+ return Array.isArray(cards) ? cards : [];
2309
+ }
2310
+ function getFeatureCardIconStatus(content) {
2311
+ return getFeatureCardIconCompletion(getFeatureCards(content));
2312
+ }
2313
+ function getFeatureCardIconDialogCards(content) {
2314
+ return toFeatureCardIconSuggestionInputs(getFeatureCards(content)).map((card, index) => {
2315
+ const semanticFallback = getBlockIconSemanticFallbackId(card.icon) ?? suggestSemanticIconForFeatureCard(card);
2316
+ return {
2317
+ cardKey: card.key,
2318
+ title: card.title.trim().length > 0 ? card.title.trim() : `Card ${index + 1}`,
2319
+ bodyText: card.bodyText.slice(0, 160),
2320
+ semanticIconId: semanticFallback
2321
+ };
2322
+ });
2323
+ }
2324
+ function getFeatureCardGeneratedIconStyleSummary(content, currentStyleGuideVersionId) {
2325
+ if (!currentStyleGuideVersionId) return { kind: "unavailable" };
2326
+ let generatedCount = 0;
2327
+ let staleCount = 0;
2328
+ let invalidGeneratedCount = 0;
2329
+ for (const card of getFeatureCards(content)) {
2330
+ const state = getGeneratedBlockIconStyleState(card.icon, currentStyleGuideVersionId);
2331
+ switch (state.kind) {
2332
+ case "not_generated":
2333
+ break;
2334
+ case "current":
2335
+ generatedCount += 1;
2336
+ break;
2337
+ case "stale":
2338
+ generatedCount += 1;
2339
+ staleCount += 1;
2340
+ break;
2341
+ case "invalid_generated":
2342
+ invalidGeneratedCount += 1;
2343
+ break;
2344
+ default:
2345
+ assertNever(state);
2346
+ }
2347
+ }
2348
+ return {
2349
+ kind: "available",
2350
+ generatedCount,
2351
+ staleCount,
2352
+ invalidGeneratedCount
2353
+ };
2354
+ }
2355
+ function applyCuratedFeatureCardIconSuggestions({
2356
+ blockId,
2357
+ content,
2358
+ drafts
2359
+ }) {
2360
+ const cards = getFeatureCards(content);
2361
+ if (cards.length === 0) return { kind: "no_cards" };
2362
+ const suggestions = suggestFeatureCardSemanticIcons(cards);
2363
+ if (suggestions.length === 0) return { kind: "complete" };
2364
+ const plan = applyFeatureCardIconSuggestions(cards, suggestions);
2365
+ switch (plan.kind) {
2366
+ case "applied":
2367
+ break;
2368
+ case "duplicate_card_key":
2369
+ case "duplicate_suggestion_card_key":
2370
+ case "missing_suggestion_card_key":
2371
+ case "unknown_card_key":
2372
+ return { kind: "plan_failed", reason: plan.kind, cardKey: plan.cardKey };
2373
+ case "invalid_semantic_icon":
2374
+ return { kind: "plan_failed", reason: plan.kind, iconId: plan.iconId };
2375
+ default:
2376
+ assertNever(plan);
2377
+ }
2378
+ for (const suggestion of plan.appliedSuggestions) {
2379
+ const cardIndex = cards.findIndex((card, index) => createFeatureCardIconKey(card, index) === suggestion.cardKey);
2380
+ if (cardIndex >= 0) {
2381
+ drafts.setAtPath(blockId, `cards.${cardIndex}.icon`, { kind: "semantic", iconId: suggestion.iconId });
2382
+ }
2383
+ }
2384
+ return { kind: "applied", appliedCount: plan.appliedSuggestions.length };
2385
+ }
2386
+ function planGeneratedFeatureCardIconSetApply(cards, assets) {
2387
+ const cardKeys = cards.map(createFeatureCardIconKey);
2388
+ const cardKeySet = new Set(cardKeys);
2389
+ const iconByCardKey = /* @__PURE__ */ new Map();
2390
+ for (const asset of assets) {
2391
+ if (iconByCardKey.has(asset.cardKey)) {
2392
+ return { kind: "duplicate_asset_card_key", cardKey: asset.cardKey };
2393
+ }
2394
+ if (!cardKeySet.has(asset.cardKey)) {
2395
+ return { kind: "unknown_card_key", cardKey: asset.cardKey };
2396
+ }
2397
+ const iconValue = parseBlockIconValue(asset.iconValue);
2398
+ if (iconValue.kind !== "generated") {
2399
+ return { kind: "invalid_generated_icon", cardKey: asset.cardKey };
2400
+ }
2401
+ iconByCardKey.set(asset.cardKey, iconValue);
2402
+ }
2403
+ const appliedIcons = [];
2404
+ for (const [cardIndex, cardKey] of cardKeys.entries()) {
2405
+ const iconValue = iconByCardKey.get(cardKey);
2406
+ if (!iconValue) {
2407
+ return { kind: "missing_asset_card_key", cardKey };
2408
+ }
2409
+ appliedIcons.push({ cardIndex, cardKey, iconValue });
2410
+ }
2411
+ return {
2412
+ kind: "applied",
2413
+ appliedIcons
2414
+ };
2415
+ }
2416
+ function applyGeneratedFeatureCardIconSet({
2417
+ blockId,
2418
+ content,
2419
+ drafts,
2420
+ assets
2421
+ }) {
2422
+ const cards = getFeatureCards(content);
2423
+ if (cards.length === 0) return { kind: "no_cards" };
2424
+ const plan = planGeneratedFeatureCardIconSetApply(cards, assets);
2425
+ switch (plan.kind) {
2426
+ case "applied":
2427
+ break;
2428
+ case "duplicate_asset_card_key":
2429
+ case "missing_asset_card_key":
2430
+ case "unknown_card_key":
2431
+ case "invalid_generated_icon":
2432
+ return { kind: "plan_failed", reason: plan.kind, cardKey: plan.cardKey };
2433
+ default:
2434
+ assertNever(plan);
2435
+ }
2436
+ for (const appliedIcon of plan.appliedIcons) {
2437
+ drafts.setAtPath(blockId, `cards.${appliedIcon.cardIndex}.icon`, appliedIcon.iconValue);
2438
+ }
2439
+ return { kind: "applied", appliedCount: plan.appliedIcons.length };
2440
+ }
2441
+ function reducer(state, action) {
2442
+ switch (action.type) {
2443
+ case "reset":
2444
+ return { kind: "idle" };
2445
+ case "generating":
2446
+ return { kind: "generating" };
2447
+ case "applying":
2448
+ return { kind: "applying", preview: action.preview };
2449
+ case "preview_ready":
2450
+ return { kind: "preview_ready", preview: action.preview };
2451
+ case "failed":
2452
+ return { kind: "failed", message: action.message };
2453
+ }
2454
+ }
2455
+ function getGenerationErrorMessage(error) {
2456
+ return error instanceof Error && error.message.length > 0 ? error.message : "Failed to generate icon set";
2457
+ }
2458
+ function validateGeneratedIconSetPreview(preview, cards) {
2459
+ const cardKeys = new Set(cards.map((card) => card.cardKey));
2460
+ if (cardKeys.size !== cards.length) {
2461
+ return { kind: "invalid", message: "Generated icon set could not match every card" };
2462
+ }
2463
+ const assetKeys = new Set(preview.assets.map((asset) => asset.cardKey));
2464
+ if (assetKeys.size !== preview.assets.length || assetKeys.size !== cardKeys.size) {
2465
+ return { kind: "invalid", message: "Generated icon set was incomplete" };
2466
+ }
2467
+ for (const asset of preview.assets) {
2468
+ if (!cardKeys.has(asset.cardKey)) {
2469
+ return { kind: "invalid", message: "Generated icon set was incomplete" };
2470
+ }
2471
+ if (parseBlockIconValue(asset.iconValue).kind !== "generated") {
2472
+ return { kind: "invalid", message: "Generated icon set included an invalid icon reference" };
2473
+ }
2474
+ }
2475
+ return { kind: "valid", preview };
2476
+ }
2477
+ function GeneratedIconSetDialog({
2478
+ open,
2479
+ onOpenChange,
2480
+ cards,
2481
+ styleGuideSummary,
2482
+ styleGuideEditHref,
2483
+ onGenerate,
2484
+ onApply
2485
+ }) {
2486
+ const [state, dispatch] = useReducer(reducer, { kind: "idle" });
2487
+ const [styleNote, setStyleNote] = useState("");
2488
+ const canGenerate = Boolean(onGenerate) && cards.length > 0 && state.kind !== "generating";
2489
+ const canApply = Boolean(onApply) && state.kind === "preview_ready";
2490
+ async function generate() {
2491
+ if (!onGenerate || cards.length === 0) return;
2492
+ dispatch({ type: "generating" });
2493
+ try {
2494
+ const result = await onGenerate({
2495
+ cards,
2496
+ userStyleNote: styleNote.trim().length > 0 ? styleNote.trim() : null
2497
+ });
2498
+ if (result.kind === "preview_ready") {
2499
+ const validation = validateGeneratedIconSetPreview(result.preview, cards);
2500
+ if (validation.kind === "invalid") {
2501
+ dispatch({ type: "failed", message: validation.message });
2502
+ return;
2503
+ }
2504
+ dispatch({ type: "preview_ready", preview: validation.preview });
2505
+ return;
2506
+ }
2507
+ dispatch({ type: "failed", message: result.message });
2508
+ } catch (error) {
2509
+ dispatch({ type: "failed", message: getGenerationErrorMessage(error) });
2510
+ }
2511
+ }
2512
+ function close(nextOpen) {
2513
+ onOpenChange(nextOpen);
2514
+ if (!nextOpen) dispatch({ type: "reset" });
2515
+ }
2516
+ async function apply(preview) {
2517
+ if (!onApply) return;
2518
+ dispatch({ type: "applying", preview });
2519
+ try {
2520
+ const result = await onApply(preview);
2521
+ if (result?.kind === "failed") {
2522
+ dispatch({ type: "failed", message: result.message });
2523
+ return;
2524
+ }
2525
+ close(false);
2526
+ } catch (error) {
2527
+ dispatch({ type: "failed", message: getGenerationErrorMessage(error) });
2528
+ }
2529
+ }
2530
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: close, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-2xl", children: [
2531
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
2532
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Generate icon set" }),
2533
+ /* @__PURE__ */ jsx(DialogDescription, { children: state.kind === "preview_ready" ? state.preview.styleGuideSummary : `${cards.length} cards` })
2534
+ ] }),
2535
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
2536
+ styleGuideSummary || styleGuideEditHref ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border bg-muted/20 px-3 py-2 text-sm", children: [
2537
+ styleGuideSummary ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: styleGuideSummary }) : null,
2538
+ styleGuideEditHref ? /* @__PURE__ */ jsx(
2539
+ "a",
2540
+ {
2541
+ href: styleGuideEditHref,
2542
+ className: "mt-1 inline-flex text-sm font-medium text-primary underline-offset-4 hover:underline",
2543
+ children: "Edit icon style"
2544
+ }
2545
+ ) : null
2546
+ ] }) : null,
2547
+ /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium", htmlFor: "generated-icon-style-note", children: "Icon style" }),
2548
+ /* @__PURE__ */ jsx(
2549
+ Textarea,
2550
+ {
2551
+ id: "generated-icon-style-note",
2552
+ value: styleNote,
2553
+ maxLength: 240,
2554
+ disabled: state.kind === "generating",
2555
+ onChange: (event) => setStyleNote(event.currentTarget.value),
2556
+ placeholder: "Simple, soft-edged, lightly textured"
2557
+ }
2558
+ ),
2559
+ state.kind === "failed" ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-destructive", children: state.message }) : null,
2560
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: cards.map((card) => {
2561
+ const previewAsset = state.kind === "preview_ready" || state.kind === "applying" ? state.preview.assets.find((asset) => asset.cardKey === card.cardKey) : null;
2562
+ return /* @__PURE__ */ jsxs(
2563
+ "div",
2564
+ {
2565
+ className: "grid min-h-24 grid-cols-[3rem_1fr] gap-3 rounded-md border bg-muted/20 p-3",
2566
+ children: [
2567
+ /* @__PURE__ */ jsx("div", { className: "flex size-12 items-center justify-center rounded-md border bg-background", children: previewAsset?.src ? /* @__PURE__ */ jsx(
2568
+ "img",
2569
+ {
2570
+ src: previewAsset.src,
2571
+ alt: "",
2572
+ className: "size-10 object-contain"
2573
+ }
2574
+ ) : /* @__PURE__ */ jsx(ImagePlus, { className: "size-5 text-muted-foreground", "aria-hidden": "true" }) }),
2575
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2576
+ /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium", children: card.title }),
2577
+ card.bodyText ? /* @__PURE__ */ jsx("p", { className: "overflow-hidden text-ellipsis text-xs text-muted-foreground", children: card.bodyText }) : null
2578
+ ] })
2579
+ ]
2580
+ },
2581
+ card.cardKey
2582
+ );
2583
+ }) })
2584
+ ] }),
2585
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
2586
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => close(false), children: "Cancel" }),
2587
+ /* @__PURE__ */ jsxs(
2588
+ Button,
2589
+ {
2590
+ type: "button",
2591
+ variant: "outline",
2592
+ disabled: !canGenerate,
2593
+ onClick: () => {
2594
+ void generate();
2595
+ },
2596
+ children: [
2597
+ state.kind === "preview_ready" ? /* @__PURE__ */ jsx(RotateCcw, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Sparkles, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
2598
+ state.kind === "preview_ready" ? "Regenerate" : state.kind === "generating" ? "Generating" : "Generate"
2599
+ ]
2600
+ }
2601
+ ),
2602
+ /* @__PURE__ */ jsx(
2603
+ Button,
2604
+ {
2605
+ type: "button",
2606
+ disabled: !canApply,
2607
+ onClick: () => {
2608
+ if (state.kind !== "preview_ready" || !onApply) return;
2609
+ void apply(state.preview);
2610
+ },
2611
+ children: state.kind === "applying" ? "Applying" : "Apply set"
2612
+ }
2613
+ )
2614
+ ] })
2615
+ ] }) });
2616
+ }
2617
+ function supportsFeatureCardIconActions(blockKind) {
2618
+ return blockKind === "block.feature-cards";
2619
+ }
2620
+ function FeatureCardIconsPanel({
2621
+ block,
2622
+ uiStore,
2623
+ currentStyleGuideVersionId,
2624
+ iconStyleGuideSummary,
2625
+ iconStyleGuideEditHref,
2626
+ onGenerateIconSet,
2627
+ onApplyGeneratedIconSet
2628
+ }) {
2629
+ const [generateDialogOpen, setGenerateDialogOpen] = useState(false);
2630
+ const blockId = typeof block.id === "string" ? unsafeAsEditorBlockId(block.id) : null;
2631
+ const currentValues = useStoreSelector(
2632
+ uiStore,
2633
+ (state) => blockId ? state.drafts.getCurrentValues(blockId) : null
2634
+ );
2635
+ const content = currentValues ?? block.draftContent ?? block.content ?? null;
2636
+ const status = useMemo(() => getFeatureCardIconStatus(content), [content]);
2637
+ const dialogCards = useMemo(() => getFeatureCardIconDialogCards(content), [content]);
2638
+ const styleSummary = useMemo(
2639
+ () => getFeatureCardGeneratedIconStyleSummary(content, currentStyleGuideVersionId),
2640
+ [content, currentStyleGuideVersionId]
2641
+ );
2642
+ const isComplete = status.totalCards > 0 && status.cardsWithIcons >= status.totalCards;
2643
+ const hasStaleGeneratedIcons = styleSummary.kind === "available" && styleSummary.staleCount > 0;
2644
+ async function applyGeneratedIconSetPreview(preview) {
2645
+ if (!blockId) return { kind: "failed", message: "Could not apply generated icon set" };
2646
+ const appliedPreview = await onApplyGeneratedIconSet?.(preview);
2647
+ const previewToApply = appliedPreview ?? preview;
2648
+ const result = applyGeneratedFeatureCardIconSet({
2649
+ blockId,
2650
+ content,
2651
+ drafts: uiStore.getState().drafts,
2652
+ assets: previewToApply.assets
2653
+ });
2654
+ if (result.kind !== "applied") {
2655
+ return { kind: "failed", message: "Could not apply generated icon set" };
2656
+ }
2657
+ return { kind: "applied" };
2658
+ }
2659
+ if (!supportsFeatureCardIconActions(block.kind) || !blockId) {
2660
+ return null;
2661
+ }
2662
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2663
+ /* @__PURE__ */ jsxs(
2664
+ "section",
2665
+ {
2666
+ className: "rounded-md border bg-muted/20 px-3 py-3",
2667
+ "aria-label": "Icons",
2668
+ "data-testid": "feature-card-icons-panel",
2669
+ children: [
2670
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
2671
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
2672
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: "Icons" }),
2673
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
2674
+ status.cardsWithIcons,
2675
+ " of ",
2676
+ status.totalCards,
2677
+ " cards"
2678
+ ] })
2679
+ ] }),
2680
+ /* @__PURE__ */ jsxs(
2681
+ Button,
2682
+ {
2683
+ type: "button",
2684
+ variant: "outline",
2685
+ size: "sm",
2686
+ disabled: status.totalCards === 0 || isComplete,
2687
+ onClick: () => {
2688
+ applyCuratedFeatureCardIconSuggestions({
2689
+ blockId,
2690
+ content,
2691
+ drafts: uiStore.getState().drafts
2692
+ });
2693
+ },
2694
+ children: [
2695
+ /* @__PURE__ */ jsx(Sparkles, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
2696
+ "Suggest icons"
2697
+ ]
2698
+ }
2699
+ ),
2700
+ /* @__PURE__ */ jsxs(
2701
+ Button,
2702
+ {
2703
+ type: "button",
2704
+ variant: "outline",
2705
+ size: "sm",
2706
+ disabled: status.totalCards === 0,
2707
+ onClick: () => setGenerateDialogOpen(true),
2708
+ children: [
2709
+ /* @__PURE__ */ jsx(ImagePlus, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
2710
+ "Generate icon set"
2711
+ ]
2712
+ }
2713
+ )
2714
+ ] }),
2715
+ hasStaleGeneratedIcons ? /* @__PURE__ */ jsxs(Callout, { tone: "warning", className: "mt-3 flex flex-wrap items-center gap-2", children: [
2716
+ /* @__PURE__ */ jsx(CalloutDescription, { className: "mt-0 min-w-0 flex-1 text-xs", children: "Generated icons are out of date with the current icon style." }),
2717
+ /* @__PURE__ */ jsxs(
2718
+ Button,
2719
+ {
2720
+ type: "button",
2721
+ variant: "outline",
2722
+ size: "sm",
2723
+ disabled: status.totalCards === 0 || !onGenerateIconSet,
2724
+ onClick: () => setGenerateDialogOpen(true),
2725
+ children: [
2726
+ /* @__PURE__ */ jsx(RotateCcw, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
2727
+ "Regenerate set"
2728
+ ]
2729
+ }
2730
+ )
2731
+ ] }) : null
2732
+ ]
2733
+ }
2734
+ ),
2735
+ /* @__PURE__ */ jsx(
2736
+ GeneratedIconSetDialog,
2737
+ {
2738
+ open: generateDialogOpen,
2739
+ onOpenChange: setGenerateDialogOpen,
2740
+ cards: dialogCards,
2741
+ styleGuideSummary: iconStyleGuideSummary,
2742
+ styleGuideEditHref: iconStyleGuideEditHref,
2743
+ onGenerate: onGenerateIconSet,
2744
+ onApply: applyGeneratedIconSetPreview
2745
+ }
2746
+ )
2747
+ ] });
2748
+ }
2304
2749
  function BlockCardBody({
2305
2750
  siteId,
2306
2751
  block,
@@ -2313,29 +2758,48 @@ function BlockCardBody({
2313
2758
  theme,
2314
2759
  widgetOverrides,
2315
2760
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2 = false,
2316
- pageDesignBlock = null
2761
+ pageDesignBlock = null,
2762
+ currentStyleGuideVersionId,
2763
+ iconStyleGuideSummary,
2764
+ iconStyleGuideEditHref,
2765
+ onGenerateIconSet,
2766
+ onApplyGeneratedIconSet
2317
2767
  }) {
2318
- return /* @__PURE__ */ jsx(CardContent, { className: "space-y-4 pb-6", children: /* @__PURE__ */ jsx(
2319
- BlockForm,
2320
- {
2321
- siteId,
2322
- block,
2323
- manifest,
2324
- uiStore,
2325
- hasRecoveryConflict,
2326
- focusSignal: focusSignal ?? null,
2327
- onFocusHandled,
2328
- onSaveSuccess: (data) => {
2329
- if (block.id && onBlockSave) {
2330
- onBlockSave(block.id, data);
2331
- }
2332
- },
2333
- theme,
2334
- widgetOverrides,
2335
- hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2,
2336
- pageDesignBlock
2337
- }
2338
- ) });
2768
+ return /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4 pb-6", children: [
2769
+ /* @__PURE__ */ jsx(
2770
+ FeatureCardIconsPanel,
2771
+ {
2772
+ block,
2773
+ uiStore,
2774
+ currentStyleGuideVersionId,
2775
+ iconStyleGuideSummary,
2776
+ iconStyleGuideEditHref,
2777
+ onGenerateIconSet,
2778
+ onApplyGeneratedIconSet
2779
+ }
2780
+ ),
2781
+ /* @__PURE__ */ jsx(
2782
+ BlockForm,
2783
+ {
2784
+ siteId,
2785
+ block,
2786
+ manifest,
2787
+ uiStore,
2788
+ hasRecoveryConflict,
2789
+ focusSignal: focusSignal ?? null,
2790
+ onFocusHandled,
2791
+ onSaveSuccess: (data) => {
2792
+ if (block.id && onBlockSave) {
2793
+ onBlockSave(block.id, data);
2794
+ }
2795
+ },
2796
+ theme,
2797
+ widgetOverrides,
2798
+ hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2,
2799
+ pageDesignBlock
2800
+ }
2801
+ )
2802
+ ] });
2339
2803
  }
2340
2804
  function getBaselineContent(content) {
2341
2805
  if (!content || typeof content !== "object") return {};
@@ -2579,10 +3043,16 @@ function BlockCardHeader({
2579
3043
  theme,
2580
3044
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2 = false,
2581
3045
  reorderControlMode = "full",
2582
- actionControlMode = DEFAULT_BLOCK_ACTION_CONTROL_MODE
3046
+ actionControlMode = DEFAULT_BLOCK_ACTION_CONTROL_MODE,
3047
+ currentStyleGuideVersionId,
3048
+ iconStyleGuideSummary,
3049
+ iconStyleGuideEditHref,
3050
+ onGenerateIconSet,
3051
+ onApplyGeneratedIconSet
2583
3052
  }) {
2584
3053
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
2585
3054
  const [settingsDialogOpen, setSettingsDialogOpen] = useState(false);
3055
+ const [generateIconSetDialogOpen, setGenerateIconSetDialogOpen] = useState(false);
2586
3056
  const [settingsAvailable, setSettingsAvailable] = useState(true);
2587
3057
  const showMoveButtons = shouldShowMoveButtons(reorderControlMode);
2588
3058
  const showActionsMenu = actionControlMode === "menu";
@@ -2591,12 +3061,42 @@ function BlockCardHeader({
2591
3061
  typeof block.id === "string" ? unsafeAsEditorBlockId(block.id) : null
2592
3062
  );
2593
3063
  const contentToUse = baselineContent ?? block.content;
3064
+ const blockId = typeof block.id === "string" ? unsafeAsEditorBlockId(block.id) : null;
3065
+ const supportsIconActions = supportsFeatureCardIconActions(block.kind);
3066
+ const currentContent = useStoreSelector(
3067
+ uiStore,
3068
+ (state) => supportsIconActions && blockId ? state.drafts.getCurrentValues(blockId) : null
3069
+ );
3070
+ const featureCardIconStatus = supportsIconActions ? getFeatureCardIconStatus(currentContent ?? block.draftContent ?? contentToUse) : null;
3071
+ const featureCardIconActionsAvailable = Boolean(blockId) && supportsIconActions && (featureCardIconStatus?.totalCards ?? 0) > 0;
3072
+ const featureCardIconsComplete = featureCardIconStatus !== null && featureCardIconStatus.totalCards > 0 && featureCardIconStatus.cardsWithIcons >= featureCardIconStatus.totalCards;
3073
+ const featureCardSuggestionActionAvailable = featureCardIconActionsAvailable && !featureCardIconsComplete;
3074
+ const generatedIconSetActionsAvailable = featureCardIconActionsAvailable && Boolean(onGenerateIconSet);
3075
+ const featureCardIconContent = currentContent ?? block.draftContent ?? contentToUse;
3076
+ const featureCardIconDialogCards = supportsIconActions ? getFeatureCardIconDialogCards(featureCardIconContent) : [];
3077
+ const featureCardIconStyleSummary = supportsIconActions ? getFeatureCardGeneratedIconStyleSummary(featureCardIconContent, currentStyleGuideVersionId) : { kind: "unavailable" };
3078
+ const hasStaleGeneratedIcons = featureCardIconStyleSummary.kind === "available" && featureCardIconStyleSummary.staleCount > 0;
3079
+ async function applyGeneratedIconSetPreview(preview) {
3080
+ if (!blockId) return { kind: "failed", message: "Could not apply generated icon set" };
3081
+ const appliedPreview = await onApplyGeneratedIconSet?.(preview);
3082
+ const previewToApply = appliedPreview ?? preview;
3083
+ const result = applyGeneratedFeatureCardIconSet({
3084
+ blockId,
3085
+ content: featureCardIconContent,
3086
+ drafts: uiStore.getState().drafts,
3087
+ assets: previewToApply.assets
3088
+ });
3089
+ if (result.kind !== "applied") {
3090
+ return { kind: "failed", message: "Could not apply generated icon set" };
3091
+ }
3092
+ return { kind: "applied" };
3093
+ }
2594
3094
  const { displayTitle, showSubtitle } = resolveBlockTitle(
2595
3095
  manifest,
2596
3096
  contentToUse,
2597
3097
  block.kind
2598
3098
  );
2599
- const hasMenuActions = settingsAvailable || Boolean(onDuplicate) || Boolean(onDelete);
3099
+ const hasMenuActions = settingsAvailable || featureCardSuggestionActionAvailable || generatedIconSetActionsAvailable || Boolean(onDuplicate) || Boolean(onDelete);
2600
3100
  const settingsModal = /* @__PURE__ */ jsx(
2601
3101
  BlockSettingsModal,
2602
3102
  {
@@ -2706,7 +3206,39 @@ function BlockCardHeader({
2706
3206
  /* @__PURE__ */ jsx(Settings, { className: "mr-2 h-4 w-4" }),
2707
3207
  "Settings"
2708
3208
  ] }) : null,
2709
- settingsAvailable && (onDuplicate || onDelete) ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
3209
+ featureCardIconActionsAvailable ? /* @__PURE__ */ jsxs(Fragment, { children: [
3210
+ settingsAvailable ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
3211
+ /* @__PURE__ */ jsxs(
3212
+ DropdownMenuItem,
3213
+ {
3214
+ disabled: !blockId || featureCardIconsComplete,
3215
+ onSelect: () => {
3216
+ if (!blockId) return;
3217
+ applyCuratedFeatureCardIconSuggestions({
3218
+ blockId,
3219
+ content: currentContent ?? block.draftContent ?? contentToUse,
3220
+ drafts: uiStore.getState().drafts
3221
+ });
3222
+ },
3223
+ children: [
3224
+ /* @__PURE__ */ jsx(Sparkles, { className: "mr-2 h-4 w-4" }),
3225
+ "Suggest icons"
3226
+ ]
3227
+ }
3228
+ ),
3229
+ generatedIconSetActionsAvailable ? /* @__PURE__ */ jsxs(
3230
+ DropdownMenuItem,
3231
+ {
3232
+ disabled: !blockId || featureCardIconDialogCards.length === 0,
3233
+ onSelect: () => setGenerateIconSetDialogOpen(true),
3234
+ children: [
3235
+ hasStaleGeneratedIcons ? /* @__PURE__ */ jsx(RotateCcw, { className: "mr-2 h-4 w-4" }) : /* @__PURE__ */ jsx(ImagePlus, { className: "mr-2 h-4 w-4" }),
3236
+ hasStaleGeneratedIcons ? "Regenerate icon set" : "Generate icon set"
3237
+ ]
3238
+ }
3239
+ ) : null
3240
+ ] }) : null,
3241
+ (settingsAvailable || featureCardIconActionsAvailable) && (onDuplicate || onDelete) ? /* @__PURE__ */ jsx(DropdownMenuSeparator, {}) : null,
2710
3242
  onDuplicate ? /* @__PURE__ */ jsxs(
2711
3243
  DropdownMenuItem,
2712
3244
  {
@@ -2803,7 +3335,19 @@ function BlockCardHeader({
2803
3335
  }
2804
3336
  )
2805
3337
  ] })
2806
- ] }) })
3338
+ ] }) }),
3339
+ generatedIconSetActionsAvailable ? /* @__PURE__ */ jsx(
3340
+ GeneratedIconSetDialog,
3341
+ {
3342
+ open: generateIconSetDialogOpen,
3343
+ onOpenChange: setGenerateIconSetDialogOpen,
3344
+ cards: featureCardIconDialogCards,
3345
+ styleGuideSummary: iconStyleGuideSummary,
3346
+ styleGuideEditHref: iconStyleGuideEditHref,
3347
+ onGenerate: onGenerateIconSet,
3348
+ onApply: applyGeneratedIconSetPreview
3349
+ }
3350
+ ) : null
2807
3351
  ] });
2808
3352
  }
2809
3353
  function BlockCard({
@@ -2831,7 +3375,12 @@ function BlockCard({
2831
3375
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2 = false,
2832
3376
  pageDesignBlock = null,
2833
3377
  reorderControlMode = DEFAULT_REORDER_CONTROL_MODE,
2834
- actionControlMode = DEFAULT_BLOCK_ACTION_CONTROL_MODE
3378
+ actionControlMode = DEFAULT_BLOCK_ACTION_CONTROL_MODE,
3379
+ currentStyleGuideVersionId,
3380
+ iconStyleGuideSummary,
3381
+ iconStyleGuideEditHref,
3382
+ onGenerateIconSet,
3383
+ onApplyGeneratedIconSet
2835
3384
  }) {
2836
3385
  const contentId = block.id ? `builder-block-content-${block.id}` : void 0;
2837
3386
  return /* @__PURE__ */ jsx(
@@ -2862,7 +3411,12 @@ function BlockCard({
2862
3411
  theme,
2863
3412
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2,
2864
3413
  reorderControlMode,
2865
- actionControlMode
3414
+ actionControlMode,
3415
+ currentStyleGuideVersionId,
3416
+ iconStyleGuideSummary,
3417
+ iconStyleGuideEditHref,
3418
+ onGenerateIconSet,
3419
+ onApplyGeneratedIconSet
2866
3420
  }
2867
3421
  ),
2868
3422
  /* @__PURE__ */ jsx(CollapsibleContent, { id: contentId, children: /* @__PURE__ */ jsx(
@@ -2879,7 +3433,12 @@ function BlockCard({
2879
3433
  theme,
2880
3434
  widgetOverrides,
2881
3435
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2,
2882
- pageDesignBlock
3436
+ pageDesignBlock,
3437
+ currentStyleGuideVersionId,
3438
+ iconStyleGuideSummary,
3439
+ iconStyleGuideEditHref,
3440
+ onGenerateIconSet,
3441
+ onApplyGeneratedIconSet
2883
3442
  }
2884
3443
  ) })
2885
3444
  ] })
@@ -2911,7 +3470,12 @@ var SortableBlockItem = memo(function SortableBlockItem2({
2911
3470
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2 = false,
2912
3471
  pageDesignBlock = null,
2913
3472
  reorderControlMode = DEFAULT_REORDER_CONTROL_MODE,
2914
- actionControlMode = DEFAULT_BLOCK_ACTION_CONTROL_MODE
3473
+ actionControlMode = DEFAULT_BLOCK_ACTION_CONTROL_MODE,
3474
+ currentStyleGuideVersionId,
3475
+ iconStyleGuideSummary,
3476
+ iconStyleGuideEditHref,
3477
+ onGenerateIconSet,
3478
+ onApplyGeneratedIconSet
2915
3479
  }) {
2916
3480
  const sortable = useSortable({
2917
3481
  id: block.id,
@@ -2994,7 +3558,12 @@ var SortableBlockItem = memo(function SortableBlockItem2({
2994
3558
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2,
2995
3559
  pageDesignBlock,
2996
3560
  reorderControlMode,
2997
- actionControlMode
3561
+ actionControlMode,
3562
+ currentStyleGuideVersionId,
3563
+ iconStyleGuideSummary,
3564
+ iconStyleGuideEditHref,
3565
+ onGenerateIconSet,
3566
+ onApplyGeneratedIconSet
2998
3567
  }
2999
3568
  )
3000
3569
  }
@@ -3046,6 +3615,7 @@ var BlockEditor = forwardRef(
3046
3615
  );
3047
3616
  const [fetchedContentTypes, setFetchedContentTypes] = useState(enabledContentTypes);
3048
3617
  const [fetchingContentTypes, setFetchingContentTypes] = useState(false);
3618
+ const [iconStyleGuide, setIconStyleGuide] = useState(null);
3049
3619
  const allowReordering = enableReordering;
3050
3620
  const allowCreation = enableCreation;
3051
3621
  const conflictedBlockIdSet = useMemo(
@@ -3072,6 +3642,99 @@ var BlockEditor = forwardRef(
3072
3642
  useEffect(() => {
3073
3643
  setBlockList(normalizeBlockListInitial(blocks));
3074
3644
  }, [blocks]);
3645
+ useEffect(() => {
3646
+ if (typeof apiClient !== "function") {
3647
+ setIconStyleGuide(null);
3648
+ return void 0;
3649
+ }
3650
+ let cancelled = false;
3651
+ void Promise.resolve().then(() => apiClient({
3652
+ endpoint: "getSiteIconStyleGuide",
3653
+ params: { siteId }
3654
+ })).then(unwrapResponse).then((response) => {
3655
+ if (cancelled) return;
3656
+ const versionId = parseSiteIconStyleGuideVersionId(response.guide.versionId);
3657
+ setIconStyleGuide(versionId ? {
3658
+ versionId,
3659
+ summary: response.guide.displaySummary,
3660
+ editHref: `/dashboard/sites/${siteId}/settings/icon-style-guide`
3661
+ } : null);
3662
+ }).catch(() => {
3663
+ if (!cancelled) setIconStyleGuide(null);
3664
+ });
3665
+ return () => {
3666
+ cancelled = true;
3667
+ };
3668
+ }, [apiClient, siteId]);
3669
+ const generateFeatureCardIconSet = useCallback(async (input) => {
3670
+ if (typeof apiClient !== "function") {
3671
+ return { kind: "failed", message: "Generated icon set API is unavailable" };
3672
+ }
3673
+ try {
3674
+ const response = unwrapResponse(await apiClient({
3675
+ endpoint: "generateGeneratedIconSet",
3676
+ params: { siteId },
3677
+ body: {
3678
+ blockKind: "block.feature-cards",
3679
+ blockLabel: "Feature cards",
3680
+ userStyleNote: input.userStyleNote,
3681
+ cards: input.cards.map((card) => ({
3682
+ cardKey: card.cardKey,
3683
+ title: card.title,
3684
+ bodyText: card.bodyText,
3685
+ semanticIconId: card.semanticIconId
3686
+ }))
3687
+ }
3688
+ }));
3689
+ const assets = response.preview.assets.map((asset) => {
3690
+ const iconValue = parseBlockIconValue(asset.iconValue);
3691
+ if (iconValue.kind !== "generated") {
3692
+ throw new Error("Generated icon response included an invalid icon reference");
3693
+ }
3694
+ return {
3695
+ cardKey: asset.cardKey,
3696
+ title: input.cards.find((card) => card.cardKey === asset.cardKey)?.title ?? asset.cardKey,
3697
+ src: asset.src,
3698
+ iconValue
3699
+ };
3700
+ });
3701
+ return {
3702
+ kind: "preview_ready",
3703
+ preview: {
3704
+ setId: response.candidate.setId,
3705
+ styleGuideSummary: response.styleGuide.displaySummary,
3706
+ candidate: response.candidate,
3707
+ assets
3708
+ }
3709
+ };
3710
+ } catch (error) {
3711
+ return {
3712
+ kind: "failed",
3713
+ message: error instanceof Error && error.message ? error.message : "Failed to generate icon set"
3714
+ };
3715
+ }
3716
+ }, [apiClient, siteId]);
3717
+ const applyGeneratedFeatureCardIconSet2 = useCallback(async (preview) => {
3718
+ if (typeof apiClient !== "function") return preview;
3719
+ if (!preview.candidate) return preview;
3720
+ const response = unwrapResponse(await apiClient({
3721
+ endpoint: "applyGeneratedIconSet",
3722
+ params: { siteId },
3723
+ body: { candidate: preview.candidate }
3724
+ }));
3725
+ const iconValuesByCardKey = new Map(response.assets.map((asset) => [asset.cardKey, asset.iconValue]));
3726
+ return {
3727
+ ...preview,
3728
+ assets: preview.assets.map((asset) => {
3729
+ const applied = iconValuesByCardKey.get(asset.cardKey);
3730
+ const iconValue = parseBlockIconValue(applied ?? asset.iconValue);
3731
+ if (iconValue.kind !== "generated") {
3732
+ throw new Error("Generated icon apply response included an invalid icon reference");
3733
+ }
3734
+ return { ...asset, iconValue };
3735
+ })
3736
+ };
3737
+ }, [apiClient, siteId]);
3075
3738
  useEffect(() => {
3076
3739
  const unsubscribe = uiStore.subscribe(() => {
3077
3740
  const structureList = uiStore.getState().structure.getList();
@@ -3385,7 +4048,12 @@ var BlockEditor = forwardRef(
3385
4048
  hideThemeV2RawStyleFields: hideThemeV2RawStyleFields2,
3386
4049
  pageDesignBlock: block.id ? pageDesignBlockById.get(block.id) ?? null : null,
3387
4050
  reorderControlMode,
3388
- actionControlMode
4051
+ actionControlMode,
4052
+ currentStyleGuideVersionId: iconStyleGuide?.versionId ?? null,
4053
+ iconStyleGuideSummary: iconStyleGuide?.summary ?? null,
4054
+ iconStyleGuideEditHref: iconStyleGuide?.editHref ?? null,
4055
+ onGenerateIconSet: generateFeatureCardIconSet,
4056
+ onApplyGeneratedIconSet: applyGeneratedFeatureCardIconSet2
3389
4057
  }
3390
4058
  ),
3391
4059
  allowCreation && index < blockList.length - 1 ? /* @__PURE__ */ jsx(
@@ -4835,15 +5503,17 @@ function EntryPickerField({
4835
5503
  }
4836
5504
  function IconPickerField({ path, backend, config }) {
4837
5505
  const { value, error, setValue } = useField(path, backend);
4838
- const preset = config.ui?.iconPickerPreset;
4839
- if (preset && preset !== "cta" && true) {
4840
- console.warn(`[IconPickerField] Unknown iconPickerPreset "${preset}" at "${path}". Falling back to "cta".`);
5506
+ const configuredPreset = config.ui?.iconPickerPreset;
5507
+ const preset = resolveIconPickerPreset(configuredPreset);
5508
+ if (configuredPreset && !isIconPickerPreset(configuredPreset) && true) {
5509
+ console.warn(`[IconPickerField] Unknown iconPickerPreset "${configuredPreset}" at "${path}". Falling back to "cta".`);
4841
5510
  }
4842
- const selected = typeof value === "string" && isCtaIconName(value) ? value : void 0;
5511
+ const options = getIconPickerOptionsForPreset(preset);
5512
+ const selected = typeof value === "string" && isKnownIconName(value) && options.some((option) => option.id === value) ? value : void 0;
4843
5513
  return /* @__PURE__ */ jsx(FieldFrame, { label: config.label, description: config.description, error: error?.message, children: () => /* @__PURE__ */ jsx(
4844
5514
  Combobox,
4845
5515
  {
4846
- items: CTA_ICON_OPTIONS.map((opt) => ({ id: opt.id, label: opt.label, item: opt })),
5516
+ items: options.map((opt) => ({ id: opt.id, label: opt.label, searchText: opt.searchText, item: opt })),
4847
5517
  value: selected,
4848
5518
  onSelect: (entry) => {
4849
5519
  if (!entry) {
@@ -4855,7 +5525,7 @@ function IconPickerField({ path, backend, config }) {
4855
5525
  placeholder: "Select icon\u2026",
4856
5526
  clearLabel: "Clear",
4857
5527
  renderItem: (entry) => {
4858
- const Icon = getCtaIconComponent(entry.id);
5528
+ const Icon = getIconComponent(entry.id);
4859
5529
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4860
5530
  Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }) : null,
4861
5531
  /* @__PURE__ */ jsx("span", { className: "truncate", children: entry.label })
@@ -6864,8 +7534,15 @@ function SiteChromeLookRow({
6864
7534
  }
6865
7535
  function PaletteRow({ expanded, onToggle, siteStyle, currentId, currentLabel, currentSwatch, onPreview, disabled }) {
6866
7536
  const options = useMemo(
6867
- () => requireEntriesForCuratedChoices(paletteVariants, siteStyle.paletteVariantChoices),
6868
- [siteStyle.paletteVariantChoices]
7537
+ () => {
7538
+ const recommended = requireEntriesForCuratedChoices(paletteVariants, siteStyle.paletteVariantChoices);
7539
+ if (recommended.some((variant) => variant.id === currentId)) {
7540
+ return recommended;
7541
+ }
7542
+ const current = findPaletteVariant(currentId);
7543
+ return current ? [current, ...recommended] : recommended;
7544
+ },
7545
+ [currentId, siteStyle.paletteVariantChoices]
6869
7546
  );
6870
7547
  return /* @__PURE__ */ jsx(
6871
7548
  StyleRowFrame,
@@ -7010,7 +7687,7 @@ function describeWarning(warning) {
7010
7687
  case "rejected-personality":
7011
7688
  return `Button style changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
7012
7689
  case "rejected-palette":
7013
- return `Palette changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
7690
+ return `Palette changed to ${warning.fellBackTo} because ${warning.requested} is not available.`;
7014
7691
  case "rejected-typography-preset":
7015
7692
  return `Typography changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
7016
7693
  default: {