@riverbankcms/sdk 0.79.0 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PreviewEditorSidebar-QZG37QIF.mjs +2655 -0
- package/dist/{PreviewEditorUI-27KJVEET.mjs → PreviewEditorUI-AXIKSMZA.mjs} +27 -4
- package/dist/SdkPreviewModeRuntime-XE5M4UKM.mjs +8 -0
- package/dist/_dts/ai/src/contracts/proposals.d.ts +20 -0
- package/dist/_dts/api/src/endpoints.d.ts +24 -0
- package/dist/_dts/api/src/index.d.ts +1 -1
- package/dist/_dts/api/src/siteInfrastructure.d.ts +124 -0
- package/dist/_dts/api/src/siteOnboarding.d.ts +13 -0
- package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +10 -1
- package/dist/_dts/block-form/src/client/index.d.ts +2 -0
- package/dist/_dts/block-form/src/index.d.ts +2 -0
- package/dist/_dts/block-form/src/utils/evaluateVisibility.d.ts +2 -1
- package/dist/_dts/blocks/src/client/header.d.ts +1 -1
- package/dist/_dts/blocks/src/client.d.ts +12 -12
- package/dist/_dts/blocks/src/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/blocks/events/event-listing.d.ts +2 -2
- package/dist/_dts/blocks/src/system/blocks/events/event-spotlight.d.ts +2 -1
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -1
- package/dist/_dts/blocks/src/system/blocks/testimonials.d.ts +7 -1
- package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +21 -12
- package/dist/_dts/blocks/src/system/fields/boxStyles.d.ts +4 -2
- package/dist/_dts/blocks/src/system/fragments/library/faqHeading.d.ts +1 -0
- package/dist/_dts/blocks/src/system/fragments/library/testimonialsCarousel.d.ts +5 -0
- package/dist/_dts/blocks/src/system/node/fragments/headingDecoration.d.ts +1 -4
- package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +7 -7
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +3 -3
- package/dist/_dts/blocks/src/system/runtime/header/enhanceHeaderSection.d.ts +10 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +5 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.server.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventSpotlight.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventDetailModal.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventModals.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/header-section.client.d.ts +2 -2
- package/dist/_dts/blocks/src/system/transforms/registry/boxStyles.d.ts +3 -0
- package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +9 -0
- package/dist/_dts/blocks/src/system/transforms/typed.d.ts +14 -1
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +9 -3
- package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +2 -6
- package/dist/_dts/editor-blocks/src/block-editor/BlockCardBody.d.ts +2 -6
- package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +2 -6
- package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +2 -6
- package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +6 -4
- package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +2 -6
- package/dist/_dts/editor-blocks/src/index.d.ts +2 -0
- package/dist/_dts/preview-next/src/client/blocks/BlockToolbar.d.ts +5 -1
- package/dist/_dts/preview-next/src/client/blocks/previewCustomizeControlPlan.d.ts +24 -0
- package/dist/_dts/preview-next/src/client/blocks/useBlockCustomizeControls.d.ts +34 -0
- package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -5
- package/dist/_dts/preview-next/src/client/preview/PageDesignEditorStateContext.d.ts +4 -1
- package/dist/_dts/preview-next/src/client/preview/PreviewBlockCustomizeSelectionContext.d.ts +20 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewOpenEditorButton.d.ts +2 -0
- package/dist/_dts/preview-next/src/client/preview/SelectedBlockCustomizePanel.d.ts +13 -0
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeEditorDraftPatch.d.ts +13 -0
- package/dist/_dts/preview-next/src/client/preview/previewCustomizeRuntimePatch.d.ts +2 -0
- package/dist/_dts/preview-next/src/client/preview/storeTypes.d.ts +4 -0
- package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +3 -1
- package/dist/_dts/sdk/src/cli/commands/webhooks.d.ts +44 -0
- package/dist/_dts/sdk/src/client/management/index.d.ts +1 -1
- package/dist/_dts/sdk/src/client/management/types.d.ts +56 -0
- package/dist/_dts/sdk/src/client/management/webhooks.d.ts +3 -0
- package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +6 -3
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/accordions/siteStyleDefaults.d.ts +220 -0
- package/dist/_dts/theme-core/src/accordions/types.d.ts +45 -2
- package/dist/_dts/theme-core/src/blockOverrides.d.ts +8 -0
- package/dist/_dts/theme-core/src/blocks/types.d.ts +1 -1
- package/dist/_dts/theme-core/src/blocks/vars/testimonials.d.ts +4 -1
- package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +1 -1
- package/dist/_dts/theme-core/src/cards/core.d.ts +20 -0
- package/dist/_dts/theme-core/src/cards/generateDefaultCardSystem.d.ts +6 -3
- package/dist/_dts/theme-core/src/cards/siteStyleDefaults.d.ts +105 -0
- package/dist/_dts/theme-core/src/cards/types.d.ts +177 -0
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/_dts/theme-core/src/mock-themes/all.d.ts +156 -18
- package/dist/_dts/theme-core/src/palette/variants/index.d.ts +15 -0
- package/dist/_dts/theme-core/src/palette/variants/soft-natural.d.ts +16 -0
- package/dist/_dts/theme-core/src/palette/variants/types.d.ts +1 -1
- package/dist/_dts/theme-core/src/schema.d.ts +446 -52
- package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +86 -17
- package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +2 -3
- package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +86 -17
- package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +110 -1
- package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +20 -1
- package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -0
- package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +286 -6
- package/dist/_dts/theme-core/src/site-styles/index.d.ts +2 -0
- package/dist/_dts/theme-core/src/site-styles/logoBranding.d.ts +193 -0
- package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +2 -8
- package/dist/_dts/theme-core/src/site-styles/rawStyleFields.d.ts +2 -0
- package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +10 -7
- package/dist/_dts/theme-core/src/site-styles/siteStyleThemeCompiler.d.ts +11 -0
- package/dist/_dts/theme-core/src/site-styles/sourceCatalogs.d.ts +2 -2
- package/dist/_dts/theme-core/src/site-styles/styleTags.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/testimonialQuotePresets.d.ts +15 -0
- package/dist/_dts/theme-core/src/site-styles/tokenRecipes.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/types.d.ts +7 -29
- package/dist/{PreviewEditorSidebar-56NMJMIK.mjs → chunk-5NZGBSJF.mjs} +1423 -2451
- package/dist/{chunk-4HCW7FHJ.mjs → chunk-7PCYG6YV.mjs} +215 -137
- package/dist/{chunk-K2IIF34C.mjs → chunk-BBLZSQEY.mjs} +24 -0
- package/dist/{chunk-V47ZU33I.mjs → chunk-GYXKAUFV.mjs} +2785 -785
- package/dist/{chunk-GP555I66.mjs → chunk-HTB4BMKD.mjs} +94 -46
- package/dist/{chunk-A3HHFKVT.mjs → chunk-MPBNEVPB.mjs} +1 -1
- package/dist/cli/index.mjs +2100 -545
- package/dist/cli/init-docs/content/workflow-isr-revalidation.md +16 -4
- package/dist/client/{accordion-QLA7KBYO.mjs → accordion-QFZMNB7O.mjs} +1 -1
- package/dist/client/{bookingForm-PYZIPA5G.mjs → bookingForm-NCIXFWIG.mjs} +3 -3
- package/dist/client/bookings.mjs +1144 -329
- package/dist/client/{carousel-5EIULWBI.mjs → carousel-EO4BJMWD.mjs} +2 -2
- package/dist/client/{cart-DOP3FNI4.mjs → cart-FTYCLYUW.mjs} +5 -5
- package/dist/client/{checkout-BVMF6FBV.mjs → checkout-NFGLVCOX.mjs} +5 -5
- package/dist/client/{chunk-TYONZMST.mjs → chunk-4W66ALYT.mjs} +1 -1
- package/dist/client/{chunk-44K2U3QI.mjs → chunk-6GVVWSPU.mjs} +4 -4
- package/dist/client/{chunk-UDS3NTWA.mjs → chunk-IWFZSQNZ.mjs} +1 -1
- package/dist/client/{chunk-R5ESWNKX.mjs → chunk-PUOELU4O.mjs} +89 -5
- package/dist/client/{chunk-YLDYVRZL.mjs → chunk-PYRBIURC.mjs} +4 -4
- package/dist/client/{chunk-GG4M2NP6.mjs → chunk-T6UIP6UZ.mjs} +1 -1
- package/dist/client/{chunk-V6M5FCR5.mjs → chunk-VDS5YFLX.mjs} +1 -1
- package/dist/client/{chunk-CCNTDRCF.mjs → chunk-Y37KDO7P.mjs} +1 -1
- package/dist/client/client.mjs +4205 -2324
- package/dist/client/{courseRegistration-E6EAA6NL.mjs → courseRegistration-2EORROPS.mjs} +3 -3
- package/dist/client/{eventCalendar-HBG3HAK6.mjs → eventCalendar-WZI4VL6N.mjs} +5 -5
- package/dist/client/{eventCombined-6K5ZZWAK.mjs → eventCombined-QCB2TCNL.mjs} +5 -5
- package/dist/client/{eventDetails-Q75ICXLT.mjs → eventDetails-TFTATAPH.mjs} +5 -5
- package/dist/client/{eventListing-27P5F7DZ.mjs → eventListing-A2CQEHEQ.mjs} +5 -5
- package/dist/client/{eventRegistration-IQ7AMASR.mjs → eventRegistration-OELPVLUY.mjs} +5 -5
- package/dist/client/{form-JRTD65FN.mjs → form-NTIFD6WQ.mjs} +1 -1
- package/dist/client/{headerSection-7FPSSZHS.mjs → headerSection-7TBNKCLA.mjs} +65 -24
- package/dist/client/hooks.mjs +3354 -2006
- package/dist/client/{locationMap-7NGFNYBH.mjs → locationMap-LRLB5A3H.mjs} +1 -1
- package/dist/client/{newsletterForm-F3BADCI2.mjs → newsletterForm-XI52RZSN.mjs} +1 -1
- package/dist/client/{productDetail-V3HP7ITJ.mjs → productDetail-GSNKBFLY.mjs} +5 -5
- package/dist/client/{productList-L3EGJUF2.mjs → productList-BGCGT4KZ.mjs} +5 -5
- package/dist/client/rendering/client.mjs +2570 -1657
- package/dist/client/rendering/islands.mjs +18 -18
- package/dist/client/rendering.mjs +4275 -2394
- package/dist/client/{shop-DQUB5E2C.mjs → shop-RQHUCLNY.mjs} +5 -5
- package/dist/preview-next/before-render.mjs +24 -0
- package/dist/preview-next/client/runtime.mjs +5 -5
- package/dist/preview-next/middleware.mjs +24 -0
- package/dist/{sdk-runtime-AF6KXJU4.mjs → sdk-runtime-A4LHT2RS.mjs} +6 -6
- package/dist/server/components.mjs +4063 -2293
- package/dist/server/config-validation.mjs +3525 -2176
- package/dist/server/config.mjs +3525 -2176
- package/dist/server/data.mjs +3354 -2006
- package/dist/server/index.mjs +25 -1
- package/dist/server/next.mjs +4006 -2236
- package/dist/server/page-converter.mjs +2747 -1816
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +4063 -2293
- package/dist/server/rendering.mjs +4063 -2293
- package/dist/server/routing.mjs +3508 -2111
- package/dist/server/server.mjs +3372 -2024
- package/dist/server/theme-bridge.mjs +1436 -310
- package/dist/server/theme.mjs +409 -219
- package/dist/styles/index.css +300 -33
- package/package.json +1 -1
- package/dist/SdkPreviewModeRuntime-H4BSP6E7.mjs +0 -8
- package/dist/chunk-LCY32PXF.mjs +0 -1175
|
@@ -1,11 +1,241 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { usePreviewAuth, getDashboardUrl } from './chunk-K2IIF34C.mjs';
|
|
5
|
-
import './chunk-R7POPVJR.mjs';
|
|
6
|
-
import React, { createContext, memo, useMemo, useState, useRef, useEffect, forwardRef, useCallback, useImperativeHandle, useContext, useSyncExternalStore, useLayoutEffect, useReducer, useTransition, useId } from 'react';
|
|
2
|
+
import { KeyboardCode, getBlockDefinition, CSS, useSdkConfig, unwrapResponse, parseSiteIconStyleGuideVersionId, parseBlockIconValue, listBlockDescriptors, useSensor, PointerSensor, useSensors, deleteBlock, createEditorRemoveBlockCommand, unsafeAsEditorBlockId, DndContext, closestCenter, Button, Plus, useDroppable, useDraggable, useCombinedRefs, isKeyboardEvent, createCustomBlockRegistry, Card, cn, Collapsible, CollapsibleContent, listContentTypes, mergeBlockDescriptorsWithRegistry, createBlock, createEditorReorderBlocksCommand, reorderBlocks, mutateBlockContent, useDndContext, useUniqueId, useIsomorphicLayoutEffect, EmptyState, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Search, getClientRect, resolveBlockTitle, CardHeader, GripVertical, ChevronRight, CardTitle, ArrowUp, ArrowDown, DropdownMenu, DropdownMenuTrigger, EllipsisVertical, DropdownMenuContent, DropdownMenuItem, Settings, DropdownMenuSeparator, Sparkles, RotateCcw, ImagePlus, Copy, Trash2, DialogFooter, DialogClose, CardContent, createEditorInsertBlockCommand, LoaderCircle, ChevronDown, getFeatureCardIconCompletion, toFeatureCardIconSuggestionInputs, getBlockIconSemanticFallbackId, suggestSemanticIconForFeatureCard, getGeneratedBlockIconStyleState, assertNever, suggestFeatureCardSemanticIcons, applyFeatureCardIconSuggestions, createFeatureCardIconKey, Textarea, Callout, CalloutDescription, normalEditorCuratedPromotedFieldPaths, resolveVisiblePromotedFieldPathsForEditorBlock, createStoreBackend, validateBlockManifestIssues, CalloutTitle, unfinishedBlockCopy, recoveryConflictCopy, ManifestForm, unsafeAsEditorBlockValues, Box, createManifestFormAdapter, getModalConfig, isNonEmptyValue, ScrollableDialogContent, FormRenderer, Tabs, TabsList, TabsTrigger, TabsContent, mergeManifestWithSdkOptions, augmentManifestWithStyleGroups, lucide_react_exports, isThemeV2NormalEditorRawStylePath, getFieldIntent, isHeaderField, isThemeV2NormalEditorRawStyleFieldName, useField, useMediaEditorOptional, useRichTextEditor, FieldFrame, RichTextEditorSurface, ThemeScope, isObjectRecord, EMPTY_DOC, useMediaEditor, MediaPickerMini, MediaPickerDialog, useAsyncPickerOptions, resolvePickerSelectionLabel, shouldShowPickerSearch, normalizePickerSearchThreshold, Combobox, Badge, useBlockContext, resolveMediaSlotContract, asRecord, parseAspectRatioValue, MediaEditor, PUBLIC_FILE_FIELD_KINDS, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, useBackendWatch, resolveIconPickerPreset, isIconPickerPreset, getIconPickerOptionsForPreset, isKnownIconName, getIconComponent, assertNever2, deriveNearestCompatibleHeaderStyle, findLegacyHeaderLookIdForSelection, compileSiteThemeFromSelections, footerLookCatalog, getOrderedHeaderStyleIdsForLayout, getOrderedHeaderLayoutIdsForCuration, footerLookRejectionReasonLabel, getHeaderStyle, getHeaderLayout, writePlanForLookCustomizationCommand, siteStyleIdFromTheme, getCuratedSiteStyle, getRichTextImagePositionFromTarget, insertOrReplaceRichTextImage, emitMediaCropDebug, Pencil, resolveVideoSelectionIntentForMediaField, evaluateVisibility, Root2, List, Trigger, Content, Input, Check, Label, isInternalResolvedLinkValue, resolveImageUrlWithContext, getDirectImageUrlForMediaAsset, isSvgMimeType, toRoutableLinkPayload, classifyKnownMimeType } from './chunk-GYXKAUFV.mjs';
|
|
3
|
+
import React2, { createContext, memo, useMemo, useState, useRef, useEffect, forwardRef, useCallback, useImperativeHandle, useContext, useSyncExternalStore, useLayoutEffect, useReducer } from 'react';
|
|
7
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
-
|
|
5
|
+
|
|
6
|
+
// ../preview-next/src/client/preview/previewChromeSurfacePolicy.ts
|
|
7
|
+
var PREVIEW_CHROME_SURFACE_POLICIES = {
|
|
8
|
+
core: {
|
|
9
|
+
banner: {
|
|
10
|
+
tone: "default",
|
|
11
|
+
bannerClassName: "border border-emerald-200/70 bg-white/95 shadow-xl backdrop-blur supports-[backdrop-filter]:bg-white/92",
|
|
12
|
+
summaryClassName: "rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-600",
|
|
13
|
+
dialogItemClassName: "rounded-md border border-slate-200 bg-slate-50 px-3 py-2",
|
|
14
|
+
titleClassName: "text-sm font-semibold tracking-tight text-foreground [font-family:var(--font-heading)]",
|
|
15
|
+
descriptionClassName: "text-sm text-muted-foreground [font-family:var(--font-body)]",
|
|
16
|
+
detailClassName: "text-xs text-muted-foreground [font-family:var(--font-body)]",
|
|
17
|
+
summaryTitleClassName: "font-medium text-foreground [font-family:var(--font-body)]",
|
|
18
|
+
summaryBodyClassName: "mt-1 text-muted-foreground [font-family:var(--font-body)]",
|
|
19
|
+
secondaryButtonClassName: "",
|
|
20
|
+
primaryButtonClassName: "",
|
|
21
|
+
dialogBodyClassName: "space-y-3 text-sm text-muted-foreground [font-family:var(--font-body)]",
|
|
22
|
+
dialogItemTitleClassName: "font-medium text-foreground [font-family:var(--font-heading)]",
|
|
23
|
+
dialogItemMetaClassName: "ml-2 text-xs font-normal uppercase tracking-wide text-muted-foreground [font-family:var(--font-body)]",
|
|
24
|
+
dialogItemDescriptionClassName: "mt-1 text-sm text-muted-foreground [font-family:var(--font-body)]",
|
|
25
|
+
ctaLabel: "Complete setup in dashboard",
|
|
26
|
+
copyByState: {
|
|
27
|
+
awaiting_confirmation: {
|
|
28
|
+
title: "Your draft preview is ready",
|
|
29
|
+
description: "Explore your site here, then confirm your email to unlock the dashboard and finish launch setup.",
|
|
30
|
+
detail: "Once your email is confirmed, Complete setup in dashboard will take you straight to the remaining checklist.",
|
|
31
|
+
checklistNote: "Email confirmation is the only blocker before dashboard access. The rest of the launch checklist lives in the dashboard."
|
|
32
|
+
},
|
|
33
|
+
dashboard_ready: {
|
|
34
|
+
title: "Your dashboard is unlocked",
|
|
35
|
+
description: "Keep exploring here, then use Complete setup in dashboard to review your pages, add offerings, connect payments, and finish launch setup.",
|
|
36
|
+
detail: "The dashboard is the place to complete the remaining checklist and get your site ready to launch.",
|
|
37
|
+
checklistNote: "The remaining launch steps are tracked in the same checklist you will see in the dashboard."
|
|
38
|
+
},
|
|
39
|
+
dashboard_resume: {
|
|
40
|
+
title: "Your draft site is ready",
|
|
41
|
+
description: "Keep exploring here, then use Complete setup in dashboard to review your pages, add offerings, connect payments, and finish launch setup.",
|
|
42
|
+
detail: "The dashboard is the normal place to finish setup for this site.",
|
|
43
|
+
checklistNote: "The remaining launch steps are tracked in the same checklist you will see in the dashboard."
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
dialog: {
|
|
47
|
+
title: "What still happens in the dashboard",
|
|
48
|
+
description: "Your preview is ready, but launch steps still happen in the dashboard so you can finish setup safely.",
|
|
49
|
+
pendingIntro: "Your preview is live now, but the launch checklist stays in the dashboard so the final setup steps happen in the right place.",
|
|
50
|
+
unlockedIntro: "Your preview is live now, and the same checklist will follow you into the dashboard when you are ready to finish setup.",
|
|
51
|
+
outro: "You can keep exploring this preview now, then jump back into the dashboard when you're ready to finish setup."
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
sidebar: {
|
|
55
|
+
tone: "default",
|
|
56
|
+
rootClassName: "bg-background",
|
|
57
|
+
headerClassName: "border-b",
|
|
58
|
+
guidance: {
|
|
59
|
+
title: "Make quick edits in preview",
|
|
60
|
+
description: "Use preview for copy and layout tweaks. Complete setup in dashboard to add offerings, connect payments, and finish the rest of your launch checklist.",
|
|
61
|
+
ctaLabel: "Complete setup in dashboard",
|
|
62
|
+
cardClassName: "rounded-lg border border-emerald-200/70 bg-emerald-50/70 px-3 py-3"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
macadamia: {
|
|
67
|
+
banner: {
|
|
68
|
+
tone: "studio",
|
|
69
|
+
bannerClassName: "border border-border bg-background shadow-xl",
|
|
70
|
+
summaryClassName: "rounded-xl border border-border bg-surface px-3 py-2 text-xs text-foreground",
|
|
71
|
+
dialogItemClassName: "rounded-xl border border-border bg-surface px-3 py-2",
|
|
72
|
+
titleClassName: "text-sm font-semibold tracking-tight text-foreground [font-family:var(--font-heading)]",
|
|
73
|
+
descriptionClassName: "text-sm text-muted-foreground [font-family:var(--font-body)]",
|
|
74
|
+
detailClassName: "text-xs text-muted-foreground [font-family:var(--font-body)]",
|
|
75
|
+
summaryTitleClassName: "font-medium text-foreground [font-family:var(--font-body)]",
|
|
76
|
+
summaryBodyClassName: "mt-1 text-muted-foreground [font-family:var(--font-body)]",
|
|
77
|
+
secondaryButtonClassName: "border border-border bg-surface text-foreground hover:bg-button-outline-hover",
|
|
78
|
+
primaryButtonClassName: "border border-primary bg-primary text-primary-foreground hover:bg-primary-hover",
|
|
79
|
+
dialogBodyClassName: "space-y-3 text-sm text-muted-foreground [font-family:var(--font-body)]",
|
|
80
|
+
dialogItemTitleClassName: "font-medium text-foreground [font-family:var(--font-heading)]",
|
|
81
|
+
dialogItemMetaClassName: "ml-2 text-xs font-normal uppercase tracking-wide text-muted-foreground [font-family:var(--font-body)]",
|
|
82
|
+
dialogItemDescriptionClassName: "mt-1 text-sm text-muted-foreground [font-family:var(--font-body)]",
|
|
83
|
+
ctaLabel: "Complete setup in Macadamia",
|
|
84
|
+
copyByState: {
|
|
85
|
+
awaiting_confirmation: {
|
|
86
|
+
title: "Confirm your email to carry on",
|
|
87
|
+
description: "We've created the bones of your site. To carry on finishing setup, and to edit your site, you need to confirm your email to activate your account.",
|
|
88
|
+
detail: "",
|
|
89
|
+
checklistNote: ""
|
|
90
|
+
},
|
|
91
|
+
dashboard_ready: {
|
|
92
|
+
title: "Here's your site preview",
|
|
93
|
+
description: "We've created the bones of your site. Have a look around. If you like, you can add your site content here, or you can go straight to your dashboard to complete your setup. You'll be able to edit your site at any time, so don't worry if it's not perfect right now.",
|
|
94
|
+
detail: "",
|
|
95
|
+
checklistNote: ""
|
|
96
|
+
},
|
|
97
|
+
dashboard_resume: {
|
|
98
|
+
title: "Your studio site is ready",
|
|
99
|
+
description: "Keep exploring here, then use Complete setup in Macadamia to review your pages, add offerings, connect payments, and finish launch setup.",
|
|
100
|
+
detail: "Macadamia is the normal place to finish setup for this studio site.",
|
|
101
|
+
checklistNote: "The remaining launch steps are tracked in the same checklist you will see in Macadamia."
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
dialog: {
|
|
105
|
+
title: "What still happens in Macadamia",
|
|
106
|
+
description: "Your preview is ready, but launch steps still happen in Macadamia so you can finish setup safely.",
|
|
107
|
+
pendingIntro: "Your studio preview is live now, but the launch checklist stays in Macadamia so the final setup steps happen in the right place.",
|
|
108
|
+
unlockedIntro: "Your studio preview is live now, and the same checklist will follow you into Macadamia when you are ready to finish setup.",
|
|
109
|
+
outro: "You can keep exploring this preview now, then jump back into Macadamia when you're ready to finish setup."
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
sidebar: {
|
|
113
|
+
tone: "studio",
|
|
114
|
+
rootClassName: "bg-stone-50/80",
|
|
115
|
+
headerClassName: "border-b border-amber-200/70 bg-amber-50/70",
|
|
116
|
+
guidance: {
|
|
117
|
+
title: "Polish your studio preview",
|
|
118
|
+
description: "Use preview for copy and layout tweaks. Complete setup in Macadamia to add offerings, connect payments, and finish the rest of your launch checklist.",
|
|
119
|
+
ctaLabel: "Complete setup in Macadamia",
|
|
120
|
+
cardClassName: "rounded-2xl border border-amber-200/80 bg-gradient-to-br from-amber-50 via-white to-orange-50 px-4 py-4 shadow-sm"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
function getPreviewChromeSurfacePolicy(surfaceId) {
|
|
126
|
+
return PREVIEW_CHROME_SURFACE_POLICIES[surfaceId];
|
|
127
|
+
}
|
|
128
|
+
function resolvePreviewSetupBannerModel(input) {
|
|
129
|
+
if (!input.bannerState) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const policy = getPreviewChromeSurfacePolicy(input.surfaceId).banner;
|
|
133
|
+
return {
|
|
134
|
+
tone: policy.tone,
|
|
135
|
+
bannerClassName: policy.bannerClassName,
|
|
136
|
+
summaryClassName: policy.summaryClassName,
|
|
137
|
+
dialogItemClassName: policy.dialogItemClassName,
|
|
138
|
+
titleClassName: policy.titleClassName,
|
|
139
|
+
descriptionClassName: policy.descriptionClassName,
|
|
140
|
+
detailClassName: policy.detailClassName,
|
|
141
|
+
summaryTitleClassName: policy.summaryTitleClassName,
|
|
142
|
+
summaryBodyClassName: policy.summaryBodyClassName,
|
|
143
|
+
secondaryButtonClassName: policy.secondaryButtonClassName,
|
|
144
|
+
primaryButtonClassName: policy.primaryButtonClassName,
|
|
145
|
+
dialogBodyClassName: policy.dialogBodyClassName,
|
|
146
|
+
dialogItemTitleClassName: policy.dialogItemTitleClassName,
|
|
147
|
+
dialogItemMetaClassName: policy.dialogItemMetaClassName,
|
|
148
|
+
dialogItemDescriptionClassName: policy.dialogItemDescriptionClassName,
|
|
149
|
+
ctaLabel: policy.ctaLabel,
|
|
150
|
+
copy: policy.copyByState[input.bannerState],
|
|
151
|
+
dialogTitle: policy.dialog.title,
|
|
152
|
+
dialogDescription: policy.dialog.description,
|
|
153
|
+
dialogIntro: input.dashboardUnlocked ? policy.dialog.unlockedIntro : policy.dialog.pendingIntro,
|
|
154
|
+
dialogOutro: policy.dialog.outro
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function resolvePreviewSidebarChromeModel(surfaceId) {
|
|
158
|
+
const policy = getPreviewChromeSurfacePolicy(surfaceId).sidebar;
|
|
159
|
+
return {
|
|
160
|
+
tone: policy.tone,
|
|
161
|
+
rootClassName: policy.rootClassName,
|
|
162
|
+
headerClassName: policy.headerClassName
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function resolvePreviewEditorGuidanceModel(input) {
|
|
166
|
+
if (!input.canEdit || !input.hasDashboardSetupHandoff) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const policy = getPreviewChromeSurfacePolicy(input.surfaceId).sidebar;
|
|
170
|
+
return {
|
|
171
|
+
tone: policy.tone,
|
|
172
|
+
title: policy.guidance.title,
|
|
173
|
+
description: policy.guidance.description,
|
|
174
|
+
ctaLabel: policy.guidance.ctaLabel,
|
|
175
|
+
cardClassName: policy.guidance.cardClassName
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ../preview-next/src/client/preview/sanitizeDashboardPath.ts
|
|
180
|
+
function sanitizeDashboardPath(value) {
|
|
181
|
+
if (!value) return null;
|
|
182
|
+
const trimmed = value.trim();
|
|
183
|
+
if (!trimmed || /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
const normalized = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
187
|
+
try {
|
|
188
|
+
const parsed = new URL(normalized, "https://preview.local");
|
|
189
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
190
|
+
} catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ../preview-next/src/client/preview/previewDashboardHandoff.ts
|
|
196
|
+
function resolvePreviewDashboardSetupHandoffFromSearch(search) {
|
|
197
|
+
const params = new URLSearchParams(search);
|
|
198
|
+
if (params.get("preview_handoff") !== "dashboard_setup") {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
const dashboardPath = sanitizeDashboardPath(params.get("preview_dashboard"));
|
|
202
|
+
if (!dashboardPath) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
kind: "dashboard_setup",
|
|
207
|
+
dashboardPath
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function resolvePreviewDashboardSetupHandoff() {
|
|
211
|
+
if (typeof window === "undefined") {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
return resolvePreviewDashboardSetupHandoffFromSearch(window.location.search);
|
|
215
|
+
}
|
|
216
|
+
function buildPreviewDashboardSetupUrl(dashboardBaseUrl, handoff) {
|
|
217
|
+
if (!dashboardBaseUrl || !handoff) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
return new URL(handoff.dashboardPath, dashboardBaseUrl).toString();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// ../preview-next/src/client/preview/siteStyleAccess.ts
|
|
224
|
+
function resolveSiteStyleAccess(session) {
|
|
225
|
+
if (session?.kind === "userSession" && session.canManage) {
|
|
226
|
+
return { kind: "apply-allowed" };
|
|
227
|
+
}
|
|
228
|
+
if (session?.kind === "userSession" && session.canEdit) {
|
|
229
|
+
return { kind: "preview-only" };
|
|
230
|
+
}
|
|
231
|
+
return { kind: "hidden" };
|
|
232
|
+
}
|
|
233
|
+
function canInspectSiteStyle(access) {
|
|
234
|
+
return access.kind !== "hidden";
|
|
235
|
+
}
|
|
236
|
+
function canApplySiteStyle(access) {
|
|
237
|
+
return access.kind === "apply-allowed";
|
|
238
|
+
}
|
|
9
239
|
|
|
10
240
|
// ../content-model/src/referenceFields.ts
|
|
11
241
|
var BUILT_IN_REFERENCE_KINDS = [
|
|
@@ -47,7 +277,7 @@ function parseReferenceKind(referenceKind) {
|
|
|
47
277
|
}
|
|
48
278
|
|
|
49
279
|
// ../content-model/src/contentManifest.ts
|
|
50
|
-
function
|
|
280
|
+
function assertNever3(value) {
|
|
51
281
|
throw new Error(`Unhandled content field mapping decision: ${JSON.stringify(value)}`);
|
|
52
282
|
}
|
|
53
283
|
function resolveContentReferenceKind(field) {
|
|
@@ -178,7 +408,7 @@ function toFieldDefinition(field, context = {}) {
|
|
|
178
408
|
valueFrom: mapping.valueFrom
|
|
179
409
|
};
|
|
180
410
|
default:
|
|
181
|
-
return
|
|
411
|
+
return assertNever3(mapping);
|
|
182
412
|
}
|
|
183
413
|
}
|
|
184
414
|
case "link":
|
|
@@ -317,65 +547,35 @@ function normalizeFieldUi(value) {
|
|
|
317
547
|
}
|
|
318
548
|
return value;
|
|
319
549
|
}
|
|
320
|
-
var
|
|
321
|
-
function
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
var DEFAULT_VARIANTS = [
|
|
345
|
-
{ id: "primary", name: "Primary", priority: 1 },
|
|
346
|
-
{ id: "secondary", name: "Secondary", priority: 2 },
|
|
347
|
-
{ id: "outline", name: "Outline", priority: 3 }
|
|
348
|
-
];
|
|
349
|
-
function ButtonVariantField({ path, backend, config }) {
|
|
350
|
-
const { value, error, setValue } = useField(path, backend);
|
|
351
|
-
const buttonContext = useButtonWidgetContext();
|
|
352
|
-
const variants = buttonContext.variants.length > 0 ? buttonContext.variants : DEFAULT_VARIANTS;
|
|
353
|
-
const options = variants.map((v) => ({ value: v.id, label: v.name }));
|
|
354
|
-
const isUnknownVariant = value && !options.some((opt) => opt.value === value);
|
|
355
|
-
if (isUnknownVariant && true) {
|
|
356
|
-
console.warn(
|
|
357
|
-
`[ButtonVariantField] Unknown button variant "${value}" at path "${path}". Available variants: ${options.map((o) => o.value).join(", ")}. The button may not render with expected styling.`
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
return /* @__PURE__ */ jsx(
|
|
361
|
-
FieldFrame,
|
|
362
|
-
{
|
|
363
|
-
label: config.label,
|
|
364
|
-
description: config.description,
|
|
365
|
-
error: error?.message,
|
|
366
|
-
children: () => /* @__PURE__ */ jsxs(
|
|
367
|
-
Select,
|
|
368
|
-
{
|
|
369
|
-
value: typeof value === "string" && value !== "" ? value : void 0,
|
|
370
|
-
onValueChange: setValue,
|
|
371
|
-
children: [
|
|
372
|
-
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: `Select ${config.label.toLowerCase()}` }) }),
|
|
373
|
-
/* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
374
|
-
]
|
|
375
|
-
}
|
|
376
|
-
)
|
|
377
|
-
}
|
|
550
|
+
var PreviewBlockCustomizeSelectionContext = createContext(null);
|
|
551
|
+
function PreviewBlockCustomizeSelectionProvider({
|
|
552
|
+
children
|
|
553
|
+
}) {
|
|
554
|
+
const [selection, setSelection] = useState({
|
|
555
|
+
kind: "none"
|
|
556
|
+
});
|
|
557
|
+
const inspectBlock = useCallback((blockId) => {
|
|
558
|
+
setSelection((current) => ({
|
|
559
|
+
kind: "selected",
|
|
560
|
+
blockId,
|
|
561
|
+
requestId: current.kind === "selected" ? current.requestId + 1 : 1
|
|
562
|
+
}));
|
|
563
|
+
}, []);
|
|
564
|
+
const clearInspection = useCallback(() => {
|
|
565
|
+
setSelection({ kind: "none" });
|
|
566
|
+
}, []);
|
|
567
|
+
const value = useMemo(
|
|
568
|
+
() => ({
|
|
569
|
+
selection,
|
|
570
|
+
inspectBlock,
|
|
571
|
+
clearInspection
|
|
572
|
+
}),
|
|
573
|
+
[clearInspection, inspectBlock, selection]
|
|
378
574
|
);
|
|
575
|
+
return /* @__PURE__ */ jsx(PreviewBlockCustomizeSelectionContext.Provider, { value, children });
|
|
576
|
+
}
|
|
577
|
+
function usePreviewBlockCustomizeSelectionOptional() {
|
|
578
|
+
return useContext(PreviewBlockCustomizeSelectionContext);
|
|
379
579
|
}
|
|
380
580
|
function useStoreSelector(store, selector, isEqual = Object.is) {
|
|
381
581
|
const cacheRef = useRef(null);
|
|
@@ -513,7 +713,7 @@ function getItemGap$1(clientRects, index, activeIndex) {
|
|
|
513
713
|
return nextRect ? nextRect.top - (currentRect.top + currentRect.height) : previousRect ? currentRect.top - (previousRect.top + previousRect.height) : 0;
|
|
514
714
|
}
|
|
515
715
|
var ID_PREFIX = "Sortable";
|
|
516
|
-
var Context = /* @__PURE__ */
|
|
716
|
+
var Context = /* @__PURE__ */ React2.createContext({
|
|
517
717
|
activeIndex: -1,
|
|
518
718
|
containerId: ID_PREFIX,
|
|
519
719
|
disableTransforms: false,
|
|
@@ -575,7 +775,7 @@ function SortableContext(_ref) {
|
|
|
575
775
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
576
776
|
[activeIndex, containerId, disabled.draggable, disabled.droppable, disableTransforms, items, overIndex, droppableRects, useDragOverlay, strategy]
|
|
577
777
|
);
|
|
578
|
-
return
|
|
778
|
+
return React2.createElement(Context.Provider, {
|
|
579
779
|
value: contextValue
|
|
580
780
|
}, children);
|
|
581
781
|
}
|
|
@@ -2485,16 +2685,30 @@ function GeneratedIconSetDialog({
|
|
|
2485
2685
|
}) {
|
|
2486
2686
|
const [state, dispatch] = useReducer(reducer, { kind: "idle" });
|
|
2487
2687
|
const [styleNote, setStyleNote] = useState("");
|
|
2688
|
+
const activeGenerationRef = useRef(null);
|
|
2488
2689
|
const canGenerate = Boolean(onGenerate) && cards.length > 0 && state.kind !== "generating";
|
|
2489
2690
|
const canApply = Boolean(onApply) && state.kind === "preview_ready";
|
|
2691
|
+
function abortActiveGeneration() {
|
|
2692
|
+
activeGenerationRef.current?.abort();
|
|
2693
|
+
activeGenerationRef.current = null;
|
|
2694
|
+
}
|
|
2695
|
+
useEffect(() => () => {
|
|
2696
|
+
activeGenerationRef.current?.abort();
|
|
2697
|
+
activeGenerationRef.current = null;
|
|
2698
|
+
}, []);
|
|
2490
2699
|
async function generate() {
|
|
2491
2700
|
if (!onGenerate || cards.length === 0) return;
|
|
2701
|
+
abortActiveGeneration();
|
|
2702
|
+
const generation = new AbortController();
|
|
2703
|
+
activeGenerationRef.current = generation;
|
|
2492
2704
|
dispatch({ type: "generating" });
|
|
2493
2705
|
try {
|
|
2494
2706
|
const result = await onGenerate({
|
|
2495
2707
|
cards,
|
|
2496
|
-
userStyleNote: styleNote.trim().length > 0 ? styleNote.trim() : null
|
|
2708
|
+
userStyleNote: styleNote.trim().length > 0 ? styleNote.trim() : null,
|
|
2709
|
+
signal: generation.signal
|
|
2497
2710
|
});
|
|
2711
|
+
if (activeGenerationRef.current !== generation || generation.signal.aborted) return;
|
|
2498
2712
|
if (result.kind === "preview_ready") {
|
|
2499
2713
|
const validation = validateGeneratedIconSetPreview(result.preview, cards);
|
|
2500
2714
|
if (validation.kind === "invalid") {
|
|
@@ -2506,10 +2720,16 @@ function GeneratedIconSetDialog({
|
|
|
2506
2720
|
}
|
|
2507
2721
|
dispatch({ type: "failed", message: result.message });
|
|
2508
2722
|
} catch (error) {
|
|
2723
|
+
if (activeGenerationRef.current !== generation || generation.signal.aborted) return;
|
|
2509
2724
|
dispatch({ type: "failed", message: getGenerationErrorMessage(error) });
|
|
2725
|
+
} finally {
|
|
2726
|
+
if (activeGenerationRef.current === generation) {
|
|
2727
|
+
activeGenerationRef.current = null;
|
|
2728
|
+
}
|
|
2510
2729
|
}
|
|
2511
2730
|
}
|
|
2512
2731
|
function close(nextOpen) {
|
|
2732
|
+
if (!nextOpen) abortActiveGeneration();
|
|
2513
2733
|
onOpenChange(nextOpen);
|
|
2514
2734
|
if (!nextOpen) dispatch({ type: "reset" });
|
|
2515
2735
|
}
|
|
@@ -3684,7 +3904,8 @@ var BlockEditor = forwardRef(
|
|
|
3684
3904
|
bodyText: card.bodyText,
|
|
3685
3905
|
semanticIconId: card.semanticIconId
|
|
3686
3906
|
}))
|
|
3687
|
-
}
|
|
3907
|
+
},
|
|
3908
|
+
options: input.signal ? { signal: input.signal } : void 0
|
|
3688
3909
|
}));
|
|
3689
3910
|
const assets = response.preview.assets.map((asset) => {
|
|
3690
3911
|
const iconValue = parseBlockIconValue(asset.iconValue);
|
|
@@ -4101,6 +4322,22 @@ var BlockEditor = forwardRef(
|
|
|
4101
4322
|
] }) });
|
|
4102
4323
|
}
|
|
4103
4324
|
);
|
|
4325
|
+
var LinkWidgetContext = createContext(null);
|
|
4326
|
+
function LinkWidgetProvider({
|
|
4327
|
+
children,
|
|
4328
|
+
siteId,
|
|
4329
|
+
adapters,
|
|
4330
|
+
initialItems
|
|
4331
|
+
}) {
|
|
4332
|
+
return /* @__PURE__ */ jsx(LinkWidgetContext.Provider, { value: { siteId, adapters, initialItems }, children });
|
|
4333
|
+
}
|
|
4334
|
+
function useLinkWidgetContext() {
|
|
4335
|
+
const ctx = useContext(LinkWidgetContext);
|
|
4336
|
+
if (!ctx) {
|
|
4337
|
+
return {};
|
|
4338
|
+
}
|
|
4339
|
+
return ctx;
|
|
4340
|
+
}
|
|
4104
4341
|
|
|
4105
4342
|
// ../editor-blocks/src/widgets/link/utils.ts
|
|
4106
4343
|
function toInternalLinkValue(item) {
|
|
@@ -4530,22 +4767,6 @@ function LinkWidget({
|
|
|
4530
4767
|
)
|
|
4531
4768
|
] }) }) });
|
|
4532
4769
|
}
|
|
4533
|
-
var LinkWidgetContext = createContext(null);
|
|
4534
|
-
function LinkWidgetProvider({
|
|
4535
|
-
children,
|
|
4536
|
-
siteId,
|
|
4537
|
-
adapters,
|
|
4538
|
-
initialItems
|
|
4539
|
-
}) {
|
|
4540
|
-
return /* @__PURE__ */ jsx(LinkWidgetContext.Provider, { value: { siteId, adapters, initialItems }, children });
|
|
4541
|
-
}
|
|
4542
|
-
function useLinkWidgetContext() {
|
|
4543
|
-
const ctx = useContext(LinkWidgetContext);
|
|
4544
|
-
if (!ctx) {
|
|
4545
|
-
return {};
|
|
4546
|
-
}
|
|
4547
|
-
return ctx;
|
|
4548
|
-
}
|
|
4549
4770
|
function LinkField({ path, backend, config }) {
|
|
4550
4771
|
const { value, setValue } = useField(path, backend);
|
|
4551
4772
|
const { siteId, adapters, initialItems } = useLinkWidgetContext();
|
|
@@ -5375,7 +5596,66 @@ function filenameExtension(filename) {
|
|
|
5375
5596
|
if (dotIndex < 0 || dotIndex === filename.length - 1) return null;
|
|
5376
5597
|
return filename.slice(dotIndex + 1).trim().toLowerCase() || null;
|
|
5377
5598
|
}
|
|
5378
|
-
createContext(null);
|
|
5599
|
+
var ButtonWidgetContext = createContext(null);
|
|
5600
|
+
function ButtonWidgetProvider({ buttonSystem, children }) {
|
|
5601
|
+
const value = useMemo(() => {
|
|
5602
|
+
const variants = buttonSystem ? buttonSystem.variants.filter((v) => v.enabled).map((v) => ({
|
|
5603
|
+
id: v.id,
|
|
5604
|
+
name: v.name,
|
|
5605
|
+
priority: v.priority
|
|
5606
|
+
})).sort((a, b) => a.priority - b.priority) : [];
|
|
5607
|
+
const defaultVariant = buttonSystem?.variants.find((v) => v.priority === 1)?.id ?? null;
|
|
5608
|
+
return {
|
|
5609
|
+
variants,
|
|
5610
|
+
defaultVariant,
|
|
5611
|
+
buttonSystem
|
|
5612
|
+
};
|
|
5613
|
+
}, [buttonSystem]);
|
|
5614
|
+
return /* @__PURE__ */ jsx(ButtonWidgetContext.Provider, { value, children });
|
|
5615
|
+
}
|
|
5616
|
+
function useButtonWidgetContext() {
|
|
5617
|
+
const context = useContext(ButtonWidgetContext);
|
|
5618
|
+
if (!context) {
|
|
5619
|
+
throw new Error("useButtonWidgetContext must be used within ButtonWidgetProvider");
|
|
5620
|
+
}
|
|
5621
|
+
return context;
|
|
5622
|
+
}
|
|
5623
|
+
var DEFAULT_VARIANTS = [
|
|
5624
|
+
{ id: "primary", name: "Primary", priority: 1 },
|
|
5625
|
+
{ id: "secondary", name: "Secondary", priority: 2 },
|
|
5626
|
+
{ id: "outline", name: "Outline", priority: 3 }
|
|
5627
|
+
];
|
|
5628
|
+
function ButtonVariantField({ path, backend, config }) {
|
|
5629
|
+
const { value, error, setValue } = useField(path, backend);
|
|
5630
|
+
const buttonContext = useButtonWidgetContext();
|
|
5631
|
+
const variants = buttonContext.variants.length > 0 ? buttonContext.variants : DEFAULT_VARIANTS;
|
|
5632
|
+
const options = variants.map((v) => ({ value: v.id, label: v.name }));
|
|
5633
|
+
const isUnknownVariant = value && !options.some((opt) => opt.value === value);
|
|
5634
|
+
if (isUnknownVariant && true) {
|
|
5635
|
+
console.warn(
|
|
5636
|
+
`[ButtonVariantField] Unknown button variant "${value}" at path "${path}". Available variants: ${options.map((o) => o.value).join(", ")}. The button may not render with expected styling.`
|
|
5637
|
+
);
|
|
5638
|
+
}
|
|
5639
|
+
return /* @__PURE__ */ jsx(
|
|
5640
|
+
FieldFrame,
|
|
5641
|
+
{
|
|
5642
|
+
label: config.label,
|
|
5643
|
+
description: config.description,
|
|
5644
|
+
error: error?.message,
|
|
5645
|
+
children: () => /* @__PURE__ */ jsxs(
|
|
5646
|
+
Select,
|
|
5647
|
+
{
|
|
5648
|
+
value: typeof value === "string" && value !== "" ? value : void 0,
|
|
5649
|
+
onValueChange: setValue,
|
|
5650
|
+
children: [
|
|
5651
|
+
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: `Select ${config.label.toLowerCase()}` }) }),
|
|
5652
|
+
/* @__PURE__ */ jsx(SelectContent, { children: options.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
5653
|
+
]
|
|
5654
|
+
}
|
|
5655
|
+
)
|
|
5656
|
+
}
|
|
5657
|
+
);
|
|
5658
|
+
}
|
|
5379
5659
|
var EntryPickerWidgetContext = createContext(null);
|
|
5380
5660
|
function EntryPickerWidgetProvider({
|
|
5381
5661
|
siteId,
|
|
@@ -5534,2482 +5814,1174 @@ function IconPickerField({ path, backend, config }) {
|
|
|
5534
5814
|
}
|
|
5535
5815
|
) });
|
|
5536
5816
|
}
|
|
5817
|
+
createContext(null);
|
|
5537
5818
|
|
|
5538
|
-
// ../
|
|
5539
|
-
function
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
return "secondary";
|
|
5545
|
-
case "scheduled":
|
|
5546
|
-
return "outline";
|
|
5547
|
-
case "archived":
|
|
5548
|
-
return "destructive";
|
|
5549
|
-
default:
|
|
5550
|
-
return "secondary";
|
|
5551
|
-
}
|
|
5552
|
-
}
|
|
5553
|
-
function mapEntryPickerItems(entries, valueFrom) {
|
|
5554
|
-
return entries.map((entry) => ({
|
|
5555
|
-
value: valueFrom === "identifier" ? entry.identifier ?? entry.id : valueFrom === "slug" ? entry.slug ?? entry.id : entry.id,
|
|
5556
|
-
label: entry.draftTitle || entry.title || entry.slug || entry.id,
|
|
5557
|
-
id: entry.id,
|
|
5558
|
-
identifier: entry.identifier ?? null,
|
|
5559
|
-
slug: entry.slug ?? null,
|
|
5560
|
-
badge: {
|
|
5561
|
-
label: entry.status,
|
|
5562
|
-
variant: getStatusBadgeVariant(entry.status)
|
|
5563
|
-
}
|
|
5564
|
-
}));
|
|
5565
|
-
}
|
|
5566
|
-
async function loadEntryPickerItems({
|
|
5567
|
-
apiClient,
|
|
5568
|
-
siteId,
|
|
5569
|
-
contentType,
|
|
5570
|
-
valueFrom
|
|
5571
|
-
}) {
|
|
5572
|
-
const result = await apiClient({
|
|
5573
|
-
endpoint: "listContentEntries",
|
|
5574
|
-
params: { siteId, type: contentType }
|
|
5575
|
-
});
|
|
5576
|
-
const { entries } = unwrapResponse(result);
|
|
5577
|
-
return mapEntryPickerItems(entries, valueFrom);
|
|
5819
|
+
// ../preview-next/src/client/utils/rfc6902.ts
|
|
5820
|
+
function cloneJson(value) {
|
|
5821
|
+
if (typeof structuredClone === "function") {
|
|
5822
|
+
return structuredClone(value);
|
|
5823
|
+
}
|
|
5824
|
+
return JSON.parse(JSON.stringify(value));
|
|
5578
5825
|
}
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
async function loadRoutableContentItems({
|
|
5582
|
-
apiClient,
|
|
5583
|
-
siteId
|
|
5584
|
-
}) {
|
|
5585
|
-
const result = await apiClient({
|
|
5586
|
-
endpoint: "getRoutableContent",
|
|
5587
|
-
params: { siteId }
|
|
5588
|
-
});
|
|
5589
|
-
const payload = unwrapResponse(result);
|
|
5590
|
-
return Array.isArray(payload?.items) ? payload.items : [];
|
|
5826
|
+
function decodePointerSegment(segment) {
|
|
5827
|
+
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
5591
5828
|
}
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
return void 0;
|
|
5599
|
-
}
|
|
5600
|
-
if (prop in target) {
|
|
5601
|
-
return target[prop];
|
|
5602
|
-
}
|
|
5603
|
-
const parsed = parseReferenceKind(prop);
|
|
5604
|
-
if (parsed.kind === "dynamicContent") {
|
|
5605
|
-
return createDynamicContentAdapter(parsed.contentTypeKey);
|
|
5606
|
-
}
|
|
5607
|
-
return void 0;
|
|
5608
|
-
}
|
|
5609
|
-
});
|
|
5829
|
+
function splitPointer(pointer) {
|
|
5830
|
+
if (pointer === "") return [];
|
|
5831
|
+
if (!pointer.startsWith("/")) {
|
|
5832
|
+
throw new Error(`Invalid JSON pointer (must start with "/"): ${pointer}`);
|
|
5833
|
+
}
|
|
5834
|
+
return pointer.split("/").slice(1).map((seg) => decodePointerSegment(seg));
|
|
5610
5835
|
}
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
function defineReferenceLoader(referenceKind, loader) {
|
|
5614
|
-
return Object.assign(loader, { referenceKind });
|
|
5836
|
+
function isJsonObject(value) {
|
|
5837
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5615
5838
|
}
|
|
5616
|
-
function
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
if (status === "scheduled") {
|
|
5621
|
-
return { label: "Scheduled", variant: "secondary" };
|
|
5839
|
+
function getContainerAndKey(root, pointer) {
|
|
5840
|
+
const segments = splitPointer(pointer);
|
|
5841
|
+
if (segments.length === 0) {
|
|
5842
|
+
throw new Error("Patching the root value is not supported");
|
|
5622
5843
|
}
|
|
5623
|
-
|
|
5624
|
-
|
|
5844
|
+
const key = segments[segments.length - 1];
|
|
5845
|
+
if (key === void 0) {
|
|
5846
|
+
throw new Error("Invalid path (missing key)");
|
|
5625
5847
|
}
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
}
|
|
5631
|
-
var loadPostReferenceItems = defineReferenceLoader("post", async ({ apiClient, siteId }) => {
|
|
5632
|
-
const result = await apiClient({
|
|
5633
|
-
endpoint: "listContentEntries",
|
|
5634
|
-
params: { siteId, type: "post" }
|
|
5635
|
-
});
|
|
5636
|
-
const { entries } = unwrapResponse(result);
|
|
5637
|
-
return entries.filter(hasSlug).filter((entry) => entry.status === "published").map((entry) => ({
|
|
5638
|
-
value: entry.slug,
|
|
5639
|
-
label: entry.title || entry.slug || entry.id,
|
|
5640
|
-
badge: formatStatusBadge(entry.status)
|
|
5641
|
-
}));
|
|
5642
|
-
});
|
|
5643
|
-
var loadFormReferenceItems = defineReferenceLoader("form", async ({ apiClient, siteId }) => {
|
|
5644
|
-
const result = await apiClient({
|
|
5645
|
-
endpoint: "listForms",
|
|
5646
|
-
params: { siteId }
|
|
5647
|
-
});
|
|
5648
|
-
const { forms } = unwrapResponse(result);
|
|
5649
|
-
return forms.map((form) => ({
|
|
5650
|
-
value: form.slug,
|
|
5651
|
-
label: form.name
|
|
5652
|
-
}));
|
|
5653
|
-
});
|
|
5654
|
-
var loadBookingFormReferenceItems = defineReferenceLoader("bookingForm", async ({ apiClient, siteId }) => {
|
|
5655
|
-
const result = await apiClient({
|
|
5656
|
-
endpoint: "listBookingForms",
|
|
5657
|
-
params: { siteId }
|
|
5658
|
-
});
|
|
5659
|
-
const { forms } = unwrapResponse(result);
|
|
5660
|
-
return forms.map((form) => ({
|
|
5661
|
-
value: form.id,
|
|
5662
|
-
label: form.name
|
|
5663
|
-
}));
|
|
5664
|
-
});
|
|
5665
|
-
var loadAppointmentServiceReferenceItems = defineReferenceLoader(
|
|
5666
|
-
"appointmentService",
|
|
5667
|
-
async ({ apiClient, siteId }) => {
|
|
5668
|
-
const result = await apiClient({
|
|
5669
|
-
endpoint: "getAppointmentServicesReference",
|
|
5670
|
-
params: { siteId }
|
|
5671
|
-
});
|
|
5672
|
-
const { options } = unwrapResponse(result);
|
|
5673
|
-
return options.map((option) => ({
|
|
5674
|
-
value: option.id,
|
|
5675
|
-
label: option.label
|
|
5676
|
-
}));
|
|
5677
|
-
}
|
|
5678
|
-
);
|
|
5679
|
-
var loadAppointmentResourceReferenceItems = defineReferenceLoader(
|
|
5680
|
-
"appointmentResource",
|
|
5681
|
-
async ({ apiClient, siteId }) => {
|
|
5682
|
-
const result = await apiClient({
|
|
5683
|
-
endpoint: "getAppointmentResourcesReference",
|
|
5684
|
-
params: { siteId }
|
|
5685
|
-
});
|
|
5686
|
-
const { options } = unwrapResponse(result);
|
|
5687
|
-
return options.map((option) => ({
|
|
5688
|
-
value: option.id,
|
|
5689
|
-
label: option.label
|
|
5690
|
-
}));
|
|
5691
|
-
}
|
|
5692
|
-
);
|
|
5693
|
-
var loadPageReferenceItems = defineReferenceLoader("page", async ({ apiClient, siteId }) => {
|
|
5694
|
-
const result = await apiClient({
|
|
5695
|
-
endpoint: "getRoutableContent",
|
|
5696
|
-
params: { siteId }
|
|
5697
|
-
});
|
|
5698
|
-
const { items } = unwrapResponse(result);
|
|
5699
|
-
return items.filter((item) => item.entityType === "page").map((page) => ({
|
|
5700
|
-
value: page.entityId,
|
|
5701
|
-
label: page.title || "Untitled"
|
|
5702
|
-
}));
|
|
5703
|
-
});
|
|
5704
|
-
var loadNewsletterListReferenceItems = defineReferenceLoader(
|
|
5705
|
-
"newsletterList",
|
|
5706
|
-
async ({ apiClient, siteId }) => {
|
|
5707
|
-
const result = await apiClient({
|
|
5708
|
-
endpoint: "listNewsletterLists",
|
|
5709
|
-
params: { siteId }
|
|
5710
|
-
});
|
|
5711
|
-
const { lists } = unwrapResponse(result);
|
|
5712
|
-
return lists.map((list) => ({
|
|
5713
|
-
value: list.id,
|
|
5714
|
-
label: list.name
|
|
5715
|
-
}));
|
|
5716
|
-
}
|
|
5717
|
-
);
|
|
5718
|
-
async function loadDynamicContentReferenceItems({
|
|
5719
|
-
apiClient,
|
|
5720
|
-
siteId,
|
|
5721
|
-
contentTypeKey
|
|
5722
|
-
}) {
|
|
5723
|
-
const result = await apiClient({
|
|
5724
|
-
endpoint: "listContentEntries",
|
|
5725
|
-
params: { siteId, type: contentTypeKey }
|
|
5726
|
-
});
|
|
5727
|
-
const { entries } = unwrapResponse(result);
|
|
5728
|
-
return entries.filter((entry) => entry.status === "published").map((entry) => ({
|
|
5729
|
-
value: entry.id,
|
|
5730
|
-
label: entry.title || entry.slug || entry.id,
|
|
5731
|
-
badge: { label: "Published", variant: "default" }
|
|
5732
|
-
}));
|
|
5733
|
-
}
|
|
5734
|
-
var referenceLoaders = {
|
|
5735
|
-
post: loadPostReferenceItems,
|
|
5736
|
-
form: loadFormReferenceItems,
|
|
5737
|
-
bookingForm: loadBookingFormReferenceItems,
|
|
5738
|
-
appointmentService: loadAppointmentServiceReferenceItems,
|
|
5739
|
-
appointmentResource: loadAppointmentResourceReferenceItems,
|
|
5740
|
-
page: loadPageReferenceItems,
|
|
5741
|
-
newsletterList: loadNewsletterListReferenceItems
|
|
5742
|
-
};
|
|
5743
|
-
|
|
5744
|
-
// ../preview-next/src/client/widgets/widgetAdapters.ts
|
|
5745
|
-
var routableContentCache = /* @__PURE__ */ new Map();
|
|
5746
|
-
var entryPickerCache = /* @__PURE__ */ new Map();
|
|
5747
|
-
var referenceItemsCache = /* @__PURE__ */ new Map();
|
|
5748
|
-
var dynamicReferenceItemsCache = /* @__PURE__ */ new Map();
|
|
5749
|
-
var MAX_CACHE_ENTRIES = 50;
|
|
5750
|
-
function setBoundedCache(map, key, value) {
|
|
5751
|
-
if (!map.has(key) && map.size >= MAX_CACHE_ENTRIES) {
|
|
5752
|
-
const firstKey = map.keys().next().value;
|
|
5753
|
-
if (firstKey !== void 0) {
|
|
5754
|
-
map.delete(firstKey);
|
|
5848
|
+
let container = root;
|
|
5849
|
+
for (const segment of segments.slice(0, -1)) {
|
|
5850
|
+
if (container == null) {
|
|
5851
|
+
throw new Error(`Invalid path: ${pointer}`);
|
|
5755
5852
|
}
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
return {
|
|
5761
|
-
labels: {
|
|
5762
|
-
loading: "Loading entries\u2026",
|
|
5763
|
-
select: "Select an entry",
|
|
5764
|
-
empty: "No entries found",
|
|
5765
|
-
emptySelection: "Select an entry to continue."
|
|
5766
|
-
},
|
|
5767
|
-
loadItems: async ({ siteId }) => {
|
|
5768
|
-
const resolvedSiteId = siteId || fallbackSiteId;
|
|
5769
|
-
if (!resolvedSiteId) {
|
|
5770
|
-
return [];
|
|
5853
|
+
if (Array.isArray(container)) {
|
|
5854
|
+
const index = Number.parseInt(segment, 10);
|
|
5855
|
+
if (!Number.isFinite(index) || String(index) !== segment) {
|
|
5856
|
+
throw new Error(`Invalid array index "${segment}" in path: ${pointer}`);
|
|
5771
5857
|
}
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
if (cached) return cached;
|
|
5775
|
-
const promise = (async () => {
|
|
5776
|
-
try {
|
|
5777
|
-
return await loadDynamicContentReferenceItems({
|
|
5778
|
-
apiClient: previewClient,
|
|
5779
|
-
siteId: resolvedSiteId,
|
|
5780
|
-
contentTypeKey
|
|
5781
|
-
});
|
|
5782
|
-
} catch (error) {
|
|
5783
|
-
dynamicReferenceItemsCache.delete(cacheKey);
|
|
5784
|
-
throw error;
|
|
5785
|
-
}
|
|
5786
|
-
})();
|
|
5787
|
-
setBoundedCache(dynamicReferenceItemsCache, cacheKey, promise);
|
|
5788
|
-
return promise;
|
|
5789
|
-
}
|
|
5790
|
-
};
|
|
5791
|
-
}
|
|
5792
|
-
function createCachedReferenceAdapterLoader(kind, loader, previewClient, fallbackSiteId) {
|
|
5793
|
-
return async ({ siteId }) => {
|
|
5794
|
-
const resolvedSiteId = siteId || fallbackSiteId;
|
|
5795
|
-
if (!resolvedSiteId) {
|
|
5796
|
-
return [];
|
|
5858
|
+
container = container[index];
|
|
5859
|
+
continue;
|
|
5797
5860
|
}
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
const promise = (async () => {
|
|
5802
|
-
try {
|
|
5803
|
-
return await loader({ apiClient: previewClient, siteId: resolvedSiteId });
|
|
5804
|
-
} catch (error) {
|
|
5805
|
-
referenceItemsCache.delete(cacheKey);
|
|
5806
|
-
throw error;
|
|
5807
|
-
}
|
|
5808
|
-
})();
|
|
5809
|
-
setBoundedCache(referenceItemsCache, cacheKey, promise);
|
|
5810
|
-
return promise;
|
|
5811
|
-
};
|
|
5812
|
-
}
|
|
5813
|
-
function createPreviewLinkAdapters(previewClient) {
|
|
5814
|
-
return {
|
|
5815
|
-
fetchRoutableContent: async (currentSiteId) => {
|
|
5816
|
-
const cached = routableContentCache.get(currentSiteId);
|
|
5817
|
-
if (cached) return cached;
|
|
5818
|
-
const promise = (async () => {
|
|
5819
|
-
try {
|
|
5820
|
-
return await loadRoutableContentItems({ apiClient: previewClient, siteId: currentSiteId });
|
|
5821
|
-
} catch (error) {
|
|
5822
|
-
routableContentCache.delete(currentSiteId);
|
|
5823
|
-
throw error;
|
|
5824
|
-
}
|
|
5825
|
-
})();
|
|
5826
|
-
setBoundedCache(routableContentCache, currentSiteId, promise);
|
|
5827
|
-
return promise;
|
|
5861
|
+
if (isJsonObject(container)) {
|
|
5862
|
+
container = container[segment];
|
|
5863
|
+
continue;
|
|
5828
5864
|
}
|
|
5829
|
-
|
|
5865
|
+
throw new Error(`Invalid container for path: ${pointer}`);
|
|
5866
|
+
}
|
|
5867
|
+
return { container, key };
|
|
5830
5868
|
}
|
|
5831
|
-
function
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
const cached = entryPickerCache.get(cacheKey);
|
|
5837
|
-
if (cached) return cached;
|
|
5838
|
-
const request = (async () => {
|
|
5839
|
-
try {
|
|
5840
|
-
return await loadEntryPickerItems({
|
|
5841
|
-
apiClient: previewClient,
|
|
5842
|
-
siteId,
|
|
5843
|
-
contentType,
|
|
5844
|
-
valueFrom
|
|
5845
|
-
});
|
|
5846
|
-
} catch (error) {
|
|
5847
|
-
entryPickerCache.delete(cacheKey);
|
|
5848
|
-
throw error;
|
|
5849
|
-
}
|
|
5850
|
-
})();
|
|
5851
|
-
setBoundedCache(entryPickerCache, cacheKey, request);
|
|
5852
|
-
return request;
|
|
5853
|
-
},
|
|
5854
|
-
labels: {
|
|
5855
|
-
loading: "Loading entries...",
|
|
5856
|
-
select: "Select an entry",
|
|
5857
|
-
empty: "No entries found",
|
|
5858
|
-
emptySelection: "Select an entry to embed.",
|
|
5859
|
-
noContentType: "Select a content type first."
|
|
5869
|
+
function applyAdd(container, key, value, pointer) {
|
|
5870
|
+
if (Array.isArray(container)) {
|
|
5871
|
+
if (key === "-") {
|
|
5872
|
+
container.push(value);
|
|
5873
|
+
return;
|
|
5860
5874
|
}
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
post: {
|
|
5865
|
-
labels: {
|
|
5866
|
-
loading: "Loading posts\u2026",
|
|
5867
|
-
select: "Select a post",
|
|
5868
|
-
empty: "No posts found",
|
|
5869
|
-
emptySelection: "Select a post to continue."
|
|
5875
|
+
const index = Number.parseInt(key, 10);
|
|
5876
|
+
if (!Number.isFinite(index) || String(index) !== key) {
|
|
5877
|
+
throw new Error(`Invalid array index "${key}" in path: ${pointer}`);
|
|
5870
5878
|
}
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
labels: {
|
|
5874
|
-
loading: "Loading forms\u2026",
|
|
5875
|
-
select: "Select a form",
|
|
5876
|
-
empty: "No forms found",
|
|
5877
|
-
emptySelection: "Select a form to continue."
|
|
5879
|
+
if (index < 0 || index > container.length) {
|
|
5880
|
+
throw new Error(`Array index out of bounds "${key}" in path: ${pointer}`);
|
|
5878
5881
|
}
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5882
|
+
container.splice(index, 0, value);
|
|
5883
|
+
return;
|
|
5884
|
+
}
|
|
5885
|
+
if (isJsonObject(container)) {
|
|
5886
|
+
container[key] = value;
|
|
5887
|
+
return;
|
|
5888
|
+
}
|
|
5889
|
+
throw new Error(`Invalid container for path: ${pointer}`);
|
|
5890
|
+
}
|
|
5891
|
+
function applyReplace(container, key, value, pointer) {
|
|
5892
|
+
if (Array.isArray(container)) {
|
|
5893
|
+
const index = Number.parseInt(key, 10);
|
|
5894
|
+
if (!Number.isFinite(index) || String(index) !== key) {
|
|
5895
|
+
throw new Error(`Invalid array index "${key}" in path: ${pointer}`);
|
|
5886
5896
|
}
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
labels: {
|
|
5890
|
-
loading: "Loading appointment services\u2026",
|
|
5891
|
-
select: "Select a service",
|
|
5892
|
-
empty: "No services available",
|
|
5893
|
-
emptySelection: "Select a service to enable booking."
|
|
5897
|
+
if (index < 0 || index >= container.length) {
|
|
5898
|
+
throw new Error(`Array index out of bounds "${key}" in path: ${pointer}`);
|
|
5894
5899
|
}
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
emptySelection: "Select a resource (optional)."
|
|
5900
|
+
container[index] = value;
|
|
5901
|
+
return;
|
|
5902
|
+
}
|
|
5903
|
+
if (isJsonObject(container)) {
|
|
5904
|
+
if (!(key in container)) {
|
|
5905
|
+
throw new Error(`Cannot replace missing key "${key}" in path: ${pointer}`);
|
|
5902
5906
|
}
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5907
|
+
container[key] = value;
|
|
5908
|
+
return;
|
|
5909
|
+
}
|
|
5910
|
+
throw new Error(`Invalid container for path: ${pointer}`);
|
|
5911
|
+
}
|
|
5912
|
+
function applyRemove(container, key, pointer) {
|
|
5913
|
+
if (Array.isArray(container)) {
|
|
5914
|
+
const index = Number.parseInt(key, 10);
|
|
5915
|
+
if (!Number.isFinite(index) || String(index) !== key) {
|
|
5916
|
+
throw new Error(`Invalid array index "${key}" in path: ${pointer}`);
|
|
5910
5917
|
}
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
labels: {
|
|
5914
|
-
loading: "Loading lists\u2026",
|
|
5915
|
-
select: "Select a list",
|
|
5916
|
-
empty: "No lists yet",
|
|
5917
|
-
emptySelection: "Select a newsletter list to subscribe users to."
|
|
5918
|
+
if (index < 0 || index >= container.length) {
|
|
5919
|
+
throw new Error(`Array index out of bounds "${key}" in path: ${pointer}`);
|
|
5918
5920
|
}
|
|
5921
|
+
container.splice(index, 1);
|
|
5922
|
+
return;
|
|
5919
5923
|
}
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
loadItems: createCachedReferenceAdapterLoader(
|
|
5927
|
-
kind,
|
|
5928
|
-
referenceLoaders[kind],
|
|
5929
|
-
previewClient,
|
|
5930
|
-
brandedFallbackSiteId
|
|
5931
|
-
),
|
|
5932
|
-
labels: previewReferenceChrome[kind].labels
|
|
5933
|
-
};
|
|
5924
|
+
if (isJsonObject(container)) {
|
|
5925
|
+
if (!(key in container)) {
|
|
5926
|
+
throw new Error(`Cannot remove missing key "${key}" in path: ${pointer}`);
|
|
5927
|
+
}
|
|
5928
|
+
delete container[key];
|
|
5929
|
+
return;
|
|
5934
5930
|
}
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5931
|
+
throw new Error(`Invalid container for path: ${pointer}`);
|
|
5932
|
+
}
|
|
5933
|
+
function applyRfc6902Patch(base, ops) {
|
|
5934
|
+
const next = cloneJson(base);
|
|
5935
|
+
for (const op of ops) {
|
|
5936
|
+
const { container, key } = getContainerAndKey(next, op.path);
|
|
5937
|
+
if (op.op === "add") {
|
|
5938
|
+
applyAdd(container, key, op.value, op.path);
|
|
5939
|
+
continue;
|
|
5940
|
+
}
|
|
5941
|
+
if (op.op === "replace") {
|
|
5942
|
+
applyReplace(container, key, op.value, op.path);
|
|
5943
|
+
continue;
|
|
5944
|
+
}
|
|
5945
|
+
applyRemove(container, key, op.path);
|
|
5946
|
+
}
|
|
5947
|
+
return next;
|
|
5948
|
+
}
|
|
5949
|
+
var PreviewThemeOverlayContext = createContext(null);
|
|
5950
|
+
var NO_THEME_OVERLAY = { kind: "none" };
|
|
5951
|
+
function isDebugEnabled() {
|
|
5952
|
+
return process.env.NEXT_PUBLIC_AI_ASSISTANT_DEBUG === "1";
|
|
5953
|
+
}
|
|
5954
|
+
function PreviewThemeOverlayProvider({ baseTheme, children }) {
|
|
5955
|
+
const [overlay, setOverlay] = useState(NO_THEME_OVERLAY);
|
|
5956
|
+
const overlayOps = overlay.kind === "patch" ? [...overlay.ops] : null;
|
|
5957
|
+
const overlayOpsSource = overlay.kind === "patch" ? overlay.source : null;
|
|
5958
|
+
const overrideTheme = overlay.kind === "theme" ? overlay.theme : null;
|
|
5959
|
+
const overrideThemeSource = overlay.kind === "theme" ? overlay.source : null;
|
|
5960
|
+
const setOverlayOps = useCallback(
|
|
5961
|
+
(ops, options) => {
|
|
5962
|
+
setOverlay((current) => {
|
|
5963
|
+
if (ops === null) {
|
|
5964
|
+
if (current.kind !== "patch") return current;
|
|
5965
|
+
if (options?.source && current.source !== options.source) return current;
|
|
5966
|
+
return NO_THEME_OVERLAY;
|
|
5967
|
+
}
|
|
5968
|
+
return {
|
|
5969
|
+
kind: "patch",
|
|
5970
|
+
source: options?.source ?? "unknown",
|
|
5971
|
+
ops
|
|
5972
|
+
};
|
|
5973
|
+
});
|
|
5974
|
+
},
|
|
5975
|
+
[]
|
|
5938
5976
|
);
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
}
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
}) {
|
|
5956
|
-
const siteId = useMemo(() => expectParsedBrandedId(parseSiteId(rawSiteId)), [rawSiteId]);
|
|
5957
|
-
const linkAdapters = useMemo(() => createPreviewLinkAdapters(previewClient), [previewClient]);
|
|
5958
|
-
const entryPickerAdapter = useMemo(() => createPreviewEntryPickerAdapter(previewClient), [previewClient]);
|
|
5959
|
-
const referenceAdapters = useMemo(
|
|
5960
|
-
() => createPreviewReferenceAdapters(previewClient),
|
|
5961
|
-
[previewClient]
|
|
5977
|
+
const setOverrideTheme = useCallback(
|
|
5978
|
+
(theme, options) => {
|
|
5979
|
+
setOverlay((current) => {
|
|
5980
|
+
if (theme === null) {
|
|
5981
|
+
if (current.kind !== "theme") return current;
|
|
5982
|
+
if (options?.source && current.source !== options.source) return current;
|
|
5983
|
+
return NO_THEME_OVERLAY;
|
|
5984
|
+
}
|
|
5985
|
+
return {
|
|
5986
|
+
kind: "theme",
|
|
5987
|
+
source: options?.source ?? "unknown",
|
|
5988
|
+
theme
|
|
5989
|
+
};
|
|
5990
|
+
});
|
|
5991
|
+
},
|
|
5992
|
+
[]
|
|
5962
5993
|
);
|
|
5963
|
-
const
|
|
5964
|
-
|
|
5994
|
+
const clearOverlay = useCallback((options) => {
|
|
5995
|
+
setOverlay((current) => {
|
|
5996
|
+
const source = options?.source;
|
|
5997
|
+
if (current.kind === "none") return current;
|
|
5998
|
+
if (source && current.source !== source) return current;
|
|
5999
|
+
return NO_THEME_OVERLAY;
|
|
6000
|
+
});
|
|
6001
|
+
}, []);
|
|
6002
|
+
const effectiveTheme = useMemo(() => {
|
|
6003
|
+
if (overlay.kind === "theme") return overlay.theme;
|
|
6004
|
+
if (overlay.kind !== "patch" || overlay.ops.length === 0) return baseTheme;
|
|
5965
6005
|
try {
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
siteId,
|
|
5976
|
-
apiClient: previewClient,
|
|
5977
|
-
bearerToken,
|
|
5978
|
-
supabaseUrl,
|
|
5979
|
-
mediaAssets,
|
|
5980
|
-
children: /* @__PURE__ */ jsx(ButtonWidgetProvider, { buttonSystem: theme?.buttons ?? null, children: /* @__PURE__ */ jsx(PreviewFormProviderInner, { theme, children }) })
|
|
5981
|
-
}
|
|
5982
|
-
) }) }) }) });
|
|
5983
|
-
}
|
|
5984
|
-
var previewWidgetOverrides = {
|
|
5985
|
-
link: LinkField,
|
|
5986
|
-
file: FileField,
|
|
5987
|
-
media: MediaField,
|
|
5988
|
-
richText: RichTextField,
|
|
5989
|
-
reference: ReferenceField,
|
|
5990
|
-
backgroundColor: BackgroundColorField,
|
|
5991
|
-
backgroundGradient: BackgroundGradientField,
|
|
5992
|
-
entryPicker: EntryPickerField,
|
|
5993
|
-
iconPicker: IconPickerField,
|
|
5994
|
-
buttonVariant: ButtonVariantField
|
|
5995
|
-
};
|
|
5996
|
-
function PreviewZoomControls({ zoom, onZoomChange, disabled }) {
|
|
5997
|
-
return /* @__PURE__ */ jsxs(
|
|
5998
|
-
Select,
|
|
5999
|
-
{
|
|
6000
|
-
value: String(zoom),
|
|
6001
|
-
onValueChange: (value) => onZoomChange(value === "fit" ? "fit" : Number(value)),
|
|
6002
|
-
disabled,
|
|
6003
|
-
children: [
|
|
6004
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 w-20", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
6005
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
6006
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "33", children: "33%" }),
|
|
6007
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "50", children: "50%" }),
|
|
6008
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "75", children: "75%" }),
|
|
6009
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "100", children: "100%" }),
|
|
6010
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "fit", children: "Fit" })
|
|
6011
|
-
] })
|
|
6012
|
-
]
|
|
6006
|
+
return applyRfc6902Patch(baseTheme, [...overlay.ops]);
|
|
6007
|
+
} catch (error) {
|
|
6008
|
+
if (isDebugEnabled()) {
|
|
6009
|
+
console.warn("[preview-theme-overlay] failed to apply theme overlay patch", {
|
|
6010
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6011
|
+
overlayOps: overlay.ops
|
|
6012
|
+
});
|
|
6013
|
+
}
|
|
6014
|
+
return baseTheme;
|
|
6013
6015
|
}
|
|
6016
|
+
}, [baseTheme, overlay]);
|
|
6017
|
+
const value = useMemo(
|
|
6018
|
+
() => ({
|
|
6019
|
+
baseTheme,
|
|
6020
|
+
overlay,
|
|
6021
|
+
overlayOps,
|
|
6022
|
+
overlayOpsSource,
|
|
6023
|
+
setOverlayOps,
|
|
6024
|
+
overrideTheme,
|
|
6025
|
+
overrideThemeSource,
|
|
6026
|
+
setOverrideTheme,
|
|
6027
|
+
effectiveTheme,
|
|
6028
|
+
clearOverlay
|
|
6029
|
+
}),
|
|
6030
|
+
[
|
|
6031
|
+
baseTheme,
|
|
6032
|
+
clearOverlay,
|
|
6033
|
+
effectiveTheme,
|
|
6034
|
+
overlay,
|
|
6035
|
+
overlayOps,
|
|
6036
|
+
overlayOpsSource,
|
|
6037
|
+
overrideTheme,
|
|
6038
|
+
overrideThemeSource,
|
|
6039
|
+
setOverlayOps,
|
|
6040
|
+
setOverrideTheme
|
|
6041
|
+
]
|
|
6014
6042
|
);
|
|
6043
|
+
return /* @__PURE__ */ jsx(PreviewThemeOverlayContext.Provider, { value, children });
|
|
6015
6044
|
}
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
function PreviewViewportControls({
|
|
6023
|
-
mode,
|
|
6024
|
-
width,
|
|
6025
|
-
onModeChange,
|
|
6026
|
-
onWidthChange,
|
|
6027
|
-
className,
|
|
6028
|
-
zoom,
|
|
6029
|
-
onZoomChange
|
|
6030
|
-
}) {
|
|
6031
|
-
const activePreset = VIEWPORT_PRESETS.find((p) => p.width === width);
|
|
6032
|
-
const ActiveIcon = activePreset?.icon ?? Monitor;
|
|
6033
|
-
const activeLabel = mode === "squeeze" ? "Auto fit" : activePreset?.label ?? `${width}px`;
|
|
6034
|
-
const showZoomControls = mode === "fixed" && zoom !== void 0 && onZoomChange !== void 0;
|
|
6035
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
|
|
6036
|
-
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
6037
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "gap-2", children: [
|
|
6038
|
-
/* @__PURE__ */ jsx(ActiveIcon, { className: "h-4 w-4" }),
|
|
6039
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs", children: activeLabel })
|
|
6040
|
-
] }) }),
|
|
6041
|
-
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
|
|
6042
|
-
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Preview size" }),
|
|
6043
|
-
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
6044
|
-
/* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onModeChange("squeeze"), className: cn(mode === "squeeze" && "bg-accent"), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
6045
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Auto fit" }),
|
|
6046
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Matches the space beside the editor" })
|
|
6047
|
-
] }) }),
|
|
6048
|
-
/* @__PURE__ */ jsx(DropdownMenuItem, { onClick: () => onModeChange("fixed"), className: cn(mode === "fixed" && "bg-accent"), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
6049
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Choose size" }),
|
|
6050
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Preview mobile, tablet, or desktop widths" })
|
|
6051
|
-
] }) })
|
|
6052
|
-
] })
|
|
6053
|
-
] }),
|
|
6054
|
-
mode === "fixed" && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
6055
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", children: activePreset?.label ?? `${width}px` }) }),
|
|
6056
|
-
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
|
|
6057
|
-
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Screen size" }),
|
|
6058
|
-
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
6059
|
-
VIEWPORT_PRESETS.map((preset) => /* @__PURE__ */ jsxs(
|
|
6060
|
-
DropdownMenuItem,
|
|
6061
|
-
{
|
|
6062
|
-
onClick: () => onWidthChange(preset.width),
|
|
6063
|
-
className: cn(width === preset.width && "bg-accent"),
|
|
6064
|
-
children: [
|
|
6065
|
-
/* @__PURE__ */ jsx(preset.icon, { className: "mr-2 h-4 w-4" }),
|
|
6066
|
-
preset.label,
|
|
6067
|
-
typeof preset.width === "number" && /* @__PURE__ */ jsxs("span", { className: "ml-auto text-xs text-muted-foreground", children: [
|
|
6068
|
-
preset.width,
|
|
6069
|
-
"px"
|
|
6070
|
-
] })
|
|
6071
|
-
]
|
|
6072
|
-
},
|
|
6073
|
-
preset.label
|
|
6074
|
-
))
|
|
6075
|
-
] })
|
|
6076
|
-
] }),
|
|
6077
|
-
showZoomControls ? /* @__PURE__ */ jsx(PreviewZoomControls, { zoom, onZoomChange }) : null
|
|
6078
|
-
] });
|
|
6079
|
-
}
|
|
6080
|
-
function SubrouteNotice({ model }) {
|
|
6081
|
-
return /* @__PURE__ */ jsxs("div", { className: "border-b bg-amber-50 px-4 py-3 text-amber-950", children: [
|
|
6082
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: model.title }),
|
|
6083
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm", children: model.body }),
|
|
6084
|
-
model.cta ? /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: /* @__PURE__ */ jsx(
|
|
6085
|
-
"a",
|
|
6086
|
-
{
|
|
6087
|
-
className: "inline-flex items-center rounded-md bg-white px-3 py-1.5 text-sm font-medium text-amber-950 shadow-sm ring-1 ring-amber-900/10 hover:bg-amber-100",
|
|
6088
|
-
href: model.cta.href,
|
|
6089
|
-
target: "_blank",
|
|
6090
|
-
rel: "noopener noreferrer",
|
|
6091
|
-
children: model.cta.label
|
|
6092
|
-
}
|
|
6093
|
-
) }) : null,
|
|
6094
|
-
model.fallbackMessage ? /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm text-amber-900/90", children: model.fallbackMessage }) : null
|
|
6095
|
-
] });
|
|
6045
|
+
function usePreviewThemeOverlay() {
|
|
6046
|
+
const ctx = useContext(PreviewThemeOverlayContext);
|
|
6047
|
+
if (!ctx) {
|
|
6048
|
+
throw new Error("usePreviewThemeOverlay must be used within PreviewThemeOverlayProvider");
|
|
6049
|
+
}
|
|
6050
|
+
return ctx;
|
|
6096
6051
|
}
|
|
6097
6052
|
|
|
6098
|
-
// ../preview-next/src/client/preview/
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6053
|
+
// ../preview-next/src/client/preview/previewDesignCoordinator.ts
|
|
6054
|
+
var NO_PREVIEW_DESIGN_STATE = { kind: "idle" };
|
|
6055
|
+
function transitionPreviewDesignState(state, command) {
|
|
6056
|
+
switch (command.kind) {
|
|
6057
|
+
case "preview-theme-patch":
|
|
6058
|
+
return acceptPreview(state, {
|
|
6059
|
+
kind: "active",
|
|
6060
|
+
owner: command.producer,
|
|
6061
|
+
surface: "theme-json-patch",
|
|
6062
|
+
apply: "idle"
|
|
6063
|
+
}, {
|
|
6064
|
+
kind: "set-patch",
|
|
6065
|
+
source: command.producer,
|
|
6066
|
+
ops: command.ops
|
|
6067
|
+
});
|
|
6068
|
+
case "preview-theme":
|
|
6069
|
+
return acceptPreview(state, {
|
|
6070
|
+
kind: "active",
|
|
6071
|
+
owner: command.producer,
|
|
6072
|
+
surface: command.sourcePlan,
|
|
6073
|
+
apply: "idle"
|
|
6074
|
+
}, {
|
|
6075
|
+
kind: "set-theme",
|
|
6076
|
+
source: command.producer,
|
|
6077
|
+
theme: command.theme
|
|
6078
|
+
});
|
|
6079
|
+
case "clear-preview":
|
|
6080
|
+
if (state.kind === "idle") {
|
|
6081
|
+
return ignored(state, "no-active-preview");
|
|
6082
|
+
}
|
|
6083
|
+
if (state.owner !== command.producer) {
|
|
6084
|
+
return ignored(state, "producer-does-not-own-preview");
|
|
6085
|
+
}
|
|
6086
|
+
return accepted(NO_PREVIEW_DESIGN_STATE, { kind: "clear" });
|
|
6087
|
+
case "base-theme-changed":
|
|
6088
|
+
if (state.kind === "idle") {
|
|
6089
|
+
return accepted(state, { kind: "none" });
|
|
6090
|
+
}
|
|
6091
|
+
return accepted(NO_PREVIEW_DESIGN_STATE, { kind: "clear" });
|
|
6092
|
+
case "apply-started":
|
|
6093
|
+
if (state.kind === "idle") {
|
|
6094
|
+
return ignored(state, "no-active-preview");
|
|
6095
|
+
}
|
|
6096
|
+
if (state.owner !== command.producer) {
|
|
6097
|
+
return ignored(state, "producer-does-not-own-preview");
|
|
6098
|
+
}
|
|
6099
|
+
return accepted({ ...state, apply: "pending" }, { kind: "none" });
|
|
6100
|
+
case "apply-succeeded":
|
|
6101
|
+
if (state.kind === "idle") {
|
|
6102
|
+
return ignored(state, "apply-event-for-displaced-preview");
|
|
6103
|
+
}
|
|
6104
|
+
if (state.owner !== command.producer) {
|
|
6105
|
+
return ignored(state, "apply-event-for-displaced-preview");
|
|
6106
|
+
}
|
|
6107
|
+
return accepted(NO_PREVIEW_DESIGN_STATE, { kind: "clear" });
|
|
6108
|
+
case "apply-failed":
|
|
6109
|
+
if (state.kind === "idle") {
|
|
6110
|
+
return ignored(state, "apply-event-for-displaced-preview");
|
|
6111
|
+
}
|
|
6112
|
+
if (state.owner !== command.producer) {
|
|
6113
|
+
return ignored(state, "apply-event-for-displaced-preview");
|
|
6114
|
+
}
|
|
6115
|
+
return accepted({ ...state, apply: "idle" }, { kind: "none" });
|
|
6116
|
+
default:
|
|
6117
|
+
return assertNever2(command, "Unhandled preview design command");
|
|
6109
6118
|
}
|
|
6119
|
+
}
|
|
6120
|
+
function acceptPreview(current, next, effect) {
|
|
6121
|
+
return accepted(next, effect);
|
|
6122
|
+
}
|
|
6123
|
+
function accepted(state, effect) {
|
|
6110
6124
|
return {
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
fallbackMessage: href ? null : "Dashboard links are unavailable. Set `NEXT_PUBLIC_DASHBOARD_URL` so preview can link back to the dashboard."
|
|
6125
|
+
kind: "accepted",
|
|
6126
|
+
state,
|
|
6127
|
+
effect
|
|
6115
6128
|
};
|
|
6116
6129
|
}
|
|
6117
|
-
function
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
}
|
|
6130
|
+
function ignored(state, reason) {
|
|
6131
|
+
return {
|
|
6132
|
+
kind: "ignored",
|
|
6133
|
+
state,
|
|
6134
|
+
reason
|
|
6135
|
+
};
|
|
6123
6136
|
}
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6137
|
+
var PreviewDesignCoordinatorContext = createContext(null);
|
|
6138
|
+
function PreviewDesignCoordinatorProvider({ children }) {
|
|
6139
|
+
const themeOverlay = usePreviewThemeOverlay();
|
|
6140
|
+
const {
|
|
6141
|
+
baseTheme,
|
|
6142
|
+
clearOverlay,
|
|
6143
|
+
overlay,
|
|
6144
|
+
setOverlayOps,
|
|
6145
|
+
setOverrideTheme
|
|
6146
|
+
} = themeOverlay;
|
|
6147
|
+
const [state, setState] = useState(NO_PREVIEW_DESIGN_STATE);
|
|
6148
|
+
const stateRef = useRef(state);
|
|
6149
|
+
const previousBaseThemeRef = useRef(null);
|
|
6150
|
+
useEffect(() => {
|
|
6151
|
+
stateRef.current = state;
|
|
6152
|
+
}, [state]);
|
|
6153
|
+
const dispatch = useCallback(
|
|
6154
|
+
(command) => {
|
|
6155
|
+
const transition = transitionPreviewDesignState(stateRef.current, command);
|
|
6156
|
+
if (transition.kind === "accepted") {
|
|
6157
|
+
stateRef.current = transition.state;
|
|
6158
|
+
setState(transition.state);
|
|
6159
|
+
switch (transition.effect.kind) {
|
|
6160
|
+
case "none":
|
|
6161
|
+
break;
|
|
6162
|
+
case "clear":
|
|
6163
|
+
clearOverlay();
|
|
6164
|
+
break;
|
|
6165
|
+
case "set-patch":
|
|
6166
|
+
setOverlayOps([...transition.effect.ops], {
|
|
6167
|
+
source: transition.effect.source
|
|
6168
|
+
});
|
|
6169
|
+
break;
|
|
6170
|
+
case "set-theme":
|
|
6171
|
+
setOverrideTheme(transition.effect.theme, {
|
|
6172
|
+
source: transition.effect.source
|
|
6173
|
+
});
|
|
6174
|
+
break;
|
|
6175
|
+
default:
|
|
6176
|
+
assertNever2(transition.effect, "Unhandled preview design overlay effect");
|
|
6177
|
+
}
|
|
6178
|
+
}
|
|
6179
|
+
return transition;
|
|
6180
|
+
},
|
|
6181
|
+
[clearOverlay, setOverlayOps, setOverrideTheme]
|
|
6182
|
+
);
|
|
6183
|
+
useEffect(() => {
|
|
6184
|
+
if (previousBaseThemeRef.current && previousBaseThemeRef.current !== baseTheme) {
|
|
6185
|
+
dispatch({ kind: "base-theme-changed" });
|
|
6186
|
+
}
|
|
6187
|
+
previousBaseThemeRef.current = baseTheme;
|
|
6188
|
+
}, [baseTheme, dispatch]);
|
|
6189
|
+
const previewTheme = useCallback(
|
|
6190
|
+
(producer, theme, sourcePlan) => dispatch({ kind: "preview-theme", producer, theme, sourcePlan }),
|
|
6191
|
+
[dispatch]
|
|
6192
|
+
);
|
|
6193
|
+
const previewThemePatch = useCallback(
|
|
6194
|
+
(producer, ops) => dispatch({ kind: "preview-theme-patch", producer, ops }),
|
|
6195
|
+
[dispatch]
|
|
6196
|
+
);
|
|
6197
|
+
const clearPreview = useCallback(
|
|
6198
|
+
(producer) => dispatch({ kind: "clear-preview", producer }),
|
|
6199
|
+
[dispatch]
|
|
6157
6200
|
);
|
|
6158
|
-
const
|
|
6201
|
+
const applyStarted = useCallback(
|
|
6202
|
+
(producer) => dispatch({ kind: "apply-started", producer }),
|
|
6203
|
+
[dispatch]
|
|
6204
|
+
);
|
|
6205
|
+
const applySucceeded = useCallback(
|
|
6206
|
+
(producer) => dispatch({ kind: "apply-succeeded", producer }),
|
|
6207
|
+
[dispatch]
|
|
6208
|
+
);
|
|
6209
|
+
const applyFailed = useCallback(
|
|
6210
|
+
(producer) => dispatch({ kind: "apply-failed", producer }),
|
|
6211
|
+
[dispatch]
|
|
6212
|
+
);
|
|
6213
|
+
const value = useMemo(
|
|
6159
6214
|
() => ({
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6215
|
+
state,
|
|
6216
|
+
overlay,
|
|
6217
|
+
dispatch,
|
|
6218
|
+
previewTheme,
|
|
6219
|
+
previewThemePatch,
|
|
6220
|
+
clearPreview,
|
|
6221
|
+
applyStarted,
|
|
6222
|
+
applySucceeded,
|
|
6223
|
+
applyFailed
|
|
6167
6224
|
}),
|
|
6168
|
-
[
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6225
|
+
[
|
|
6226
|
+
applyFailed,
|
|
6227
|
+
applyStarted,
|
|
6228
|
+
applySucceeded,
|
|
6229
|
+
clearPreview,
|
|
6230
|
+
dispatch,
|
|
6231
|
+
previewTheme,
|
|
6232
|
+
previewThemePatch,
|
|
6233
|
+
state,
|
|
6234
|
+
overlay
|
|
6235
|
+
]
|
|
6174
6236
|
);
|
|
6175
|
-
return /* @__PURE__ */
|
|
6176
|
-
/* @__PURE__ */ jsx("div", { className: "shrink-0 border-b px-4 py-2", children: /* @__PURE__ */ jsx(
|
|
6177
|
-
PreviewViewportControls,
|
|
6178
|
-
{
|
|
6179
|
-
mode: viewportMode,
|
|
6180
|
-
width: viewportWidth,
|
|
6181
|
-
onModeChange: onViewportModeChange,
|
|
6182
|
-
onWidthChange: onViewportWidthChange,
|
|
6183
|
-
zoom,
|
|
6184
|
-
onZoomChange
|
|
6185
|
-
}
|
|
6186
|
-
) }),
|
|
6187
|
-
subrouteNotice ? /* @__PURE__ */ jsx(SubrouteNotice, { model: subrouteNotice }) : null,
|
|
6188
|
-
/* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 space-y-0 overflow-auto", children: [
|
|
6189
|
-
contentTypeSchema && entryData.type ? /* @__PURE__ */ jsx(Collapsible, { open: contentOpen, onOpenChange: setContentOpen, children: /* @__PURE__ */ jsxs("div", { className: "border-b", children: [
|
|
6190
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex cursor-pointer items-center gap-2 px-4 py-3 hover:bg-accent/40", children: [
|
|
6191
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${contentOpen ? "rotate-90" : ""}` }),
|
|
6192
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Content" })
|
|
6193
|
-
] }) }),
|
|
6194
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children: /* @__PURE__ */ jsx(
|
|
6195
|
-
PreviewFormProvider,
|
|
6196
|
-
{
|
|
6197
|
-
siteId,
|
|
6198
|
-
theme: theme ?? null,
|
|
6199
|
-
previewClient: apiClient,
|
|
6200
|
-
bearerToken,
|
|
6201
|
-
supabaseUrl,
|
|
6202
|
-
mediaAssets,
|
|
6203
|
-
children: /* @__PURE__ */ jsx(
|
|
6204
|
-
ContentFieldsForm,
|
|
6205
|
-
{
|
|
6206
|
-
siteId,
|
|
6207
|
-
form: contentFormSpec,
|
|
6208
|
-
initialValues: contentInitialValues,
|
|
6209
|
-
widgets
|
|
6210
|
-
}
|
|
6211
|
-
)
|
|
6212
|
-
}
|
|
6213
|
-
) }) })
|
|
6214
|
-
] }) }) : /* @__PURE__ */ jsx("div", { className: "border-b px-4 py-3", children: /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed px-4 py-6 text-sm text-muted-foreground", children: "Content schema not available for this entry type." }) }),
|
|
6215
|
-
currentTemplate && entryData.type ? /* @__PURE__ */ jsx(Collapsible, { open: templateOpen, onOpenChange: setTemplateOpen, children: /* @__PURE__ */ jsxs("div", { className: "border-b", children: [
|
|
6216
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex cursor-pointer items-center gap-2 px-4 py-3 hover:bg-accent/40", children: [
|
|
6217
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${templateOpen ? "rotate-90" : ""}` }),
|
|
6218
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Template" })
|
|
6219
|
-
] }) }),
|
|
6220
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-3 px-4 pb-4", children: [
|
|
6221
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-md border px-4 py-3", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
6222
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: currentTemplate.name }),
|
|
6223
|
-
currentTemplate.description ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: currentTemplate.description }) : null
|
|
6224
|
-
] }) }),
|
|
6225
|
-
/* @__PURE__ */ jsx(
|
|
6226
|
-
"a",
|
|
6227
|
-
{
|
|
6228
|
-
href: (() => {
|
|
6229
|
-
try {
|
|
6230
|
-
return getDashboardUrl(`sites/${siteId}/content/${entryData.type}/template`);
|
|
6231
|
-
} catch {
|
|
6232
|
-
return "#";
|
|
6233
|
-
}
|
|
6234
|
-
})(),
|
|
6235
|
-
target: "_blank",
|
|
6236
|
-
rel: "noopener noreferrer",
|
|
6237
|
-
className: "inline-flex items-center text-sm text-primary hover:underline",
|
|
6238
|
-
children: "Edit template in dashboard \u2192"
|
|
6239
|
-
}
|
|
6240
|
-
)
|
|
6241
|
-
] }) })
|
|
6242
|
-
] }) }) : null,
|
|
6243
|
-
metadataPanel ? /* @__PURE__ */ jsx(Collapsible, { open: detailsOpen, onOpenChange: setDetailsOpen, children: /* @__PURE__ */ jsxs("div", { className: "border-b", children: [
|
|
6244
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex cursor-pointer items-center gap-2 px-4 py-3 hover:bg-accent/40", children: [
|
|
6245
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${detailsOpen ? "rotate-90" : ""}` }),
|
|
6246
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Details" })
|
|
6247
|
-
] }) }),
|
|
6248
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children: metadataPanel }) })
|
|
6249
|
-
] }) }) : null
|
|
6250
|
-
] })
|
|
6251
|
-
] });
|
|
6237
|
+
return /* @__PURE__ */ jsx(PreviewDesignCoordinatorContext.Provider, { value, children });
|
|
6252
6238
|
}
|
|
6253
|
-
function
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
const [contentOpen, setContentOpen] = useState(true);
|
|
6277
|
-
const [detailsOpen, setDetailsOpen] = useState(false);
|
|
6278
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
|
|
6279
|
-
/* @__PURE__ */ jsx("div", { className: "shrink-0 border-b px-4 py-2", children: /* @__PURE__ */ jsx(
|
|
6280
|
-
PreviewViewportControls,
|
|
6281
|
-
{
|
|
6282
|
-
mode: viewportMode,
|
|
6283
|
-
width: viewportWidth,
|
|
6284
|
-
onModeChange: onViewportModeChange,
|
|
6285
|
-
onWidthChange: onViewportWidthChange,
|
|
6286
|
-
zoom,
|
|
6287
|
-
onZoomChange
|
|
6239
|
+
function usePreviewDesignCoordinator() {
|
|
6240
|
+
const ctx = useContext(PreviewDesignCoordinatorContext);
|
|
6241
|
+
if (!ctx) {
|
|
6242
|
+
throw new Error("usePreviewDesignCoordinator must be used within PreviewDesignCoordinatorProvider");
|
|
6243
|
+
}
|
|
6244
|
+
return ctx;
|
|
6245
|
+
}
|
|
6246
|
+
|
|
6247
|
+
// ../preview-next/src/client/blocks/runOptimisticCustomizeAction.ts
|
|
6248
|
+
function createOptimisticActionRunner() {
|
|
6249
|
+
let latest = 0;
|
|
6250
|
+
return {
|
|
6251
|
+
async run(action) {
|
|
6252
|
+
latest += 1;
|
|
6253
|
+
const seq = latest;
|
|
6254
|
+
action.optimistic?.();
|
|
6255
|
+
try {
|
|
6256
|
+
const success = await action.network();
|
|
6257
|
+
if (seq !== latest) return seq;
|
|
6258
|
+
action.onSuccess(success);
|
|
6259
|
+
} catch (error) {
|
|
6260
|
+
if (seq !== latest) return seq;
|
|
6261
|
+
action.onError(error);
|
|
6288
6262
|
}
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
/* @__PURE__ */ jsx(Collapsible, { open: contentOpen, onOpenChange: setContentOpen, children: /* @__PURE__ */ jsxs("div", { className: "border-b", children: [
|
|
6299
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex cursor-pointer items-center gap-2 px-4 py-3 hover:bg-accent/40", children: [
|
|
6300
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${contentOpen ? "rotate-90" : ""}` }),
|
|
6301
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Page Blocks" })
|
|
6302
|
-
] }) }),
|
|
6303
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children: /* @__PURE__ */ jsx(
|
|
6304
|
-
PreviewFormProvider,
|
|
6305
|
-
{
|
|
6306
|
-
siteId,
|
|
6307
|
-
theme: theme ?? null,
|
|
6308
|
-
previewClient: apiClient,
|
|
6309
|
-
bearerToken,
|
|
6310
|
-
supabaseUrl,
|
|
6311
|
-
mediaAssets,
|
|
6312
|
-
children: /* @__PURE__ */ jsx(
|
|
6313
|
-
BlockEditor,
|
|
6314
|
-
{
|
|
6315
|
-
ref: blockEditorRef,
|
|
6316
|
-
siteId,
|
|
6317
|
-
pageId,
|
|
6318
|
-
blocks: blockItems,
|
|
6319
|
-
uiStore: uiStoreForBlockEditor,
|
|
6320
|
-
apiClient,
|
|
6321
|
-
onBlocksChange,
|
|
6322
|
-
widgetOverrides: previewWidgetOverrides,
|
|
6323
|
-
sdkConfig: sdkConfig ?? null,
|
|
6324
|
-
reorderControlMode: "drag-handle-only",
|
|
6325
|
-
actionControlMode: "menu"
|
|
6326
|
-
},
|
|
6327
|
-
pageId
|
|
6328
|
-
)
|
|
6329
|
-
}
|
|
6330
|
-
) }) })
|
|
6331
|
-
] }) }),
|
|
6332
|
-
metadataPanel ? /* @__PURE__ */ jsx(Collapsible, { open: detailsOpen, onOpenChange: setDetailsOpen, children: /* @__PURE__ */ jsxs("div", { className: "border-b", children: [
|
|
6333
|
-
/* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex cursor-pointer items-center gap-2 px-4 py-3 hover:bg-accent/40", children: [
|
|
6334
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: `h-4 w-4 transition ${detailsOpen ? "rotate-90" : ""}` }),
|
|
6335
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Page Details" })
|
|
6336
|
-
] }) }),
|
|
6337
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children: metadataPanel }) })
|
|
6338
|
-
] }) }) : null
|
|
6339
|
-
] })
|
|
6340
|
-
] });
|
|
6341
|
-
}
|
|
6342
|
-
function PreviewEditorGuidanceCard({
|
|
6343
|
-
guidance,
|
|
6344
|
-
completeSetupDisabled,
|
|
6345
|
-
onCompleteSetup
|
|
6346
|
-
}) {
|
|
6347
|
-
return /* @__PURE__ */ jsxs(
|
|
6348
|
-
"div",
|
|
6349
|
-
{
|
|
6350
|
-
className: guidance.cardClassName,
|
|
6351
|
-
"data-preview-guidance-tone": guidance.tone,
|
|
6352
|
-
children: [
|
|
6353
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold tracking-tight text-slate-900", children: guidance.title }),
|
|
6354
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs leading-5 text-slate-700", children: guidance.description }),
|
|
6355
|
-
/* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(
|
|
6356
|
-
Button,
|
|
6357
|
-
{
|
|
6358
|
-
type: "button",
|
|
6359
|
-
size: "sm",
|
|
6360
|
-
variant: "outline",
|
|
6361
|
-
onClick: onCompleteSetup,
|
|
6362
|
-
disabled: completeSetupDisabled,
|
|
6363
|
-
children: guidance.ctaLabel
|
|
6364
|
-
}
|
|
6365
|
-
) })
|
|
6366
|
-
]
|
|
6367
|
-
}
|
|
6368
|
-
);
|
|
6263
|
+
return seq;
|
|
6264
|
+
},
|
|
6265
|
+
invalidate() {
|
|
6266
|
+
latest += 1;
|
|
6267
|
+
},
|
|
6268
|
+
current() {
|
|
6269
|
+
return latest;
|
|
6270
|
+
}
|
|
6271
|
+
};
|
|
6369
6272
|
}
|
|
6370
6273
|
|
|
6371
|
-
// ../
|
|
6372
|
-
function
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
function hexToRgb(hex) {
|
|
6382
|
-
const normalized = normalizeHex(hex).replace("#", "");
|
|
6383
|
-
const match = normalized.match(/.{2}/g);
|
|
6384
|
-
if (!match || match.length < 3) return null;
|
|
6385
|
-
const [r, g, b] = match.map((value) => parseInt(value, 16));
|
|
6386
|
-
return [r, g, b];
|
|
6387
|
-
}
|
|
6388
|
-
function luminanceChannel(raw) {
|
|
6389
|
-
const channel = raw / 255;
|
|
6390
|
-
return channel <= 0.03928 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);
|
|
6391
|
-
}
|
|
6392
|
-
function contrastRatio(hexA, hexB) {
|
|
6393
|
-
const rgbA = hexToRgb(hexA);
|
|
6394
|
-
const rgbB = hexToRgb(hexB);
|
|
6395
|
-
if (!rgbA || !rgbB) return 1;
|
|
6396
|
-
const lumA = 0.2126 * luminanceChannel(rgbA[0]) + 0.7152 * luminanceChannel(rgbA[1]) + 0.0722 * luminanceChannel(rgbA[2]);
|
|
6397
|
-
const lumB = 0.2126 * luminanceChannel(rgbB[0]) + 0.7152 * luminanceChannel(rgbB[1]) + 0.0722 * luminanceChannel(rgbB[2]);
|
|
6398
|
-
const brighter = Math.max(lumA, lumB);
|
|
6399
|
-
const darker = Math.min(lumA, lumB);
|
|
6400
|
-
return Number(((brighter + 0.05) / (darker + 0.05)).toFixed(2));
|
|
6401
|
-
}
|
|
6402
|
-
var DEFAULT_BRAND_ROLES = [
|
|
6403
|
-
{ key: "primary", label: "Primary" },
|
|
6404
|
-
{ key: "secondary", label: "Secondary" },
|
|
6405
|
-
{ key: "accent", label: "Accent" }
|
|
6406
|
-
];
|
|
6407
|
-
var DEFAULT_FEEDBACK_ROLES = [
|
|
6408
|
-
{ key: "success", label: "Success" },
|
|
6409
|
-
{ key: "warning", label: "Warning" },
|
|
6410
|
-
{ key: "destructive", label: "Destructive" }
|
|
6411
|
-
];
|
|
6412
|
-
var DEFAULT_SURFACE_ROLES = [
|
|
6413
|
-
{ key: "background", label: "Background" },
|
|
6414
|
-
{ key: "surface", label: "Surface" },
|
|
6415
|
-
{ key: "text", label: "Text" },
|
|
6416
|
-
{ key: "border", label: "Border" }
|
|
6417
|
-
];
|
|
6418
|
-
function PaletteTokenEditor({
|
|
6419
|
-
palette,
|
|
6420
|
-
onChange,
|
|
6421
|
-
hasInvalidValues = false,
|
|
6422
|
-
brandRoles = DEFAULT_BRAND_ROLES,
|
|
6423
|
-
feedbackRoles = DEFAULT_FEEDBACK_ROLES,
|
|
6424
|
-
surfaceRoles = DEFAULT_SURFACE_ROLES,
|
|
6425
|
-
showContrastChecks = true,
|
|
6426
|
-
className
|
|
6427
|
-
}) {
|
|
6428
|
-
const paletteValues = useMemo(() => {
|
|
6429
|
-
const map = /* @__PURE__ */ new Map();
|
|
6430
|
-
for (const entry of palette) {
|
|
6431
|
-
if (entry?.name) map.set(entry.name, normalizeHex(entry.hex));
|
|
6432
|
-
}
|
|
6433
|
-
return map;
|
|
6434
|
-
}, [palette]);
|
|
6435
|
-
const getColor = (role) => paletteValues.get(role) ?? "#000000";
|
|
6436
|
-
const handleRoleChange = (role, hex) => {
|
|
6437
|
-
if (!isPlausibleHexInput(hex)) return;
|
|
6438
|
-
onChange(role, normalizeHex(hex));
|
|
6274
|
+
// ../preview-next/src/client/preview/StyleConfigurator.state.ts
|
|
6275
|
+
function createStyleConfiguratorState(base) {
|
|
6276
|
+
return {
|
|
6277
|
+
base,
|
|
6278
|
+
previewed: base,
|
|
6279
|
+
saveStatus: { kind: "idle" },
|
|
6280
|
+
warnings: [],
|
|
6281
|
+
notices: [],
|
|
6282
|
+
paletteOverrideDrafts: paletteOverrideDraftsFromSnapshot(base),
|
|
6283
|
+
expandedRow: null
|
|
6439
6284
|
};
|
|
6440
|
-
const backgroundHex = getColor("background");
|
|
6441
|
-
const textHex = getColor("text");
|
|
6442
|
-
const primaryHex = getColor("primary");
|
|
6443
|
-
const contrast = contrastRatio(backgroundHex, textHex);
|
|
6444
|
-
const actionContrast = contrastRatio(primaryHex, backgroundHex);
|
|
6445
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", className), children: [
|
|
6446
|
-
hasInvalidValues ? /* @__PURE__ */ jsx(Callout, { tone: "danger", role: "alert", className: "p-3", children: /* @__PURE__ */ jsx(CalloutDescription, { className: "mt-0", children: "Some palette values are invalid or incomplete." }) }) : null,
|
|
6447
|
-
/* @__PURE__ */ jsx(ColorRoleGroup, { title: "Brand & accents", roles: brandRoles, getColor, onChange: handleRoleChange }),
|
|
6448
|
-
/* @__PURE__ */ jsx(ColorRoleGroup, { title: "Feedback", roles: feedbackRoles, getColor, onChange: handleRoleChange }),
|
|
6449
|
-
/* @__PURE__ */ jsx(ColorRoleGroup, { title: "Surfaces & text", roles: surfaceRoles, getColor, onChange: handleRoleChange }),
|
|
6450
|
-
showContrastChecks ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6451
|
-
/* @__PURE__ */ jsx(Separator, {}),
|
|
6452
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [
|
|
6453
|
-
/* @__PURE__ */ jsx(
|
|
6454
|
-
ContrastCard,
|
|
6455
|
-
{
|
|
6456
|
-
title: "Background \u2194 Text contrast",
|
|
6457
|
-
value: contrast,
|
|
6458
|
-
threshold: 4.5,
|
|
6459
|
-
primaryLabel: "Background",
|
|
6460
|
-
primaryHex: backgroundHex,
|
|
6461
|
-
secondaryLabel: "Text",
|
|
6462
|
-
secondaryHex: textHex
|
|
6463
|
-
}
|
|
6464
|
-
),
|
|
6465
|
-
/* @__PURE__ */ jsx(
|
|
6466
|
-
ContrastCard,
|
|
6467
|
-
{
|
|
6468
|
-
title: "Primary action contrast",
|
|
6469
|
-
value: actionContrast,
|
|
6470
|
-
threshold: 3,
|
|
6471
|
-
primaryLabel: "Primary",
|
|
6472
|
-
primaryHex,
|
|
6473
|
-
secondaryLabel: "Background",
|
|
6474
|
-
secondaryHex: backgroundHex
|
|
6475
|
-
}
|
|
6476
|
-
)
|
|
6477
|
-
] })
|
|
6478
|
-
] }) : null
|
|
6479
|
-
] });
|
|
6480
6285
|
}
|
|
6481
|
-
function
|
|
6482
|
-
|
|
6483
|
-
return /^#?[0-9a-fA-F]{3}$/.test(trimmed) || /^#?[0-9a-fA-F]{6}$/.test(trimmed);
|
|
6286
|
+
function openRow(state, row) {
|
|
6287
|
+
return state.expandedRow === row ? state : { ...state, expandedRow: row };
|
|
6484
6288
|
}
|
|
6485
|
-
function
|
|
6486
|
-
|
|
6487
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
6488
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
6489
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-foreground", children: title }),
|
|
6490
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Adjust hex values or drag the color picker." })
|
|
6491
|
-
] }),
|
|
6492
|
-
/* @__PURE__ */ jsx("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: roles.map((role) => /* @__PURE__ */ jsx(ColorRoleField, { role, value: getColor(role.key), onChange }, role.key)) })
|
|
6493
|
-
] });
|
|
6289
|
+
function isPreviewingChange(state) {
|
|
6290
|
+
return !selectionSnapshotsEqual(state.base, state.previewed);
|
|
6494
6291
|
}
|
|
6495
|
-
function
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
{
|
|
6502
|
-
htmlFor: inputId,
|
|
6503
|
-
className: "text-xs uppercase text-muted-foreground font-medium leading-5 block",
|
|
6504
|
-
children: role.label
|
|
6505
|
-
}
|
|
6506
|
-
),
|
|
6507
|
-
/* @__PURE__ */ jsx(
|
|
6508
|
-
ColorPicker,
|
|
6509
|
-
{
|
|
6510
|
-
value,
|
|
6511
|
-
onChange: ((next) => {
|
|
6512
|
-
if (typeof next === "string") {
|
|
6513
|
-
onChange(role.key, next);
|
|
6514
|
-
}
|
|
6515
|
-
}),
|
|
6516
|
-
className: "w-full",
|
|
6517
|
-
"aria-label": colorPickerLabel
|
|
6518
|
-
}
|
|
6519
|
-
),
|
|
6520
|
-
/* @__PURE__ */ jsx(
|
|
6521
|
-
Input,
|
|
6522
|
-
{
|
|
6523
|
-
id: inputId,
|
|
6524
|
-
value,
|
|
6525
|
-
onChange: (event) => onChange(role.key, event.target.value),
|
|
6526
|
-
className: "font-mono text-xs uppercase",
|
|
6527
|
-
placeholder: "#000000"
|
|
6528
|
-
}
|
|
6529
|
-
)
|
|
6530
|
-
] });
|
|
6292
|
+
function previewSiteStyle(state, siteStyleId) {
|
|
6293
|
+
return {
|
|
6294
|
+
...state,
|
|
6295
|
+
previewed: { ...state.previewed, siteStyleId },
|
|
6296
|
+
saveStatus: { kind: "idle" }
|
|
6297
|
+
};
|
|
6531
6298
|
}
|
|
6532
|
-
function
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
{
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
),
|
|
6544
|
-
children: [
|
|
6545
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
6546
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: title }),
|
|
6547
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs font-semibold", children: [
|
|
6548
|
-
value,
|
|
6549
|
-
":1"
|
|
6550
|
-
] })
|
|
6551
|
-
] }),
|
|
6552
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs", children: passes ? "Contrast meets WCAG AA guidance." : `Increase contrast to reach ${threshold}:1 or higher.` }),
|
|
6553
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 pt-2 text-xs", children: [
|
|
6554
|
-
/* @__PURE__ */ jsx(ContrastSwatch, { hex: primaryHex, label: primaryLabel }),
|
|
6555
|
-
/* @__PURE__ */ jsx(ContrastSwatch, { hex: secondaryHex, label: secondaryLabel })
|
|
6556
|
-
] })
|
|
6557
|
-
]
|
|
6558
|
-
}
|
|
6299
|
+
function previewButtonPersonality(state, buttonPersonalityId) {
|
|
6300
|
+
return {
|
|
6301
|
+
...state,
|
|
6302
|
+
previewed: { ...state.previewed, buttonPersonalityId },
|
|
6303
|
+
saveStatus: { kind: "idle" }
|
|
6304
|
+
};
|
|
6305
|
+
}
|
|
6306
|
+
function previewHeaderLayout(state, headerLayoutId) {
|
|
6307
|
+
const headerStyleId = deriveNearestCompatibleHeaderStyle(
|
|
6308
|
+
state.previewed.headerStyleId,
|
|
6309
|
+
headerLayoutId
|
|
6559
6310
|
);
|
|
6311
|
+
return previewHeaderSelection(state, { headerLayoutId, headerStyleId });
|
|
6560
6312
|
}
|
|
6561
|
-
function
|
|
6562
|
-
return
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
": ",
|
|
6567
|
-
hex
|
|
6568
|
-
] })
|
|
6569
|
-
] });
|
|
6313
|
+
function previewHeaderStyle(state, headerStyleId) {
|
|
6314
|
+
return previewHeaderSelection(state, {
|
|
6315
|
+
headerLayoutId: state.previewed.headerLayoutId,
|
|
6316
|
+
headerStyleId
|
|
6317
|
+
});
|
|
6570
6318
|
}
|
|
6571
|
-
|
|
6572
|
-
// ../preview-next/src/client/preview/styleConfiguratorApplyPayload.ts
|
|
6573
|
-
function buildApplySiteStyleSelectionBody(input) {
|
|
6319
|
+
function previewFooterLook(state, footerLookId) {
|
|
6574
6320
|
return {
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
paletteOverrides: input.previewed.paletteOverrides,
|
|
6579
|
-
typographyPresetId: input.previewed.typographyPresetId,
|
|
6580
|
-
typographyBodyFontOverride: input.previewed.typographyBodyFontOverride,
|
|
6581
|
-
typographyHeadingFontOverride: input.previewed.typographyHeadingFontOverride,
|
|
6582
|
-
headerLookId: input.previewed.headerLookId,
|
|
6583
|
-
headerLayoutId: input.previewed.headerLayoutId,
|
|
6584
|
-
headerStyleId: input.previewed.headerStyleId,
|
|
6585
|
-
footerLookId: input.previewed.footerLookId,
|
|
6586
|
-
baseSelectionVersion: input.base.selectionVersion,
|
|
6587
|
-
selectionId: input.selectionId ?? null
|
|
6321
|
+
...state,
|
|
6322
|
+
previewed: { ...state.previewed, footerLookId },
|
|
6323
|
+
saveStatus: { kind: "idle" }
|
|
6588
6324
|
};
|
|
6589
6325
|
}
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
selectionId,
|
|
6597
|
-
selectionVersion = null,
|
|
6598
|
-
selectionUpdatedAt,
|
|
6599
|
-
initialSelections,
|
|
6600
|
-
headerSelectionContext,
|
|
6601
|
-
footerSelectionContext,
|
|
6602
|
-
expandedRowRequest = null,
|
|
6603
|
-
siteStyleAccess
|
|
6604
|
-
}) {
|
|
6605
|
-
const router = useRouter();
|
|
6606
|
-
const previewDesign = usePreviewDesignCoordinator();
|
|
6607
|
-
const {
|
|
6608
|
-
applyFailed,
|
|
6609
|
-
applyStarted,
|
|
6610
|
-
applySucceeded,
|
|
6611
|
-
clearPreview,
|
|
6612
|
-
previewTheme
|
|
6613
|
-
} = previewDesign;
|
|
6614
|
-
const [isRefreshPending, startRefreshTransition] = useTransition();
|
|
6615
|
-
const baseSnapshot = useMemo(
|
|
6616
|
-
() => resolveStyleConfiguratorInitialSnapshot({
|
|
6617
|
-
theme,
|
|
6618
|
-
initialSelections: {
|
|
6619
|
-
...initialSelections,
|
|
6620
|
-
selectionVersion: initialSelections.selectionVersion ?? selectionVersion ?? 0,
|
|
6621
|
-
selectionUpdatedAt: initialSelections.selectionUpdatedAt ?? selectionUpdatedAt ?? null
|
|
6622
|
-
},
|
|
6623
|
-
headerSelectionContext,
|
|
6624
|
-
footerSelectionContext
|
|
6625
|
-
}),
|
|
6626
|
-
[footerSelectionContext, headerSelectionContext, theme, initialSelections, selectionUpdatedAt, selectionVersion]
|
|
6627
|
-
);
|
|
6628
|
-
const [state, setState] = useState(
|
|
6629
|
-
() => baseSnapshot ? createStyleConfiguratorState(baseSnapshot) : null
|
|
6630
|
-
);
|
|
6631
|
-
const hasLoadedState = state !== null;
|
|
6632
|
-
const stateRef = useRef(state);
|
|
6633
|
-
const clearPreviewRef = useRef(clearPreview);
|
|
6634
|
-
const runnerRef = useRef(createOptimisticActionRunner());
|
|
6635
|
-
const appliedExpandedRowRequestIdRef = useRef(null);
|
|
6636
|
-
useEffect(() => {
|
|
6637
|
-
stateRef.current = state;
|
|
6638
|
-
}, [state]);
|
|
6639
|
-
useEffect(() => {
|
|
6640
|
-
clearPreviewRef.current = clearPreview;
|
|
6641
|
-
}, [clearPreview]);
|
|
6642
|
-
useEffect(() => {
|
|
6643
|
-
if (!baseSnapshot) return;
|
|
6644
|
-
setState((current) => current ? syncStyleConfiguratorState(current, baseSnapshot) : createStyleConfiguratorState(baseSnapshot));
|
|
6645
|
-
}, [baseSnapshot]);
|
|
6646
|
-
useEffect(() => {
|
|
6647
|
-
if (!state || !baseSnapshot) {
|
|
6648
|
-
clearPreview("style-configurator");
|
|
6649
|
-
return;
|
|
6650
|
-
}
|
|
6651
|
-
if (!isPreviewingChange(state)) {
|
|
6652
|
-
clearPreview("style-configurator");
|
|
6653
|
-
return;
|
|
6654
|
-
}
|
|
6655
|
-
const siteStyle = getCuratedSiteStyle(state.previewed.siteStyleId);
|
|
6656
|
-
if (!siteStyle) {
|
|
6657
|
-
clearPreview("style-configurator");
|
|
6658
|
-
return;
|
|
6659
|
-
}
|
|
6660
|
-
const result = planSiteStylePreviewChange({
|
|
6661
|
-
siteStyle,
|
|
6662
|
-
selection: state.previewed,
|
|
6663
|
-
baseTheme: theme,
|
|
6664
|
-
headerSelectionContext,
|
|
6665
|
-
footerSelectionContext
|
|
6666
|
-
});
|
|
6667
|
-
previewTheme("style-configurator", result.themeOverlay, "site-style");
|
|
6668
|
-
}, [state, baseSnapshot, clearPreview, previewTheme, headerSelectionContext, footerSelectionContext, theme]);
|
|
6669
|
-
useEffect(() => {
|
|
6670
|
-
const runner = runnerRef.current;
|
|
6671
|
-
return () => {
|
|
6672
|
-
runner.invalidate();
|
|
6673
|
-
clearPreviewRef.current("style-configurator");
|
|
6674
|
-
};
|
|
6675
|
-
}, []);
|
|
6676
|
-
useEffect(() => {
|
|
6677
|
-
if (!expandedRowRequest) return;
|
|
6678
|
-
if (appliedExpandedRowRequestIdRef.current === expandedRowRequest.id) return;
|
|
6679
|
-
setState((current) => {
|
|
6680
|
-
if (!current) return current;
|
|
6681
|
-
appliedExpandedRowRequestIdRef.current = expandedRowRequest.id;
|
|
6682
|
-
return openRow(current, expandedRowRequest.row === "header" ? "header-layout" : expandedRowRequest.row);
|
|
6683
|
-
});
|
|
6684
|
-
}, [expandedRowRequest, hasLoadedState]);
|
|
6685
|
-
const handlePreviewSiteStyle = useCallback((siteStyleId) => {
|
|
6686
|
-
setState((current) => {
|
|
6687
|
-
if (!current) return current;
|
|
6688
|
-
const next = previewSiteStyle(current, siteStyleId);
|
|
6689
|
-
const siteStyle = getCuratedSiteStyle(siteStyleId);
|
|
6690
|
-
if (!siteStyle) return next;
|
|
6691
|
-
const result = planSiteStylePreviewChange({
|
|
6692
|
-
siteStyle,
|
|
6693
|
-
selection: next.previewed,
|
|
6694
|
-
baseTheme: theme,
|
|
6695
|
-
headerSelectionContext,
|
|
6696
|
-
footerSelectionContext
|
|
6697
|
-
});
|
|
6698
|
-
return applyResolvedSelections(next, {
|
|
6699
|
-
resolved: result.resolvedSelections,
|
|
6700
|
-
warnings: result.warnings
|
|
6701
|
-
});
|
|
6702
|
-
});
|
|
6703
|
-
}, [footerSelectionContext, headerSelectionContext, theme]);
|
|
6704
|
-
const handlePreviewPersonality = useCallback((id) => {
|
|
6705
|
-
setState((current) => current ? previewButtonPersonality(current, id) : current);
|
|
6706
|
-
}, []);
|
|
6707
|
-
const handlePreviewHeaderLayout = useCallback((id) => {
|
|
6708
|
-
if (!id) return;
|
|
6709
|
-
setState((current) => current ? previewHeaderLayout(current, id) : current);
|
|
6710
|
-
}, []);
|
|
6711
|
-
const handlePreviewHeaderStyle = useCallback((id) => {
|
|
6712
|
-
if (!id) return;
|
|
6713
|
-
setState((current) => current ? previewHeaderStyle(current, id) : current);
|
|
6714
|
-
}, []);
|
|
6715
|
-
const handlePreviewFooterLook = useCallback((id) => {
|
|
6716
|
-
const plan = planSiteChromeLookSelection({ surface: "footer", lookId: id });
|
|
6717
|
-
if (plan.kind !== "footer") return;
|
|
6718
|
-
setState((current) => current ? previewFooterLook(current, plan.next.footerLookId) : current);
|
|
6719
|
-
}, []);
|
|
6720
|
-
const handlePreviewPalette = useCallback((id) => {
|
|
6721
|
-
setState((current) => current ? previewPaletteVariant(current, id) : current);
|
|
6722
|
-
}, []);
|
|
6723
|
-
const handlePreviewTypographyPreset = useCallback((id) => {
|
|
6724
|
-
setState((current) => current ? previewTypographyPreset(current, id) : current);
|
|
6725
|
-
}, []);
|
|
6726
|
-
const handleBodyFontOverride = useCallback((fontFamily) => {
|
|
6727
|
-
setState((current) => current ? setTypographyBodyFontOverride(current, fontFamily) : current);
|
|
6728
|
-
}, []);
|
|
6729
|
-
const handleHeadingFontOverride = useCallback((fontFamily) => {
|
|
6730
|
-
setState((current) => current ? setTypographyHeadingFontOverride(current, fontFamily) : current);
|
|
6731
|
-
}, []);
|
|
6732
|
-
const handleClearTypographyOverrides = useCallback(() => {
|
|
6733
|
-
setState((current) => current ? clearTypographyFontOverrides(current) : current);
|
|
6734
|
-
}, []);
|
|
6735
|
-
const handleTokenOverride = useCallback((role, hex) => {
|
|
6736
|
-
setState((current) => {
|
|
6737
|
-
if (!current) return current;
|
|
6738
|
-
const next = { ...current.previewed.paletteOverrides ?? {}, [role]: hex };
|
|
6739
|
-
const parsed = paletteOverridesSchema.safeParse(next);
|
|
6740
|
-
if (!parsed.success) return current;
|
|
6741
|
-
return setPaletteOverrides(current, parsed.data);
|
|
6742
|
-
});
|
|
6743
|
-
}, []);
|
|
6744
|
-
const handleResetOverrides = useCallback(() => {
|
|
6745
|
-
setState((current) => current ? setPaletteOverrides(current, null) : current);
|
|
6746
|
-
}, []);
|
|
6747
|
-
const handleToggleRow = useCallback((row) => {
|
|
6748
|
-
setState((current) => current ? toggleRow(current, row) : current);
|
|
6749
|
-
}, []);
|
|
6750
|
-
const handleCancel = useCallback(() => {
|
|
6751
|
-
setState((current) => current ? cancelPreview(current) : current);
|
|
6752
|
-
}, []);
|
|
6753
|
-
const handleDismissWarnings = useCallback(() => {
|
|
6754
|
-
setState((current) => current ? dismissWarnings(current) : current);
|
|
6755
|
-
}, []);
|
|
6756
|
-
const handleDismissNotices = useCallback(() => {
|
|
6757
|
-
setState((current) => current ? dismissNotices(current) : current);
|
|
6758
|
-
}, []);
|
|
6759
|
-
const handleApply = useCallback(async () => {
|
|
6760
|
-
const live = stateRef.current;
|
|
6761
|
-
if (!live || !isPreviewingChange(live)) return;
|
|
6762
|
-
const previewed = live.previewed;
|
|
6763
|
-
const siteStyle = getCuratedSiteStyle(previewed.siteStyleId);
|
|
6764
|
-
if (!siteStyle) return;
|
|
6765
|
-
const compiled = planSiteStylePreviewChange({
|
|
6766
|
-
siteStyle,
|
|
6767
|
-
selection: previewed,
|
|
6768
|
-
baseTheme: theme,
|
|
6769
|
-
headerSelectionContext,
|
|
6770
|
-
footerSelectionContext
|
|
6771
|
-
});
|
|
6772
|
-
const body = buildApplySiteStyleSelectionBody({
|
|
6773
|
-
base: live.base,
|
|
6774
|
-
previewed: {
|
|
6775
|
-
...previewed,
|
|
6776
|
-
buttonPersonalityId: compiled.resolvedSelections.buttonPersonalityId,
|
|
6777
|
-
paletteVariantId: compiled.resolvedSelections.paletteVariantId,
|
|
6778
|
-
headerLayoutId: compiled.resolvedSelections.headerLayoutId,
|
|
6779
|
-
headerStyleId: compiled.resolvedSelections.headerStyleId,
|
|
6780
|
-
headerLookId: compiled.resolvedSelections.headerLookId,
|
|
6781
|
-
typographyPresetId: compiled.resolvedSelections.typographyPresetId,
|
|
6782
|
-
typographyBodyFontOverride: compiled.resolvedSelections.typographyBodyFontOverride,
|
|
6783
|
-
typographyHeadingFontOverride: compiled.resolvedSelections.typographyHeadingFontOverride
|
|
6784
|
-
},
|
|
6785
|
-
selectionId
|
|
6786
|
-
});
|
|
6787
|
-
await runnerRef.current.run({
|
|
6788
|
-
optimistic: () => {
|
|
6789
|
-
applyStarted("style-configurator");
|
|
6790
|
-
setState((current) => current ? markApplySaving(current) : current);
|
|
6791
|
-
},
|
|
6792
|
-
network: async () => {
|
|
6793
|
-
const response = await apiClient({
|
|
6794
|
-
endpoint: "applySiteStyleSelection",
|
|
6795
|
-
params: { siteId },
|
|
6796
|
-
body
|
|
6797
|
-
});
|
|
6798
|
-
return unwrapResponse(response);
|
|
6799
|
-
},
|
|
6800
|
-
onSuccess: (saved) => {
|
|
6801
|
-
setState(
|
|
6802
|
-
(current) => current ? markApplySaved(current, {
|
|
6803
|
-
siteStyleId: previewed.siteStyleId,
|
|
6804
|
-
selectionVersion: saved.selectionVersion,
|
|
6805
|
-
selectionUpdatedAt: saved.selectionUpdatedAt ?? previewed.selectionUpdatedAt ?? null,
|
|
6806
|
-
buttonPersonalityId: saved.buttonPersonalityId,
|
|
6807
|
-
paletteVariantId: saved.paletteVariantId,
|
|
6808
|
-
paletteOverrides: saved.paletteOverrides ?? null,
|
|
6809
|
-
typographyPresetId: saved.typographyPresetId,
|
|
6810
|
-
typographyBodyFontOverride: saved.typographyBodyFontOverride,
|
|
6811
|
-
typographyHeadingFontOverride: saved.typographyHeadingFontOverride,
|
|
6812
|
-
headerLookId: saved.headerLookId,
|
|
6813
|
-
headerLayoutId: saved.headerLayoutId,
|
|
6814
|
-
headerStyleId: saved.headerStyleId,
|
|
6815
|
-
footerLookId: saved.footerLookId
|
|
6816
|
-
}) : current
|
|
6817
|
-
);
|
|
6818
|
-
applySucceeded("style-configurator");
|
|
6819
|
-
startRefreshTransition(() => {
|
|
6820
|
-
router.refresh();
|
|
6821
|
-
});
|
|
6822
|
-
},
|
|
6823
|
-
onError: (error) => {
|
|
6824
|
-
applyFailed("style-configurator");
|
|
6825
|
-
const applyError = classifyStyleApplyError(error);
|
|
6826
|
-
if (applyError.kind === "stale") {
|
|
6827
|
-
startRefreshTransition(() => {
|
|
6828
|
-
router.refresh();
|
|
6829
|
-
});
|
|
6830
|
-
}
|
|
6831
|
-
const message = applyError.message;
|
|
6832
|
-
setState((current) => current ? markApplyFailed(current, message) : current);
|
|
6833
|
-
}
|
|
6834
|
-
});
|
|
6835
|
-
}, [
|
|
6836
|
-
apiClient,
|
|
6837
|
-
footerSelectionContext,
|
|
6838
|
-
headerSelectionContext,
|
|
6839
|
-
applyFailed,
|
|
6840
|
-
applyStarted,
|
|
6841
|
-
applySucceeded,
|
|
6842
|
-
router,
|
|
6843
|
-
selectionId,
|
|
6844
|
-
siteId,
|
|
6845
|
-
startRefreshTransition,
|
|
6846
|
-
theme
|
|
6847
|
-
]);
|
|
6848
|
-
if (!state || !baseSnapshot) {
|
|
6849
|
-
return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Loading design controls..." });
|
|
6850
|
-
}
|
|
6851
|
-
const applyAllowed = canApplySiteStyle(siteStyleAccess);
|
|
6852
|
-
const previewingChange = isPreviewingChange(state);
|
|
6853
|
-
const saving = state.saveStatus.kind === "saving" || isRefreshPending;
|
|
6854
|
-
const currentSiteStyle = getCuratedSiteStyle(state.previewed.siteStyleId);
|
|
6855
|
-
if (!currentSiteStyle) {
|
|
6856
|
-
return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "This site uses a Site Style that cannot be configured here." });
|
|
6857
|
-
}
|
|
6858
|
-
const currentPersonality = findButtonPersonality(state.previewed.buttonPersonalityId);
|
|
6859
|
-
const currentPaletteVariant = findPaletteVariant(state.previewed.paletteVariantId);
|
|
6860
|
-
const currentTypographyPreset = state.previewed.typographyPresetId ? findTypographyPreset(state.previewed.typographyPresetId) : null;
|
|
6861
|
-
const chromeLookModels = buildSiteChromeLookModels({
|
|
6862
|
-
state,
|
|
6863
|
-
siteStyle: currentSiteStyle,
|
|
6864
|
-
headerSelectionContext,
|
|
6865
|
-
footerSelectionContext
|
|
6866
|
-
});
|
|
6867
|
-
const currentHeaderLayout = getHeaderLayout(state.previewed.headerLayoutId);
|
|
6868
|
-
const currentHeaderStyle = getHeaderStyle(state.previewed.headerStyleId);
|
|
6869
|
-
const currentFooterLook = state.previewed.footerLookId ? findFooterLook(state.previewed.footerLookId) : findFooterLook(chromeLookModels.footer.renderedLookId);
|
|
6870
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
6871
|
-
state.warnings.length > 0 ? /* @__PURE__ */ jsx(WarningNotice, { warnings: state.warnings, onDismiss: handleDismissWarnings }) : null,
|
|
6872
|
-
state.notices.length > 0 ? /* @__PURE__ */ jsx(NoticeBanner, { notices: state.notices, onDismiss: handleDismissNotices }) : null,
|
|
6873
|
-
/* @__PURE__ */ jsx(
|
|
6874
|
-
SiteStyleRow,
|
|
6875
|
-
{
|
|
6876
|
-
expanded: state.expandedRow === "style",
|
|
6877
|
-
onToggle: () => handleToggleRow("style"),
|
|
6878
|
-
current: currentSiteStyle,
|
|
6879
|
-
onPreview: handlePreviewSiteStyle,
|
|
6880
|
-
disabled: saving
|
|
6881
|
-
}
|
|
6882
|
-
),
|
|
6883
|
-
/* @__PURE__ */ jsx(
|
|
6884
|
-
SiteChromeLookRow,
|
|
6885
|
-
{
|
|
6886
|
-
label: "Header layout",
|
|
6887
|
-
ariaLabel: "Header layout",
|
|
6888
|
-
defaultDescription: "Choose the header structure.",
|
|
6889
|
-
expanded: state.expandedRow === "header-layout",
|
|
6890
|
-
onToggle: () => handleToggleRow("header-layout"),
|
|
6891
|
-
currentId: state.previewed.headerLayoutId,
|
|
6892
|
-
currentLabel: currentHeaderLayout?.label ?? state.previewed.headerLayoutId,
|
|
6893
|
-
scopeDescription: "Changes the header structure on every page.",
|
|
6894
|
-
options: chromeLookModels.headerLayout.options,
|
|
6895
|
-
diagnostics: [],
|
|
6896
|
-
onCycle: (direction) => {
|
|
6897
|
-
const next = cycleSiteChromeLookId(chromeLookModels.headerLayout.options, state.previewed.headerLayoutId, direction);
|
|
6898
|
-
if (next !== void 0) handlePreviewHeaderLayout(next);
|
|
6899
|
-
},
|
|
6900
|
-
onPreview: handlePreviewHeaderLayout,
|
|
6901
|
-
disabled: saving
|
|
6902
|
-
}
|
|
6903
|
-
),
|
|
6904
|
-
/* @__PURE__ */ jsx(
|
|
6905
|
-
SiteChromeLookRow,
|
|
6906
|
-
{
|
|
6907
|
-
label: "Header look",
|
|
6908
|
-
ariaLabel: "Header look",
|
|
6909
|
-
defaultDescription: "Choose the header visual style.",
|
|
6910
|
-
expanded: state.expandedRow === "header-style",
|
|
6911
|
-
onToggle: () => handleToggleRow("header-style"),
|
|
6912
|
-
currentId: state.previewed.headerStyleId,
|
|
6913
|
-
currentLabel: currentHeaderStyle?.label ?? state.previewed.headerStyleId,
|
|
6914
|
-
scopeDescription: "Changes the header surface and link style.",
|
|
6915
|
-
options: chromeLookModels.headerStyle.options,
|
|
6916
|
-
diagnostics: [],
|
|
6917
|
-
onCycle: (direction) => {
|
|
6918
|
-
const next = cycleSiteChromeLookId(chromeLookModels.headerStyle.options, state.previewed.headerStyleId, direction);
|
|
6919
|
-
if (next !== void 0) handlePreviewHeaderStyle(next);
|
|
6920
|
-
},
|
|
6921
|
-
onPreview: handlePreviewHeaderStyle,
|
|
6922
|
-
disabled: saving
|
|
6923
|
-
}
|
|
6924
|
-
),
|
|
6925
|
-
/* @__PURE__ */ jsx(
|
|
6926
|
-
SiteChromeLookRow,
|
|
6927
|
-
{
|
|
6928
|
-
label: "Footer",
|
|
6929
|
-
ariaLabel: "Footer",
|
|
6930
|
-
defaultDescription: "Use the footer chosen for this site style.",
|
|
6931
|
-
catalog: footerLookCatalog,
|
|
6932
|
-
expanded: state.expandedRow === "footer",
|
|
6933
|
-
onToggle: () => handleToggleRow("footer"),
|
|
6934
|
-
currentId: state.previewed.footerLookId,
|
|
6935
|
-
currentLabel: state.previewed.footerLookId ? currentFooterLook?.label ?? "Unknown footer Look" : `${currentFooterLook?.label ?? "Site style"} (default)`,
|
|
6936
|
-
scopeDescription: "Changes the footer on every page.",
|
|
6937
|
-
options: chromeLookModels.footer.options,
|
|
6938
|
-
diagnostics: chromeLookModels.footer.diagnostics,
|
|
6939
|
-
onCycle: (direction) => {
|
|
6940
|
-
const next = cycleSiteChromeLookId(chromeLookModels.footer.options, state.previewed.footerLookId, direction);
|
|
6941
|
-
if (next !== void 0) handlePreviewFooterLook(next);
|
|
6942
|
-
},
|
|
6943
|
-
onPreview: handlePreviewFooterLook,
|
|
6944
|
-
disabled: saving
|
|
6945
|
-
}
|
|
6946
|
-
),
|
|
6947
|
-
/* @__PURE__ */ jsx(
|
|
6948
|
-
PersonalityRow,
|
|
6949
|
-
{
|
|
6950
|
-
expanded: state.expandedRow === "buttons",
|
|
6951
|
-
onToggle: () => handleToggleRow("buttons"),
|
|
6952
|
-
siteStyle: currentSiteStyle,
|
|
6953
|
-
currentId: state.previewed.buttonPersonalityId,
|
|
6954
|
-
currentLabel: currentPersonality?.name ?? state.previewed.buttonPersonalityId,
|
|
6955
|
-
onPreview: handlePreviewPersonality,
|
|
6956
|
-
disabled: saving
|
|
6957
|
-
}
|
|
6958
|
-
),
|
|
6959
|
-
/* @__PURE__ */ jsx(
|
|
6960
|
-
TypographyRow,
|
|
6961
|
-
{
|
|
6962
|
-
expanded: state.expandedRow === "typography",
|
|
6963
|
-
onToggle: () => handleToggleRow("typography"),
|
|
6964
|
-
apiClient,
|
|
6965
|
-
siteStyle: currentSiteStyle,
|
|
6966
|
-
currentPresetId: state.previewed.typographyPresetId,
|
|
6967
|
-
currentLabel: currentTypographyPreset?.name ?? "Custom typography",
|
|
6968
|
-
bodyFontOverride: state.previewed.typographyBodyFontOverride,
|
|
6969
|
-
headingFontOverride: state.previewed.typographyHeadingFontOverride,
|
|
6970
|
-
onPreviewPreset: handlePreviewTypographyPreset,
|
|
6971
|
-
onBodyFontOverride: handleBodyFontOverride,
|
|
6972
|
-
onHeadingFontOverride: handleHeadingFontOverride,
|
|
6973
|
-
onClearOverrides: handleClearTypographyOverrides,
|
|
6974
|
-
disabled: saving
|
|
6975
|
-
}
|
|
6976
|
-
),
|
|
6977
|
-
/* @__PURE__ */ jsx(
|
|
6978
|
-
PaletteRow,
|
|
6979
|
-
{
|
|
6980
|
-
expanded: state.expandedRow === "palette",
|
|
6981
|
-
onToggle: () => handleToggleRow("palette"),
|
|
6982
|
-
siteStyle: currentSiteStyle,
|
|
6983
|
-
currentId: state.previewed.paletteVariantId,
|
|
6984
|
-
currentLabel: currentPaletteVariant?.name ?? state.previewed.paletteVariantId,
|
|
6985
|
-
currentSwatch: currentPaletteVariant?.colors.find((c) => c.name === "primary")?.hex ?? null,
|
|
6986
|
-
onPreview: handlePreviewPalette,
|
|
6987
|
-
disabled: saving
|
|
6988
|
-
}
|
|
6989
|
-
),
|
|
6990
|
-
currentPaletteVariant ? /* @__PURE__ */ jsx(
|
|
6991
|
-
ColoursRow,
|
|
6992
|
-
{
|
|
6993
|
-
expanded: state.expandedRow === "colours",
|
|
6994
|
-
onToggle: () => handleToggleRow("colours"),
|
|
6995
|
-
variant: currentPaletteVariant,
|
|
6996
|
-
overrides: state.previewed.paletteOverrides,
|
|
6997
|
-
onTokenChange: handleTokenOverride,
|
|
6998
|
-
onReset: handleResetOverrides,
|
|
6999
|
-
disabled: saving
|
|
7000
|
-
}
|
|
7001
|
-
) : null,
|
|
7002
|
-
previewingChange ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [
|
|
7003
|
-
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "outline", onClick: handleCancel, disabled: saving, children: "Cancel" }),
|
|
7004
|
-
applyAllowed ? /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: handleApply, disabled: saving, children: saving ? "Applying\u2026" : "Apply" }) : /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Preview only \u2014 ask an admin to apply." })
|
|
7005
|
-
] }) : null,
|
|
7006
|
-
state.saveStatus.kind === "saved" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-success", children: "Saved." }) : null,
|
|
7007
|
-
state.saveStatus.kind === "failed" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: state.saveStatus.message }) : null
|
|
7008
|
-
] });
|
|
6326
|
+
function previewTypographyPreset(state, typographyPresetId) {
|
|
6327
|
+
return {
|
|
6328
|
+
...state,
|
|
6329
|
+
previewed: { ...state.previewed, typographyPresetId },
|
|
6330
|
+
saveStatus: { kind: "idle" }
|
|
6331
|
+
};
|
|
7009
6332
|
}
|
|
7010
|
-
function
|
|
7011
|
-
return
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
className: "flex w-full items-center gap-2 px-3 py-2 text-left hover:bg-accent/30",
|
|
7017
|
-
"aria-expanded": expanded,
|
|
7018
|
-
children: [
|
|
7019
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: cn("h-4 w-4 transition", expanded && "rotate-90") }),
|
|
7020
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
7021
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs uppercase tracking-wide text-muted-foreground", children: label }),
|
|
7022
|
-
/* @__PURE__ */ jsx("div", { className: "truncate text-sm font-medium", children: currentLabel })
|
|
7023
|
-
] }),
|
|
7024
|
-
swatch ? /* @__PURE__ */ jsx(
|
|
7025
|
-
"span",
|
|
7026
|
-
{
|
|
7027
|
-
className: "h-5 w-5 shrink-0 rounded-full border border-black/10",
|
|
7028
|
-
style: { backgroundColor: swatch },
|
|
7029
|
-
"aria-hidden": "true"
|
|
7030
|
-
}
|
|
7031
|
-
) : null
|
|
7032
|
-
]
|
|
7033
|
-
}
|
|
7034
|
-
) }),
|
|
7035
|
-
/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "border-t px-3 py-3", children }) })
|
|
7036
|
-
] }) });
|
|
6333
|
+
function setTypographyBodyFontOverride(state, typographyBodyFontOverride) {
|
|
6334
|
+
return {
|
|
6335
|
+
...state,
|
|
6336
|
+
previewed: { ...state.previewed, typographyBodyFontOverride },
|
|
6337
|
+
saveStatus: { kind: "idle" }
|
|
6338
|
+
};
|
|
7037
6339
|
}
|
|
7038
|
-
function
|
|
7039
|
-
return
|
|
7040
|
-
|
|
7041
|
-
{
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
6340
|
+
function setTypographyHeadingFontOverride(state, typographyHeadingFontOverride) {
|
|
6341
|
+
return {
|
|
6342
|
+
...state,
|
|
6343
|
+
previewed: { ...state.previewed, typographyHeadingFontOverride },
|
|
6344
|
+
saveStatus: { kind: "idle" }
|
|
6345
|
+
};
|
|
6346
|
+
}
|
|
6347
|
+
function clearTypographyFontOverrides(state) {
|
|
6348
|
+
return {
|
|
6349
|
+
...state,
|
|
6350
|
+
previewed: {
|
|
6351
|
+
...state.previewed,
|
|
6352
|
+
typographyBodyFontOverride: null,
|
|
6353
|
+
typographyHeadingFontOverride: null
|
|
7047
6354
|
},
|
|
7048
|
-
|
|
7049
|
-
|
|
6355
|
+
saveStatus: { kind: "idle" }
|
|
6356
|
+
};
|
|
6357
|
+
}
|
|
6358
|
+
function previewPaletteVariant(state, paletteVariantId) {
|
|
6359
|
+
return movePreviewToPaletteVariant(state, paletteVariantId);
|
|
7050
6360
|
}
|
|
7051
|
-
function
|
|
7052
|
-
const
|
|
7053
|
-
|
|
7054
|
-
|
|
6361
|
+
function setPaletteOverrides(state, paletteOverrides) {
|
|
6362
|
+
const paletteOverrideDrafts = withPaletteOverrideDraft(
|
|
6363
|
+
state.paletteOverrideDrafts,
|
|
6364
|
+
state.previewed.paletteVariantId,
|
|
6365
|
+
paletteOverrides
|
|
7055
6366
|
);
|
|
7056
|
-
return
|
|
7057
|
-
|
|
7058
|
-
{
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
6367
|
+
return {
|
|
6368
|
+
...state,
|
|
6369
|
+
previewed: { ...state.previewed, paletteOverrides },
|
|
6370
|
+
paletteOverrideDrafts,
|
|
6371
|
+
saveStatus: { kind: "idle" }
|
|
6372
|
+
};
|
|
6373
|
+
}
|
|
6374
|
+
function applyResolvedSelections(state, input) {
|
|
6375
|
+
const paletteScoped = movePreviewToPaletteVariant(state, input.resolved.paletteVariantId);
|
|
6376
|
+
return {
|
|
6377
|
+
...paletteScoped,
|
|
6378
|
+
previewed: {
|
|
6379
|
+
...paletteScoped.previewed,
|
|
6380
|
+
buttonPersonalityId: input.resolved.buttonPersonalityId,
|
|
6381
|
+
headerLayoutId: input.resolved.headerLayoutId,
|
|
6382
|
+
headerStyleId: input.resolved.headerStyleId,
|
|
6383
|
+
headerLookId: input.resolved.headerLookId,
|
|
6384
|
+
typographyPresetId: input.resolved.typographyPresetId,
|
|
6385
|
+
typographyBodyFontOverride: input.resolved.typographyBodyFontOverride,
|
|
6386
|
+
typographyHeadingFontOverride: input.resolved.typographyHeadingFontOverride
|
|
7064
6387
|
},
|
|
7065
|
-
|
|
7066
|
-
|
|
6388
|
+
warnings: input.warnings
|
|
6389
|
+
};
|
|
7067
6390
|
}
|
|
7068
|
-
function
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
onPreviewPreset,
|
|
7078
|
-
onBodyFontOverride,
|
|
7079
|
-
onHeadingFontOverride,
|
|
7080
|
-
onClearOverrides,
|
|
7081
|
-
disabled
|
|
7082
|
-
}) {
|
|
7083
|
-
const options = useMemo(
|
|
7084
|
-
() => requireEntriesForCuratedChoices(typographyPresets, siteStyle.typographyPresetChoices),
|
|
7085
|
-
[siteStyle.typographyPresetChoices]
|
|
7086
|
-
);
|
|
7087
|
-
const fontCatalog = useFontCatalog(apiClient, expanded);
|
|
7088
|
-
const selectedPreset = currentPresetId ? findTypographyPreset(currentPresetId) : null;
|
|
7089
|
-
return /* @__PURE__ */ jsxs(StyleRowFrame, { label: "Typography", currentLabel, expanded, onToggle, children: [
|
|
7090
|
-
currentPresetId === null ? /* @__PURE__ */ jsx("div", { className: "mb-3 rounded-md border border-muted-foreground/20 bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: "Current custom setup" }) : null,
|
|
7091
|
-
/* @__PURE__ */ jsx("ul", { role: "radiogroup", "aria-label": "Typography preset", className: "space-y-1", children: options.map((preset) => /* @__PURE__ */ jsx(
|
|
7092
|
-
TypographyPresetOption,
|
|
7093
|
-
{
|
|
7094
|
-
preset,
|
|
7095
|
-
selected: preset.id === currentPresetId,
|
|
7096
|
-
onSelect: () => onPreviewPreset(preset.id),
|
|
7097
|
-
disabled
|
|
7098
|
-
},
|
|
7099
|
-
preset.id
|
|
7100
|
-
)) }),
|
|
7101
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3 border-t pt-3", children: [
|
|
7102
|
-
selectedPreset ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7103
|
-
/* @__PURE__ */ jsx(
|
|
7104
|
-
TypographyFontSlotPicker,
|
|
7105
|
-
{
|
|
7106
|
-
label: "Body font",
|
|
7107
|
-
slot: "body",
|
|
7108
|
-
preset: selectedPreset,
|
|
7109
|
-
catalog: fontCatalog,
|
|
7110
|
-
value: bodyFontOverride,
|
|
7111
|
-
onChange: onBodyFontOverride,
|
|
7112
|
-
disabled
|
|
7113
|
-
}
|
|
7114
|
-
),
|
|
7115
|
-
/* @__PURE__ */ jsx(
|
|
7116
|
-
TypographyFontSlotPicker,
|
|
7117
|
-
{
|
|
7118
|
-
label: "Heading font",
|
|
7119
|
-
slot: "heading",
|
|
7120
|
-
preset: selectedPreset,
|
|
7121
|
-
catalog: fontCatalog,
|
|
7122
|
-
value: headingFontOverride,
|
|
7123
|
-
onChange: onHeadingFontOverride,
|
|
7124
|
-
disabled
|
|
7125
|
-
}
|
|
7126
|
-
)
|
|
7127
|
-
] }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Choose a typography preset to use curated font overrides." }),
|
|
7128
|
-
/* @__PURE__ */ jsx(
|
|
7129
|
-
Button,
|
|
7130
|
-
{
|
|
7131
|
-
type: "button",
|
|
7132
|
-
size: "sm",
|
|
7133
|
-
variant: "outline",
|
|
7134
|
-
onClick: onClearOverrides,
|
|
7135
|
-
disabled: disabled || !bodyFontOverride && !headingFontOverride,
|
|
7136
|
-
children: "Use preset fonts"
|
|
7137
|
-
}
|
|
7138
|
-
)
|
|
7139
|
-
] })
|
|
7140
|
-
] });
|
|
6391
|
+
function cancelPreview(state) {
|
|
6392
|
+
return {
|
|
6393
|
+
...state,
|
|
6394
|
+
previewed: state.base,
|
|
6395
|
+
saveStatus: { kind: "idle" },
|
|
6396
|
+
warnings: [],
|
|
6397
|
+
notices: [],
|
|
6398
|
+
paletteOverrideDrafts: paletteOverrideDraftsFromSnapshot(state.base)
|
|
6399
|
+
};
|
|
7141
6400
|
}
|
|
7142
|
-
function
|
|
7143
|
-
|
|
7144
|
-
selected,
|
|
7145
|
-
onSelect,
|
|
7146
|
-
disabled
|
|
7147
|
-
}) {
|
|
7148
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
7149
|
-
"button",
|
|
7150
|
-
{
|
|
7151
|
-
type: "button",
|
|
7152
|
-
role: "radio",
|
|
7153
|
-
"aria-checked": selected,
|
|
7154
|
-
onClick: onSelect,
|
|
7155
|
-
disabled,
|
|
7156
|
-
className: cn(
|
|
7157
|
-
"w-full rounded-md border px-3 py-2 text-left transition disabled:cursor-not-allowed disabled:opacity-50",
|
|
7158
|
-
selected ? "border-primary bg-primary/5" : "border-border hover:bg-muted/60"
|
|
7159
|
-
),
|
|
7160
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
7161
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
7162
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: preset.name }),
|
|
7163
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: preset.description })
|
|
7164
|
-
] }),
|
|
7165
|
-
/* @__PURE__ */ jsxs("div", { className: "shrink-0 text-right", children: [
|
|
7166
|
-
/* @__PURE__ */ jsx("div", { className: "text-[11px] font-semibold uppercase tracking-wide", children: preset.defaultFonts.heading.split(",")[0] }),
|
|
7167
|
-
/* @__PURE__ */ jsx("div", { className: "text-[11px] text-muted-foreground", children: preset.defaultFonts.body.split(",")[0] })
|
|
7168
|
-
] })
|
|
7169
|
-
] })
|
|
7170
|
-
}
|
|
7171
|
-
) });
|
|
6401
|
+
function markApplySaving(state) {
|
|
6402
|
+
return { ...state, saveStatus: { kind: "saving" } };
|
|
7172
6403
|
}
|
|
7173
|
-
function
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
const defaultFont = primaryFontFamily(preset.defaultFonts[slot]);
|
|
7184
|
-
const selectedFamily = value ?? defaultFont;
|
|
7185
|
-
const recordsByFamily = useMemo(() => indexFontsByFamily(catalog.fonts), [catalog.fonts]);
|
|
7186
|
-
const selectedFit = evaluateTypographyFontSlot({
|
|
7187
|
-
slot,
|
|
7188
|
-
policy: preset.slotPolicies[slot],
|
|
7189
|
-
capability: capabilityForFamily(selectedFamily, recordsByFamily)
|
|
7190
|
-
});
|
|
7191
|
-
const recommendedFamilies = preset.recommendedFonts[slot];
|
|
7192
|
-
const recommendedOptions = useMemo(
|
|
7193
|
-
() => uniqueFontFamilies(recommendedFamilies),
|
|
7194
|
-
[recommendedFamilies]
|
|
7195
|
-
);
|
|
7196
|
-
const browseOptions = useMemo(() => {
|
|
7197
|
-
const normalizedQuery = query.trim().toLowerCase();
|
|
7198
|
-
const source = normalizedQuery.length > 0 ? catalog.fonts.filter((font) => font.family.toLowerCase().includes(normalizedQuery)) : catalog.fonts;
|
|
7199
|
-
return [...source].sort((a, b) => sortFontForPresetSlot(a, b, slot, preset, recordsByFamily)).slice(0, normalizedQuery.length > 0 ? MAX_FONT_RESULTS_WHEN_SEARCHING : MAX_FONT_RESULTS_WHEN_BROWSING);
|
|
7200
|
-
}, [catalog.fonts, preset, query, recordsByFamily, slot]);
|
|
7201
|
-
return /* @__PURE__ */ jsxs("section", { className: "space-y-2", "aria-label": label, children: [
|
|
7202
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
7203
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
7204
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground", children: label }),
|
|
7205
|
-
/* @__PURE__ */ jsx("div", { className: "truncate text-sm", children: value ? selectedFamily : `${defaultFont} (preset)` })
|
|
7206
|
-
] }),
|
|
7207
|
-
/* @__PURE__ */ jsx(TypographyFontFitBadge, { fit: selectedFit })
|
|
7208
|
-
] }),
|
|
7209
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-1", children: [
|
|
7210
|
-
/* @__PURE__ */ jsxs(
|
|
7211
|
-
"button",
|
|
7212
|
-
{
|
|
7213
|
-
type: "button",
|
|
7214
|
-
className: cn(
|
|
7215
|
-
"rounded-md border px-3 py-2 text-left text-sm transition disabled:cursor-not-allowed disabled:opacity-50",
|
|
7216
|
-
value === null ? "border-foreground bg-accent/40" : "border-transparent hover:border-foreground/40 hover:bg-accent/20"
|
|
7217
|
-
),
|
|
7218
|
-
onClick: () => onChange(null),
|
|
7219
|
-
disabled,
|
|
7220
|
-
children: [
|
|
7221
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Use preset font" }),
|
|
7222
|
-
/* @__PURE__ */ jsx("span", { className: "ml-2 text-xs text-muted-foreground", children: defaultFont })
|
|
7223
|
-
]
|
|
7224
|
-
}
|
|
7225
|
-
),
|
|
7226
|
-
recommendedOptions.map((family) => /* @__PURE__ */ jsx(
|
|
7227
|
-
FontFamilyOption,
|
|
7228
|
-
{
|
|
7229
|
-
family,
|
|
7230
|
-
selected: value === family,
|
|
7231
|
-
fit: evaluateTypographyFontSlot({
|
|
7232
|
-
slot,
|
|
7233
|
-
policy: preset.slotPolicies[slot],
|
|
7234
|
-
capability: capabilityForFamily(family, recordsByFamily)
|
|
7235
|
-
}),
|
|
7236
|
-
onSelect: () => onChange(family),
|
|
7237
|
-
disabled
|
|
7238
|
-
},
|
|
7239
|
-
family
|
|
7240
|
-
))
|
|
7241
|
-
] }),
|
|
7242
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md border bg-muted/20 p-2", children: [
|
|
7243
|
-
/* @__PURE__ */ jsx(
|
|
7244
|
-
"input",
|
|
7245
|
-
{
|
|
7246
|
-
type: "search",
|
|
7247
|
-
value: query,
|
|
7248
|
-
placeholder: `Search ${slot} fonts`,
|
|
7249
|
-
onChange: (event) => setQuery(event.currentTarget.value),
|
|
7250
|
-
disabled: disabled || catalog.kind === "loading",
|
|
7251
|
-
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"
|
|
7252
|
-
}
|
|
7253
|
-
),
|
|
7254
|
-
catalog.kind === "loading" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Loading font catalog..." }) : catalog.kind === "failed" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: catalog.message }) : null,
|
|
7255
|
-
browseOptions.length > 0 ? /* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-1 overflow-y-auto pr-1", children: browseOptions.map((font) => /* @__PURE__ */ jsx(
|
|
7256
|
-
FontFamilyOption,
|
|
7257
|
-
{
|
|
7258
|
-
family: font.family,
|
|
7259
|
-
selected: value === font.family,
|
|
7260
|
-
fit: evaluateTypographyFontSlot({
|
|
7261
|
-
slot,
|
|
7262
|
-
policy: preset.slotPolicies[slot],
|
|
7263
|
-
capability: capabilityFromFontRecord(font)
|
|
7264
|
-
}),
|
|
7265
|
-
onSelect: () => onChange(font.family),
|
|
7266
|
-
disabled
|
|
7267
|
-
},
|
|
7268
|
-
font.family
|
|
7269
|
-
)) }) : catalog.kind === "loaded" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "No matching Google Fonts." }) : null
|
|
7270
|
-
] }),
|
|
7271
|
-
/* @__PURE__ */ jsxs("label", { className: "block space-y-1", children: [
|
|
7272
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Brand or uploaded font name" }),
|
|
7273
|
-
/* @__PURE__ */ jsx(
|
|
7274
|
-
"input",
|
|
7275
|
-
{
|
|
7276
|
-
type: "text",
|
|
7277
|
-
value: value ?? "",
|
|
7278
|
-
placeholder: "Enter any font family",
|
|
7279
|
-
onChange: (event) => onChange(normalizeFontFamilyOverride(event.currentTarget.value)),
|
|
7280
|
-
disabled,
|
|
7281
|
-
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"
|
|
7282
|
-
}
|
|
7283
|
-
)
|
|
7284
|
-
] })
|
|
7285
|
-
] });
|
|
6404
|
+
function markApplySaved(state, persisted) {
|
|
6405
|
+
return {
|
|
6406
|
+
...state,
|
|
6407
|
+
base: persisted,
|
|
6408
|
+
previewed: persisted,
|
|
6409
|
+
saveStatus: { kind: "saved" },
|
|
6410
|
+
warnings: [],
|
|
6411
|
+
notices: [],
|
|
6412
|
+
paletteOverrideDrafts: paletteOverrideDraftsFromSnapshot(persisted)
|
|
6413
|
+
};
|
|
7286
6414
|
}
|
|
7287
|
-
function
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
disabled
|
|
7293
|
-
}) {
|
|
7294
|
-
return /* @__PURE__ */ jsxs(
|
|
7295
|
-
"button",
|
|
7296
|
-
{
|
|
7297
|
-
type: "button",
|
|
7298
|
-
className: cn(
|
|
7299
|
-
"flex w-full items-center justify-between gap-3 rounded-md border px-3 py-2 text-left text-sm transition disabled:cursor-not-allowed disabled:opacity-50",
|
|
7300
|
-
selected ? "border-foreground bg-accent/40" : "border-transparent bg-background hover:border-foreground/40 hover:bg-accent/20"
|
|
7301
|
-
),
|
|
7302
|
-
onClick: onSelect,
|
|
7303
|
-
disabled,
|
|
7304
|
-
children: [
|
|
7305
|
-
/* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: family }),
|
|
7306
|
-
/* @__PURE__ */ jsx(TypographyFontFitBadge, { fit })
|
|
7307
|
-
]
|
|
7308
|
-
}
|
|
7309
|
-
);
|
|
6415
|
+
function markApplyFailed(state, message) {
|
|
6416
|
+
return {
|
|
6417
|
+
...state,
|
|
6418
|
+
saveStatus: { kind: "failed", message }
|
|
6419
|
+
};
|
|
7310
6420
|
}
|
|
7311
|
-
function
|
|
7312
|
-
return
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
"shrink-0 rounded-full px-2 py-0.5 text-[11px] font-medium",
|
|
7317
|
-
fit.kind === "recommended" && "bg-emerald-100 text-emerald-800",
|
|
7318
|
-
fit.kind === "compatible" && "bg-sky-100 text-sky-800",
|
|
7319
|
-
fit.kind === "limited" && "bg-amber-100 text-amber-900",
|
|
7320
|
-
fit.kind === "risky" && "bg-rose-100 text-rose-800",
|
|
7321
|
-
fit.kind === "unknown" && "bg-muted text-muted-foreground"
|
|
7322
|
-
),
|
|
7323
|
-
title: fit.reason,
|
|
7324
|
-
children: typographyFontFitLabel(fit.kind)
|
|
7325
|
-
}
|
|
7326
|
-
);
|
|
6421
|
+
function toggleRow(state, row) {
|
|
6422
|
+
return {
|
|
6423
|
+
...state,
|
|
6424
|
+
expandedRow: state.expandedRow === row ? null : row
|
|
6425
|
+
};
|
|
7327
6426
|
}
|
|
7328
|
-
function
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
useEffect(() => {
|
|
7332
|
-
if (!enabled) return;
|
|
7333
|
-
if (requestedClientRef.current === apiClient) return;
|
|
7334
|
-
requestedClientRef.current = apiClient;
|
|
7335
|
-
let cancelled = false;
|
|
7336
|
-
setCatalog({ kind: "loading", fonts: [] });
|
|
7337
|
-
async function loadFonts() {
|
|
7338
|
-
try {
|
|
7339
|
-
const response = await apiClient({ endpoint: "listFonts" });
|
|
7340
|
-
const fonts = unwrapResponse(response);
|
|
7341
|
-
if (!cancelled) {
|
|
7342
|
-
setCatalog({
|
|
7343
|
-
kind: "loaded",
|
|
7344
|
-
fonts: Array.isArray(fonts) ? fonts : []
|
|
7345
|
-
});
|
|
7346
|
-
}
|
|
7347
|
-
} catch (error) {
|
|
7348
|
-
if (!cancelled) {
|
|
7349
|
-
setCatalog({
|
|
7350
|
-
kind: "failed",
|
|
7351
|
-
fonts: [],
|
|
7352
|
-
message: error instanceof Error ? error.message : "Unable to load the font catalog."
|
|
7353
|
-
});
|
|
7354
|
-
}
|
|
7355
|
-
}
|
|
7356
|
-
}
|
|
7357
|
-
void loadFonts();
|
|
7358
|
-
return () => {
|
|
7359
|
-
cancelled = true;
|
|
7360
|
-
};
|
|
7361
|
-
}, [apiClient, enabled]);
|
|
7362
|
-
return catalog;
|
|
6427
|
+
function dismissWarnings(state) {
|
|
6428
|
+
if (state.warnings.length === 0) return state;
|
|
6429
|
+
return { ...state, warnings: [] };
|
|
7363
6430
|
}
|
|
7364
|
-
function
|
|
7365
|
-
|
|
6431
|
+
function dismissNotices(state) {
|
|
6432
|
+
if (state.notices.length === 0) return state;
|
|
6433
|
+
return { ...state, notices: [] };
|
|
7366
6434
|
}
|
|
7367
|
-
function
|
|
7368
|
-
|
|
7369
|
-
if (
|
|
6435
|
+
function syncStyleConfiguratorState(state, base) {
|
|
6436
|
+
if (selectionSnapshotsEqual(state.base, base)) return state;
|
|
6437
|
+
if (selectionSnapshotsEqual(state.previewed, base)) {
|
|
6438
|
+
return {
|
|
6439
|
+
...state,
|
|
6440
|
+
base,
|
|
6441
|
+
saveStatus: state.saveStatus.kind === "saving" ? { kind: "saved" } : state.saveStatus,
|
|
6442
|
+
warnings: [],
|
|
6443
|
+
notices: [],
|
|
6444
|
+
paletteOverrideDrafts: paletteOverrideDraftsFromSnapshot(base)
|
|
6445
|
+
};
|
|
6446
|
+
}
|
|
6447
|
+
return {
|
|
6448
|
+
...state,
|
|
6449
|
+
base,
|
|
6450
|
+
previewed: base,
|
|
6451
|
+
saveStatus: { kind: "idle" },
|
|
6452
|
+
warnings: [],
|
|
6453
|
+
notices: [],
|
|
6454
|
+
paletteOverrideDrafts: paletteOverrideDraftsFromSnapshot(base)
|
|
6455
|
+
};
|
|
6456
|
+
}
|
|
6457
|
+
function movePreviewToPaletteVariant(state, paletteVariantId) {
|
|
6458
|
+
if (state.previewed.paletteVariantId === paletteVariantId) {
|
|
6459
|
+
return {
|
|
6460
|
+
...state,
|
|
6461
|
+
saveStatus: { kind: "idle" }
|
|
6462
|
+
};
|
|
6463
|
+
}
|
|
6464
|
+
const paletteOverrideDrafts = withPaletteOverrideDraft(
|
|
6465
|
+
state.paletteOverrideDrafts,
|
|
6466
|
+
state.previewed.paletteVariantId,
|
|
6467
|
+
state.previewed.paletteOverrides
|
|
6468
|
+
);
|
|
6469
|
+
const restoredOverrides = paletteOverrideDrafts[paletteVariantId] ?? null;
|
|
7370
6470
|
return {
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
6471
|
+
...state,
|
|
6472
|
+
previewed: {
|
|
6473
|
+
...state.previewed,
|
|
6474
|
+
paletteVariantId,
|
|
6475
|
+
paletteOverrides: restoredOverrides
|
|
6476
|
+
},
|
|
6477
|
+
paletteOverrideDrafts,
|
|
6478
|
+
notices: appendPaletteOverrideScopeNotice(state.notices, {
|
|
6479
|
+
previousOverrides: state.previewed.paletteOverrides,
|
|
6480
|
+
restoredOverrides
|
|
6481
|
+
}),
|
|
6482
|
+
saveStatus: { kind: "idle" }
|
|
7375
6483
|
};
|
|
7376
6484
|
}
|
|
7377
|
-
function
|
|
6485
|
+
function previewHeaderSelection(state, selection) {
|
|
6486
|
+
const headerStyleId = deriveNearestCompatibleHeaderStyle(
|
|
6487
|
+
selection.headerStyleId,
|
|
6488
|
+
selection.headerLayoutId
|
|
6489
|
+
);
|
|
6490
|
+
const headerLookId = findLegacyHeaderLookIdForSelection({
|
|
6491
|
+
layoutId: selection.headerLayoutId,
|
|
6492
|
+
styleId: headerStyleId
|
|
6493
|
+
});
|
|
7378
6494
|
return {
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
6495
|
+
...state,
|
|
6496
|
+
previewed: {
|
|
6497
|
+
...state.previewed,
|
|
6498
|
+
headerLayoutId: selection.headerLayoutId,
|
|
6499
|
+
headerStyleId,
|
|
6500
|
+
headerLookId
|
|
6501
|
+
},
|
|
6502
|
+
saveStatus: { kind: "idle" }
|
|
7383
6503
|
};
|
|
7384
6504
|
}
|
|
7385
|
-
function
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
case "monospace":
|
|
7392
|
-
return category;
|
|
7393
|
-
default:
|
|
7394
|
-
return "unknown";
|
|
6505
|
+
function withPaletteOverrideDraft(drafts, paletteVariantId, paletteOverrides) {
|
|
6506
|
+
const next = { ...drafts };
|
|
6507
|
+
if (paletteOverrides === null) {
|
|
6508
|
+
delete next[paletteVariantId];
|
|
6509
|
+
} else {
|
|
6510
|
+
next[paletteVariantId] = paletteOverrides;
|
|
7395
6511
|
}
|
|
6512
|
+
return next;
|
|
7396
6513
|
}
|
|
7397
|
-
function
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
slot,
|
|
7405
|
-
policy: preset.slotPolicies[slot],
|
|
7406
|
-
capability: capabilityForFamily(b.family, recordsByFamily)
|
|
7407
|
-
});
|
|
7408
|
-
const fitDelta = typographyFontFitRank(aFit.kind) - typographyFontFitRank(bFit.kind);
|
|
7409
|
-
if (fitDelta !== 0) return fitDelta;
|
|
7410
|
-
const popularityDelta = (a.popularity ?? Infinity) - (b.popularity ?? Infinity);
|
|
7411
|
-
if (popularityDelta !== 0) return popularityDelta;
|
|
7412
|
-
return a.family.localeCompare(b.family);
|
|
7413
|
-
}
|
|
7414
|
-
function typographyFontFitRank(kind) {
|
|
7415
|
-
switch (kind) {
|
|
7416
|
-
case "recommended":
|
|
7417
|
-
return 0;
|
|
7418
|
-
case "compatible":
|
|
7419
|
-
return 1;
|
|
7420
|
-
case "limited":
|
|
7421
|
-
return 2;
|
|
7422
|
-
case "risky":
|
|
7423
|
-
return 3;
|
|
7424
|
-
case "unknown":
|
|
7425
|
-
return 4;
|
|
7426
|
-
default: {
|
|
7427
|
-
const exhaustive = kind;
|
|
7428
|
-
return exhaustive;
|
|
7429
|
-
}
|
|
6514
|
+
function paletteOverrideDraftsFromSnapshot(snapshot) {
|
|
6515
|
+
return snapshot.paletteOverrides ? { [snapshot.paletteVariantId]: snapshot.paletteOverrides } : {};
|
|
6516
|
+
}
|
|
6517
|
+
function appendPaletteOverrideScopeNotice(notices, input) {
|
|
6518
|
+
const kind = input.restoredOverrides !== null ? "palette-overrides-restored" : input.previousOverrides !== null ? "palette-overrides-hidden" : null;
|
|
6519
|
+
if (!kind || notices.some((notice) => notice.kind === kind)) {
|
|
6520
|
+
return notices;
|
|
7430
6521
|
}
|
|
6522
|
+
return [...notices, { kind }];
|
|
7431
6523
|
}
|
|
7432
|
-
function
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
6524
|
+
function selectionSnapshotsEqual(a, b) {
|
|
6525
|
+
return a.siteStyleId === b.siteStyleId && a.selectionVersion === b.selectionVersion && a.selectionUpdatedAt === b.selectionUpdatedAt && a.headerLayoutId === b.headerLayoutId && a.headerStyleId === b.headerStyleId && a.headerLookId === b.headerLookId && a.footerLookId === b.footerLookId && a.buttonPersonalityId === b.buttonPersonalityId && a.paletteVariantId === b.paletteVariantId && a.typographyPresetId === b.typographyPresetId && a.typographyBodyFontOverride === b.typographyBodyFontOverride && a.typographyHeadingFontOverride === b.typographyHeadingFontOverride && paletteOverridesEqual(a.paletteOverrides, b.paletteOverrides);
|
|
6526
|
+
}
|
|
6527
|
+
function paletteOverridesEqual(a, b) {
|
|
6528
|
+
if (a === b) return true;
|
|
6529
|
+
if (!a || !b) return false;
|
|
6530
|
+
const keysA = Object.keys(a);
|
|
6531
|
+
const keysB = Object.keys(b);
|
|
6532
|
+
if (keysA.length !== keysB.length) return false;
|
|
6533
|
+
return keysA.every((key) => a[key] === b[key]);
|
|
6534
|
+
}
|
|
6535
|
+
|
|
6536
|
+
// ../preview-next/src/client/preview/siteChromeLookRows.ts
|
|
6537
|
+
function buildSiteChromeLookModels(input) {
|
|
6538
|
+
const selection = input.state.previewed;
|
|
6539
|
+
const common = {
|
|
6540
|
+
siteStyle: input.siteStyle,
|
|
6541
|
+
buttonPersonalityId: selection.buttonPersonalityId,
|
|
6542
|
+
paletteVariantId: selection.paletteVariantId,
|
|
6543
|
+
paletteOverrides: selection.paletteOverrides,
|
|
6544
|
+
headerLayoutId: selection.headerLayoutId,
|
|
6545
|
+
headerStyleId: selection.headerStyleId,
|
|
6546
|
+
headerLookId: selection.headerLookId,
|
|
6547
|
+
footerLookId: selection.footerLookId,
|
|
6548
|
+
headerSelectionContext: input.headerSelectionContext,
|
|
6549
|
+
footerSelectionContext: input.footerSelectionContext
|
|
6550
|
+
};
|
|
6551
|
+
const current = compileSiteThemeFromSelections(common);
|
|
6552
|
+
const renderedHeaderLayoutId = current.resolvedSelections.headerLayoutId;
|
|
6553
|
+
const renderedHeaderStyleId = current.resolvedSelections.headerStyleId;
|
|
6554
|
+
return {
|
|
6555
|
+
headerLayout: {
|
|
6556
|
+
renderedLayoutId: renderedHeaderLayoutId,
|
|
6557
|
+
options: getOrderedHeaderLayoutIdsForCuration(input.siteStyle).map(
|
|
6558
|
+
(layoutId) => {
|
|
6559
|
+
const layout = getHeaderLayout(layoutId);
|
|
6560
|
+
return {
|
|
6561
|
+
id: layoutId,
|
|
6562
|
+
label: layout?.label ?? layoutId,
|
|
6563
|
+
description: layout?.description,
|
|
6564
|
+
available: true
|
|
6565
|
+
};
|
|
6566
|
+
}
|
|
6567
|
+
)
|
|
6568
|
+
},
|
|
6569
|
+
headerStyle: {
|
|
6570
|
+
renderedStyleId: renderedHeaderStyleId,
|
|
6571
|
+
options: getOrderedHeaderStyleIdsForLayout(
|
|
6572
|
+
input.siteStyle,
|
|
6573
|
+
selection.headerLayoutId
|
|
6574
|
+
).map((styleId) => {
|
|
6575
|
+
const style = getHeaderStyle(styleId);
|
|
6576
|
+
return {
|
|
6577
|
+
id: styleId,
|
|
6578
|
+
label: style?.label ?? styleId,
|
|
6579
|
+
description: style?.description,
|
|
6580
|
+
available: true
|
|
6581
|
+
};
|
|
6582
|
+
})
|
|
6583
|
+
},
|
|
6584
|
+
footer: {
|
|
6585
|
+
renderedLookId: current.resolvedSelections.footerLookId,
|
|
6586
|
+
options: [
|
|
6587
|
+
{
|
|
6588
|
+
id: null,
|
|
6589
|
+
label: "Site style default",
|
|
6590
|
+
description: "Use the footer chosen for this site style.",
|
|
6591
|
+
available: true
|
|
6592
|
+
},
|
|
6593
|
+
...footerLookCatalog.map((look) => {
|
|
6594
|
+
const result = compileSiteThemeFromSelections({
|
|
6595
|
+
...common,
|
|
6596
|
+
footerLookId: look.id
|
|
6597
|
+
});
|
|
6598
|
+
const rejected = result.footerSelection.rejected.find(
|
|
6599
|
+
(item) => item.lookId === look.id
|
|
6600
|
+
);
|
|
6601
|
+
return {
|
|
6602
|
+
id: look.id,
|
|
6603
|
+
label: look.label,
|
|
6604
|
+
description: rejected ? rejected.reasons.map(footerLookRejectionReasonLabel).join(" ") : void 0,
|
|
6605
|
+
available: !rejected
|
|
6606
|
+
};
|
|
6607
|
+
})
|
|
6608
|
+
],
|
|
6609
|
+
diagnostics: diagnosticsForRequestedFooterSelection(
|
|
6610
|
+
selection.footerLookId,
|
|
6611
|
+
current.resolvedSelections.footerLookId,
|
|
6612
|
+
current.footerSelection.rejected
|
|
6613
|
+
)
|
|
7447
6614
|
}
|
|
6615
|
+
};
|
|
6616
|
+
}
|
|
6617
|
+
function cycleSiteChromeLookId(options, currentId, direction) {
|
|
6618
|
+
const cycleable = cycleableSiteChromeOptions(options);
|
|
6619
|
+
if (cycleable.length <= 1) return void 0;
|
|
6620
|
+
const currentIndex = cycleable.findIndex((option) => option.id === currentId);
|
|
6621
|
+
const safeIndex = currentIndex === -1 ? 0 : currentIndex;
|
|
6622
|
+
const nextIndex = direction === "next" ? (safeIndex + 1) % cycleable.length : safeIndex === 0 ? cycleable.length - 1 : safeIndex - 1;
|
|
6623
|
+
return cycleable[nextIndex]?.id;
|
|
6624
|
+
}
|
|
6625
|
+
function cycleableSiteChromeOptions(options) {
|
|
6626
|
+
return options.filter((option) => option.available);
|
|
6627
|
+
}
|
|
6628
|
+
function planSiteChromeLookSelection(command) {
|
|
6629
|
+
if (command.surface === "header") {
|
|
6630
|
+
const headerLookId = findLegacyHeaderLookIdForSelection({
|
|
6631
|
+
layoutId: command.layoutId,
|
|
6632
|
+
styleId: command.styleId
|
|
6633
|
+
});
|
|
6634
|
+
const lookCommand2 = headerLookId ? {
|
|
6635
|
+
kind: "select",
|
|
6636
|
+
surface: { kind: "site-header" },
|
|
6637
|
+
lookId: headerLookId
|
|
6638
|
+
} : {
|
|
6639
|
+
kind: "clear",
|
|
6640
|
+
surface: { kind: "site-header" }
|
|
6641
|
+
};
|
|
6642
|
+
return {
|
|
6643
|
+
kind: "header",
|
|
6644
|
+
writePlan: writePlanForLookCustomizationCommand(lookCommand2),
|
|
6645
|
+
next: {
|
|
6646
|
+
headerLayoutId: command.layoutId,
|
|
6647
|
+
headerStyleId: command.styleId,
|
|
6648
|
+
headerLookId
|
|
6649
|
+
}
|
|
6650
|
+
};
|
|
7448
6651
|
}
|
|
6652
|
+
const lookCommand = command.lookId ? {
|
|
6653
|
+
kind: "select",
|
|
6654
|
+
surface: { kind: "site-footer" },
|
|
6655
|
+
lookId: command.lookId
|
|
6656
|
+
} : {
|
|
6657
|
+
kind: "clear",
|
|
6658
|
+
surface: { kind: "site-footer" }
|
|
6659
|
+
};
|
|
6660
|
+
return {
|
|
6661
|
+
kind: "footer",
|
|
6662
|
+
writePlan: writePlanForLookCustomizationCommand(lookCommand),
|
|
6663
|
+
next: { footerLookId: command.lookId }
|
|
6664
|
+
};
|
|
7449
6665
|
}
|
|
7450
|
-
function
|
|
7451
|
-
|
|
6666
|
+
function diagnosticsForRequestedFooterSelection(requestedLookId, renderedLookId, rejected) {
|
|
6667
|
+
if (!requestedLookId || requestedLookId === renderedLookId) return [];
|
|
6668
|
+
const rejectedRequest = rejected.find(
|
|
6669
|
+
(item) => item.lookId === requestedLookId
|
|
6670
|
+
);
|
|
6671
|
+
return rejectedRequest?.reasons.map(footerLookRejectionReasonLabel) ?? [];
|
|
7452
6672
|
}
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
6673
|
+
|
|
6674
|
+
// ../preview-next/src/client/preview/typographySelectionInput.ts
|
|
6675
|
+
function typographySelectionInputForSnapshot(snapshot, theme) {
|
|
6676
|
+
if (snapshot.typographyPresetId === null && theme?.typography) {
|
|
6677
|
+
return {
|
|
6678
|
+
typographySelection: {
|
|
6679
|
+
kind: "custom",
|
|
6680
|
+
typography: theme.typography
|
|
6681
|
+
}
|
|
6682
|
+
};
|
|
7462
6683
|
}
|
|
7463
|
-
return
|
|
6684
|
+
return {
|
|
6685
|
+
typographyPresetId: snapshot.typographyPresetId,
|
|
6686
|
+
typographyBodyFontOverride: snapshot.typographyBodyFontOverride,
|
|
6687
|
+
typographyHeadingFontOverride: snapshot.typographyHeadingFontOverride
|
|
6688
|
+
};
|
|
7464
6689
|
}
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
6690
|
+
|
|
6691
|
+
// ../preview-next/src/client/preview/styleConfiguratorSnapshot.ts
|
|
6692
|
+
function resolveStyleConfiguratorInitialSnapshot(input) {
|
|
6693
|
+
const themeSiteStyleId = siteStyleIdFromTheme(input.theme);
|
|
6694
|
+
if (!themeSiteStyleId) return null;
|
|
6695
|
+
const siteStyle = getCuratedSiteStyle(themeSiteStyleId);
|
|
6696
|
+
if (!siteStyle) return null;
|
|
6697
|
+
const compiled = compileSiteThemeFromSelections({
|
|
6698
|
+
siteStyle,
|
|
6699
|
+
buttonPersonalityId: input.initialSelections.buttonPersonalityId,
|
|
6700
|
+
paletteVariantId: input.initialSelections.paletteVariantId,
|
|
6701
|
+
paletteOverrides: input.initialSelections.paletteOverrides,
|
|
6702
|
+
headerLayoutId: input.initialSelections.headerLayoutId ?? null,
|
|
6703
|
+
headerStyleId: input.initialSelections.headerStyleId ?? null,
|
|
6704
|
+
...typographySelectionInputForSnapshot(input.initialSelections, input.theme),
|
|
6705
|
+
headerLookId: input.initialSelections.headerLookId ?? null,
|
|
6706
|
+
footerLookId: input.initialSelections.footerLookId ?? null,
|
|
6707
|
+
headerSelectionContext: input.headerSelectionContext,
|
|
6708
|
+
footerSelectionContext: input.footerSelectionContext
|
|
6709
|
+
});
|
|
6710
|
+
const paletteChanged = input.initialSelections.paletteVariantId !== null && compiled.resolvedSelections.paletteVariantId !== input.initialSelections.paletteVariantId;
|
|
6711
|
+
return {
|
|
6712
|
+
siteStyleId: siteStyle.id,
|
|
6713
|
+
selectionVersion: input.initialSelections.selectionVersion ?? 0,
|
|
6714
|
+
selectionUpdatedAt: input.initialSelections.selectionUpdatedAt ?? null,
|
|
6715
|
+
headerLayoutId: compiled.resolvedSelections.headerLayoutId,
|
|
6716
|
+
headerStyleId: compiled.resolvedSelections.headerStyleId,
|
|
6717
|
+
headerLookId: compiled.requestedSelections.headerLookId,
|
|
6718
|
+
footerLookId: compiled.requestedSelections.footerLookId,
|
|
6719
|
+
buttonPersonalityId: compiled.resolvedSelections.buttonPersonalityId,
|
|
6720
|
+
paletteVariantId: compiled.resolvedSelections.paletteVariantId,
|
|
6721
|
+
paletteOverrides: paletteChanged ? null : input.initialSelections.paletteOverrides,
|
|
6722
|
+
typographyPresetId: compiled.resolvedSelections.typographyPresetId,
|
|
6723
|
+
typographyBodyFontOverride: compiled.resolvedSelections.typographyBodyFontOverride,
|
|
6724
|
+
typographyHeadingFontOverride: compiled.resolvedSelections.typographyHeadingFontOverride
|
|
6725
|
+
};
|
|
7468
6726
|
}
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
6727
|
+
|
|
6728
|
+
// ../preview-next/src/client/preview/siteStylePreviewPlanner.ts
|
|
6729
|
+
function planSiteStylePreviewChange(input) {
|
|
6730
|
+
const compiled = compileSiteThemeFromSelections({
|
|
6731
|
+
siteStyle: input.siteStyle,
|
|
6732
|
+
buttonPersonalityId: input.selection.buttonPersonalityId,
|
|
6733
|
+
paletteVariantId: input.selection.paletteVariantId,
|
|
6734
|
+
paletteOverrides: input.selection.paletteOverrides,
|
|
6735
|
+
...typographySelectionInputForSnapshot(input.selection, input.baseTheme),
|
|
6736
|
+
headerLayoutId: input.selection.headerLayoutId,
|
|
6737
|
+
headerStyleId: input.selection.headerStyleId,
|
|
6738
|
+
headerLookId: input.selection.headerLookId,
|
|
6739
|
+
footerLookId: input.selection.footerLookId,
|
|
6740
|
+
headerSelectionContext: input.headerSelectionContext,
|
|
6741
|
+
footerSelectionContext: input.footerSelectionContext
|
|
6742
|
+
});
|
|
6743
|
+
return {
|
|
6744
|
+
themeOverlay: compiled.theme,
|
|
6745
|
+
resolvedSelections: compiled.resolvedSelections,
|
|
6746
|
+
chromeSelection: {
|
|
6747
|
+
headerLookId: input.selection.headerLookId,
|
|
6748
|
+
footerLookId: input.selection.footerLookId
|
|
7480
6749
|
},
|
|
7481
|
-
|
|
6750
|
+
warnings: compiled.warnings
|
|
6751
|
+
};
|
|
6752
|
+
}
|
|
6753
|
+
|
|
6754
|
+
// ../preview-next/src/client/blocks/previewCustomizeControlPlan.ts
|
|
6755
|
+
var ABSOLUTE_MAX_QUICK_FIELDS = 3;
|
|
6756
|
+
var QUICK_FIELD_PRIORITY_BY_BLOCK_KIND = {
|
|
6757
|
+
"block.testimonials": [
|
|
6758
|
+
"avatarLayout",
|
|
6759
|
+
"gridColumns",
|
|
6760
|
+
"slidesToShow",
|
|
6761
|
+
"maxEntries",
|
|
6762
|
+
"autoplay"
|
|
7482
6763
|
],
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
6764
|
+
"block.image-gallery": [
|
|
6765
|
+
"aspectRatio",
|
|
6766
|
+
"slidesToShow",
|
|
6767
|
+
"fullBleed",
|
|
6768
|
+
"marqueeSpeed",
|
|
6769
|
+
"marqueePauseOnHover"
|
|
6770
|
+
],
|
|
6771
|
+
"block.event-calendar": [
|
|
6772
|
+
"listLayout",
|
|
6773
|
+
"eventsPerPage",
|
|
6774
|
+
"showFilters",
|
|
6775
|
+
"calendarView",
|
|
6776
|
+
"eventSurface"
|
|
6777
|
+
],
|
|
6778
|
+
"block.event-listing": [
|
|
6779
|
+
"layout",
|
|
6780
|
+
"columns",
|
|
6781
|
+
"eventsPerPage",
|
|
6782
|
+
"showFilters",
|
|
6783
|
+
"eventSurface"
|
|
6784
|
+
]
|
|
6785
|
+
};
|
|
6786
|
+
function createPreviewCustomizeControlPlan({
|
|
6787
|
+
blockKind,
|
|
6788
|
+
fields,
|
|
6789
|
+
content,
|
|
6790
|
+
maxQuickFields = ABSOLUTE_MAX_QUICK_FIELDS
|
|
7492
6791
|
}) {
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
/* @__PURE__ */ jsx(
|
|
7498
|
-
"button",
|
|
7499
|
-
{
|
|
7500
|
-
type: "button",
|
|
7501
|
-
onClick: () => onCycle("prev"),
|
|
7502
|
-
className: "grid h-8 w-8 place-items-center hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
7503
|
-
"aria-label": `Previous ${label.toLowerCase()}`,
|
|
7504
|
-
disabled: disabled || cycleableSiteChromeOptions(options).length <= 1,
|
|
7505
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
7506
|
-
}
|
|
7507
|
-
),
|
|
7508
|
-
/* @__PURE__ */ jsx(
|
|
7509
|
-
"button",
|
|
7510
|
-
{
|
|
7511
|
-
type: "button",
|
|
7512
|
-
onClick: () => onCycle("next"),
|
|
7513
|
-
className: "grid h-8 w-8 place-items-center border-l hover:bg-muted disabled:cursor-not-allowed disabled:opacity-50",
|
|
7514
|
-
"aria-label": `Next ${label.toLowerCase()}`,
|
|
7515
|
-
disabled: disabled || cycleableSiteChromeOptions(options).length <= 1,
|
|
7516
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
7517
|
-
}
|
|
7518
|
-
)
|
|
7519
|
-
] })
|
|
7520
|
-
] }),
|
|
7521
|
-
diagnostics.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "mb-3 list-none space-y-1 p-0 text-xs text-amber-700", children: diagnostics.map((diagnostic) => /* @__PURE__ */ jsx("li", { children: diagnostic }, diagnostic)) }) : null,
|
|
7522
|
-
/* @__PURE__ */ jsx("ul", { role: "radiogroup", "aria-label": ariaLabel, className: "list-none space-y-1 p-0", children: options.map((look) => /* @__PURE__ */ jsx(
|
|
7523
|
-
PickerOption,
|
|
7524
|
-
{
|
|
7525
|
-
selected: look.id === currentId,
|
|
7526
|
-
label: look.label,
|
|
7527
|
-
description: look.description,
|
|
7528
|
-
onSelect: () => onPreview(look.id),
|
|
7529
|
-
disabled: disabled || !look.available
|
|
7530
|
-
},
|
|
7531
|
-
look.id ?? "site-style-default"
|
|
7532
|
-
)) })
|
|
7533
|
-
] });
|
|
7534
|
-
}
|
|
7535
|
-
function PaletteRow({ expanded, onToggle, siteStyle, currentId, currentLabel, currentSwatch, onPreview, disabled }) {
|
|
7536
|
-
const options = useMemo(
|
|
7537
|
-
() => {
|
|
7538
|
-
const recommended = requireEntriesForCuratedChoices(paletteVariants, siteStyle.paletteVariantChoices);
|
|
7539
|
-
if (recommended.some((variant) => variant.id === currentId)) {
|
|
7540
|
-
return recommended;
|
|
7541
|
-
}
|
|
7542
|
-
const current = findPaletteVariant(currentId);
|
|
7543
|
-
return current ? [current, ...recommended] : recommended;
|
|
7544
|
-
},
|
|
7545
|
-
[currentId, siteStyle.paletteVariantChoices]
|
|
6792
|
+
const valueReader = createVisibilityValueReader(content);
|
|
6793
|
+
const quickPriority = QUICK_FIELD_PRIORITY_BY_BLOCK_KIND[blockKind] ?? [];
|
|
6794
|
+
const quickPriorityIndex = new Map(
|
|
6795
|
+
quickPriority.map((fieldId, index) => [fieldId, index])
|
|
7546
6796
|
);
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
return /* @__PURE__ */ jsx(
|
|
7558
|
-
PickerOption,
|
|
7559
|
-
{
|
|
7560
|
-
selected: variant.id === currentId,
|
|
7561
|
-
label: variant.name,
|
|
7562
|
-
description: variant.description,
|
|
7563
|
-
swatch: primaryHex,
|
|
7564
|
-
onSelect: () => onPreview(variant.id),
|
|
7565
|
-
disabled
|
|
7566
|
-
},
|
|
7567
|
-
variant.id
|
|
7568
|
-
);
|
|
7569
|
-
}) })
|
|
6797
|
+
const maxQuick = Math.max(0, Math.min(ABSOLUTE_MAX_QUICK_FIELDS, maxQuickFields));
|
|
6798
|
+
const visibleControls = [];
|
|
6799
|
+
const hiddenControls = [];
|
|
6800
|
+
for (const field of fields) {
|
|
6801
|
+
if (isThemeV2NormalEditorRawStyleFieldName(field.id)) {
|
|
6802
|
+
hiddenControls.push({
|
|
6803
|
+
fieldId: field.id,
|
|
6804
|
+
reason: "theme-v2-raw-style-field"
|
|
6805
|
+
});
|
|
6806
|
+
continue;
|
|
7570
6807
|
}
|
|
7571
|
-
|
|
7572
|
-
}
|
|
7573
|
-
|
|
7574
|
-
const mergedPalette = useMemo(() => {
|
|
7575
|
-
return variant.colors.map((color) => ({
|
|
7576
|
-
name: color.name,
|
|
7577
|
-
hex: overrides?.[color.name] ?? color.hex
|
|
7578
|
-
}));
|
|
7579
|
-
}, [variant, overrides]);
|
|
7580
|
-
const overrideCount = overrides ? Object.keys(overrides).length : 0;
|
|
7581
|
-
const currentLabel = overrideCount > 0 ? `${overrideCount} colour${overrideCount === 1 ? "" : "s"} customised` : "Use variant colours";
|
|
7582
|
-
return /* @__PURE__ */ jsx(
|
|
7583
|
-
StyleRowFrame,
|
|
7584
|
-
{
|
|
7585
|
-
label: "Brand colours",
|
|
7586
|
-
currentLabel,
|
|
7587
|
-
expanded,
|
|
7588
|
-
onToggle,
|
|
7589
|
-
children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
7590
|
-
/* @__PURE__ */ jsx(
|
|
7591
|
-
PaletteTokenEditor,
|
|
7592
|
-
{
|
|
7593
|
-
palette: mergedPalette,
|
|
7594
|
-
onChange: onTokenChange,
|
|
7595
|
-
feedbackRoles: [],
|
|
7596
|
-
surfaceRoles: [],
|
|
7597
|
-
showContrastChecks: false
|
|
7598
|
-
}
|
|
7599
|
-
),
|
|
7600
|
-
overrideCount > 0 ? /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
|
|
7601
|
-
Button,
|
|
7602
|
-
{
|
|
7603
|
-
type: "button",
|
|
7604
|
-
variant: "outline",
|
|
7605
|
-
size: "sm",
|
|
7606
|
-
onClick: onReset,
|
|
7607
|
-
disabled,
|
|
7608
|
-
children: "Reset to variant"
|
|
7609
|
-
}
|
|
7610
|
-
) }) : null
|
|
7611
|
-
] })
|
|
6808
|
+
if (isHeaderField(field)) {
|
|
6809
|
+
hiddenControls.push({ fieldId: field.id, reason: "header-field" });
|
|
6810
|
+
continue;
|
|
7612
6811
|
}
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
role: "radio",
|
|
7621
|
-
"aria-checked": selected,
|
|
7622
|
-
onClick: onSelect,
|
|
7623
|
-
disabled,
|
|
7624
|
-
className: cn(
|
|
7625
|
-
"flex w-full items-center gap-3 rounded-md border px-3 py-2 text-left transition",
|
|
7626
|
-
selected ? "border-foreground bg-accent/40 shadow-sm" : "border-transparent bg-background hover:border-foreground/40 hover:bg-accent/20",
|
|
7627
|
-
disabled && "cursor-not-allowed opacity-60"
|
|
7628
|
-
),
|
|
7629
|
-
children: [
|
|
7630
|
-
swatch ? /* @__PURE__ */ jsx(
|
|
7631
|
-
"span",
|
|
7632
|
-
{
|
|
7633
|
-
className: "h-5 w-5 shrink-0 rounded-full border border-black/10",
|
|
7634
|
-
style: { backgroundColor: swatch },
|
|
7635
|
-
"aria-hidden": "true"
|
|
7636
|
-
}
|
|
7637
|
-
) : null,
|
|
7638
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
7639
|
-
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: label }),
|
|
7640
|
-
description ? /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
7641
|
-
] })
|
|
7642
|
-
]
|
|
6812
|
+
const intent = getFieldIntent(field);
|
|
6813
|
+
if (intent !== "display" && intent !== "behavior") {
|
|
6814
|
+
hiddenControls.push({
|
|
6815
|
+
fieldId: field.id,
|
|
6816
|
+
reason: "unsupported-intent"
|
|
6817
|
+
});
|
|
6818
|
+
continue;
|
|
7643
6819
|
}
|
|
7644
|
-
|
|
7645
|
-
}
|
|
7646
|
-
|
|
7647
|
-
if (isRecord(error)) {
|
|
7648
|
-
const status = error.status;
|
|
7649
|
-
const code = error.code;
|
|
7650
|
-
if (status === 409 || code === "resource:conflict") {
|
|
7651
|
-
return {
|
|
7652
|
-
kind: "stale",
|
|
7653
|
-
message: "This design changed elsewhere. Refreshing the latest version now."
|
|
7654
|
-
};
|
|
6820
|
+
if (!evaluateVisibility(field, valueReader, field.id)) {
|
|
6821
|
+
hiddenControls.push({ fieldId: field.id, reason: "not-visible" });
|
|
6822
|
+
continue;
|
|
7655
6823
|
}
|
|
6824
|
+
visibleControls.push({
|
|
6825
|
+
kind: "manifest-field",
|
|
6826
|
+
field,
|
|
6827
|
+
placement: "panel",
|
|
6828
|
+
intent
|
|
6829
|
+
});
|
|
7656
6830
|
}
|
|
6831
|
+
const quickFieldIds = new Set(
|
|
6832
|
+
visibleControls.filter((control) => quickPriorityIndex.has(control.field.id)).sort(
|
|
6833
|
+
(left, right) => (quickPriorityIndex.get(left.field.id) ?? Number.MAX_SAFE_INTEGER) - (quickPriorityIndex.get(right.field.id) ?? Number.MAX_SAFE_INTEGER)
|
|
6834
|
+
).slice(0, maxQuick).map((control) => control.field.id)
|
|
6835
|
+
);
|
|
7657
6836
|
return {
|
|
7658
|
-
|
|
7659
|
-
|
|
6837
|
+
quickControls: visibleControls.filter((control) => quickFieldIds.has(control.field.id)).map((control) => ({ ...control, placement: "quick" })),
|
|
6838
|
+
panelControls: visibleControls.filter(
|
|
6839
|
+
(control) => !quickFieldIds.has(control.field.id)
|
|
6840
|
+
),
|
|
6841
|
+
hiddenControls
|
|
7660
6842
|
};
|
|
7661
6843
|
}
|
|
7662
|
-
function
|
|
7663
|
-
return
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
return /* @__PURE__ */ jsxs("div", { role: "status", className: "rounded-md border border-warning/40 bg-warning/10 px-3 py-2 text-xs text-warning-foreground", children: [
|
|
7667
|
-
/* @__PURE__ */ jsx("ul", { className: "space-y-1", children: warnings.map((warning, index) => /* @__PURE__ */ jsx("li", { children: describeWarning(warning) }, `${warning.kind}-${index}`)) }),
|
|
7668
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: onDismiss, className: "mt-2 underline", children: "Dismiss" })
|
|
7669
|
-
] });
|
|
7670
|
-
}
|
|
7671
|
-
function NoticeBanner({ notices, onDismiss }) {
|
|
7672
|
-
return /* @__PURE__ */ jsxs("div", { role: "status", className: "rounded-md border border-muted-foreground/20 bg-muted/40 px-3 py-2 text-xs", children: [
|
|
7673
|
-
/* @__PURE__ */ jsx("ul", { className: "space-y-1", children: notices.map((notice, index) => /* @__PURE__ */ jsx("li", { children: describeNotice(notice) }, `${notice.kind}-${index}`)) }),
|
|
7674
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: onDismiss, className: "mt-2 underline", children: "Dismiss" })
|
|
7675
|
-
] });
|
|
6844
|
+
function createVisibilityValueReader(content) {
|
|
6845
|
+
return {
|
|
6846
|
+
getValue: (path) => getValueAtPath(content, path)
|
|
6847
|
+
};
|
|
7676
6848
|
}
|
|
7677
|
-
function
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
return
|
|
7683
|
-
}
|
|
7684
|
-
}
|
|
7685
|
-
function describeWarning(warning) {
|
|
7686
|
-
switch (warning.kind) {
|
|
7687
|
-
case "rejected-personality":
|
|
7688
|
-
return `Button style changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
|
|
7689
|
-
case "rejected-palette":
|
|
7690
|
-
return `Palette changed to ${warning.fellBackTo} because ${warning.requested} is not available.`;
|
|
7691
|
-
case "rejected-typography-preset":
|
|
7692
|
-
return `Typography changed to ${warning.fellBackTo} because ${warning.requested} is not offered for this site style.`;
|
|
7693
|
-
default: {
|
|
7694
|
-
const exhaustive = warning;
|
|
7695
|
-
return exhaustive;
|
|
6849
|
+
function getValueAtPath(source, path) {
|
|
6850
|
+
if (!path) return source;
|
|
6851
|
+
let current = source;
|
|
6852
|
+
for (const segment of path.split(".")) {
|
|
6853
|
+
if (!current || typeof current !== "object") {
|
|
6854
|
+
return void 0;
|
|
7696
6855
|
}
|
|
6856
|
+
current = current[segment];
|
|
7697
6857
|
}
|
|
6858
|
+
return current;
|
|
7698
6859
|
}
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
currentTemplate,
|
|
6860
|
+
|
|
6861
|
+
// ../preview-next/src/client/blocks/useBlockCustomizeControls.ts
|
|
6862
|
+
var MAX_CUSTOMIZE_POPOVER_ROWS = 6;
|
|
6863
|
+
var MAX_QUICK_MANIFEST_FIELDS = 3;
|
|
6864
|
+
function useBlockCustomizeControls({
|
|
6865
|
+
blockId,
|
|
6866
|
+
blockKind,
|
|
6867
|
+
content,
|
|
6868
|
+
uiStore,
|
|
7709
6869
|
theme,
|
|
7710
|
-
themeId = null,
|
|
7711
|
-
themeSelectionId = null,
|
|
7712
|
-
themeSelectionVersion = null,
|
|
7713
|
-
themeSelectionUpdatedAt = null,
|
|
7714
|
-
themeSelectionButtonPersonalityId = null,
|
|
7715
|
-
themeSelectionPaletteVariantId = null,
|
|
7716
|
-
themeSelectionPaletteOverrides = null,
|
|
7717
|
-
themeSelectionHeaderLayoutId = null,
|
|
7718
|
-
themeSelectionHeaderStyleId = null,
|
|
7719
|
-
themeSelectionTypographyPresetId = null,
|
|
7720
|
-
themeSelectionTypographyBodyFontOverride = null,
|
|
7721
|
-
themeSelectionTypographyHeadingFontOverride = null,
|
|
7722
|
-
themeSelectionHeaderLookId = null,
|
|
7723
|
-
themeSelectionFooterLookId = null,
|
|
7724
|
-
themeSelectionHeaderContext,
|
|
7725
|
-
themeSelectionFooterContext,
|
|
7726
|
-
designRowRequest = null,
|
|
7727
|
-
apiClient,
|
|
7728
|
-
bearerToken,
|
|
7729
|
-
supabaseUrl,
|
|
7730
|
-
entrySubrouteContext,
|
|
7731
|
-
assistantPanel,
|
|
7732
6870
|
sdkConfig,
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
onTabChange,
|
|
7737
|
-
onClose,
|
|
7738
|
-
viewportMode,
|
|
7739
|
-
viewportWidth,
|
|
7740
|
-
zoom,
|
|
7741
|
-
onViewportModeChange,
|
|
7742
|
-
onViewportWidthChange,
|
|
7743
|
-
onZoomChange
|
|
6871
|
+
maxQuickFields = MAX_QUICK_MANIFEST_FIELDS,
|
|
6872
|
+
maxPopoverRows,
|
|
6873
|
+
builtInPopoverRows = 0
|
|
7744
6874
|
}) {
|
|
7745
|
-
const
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
[
|
|
7754
|
-
);
|
|
7755
|
-
const focusRequest = useUISelector(uiStore, (s) => s.focusRequest);
|
|
7756
|
-
const { canEdit } = usePreviewAuth();
|
|
7757
|
-
const dashboardSetupHandoff = useMemo(
|
|
7758
|
-
() => resolvePreviewDashboardSetupHandoff(),
|
|
7759
|
-
[]
|
|
7760
|
-
);
|
|
7761
|
-
const dashboardContinueUrl = useMemo(
|
|
7762
|
-
() => buildPreviewDashboardSetupUrl(dashboardBaseUrl, dashboardSetupHandoff),
|
|
7763
|
-
[dashboardBaseUrl, dashboardSetupHandoff]
|
|
7764
|
-
);
|
|
7765
|
-
const sidebarChrome = useMemo(
|
|
7766
|
-
() => resolvePreviewSidebarChromeModel(surfaceId),
|
|
7767
|
-
[surfaceId]
|
|
6875
|
+
const {
|
|
6876
|
+
blockFieldOptions,
|
|
6877
|
+
blockFieldExtensions,
|
|
6878
|
+
sdkConfig: contextSdkConfig
|
|
6879
|
+
} = useSdkConfig();
|
|
6880
|
+
const effectiveSdkConfig = sdkConfig ?? contextSdkConfig;
|
|
6881
|
+
const manifest = useMemo(
|
|
6882
|
+
() => resolveBlockManifest(blockKind, effectiveSdkConfig ?? null),
|
|
6883
|
+
[blockKind, effectiveSdkConfig]
|
|
7768
6884
|
);
|
|
7769
|
-
const
|
|
7770
|
-
()
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
6885
|
+
const preparedManifest = useMemo(() => {
|
|
6886
|
+
if (!manifest) return null;
|
|
6887
|
+
return prepareBlockEditorManifest({
|
|
6888
|
+
manifest,
|
|
6889
|
+
blockKind,
|
|
6890
|
+
styleGroups: theme?.styleGroups,
|
|
6891
|
+
blockFieldOptions,
|
|
6892
|
+
blockFieldExtensions,
|
|
6893
|
+
visibilityPolicy: hideThemeV2RawStyleFields
|
|
6894
|
+
});
|
|
6895
|
+
}, [
|
|
6896
|
+
blockFieldExtensions,
|
|
6897
|
+
blockFieldOptions,
|
|
6898
|
+
blockKind,
|
|
6899
|
+
manifest,
|
|
6900
|
+
theme?.styleGroups
|
|
6901
|
+
]);
|
|
6902
|
+
const fields = useMemo(() => {
|
|
6903
|
+
if (!preparedManifest) return [];
|
|
6904
|
+
return createManifestFormAdapter(preparedManifest.renderManifest).fields;
|
|
6905
|
+
}, [preparedManifest]);
|
|
6906
|
+
const preliminaryPlan = useMemo(
|
|
6907
|
+
() => createPreviewCustomizeControlPlan({
|
|
6908
|
+
blockKind,
|
|
6909
|
+
fields,
|
|
6910
|
+
content,
|
|
6911
|
+
maxQuickFields
|
|
7774
6912
|
}),
|
|
7775
|
-
[
|
|
6913
|
+
[blockKind, content, fields, maxQuickFields]
|
|
7776
6914
|
);
|
|
7777
|
-
const
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
6915
|
+
const budgetedMaxQuickFields = resolveQuickFieldBudget({
|
|
6916
|
+
requestedMaxQuickFields: maxQuickFields,
|
|
6917
|
+
maxPopoverRows,
|
|
6918
|
+
builtInPopoverRows,
|
|
6919
|
+
hasOverflowControls: preliminaryPlan.panelControls.length > 0
|
|
6920
|
+
});
|
|
6921
|
+
const controlPlan = useMemo(() => {
|
|
6922
|
+
if (budgetedMaxQuickFields === maxQuickFields) {
|
|
6923
|
+
return preliminaryPlan;
|
|
6924
|
+
}
|
|
6925
|
+
return createPreviewCustomizeControlPlan({
|
|
6926
|
+
blockKind,
|
|
6927
|
+
fields,
|
|
6928
|
+
content,
|
|
6929
|
+
maxQuickFields: budgetedMaxQuickFields
|
|
6930
|
+
});
|
|
6931
|
+
}, [
|
|
6932
|
+
blockKind,
|
|
6933
|
+
budgetedMaxQuickFields,
|
|
6934
|
+
content,
|
|
6935
|
+
fields,
|
|
6936
|
+
maxQuickFields,
|
|
6937
|
+
preliminaryPlan
|
|
6938
|
+
]);
|
|
6939
|
+
const quickFields = useMemo(
|
|
6940
|
+
() => controlPlan.quickControls.map((control) => stripTopLevelRoutingUi(control.field)),
|
|
6941
|
+
[controlPlan.quickControls]
|
|
7783
6942
|
);
|
|
7784
|
-
const
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
(nextItems) => {
|
|
7788
|
-
controllerBlocks.actions.setList(nextItems);
|
|
7789
|
-
const drafts = uiStore.getState().drafts;
|
|
7790
|
-
const extractData = (content) => {
|
|
7791
|
-
if (!content || typeof content !== "object") return null;
|
|
7792
|
-
const obj = content;
|
|
7793
|
-
if ("data" in obj && obj.data && typeof obj.data === "object") {
|
|
7794
|
-
return obj.data;
|
|
7795
|
-
}
|
|
7796
|
-
return obj;
|
|
7797
|
-
};
|
|
7798
|
-
for (const block of nextItems) {
|
|
7799
|
-
if (!block.id) continue;
|
|
7800
|
-
const baseline = extractData(
|
|
7801
|
-
block.content ?? block.draftContent ?? block.publishedContent ?? null
|
|
7802
|
-
);
|
|
7803
|
-
const blockId = unsafeAsEditorBlockId(block.id);
|
|
7804
|
-
if (drafts.getBlockSnapshot(blockId)) {
|
|
7805
|
-
drafts.updateBlockBaseline(blockId, baseline, { kind: block.kind });
|
|
7806
|
-
} else {
|
|
7807
|
-
drafts.initNewBlock(blockId, baseline, { kind: block.kind });
|
|
7808
|
-
}
|
|
7809
|
-
}
|
|
7810
|
-
},
|
|
7811
|
-
[controllerBlocks.actions, uiStore]
|
|
6943
|
+
const panelFields = useMemo(
|
|
6944
|
+
() => controlPlan.panelControls.map((control) => stripTopLevelRoutingUi(control.field)),
|
|
6945
|
+
[controlPlan.panelControls]
|
|
7812
6946
|
);
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
6947
|
+
const backend = useMemo(() => {
|
|
6948
|
+
if (!preparedManifest) return null;
|
|
6949
|
+
return createStoreBackend({
|
|
6950
|
+
scope: "blocks",
|
|
6951
|
+
store: uiStore,
|
|
6952
|
+
blockId: unsafeAsEditorBlockId(blockId),
|
|
6953
|
+
validateFn: (values) => validateBlockManifestIssues(preparedManifest.validationManifest, values, "strict")
|
|
7820
6954
|
});
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
entryData,
|
|
7832
|
-
contentTypeSchema,
|
|
7833
|
-
referenceContentTypeKeys,
|
|
7834
|
-
draftContent,
|
|
7835
|
-
currentTemplate,
|
|
7836
|
-
theme,
|
|
7837
|
-
apiClient,
|
|
7838
|
-
bearerToken,
|
|
7839
|
-
supabaseUrl,
|
|
7840
|
-
entrySubrouteContext,
|
|
7841
|
-
metadataPanel: metadataSectionContent,
|
|
7842
|
-
mediaAssets,
|
|
7843
|
-
widgets: contentFormWidgets,
|
|
7844
|
-
viewportMode,
|
|
7845
|
-
viewportWidth,
|
|
7846
|
-
zoom,
|
|
7847
|
-
onViewportModeChange,
|
|
7848
|
-
onViewportWidthChange,
|
|
7849
|
-
onZoomChange
|
|
7850
|
-
}
|
|
7851
|
-
) : pageId ? /* @__PURE__ */ jsx(
|
|
7852
|
-
PageBlockEditorPanel,
|
|
7853
|
-
{
|
|
7854
|
-
siteId,
|
|
7855
|
-
pageId,
|
|
7856
|
-
theme,
|
|
7857
|
-
apiClient,
|
|
7858
|
-
bearerToken,
|
|
7859
|
-
supabaseUrl,
|
|
7860
|
-
blockItems,
|
|
7861
|
-
uiStoreForBlockEditor,
|
|
7862
|
-
blockEditorRef,
|
|
7863
|
-
onBlocksChange: handleBlocksChange,
|
|
7864
|
-
metadataPanel: metadataSectionContent,
|
|
7865
|
-
designPanel: canInspectSiteStyle(siteStyleAccess) ? /* @__PURE__ */ jsx(
|
|
7866
|
-
StyleConfigurator,
|
|
7867
|
-
{
|
|
7868
|
-
siteId,
|
|
7869
|
-
apiClient,
|
|
7870
|
-
theme,
|
|
7871
|
-
themeId,
|
|
7872
|
-
selectionId: themeSelectionId,
|
|
7873
|
-
selectionVersion: themeSelectionVersion,
|
|
7874
|
-
selectionUpdatedAt: themeSelectionUpdatedAt,
|
|
7875
|
-
initialSelections: {
|
|
7876
|
-
selectionVersion: themeSelectionVersion,
|
|
7877
|
-
selectionUpdatedAt: themeSelectionUpdatedAt,
|
|
7878
|
-
buttonPersonalityId: themeSelectionButtonPersonalityId,
|
|
7879
|
-
paletteVariantId: themeSelectionPaletteVariantId,
|
|
7880
|
-
paletteOverrides: themeSelectionPaletteOverrides,
|
|
7881
|
-
headerLayoutId: themeSelectionHeaderLayoutId,
|
|
7882
|
-
headerStyleId: themeSelectionHeaderStyleId,
|
|
7883
|
-
typographyPresetId: themeSelectionTypographyPresetId,
|
|
7884
|
-
typographyBodyFontOverride: themeSelectionTypographyBodyFontOverride,
|
|
7885
|
-
typographyHeadingFontOverride: themeSelectionTypographyHeadingFontOverride,
|
|
7886
|
-
headerLookId: themeSelectionHeaderLookId,
|
|
7887
|
-
footerLookId: themeSelectionFooterLookId
|
|
7888
|
-
},
|
|
7889
|
-
headerSelectionContext: themeSelectionHeaderContext,
|
|
7890
|
-
footerSelectionContext: themeSelectionFooterContext,
|
|
7891
|
-
expandedRowRequest: designRowRequest,
|
|
7892
|
-
siteStyleAccess
|
|
7893
|
-
}
|
|
7894
|
-
) : null,
|
|
7895
|
-
sdkConfig: sdkConfig ?? null,
|
|
7896
|
-
mediaAssets,
|
|
7897
|
-
viewportMode,
|
|
7898
|
-
viewportWidth,
|
|
7899
|
-
zoom,
|
|
7900
|
-
onViewportModeChange,
|
|
7901
|
-
onViewportWidthChange,
|
|
7902
|
-
onZoomChange
|
|
7903
|
-
}
|
|
7904
|
-
) : /* @__PURE__ */ jsx("div", { className: "flex h-full flex-col", children: /* @__PURE__ */ jsx("div", { className: "flex-1 p-4", children: /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed px-4 py-6 text-sm text-muted-foreground", children: "Block editing is only available when a page is selected." }) }) });
|
|
7905
|
-
const assistantPanelDisplay = assistantAvailable ? assistantPanel : /* @__PURE__ */ jsx("div", { className: "flex h-full flex-col items-center justify-center p-6 text-center text-sm text-muted-foreground", children: "AI Assistant is available for pages in preview mode." });
|
|
7906
|
-
return /* @__PURE__ */ jsx(
|
|
7907
|
-
"div",
|
|
7908
|
-
{
|
|
7909
|
-
className: `flex h-full min-h-0 flex-col overflow-hidden pb-[calc(var(--builder-editor-chrome-offset,0px)+var(--builder-preview-banner-offset,0px))] ${sidebarChrome.rootClassName}`,
|
|
7910
|
-
"data-preview-sidebar-tone": sidebarChrome.tone,
|
|
7911
|
-
children: /* @__PURE__ */ jsxs(
|
|
7912
|
-
Tabs,
|
|
7913
|
-
{
|
|
7914
|
-
value: effectiveActiveTab,
|
|
7915
|
-
onValueChange: (value) => onTabChange(
|
|
7916
|
-
resolvePreviewSidebarTab(value)
|
|
7917
|
-
),
|
|
7918
|
-
className: "flex h-full min-h-0 flex-col overflow-hidden",
|
|
7919
|
-
children: [
|
|
7920
|
-
/* @__PURE__ */ jsxs(
|
|
7921
|
-
"div",
|
|
7922
|
-
{
|
|
7923
|
-
className: `shrink-0 flex items-center justify-between px-4 py-3 ${sidebarChrome.headerClassName}`,
|
|
7924
|
-
children: [
|
|
7925
|
-
/* @__PURE__ */ jsxs(TabsList, { className: "h-8", children: [
|
|
7926
|
-
/* @__PURE__ */ jsx(TabsTrigger, { value: "editor", children: "Editor" }),
|
|
7927
|
-
showAssistantTab ? /* @__PURE__ */ jsx(TabsTrigger, { value: "assistant", children: "AI Assistant" }) : null
|
|
7928
|
-
] }),
|
|
7929
|
-
/* @__PURE__ */ jsx(
|
|
7930
|
-
Button,
|
|
7931
|
-
{
|
|
7932
|
-
variant: "ghost",
|
|
7933
|
-
size: "icon",
|
|
7934
|
-
onClick: onClose,
|
|
7935
|
-
"aria-label": "Close sidebar",
|
|
7936
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
7937
|
-
}
|
|
7938
|
-
)
|
|
7939
|
-
]
|
|
7940
|
-
}
|
|
7941
|
-
),
|
|
7942
|
-
editorGuidance ? /* @__PURE__ */ jsx("div", { className: "shrink-0 border-b px-4 py-3", children: /* @__PURE__ */ jsx(
|
|
7943
|
-
PreviewEditorGuidanceCard,
|
|
7944
|
-
{
|
|
7945
|
-
guidance: editorGuidance,
|
|
7946
|
-
completeSetupDisabled: !dashboardContinueUrl,
|
|
7947
|
-
onCompleteSetup: () => {
|
|
7948
|
-
if (!dashboardContinueUrl || typeof window === "undefined")
|
|
7949
|
-
return;
|
|
7950
|
-
window.location.href = dashboardContinueUrl;
|
|
7951
|
-
}
|
|
7952
|
-
}
|
|
7953
|
-
) }) : null,
|
|
7954
|
-
/* @__PURE__ */ jsx(
|
|
7955
|
-
TabsContent,
|
|
7956
|
-
{
|
|
7957
|
-
value: "editor",
|
|
7958
|
-
forceMount: true,
|
|
7959
|
-
className: "mt-0 min-h-0 flex-1 overflow-hidden data-[state=inactive]:hidden",
|
|
7960
|
-
children: editorPanel
|
|
7961
|
-
}
|
|
7962
|
-
),
|
|
7963
|
-
showAssistantTab ? /* @__PURE__ */ jsx(
|
|
7964
|
-
TabsContent,
|
|
7965
|
-
{
|
|
7966
|
-
value: "assistant",
|
|
7967
|
-
forceMount: true,
|
|
7968
|
-
className: "mt-0 min-h-0 flex-1 overflow-hidden data-[state=inactive]:hidden",
|
|
7969
|
-
children: assistantPanelDisplay
|
|
7970
|
-
}
|
|
7971
|
-
) : null
|
|
7972
|
-
]
|
|
7973
|
-
}
|
|
7974
|
-
)
|
|
7975
|
-
}
|
|
7976
|
-
);
|
|
6955
|
+
}, [blockId, preparedManifest, uiStore]);
|
|
6956
|
+
return {
|
|
6957
|
+
manifest,
|
|
6958
|
+
controlPlan,
|
|
6959
|
+
quickFields,
|
|
6960
|
+
panelFields,
|
|
6961
|
+
backend,
|
|
6962
|
+
hasControls: quickFields.length > 0 || panelFields.length > 0,
|
|
6963
|
+
hasOverflowControls: panelFields.length > 0
|
|
6964
|
+
};
|
|
7977
6965
|
}
|
|
7978
|
-
function
|
|
7979
|
-
|
|
6966
|
+
function resolveQuickFieldBudget({
|
|
6967
|
+
requestedMaxQuickFields,
|
|
6968
|
+
maxPopoverRows,
|
|
6969
|
+
builtInPopoverRows,
|
|
6970
|
+
hasOverflowControls
|
|
7980
6971
|
}) {
|
|
7981
|
-
const
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
getRouteMetadataManifestForType(contentTypeKey)
|
|
7985
|
-
);
|
|
7986
|
-
}, [contentTypeKey]);
|
|
7987
|
-
const validation = useMemo(
|
|
7988
|
-
() => createManifestValidation(manifest),
|
|
7989
|
-
[manifest]
|
|
7990
|
-
);
|
|
7991
|
-
const backend = useMemo(
|
|
7992
|
-
() => createStoreBackend({
|
|
7993
|
-
scope: "metadata",
|
|
7994
|
-
store: uiStore,
|
|
7995
|
-
validateFn: (values) => {
|
|
7996
|
-
const result = validation.schema.safeParse(values);
|
|
7997
|
-
if (!result.success) {
|
|
7998
|
-
return result.error.issues;
|
|
7999
|
-
}
|
|
8000
|
-
return [];
|
|
8001
|
-
}
|
|
8002
|
-
}),
|
|
8003
|
-
[uiStore, validation]
|
|
6972
|
+
const cappedRequested = Math.max(
|
|
6973
|
+
0,
|
|
6974
|
+
Math.min(MAX_QUICK_MANIFEST_FIELDS, requestedMaxQuickFields)
|
|
8004
6975
|
);
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
6976
|
+
if (typeof maxPopoverRows !== "number") {
|
|
6977
|
+
return cappedRequested;
|
|
6978
|
+
}
|
|
6979
|
+
const settingsRowCount = hasOverflowControls ? 1 : 0;
|
|
6980
|
+
const availableRows = maxPopoverRows - builtInPopoverRows - settingsRowCount;
|
|
6981
|
+
return Math.max(0, Math.min(cappedRequested, availableRows));
|
|
6982
|
+
}
|
|
6983
|
+
function resolveBlockManifest(blockKind, sdkConfig) {
|
|
6984
|
+
return getBlockManifestFromSdkConfig(blockKind, sdkConfig) ?? getBlockDefinition(blockKind)?.manifest ?? null;
|
|
8013
6985
|
}
|
|
8014
6986
|
|
|
8015
|
-
export {
|
|
6987
|
+
export { BUILT_IN_REFERENCE_KINDS, BlockEditor, ButtonVariantField, ButtonWidgetProvider, EntryPickerField, EntryPickerWidgetProvider, FileField, IconPickerField, LinkField, LinkWidgetProvider, MAX_CUSTOMIZE_POPOVER_ROWS, MAX_QUICK_MANIFEST_FIELDS, MediaField, PreviewBlockCustomizeSelectionProvider, PreviewDesignCoordinatorProvider, PreviewThemeOverlayProvider, ReferenceField, ReferenceWidgetProvider, RichTextField, RichTextWidgetProvider, applyResolvedSelections, buildPreviewDashboardSetupUrl, buildSiteChromeLookModels, canApplySiteStyle, canInspectSiteStyle, cancelPreview, clearTypographyFontOverrides, createOptimisticActionRunner, createStyleConfiguratorState, cycleSiteChromeLookId, cycleableSiteChromeOptions, dismissNotices, dismissWarnings, isPreviewingChange, mapContentSchemaToFormFields, markApplyFailed, markApplySaved, markApplySaving, openRow, parseReferenceKind, planSiteChromeLookSelection, planSiteStylePreviewChange, previewButtonPersonality, previewFooterLook, previewHeaderLayout, previewHeaderStyle, previewPaletteVariant, previewSiteStyle, previewTypographyPreset, resolvePreviewDashboardSetupHandoff, resolvePreviewEditorGuidanceModel, resolvePreviewSetupBannerModel, resolvePreviewSidebarChromeModel, resolveSiteStyleAccess, resolveStyleConfiguratorInitialSnapshot, sanitizeDashboardPath, setPaletteOverrides, setTypographyBodyFontOverride, setTypographyHeadingFontOverride, syncStyleConfiguratorState, toggleRow, useBlockCustomizeControls, usePreviewBlockCustomizeSelectionOptional, usePreviewDesignCoordinator, usePreviewThemeOverlay, useRichTextImagePicker };
|