@riverbankcms/sdk 0.78.0 → 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 (222) hide show
  1. package/README.md +125 -43
  2. package/dist/{PreviewEditorSidebar-RIKFQ72L.mjs → PreviewEditorSidebar-56NMJMIK.mjs} +750 -65
  3. package/dist/{PreviewEditorUI-XO7TUWKK.mjs → PreviewEditorUI-27KJVEET.mjs} +4 -4
  4. package/dist/SdkPreviewModeRuntime-H4BSP6E7.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +72 -0
  6. package/dist/_dts/api/src/contentRuntime.d.ts +1 -0
  7. package/dist/_dts/api/src/endpoints.d.ts +64 -0
  8. package/dist/_dts/api/src/index.d.ts +8 -6
  9. package/dist/_dts/api/src/media.d.ts +8 -1
  10. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  11. package/dist/_dts/api/src/navigation/dashboardSiteNav.d.ts +8 -8
  12. package/dist/_dts/api/src/navigation/identity.d.ts +59 -0
  13. package/dist/_dts/api/src/navigation.d.ts +2 -0
  14. package/dist/_dts/api/src/public/types.d.ts +1 -1
  15. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +4 -0
  16. package/dist/_dts/api/src/request.d.ts +3 -11
  17. package/dist/_dts/api/src/sdkConfig/contracts.d.ts +1 -0
  18. package/dist/_dts/api/src/sdkContracts.d.ts +8 -1
  19. package/dist/_dts/api/src/siteIcons.d.ts +128 -0
  20. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +26 -0
  21. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +8 -0
  22. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +21 -20
  23. package/dist/_dts/api/src/types.d.ts +12 -27
  24. package/dist/_dts/api/src/webhooks.d.ts +239 -0
  25. package/dist/_dts/block-form/src/fields/types.d.ts +6 -0
  26. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterList.d.ts +3 -2
  27. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRow.d.ts +6 -3
  28. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRowActions.d.ts +8 -3
  29. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/index.d.ts +1 -1
  30. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useLinearRepeaterDnd.d.ts +1 -0
  31. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useRepeaterPointerDragCapability.d.ts +1 -0
  32. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useResolvedItemLabel.d.ts +7 -0
  33. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/buildSummary.d.ts +1 -0
  34. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/index.d.ts +3 -1
  35. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterDndDomain.d.ts +1 -1
  36. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterLabelSource.d.ts +15 -0
  37. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterRowActionsDomain.d.ts +50 -0
  38. package/dist/_dts/blocks/src/index.d.ts +4 -0
  39. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +879 -288
  40. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +879 -288
  41. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +879 -288
  42. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +879 -288
  43. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +879 -288
  44. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +885 -289
  45. package/dist/_dts/blocks/src/system/blocks/feature-card-icons.d.ts +57 -0
  46. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +4 -0
  47. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +879 -288
  48. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  49. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +3 -1
  50. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +69 -22
  51. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +879 -288
  52. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +879 -288
  53. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +879 -288
  54. package/dist/_dts/blocks/src/system/blocks/team-members.d.ts +3 -0
  55. package/dist/_dts/blocks/src/system/blocks/testimonials.d.ts +7 -1
  56. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +170 -0
  57. package/dist/_dts/blocks/src/system/fragments/library/testimonialsCarousel.d.ts +5 -0
  58. package/dist/_dts/blocks/src/system/helpers/resolveBackground.d.ts +3 -1
  59. package/dist/_dts/blocks/src/system/icons/ids.d.ts +13 -0
  60. package/dist/_dts/blocks/src/system/icons/index.d.ts +6 -0
  61. package/dist/_dts/blocks/src/system/icons/presets.d.ts +4 -0
  62. package/dist/_dts/blocks/src/system/icons/registry.d.ts +18 -0
  63. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +239 -0
  64. package/dist/_dts/blocks/src/system/icons/value.d.ts +94 -0
  65. package/dist/_dts/blocks/src/system/index.d.ts +1 -0
  66. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +4 -1
  67. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +187 -0
  68. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -1
  69. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/feature-card-icon.d.ts +13 -0
  71. package/dist/_dts/content-editor/src/index.d.ts +1 -1
  72. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +2 -2
  73. package/dist/_dts/content-model/src/content-types/schema.d.ts +14 -0
  74. package/dist/_dts/content-model/src/contentManifest.d.ts +3 -1
  75. package/dist/_dts/content-model/src/templates/bindingTypeCompatibility.d.ts +3 -1
  76. package/dist/_dts/content-model/src/templates/bindingValidation.d.ts +10 -4
  77. package/dist/_dts/content-model/src/templates/fieldPaths.d.ts +20 -0
  78. package/dist/_dts/content-model/src/templates/manifestAdapter.d.ts +5 -2
  79. package/dist/_dts/core/src/branded.d.ts +114 -85
  80. package/dist/_dts/core/src/csv-types.d.ts +2 -2
  81. package/dist/_dts/core/src/editor-state.d.ts +7 -7
  82. package/dist/_dts/core/src/participants.d.ts +2 -2
  83. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +202 -0
  84. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +12 -1
  85. package/dist/_dts/editor-blocks/src/block-editor/BlockCardBody.d.ts +12 -1
  86. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +12 -2
  87. package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +21 -0
  88. package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +40 -0
  89. package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +11 -1
  90. package/dist/_dts/editor-blocks/src/block-editor/featureCardIconActions.d.ts +82 -0
  91. package/dist/_dts/editor-blocks/src/blockPayload.d.ts +1 -1
  92. package/dist/_dts/editor-blocks/src/widgets/icon-picker/IconPickerField.d.ts +1 -1
  93. package/dist/_dts/media-core/src/fileDomain.d.ts +8 -1
  94. package/dist/_dts/media-editor/src/MediaEditor.d.ts +5 -2
  95. package/dist/_dts/media-editor/src/MediaPreview.d.ts +3 -1
  96. package/dist/_dts/media-editor/src/fieldUi.d.ts +5 -0
  97. package/dist/_dts/media-editor/src/index.d.ts +1 -1
  98. package/dist/_dts/media-react/src/components/MediaLibrary.d.ts +2 -1
  99. package/dist/_dts/media-react/src/components/MediaPickerMini.d.ts +2 -1
  100. package/dist/_dts/preview-next/src/client/blocks/previewCustomizeActions.d.ts +17 -0
  101. package/dist/_dts/preview-next/src/client/preview/PageDesignEditorStateContext.d.ts +4 -0
  102. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +3 -2
  103. package/dist/_dts/preview-next/src/client/preview/previewCustomizeHistory.d.ts +6 -0
  104. package/dist/_dts/sdk/src/cli/commands/push/consts.d.ts +1 -1
  105. package/dist/_dts/sdk/src/cli/commands/push/metadata.d.ts +2 -0
  106. package/dist/_dts/sdk/src/cli/commands/push/stale.d.ts +3 -3
  107. package/dist/_dts/sdk/src/cli/commands/push-execute.d.ts +7 -0
  108. package/dist/_dts/sdk/src/cli/commands/push.d.ts +2 -0
  109. package/dist/_dts/sdk/src/cli/content/reader.d.ts +13 -0
  110. package/dist/_dts/sdk/src/cli/content/writer.d.ts +2 -1
  111. package/dist/_dts/sdk/src/cli/helpers.d.ts +2 -0
  112. package/dist/_dts/sdk/src/cli/navigationIdentity.d.ts +11 -0
  113. package/dist/_dts/sdk/src/cli/site-commands/commandKeys.d.ts +6 -6
  114. package/dist/_dts/sdk/src/cli/site-commands/commandRuntime.d.ts +5 -0
  115. package/dist/_dts/sdk/src/cli/site-commands/commandSurfaceDispatch.d.ts +4 -0
  116. package/dist/_dts/sdk/src/cli/site-commands/navigationCommands.d.ts +4 -0
  117. package/dist/_dts/sdk/src/cli/site-commands/oneOffCommands.d.ts +1 -0
  118. package/dist/_dts/sdk/src/cli/site-commands/pageCommands.d.ts +5 -2
  119. package/dist/_dts/sdk/src/cli/site-commands/pushExecution.d.ts +10 -1
  120. package/dist/_dts/sdk/src/cli/site-commands/pushExecutionTypes.d.ts +1 -1
  121. package/dist/_dts/sdk/src/cli/sync/diff.d.ts +9 -0
  122. package/dist/_dts/sdk/src/client/management/types.d.ts +8 -0
  123. package/dist/_dts/sdk/src/client/types.d.ts +2 -2
  124. package/dist/_dts/sdk/src/config/content-types.d.ts +7 -0
  125. package/dist/_dts/sdk/src/config/field-definitions.d.ts +5 -1
  126. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  127. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +19 -2
  128. package/dist/_dts/sdk/src/next/index.d.ts +1 -1
  129. package/dist/_dts/sdk/src/next/revalidate.d.ts +26 -5
  130. package/dist/_dts/sdk/src/next/static-params.d.ts +28 -3
  131. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -1
  132. package/dist/_dts/sdk/src/public-api/runtime.d.ts +1 -1
  133. package/dist/_dts/sdk/src/version.d.ts +1 -1
  134. package/dist/_dts/sdk/src/webhooks/index.d.ts +1 -1
  135. package/dist/_dts/sdk/src/webhooks/verify.d.ts +6 -102
  136. package/dist/_dts/site-commands/src/commands.d.ts +6 -0
  137. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  138. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +3 -3
  139. package/dist/_dts/theme-core/src/schema.d.ts +5 -5
  140. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +25 -2
  141. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +5 -5
  142. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  143. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +4 -4
  144. package/dist/_dts/theme-core/src/tokens/themeColorTokens.d.ts +2 -0
  145. package/dist/_dts/ui/src/combobox.d.ts +1 -0
  146. package/dist/{altcha-B5XGSXP5.mjs → altcha-EKUEQ4RP.mjs} +1 -1
  147. package/dist/{chunk-F7RTCZYN.mjs → chunk-4HCW7FHJ.mjs} +504 -63
  148. package/dist/{chunk-SXOLGNMX.mjs → chunk-A3HHFKVT.mjs} +1 -1
  149. package/dist/{chunk-TXDES5P2.mjs → chunk-GP555I66.mjs} +180 -10
  150. package/dist/{chunk-SVMMM2NA.mjs → chunk-K2IIF34C.mjs} +79 -5
  151. package/dist/{chunk-NIDXI46P.mjs → chunk-LCY32PXF.mjs} +1 -1
  152. package/dist/{chunk-XGB3TDIC.mjs → chunk-R7POPVJR.mjs} +2 -8
  153. package/dist/{chunk-OECWLDHN.mjs → chunk-V47ZU33I.mjs} +2762 -732
  154. package/dist/cli/index.mjs +1799 -345
  155. package/dist/cli/init-docs/content/cli-reference.md +3 -2
  156. package/dist/cli/init-docs/content/content-management.md +2 -2
  157. package/dist/cli/init-docs/content/workflow-editor-workflows.md +2 -0
  158. package/dist/cli/init-docs/content/workflow-isr-revalidation.md +138 -0
  159. package/dist/cli/init-docs/content/workflow-preview-mode.md +68 -2
  160. package/dist/client/{accordion-EVDEOUPR.mjs → accordion-QLA7KBYO.mjs} +2 -2
  161. package/dist/client/analytics.mjs +1 -1
  162. package/dist/client/{bookingForm-DIHBLC64.mjs → bookingForm-PYZIPA5G.mjs} +55 -48
  163. package/dist/client/bookings.mjs +172 -57
  164. package/dist/client/{carousel-FEBQHIWI.mjs → carousel-5EIULWBI.mjs} +3 -3
  165. package/dist/client/{cart-7CKSXAE4.mjs → cart-DOP3FNI4.mjs} +7 -7
  166. package/dist/client/{checkout-WKYCANLV.mjs → checkout-BVMF6FBV.mjs} +7 -7
  167. package/dist/client/{chunk-GUK2FPXQ.mjs → chunk-44K2U3QI.mjs} +37 -15
  168. package/dist/client/{chunk-IVNCUVAV.mjs → chunk-AUJ5DBZJ.mjs} +18 -18
  169. package/dist/client/{chunk-VPPMNXCF.mjs → chunk-CCNTDRCF.mjs} +2 -2
  170. package/dist/client/{chunk-36WJCERQ.mjs → chunk-CE7IBGVW.mjs} +3 -1
  171. package/dist/client/{chunk-2SAVKN2M.mjs → chunk-GG4M2NP6.mjs} +2 -2
  172. package/dist/client/{chunk-65F47D7Y.mjs → chunk-R5ESWNKX.mjs} +49 -39
  173. package/dist/client/{chunk-RZDWX7QW.mjs → chunk-TYONZMST.mjs} +1 -1
  174. package/dist/client/{chunk-OFMSCGNY.mjs → chunk-UDS3NTWA.mjs} +2 -2
  175. package/dist/client/{chunk-YDSEG6GZ.mjs → chunk-V6M5FCR5.mjs} +2 -2
  176. package/dist/client/{chunk-F7LHOKEH.mjs → chunk-XSV6KW4D.mjs} +1 -1
  177. package/dist/client/{chunk-RV6FX7UH.mjs → chunk-YLDYVRZL.mjs} +9 -9
  178. package/dist/client/{chunk-PD6NBCEY.mjs → chunk-ZFHRN6W2.mjs} +1 -1
  179. package/dist/client/client.mjs +21501 -19812
  180. package/dist/client/{courseRegistration-5QF2PHKM.mjs → courseRegistration-E6EAA6NL.mjs} +10 -10
  181. package/dist/client/{eventCalendar-4ZOSETDU.mjs → eventCalendar-HBG3HAK6.mjs} +9 -9
  182. package/dist/client/{eventCombined-WQGU7JUX.mjs → eventCombined-6K5ZZWAK.mjs} +9 -9
  183. package/dist/client/{eventDetails-AYWVUJ5Y.mjs → eventDetails-Q75ICXLT.mjs} +9 -9
  184. package/dist/client/{eventListing-NT7C6UT5.mjs → eventListing-27P5F7DZ.mjs} +9 -9
  185. package/dist/client/{eventRegistration-OH24F4ZJ.mjs → eventRegistration-IQ7AMASR.mjs} +9 -9
  186. package/dist/client/{form-7L42SRBB.mjs → form-JRTD65FN.mjs} +6 -3
  187. package/dist/client/{headerSection-OZRZNZ52.mjs → headerSection-7FPSSZHS.mjs} +3 -3
  188. package/dist/client/hooks.mjs +428 -83
  189. package/dist/client/{locationMap-ZBXRPQ7C.mjs → locationMap-7NGFNYBH.mjs} +3 -3
  190. package/dist/client/{newsletterForm-SNAGFF2I.mjs → newsletterForm-F3BADCI2.mjs} +2 -2
  191. package/dist/client/{productDetail-I46BOFGV.mjs → productDetail-V3HP7ITJ.mjs} +7 -7
  192. package/dist/client/{productList-BOYHTYI6.mjs → productList-L3EGJUF2.mjs} +7 -7
  193. package/dist/client/rendering/client.mjs +2886 -1513
  194. package/dist/client/rendering/islands.mjs +19 -19
  195. package/dist/client/rendering.mjs +2244 -564
  196. package/dist/client/{shop-XTXPZTKR.mjs → shop-DQUB5E2C.mjs} +7 -7
  197. package/dist/preview-next/before-render.mjs +65 -1
  198. package/dist/preview-next/client/runtime.mjs +6 -6
  199. package/dist/preview-next/middleware.mjs +65 -1
  200. package/dist/preview-next/tailwind-sources.css +1 -0
  201. package/dist/sdk-runtime-AF6KXJU4.mjs +8 -0
  202. package/dist/server/components.mjs +2270 -835
  203. package/dist/server/config-template-validation.mjs +221 -15
  204. package/dist/server/config-validation.mjs +426 -77
  205. package/dist/server/config.mjs +426 -77
  206. package/dist/server/data.mjs +427 -82
  207. package/dist/server/index.mjs +94 -10
  208. package/dist/server/next/revalidate.mjs +229 -34
  209. package/dist/server/next.mjs +2439 -888
  210. package/dist/server/page-converter.mjs +335 -74
  211. package/dist/server/prebuild.mjs +1 -1
  212. package/dist/server/rendering/server.mjs +2281 -846
  213. package/dist/server/rendering.mjs +2298 -860
  214. package/dist/server/routing.mjs +860 -113
  215. package/dist/server/server.mjs +452 -92
  216. package/dist/server/theme-bridge.mjs +164 -2
  217. package/dist/server/theme.mjs +2 -2
  218. package/dist/server/webhooks.mjs +129 -25
  219. package/dist/styles/index.css +55 -0
  220. package/package.json +2 -1
  221. package/dist/SdkPreviewModeRuntime-LAGYMPNF.mjs +0 -8
  222. package/dist/sdk-runtime-ZJLKC6DR.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-NIDXI46P.mjs';
