@riverbankcms/sdk 0.104.3 → 0.108.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/README.md +84 -51
- package/dist/{PreviewEditorSidebar-CBMhU9p_.mjs → PreviewEditorSidebar-BBT-kZAM.mjs} +1850 -1183
- package/dist/{PreviewEditorUI-C5KEw4M8.mjs → PreviewEditorUI-D69xNKT2.mjs} +10 -9
- package/dist/{PreviewQueryProvider-CStABBUh.mjs → PreviewQueryProvider-RRu7wyQ5.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-Iq12HjL7.mjs → SdkPreviewModeRuntime-CuDjXH6o.mjs} +2562 -457
- package/dist/{SiteChromeCustomizeContext-Cx0NMdyv.mjs → SiteChromeCustomizeContext-BQUY2dEk.mjs} +7689 -3196
- package/dist/_dts/ai/src/contracts/proposals.d.ts +36493 -1395
- package/dist/_dts/api/src/blocks.d.ts +41 -7
- package/dist/_dts/api/src/bookingConfig.d.ts +2 -0
- package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +5 -1
- package/dist/_dts/api/src/bookingRecords.d.ts +180 -115
- package/dist/_dts/api/src/cache-tags.d.ts +3 -0
- package/dist/_dts/api/src/contentRuntime.d.ts +25 -16
- package/dist/_dts/api/src/courses.d.ts +68 -10
- package/dist/_dts/api/src/endpoints.d.ts +128 -0
- package/dist/_dts/api/src/footer-settings.d.ts +1 -0
- package/dist/_dts/api/src/footerSettings.d.ts +8 -0
- package/dist/_dts/api/src/index.d.ts +127 -124
- package/dist/_dts/api/src/navigation/contracts.d.ts +3 -3
- package/dist/_dts/api/src/previewContentContract.d.ts +4 -0
- package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +9 -0
- package/dist/_dts/api/src/sdkContracts.d.ts +178 -6
- package/dist/_dts/api/src/siteBanner.d.ts +2 -2
- package/dist/_dts/api/src/siteManagementEndpoints.d.ts +143 -55
- package/dist/_dts/api/src/siteOperations.d.ts +1 -0
- package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +32 -4
- package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +72 -47
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +36 -4
- package/dist/_dts/blocks/src/definitions.d.ts +1 -1
- package/dist/_dts/blocks/src/portal/types.d.ts +25 -7
- package/dist/_dts/blocks/src/primitives/layout/Section.d.ts +0 -1
- package/dist/_dts/blocks/src/rendering/server.d.ts +1 -0
- package/dist/_dts/blocks/src/system/blocks/course-registration.d.ts +2 -2
- package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +2 -0
- package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +2 -0
- package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +4 -0
- package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule-projection.d.ts +52 -0
- package/dist/_dts/blocks/src/system/blocks/events/recurring-schedule.d.ts +22 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +45 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +10 -0
- package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +4 -1
- package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
- package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +9 -0
- package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +8 -2
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/index.d.ts +8 -8
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +24 -24
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/scheduleSummary.d.ts +29 -0
- package/dist/_dts/blocks/src/system/blocks/shop.d.ts +2 -1
- package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +50 -0
- package/dist/_dts/blocks/src/system/blocks/site-footer.d.ts +9 -48
- 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 +2 -5
- package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
- package/dist/_dts/blocks/src/system/designCapabilities.d.ts +1 -0
- package/dist/_dts/blocks/src/system/fragments/library/newsletterForm.d.ts +2 -2
- package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -1
- package/dist/_dts/blocks/src/system/icons/social.d.ts +5 -0
- package/dist/_dts/blocks/src/system/icons/svg.d.ts +1 -0
- package/dist/_dts/blocks/src/system/manifest/schema.d.ts +2 -2
- package/dist/_dts/blocks/src/system/node/fragments/backgroundLayer.d.ts +13 -0
- package/dist/_dts/blocks/src/system/node/fragments/footerNav.d.ts +2 -0
- package/dist/_dts/blocks/src/system/node/fragments/styledCard.d.ts +3 -0
- package/dist/_dts/blocks/src/system/node/fragments/styledContainer.d.ts +4 -4
- package/dist/_dts/blocks/src/system/node/fragments/styledSection.d.ts +3 -12
- package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/blockComposition.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +90 -6
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +45 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/commerce/shared/display.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details/logic.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details/view.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details.server.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/course-page-surface-scope.d.ts +17 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/types.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.server.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventScope.d.ts +9 -18
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +106 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/RecurringSchedule.d.ts +11 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +7 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +11 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/offerings-preview.d.ts +6 -6
- package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +11 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/shop.types.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/svg.d.ts +7 -0
- package/dist/_dts/blocks/src/system/types/link.d.ts +3 -3
- package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +14 -0
- package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +27 -8
- package/dist/_dts/content-editor/src/footerComposer.d.ts +56 -0
- package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +1 -1
- package/dist/_dts/content-editor/src/hooks/useEntryMutations.d.ts +5 -5
- package/dist/_dts/content-editor/src/index.d.ts +2 -0
- package/dist/_dts/content-editor/src/primitives/PreviewRichTextEditor.d.ts +3 -1
- package/dist/_dts/content-editor/src/services/contentEntryServices.d.ts +20 -36
- package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +5 -1
- package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +11 -0
- package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
- package/dist/_dts/content-model/src/definitions/shared.d.ts +3 -0
- package/dist/_dts/core/src/branded.d.ts +47 -0
- package/dist/_dts/core/src/dated-offering-settlement.d.ts +47 -0
- package/dist/_dts/core/src/editor-state.d.ts +4 -0
- package/dist/_dts/core/src/event-page-surface-subject.d.ts +44 -0
- package/dist/_dts/core/src/footer-composition.d.ts +143 -0
- package/dist/_dts/core/src/index.d.ts +51 -47
- package/dist/_dts/core/src/public-profile.d.ts +73 -0
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +4398 -2859
- package/dist/_dts/db/src/schemas/forms.d.ts +10 -10
- package/dist/_dts/editor/src/primitives/rich-text/RichTextEditorSurface.d.ts +5 -0
- package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +1 -0
- package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +4 -1
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +2 -1
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +2 -1
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockReorder.d.ts +2 -1
- package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +10 -0
- package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +1 -0
- package/dist/_dts/media-core/src/index.d.ts +2 -1
- package/dist/_dts/media-core/src/storagePathDomain.d.ts +47 -0
- package/dist/_dts/media-core/src/url.d.ts +1 -21
- package/dist/_dts/path-utils/src/index.d.ts +5 -0
- package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +4 -2
- package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -1
- package/dist/_dts/preview-next/src/client/preview/PreviewChromeLayer.d.ts +5 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +4 -9
- package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +8 -11
- package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +4 -9
- package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +2 -6
- package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +5 -9
- package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +81 -43
- package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.typography.d.ts +61 -0
- package/dist/_dts/preview-next/src/client/preview/previewErrorMessages.d.ts +4 -0
- package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +7 -17
- package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +15 -8
- package/dist/_dts/preview-next/src/client/preview/typographyFontCatalog.d.ts +57 -0
- package/dist/_dts/sdk/src/cli/commands/pull.d.ts +1 -1
- package/dist/_dts/sdk/src/cli/commands/push/execute/theme.d.ts +4 -7
- package/dist/_dts/sdk/src/cli/commands/style.d.ts +24 -10
- package/dist/_dts/sdk/src/cli/content/reader.d.ts +1 -0
- package/dist/_dts/sdk/src/cli/site-commands/oneOffCommands.d.ts +3 -3
- package/dist/_dts/sdk/src/cli/sync/media.d.ts +16 -2
- package/dist/_dts/sdk/src/client/management/blocks.d.ts +14 -1
- package/dist/_dts/sdk/src/client/management/index.d.ts +2 -1
- package/dist/_dts/sdk/src/client/management/types.d.ts +147 -24
- package/dist/_dts/sdk/src/client/types.d.ts +2 -0
- package/dist/_dts/sdk/src/config/content-types.d.ts +2 -0
- package/dist/_dts/sdk/src/config/content-validation.d.ts +4 -0
- package/dist/_dts/sdk/src/config/types.d.ts +1 -1
- package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
- package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
- package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +23 -3
- package/dist/_dts/sdk/src/data/dataLoaderContext.d.ts +17 -0
- package/dist/_dts/sdk/src/data/dataLoaderValue.d.ts +36 -0
- package/dist/_dts/sdk/src/data/defineOwnDataProperty.d.ts +2 -0
- package/dist/_dts/sdk/src/data/executeCodeLoaders.d.ts +36 -40
- package/dist/_dts/sdk/src/data/index.d.ts +3 -3
- package/dist/_dts/sdk/src/data/resolveBlockData.d.ts +54 -0
- package/dist/_dts/sdk/src/data/types.d.ts +43 -78
- package/dist/_dts/sdk/src/navigation/index.d.ts +2 -0
- package/dist/_dts/sdk/src/next/index.d.ts +1 -0
- package/dist/_dts/sdk/src/next/redirect-destination.d.ts +1 -1
- package/dist/_dts/sdk/src/next/resolveTheme.d.ts +2 -1
- package/dist/_dts/sdk/src/next/types.d.ts +10 -1
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +6 -10
- package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +2 -1
- package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +10 -5
- package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +6 -10
- package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
- package/dist/_dts/sdk/src/server.d.ts +4 -3
- 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/site-commands/src/capabilityGaps.d.ts +2 -2
- package/dist/_dts/site-commands/src/commands.d.ts +934 -40
- package/dist/_dts/theme-core/src/accordions/types.d.ts +2 -2
- package/dist/_dts/theme-core/src/buttons/generateDefaultButtonSystem.d.ts +5 -1
- package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +22 -0
- package/dist/_dts/theme-core/src/buttons/personalities/quiet-arrow.d.ts +17 -0
- package/dist/_dts/theme-core/src/buttons/personalities/two-tone-pill.d.ts +17 -0
- package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +3 -3
- package/dist/_dts/theme-core/src/buttons/types.d.ts +12 -8
- package/dist/_dts/theme-core/src/cards/types.d.ts +3 -3
- package/dist/_dts/theme-core/src/data.d.ts +12 -0
- package/dist/_dts/theme-core/src/fonts/index.d.ts +1 -1
- package/dist/_dts/theme-core/src/fonts/types.d.ts +6 -0
- package/dist/_dts/theme-core/src/footer/mode.d.ts +15 -0
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/_dts/theme-core/src/interactive/baseSchema.d.ts +1 -1
- package/dist/_dts/theme-core/src/mock-themes/all.d.ts +72 -54
- package/dist/_dts/theme-core/src/navigation/types.d.ts +1 -1
- package/dist/_dts/theme-core/src/palette/colors.d.ts +12 -0
- package/dist/_dts/theme-core/src/palette/curated/brand-led.d.ts +10 -5
- package/dist/_dts/theme-core/src/palette/curated/high-contrast.d.ts +6 -3
- package/dist/_dts/theme-core/src/palette/curated/index.d.ts +31 -236
- package/dist/_dts/theme-core/src/palette/curated/soft-natural.d.ts +8 -4
- package/dist/_dts/theme-core/src/palette/curated/types.d.ts +14 -12
- package/dist/_dts/theme-core/src/palette/curated/warm-dark.d.ts +4 -2
- package/dist/_dts/theme-core/src/palette/curated/warm-neutral.d.ts +8 -4
- package/dist/_dts/theme-core/src/palette/editorState.d.ts +33 -3
- package/dist/_dts/theme-core/src/palette/index.d.ts +0 -4
- package/dist/_dts/theme-core/src/palette/libraryModel.d.ts +12 -6
- package/dist/_dts/theme-core/src/palette/persistenceReadSource.d.ts +20 -72
- package/dist/_dts/theme-core/src/palette/resolveSelection.d.ts +29 -4
- package/dist/_dts/theme-core/src/palette/selection.d.ts +6 -4
- package/dist/_dts/theme-core/src/schema.d.ts +1307 -38
- package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +218 -158
- package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +5 -6
- package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +218 -158
- package/dist/_dts/theme-core/src/site-styles/compositionBudget.d.ts +1 -0
- package/dist/_dts/theme-core/src/site-styles/contentTemplateRuntimeCompiler.d.ts +2 -1
- package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +161 -51
- package/dist/_dts/theme-core/src/site-styles/designState.d.ts +6 -0
- package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
- package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +12 -1
- package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +24 -1
- package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +14 -48
- package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +10 -23
- package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +15 -0
- package/dist/_dts/theme-core/src/site-styles/siteStyleThemeCompiler.d.ts +1 -2
- package/dist/_dts/theme-core/src/site-styles/siteStyleTypography.d.ts +456 -0
- package/dist/_dts/theme-core/src/site-styles/types.d.ts +52 -3
- package/dist/cli/index.mjs +4118 -2278
- package/dist/client/{DiscountCodeDisclosure-BXM73_E5.mjs → DiscountCodeDisclosure-D6TOf6Hi.mjs} +1 -1
- package/dist/client/{EventCombined.client-DT5elP7j.mjs → EventCombined.client-Dao3zxRk.mjs} +3 -3
- package/dist/client/{EventListing.client-pTYGfV9C.mjs → EventListing.client-B2NNt4y1.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-dQrhlUe3.mjs → LeafletStaticMap-BhwFo16w.mjs} +1 -1
- package/dist/client/{MagicLinkForm-u6Dul4j5.mjs → MagicLinkForm-BWnB7cMR.mjs} +2 -2
- package/dist/client/{StepIndicator-nWqineJ2.mjs → StepIndicator-TzRiQ0BY.mjs} +2 -2
- package/dist/client/{accordion-CSJcTUyH.mjs → accordion-BPy-AJ4_.mjs} +1 -1
- package/dist/client/{bookingForm-C73wOuVa.mjs → bookingForm-BL4PGZds.mjs} +7 -7
- package/dist/client/bookings.mjs +382 -204
- package/dist/client/{buttons-DfYyqt8C.mjs → buttons-EBjyslaX.mjs} +265 -152
- package/dist/client/{carousel-fMBb0JSc.mjs → carousel-C2b7Cn9-.mjs} +1 -1
- package/dist/client/{cart-BtaCwT3S.mjs → cart-BQcbXIVD.mjs} +3 -3
- package/dist/client/{checkout-DkTwZSnh.mjs → checkout-DEmpGRJu.mjs} +3 -3
- package/dist/client/client.mjs +5019 -1886
- package/dist/client/{colorStyles-Wyl6JujD.mjs → colorStyles-jZS6KfkP.mjs} +1 -1
- package/dist/client/{colorTokenParts-dT8MISgJ.mjs → colorTokenParts-CMugwvX_.mjs} +3 -1
- package/dist/client/{courseRegistration-DnLmapJu.mjs → courseRegistration-BqRZPmsq.mjs} +56 -21
- package/dist/client/{eventCalendar-BvLOc9KY.mjs → eventCalendar-B8N_tSl5.mjs} +29 -21
- package/dist/client/{eventCombined-kShgJPQr.mjs → eventCombined-Gjn6gtq7.mjs} +2 -2
- package/dist/client/{eventDetails-C5NTM0Vo.mjs → eventDetails-M-VCxA-r.mjs} +4 -4
- package/dist/client/{eventListing-B82ZdKP6.mjs → eventListing-DR19hqYi.mjs} +2 -2
- package/dist/client/{eventRegistration-qJVFqBWo.mjs → eventRegistration-BR02a0k3.mjs} +8 -8
- package/dist/client/{form-BvAcKiuu.mjs → form-LY2xIbwg.mjs} +2 -2
- package/dist/client/{headerSection-NvAiEHAg.mjs → headerSection-CYwwXJfh.mjs} +3 -3
- package/dist/client/hooks.mjs +3335 -2210
- package/dist/client/{locationMap-D0j52xfI.mjs → locationMap-DWnBXrFq.mjs} +3 -3
- package/dist/client/{media-BCW_g2cQ.mjs → media-DHtSxS5V.mjs} +61 -56
- package/dist/client/{newsletterForm-B8_i93qH.mjs → newsletterForm-D9s-fQ2P.mjs} +3 -3
- package/dist/client/{pricing-DIYnyHOk.mjs → pricing-DDq80oYc.mjs} +1 -1
- package/dist/client/{productDetail-w0eAHkuQ.mjs → productDetail-B0SbWd45.mjs} +3 -3
- package/dist/client/{productList-Vsguq5Xt.mjs → productList-PwYlZn0y.mjs} +3 -3
- package/dist/client/{propsDecoder-CD2pJ1WB.mjs → propsDecoder-BRWBiH7i.mjs} +225 -68
- package/dist/client/rendering/client.mjs +2266 -1267
- package/dist/client/rendering/islands.mjs +20 -20
- package/dist/client/rendering.mjs +5364 -1979
- package/dist/client/{shop-Dgxs-Q8F.mjs → shop-CMwZPYME.mjs} +8 -8
- package/dist/client/{shop-commerce-DJAhsTaT.mjs → shop-commerce-BuxsFate.mjs} +6 -6
- package/dist/client/{shop-commerce-store-CfCXltXW.mjs → shop-commerce-store-boYlEJ91.mjs} +1 -1
- package/dist/client/{shopShared-CmDcPXUt.mjs → shopShared-D2naaOes.mjs} +3 -3
- package/dist/client/{useDiscountCodeUi-CirrT2bM.mjs → useDiscountCodeUi-D9RHpVoj.mjs} +1 -1
- package/dist/client/{useEventFilters-CNZxlCcO.mjs → useEventFilters-igGiK1re.mjs} +6 -6
- package/dist/client/{usePolling-Baks_iBI.mjs → usePolling-CI7MbsFB.mjs} +2 -2
- package/dist/preview-next/before-render.mjs +218 -1
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/middleware.mjs +218 -1
- package/dist/{previewAuthStore-CfquDtTh.mjs → previewAuthStore-a_cBD28m.mjs} +218 -1
- package/dist/{sdk-runtime-BfNiFeNJ.mjs → sdk-runtime-MBzD-GmP.mjs} +2 -2
- package/dist/{separator-BhAR_Xmf.mjs → separator-5ahRBC85.mjs} +1 -1
- package/dist/server/components.mjs +5218 -2529
- package/dist/server/config-validation.mjs +3112 -2210
- package/dist/server/config.mjs +3112 -2211
- package/dist/server/data.mjs +3758 -2277
- package/dist/server/index.mjs +224 -4
- package/dist/server/navigation.mjs +9 -3
- package/dist/server/next/middleware.mjs +1 -1
- package/dist/server/next.mjs +6468 -2749
- package/dist/server/page-converter.mjs +3524 -2635
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +5392 -2488
- package/dist/server/rendering.mjs +6241 -2851
- package/dist/server/routing.mjs +3414 -1826
- package/dist/server/server.mjs +4174 -2354
- package/dist/server/theme-bridge.mjs +9579 -8132
- package/dist/server/theme.mjs +313 -154
- package/dist/styles/index.css +1223 -31
- package/package.json +1 -1
- package/dist/_dts/preview-next/src/client/preview/typographySelectionInput.d.ts +0 -16
- package/dist/_dts/theme-core/src/palette/historicalThemePalette.d.ts +0 -44
- package/dist/_dts/theme-core/src/palette/legacyRuntimeProjection.d.ts +0 -55
- package/dist/_dts/theme-core/src/palette/legacySelection.d.ts +0 -45
- package/dist/_dts/theme-core/src/palette/paletteCompatibilityTransition.d.ts +0 -232
- package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +0 -234
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { $
|
|
3
|
-
import { d as unwrapResponse, f as getDashboardUrl, r as usePreviewAuth } from "./previewAuthStore-
|
|
4
|
-
import { S as isAdapterReferenceKind, T as
|
|
5
|
-
import { t as Separator } from "./separator-
|
|
2
|
+
import { $l as Input, A as deriveStyleConfiguratorCapabilities, Au as DropdownMenuItem, B as previewButtonPersonality, Bd as X$1, Ca as curatedPalettes, Ct as useEntryController, D as committedPaletteForSnapshot, Da as paletteColorsEqual, Dt as useEditorUiStoreInstance, Du as Surface, E as cancelPreview, Ea as paletteColorEntries, Et as useEditorUiStore, F as markApplySaving, G as previewSitePalette, Gl as SelectTrigger, H as previewFooterLook, Hl as Select, Ht as resolvePageRouteSlug, I as openRow, If as Check, J as resetTypographyToSaved, K as previewSiteStyle, Kd as Tablet, Kl as SelectValue, L as paletteMutationCapability, M as isPreviewingChange, Mu as DropdownMenuSeparator, N as markApplyFailed, Nf as ChevronRight, Nu as DropdownMenuTrigger, O as createPalette, Oa as paletteColorsSchema, Ou as DropdownMenu, P as markApplySaved, Pf as ChevronLeft, Q as toggleRow, Ql as PopoverTrigger, Qt as FormRenderer, Qu as cn, R as palettePreviewProjection, T as applyTypographyDraftPatch, Ta as buildPaletteLibraryReadModel, Td as assertNever$1, U as previewHeaderLayout, Ui as getCuratedSiteStyle, Ul as SelectContent, Ut as resolveContentTitle, V as previewCuratedPalette, Vi as curatedSiteStyles, Vt as deriveRouteMetadataPresentation, W as previewHeaderStyle, Wl as SelectItem, X as styleConfiguratorHistoryEntryForPersistedSelection, Xd as SlidersHorizontal, Xl as Popover, Y as setPaletteColors, Yd as Smartphone, Yl as SearchInput, Yt as ManifestForm, Yu as Button, Z as syncStyleConfiguratorState, Zl as PopoverContent, Zt as createManifestValidation, _ as planSiteChromeFooterLayoutSelection, _u as CollapsibleContent, af as Monitor, at as createOptimisticActionRunner, bt as useUISelector, c as selectionSnapshotFromApplySiteStyleSelectionResponse, ca as findFooterLook, cf as LoaderCircle, d as PREVIEW_DESIGN_REFRESH_ERROR_MESSAGE, da as getHeaderStyle, dn as listEntryPageContentSlots, en as createStoreBackend, eu as Tabs, f as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, g as cycleableSiteChromeOptions, gu as Collapsible, h as cycleSiteChromeLookId, id as unsafeAsEditorBlockId, j as dismissWarnings, ju as DropdownMenuLabel, k as createStyleConfiguratorState, ku as DropdownMenuContent, l as resolveStyleConfiguratorInitialSnapshot, la as getFooterLayout, m as buildSiteChromeLookModels, n as useSiteChromeCustomizeOptional, nl as buttonPersonalities, nu as TabsList, ot as resolvePreviewSidebarTab, p as reportPreviewDesignError, q as reconcilePaletteLibraryActive, rl as findButtonPersonality, ru as TabsTrigger, s as buildApplySiteStyleSelectionBody, sa as requireEntriesForCuratedChoices, sf as Maximize2, st as FooterComposerPanel, tf as Plus, tu as TabsContent, u as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, ua as getHeaderLayout, v as planSiteChromeLookSelection, vu as CollapsibleTrigger, w as applyResolvedSelections, wa as findCuratedPalette, x as usePreviewDesignCoordinator, y as planSiteStylePreviewChange, yt as ContentFieldsForm, z as prepareStalePaletteRetry } from "./SiteChromeCustomizeContext-BQUY2dEk.mjs";
|
|
3
|
+
import { d as unwrapResponse, f as getDashboardUrl, r as usePreviewAuth } from "./previewAuthStore-a_cBD28m.mjs";
|
|
4
|
+
import { C as buildFontPreviewUrl, D as Callout, O as CalloutDescription, S as isAdapterReferenceKind, T as getSiteFontsStorageUrl, _ as usePreviewBlockCustomizeSelectionOptional, b as previewWidgetOverrides, d as buildPreviewDashboardSetupUrl, f as resolvePreviewDashboardSetupHandoff, g as canInspectSiteStyle, h as canApplySiteStyle, m as resolvePreviewSidebarChromeModel, p as resolvePreviewEditorGuidanceModel, v as useBlockCustomizeControls, w as generateFontFaceCss, x as BlockEditor, y as PreviewFormProvider } from "./SdkPreviewModeRuntime-CuDjXH6o.mjs";
|
|
5
|
+
import { t as Separator } from "./separator-5ahRBC85.mjs";
|
|
6
6
|
import React, { forwardRef, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, useTransition } from "react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
@@ -1564,7 +1564,7 @@ function formatBlockKindLabel(blockKind) {
|
|
|
1564
1564
|
}
|
|
1565
1565
|
//#endregion
|
|
1566
1566
|
//#region ../preview-next/src/client/preview/PageBlockEditorPanel.tsx
|
|
1567
|
-
function PageBlockEditorPanel({ siteId, pageId, dashboardBaseUrl, theme, apiClient, bearerToken, supabaseUrl, blockItems, uiStoreForBlockEditor, blockEditorRef, onBlocksChange, metadataPanel, linkedEntrySection, designPanel, designOpenRequestId = null, sdkConfig, mediaAssets, bookingOfferingPresets, viewportMode, viewportWidth, zoom, onViewportModeChange, onViewportWidthChange, onZoomChange }) {
|
|
1567
|
+
function PageBlockEditorPanel({ siteId, pageId, dashboardBaseUrl, theme, apiClient, bearerToken, supabaseUrl, blockItems, uiStoreForBlockEditor, blockEditorRef, onBlocksChange, metadataPanel, linkedEntrySection, designPanel, designOpenRequestId = null, designTakeoverActive = false, sdkConfig, mediaAssets, bookingOfferingPresets, viewportMode, viewportWidth, zoom, onViewportModeChange, onViewportWidthChange, onZoomChange }) {
|
|
1568
1568
|
const customizeSelection = usePreviewBlockCustomizeSelectionOptional();
|
|
1569
1569
|
const [designOpen, setDesignOpen] = useState(false);
|
|
1570
1570
|
const [customizeOpen, setCustomizeOpen] = useState(false);
|
|
@@ -1627,35 +1627,48 @@ function PageBlockEditorPanel({ siteId, pageId, dashboardBaseUrl, theme, apiClie
|
|
|
1627
1627
|
bookingOfferingPresets,
|
|
1628
1628
|
sdkConfig: sdkConfig ?? null,
|
|
1629
1629
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1630
|
-
className:
|
|
1630
|
+
className: `min-h-0 flex-1 space-y-0 ${designTakeoverActive ? "flex flex-col overflow-hidden" : "overflow-auto"}`,
|
|
1631
|
+
"data-design-takeover-active": designTakeoverActive ? "true" : "false",
|
|
1631
1632
|
children: [
|
|
1632
|
-
linkedEntrySection ? /* @__PURE__ */ jsx(
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
children:
|
|
1633
|
+
linkedEntrySection ? /* @__PURE__ */ jsx("div", {
|
|
1634
|
+
hidden: designTakeoverActive,
|
|
1635
|
+
"data-design-takeover-sibling": true,
|
|
1636
|
+
children: /* @__PURE__ */ jsx(PreviewSidebarSection, {
|
|
1637
|
+
label: linkedEntrySection.label,
|
|
1638
|
+
openRequestId: linkedEntrySection.openRequestId,
|
|
1639
|
+
children: linkedEntrySection.content
|
|
1640
|
+
})
|
|
1636
1641
|
}) : null,
|
|
1637
1642
|
designPanel ? /* @__PURE__ */ jsx(Collapsible, {
|
|
1638
|
-
|
|
1639
|
-
|
|
1643
|
+
className: designTakeoverActive ? "flex min-h-0 flex-1 flex-col overflow-hidden" : void 0,
|
|
1644
|
+
open: designTakeoverActive || designOpen,
|
|
1645
|
+
onOpenChange: (open) => {
|
|
1646
|
+
if (!designTakeoverActive) setDesignOpen(open);
|
|
1647
|
+
},
|
|
1640
1648
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1641
1649
|
ref: designSectionRef,
|
|
1642
|
-
className: "border-b",
|
|
1650
|
+
className: designTakeoverActive ? "flex min-h-0 flex-1 flex-col overflow-hidden" : "border-b",
|
|
1643
1651
|
children: [/* @__PURE__ */ jsx(CollapsibleTrigger, {
|
|
1644
1652
|
asChild: true,
|
|
1645
1653
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1646
|
-
className:
|
|
1647
|
-
children: [/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${designOpen ? "rotate-90" : ""}` }), /* @__PURE__ */ jsx("span", {
|
|
1654
|
+
className: `flex shrink-0 cursor-pointer items-center gap-2 px-4 py-3 hover:bg-accent/40 ${designTakeoverActive ? "border-b" : ""}`,
|
|
1655
|
+
children: [/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${designTakeoverActive || designOpen ? "rotate-90" : ""}` }), /* @__PURE__ */ jsx("span", {
|
|
1648
1656
|
className: "text-sm font-semibold",
|
|
1649
1657
|
children: "Design"
|
|
1650
1658
|
})]
|
|
1651
1659
|
})
|
|
1652
|
-
}), /* @__PURE__ */ jsx(CollapsibleContent, {
|
|
1653
|
-
className: "
|
|
1654
|
-
children:
|
|
1655
|
-
|
|
1660
|
+
}), /* @__PURE__ */ jsx(CollapsibleContent, {
|
|
1661
|
+
className: designTakeoverActive ? "min-h-0 flex-1 data-[state=open]:h-full data-[state=open]:overflow-hidden" : void 0,
|
|
1662
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1663
|
+
className: designTakeoverActive ? "h-full min-h-0" : "px-4 pb-4",
|
|
1664
|
+
children: designPanel
|
|
1665
|
+
})
|
|
1666
|
+
})]
|
|
1656
1667
|
})
|
|
1657
1668
|
}) : null,
|
|
1658
1669
|
/* @__PURE__ */ jsx(Collapsible, {
|
|
1670
|
+
hidden: designTakeoverActive,
|
|
1671
|
+
"data-design-takeover-sibling": true,
|
|
1659
1672
|
open: customizeOpen,
|
|
1660
1673
|
onOpenChange: setCustomizeOpen,
|
|
1661
1674
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -1682,6 +1695,8 @@ function PageBlockEditorPanel({ siteId, pageId, dashboardBaseUrl, theme, apiClie
|
|
|
1682
1695
|
})
|
|
1683
1696
|
}),
|
|
1684
1697
|
/* @__PURE__ */ jsx(Collapsible, {
|
|
1698
|
+
hidden: designTakeoverActive,
|
|
1699
|
+
"data-design-takeover-sibling": true,
|
|
1685
1700
|
open: contentOpen,
|
|
1686
1701
|
onOpenChange: setContentOpen,
|
|
1687
1702
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -1718,6 +1733,8 @@ function PageBlockEditorPanel({ siteId, pageId, dashboardBaseUrl, theme, apiClie
|
|
|
1718
1733
|
})
|
|
1719
1734
|
}),
|
|
1720
1735
|
metadataPanel ? /* @__PURE__ */ jsx(Collapsible, {
|
|
1736
|
+
hidden: designTakeoverActive,
|
|
1737
|
+
"data-design-takeover-sibling": true,
|
|
1721
1738
|
open: detailsOpen,
|
|
1722
1739
|
onOpenChange: setDetailsOpen,
|
|
1723
1740
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -2061,712 +2078,516 @@ function ContrastSwatch({ hex, label }) {
|
|
|
2061
2078
|
});
|
|
2062
2079
|
}
|
|
2063
2080
|
//#endregion
|
|
2064
|
-
//#region ../preview-next/src/client/preview/
|
|
2065
|
-
const
|
|
2066
|
-
const MAX_FONT_RESULTS_WHEN_BROWSING = 8;
|
|
2067
|
-
const PALETTE_BRAND_ROLES = [
|
|
2081
|
+
//#region ../preview-next/src/client/preview/typographyFontCatalog.ts
|
|
2082
|
+
const typographyFontCategories = [
|
|
2068
2083
|
{
|
|
2069
|
-
|
|
2070
|
-
label: "
|
|
2084
|
+
value: "all",
|
|
2085
|
+
label: "All"
|
|
2071
2086
|
},
|
|
2072
2087
|
{
|
|
2073
|
-
|
|
2074
|
-
label: "
|
|
2088
|
+
value: "sans-serif",
|
|
2089
|
+
label: "Sans"
|
|
2075
2090
|
},
|
|
2076
2091
|
{
|
|
2077
|
-
|
|
2078
|
-
label: "
|
|
2092
|
+
value: "serif",
|
|
2093
|
+
label: "Serif"
|
|
2079
2094
|
},
|
|
2080
2095
|
{
|
|
2081
|
-
|
|
2082
|
-
label: "
|
|
2083
|
-
}
|
|
2084
|
-
];
|
|
2085
|
-
const PALETTE_FEEDBACK_ROLES = [
|
|
2086
|
-
{
|
|
2087
|
-
key: "success",
|
|
2088
|
-
label: "Success"
|
|
2096
|
+
value: "display",
|
|
2097
|
+
label: "Display"
|
|
2089
2098
|
},
|
|
2090
2099
|
{
|
|
2091
|
-
|
|
2092
|
-
label: "
|
|
2100
|
+
value: "handwriting",
|
|
2101
|
+
label: "Handwriting"
|
|
2093
2102
|
},
|
|
2094
2103
|
{
|
|
2095
|
-
|
|
2096
|
-
label: "
|
|
2104
|
+
value: "monospace",
|
|
2105
|
+
label: "Mono"
|
|
2097
2106
|
}
|
|
2098
2107
|
];
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2108
|
+
function buildTypographyFontCatalog(input) {
|
|
2109
|
+
const normalizedQuery = input.query.trim().toLocaleLowerCase();
|
|
2110
|
+
const site = input.siteFonts.map(siteFontOption).filter((option) => fontOptionMatches(option, normalizedQuery, input.category)).sort(compareFontOptionsAlphabetically);
|
|
2111
|
+
const siteFamilies = new Set(input.siteFonts.map((font) => familyKey(font.familyName)));
|
|
2112
|
+
return {
|
|
2113
|
+
site,
|
|
2114
|
+
google: input.googleFonts.map(googleFontOption).filter((option) => !siteFamilies.has(familyKey(option.family))).filter((option) => fontOptionMatches(option, normalizedQuery, input.category)).sort(compareGoogleOptions)
|
|
2115
|
+
};
|
|
2116
|
+
}
|
|
2117
|
+
function visibleTypographyFontOptions(input) {
|
|
2118
|
+
const initial = input.options.slice(0, input.limit);
|
|
2119
|
+
if (input.limit <= 0 || initial.some((option) => familyKey(option.family) === familyKey(input.selectedFamily))) return initial;
|
|
2120
|
+
const selected = input.options.find((option) => familyKey(option.family) === familyKey(input.selectedFamily));
|
|
2121
|
+
if (!selected) return initial;
|
|
2122
|
+
return [...initial.slice(0, Math.max(0, input.limit - 1)), selected];
|
|
2123
|
+
}
|
|
2124
|
+
function fontOptionForFamily(family, catalog) {
|
|
2125
|
+
const key = familyKey(primaryFontFamily(family));
|
|
2126
|
+
const site = catalog.siteFonts.find((font) => familyKey(font.familyName) === key);
|
|
2127
|
+
if (site) return siteFontOption(site);
|
|
2128
|
+
const google = catalog.googleFonts.find((font) => familyKey(font.family) === key);
|
|
2129
|
+
return google ? googleFontOption(google) : null;
|
|
2130
|
+
}
|
|
2131
|
+
function primaryFontFamily(cssFamily) {
|
|
2132
|
+
return cssFamily.split(",")[0]?.trim().replace(/^["']|["']$/gu, "") || cssFamily;
|
|
2133
|
+
}
|
|
2134
|
+
function siteFontOption(font) {
|
|
2135
|
+
return {
|
|
2136
|
+
source: "site",
|
|
2137
|
+
family: font.familyName,
|
|
2138
|
+
label: font.displayName ?? font.familyName,
|
|
2139
|
+
category: normalizeCategory(font.category),
|
|
2140
|
+
siteFont: font
|
|
2141
|
+
};
|
|
2142
|
+
}
|
|
2143
|
+
function googleFontOption(font) {
|
|
2144
|
+
return {
|
|
2145
|
+
source: "google",
|
|
2146
|
+
family: font.family,
|
|
2147
|
+
label: font.family,
|
|
2148
|
+
category: normalizeCategory(font.category),
|
|
2149
|
+
googleFont: font
|
|
2150
|
+
};
|
|
2151
|
+
}
|
|
2152
|
+
function normalizeCategory(category) {
|
|
2153
|
+
switch (category) {
|
|
2154
|
+
case "sans-serif":
|
|
2155
|
+
case "serif":
|
|
2156
|
+
case "display":
|
|
2157
|
+
case "handwriting":
|
|
2158
|
+
case "monospace": return category;
|
|
2159
|
+
default: return null;
|
|
2123
2160
|
}
|
|
2124
|
-
|
|
2125
|
-
function
|
|
2126
|
-
const
|
|
2127
|
-
const
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
]
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
const
|
|
2153
|
-
const
|
|
2154
|
-
const runnerRef = useRef(createOptimisticActionRunner());
|
|
2155
|
-
const appliedExpandedRowRequestIdRef = useRef(null);
|
|
2156
|
-
useEffect(() => {
|
|
2157
|
-
stateRef.current = state;
|
|
2158
|
-
}, [state]);
|
|
2159
|
-
useEffect(() => {
|
|
2160
|
-
clearPreviewRef.current = clearPreview;
|
|
2161
|
-
}, [clearPreview]);
|
|
2161
|
+
}
|
|
2162
|
+
function fontOptionMatches(option, normalizedQuery, category) {
|
|
2163
|
+
const matchesQuery = normalizedQuery.length === 0 || option.family.toLocaleLowerCase().includes(normalizedQuery) || option.label.toLocaleLowerCase().includes(normalizedQuery);
|
|
2164
|
+
const matchesCategory = category === "all" || option.category === category;
|
|
2165
|
+
return matchesQuery && matchesCategory;
|
|
2166
|
+
}
|
|
2167
|
+
function compareGoogleOptions(left, right) {
|
|
2168
|
+
if (left.source !== "google" || right.source !== "google") return compareFontOptionsAlphabetically(left, right);
|
|
2169
|
+
return (left.googleFont.popularity ?? Number.POSITIVE_INFINITY) - (right.googleFont.popularity ?? Number.POSITIVE_INFINITY) || compareFontOptionsAlphabetically(left, right);
|
|
2170
|
+
}
|
|
2171
|
+
function compareFontOptionsAlphabetically(left, right) {
|
|
2172
|
+
return left.label.localeCompare(right.label);
|
|
2173
|
+
}
|
|
2174
|
+
function familyKey(family) {
|
|
2175
|
+
return family.trim().toLocaleLowerCase();
|
|
2176
|
+
}
|
|
2177
|
+
//#endregion
|
|
2178
|
+
//#region ../preview-next/src/client/preview/StyleConfigurator.typography.tsx
|
|
2179
|
+
const typographyOverviewSurface = { kind: "overview" };
|
|
2180
|
+
function useTypographyFontCatalog(apiClient, siteId, enabled) {
|
|
2181
|
+
const [google, setGoogle] = useState({
|
|
2182
|
+
kind: "idle",
|
|
2183
|
+
value: []
|
|
2184
|
+
});
|
|
2185
|
+
const [site, setSite] = useState({
|
|
2186
|
+
kind: "idle",
|
|
2187
|
+
value: []
|
|
2188
|
+
});
|
|
2189
|
+
const googleRequestRef = useRef(null);
|
|
2190
|
+
const siteRequestRef = useRef(null);
|
|
2162
2191
|
useEffect(() => {
|
|
2163
|
-
if (!
|
|
2164
|
-
|
|
2192
|
+
if (!enabled) return;
|
|
2193
|
+
if (googleRequestRef.current?.apiClient === apiClient) return;
|
|
2194
|
+
let cancelled = false;
|
|
2195
|
+
googleRequestRef.current = {
|
|
2196
|
+
apiClient,
|
|
2197
|
+
status: "loading"
|
|
2198
|
+
};
|
|
2199
|
+
setGoogle((current) => ({
|
|
2200
|
+
kind: "loading",
|
|
2201
|
+
value: current.value
|
|
2202
|
+
}));
|
|
2203
|
+
async function loadGoogleFonts() {
|
|
2204
|
+
try {
|
|
2205
|
+
const value = unwrapResponse(await apiClient({ endpoint: "listFonts" }));
|
|
2206
|
+
if (!cancelled) {
|
|
2207
|
+
googleRequestRef.current = {
|
|
2208
|
+
apiClient,
|
|
2209
|
+
status: "loaded"
|
|
2210
|
+
};
|
|
2211
|
+
setGoogle({
|
|
2212
|
+
kind: "loaded",
|
|
2213
|
+
value: Array.isArray(value) ? value : []
|
|
2214
|
+
});
|
|
2215
|
+
}
|
|
2216
|
+
} catch (error) {
|
|
2217
|
+
if (!cancelled) {
|
|
2218
|
+
googleRequestRef.current = null;
|
|
2219
|
+
setGoogle({
|
|
2220
|
+
kind: "failed",
|
|
2221
|
+
value: [],
|
|
2222
|
+
message: errorMessage(error, "Unable to load Google Fonts.")
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
loadGoogleFonts();
|
|
2165
2228
|
return () => {
|
|
2166
|
-
|
|
2229
|
+
cancelled = true;
|
|
2230
|
+
if (googleRequestRef.current?.status === "loading") googleRequestRef.current = null;
|
|
2167
2231
|
};
|
|
2168
|
-
}, [
|
|
2169
|
-
useEffect(() => {
|
|
2170
|
-
if (!baseSnapshot) return;
|
|
2171
|
-
setState((current) => current ? syncStyleConfiguratorState(current, baseSnapshot) : createStyleConfiguratorState(baseSnapshot));
|
|
2172
|
-
}, [baseSnapshot]);
|
|
2232
|
+
}, [apiClient, enabled]);
|
|
2173
2233
|
useEffect(() => {
|
|
2174
|
-
if (!
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2234
|
+
if (!enabled) return;
|
|
2235
|
+
if (siteRequestRef.current?.apiClient === apiClient && siteRequestRef.current.siteId === siteId) return;
|
|
2236
|
+
let cancelled = false;
|
|
2237
|
+
siteRequestRef.current = {
|
|
2238
|
+
apiClient,
|
|
2239
|
+
siteId,
|
|
2240
|
+
status: "loading"
|
|
2241
|
+
};
|
|
2242
|
+
setSite((current) => ({
|
|
2243
|
+
kind: "loading",
|
|
2244
|
+
value: current.value
|
|
2245
|
+
}));
|
|
2246
|
+
async function loadSiteFonts() {
|
|
2247
|
+
try {
|
|
2248
|
+
const value = unwrapResponse(await apiClient({
|
|
2249
|
+
endpoint: "listSiteFonts",
|
|
2250
|
+
params: { siteId }
|
|
2251
|
+
}));
|
|
2252
|
+
if (!cancelled) {
|
|
2253
|
+
siteRequestRef.current = {
|
|
2254
|
+
apiClient,
|
|
2255
|
+
siteId,
|
|
2256
|
+
status: "loaded"
|
|
2257
|
+
};
|
|
2258
|
+
setSite({
|
|
2259
|
+
kind: "loaded",
|
|
2260
|
+
value: Array.isArray(value?.fonts) ? value.fonts : []
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
} catch (error) {
|
|
2264
|
+
if (!cancelled) {
|
|
2265
|
+
siteRequestRef.current = null;
|
|
2266
|
+
setSite({
|
|
2267
|
+
kind: "failed",
|
|
2268
|
+
value: [],
|
|
2269
|
+
message: errorMessage(error, "Unable to load your fonts.")
|
|
2270
|
+
});
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2186
2273
|
}
|
|
2187
|
-
|
|
2188
|
-
siteStyle,
|
|
2189
|
-
selection: state.previewed,
|
|
2190
|
-
baseTheme: theme,
|
|
2191
|
-
headerSelectionContext,
|
|
2192
|
-
footerSelectionContext
|
|
2193
|
-
}).themeOverlay, "site-style");
|
|
2194
|
-
}, [
|
|
2195
|
-
state,
|
|
2196
|
-
baseSnapshot,
|
|
2197
|
-
clearPreview,
|
|
2198
|
-
previewTheme,
|
|
2199
|
-
headerSelectionContext,
|
|
2200
|
-
footerSelectionContext,
|
|
2201
|
-
theme
|
|
2202
|
-
]);
|
|
2203
|
-
useEffect(() => {
|
|
2204
|
-
const runner = runnerRef.current;
|
|
2274
|
+
loadSiteFonts();
|
|
2205
2275
|
return () => {
|
|
2206
|
-
|
|
2207
|
-
|
|
2276
|
+
cancelled = true;
|
|
2277
|
+
if (siteRequestRef.current?.status === "loading") siteRequestRef.current = null;
|
|
2208
2278
|
};
|
|
2209
|
-
}, []);
|
|
2210
|
-
useEffect(() => {
|
|
2211
|
-
if (!expandedRowRequest) return;
|
|
2212
|
-
if (appliedExpandedRowRequestIdRef.current === expandedRowRequest.id) return;
|
|
2213
|
-
setState((current) => {
|
|
2214
|
-
if (!current) return current;
|
|
2215
|
-
appliedExpandedRowRequestIdRef.current = expandedRowRequest.id;
|
|
2216
|
-
return openRow(current, expandedRowForPreviewDesignRow(expandedRowRequest.row));
|
|
2217
|
-
});
|
|
2218
|
-
}, [expandedRowRequest, hasLoadedState]);
|
|
2219
|
-
const handlePreviewSiteStyle = useCallback((siteStyleId) => {
|
|
2220
|
-
setState((current) => {
|
|
2221
|
-
if (!current) return current;
|
|
2222
|
-
const next = previewSiteStyle(current, siteStyleId);
|
|
2223
|
-
const siteStyle = getCuratedSiteStyle(siteStyleId);
|
|
2224
|
-
if (!siteStyle) return next;
|
|
2225
|
-
const result = planSiteStylePreviewChange({
|
|
2226
|
-
siteStyle,
|
|
2227
|
-
selection: next.previewed,
|
|
2228
|
-
baseTheme: theme,
|
|
2229
|
-
headerSelectionContext,
|
|
2230
|
-
footerSelectionContext
|
|
2231
|
-
});
|
|
2232
|
-
return applyResolvedSelections(next, {
|
|
2233
|
-
resolved: result.resolvedSelections,
|
|
2234
|
-
...result.resolvedSelections.typographySelection.kind === "custom" ? { typographySelection: {
|
|
2235
|
-
kind: "custom",
|
|
2236
|
-
typography: result.themeOverlay.typography
|
|
2237
|
-
} } : {},
|
|
2238
|
-
warnings: result.warnings
|
|
2239
|
-
});
|
|
2240
|
-
});
|
|
2241
2279
|
}, [
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2280
|
+
apiClient,
|
|
2281
|
+
enabled,
|
|
2282
|
+
siteId
|
|
2245
2283
|
]);
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
}, []);
|
|
2253
|
-
const handlePreviewHeaderStyle = useCallback((id) => {
|
|
2254
|
-
if (!id) return;
|
|
2255
|
-
setState((current) => current ? previewHeaderStyle(current, id) : current);
|
|
2256
|
-
}, []);
|
|
2257
|
-
const handlePreviewFooterLook = useCallback((id) => {
|
|
2258
|
-
const plan = planSiteChromeLookSelection({
|
|
2259
|
-
surface: "footer",
|
|
2260
|
-
lookId: id
|
|
2261
|
-
});
|
|
2262
|
-
if (plan.kind !== "footer") return;
|
|
2263
|
-
setState((current) => current ? previewFooterLook(current, plan.next.footerLookId) : current);
|
|
2264
|
-
}, []);
|
|
2265
|
-
const handlePreviewFooterLayout = useCallback((id) => {
|
|
2266
|
-
if (!id) return;
|
|
2267
|
-
setState((current) => {
|
|
2268
|
-
if (!current) return current;
|
|
2269
|
-
const siteStyle = getCuratedSiteStyle(current.previewed.siteStyleId);
|
|
2270
|
-
if (!siteStyle) return current;
|
|
2271
|
-
const models = buildSiteChromeLookModels({
|
|
2272
|
-
state: current,
|
|
2273
|
-
siteStyle,
|
|
2274
|
-
headerSelectionContext,
|
|
2275
|
-
footerSelectionContext
|
|
2276
|
-
});
|
|
2277
|
-
const nextLookId = planSiteChromeFooterLayoutSelection({
|
|
2278
|
-
layoutId: id,
|
|
2279
|
-
currentLookId: current.previewed.footerLookId ?? models.footer.renderedLookId
|
|
2280
|
-
});
|
|
2281
|
-
return nextLookId ? previewFooterLook(current, nextLookId) : current;
|
|
2282
|
-
});
|
|
2283
|
-
}, [footerSelectionContext, headerSelectionContext]);
|
|
2284
|
-
const handlePreviewPalette = useCallback((id) => {
|
|
2285
|
-
const curated = findCuratedPalette(id);
|
|
2286
|
-
if (!curated) return;
|
|
2287
|
-
setState((current) => current ? previewCuratedPalette(current, {
|
|
2288
|
-
paletteId: curated.id,
|
|
2289
|
-
colors: curated.colors,
|
|
2290
|
-
mode: curated.mode
|
|
2291
|
-
}) : current);
|
|
2292
|
-
}, []);
|
|
2293
|
-
const handlePreviewTypographyPreset = useCallback((id) => {
|
|
2294
|
-
setState((current) => current ? previewTypographyPreset(current, id) : current);
|
|
2295
|
-
}, []);
|
|
2296
|
-
const patchTypography = useCallback((patch) => {
|
|
2297
|
-
setState((current) => {
|
|
2298
|
-
if (!current) return current;
|
|
2299
|
-
const siteStyle = getCuratedSiteStyle(current.previewed.siteStyleId);
|
|
2300
|
-
if (!siteStyle) return current;
|
|
2301
|
-
return applyTypographyDraftPatch(current, planSiteStylePreviewChange({
|
|
2302
|
-
siteStyle,
|
|
2303
|
-
selection: current.previewed,
|
|
2304
|
-
baseTheme: theme,
|
|
2305
|
-
headerSelectionContext,
|
|
2306
|
-
footerSelectionContext
|
|
2307
|
-
}).themeOverlay.typography, patch);
|
|
2308
|
-
});
|
|
2309
|
-
}, [
|
|
2310
|
-
footerSelectionContext,
|
|
2311
|
-
headerSelectionContext,
|
|
2312
|
-
theme
|
|
2313
|
-
]);
|
|
2314
|
-
const handleHeadingTypographyChange = useCallback((patch) => {
|
|
2315
|
-
patchTypography({
|
|
2316
|
-
kind: "heading",
|
|
2317
|
-
patch
|
|
2318
|
-
});
|
|
2319
|
-
}, [patchTypography]);
|
|
2320
|
-
const handleBodyTypographyChange = useCallback((patch) => {
|
|
2321
|
-
patchTypography({
|
|
2322
|
-
kind: "body",
|
|
2323
|
-
patch
|
|
2324
|
-
});
|
|
2325
|
-
}, [patchTypography]);
|
|
2326
|
-
const handleTypographyScaleChange = useCallback((scale) => {
|
|
2327
|
-
patchTypography({
|
|
2328
|
-
kind: "scale",
|
|
2329
|
-
scale
|
|
2330
|
-
});
|
|
2331
|
-
}, [patchTypography]);
|
|
2332
|
-
const handleResetTypography = useCallback(() => {
|
|
2333
|
-
setState((current) => current ? resetTypographyToSaved(current) : current);
|
|
2334
|
-
}, []);
|
|
2335
|
-
const handleTokenOverride = useCallback((role, hex) => {
|
|
2336
|
-
setState((current) => {
|
|
2337
|
-
if (!current) return current;
|
|
2338
|
-
const palette = current.previewed.palette;
|
|
2339
|
-
if (palette.kind === "invalid") return current;
|
|
2340
|
-
if (!(role in palette.colors)) return current;
|
|
2341
|
-
const nextColors = paletteColorsSchema.safeParse({
|
|
2342
|
-
...palette.colors,
|
|
2343
|
-
[role]: hex
|
|
2344
|
-
});
|
|
2345
|
-
return nextColors.success ? setPaletteColors(current, nextColors.data) : current;
|
|
2346
|
-
});
|
|
2347
|
-
}, []);
|
|
2348
|
-
const handleResetOverrides = useCallback(() => {
|
|
2349
|
-
setState((current) => {
|
|
2350
|
-
if (!current || current.previewed.palette.kind !== "migrated-curated") return current;
|
|
2351
|
-
const curated = findCuratedPalette(current.previewed.palette.paletteId);
|
|
2352
|
-
return curated ? setPaletteColors(current, curated.colors) : current;
|
|
2353
|
-
});
|
|
2354
|
-
}, []);
|
|
2355
|
-
const handleToggleRow = useCallback((row) => {
|
|
2356
|
-
setState((current) => current ? toggleRow(current, row) : current);
|
|
2357
|
-
}, []);
|
|
2358
|
-
const handleCancel = useCallback(() => {
|
|
2359
|
-
setState((current) => current ? cancelPreview(current) : current);
|
|
2360
|
-
}, []);
|
|
2361
|
-
const handleDismissWarnings = useCallback(() => {
|
|
2362
|
-
setState((current) => current ? dismissWarnings(current) : current);
|
|
2363
|
-
}, []);
|
|
2364
|
-
const handleApply = useCallback(async () => {
|
|
2365
|
-
const live = stateRef.current;
|
|
2366
|
-
if (!live || !isPreviewingChange(live)) return;
|
|
2367
|
-
if (!deriveStyleConfiguratorCapabilities(live).canApplyStaged) return;
|
|
2368
|
-
const previewed = live.previewed;
|
|
2369
|
-
const siteStyle = getCuratedSiteStyle(previewed.siteStyleId);
|
|
2370
|
-
if (!siteStyle) return;
|
|
2371
|
-
const compiled = planSiteStylePreviewChange({
|
|
2372
|
-
siteStyle,
|
|
2373
|
-
selection: previewed,
|
|
2374
|
-
baseTheme: theme,
|
|
2375
|
-
headerSelectionContext,
|
|
2376
|
-
footerSelectionContext
|
|
2377
|
-
});
|
|
2378
|
-
await runnerRef.current.run({
|
|
2379
|
-
optimistic: () => {
|
|
2380
|
-
applyStarted("style-configurator");
|
|
2381
|
-
setState((current) => current ? markApplySaving(current) : current);
|
|
2382
|
-
},
|
|
2383
|
-
network: async () => {
|
|
2384
|
-
const body = buildApplySiteStyleSelectionBody({
|
|
2385
|
-
base: live.base,
|
|
2386
|
-
previewed: {
|
|
2387
|
-
...previewed,
|
|
2388
|
-
buttonPersonalityId: compiled.resolvedSelections.buttonPersonalityId,
|
|
2389
|
-
headerLayoutId: compiled.resolvedSelections.headerLayoutId,
|
|
2390
|
-
headerStyleId: compiled.resolvedSelections.headerStyleId,
|
|
2391
|
-
headerLookId: compiled.resolvedSelections.headerLookId,
|
|
2392
|
-
typographySelection: compiled.resolvedSelections.typographySelection.kind === "custom" ? {
|
|
2393
|
-
kind: "custom",
|
|
2394
|
-
typography: compiled.themeOverlay.typography
|
|
2395
|
-
} : typographySelectionSnapshotFromFlat(compiled.resolvedSelections)
|
|
2396
|
-
},
|
|
2397
|
-
selectionId
|
|
2398
|
-
});
|
|
2399
|
-
if (!body.ok) throw new Error(paletteApplyPlanErrorMessage(body.error));
|
|
2400
|
-
return unwrapResponse(await apiClient({
|
|
2401
|
-
endpoint: "applySiteStyleSelection",
|
|
2402
|
-
params: { siteId },
|
|
2403
|
-
body: body.body
|
|
2404
|
-
}));
|
|
2405
|
-
},
|
|
2406
|
-
onSuccess: (saved) => {
|
|
2407
|
-
const persisted = selectionSnapshotFromApplySiteStyleSelectionResponse(saved, previewed);
|
|
2408
|
-
const historyEntry = styleConfiguratorHistoryEntryForPersistedSelection(live, persisted);
|
|
2409
|
-
setState((current) => current ? markApplySaved(current, persisted) : current);
|
|
2410
|
-
if (historyEntry) siteChromeCustomize?.siteStyleHistory?.recordAppliedSelection(historyEntry);
|
|
2411
|
-
applySucceeded("style-configurator");
|
|
2412
|
-
startRefreshTransition(() => {
|
|
2413
|
-
router.refresh();
|
|
2414
|
-
});
|
|
2415
|
-
},
|
|
2416
|
-
onError: (error) => {
|
|
2417
|
-
applyFailed("style-configurator");
|
|
2418
|
-
const applyError = classifyStyleApplyError(error);
|
|
2419
|
-
if (applyError.kind === "stale") startRefreshTransition(() => {
|
|
2420
|
-
router.refresh();
|
|
2421
|
-
});
|
|
2422
|
-
const message = applyError.message;
|
|
2423
|
-
setState((current) => current ? markApplyFailed(current, message, applyError.kind === "stale" ? "stale" : "retryable") : current);
|
|
2424
|
-
}
|
|
2425
|
-
});
|
|
2426
|
-
}, [
|
|
2427
|
-
apiClient,
|
|
2428
|
-
footerSelectionContext,
|
|
2429
|
-
headerSelectionContext,
|
|
2430
|
-
applyFailed,
|
|
2431
|
-
applyStarted,
|
|
2432
|
-
applySucceeded,
|
|
2433
|
-
router,
|
|
2434
|
-
selectionId,
|
|
2435
|
-
siteChromeCustomize?.siteStyleHistory,
|
|
2436
|
-
siteId,
|
|
2437
|
-
startRefreshTransition,
|
|
2438
|
-
theme
|
|
2439
|
-
]);
|
|
2440
|
-
if (!state || !baseSnapshot) return /* @__PURE__ */ jsx("p", {
|
|
2441
|
-
className: "text-sm text-muted-foreground",
|
|
2442
|
-
children: "Loading design controls..."
|
|
2443
|
-
});
|
|
2444
|
-
const applyAllowed = canApplySiteStyle(siteStyleAccess);
|
|
2445
|
-
const stagedCapabilities = deriveStyleConfiguratorCapabilities(state);
|
|
2446
|
-
const previewingChange = isPreviewingChange(state);
|
|
2447
|
-
const saving = stagedCapabilities.isApplyingStaged || isRefreshPending;
|
|
2448
|
-
const aggregateMutationControlsDisabled = saving || !stagedCapabilities.canPreviewStaged;
|
|
2449
|
-
const currentSiteStyle = getCuratedSiteStyle(state.previewed.siteStyleId);
|
|
2450
|
-
if (!currentSiteStyle) return /* @__PURE__ */ jsx("p", {
|
|
2451
|
-
className: "text-sm text-muted-foreground",
|
|
2452
|
-
children: "This site uses a Site Style that cannot be configured here."
|
|
2453
|
-
});
|
|
2454
|
-
const currentPersonality = findButtonPersonality(state.previewed.buttonPersonalityId);
|
|
2455
|
-
const currentPalette = state.previewed.palette;
|
|
2456
|
-
const paletteMutation = paletteMutationCapability(state);
|
|
2457
|
-
const paletteControlsDisabled = saving || paletteMutation.kind !== "editable";
|
|
2458
|
-
const currentCuratedPalette = currentPalette.kind === "migrated-curated" ? findCuratedPalette(currentPalette.paletteId) : null;
|
|
2459
|
-
const currentTypographyPreset = state.previewed.typographySelection.kind === "preset" && state.previewed.typographySelection.presetId ? findTypographyPreset(state.previewed.typographySelection.presetId) : null;
|
|
2460
|
-
const currentTypography = planSiteStylePreviewChange({
|
|
2461
|
-
siteStyle: currentSiteStyle,
|
|
2462
|
-
selection: state.previewed,
|
|
2463
|
-
baseTheme: theme,
|
|
2464
|
-
headerSelectionContext,
|
|
2465
|
-
footerSelectionContext
|
|
2466
|
-
}).themeOverlay.typography;
|
|
2467
|
-
const chromeLookModels = buildSiteChromeLookModels({
|
|
2468
|
-
state,
|
|
2469
|
-
siteStyle: currentSiteStyle,
|
|
2470
|
-
headerSelectionContext,
|
|
2471
|
-
footerSelectionContext
|
|
2472
|
-
});
|
|
2473
|
-
const currentHeaderLayout = getHeaderLayout(state.previewed.headerLayoutId);
|
|
2474
|
-
const currentHeaderStyle = getHeaderStyle(state.previewed.headerStyleId);
|
|
2475
|
-
const currentFooterLayout = getFooterLayout(chromeLookModels.footerLayout.renderedLayoutId);
|
|
2476
|
-
const currentFooterLook = state.previewed.footerLookId ? findFooterLook(state.previewed.footerLookId) : findFooterLook(chromeLookModels.footer.renderedLookId);
|
|
2477
|
-
const headerSurfaceState = siteChromeCustomize?.getSurfaceState("header") ?? { kind: "unavailable" };
|
|
2284
|
+
return {
|
|
2285
|
+
google,
|
|
2286
|
+
site
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2289
|
+
function TypographyOverviewContent({ typography, catalog, onChooseFont, onOpenAdvanced, onReset, disabled }) {
|
|
2478
2290
|
return /* @__PURE__ */ jsxs("div", {
|
|
2479
2291
|
className: "space-y-3",
|
|
2480
2292
|
children: [
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2293
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2294
|
+
className: "space-y-2",
|
|
2295
|
+
children: [/* @__PURE__ */ jsx(TypographyRoleSummary, {
|
|
2296
|
+
slot: "heading",
|
|
2297
|
+
family: typography.headings.default.family,
|
|
2298
|
+
catalog,
|
|
2299
|
+
onChoose: () => onChooseFont("heading"),
|
|
2300
|
+
disabled
|
|
2301
|
+
}), /* @__PURE__ */ jsx(TypographyRoleSummary, {
|
|
2302
|
+
slot: "body",
|
|
2303
|
+
family: typography.body.family,
|
|
2304
|
+
catalog,
|
|
2305
|
+
onChoose: () => onChooseFont("body"),
|
|
2306
|
+
disabled
|
|
2307
|
+
})]
|
|
2491
2308
|
}),
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2309
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2310
|
+
className: "flex items-center gap-2 border-t pt-3",
|
|
2311
|
+
children: [/* @__PURE__ */ jsxs(Button, {
|
|
2312
|
+
type: "button",
|
|
2313
|
+
size: "sm",
|
|
2314
|
+
variant: "outline",
|
|
2315
|
+
className: "flex-1 justify-between",
|
|
2316
|
+
onClick: onOpenAdvanced,
|
|
2317
|
+
disabled,
|
|
2318
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
2319
|
+
className: "inline-flex items-center gap-2",
|
|
2320
|
+
children: [/* @__PURE__ */ jsx(SlidersHorizontal, {
|
|
2321
|
+
className: "h-3.5 w-3.5",
|
|
2322
|
+
"aria-hidden": "true"
|
|
2323
|
+
}), "Advanced typography"]
|
|
2324
|
+
}), /* @__PURE__ */ jsx(ChevronRight, {
|
|
2325
|
+
className: "h-3.5 w-3.5",
|
|
2326
|
+
"aria-hidden": "true"
|
|
2327
|
+
})]
|
|
2328
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
2329
|
+
type: "button",
|
|
2330
|
+
size: "sm",
|
|
2331
|
+
variant: "ghost",
|
|
2332
|
+
onClick: onReset,
|
|
2333
|
+
disabled,
|
|
2334
|
+
children: "Reset"
|
|
2335
|
+
})]
|
|
2509
2336
|
}),
|
|
2510
|
-
/* @__PURE__ */ jsx(
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2337
|
+
/* @__PURE__ */ jsx(SiteFontFaceStyles, { siteFonts: catalog.site.value })
|
|
2338
|
+
]
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
function TypographyRoleSummary({ slot, family, catalog, onChoose, disabled }) {
|
|
2342
|
+
const primaryFamily = primaryFontFamily(family);
|
|
2343
|
+
const option = fontOptionForFamily(primaryFamily, {
|
|
2344
|
+
googleFonts: catalog.google.value,
|
|
2345
|
+
siteFonts: catalog.site.value
|
|
2346
|
+
});
|
|
2347
|
+
const label = slot === "heading" ? "Heading" : "Body";
|
|
2348
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
2349
|
+
type: "button",
|
|
2350
|
+
className: "group flex w-full items-center gap-3 rounded-md border bg-background px-3 py-3 text-left transition hover:border-foreground/30 hover:bg-accent/20 disabled:cursor-not-allowed disabled:opacity-50",
|
|
2351
|
+
"aria-label": `Choose ${label.toLocaleLowerCase()} font, currently ${primaryFamily}`,
|
|
2352
|
+
onClick: onChoose,
|
|
2353
|
+
disabled,
|
|
2354
|
+
children: [
|
|
2355
|
+
/* @__PURE__ */ jsx(FontPreviewText, {
|
|
2356
|
+
family: primaryFamily,
|
|
2357
|
+
source: option?.source ?? "unknown",
|
|
2358
|
+
className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted/70 text-xl",
|
|
2359
|
+
children: slot === "heading" ? "Hh" : "Aa"
|
|
2533
2360
|
}),
|
|
2534
|
-
/* @__PURE__ */
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
onCycle: (direction) => {
|
|
2546
|
-
const next = cycleSiteChromeLookId(chromeLookModels.footerLayout.options, chromeLookModels.footerLayout.renderedLayoutId, direction);
|
|
2547
|
-
if (next !== void 0) handlePreviewFooterLayout(next);
|
|
2548
|
-
},
|
|
2549
|
-
onPreview: handlePreviewFooterLayout,
|
|
2550
|
-
disabled: aggregateMutationControlsDisabled
|
|
2551
|
-
}),
|
|
2552
|
-
/* @__PURE__ */ jsx(SiteChromeLookRow, {
|
|
2553
|
-
label: "Footer look",
|
|
2554
|
-
ariaLabel: "Footer look",
|
|
2555
|
-
defaultDescription: "Use the footer look chosen for this site style.",
|
|
2556
|
-
expanded: state.expandedRow === "footer",
|
|
2557
|
-
onToggle: () => handleToggleRow("footer"),
|
|
2558
|
-
currentId: state.previewed.footerLookId,
|
|
2559
|
-
currentLabel: state.previewed.footerLookId ? currentFooterLook?.label ?? "Unknown footer Look" : `${currentFooterLook?.label ?? "Site style"} (default)`,
|
|
2560
|
-
scopeDescription: "Changes the footer on every page.",
|
|
2561
|
-
options: chromeLookModels.footer.options,
|
|
2562
|
-
diagnostics: chromeLookModels.footer.diagnostics,
|
|
2563
|
-
onCycle: (direction) => {
|
|
2564
|
-
const next = cycleSiteChromeLookId(chromeLookModels.footer.options, state.previewed.footerLookId, direction);
|
|
2565
|
-
if (next !== void 0) handlePreviewFooterLook(next);
|
|
2566
|
-
},
|
|
2567
|
-
onPreview: handlePreviewFooterLook,
|
|
2568
|
-
disabled: aggregateMutationControlsDisabled
|
|
2569
|
-
}),
|
|
2570
|
-
/* @__PURE__ */ jsx(PersonalityRow, {
|
|
2571
|
-
expanded: state.expandedRow === "buttons",
|
|
2572
|
-
onToggle: () => handleToggleRow("buttons"),
|
|
2573
|
-
siteStyle: currentSiteStyle,
|
|
2574
|
-
currentId: state.previewed.buttonPersonalityId,
|
|
2575
|
-
currentLabel: currentPersonality?.name ?? state.previewed.buttonPersonalityId,
|
|
2576
|
-
onPreview: handlePreviewPersonality,
|
|
2577
|
-
disabled: aggregateMutationControlsDisabled
|
|
2361
|
+
/* @__PURE__ */ jsxs("span", {
|
|
2362
|
+
className: "min-w-0 flex-1",
|
|
2363
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2364
|
+
className: "block text-xs font-medium text-muted-foreground",
|
|
2365
|
+
children: label
|
|
2366
|
+
}), /* @__PURE__ */ jsx(FontPreviewText, {
|
|
2367
|
+
family: primaryFamily,
|
|
2368
|
+
source: option?.source ?? "unknown",
|
|
2369
|
+
className: "block truncate text-base",
|
|
2370
|
+
children: primaryFamily
|
|
2371
|
+
})]
|
|
2578
2372
|
}),
|
|
2579
|
-
/* @__PURE__ */ jsx(
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2373
|
+
/* @__PURE__ */ jsx(ChevronRight, {
|
|
2374
|
+
className: "h-4 w-4 shrink-0 text-muted-foreground transition group-hover:text-foreground",
|
|
2375
|
+
"aria-hidden": "true"
|
|
2376
|
+
})
|
|
2377
|
+
]
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
function TypographyFontPickerTakeover({ slot, value, catalog, onBack, onChange, disabled }) {
|
|
2381
|
+
const [query, setQuery] = useState("");
|
|
2382
|
+
const [category, setCategory] = useState("all");
|
|
2383
|
+
const [visibleGoogleCount, setVisibleGoogleCount] = useState(24);
|
|
2384
|
+
const selectedFamily = primaryFontFamily(value);
|
|
2385
|
+
const catalogResult = useMemo(() => buildTypographyFontCatalog({
|
|
2386
|
+
googleFonts: catalog.google.value,
|
|
2387
|
+
siteFonts: catalog.site.value,
|
|
2388
|
+
query,
|
|
2389
|
+
category
|
|
2390
|
+
}), [
|
|
2391
|
+
catalog.google.value,
|
|
2392
|
+
catalog.site.value,
|
|
2393
|
+
category,
|
|
2394
|
+
query
|
|
2395
|
+
]);
|
|
2396
|
+
const searching = query.trim().length > 0;
|
|
2397
|
+
const visibleGoogle = searching ? catalogResult.google : visibleTypographyFontOptions({
|
|
2398
|
+
options: catalogResult.google,
|
|
2399
|
+
selectedFamily,
|
|
2400
|
+
limit: visibleGoogleCount
|
|
2401
|
+
});
|
|
2402
|
+
const hasMore = !searching && visibleGoogle.length < catalogResult.google.length;
|
|
2403
|
+
const title = slot === "heading" ? "Heading font" : "Body font";
|
|
2404
|
+
useEffect(() => {
|
|
2405
|
+
setVisibleGoogleCount(24);
|
|
2406
|
+
}, [category, slot]);
|
|
2407
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
2408
|
+
"aria-label": title,
|
|
2409
|
+
className: "flex min-h-0 flex-1 flex-col overflow-hidden bg-background",
|
|
2410
|
+
children: [
|
|
2411
|
+
/* @__PURE__ */ jsxs("header", {
|
|
2412
|
+
className: "shrink-0 space-y-3 border-b p-3",
|
|
2413
|
+
children: [
|
|
2414
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2415
|
+
className: "flex items-center gap-2",
|
|
2416
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
2417
|
+
type: "button",
|
|
2418
|
+
size: "icon",
|
|
2419
|
+
variant: "ghost",
|
|
2420
|
+
className: "h-8 w-8 shrink-0",
|
|
2421
|
+
onClick: onBack,
|
|
2422
|
+
"aria-label": "Back to typography",
|
|
2423
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, {
|
|
2424
|
+
className: "h-4 w-4",
|
|
2425
|
+
"aria-hidden": "true"
|
|
2426
|
+
})
|
|
2427
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
2428
|
+
className: "min-w-0",
|
|
2429
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
2430
|
+
className: "text-sm font-semibold",
|
|
2431
|
+
children: title
|
|
2432
|
+
}), /* @__PURE__ */ jsxs("p", {
|
|
2433
|
+
className: "truncate text-xs text-muted-foreground",
|
|
2434
|
+
children: ["Current: ", selectedFamily]
|
|
2435
|
+
})]
|
|
2436
|
+
})]
|
|
2437
|
+
}),
|
|
2438
|
+
/* @__PURE__ */ jsx(SearchInput, {
|
|
2439
|
+
value: query,
|
|
2440
|
+
onChange: (event) => setQuery(event.currentTarget.value),
|
|
2441
|
+
placeholder: "Search fonts",
|
|
2442
|
+
"aria-label": `Search ${slot} fonts`,
|
|
2443
|
+
disabled
|
|
2444
|
+
}),
|
|
2445
|
+
/* @__PURE__ */ jsx("div", {
|
|
2446
|
+
role: "group",
|
|
2447
|
+
"aria-label": "Font category",
|
|
2448
|
+
className: "flex gap-1 overflow-x-auto pb-0.5",
|
|
2449
|
+
children: typographyFontCategories.map((option) => /* @__PURE__ */ jsx(Button, {
|
|
2450
|
+
type: "button",
|
|
2451
|
+
size: "sm",
|
|
2452
|
+
variant: category === option.value ? "secondary" : "ghost",
|
|
2453
|
+
className: "h-7 shrink-0 px-2 text-xs",
|
|
2454
|
+
"aria-pressed": category === option.value,
|
|
2455
|
+
onClick: () => setCategory(option.value),
|
|
2456
|
+
disabled,
|
|
2457
|
+
children: option.label
|
|
2458
|
+
}, option.value))
|
|
2459
|
+
})
|
|
2460
|
+
]
|
|
2593
2461
|
}),
|
|
2594
|
-
/* @__PURE__ */
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2462
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2463
|
+
"data-typography-font-catalog-scroll": true,
|
|
2464
|
+
className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-2",
|
|
2465
|
+
children: [
|
|
2466
|
+
/* @__PURE__ */ jsx(FontCatalogFeedback, { catalog }),
|
|
2467
|
+
catalogResult.site.length > 0 ? /* @__PURE__ */ jsx(FontOptionSection, {
|
|
2468
|
+
label: "Your fonts",
|
|
2469
|
+
children: catalogResult.site.map((option) => /* @__PURE__ */ jsx(TypographyFontOptionRow, {
|
|
2470
|
+
option,
|
|
2471
|
+
selected: familyMatches(selectedFamily, option.family),
|
|
2472
|
+
onSelect: () => onChange(option.family),
|
|
2473
|
+
disabled
|
|
2474
|
+
}, `site:${option.family}`))
|
|
2475
|
+
}) : null,
|
|
2476
|
+
visibleGoogle.length > 0 ? /* @__PURE__ */ jsxs(FontOptionSection, {
|
|
2477
|
+
label: searching ? "Matching fonts" : "Popular fonts",
|
|
2478
|
+
children: [visibleGoogle.map((option) => /* @__PURE__ */ jsx(TypographyFontOptionRow, {
|
|
2479
|
+
option,
|
|
2480
|
+
selected: familyMatches(selectedFamily, option.family),
|
|
2481
|
+
onSelect: () => onChange(option.family),
|
|
2482
|
+
disabled
|
|
2483
|
+
}, `google:${option.family}`)), hasMore ? /* @__PURE__ */ jsx(Button, {
|
|
2484
|
+
type: "button",
|
|
2485
|
+
size: "sm",
|
|
2486
|
+
variant: "ghost",
|
|
2487
|
+
className: "mt-1 w-full",
|
|
2488
|
+
onClick: () => setVisibleGoogleCount((count) => count + 24),
|
|
2489
|
+
disabled,
|
|
2490
|
+
children: "Show more fonts"
|
|
2491
|
+
}) : null]
|
|
2492
|
+
}) : catalog.google.kind === "loaded" && catalog.site.kind === "loaded" ? /* @__PURE__ */ jsx("p", {
|
|
2493
|
+
className: "px-2 py-8 text-center text-sm text-muted-foreground",
|
|
2494
|
+
children: "No fonts match your search."
|
|
2495
|
+
}) : null
|
|
2496
|
+
]
|
|
2604
2497
|
}),
|
|
2605
|
-
|
|
2606
|
-
expanded: state.expandedRow === "colours",
|
|
2607
|
-
onToggle: () => handleToggleRow("colours"),
|
|
2608
|
-
palette: currentPalette.colors,
|
|
2609
|
-
isCustom: !currentCuratedPalette || currentPalette.mode !== currentCuratedPalette.mode || !paletteColorsEqual(currentPalette.colors, currentCuratedPalette.colors),
|
|
2610
|
-
onTokenChange: handleTokenOverride,
|
|
2611
|
-
onReset: handleResetOverrides,
|
|
2612
|
-
disabled: paletteControlsDisabled,
|
|
2613
|
-
mutationCapability: paletteMutation
|
|
2614
|
-
}) : null,
|
|
2615
|
-
previewingChange ? /* @__PURE__ */ jsxs("div", {
|
|
2616
|
-
className: "flex items-center gap-2 pt-2",
|
|
2617
|
-
children: [/* @__PURE__ */ jsx(Button, {
|
|
2618
|
-
type: "button",
|
|
2619
|
-
size: "sm",
|
|
2620
|
-
variant: "outline",
|
|
2621
|
-
onClick: handleCancel,
|
|
2622
|
-
disabled: !stagedCapabilities.canCancelStaged || saving,
|
|
2623
|
-
children: "Cancel"
|
|
2624
|
-
}), applyAllowed ? /* @__PURE__ */ jsx(Button, {
|
|
2625
|
-
type: "button",
|
|
2626
|
-
size: "sm",
|
|
2627
|
-
onClick: handleApply,
|
|
2628
|
-
disabled: !stagedCapabilities.canApplyStaged || saving,
|
|
2629
|
-
children: saving ? "Applying…" : "Apply"
|
|
2630
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
2631
|
-
className: "text-xs text-muted-foreground",
|
|
2632
|
-
children: "Preview only — ask an admin to apply."
|
|
2633
|
-
})]
|
|
2634
|
-
}) : null,
|
|
2635
|
-
state.saveStatus.kind === "saved" ? /* @__PURE__ */ jsx("p", {
|
|
2636
|
-
className: "text-xs text-success",
|
|
2637
|
-
children: "Saved."
|
|
2638
|
-
}) : null,
|
|
2639
|
-
state.saveStatus.kind === "failed" ? /* @__PURE__ */ jsx("p", {
|
|
2640
|
-
className: "text-xs text-destructive",
|
|
2641
|
-
children: state.saveStatus.message
|
|
2642
|
-
}) : null
|
|
2498
|
+
/* @__PURE__ */ jsx(SiteFontFaceStyles, { siteFonts: catalog.site.value })
|
|
2643
2499
|
]
|
|
2644
2500
|
});
|
|
2645
2501
|
}
|
|
2646
|
-
function
|
|
2647
|
-
return /* @__PURE__ */
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
children: /* @__PURE__ */
|
|
2651
|
-
className: "
|
|
2652
|
-
children:
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
"aria-expanded": expanded,
|
|
2658
|
-
children: [
|
|
2659
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: cn("h-4 w-4 transition", expanded && "rotate-90") }),
|
|
2660
|
-
/* @__PURE__ */ jsxs("div", {
|
|
2661
|
-
className: "flex-1 min-w-0",
|
|
2662
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
2663
|
-
className: "text-xs uppercase tracking-wide text-muted-foreground",
|
|
2664
|
-
children: label
|
|
2665
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
2666
|
-
className: "truncate text-sm font-medium",
|
|
2667
|
-
children: currentLabel
|
|
2668
|
-
})]
|
|
2669
|
-
}),
|
|
2670
|
-
swatch ? /* @__PURE__ */ jsx("span", {
|
|
2671
|
-
className: "h-5 w-5 shrink-0 rounded-full border border-black/10",
|
|
2672
|
-
style: { backgroundColor: swatch },
|
|
2673
|
-
"aria-hidden": "true"
|
|
2674
|
-
}) : null
|
|
2675
|
-
]
|
|
2676
|
-
})
|
|
2677
|
-
}), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", {
|
|
2678
|
-
className: "border-t px-3 py-3",
|
|
2679
|
-
children
|
|
2680
|
-
}) })]
|
|
2681
|
-
})
|
|
2502
|
+
function FontOptionSection({ label, children }) {
|
|
2503
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
2504
|
+
"aria-label": label,
|
|
2505
|
+
className: "mb-3 last:mb-0",
|
|
2506
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
2507
|
+
className: "sticky top-0 z-[1] bg-background px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",
|
|
2508
|
+
children: label
|
|
2509
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
2510
|
+
className: "space-y-0.5",
|
|
2511
|
+
children
|
|
2512
|
+
})]
|
|
2682
2513
|
});
|
|
2683
2514
|
}
|
|
2684
|
-
function
|
|
2685
|
-
return /* @__PURE__ */
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
})
|
|
2515
|
+
function TypographyFontOptionRow({ option, selected, onSelect, disabled }) {
|
|
2516
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
2517
|
+
type: "button",
|
|
2518
|
+
"aria-pressed": selected,
|
|
2519
|
+
"aria-label": option.label,
|
|
2520
|
+
className: cn("flex min-h-11 w-full items-center gap-3 rounded-md border border-transparent px-3 py-2 text-left transition disabled:cursor-not-allowed disabled:opacity-50", selected ? "border-primary/60 bg-primary/10" : "hover:border-border hover:bg-accent/30"),
|
|
2521
|
+
onClick: onSelect,
|
|
2522
|
+
disabled,
|
|
2523
|
+
children: [/* @__PURE__ */ jsx(FontPreviewText, {
|
|
2524
|
+
family: option.family,
|
|
2525
|
+
source: option.source,
|
|
2526
|
+
className: "min-w-0 flex-1 truncate text-base",
|
|
2527
|
+
children: option.label
|
|
2528
|
+
}), selected ? /* @__PURE__ */ jsx(Check, {
|
|
2529
|
+
className: "h-4 w-4 shrink-0 text-primary",
|
|
2530
|
+
"aria-hidden": "true"
|
|
2531
|
+
}) : null]
|
|
2702
2532
|
});
|
|
2703
2533
|
}
|
|
2704
|
-
function
|
|
2705
|
-
return /* @__PURE__ */ jsx(
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
className: "
|
|
2714
|
-
children:
|
|
2715
|
-
|
|
2716
|
-
label: personality.name,
|
|
2717
|
-
description: personality.description,
|
|
2718
|
-
onSelect: () => onPreview(personality.id),
|
|
2719
|
-
disabled
|
|
2720
|
-
}, personality.id))
|
|
2721
|
-
})
|
|
2534
|
+
function FontCatalogFeedback({ catalog }) {
|
|
2535
|
+
if ((catalog.google.kind === "loading" || catalog.google.kind === "idle") && catalog.google.value.length === 0) return /* @__PURE__ */ jsx("p", {
|
|
2536
|
+
className: "px-2 py-6 text-center text-sm text-muted-foreground",
|
|
2537
|
+
children: "Loading font catalog…"
|
|
2538
|
+
});
|
|
2539
|
+
const failureMessages = [catalog.site.kind === "failed" ? catalog.site.message : null, catalog.google.kind === "failed" ? catalog.google.message : null].filter((message) => message !== null);
|
|
2540
|
+
if (failureMessages.length > 0) return /* @__PURE__ */ jsx("div", {
|
|
2541
|
+
className: "mb-2 space-y-1",
|
|
2542
|
+
children: failureMessages.map((message) => /* @__PURE__ */ jsx("p", {
|
|
2543
|
+
className: "rounded-md bg-muted/60 px-3 py-2 text-xs text-muted-foreground",
|
|
2544
|
+
children: message
|
|
2545
|
+
}, message))
|
|
2722
2546
|
});
|
|
2547
|
+
return null;
|
|
2723
2548
|
}
|
|
2724
|
-
function
|
|
2725
|
-
const
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
const
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
className: "
|
|
2741
|
-
children:
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2549
|
+
function TypographyAdvancedTakeover({ typography, catalog, onBack, onHeadingChange, onBodyChange, onScaleChange, disabled }) {
|
|
2550
|
+
const headingOption = fontOptionForFamily(typography.headings.default.family, {
|
|
2551
|
+
googleFonts: catalog.google.value,
|
|
2552
|
+
siteFonts: catalog.site.value
|
|
2553
|
+
});
|
|
2554
|
+
const bodyOption = fontOptionForFamily(typography.body.family, {
|
|
2555
|
+
googleFonts: catalog.google.value,
|
|
2556
|
+
siteFonts: catalog.site.value
|
|
2557
|
+
});
|
|
2558
|
+
const headingWeightWarning = unsupportedWeightMessage(headingOption, typography.headings.default.weight, typography.headings.default.italic === true ? "italic" : "normal");
|
|
2559
|
+
const bodyWeightWarning = unsupportedWeightMessage(bodyOption, typography.body.weight, "normal");
|
|
2560
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
2561
|
+
"aria-label": "Advanced typography",
|
|
2562
|
+
className: "flex min-h-0 flex-1 flex-col overflow-hidden bg-background",
|
|
2563
|
+
children: [
|
|
2564
|
+
/* @__PURE__ */ jsxs("header", {
|
|
2565
|
+
className: "flex items-center gap-2 border-b p-3",
|
|
2566
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
2567
|
+
type: "button",
|
|
2568
|
+
size: "icon",
|
|
2569
|
+
variant: "ghost",
|
|
2570
|
+
className: "h-8 w-8 shrink-0",
|
|
2571
|
+
onClick: onBack,
|
|
2572
|
+
"aria-label": "Back to typography",
|
|
2573
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, {
|
|
2574
|
+
className: "h-4 w-4",
|
|
2575
|
+
"aria-hidden": "true"
|
|
2576
|
+
})
|
|
2577
|
+
}), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h2", {
|
|
2578
|
+
className: "text-sm font-semibold",
|
|
2579
|
+
children: "Advanced typography"
|
|
2580
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
2581
|
+
className: "text-xs text-muted-foreground",
|
|
2582
|
+
children: "Fine-tune the type system."
|
|
2583
|
+
})] })]
|
|
2584
|
+
}),
|
|
2585
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2586
|
+
className: "min-h-0 flex-1 space-y-2 overflow-y-auto p-3",
|
|
2587
|
+
children: [/* @__PURE__ */ jsxs(TypographyDisclosure, {
|
|
2757
2588
|
label: "Heading",
|
|
2758
|
-
|
|
2759
|
-
onOpenChange: setHeadingOpen,
|
|
2589
|
+
defaultOpen: true,
|
|
2760
2590
|
children: [
|
|
2761
|
-
/* @__PURE__ */ jsx(TypographyFontSlotPicker, {
|
|
2762
|
-
label: "Heading font",
|
|
2763
|
-
slot: "heading",
|
|
2764
|
-
preset: fontPolicyPreset,
|
|
2765
|
-
catalog: fontCatalog,
|
|
2766
|
-
value: typography.headings.default.family,
|
|
2767
|
-
onChange: (family) => onHeadingChange({ family }),
|
|
2768
|
-
disabled
|
|
2769
|
-
}),
|
|
2770
2591
|
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2771
2592
|
label: "Weight",
|
|
2772
2593
|
value: typography.headings.default.weight,
|
|
@@ -2774,6 +2595,7 @@ function TypographyRow({ expanded, onToggle, apiClient, siteStyle, typography, c
|
|
|
2774
2595
|
onChange: (weight) => onHeadingChange({ weight }),
|
|
2775
2596
|
disabled
|
|
2776
2597
|
}),
|
|
2598
|
+
headingWeightWarning ? /* @__PURE__ */ jsx(ContextualFontWarning, { message: headingWeightWarning }) : null,
|
|
2777
2599
|
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2778
2600
|
label: "Line height",
|
|
2779
2601
|
value: typography.headings.default.lineHeight,
|
|
@@ -2781,6 +2603,13 @@ function TypographyRow({ expanded, onToggle, apiClient, siteStyle, typography, c
|
|
|
2781
2603
|
onChange: (lineHeight) => onHeadingChange({ lineHeight }),
|
|
2782
2604
|
disabled
|
|
2783
2605
|
}),
|
|
2606
|
+
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2607
|
+
label: "Letter spacing",
|
|
2608
|
+
value: typography.headings.default.letterSpacing,
|
|
2609
|
+
options: typographyLetterSpacingOptions,
|
|
2610
|
+
onChange: (letterSpacing) => onHeadingChange({ letterSpacing }),
|
|
2611
|
+
disabled
|
|
2612
|
+
}),
|
|
2784
2613
|
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2785
2614
|
label: "Scale",
|
|
2786
2615
|
value: normalizeTypographyScaleForControl(typography.scale),
|
|
@@ -2788,27 +2617,31 @@ function TypographyRow({ expanded, onToggle, apiClient, siteStyle, typography, c
|
|
|
2788
2617
|
onChange: onScaleChange,
|
|
2789
2618
|
disabled
|
|
2790
2619
|
}),
|
|
2620
|
+
/* @__PURE__ */ jsx(HeadingCaseControl, {
|
|
2621
|
+
value: typography.headings.default.case,
|
|
2622
|
+
onChange: (value) => onHeadingChange({ case: value }),
|
|
2623
|
+
disabled
|
|
2624
|
+
}),
|
|
2625
|
+
/* @__PURE__ */ jsxs("button", {
|
|
2626
|
+
type: "button",
|
|
2627
|
+
className: "flex w-full items-center justify-between rounded-md border px-3 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-50",
|
|
2628
|
+
"aria-pressed": typography.headings.default.italic === true,
|
|
2629
|
+
onClick: () => onHeadingChange({ italic: typography.headings.default.italic === true ? null : true }),
|
|
2630
|
+
disabled,
|
|
2631
|
+
children: ["Italic headings", /* @__PURE__ */ jsx("span", {
|
|
2632
|
+
className: "text-xs text-muted-foreground",
|
|
2633
|
+
children: typography.headings.default.italic === true ? "On" : "Default"
|
|
2634
|
+
})]
|
|
2635
|
+
}),
|
|
2791
2636
|
/* @__PURE__ */ jsx(TypographyColorTokenControl, {
|
|
2792
|
-
value: typography.headings.default.colorToken
|
|
2637
|
+
value: normalizeHeadingColorTokenForControl(typography.headings.default.colorToken),
|
|
2793
2638
|
onChange: (colorToken) => onHeadingChange({ colorToken: colorToken === "text" ? null : colorToken }),
|
|
2794
2639
|
disabled
|
|
2795
2640
|
})
|
|
2796
2641
|
]
|
|
2797
|
-
}),
|
|
2798
|
-
/* @__PURE__ */ jsxs(TypographyDisclosure, {
|
|
2642
|
+
}), /* @__PURE__ */ jsxs(TypographyDisclosure, {
|
|
2799
2643
|
label: "Body",
|
|
2800
|
-
open: bodyOpen,
|
|
2801
|
-
onOpenChange: setBodyOpen,
|
|
2802
2644
|
children: [
|
|
2803
|
-
/* @__PURE__ */ jsx(TypographyFontSlotPicker, {
|
|
2804
|
-
label: "Body font",
|
|
2805
|
-
slot: "body",
|
|
2806
|
-
preset: fontPolicyPreset,
|
|
2807
|
-
catalog: fontCatalog,
|
|
2808
|
-
value: typography.body.family,
|
|
2809
|
-
onChange: (family) => onBodyChange({ family }),
|
|
2810
|
-
disabled
|
|
2811
|
-
}),
|
|
2812
2645
|
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2813
2646
|
label: "Size",
|
|
2814
2647
|
value: typography.body.size,
|
|
@@ -2823,42 +2656,301 @@ function TypographyRow({ expanded, onToggle, apiClient, siteStyle, typography, c
|
|
|
2823
2656
|
onChange: (weight) => onBodyChange({ weight }),
|
|
2824
2657
|
disabled
|
|
2825
2658
|
}),
|
|
2659
|
+
bodyWeightWarning ? /* @__PURE__ */ jsx(ContextualFontWarning, { message: bodyWeightWarning }) : null,
|
|
2826
2660
|
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2827
2661
|
label: "Line height",
|
|
2828
2662
|
value: typography.body.lineHeight,
|
|
2829
2663
|
options: typographyLineHeightOptions,
|
|
2830
2664
|
onChange: (lineHeight) => onBodyChange({ lineHeight }),
|
|
2831
2665
|
disabled
|
|
2666
|
+
}),
|
|
2667
|
+
/* @__PURE__ */ jsx(TypographySelectControl, {
|
|
2668
|
+
label: "Letter spacing",
|
|
2669
|
+
value: typography.body.letterSpacing,
|
|
2670
|
+
options: typographyLetterSpacingOptions,
|
|
2671
|
+
onChange: (letterSpacing) => onBodyChange({ letterSpacing }),
|
|
2672
|
+
disabled
|
|
2832
2673
|
})
|
|
2833
2674
|
]
|
|
2834
|
-
})
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
variant: "outline",
|
|
2839
|
-
onClick: onReset,
|
|
2840
|
-
disabled,
|
|
2841
|
-
children: "Reset typography"
|
|
2842
|
-
})
|
|
2843
|
-
]
|
|
2844
|
-
})]
|
|
2675
|
+
})]
|
|
2676
|
+
}),
|
|
2677
|
+
/* @__PURE__ */ jsx(SiteFontFaceStyles, { siteFonts: catalog.site.value })
|
|
2678
|
+
]
|
|
2845
2679
|
});
|
|
2846
2680
|
}
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2681
|
+
function TypographyDisclosure({ label, defaultOpen = false, children }) {
|
|
2682
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
2683
|
+
return /* @__PURE__ */ jsx(Collapsible, {
|
|
2684
|
+
open,
|
|
2685
|
+
onOpenChange: setOpen,
|
|
2686
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2687
|
+
className: "rounded-md border bg-muted/10",
|
|
2688
|
+
children: [/* @__PURE__ */ jsx(CollapsibleTrigger, {
|
|
2689
|
+
asChild: true,
|
|
2690
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
2691
|
+
type: "button",
|
|
2692
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm font-medium hover:bg-accent/30",
|
|
2693
|
+
"aria-expanded": open,
|
|
2694
|
+
children: [/* @__PURE__ */ jsx(ChevronRight, {
|
|
2695
|
+
className: cn("h-4 w-4 transition", open && "rotate-90"),
|
|
2696
|
+
"aria-hidden": "true"
|
|
2697
|
+
}), label]
|
|
2698
|
+
})
|
|
2699
|
+
}), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", {
|
|
2700
|
+
className: "space-y-3 border-t px-3 py-3",
|
|
2701
|
+
children
|
|
2702
|
+
}) })]
|
|
2703
|
+
})
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
2706
|
+
function TypographySelectControl({ label, value, options, onChange, disabled }) {
|
|
2707
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
2708
|
+
className: "block space-y-1",
|
|
2709
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2710
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
2711
|
+
children: label
|
|
2712
|
+
}), /* @__PURE__ */ jsxs(Select, {
|
|
2713
|
+
value,
|
|
2714
|
+
onValueChange: (next) => {
|
|
2715
|
+
const option = options.find((candidate) => candidate.value === next);
|
|
2716
|
+
if (option) onChange(option.value);
|
|
2717
|
+
},
|
|
2718
|
+
disabled,
|
|
2719
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
2720
|
+
size: "sm",
|
|
2721
|
+
className: "w-full",
|
|
2722
|
+
"aria-label": label,
|
|
2723
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
2724
|
+
}), /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
|
|
2725
|
+
value: option.value,
|
|
2726
|
+
children: option.label
|
|
2727
|
+
}, option.value)) })]
|
|
2728
|
+
})]
|
|
2729
|
+
});
|
|
2730
|
+
}
|
|
2731
|
+
function HeadingCaseControl({ value, onChange, disabled }) {
|
|
2732
|
+
const options = [
|
|
2733
|
+
{
|
|
2734
|
+
value: "default",
|
|
2735
|
+
label: "Default",
|
|
2736
|
+
resolved: null
|
|
2737
|
+
},
|
|
2738
|
+
{
|
|
2739
|
+
value: "normal",
|
|
2740
|
+
label: "Normal",
|
|
2741
|
+
resolved: "normal"
|
|
2742
|
+
},
|
|
2743
|
+
{
|
|
2744
|
+
value: "uppercase",
|
|
2745
|
+
label: "Uppercase",
|
|
2746
|
+
resolved: "uppercase"
|
|
2747
|
+
},
|
|
2748
|
+
{
|
|
2749
|
+
value: "smallCaps",
|
|
2750
|
+
label: "Small caps",
|
|
2751
|
+
resolved: "smallCaps"
|
|
2752
|
+
}
|
|
2753
|
+
];
|
|
2754
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
2755
|
+
className: "block space-y-1",
|
|
2756
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2757
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
2758
|
+
children: "Case"
|
|
2759
|
+
}), /* @__PURE__ */ jsxs(Select, {
|
|
2760
|
+
value: value ?? "default",
|
|
2761
|
+
onValueChange: (next) => {
|
|
2762
|
+
const option = options.find((candidate) => candidate.value === next);
|
|
2763
|
+
if (option) onChange(option.resolved);
|
|
2764
|
+
},
|
|
2765
|
+
disabled,
|
|
2766
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
2767
|
+
size: "sm",
|
|
2768
|
+
className: "w-full",
|
|
2769
|
+
"aria-label": "Heading case",
|
|
2770
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
2771
|
+
}), /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
|
|
2772
|
+
value: option.value,
|
|
2773
|
+
children: option.label
|
|
2774
|
+
}, option.value)) })]
|
|
2775
|
+
})]
|
|
2776
|
+
});
|
|
2777
|
+
}
|
|
2778
|
+
function TypographyColorTokenControl({ value, onChange, disabled }) {
|
|
2779
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
2780
|
+
className: "space-y-2",
|
|
2781
|
+
"aria-label": "Default heading color",
|
|
2782
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [
|
|
2783
|
+
/* @__PURE__ */ jsx("div", {
|
|
2784
|
+
className: "text-xs font-medium text-muted-foreground",
|
|
2785
|
+
children: "Default heading color"
|
|
2786
|
+
}),
|
|
2787
|
+
/* @__PURE__ */ jsx("p", {
|
|
2788
|
+
className: "text-[11px] text-muted-foreground",
|
|
2789
|
+
children: "Sections may override this for readability."
|
|
2790
|
+
}),
|
|
2791
|
+
value.kind === "existing" ? /* @__PURE__ */ jsxs("p", {
|
|
2792
|
+
className: "mt-1 text-[11px] text-muted-foreground",
|
|
2793
|
+
children: [
|
|
2794
|
+
"Current: ",
|
|
2795
|
+
formatColorTokenLabel(value.value),
|
|
2796
|
+
" (outside quick choices)"
|
|
2797
|
+
]
|
|
2798
|
+
}) : null
|
|
2799
|
+
] }), /* @__PURE__ */ jsx("div", {
|
|
2800
|
+
className: "grid grid-cols-2 gap-1",
|
|
2801
|
+
children: headingColorTokenOptions.map((option) => /* @__PURE__ */ jsx(Button, {
|
|
2802
|
+
type: "button",
|
|
2803
|
+
size: "sm",
|
|
2804
|
+
variant: value.kind === "curated" && value.value === option.value ? "secondary" : "outline",
|
|
2805
|
+
className: "justify-start text-xs",
|
|
2806
|
+
"aria-pressed": value.kind === "curated" && value.value === option.value,
|
|
2807
|
+
onClick: () => onChange(option.value),
|
|
2808
|
+
disabled,
|
|
2809
|
+
children: option.label
|
|
2810
|
+
}, option.value))
|
|
2811
|
+
})]
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2814
|
+
function ContextualFontWarning({ message }) {
|
|
2815
|
+
return /* @__PURE__ */ jsx("p", {
|
|
2816
|
+
className: "rounded-md bg-warning/10 px-2 py-1.5 text-xs text-muted-foreground",
|
|
2817
|
+
children: message
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
function FontPreviewText({ family, source, className, children }) {
|
|
2821
|
+
const elementRef = useRef(null);
|
|
2822
|
+
const [visible, setVisible] = useState(() => typeof globalThis.IntersectionObserver !== "function");
|
|
2823
|
+
useEffect(() => {
|
|
2824
|
+
if (visible || source !== "google") return;
|
|
2825
|
+
const element = elementRef.current;
|
|
2826
|
+
if (!element || typeof globalThis.IntersectionObserver !== "function") {
|
|
2827
|
+
setVisible(true);
|
|
2828
|
+
return;
|
|
2829
|
+
}
|
|
2830
|
+
const observer = new globalThis.IntersectionObserver((entries) => {
|
|
2831
|
+
if (!entries.some((entry) => entry.isIntersecting)) return;
|
|
2832
|
+
setVisible(true);
|
|
2833
|
+
observer.disconnect();
|
|
2834
|
+
}, { rootMargin: "160px 0px" });
|
|
2835
|
+
observer.observe(element);
|
|
2836
|
+
return () => observer.disconnect();
|
|
2837
|
+
}, [source, visible]);
|
|
2838
|
+
useEffect(() => {
|
|
2839
|
+
if (!visible || source !== "google") return;
|
|
2840
|
+
ensureGoogleFontPreviewLink(family);
|
|
2841
|
+
}, [
|
|
2842
|
+
family,
|
|
2843
|
+
source,
|
|
2844
|
+
visible
|
|
2845
|
+
]);
|
|
2846
|
+
return /* @__PURE__ */ jsx("span", {
|
|
2847
|
+
ref: elementRef,
|
|
2848
|
+
className,
|
|
2849
|
+
style: source === "site" || source === "google" ? { fontFamily: quoteFontFamily(family) } : void 0,
|
|
2850
|
+
children
|
|
2851
|
+
});
|
|
2852
|
+
}
|
|
2853
|
+
function SiteFontFaceStyles({ siteFonts }) {
|
|
2854
|
+
const css = useMemo(() => {
|
|
2855
|
+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
2856
|
+
if (!supabaseUrl || siteFonts.length === 0) return "";
|
|
2857
|
+
return generateFontFaceCss([...siteFonts], getSiteFontsStorageUrl(supabaseUrl));
|
|
2858
|
+
}, [siteFonts]);
|
|
2859
|
+
return css ? /* @__PURE__ */ jsx("style", {
|
|
2860
|
+
"data-typography-site-fonts": true,
|
|
2861
|
+
children: css
|
|
2862
|
+
}) : null;
|
|
2863
|
+
}
|
|
2864
|
+
function ensureGoogleFontPreviewLink(family) {
|
|
2865
|
+
const url = buildFontPreviewUrl(family);
|
|
2866
|
+
if (Array.from(document.head.querySelectorAll("link[data-font-preview]")).some((link) => link.href === url)) return;
|
|
2867
|
+
const link = document.createElement("link");
|
|
2868
|
+
link.rel = "stylesheet";
|
|
2869
|
+
link.href = url;
|
|
2870
|
+
link.dataset.fontPreview = family;
|
|
2871
|
+
document.head.appendChild(link);
|
|
2872
|
+
}
|
|
2873
|
+
function unsupportedWeightMessage(option, weight, style) {
|
|
2874
|
+
if (!option) return null;
|
|
2875
|
+
const numericWeight = semanticFontWeight(weight);
|
|
2876
|
+
if (option.source === "site") {
|
|
2877
|
+
const font = option.siteFont;
|
|
2878
|
+
if (font.isVariable && font.variableWeightMin !== null && font.variableWeightMax !== null) return numericWeight >= font.variableWeightMin && numericWeight <= font.variableWeightMax && font.files.some((file) => file.style === style) ? null : unsupportedFontStyleMessage(option.label, style);
|
|
2879
|
+
return font.files.some((file) => file.weight === numericWeight && file.style === style) ? null : unsupportedFontStyleMessage(option.label, style);
|
|
2880
|
+
}
|
|
2881
|
+
const variants = new Set(option.googleFont.variants);
|
|
2882
|
+
return (style === "italic" ? variants.has(numericWeight === 400 ? "italic" : `${numericWeight}italic`) : variants.has(String(numericWeight)) || numericWeight === 400 && variants.has("regular")) ? null : unsupportedFontStyleMessage(option.label, style);
|
|
2883
|
+
}
|
|
2884
|
+
function unsupportedFontStyleMessage(family, style) {
|
|
2885
|
+
return style === "italic" ? `${family} may not include italics at this weight.` : `${family} may not include this weight.`;
|
|
2886
|
+
}
|
|
2887
|
+
function semanticFontWeight(weight) {
|
|
2888
|
+
switch (weight) {
|
|
2889
|
+
case "light": return 300;
|
|
2890
|
+
case "regular": return 400;
|
|
2891
|
+
case "medium": return 500;
|
|
2892
|
+
case "semibold": return 600;
|
|
2893
|
+
case "bold": return 700;
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
function normalizeTypographyScaleForControl(scale) {
|
|
2897
|
+
switch (scale) {
|
|
2898
|
+
case "compact":
|
|
2899
|
+
case "balanced":
|
|
2900
|
+
case "spacious": return scale;
|
|
2901
|
+
case "minorThird": return "compact";
|
|
2902
|
+
case "majorThird": return "balanced";
|
|
2903
|
+
case "perfectFourth": return "spacious";
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
function normalizeHeadingColorTokenForControl(value) {
|
|
2907
|
+
switch (value) {
|
|
2908
|
+
case "primary":
|
|
2909
|
+
case "secondary":
|
|
2910
|
+
case "accent": return {
|
|
2911
|
+
kind: "curated",
|
|
2912
|
+
value
|
|
2913
|
+
};
|
|
2914
|
+
case "text":
|
|
2915
|
+
case void 0:
|
|
2916
|
+
case null: return {
|
|
2917
|
+
kind: "curated",
|
|
2918
|
+
value: "text"
|
|
2919
|
+
};
|
|
2920
|
+
default: return {
|
|
2921
|
+
kind: "existing",
|
|
2922
|
+
value
|
|
2923
|
+
};
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
function formatColorTokenLabel(value) {
|
|
2927
|
+
const words = value.replace(/([a-z])([A-Z])/gu, "$1 $2").replace(/[-_]+/gu, " ").toLocaleLowerCase();
|
|
2928
|
+
return `${words.charAt(0).toLocaleUpperCase()}${words.slice(1)}`;
|
|
2929
|
+
}
|
|
2930
|
+
function familyMatches(left, right) {
|
|
2931
|
+
return left.toLocaleLowerCase() === right.toLocaleLowerCase();
|
|
2932
|
+
}
|
|
2933
|
+
function quoteFontFamily(family) {
|
|
2934
|
+
return `"${family.replace(/["\\]/gu, "")}", sans-serif`;
|
|
2935
|
+
}
|
|
2936
|
+
function errorMessage(error, fallback) {
|
|
2937
|
+
return error instanceof Error && error.message ? error.message : fallback;
|
|
2938
|
+
}
|
|
2939
|
+
const typographyWeightOptions = [
|
|
2940
|
+
{
|
|
2941
|
+
value: "light",
|
|
2942
|
+
label: "Light"
|
|
2943
|
+
},
|
|
2944
|
+
{
|
|
2945
|
+
value: "regular",
|
|
2946
|
+
label: "Regular"
|
|
2947
|
+
},
|
|
2948
|
+
{
|
|
2949
|
+
value: "medium",
|
|
2950
|
+
label: "Medium"
|
|
2951
|
+
},
|
|
2952
|
+
{
|
|
2953
|
+
value: "semibold",
|
|
2862
2954
|
label: "Semibold"
|
|
2863
2955
|
},
|
|
2864
2956
|
{
|
|
@@ -2880,6 +2972,20 @@ const typographyLineHeightOptions = [
|
|
|
2880
2972
|
label: "Loose"
|
|
2881
2973
|
}
|
|
2882
2974
|
];
|
|
2975
|
+
const typographyLetterSpacingOptions = [
|
|
2976
|
+
{
|
|
2977
|
+
value: "tight",
|
|
2978
|
+
label: "Tight"
|
|
2979
|
+
},
|
|
2980
|
+
{
|
|
2981
|
+
value: "normal",
|
|
2982
|
+
label: "Normal"
|
|
2983
|
+
},
|
|
2984
|
+
{
|
|
2985
|
+
value: "loose",
|
|
2986
|
+
label: "Loose"
|
|
2987
|
+
}
|
|
2988
|
+
];
|
|
2883
2989
|
const bodySizeOptions = [
|
|
2884
2990
|
{
|
|
2885
2991
|
value: "md",
|
|
@@ -2911,7 +3017,7 @@ const typographyScaleOptions = [
|
|
|
2911
3017
|
const headingColorTokenOptions = [
|
|
2912
3018
|
{
|
|
2913
3019
|
value: "text",
|
|
2914
|
-
label: "
|
|
3020
|
+
label: "Default text"
|
|
2915
3021
|
},
|
|
2916
3022
|
{
|
|
2917
3023
|
value: "primary",
|
|
@@ -2926,400 +3032,770 @@ const headingColorTokenOptions = [
|
|
|
2926
3032
|
label: "Accent"
|
|
2927
3033
|
}
|
|
2928
3034
|
];
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
3035
|
+
//#endregion
|
|
3036
|
+
//#region ../preview-next/src/client/preview/StyleConfigurator.tsx
|
|
3037
|
+
const PALETTE_BRAND_ROLES = [
|
|
3038
|
+
{
|
|
3039
|
+
key: "primary",
|
|
3040
|
+
label: "Primary"
|
|
3041
|
+
},
|
|
3042
|
+
{
|
|
3043
|
+
key: "primaryForeground",
|
|
3044
|
+
label: "Primary text"
|
|
3045
|
+
},
|
|
3046
|
+
{
|
|
3047
|
+
key: "secondary",
|
|
3048
|
+
label: "Secondary"
|
|
3049
|
+
},
|
|
3050
|
+
{
|
|
3051
|
+
key: "accent",
|
|
3052
|
+
label: "Accent"
|
|
3053
|
+
}
|
|
3054
|
+
];
|
|
3055
|
+
const PALETTE_FEEDBACK_ROLES = [
|
|
3056
|
+
{
|
|
3057
|
+
key: "success",
|
|
3058
|
+
label: "Success"
|
|
3059
|
+
},
|
|
3060
|
+
{
|
|
3061
|
+
key: "warning",
|
|
3062
|
+
label: "Warning"
|
|
3063
|
+
},
|
|
3064
|
+
{
|
|
3065
|
+
key: "destructive",
|
|
3066
|
+
label: "Destructive"
|
|
3067
|
+
}
|
|
3068
|
+
];
|
|
3069
|
+
const PALETTE_SURFACE_ROLES = [
|
|
3070
|
+
{
|
|
3071
|
+
key: "background",
|
|
3072
|
+
label: "Background"
|
|
3073
|
+
},
|
|
3074
|
+
{
|
|
3075
|
+
key: "surface",
|
|
3076
|
+
label: "Surface"
|
|
3077
|
+
},
|
|
3078
|
+
{
|
|
3079
|
+
key: "surfaceAlt",
|
|
3080
|
+
label: "Alternate surface"
|
|
3081
|
+
},
|
|
3082
|
+
{
|
|
3083
|
+
key: "muted",
|
|
3084
|
+
label: "Muted surface"
|
|
3085
|
+
},
|
|
3086
|
+
{
|
|
3087
|
+
key: "text",
|
|
3088
|
+
label: "Text"
|
|
3089
|
+
},
|
|
3090
|
+
{
|
|
3091
|
+
key: "border",
|
|
3092
|
+
label: "Border"
|
|
3093
|
+
}
|
|
3094
|
+
];
|
|
3095
|
+
function StyleConfigurator({ siteId, apiClient, theme, selectionId, selectionVersion = null, selectionUpdatedAt, initialSelections, headerSelectionContext, footerSelectionContext, expandedRowRequest = null, onFocusedSurfaceChange, siteStyleAccess }) {
|
|
3096
|
+
const router = useRouter();
|
|
3097
|
+
const previewDesign = usePreviewDesignCoordinator();
|
|
3098
|
+
const siteChromeCustomize = useSiteChromeCustomizeOptional();
|
|
3099
|
+
const setSiteStyleStagedPreviewActive = siteChromeCustomize?.siteStyleHistory?.setStagedPreviewActive;
|
|
3100
|
+
const { applyFailed, applyStarted, applySucceeded, clearPreview, previewTheme } = previewDesign;
|
|
3101
|
+
const [isRefreshPending, startRefreshTransition] = useTransition();
|
|
3102
|
+
const baseSnapshot = useMemo(() => resolveStyleConfiguratorInitialSnapshot({
|
|
3103
|
+
theme,
|
|
3104
|
+
initialSelections: {
|
|
3105
|
+
...initialSelections,
|
|
3106
|
+
selectionVersion: initialSelections.selectionVersion ?? selectionVersion ?? 0,
|
|
3107
|
+
selectionUpdatedAt: initialSelections.selectionUpdatedAt ?? selectionUpdatedAt ?? null
|
|
3108
|
+
},
|
|
3109
|
+
headerSelectionContext,
|
|
3110
|
+
footerSelectionContext
|
|
3111
|
+
}), [
|
|
3112
|
+
footerSelectionContext,
|
|
3113
|
+
headerSelectionContext,
|
|
3114
|
+
theme,
|
|
3115
|
+
initialSelections,
|
|
3116
|
+
selectionUpdatedAt,
|
|
3117
|
+
selectionVersion
|
|
3118
|
+
]);
|
|
3119
|
+
const [state, setState] = useState(() => baseSnapshot ? createStyleConfiguratorState(baseSnapshot) : null);
|
|
3120
|
+
const [typographySurface, setTypographySurface] = useState(typographyOverviewSurface);
|
|
3121
|
+
const fontCatalog = useTypographyFontCatalog(apiClient, siteId, state?.expandedRow === "typography");
|
|
3122
|
+
const hasLoadedState = state !== null;
|
|
3123
|
+
const hasStagedSiteStylePreview = state ? isPreviewingChange(state) : false;
|
|
3124
|
+
const hasFocusedTypographySurface = state?.expandedRow === "typography" && typographySurface.kind !== "overview";
|
|
3125
|
+
const stateRef = useRef(state);
|
|
3126
|
+
const clearPreviewRef = useRef(clearPreview);
|
|
3127
|
+
const runnerRef = useRef(createOptimisticActionRunner());
|
|
3128
|
+
const appliedExpandedRowRequestIdRef = useRef(null);
|
|
3129
|
+
useEffect(() => {
|
|
3130
|
+
stateRef.current = state;
|
|
3131
|
+
}, [state]);
|
|
3132
|
+
useEffect(() => {
|
|
3133
|
+
if (state?.expandedRow !== "typography" && typographySurface.kind !== "overview") setTypographySurface(typographyOverviewSurface);
|
|
3134
|
+
}, [state?.expandedRow, typographySurface.kind]);
|
|
3135
|
+
useEffect(() => {
|
|
3136
|
+
onFocusedSurfaceChange?.(hasFocusedTypographySurface);
|
|
3137
|
+
return () => {
|
|
3138
|
+
if (hasFocusedTypographySurface) onFocusedSurfaceChange?.(false);
|
|
3139
|
+
};
|
|
3140
|
+
}, [hasFocusedTypographySurface, onFocusedSurfaceChange]);
|
|
3141
|
+
useEffect(() => {
|
|
3142
|
+
clearPreviewRef.current = clearPreview;
|
|
3143
|
+
}, [clearPreview]);
|
|
3144
|
+
useEffect(() => {
|
|
3145
|
+
if (!setSiteStyleStagedPreviewActive) return;
|
|
3146
|
+
setSiteStyleStagedPreviewActive(hasStagedSiteStylePreview);
|
|
3147
|
+
return () => {
|
|
3148
|
+
setSiteStyleStagedPreviewActive(false);
|
|
3149
|
+
};
|
|
3150
|
+
}, [hasStagedSiteStylePreview, setSiteStyleStagedPreviewActive]);
|
|
3151
|
+
useEffect(() => {
|
|
3152
|
+
if (!baseSnapshot) return;
|
|
3153
|
+
setState((current) => current ? syncStyleConfiguratorState(current, baseSnapshot) : createStyleConfiguratorState(baseSnapshot));
|
|
3154
|
+
}, [baseSnapshot]);
|
|
3155
|
+
useEffect(() => {
|
|
3156
|
+
if (!state || !baseSnapshot) {
|
|
3157
|
+
clearPreview("style-configurator");
|
|
3158
|
+
return;
|
|
3159
|
+
}
|
|
3160
|
+
if (!isPreviewingChange(state)) {
|
|
3161
|
+
clearPreview("style-configurator");
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3164
|
+
const siteStyle = getCuratedSiteStyle(state.previewed.siteStyleId);
|
|
3165
|
+
if (!siteStyle) {
|
|
3166
|
+
clearPreview("style-configurator");
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3169
|
+
previewTheme("style-configurator", planSiteStylePreviewChange({
|
|
3170
|
+
siteStyle,
|
|
3171
|
+
selection: state.previewed,
|
|
3172
|
+
baseTheme: theme,
|
|
3173
|
+
headerSelectionContext,
|
|
3174
|
+
footerSelectionContext
|
|
3175
|
+
}).themeOverlay, "site-style");
|
|
3176
|
+
}, [
|
|
3177
|
+
state,
|
|
3178
|
+
baseSnapshot,
|
|
3179
|
+
clearPreview,
|
|
3180
|
+
previewTheme,
|
|
3181
|
+
headerSelectionContext,
|
|
3182
|
+
footerSelectionContext,
|
|
3183
|
+
theme
|
|
3184
|
+
]);
|
|
3185
|
+
useEffect(() => {
|
|
3186
|
+
const runner = runnerRef.current;
|
|
3187
|
+
return () => {
|
|
3188
|
+
runner.invalidate();
|
|
3189
|
+
clearPreviewRef.current("style-configurator");
|
|
3190
|
+
};
|
|
3191
|
+
}, []);
|
|
3192
|
+
useEffect(() => {
|
|
3193
|
+
if (!expandedRowRequest) return;
|
|
3194
|
+
if (appliedExpandedRowRequestIdRef.current === expandedRowRequest.id) return;
|
|
3195
|
+
setState((current) => {
|
|
3196
|
+
if (!current) return current;
|
|
3197
|
+
appliedExpandedRowRequestIdRef.current = expandedRowRequest.id;
|
|
3198
|
+
return openRow(current, expandedRowForPreviewDesignRow(expandedRowRequest.row));
|
|
3199
|
+
});
|
|
3200
|
+
}, [expandedRowRequest, hasLoadedState]);
|
|
3201
|
+
const handlePreviewSiteStyle = useCallback((siteStyleId) => {
|
|
3202
|
+
setState((current) => {
|
|
3203
|
+
if (!current) return current;
|
|
3204
|
+
const next = previewSiteStyle(current, siteStyleId);
|
|
3205
|
+
const siteStyle = getCuratedSiteStyle(siteStyleId);
|
|
3206
|
+
if (!siteStyle) return next;
|
|
3207
|
+
const result = planSiteStylePreviewChange({
|
|
3208
|
+
siteStyle,
|
|
3209
|
+
selection: next.previewed,
|
|
3210
|
+
baseTheme: theme,
|
|
3211
|
+
headerSelectionContext,
|
|
3212
|
+
footerSelectionContext
|
|
3213
|
+
});
|
|
3214
|
+
return applyResolvedSelections(next, {
|
|
3215
|
+
resolved: {
|
|
3216
|
+
...result.resolvedSelections,
|
|
3217
|
+
typography: result.themeOverlay.typography
|
|
3218
|
+
},
|
|
3219
|
+
warnings: result.warnings
|
|
3220
|
+
});
|
|
3221
|
+
});
|
|
3222
|
+
}, [
|
|
3223
|
+
footerSelectionContext,
|
|
3224
|
+
headerSelectionContext,
|
|
3225
|
+
theme
|
|
3226
|
+
]);
|
|
3227
|
+
const handlePreviewPersonality = useCallback((id) => {
|
|
3228
|
+
setState((current) => current ? previewButtonPersonality(current, id) : current);
|
|
3229
|
+
}, []);
|
|
3230
|
+
const handlePreviewHeaderLayout = useCallback((id) => {
|
|
3231
|
+
if (!id) return;
|
|
3232
|
+
setState((current) => current ? previewHeaderLayout(current, id) : current);
|
|
3233
|
+
}, []);
|
|
3234
|
+
const handlePreviewHeaderStyle = useCallback((id) => {
|
|
3235
|
+
if (!id) return;
|
|
3236
|
+
setState((current) => current ? previewHeaderStyle(current, id) : current);
|
|
3237
|
+
}, []);
|
|
3238
|
+
const handlePreviewFooterLook = useCallback((id) => {
|
|
3239
|
+
const plan = planSiteChromeLookSelection({
|
|
3240
|
+
surface: "footer",
|
|
3241
|
+
lookId: id
|
|
3242
|
+
});
|
|
3243
|
+
if (plan.kind !== "footer") return;
|
|
3244
|
+
setState((current) => current ? previewFooterLook(current, plan.next.footerLookId) : current);
|
|
3245
|
+
}, []);
|
|
3246
|
+
const handlePreviewFooterLayout = useCallback((id) => {
|
|
3247
|
+
if (!id) return;
|
|
3248
|
+
setState((current) => {
|
|
3249
|
+
if (!current) return current;
|
|
3250
|
+
const siteStyle = getCuratedSiteStyle(current.previewed.siteStyleId);
|
|
3251
|
+
if (!siteStyle) return current;
|
|
3252
|
+
const models = buildSiteChromeLookModels({
|
|
3253
|
+
state: current,
|
|
3254
|
+
siteStyle,
|
|
3255
|
+
headerSelectionContext,
|
|
3256
|
+
footerSelectionContext
|
|
3257
|
+
});
|
|
3258
|
+
const nextLookId = planSiteChromeFooterLayoutSelection({
|
|
3259
|
+
layoutId: id,
|
|
3260
|
+
currentLookId: current.previewed.footerLookId ?? models.footer.renderedLookId
|
|
3261
|
+
});
|
|
3262
|
+
return nextLookId ? previewFooterLook(current, nextLookId) : current;
|
|
3263
|
+
});
|
|
3264
|
+
}, [footerSelectionContext, headerSelectionContext]);
|
|
3265
|
+
const handlePreviewPaletteItem = useCallback((item) => {
|
|
3266
|
+
setState((current) => {
|
|
3267
|
+
if (!current) return current;
|
|
3268
|
+
if (item.kind === "curated") return previewCuratedPalette(current, item.valueKey);
|
|
3269
|
+
return previewSitePalette(current, {
|
|
3270
|
+
paletteId: item.paletteId,
|
|
3271
|
+
colors: item.colors,
|
|
3272
|
+
mode: item.mode,
|
|
3273
|
+
version: item.version
|
|
3274
|
+
});
|
|
3275
|
+
});
|
|
3276
|
+
}, []);
|
|
3277
|
+
const handleCreatePalette = useCallback(() => {
|
|
3278
|
+
setState((current) => current ? createPalette(current) : current);
|
|
3279
|
+
}, []);
|
|
3280
|
+
const handlePaletteLibraryLoaded = useCallback((response) => {
|
|
3281
|
+
setState((current) => current ? reconcilePaletteLibraryActive(current, response.active, response.palettes) : current);
|
|
3282
|
+
}, []);
|
|
3283
|
+
const patchTypography = useCallback((patch) => {
|
|
3284
|
+
setState((current) => {
|
|
3285
|
+
if (!current) return current;
|
|
3286
|
+
const siteStyle = getCuratedSiteStyle(current.previewed.siteStyleId);
|
|
3287
|
+
if (!siteStyle) return current;
|
|
3288
|
+
return applyTypographyDraftPatch(current, planSiteStylePreviewChange({
|
|
3289
|
+
siteStyle,
|
|
3290
|
+
selection: current.previewed,
|
|
3291
|
+
baseTheme: theme,
|
|
3292
|
+
headerSelectionContext,
|
|
3293
|
+
footerSelectionContext
|
|
3294
|
+
}).themeOverlay.typography, patch);
|
|
3295
|
+
});
|
|
3296
|
+
}, [
|
|
3297
|
+
footerSelectionContext,
|
|
3298
|
+
headerSelectionContext,
|
|
3299
|
+
theme
|
|
3300
|
+
]);
|
|
3301
|
+
const handleHeadingTypographyChange = useCallback((patch) => {
|
|
3302
|
+
patchTypography({
|
|
3303
|
+
kind: "heading",
|
|
3304
|
+
patch
|
|
3305
|
+
});
|
|
3306
|
+
}, [patchTypography]);
|
|
3307
|
+
const handleBodyTypographyChange = useCallback((patch) => {
|
|
3308
|
+
patchTypography({
|
|
3309
|
+
kind: "body",
|
|
3310
|
+
patch
|
|
3311
|
+
});
|
|
3312
|
+
}, [patchTypography]);
|
|
3313
|
+
const handleTypographyScaleChange = useCallback((scale) => {
|
|
3314
|
+
patchTypography({
|
|
3315
|
+
kind: "scale",
|
|
3316
|
+
scale
|
|
3317
|
+
});
|
|
3318
|
+
}, [patchTypography]);
|
|
3319
|
+
const handleResetTypography = useCallback(() => {
|
|
3320
|
+
setState((current) => current ? resetTypographyToSaved(current) : current);
|
|
3321
|
+
}, []);
|
|
3322
|
+
const handleTokenOverride = useCallback((role, hex) => {
|
|
3323
|
+
setState((current) => {
|
|
3324
|
+
if (!current) return current;
|
|
3325
|
+
const palette = palettePreviewProjection(current.previewed.palette);
|
|
3326
|
+
if (palette.kind === "invalid") return current;
|
|
3327
|
+
if (!(role in palette.colors)) return current;
|
|
3328
|
+
const nextColors = paletteColorsSchema.safeParse({
|
|
3329
|
+
...palette.colors,
|
|
3330
|
+
[role]: hex
|
|
3331
|
+
});
|
|
3332
|
+
return nextColors.success ? setPaletteColors(current, nextColors.data) : current;
|
|
3333
|
+
});
|
|
3334
|
+
}, []);
|
|
3335
|
+
const handleResetOverrides = useCallback(() => {
|
|
3336
|
+
setState((current) => {
|
|
3337
|
+
if (!current) return current;
|
|
3338
|
+
const palette = palettePreviewProjection(current.previewed.palette);
|
|
3339
|
+
const sourceValueKey = palette.kind === "curated" ? palette.valueKey : palette.kind === "curated-fork" ? palette.sourceValueKey : null;
|
|
3340
|
+
if (!sourceValueKey) return current;
|
|
3341
|
+
const curated = findCuratedPalette(sourceValueKey);
|
|
3342
|
+
return curated ? setPaletteColors(current, curated.colors) : current;
|
|
3343
|
+
});
|
|
3344
|
+
}, []);
|
|
3345
|
+
const handleToggleRow = useCallback((row) => {
|
|
3346
|
+
if (row === "typography") setTypographySurface(typographyOverviewSurface);
|
|
3347
|
+
setState((current) => current ? toggleRow(current, row) : current);
|
|
3348
|
+
}, []);
|
|
3349
|
+
const handleCancel = useCallback(() => {
|
|
3350
|
+
setTypographySurface(typographyOverviewSurface);
|
|
3351
|
+
setState((current) => current ? cancelPreview(current) : current);
|
|
3352
|
+
}, []);
|
|
3353
|
+
const handleDismissWarnings = useCallback(() => {
|
|
3354
|
+
setState((current) => current ? dismissWarnings(current) : current);
|
|
3355
|
+
}, []);
|
|
3356
|
+
const handleApply = useCallback(async (retry = false) => {
|
|
3357
|
+
const current = stateRef.current;
|
|
3358
|
+
let live = current;
|
|
3359
|
+
if (current && retry) try {
|
|
3360
|
+
const paletteAuthority = await apiClient({
|
|
3361
|
+
endpoint: "listSiteThemePalettes",
|
|
3362
|
+
params: { siteId }
|
|
3363
|
+
}).then(unwrapResponse);
|
|
3364
|
+
live = prepareStalePaletteRetry(reconcilePaletteLibraryActive(current, paletteAuthority.active, paletteAuthority.palettes), { sitePalettes: paletteAuthority.palettes });
|
|
3365
|
+
} catch (error) {
|
|
3366
|
+
reportPreviewDesignError("Failed to refresh palette authority", error);
|
|
3367
|
+
const message = PREVIEW_DESIGN_REFRESH_ERROR_MESSAGE;
|
|
3368
|
+
setState((latest) => latest ? markApplyFailed(latest, message, "stale") : latest);
|
|
3369
|
+
return;
|
|
3370
|
+
}
|
|
3371
|
+
if (!live || !isPreviewingChange(live)) return;
|
|
3372
|
+
if (!deriveStyleConfiguratorCapabilities(live).canApplyStaged) return;
|
|
3373
|
+
if (live !== current) {
|
|
3374
|
+
stateRef.current = live;
|
|
3375
|
+
setState(live);
|
|
3376
|
+
}
|
|
3377
|
+
const previewed = live.previewed;
|
|
3378
|
+
const siteStyle = getCuratedSiteStyle(previewed.siteStyleId);
|
|
3379
|
+
if (!siteStyle) return;
|
|
3380
|
+
const compiled = planSiteStylePreviewChange({
|
|
3381
|
+
siteStyle,
|
|
3382
|
+
selection: previewed,
|
|
3383
|
+
baseTheme: theme,
|
|
3384
|
+
headerSelectionContext,
|
|
3385
|
+
footerSelectionContext
|
|
3386
|
+
});
|
|
3387
|
+
await runnerRef.current.run({
|
|
3388
|
+
optimistic: () => {
|
|
3389
|
+
applyStarted("style-configurator");
|
|
3390
|
+
setState((current) => current ? markApplySaving(current) : current);
|
|
3391
|
+
},
|
|
3392
|
+
network: async () => {
|
|
3393
|
+
const body = buildApplySiteStyleSelectionBody({
|
|
3394
|
+
base: live.base,
|
|
3395
|
+
previewed: {
|
|
3396
|
+
...previewed,
|
|
3397
|
+
buttonPersonalityId: compiled.resolvedSelections.buttonPersonalityId,
|
|
3398
|
+
headerLayoutId: compiled.resolvedSelections.headerLayoutId,
|
|
3399
|
+
headerStyleId: compiled.resolvedSelections.headerStyleId,
|
|
3400
|
+
headerLookId: compiled.resolvedSelections.headerLookId,
|
|
3401
|
+
footerLookId: compiled.resolvedSelections.footerLookId,
|
|
3402
|
+
typography: compiled.themeOverlay.typography
|
|
3403
|
+
},
|
|
3404
|
+
selectionId
|
|
3405
|
+
});
|
|
3406
|
+
if (!body.ok) throw new StyleApplyPlanError(paletteApplyPlanErrorMessage(body.error));
|
|
3407
|
+
return unwrapResponse(await apiClient({
|
|
3408
|
+
endpoint: "applySiteStyleSelection",
|
|
3409
|
+
params: { siteId },
|
|
3410
|
+
body: body.body
|
|
3411
|
+
}));
|
|
3412
|
+
},
|
|
3413
|
+
onSuccess: (saved) => {
|
|
3414
|
+
const persisted = selectionSnapshotFromApplySiteStyleSelectionResponse(saved, previewed);
|
|
3415
|
+
const historyEntry = styleConfiguratorHistoryEntryForPersistedSelection(live, persisted);
|
|
3416
|
+
setState((current) => current ? markApplySaved(current, persisted) : current);
|
|
3417
|
+
if (historyEntry) siteChromeCustomize?.siteStyleHistory?.recordAppliedSelection(historyEntry);
|
|
3418
|
+
applySucceeded("style-configurator");
|
|
3419
|
+
startRefreshTransition(() => {
|
|
3420
|
+
router.refresh();
|
|
3421
|
+
});
|
|
3422
|
+
},
|
|
3423
|
+
onError: (error) => {
|
|
3424
|
+
applyFailed("style-configurator");
|
|
3425
|
+
const applyError = classifyStyleApplyError(error);
|
|
3426
|
+
if (applyError.kind === "stale") startRefreshTransition(() => {
|
|
3427
|
+
router.refresh();
|
|
3428
|
+
});
|
|
3429
|
+
const message = applyError.message;
|
|
3430
|
+
setState((current) => current ? markApplyFailed(current, message, applyError.kind === "stale" ? "stale" : "retryable") : current);
|
|
3431
|
+
}
|
|
3432
|
+
});
|
|
3433
|
+
}, [
|
|
3434
|
+
apiClient,
|
|
3435
|
+
footerSelectionContext,
|
|
3436
|
+
headerSelectionContext,
|
|
3437
|
+
applyFailed,
|
|
3438
|
+
applyStarted,
|
|
3439
|
+
applySucceeded,
|
|
3440
|
+
router,
|
|
3441
|
+
selectionId,
|
|
3442
|
+
siteChromeCustomize?.siteStyleHistory,
|
|
3443
|
+
siteId,
|
|
3444
|
+
startRefreshTransition,
|
|
3445
|
+
theme
|
|
3446
|
+
]);
|
|
3447
|
+
if (!state || !baseSnapshot) return /* @__PURE__ */ jsx("p", {
|
|
3448
|
+
className: "text-sm text-muted-foreground",
|
|
3449
|
+
children: "Loading design controls..."
|
|
2951
3450
|
});
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
onChange: (event) => onChange(event.currentTarget.value),
|
|
2962
|
-
disabled,
|
|
2963
|
-
className: "h-8 w-full rounded-md border bg-background px-2 text-sm outline-none focus:border-primary disabled:cursor-not-allowed disabled:opacity-50",
|
|
2964
|
-
children: options.map((option) => /* @__PURE__ */ jsx("option", {
|
|
2965
|
-
value: option.value,
|
|
2966
|
-
children: option.label
|
|
2967
|
-
}, option.value))
|
|
2968
|
-
})]
|
|
3451
|
+
const applyAllowed = canApplySiteStyle(siteStyleAccess);
|
|
3452
|
+
const stagedCapabilities = deriveStyleConfiguratorCapabilities(state);
|
|
3453
|
+
const previewingChange = isPreviewingChange(state);
|
|
3454
|
+
const saving = stagedCapabilities.isApplyingStaged || isRefreshPending;
|
|
3455
|
+
const aggregateMutationControlsDisabled = saving || !stagedCapabilities.canPreviewStaged;
|
|
3456
|
+
const currentSiteStyle = getCuratedSiteStyle(state.previewed.siteStyleId);
|
|
3457
|
+
if (!currentSiteStyle) return /* @__PURE__ */ jsx("p", {
|
|
3458
|
+
className: "text-sm text-muted-foreground",
|
|
3459
|
+
children: "This site uses a Site Style that cannot be configured here."
|
|
2969
3460
|
});
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
3461
|
+
const currentPersonality = findButtonPersonality(state.previewed.buttonPersonalityId);
|
|
3462
|
+
const currentPalette = palettePreviewProjection(state.previewed.palette);
|
|
3463
|
+
const paletteMutation = paletteMutationCapability(state);
|
|
3464
|
+
const paletteControlsDisabled = saving || !stagedCapabilities.canPreviewStaged || paletteMutation.kind !== "editable";
|
|
3465
|
+
const currentCuratedValueKey = currentPalette.kind === "curated" ? currentPalette.valueKey : currentPalette.kind === "curated-fork" ? currentPalette.sourceValueKey : null;
|
|
3466
|
+
const currentCuratedPalette = currentCuratedValueKey ? findCuratedPalette(currentCuratedValueKey) : null;
|
|
3467
|
+
const paletteIsCustom = currentPalette.kind !== "invalid" && (!currentCuratedPalette || currentPalette.mode !== currentCuratedPalette.mode || !paletteColorsEqual(currentPalette.colors, currentCuratedPalette.colors));
|
|
3468
|
+
const currentTypography = planSiteStylePreviewChange({
|
|
3469
|
+
siteStyle: currentSiteStyle,
|
|
3470
|
+
selection: state.previewed,
|
|
3471
|
+
baseTheme: theme,
|
|
3472
|
+
headerSelectionContext,
|
|
3473
|
+
footerSelectionContext
|
|
3474
|
+
}).themeOverlay.typography;
|
|
3475
|
+
const chromeLookModels = buildSiteChromeLookModels({
|
|
3476
|
+
state,
|
|
3477
|
+
siteStyle: currentSiteStyle,
|
|
3478
|
+
headerSelectionContext,
|
|
3479
|
+
footerSelectionContext
|
|
3480
|
+
});
|
|
3481
|
+
const currentHeaderLayout = getHeaderLayout(state.previewed.headerLayoutId);
|
|
3482
|
+
const currentHeaderStyle = getHeaderStyle(state.previewed.headerStyleId);
|
|
3483
|
+
const currentFooterLayout = getFooterLayout(chromeLookModels.footerLayout.renderedLayoutId);
|
|
3484
|
+
const currentFooterLook = state.previewed.footerLookId ? findFooterLook(state.previewed.footerLookId) : findFooterLook(chromeLookModels.footer.renderedLookId);
|
|
3485
|
+
const headerSurfaceState = siteChromeCustomize?.getSurfaceState("header") ?? { kind: "unavailable" };
|
|
3486
|
+
if (state.expandedRow === "typography" && typographySurface.kind !== "overview") return /* @__PURE__ */ jsxs("div", {
|
|
3487
|
+
className: "flex h-full min-h-0 flex-col",
|
|
3488
|
+
"data-style-configurator-focused-surface": true,
|
|
3489
|
+
children: [typographySurface.kind === "font-picker" ? /* @__PURE__ */ jsx(TypographyFontPickerTakeover, {
|
|
3490
|
+
slot: typographySurface.slot,
|
|
3491
|
+
value: typographySurface.slot === "heading" ? currentTypography.headings.default.family : currentTypography.body.family,
|
|
3492
|
+
catalog: fontCatalog,
|
|
3493
|
+
onBack: () => setTypographySurface(typographyOverviewSurface),
|
|
3494
|
+
onChange: (family) => typographySurface.slot === "heading" ? handleHeadingTypographyChange({ family }) : handleBodyTypographyChange({ family }),
|
|
3495
|
+
disabled: aggregateMutationControlsDisabled
|
|
3496
|
+
}) : /* @__PURE__ */ jsx(TypographyAdvancedTakeover, {
|
|
3497
|
+
typography: currentTypography,
|
|
3498
|
+
catalog: fontCatalog,
|
|
3499
|
+
onBack: () => setTypographySurface(typographyOverviewSurface),
|
|
3500
|
+
onHeadingChange: handleHeadingTypographyChange,
|
|
3501
|
+
onBodyChange: handleBodyTypographyChange,
|
|
3502
|
+
onScaleChange: handleTypographyScaleChange,
|
|
3503
|
+
disabled: aggregateMutationControlsDisabled
|
|
2984
3504
|
}), /* @__PURE__ */ jsx("div", {
|
|
2985
|
-
className: "
|
|
2986
|
-
children:
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
3505
|
+
className: "shrink-0 px-3 pb-3",
|
|
3506
|
+
children: /* @__PURE__ */ jsx(StyleConfiguratorSaveControls, {
|
|
3507
|
+
previewingChange,
|
|
3508
|
+
applyAllowed,
|
|
3509
|
+
saving,
|
|
3510
|
+
canCancel: stagedCapabilities.canCancelStaged,
|
|
3511
|
+
canApply: stagedCapabilities.canApplyStaged,
|
|
3512
|
+
saveStatus: state.saveStatus,
|
|
3513
|
+
onCancel: handleCancel,
|
|
3514
|
+
onApply: () => void handleApply(),
|
|
3515
|
+
onRetry: () => void handleApply(true)
|
|
3516
|
+
})
|
|
2994
3517
|
})]
|
|
2995
3518
|
});
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
switch (scale) {
|
|
2999
|
-
case "compact":
|
|
3000
|
-
case "balanced":
|
|
3001
|
-
case "spacious": return scale;
|
|
3002
|
-
case "minorThird": return "compact";
|
|
3003
|
-
case "majorThird": return "balanced";
|
|
3004
|
-
case "perfectFourth": return "spacious";
|
|
3005
|
-
default: return "balanced";
|
|
3006
|
-
}
|
|
3007
|
-
}
|
|
3008
|
-
function TypographyPresetOption({ preset, selected, onSelect, disabled }) {
|
|
3009
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
|
|
3010
|
-
type: "button",
|
|
3011
|
-
role: "radio",
|
|
3012
|
-
"aria-checked": selected,
|
|
3013
|
-
onClick: onSelect,
|
|
3014
|
-
disabled,
|
|
3015
|
-
className: cn("w-full rounded-md border px-3 py-2 text-left transition disabled:cursor-not-allowed disabled:opacity-50", selected ? "border-primary bg-primary/5" : "border-border hover:bg-muted/60"),
|
|
3016
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
3017
|
-
className: "flex items-start justify-between gap-3",
|
|
3018
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
3019
|
-
className: "min-w-0",
|
|
3020
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
3021
|
-
className: "text-sm font-medium",
|
|
3022
|
-
children: preset.name
|
|
3023
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
3024
|
-
className: "text-xs text-muted-foreground",
|
|
3025
|
-
children: preset.description
|
|
3026
|
-
})]
|
|
3027
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
3028
|
-
className: "shrink-0 text-right",
|
|
3029
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
3030
|
-
className: "text-[11px] font-semibold uppercase tracking-wide",
|
|
3031
|
-
children: preset.defaultFonts.heading.split(",")[0]
|
|
3032
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
3033
|
-
className: "text-[11px] text-muted-foreground",
|
|
3034
|
-
children: preset.defaultFonts.body.split(",")[0]
|
|
3035
|
-
})]
|
|
3036
|
-
})]
|
|
3037
|
-
})
|
|
3038
|
-
}) });
|
|
3039
|
-
}
|
|
3040
|
-
function TypographyFontSlotPicker({ label, slot, preset, catalog, value, onChange, disabled }) {
|
|
3041
|
-
const [query, setQuery] = useState("");
|
|
3042
|
-
const [manualFamilyDraft, setManualFamilyDraft] = useState(value);
|
|
3043
|
-
const defaultFont = primaryFontFamily(preset.defaultFonts[slot]);
|
|
3044
|
-
const selectedFamily = primaryFontFamily(value);
|
|
3045
|
-
useEffect(() => {
|
|
3046
|
-
setManualFamilyDraft(value);
|
|
3047
|
-
}, [value]);
|
|
3048
|
-
const commitManualFamilyDraft = useCallback(() => {
|
|
3049
|
-
const normalized = normalizeFontFamilyOverride(manualFamilyDraft);
|
|
3050
|
-
if (!normalized) {
|
|
3051
|
-
setManualFamilyDraft(value);
|
|
3052
|
-
return;
|
|
3053
|
-
}
|
|
3054
|
-
onChange(normalized);
|
|
3055
|
-
}, [
|
|
3056
|
-
manualFamilyDraft,
|
|
3057
|
-
onChange,
|
|
3058
|
-
value
|
|
3059
|
-
]);
|
|
3060
|
-
const recordsByFamily = useMemo(() => indexFontsByFamily(catalog.fonts), [catalog.fonts]);
|
|
3061
|
-
const selectedFit = evaluateTypographyFontSlot({
|
|
3062
|
-
slot,
|
|
3063
|
-
policy: preset.slotPolicies[slot],
|
|
3064
|
-
capability: capabilityForFamily(selectedFamily, recordsByFamily)
|
|
3065
|
-
});
|
|
3066
|
-
const recommendedFamilies = preset.recommendedFonts[slot];
|
|
3067
|
-
const recommendedOptions = useMemo(() => uniqueFontFamilies(recommendedFamilies), [recommendedFamilies]);
|
|
3068
|
-
const browseOptions = useMemo(() => {
|
|
3069
|
-
const normalizedQuery = query.trim().toLowerCase();
|
|
3070
|
-
return [...normalizedQuery.length > 0 ? catalog.fonts.filter((font) => font.family.toLowerCase().includes(normalizedQuery)) : catalog.fonts].sort((a, b) => sortFontForPresetSlot(a, b, slot, preset, recordsByFamily)).slice(0, normalizedQuery.length > 0 ? MAX_FONT_RESULTS_WHEN_SEARCHING : MAX_FONT_RESULTS_WHEN_BROWSING);
|
|
3071
|
-
}, [
|
|
3072
|
-
catalog.fonts,
|
|
3073
|
-
preset,
|
|
3074
|
-
query,
|
|
3075
|
-
recordsByFamily,
|
|
3076
|
-
slot
|
|
3077
|
-
]);
|
|
3078
|
-
return /* @__PURE__ */ jsxs("section", {
|
|
3079
|
-
className: "space-y-2",
|
|
3080
|
-
"aria-label": label,
|
|
3519
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3520
|
+
className: "space-y-3",
|
|
3081
3521
|
children: [
|
|
3082
|
-
/* @__PURE__ */
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
})]
|
|
3093
|
-
}), /* @__PURE__ */ jsx(TypographyFontFitBadge, { fit: selectedFit })]
|
|
3522
|
+
state.warnings.length > 0 ? /* @__PURE__ */ jsx(WarningNotice, {
|
|
3523
|
+
warnings: state.warnings,
|
|
3524
|
+
onDismiss: handleDismissWarnings
|
|
3525
|
+
}) : null,
|
|
3526
|
+
/* @__PURE__ */ jsx(SiteStyleRow, {
|
|
3527
|
+
expanded: state.expandedRow === "style",
|
|
3528
|
+
onToggle: () => handleToggleRow("style"),
|
|
3529
|
+
current: currentSiteStyle,
|
|
3530
|
+
onPreview: handlePreviewSiteStyle,
|
|
3531
|
+
disabled: aggregateMutationControlsDisabled
|
|
3094
3532
|
}),
|
|
3095
|
-
/* @__PURE__ */
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
}
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
fit: evaluateTypographyFontSlot({
|
|
3113
|
-
slot,
|
|
3114
|
-
policy: preset.slotPolicies[slot],
|
|
3115
|
-
capability: capabilityForFamily(family, recordsByFamily)
|
|
3116
|
-
}),
|
|
3117
|
-
onSelect: () => onChange(family),
|
|
3118
|
-
disabled
|
|
3119
|
-
}, family))]
|
|
3533
|
+
/* @__PURE__ */ jsx(SiteChromeLookRow, {
|
|
3534
|
+
label: "Header layout",
|
|
3535
|
+
ariaLabel: "Header layout",
|
|
3536
|
+
defaultDescription: "Choose the header structure.",
|
|
3537
|
+
expanded: state.expandedRow === "header-layout",
|
|
3538
|
+
onToggle: () => handleToggleRow("header-layout"),
|
|
3539
|
+
currentId: state.previewed.headerLayoutId,
|
|
3540
|
+
currentLabel: currentHeaderLayout?.label ?? state.previewed.headerLayoutId,
|
|
3541
|
+
scopeDescription: "Changes the header structure on every page.",
|
|
3542
|
+
options: chromeLookModels.headerLayout.options,
|
|
3543
|
+
diagnostics: [],
|
|
3544
|
+
onCycle: (direction) => {
|
|
3545
|
+
const next = cycleSiteChromeLookId(chromeLookModels.headerLayout.options, state.previewed.headerLayoutId, direction);
|
|
3546
|
+
if (next !== void 0) handlePreviewHeaderLayout(next);
|
|
3547
|
+
},
|
|
3548
|
+
onPreview: handlePreviewHeaderLayout,
|
|
3549
|
+
disabled: aggregateMutationControlsDisabled
|
|
3120
3550
|
}),
|
|
3121
|
-
/* @__PURE__ */
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3551
|
+
/* @__PURE__ */ jsx(SiteChromeLookRow, {
|
|
3552
|
+
label: "Header look",
|
|
3553
|
+
ariaLabel: "Header look",
|
|
3554
|
+
defaultDescription: "Choose the header visual style.",
|
|
3555
|
+
expanded: state.expandedRow === "header-style",
|
|
3556
|
+
onToggle: () => handleToggleRow("header-style"),
|
|
3557
|
+
currentId: state.previewed.headerStyleId,
|
|
3558
|
+
currentLabel: currentHeaderStyle?.label ?? state.previewed.headerStyleId,
|
|
3559
|
+
scopeDescription: "Changes the header surface and link style.",
|
|
3560
|
+
options: chromeLookModels.headerStyle.options,
|
|
3561
|
+
diagnostics: [],
|
|
3562
|
+
onCycle: (direction) => {
|
|
3563
|
+
const next = cycleSiteChromeLookId(chromeLookModels.headerStyle.options, state.previewed.headerStyleId, direction);
|
|
3564
|
+
if (next !== void 0) handlePreviewHeaderStyle(next);
|
|
3565
|
+
},
|
|
3566
|
+
onPreview: handlePreviewHeaderStyle,
|
|
3567
|
+
disabled: aggregateMutationControlsDisabled,
|
|
3568
|
+
extraControls: isHeaderMenuSurfaceState(headerSurfaceState) ? /* @__PURE__ */ jsx(HeaderMenuControls, {
|
|
3569
|
+
state: headerSurfaceState,
|
|
3570
|
+
disabled: saving,
|
|
3571
|
+
onMenuFontChange: siteChromeCustomize?.setHeaderMenuFont,
|
|
3572
|
+
onMenuFontSizeChange: siteChromeCustomize?.setHeaderMenuFontSize
|
|
3573
|
+
}) : null
|
|
3574
|
+
}),
|
|
3575
|
+
/* @__PURE__ */ jsx(SiteChromeLookRow, {
|
|
3576
|
+
label: "Footer layout",
|
|
3577
|
+
ariaLabel: "Footer layout",
|
|
3578
|
+
defaultDescription: "Choose the footer structure.",
|
|
3579
|
+
expanded: state.expandedRow === "footer-layout",
|
|
3580
|
+
onToggle: () => handleToggleRow("footer-layout"),
|
|
3581
|
+
currentId: chromeLookModels.footerLayout.renderedLayoutId,
|
|
3582
|
+
currentLabel: currentFooterLayout?.label ?? chromeLookModels.footerLayout.renderedLayoutId,
|
|
3583
|
+
scopeDescription: "Changes the footer structure on every page.",
|
|
3584
|
+
options: chromeLookModels.footerLayout.options,
|
|
3585
|
+
diagnostics: [],
|
|
3586
|
+
onCycle: (direction) => {
|
|
3587
|
+
const next = cycleSiteChromeLookId(chromeLookModels.footerLayout.options, chromeLookModels.footerLayout.renderedLayoutId, direction);
|
|
3588
|
+
if (next !== void 0) handlePreviewFooterLayout(next);
|
|
3589
|
+
},
|
|
3590
|
+
onPreview: handlePreviewFooterLayout,
|
|
3591
|
+
disabled: aggregateMutationControlsDisabled
|
|
3592
|
+
}),
|
|
3593
|
+
/* @__PURE__ */ jsx(SiteChromeLookRow, {
|
|
3594
|
+
label: "Footer look",
|
|
3595
|
+
ariaLabel: "Footer look",
|
|
3596
|
+
defaultDescription: "Use the footer look chosen for this site style.",
|
|
3597
|
+
expanded: state.expandedRow === "footer",
|
|
3598
|
+
onToggle: () => handleToggleRow("footer"),
|
|
3599
|
+
currentId: state.previewed.footerLookId,
|
|
3600
|
+
currentLabel: state.previewed.footerLookId ? currentFooterLook?.label ?? "Unknown footer Look" : `${currentFooterLook?.label ?? "Site style"} (default)`,
|
|
3601
|
+
scopeDescription: "Changes the footer on every page.",
|
|
3602
|
+
options: chromeLookModels.footer.options,
|
|
3603
|
+
diagnostics: chromeLookModels.footer.diagnostics,
|
|
3604
|
+
onCycle: (direction) => {
|
|
3605
|
+
const next = cycleSiteChromeLookId(chromeLookModels.footer.options, state.previewed.footerLookId, direction);
|
|
3606
|
+
if (next !== void 0) handlePreviewFooterLook(next);
|
|
3607
|
+
},
|
|
3608
|
+
onPreview: handlePreviewFooterLook,
|
|
3609
|
+
disabled: aggregateMutationControlsDisabled
|
|
3610
|
+
}),
|
|
3611
|
+
/* @__PURE__ */ jsx(PersonalityRow, {
|
|
3612
|
+
expanded: state.expandedRow === "buttons",
|
|
3613
|
+
onToggle: () => handleToggleRow("buttons"),
|
|
3614
|
+
siteStyle: currentSiteStyle,
|
|
3615
|
+
currentId: state.previewed.buttonPersonalityId,
|
|
3616
|
+
currentLabel: currentPersonality?.name ?? state.previewed.buttonPersonalityId,
|
|
3617
|
+
onPreview: handlePreviewPersonality,
|
|
3618
|
+
disabled: aggregateMutationControlsDisabled
|
|
3619
|
+
}),
|
|
3620
|
+
/* @__PURE__ */ jsx(TypographyRow, {
|
|
3621
|
+
expanded: state.expandedRow === "typography",
|
|
3622
|
+
onToggle: () => handleToggleRow("typography"),
|
|
3623
|
+
typography: currentTypography,
|
|
3624
|
+
catalog: fontCatalog,
|
|
3625
|
+
currentLabel: `${primaryFontFamily(currentTypography.headings.default.family)} / ${primaryFontFamily(currentTypography.body.family)}`,
|
|
3626
|
+
onChooseFont: (slot) => setTypographySurface({
|
|
3627
|
+
kind: "font-picker",
|
|
3628
|
+
slot
|
|
3629
|
+
}),
|
|
3630
|
+
onOpenAdvanced: () => setTypographySurface({ kind: "advanced" }),
|
|
3631
|
+
onReset: handleResetTypography,
|
|
3632
|
+
disabled: aggregateMutationControlsDisabled
|
|
3158
3633
|
}),
|
|
3159
|
-
/* @__PURE__ */
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3634
|
+
/* @__PURE__ */ jsx(PaletteRow, {
|
|
3635
|
+
expanded: state.expandedRow === "palette",
|
|
3636
|
+
onToggle: () => handleToggleRow("palette"),
|
|
3637
|
+
apiClient,
|
|
3638
|
+
siteId,
|
|
3639
|
+
siteStyle: currentSiteStyle,
|
|
3640
|
+
palette: currentPalette,
|
|
3641
|
+
committedSelection: committedPaletteForSnapshot(state.base.palette)?.selection ?? null,
|
|
3642
|
+
onPreview: handlePreviewPaletteItem,
|
|
3643
|
+
onCreate: handleCreatePalette,
|
|
3644
|
+
onLibraryLoaded: handlePaletteLibraryLoaded,
|
|
3645
|
+
isCustom: paletteIsCustom,
|
|
3646
|
+
onTokenChange: handleTokenOverride,
|
|
3647
|
+
onReset: handleResetOverrides,
|
|
3648
|
+
mutationCapability: paletteMutation,
|
|
3649
|
+
disabled: saving || !applyAllowed,
|
|
3650
|
+
mutationDisabled: paletteControlsDisabled || !applyAllowed
|
|
3651
|
+
}),
|
|
3652
|
+
/* @__PURE__ */ jsx(StyleConfiguratorSaveControls, {
|
|
3653
|
+
previewingChange,
|
|
3654
|
+
applyAllowed,
|
|
3655
|
+
saving,
|
|
3656
|
+
canCancel: stagedCapabilities.canCancelStaged,
|
|
3657
|
+
canApply: stagedCapabilities.canApplyStaged,
|
|
3658
|
+
saveStatus: state.saveStatus,
|
|
3659
|
+
onCancel: handleCancel,
|
|
3660
|
+
onApply: () => void handleApply(),
|
|
3661
|
+
onRetry: () => void handleApply(true)
|
|
3177
3662
|
})
|
|
3178
3663
|
]
|
|
3179
3664
|
});
|
|
3180
3665
|
}
|
|
3181
|
-
function
|
|
3182
|
-
return /* @__PURE__ */ jsxs(
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3666
|
+
function StyleConfiguratorSaveControls({ previewingChange, applyAllowed, saving, canCancel, canApply, saveStatus, onCancel, onApply, onRetry }) {
|
|
3667
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
3668
|
+
previewingChange ? /* @__PURE__ */ jsxs("div", {
|
|
3669
|
+
className: "flex items-center gap-2 pt-2",
|
|
3670
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
3671
|
+
type: "button",
|
|
3672
|
+
size: "sm",
|
|
3673
|
+
variant: "outline",
|
|
3674
|
+
onClick: onCancel,
|
|
3675
|
+
disabled: !canCancel || saving,
|
|
3676
|
+
children: "Cancel"
|
|
3677
|
+
}), applyAllowed ? /* @__PURE__ */ jsx(Button, {
|
|
3678
|
+
type: "button",
|
|
3679
|
+
size: "sm",
|
|
3680
|
+
onClick: onApply,
|
|
3681
|
+
disabled: !canApply || saving,
|
|
3682
|
+
children: saving ? "Applying…" : "Apply"
|
|
3683
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
3684
|
+
className: "text-xs text-muted-foreground",
|
|
3685
|
+
children: "Preview only — ask an admin to apply."
|
|
3686
|
+
})]
|
|
3687
|
+
}) : null,
|
|
3688
|
+
saveStatus.kind === "saved" ? /* @__PURE__ */ jsx("p", {
|
|
3689
|
+
className: "text-xs text-success",
|
|
3690
|
+
children: "Saved."
|
|
3691
|
+
}) : null,
|
|
3692
|
+
saveStatus.kind === "failed" ? /* @__PURE__ */ jsxs("div", {
|
|
3693
|
+
role: "status",
|
|
3694
|
+
className: "flex items-center gap-2 text-xs text-destructive",
|
|
3695
|
+
children: [/* @__PURE__ */ jsx("span", { children: saveStatus.message }), saveStatus.failureKind === "stale" && previewingChange && applyAllowed ? /* @__PURE__ */ jsx(Button, {
|
|
3696
|
+
type: "button",
|
|
3697
|
+
size: "sm",
|
|
3698
|
+
variant: "outline",
|
|
3699
|
+
onClick: onRetry,
|
|
3700
|
+
disabled: saving,
|
|
3701
|
+
children: "Retry"
|
|
3702
|
+
}) : null]
|
|
3703
|
+
}) : null
|
|
3704
|
+
] });
|
|
3192
3705
|
}
|
|
3193
|
-
function
|
|
3194
|
-
return /* @__PURE__ */ jsx(
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
children:
|
|
3706
|
+
function StyleRowFrame({ label, currentLabel, swatch, expanded, onToggle, children }) {
|
|
3707
|
+
return /* @__PURE__ */ jsx(Collapsible, {
|
|
3708
|
+
open: expanded,
|
|
3709
|
+
onOpenChange: onToggle,
|
|
3710
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
3711
|
+
className: "rounded-md border bg-background",
|
|
3712
|
+
children: [/* @__PURE__ */ jsx(CollapsibleTrigger, {
|
|
3713
|
+
asChild: true,
|
|
3714
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
3715
|
+
type: "button",
|
|
3716
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-accent/30",
|
|
3717
|
+
"aria-expanded": expanded,
|
|
3718
|
+
children: [
|
|
3719
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: cn("h-4 w-4 transition", expanded && "rotate-90") }),
|
|
3720
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3721
|
+
className: "flex-1 min-w-0",
|
|
3722
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
3723
|
+
className: "text-xs uppercase tracking-wide text-muted-foreground",
|
|
3724
|
+
children: label
|
|
3725
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
3726
|
+
className: "truncate text-sm font-medium",
|
|
3727
|
+
children: currentLabel
|
|
3728
|
+
})]
|
|
3729
|
+
}),
|
|
3730
|
+
swatch ? /* @__PURE__ */ jsx("span", {
|
|
3731
|
+
className: "h-5 w-5 shrink-0 rounded-full border border-black/10",
|
|
3732
|
+
style: { backgroundColor: swatch },
|
|
3733
|
+
"aria-hidden": "true"
|
|
3734
|
+
}) : null
|
|
3735
|
+
]
|
|
3736
|
+
})
|
|
3737
|
+
}), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", {
|
|
3738
|
+
className: "border-t px-3 py-3",
|
|
3739
|
+
children
|
|
3740
|
+
}) })]
|
|
3741
|
+
})
|
|
3198
3742
|
});
|
|
3199
3743
|
}
|
|
3200
|
-
function
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3744
|
+
function SiteStyleRow({ expanded, onToggle, current, onPreview, disabled }) {
|
|
3745
|
+
return /* @__PURE__ */ jsx(StyleRowFrame, {
|
|
3746
|
+
label: "Site style",
|
|
3747
|
+
currentLabel: current.name,
|
|
3748
|
+
expanded,
|
|
3749
|
+
onToggle,
|
|
3750
|
+
children: /* @__PURE__ */ jsx("ul", {
|
|
3751
|
+
role: "radiogroup",
|
|
3752
|
+
"aria-label": "Site style",
|
|
3753
|
+
className: "list-none space-y-1 p-0",
|
|
3754
|
+
children: curatedSiteStyles.map((style) => /* @__PURE__ */ jsx(PickerOption, {
|
|
3755
|
+
selected: style.id === current.id,
|
|
3756
|
+
label: style.name,
|
|
3757
|
+
description: style.description,
|
|
3758
|
+
onSelect: () => onPreview(style.id),
|
|
3759
|
+
disabled
|
|
3760
|
+
}, style.id))
|
|
3761
|
+
})
|
|
3204
3762
|
});
|
|
3205
|
-
const requestedClientRef = useRef(null);
|
|
3206
|
-
useEffect(() => {
|
|
3207
|
-
if (!enabled) return;
|
|
3208
|
-
if (requestedClientRef.current === apiClient) return;
|
|
3209
|
-
requestedClientRef.current = apiClient;
|
|
3210
|
-
let cancelled = false;
|
|
3211
|
-
setCatalog({
|
|
3212
|
-
kind: "loading",
|
|
3213
|
-
fonts: []
|
|
3214
|
-
});
|
|
3215
|
-
async function loadFonts() {
|
|
3216
|
-
try {
|
|
3217
|
-
const fonts = unwrapResponse(await apiClient({ endpoint: "listFonts" }));
|
|
3218
|
-
if (!cancelled) setCatalog({
|
|
3219
|
-
kind: "loaded",
|
|
3220
|
-
fonts: Array.isArray(fonts) ? fonts : []
|
|
3221
|
-
});
|
|
3222
|
-
} catch (error) {
|
|
3223
|
-
if (!cancelled) setCatalog({
|
|
3224
|
-
kind: "failed",
|
|
3225
|
-
fonts: [],
|
|
3226
|
-
message: error instanceof Error ? error.message : "Unable to load the font catalog."
|
|
3227
|
-
});
|
|
3228
|
-
}
|
|
3229
|
-
}
|
|
3230
|
-
loadFonts();
|
|
3231
|
-
return () => {
|
|
3232
|
-
cancelled = true;
|
|
3233
|
-
};
|
|
3234
|
-
}, [apiClient, enabled]);
|
|
3235
|
-
return catalog;
|
|
3236
|
-
}
|
|
3237
|
-
function indexFontsByFamily(fonts) {
|
|
3238
|
-
return new Map(fonts.map((font) => [font.family.toLowerCase(), font]));
|
|
3239
|
-
}
|
|
3240
|
-
function capabilityForFamily(family, recordsByFamily) {
|
|
3241
|
-
const record = recordsByFamily.get(family.toLowerCase());
|
|
3242
|
-
if (record) return capabilityFromFontRecord(record);
|
|
3243
|
-
return {
|
|
3244
|
-
source: "unknown",
|
|
3245
|
-
family,
|
|
3246
|
-
category: "unknown",
|
|
3247
|
-
variants: []
|
|
3248
|
-
};
|
|
3249
|
-
}
|
|
3250
|
-
function capabilityFromFontRecord(font) {
|
|
3251
|
-
return {
|
|
3252
|
-
source: "google",
|
|
3253
|
-
family: font.family,
|
|
3254
|
-
category: normalizeGoogleFontCategory(font.category),
|
|
3255
|
-
variants: font.variants
|
|
3256
|
-
};
|
|
3257
|
-
}
|
|
3258
|
-
function normalizeGoogleFontCategory(category) {
|
|
3259
|
-
switch (category) {
|
|
3260
|
-
case "serif":
|
|
3261
|
-
case "sans-serif":
|
|
3262
|
-
case "display":
|
|
3263
|
-
case "handwriting":
|
|
3264
|
-
case "monospace": return category;
|
|
3265
|
-
default: return "unknown";
|
|
3266
|
-
}
|
|
3267
|
-
}
|
|
3268
|
-
function sortFontForPresetSlot(a, b, slot, preset, recordsByFamily) {
|
|
3269
|
-
const aFit = evaluateTypographyFontSlot({
|
|
3270
|
-
slot,
|
|
3271
|
-
policy: preset.slotPolicies[slot],
|
|
3272
|
-
capability: capabilityForFamily(a.family, recordsByFamily)
|
|
3273
|
-
});
|
|
3274
|
-
const bFit = evaluateTypographyFontSlot({
|
|
3275
|
-
slot,
|
|
3276
|
-
policy: preset.slotPolicies[slot],
|
|
3277
|
-
capability: capabilityForFamily(b.family, recordsByFamily)
|
|
3278
|
-
});
|
|
3279
|
-
const fitDelta = typographyFontFitRank(aFit.kind) - typographyFontFitRank(bFit.kind);
|
|
3280
|
-
if (fitDelta !== 0) return fitDelta;
|
|
3281
|
-
const popularityDelta = (a.popularity ?? Infinity) - (b.popularity ?? Infinity);
|
|
3282
|
-
if (popularityDelta !== 0) return popularityDelta;
|
|
3283
|
-
return a.family.localeCompare(b.family);
|
|
3284
|
-
}
|
|
3285
|
-
function typographyFontFitRank(kind) {
|
|
3286
|
-
switch (kind) {
|
|
3287
|
-
case "recommended": return 0;
|
|
3288
|
-
case "compatible": return 1;
|
|
3289
|
-
case "limited": return 2;
|
|
3290
|
-
case "risky": return 3;
|
|
3291
|
-
case "unknown": return 4;
|
|
3292
|
-
default: return kind;
|
|
3293
|
-
}
|
|
3294
|
-
}
|
|
3295
|
-
function typographyFontFitLabel(kind) {
|
|
3296
|
-
switch (kind) {
|
|
3297
|
-
case "recommended": return "Recommended";
|
|
3298
|
-
case "compatible": return "Compatible";
|
|
3299
|
-
case "limited": return "Limited";
|
|
3300
|
-
case "risky": return "Risky";
|
|
3301
|
-
case "unknown": return "Unknown";
|
|
3302
|
-
default: return kind;
|
|
3303
|
-
}
|
|
3304
|
-
}
|
|
3305
|
-
function primaryFontFamily(cssFamily) {
|
|
3306
|
-
return cssFamily.split(",")[0]?.trim().replace(/^["']|["']$/gu, "") || cssFamily;
|
|
3307
3763
|
}
|
|
3308
|
-
function
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3764
|
+
function PersonalityRow({ expanded, onToggle, siteStyle, currentId, currentLabel, onPreview, disabled }) {
|
|
3765
|
+
return /* @__PURE__ */ jsx(StyleRowFrame, {
|
|
3766
|
+
label: "Button style",
|
|
3767
|
+
currentLabel,
|
|
3768
|
+
expanded,
|
|
3769
|
+
onToggle,
|
|
3770
|
+
children: /* @__PURE__ */ jsx("ul", {
|
|
3771
|
+
role: "radiogroup",
|
|
3772
|
+
"aria-label": "Button style",
|
|
3773
|
+
className: "list-none space-y-1 p-0",
|
|
3774
|
+
children: useMemo(() => requireEntriesForCuratedChoices(buttonPersonalities, siteStyle.buttonPersonalityChoices), [siteStyle.buttonPersonalityChoices]).map((personality) => /* @__PURE__ */ jsx(PickerOption, {
|
|
3775
|
+
selected: personality.id === currentId,
|
|
3776
|
+
label: personality.name,
|
|
3777
|
+
description: personality.description,
|
|
3778
|
+
onSelect: () => onPreview(personality.id),
|
|
3779
|
+
disabled
|
|
3780
|
+
}, personality.id))
|
|
3781
|
+
})
|
|
3782
|
+
});
|
|
3319
3783
|
}
|
|
3320
|
-
function
|
|
3321
|
-
|
|
3322
|
-
|
|
3784
|
+
function TypographyRow({ expanded, onToggle, typography, catalog, currentLabel, onChooseFont, onOpenAdvanced, onReset, disabled }) {
|
|
3785
|
+
return /* @__PURE__ */ jsx(StyleRowFrame, {
|
|
3786
|
+
label: "Typography",
|
|
3787
|
+
currentLabel,
|
|
3788
|
+
expanded,
|
|
3789
|
+
onToggle,
|
|
3790
|
+
children: /* @__PURE__ */ jsx(TypographyOverviewContent, {
|
|
3791
|
+
typography,
|
|
3792
|
+
catalog,
|
|
3793
|
+
onChooseFont,
|
|
3794
|
+
onOpenAdvanced,
|
|
3795
|
+
onReset,
|
|
3796
|
+
disabled
|
|
3797
|
+
})
|
|
3798
|
+
});
|
|
3323
3799
|
}
|
|
3324
3800
|
function SiteChromeLookRow({ label, ariaLabel, defaultDescription, catalog, options = [{
|
|
3325
3801
|
id: null,
|
|
@@ -3417,93 +3893,255 @@ function HeaderMenuControls({ state, disabled, onMenuFontChange, onMenuFontSizeC
|
|
|
3417
3893
|
})]
|
|
3418
3894
|
});
|
|
3419
3895
|
}
|
|
3420
|
-
function PaletteRow({ expanded, onToggle,
|
|
3421
|
-
const
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3896
|
+
function PaletteRow({ expanded, onToggle, apiClient, siteId, siteStyle, palette, committedSelection, onPreview, onCreate, onLibraryLoaded, isCustom, onTokenChange, onReset, mutationCapability, disabled, mutationDisabled }) {
|
|
3897
|
+
const [library, setLibrary] = useState({
|
|
3898
|
+
kind: "idle",
|
|
3899
|
+
palettes: []
|
|
3900
|
+
});
|
|
3901
|
+
const optionRefs = useRef([]);
|
|
3902
|
+
const activeSelection = selectionForPaletteSnapshot(palette) ?? committedSelection;
|
|
3903
|
+
const libraryModel = useMemo(() => buildPaletteLibraryReadModel({
|
|
3904
|
+
active: activeSelection ? {
|
|
3905
|
+
kind: "available",
|
|
3906
|
+
selection: activeSelection
|
|
3907
|
+
} : { kind: "invalid" },
|
|
3908
|
+
sitePalettes: library.palettes,
|
|
3909
|
+
curatedPalettes,
|
|
3910
|
+
recommendations: siteStyle.paletteRecommendations.map((recommendation) => recommendation.id)
|
|
3911
|
+
}), [
|
|
3912
|
+
activeSelection,
|
|
3913
|
+
library.palettes,
|
|
3914
|
+
siteStyle.paletteRecommendations
|
|
3915
|
+
]);
|
|
3916
|
+
useEffect(() => {
|
|
3917
|
+
if (!expanded || library.kind !== "idle") return;
|
|
3918
|
+
setLibrary((current) => ({
|
|
3919
|
+
kind: "loading",
|
|
3920
|
+
palettes: current.palettes
|
|
3921
|
+
}));
|
|
3922
|
+
}, [expanded, library.kind]);
|
|
3923
|
+
useEffect(() => {
|
|
3924
|
+
if (library.kind !== "loading") return;
|
|
3925
|
+
let cancelled = false;
|
|
3926
|
+
apiClient({
|
|
3927
|
+
endpoint: "listSiteThemePalettes",
|
|
3928
|
+
params: { siteId }
|
|
3929
|
+
}).then(unwrapResponse).then((response) => {
|
|
3930
|
+
if (cancelled) return;
|
|
3931
|
+
setLibrary({
|
|
3932
|
+
kind: "loaded",
|
|
3933
|
+
palettes: response.palettes
|
|
3934
|
+
});
|
|
3935
|
+
onLibraryLoaded(response);
|
|
3936
|
+
}).catch((error) => {
|
|
3937
|
+
if (cancelled) return;
|
|
3938
|
+
reportPreviewDesignError("Failed to load site palettes", error);
|
|
3939
|
+
setLibrary((current) => ({
|
|
3940
|
+
kind: "failed",
|
|
3941
|
+
palettes: current.palettes,
|
|
3942
|
+
message: PREVIEW_DESIGN_LOAD_ERROR_MESSAGE
|
|
3943
|
+
}));
|
|
3944
|
+
});
|
|
3945
|
+
return () => {
|
|
3946
|
+
cancelled = true;
|
|
3947
|
+
};
|
|
3948
|
+
}, [
|
|
3949
|
+
apiClient,
|
|
3950
|
+
library.kind,
|
|
3951
|
+
onLibraryLoaded,
|
|
3952
|
+
siteId
|
|
3953
|
+
]);
|
|
3954
|
+
const items = libraryModel?.ok ? [
|
|
3955
|
+
...libraryModel.model.yours,
|
|
3956
|
+
...libraryModel.model.suggested,
|
|
3957
|
+
...libraryModel.model.more
|
|
3958
|
+
] : [];
|
|
3959
|
+
const currentLabel = palette.kind === "new-site" ? "New palette" : "Selected palette";
|
|
3960
|
+
const onOptionKeyDown = (event, index) => {
|
|
3961
|
+
if (items.length === 0) return;
|
|
3962
|
+
const direction = event.key === "ArrowDown" || event.key === "ArrowRight" ? 1 : event.key === "ArrowUp" || event.key === "ArrowLeft" ? -1 : 0;
|
|
3963
|
+
if (direction === 0) return;
|
|
3964
|
+
event.preventDefault();
|
|
3965
|
+
const nextIndex = (index + direction + items.length) % items.length;
|
|
3966
|
+
const next = items[nextIndex];
|
|
3967
|
+
if (!next) return;
|
|
3968
|
+
onPreview(next);
|
|
3969
|
+
optionRefs.current[nextIndex]?.focus();
|
|
3970
|
+
};
|
|
3427
3971
|
return /* @__PURE__ */ jsxs(StyleRowFrame, {
|
|
3428
3972
|
label: "Palette",
|
|
3429
3973
|
currentLabel,
|
|
3430
|
-
swatch:
|
|
3974
|
+
swatch: palette.kind === "invalid" ? null : palette.colors.primary,
|
|
3431
3975
|
expanded,
|
|
3432
3976
|
onToggle,
|
|
3433
3977
|
children: [
|
|
3434
|
-
/* @__PURE__ */ jsx("p", {
|
|
3435
|
-
className: "mb-3 text-xs text-muted-foreground",
|
|
3436
|
-
children: "These palette bases are recommended for the current Site Style. Choose a base here, then edit exact colours in Palette colours."
|
|
3437
|
-
}),
|
|
3438
3978
|
mutationCapability.kind === "blocked" && mutationCapability.reason === "invalid-palette" ? /* @__PURE__ */ jsx("div", {
|
|
3439
3979
|
role: "status",
|
|
3440
3980
|
className: "mb-3 flex items-center justify-between gap-3 rounded-md border border-muted px-3 py-2 text-xs text-muted-foreground",
|
|
3441
3981
|
children: /* @__PURE__ */ jsx("span", { children: mutationCapability.message })
|
|
3442
3982
|
}) : null,
|
|
3443
|
-
/* @__PURE__ */ jsx("
|
|
3983
|
+
library.kind === "loading" ? /* @__PURE__ */ jsx("p", {
|
|
3984
|
+
className: "text-xs text-muted-foreground",
|
|
3985
|
+
children: "Loading palettes..."
|
|
3986
|
+
}) : null,
|
|
3987
|
+
library.kind === "failed" ? /* @__PURE__ */ jsxs("div", {
|
|
3988
|
+
role: "status",
|
|
3989
|
+
className: "space-y-2 text-xs text-muted-foreground",
|
|
3990
|
+
children: [/* @__PURE__ */ jsx("p", { children: library.message }), /* @__PURE__ */ jsx(Button, {
|
|
3991
|
+
type: "button",
|
|
3992
|
+
size: "sm",
|
|
3993
|
+
variant: "outline",
|
|
3994
|
+
onClick: () => setLibrary({
|
|
3995
|
+
kind: "idle",
|
|
3996
|
+
palettes: library.palettes
|
|
3997
|
+
}),
|
|
3998
|
+
children: "Retry loading palettes"
|
|
3999
|
+
})]
|
|
4000
|
+
}) : null,
|
|
4001
|
+
libraryModel.ok ? /* @__PURE__ */ jsxs("div", {
|
|
3444
4002
|
role: "radiogroup",
|
|
3445
|
-
"aria-label": "Palette",
|
|
3446
|
-
className: "
|
|
3447
|
-
children:
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
4003
|
+
"aria-label": "Palette library",
|
|
4004
|
+
className: "space-y-3",
|
|
4005
|
+
children: [
|
|
4006
|
+
/* @__PURE__ */ jsx(PaletteLibraryGroup, {
|
|
4007
|
+
label: "Your palettes",
|
|
4008
|
+
items: libraryModel.model.yours,
|
|
4009
|
+
offset: 0,
|
|
4010
|
+
optionRefs,
|
|
4011
|
+
onPreview,
|
|
4012
|
+
onOptionKeyDown,
|
|
3455
4013
|
disabled
|
|
3456
|
-
},
|
|
3457
|
-
|
|
3458
|
-
|
|
4014
|
+
}),
|
|
4015
|
+
/* @__PURE__ */ jsx(PaletteLibraryGroup, {
|
|
4016
|
+
label: "Suggested for this style",
|
|
4017
|
+
items: libraryModel.model.suggested,
|
|
4018
|
+
offset: libraryModel.model.yours.length,
|
|
4019
|
+
optionRefs,
|
|
4020
|
+
onPreview,
|
|
4021
|
+
onOptionKeyDown,
|
|
4022
|
+
disabled
|
|
4023
|
+
}),
|
|
4024
|
+
/* @__PURE__ */ jsx(PaletteLibraryGroup, {
|
|
4025
|
+
label: "More palettes",
|
|
4026
|
+
items: libraryModel.model.more,
|
|
4027
|
+
offset: libraryModel.model.yours.length + libraryModel.model.suggested.length,
|
|
4028
|
+
optionRefs,
|
|
4029
|
+
onPreview,
|
|
4030
|
+
onOptionKeyDown,
|
|
4031
|
+
disabled
|
|
4032
|
+
})
|
|
4033
|
+
]
|
|
4034
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
4035
|
+
role: "status",
|
|
4036
|
+
className: "text-xs text-muted-foreground",
|
|
4037
|
+
children: "Palette details are unavailable."
|
|
4038
|
+
}),
|
|
4039
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
4040
|
+
type: "button",
|
|
4041
|
+
size: "sm",
|
|
4042
|
+
variant: "outline",
|
|
4043
|
+
className: "mt-3",
|
|
4044
|
+
onClick: onCreate,
|
|
4045
|
+
disabled: mutationDisabled,
|
|
4046
|
+
children: [/* @__PURE__ */ jsx(Plus, {
|
|
4047
|
+
"aria-hidden": "true",
|
|
4048
|
+
className: "size-3.5"
|
|
4049
|
+
}), "Create palette"]
|
|
4050
|
+
}),
|
|
4051
|
+
palette.kind !== "invalid" ? /* @__PURE__ */ jsx(PaletteTokenControls, {
|
|
4052
|
+
palette: palette.colors,
|
|
4053
|
+
isCustom,
|
|
4054
|
+
onTokenChange,
|
|
4055
|
+
onReset,
|
|
4056
|
+
disabled: mutationDisabled
|
|
4057
|
+
}) : null
|
|
3459
4058
|
]
|
|
3460
4059
|
});
|
|
3461
4060
|
}
|
|
3462
|
-
function
|
|
3463
|
-
|
|
3464
|
-
return /* @__PURE__ */
|
|
3465
|
-
label:
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
className: "
|
|
3471
|
-
children:
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
})
|
|
3493
|
-
}),
|
|
3494
|
-
isCustom ? /* @__PURE__ */ jsx("div", {
|
|
3495
|
-
className: "flex justify-end",
|
|
3496
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
3497
|
-
type: "button",
|
|
3498
|
-
variant: "outline",
|
|
3499
|
-
size: "sm",
|
|
3500
|
-
onClick: onReset,
|
|
3501
|
-
disabled,
|
|
3502
|
-
children: "Reset to variant"
|
|
4061
|
+
function PaletteLibraryGroup({ label, items, offset, optionRefs, onPreview, onOptionKeyDown, disabled }) {
|
|
4062
|
+
if (items.length === 0) return null;
|
|
4063
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
4064
|
+
"aria-label": label,
|
|
4065
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
4066
|
+
className: "mb-1.5 text-xs font-medium text-muted-foreground",
|
|
4067
|
+
children: label
|
|
4068
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
4069
|
+
className: "grid grid-cols-4 gap-2",
|
|
4070
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs("button", {
|
|
4071
|
+
ref: (element) => {
|
|
4072
|
+
optionRefs.current[offset + index] = element;
|
|
4073
|
+
},
|
|
4074
|
+
type: "button",
|
|
4075
|
+
role: "radio",
|
|
4076
|
+
"aria-label": item.accessibleLabel,
|
|
4077
|
+
"aria-checked": item.selected,
|
|
4078
|
+
disabled,
|
|
4079
|
+
onClick: () => onPreview(item),
|
|
4080
|
+
onKeyDown: (event) => onOptionKeyDown(event, offset + index),
|
|
4081
|
+
className: cn("relative h-10 overflow-hidden rounded-md border p-0.5 outline-none transition focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", item.selected ? "border-foreground ring-1 ring-foreground" : "border-border hover:border-foreground/60"),
|
|
4082
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
4083
|
+
className: "grid h-full grid-cols-5 overflow-hidden rounded-[3px]",
|
|
4084
|
+
"aria-hidden": "true",
|
|
4085
|
+
children: item.swatch.map((color, swatchIndex) => /* @__PURE__ */ jsx("span", { style: { backgroundColor: color } }, `${paletteLibraryItemKey(item)}:${swatchIndex}`))
|
|
4086
|
+
}), item.selected ? /* @__PURE__ */ jsx("span", {
|
|
4087
|
+
className: "absolute right-1 top-1 grid size-4 place-items-center rounded-full bg-foreground text-background",
|
|
4088
|
+
children: /* @__PURE__ */ jsx(Check, {
|
|
4089
|
+
"aria-hidden": "true",
|
|
4090
|
+
className: "size-3"
|
|
3503
4091
|
})
|
|
3504
|
-
}) : null
|
|
3505
|
-
|
|
3506
|
-
})
|
|
4092
|
+
}) : null]
|
|
4093
|
+
}, paletteLibraryItemKey(item)))
|
|
4094
|
+
})]
|
|
4095
|
+
});
|
|
4096
|
+
}
|
|
4097
|
+
function paletteLibraryItemKey(item) {
|
|
4098
|
+
return item.kind === "curated" ? `curated:${item.valueKey}` : `site:${item.paletteId}`;
|
|
4099
|
+
}
|
|
4100
|
+
function selectionForPaletteSnapshot(palette) {
|
|
4101
|
+
switch (palette.kind) {
|
|
4102
|
+
case "curated": return {
|
|
4103
|
+
kind: "curated",
|
|
4104
|
+
valueKey: palette.valueKey
|
|
4105
|
+
};
|
|
4106
|
+
case "curated-fork": return {
|
|
4107
|
+
kind: "curated",
|
|
4108
|
+
valueKey: palette.sourceValueKey
|
|
4109
|
+
};
|
|
4110
|
+
case "site": return {
|
|
4111
|
+
kind: "site",
|
|
4112
|
+
paletteId: palette.paletteId
|
|
4113
|
+
};
|
|
4114
|
+
case "new-site":
|
|
4115
|
+
case "invalid": return null;
|
|
4116
|
+
default: return assertNever$1(palette);
|
|
4117
|
+
}
|
|
4118
|
+
}
|
|
4119
|
+
function PaletteTokenControls({ palette, isCustom, onTokenChange, onReset, disabled }) {
|
|
4120
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
4121
|
+
className: "mt-4 space-y-3 border-t pt-4",
|
|
4122
|
+
children: [/* @__PURE__ */ jsx("fieldset", {
|
|
4123
|
+
disabled,
|
|
4124
|
+
className: "min-w-0 border-0 p-0",
|
|
4125
|
+
children: /* @__PURE__ */ jsx(PaletteTokenEditor, {
|
|
4126
|
+
palette: useMemo(() => paletteColorEntries(palette), [palette]),
|
|
4127
|
+
onChange: onTokenChange,
|
|
4128
|
+
brandRoles: PALETTE_BRAND_ROLES,
|
|
4129
|
+
feedbackRoles: PALETTE_FEEDBACK_ROLES,
|
|
4130
|
+
surfaceRoles: PALETTE_SURFACE_ROLES,
|
|
4131
|
+
showContrastChecks: false,
|
|
4132
|
+
disabled
|
|
4133
|
+
})
|
|
4134
|
+
}), isCustom ? /* @__PURE__ */ jsx("div", {
|
|
4135
|
+
className: "flex justify-end",
|
|
4136
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
4137
|
+
type: "button",
|
|
4138
|
+
variant: "outline",
|
|
4139
|
+
size: "sm",
|
|
4140
|
+
onClick: onReset,
|
|
4141
|
+
disabled,
|
|
4142
|
+
children: "Reset to variant"
|
|
4143
|
+
})
|
|
4144
|
+
}) : null]
|
|
3507
4145
|
});
|
|
3508
4146
|
}
|
|
3509
4147
|
function PickerOption({ selected, label, description, swatch, onSelect, disabled }) {
|
|
@@ -3541,19 +4179,34 @@ function paletteApplyPlanErrorMessage(error) {
|
|
|
3541
4179
|
}
|
|
3542
4180
|
}
|
|
3543
4181
|
function classifyStyleApplyError(error) {
|
|
4182
|
+
if (error instanceof StyleApplyPlanError) return {
|
|
4183
|
+
kind: "other",
|
|
4184
|
+
message: error.message
|
|
4185
|
+
};
|
|
3544
4186
|
if (isRecord(error)) {
|
|
3545
4187
|
const status = error.status;
|
|
3546
|
-
const code = error.code;
|
|
4188
|
+
const code = error.code ?? error.errorCode;
|
|
4189
|
+
if (code === "PALETTE_CAP_REACHED") return {
|
|
4190
|
+
kind: "palette-cap",
|
|
4191
|
+
message: "This site has reached its palette limit. Your palette draft is still here."
|
|
4192
|
+
};
|
|
3547
4193
|
if (status === 409 || code === "resource:conflict") return {
|
|
3548
4194
|
kind: "stale",
|
|
3549
4195
|
message: "This design changed elsewhere. Refreshing the latest version now."
|
|
3550
4196
|
};
|
|
3551
4197
|
}
|
|
4198
|
+
reportPreviewDesignError("Failed to apply site style selection", error);
|
|
3552
4199
|
return {
|
|
3553
4200
|
kind: "other",
|
|
3554
|
-
message:
|
|
4201
|
+
message: PREVIEW_DESIGN_SAVE_ERROR_MESSAGE
|
|
3555
4202
|
};
|
|
3556
4203
|
}
|
|
4204
|
+
var StyleApplyPlanError = class extends Error {
|
|
4205
|
+
constructor(..._args) {
|
|
4206
|
+
super(..._args);
|
|
4207
|
+
this.name = "StyleApplyPlanError";
|
|
4208
|
+
}
|
|
4209
|
+
};
|
|
3557
4210
|
function expandedRowForPreviewDesignRow(row) {
|
|
3558
4211
|
switch (row) {
|
|
3559
4212
|
case "header": return "header-layout";
|
|
@@ -3583,16 +4236,11 @@ function WarningNotice({ warnings, onDismiss }) {
|
|
|
3583
4236
|
});
|
|
3584
4237
|
}
|
|
3585
4238
|
function describeWarning(warning) {
|
|
3586
|
-
|
|
3587
|
-
case "rejected-personality": return `Button style changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
|
|
3588
|
-
case "rejected-palette": return `Palette changed to ${warning.fellBackTo} because ${warning.requested} is not available.`;
|
|
3589
|
-
case "rejected-typography-preset": return `Typography changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
|
|
3590
|
-
default: return warning;
|
|
3591
|
-
}
|
|
4239
|
+
return `Button style changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
|
|
3592
4240
|
}
|
|
3593
4241
|
//#endregion
|
|
3594
4242
|
//#region ../preview-next/src/client/preview/PreviewEditorSidebar.tsx
|
|
3595
|
-
function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, pageId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, theme, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonPersonalityId = null, runtimePaletteState
|
|
4243
|
+
function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, pageId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, theme, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonPersonalityId = null, runtimePaletteState, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, themeSelectionFooterContext, designRowRequest = null, apiClient, bearerToken, supabaseUrl, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, siteStyleAccess = { kind: "hidden" }, activeTab, onTabChange, onClose, onFooterSaved, viewportMode, viewportWidth, zoom, onViewportModeChange, onViewportWidthChange, onZoomChange }) {
|
|
3596
4244
|
const controller = useEntryController();
|
|
3597
4245
|
const controllerBlocks = controller.blocks;
|
|
3598
4246
|
const uiStore = useEditorUiStoreInstance();
|
|
@@ -3603,6 +4251,7 @@ function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, page
|
|
|
3603
4251
|
const focusRequest = useUISelector(uiStore, (s) => s.focusRequest);
|
|
3604
4252
|
const activeLinkedEntrySnapshot = useUISelector(uiStore, (s) => s.linkedEntries.getSelectedSnapshot());
|
|
3605
4253
|
const previewInspection = useUISelector(uiStore, (s) => s.previewInspection);
|
|
4254
|
+
const [designTakeoverActive, setDesignTakeoverActive] = useState(false);
|
|
3606
4255
|
const { canEdit } = usePreviewAuth();
|
|
3607
4256
|
const dashboardSetupHandoff = useMemo(() => resolvePreviewDashboardSetupHandoff(), []);
|
|
3608
4257
|
const dashboardContinueUrl = useMemo(() => buildPreviewDashboardSetupUrl(dashboardBaseUrl, dashboardSetupHandoff), [dashboardBaseUrl, dashboardSetupHandoff]);
|
|
@@ -3719,6 +4368,7 @@ function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, page
|
|
|
3719
4368
|
onBlocksChange: handleBlocksChange,
|
|
3720
4369
|
metadataPanel: metadataSectionContent,
|
|
3721
4370
|
designOpenRequestId: designRowRequest?.id ?? null,
|
|
4371
|
+
designTakeoverActive,
|
|
3722
4372
|
designPanel: canInspectSiteStyle(siteStyleAccess) ? /* @__PURE__ */ jsx(StyleConfigurator, {
|
|
3723
4373
|
siteId,
|
|
3724
4374
|
apiClient,
|
|
@@ -3732,19 +4382,15 @@ function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, page
|
|
|
3732
4382
|
selectionUpdatedAt: themeSelectionUpdatedAt,
|
|
3733
4383
|
buttonPersonalityId: themeSelectionButtonPersonalityId,
|
|
3734
4384
|
runtimePaletteState,
|
|
3735
|
-
paletteVariantId: themeSelectionPaletteVariantId,
|
|
3736
|
-
paletteOverrides: themeSelectionPaletteOverrides,
|
|
3737
4385
|
headerLayoutId: themeSelectionHeaderLayoutId,
|
|
3738
4386
|
headerStyleId: themeSelectionHeaderStyleId,
|
|
3739
|
-
typographyPresetId: themeSelectionTypographyPresetId,
|
|
3740
|
-
typographyBodyFontOverride: themeSelectionTypographyBodyFontOverride,
|
|
3741
|
-
typographyHeadingFontOverride: themeSelectionTypographyHeadingFontOverride,
|
|
3742
4387
|
headerLookId: themeSelectionHeaderLookId,
|
|
3743
4388
|
footerLookId: themeSelectionFooterLookId
|
|
3744
4389
|
},
|
|
3745
4390
|
headerSelectionContext: themeSelectionHeaderContext,
|
|
3746
4391
|
footerSelectionContext: themeSelectionFooterContext,
|
|
3747
4392
|
expandedRowRequest: designRowRequest,
|
|
4393
|
+
onFocusedSurfaceChange: setDesignTakeoverActive,
|
|
3748
4394
|
siteStyleAccess
|
|
3749
4395
|
}) : null,
|
|
3750
4396
|
sdkConfig: sdkConfig ?? null,
|
|
@@ -3767,6 +4413,24 @@ function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, page
|
|
|
3767
4413
|
})
|
|
3768
4414
|
})
|
|
3769
4415
|
});
|
|
4416
|
+
const resolvedEditorPanel = previewInspection.kind === "footer-module" || previewInspection.kind === "footer" ? /* @__PURE__ */ jsx("div", {
|
|
4417
|
+
className: "h-full overflow-y-auto",
|
|
4418
|
+
children: /* @__PURE__ */ jsx(FooterComposerPanel, {
|
|
4419
|
+
apiClient,
|
|
4420
|
+
siteId,
|
|
4421
|
+
customFooterMode: resolvePreviewFooterMode(theme?.footer?.mode),
|
|
4422
|
+
manageLinksHref: `${dashboardBaseUrl?.replace(/\/$/u, "") ?? ""}/dashboard/sites/${siteId}/navigation`,
|
|
4423
|
+
manageSettingsHref: `${dashboardBaseUrl?.replace(/\/$/u, "") ?? ""}/dashboard/sites/${siteId}/settings`,
|
|
4424
|
+
legalRegion: theme?.footer?.bottomBar?.enabled === true ? "separate" : "integrated",
|
|
4425
|
+
initialTarget: previewInspection.kind === "footer-module" ? {
|
|
4426
|
+
kind: "module",
|
|
4427
|
+
moduleId: previewInspection.moduleId
|
|
4428
|
+
} : { kind: "overview" },
|
|
4429
|
+
variant: "sidebar",
|
|
4430
|
+
canEdit,
|
|
4431
|
+
onSaved: onFooterSaved
|
|
4432
|
+
})
|
|
4433
|
+
}) : editorPanel;
|
|
3770
4434
|
const assistantPanelDisplay = assistantAvailable ? assistantPanel : /* @__PURE__ */ jsx("div", {
|
|
3771
4435
|
className: "flex h-full flex-col items-center justify-center p-6 text-center text-sm text-muted-foreground",
|
|
3772
4436
|
children: "AI Assistant is available for pages in preview mode."
|
|
@@ -3813,7 +4477,7 @@ function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, page
|
|
|
3813
4477
|
value: "editor",
|
|
3814
4478
|
forceMount: true,
|
|
3815
4479
|
className: "mt-0 min-h-0 flex-1 overflow-hidden data-[state=inactive]:hidden",
|
|
3816
|
-
children:
|
|
4480
|
+
children: resolvedEditorPanel
|
|
3817
4481
|
}),
|
|
3818
4482
|
showAssistantTab ? /* @__PURE__ */ jsx(TabsContent, {
|
|
3819
4483
|
value: "assistant",
|
|
@@ -3825,6 +4489,9 @@ function PreviewEditorSidebar({ surfaceId, siteId, dashboardBaseUrl = null, page
|
|
|
3825
4489
|
})
|
|
3826
4490
|
});
|
|
3827
4491
|
}
|
|
4492
|
+
function resolvePreviewFooterMode(value) {
|
|
4493
|
+
return value === "blocks" || value === "default+blocks" || value === "none" ? value : "default";
|
|
4494
|
+
}
|
|
3828
4495
|
function PreviewMetadataPanel({ ownerKind, contentTypeKey, entry }) {
|
|
3829
4496
|
const uiStore = useEditorUiStoreInstance();
|
|
3830
4497
|
const currentSlug = useEditorUiStore((state) => state.metadata.getAtPath("draftSlug")) ?? void 0;
|