@riverbankcms/sdk 0.80.0 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PreviewEditorSidebar-QZG37QIF.mjs → PreviewEditorSidebar-RDCMEXIJ.mjs} +763 -255
- package/dist/{PreviewEditorUI-AXIKSMZA.mjs → PreviewEditorUI-NYGQ6K7B.mjs} +170 -29
- package/dist/SdkPreviewModeRuntime-AKCSCZEC.mjs +8 -0
- package/dist/_dts/api/src/contentRuntime.d.ts +12 -0
- package/dist/_dts/api/src/contentTypes.d.ts +6 -0
- package/dist/_dts/api/src/index.d.ts +2 -2
- package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +53 -0
- package/dist/_dts/block-form/src/backend/store-backend.d.ts +3 -1
- package/dist/_dts/block-form/src/backend/types.d.ts +3 -3
- package/dist/_dts/blocks/src/PageRenderer.d.ts +3 -0
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +20 -28
- package/dist/_dts/blocks/src/index.d.ts +6 -4
- package/dist/_dts/blocks/src/primitives/content/components/Text.d.ts +1 -1
- package/dist/_dts/blocks/src/primitives/content/primitives.d.ts +1 -0
- package/dist/_dts/blocks/src/server.d.ts +1 -1
- package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +3 -2
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +135 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +5 -0
- package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +2 -0
- package/dist/_dts/blocks/src/system/blocks/form.d.ts +20 -1
- package/dist/_dts/blocks/src/system/blocks/hero.d.ts +2 -0
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/index.d.ts +19 -0
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +134 -0
- package/dist/_dts/blocks/src/system/componentFactory.d.ts +1 -0
- package/dist/_dts/blocks/src/system/constants/background.d.ts +1 -1
- package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
- package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +13 -3
- package/dist/_dts/blocks/src/system/data/index.d.ts +2 -0
- package/dist/_dts/blocks/src/system/data/linkedContentEntries.d.ts +64 -0
- package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
- package/dist/_dts/blocks/src/system/designCapabilities.d.ts +2 -2
- package/dist/_dts/blocks/src/system/fields/boxStyles.d.ts +6 -1
- package/dist/_dts/blocks/src/system/fragments/library/faqHeading.d.ts +0 -1
- package/dist/_dts/blocks/src/system/media/slotContracts.d.ts +2 -0
- package/dist/_dts/blocks/src/system/node/types.d.ts +8 -1
- package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
- package/dist/_dts/blocks/src/system/registry.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +44 -50
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -24
- package/dist/_dts/blocks/src/system/runtime/headingDecoration.d.ts +21 -0
- package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +45 -14
- package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.d.ts +2 -9
- package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +1 -10
- package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +21 -16
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +3 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +21 -16
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +17 -28
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +2 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekAgendaView.d.ts +3 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listOptions.d.ts +50 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +29 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/offerings-preview.d.ts +21 -0
- package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +7 -0
- package/dist/_dts/blocks/src/system/transforms/registry/_utils/sectionForegroundStyles.d.ts +2 -0
- package/dist/_dts/blocks/src/system/transforms/registry/boxStyles.d.ts +4 -2
- package/dist/_dts/calendar/src/grid.d.ts +27 -0
- package/dist/_dts/calendar/src/index.d.ts +2 -2
- package/dist/_dts/content-editor/src/controller/useAutosaveTriggers.d.ts +3 -1
- package/dist/_dts/content-editor/src/editorTransactionState.d.ts +1 -0
- package/dist/_dts/content-editor/src/hooks/autosaveScopePlanning.d.ts +26 -0
- package/dist/_dts/content-editor/src/hooks/publishability.d.ts +1 -0
- package/dist/_dts/content-editor/src/hooks/useLinkedEntryAutosave.d.ts +23 -0
- package/dist/_dts/content-editor/src/hooks/useReactiveToolbar.d.ts +1 -1
- package/dist/_dts/content-editor/src/hooks/useSimpleAutosave.d.ts +2 -2
- package/dist/_dts/content-editor/src/index.d.ts +3 -1
- package/dist/_dts/content-editor/src/lib/json.d.ts +2 -0
- package/dist/_dts/content-editor/src/linkedEntries/domain.d.ts +8 -0
- package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +58 -0
- package/dist/_dts/content-editor/src/ui/editorTransactionState.d.ts +93 -0
- package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +60 -3
- package/dist/_dts/content-editor/src/ui/stores/autosaveStore.d.ts +2 -0
- package/dist/_dts/content-editor/src/ui/stores/types.d.ts +1 -1
- package/dist/_dts/content-model/src/content-types/builtins.d.ts +43 -0
- package/dist/_dts/content-model/src/metadataConfig.d.ts +87 -47
- package/dist/_dts/core/src/branded.d.ts +5 -0
- package/dist/_dts/core/src/index.d.ts +1 -0
- package/dist/_dts/core/src/stable-json.d.ts +1 -0
- package/dist/_dts/editor/src/EditorProvider.d.ts +26 -0
- package/dist/_dts/editor/src/chrome/EditorChrome.d.ts +26 -0
- package/dist/_dts/editor/src/chrome/EditorStatusBar.d.ts +45 -0
- package/dist/_dts/editor/src/chrome/statusBarPresentation.d.ts +25 -0
- package/dist/_dts/editor/src/components/EditingToggle.d.ts +9 -0
- package/dist/_dts/editor/src/hooks/useEditableElement.d.ts +18 -0
- package/dist/_dts/editor/src/index.d.ts +29 -0
- package/dist/_dts/editor/src/inline/InlineTextEditor.d.ts +1 -0
- package/dist/_dts/editor/src/lib/utils.d.ts +1 -0
- package/dist/_dts/editor/src/primitives/EditorPrimitivesProvider.d.ts +20 -0
- package/dist/_dts/editor/src/primitives/InlineFieldContext.d.ts +11 -0
- package/dist/_dts/editor/src/primitives/SaveContext.d.ts +12 -0
- package/dist/_dts/editor/src/primitives/helpers.d.ts +1 -0
- package/dist/_dts/editor/src/primitives/rich-text/RichTextEditorSurface.d.ts +26 -0
- package/dist/_dts/editor/src/primitives/rich-text/RichTextToolbar.d.ts +16 -0
- package/dist/_dts/editor/src/primitives/rich-text/config.d.ts +23 -0
- package/dist/_dts/editor/src/primitives/rich-text/extensions/RichTextImage.d.ts +2 -0
- package/dist/_dts/editor/src/primitives/rich-text/extensions/RichTextLink.d.ts +1 -0
- package/dist/_dts/editor/src/primitives/rich-text/imageActions.d.ts +22 -0
- package/dist/_dts/editor/src/primitives/rich-text/sanitize.d.ts +23 -0
- package/dist/_dts/editor/src/primitives/rich-text/toolbar/BlockTypeDropdown.d.ts +6 -0
- package/dist/_dts/editor/src/primitives/rich-text/toolbar/LinkPopover.d.ts +10 -0
- package/dist/_dts/editor/src/primitives/rich-text/toolbar/ToolbarIconButton.d.ts +11 -0
- package/dist/_dts/editor/src/primitives/rich-text/toolbar/linkPopoverUtils.d.ts +58 -0
- package/dist/_dts/editor/src/primitives/rich-text/useRichTextEditor.d.ts +19 -0
- package/dist/_dts/editor/src/primitives/rich-text/utils.d.ts +20 -0
- package/dist/_dts/editor/src/utils/optimisticTokens.d.ts +27 -0
- package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +2 -2
- package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +3 -3
- package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +4 -4
- package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +2 -2
- package/dist/_dts/editor-blocks/src/block-editor/actionPresentation.d.ts +15 -0
- package/dist/_dts/editor-blocks/src/block-editor/blockHeaderActionPlan.d.ts +49 -0
- package/dist/_dts/editor-blocks/src/widgets/index.d.ts +1 -0
- package/dist/_dts/editor-blocks/src/widgets/rich-text/RichTextWidgetProvider.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/rich-text/useImagePicker.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/SiteOptionPickerField.d.ts +3 -0
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/SiteOptionWidgetProvider.d.ts +14 -0
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/index.d.ts +6 -0
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +51 -0
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/types.d.ts +20 -0
- package/dist/_dts/editor-blocks/src/widgets/site-option-picker/utils.d.ts +5 -0
- package/dist/_dts/media-core/src/index.d.ts +1 -0
- package/dist/_dts/media-core/src/renderableMediaAsset.d.ts +18 -0
- package/dist/_dts/media-editor/src/MediaEditor.d.ts +4 -1
- package/dist/_dts/media-editor/src/MediaPickerDialog.d.ts +2 -1
- package/dist/_dts/media-editor/src/index.d.ts +1 -1
- package/dist/_dts/preview-next/src/client/blocks/BlockToolbar.d.ts +3 -2
- package/dist/_dts/preview-next/src/client/blocks/EditablePageRenderer.d.ts +5 -1
- package/dist/_dts/preview-next/src/client/blocks/blockCustomizePopoverRows.d.ts +25 -0
- package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +4 -30
- package/dist/_dts/preview-next/src/client/blocks/linkedEntryRenderOverlay.d.ts +11 -0
- package/dist/_dts/preview-next/src/client/blocks/previewCustomizeActions.d.ts +3 -9
- package/dist/_dts/preview-next/src/client/blocks/useBlockCustomizeControls.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/index.d.ts +0 -1
- package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +3 -1
- package/dist/_dts/preview-next/src/client/preview/LinkedEntryEditEventBridge.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +3 -1
- package/dist/_dts/preview-next/src/client/preview/PreviewChromeLayer.d.ts +20 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewDesignHistoryOrderContext.d.ts +13 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewOpenEditorButton.d.ts +1 -1
- package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +19 -19
- package/dist/_dts/preview-next/src/client/preview/PreviewSidebarSection.d.ts +13 -0
- package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +47 -4
- package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +14 -1
- package/dist/_dts/preview-next/src/client/preview/linkedEntryEditEvents.d.ts +5 -0
- package/dist/_dts/preview-next/src/client/preview/previewChromePlacement.d.ts +46 -0
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeControls.d.ts +68 -0
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeHistory.d.ts +8 -1
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeWorkflowState.d.ts +11 -9
- package/dist/_dts/preview-next/src/client/preview/previewDesignHistoryOrder.d.ts +18 -0
- package/dist/_dts/preview-next/src/client/preview/previewUndoDomains.d.ts +1 -1
- package/dist/_dts/preview-next/src/client/preview/siteChromeBrandPreferences.d.ts +41 -0
- package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +101 -0
- package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +29 -0
- package/dist/_dts/preview-next/src/client/preview/siteStyleHistoryState.d.ts +55 -0
- package/dist/_dts/preview-next/src/client/preview/styleConfiguratorApplyPayload.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/widgets/widgetAdapters.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +3 -2
- package/dist/_dts/preview-next/src/constants.d.ts +0 -1
- package/dist/_dts/sdk/src/cli/config-loader.d.ts +3 -1
- package/dist/_dts/sdk/src/cli/content/reader.d.ts +5 -3
- package/dist/_dts/sdk/src/cli/site-commands/commandSurfaceDispatch.d.ts +1 -0
- package/dist/_dts/sdk/src/cli/site-commands/pageCommands.d.ts +3 -1
- package/dist/_dts/sdk/src/cli/site-commands/pushExecution.d.ts +1 -0
- package/dist/_dts/sdk/src/config/types.d.ts +1 -1
- package/dist/_dts/sdk/src/config/validation.d.ts +3 -3
- package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +28 -2
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +10 -0
- package/dist/_dts/sdk/src/rendering/islands/types.d.ts +42 -0
- package/dist/_dts/sdk/src/rendering/mediaAssets.d.ts +4 -0
- package/dist/_dts/sdk/src/types/block-kinds.d.ts +1 -1
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/buttons/constants.d.ts +26 -1
- package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
- package/dist/_dts/theme-core/src/buttons/personalities/joy-stamp.d.ts +22 -0
- package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +1 -0
- package/dist/_dts/theme-core/src/buttons/types.d.ts +9 -0
- package/dist/_dts/theme-core/src/cards/siteStyleDefaults.d.ts +44 -0
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/_dts/theme-core/src/interactive/types.d.ts +10 -0
- package/dist/_dts/theme-core/src/mock-themes/all.d.ts +27 -6
- package/dist/_dts/theme-core/src/palette/variants/index.d.ts +15 -0
- package/dist/_dts/theme-core/src/palette/variants/warm-dark.d.ts +27 -0
- package/dist/_dts/theme-core/src/schema.d.ts +40 -3
- package/dist/_dts/theme-core/src/site-styles/accessibleSurfaces.d.ts +4 -1
- package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +87 -31
- package/dist/_dts/theme-core/src/site-styles/appearancePresetResolution.d.ts +6 -2
- package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +87 -31
- package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +30 -1
- package/dist/_dts/theme-core/src/site-styles/designState.d.ts +18 -2
- package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +6 -2
- package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +5 -0
- package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -0
- package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +3 -23
- package/dist/_dts/theme-core/src/site-styles/pageDesignIntent.d.ts +276 -4
- package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +33 -3
- package/dist/_dts/theme-core/src/site-styles/sectionTransitions.d.ts +508 -0
- package/dist/_dts/theme-core/src/site-styles/sourceCatalogs.d.ts +10 -10
- package/dist/_dts/theme-core/src/site-styles/types.d.ts +24 -6
- package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +16 -1
- package/dist/{chunk-7PCYG6YV.mjs → chunk-3PTVPAT4.mjs} +1863 -1099
- package/dist/{chunk-5NZGBSJF.mjs → chunk-3QWQ2MUQ.mjs} +469 -1000
- package/dist/{chunk-HTB4BMKD.mjs → chunk-3VT7LZY2.mjs} +321 -113
- package/dist/{chunk-MPBNEVPB.mjs → chunk-4T5JIPWY.mjs} +1 -1
- package/dist/{chunk-BBLZSQEY.mjs → chunk-E3NZYEKF.mjs} +1 -7
- package/dist/{chunk-GYXKAUFV.mjs → chunk-WUHKQBB6.mjs} +9509 -2658
- package/dist/cli/index.mjs +1347 -324
- package/dist/client/{accordion-QFZMNB7O.mjs → accordion-SFIIZWNH.mjs} +2 -2
- package/dist/client/{bookingForm-NCIXFWIG.mjs → bookingForm-CFKZVWGA.mjs} +5 -5
- package/dist/client/bookings.mjs +281 -19
- package/dist/client/{carousel-EO4BJMWD.mjs → carousel-ELXWSBLA.mjs} +3 -3
- package/dist/client/{cart-FTYCLYUW.mjs → cart-6SSCPYY5.mjs} +6 -6
- package/dist/client/{checkout-NFGLVCOX.mjs → checkout-UFQ34HPV.mjs} +6 -6
- package/dist/client/{chunk-6GVVWSPU.mjs → chunk-76JUETXQ.mjs} +139 -186
- package/dist/client/{chunk-AUJ5DBZJ.mjs → chunk-7BXX7WXH.mjs} +112 -28
- package/dist/client/{chunk-IWFZSQNZ.mjs → chunk-G56BSZAM.mjs} +2 -2
- package/dist/client/{chunk-VDS5YFLX.mjs → chunk-IUEDYLFJ.mjs} +1 -1
- package/dist/client/{chunk-PYRBIURC.mjs → chunk-NP47RHIX.mjs} +5 -5
- package/dist/client/{chunk-PUOELU4O.mjs → chunk-NX6X3GRF.mjs} +330 -80
- package/dist/client/{chunk-Y37KDO7P.mjs → chunk-PA2LJH2M.mjs} +2 -2
- package/dist/client/{chunk-CE7IBGVW.mjs → chunk-RMWMT3ZD.mjs} +1 -1
- package/dist/client/{chunk-4W66ALYT.mjs → chunk-TCJS3NY5.mjs} +1 -1
- package/dist/client/{chunk-T6UIP6UZ.mjs → chunk-V6XI4M2Q.mjs} +1 -1
- package/dist/client/client.mjs +5924 -3138
- package/dist/client/{courseRegistration-2EORROPS.mjs → courseRegistration-HJIISAAG.mjs} +5 -5
- package/dist/client/{eventCalendar-WZI4VL6N.mjs → eventCalendar-F6YVUCZR.mjs} +7 -7
- package/dist/client/{eventCombined-QCB2TCNL.mjs → eventCombined-B5DSTIOK.mjs} +7 -7
- package/dist/client/{eventDetails-TFTATAPH.mjs → eventDetails-SEJDDHQC.mjs} +7 -7
- package/dist/client/{eventListing-A2CQEHEQ.mjs → eventListing-TPMWIIBO.mjs} +7 -7
- package/dist/client/{eventRegistration-OELPVLUY.mjs → eventRegistration-QU6W2PV6.mjs} +7 -7
- package/dist/client/{form-NTIFD6WQ.mjs → form-LVTYNTDE.mjs} +2 -2
- package/dist/client/{headerSection-7TBNKCLA.mjs → headerSection-SO3MFC4U.mjs} +54 -13
- package/dist/client/hooks.mjs +2266 -1179
- package/dist/client/{locationMap-LRLB5A3H.mjs → locationMap-5E5FLAKO.mjs} +2 -2
- package/dist/client/{newsletterForm-XI52RZSN.mjs → newsletterForm-GN32JEBQ.mjs} +2 -2
- package/dist/client/{productDetail-GSNKBFLY.mjs → productDetail-Q346KSVR.mjs} +6 -6
- package/dist/client/{productList-BGCGT4KZ.mjs → productList-DTDMQYGZ.mjs} +6 -6
- package/dist/client/rendering/client.mjs +4618 -3318
- package/dist/client/rendering/islands.mjs +32 -20
- package/dist/client/rendering.mjs +4898 -2108
- package/dist/client/{shop-RQHUCLNY.mjs → shop-OFUW7KPN.mjs} +6 -6
- package/dist/preview-next/client/runtime.mjs +5 -5
- package/dist/preview-next/constants.mjs +0 -2
- package/dist/preview-next/index.mjs +0 -2
- package/dist/{sdk-runtime-A4LHT2RS.mjs → sdk-runtime-2GIX6I7X.mjs} +6 -6
- package/dist/server/components.mjs +4377 -1852
- package/dist/server/config-validation.mjs +2283 -1303
- package/dist/server/config.mjs +2283 -1303
- package/dist/server/data.mjs +2267 -1180
- package/dist/server/index.mjs +2 -1
- package/dist/server/next.mjs +4394 -1773
- package/dist/server/page-converter.mjs +1999 -1015
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +4482 -1857
- package/dist/server/rendering.mjs +4484 -1859
- package/dist/server/routing.mjs +2302 -1120
- package/dist/server/server.mjs +2284 -1197
- package/dist/server/theme-bridge.mjs +757 -85
- package/dist/server/theme.mjs +69 -4
- package/dist/styles/index.css +474 -65
- package/package.json +1 -1
- package/dist/SdkPreviewModeRuntime-XE5M4UKM.mjs +0 -8
- package/dist/_dts/editor-blocks/src/block-editor/actionControlMode.d.ts +0 -2
- package/dist/_dts/preview-next/src/client/preview/previewSurface.d.ts +0 -3
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useOptionalPreviewLayout, PreviewQueryProvider } from './chunk-
|
|
3
|
-
import {
|
|
4
|
-
import { resolvePreviewChromeSurface, getPreviewSidebarTab, onPreviewSidebarOpenRequest, getPreviewChromeSurfaceDataProps, PREVIEW_CHROME_THEME_CLASS_NAME, setPreviewSidebarTab, PreviewPageDesignEditorStateProvider, usePreviewPageDesignEditorState
|
|
5
|
-
import { clientComponentRegistry, deriveLaunchReadiness, DEFAULT_LAUNCH_READINESS_INPUT, useEditorUiStore, ResizableSplitPane, BlockApiProvider, EditorProvider, MediaEditorProvider,
|
|
6
|
-
import { API_ENDPOINTS, createBearerAPIClient, isPreviewRuntimeSessionEditable, DEFAULT_SURFACE_ID, initPreviewAuth, usePreviewAuth, usePreviewAuthFetch, markPreviewAuthExpired, usePreviewToken
|
|
7
|
-
import
|
|
2
|
+
import { useOptionalPreviewLayout, PreviewQueryProvider } from './chunk-4T5JIPWY.mjs';
|
|
3
|
+
import { PreviewBlockCustomizeSelectionProvider, resolveSiteStyleAccess, resolvePreviewDashboardSetupHandoff, buildPreviewDashboardSetupUrl, resolvePreviewSetupBannerModel, usePreviewBlockCustomizeSelectionOptional, useBlockCustomizeControls, MAX_CUSTOMIZE_POPOVER_ROWS, MAX_QUICK_MANIFEST_FIELDS, sanitizeDashboardPath } from './chunk-3QWQ2MUQ.mjs';
|
|
4
|
+
import { resolvePreviewChromeSurface, getPreviewSidebarTab, onPreviewSidebarOpenRequest, getPreviewChromeSurfaceDataProps, PREVIEW_CHROME_THEME_CLASS_NAME, setPreviewSidebarTab, PreviewPageDesignEditorStateProvider, usePreviewPageDesignEditorState } from './chunk-3VT7LZY2.mjs';
|
|
5
|
+
import { clientComponentRegistry, deriveLaunchReadiness, DEFAULT_LAUNCH_READINESS_INPUT, useEditorUiStore, PreviewThemeOverlayProvider, PreviewDesignCoordinatorProvider, SiteChromeCustomizeProvider, ResizableSplitPane, BlockApiProvider, EditorProvider, PreviewDesignHistoryOrderProvider, MediaEditorProvider, useEditorUiStoreInstance, useEditor, createRoutingHelpers, createSnapshotFromPageRecord, EntryControllerProvider, useEntryEditorController, surfaceResolutionContextFromTheme, unsafeAsEditorBlockId, EditableBlockProvider, asDesignBlockId, PageRenderer, usePreviewThemeOverlay, planSiteDocument, ThemeScope, FixedBottomSurface, Button, sectionTransitionVariantForBoundaryOptionId, sectionTransitionFamilyForBoundaryOptionId, sectionTransitionFamilies, X, defaultSectionTransitionVariantForFamily, RotateCcw, parseBackgroundOverrideFromContent, rankBackgroundImagePoolItems, imagePoolForOverride, resolveBackgroundCapability, enabledBackgroundModes, FormRenderer, stableSerialize, prefetchBlockData, isSupportedLoaderEndpoint, PreviewRichTextEditor, RichText, PreviewTextEditor, Text, buildThemeRuntime, renderBlock, siteHeaderManifest, siteFooterManifest, SiteDocumentLayout, SITE_CHROME_CLASS_NAMES, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, buildEditorModelRuntimeFieldsByBlockId, applyCompiledRuntimeFieldsToContent, assertNever2, getBlockDefinition, systemCustomizeFacetDefinitionsForBlock, systemCustomizeFacetAppliesToLayoutVariant, systemCustomizeFacetCurrentValue, systemCustomizeFacetLabelForValue, backgroundColorTokens, ChevronLeft, ChevronRight, createMicrobatcher, unwrapResponse, normalizePublicApiLoaderParams, visibleHeaderClearancePx, LINKED_CONTENT_ENTRY_META_KEY, unsafeAsLinkedContentEntryId, useMediaEditorOptional, Image, defaultBackgroundOverrideForMode, decodePublicProductCategorySelectorQuery, EDITABLE_SURFACE_FORWARDING_PROP, useSiteChromeCustomizeOptional, assertNever, SITE_CHROME_VISIBLE_HEADER_SELECTOR, GRADIENT_PRESETS, resolveImageUrlWithContext, gradientToCss, Upload, MediaEditor, SECTION_BACKGROUND_MIN_SOURCE_WIDTH, SECTION_BACKGROUND_MIN_SOURCE_HEIGHT, parseMediaAssetId, planBackgroundOverride, planBackgroundTransition, systemCustomizeFacetNextValue } from './chunk-WUHKQBB6.mjs';
|
|
6
|
+
import { API_ENDPOINTS, createBearerAPIClient, isPreviewRuntimeSessionEditable, DEFAULT_SURFACE_ID, initPreviewAuth, usePreviewAuth, usePreviewAuthFetch, markPreviewAuthExpired, usePreviewToken } from './chunk-E3NZYEKF.mjs';
|
|
7
|
+
import React10, { createContext, useMemo, useState, useEffect, useRef, useCallback, useId, useReducer, Children, isValidElement, Fragment as Fragment$1, cloneElement, useContext } from 'react';
|
|
8
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
9
10
|
|
|
10
11
|
// ../preview-next/src/client/utils/path.ts
|
|
11
12
|
var PATH_SEPARATOR_REGEX = /\./g;
|
|
@@ -252,12 +253,90 @@ function blockHasPreviewContentFieldProjection(blockId, projections) {
|
|
|
252
253
|
);
|
|
253
254
|
}
|
|
254
255
|
|
|
256
|
+
// ../preview-next/src/client/blocks/linkedEntryRenderOverlay.ts
|
|
257
|
+
function applyLinkedEntryRenderOverlay(value, overlays) {
|
|
258
|
+
if (overlays.size === 0) return value;
|
|
259
|
+
return overlayValue(value, overlays);
|
|
260
|
+
}
|
|
261
|
+
function applyLinkedEntryRenderOverlayToDataContext(dataContext, overlays) {
|
|
262
|
+
if (!dataContext?.resolvedData || overlays.size === 0) {
|
|
263
|
+
return dataContext;
|
|
264
|
+
}
|
|
265
|
+
const resolvedData = applyLinkedEntryRenderOverlay(
|
|
266
|
+
dataContext.resolvedData,
|
|
267
|
+
overlays
|
|
268
|
+
);
|
|
269
|
+
if (resolvedData === dataContext.resolvedData) {
|
|
270
|
+
return dataContext;
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
...dataContext,
|
|
274
|
+
resolvedData
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function overlayValue(value, overlays) {
|
|
278
|
+
if (Array.isArray(value)) {
|
|
279
|
+
let changed2 = false;
|
|
280
|
+
const next2 = value.map((item) => {
|
|
281
|
+
const overlaid = overlayValue(item, overlays);
|
|
282
|
+
if (overlaid !== item) changed2 = true;
|
|
283
|
+
return overlaid;
|
|
284
|
+
});
|
|
285
|
+
return changed2 ? next2 : value;
|
|
286
|
+
}
|
|
287
|
+
if (!isRecord3(value)) return value;
|
|
288
|
+
const meta = parseLinkedEntryMeta(value[LINKED_CONTENT_ENTRY_META_KEY]);
|
|
289
|
+
if (meta) {
|
|
290
|
+
const overlay = overlays.get(unsafeAsLinkedContentEntryId(meta.entryId));
|
|
291
|
+
if (overlay) {
|
|
292
|
+
const title = resolveOverlayTitle(overlay.content, meta);
|
|
293
|
+
return {
|
|
294
|
+
...value,
|
|
295
|
+
title,
|
|
296
|
+
content: overlay.content,
|
|
297
|
+
optimisticHash: overlay.optimisticHash,
|
|
298
|
+
[LINKED_CONTENT_ENTRY_META_KEY]: {
|
|
299
|
+
...meta,
|
|
300
|
+
title,
|
|
301
|
+
optimisticHash: overlay.optimisticHash
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
let changed = false;
|
|
307
|
+
const next = {};
|
|
308
|
+
for (const [key, child] of Object.entries(value)) {
|
|
309
|
+
const overlaid = overlayValue(child, overlays);
|
|
310
|
+
if (overlaid !== child) changed = true;
|
|
311
|
+
next[key] = overlaid;
|
|
312
|
+
}
|
|
313
|
+
return changed ? next : value;
|
|
314
|
+
}
|
|
315
|
+
function resolveOverlayTitle(content, meta) {
|
|
316
|
+
const titleField = meta.contentType.titleField;
|
|
317
|
+
if (titleField) {
|
|
318
|
+
const value = content[titleField];
|
|
319
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
320
|
+
return value;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return meta.title;
|
|
324
|
+
}
|
|
325
|
+
function parseLinkedEntryMeta(value) {
|
|
326
|
+
if (!isRecord3(value)) return null;
|
|
327
|
+
return value.kind === "linked-content-entry" && typeof value.entryId === "string" ? value : null;
|
|
328
|
+
}
|
|
329
|
+
function isRecord3(value) {
|
|
330
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
331
|
+
}
|
|
332
|
+
|
|
255
333
|
// ../preview-next/src/client/blocks/composer/mergeDrafts.ts
|
|
334
|
+
var EMPTY_LINKED_ENTRY_OVERLAY = /* @__PURE__ */ new Map();
|
|
256
335
|
function getDraftSnapshots(uiStore) {
|
|
257
336
|
const snapshots = uiStore.getState().drafts.inspect();
|
|
258
337
|
return new Map(snapshots.map((snap) => [snap.id, snap]));
|
|
259
338
|
}
|
|
260
|
-
function mergeBlockWithDraft(block, draftMap, index, projections = []) {
|
|
339
|
+
function mergeBlockWithDraft(block, draftMap, index, projections = [], linkedEntryOverlays = EMPTY_LINKED_ENTRY_OVERLAY) {
|
|
261
340
|
const id = block.id ?? null;
|
|
262
341
|
const editorBlockId = id ? unsafeAsEditorBlockId(id) : null;
|
|
263
342
|
const snap = editorBlockId ? draftMap.get(editorBlockId) ?? null : null;
|
|
@@ -269,20 +348,22 @@ function mergeBlockWithDraft(block, draftMap, index, projections = []) {
|
|
|
269
348
|
kind: block.kind,
|
|
270
349
|
purpose: "content",
|
|
271
350
|
orderIndex: block.orderIndex ?? index,
|
|
272
|
-
content: renderContent(block, baseline, projections),
|
|
273
|
-
draftContent: renderContent(block, draftContent, projections),
|
|
351
|
+
content: renderContent(block, baseline, projections, linkedEntryOverlays),
|
|
352
|
+
draftContent: renderContent(block, draftContent, projections, linkedEntryOverlays),
|
|
274
353
|
publishedContent: renderContent(
|
|
275
354
|
block,
|
|
276
355
|
block.publishedContent ?? null,
|
|
277
|
-
projections
|
|
356
|
+
projections,
|
|
357
|
+
EMPTY_LINKED_ENTRY_OVERLAY
|
|
278
358
|
),
|
|
279
359
|
bindings: block.bindings ?? null
|
|
280
360
|
};
|
|
281
361
|
}
|
|
282
|
-
function renderContent(block, content, projections) {
|
|
362
|
+
function renderContent(block, content, projections, linkedEntryOverlays) {
|
|
363
|
+
const overlaidContent = applyLinkedEntryRenderOverlay(content, linkedEntryOverlays);
|
|
283
364
|
return applyPreviewRuntimeContentProjections(
|
|
284
365
|
block,
|
|
285
|
-
|
|
366
|
+
overlaidContent,
|
|
286
367
|
projections
|
|
287
368
|
);
|
|
288
369
|
}
|
|
@@ -333,18 +414,20 @@ function composePageFromBlocks(args, cacheRef) {
|
|
|
333
414
|
const aiProjections = previewProjectionsFromAiOverlays(
|
|
334
415
|
uiStore.getState().aiOverlays
|
|
335
416
|
);
|
|
417
|
+
const linkedEntryOverlays = getLinkedEntryRenderOverlays(uiStore);
|
|
336
418
|
return composePreviewRenderPage(
|
|
337
419
|
{
|
|
338
420
|
page,
|
|
339
421
|
blockItems,
|
|
340
422
|
draftSnapshots: Array.from(draftMap.values()),
|
|
341
|
-
projections: [...aiProjections, ...projections]
|
|
423
|
+
projections: [...aiProjections, ...projections],
|
|
424
|
+
linkedEntryOverlays
|
|
342
425
|
},
|
|
343
426
|
cacheRef
|
|
344
427
|
);
|
|
345
428
|
}
|
|
346
429
|
function composePreviewRenderPage(args, cacheRef) {
|
|
347
|
-
const { page, blockItems, draftSnapshots, projections } = args;
|
|
430
|
+
const { page, blockItems, draftSnapshots, projections, linkedEntryOverlays } = args;
|
|
348
431
|
if (!page) return page;
|
|
349
432
|
if (!blockItems.length) return page;
|
|
350
433
|
const draftMap = draftSnapshotMap(draftSnapshots);
|
|
@@ -353,7 +436,7 @@ function composePreviewRenderPage(args, cacheRef) {
|
|
|
353
436
|
projections
|
|
354
437
|
);
|
|
355
438
|
const enrichedBlocks = projectedBlockItems.map(
|
|
356
|
-
(block, index) => mergeBlockWithDraft(block, draftMap, index, projections)
|
|
439
|
+
(block, index) => mergeBlockWithDraft(block, draftMap, index, projections, linkedEntryOverlays)
|
|
357
440
|
);
|
|
358
441
|
const sortedBlocks = [...enrichedBlocks].sort(
|
|
359
442
|
(a, b) => (a.orderIndex ?? 0) - (b.orderIndex ?? 0)
|
|
@@ -361,9 +444,35 @@ function composePreviewRenderPage(args, cacheRef) {
|
|
|
361
444
|
const renderedBlocks = applyCacheOptimization(sortedBlocks, cacheRef);
|
|
362
445
|
return { ...page, blocks: renderedBlocks };
|
|
363
446
|
}
|
|
447
|
+
function getLinkedEntryRenderOverlays(uiStore) {
|
|
448
|
+
const linkedEntries = uiStore.getState().linkedEntries.inspect();
|
|
449
|
+
const overlays = /* @__PURE__ */ new Map();
|
|
450
|
+
for (const linkedEntry of linkedEntries) {
|
|
451
|
+
const content = linkedEntry.current ?? linkedEntry.baseline;
|
|
452
|
+
if (!content) continue;
|
|
453
|
+
overlays.set(linkedEntry.meta.entryId, {
|
|
454
|
+
content,
|
|
455
|
+
optimisticHash: linkedEntry.meta.optimisticHash
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
return overlays;
|
|
459
|
+
}
|
|
364
460
|
function draftSnapshotMap(snapshots) {
|
|
365
461
|
return new Map(snapshots.map((snap) => [snap.id, snap]));
|
|
366
462
|
}
|
|
463
|
+
|
|
464
|
+
// ../preview-next/src/client/preview/linkedEntryEditEvents.ts
|
|
465
|
+
var LINKED_ENTRY_EDIT_EVENT = "riverbank:preview:linked-entry-edit";
|
|
466
|
+
function dispatchLinkedEntryEditEvent(target) {
|
|
467
|
+
window.dispatchEvent(new CustomEvent(LINKED_ENTRY_EDIT_EVENT, {
|
|
468
|
+
detail: target
|
|
469
|
+
}));
|
|
470
|
+
}
|
|
471
|
+
function isLinkedEntryEditEvent(event) {
|
|
472
|
+
if (!(event instanceof CustomEvent)) return false;
|
|
473
|
+
const detail = event.detail;
|
|
474
|
+
return Boolean(detail) && typeof detail === "object" && detail.kind === "linked-content-entry";
|
|
475
|
+
}
|
|
367
476
|
function requireClientRegistryComponent(key) {
|
|
368
477
|
const component = clientComponentRegistry[key];
|
|
369
478
|
if (!component) {
|
|
@@ -388,6 +497,37 @@ var RichTextWithEditor = ({ value, path, ...rest }) => {
|
|
|
388
497
|
}
|
|
389
498
|
return /* @__PURE__ */ jsx(RichText, { ...rest, path, doc: value });
|
|
390
499
|
};
|
|
500
|
+
var LinkedEntryEditFrame = ({ target, children }) => {
|
|
501
|
+
const { isEditingMode } = useEditor();
|
|
502
|
+
if (!isEditingMode) {
|
|
503
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
504
|
+
}
|
|
505
|
+
return /* @__PURE__ */ jsxs(
|
|
506
|
+
"div",
|
|
507
|
+
{
|
|
508
|
+
className: "group/linked-entry-edit relative",
|
|
509
|
+
"data-linked-entry-id": target.entryId,
|
|
510
|
+
"data-linked-entry-type": target.contentTypeKey,
|
|
511
|
+
children: [
|
|
512
|
+
children,
|
|
513
|
+
/* @__PURE__ */ jsx(
|
|
514
|
+
"button",
|
|
515
|
+
{
|
|
516
|
+
type: "button",
|
|
517
|
+
"aria-label": `Edit ${target.contentTypeLabel}: ${target.title}`,
|
|
518
|
+
className: "absolute right-2 top-2 z-20 rounded-full border border-white/80 bg-neutral-950/85 px-3 py-1 text-xs font-medium text-white opacity-0 shadow-sm transition focus:opacity-100 group-hover/linked-entry-edit:opacity-100",
|
|
519
|
+
onClick: (event) => {
|
|
520
|
+
event.preventDefault();
|
|
521
|
+
event.stopPropagation();
|
|
522
|
+
dispatchLinkedEntryEditEvent(target);
|
|
523
|
+
},
|
|
524
|
+
children: "Edit"
|
|
525
|
+
}
|
|
526
|
+
)
|
|
527
|
+
]
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
};
|
|
391
531
|
var ButtonWithEditorInterception = (props) => {
|
|
392
532
|
const { isEditingMode } = useEditor();
|
|
393
533
|
if (!isEditingMode) {
|
|
@@ -411,14 +551,599 @@ var editorRegistry = {
|
|
|
411
551
|
text: TextWithEditor,
|
|
412
552
|
richText: RichTextWithEditor,
|
|
413
553
|
button: ButtonWithEditorInterception,
|
|
414
|
-
media: requireClientRegistryComponent("media")
|
|
554
|
+
media: requireClientRegistryComponent("media"),
|
|
555
|
+
linkedEntryEditFrame: LinkedEntryEditFrame
|
|
415
556
|
};
|
|
416
557
|
|
|
558
|
+
// ../preview-next/src/client/preview/previewChromePlacement.ts
|
|
559
|
+
var PREVIEW_CHROME_EDGE_OFFSET_PX = 8;
|
|
560
|
+
var DEFAULT_PREVIEW_CHROME_FLOATING_PLACEMENT = Object.freeze({
|
|
561
|
+
kind: "anchor-top-right",
|
|
562
|
+
topPx: PREVIEW_CHROME_EDGE_OFFSET_PX,
|
|
563
|
+
rightPx: PREVIEW_CHROME_EDGE_OFFSET_PX
|
|
564
|
+
});
|
|
565
|
+
function headerClearanceFromPx(px) {
|
|
566
|
+
return Number.isFinite(px) && px > 0 ? { kind: "overlay", px: Math.ceil(px) } : { kind: "none" };
|
|
567
|
+
}
|
|
568
|
+
function findFirstEditableContentBlockIndex(blocks) {
|
|
569
|
+
const index = blocks.findIndex((block) => block.kind !== "block.site-header");
|
|
570
|
+
return index >= 0 ? index : null;
|
|
571
|
+
}
|
|
572
|
+
function blockReceivesHeaderClearance(blocks, blockIndex) {
|
|
573
|
+
return findFirstEditableContentBlockIndex(blocks) === blockIndex;
|
|
574
|
+
}
|
|
575
|
+
function planBlockToolbarPlacement(input) {
|
|
576
|
+
if (input.headerClearance.kind === "overlay" && blockReceivesHeaderClearance(input.blocks, input.blockIndex)) {
|
|
577
|
+
return {
|
|
578
|
+
kind: "anchor-top-right",
|
|
579
|
+
topPx: input.headerClearance.px + PREVIEW_CHROME_EDGE_OFFSET_PX,
|
|
580
|
+
rightPx: PREVIEW_CHROME_EDGE_OFFSET_PX
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
return {
|
|
584
|
+
kind: "anchor-top-right",
|
|
585
|
+
topPx: PREVIEW_CHROME_EDGE_OFFSET_PX,
|
|
586
|
+
rightPx: PREVIEW_CHROME_EDGE_OFFSET_PX
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
function planSiteChromeCustomizePlacement(input) {
|
|
590
|
+
if (input.surface === "header" && !isUsableAnchorBox(input.anchorBox)) {
|
|
591
|
+
return {
|
|
592
|
+
kind: "viewport-top-right",
|
|
593
|
+
topPx: PREVIEW_CHROME_EDGE_OFFSET_PX * 2,
|
|
594
|
+
rightPx: PREVIEW_CHROME_EDGE_OFFSET_PX * 2
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
return {
|
|
598
|
+
kind: "anchor-top-right",
|
|
599
|
+
topPx: PREVIEW_CHROME_EDGE_OFFSET_PX,
|
|
600
|
+
rightPx: PREVIEW_CHROME_EDGE_OFFSET_PX
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
function resolvePreviewChromeFloatingPosition(input) {
|
|
604
|
+
if (input.placement.kind === "viewport-top-right") {
|
|
605
|
+
return {
|
|
606
|
+
topPx: input.placement.topPx,
|
|
607
|
+
rightPx: input.placement.rightPx
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
const anchorBox = input.anchorBox;
|
|
611
|
+
if (!isUsableAnchorBox(anchorBox)) {
|
|
612
|
+
return {
|
|
613
|
+
topPx: input.placement.topPx,
|
|
614
|
+
rightPx: input.placement.rightPx
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
return {
|
|
618
|
+
topPx: Math.max(
|
|
619
|
+
PREVIEW_CHROME_EDGE_OFFSET_PX,
|
|
620
|
+
anchorBox.top - (input.containerTopEdgePx ?? 0) + input.placement.topPx
|
|
621
|
+
),
|
|
622
|
+
rightPx: Math.max(
|
|
623
|
+
PREVIEW_CHROME_EDGE_OFFSET_PX,
|
|
624
|
+
input.containerRightEdgePx - anchorBox.right + input.placement.rightPx
|
|
625
|
+
)
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
function isUsableAnchorBox(box) {
|
|
629
|
+
return Boolean(
|
|
630
|
+
box && Number.isFinite(box.top) && Number.isFinite(box.right) && Number.isFinite(box.bottom) && Number.isFinite(box.height) && box.height > 0
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
var PreviewChromeLayerContext = createContext(null);
|
|
634
|
+
function PreviewChromeLayerProvider({
|
|
635
|
+
children
|
|
636
|
+
}) {
|
|
637
|
+
const [portalTarget, setPortalTarget] = useState(null);
|
|
638
|
+
const listenersRef = useRef(/* @__PURE__ */ new Set());
|
|
639
|
+
const notifyLayout = useCallback(() => {
|
|
640
|
+
listenersRef.current.forEach((listener) => listener());
|
|
641
|
+
}, []);
|
|
642
|
+
const subscribeLayout = useCallback((listener) => {
|
|
643
|
+
listenersRef.current.add(listener);
|
|
644
|
+
return () => {
|
|
645
|
+
listenersRef.current.delete(listener);
|
|
646
|
+
};
|
|
647
|
+
}, []);
|
|
648
|
+
useEffect(() => {
|
|
649
|
+
let frame = null;
|
|
650
|
+
const scheduleNotify = () => {
|
|
651
|
+
if (frame !== null) return;
|
|
652
|
+
frame = window.requestAnimationFrame(() => {
|
|
653
|
+
frame = null;
|
|
654
|
+
notifyLayout();
|
|
655
|
+
});
|
|
656
|
+
};
|
|
657
|
+
const mutationObserver = typeof MutationObserver !== "undefined" ? new MutationObserver(scheduleNotify) : null;
|
|
658
|
+
mutationObserver?.observe(document.body, {
|
|
659
|
+
attributes: true,
|
|
660
|
+
childList: true,
|
|
661
|
+
subtree: true
|
|
662
|
+
});
|
|
663
|
+
window.addEventListener("resize", scheduleNotify);
|
|
664
|
+
window.addEventListener("scroll", scheduleNotify, true);
|
|
665
|
+
return () => {
|
|
666
|
+
if (frame !== null) {
|
|
667
|
+
window.cancelAnimationFrame(frame);
|
|
668
|
+
}
|
|
669
|
+
mutationObserver?.disconnect();
|
|
670
|
+
window.removeEventListener("resize", scheduleNotify);
|
|
671
|
+
window.removeEventListener("scroll", scheduleNotify, true);
|
|
672
|
+
};
|
|
673
|
+
}, [notifyLayout]);
|
|
674
|
+
const value = useMemo(
|
|
675
|
+
() => ({ portalTarget, subscribeLayout }),
|
|
676
|
+
[portalTarget, subscribeLayout]
|
|
677
|
+
);
|
|
678
|
+
return /* @__PURE__ */ jsxs(PreviewChromeLayerContext.Provider, { value, children: [
|
|
679
|
+
children,
|
|
680
|
+
/* @__PURE__ */ jsx(
|
|
681
|
+
"div",
|
|
682
|
+
{
|
|
683
|
+
ref: setPortalTarget,
|
|
684
|
+
className: "pointer-events-none fixed inset-0 z-[70]",
|
|
685
|
+
"data-preview-chrome-layer": ""
|
|
686
|
+
}
|
|
687
|
+
)
|
|
688
|
+
] });
|
|
689
|
+
}
|
|
690
|
+
function usePreviewChromeLayerOptional() {
|
|
691
|
+
return useContext(PreviewChromeLayerContext);
|
|
692
|
+
}
|
|
693
|
+
function PreviewChromeFloatingControl({
|
|
694
|
+
anchorSelector,
|
|
695
|
+
placement,
|
|
696
|
+
fallbackClassName,
|
|
697
|
+
fallbackStyle,
|
|
698
|
+
portalClassName = "absolute z-[70] flex gap-1 transition",
|
|
699
|
+
forceVisible = false,
|
|
700
|
+
children
|
|
701
|
+
}) {
|
|
702
|
+
const layer = usePreviewChromeLayerOptional();
|
|
703
|
+
const probeRef = useRef(null);
|
|
704
|
+
const anchorElementRef = useRef(null);
|
|
705
|
+
const [controlElement, setControlElement] = useState(
|
|
706
|
+
null
|
|
707
|
+
);
|
|
708
|
+
const [anchorElement, setAnchorElement] = useState(null);
|
|
709
|
+
const [anchorBox, setAnchorBox] = useState(
|
|
710
|
+
null
|
|
711
|
+
);
|
|
712
|
+
const [themeCustomProperties, setThemeCustomProperties] = useState({});
|
|
713
|
+
const [isActive, setIsActive] = useState(false);
|
|
714
|
+
const hoverStateRef = useRef({ anchor: false, control: false });
|
|
715
|
+
useEffect(() => {
|
|
716
|
+
if (!layer?.portalTarget) return;
|
|
717
|
+
let resizeObserver = null;
|
|
718
|
+
const readAnchor = () => probeRef.current?.closest(anchorSelector);
|
|
719
|
+
const update = () => {
|
|
720
|
+
const anchor = readAnchor();
|
|
721
|
+
if (anchor !== anchorElementRef.current) {
|
|
722
|
+
resizeObserver?.disconnect();
|
|
723
|
+
resizeObserver = null;
|
|
724
|
+
anchorElementRef.current = anchor;
|
|
725
|
+
setAnchorElement(anchor);
|
|
726
|
+
if (anchor && typeof ResizeObserver !== "undefined") {
|
|
727
|
+
resizeObserver = new ResizeObserver(update);
|
|
728
|
+
resizeObserver.observe(anchor);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
if (!anchor) {
|
|
732
|
+
setAnchorBox(null);
|
|
733
|
+
setThemeCustomProperties({});
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
const rect = anchor.getBoundingClientRect();
|
|
737
|
+
setThemeCustomProperties(readThemeCustomProperties(anchor));
|
|
738
|
+
setAnchorBox({
|
|
739
|
+
top: rect.top,
|
|
740
|
+
right: rect.right,
|
|
741
|
+
bottom: rect.bottom,
|
|
742
|
+
height: rect.height
|
|
743
|
+
});
|
|
744
|
+
};
|
|
745
|
+
update();
|
|
746
|
+
const unsubscribe = layer.subscribeLayout(update);
|
|
747
|
+
return () => {
|
|
748
|
+
resizeObserver?.disconnect();
|
|
749
|
+
anchorElementRef.current = null;
|
|
750
|
+
unsubscribe();
|
|
751
|
+
};
|
|
752
|
+
}, [anchorSelector, layer]);
|
|
753
|
+
useEffect(() => {
|
|
754
|
+
if (!anchorElement || !controlElement) return;
|
|
755
|
+
hoverStateRef.current = { anchor: false, control: false };
|
|
756
|
+
const show = (event) => {
|
|
757
|
+
updatePreviewChromeHoverState(
|
|
758
|
+
hoverStateRef.current,
|
|
759
|
+
event.currentTarget,
|
|
760
|
+
anchorElement,
|
|
761
|
+
controlElement,
|
|
762
|
+
true
|
|
763
|
+
);
|
|
764
|
+
setIsActive(true);
|
|
765
|
+
};
|
|
766
|
+
const hideIfFocusLeft = (event) => {
|
|
767
|
+
updatePreviewChromeHoverState(
|
|
768
|
+
hoverStateRef.current,
|
|
769
|
+
event.currentTarget,
|
|
770
|
+
anchorElement,
|
|
771
|
+
controlElement,
|
|
772
|
+
false
|
|
773
|
+
);
|
|
774
|
+
window.setTimeout(() => {
|
|
775
|
+
const active = document.activeElement;
|
|
776
|
+
const hoverState = hoverStateRef.current;
|
|
777
|
+
const nextIsActive = Boolean(
|
|
778
|
+
hoverState.anchor || hoverState.control || active && (anchorElement.contains(active) || controlElement.contains(active))
|
|
779
|
+
);
|
|
780
|
+
setIsActive(nextIsActive);
|
|
781
|
+
}, 0);
|
|
782
|
+
};
|
|
783
|
+
anchorElement.addEventListener("mouseenter", show);
|
|
784
|
+
anchorElement.addEventListener("mouseleave", hideIfFocusLeft);
|
|
785
|
+
anchorElement.addEventListener("focusin", show);
|
|
786
|
+
anchorElement.addEventListener("focusout", hideIfFocusLeft);
|
|
787
|
+
controlElement.addEventListener("mouseenter", show);
|
|
788
|
+
controlElement.addEventListener("mouseleave", hideIfFocusLeft);
|
|
789
|
+
controlElement.addEventListener("focusin", show);
|
|
790
|
+
controlElement.addEventListener("focusout", hideIfFocusLeft);
|
|
791
|
+
return () => {
|
|
792
|
+
anchorElement.removeEventListener("mouseenter", show);
|
|
793
|
+
anchorElement.removeEventListener("mouseleave", hideIfFocusLeft);
|
|
794
|
+
anchorElement.removeEventListener("focusin", show);
|
|
795
|
+
anchorElement.removeEventListener("focusout", hideIfFocusLeft);
|
|
796
|
+
controlElement.removeEventListener("mouseenter", show);
|
|
797
|
+
controlElement.removeEventListener("mouseleave", hideIfFocusLeft);
|
|
798
|
+
controlElement.removeEventListener("focusin", show);
|
|
799
|
+
controlElement.removeEventListener("focusout", hideIfFocusLeft);
|
|
800
|
+
};
|
|
801
|
+
}, [anchorElement, controlElement]);
|
|
802
|
+
if (!layer?.portalTarget) {
|
|
803
|
+
return /* @__PURE__ */ jsx("div", { className: fallbackClassName, style: fallbackStyle, children });
|
|
804
|
+
}
|
|
805
|
+
const resolvedPlacement = typeof placement === "function" ? placement(anchorBox) : placement;
|
|
806
|
+
const position = resolvePreviewChromeFloatingPosition({
|
|
807
|
+
anchorBox,
|
|
808
|
+
containerTopEdgePx: resolvePortalTopEdgePx(layer.portalTarget),
|
|
809
|
+
containerRightEdgePx: resolvePortalRightEdgePx(layer.portalTarget),
|
|
810
|
+
placement: resolvedPlacement
|
|
811
|
+
});
|
|
812
|
+
const isVisible = forceVisible || isActive;
|
|
813
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
814
|
+
/* @__PURE__ */ jsx("span", { ref: probeRef, "aria-hidden": "true", style: { display: "contents" } }),
|
|
815
|
+
createPortal(
|
|
816
|
+
/* @__PURE__ */ jsx(
|
|
817
|
+
"div",
|
|
818
|
+
{
|
|
819
|
+
ref: setControlElement,
|
|
820
|
+
className: joinClassNames(
|
|
821
|
+
portalClassName,
|
|
822
|
+
isVisible ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"
|
|
823
|
+
),
|
|
824
|
+
style: {
|
|
825
|
+
...themeCustomProperties,
|
|
826
|
+
top: position.topPx,
|
|
827
|
+
right: position.rightPx
|
|
828
|
+
},
|
|
829
|
+
children
|
|
830
|
+
}
|
|
831
|
+
),
|
|
832
|
+
layer.portalTarget
|
|
833
|
+
)
|
|
834
|
+
] });
|
|
835
|
+
}
|
|
836
|
+
function readThemeCustomProperties(element) {
|
|
837
|
+
if (typeof window === "undefined") return {};
|
|
838
|
+
const computedStyle = window.getComputedStyle(element);
|
|
839
|
+
const properties = {};
|
|
840
|
+
copyThemeCustomProperties(computedStyle, properties);
|
|
841
|
+
for (let current = element; current; current = current.parentElement) {
|
|
842
|
+
copyThemeCustomProperties(current.style, properties);
|
|
843
|
+
}
|
|
844
|
+
return properties;
|
|
845
|
+
}
|
|
846
|
+
function copyThemeCustomProperties(style, target) {
|
|
847
|
+
for (let index = 0; index < style.length; index += 1) {
|
|
848
|
+
const propertyName = style.item(index);
|
|
849
|
+
if (!propertyName.startsWith("--tb-")) continue;
|
|
850
|
+
const propertyValue = style.getPropertyValue(propertyName).trim();
|
|
851
|
+
if (propertyValue.length > 0 && target[propertyName] === void 0) {
|
|
852
|
+
target[propertyName] = propertyValue;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function resolvePortalRightEdgePx(portalTarget) {
|
|
857
|
+
const rect = portalTarget.getBoundingClientRect();
|
|
858
|
+
if (Number.isFinite(rect.right) && rect.right > 0) {
|
|
859
|
+
return rect.right;
|
|
860
|
+
}
|
|
861
|
+
if (typeof window === "undefined") {
|
|
862
|
+
return 0;
|
|
863
|
+
}
|
|
864
|
+
return window.innerWidth;
|
|
865
|
+
}
|
|
866
|
+
function resolvePortalTopEdgePx(portalTarget) {
|
|
867
|
+
const rect = portalTarget.getBoundingClientRect();
|
|
868
|
+
return Number.isFinite(rect.top) ? rect.top : 0;
|
|
869
|
+
}
|
|
870
|
+
function joinClassNames(...values) {
|
|
871
|
+
const className = values.filter(Boolean).join(" ");
|
|
872
|
+
return className.length > 0 ? className : void 0;
|
|
873
|
+
}
|
|
874
|
+
function updatePreviewChromeHoverState(hoverState, currentTarget, anchorElement, controlElement, value) {
|
|
875
|
+
if (currentTarget === anchorElement) {
|
|
876
|
+
hoverState.anchor = value;
|
|
877
|
+
} else if (currentTarget === controlElement) {
|
|
878
|
+
hoverState.control = value;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
function useDialogFocusTrap(input) {
|
|
882
|
+
const { open, onClose } = input;
|
|
883
|
+
const dialogRef = useRef(null);
|
|
884
|
+
const initialFocusRef = useRef(null);
|
|
885
|
+
const returnFocusRef = useRef(null);
|
|
886
|
+
useEffect(() => {
|
|
887
|
+
if (open) {
|
|
888
|
+
initialFocusRef.current?.focus();
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
const returnFocusTarget = returnFocusRef.current;
|
|
892
|
+
returnFocusRef.current = null;
|
|
893
|
+
returnFocusTarget?.focus();
|
|
894
|
+
}, [open]);
|
|
895
|
+
const registerInitialFocus = useCallback((node) => {
|
|
896
|
+
initialFocusRef.current = node;
|
|
897
|
+
}, []);
|
|
898
|
+
const setReturnFocusTarget = useCallback((node) => {
|
|
899
|
+
returnFocusRef.current = node;
|
|
900
|
+
}, []);
|
|
901
|
+
const handleDialogKeyDown = useCallback(
|
|
902
|
+
(event) => {
|
|
903
|
+
if (event.key === "Escape") {
|
|
904
|
+
event.preventDefault();
|
|
905
|
+
onClose();
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
if (event.key !== "Tab") return;
|
|
909
|
+
const focusableElements = focusableElementsIn(dialogRef.current);
|
|
910
|
+
if (focusableElements.length === 0) {
|
|
911
|
+
event.preventDefault();
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
const firstElement = focusableElements[0];
|
|
915
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
916
|
+
if (!firstElement || !lastElement) return;
|
|
917
|
+
if (event.shiftKey && document.activeElement === firstElement) {
|
|
918
|
+
event.preventDefault();
|
|
919
|
+
lastElement.focus();
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
if (!event.shiftKey && document.activeElement === lastElement) {
|
|
923
|
+
event.preventDefault();
|
|
924
|
+
firstElement.focus();
|
|
925
|
+
}
|
|
926
|
+
},
|
|
927
|
+
[onClose]
|
|
928
|
+
);
|
|
929
|
+
return {
|
|
930
|
+
dialogRef,
|
|
931
|
+
registerInitialFocus,
|
|
932
|
+
setReturnFocusTarget,
|
|
933
|
+
handleDialogKeyDown
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
function focusableElementsIn(root) {
|
|
937
|
+
if (!root) return [];
|
|
938
|
+
return Array.from(
|
|
939
|
+
root.querySelectorAll(
|
|
940
|
+
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
941
|
+
)
|
|
942
|
+
).filter((element) => !element.hasAttribute("disabled") && element.getAttribute("aria-hidden") !== "true");
|
|
943
|
+
}
|
|
944
|
+
|
|
417
945
|
// ../preview-next/src/client/preview/previewCustomizeControlStyles.ts
|
|
418
946
|
var previewCustomizePillButtonClassName = "rounded-full bg-black/80 px-2.5 py-1 text-xs text-white shadow hover:bg-black";
|
|
947
|
+
function useCustomizePopoverController() {
|
|
948
|
+
const panelId = useId();
|
|
949
|
+
const descriptionId = `${panelId}-description`;
|
|
950
|
+
const [open, setOpen] = useState(false);
|
|
951
|
+
const buttonRef = useRef(null);
|
|
952
|
+
const close = useCallback(() => {
|
|
953
|
+
setOpen(false);
|
|
954
|
+
}, []);
|
|
955
|
+
const {
|
|
956
|
+
dialogRef,
|
|
957
|
+
registerInitialFocus,
|
|
958
|
+
setReturnFocusTarget,
|
|
959
|
+
handleDialogKeyDown
|
|
960
|
+
} = useDialogFocusTrap({
|
|
961
|
+
open,
|
|
962
|
+
onClose: close
|
|
963
|
+
});
|
|
964
|
+
const toggle = useCallback(
|
|
965
|
+
(event) => {
|
|
966
|
+
event.preventDefault();
|
|
967
|
+
event.stopPropagation();
|
|
968
|
+
if (!open) {
|
|
969
|
+
setReturnFocusTarget(
|
|
970
|
+
event.currentTarget instanceof HTMLElement ? event.currentTarget : buttonRef.current
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
setOpen((current) => !current);
|
|
974
|
+
},
|
|
975
|
+
[open, setReturnFocusTarget]
|
|
976
|
+
);
|
|
977
|
+
return {
|
|
978
|
+
open,
|
|
979
|
+
close,
|
|
980
|
+
toggle,
|
|
981
|
+
buttonRef,
|
|
982
|
+
panelId,
|
|
983
|
+
descriptionId,
|
|
984
|
+
dialogRef,
|
|
985
|
+
registerInitialFocus,
|
|
986
|
+
handleDialogKeyDown
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
function CustomizePillButton({
|
|
990
|
+
buttonRef,
|
|
991
|
+
ariaLabel,
|
|
992
|
+
open,
|
|
993
|
+
controlsId,
|
|
994
|
+
onClick,
|
|
995
|
+
disabled = false
|
|
996
|
+
}) {
|
|
997
|
+
return /* @__PURE__ */ jsx(
|
|
998
|
+
"button",
|
|
999
|
+
{
|
|
1000
|
+
ref: buttonRef,
|
|
1001
|
+
type: "button",
|
|
1002
|
+
onClick,
|
|
1003
|
+
className: previewCustomizePillButtonClassName,
|
|
1004
|
+
"aria-label": ariaLabel,
|
|
1005
|
+
"aria-expanded": open,
|
|
1006
|
+
"aria-haspopup": "dialog",
|
|
1007
|
+
"aria-controls": open ? controlsId : void 0,
|
|
1008
|
+
disabled,
|
|
1009
|
+
children: "Customize"
|
|
1010
|
+
}
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
function CustomizePopoverShell({
|
|
1014
|
+
panelId,
|
|
1015
|
+
descriptionId,
|
|
1016
|
+
dialogLabel,
|
|
1017
|
+
eyebrow,
|
|
1018
|
+
title,
|
|
1019
|
+
dialogRef,
|
|
1020
|
+
closeButtonRef,
|
|
1021
|
+
onClose,
|
|
1022
|
+
onKeyDown,
|
|
1023
|
+
spacing = "normal",
|
|
1024
|
+
children
|
|
1025
|
+
}) {
|
|
1026
|
+
return /* @__PURE__ */ jsxs(
|
|
1027
|
+
"div",
|
|
1028
|
+
{
|
|
1029
|
+
id: panelId,
|
|
1030
|
+
className: "builder-dashboard-chrome-theme fixed inset-x-3 bottom-[calc(var(--builder-editor-chrome-offset,0px)+1rem)] z-[70] rounded-lg border bg-background p-3 text-foreground shadow-xl sm:absolute sm:inset-x-auto sm:bottom-auto sm:right-0 sm:top-9 sm:w-72",
|
|
1031
|
+
role: "dialog",
|
|
1032
|
+
"aria-modal": "true",
|
|
1033
|
+
"aria-label": dialogLabel,
|
|
1034
|
+
"aria-describedby": descriptionId,
|
|
1035
|
+
ref: dialogRef,
|
|
1036
|
+
onKeyDown,
|
|
1037
|
+
onClick: (event) => event.stopPropagation(),
|
|
1038
|
+
children: [
|
|
1039
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-start justify-between gap-3", children: [
|
|
1040
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1041
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium uppercase text-muted-foreground", children: eyebrow }),
|
|
1042
|
+
/* @__PURE__ */ jsx("div", { id: descriptionId, className: "text-sm font-semibold", children: title })
|
|
1043
|
+
] }),
|
|
1044
|
+
/* @__PURE__ */ jsx(
|
|
1045
|
+
"button",
|
|
1046
|
+
{
|
|
1047
|
+
ref: closeButtonRef,
|
|
1048
|
+
type: "button",
|
|
1049
|
+
className: "rounded-full px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
1050
|
+
onClick: (event) => {
|
|
1051
|
+
event.preventDefault();
|
|
1052
|
+
event.stopPropagation();
|
|
1053
|
+
onClose();
|
|
1054
|
+
},
|
|
1055
|
+
children: "Close"
|
|
1056
|
+
}
|
|
1057
|
+
)
|
|
1058
|
+
] }),
|
|
1059
|
+
/* @__PURE__ */ jsx("div", { className: spacing === "compact" ? "space-y-2" : "space-y-3", children })
|
|
1060
|
+
]
|
|
1061
|
+
}
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
function CustomizeCycleRow({
|
|
1065
|
+
label,
|
|
1066
|
+
valueLabel,
|
|
1067
|
+
previousLabel,
|
|
1068
|
+
nextLabel,
|
|
1069
|
+
availability,
|
|
1070
|
+
onPrevious,
|
|
1071
|
+
onNext
|
|
1072
|
+
}) {
|
|
1073
|
+
const reasonId = useId();
|
|
1074
|
+
const disabled = availability.kind === "unavailable";
|
|
1075
|
+
const unavailableReason = availability.kind === "unavailable" ? cycleUnavailableReasonLabel(availability.reason) : null;
|
|
1076
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1077
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1078
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: label }),
|
|
1079
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: valueLabel })
|
|
1080
|
+
] }),
|
|
1081
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center overflow-hidden rounded-full border bg-background", children: [
|
|
1082
|
+
unavailableReason ? /* @__PURE__ */ jsx("span", { id: reasonId, className: "sr-only", children: unavailableReason }) : null,
|
|
1083
|
+
/* @__PURE__ */ jsx(
|
|
1084
|
+
"button",
|
|
1085
|
+
{
|
|
1086
|
+
type: "button",
|
|
1087
|
+
onClick: (event) => {
|
|
1088
|
+
event.preventDefault();
|
|
1089
|
+
event.stopPropagation();
|
|
1090
|
+
onPrevious();
|
|
1091
|
+
},
|
|
1092
|
+
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1093
|
+
"aria-label": previousLabel,
|
|
1094
|
+
"aria-describedby": unavailableReason ? reasonId : void 0,
|
|
1095
|
+
title: unavailableReason ?? void 0,
|
|
1096
|
+
disabled,
|
|
1097
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
1098
|
+
}
|
|
1099
|
+
),
|
|
1100
|
+
/* @__PURE__ */ jsx(
|
|
1101
|
+
"button",
|
|
1102
|
+
{
|
|
1103
|
+
type: "button",
|
|
1104
|
+
onClick: (event) => {
|
|
1105
|
+
event.preventDefault();
|
|
1106
|
+
event.stopPropagation();
|
|
1107
|
+
onNext();
|
|
1108
|
+
},
|
|
1109
|
+
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1110
|
+
"aria-label": nextLabel,
|
|
1111
|
+
"aria-describedby": unavailableReason ? reasonId : void 0,
|
|
1112
|
+
title: unavailableReason ?? void 0,
|
|
1113
|
+
disabled,
|
|
1114
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
1115
|
+
}
|
|
1116
|
+
)
|
|
1117
|
+
] })
|
|
1118
|
+
] });
|
|
1119
|
+
}
|
|
1120
|
+
function cycleAvailability(input) {
|
|
1121
|
+
if (input.kind === "available") {
|
|
1122
|
+
return input;
|
|
1123
|
+
}
|
|
1124
|
+
return { kind: "unavailable", reason: input.kind };
|
|
1125
|
+
}
|
|
1126
|
+
function cycleUnavailableReasonLabel(reason) {
|
|
1127
|
+
if (reason === "preview-only") {
|
|
1128
|
+
return "Preview-only users cannot change this control.";
|
|
1129
|
+
}
|
|
1130
|
+
if (reason === "single-option") {
|
|
1131
|
+
return "There are no other options to cycle to.";
|
|
1132
|
+
}
|
|
1133
|
+
return reason;
|
|
1134
|
+
}
|
|
1135
|
+
function cycleAvailabilityFromFlags(input) {
|
|
1136
|
+
if (!input.applyAllowed) {
|
|
1137
|
+
return { kind: "unavailable", reason: "preview-only" };
|
|
1138
|
+
}
|
|
1139
|
+
if (!input.canCycle) {
|
|
1140
|
+
return { kind: "unavailable", reason: "single-option" };
|
|
1141
|
+
}
|
|
1142
|
+
return { kind: "available" };
|
|
1143
|
+
}
|
|
419
1144
|
|
|
420
1145
|
// ../preview-next/src/client/blocks/isRecord.ts
|
|
421
|
-
function
|
|
1146
|
+
function isRecord4(value) {
|
|
422
1147
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
423
1148
|
}
|
|
424
1149
|
|
|
@@ -484,35 +1209,18 @@ function setPageDesignBlockBackground(input) {
|
|
|
484
1209
|
});
|
|
485
1210
|
const plan = planBackgroundOverride(current, capability, input.override);
|
|
486
1211
|
if (plan.kind !== "apply") return null;
|
|
1212
|
+
const imageAsset = plan.override.kind === "image" ? imagePoolAssetForMediaId(input.imagePool, plan.override.mediaId) : void 0;
|
|
487
1213
|
return {
|
|
488
1214
|
kind: "set-background",
|
|
489
1215
|
blockId: input.block.blockId,
|
|
490
1216
|
override: plan.override,
|
|
491
1217
|
fromOverride: plan.fromOverride,
|
|
492
|
-
baseContentId: input.block.contentRevision?.contentId ?? null
|
|
1218
|
+
baseContentId: input.block.contentRevision?.contentId ?? null,
|
|
1219
|
+
...imageAsset ? { imageAsset } : {}
|
|
493
1220
|
};
|
|
494
1221
|
}
|
|
495
|
-
function
|
|
496
|
-
|
|
497
|
-
const breakIds = boundary.availableBreaks.map((option) => option.id);
|
|
498
|
-
const values = [null, ...breakIds];
|
|
499
|
-
const currentIndex = cycleChoiceIndex(boundary.breakChoice, values, direction);
|
|
500
|
-
if (currentIndex === -1) return null;
|
|
501
|
-
const nextIndex = direction === "next" ? (currentIndex + 1) % values.length : currentIndex === 0 ? values.length - 1 : currentIndex - 1;
|
|
502
|
-
const boundaryOptionId = values[nextIndex];
|
|
503
|
-
if (boundaryOptionId === void 0) return null;
|
|
504
|
-
return {
|
|
505
|
-
...boundaryOptionId ? {
|
|
506
|
-
kind: "set-boundary",
|
|
507
|
-
previousBlockId: boundary.previousBlockId,
|
|
508
|
-
nextBlockId: boundary.nextBlockId,
|
|
509
|
-
boundaryOptionId
|
|
510
|
-
} : {
|
|
511
|
-
kind: "reset-boundary",
|
|
512
|
-
previousBlockId: boundary.previousBlockId,
|
|
513
|
-
nextBlockId: boundary.nextBlockId
|
|
514
|
-
}
|
|
515
|
-
};
|
|
1222
|
+
function imagePoolAssetForMediaId(imagePool, mediaId) {
|
|
1223
|
+
return imagePool?.find((item) => item.mediaId === mediaId)?.mediaAsset;
|
|
516
1224
|
}
|
|
517
1225
|
function cycleChoiceIndex(choice, values, direction) {
|
|
518
1226
|
if (choice.kind === "user-pinned" && choice.status === "supported") {
|
|
@@ -543,68 +1251,37 @@ function previewCustomizeFacetControlsFor(blockKind, content, designBlock) {
|
|
|
543
1251
|
};
|
|
544
1252
|
});
|
|
545
1253
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
573
|
-
if (event.key !== "Tab") return;
|
|
574
|
-
const focusableElements = focusableElementsIn(dialogRef.current);
|
|
575
|
-
if (focusableElements.length === 0) {
|
|
576
|
-
event.preventDefault();
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
|
-
const firstElement = focusableElements[0];
|
|
580
|
-
const lastElement = focusableElements[focusableElements.length - 1];
|
|
581
|
-
if (!firstElement || !lastElement) return;
|
|
582
|
-
if (event.shiftKey && document.activeElement === firstElement) {
|
|
583
|
-
event.preventDefault();
|
|
584
|
-
lastElement.focus();
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
if (!event.shiftKey && document.activeElement === lastElement) {
|
|
588
|
-
event.preventDefault();
|
|
589
|
-
firstElement.focus();
|
|
590
|
-
}
|
|
591
|
-
},
|
|
592
|
-
[onClose]
|
|
1254
|
+
|
|
1255
|
+
// ../preview-next/src/client/blocks/blockCustomizePopoverRows.ts
|
|
1256
|
+
function buildBlockCustomizeBuiltinRows({
|
|
1257
|
+
designBlock,
|
|
1258
|
+
facetControls,
|
|
1259
|
+
hasLayoutControls,
|
|
1260
|
+
hasLookControls,
|
|
1261
|
+
hasBackgroundControls
|
|
1262
|
+
}) {
|
|
1263
|
+
const rows = [];
|
|
1264
|
+
if (designBlock?.layout && hasLayoutControls) {
|
|
1265
|
+
rows.push({ kind: "variant", block: designBlock });
|
|
1266
|
+
}
|
|
1267
|
+
if (designBlock?.layout?.status === "unsupported") {
|
|
1268
|
+
rows.push({ kind: "unsupported-variant-warning" });
|
|
1269
|
+
}
|
|
1270
|
+
if (designBlock && hasLookControls) {
|
|
1271
|
+
rows.push({ kind: "look", block: designBlock });
|
|
1272
|
+
}
|
|
1273
|
+
if (hasBackgroundControls) {
|
|
1274
|
+
rows.push({ kind: "background" });
|
|
1275
|
+
}
|
|
1276
|
+
rows.push(
|
|
1277
|
+
...facetControls.map(
|
|
1278
|
+
(control) => ({ kind: "facet", control })
|
|
1279
|
+
)
|
|
593
1280
|
);
|
|
594
|
-
return
|
|
595
|
-
dialogRef,
|
|
596
|
-
registerInitialFocus,
|
|
597
|
-
setReturnFocusTarget,
|
|
598
|
-
handleDialogKeyDown
|
|
599
|
-
};
|
|
1281
|
+
return rows;
|
|
600
1282
|
}
|
|
601
|
-
function
|
|
602
|
-
|
|
603
|
-
return Array.from(
|
|
604
|
-
root.querySelectorAll(
|
|
605
|
-
'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
606
|
-
)
|
|
607
|
-
).filter((element) => !element.hasAttribute("disabled") && element.getAttribute("aria-hidden") !== "true");
|
|
1283
|
+
function blockCustomizeBuiltinRowBudget(rows) {
|
|
1284
|
+
return rows.length;
|
|
608
1285
|
}
|
|
609
1286
|
function isUnknownArray(value) {
|
|
610
1287
|
return Array.isArray(value);
|
|
@@ -614,7 +1291,7 @@ function BlockToolbar({
|
|
|
614
1291
|
blockKind,
|
|
615
1292
|
content,
|
|
616
1293
|
theme = null,
|
|
617
|
-
|
|
1294
|
+
placement = DEFAULT_PREVIEW_CHROME_FLOATING_PLACEMENT
|
|
618
1295
|
}) {
|
|
619
1296
|
const uiStore = useEditorUiStoreInstance();
|
|
620
1297
|
const editorBlockId = useMemo(() => unsafeAsEditorBlockId(blockId), [blockId]);
|
|
@@ -622,41 +1299,25 @@ function BlockToolbar({
|
|
|
622
1299
|
(state) => state.drafts.getCurrentValues(editorBlockId)
|
|
623
1300
|
);
|
|
624
1301
|
const customizeContent = useMemo(
|
|
625
|
-
() =>
|
|
1302
|
+
() => isRecord4(draftContent) ? draftContent : content,
|
|
626
1303
|
[content, draftContent]
|
|
627
1304
|
);
|
|
628
1305
|
const customizeSelection = usePreviewBlockCustomizeSelectionOptional();
|
|
629
|
-
const
|
|
630
|
-
const customizeDescriptionId = `${customizePanelId}-description`;
|
|
1306
|
+
const popover = useCustomizePopoverController();
|
|
631
1307
|
const focusTarget = useMemo(
|
|
632
1308
|
() => computeDefaultFocus(blockKind, customizeContent),
|
|
633
1309
|
[blockKind, customizeContent]
|
|
634
1310
|
);
|
|
635
|
-
const [customizeOpen, setCustomizeOpen] = useState(false);
|
|
636
1311
|
const [backgroundChooserOpen, setBackgroundChooserOpen] = useState(false);
|
|
637
1312
|
const [backgroundColorPalette, setBackgroundColorPalette] = useState(null);
|
|
638
|
-
const customizeButtonRef = useRef(null);
|
|
639
1313
|
const {
|
|
640
1314
|
state: pageDesignState,
|
|
641
1315
|
applyAction: applyPageDesignAction,
|
|
642
|
-
isHistoryPending,
|
|
643
1316
|
historyFailure,
|
|
644
1317
|
backgroundImagePool = [],
|
|
645
1318
|
backgroundImagePoolStatus = "idle",
|
|
646
1319
|
loadBackgroundImagePool = async () => []
|
|
647
1320
|
} = usePreviewPageDesignEditorState();
|
|
648
|
-
const closeCustomize = useCallback(() => {
|
|
649
|
-
setCustomizeOpen(false);
|
|
650
|
-
}, []);
|
|
651
|
-
const {
|
|
652
|
-
dialogRef: customizeDialogRef,
|
|
653
|
-
registerInitialFocus: registerCustomizeInitialFocus,
|
|
654
|
-
setReturnFocusTarget: setCustomizeReturnFocusTarget,
|
|
655
|
-
handleDialogKeyDown: handleCustomizeDialogKeyDown
|
|
656
|
-
} = useDialogFocusTrap({
|
|
657
|
-
open: customizeOpen,
|
|
658
|
-
onClose: closeCustomize
|
|
659
|
-
});
|
|
660
1321
|
const designBlock = useMemo(() => {
|
|
661
1322
|
if (pageDesignState.kind !== "loaded") return null;
|
|
662
1323
|
return pageDesignState.editorModel.blocks.find(
|
|
@@ -669,11 +1330,12 @@ function BlockToolbar({
|
|
|
669
1330
|
const hasLookControls = Boolean(
|
|
670
1331
|
designBlock && designBlock.availableLooks.length > 0
|
|
671
1332
|
);
|
|
672
|
-
const canCycleLook = Boolean(
|
|
673
|
-
designBlock && designBlock.availableLooks.length > 1
|
|
674
|
-
);
|
|
675
1333
|
const facetControls = useMemo(
|
|
676
|
-
() => previewCustomizeFacetControlsFor(
|
|
1334
|
+
() => previewCustomizeFacetControlsFor(
|
|
1335
|
+
blockKind,
|
|
1336
|
+
customizeContent,
|
|
1337
|
+
designBlock
|
|
1338
|
+
),
|
|
677
1339
|
[blockKind, customizeContent, designBlock]
|
|
678
1340
|
);
|
|
679
1341
|
const hasFacetControls = facetControls.length > 0;
|
|
@@ -690,6 +1352,26 @@ function BlockToolbar({
|
|
|
690
1352
|
),
|
|
691
1353
|
[backgroundImagePool, currentBackground]
|
|
692
1354
|
);
|
|
1355
|
+
const backgroundCycleImagePool = useMemo(
|
|
1356
|
+
() => {
|
|
1357
|
+
if (currentBackground.kind === "supported" && currentBackground.override.kind === "image") {
|
|
1358
|
+
const currentOverride = currentBackground.override;
|
|
1359
|
+
const currentExistsInPool = backgroundImagePool.some(
|
|
1360
|
+
(item) => item.mediaId === currentOverride.mediaId
|
|
1361
|
+
);
|
|
1362
|
+
if (!currentExistsInPool) {
|
|
1363
|
+
return rankBackgroundImagePoolItems(
|
|
1364
|
+
dedupeBackgroundImagePool([
|
|
1365
|
+
...imagePoolForOverride(currentOverride),
|
|
1366
|
+
...backgroundImagePool
|
|
1367
|
+
])
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return rankBackgroundImagePoolItems(backgroundImagePool);
|
|
1372
|
+
},
|
|
1373
|
+
[backgroundImagePool, currentBackground]
|
|
1374
|
+
);
|
|
693
1375
|
const backgroundCapability = useMemo(
|
|
694
1376
|
() => designBlock ? resolveBackgroundCapability({
|
|
695
1377
|
block: designBlock,
|
|
@@ -698,14 +1380,34 @@ function BlockToolbar({
|
|
|
698
1380
|
}) : null,
|
|
699
1381
|
[backgroundColorPalette, designBlock, mergedBackgroundImagePool]
|
|
700
1382
|
);
|
|
1383
|
+
const backgroundTransitionCapability = useMemo(
|
|
1384
|
+
() => backgroundCapability ? { ...backgroundCapability, imagePool: backgroundCycleImagePool } : null,
|
|
1385
|
+
[backgroundCapability, backgroundCycleImagePool]
|
|
1386
|
+
);
|
|
701
1387
|
const enabledBackgroundModeList = useMemo(
|
|
702
1388
|
() => backgroundCapability ? enabledBackgroundModes(backgroundCapability) : [],
|
|
703
1389
|
[backgroundCapability]
|
|
704
1390
|
);
|
|
705
1391
|
const hasBackgroundControls = currentBackground.kind === "supported" && enabledBackgroundModeList.length > 1;
|
|
706
|
-
const
|
|
1392
|
+
const builtInCustomizeRows = useMemo(
|
|
1393
|
+
() => buildBlockCustomizeBuiltinRows({
|
|
1394
|
+
designBlock,
|
|
1395
|
+
facetControls,
|
|
1396
|
+
hasLayoutControls,
|
|
1397
|
+
hasLookControls,
|
|
1398
|
+
hasBackgroundControls
|
|
1399
|
+
}),
|
|
1400
|
+
[
|
|
1401
|
+
designBlock,
|
|
1402
|
+
facetControls,
|
|
1403
|
+
hasBackgroundControls,
|
|
1404
|
+
hasLayoutControls,
|
|
1405
|
+
hasLookControls
|
|
1406
|
+
]
|
|
1407
|
+
);
|
|
1408
|
+
const builtInCustomizeRowCount = blockCustomizeBuiltinRowBudget(builtInCustomizeRows);
|
|
707
1409
|
const manifestCustomize = useBlockCustomizeControls({
|
|
708
|
-
blockId,
|
|
1410
|
+
blockId: editorBlockId,
|
|
709
1411
|
blockKind,
|
|
710
1412
|
content: customizeContent,
|
|
711
1413
|
uiStore,
|
|
@@ -719,24 +1421,23 @@ function BlockToolbar({
|
|
|
719
1421
|
const hasOverflowCustomizeControls = manifestCustomize.hasOverflowControls;
|
|
720
1422
|
const quickManifestBackend = manifestCustomize.backend;
|
|
721
1423
|
const canCycleBackgroundMode = enabledBackgroundModeList.length > 1;
|
|
722
|
-
const canCycleBackgroundValue = currentBackground.kind === "supported" &&
|
|
1424
|
+
const canCycleBackgroundValue = currentBackground.kind === "supported" && backgroundTransitionCapability ? canCycleBackgroundOverrideValue(
|
|
723
1425
|
currentBackground.override,
|
|
724
|
-
|
|
1426
|
+
backgroundTransitionCapability
|
|
725
1427
|
) : false;
|
|
726
1428
|
const hasCustomizeControls = hasLayoutControls || hasLookControls || hasFacetControls || hasBackgroundControls || quickManifestFields.length > 0 || hasSidebarCustomizeControls;
|
|
727
|
-
const isSavingCustomize = isHistoryPending;
|
|
728
1429
|
useEffect(() => {
|
|
729
1430
|
if (!hasCustomizeControls) {
|
|
730
|
-
|
|
1431
|
+
popover.close();
|
|
731
1432
|
setBackgroundChooserOpen(false);
|
|
732
1433
|
}
|
|
733
|
-
}, [hasCustomizeControls]);
|
|
1434
|
+
}, [hasCustomizeControls, popover.close]);
|
|
734
1435
|
useEffect(() => {
|
|
735
|
-
if (!
|
|
1436
|
+
if (!popover.open) return;
|
|
736
1437
|
setBackgroundColorPalette(readBackgroundColorPaletteSnapshot());
|
|
737
|
-
}, [
|
|
1438
|
+
}, [pageDesignState, popover.open]);
|
|
738
1439
|
useEffect(() => {
|
|
739
|
-
if (!
|
|
1440
|
+
if (!popover.open || !backgroundCapability?.modes.includes("image")) {
|
|
740
1441
|
return;
|
|
741
1442
|
}
|
|
742
1443
|
if (backgroundImagePoolStatus !== "idle") return;
|
|
@@ -744,8 +1445,8 @@ function BlockToolbar({
|
|
|
744
1445
|
}, [
|
|
745
1446
|
backgroundCapability,
|
|
746
1447
|
backgroundImagePoolStatus,
|
|
747
|
-
|
|
748
|
-
|
|
1448
|
+
loadBackgroundImagePool,
|
|
1449
|
+
popover.open
|
|
749
1450
|
]);
|
|
750
1451
|
const handleEdit = (e) => {
|
|
751
1452
|
e.preventDefault();
|
|
@@ -763,40 +1464,32 @@ function BlockToolbar({
|
|
|
763
1464
|
const inspectBlock = useCallback(() => {
|
|
764
1465
|
customizeSelection?.inspectBlock(unsafeAsEditorBlockId(blockId));
|
|
765
1466
|
}, [blockId, customizeSelection]);
|
|
766
|
-
const
|
|
767
|
-
e
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
1467
|
+
const openSidebarCustomize = useCallback(
|
|
1468
|
+
(e) => {
|
|
1469
|
+
e.preventDefault();
|
|
1470
|
+
e.stopPropagation();
|
|
1471
|
+
inspectBlock();
|
|
1472
|
+
const state = uiStore.getState();
|
|
1473
|
+
setPreviewSidebarTab("editor");
|
|
1474
|
+
state.setPreviewSidebarTab("editor");
|
|
1475
|
+
state.setDrawerOpen(true);
|
|
1476
|
+
},
|
|
1477
|
+
[inspectBlock, uiStore]
|
|
1478
|
+
);
|
|
1479
|
+
const cycleLayout = (direction) => {
|
|
778
1480
|
if (!designBlock) return;
|
|
779
1481
|
const action = cyclePageDesignBlockLayout(designBlock, direction);
|
|
780
1482
|
if (!action) return;
|
|
781
1483
|
saveBlockCustomizeAction(action);
|
|
782
1484
|
};
|
|
783
|
-
const cycleLook = (direction) =>
|
|
784
|
-
e.preventDefault();
|
|
785
|
-
e.stopPropagation();
|
|
1485
|
+
const cycleLook = (direction) => {
|
|
786
1486
|
if (!designBlock) return;
|
|
787
1487
|
const action = cyclePageDesignBlockLook(designBlock, direction);
|
|
788
1488
|
if (!action) return;
|
|
789
1489
|
saveBlockCustomizeAction(action);
|
|
790
1490
|
};
|
|
791
|
-
const
|
|
792
|
-
e.preventDefault();
|
|
793
|
-
e.stopPropagation();
|
|
1491
|
+
const cycleFacet = (control, direction) => {
|
|
794
1492
|
if (!designBlock) return;
|
|
795
|
-
const facetId = e.currentTarget.dataset.facetId;
|
|
796
|
-
const direction = e.currentTarget.dataset.direction;
|
|
797
|
-
if (direction !== "prev" && direction !== "next") return;
|
|
798
|
-
const control = facetControls.find((candidate) => candidate.facetId === facetId) ?? null;
|
|
799
|
-
if (!control) return;
|
|
800
1493
|
const action = cyclePageDesignBlockFacet({
|
|
801
1494
|
block: designBlock,
|
|
802
1495
|
facetId: control.facetId,
|
|
@@ -824,12 +1517,12 @@ function BlockToolbar({
|
|
|
824
1517
|
setBackgroundChooserOpen(false);
|
|
825
1518
|
};
|
|
826
1519
|
const saveBackgroundTransition = (transition) => {
|
|
827
|
-
if (!designBlock || !
|
|
1520
|
+
if (!designBlock || !backgroundTransitionCapability || currentBackground.kind !== "supported") {
|
|
828
1521
|
return;
|
|
829
1522
|
}
|
|
830
1523
|
const plan = planBackgroundTransition(
|
|
831
1524
|
currentBackground.override,
|
|
832
|
-
|
|
1525
|
+
backgroundTransitionCapability,
|
|
833
1526
|
transition
|
|
834
1527
|
);
|
|
835
1528
|
if (plan.kind !== "apply") return;
|
|
@@ -846,34 +1539,31 @@ function BlockToolbar({
|
|
|
846
1539
|
void applyPageDesignAction(action, { runtimeContent: customizeContent });
|
|
847
1540
|
};
|
|
848
1541
|
const toggleCustomize = (e) => {
|
|
849
|
-
|
|
850
|
-
e.stopPropagation();
|
|
851
|
-
if (!customizeOpen) {
|
|
1542
|
+
if (!popover.open) {
|
|
852
1543
|
inspectBlock();
|
|
853
|
-
setCustomizeReturnFocusTarget(
|
|
854
|
-
e.currentTarget instanceof HTMLElement ? e.currentTarget : customizeButtonRef.current
|
|
855
|
-
);
|
|
856
1544
|
}
|
|
857
|
-
|
|
1545
|
+
popover.toggle(e);
|
|
858
1546
|
};
|
|
859
1547
|
return /* @__PURE__ */ jsxs(
|
|
860
|
-
|
|
1548
|
+
PreviewChromeFloatingControl,
|
|
861
1549
|
{
|
|
862
|
-
|
|
863
|
-
|
|
1550
|
+
anchorSelector: "[data-block-id]",
|
|
1551
|
+
placement,
|
|
1552
|
+
fallbackClassName: "pointer-events-auto absolute z-50 flex gap-1 opacity-0 transition group-focus-within:opacity-100 group-hover:opacity-100",
|
|
1553
|
+
fallbackStyle: {
|
|
1554
|
+
top: placement.topPx,
|
|
1555
|
+
right: placement.rightPx
|
|
1556
|
+
},
|
|
1557
|
+
forceVisible: popover.open,
|
|
864
1558
|
children: [
|
|
865
1559
|
hasCustomizeControls ? /* @__PURE__ */ jsx(
|
|
866
|
-
|
|
1560
|
+
CustomizePillButton,
|
|
867
1561
|
{
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
"aria-expanded": customizeOpen,
|
|
874
|
-
"aria-haspopup": "dialog",
|
|
875
|
-
"aria-controls": customizeOpen ? customizePanelId : void 0,
|
|
876
|
-
children: isSavingCustomize ? "Saving..." : "Customize"
|
|
1562
|
+
buttonRef: popover.buttonRef,
|
|
1563
|
+
ariaLabel: "Customize",
|
|
1564
|
+
open: popover.open,
|
|
1565
|
+
controlsId: popover.panelId,
|
|
1566
|
+
onClick: toggleCustomize
|
|
877
1567
|
}
|
|
878
1568
|
) : null,
|
|
879
1569
|
/* @__PURE__ */ jsx(
|
|
@@ -885,266 +1575,59 @@ function BlockToolbar({
|
|
|
885
1575
|
children: "Edit"
|
|
886
1576
|
}
|
|
887
1577
|
),
|
|
888
|
-
|
|
889
|
-
|
|
1578
|
+
popover.open && (designBlock || hasSidebarCustomizeControls) ? /* @__PURE__ */ jsxs(
|
|
1579
|
+
CustomizePopoverShell,
|
|
890
1580
|
{
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1581
|
+
panelId: popover.panelId,
|
|
1582
|
+
descriptionId: popover.descriptionId,
|
|
1583
|
+
dialogLabel: "Customize section",
|
|
1584
|
+
eyebrow: "Section",
|
|
1585
|
+
title: formatBlockKindLabel(blockKind),
|
|
1586
|
+
dialogRef: popover.dialogRef,
|
|
1587
|
+
closeButtonRef: popover.registerInitialFocus,
|
|
1588
|
+
onClose: popover.close,
|
|
1589
|
+
onKeyDown: popover.handleDialogKeyDown,
|
|
1590
|
+
spacing: "compact",
|
|
900
1591
|
children: [
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
{
|
|
941
|
-
type: "button",
|
|
942
|
-
onClick: cycleLayout("prev"),
|
|
943
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
944
|
-
"aria-label": "Previous layout",
|
|
945
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
946
|
-
}
|
|
947
|
-
),
|
|
948
|
-
/* @__PURE__ */ jsx(
|
|
949
|
-
"button",
|
|
950
|
-
{
|
|
951
|
-
type: "button",
|
|
952
|
-
onClick: cycleLayout("next"),
|
|
953
|
-
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
954
|
-
"aria-label": "Next layout",
|
|
955
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
956
|
-
}
|
|
957
|
-
)
|
|
958
|
-
] })
|
|
959
|
-
] }) : null,
|
|
960
|
-
designBlock?.layout?.status === "unsupported" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-amber-700", children: "This layout is no longer available. The preview is using the closest safe option." }) : null,
|
|
961
|
-
facetControls.map((control) => /* @__PURE__ */ jsxs(
|
|
962
|
-
"div",
|
|
963
|
-
{
|
|
964
|
-
className: "flex items-center justify-between gap-2",
|
|
965
|
-
children: [
|
|
966
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
967
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: control.label }),
|
|
968
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: control.valueLabel })
|
|
969
|
-
] }),
|
|
970
|
-
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center overflow-hidden rounded-full border bg-background", children: [
|
|
971
|
-
/* @__PURE__ */ jsx(
|
|
972
|
-
"button",
|
|
973
|
-
{
|
|
974
|
-
type: "button",
|
|
975
|
-
onClick: handleFacetCycle,
|
|
976
|
-
"data-facet-id": control.facetId,
|
|
977
|
-
"data-direction": "prev",
|
|
978
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
979
|
-
"aria-label": `Previous ${control.label.toLowerCase()}`,
|
|
980
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
981
|
-
}
|
|
982
|
-
),
|
|
983
|
-
/* @__PURE__ */ jsx(
|
|
984
|
-
"button",
|
|
985
|
-
{
|
|
986
|
-
type: "button",
|
|
987
|
-
onClick: handleFacetCycle,
|
|
988
|
-
"data-facet-id": control.facetId,
|
|
989
|
-
"data-direction": "next",
|
|
990
|
-
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
991
|
-
"aria-label": `Next ${control.label.toLowerCase()}`,
|
|
992
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
993
|
-
}
|
|
994
|
-
)
|
|
995
|
-
] })
|
|
996
|
-
]
|
|
997
|
-
},
|
|
998
|
-
control.facetId
|
|
999
|
-
)),
|
|
1000
|
-
hasBackgroundControls && currentBackground.kind === "supported" && backgroundCapability ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1001
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-stretch overflow-hidden rounded-full border bg-background", children: [
|
|
1002
|
-
/* @__PURE__ */ jsx(
|
|
1003
|
-
"button",
|
|
1004
|
-
{
|
|
1005
|
-
type: "button",
|
|
1006
|
-
onClick: handleBackgroundCycle({
|
|
1007
|
-
kind: "cycle-mode",
|
|
1008
|
-
direction: "prev"
|
|
1009
|
-
}),
|
|
1010
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1011
|
-
"aria-label": "Previous background mode",
|
|
1012
|
-
disabled: !canCycleBackgroundMode,
|
|
1013
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
1014
|
-
}
|
|
1015
|
-
),
|
|
1016
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 border-x px-2 py-1 text-center", children: [
|
|
1017
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium leading-3 text-muted-foreground", children: "Background:" }),
|
|
1018
|
-
/* @__PURE__ */ jsx("div", { className: "truncate text-xs font-semibold leading-4", children: backgroundModeLabel(currentBackground.override.kind) })
|
|
1019
|
-
] }),
|
|
1020
|
-
/* @__PURE__ */ jsx(
|
|
1021
|
-
"button",
|
|
1022
|
-
{
|
|
1023
|
-
type: "button",
|
|
1024
|
-
onClick: handleBackgroundCycle({
|
|
1025
|
-
kind: "cycle-mode",
|
|
1026
|
-
direction: "next"
|
|
1027
|
-
}),
|
|
1028
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1029
|
-
"aria-label": "Next background mode",
|
|
1030
|
-
disabled: !canCycleBackgroundMode,
|
|
1031
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
1032
|
-
}
|
|
1033
|
-
)
|
|
1034
|
-
] }),
|
|
1035
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-stretch overflow-hidden rounded-full border bg-background", children: [
|
|
1036
|
-
/* @__PURE__ */ jsx(
|
|
1037
|
-
"button",
|
|
1038
|
-
{
|
|
1039
|
-
type: "button",
|
|
1040
|
-
onClick: handleBackgroundCycle({
|
|
1041
|
-
kind: "cycle-value",
|
|
1042
|
-
direction: "prev"
|
|
1043
|
-
}),
|
|
1044
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1045
|
-
"aria-label": "Previous background value",
|
|
1046
|
-
disabled: !canCycleBackgroundValue,
|
|
1047
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
1048
|
-
}
|
|
1049
|
-
),
|
|
1050
|
-
/* @__PURE__ */ jsxs(
|
|
1051
|
-
"button",
|
|
1052
|
-
{
|
|
1053
|
-
type: "button",
|
|
1054
|
-
className: "flex min-w-0 flex-1 items-center justify-center gap-2 border-x px-2 py-1 text-center hover:bg-muted",
|
|
1055
|
-
"aria-expanded": backgroundChooserOpen,
|
|
1056
|
-
"aria-label": `Choose background ${backgroundOverrideLabel(currentBackground.override).toLowerCase()}`,
|
|
1057
|
-
onClick: (event) => {
|
|
1058
|
-
event.preventDefault();
|
|
1059
|
-
event.stopPropagation();
|
|
1060
|
-
setBackgroundChooserOpen((open) => !open);
|
|
1061
|
-
},
|
|
1062
|
-
children: [
|
|
1063
|
-
/* @__PURE__ */ jsx(BackgroundPreviewSwatch, { override: currentBackground.override }),
|
|
1064
|
-
/* @__PURE__ */ jsx("span", { className: "truncate text-xs font-medium", children: backgroundOverrideValueLabel(
|
|
1065
|
-
currentBackground.override,
|
|
1066
|
-
mergedBackgroundImagePool
|
|
1067
|
-
) })
|
|
1068
|
-
]
|
|
1069
|
-
}
|
|
1070
|
-
),
|
|
1071
|
-
/* @__PURE__ */ jsx(
|
|
1072
|
-
"button",
|
|
1073
|
-
{
|
|
1074
|
-
type: "button",
|
|
1075
|
-
onClick: handleBackgroundCycle({
|
|
1076
|
-
kind: "cycle-value",
|
|
1077
|
-
direction: "next"
|
|
1078
|
-
}),
|
|
1079
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1080
|
-
"aria-label": "Next background value",
|
|
1081
|
-
disabled: !canCycleBackgroundValue,
|
|
1082
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
1083
|
-
}
|
|
1084
|
-
)
|
|
1085
|
-
] }),
|
|
1086
|
-
backgroundChooserOpen ? /* @__PURE__ */ jsx(
|
|
1087
|
-
BackgroundChooser,
|
|
1088
|
-
{
|
|
1089
|
-
capability: backgroundCapability,
|
|
1090
|
-
current: currentBackground.override,
|
|
1091
|
-
enabledModes: enabledBackgroundModeList,
|
|
1092
|
-
imagePoolStatus: backgroundImagePoolStatus,
|
|
1093
|
-
onChoose: chooseBackgroundOverride
|
|
1094
|
-
}
|
|
1095
|
-
) : null
|
|
1096
|
-
] }) : null,
|
|
1097
|
-
quickManifestFields.length > 0 && quickManifestBackend ? /* @__PURE__ */ jsx("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsx(
|
|
1098
|
-
FormRenderer,
|
|
1099
|
-
{
|
|
1100
|
-
fields: quickManifestFields,
|
|
1101
|
-
backend: quickManifestBackend,
|
|
1102
|
-
showSettingsTrigger: false,
|
|
1103
|
-
blockKind,
|
|
1104
|
-
className: "space-y-3"
|
|
1105
|
-
}
|
|
1106
|
-
) }) : null,
|
|
1107
|
-
hasLookControls && designBlock ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1108
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1109
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: "Look" }),
|
|
1110
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: lookLabel(designBlock) })
|
|
1111
|
-
] }),
|
|
1112
|
-
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center overflow-hidden rounded-full border bg-background", children: [
|
|
1113
|
-
/* @__PURE__ */ jsx(
|
|
1114
|
-
"button",
|
|
1115
|
-
{
|
|
1116
|
-
type: "button",
|
|
1117
|
-
onClick: cycleLook("prev"),
|
|
1118
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1119
|
-
"aria-label": "Previous look",
|
|
1120
|
-
disabled: !canCycleLook,
|
|
1121
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
1122
|
-
}
|
|
1123
|
-
),
|
|
1124
|
-
/* @__PURE__ */ jsx(
|
|
1125
|
-
"button",
|
|
1126
|
-
{
|
|
1127
|
-
type: "button",
|
|
1128
|
-
onClick: cycleLook("next"),
|
|
1129
|
-
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1130
|
-
"aria-label": "Next look",
|
|
1131
|
-
disabled: !canCycleLook,
|
|
1132
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
1133
|
-
}
|
|
1134
|
-
)
|
|
1135
|
-
] })
|
|
1136
|
-
] }) : null,
|
|
1137
|
-
historyFailure ? /* @__PURE__ */ jsx("p", { className: "text-xs text-red-700", children: historyFailure }) : null,
|
|
1138
|
-
hasOverflowCustomizeControls ? /* @__PURE__ */ jsx("div", { className: "border-t pt-2", children: /* @__PURE__ */ jsx(
|
|
1139
|
-
"button",
|
|
1140
|
-
{
|
|
1141
|
-
type: "button",
|
|
1142
|
-
className: "w-full rounded-md border bg-background px-3 py-2 text-sm font-medium hover:bg-muted",
|
|
1143
|
-
onClick: openCustomizeSettings,
|
|
1144
|
-
children: "Settings"
|
|
1145
|
-
}
|
|
1146
|
-
) }) : null
|
|
1147
|
-
] })
|
|
1592
|
+
builtInCustomizeRows.map(
|
|
1593
|
+
(row) => renderBlockCustomizeBuiltinRow(row, {
|
|
1594
|
+
backgroundCapability,
|
|
1595
|
+
backgroundChooserOpen,
|
|
1596
|
+
canCycleBackgroundMode,
|
|
1597
|
+
canCycleBackgroundValue,
|
|
1598
|
+
currentBackground,
|
|
1599
|
+
cycleLayout,
|
|
1600
|
+
cycleLook,
|
|
1601
|
+
cycleFacet,
|
|
1602
|
+
enabledBackgroundModeList,
|
|
1603
|
+
handleBackgroundCycle,
|
|
1604
|
+
imagePoolStatus: backgroundImagePoolStatus,
|
|
1605
|
+
mergedBackgroundImagePool,
|
|
1606
|
+
onChooseBackgroundOverride: chooseBackgroundOverride,
|
|
1607
|
+
onToggleBackgroundChooser: () => setBackgroundChooserOpen((open) => !open)
|
|
1608
|
+
})
|
|
1609
|
+
),
|
|
1610
|
+
quickManifestFields.length > 0 && quickManifestBackend ? /* @__PURE__ */ jsx("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsx(
|
|
1611
|
+
FormRenderer,
|
|
1612
|
+
{
|
|
1613
|
+
fields: quickManifestFields,
|
|
1614
|
+
backend: quickManifestBackend,
|
|
1615
|
+
showSettingsTrigger: false,
|
|
1616
|
+
blockKind,
|
|
1617
|
+
className: "space-y-3"
|
|
1618
|
+
}
|
|
1619
|
+
) }) : null,
|
|
1620
|
+
historyFailure ? /* @__PURE__ */ jsx("p", { className: "text-xs text-red-700", children: historyFailure }) : null,
|
|
1621
|
+
hasOverflowCustomizeControls ? /* @__PURE__ */ jsx("div", { className: "border-t pt-2", children: /* @__PURE__ */ jsx(
|
|
1622
|
+
"button",
|
|
1623
|
+
{
|
|
1624
|
+
type: "button",
|
|
1625
|
+
"aria-label": "Open detailed customization settings",
|
|
1626
|
+
className: "w-full rounded-md border bg-background px-3 py-2 text-sm font-medium hover:bg-muted",
|
|
1627
|
+
onClick: openSidebarCustomize,
|
|
1628
|
+
children: "Customize"
|
|
1629
|
+
}
|
|
1630
|
+
) }) : null
|
|
1148
1631
|
]
|
|
1149
1632
|
}
|
|
1150
1633
|
) : null
|
|
@@ -1152,16 +1635,178 @@ function BlockToolbar({
|
|
|
1152
1635
|
}
|
|
1153
1636
|
);
|
|
1154
1637
|
}
|
|
1638
|
+
function renderBlockCustomizeBuiltinRow(row, context) {
|
|
1639
|
+
switch (row.kind) {
|
|
1640
|
+
case "variant":
|
|
1641
|
+
return /* @__PURE__ */ jsx(
|
|
1642
|
+
CustomizeCycleRow,
|
|
1643
|
+
{
|
|
1644
|
+
label: "Variant",
|
|
1645
|
+
valueLabel: layoutLabel(
|
|
1646
|
+
row.block.availableLayouts,
|
|
1647
|
+
row.block.layout?.effectiveValue ?? ""
|
|
1648
|
+
),
|
|
1649
|
+
previousLabel: "Previous variant",
|
|
1650
|
+
nextLabel: "Next variant",
|
|
1651
|
+
availability: cycleAvailability({ kind: "available" }),
|
|
1652
|
+
onPrevious: () => context.cycleLayout("prev"),
|
|
1653
|
+
onNext: () => context.cycleLayout("next")
|
|
1654
|
+
},
|
|
1655
|
+
"variant"
|
|
1656
|
+
);
|
|
1657
|
+
case "unsupported-variant-warning":
|
|
1658
|
+
return /* @__PURE__ */ jsx("p", { className: "text-xs text-amber-700", children: "This layout is no longer available. The preview is using the closest safe option." }, "unsupported-variant-warning");
|
|
1659
|
+
case "look":
|
|
1660
|
+
return /* @__PURE__ */ jsx(
|
|
1661
|
+
CustomizeCycleRow,
|
|
1662
|
+
{
|
|
1663
|
+
label: "Look",
|
|
1664
|
+
valueLabel: lookLabel(row.block),
|
|
1665
|
+
previousLabel: "Previous look",
|
|
1666
|
+
nextLabel: "Next look",
|
|
1667
|
+
availability: cycleAvailability(
|
|
1668
|
+
canCycleLookForRow(row.block) ? { kind: "available" } : { kind: "single-option" }
|
|
1669
|
+
),
|
|
1670
|
+
onPrevious: () => context.cycleLook("prev"),
|
|
1671
|
+
onNext: () => context.cycleLook("next")
|
|
1672
|
+
},
|
|
1673
|
+
"look"
|
|
1674
|
+
);
|
|
1675
|
+
case "background":
|
|
1676
|
+
if (context.currentBackground.kind !== "supported" || !context.backgroundCapability) {
|
|
1677
|
+
return null;
|
|
1678
|
+
}
|
|
1679
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1680
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-stretch overflow-hidden rounded-full border bg-background", children: [
|
|
1681
|
+
/* @__PURE__ */ jsx(
|
|
1682
|
+
"button",
|
|
1683
|
+
{
|
|
1684
|
+
type: "button",
|
|
1685
|
+
onClick: context.handleBackgroundCycle({
|
|
1686
|
+
kind: "cycle-mode",
|
|
1687
|
+
direction: "prev"
|
|
1688
|
+
}),
|
|
1689
|
+
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1690
|
+
"aria-label": "Previous background mode",
|
|
1691
|
+
disabled: !context.canCycleBackgroundMode,
|
|
1692
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
1693
|
+
}
|
|
1694
|
+
),
|
|
1695
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 border-x px-2 py-1 text-center", children: [
|
|
1696
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium leading-3 text-muted-foreground", children: "Background:" }),
|
|
1697
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-xs font-semibold leading-4", children: backgroundModeLabel(context.currentBackground.override.kind) })
|
|
1698
|
+
] }),
|
|
1699
|
+
/* @__PURE__ */ jsx(
|
|
1700
|
+
"button",
|
|
1701
|
+
{
|
|
1702
|
+
type: "button",
|
|
1703
|
+
onClick: context.handleBackgroundCycle({
|
|
1704
|
+
kind: "cycle-mode",
|
|
1705
|
+
direction: "next"
|
|
1706
|
+
}),
|
|
1707
|
+
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1708
|
+
"aria-label": "Next background mode",
|
|
1709
|
+
disabled: !context.canCycleBackgroundMode,
|
|
1710
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
1711
|
+
}
|
|
1712
|
+
)
|
|
1713
|
+
] }),
|
|
1714
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-stretch overflow-hidden rounded-full border bg-background", children: [
|
|
1715
|
+
/* @__PURE__ */ jsx(
|
|
1716
|
+
"button",
|
|
1717
|
+
{
|
|
1718
|
+
type: "button",
|
|
1719
|
+
onClick: context.handleBackgroundCycle({
|
|
1720
|
+
kind: "cycle-value",
|
|
1721
|
+
direction: "prev"
|
|
1722
|
+
}),
|
|
1723
|
+
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1724
|
+
"aria-label": "Previous background value",
|
|
1725
|
+
disabled: !context.canCycleBackgroundValue,
|
|
1726
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
1727
|
+
}
|
|
1728
|
+
),
|
|
1729
|
+
/* @__PURE__ */ jsxs(
|
|
1730
|
+
"button",
|
|
1731
|
+
{
|
|
1732
|
+
type: "button",
|
|
1733
|
+
className: "flex min-w-0 flex-1 items-center justify-center gap-2 border-x px-2 py-1 text-center hover:bg-muted",
|
|
1734
|
+
"aria-expanded": context.backgroundChooserOpen,
|
|
1735
|
+
"aria-label": `Choose background ${backgroundOverrideLabel(context.currentBackground.override).toLowerCase()}`,
|
|
1736
|
+
onClick: (event) => {
|
|
1737
|
+
event.preventDefault();
|
|
1738
|
+
event.stopPropagation();
|
|
1739
|
+
context.onToggleBackgroundChooser();
|
|
1740
|
+
},
|
|
1741
|
+
children: [
|
|
1742
|
+
/* @__PURE__ */ jsx(
|
|
1743
|
+
BackgroundPreviewSwatch,
|
|
1744
|
+
{
|
|
1745
|
+
override: context.currentBackground.override,
|
|
1746
|
+
imagePool: context.mergedBackgroundImagePool
|
|
1747
|
+
}
|
|
1748
|
+
),
|
|
1749
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-xs font-medium", children: backgroundOverrideValueLabel(
|
|
1750
|
+
context.currentBackground.override,
|
|
1751
|
+
context.mergedBackgroundImagePool
|
|
1752
|
+
) })
|
|
1753
|
+
]
|
|
1754
|
+
}
|
|
1755
|
+
),
|
|
1756
|
+
/* @__PURE__ */ jsx(
|
|
1757
|
+
"button",
|
|
1758
|
+
{
|
|
1759
|
+
type: "button",
|
|
1760
|
+
onClick: context.handleBackgroundCycle({
|
|
1761
|
+
kind: "cycle-value",
|
|
1762
|
+
direction: "next"
|
|
1763
|
+
}),
|
|
1764
|
+
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
1765
|
+
"aria-label": "Next background value",
|
|
1766
|
+
disabled: !context.canCycleBackgroundValue,
|
|
1767
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
1768
|
+
}
|
|
1769
|
+
)
|
|
1770
|
+
] }),
|
|
1771
|
+
context.backgroundChooserOpen ? /* @__PURE__ */ jsx(
|
|
1772
|
+
BackgroundChooser,
|
|
1773
|
+
{
|
|
1774
|
+
capability: context.backgroundCapability,
|
|
1775
|
+
current: context.currentBackground.override,
|
|
1776
|
+
imagePoolStatus: context.imagePoolStatus,
|
|
1777
|
+
onChoose: context.onChooseBackgroundOverride
|
|
1778
|
+
}
|
|
1779
|
+
) : null
|
|
1780
|
+
] }, "background");
|
|
1781
|
+
case "facet":
|
|
1782
|
+
return /* @__PURE__ */ jsx(
|
|
1783
|
+
CustomizeCycleRow,
|
|
1784
|
+
{
|
|
1785
|
+
label: row.control.label,
|
|
1786
|
+
valueLabel: row.control.valueLabel,
|
|
1787
|
+
previousLabel: `Previous ${row.control.label.toLowerCase()}`,
|
|
1788
|
+
nextLabel: `Next ${row.control.label.toLowerCase()}`,
|
|
1789
|
+
availability: cycleAvailability({ kind: "available" }),
|
|
1790
|
+
onPrevious: () => context.cycleFacet(row.control, "prev"),
|
|
1791
|
+
onNext: () => context.cycleFacet(row.control, "next")
|
|
1792
|
+
},
|
|
1793
|
+
`facet:${row.control.facetId}`
|
|
1794
|
+
);
|
|
1795
|
+
default:
|
|
1796
|
+
return assertNever2(row, "Unhandled block customize builtin row");
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
function canCycleLookForRow(block) {
|
|
1800
|
+
return block.availableLooks.length > 1;
|
|
1801
|
+
}
|
|
1155
1802
|
function BackgroundChooser({
|
|
1156
1803
|
capability,
|
|
1157
1804
|
current,
|
|
1158
|
-
enabledModes,
|
|
1159
1805
|
imagePoolStatus,
|
|
1160
1806
|
onChoose
|
|
1161
1807
|
}) {
|
|
1162
1808
|
const mediaEditorContext = useMediaEditorOptional();
|
|
1163
1809
|
const [mediaPickerOpenKey, setMediaPickerOpenKey] = useState(0);
|
|
1164
|
-
const enabledModeSet = new Set(enabledModes);
|
|
1165
1810
|
const images = rankBackgroundImagePoolItems(capability.imagePool ?? []);
|
|
1166
1811
|
const recommendedTokens = capability.recommendedColorTokens ?? capability.colorTokens ?? [];
|
|
1167
1812
|
const advancedTokens = capability.advancedColorTokens ?? [];
|
|
@@ -1177,21 +1822,30 @@ function BackgroundChooser({
|
|
|
1177
1822
|
onChoose({ kind: "image", mediaId: parsed.value });
|
|
1178
1823
|
setMediaPickerOpenKey(0);
|
|
1179
1824
|
};
|
|
1180
|
-
|
|
1181
|
-
/* @__PURE__ */ jsx("div", { className: "mb-
|
|
1825
|
+
const renderColorOptions = () => recommendedTokens.length || advancedTokens.length ? /* @__PURE__ */ jsxs("div", { children: [
|
|
1826
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: "Colors" }),
|
|
1827
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-1", children: recommendedTokens.map((token) => /* @__PURE__ */ jsxs(
|
|
1182
1828
|
"button",
|
|
1183
1829
|
{
|
|
1184
1830
|
type: "button",
|
|
1185
|
-
className: `rounded-md border px-2 py-1 text-xs ${current.kind ===
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1831
|
+
className: `flex min-w-0 items-center gap-2 rounded-md border px-2 py-1 text-left text-xs hover:bg-muted ${current.kind === "color" && current.token === token ? "border-foreground" : "bg-background"}`,
|
|
1832
|
+
onClick: chooseFromClick({ kind: "color", token }),
|
|
1833
|
+
children: [
|
|
1834
|
+
/* @__PURE__ */ jsx(
|
|
1835
|
+
"span",
|
|
1836
|
+
{
|
|
1837
|
+
className: "h-3 w-3 shrink-0 rounded-full border",
|
|
1838
|
+
style: { backgroundColor: tokenSwatchCss(token) }
|
|
1839
|
+
}
|
|
1840
|
+
),
|
|
1841
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: formatTokenLabel(token) })
|
|
1842
|
+
]
|
|
1189
1843
|
},
|
|
1190
|
-
|
|
1844
|
+
token
|
|
1191
1845
|
)) }),
|
|
1192
|
-
|
|
1193
|
-
/* @__PURE__ */ jsx("
|
|
1194
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-1", children:
|
|
1846
|
+
advancedTokens.length ? /* @__PURE__ */ jsxs("details", { className: "mt-1", children: [
|
|
1847
|
+
/* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-xs text-muted-foreground", children: "More colors" }),
|
|
1848
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 grid grid-cols-2 gap-1", children: advancedTokens.map((token) => /* @__PURE__ */ jsxs(
|
|
1195
1849
|
"button",
|
|
1196
1850
|
{
|
|
1197
1851
|
type: "button",
|
|
@@ -1209,78 +1863,72 @@ function BackgroundChooser({
|
|
|
1209
1863
|
]
|
|
1210
1864
|
},
|
|
1211
1865
|
token
|
|
1212
|
-
)) }),
|
|
1213
|
-
advancedTokens.length ? /* @__PURE__ */ jsxs("details", { className: "mt-1", children: [
|
|
1214
|
-
/* @__PURE__ */ jsx("summary", { className: "cursor-pointer text-xs text-muted-foreground", children: "More colors" }),
|
|
1215
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1 grid grid-cols-2 gap-1", children: advancedTokens.map((token) => /* @__PURE__ */ jsxs(
|
|
1216
|
-
"button",
|
|
1217
|
-
{
|
|
1218
|
-
type: "button",
|
|
1219
|
-
className: `flex min-w-0 items-center gap-2 rounded-md border px-2 py-1 text-left text-xs hover:bg-muted ${current.kind === "color" && current.token === token ? "border-foreground" : "bg-background"}`,
|
|
1220
|
-
onClick: chooseFromClick({ kind: "color", token }),
|
|
1221
|
-
children: [
|
|
1222
|
-
/* @__PURE__ */ jsx(
|
|
1223
|
-
"span",
|
|
1224
|
-
{
|
|
1225
|
-
className: "h-3 w-3 shrink-0 rounded-full border",
|
|
1226
|
-
style: { backgroundColor: tokenSwatchCss(token) }
|
|
1227
|
-
}
|
|
1228
|
-
),
|
|
1229
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: formatTokenLabel(token) })
|
|
1230
|
-
]
|
|
1231
|
-
},
|
|
1232
|
-
token
|
|
1233
|
-
)) })
|
|
1234
|
-
] }) : null
|
|
1235
|
-
] }) : null,
|
|
1236
|
-
capability.gradientIds?.length ? /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
1237
|
-
/* @__PURE__ */ jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: "Gradients" }),
|
|
1238
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: capability.gradientIds.map((gradientId) => /* @__PURE__ */ jsx(
|
|
1239
|
-
"button",
|
|
1240
|
-
{
|
|
1241
|
-
type: "button",
|
|
1242
|
-
className: `w-full rounded-md border px-2 py-1 text-left text-xs hover:bg-muted ${current.kind === "gradient" && current.gradientId === gradientId ? "border-foreground" : "bg-background"}`,
|
|
1243
|
-
onClick: chooseFromClick({ kind: "gradient", gradientId }),
|
|
1244
|
-
children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
1245
|
-
/* @__PURE__ */ jsx(
|
|
1246
|
-
"span",
|
|
1247
|
-
{
|
|
1248
|
-
className: "h-4 w-8 shrink-0 rounded border",
|
|
1249
|
-
style: { backgroundImage: gradientPreviewCss(gradientId) }
|
|
1250
|
-
}
|
|
1251
|
-
),
|
|
1252
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: gradientLabel(gradientId) })
|
|
1253
|
-
] })
|
|
1254
|
-
},
|
|
1255
|
-
gradientId
|
|
1256
1866
|
)) })
|
|
1257
|
-
] }) : null
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1867
|
+
] }) : null
|
|
1868
|
+
] }) : null;
|
|
1869
|
+
const renderGradientOptions = () => capability.gradientIds?.length ? /* @__PURE__ */ jsxs("div", { children: [
|
|
1870
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: "Gradients" }),
|
|
1871
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: capability.gradientIds.map((gradientId) => /* @__PURE__ */ jsx(
|
|
1872
|
+
"button",
|
|
1873
|
+
{
|
|
1874
|
+
type: "button",
|
|
1875
|
+
className: `w-full rounded-md border px-2 py-1 text-left text-xs hover:bg-muted ${current.kind === "gradient" && current.gradientId === gradientId ? "border-foreground" : "bg-background"}`,
|
|
1876
|
+
onClick: chooseFromClick({ kind: "gradient", gradientId }),
|
|
1877
|
+
children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
1878
|
+
/* @__PURE__ */ jsx(
|
|
1879
|
+
"span",
|
|
1880
|
+
{
|
|
1881
|
+
className: "h-4 w-8 shrink-0 rounded border",
|
|
1882
|
+
style: { backgroundImage: gradientPreviewCss(gradientId) }
|
|
1883
|
+
}
|
|
1884
|
+
),
|
|
1885
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: gradientLabel(gradientId) })
|
|
1886
|
+
] })
|
|
1887
|
+
},
|
|
1888
|
+
gradientId
|
|
1889
|
+
)) })
|
|
1890
|
+
] }) : null;
|
|
1891
|
+
const renderImageOptions = () => capability.modes.includes("image") ? /* @__PURE__ */ jsxs("div", { children: [
|
|
1892
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: "Images" }),
|
|
1893
|
+
mediaEditorContext ? /* @__PURE__ */ jsxs(
|
|
1894
|
+
"button",
|
|
1895
|
+
{
|
|
1896
|
+
type: "button",
|
|
1897
|
+
className: "mb-2 inline-flex w-full items-center justify-center gap-2 rounded-md border bg-background px-2 py-1.5 text-xs font-medium hover:bg-muted",
|
|
1898
|
+
onClick: (event) => {
|
|
1899
|
+
event.preventDefault();
|
|
1900
|
+
event.stopPropagation();
|
|
1901
|
+
setMediaPickerOpenKey((key) => key + 1);
|
|
1902
|
+
},
|
|
1903
|
+
children: [
|
|
1904
|
+
/* @__PURE__ */ jsx(Upload, { size: 13 }),
|
|
1905
|
+
"Media library"
|
|
1906
|
+
]
|
|
1907
|
+
}
|
|
1908
|
+
) : null,
|
|
1909
|
+
images.length ? /* @__PURE__ */ jsx("div", { className: "space-y-1", children: images.map((item) => {
|
|
1910
|
+
const thumbnailUrl = backgroundImagePreviewUrl(
|
|
1911
|
+
item,
|
|
1912
|
+
mediaEditorContext
|
|
1913
|
+
);
|
|
1914
|
+
return /* @__PURE__ */ jsx(
|
|
1277
1915
|
"button",
|
|
1278
1916
|
{
|
|
1279
1917
|
type: "button",
|
|
1280
1918
|
className: `w-full rounded-md border px-2 py-1 text-left text-xs hover:bg-muted ${current.kind === "image" && current.mediaId === item.mediaId ? "border-foreground" : "bg-background"}`,
|
|
1281
|
-
onClick: chooseFromClick({
|
|
1919
|
+
onClick: chooseFromClick({
|
|
1920
|
+
kind: "image",
|
|
1921
|
+
mediaId: item.mediaId
|
|
1922
|
+
}),
|
|
1282
1923
|
children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1283
|
-
/* @__PURE__ */ jsx("span", { className: "grid h-7 w-9 shrink-0 place-items-center rounded border bg-muted", children: /* @__PURE__ */ jsx(
|
|
1924
|
+
/* @__PURE__ */ jsx("span", { className: "grid h-7 w-9 shrink-0 place-items-center overflow-hidden rounded border bg-muted", children: thumbnailUrl ? /* @__PURE__ */ jsx(
|
|
1925
|
+
"img",
|
|
1926
|
+
{
|
|
1927
|
+
alt: "",
|
|
1928
|
+
className: "h-full w-full object-cover",
|
|
1929
|
+
src: thumbnailUrl
|
|
1930
|
+
}
|
|
1931
|
+
) : /* @__PURE__ */ jsx(Image, { size: 14 }) }),
|
|
1284
1932
|
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
1285
1933
|
/* @__PURE__ */ jsx("span", { className: "block truncate", children: item.label ?? "Image" }),
|
|
1286
1934
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: imageSourceLabel(item.source) })
|
|
@@ -1288,25 +1936,51 @@ function BackgroundChooser({
|
|
|
1288
1936
|
] })
|
|
1289
1937
|
},
|
|
1290
1938
|
`${item.source}:${item.mediaId}`
|
|
1291
|
-
)
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
onUploadComplete: (asset) => {
|
|
1303
|
-
onChoose({ kind: "image", mediaId: asset.id });
|
|
1304
|
-
setMediaPickerOpenKey(0);
|
|
1305
|
-
}
|
|
1939
|
+
);
|
|
1940
|
+
}) }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: imagePoolStatus === "loading" ? "Loading images..." : "No background-ready images yet." }),
|
|
1941
|
+
mediaPickerOpenKey > 0 && mediaEditorContext ? /* @__PURE__ */ jsx("div", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx(
|
|
1942
|
+
MediaEditor,
|
|
1943
|
+
{
|
|
1944
|
+
value: void 0,
|
|
1945
|
+
onChange: chooseMediaValue,
|
|
1946
|
+
allowedKinds: ["image"],
|
|
1947
|
+
mediaPickerAutoOpen: true,
|
|
1948
|
+
mediaPickerPolicy: {
|
|
1949
|
+
assetSelection: backgroundMediaPickerAssetSelection
|
|
1306
1950
|
},
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1951
|
+
showPreview: false,
|
|
1952
|
+
showAltInput: false,
|
|
1953
|
+
uploadIntent: {
|
|
1954
|
+
tag: "media-library",
|
|
1955
|
+
allowedRenderUses: ["image"]
|
|
1956
|
+
},
|
|
1957
|
+
onUploadComplete: (asset) => {
|
|
1958
|
+
if (backgroundMediaPickerAssetSelection(asset).tag === "disabled") {
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
onChoose({ kind: "image", mediaId: asset.id });
|
|
1962
|
+
setMediaPickerOpenKey(0);
|
|
1963
|
+
}
|
|
1964
|
+
},
|
|
1965
|
+
mediaPickerOpenKey
|
|
1966
|
+
) }) : null
|
|
1967
|
+
] }) : null;
|
|
1968
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-2 max-h-80 overflow-y-auto rounded-md border bg-muted/20 p-2", children: [
|
|
1969
|
+
current.kind === "default" ? /* @__PURE__ */ jsxs(
|
|
1970
|
+
"button",
|
|
1971
|
+
{
|
|
1972
|
+
type: "button",
|
|
1973
|
+
className: "flex w-full items-center gap-2 rounded-md border border-foreground bg-background px-2 py-1 text-left text-xs",
|
|
1974
|
+
onClick: chooseFromClick(defaultBackgroundOverrideForMode("default", capability)),
|
|
1975
|
+
children: [
|
|
1976
|
+
/* @__PURE__ */ jsx(BackgroundPreviewSwatch, { override: current, imagePool: images }),
|
|
1977
|
+
/* @__PURE__ */ jsx("span", { children: "Default background" })
|
|
1978
|
+
]
|
|
1979
|
+
}
|
|
1980
|
+
) : null,
|
|
1981
|
+
current.kind === "color" ? renderColorOptions() : null,
|
|
1982
|
+
current.kind === "gradient" ? renderGradientOptions() : null,
|
|
1983
|
+
current.kind === "image" ? renderImageOptions() : null
|
|
1310
1984
|
] });
|
|
1311
1985
|
}
|
|
1312
1986
|
function computeDefaultFocus(blockKind, content) {
|
|
@@ -1331,7 +2005,7 @@ function findFirstFieldPath(fields, data, prefix) {
|
|
|
1331
2005
|
}
|
|
1332
2006
|
const nextPrefix = [...prefix, field.id];
|
|
1333
2007
|
if (field.type === "group") {
|
|
1334
|
-
const groupValue =
|
|
2008
|
+
const groupValue = isRecord4(data) ? data[field.id] : void 0;
|
|
1335
2009
|
const nested = findFirstFieldPath(
|
|
1336
2010
|
field.schema.fields,
|
|
1337
2011
|
groupValue,
|
|
@@ -1341,7 +2015,7 @@ function findFirstFieldPath(fields, data, prefix) {
|
|
|
1341
2015
|
continue;
|
|
1342
2016
|
}
|
|
1343
2017
|
if (field.type === "repeater" && field.schema) {
|
|
1344
|
-
const collection =
|
|
2018
|
+
const collection = isRecord4(data) ? data[field.id] : void 0;
|
|
1345
2019
|
const items = isUnknownArray(collection) ? collection : [];
|
|
1346
2020
|
if (items.length > 0) {
|
|
1347
2021
|
const firstItem = items[0];
|
|
@@ -1414,7 +2088,11 @@ function canCycleBackgroundOverrideValue(override, capability) {
|
|
|
1414
2088
|
return rankBackgroundImagePoolItems(capability.imagePool ?? []).length > 1;
|
|
1415
2089
|
}
|
|
1416
2090
|
}
|
|
1417
|
-
function BackgroundPreviewSwatch({
|
|
2091
|
+
function BackgroundPreviewSwatch({
|
|
2092
|
+
override,
|
|
2093
|
+
imagePool
|
|
2094
|
+
}) {
|
|
2095
|
+
const mediaEditorContext = useMediaEditorOptional();
|
|
1418
2096
|
const baseClassName = "grid h-6 w-9 shrink-0 place-items-center overflow-hidden rounded-md border";
|
|
1419
2097
|
switch (override.kind) {
|
|
1420
2098
|
case "default":
|
|
@@ -1436,8 +2114,47 @@ function BackgroundPreviewSwatch({ override }) {
|
|
|
1436
2114
|
}
|
|
1437
2115
|
);
|
|
1438
2116
|
case "image":
|
|
1439
|
-
|
|
2117
|
+
const imageItem = imagePool.find((item) => item.mediaId === override.mediaId);
|
|
2118
|
+
const thumbnailUrl = imageItem ? backgroundImagePreviewUrl(imageItem, mediaEditorContext) : void 0;
|
|
2119
|
+
return /* @__PURE__ */ jsx("span", { className: `${baseClassName} bg-muted`, children: thumbnailUrl ? /* @__PURE__ */ jsx("img", { alt: "", className: "h-full w-full object-cover", src: thumbnailUrl }) : /* @__PURE__ */ jsx(Image, { size: 15 }) });
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
function backgroundImagePreviewUrl(item, mediaEditorContext) {
|
|
2123
|
+
const asset = item.mediaAsset;
|
|
2124
|
+
if (!asset) return void 0;
|
|
2125
|
+
return resolveImageUrlWithContext(
|
|
2126
|
+
{
|
|
2127
|
+
type: "image",
|
|
2128
|
+
assetId: asset.id,
|
|
2129
|
+
...asset.identifier ? { identifier: asset.identifier } : {},
|
|
2130
|
+
storageBucket: asset.storageBucket,
|
|
2131
|
+
storagePath: asset.storagePath,
|
|
2132
|
+
...asset.width != null ? { width: asset.width } : {},
|
|
2133
|
+
...asset.height != null ? { height: asset.height } : {},
|
|
2134
|
+
mimeType: asset.mimeType
|
|
2135
|
+
},
|
|
2136
|
+
{ width: 72, height: 48, resize: "cover", quality: 70 },
|
|
2137
|
+
mediaEditorContext?.imageResolveContext ?? null
|
|
2138
|
+
);
|
|
2139
|
+
}
|
|
2140
|
+
function backgroundMediaPickerAssetSelection(asset) {
|
|
2141
|
+
if (isMarkedBackgroundAsset(asset)) return { tag: "selectable" };
|
|
2142
|
+
if (asset.width == null || asset.height == null) {
|
|
2143
|
+
return {
|
|
2144
|
+
tag: "disabled",
|
|
2145
|
+
reason: "This image is missing dimensions, so it cannot be checked for background use."
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
if (asset.width < SECTION_BACKGROUND_MIN_SOURCE_WIDTH || asset.height < SECTION_BACKGROUND_MIN_SOURCE_HEIGHT) {
|
|
2149
|
+
return {
|
|
2150
|
+
tag: "disabled",
|
|
2151
|
+
reason: `Background images need to be at least ${SECTION_BACKGROUND_MIN_SOURCE_WIDTH}x${SECTION_BACKGROUND_MIN_SOURCE_HEIGHT}. This image is ${asset.width}x${asset.height}.`
|
|
2152
|
+
};
|
|
1440
2153
|
}
|
|
2154
|
+
return { tag: "selectable" };
|
|
2155
|
+
}
|
|
2156
|
+
function isMarkedBackgroundAsset(asset) {
|
|
2157
|
+
return asset.fileUses?.some((fileUse) => fileUse.tag === "site-background-asset") ?? false;
|
|
1441
2158
|
}
|
|
1442
2159
|
function backgroundModeLabel(mode) {
|
|
1443
2160
|
return mode === "default" ? "Default" : formatVariantLabel(mode);
|
|
@@ -1461,7 +2178,9 @@ function tokenSwatchCss(token) {
|
|
|
1461
2178
|
return `rgb(var(--tb-${token}))`;
|
|
1462
2179
|
}
|
|
1463
2180
|
function gradientPreviewCss(gradientId) {
|
|
1464
|
-
const preset = GRADIENT_PRESETS.find(
|
|
2181
|
+
const preset = GRADIENT_PRESETS.find(
|
|
2182
|
+
(candidate) => candidate.id === gradientId
|
|
2183
|
+
);
|
|
1465
2184
|
if (!preset) {
|
|
1466
2185
|
return "linear-gradient(135deg, rgb(var(--tb-primary)), rgb(var(--tb-secondary)))";
|
|
1467
2186
|
}
|
|
@@ -1491,7 +2210,21 @@ function dedupeBackgroundImagePool(items) {
|
|
|
1491
2210
|
const seen = /* @__PURE__ */ new Set();
|
|
1492
2211
|
const deduped = [];
|
|
1493
2212
|
for (const item of items) {
|
|
1494
|
-
if (seen.has(item.mediaId))
|
|
2213
|
+
if (seen.has(item.mediaId)) {
|
|
2214
|
+
const existingIndex = deduped.findIndex(
|
|
2215
|
+
(candidate) => candidate.mediaId === item.mediaId
|
|
2216
|
+
);
|
|
2217
|
+
const existing = deduped[existingIndex];
|
|
2218
|
+
if (existing && !existing.mediaAsset && item.mediaAsset) {
|
|
2219
|
+
deduped[existingIndex] = {
|
|
2220
|
+
...existing,
|
|
2221
|
+
mediaAsset: item.mediaAsset,
|
|
2222
|
+
label: existing.label ?? item.label,
|
|
2223
|
+
rank: existing.rank ?? item.rank
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
continue;
|
|
2227
|
+
}
|
|
1495
2228
|
seen.add(item.mediaId);
|
|
1496
2229
|
deduped.push(item);
|
|
1497
2230
|
}
|
|
@@ -1564,12 +2297,15 @@ function BoundaryControl({
|
|
|
1564
2297
|
});
|
|
1565
2298
|
});
|
|
1566
2299
|
};
|
|
1567
|
-
const
|
|
2300
|
+
const applyBoundaryOption = (boundaryOptionId) => (event) => {
|
|
1568
2301
|
event.preventDefault();
|
|
1569
2302
|
event.stopPropagation();
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
2303
|
+
saveBoundaryAction({
|
|
2304
|
+
kind: "set-boundary",
|
|
2305
|
+
previousBlockId: boundary.previousBlockId,
|
|
2306
|
+
nextBlockId: boundary.nextBlockId,
|
|
2307
|
+
boundaryOptionId
|
|
2308
|
+
});
|
|
1573
2309
|
};
|
|
1574
2310
|
const resetBoundaryBreak = (event) => {
|
|
1575
2311
|
event.preventDefault();
|
|
@@ -1580,19 +2316,26 @@ function BoundaryControl({
|
|
|
1580
2316
|
nextBlockId: boundary.nextBlockId
|
|
1581
2317
|
});
|
|
1582
2318
|
};
|
|
2319
|
+
const selectedVariant = sectionTransitionVariantForBoundaryOptionId(
|
|
2320
|
+
boundary.breakChoice.effectiveValue
|
|
2321
|
+
);
|
|
2322
|
+
const selectedFamily = sectionTransitionFamilyForBoundaryOptionId(
|
|
2323
|
+
boundary.breakChoice.effectiveValue
|
|
2324
|
+
) ?? sectionTransitionFamilies[0];
|
|
2325
|
+
const variantOptions = selectedFamily.variants.length > 1 ? selectedFamily.variants : null;
|
|
1583
2326
|
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-0 z-20 h-16 -translate-y-1/2", children: /* @__PURE__ */ jsxs("div", { className: "group/boundary relative flex h-full items-center justify-center", children: [
|
|
1584
2327
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-sky-500/10 opacity-0 transition-opacity duration-150 group-hover/boundary:opacity-100 group-focus-within/boundary:opacity-100" }),
|
|
1585
2328
|
/* @__PURE__ */ jsx(
|
|
1586
2329
|
"button",
|
|
1587
2330
|
{
|
|
1588
2331
|
type: "button",
|
|
1589
|
-
className: "pointer-events-auto relative z-10
|
|
2332
|
+
className: "pointer-events-auto relative z-10 flex h-12 min-w-32 items-center justify-center rounded-full opacity-0 transition hover:opacity-100 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-sky-300 group-hover/boundary:opacity-100 group-focus-within/boundary:opacity-100",
|
|
1590
2333
|
"aria-controls": open ? panelId : void 0,
|
|
1591
2334
|
"aria-expanded": open,
|
|
1592
2335
|
"aria-haspopup": "dialog",
|
|
1593
2336
|
"aria-label": "Customize section break",
|
|
1594
2337
|
onClick: openPanel,
|
|
1595
|
-
children: "Break"
|
|
2338
|
+
children: /* @__PURE__ */ jsx("span", { className: "rounded-full border border-white/20 bg-zinc-950/85 px-3 py-1 text-xs font-semibold text-white shadow-lg shadow-zinc-950/25 backdrop-blur transition hover:bg-zinc-900", children: "Break" })
|
|
1596
2339
|
}
|
|
1597
2340
|
),
|
|
1598
2341
|
open ? /* @__PURE__ */ jsxs(
|
|
@@ -1629,32 +2372,39 @@ function BoundaryControl({
|
|
|
1629
2372
|
}
|
|
1630
2373
|
)
|
|
1631
2374
|
] }),
|
|
1632
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
1633
|
-
/* @__PURE__ */ jsx(
|
|
1634
|
-
|
|
2375
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-slate-200 bg-slate-50 p-2 text-center", children: [
|
|
2376
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-sm font-medium", children: boundaryBreakLabel(boundary) }),
|
|
2377
|
+
/* @__PURE__ */ jsx("div", { className: "mt-0.5 text-xs text-slate-500", children: boundaryBreakModeLabel(boundary) })
|
|
2378
|
+
] }),
|
|
2379
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3", children: [
|
|
2380
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 text-xs font-medium text-slate-500", children: "Type" }),
|
|
2381
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1 rounded-lg border border-slate-200 bg-slate-50 p-1", children: sectionTransitionFamilies.map((family) => /* @__PURE__ */ jsx(
|
|
2382
|
+
SectionTransitionFamilyButton,
|
|
1635
2383
|
{
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
2384
|
+
family,
|
|
2385
|
+
active: selectedFamily.id === family.id,
|
|
2386
|
+
onClick: applyBoundaryOption(
|
|
2387
|
+
defaultSectionTransitionVariantForFamily(family.id).boundaryOption.id
|
|
2388
|
+
)
|
|
2389
|
+
},
|
|
2390
|
+
family.id
|
|
2391
|
+
)) })
|
|
2392
|
+
] }),
|
|
2393
|
+
variantOptions ? /* @__PURE__ */ jsxs("div", { className: "mt-3", children: [
|
|
2394
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1 text-xs font-medium text-slate-500", children: [
|
|
2395
|
+
selectedFamily.label,
|
|
2396
|
+
" style"
|
|
1646
2397
|
] }),
|
|
1647
|
-
/* @__PURE__ */ jsx(
|
|
1648
|
-
|
|
2398
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1 rounded-lg border border-slate-200 bg-slate-50 p-1", children: variantOptions.map((variant) => /* @__PURE__ */ jsx(
|
|
2399
|
+
SectionTransitionVariantButton,
|
|
1649
2400
|
{
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
] }),
|
|
2401
|
+
variant,
|
|
2402
|
+
active: selectedVariant?.boundaryOption.id === variant.boundaryOption.id,
|
|
2403
|
+
onClick: applyBoundaryOption(variant.boundaryOption.id)
|
|
2404
|
+
},
|
|
2405
|
+
variant.boundaryOption.id
|
|
2406
|
+
)) })
|
|
2407
|
+
] }) : null,
|
|
1658
2408
|
panelStatus ? /* @__PURE__ */ jsx("p", { id: panelStatus.id, className: "mt-2 text-xs text-slate-500", children: panelStatus.text }) : null,
|
|
1659
2409
|
display.canReset ? /* @__PURE__ */ jsxs(
|
|
1660
2410
|
"button",
|
|
@@ -1675,6 +2425,46 @@ function BoundaryControl({
|
|
|
1675
2425
|
) : null
|
|
1676
2426
|
] }) });
|
|
1677
2427
|
}
|
|
2428
|
+
function SectionTransitionFamilyButton({
|
|
2429
|
+
family,
|
|
2430
|
+
active,
|
|
2431
|
+
onClick
|
|
2432
|
+
}) {
|
|
2433
|
+
return /* @__PURE__ */ jsx(
|
|
2434
|
+
"button",
|
|
2435
|
+
{
|
|
2436
|
+
type: "button",
|
|
2437
|
+
className: sectionTransitionChoiceClassName(active),
|
|
2438
|
+
"aria-pressed": active,
|
|
2439
|
+
"aria-label": `Use ${family.label} section break`,
|
|
2440
|
+
onClick,
|
|
2441
|
+
children: family.label
|
|
2442
|
+
}
|
|
2443
|
+
);
|
|
2444
|
+
}
|
|
2445
|
+
function SectionTransitionVariantButton({
|
|
2446
|
+
variant,
|
|
2447
|
+
active,
|
|
2448
|
+
onClick
|
|
2449
|
+
}) {
|
|
2450
|
+
return /* @__PURE__ */ jsx(
|
|
2451
|
+
"button",
|
|
2452
|
+
{
|
|
2453
|
+
type: "button",
|
|
2454
|
+
className: sectionTransitionChoiceClassName(active),
|
|
2455
|
+
"aria-pressed": active,
|
|
2456
|
+
"aria-label": `Use ${variant.label} section break`,
|
|
2457
|
+
onClick,
|
|
2458
|
+
children: variant.label
|
|
2459
|
+
}
|
|
2460
|
+
);
|
|
2461
|
+
}
|
|
2462
|
+
function sectionTransitionChoiceClassName(active) {
|
|
2463
|
+
return [
|
|
2464
|
+
"min-h-8 flex-1 rounded-md px-2.5 text-xs font-medium transition focus:outline-none focus:ring-2 focus:ring-sky-400",
|
|
2465
|
+
active ? "bg-slate-950 text-white shadow-sm" : "bg-transparent text-slate-600 hover:bg-white hover:text-slate-950"
|
|
2466
|
+
].join(" ");
|
|
2467
|
+
}
|
|
1678
2468
|
function boundaryBreakLabel(boundary) {
|
|
1679
2469
|
return boundaryBreakDisplay(boundary).label;
|
|
1680
2470
|
}
|
|
@@ -1738,7 +2528,9 @@ function resolveRuntimePreviewSource(input) {
|
|
|
1738
2528
|
}
|
|
1739
2529
|
return { kind: "preserve-server-runtime" };
|
|
1740
2530
|
}
|
|
2531
|
+
var MAX_PREVIEW_BLOCK_DATA_BATCH_SIZE = 25;
|
|
1741
2532
|
function EditablePageRenderer(props) {
|
|
2533
|
+
const { blockDataApiClient = null, ...pageRendererProps } = props;
|
|
1742
2534
|
const { blocks } = useEntryEditorController();
|
|
1743
2535
|
const uiStore = useEditorUiStoreInstance();
|
|
1744
2536
|
const { state: pageDesignState } = usePreviewPageDesignEditorState();
|
|
@@ -1749,21 +2541,45 @@ function EditablePageRenderer(props) {
|
|
|
1749
2541
|
(state) => state.aiOverlays.hasActiveProposals()
|
|
1750
2542
|
);
|
|
1751
2543
|
const allowInlineEditing = isEditingMode && !isStreaming && !hasProposals;
|
|
1752
|
-
const isEntryTemplatePage = Boolean(
|
|
1753
|
-
const
|
|
2544
|
+
const isEntryTemplatePage = Boolean(pageRendererProps.dataContext?.contentEntry);
|
|
2545
|
+
const headerClearance = usePreviewHeaderClearance();
|
|
1754
2546
|
const cacheRef = useRef(/* @__PURE__ */ new Map());
|
|
1755
|
-
const
|
|
2547
|
+
const renderStateVersion = useEditorUiStore((state) => {
|
|
1756
2548
|
const snapshots = state.drafts.inspect();
|
|
2549
|
+
const linkedEntries = state.linkedEntries.inspect();
|
|
1757
2550
|
const overlayRevision = state.aiOverlays.revision;
|
|
1758
|
-
return
|
|
2551
|
+
return [
|
|
2552
|
+
snapshots.map((s) => `${s.id}:${s.version}`).join("|"),
|
|
2553
|
+
linkedEntries.map((entry) => `${entry.meta.entryId}:${entry.version}`).join("|"),
|
|
2554
|
+
`overlay:${overlayRevision}`
|
|
2555
|
+
].join("|");
|
|
1759
2556
|
});
|
|
2557
|
+
const linkedEntryOverlays = useMemo(() => {
|
|
2558
|
+
const overlays = /* @__PURE__ */ new Map();
|
|
2559
|
+
for (const linkedEntry of uiStore.getState().linkedEntries.inspect()) {
|
|
2560
|
+
const content = linkedEntry.current ?? linkedEntry.baseline;
|
|
2561
|
+
if (!content) continue;
|
|
2562
|
+
overlays.set(linkedEntry.meta.entryId, {
|
|
2563
|
+
content,
|
|
2564
|
+
optimisticHash: linkedEntry.meta.optimisticHash
|
|
2565
|
+
});
|
|
2566
|
+
}
|
|
2567
|
+
return overlays;
|
|
2568
|
+
}, [uiStore, renderStateVersion]);
|
|
2569
|
+
const linkedEntryDataContext = useMemo(
|
|
2570
|
+
() => applyLinkedEntryRenderOverlayToDataContext(
|
|
2571
|
+
pageRendererProps.dataContext,
|
|
2572
|
+
linkedEntryOverlays
|
|
2573
|
+
),
|
|
2574
|
+
[linkedEntryOverlays, pageRendererProps.dataContext]
|
|
2575
|
+
);
|
|
1760
2576
|
const aiProjections = useMemo(
|
|
1761
2577
|
() => previewProjectionsFromAiOverlays(uiStore.getState().aiOverlays),
|
|
1762
|
-
[uiStore,
|
|
2578
|
+
[uiStore, renderStateVersion]
|
|
1763
2579
|
);
|
|
1764
2580
|
const surfaceResolutionContext = useMemo(
|
|
1765
|
-
() => hasThemePalette(
|
|
1766
|
-
[
|
|
2581
|
+
() => hasThemePalette(pageRendererProps.theme) ? surfaceResolutionContextFromTheme(pageRendererProps.theme) : null,
|
|
2582
|
+
[pageRendererProps.theme]
|
|
1767
2583
|
);
|
|
1768
2584
|
const runtimePreviewSource = useMemo(
|
|
1769
2585
|
() => resolveRuntimePreviewSource({
|
|
@@ -1786,19 +2602,34 @@ function EditablePageRenderer(props) {
|
|
|
1786
2602
|
const mergedPage = useMemo(() => {
|
|
1787
2603
|
return composePageFromBlocks(
|
|
1788
2604
|
{
|
|
1789
|
-
page:
|
|
2605
|
+
page: pageRendererProps.page,
|
|
1790
2606
|
blockItems,
|
|
1791
2607
|
uiStore,
|
|
1792
2608
|
projections: renderProjections
|
|
1793
2609
|
},
|
|
1794
2610
|
cacheRef
|
|
1795
2611
|
);
|
|
1796
|
-
}, [
|
|
2612
|
+
}, [
|
|
2613
|
+
blockItems,
|
|
2614
|
+
pageRendererProps.page,
|
|
2615
|
+
renderProjections,
|
|
2616
|
+
uiStore,
|
|
2617
|
+
renderStateVersion
|
|
2618
|
+
]);
|
|
2619
|
+
const renderPage = mergedPage ?? pageRendererProps.page;
|
|
1797
2620
|
const wrapBlockWithProvider = useCallback(
|
|
1798
2621
|
(blockId, rendered) => {
|
|
1799
|
-
const
|
|
1800
|
-
const
|
|
1801
|
-
|
|
2622
|
+
const renderedBlocks = renderPage?.blocks ?? [];
|
|
2623
|
+
const controllerBlockIndex = blockItemsForRender.findIndex(
|
|
2624
|
+
(b) => b.id === blockId
|
|
2625
|
+
);
|
|
2626
|
+
const renderedBlockIndex = renderedBlocks.findIndex(
|
|
2627
|
+
(b) => b.id === blockId
|
|
2628
|
+
);
|
|
2629
|
+
const blockIndex = controllerBlockIndex >= 0 ? controllerBlockIndex : renderedBlockIndex;
|
|
2630
|
+
const chromeBlocks = controllerBlockIndex >= 0 ? blockItemsForRender : renderedBlocks;
|
|
2631
|
+
const block = blockIndex >= 0 ? chromeBlocks[blockIndex] ?? null : null;
|
|
2632
|
+
const previousBlock = blockIndex > 0 ? chromeBlocks[blockIndex - 1] ?? null : null;
|
|
1802
2633
|
const canonicalBlockIndex = blockItems.findIndex((b) => b.id === blockId);
|
|
1803
2634
|
const canonicalPreviousBlock = canonicalBlockIndex > 0 ? blockItems[canonicalBlockIndex - 1] ?? null : null;
|
|
1804
2635
|
const editorBlockId = unsafeAsEditorBlockId(blockId);
|
|
@@ -1839,8 +2670,12 @@ function EditablePageRenderer(props) {
|
|
|
1839
2670
|
blockId,
|
|
1840
2671
|
blockKind: block.kind,
|
|
1841
2672
|
content,
|
|
1842
|
-
theme:
|
|
1843
|
-
|
|
2673
|
+
theme: pageRendererProps.theme,
|
|
2674
|
+
placement: planBlockToolbarPlacement({
|
|
2675
|
+
blocks: chromeBlocks,
|
|
2676
|
+
blockIndex,
|
|
2677
|
+
headerClearance
|
|
2678
|
+
})
|
|
1844
2679
|
}
|
|
1845
2680
|
)
|
|
1846
2681
|
] }) : null
|
|
@@ -1854,16 +2689,29 @@ function EditablePageRenderer(props) {
|
|
|
1854
2689
|
aiProjections,
|
|
1855
2690
|
blockItems,
|
|
1856
2691
|
blockItemsForRender,
|
|
1857
|
-
|
|
2692
|
+
headerClearance,
|
|
2693
|
+
isEntryTemplatePage,
|
|
2694
|
+
pageRendererProps.theme,
|
|
1858
2695
|
renderProjections,
|
|
2696
|
+
renderPage?.blocks,
|
|
1859
2697
|
uiStore
|
|
1860
2698
|
]
|
|
1861
2699
|
);
|
|
2700
|
+
const liveResolvedData = usePreviewBlockResolvedData({
|
|
2701
|
+
page: renderPage,
|
|
2702
|
+
dataContext: linkedEntryDataContext,
|
|
2703
|
+
apiClient: blockDataApiClient
|
|
2704
|
+
});
|
|
2705
|
+
const dataContext = useMemo(
|
|
2706
|
+
() => mergeResolvedDataContext(linkedEntryDataContext, liveResolvedData),
|
|
2707
|
+
[linkedEntryDataContext, liveResolvedData]
|
|
2708
|
+
);
|
|
1862
2709
|
const rendererProps = {
|
|
1863
|
-
...
|
|
1864
|
-
page:
|
|
1865
|
-
registry: allowInlineEditing ? editorRegistry :
|
|
1866
|
-
wrapBlock: allowInlineEditing ? wrapBlockWithProvider :
|
|
2710
|
+
...pageRendererProps,
|
|
2711
|
+
page: renderPage,
|
|
2712
|
+
registry: allowInlineEditing ? editorRegistry : pageRendererProps.registry ?? clientComponentRegistry,
|
|
2713
|
+
wrapBlock: allowInlineEditing ? wrapBlockWithProvider : pageRendererProps.wrapBlock,
|
|
2714
|
+
dataContext,
|
|
1867
2715
|
// Phase 10: the legacy `isEditingMode` flag forced the renderer into
|
|
1868
2716
|
// draft-mode validation; `usePlaceholders` consolidates that into a
|
|
1869
2717
|
// narrowly-scoped fallback. The editor's contract is unchanged: a user
|
|
@@ -1875,16 +2723,258 @@ function EditablePageRenderer(props) {
|
|
|
1875
2723
|
};
|
|
1876
2724
|
return /* @__PURE__ */ jsx(PageRenderer, { ...rendererProps });
|
|
1877
2725
|
}
|
|
2726
|
+
function usePreviewBlockResolvedData(args) {
|
|
2727
|
+
const { page, dataContext, apiClient } = args;
|
|
2728
|
+
const cacheKey = useMemo(() => {
|
|
2729
|
+
if (!apiClient || !dataContext?.siteId) return null;
|
|
2730
|
+
return stableSerialize({
|
|
2731
|
+
siteId: dataContext.siteId,
|
|
2732
|
+
pageId: dataContext.pageId ?? null,
|
|
2733
|
+
previewStage: dataContext.previewStage ?? "published",
|
|
2734
|
+
blocks: page.blocks.map((block) => ({
|
|
2735
|
+
id: block.id,
|
|
2736
|
+
kind: block.kind,
|
|
2737
|
+
content: block.content ?? null,
|
|
2738
|
+
draftContent: block.draftContent ?? null,
|
|
2739
|
+
publishedContent: block.publishedContent ?? null
|
|
2740
|
+
}))
|
|
2741
|
+
});
|
|
2742
|
+
}, [apiClient, dataContext?.pageId, dataContext?.previewStage, dataContext?.siteId, page]);
|
|
2743
|
+
const [resolvedData, setResolvedData] = useState(null);
|
|
2744
|
+
useEffect(() => {
|
|
2745
|
+
if (!apiClient || !dataContext?.siteId || !cacheKey) {
|
|
2746
|
+
setResolvedData(null);
|
|
2747
|
+
return;
|
|
2748
|
+
}
|
|
2749
|
+
let cancelled = false;
|
|
2750
|
+
const context = buildPreviewBlockDataContext(dataContext);
|
|
2751
|
+
const loaderClient = createPreviewBlockDataApiClient(apiClient, context);
|
|
2752
|
+
void prefetchBlockData(page, context, {
|
|
2753
|
+
apiClient: loaderClient,
|
|
2754
|
+
isValidEndpoint: isSupportedLoaderEndpoint,
|
|
2755
|
+
onError: () => {
|
|
2756
|
+
}
|
|
2757
|
+
}).then((data) => {
|
|
2758
|
+
if (!cancelled) setResolvedData({ key: cacheKey, data });
|
|
2759
|
+
}).catch(() => {
|
|
2760
|
+
});
|
|
2761
|
+
return () => {
|
|
2762
|
+
cancelled = true;
|
|
2763
|
+
};
|
|
2764
|
+
}, [apiClient, cacheKey, dataContext, page]);
|
|
2765
|
+
return resolvedData?.data ?? null;
|
|
2766
|
+
}
|
|
2767
|
+
function buildPreviewBlockDataContext(dataContext) {
|
|
2768
|
+
return {
|
|
2769
|
+
siteId: dataContext.siteId,
|
|
2770
|
+
pageId: dataContext.pageId,
|
|
2771
|
+
previewStage: dataContext.previewStage,
|
|
2772
|
+
root: {
|
|
2773
|
+
...dataContext.routes ? { routes: dataContext.routes } : {},
|
|
2774
|
+
...dataContext.pagesByIdentifier ? { pagesByIdentifier: dataContext.pagesByIdentifier } : {},
|
|
2775
|
+
...dataContext.entriesByIdentifier ? { entriesByIdentifier: dataContext.entriesByIdentifier } : {},
|
|
2776
|
+
occurrenceContext: dataContext.occurrenceContext ?? null,
|
|
2777
|
+
entrySubrouteContext: dataContext.entrySubrouteContext ?? null,
|
|
2778
|
+
contentEntry: dataContext.contentEntry ?? null,
|
|
2779
|
+
bookingOfferingPresets: dataContext.bookingOfferingPresets ?? []
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2783
|
+
function mergeResolvedDataContext(dataContext, liveResolvedData) {
|
|
2784
|
+
if (!dataContext || !liveResolvedData) return dataContext;
|
|
2785
|
+
return {
|
|
2786
|
+
...dataContext,
|
|
2787
|
+
resolvedData: {
|
|
2788
|
+
...dataContext.resolvedData ?? {},
|
|
2789
|
+
...liveResolvedData
|
|
2790
|
+
}
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
function createPreviewBlockDataApiClient(dashboardApiClient, context) {
|
|
2794
|
+
const batcher = createMicrobatcher({
|
|
2795
|
+
maxBatchSize: MAX_PREVIEW_BLOCK_DATA_BATCH_SIZE,
|
|
2796
|
+
runBatch: async (requests) => {
|
|
2797
|
+
if (!context.siteId) {
|
|
2798
|
+
return requests.reduce((acc, request) => {
|
|
2799
|
+
acc[request.id] = {
|
|
2800
|
+
ok: false,
|
|
2801
|
+
error: { code: "missing_site_id", message: "Missing siteId" }
|
|
2802
|
+
};
|
|
2803
|
+
return acc;
|
|
2804
|
+
}, {});
|
|
2805
|
+
}
|
|
2806
|
+
const envelope = await dashboardApiClient({
|
|
2807
|
+
endpoint: "batchBlockLoaders",
|
|
2808
|
+
params: {
|
|
2809
|
+
siteId: context.siteId,
|
|
2810
|
+
stage: context.previewStage
|
|
2811
|
+
},
|
|
2812
|
+
body: { requests }
|
|
2813
|
+
});
|
|
2814
|
+
const payload = unwrapResponse(envelope);
|
|
2815
|
+
return payload.results;
|
|
2816
|
+
}
|
|
2817
|
+
});
|
|
2818
|
+
return async ({ endpoint, params }) => {
|
|
2819
|
+
if (!isSupportedLoaderEndpoint(endpoint)) {
|
|
2820
|
+
throw new Error(`Unsupported block loader endpoint: ${endpoint}`);
|
|
2821
|
+
}
|
|
2822
|
+
const normalizedParams = normalizePublicApiLoaderParams(endpoint, params, context);
|
|
2823
|
+
if (isBatchableEndpoint(endpoint)) {
|
|
2824
|
+
const batchParams = toBatchParams(endpoint, normalizedParams);
|
|
2825
|
+
const batchKey = `${endpoint}:${stableSerialize(batchParams ?? null)}`;
|
|
2826
|
+
return batcher.getOrEnqueue(
|
|
2827
|
+
batchKey,
|
|
2828
|
+
(id) => buildBatchLoaderRequest(id, endpoint, batchParams)
|
|
2829
|
+
);
|
|
2830
|
+
}
|
|
2831
|
+
return callDirectLoaderApiEndpoint(
|
|
2832
|
+
dashboardApiClient,
|
|
2833
|
+
endpoint,
|
|
2834
|
+
normalizedParams
|
|
2835
|
+
);
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
async function callDirectLoaderApiEndpoint(dashboardApiClient, endpoint, params) {
|
|
2839
|
+
switch (endpoint) {
|
|
2840
|
+
case "listPublishedEntries":
|
|
2841
|
+
return unwrapResponse(await dashboardApiClient({
|
|
2842
|
+
endpoint,
|
|
2843
|
+
params
|
|
2844
|
+
}));
|
|
2845
|
+
case "getPublishedEntryPreview":
|
|
2846
|
+
return unwrapResponse(await dashboardApiClient({
|
|
2847
|
+
endpoint,
|
|
2848
|
+
params
|
|
2849
|
+
}));
|
|
2850
|
+
case "listPublicPasses":
|
|
2851
|
+
return unwrapResponse(await dashboardApiClient({
|
|
2852
|
+
endpoint,
|
|
2853
|
+
params
|
|
2854
|
+
}));
|
|
2855
|
+
case "listPublicMemberships":
|
|
2856
|
+
return unwrapResponse(await dashboardApiClient({
|
|
2857
|
+
endpoint,
|
|
2858
|
+
params
|
|
2859
|
+
}));
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
function isBatchableEndpoint(endpoint) {
|
|
2863
|
+
return endpoint === "listPublicEvents" || endpoint === "getPublicEventDetails" || endpoint === "listPublicCourses" || endpoint === "listPublicRouteCandidates" || endpoint === "listPublicTeamMembers" || endpoint === "listPublicProducts" || endpoint === "getPublicBookingServices" || endpoint === "getPublicFormById";
|
|
2864
|
+
}
|
|
2865
|
+
function buildBatchLoaderRequest(id, endpoint, params) {
|
|
2866
|
+
switch (endpoint) {
|
|
2867
|
+
case "listPublicEvents": {
|
|
2868
|
+
const typedParams = params;
|
|
2869
|
+
return typedParams ? { id, endpoint, params: typedParams } : { id, endpoint };
|
|
2870
|
+
}
|
|
2871
|
+
case "getPublicEventDetails": {
|
|
2872
|
+
const typedParams = params;
|
|
2873
|
+
return typedParams ? { id, endpoint, params: typedParams } : { id, endpoint };
|
|
2874
|
+
}
|
|
2875
|
+
case "listPublicCourses": {
|
|
2876
|
+
const typedParams = params;
|
|
2877
|
+
return typedParams ? { id, endpoint, params: typedParams } : { id, endpoint };
|
|
2878
|
+
}
|
|
2879
|
+
case "listPublicRouteCandidates":
|
|
2880
|
+
return { id, endpoint };
|
|
2881
|
+
case "listPublicProducts": {
|
|
2882
|
+
const typedParams = params;
|
|
2883
|
+
return typedParams ? { id, endpoint, params: typedParams } : { id, endpoint };
|
|
2884
|
+
}
|
|
2885
|
+
case "listPublicTeamMembers":
|
|
2886
|
+
return { id, endpoint };
|
|
2887
|
+
case "getPublicBookingServices": {
|
|
2888
|
+
const typedParams = params;
|
|
2889
|
+
return typedParams ? { id, endpoint, params: typedParams } : { id, endpoint };
|
|
2890
|
+
}
|
|
2891
|
+
case "getPublicFormById":
|
|
2892
|
+
return {
|
|
2893
|
+
id,
|
|
2894
|
+
endpoint,
|
|
2895
|
+
params: params ?? { formId: "" }
|
|
2896
|
+
};
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
function stripUndefined(obj) {
|
|
2900
|
+
const out = {};
|
|
2901
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
2902
|
+
if (value !== void 0) out[key] = value;
|
|
2903
|
+
}
|
|
2904
|
+
return out;
|
|
2905
|
+
}
|
|
2906
|
+
function normalizeIdsParam(ids) {
|
|
2907
|
+
if (!ids) return void 0;
|
|
2908
|
+
const parts = ids.split(",").map((id) => id.trim()).filter(Boolean).sort();
|
|
2909
|
+
return parts.length ? parts.join(",") : void 0;
|
|
2910
|
+
}
|
|
2911
|
+
function toBatchParams(endpoint, params) {
|
|
2912
|
+
if (endpoint === "listPublicEvents") {
|
|
2913
|
+
const p = stripUndefined({
|
|
2914
|
+
limit: params.limit || void 0,
|
|
2915
|
+
from: params.from || void 0,
|
|
2916
|
+
to: params.to || void 0,
|
|
2917
|
+
afterStartsAt: params.afterStartsAt || void 0,
|
|
2918
|
+
afterId: params.afterId || void 0,
|
|
2919
|
+
categoryIds: params.categoryIds || void 0,
|
|
2920
|
+
venueId: params.venueId || void 0,
|
|
2921
|
+
staffMemberId: params.staffMemberId || void 0,
|
|
2922
|
+
kind: params.kind || void 0,
|
|
2923
|
+
eventSurface: params.eventSurface || void 0,
|
|
2924
|
+
eventPresets: params.eventPresets || void 0,
|
|
2925
|
+
scheduleScope: params.scheduleScope || void 0,
|
|
2926
|
+
entryId: params.entryId || void 0,
|
|
2927
|
+
seriesId: params.seriesId || void 0,
|
|
2928
|
+
includeOccurrenceId: params.includeOccurrenceId || void 0,
|
|
2929
|
+
detailLevel: params.detailLevel || void 0,
|
|
2930
|
+
readProfile: params.readProfile || void 0
|
|
2931
|
+
});
|
|
2932
|
+
return Object.keys(p).length ? p : void 0;
|
|
2933
|
+
}
|
|
2934
|
+
if (endpoint === "getPublicEventDetails") {
|
|
2935
|
+
const p = stripUndefined({
|
|
2936
|
+
limit: params.limit || void 0,
|
|
2937
|
+
from: params.from || void 0,
|
|
2938
|
+
to: params.to || void 0,
|
|
2939
|
+
afterStartsAt: params.afterStartsAt || void 0,
|
|
2940
|
+
afterId: params.afterId || void 0,
|
|
2941
|
+
categoryIds: params.categoryIds || void 0,
|
|
2942
|
+
venueId: params.venueId || void 0,
|
|
2943
|
+
staffMemberId: params.staffMemberId || void 0,
|
|
2944
|
+
kind: params.kind || void 0,
|
|
2945
|
+
eventSurface: params.eventSurface || void 0,
|
|
2946
|
+
eventPresets: params.eventPresets || void 0,
|
|
2947
|
+
scheduleScope: params.scheduleScope || void 0,
|
|
2948
|
+
entryId: params.entryId || void 0,
|
|
2949
|
+
seriesId: params.seriesId || void 0,
|
|
2950
|
+
includeOccurrenceId: params.includeOccurrenceId || void 0
|
|
2951
|
+
});
|
|
2952
|
+
return Object.keys(p).length ? p : void 0;
|
|
2953
|
+
}
|
|
2954
|
+
if (endpoint === "listPublicCourses") {
|
|
2955
|
+
const p = stripUndefined({ limit: params.limit || void 0 });
|
|
2956
|
+
return Object.keys(p).length ? p : void 0;
|
|
2957
|
+
}
|
|
2958
|
+
if (endpoint === "listPublicProducts") {
|
|
2959
|
+
const p = stripUndefined({
|
|
2960
|
+
categorySelector: decodePublicProductCategorySelectorQuery(params) ?? void 0
|
|
2961
|
+
});
|
|
2962
|
+
return Object.keys(p).length ? p : void 0;
|
|
2963
|
+
}
|
|
2964
|
+
if (endpoint === "getPublicBookingServices") {
|
|
2965
|
+
const p = stripUndefined({ ids: normalizeIdsParam(params.ids || void 0) });
|
|
2966
|
+
return Object.keys(p).length ? p : void 0;
|
|
2967
|
+
}
|
|
2968
|
+
if (endpoint === "getPublicFormById") {
|
|
2969
|
+
return { formId: params.formId ?? "" };
|
|
2970
|
+
}
|
|
2971
|
+
return void 0;
|
|
2972
|
+
}
|
|
1878
2973
|
function hasThemePalette(theme) {
|
|
1879
2974
|
return Boolean(theme?.palette);
|
|
1880
2975
|
}
|
|
1881
|
-
function shouldClearHeaderForBlock(blocks, blockIndex) {
|
|
1882
|
-
const block = blocks[blockIndex];
|
|
1883
|
-
if (block?.kind !== "block.hero") return false;
|
|
1884
|
-
return blocks.slice(0, blockIndex).every((candidate) => candidate.kind === "block.site-header");
|
|
1885
|
-
}
|
|
1886
2976
|
function usePreviewHeaderClearance() {
|
|
1887
|
-
const [clearance, setClearance] = useState(
|
|
2977
|
+
const [clearance, setClearance] = useState({ kind: "none" });
|
|
1888
2978
|
useEffect(() => {
|
|
1889
2979
|
let observedHeader = null;
|
|
1890
2980
|
let resizeObserver = null;
|
|
@@ -1899,12 +2989,19 @@ function usePreviewHeaderClearance() {
|
|
|
1899
2989
|
}
|
|
1900
2990
|
}
|
|
1901
2991
|
if (!header) {
|
|
1902
|
-
setClearance(
|
|
2992
|
+
setClearance(
|
|
2993
|
+
(current) => current.kind === "none" ? current : { kind: "none" }
|
|
2994
|
+
);
|
|
1903
2995
|
return;
|
|
1904
2996
|
}
|
|
1905
2997
|
const style = window.getComputedStyle(header);
|
|
1906
2998
|
const isOverlayHeader = style.position === "fixed" || style.position === "sticky";
|
|
1907
|
-
|
|
2999
|
+
const nextClearance = headerClearanceFromPx(
|
|
3000
|
+
isOverlayHeader ? measuredOverlayHeaderClearancePx(header) : 0
|
|
3001
|
+
);
|
|
3002
|
+
setClearance(
|
|
3003
|
+
(current) => headerClearanceEquals(current, nextClearance) ? current : nextClearance
|
|
3004
|
+
);
|
|
1908
3005
|
};
|
|
1909
3006
|
update();
|
|
1910
3007
|
const mutationObserver = new MutationObserver(update);
|
|
@@ -1923,6 +3020,15 @@ function usePreviewHeaderClearance() {
|
|
|
1923
3020
|
}, []);
|
|
1924
3021
|
return clearance;
|
|
1925
3022
|
}
|
|
3023
|
+
function headerClearanceEquals(left, right) {
|
|
3024
|
+
if (left.kind !== right.kind) return false;
|
|
3025
|
+
switch (left.kind) {
|
|
3026
|
+
case "none":
|
|
3027
|
+
return true;
|
|
3028
|
+
case "overlay":
|
|
3029
|
+
return right.kind === "overlay" && left.px === right.px;
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
1926
3032
|
function findPreviewOverlayHeader() {
|
|
1927
3033
|
return document.querySelector(
|
|
1928
3034
|
".block-site-header.rb-fixed, .block-site-header.rb-sticky"
|
|
@@ -2388,25 +3494,25 @@ var INITIAL_ONBOARDING_CONFIRMATION_STATE = {
|
|
|
2388
3494
|
resendFeedback: null,
|
|
2389
3495
|
statusLoadFailed: false
|
|
2390
3496
|
};
|
|
2391
|
-
function
|
|
3497
|
+
function isRecord5(value) {
|
|
2392
3498
|
return value !== null && typeof value === "object";
|
|
2393
3499
|
}
|
|
2394
3500
|
function getErrorMessageFromEnvelope(payload, fallback) {
|
|
2395
|
-
const error =
|
|
2396
|
-
const message =
|
|
3501
|
+
const error = isRecord5(payload) ? payload.error : null;
|
|
3502
|
+
const message = isRecord5(error) ? error.message : null;
|
|
2397
3503
|
return typeof message === "string" && message.trim().length > 0 ? message : fallback;
|
|
2398
3504
|
}
|
|
2399
3505
|
function isLaunchReadiness(value) {
|
|
2400
|
-
return
|
|
3506
|
+
return isRecord5(value) && Array.isArray(value.requirements) && typeof value.pendingRequiredCount === "number" && typeof value.pendingRecommendedCount === "number" && typeof value.pendingOptionalCount === "number" && isRecord5(value.goLiveDecision) && (value.goLiveDecision.kind === "allowed" || value.goLiveDecision.kind === "blocked");
|
|
2401
3507
|
}
|
|
2402
3508
|
function isOnboardingPreviewStatusResponse(value) {
|
|
2403
|
-
return
|
|
3509
|
+
return isRecord5(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
|
|
2404
3510
|
}
|
|
2405
3511
|
function isResendOnboardingPreviewConfirmationResponse(value) {
|
|
2406
|
-
return
|
|
3512
|
+
return isRecord5(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
|
|
2407
3513
|
}
|
|
2408
3514
|
function getSuccessData(payload, isData) {
|
|
2409
|
-
if (!
|
|
3515
|
+
if (!isRecord5(payload) || payload.success !== true || !isData(payload.data)) {
|
|
2410
3516
|
return null;
|
|
2411
3517
|
}
|
|
2412
3518
|
return payload.data;
|
|
@@ -2872,313 +3978,6 @@ function PreviewAuthBanner({
|
|
|
2872
3978
|
)
|
|
2873
3979
|
] });
|
|
2874
3980
|
}
|
|
2875
|
-
var SiteChromeCustomizeContext = createContext(null);
|
|
2876
|
-
function SiteChromeCustomizeProvider({
|
|
2877
|
-
children,
|
|
2878
|
-
siteId,
|
|
2879
|
-
apiClient,
|
|
2880
|
-
theme,
|
|
2881
|
-
themeId = null,
|
|
2882
|
-
selectionId = null,
|
|
2883
|
-
selectionVersion = null,
|
|
2884
|
-
selectionUpdatedAt = null,
|
|
2885
|
-
initialSelections,
|
|
2886
|
-
headerSelectionContext,
|
|
2887
|
-
footerSelectionContext,
|
|
2888
|
-
siteStyleAccess = { kind: "hidden" }
|
|
2889
|
-
}) {
|
|
2890
|
-
const previewDesign = usePreviewDesignCoordinator();
|
|
2891
|
-
const { clearPreview, previewTheme } = previewDesign;
|
|
2892
|
-
const runnerRef = useRef(createOptimisticActionRunner());
|
|
2893
|
-
const saveQueueRef = useRef(Promise.resolve());
|
|
2894
|
-
const latestSelectionUpdatedAtRef = useRef(
|
|
2895
|
-
initialSelections.selectionUpdatedAt ?? selectionUpdatedAt ?? null
|
|
2896
|
-
);
|
|
2897
|
-
const initialSelectionVersion = initialSelections.selectionVersion ?? selectionVersion ?? 0;
|
|
2898
|
-
const baseSnapshot = useMemo(
|
|
2899
|
-
() => resolveStyleConfiguratorInitialSnapshot({
|
|
2900
|
-
theme,
|
|
2901
|
-
initialSelections: {
|
|
2902
|
-
...initialSelections,
|
|
2903
|
-
selectionVersion: initialSelectionVersion,
|
|
2904
|
-
selectionUpdatedAt: initialSelections.selectionUpdatedAt ?? selectionUpdatedAt ?? null
|
|
2905
|
-
},
|
|
2906
|
-
headerSelectionContext,
|
|
2907
|
-
footerSelectionContext
|
|
2908
|
-
}),
|
|
2909
|
-
[footerSelectionContext, headerSelectionContext, initialSelectionVersion, initialSelections, selectionUpdatedAt, theme]
|
|
2910
|
-
);
|
|
2911
|
-
const [state, setState] = useState(
|
|
2912
|
-
() => baseSnapshot ? createStyleConfiguratorState(baseSnapshot) : null
|
|
2913
|
-
);
|
|
2914
|
-
const stateRef = useRef(state);
|
|
2915
|
-
const clearPreviewRef = useRef(clearPreview);
|
|
2916
|
-
useEffect(() => {
|
|
2917
|
-
stateRef.current = state;
|
|
2918
|
-
}, [state]);
|
|
2919
|
-
useEffect(() => {
|
|
2920
|
-
clearPreviewRef.current = clearPreview;
|
|
2921
|
-
}, [clearPreview]);
|
|
2922
|
-
useEffect(() => {
|
|
2923
|
-
latestSelectionUpdatedAtRef.current = baseSnapshot?.selectionUpdatedAt ?? null;
|
|
2924
|
-
}, [baseSnapshot?.selectionUpdatedAt]);
|
|
2925
|
-
useEffect(() => {
|
|
2926
|
-
if (!baseSnapshot) {
|
|
2927
|
-
setState(null);
|
|
2928
|
-
return;
|
|
2929
|
-
}
|
|
2930
|
-
setState(
|
|
2931
|
-
(current) => current ? syncStyleConfiguratorState(current, baseSnapshot) : createStyleConfiguratorState(baseSnapshot)
|
|
2932
|
-
);
|
|
2933
|
-
}, [baseSnapshot]);
|
|
2934
|
-
useEffect(() => {
|
|
2935
|
-
const runner = runnerRef.current;
|
|
2936
|
-
return () => {
|
|
2937
|
-
runner.invalidate();
|
|
2938
|
-
clearPreviewRef.current("site-chrome");
|
|
2939
|
-
};
|
|
2940
|
-
}, []);
|
|
2941
|
-
const lookModels = useMemo(() => {
|
|
2942
|
-
if (!state) return null;
|
|
2943
|
-
const siteStyle = getCuratedSiteStyle(state.previewed.siteStyleId);
|
|
2944
|
-
if (!siteStyle) return null;
|
|
2945
|
-
return buildSiteChromeLookModels({
|
|
2946
|
-
state,
|
|
2947
|
-
siteStyle,
|
|
2948
|
-
headerSelectionContext,
|
|
2949
|
-
footerSelectionContext
|
|
2950
|
-
});
|
|
2951
|
-
}, [footerSelectionContext, headerSelectionContext, state]);
|
|
2952
|
-
const applyAllowed = siteStyleAccess.kind === "apply-allowed";
|
|
2953
|
-
const getSurfaceState = useCallback(
|
|
2954
|
-
(surface) => {
|
|
2955
|
-
if (!state || !lookModels) return { kind: "unavailable" };
|
|
2956
|
-
if (surface === "header") {
|
|
2957
|
-
const currentLayoutId = state.previewed.headerLayoutId;
|
|
2958
|
-
const selectedLayout = lookModels.headerLayout.options.find(
|
|
2959
|
-
(option) => option.id === currentLayoutId
|
|
2960
|
-
);
|
|
2961
|
-
const renderedLayout = lookModels.headerLayout.options.find(
|
|
2962
|
-
(option) => option.id === lookModels.headerLayout.renderedLayoutId
|
|
2963
|
-
);
|
|
2964
|
-
const currentId2 = state.previewed.headerStyleId;
|
|
2965
|
-
const selected2 = lookModels.headerStyle.options.find(
|
|
2966
|
-
(option) => option.id === currentId2
|
|
2967
|
-
);
|
|
2968
|
-
const rendered2 = lookModels.headerStyle.options.find(
|
|
2969
|
-
(option) => option.id === lookModels.headerStyle.renderedStyleId
|
|
2970
|
-
);
|
|
2971
|
-
return {
|
|
2972
|
-
kind: "available",
|
|
2973
|
-
surface: "header",
|
|
2974
|
-
label: "Header",
|
|
2975
|
-
currentLayoutId,
|
|
2976
|
-
currentLayoutLabel: selectedLayout?.label ?? (renderedLayout ? `${renderedLayout.label} (default)` : "Unknown Layout"),
|
|
2977
|
-
layoutOptions: lookModels.headerLayout.options,
|
|
2978
|
-
currentId: currentId2,
|
|
2979
|
-
currentLabel: selected2?.label ?? (rendered2 ? `${rendered2.label} (default)` : "Unknown Look"),
|
|
2980
|
-
options: lookModels.headerStyle.options,
|
|
2981
|
-
diagnostics: [],
|
|
2982
|
-
saving: state.saveStatus.kind === "saving",
|
|
2983
|
-
failure: state.saveStatus.kind === "failed" ? state.saveStatus.message : null,
|
|
2984
|
-
applyAllowed
|
|
2985
|
-
};
|
|
2986
|
-
}
|
|
2987
|
-
const currentId = state.previewed.footerLookId;
|
|
2988
|
-
const selected = lookModels.footer.options.find((option) => option.id === currentId);
|
|
2989
|
-
const rendered = lookModels.footer.options.find(
|
|
2990
|
-
(option) => option.id === lookModels.footer.renderedLookId
|
|
2991
|
-
);
|
|
2992
|
-
return {
|
|
2993
|
-
kind: "available",
|
|
2994
|
-
surface: "footer",
|
|
2995
|
-
label: "Footer",
|
|
2996
|
-
currentId,
|
|
2997
|
-
currentLabel: selected?.label ?? (currentId ? "Unknown Look" : `${rendered?.label ?? "Site style"} (default)`),
|
|
2998
|
-
options: lookModels.footer.options,
|
|
2999
|
-
diagnostics: lookModels.footer.diagnostics,
|
|
3000
|
-
saving: state.saveStatus.kind === "saving",
|
|
3001
|
-
failure: state.saveStatus.kind === "failed" ? state.saveStatus.message : null,
|
|
3002
|
-
applyAllowed
|
|
3003
|
-
};
|
|
3004
|
-
},
|
|
3005
|
-
[applyAllowed, lookModels, state]
|
|
3006
|
-
);
|
|
3007
|
-
const persistSelection = useCallback(
|
|
3008
|
-
(surface, nextSnapshot) => {
|
|
3009
|
-
const siteStyle = getCuratedSiteStyle(nextSnapshot.siteStyleId);
|
|
3010
|
-
if (!siteStyle) return;
|
|
3011
|
-
const compiled = planSiteStylePreviewChange({
|
|
3012
|
-
siteStyle,
|
|
3013
|
-
selection: nextSnapshot,
|
|
3014
|
-
baseTheme: theme,
|
|
3015
|
-
headerSelectionContext,
|
|
3016
|
-
footerSelectionContext
|
|
3017
|
-
});
|
|
3018
|
-
void runnerRef.current.run({
|
|
3019
|
-
optimistic: () => {
|
|
3020
|
-
previewTheme("site-chrome", compiled.themeOverlay, "site-chrome");
|
|
3021
|
-
setState((latest) => {
|
|
3022
|
-
if (!latest) return latest;
|
|
3023
|
-
return markApplySaving({ ...latest, previewed: nextSnapshot });
|
|
3024
|
-
});
|
|
3025
|
-
},
|
|
3026
|
-
network: async () => {
|
|
3027
|
-
const runSave = async () => {
|
|
3028
|
-
const body = surface === "header" ? {
|
|
3029
|
-
surface,
|
|
3030
|
-
lookId: nextSnapshot.headerLookId,
|
|
3031
|
-
layoutId: nextSnapshot.headerLayoutId,
|
|
3032
|
-
styleId: nextSnapshot.headerStyleId,
|
|
3033
|
-
theme: compiled.themeOverlay,
|
|
3034
|
-
themeId: themeId ?? null,
|
|
3035
|
-
selectionId: selectionId ?? null,
|
|
3036
|
-
baseSelectionUpdatedAt: latestSelectionUpdatedAtRef.current
|
|
3037
|
-
} : {
|
|
3038
|
-
surface,
|
|
3039
|
-
lookId: nextSnapshot.footerLookId,
|
|
3040
|
-
theme: compiled.themeOverlay,
|
|
3041
|
-
themeId: themeId ?? null,
|
|
3042
|
-
selectionId: selectionId ?? null,
|
|
3043
|
-
baseSelectionUpdatedAt: latestSelectionUpdatedAtRef.current
|
|
3044
|
-
};
|
|
3045
|
-
const response = await apiClient({
|
|
3046
|
-
endpoint: "saveSiteChromeLookSelection",
|
|
3047
|
-
params: { siteId },
|
|
3048
|
-
body
|
|
3049
|
-
});
|
|
3050
|
-
const saved = unwrapResponse(response);
|
|
3051
|
-
latestSelectionUpdatedAtRef.current = saved.selectionUpdatedAt ?? latestSelectionUpdatedAtRef.current;
|
|
3052
|
-
return saved;
|
|
3053
|
-
};
|
|
3054
|
-
const queuedSave = saveQueueRef.current.catch(() => void 0).then(runSave);
|
|
3055
|
-
saveQueueRef.current = queuedSave.then(
|
|
3056
|
-
() => void 0,
|
|
3057
|
-
() => void 0
|
|
3058
|
-
);
|
|
3059
|
-
return queuedSave;
|
|
3060
|
-
},
|
|
3061
|
-
onSuccess: (saved) => {
|
|
3062
|
-
latestSelectionUpdatedAtRef.current = saved.selectionUpdatedAt ?? latestSelectionUpdatedAtRef.current;
|
|
3063
|
-
const persisted = {
|
|
3064
|
-
siteStyleId: nextSnapshot.siteStyleId,
|
|
3065
|
-
selectionVersion: nextSnapshot.selectionVersion,
|
|
3066
|
-
selectionUpdatedAt: saved.selectionUpdatedAt ?? nextSnapshot.selectionUpdatedAt ?? null,
|
|
3067
|
-
buttonPersonalityId: compiled.resolvedSelections.buttonPersonalityId,
|
|
3068
|
-
paletteVariantId: compiled.resolvedSelections.paletteVariantId,
|
|
3069
|
-
paletteOverrides: nextSnapshot.paletteOverrides,
|
|
3070
|
-
typographyPresetId: compiled.resolvedSelections.typographyPresetId,
|
|
3071
|
-
typographyBodyFontOverride: compiled.resolvedSelections.typographyBodyFontOverride,
|
|
3072
|
-
typographyHeadingFontOverride: compiled.resolvedSelections.typographyHeadingFontOverride,
|
|
3073
|
-
headerLookId: saved.headerLookId ?? nextSnapshot.headerLookId,
|
|
3074
|
-
headerLayoutId: saved.headerLayoutId ?? compiled.resolvedSelections.headerLayoutId,
|
|
3075
|
-
headerStyleId: saved.headerStyleId ?? compiled.resolvedSelections.headerStyleId,
|
|
3076
|
-
footerLookId: saved.footerLookId ?? nextSnapshot.footerLookId
|
|
3077
|
-
};
|
|
3078
|
-
setState((latest) => latest ? markApplySaved(latest, persisted) : latest);
|
|
3079
|
-
},
|
|
3080
|
-
onError: (error) => {
|
|
3081
|
-
const message = error instanceof Error ? error.message : "Unable to apply your selection.";
|
|
3082
|
-
setState((latest) => latest ? markApplyFailed(latest, message) : latest);
|
|
3083
|
-
}
|
|
3084
|
-
});
|
|
3085
|
-
},
|
|
3086
|
-
[
|
|
3087
|
-
apiClient,
|
|
3088
|
-
footerSelectionContext,
|
|
3089
|
-
headerSelectionContext,
|
|
3090
|
-
previewTheme,
|
|
3091
|
-
selectionId,
|
|
3092
|
-
siteId,
|
|
3093
|
-
themeId,
|
|
3094
|
-
theme
|
|
3095
|
-
]
|
|
3096
|
-
);
|
|
3097
|
-
const selectHeaderStyle = useCallback(
|
|
3098
|
-
(styleId) => {
|
|
3099
|
-
if (!applyAllowed) return;
|
|
3100
|
-
const current = stateRef.current;
|
|
3101
|
-
if (!current) return;
|
|
3102
|
-
const nextState = previewHeaderStyle(current, styleId);
|
|
3103
|
-
persistSelection("header", nextState.previewed);
|
|
3104
|
-
},
|
|
3105
|
-
[applyAllowed, persistSelection]
|
|
3106
|
-
);
|
|
3107
|
-
const selectHeaderLayout = useCallback(
|
|
3108
|
-
(layoutId) => {
|
|
3109
|
-
if (!applyAllowed) return;
|
|
3110
|
-
const current = stateRef.current;
|
|
3111
|
-
if (!current) return;
|
|
3112
|
-
const nextState = previewHeaderLayout(current, layoutId);
|
|
3113
|
-
persistSelection("header", nextState.previewed);
|
|
3114
|
-
},
|
|
3115
|
-
[applyAllowed, persistSelection]
|
|
3116
|
-
);
|
|
3117
|
-
const selectFooterLook = useCallback(
|
|
3118
|
-
(lookId) => {
|
|
3119
|
-
if (!applyAllowed) return;
|
|
3120
|
-
const current = stateRef.current;
|
|
3121
|
-
if (!current) return;
|
|
3122
|
-
const nextState = previewFooterLook(current, planFooterLookSelection(lookId));
|
|
3123
|
-
persistSelection("footer", nextState.previewed);
|
|
3124
|
-
},
|
|
3125
|
-
[applyAllowed, persistSelection]
|
|
3126
|
-
);
|
|
3127
|
-
const cycleSurfaceLook = useCallback(
|
|
3128
|
-
(surface, direction) => {
|
|
3129
|
-
const currentState = getSurfaceState(surface);
|
|
3130
|
-
if (currentState.kind !== "available") return;
|
|
3131
|
-
if (currentState.surface === "header") {
|
|
3132
|
-
const next2 = cycleSiteChromeLookId(
|
|
3133
|
-
currentState.options,
|
|
3134
|
-
currentState.currentId,
|
|
3135
|
-
direction
|
|
3136
|
-
);
|
|
3137
|
-
if (next2 !== void 0 && next2 !== null) selectHeaderStyle(next2);
|
|
3138
|
-
return;
|
|
3139
|
-
}
|
|
3140
|
-
const next = cycleSiteChromeLookId(
|
|
3141
|
-
currentState.options,
|
|
3142
|
-
currentState.currentId,
|
|
3143
|
-
direction
|
|
3144
|
-
);
|
|
3145
|
-
if (next !== void 0) selectFooterLook(next);
|
|
3146
|
-
},
|
|
3147
|
-
[getSurfaceState, selectFooterLook, selectHeaderStyle]
|
|
3148
|
-
);
|
|
3149
|
-
const cycleSurfaceLayout = useCallback(
|
|
3150
|
-
(surface, direction) => {
|
|
3151
|
-
const currentState = getSurfaceState(surface);
|
|
3152
|
-
if (currentState.kind !== "available" || currentState.surface !== "header") {
|
|
3153
|
-
return;
|
|
3154
|
-
}
|
|
3155
|
-
const next = cycleSiteChromeLookId(
|
|
3156
|
-
currentState.layoutOptions,
|
|
3157
|
-
currentState.currentLayoutId,
|
|
3158
|
-
direction
|
|
3159
|
-
);
|
|
3160
|
-
if (next !== void 0 && next !== null) selectHeaderLayout(next);
|
|
3161
|
-
},
|
|
3162
|
-
[getSurfaceState, selectHeaderLayout]
|
|
3163
|
-
);
|
|
3164
|
-
const value = useMemo(
|
|
3165
|
-
() => ({
|
|
3166
|
-
getSurfaceState,
|
|
3167
|
-
cycleSurfaceLook,
|
|
3168
|
-
cycleSurfaceLayout
|
|
3169
|
-
}),
|
|
3170
|
-
[cycleSurfaceLayout, cycleSurfaceLook, getSurfaceState]
|
|
3171
|
-
);
|
|
3172
|
-
return /* @__PURE__ */ jsx(SiteChromeCustomizeContext.Provider, { value, children });
|
|
3173
|
-
}
|
|
3174
|
-
function planFooterLookSelection(lookId) {
|
|
3175
|
-
const plan = planSiteChromeLookSelection({ surface: "footer", lookId });
|
|
3176
|
-
if (plan.kind !== "footer") return lookId;
|
|
3177
|
-
return plan.next.footerLookId;
|
|
3178
|
-
}
|
|
3179
|
-
function useSiteChromeCustomizeOptional() {
|
|
3180
|
-
return useContext(SiteChromeCustomizeContext);
|
|
3181
|
-
}
|
|
3182
3981
|
|
|
3183
3982
|
// ../blocks/src/client/site-chrome.tsx
|
|
3184
3983
|
function renderSiteChromeBlock(model, surface, theme, options = {}) {
|
|
@@ -3212,22 +4011,7 @@ function SiteChromeCustomizeButton({
|
|
|
3212
4011
|
containerClassName = "pointer-events-auto absolute right-2 top-2 z-50 opacity-0 transition group-focus-within/site-chrome:opacity-100 group-hover/site-chrome:opacity-100"
|
|
3213
4012
|
}) {
|
|
3214
4013
|
const customize = useSiteChromeCustomizeOptional();
|
|
3215
|
-
const
|
|
3216
|
-
const customizeDescriptionId = `${customizePanelId}-description`;
|
|
3217
|
-
const [customizeOpen, setCustomizeOpen] = useState(false);
|
|
3218
|
-
const customizeButtonRef = useRef(null);
|
|
3219
|
-
const closeCustomize = useCallback(() => {
|
|
3220
|
-
setCustomizeOpen(false);
|
|
3221
|
-
}, []);
|
|
3222
|
-
const {
|
|
3223
|
-
dialogRef: customizeDialogRef,
|
|
3224
|
-
registerInitialFocus: registerCustomizeInitialFocus,
|
|
3225
|
-
setReturnFocusTarget: setCustomizeReturnFocusTarget,
|
|
3226
|
-
handleDialogKeyDown: handleCustomizeDialogKeyDown
|
|
3227
|
-
} = useDialogFocusTrap({
|
|
3228
|
-
open: customizeOpen,
|
|
3229
|
-
onClose: closeCustomize
|
|
3230
|
-
});
|
|
4014
|
+
const popover = useCustomizePopoverController();
|
|
3231
4015
|
const surfaceState = customize?.getSurfaceState(surface) ?? {
|
|
3232
4016
|
kind: "unavailable"
|
|
3233
4017
|
};
|
|
@@ -3242,157 +4026,133 @@ function SiteChromeCustomizeButton({
|
|
|
3242
4026
|
}
|
|
3243
4027
|
return surfaceState.layoutOptions.filter((option) => option.available).length;
|
|
3244
4028
|
}, [surfaceState]);
|
|
3245
|
-
const
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
4029
|
+
const controlPlan = useMemo(() => {
|
|
4030
|
+
if (surfaceState.kind !== "available") return { cycleRows: [] };
|
|
4031
|
+
return {
|
|
4032
|
+
cycleRows: [
|
|
4033
|
+
...surfaceState.surface === "header" ? [
|
|
4034
|
+
{
|
|
4035
|
+
label: "Layout",
|
|
4036
|
+
valueLabel: surfaceState.currentLayoutLabel,
|
|
4037
|
+
previousLabel: `Previous ${surface} Layout`,
|
|
4038
|
+
nextLabel: `Next ${surface} Layout`,
|
|
4039
|
+
availability: cycleAvailabilityFromFlags({
|
|
4040
|
+
canCycle: cycleableLayoutOptionCount > 1,
|
|
4041
|
+
applyAllowed: surfaceState.applyAllowed
|
|
4042
|
+
}),
|
|
4043
|
+
onPrevious: () => customize?.cycleSurfaceLayout(surface, "prev"),
|
|
4044
|
+
onNext: () => customize?.cycleSurfaceLayout(surface, "next")
|
|
4045
|
+
}
|
|
4046
|
+
] : [],
|
|
4047
|
+
{
|
|
4048
|
+
label: "Look",
|
|
4049
|
+
valueLabel: surfaceState.currentLabel,
|
|
4050
|
+
previousLabel: `Previous ${surface} Look`,
|
|
4051
|
+
nextLabel: `Next ${surface} Look`,
|
|
4052
|
+
availability: cycleAvailabilityFromFlags({
|
|
4053
|
+
canCycle: cycleableOptionCount > 1,
|
|
4054
|
+
applyAllowed: surfaceState.applyAllowed
|
|
4055
|
+
}),
|
|
4056
|
+
onPrevious: () => customize?.cycleSurfaceLook(surface, "prev"),
|
|
4057
|
+
onNext: () => customize?.cycleSurfaceLook(surface, "next")
|
|
4058
|
+
}
|
|
4059
|
+
]
|
|
4060
|
+
};
|
|
4061
|
+
}, [
|
|
4062
|
+
customize,
|
|
4063
|
+
cycleableLayoutOptionCount,
|
|
4064
|
+
cycleableOptionCount,
|
|
4065
|
+
surface,
|
|
4066
|
+
surfaceState
|
|
4067
|
+
]);
|
|
4068
|
+
return /* @__PURE__ */ jsxs(
|
|
4069
|
+
PreviewChromeFloatingControl,
|
|
4070
|
+
{
|
|
4071
|
+
anchorSelector: "[data-preview-site-chrome-surface]",
|
|
4072
|
+
placement: (anchorBox) => planSiteChromeCustomizePlacement({ surface, anchorBox }),
|
|
4073
|
+
fallbackClassName: containerClassName,
|
|
4074
|
+
forceVisible: popover.open,
|
|
4075
|
+
children: [
|
|
4076
|
+
/* @__PURE__ */ jsx(
|
|
4077
|
+
CustomizePillButton,
|
|
4078
|
+
{
|
|
4079
|
+
buttonRef: popover.buttonRef,
|
|
4080
|
+
ariaLabel: `Customize ${surface}`,
|
|
4081
|
+
open: popover.open,
|
|
4082
|
+
controlsId: popover.panelId,
|
|
4083
|
+
onClick: popover.toggle,
|
|
4084
|
+
disabled: !hasCustomizeControls
|
|
4085
|
+
}
|
|
4086
|
+
),
|
|
4087
|
+
popover.open && surfaceState.kind === "available" ? /* @__PURE__ */ jsxs(
|
|
4088
|
+
CustomizePopoverShell,
|
|
4089
|
+
{
|
|
4090
|
+
panelId: popover.panelId,
|
|
4091
|
+
descriptionId: popover.descriptionId,
|
|
4092
|
+
dialogLabel: `Customize ${surface}`,
|
|
4093
|
+
eyebrow: "Site",
|
|
4094
|
+
title: surfaceState.label,
|
|
4095
|
+
dialogRef: popover.dialogRef,
|
|
4096
|
+
closeButtonRef: popover.registerInitialFocus,
|
|
4097
|
+
onClose: popover.close,
|
|
4098
|
+
onKeyDown: popover.handleDialogKeyDown,
|
|
4099
|
+
children: [
|
|
4100
|
+
controlPlan.cycleRows.map((row) => /* @__PURE__ */ jsx(CustomizeCycleRow, { ...row }, row.label)),
|
|
4101
|
+
surfaceState.surface === "header" ? /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 border-t pt-3", children: [
|
|
4102
|
+
/* @__PURE__ */ jsxs("label", { className: "block text-xs font-medium text-muted-foreground", children: [
|
|
4103
|
+
/* @__PURE__ */ jsx("span", { children: "Display" }),
|
|
4104
|
+
/* @__PURE__ */ jsx(
|
|
4105
|
+
"select",
|
|
4106
|
+
{
|
|
4107
|
+
className: "mt-1 h-8 w-full rounded-md border bg-background px-2 text-sm text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
4108
|
+
value: surfaceState.brandDisplay,
|
|
4109
|
+
onChange: (event) => {
|
|
4110
|
+
event.stopPropagation();
|
|
4111
|
+
customize?.setHeaderBrandDisplay(
|
|
4112
|
+
event.currentTarget.value
|
|
4113
|
+
);
|
|
4114
|
+
},
|
|
4115
|
+
disabled: !surfaceState.applyAllowed,
|
|
4116
|
+
children: surfaceState.brandDisplayOptions.map((option) => /* @__PURE__ */ jsx(
|
|
4117
|
+
"option",
|
|
4118
|
+
{
|
|
4119
|
+
value: option.value,
|
|
4120
|
+
disabled: option.disabled,
|
|
4121
|
+
children: option.label
|
|
4122
|
+
},
|
|
4123
|
+
option.value
|
|
4124
|
+
))
|
|
4125
|
+
}
|
|
4126
|
+
)
|
|
4127
|
+
] }),
|
|
4128
|
+
/* @__PURE__ */ jsxs("label", { className: "block text-xs font-medium text-muted-foreground", children: [
|
|
4129
|
+
/* @__PURE__ */ jsx("span", { children: "Logo size" }),
|
|
4130
|
+
/* @__PURE__ */ jsx(
|
|
4131
|
+
"select",
|
|
4132
|
+
{
|
|
4133
|
+
className: "mt-1 h-8 w-full rounded-md border bg-background px-2 text-sm text-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
4134
|
+
value: surfaceState.logoSize,
|
|
4135
|
+
onChange: (event) => {
|
|
4136
|
+
event.stopPropagation();
|
|
4137
|
+
customize?.setHeaderLogoSize(
|
|
4138
|
+
event.currentTarget.value
|
|
4139
|
+
);
|
|
4140
|
+
},
|
|
4141
|
+
disabled: !surfaceState.applyAllowed,
|
|
4142
|
+
children: surfaceState.logoSizeOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
|
|
4143
|
+
}
|
|
4144
|
+
)
|
|
4145
|
+
] })
|
|
4146
|
+
] }) : null,
|
|
4147
|
+
surfaceState.diagnostics.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-1 text-xs text-amber-700", children: surfaceState.diagnostics.map((diagnostic) => /* @__PURE__ */ jsx("li", { children: diagnostic }, diagnostic)) }) : null,
|
|
4148
|
+
surfaceState.failure ? /* @__PURE__ */ jsx("p", { className: "text-xs text-red-700", children: surfaceState.failure }) : null,
|
|
4149
|
+
!surfaceState.applyAllowed ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Preview only - ask an admin to apply." }) : null
|
|
4150
|
+
]
|
|
4151
|
+
}
|
|
4152
|
+
) : null
|
|
4153
|
+
]
|
|
3252
4154
|
}
|
|
3253
|
-
|
|
3254
|
-
};
|
|
3255
|
-
return /* @__PURE__ */ jsxs("div", { className: containerClassName, children: [
|
|
3256
|
-
/* @__PURE__ */ jsx(
|
|
3257
|
-
"button",
|
|
3258
|
-
{
|
|
3259
|
-
ref: customizeButtonRef,
|
|
3260
|
-
type: "button",
|
|
3261
|
-
onClick: toggleCustomize,
|
|
3262
|
-
className: previewCustomizePillButtonClassName,
|
|
3263
|
-
"aria-label": `Customize ${surface}`,
|
|
3264
|
-
"aria-expanded": customizeOpen,
|
|
3265
|
-
"aria-haspopup": "dialog",
|
|
3266
|
-
"aria-controls": customizeOpen ? customizePanelId : void 0,
|
|
3267
|
-
disabled: !hasCustomizeControls,
|
|
3268
|
-
children: surfaceState.kind === "available" && surfaceState.saving ? "Saving..." : "Customize"
|
|
3269
|
-
}
|
|
3270
|
-
),
|
|
3271
|
-
customizeOpen && surfaceState.kind === "available" ? /* @__PURE__ */ jsxs(
|
|
3272
|
-
"div",
|
|
3273
|
-
{
|
|
3274
|
-
id: customizePanelId,
|
|
3275
|
-
className: "builder-dashboard-chrome-theme fixed inset-x-3 bottom-[calc(var(--builder-editor-chrome-offset,0px)+1rem)] z-[70] rounded-lg border bg-background p-3 text-foreground shadow-xl sm:absolute sm:inset-x-auto sm:bottom-auto sm:right-0 sm:top-9 sm:w-72",
|
|
3276
|
-
role: "dialog",
|
|
3277
|
-
"aria-modal": "true",
|
|
3278
|
-
"aria-label": `Customize ${surface}`,
|
|
3279
|
-
"aria-describedby": customizeDescriptionId,
|
|
3280
|
-
ref: customizeDialogRef,
|
|
3281
|
-
onKeyDown: handleCustomizeDialogKeyDown,
|
|
3282
|
-
onClick: (event) => event.stopPropagation(),
|
|
3283
|
-
children: [
|
|
3284
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-start justify-between gap-3", children: [
|
|
3285
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3286
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium uppercase text-muted-foreground", children: "Site" }),
|
|
3287
|
-
/* @__PURE__ */ jsx(
|
|
3288
|
-
"div",
|
|
3289
|
-
{
|
|
3290
|
-
id: customizeDescriptionId,
|
|
3291
|
-
className: "text-sm font-semibold",
|
|
3292
|
-
children: surfaceState.label
|
|
3293
|
-
}
|
|
3294
|
-
)
|
|
3295
|
-
] }),
|
|
3296
|
-
/* @__PURE__ */ jsx(
|
|
3297
|
-
"button",
|
|
3298
|
-
{
|
|
3299
|
-
ref: registerCustomizeInitialFocus,
|
|
3300
|
-
type: "button",
|
|
3301
|
-
className: "rounded-full px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
3302
|
-
onClick: (event) => {
|
|
3303
|
-
event.preventDefault();
|
|
3304
|
-
event.stopPropagation();
|
|
3305
|
-
closeCustomize();
|
|
3306
|
-
},
|
|
3307
|
-
children: "Close"
|
|
3308
|
-
}
|
|
3309
|
-
)
|
|
3310
|
-
] }),
|
|
3311
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
3312
|
-
surfaceState.surface === "header" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3313
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3314
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: "Layout" }),
|
|
3315
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: surfaceState.currentLayoutLabel })
|
|
3316
|
-
] }),
|
|
3317
|
-
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center overflow-hidden rounded-full border bg-background", children: [
|
|
3318
|
-
/* @__PURE__ */ jsx(
|
|
3319
|
-
"button",
|
|
3320
|
-
{
|
|
3321
|
-
type: "button",
|
|
3322
|
-
onClick: (event) => {
|
|
3323
|
-
event.preventDefault();
|
|
3324
|
-
event.stopPropagation();
|
|
3325
|
-
customize?.cycleSurfaceLayout(surface, "prev");
|
|
3326
|
-
},
|
|
3327
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
3328
|
-
"aria-label": `Previous ${surface} Layout`,
|
|
3329
|
-
disabled: surfaceState.saving || !surfaceState.applyAllowed || cycleableLayoutOptionCount <= 1,
|
|
3330
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
3331
|
-
}
|
|
3332
|
-
),
|
|
3333
|
-
/* @__PURE__ */ jsx(
|
|
3334
|
-
"button",
|
|
3335
|
-
{
|
|
3336
|
-
type: "button",
|
|
3337
|
-
onClick: (event) => {
|
|
3338
|
-
event.preventDefault();
|
|
3339
|
-
event.stopPropagation();
|
|
3340
|
-
customize?.cycleSurfaceLayout(surface, "next");
|
|
3341
|
-
},
|
|
3342
|
-
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
3343
|
-
"aria-label": `Next ${surface} Layout`,
|
|
3344
|
-
disabled: surfaceState.saving || !surfaceState.applyAllowed || cycleableLayoutOptionCount <= 1,
|
|
3345
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
3346
|
-
}
|
|
3347
|
-
)
|
|
3348
|
-
] })
|
|
3349
|
-
] }) : null,
|
|
3350
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3351
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
3352
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: "Look" }),
|
|
3353
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: surfaceState.currentLabel })
|
|
3354
|
-
] }),
|
|
3355
|
-
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center overflow-hidden rounded-full border bg-background", children: [
|
|
3356
|
-
/* @__PURE__ */ jsx(
|
|
3357
|
-
"button",
|
|
3358
|
-
{
|
|
3359
|
-
type: "button",
|
|
3360
|
-
onClick: (event) => {
|
|
3361
|
-
event.preventDefault();
|
|
3362
|
-
event.stopPropagation();
|
|
3363
|
-
customize?.cycleSurfaceLook(surface, "prev");
|
|
3364
|
-
},
|
|
3365
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
3366
|
-
"aria-label": `Previous ${surface} Look`,
|
|
3367
|
-
disabled: surfaceState.saving || !surfaceState.applyAllowed || cycleableOptionCount <= 1,
|
|
3368
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
3369
|
-
}
|
|
3370
|
-
),
|
|
3371
|
-
/* @__PURE__ */ jsx(
|
|
3372
|
-
"button",
|
|
3373
|
-
{
|
|
3374
|
-
type: "button",
|
|
3375
|
-
onClick: (event) => {
|
|
3376
|
-
event.preventDefault();
|
|
3377
|
-
event.stopPropagation();
|
|
3378
|
-
customize?.cycleSurfaceLook(surface, "next");
|
|
3379
|
-
},
|
|
3380
|
-
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
3381
|
-
"aria-label": `Next ${surface} Look`,
|
|
3382
|
-
disabled: surfaceState.saving || !surfaceState.applyAllowed || cycleableOptionCount <= 1,
|
|
3383
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
3384
|
-
}
|
|
3385
|
-
)
|
|
3386
|
-
] })
|
|
3387
|
-
] }),
|
|
3388
|
-
surfaceState.diagnostics.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "space-y-1 text-xs text-amber-700", children: surfaceState.diagnostics.map((diagnostic) => /* @__PURE__ */ jsx("li", { children: diagnostic }, diagnostic)) }) : null,
|
|
3389
|
-
surfaceState.failure ? /* @__PURE__ */ jsx("p", { className: "text-xs text-red-700", children: surfaceState.failure }) : null,
|
|
3390
|
-
!surfaceState.applyAllowed ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Preview only - ask an admin to apply." }) : null
|
|
3391
|
-
] })
|
|
3392
|
-
]
|
|
3393
|
-
}
|
|
3394
|
-
) : null
|
|
3395
|
-
] });
|
|
4155
|
+
);
|
|
3396
4156
|
}
|
|
3397
4157
|
function SiteChromeEditableSurface({
|
|
3398
4158
|
surface,
|
|
@@ -3410,7 +4170,7 @@ function renderEditableSurface(children, surface, options) {
|
|
|
3410
4170
|
const child = childArray.length === 1 ? childArray[0] : null;
|
|
3411
4171
|
if (isValidElement(child) && child.type !== Fragment$1 && (isHostElement(child) || options.preserveSingleComponentRoot || isEditableSurfaceForwardingElement(child))) {
|
|
3412
4172
|
return cloneElement(child, {
|
|
3413
|
-
className:
|
|
4173
|
+
className: joinClassNames2(child.props.className, "group/site-chrome relative"),
|
|
3414
4174
|
"data-preview-site-chrome-surface": surface,
|
|
3415
4175
|
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3416
4176
|
child.props.children,
|
|
@@ -3449,7 +4209,7 @@ function isHostElement(child) {
|
|
|
3449
4209
|
function isEditableSurfaceForwardingElement(child) {
|
|
3450
4210
|
return typeof child.type !== "string" && child.type !== Fragment$1 && child.type[EDITABLE_SURFACE_FORWARDING_PROP] === true;
|
|
3451
4211
|
}
|
|
3452
|
-
function
|
|
4212
|
+
function joinClassNames2(...values) {
|
|
3453
4213
|
const className = values.filter(Boolean).join(" ");
|
|
3454
4214
|
return className.length > 0 ? className : void 0;
|
|
3455
4215
|
}
|
|
@@ -3631,13 +4391,27 @@ function renderPreviewDocument({
|
|
|
3631
4391
|
}
|
|
3632
4392
|
return null;
|
|
3633
4393
|
}
|
|
4394
|
+
function LinkedEntryEditEventBridge() {
|
|
4395
|
+
const uiStore = useEditorUiStoreInstance();
|
|
4396
|
+
useEffect(() => {
|
|
4397
|
+
const handleLinkedEntryEdit = (event) => {
|
|
4398
|
+
if (!isLinkedEntryEditEvent(event)) return;
|
|
4399
|
+
uiStore.getState().linkedEntries.open(event.detail);
|
|
4400
|
+
};
|
|
4401
|
+
window.addEventListener(LINKED_ENTRY_EDIT_EVENT, handleLinkedEntryEdit);
|
|
4402
|
+
return () => {
|
|
4403
|
+
window.removeEventListener(LINKED_ENTRY_EDIT_EVENT, handleLinkedEntryEdit);
|
|
4404
|
+
};
|
|
4405
|
+
}, [uiStore]);
|
|
4406
|
+
return null;
|
|
4407
|
+
}
|
|
3634
4408
|
var previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
|
|
3635
|
-
var PreviewEditorSidebar =
|
|
3636
|
-
const mod = await import('./PreviewEditorSidebar-
|
|
4409
|
+
var PreviewEditorSidebar = React10.lazy(async () => {
|
|
4410
|
+
const mod = await import('./PreviewEditorSidebar-RDCMEXIJ.mjs');
|
|
3637
4411
|
return { default: mod.PreviewEditorSidebar };
|
|
3638
4412
|
});
|
|
3639
|
-
var PreviewEditorUI =
|
|
3640
|
-
const mod = await import('./PreviewEditorUI-
|
|
4413
|
+
var PreviewEditorUI = React10.lazy(async () => {
|
|
4414
|
+
const mod = await import('./PreviewEditorUI-NYGQ6K7B.mjs');
|
|
3641
4415
|
return { default: mod.PreviewEditorUI };
|
|
3642
4416
|
});
|
|
3643
4417
|
var previewPaneContainmentStyle = {
|
|
@@ -3853,7 +4627,7 @@ function PreviewShellLayout({
|
|
|
3853
4627
|
{
|
|
3854
4628
|
className: "relative flex h-full min-h-0 flex-col overflow-auto bg-muted/30",
|
|
3855
4629
|
style: previewPaneContainmentStyle,
|
|
3856
|
-
children: /* @__PURE__ */ jsx(
|
|
4630
|
+
children: /* @__PURE__ */ jsx(PreviewChromeLayerProvider, { children: /* @__PURE__ */ jsx(
|
|
3857
4631
|
PreviewThemedSiteDocument,
|
|
3858
4632
|
{
|
|
3859
4633
|
useThemeScope,
|
|
@@ -3870,7 +4644,7 @@ function PreviewShellLayout({
|
|
|
3870
4644
|
siteChromeRenderModel,
|
|
3871
4645
|
children
|
|
3872
4646
|
}
|
|
3873
|
-
)
|
|
4647
|
+
) })
|
|
3874
4648
|
}
|
|
3875
4649
|
);
|
|
3876
4650
|
const rightPane = /* @__PURE__ */ jsx(
|
|
@@ -3878,7 +4652,7 @@ function PreviewShellLayout({
|
|
|
3878
4652
|
{
|
|
3879
4653
|
className: `${PREVIEW_CHROME_THEME_CLASS_NAME} flex h-full min-h-0 flex-col overflow-hidden ${surfaceDocument.surfaceClassName ?? ""}`,
|
|
3880
4654
|
...getPreviewChromeSurfaceDataProps(surfaceDocument),
|
|
3881
|
-
children: /* @__PURE__ */ jsx(
|
|
4655
|
+
children: /* @__PURE__ */ jsx(React10.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
3882
4656
|
PreviewEditorSidebar,
|
|
3883
4657
|
{
|
|
3884
4658
|
surfaceId,
|
|
@@ -3933,7 +4707,7 @@ function PreviewShellLayout({
|
|
|
3933
4707
|
) })
|
|
3934
4708
|
}
|
|
3935
4709
|
);
|
|
3936
|
-
const editorUI = /* @__PURE__ */ jsx(
|
|
4710
|
+
const editorUI = /* @__PURE__ */ jsx(React10.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
3937
4711
|
PreviewEditorUI,
|
|
3938
4712
|
{
|
|
3939
4713
|
inMaintenanceMode: maintenanceModeEnabled,
|
|
@@ -3978,6 +4752,7 @@ function PreviewShellLayout({
|
|
|
3978
4752
|
footerSelectionContext: themeSelectionFooterContext,
|
|
3979
4753
|
siteStyleAccess,
|
|
3980
4754
|
children: /* @__PURE__ */ jsxs(PreviewBlockCustomizeSelectionProvider, { children: [
|
|
4755
|
+
/* @__PURE__ */ jsx(LinkedEntryEditEventBridge, {}),
|
|
3981
4756
|
editorUI,
|
|
3982
4757
|
previewBanner,
|
|
3983
4758
|
/* @__PURE__ */ jsx("div", { className: "fixed inset-0 overflow-hidden bg-background", children: isOpen ? /* @__PURE__ */ jsx(
|
|
@@ -4077,7 +4852,7 @@ function PreviewShell({
|
|
|
4077
4852
|
initialBlocks,
|
|
4078
4853
|
pageMetadata,
|
|
4079
4854
|
apiClient,
|
|
4080
|
-
children: /* @__PURE__ */ jsx(
|
|
4855
|
+
children: /* @__PURE__ */ jsx(PreviewDesignHistoryOrderProvider, { children: /* @__PURE__ */ jsx(
|
|
4081
4856
|
PreviewPageDesignEditorStateProvider,
|
|
4082
4857
|
{
|
|
4083
4858
|
apiClient,
|
|
@@ -4141,7 +4916,7 @@ function PreviewShell({
|
|
|
4141
4916
|
}
|
|
4142
4917
|
)
|
|
4143
4918
|
}
|
|
4144
|
-
)
|
|
4919
|
+
) })
|
|
4145
4920
|
}
|
|
4146
4921
|
) })
|
|
4147
4922
|
}
|
|
@@ -4156,17 +4931,6 @@ function defaultDesignEditorEligibility(input) {
|
|
|
4156
4931
|
}
|
|
4157
4932
|
return { kind: "unsupported" };
|
|
4158
4933
|
}
|
|
4159
|
-
|
|
4160
|
-
// ../preview-next/src/client/preview/previewSurface.ts
|
|
4161
|
-
function resolvePreviewSurfaceIdFromSearch(search) {
|
|
4162
|
-
return parseSurfaceId(new URLSearchParams(search).get(PREVIEW_SURFACE_PARAM));
|
|
4163
|
-
}
|
|
4164
|
-
function resolvePreviewSurfaceId() {
|
|
4165
|
-
if (typeof window === "undefined") {
|
|
4166
|
-
return null;
|
|
4167
|
-
}
|
|
4168
|
-
return resolvePreviewSurfaceIdFromSearch(window.location.search);
|
|
4169
|
-
}
|
|
4170
4934
|
function SdkPreviewModeRuntime(props) {
|
|
4171
4935
|
const {
|
|
4172
4936
|
apiBaseUrl,
|
|
@@ -4180,7 +4944,7 @@ function SdkPreviewModeRuntime(props) {
|
|
|
4180
4944
|
useThemeScope = true
|
|
4181
4945
|
} = props;
|
|
4182
4946
|
const resolvedDashboardBaseUrl = dashboardBaseUrl ?? deriveDashboardBaseUrlFromApiBaseUrl(apiBaseUrl);
|
|
4183
|
-
const surfaceId = props.surfaceId ??
|
|
4947
|
+
const surfaceId = props.surfaceId ?? DEFAULT_SURFACE_ID;
|
|
4184
4948
|
const theme = content.theme;
|
|
4185
4949
|
const page = content.page;
|
|
4186
4950
|
const routeMap = content.routeMap ?? void 0;
|