3
- import { KeyboardCode, getBlockDefinition, CSS, useSdkConfig, listBlockDescriptors, useSensor, PointerSensor, useSensors, deleteBlock, createEditorRemoveBlockCommand, asEditorBlockId, 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, asEditorBlockValues, 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, asSiteId, 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-OECWLDHN.mjs';
4
- import { usePreviewAuth, getDashboardUrl } from './chunk-SVMMM2NA.mjs';
5
- import './chunk-XGB3TDIC.mjs';
6
- import React, { createContext, memo, useMemo, useState, useRef, useEffect, forwardRef, useCallback, useImperativeHandle, useContext, useSyncExternalStore, useLayoutEffect, useTransition, useId } from 'react';
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
+ import './chunk-R7POPVJR.mjs';
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":
@@ -1479,7 +1479,7 @@ function useBlockBaselineSync({
1479
1479
  const keepIds = /* @__PURE__ */ new Set();
1480
1480
  blockList.forEach((block, index) => {
1481
1481
  if (!block.id) return;
1482
- const blockId = asEditorBlockId(block.id);
1482
+ const blockId = unsafeAsEditorBlockId(block.id);
1483
1483
  keepIds.add(blockId);
1484
1484
  const normalizedBaseline = applyExtendedFieldDefaults(
1485
1485
  block.kind,
@@ -1575,7 +1575,7 @@ var reindexBlockList = (items) => items.map((block, index) => ({ ...block, order
1575
1575
 
1576
1576
  // ../editor-blocks/src/block-editor/hooks/buildInsertBlockHistoryCommand.ts
1577
1577
  function toEditorBlockValues(value) {
1578
- return value ? asEditorBlockValues(value) : null;
1578
+ return value ? unsafeAsEditorBlockValues(value) : null;
1579
1579
  }
1580
1580
  function buildInsertBlockHistoryCommand({
1581
1581
  block,
@@ -1584,7 +1584,7 @@ function buildInsertBlockHistoryCommand({
1584
1584
  publishedContent
1585
1585
  }) {
1586
1586
  if (!block.id) return null;
1587
- const blockId = asEditorBlockId(block.id);
1587
+ const blockId = unsafeAsEditorBlockId(block.id);
1588
1588
  const purpose = typeof block.purpose === "string" ? block.purpose ?? null : "content";
1589
1589
  const baseline = draftContent ?? block.draftContent ?? block.content ?? null;
1590
1590
  const nextPublishedContent = publishedContent ?? block.publishedContent ?? null;
@@ -1790,7 +1790,7 @@ function useBlockDuplication({
1790
1790
  }
1791
1791
  onBlocksChange?.(next);
1792
1792
  if (triggerFocus) {
1793
- const nextBlockId = insertCommand?.block.id ?? asEditorBlockId(createdBlock.id);
1793
+ const nextBlockId = insertCommand?.block.id ?? unsafeAsEditorBlockId(createdBlock.id);
1794
1794
  setTimeout(() => {
1795
1795
  triggerFocus({ blockId: nextBlockId });
1796
1796
  }, 100);
@@ -1860,7 +1860,7 @@ function useBlockReorder({
1860
1860
  const nextBlockIds = getBlockIds(updated);
1861
1861
  uiStore?.getState().history.applyCommand?.({
1862
1862
  ...createEditorReorderBlocksCommand(
1863
- nextBlockIds.map((blockId) => asEditorBlockId(blockId))
1863
+ nextBlockIds.map((blockId) => unsafeAsEditorBlockId(blockId))
1864
1864
  )
1865
1865
  });
1866
1866
  try {
@@ -2065,7 +2065,7 @@ function BlockForm({
2065
2065
  pageDesignBlock = null
2066
2066
  }) {
2067
2067
  const formRootRef = useRef(null);
2068
- const blockId = typeof block.id === "string" ? asEditorBlockId(block.id) : null;
2068
+ const blockId = typeof block.id === "string" ? unsafeAsEditorBlockId(block.id) : null;
2069
2069
  const blockSnapshot = useStoreSelector(
2070
2070
  uiStore,
2071
2071
  (state) => blockId ? state.drafts.getBlockSnapshot(blockId) : null
@@ -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 {};
@@ -2380,7 +2844,7 @@ function BlockSettingsModal({
2380
2844
  },
2381
2845
  [controlledOpen, onOpenChange]
2382
2846
  );
2383
- const blockId = typeof block.id === "string" ? asEditorBlockId(block.id) : null;
2847
+ const blockId = typeof block.id === "string" ? unsafeAsEditorBlockId(block.id) : null;
2384
2848
  const hasDraftSnapshot = useStoreSelector(
2385
2849
  uiStore,
2386
2850
  (state) => blockId ? state.drafts.getBlockSnapshot(blockId) !== null : false
@@ -2579,24 +3043,60 @@ 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";
2589
3059
  const baselineContent = useDraftContent(
2590
3060
  uiStore,
2591
- typeof block.id === "string" ? asEditorBlockId(block.id) : null
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();
@@ -3110,7 +3773,7 @@ var BlockEditor = forwardRef(
3110
3773
  }
3111
3774
  }
3112
3775
  }
3113
- fetchContentTypesFromApi();
3776
+ void fetchContentTypesFromApi();
3114
3777
  return () => {
3115
3778
  cancelled = true;
3116
3779
  };
@@ -3210,7 +3873,7 @@ var BlockEditor = forwardRef(
3210
3873
  setBlockList(updatedList);
3211
3874
  if (uiStore) {
3212
3875
  uiStore.getState().history.applyCommand?.({
3213
- ...createEditorRemoveBlockCommand(asEditorBlockId(blockId))
3876
+ ...createEditorRemoveBlockCommand(unsafeAsEditorBlockId(blockId))
3214
3877
  });
3215
3878
  }
3216
3879
  onBlocksChange?.(updatedList);
@@ -3272,7 +3935,7 @@ var BlockEditor = forwardRef(
3272
3935
  if (!firstRecoveryBlockId) {
3273
3936
  return;
3274
3937
  }
3275
- uiStore.getState().requestFocus({ blockId: asEditorBlockId(firstRecoveryBlockId) });
3938
+ uiStore.getState().requestFocus({ blockId: unsafeAsEditorBlockId(firstRecoveryBlockId) });
3276
3939
  }, [
3277
3940
  recoveryConflictBlockIds,
3278
3941
  recoveryConflictReviewRequestId,
@@ -3284,7 +3947,7 @@ var BlockEditor = forwardRef(
3284
3947
  return;
3285
3948
  }
3286
3949
  const stillExists = blockList.some(
3287
- (block) => typeof block.id === "string" && asEditorBlockId(block.id) === activeBlockId
3950
+ (block) => typeof block.id === "string" && unsafeAsEditorBlockId(block.id) === activeBlockId
3288
3951
  );
3289
3952
  if (!stillExists) {
3290
3953
  uiStore.getState().setActiveBlockId(null);
@@ -3333,7 +3996,7 @@ var BlockEditor = forwardRef(
3333
3996
  children: /* @__PURE__ */ jsxs("div", { className: "space-y-0", children: [
3334
3997
  allowCreation ? /* @__PURE__ */ jsx(AddBlockDivider, { onOpen: openPicker, position: 0 }) : null,
3335
3998
  blockList.map((block, index) => {
3336
- const focusSignal = focusRequest && block.id && focusRequest.blockId === asEditorBlockId(block.id) ? focusRequest : null;
3999
+ const focusSignal = focusRequest && block.id && focusRequest.blockId === unsafeAsEditorBlockId(block.id) ? focusRequest : null;
3337
4000
  const collapsed = isCollapsed(block.id);
3338
4001
  return /* @__PURE__ */ jsxs(
3339
4002
  "div",
@@ -3365,12 +4028,12 @@ var BlockEditor = forwardRef(
3365
4028
  if (!block.id) return;
3366
4029
  setCollapsed(block.id, nextCollapsed);
3367
4030
  if (nextCollapsed) {
3368
- if (activeBlockId === asEditorBlockId(block.id)) {
4031
+ if (activeBlockId === unsafeAsEditorBlockId(block.id)) {
3369
4032
  uiStore.getState().setActiveBlockId(null);
3370
4033
  }
3371
4034
  return;
3372
4035
  }
3373
- uiStore.getState().setActiveBlockId(asEditorBlockId(block.id));
4036
+ uiStore.getState().setActiveBlockId(unsafeAsEditorBlockId(block.id));
3374
4037
  },
3375
4038
  highlighted: highlightedBlockId === block.id,
3376
4039
  hasRecoveryConflict: typeof block.id === "string" && conflictedBlockIdSet.has(block.id),
@@ -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(
@@ -4589,6 +5257,8 @@ function MediaField({
4589
5257
  const mediaPickerAutoOpen = config.ui?.mediaPickerAutoOpen === true;
4590
5258
  const showMediaPreview = config.ui?.showMediaPreview !== false;
4591
5259
  const showMediaOverlayActions = config.ui?.showMediaOverlayActions !== false;
5260
+ const mediaPreviewMaxWidth = config.ui?.mediaPreviewMaxWidth ?? "md";
5261
+ const preventMediaPreviewUpscale = config.ui?.preventMediaPreviewUpscale === true;
4592
5262
  const slotContract = resolveMediaSlotContract({
4593
5263
  blockKind: blockContext?.blockKind,
4594
5264
  fieldPath: path,
@@ -4626,6 +5296,8 @@ function MediaField({
4626
5296
  fullWidth: isInlineVariant,
4627
5297
  previewVariant: isInlineVariant ? "thumbnail" : "default",
4628
5298
  showRemoveAction: !isInlineVariant,
5299
+ previewMaxWidth: mediaPreviewMaxWidth,
5300
+ preventPreviewUpscale: preventMediaPreviewUpscale,
4629
5301
  videoPrepIntent: videoPrepIntentForMediaField(
4630
5302
  path,
4631
5303
  config.mediaKinds
@@ -4652,6 +5324,8 @@ function FileField({
4652
5324
  const mediaPickerAutoOpen = config.ui?.mediaPickerAutoOpen === true;
4653
5325
  const showMediaPreview = config.ui?.showMediaPreview !== false;
4654
5326
  const showMediaOverlayActions = config.ui?.showMediaOverlayActions !== false;
5327
+ const mediaPreviewMaxWidth = config.ui?.mediaPreviewMaxWidth ?? "md";
5328
+ const preventMediaPreviewUpscale = config.ui?.preventMediaPreviewUpscale === true;
4655
5329
  const handleChange = (next) => {
4656
5330
  emitMediaCropDebug("MediaField", "file_change", {
4657
5331
  path,
@@ -4675,6 +5349,8 @@ function FileField({
4675
5349
  fullWidth: isInlineVariant,
4676
5350
  previewVariant: isInlineVariant ? "thumbnail" : "default",
4677
5351
  showRemoveAction: !isInlineVariant,
5352
+ previewMaxWidth: mediaPreviewMaxWidth,
5353
+ preventPreviewUpscale: preventMediaPreviewUpscale,
4678
5354
  uploadIntent: uploadIntentForFileField()
4679
5355
  }
4680
5356
  );
@@ -4827,15 +5503,17 @@ function EntryPickerField({
4827
5503
  }
4828
5504
  function IconPickerField({ path, backend, config }) {
4829
5505
  const { value, error, setValue } = useField(path, backend);
4830
- const preset = config.ui?.iconPickerPreset;
4831
- if (preset && preset !== "cta" && true) {
4832
- 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".`);
4833
5510
  }
4834
- 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;
4835
5513
  return /* @__PURE__ */ jsx(FieldFrame, { label: config.label, description: config.description, error: error?.message, children: () => /* @__PURE__ */ jsx(
4836
5514
  Combobox,
4837
5515
  {
4838
- 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 })),
4839
5517
  value: selected,
4840
5518
  onSelect: (entry) => {
4841
5519
  if (!entry) {
@@ -4847,7 +5525,7 @@ function IconPickerField({ path, backend, config }) {
4847
5525
  placeholder: "Select icon\u2026",
4848
5526
  clearLabel: "Clear",
4849
5527
  renderItem: (entry) => {
4850
- const Icon = getCtaIconComponent(entry.id);
5528
+ const Icon = getIconComponent(entry.id);
4851
5529
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4852
5530
  Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }) : null,
4853
5531
  /* @__PURE__ */ jsx("span", { className: "truncate", children: entry.label })
@@ -5275,7 +5953,7 @@ function PreviewFormProvider({
5275
5953
  mediaAssets,
5276
5954
  children
5277
5955
  }) {
5278
- const siteId = useMemo(() => asSiteId(rawSiteId), [rawSiteId]);
5956
+ const siteId = useMemo(() => expectParsedBrandedId(parseSiteId(rawSiteId)), [rawSiteId]);
5279
5957
  const linkAdapters = useMemo(() => createPreviewLinkAdapters(previewClient), [previewClient]);
5280
5958
  const entryPickerAdapter = useMemo(() => createPreviewEntryPickerAdapter(previewClient), [previewClient]);
5281
5959
  const referenceAdapters = useMemo(
@@ -6856,8 +7534,15 @@ function SiteChromeLookRow({
6856
7534
  }
6857
7535
  function PaletteRow({ expanded, onToggle, siteStyle, currentId, currentLabel, currentSwatch, onPreview, disabled }) {
6858
7536
  const options = useMemo(
6859
- () => requireEntriesForCuratedChoices(paletteVariants, siteStyle.paletteVariantChoices),
6860
- [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]
6861
7546
  );
6862
7547
  return /* @__PURE__ */ jsx(
6863
7548
  StyleRowFrame,
@@ -7002,7 +7687,7 @@ function describeWarning(warning) {
7002
7687
  case "rejected-personality":
7003
7688
  return `Button style changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
7004
7689
  case "rejected-palette":
7005
- 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.`;
7006
7691
  case "rejected-typography-preset":
7007
7692
  return `Typography changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
7008
7693
  default: {
@@ -7115,7 +7800,7 @@ function PreviewEditorSidebar({
7115
7800
  const baseline = extractData(
7116
7801
  block.content ?? block.draftContent ?? block.publishedContent ?? null
7117
7802
  );
7118
- const blockId = asEditorBlockId(block.id);
7803
+ const blockId = unsafeAsEditorBlockId(block.id);
7119
7804
  if (drafts.getBlockSnapshot(blockId)) {
7120
7805
  drafts.updateBlockBaseline(blockId, baseline, { kind: block.kind });
7121
7806
  } else {