@delmaredigital/payload-puck 0.6.13 → 0.6.14
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/admin/EditWithPuckButton.d.ts +0 -1
- package/dist/admin/EditWithPuckButton.js +0 -2
- package/dist/admin/EditWithPuckCell.d.ts +0 -1
- package/dist/admin/EditWithPuckCell.js +0 -2
- package/dist/admin/PuckEditorView.d.ts +0 -1
- package/dist/admin/PuckEditorView.js +0 -2
- package/dist/admin/client.d.ts +0 -1
- package/dist/admin/client.js +0 -2
- package/dist/admin/generateAdminComponents.d.ts +0 -1
- package/dist/admin/generateAdminComponents.js +0 -2
- package/dist/admin/index.d.ts +0 -1
- package/dist/admin/index.js +0 -2
- package/dist/ai/collections/AiContext.d.ts +0 -1
- package/dist/ai/collections/AiContext.js +0 -2
- package/dist/ai/collections/AiPrompts.d.ts +0 -1
- package/dist/ai/collections/AiPrompts.js +0 -2
- package/dist/ai/createAiApiRoutes.d.ts +0 -1
- package/dist/ai/createAiApiRoutes.js +0 -2
- package/dist/ai/createAiGenerate.d.ts +0 -1
- package/dist/ai/createAiGenerate.js +0 -2
- package/dist/ai/createAiPlugin.d.ts +0 -1
- package/dist/ai/createAiPlugin.js +0 -2
- package/dist/ai/hooks/useAiContext.d.ts +0 -1
- package/dist/ai/hooks/useAiContext.js +0 -2
- package/dist/ai/hooks/useAiPrompts.d.ts +0 -1
- package/dist/ai/hooks/useAiPrompts.js +0 -2
- package/dist/ai/index.d.ts +0 -1
- package/dist/ai/index.js +0 -2
- package/dist/ai/plugins/ContextEditorPanel.d.ts +0 -1
- package/dist/ai/plugins/ContextEditorPanel.js +0 -2
- package/dist/ai/plugins/PromptEditorPanel.d.ts +0 -1
- package/dist/ai/plugins/PromptEditorPanel.js +0 -2
- package/dist/ai/plugins/contextEditorPlugin.d.ts +0 -1
- package/dist/ai/plugins/contextEditorPlugin.js +0 -2
- package/dist/ai/plugins/promptApiRoutes.d.ts +0 -1
- package/dist/ai/plugins/promptApiRoutes.js +0 -2
- package/dist/ai/plugins/promptEditorPlugin.d.ts +0 -1
- package/dist/ai/plugins/promptEditorPlugin.js +0 -2
- package/dist/ai/presets/componentAiDefaults.d.ts +0 -1
- package/dist/ai/presets/componentAiDefaults.js +0 -2
- package/dist/ai/presets/index.d.ts +0 -1
- package/dist/ai/presets/index.js +0 -2
- package/dist/ai/presets/instructions/interactive.d.ts +0 -1
- package/dist/ai/presets/instructions/interactive.js +0 -2
- package/dist/ai/presets/instructions/layout.d.ts +0 -1
- package/dist/ai/presets/instructions/layout.js +0 -2
- package/dist/ai/presets/instructions/media.d.ts +0 -1
- package/dist/ai/presets/instructions/media.js +0 -2
- package/dist/ai/presets/instructions/pagePatterns.d.ts +0 -1
- package/dist/ai/presets/instructions/pagePatterns.js +0 -2
- package/dist/ai/presets/instructions/schemas.d.ts +0 -1
- package/dist/ai/presets/instructions/schemas.js +0 -2
- package/dist/ai/presets/instructions/typography.d.ts +0 -1
- package/dist/ai/presets/instructions/typography.js +0 -2
- package/dist/ai/tools/index.d.ts +0 -1
- package/dist/ai/tools/index.js +0 -2
- package/dist/ai/types.d.ts +0 -1
- package/dist/ai/types.js +0 -2
- package/dist/ai/utils/injectAiConfig.d.ts +0 -1
- package/dist/ai/utils/injectAiConfig.js +0 -2
- package/dist/api/createPuckApiRoutes.d.ts +0 -1
- package/dist/api/createPuckApiRoutes.js +0 -2
- package/dist/api/createPuckApiRoutesVersions.d.ts +0 -1
- package/dist/api/createPuckApiRoutesVersions.js +0 -2
- package/dist/api/createPuckApiRoutesWithId.d.ts +0 -1
- package/dist/api/createPuckApiRoutesWithId.js +0 -2
- package/dist/api/index.d.ts +0 -1
- package/dist/api/index.js +0 -2
- package/dist/api/payload-config.d.js +1 -2
- package/dist/api/types.d.ts +0 -1
- package/dist/api/types.js +0 -2
- package/dist/api/utils/mapRootProps.d.ts +0 -1
- package/dist/api/utils/mapRootProps.js +0 -2
- package/dist/collections/Templates.d.ts +0 -1
- package/dist/collections/Templates.js +0 -2
- package/dist/components/AccordionClient.d.ts +0 -1
- package/dist/components/AccordionClient.js +0 -2
- package/dist/components/AnimatedWrapper.d.ts +0 -1
- package/dist/components/AnimatedWrapper.js +0 -2
- package/dist/components/exports.d.ts +0 -1
- package/dist/components/exports.js +0 -2
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.js +0 -2
- package/dist/components/interactive/Accordion.d.ts +0 -1
- package/dist/components/interactive/Accordion.js +0 -2
- package/dist/components/interactive/Accordion.server.d.ts +0 -1
- package/dist/components/interactive/Accordion.server.js +0 -2
- package/dist/components/interactive/Button.d.ts +0 -1
- package/dist/components/interactive/Button.js +0 -2
- package/dist/components/interactive/Button.server.d.ts +0 -1
- package/dist/components/interactive/Button.server.js +0 -2
- package/dist/components/interactive/Card.d.ts +0 -1
- package/dist/components/interactive/Card.js +0 -2
- package/dist/components/interactive/Card.server.d.ts +0 -1
- package/dist/components/interactive/Card.server.js +0 -2
- package/dist/components/interactive/Divider.d.ts +0 -1
- package/dist/components/interactive/Divider.js +0 -2
- package/dist/components/interactive/Divider.server.d.ts +0 -1
- package/dist/components/interactive/Divider.server.js +0 -2
- package/dist/components/interactive/index.d.ts +0 -1
- package/dist/components/interactive/index.js +0 -2
- package/dist/components/layout/Container.d.ts +0 -1
- package/dist/components/layout/Container.js +0 -2
- package/dist/components/layout/Container.server.d.ts +0 -1
- package/dist/components/layout/Container.server.js +0 -2
- package/dist/components/layout/Flex.d.ts +0 -1
- package/dist/components/layout/Flex.js +0 -2
- package/dist/components/layout/Flex.server.d.ts +0 -1
- package/dist/components/layout/Flex.server.js +0 -2
- package/dist/components/layout/Grid.d.ts +0 -1
- package/dist/components/layout/Grid.js +0 -2
- package/dist/components/layout/Grid.server.d.ts +0 -1
- package/dist/components/layout/Grid.server.js +0 -2
- package/dist/components/layout/Section.d.ts +0 -1
- package/dist/components/layout/Section.js +0 -2
- package/dist/components/layout/Section.server.d.ts +0 -1
- package/dist/components/layout/Section.server.js +0 -2
- package/dist/components/layout/Spacer.d.ts +0 -1
- package/dist/components/layout/Spacer.js +0 -2
- package/dist/components/layout/Spacer.server.d.ts +0 -1
- package/dist/components/layout/Spacer.server.js +0 -2
- package/dist/components/layout/Template.d.ts +0 -1
- package/dist/components/layout/Template.js +0 -2
- package/dist/components/layout/Template.server.d.ts +0 -1
- package/dist/components/layout/Template.server.js +0 -2
- package/dist/components/layout/index.d.ts +0 -1
- package/dist/components/layout/index.js +0 -2
- package/dist/components/media/Image.d.ts +0 -1
- package/dist/components/media/Image.js +0 -2
- package/dist/components/media/Image.server.d.ts +0 -1
- package/dist/components/media/Image.server.js +0 -2
- package/dist/components/media/index.d.ts +0 -1
- package/dist/components/media/index.js +0 -2
- package/dist/components/typography/Heading.d.ts +0 -1
- package/dist/components/typography/Heading.js +0 -2
- package/dist/components/typography/Heading.server.d.ts +0 -1
- package/dist/components/typography/Heading.server.js +0 -2
- package/dist/components/typography/RichText.editor.d.ts +0 -1
- package/dist/components/typography/RichText.editor.js +0 -2
- package/dist/components/typography/RichText.server.d.ts +0 -1
- package/dist/components/typography/RichText.server.js +0 -2
- package/dist/components/typography/Text.d.ts +0 -1
- package/dist/components/typography/Text.js +0 -2
- package/dist/components/typography/Text.server.d.ts +0 -1
- package/dist/components/typography/Text.server.js +0 -2
- package/dist/components/typography/index.d.ts +0 -1
- package/dist/components/typography/index.js +0 -2
- package/dist/config/config.editor.d.ts +0 -1
- package/dist/config/config.editor.js +0 -2
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +0 -2
- package/dist/config/merge.d.ts +0 -1
- package/dist/config/merge.js +0 -2
- package/dist/config/presets.d.ts +0 -1
- package/dist/config/presets.js +0 -2
- package/dist/config/types.d.ts +0 -1
- package/dist/config/types.js +0 -2
- package/dist/editor/PuckEditor.d.ts +0 -1
- package/dist/editor/PuckEditor.js +0 -2
- package/dist/editor/PuckEditorImpl.client.d.ts +0 -1
- package/dist/editor/PuckEditorImpl.client.js +0 -2
- package/dist/editor/components/DarkModeStyles.d.ts +0 -1
- package/dist/editor/components/DarkModeStyles.js +0 -2
- package/dist/editor/components/HeaderActions.d.ts +0 -1
- package/dist/editor/components/HeaderActions.js +0 -2
- package/dist/editor/components/IframeWrapper.d.ts +0 -1
- package/dist/editor/components/IframeWrapper.js +0 -2
- package/dist/editor/components/LoadingState.d.ts +0 -1
- package/dist/editor/components/LoadingState.js +0 -2
- package/dist/editor/components/PreviewModal.d.ts +0 -1
- package/dist/editor/components/PreviewModal.js +0 -2
- package/dist/editor/components/PreviewModeToggle.d.ts +0 -1
- package/dist/editor/components/PreviewModeToggle.js +0 -2
- package/dist/editor/components/VersionHistory.d.ts +0 -1
- package/dist/editor/components/VersionHistory.js +0 -2
- package/dist/editor/hooks/useDarkMode.d.ts +0 -1
- package/dist/editor/hooks/useDarkMode.js +0 -2
- package/dist/editor/hooks/useUnsavedChanges.d.ts +0 -1
- package/dist/editor/hooks/useUnsavedChanges.js +0 -2
- package/dist/editor/index.d.ts +0 -1
- package/dist/editor/index.js +0 -2
- package/dist/editor/plugins/VersionHistoryPanel.d.ts +0 -1
- package/dist/editor/plugins/VersionHistoryPanel.js +0 -2
- package/dist/editor/plugins/index.d.ts +0 -1
- package/dist/editor/plugins/index.js +0 -2
- package/dist/editor/plugins/versionHistoryPlugin.d.ts +0 -1
- package/dist/editor/plugins/versionHistoryPlugin.js +0 -2
- package/dist/editor/utils/detectPageTree.d.ts +0 -1
- package/dist/editor/utils/detectPageTree.js +0 -2
- package/dist/editor/utils/index.d.ts +0 -1
- package/dist/editor/utils/index.js +0 -2
- package/dist/editor/utils/injectPageTreeFields.d.ts +0 -1
- package/dist/editor/utils/injectPageTreeFields.js +0 -2
- package/dist/endpoints/ai.d.ts +0 -1
- package/dist/endpoints/ai.js +0 -2
- package/dist/endpoints/context.d.ts +0 -1
- package/dist/endpoints/context.js +0 -2
- package/dist/endpoints/index.d.ts +0 -1
- package/dist/endpoints/index.js +0 -2
- package/dist/endpoints/postcss.d.js +1 -2
- package/dist/endpoints/prompts.d.ts +0 -1
- package/dist/endpoints/prompts.js +0 -2
- package/dist/endpoints/styles.d.ts +0 -1
- package/dist/endpoints/styles.js +0 -2
- package/dist/exports/client.d.ts +0 -1
- package/dist/exports/client.js +0 -2
- package/dist/exports/rsc.d.ts +0 -1
- package/dist/exports/rsc.js +0 -2
- package/dist/fields/AlignmentField.d.ts +0 -1
- package/dist/fields/AlignmentField.js +0 -2
- package/dist/fields/AnimationField.d.ts +0 -1
- package/dist/fields/AnimationField.js +0 -2
- package/dist/fields/BackgroundField.d.ts +0 -1
- package/dist/fields/BackgroundField.js +0 -2
- package/dist/fields/BorderField.d.ts +0 -1
- package/dist/fields/BorderField.js +0 -2
- package/dist/fields/ColorPickerField.d.ts +0 -1
- package/dist/fields/ColorPickerField.js +0 -2
- package/dist/fields/ContentAlignmentField.d.ts +0 -1
- package/dist/fields/ContentAlignmentField.js +0 -2
- package/dist/fields/DimensionsField.d.ts +0 -1
- package/dist/fields/DimensionsField.js +0 -2
- package/dist/fields/FlexAlignmentField.d.ts +0 -1
- package/dist/fields/FlexAlignmentField.js +0 -2
- package/dist/fields/FolderPickerField.d.ts +0 -1
- package/dist/fields/FolderPickerField.js +0 -2
- package/dist/fields/GradientEditor.d.ts +0 -1
- package/dist/fields/GradientEditor.js +0 -2
- package/dist/fields/LockedField.d.ts +0 -1
- package/dist/fields/LockedField.js +0 -2
- package/dist/fields/MarginField.d.ts +0 -1
- package/dist/fields/MarginField.js +0 -2
- package/dist/fields/MediaField.d.ts +0 -1
- package/dist/fields/MediaField.js +0 -2
- package/dist/fields/PaddingField.d.ts +0 -1
- package/dist/fields/PaddingField.js +0 -2
- package/dist/fields/PageSegmentField.d.ts +0 -1
- package/dist/fields/PageSegmentField.js +0 -2
- package/dist/fields/ResetField.d.ts +0 -1
- package/dist/fields/ResetField.js +0 -2
- package/dist/fields/ResponsiveField.d.ts +0 -1
- package/dist/fields/ResponsiveField.js +0 -2
- package/dist/fields/ResponsiveVisibilityField.d.ts +0 -1
- package/dist/fields/ResponsiveVisibilityField.js +0 -2
- package/dist/fields/SizeField.d.ts +0 -1
- package/dist/fields/SizeField.js +0 -2
- package/dist/fields/SlugPreviewField.d.ts +0 -1
- package/dist/fields/SlugPreviewField.js +0 -2
- package/dist/fields/TemplateField.d.ts +0 -1
- package/dist/fields/TemplateField.js +0 -2
- package/dist/fields/TransformField.d.ts +0 -1
- package/dist/fields/TransformField.js +0 -2
- package/dist/fields/VerticalAlignmentField.d.ts +0 -1
- package/dist/fields/VerticalAlignmentField.js +0 -2
- package/dist/fields/WidthField.d.ts +0 -1
- package/dist/fields/WidthField.js +0 -2
- package/dist/fields/index.d.ts +0 -1
- package/dist/fields/index.js +0 -2
- package/dist/fields/richtext/controls/ColorPickerControl.d.ts +0 -1
- package/dist/fields/richtext/controls/ColorPickerControl.js +0 -2
- package/dist/fields/richtext/controls/DropdownPortal.d.ts +0 -1
- package/dist/fields/richtext/controls/DropdownPortal.js +0 -2
- package/dist/fields/richtext/controls/FontSizeControl.d.ts +0 -1
- package/dist/fields/richtext/controls/FontSizeControl.js +0 -2
- package/dist/fields/richtext/controls/HighlightControl.d.ts +0 -1
- package/dist/fields/richtext/controls/HighlightControl.js +0 -2
- package/dist/fields/richtext/controls/index.d.ts +0 -1
- package/dist/fields/richtext/controls/index.js +0 -2
- package/dist/fields/richtext/controls/shared.d.ts +0 -1
- package/dist/fields/richtext/controls/shared.js +0 -2
- package/dist/fields/richtext/createRichTextField.d.ts +0 -1
- package/dist/fields/richtext/createRichTextField.js +0 -2
- package/dist/fields/richtext/extensions/FontSize.d.ts +0 -1
- package/dist/fields/richtext/extensions/FontSize.js +0 -2
- package/dist/fields/richtext/extensions/index.d.ts +0 -1
- package/dist/fields/richtext/extensions/index.js +0 -2
- package/dist/fields/richtext/index.d.ts +0 -1
- package/dist/fields/richtext/index.js +0 -2
- package/dist/fields/shared.d.ts +0 -1
- package/dist/fields/shared.js +0 -2
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.js +0 -2
- package/dist/hooks/useResponsiveStyles.d.ts +0 -1
- package/dist/hooks/useResponsiveStyles.js +0 -2
- package/dist/hooks/useScrollAnimation.d.ts +0 -1
- package/dist/hooks/useScrollAnimation.js +0 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -2
- package/dist/layouts/LayoutWrapper.d.ts +0 -1
- package/dist/layouts/LayoutWrapper.js +0 -2
- package/dist/layouts/defaults.d.ts +0 -1
- package/dist/layouts/defaults.js +0 -2
- package/dist/layouts/index.d.ts +0 -1
- package/dist/layouts/index.js +0 -2
- package/dist/layouts/types.d.ts +0 -1
- package/dist/layouts/types.js +0 -2
- package/dist/layouts/utils.d.ts +0 -1
- package/dist/layouts/utils.js +0 -2
- package/dist/next/index.d.ts +0 -1
- package/dist/next/index.js +0 -2
- package/dist/plugin/collections/Pages.d.ts +0 -1
- package/dist/plugin/collections/Pages.js +0 -2
- package/dist/plugin/fields/index.d.ts +0 -1
- package/dist/plugin/fields/index.js +0 -2
- package/dist/plugin/fields/types.d.ts +0 -1
- package/dist/plugin/fields/types.js +0 -2
- package/dist/plugin/hooks/index.d.ts +0 -1
- package/dist/plugin/hooks/index.js +0 -2
- package/dist/plugin/hooks/isHomepageUnique.d.ts +0 -1
- package/dist/plugin/hooks/isHomepageUnique.js +0 -2
- package/dist/plugin/index.d.ts +0 -1
- package/dist/plugin/index.js +0 -2
- package/dist/render/HybridPageRenderer.d.ts +0 -1
- package/dist/render/HybridPageRenderer.js +0 -2
- package/dist/render/PageRenderer.d.ts +0 -1
- package/dist/render/PageRenderer.js +0 -2
- package/dist/render/PuckEditor.client.d.ts +0 -1
- package/dist/render/PuckEditor.client.js +0 -2
- package/dist/render/index.d.ts +0 -1
- package/dist/render/index.js +0 -2
- package/dist/theme/context.d.ts +0 -1
- package/dist/theme/context.js +0 -2
- package/dist/theme/defaults.d.ts +0 -1
- package/dist/theme/defaults.js +0 -2
- package/dist/theme/example.d.ts +0 -1
- package/dist/theme/example.js +0 -2
- package/dist/theme/index.d.ts +0 -1
- package/dist/theme/index.js +0 -2
- package/dist/theme/types.d.ts +0 -1
- package/dist/theme/types.js +0 -2
- package/dist/theme/utils.d.ts +0 -1
- package/dist/theme/utils.js +0 -2
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -2
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -2
- package/dist/utils/migration.d.ts +0 -1
- package/dist/utils/migration.js +0 -2
- package/dist/utils/validation.d.ts +0 -1
- package/dist/utils/validation.js +0 -2
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -3
- package/dist/views/PuckConfigContext.d.ts +0 -1
- package/dist/views/PuckConfigContext.js +0 -2
- package/dist/views/PuckEditorView.d.ts +0 -1
- package/dist/views/PuckEditorView.js +0 -2
- package/dist/views/index.d.ts +0 -1
- package/dist/views/index.js +0 -2
- package/package.json +1 -1
- package/dist/admin/EditWithPuckButton.d.ts.map +0 -1
- package/dist/admin/EditWithPuckButton.js.map +0 -1
- package/dist/admin/EditWithPuckCell.d.ts.map +0 -1
- package/dist/admin/EditWithPuckCell.js.map +0 -1
- package/dist/admin/PuckEditorView.d.ts.map +0 -1
- package/dist/admin/PuckEditorView.js.map +0 -1
- package/dist/admin/client.d.ts.map +0 -1
- package/dist/admin/client.js.map +0 -1
- package/dist/admin/generateAdminComponents.d.ts.map +0 -1
- package/dist/admin/generateAdminComponents.js.map +0 -1
- package/dist/admin/index.d.ts.map +0 -1
- package/dist/admin/index.js.map +0 -1
- package/dist/ai/collections/AiContext.d.ts.map +0 -1
- package/dist/ai/collections/AiContext.js.map +0 -1
- package/dist/ai/collections/AiPrompts.d.ts.map +0 -1
- package/dist/ai/collections/AiPrompts.js.map +0 -1
- package/dist/ai/createAiApiRoutes.d.ts.map +0 -1
- package/dist/ai/createAiApiRoutes.js.map +0 -1
- package/dist/ai/createAiGenerate.d.ts.map +0 -1
- package/dist/ai/createAiGenerate.js.map +0 -1
- package/dist/ai/createAiPlugin.d.ts.map +0 -1
- package/dist/ai/createAiPlugin.js.map +0 -1
- package/dist/ai/hooks/useAiContext.d.ts.map +0 -1
- package/dist/ai/hooks/useAiContext.js.map +0 -1
- package/dist/ai/hooks/useAiPrompts.d.ts.map +0 -1
- package/dist/ai/hooks/useAiPrompts.js.map +0 -1
- package/dist/ai/index.d.ts.map +0 -1
- package/dist/ai/index.js.map +0 -1
- package/dist/ai/plugins/ContextEditorPanel.d.ts.map +0 -1
- package/dist/ai/plugins/ContextEditorPanel.js.map +0 -1
- package/dist/ai/plugins/PromptEditorPanel.d.ts.map +0 -1
- package/dist/ai/plugins/PromptEditorPanel.js.map +0 -1
- package/dist/ai/plugins/contextEditorPlugin.d.ts.map +0 -1
- package/dist/ai/plugins/contextEditorPlugin.js.map +0 -1
- package/dist/ai/plugins/promptApiRoutes.d.ts.map +0 -1
- package/dist/ai/plugins/promptApiRoutes.js.map +0 -1
- package/dist/ai/plugins/promptEditorPlugin.d.ts.map +0 -1
- package/dist/ai/plugins/promptEditorPlugin.js.map +0 -1
- package/dist/ai/presets/componentAiDefaults.d.ts.map +0 -1
- package/dist/ai/presets/componentAiDefaults.js.map +0 -1
- package/dist/ai/presets/index.d.ts.map +0 -1
- package/dist/ai/presets/index.js.map +0 -1
- package/dist/ai/presets/instructions/interactive.d.ts.map +0 -1
- package/dist/ai/presets/instructions/interactive.js.map +0 -1
- package/dist/ai/presets/instructions/layout.d.ts.map +0 -1
- package/dist/ai/presets/instructions/layout.js.map +0 -1
- package/dist/ai/presets/instructions/media.d.ts.map +0 -1
- package/dist/ai/presets/instructions/media.js.map +0 -1
- package/dist/ai/presets/instructions/pagePatterns.d.ts.map +0 -1
- package/dist/ai/presets/instructions/pagePatterns.js.map +0 -1
- package/dist/ai/presets/instructions/schemas.d.ts.map +0 -1
- package/dist/ai/presets/instructions/schemas.js.map +0 -1
- package/dist/ai/presets/instructions/typography.d.ts.map +0 -1
- package/dist/ai/presets/instructions/typography.js.map +0 -1
- package/dist/ai/tools/index.d.ts.map +0 -1
- package/dist/ai/tools/index.js.map +0 -1
- package/dist/ai/types.d.ts.map +0 -1
- package/dist/ai/types.js.map +0 -1
- package/dist/ai/utils/injectAiConfig.d.ts.map +0 -1
- package/dist/ai/utils/injectAiConfig.js.map +0 -1
- package/dist/api/createPuckApiRoutes.d.ts.map +0 -1
- package/dist/api/createPuckApiRoutes.js.map +0 -1
- package/dist/api/createPuckApiRoutesVersions.d.ts.map +0 -1
- package/dist/api/createPuckApiRoutesVersions.js.map +0 -1
- package/dist/api/createPuckApiRoutesWithId.d.ts.map +0 -1
- package/dist/api/createPuckApiRoutesWithId.js.map +0 -1
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/index.js.map +0 -1
- package/dist/api/payload-config.d.js.map +0 -1
- package/dist/api/types.d.ts.map +0 -1
- package/dist/api/types.js.map +0 -1
- package/dist/api/utils/mapRootProps.d.ts.map +0 -1
- package/dist/api/utils/mapRootProps.js.map +0 -1
- package/dist/collections/Templates.d.ts.map +0 -1
- package/dist/collections/Templates.js.map +0 -1
- package/dist/components/AccordionClient.d.ts.map +0 -1
- package/dist/components/AccordionClient.js.map +0 -1
- package/dist/components/AnimatedWrapper.d.ts.map +0 -1
- package/dist/components/AnimatedWrapper.js.map +0 -1
- package/dist/components/exports.d.ts.map +0 -1
- package/dist/components/exports.js.map +0 -1
- package/dist/components/index.d.ts.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/components/interactive/Accordion.d.ts.map +0 -1
- package/dist/components/interactive/Accordion.js.map +0 -1
- package/dist/components/interactive/Accordion.server.d.ts.map +0 -1
- package/dist/components/interactive/Accordion.server.js.map +0 -1
- package/dist/components/interactive/Button.d.ts.map +0 -1
- package/dist/components/interactive/Button.js.map +0 -1
- package/dist/components/interactive/Button.server.d.ts.map +0 -1
- package/dist/components/interactive/Button.server.js.map +0 -1
- package/dist/components/interactive/Card.d.ts.map +0 -1
- package/dist/components/interactive/Card.js.map +0 -1
- package/dist/components/interactive/Card.server.d.ts.map +0 -1
- package/dist/components/interactive/Card.server.js.map +0 -1
- package/dist/components/interactive/Divider.d.ts.map +0 -1
- package/dist/components/interactive/Divider.js.map +0 -1
- package/dist/components/interactive/Divider.server.d.ts.map +0 -1
- package/dist/components/interactive/Divider.server.js.map +0 -1
- package/dist/components/interactive/index.d.ts.map +0 -1
- package/dist/components/interactive/index.js.map +0 -1
- package/dist/components/layout/Container.d.ts.map +0 -1
- package/dist/components/layout/Container.js.map +0 -1
- package/dist/components/layout/Container.server.d.ts.map +0 -1
- package/dist/components/layout/Container.server.js.map +0 -1
- package/dist/components/layout/Flex.d.ts.map +0 -1
- package/dist/components/layout/Flex.js.map +0 -1
- package/dist/components/layout/Flex.server.d.ts.map +0 -1
- package/dist/components/layout/Flex.server.js.map +0 -1
- package/dist/components/layout/Grid.d.ts.map +0 -1
- package/dist/components/layout/Grid.js.map +0 -1
- package/dist/components/layout/Grid.server.d.ts.map +0 -1
- package/dist/components/layout/Grid.server.js.map +0 -1
- package/dist/components/layout/Section.d.ts.map +0 -1
- package/dist/components/layout/Section.js.map +0 -1
- package/dist/components/layout/Section.server.d.ts.map +0 -1
- package/dist/components/layout/Section.server.js.map +0 -1
- package/dist/components/layout/Spacer.d.ts.map +0 -1
- package/dist/components/layout/Spacer.js.map +0 -1
- package/dist/components/layout/Spacer.server.d.ts.map +0 -1
- package/dist/components/layout/Spacer.server.js.map +0 -1
- package/dist/components/layout/Template.d.ts.map +0 -1
- package/dist/components/layout/Template.js.map +0 -1
- package/dist/components/layout/Template.server.d.ts.map +0 -1
- package/dist/components/layout/Template.server.js.map +0 -1
- package/dist/components/layout/index.d.ts.map +0 -1
- package/dist/components/layout/index.js.map +0 -1
- package/dist/components/media/Image.d.ts.map +0 -1
- package/dist/components/media/Image.js.map +0 -1
- package/dist/components/media/Image.server.d.ts.map +0 -1
- package/dist/components/media/Image.server.js.map +0 -1
- package/dist/components/media/index.d.ts.map +0 -1
- package/dist/components/media/index.js.map +0 -1
- package/dist/components/typography/Heading.d.ts.map +0 -1
- package/dist/components/typography/Heading.js.map +0 -1
- package/dist/components/typography/Heading.server.d.ts.map +0 -1
- package/dist/components/typography/Heading.server.js.map +0 -1
- package/dist/components/typography/RichText.editor.d.ts.map +0 -1
- package/dist/components/typography/RichText.editor.js.map +0 -1
- package/dist/components/typography/RichText.server.d.ts.map +0 -1
- package/dist/components/typography/RichText.server.js.map +0 -1
- package/dist/components/typography/Text.d.ts.map +0 -1
- package/dist/components/typography/Text.js.map +0 -1
- package/dist/components/typography/Text.server.d.ts.map +0 -1
- package/dist/components/typography/Text.server.js.map +0 -1
- package/dist/components/typography/index.d.ts.map +0 -1
- package/dist/components/typography/index.js.map +0 -1
- package/dist/config/config.editor.d.ts.map +0 -1
- package/dist/config/config.editor.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/merge.d.ts.map +0 -1
- package/dist/config/merge.js.map +0 -1
- package/dist/config/presets.d.ts.map +0 -1
- package/dist/config/presets.js.map +0 -1
- package/dist/config/types.d.ts.map +0 -1
- package/dist/config/types.js.map +0 -1
- package/dist/editor/PuckEditor.d.ts.map +0 -1
- package/dist/editor/PuckEditor.js.map +0 -1
- package/dist/editor/PuckEditorImpl.client.d.ts.map +0 -1
- package/dist/editor/PuckEditorImpl.client.js.map +0 -1
- package/dist/editor/components/DarkModeStyles.d.ts.map +0 -1
- package/dist/editor/components/DarkModeStyles.js.map +0 -1
- package/dist/editor/components/HeaderActions.d.ts.map +0 -1
- package/dist/editor/components/HeaderActions.js.map +0 -1
- package/dist/editor/components/IframeWrapper.d.ts.map +0 -1
- package/dist/editor/components/IframeWrapper.js.map +0 -1
- package/dist/editor/components/LoadingState.d.ts.map +0 -1
- package/dist/editor/components/LoadingState.js.map +0 -1
- package/dist/editor/components/PreviewModal.d.ts.map +0 -1
- package/dist/editor/components/PreviewModal.js.map +0 -1
- package/dist/editor/components/PreviewModeToggle.d.ts.map +0 -1
- package/dist/editor/components/PreviewModeToggle.js.map +0 -1
- package/dist/editor/components/VersionHistory.d.ts.map +0 -1
- package/dist/editor/components/VersionHistory.js.map +0 -1
- package/dist/editor/hooks/useDarkMode.d.ts.map +0 -1
- package/dist/editor/hooks/useDarkMode.js.map +0 -1
- package/dist/editor/hooks/useUnsavedChanges.d.ts.map +0 -1
- package/dist/editor/hooks/useUnsavedChanges.js.map +0 -1
- package/dist/editor/index.d.ts.map +0 -1
- package/dist/editor/index.js.map +0 -1
- package/dist/editor/plugins/VersionHistoryPanel.d.ts.map +0 -1
- package/dist/editor/plugins/VersionHistoryPanel.js.map +0 -1
- package/dist/editor/plugins/index.d.ts.map +0 -1
- package/dist/editor/plugins/index.js.map +0 -1
- package/dist/editor/plugins/versionHistoryPlugin.d.ts.map +0 -1
- package/dist/editor/plugins/versionHistoryPlugin.js.map +0 -1
- package/dist/editor/utils/detectPageTree.d.ts.map +0 -1
- package/dist/editor/utils/detectPageTree.js.map +0 -1
- package/dist/editor/utils/index.d.ts.map +0 -1
- package/dist/editor/utils/index.js.map +0 -1
- package/dist/editor/utils/injectPageTreeFields.d.ts.map +0 -1
- package/dist/editor/utils/injectPageTreeFields.js.map +0 -1
- package/dist/endpoints/ai.d.ts.map +0 -1
- package/dist/endpoints/ai.js.map +0 -1
- package/dist/endpoints/context.d.ts.map +0 -1
- package/dist/endpoints/context.js.map +0 -1
- package/dist/endpoints/index.d.ts.map +0 -1
- package/dist/endpoints/index.js.map +0 -1
- package/dist/endpoints/postcss.d.js.map +0 -1
- package/dist/endpoints/prompts.d.ts.map +0 -1
- package/dist/endpoints/prompts.js.map +0 -1
- package/dist/endpoints/styles.d.ts.map +0 -1
- package/dist/endpoints/styles.js.map +0 -1
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/client.js.map +0 -1
- package/dist/exports/rsc.d.ts.map +0 -1
- package/dist/exports/rsc.js.map +0 -1
- package/dist/fields/AlignmentField.d.ts.map +0 -1
- package/dist/fields/AlignmentField.js.map +0 -1
- package/dist/fields/AnimationField.d.ts.map +0 -1
- package/dist/fields/AnimationField.js.map +0 -1
- package/dist/fields/BackgroundField.d.ts.map +0 -1
- package/dist/fields/BackgroundField.js.map +0 -1
- package/dist/fields/BorderField.d.ts.map +0 -1
- package/dist/fields/BorderField.js.map +0 -1
- package/dist/fields/ColorPickerField.d.ts.map +0 -1
- package/dist/fields/ColorPickerField.js.map +0 -1
- package/dist/fields/ContentAlignmentField.d.ts.map +0 -1
- package/dist/fields/ContentAlignmentField.js.map +0 -1
- package/dist/fields/DimensionsField.d.ts.map +0 -1
- package/dist/fields/DimensionsField.js.map +0 -1
- package/dist/fields/FlexAlignmentField.d.ts.map +0 -1
- package/dist/fields/FlexAlignmentField.js.map +0 -1
- package/dist/fields/FolderPickerField.d.ts.map +0 -1
- package/dist/fields/FolderPickerField.js.map +0 -1
- package/dist/fields/GradientEditor.d.ts.map +0 -1
- package/dist/fields/GradientEditor.js.map +0 -1
- package/dist/fields/LockedField.d.ts.map +0 -1
- package/dist/fields/LockedField.js.map +0 -1
- package/dist/fields/MarginField.d.ts.map +0 -1
- package/dist/fields/MarginField.js.map +0 -1
- package/dist/fields/MediaField.d.ts.map +0 -1
- package/dist/fields/MediaField.js.map +0 -1
- package/dist/fields/PaddingField.d.ts.map +0 -1
- package/dist/fields/PaddingField.js.map +0 -1
- package/dist/fields/PageSegmentField.d.ts.map +0 -1
- package/dist/fields/PageSegmentField.js.map +0 -1
- package/dist/fields/ResetField.d.ts.map +0 -1
- package/dist/fields/ResetField.js.map +0 -1
- package/dist/fields/ResponsiveField.d.ts.map +0 -1
- package/dist/fields/ResponsiveField.js.map +0 -1
- package/dist/fields/ResponsiveVisibilityField.d.ts.map +0 -1
- package/dist/fields/ResponsiveVisibilityField.js.map +0 -1
- package/dist/fields/SizeField.d.ts.map +0 -1
- package/dist/fields/SizeField.js.map +0 -1
- package/dist/fields/SlugPreviewField.d.ts.map +0 -1
- package/dist/fields/SlugPreviewField.js.map +0 -1
- package/dist/fields/TemplateField.d.ts.map +0 -1
- package/dist/fields/TemplateField.js.map +0 -1
- package/dist/fields/TransformField.d.ts.map +0 -1
- package/dist/fields/TransformField.js.map +0 -1
- package/dist/fields/VerticalAlignmentField.d.ts.map +0 -1
- package/dist/fields/VerticalAlignmentField.js.map +0 -1
- package/dist/fields/WidthField.d.ts.map +0 -1
- package/dist/fields/WidthField.js.map +0 -1
- package/dist/fields/index.d.ts.map +0 -1
- package/dist/fields/index.js.map +0 -1
- package/dist/fields/richtext/controls/ColorPickerControl.d.ts.map +0 -1
- package/dist/fields/richtext/controls/ColorPickerControl.js.map +0 -1
- package/dist/fields/richtext/controls/DropdownPortal.d.ts.map +0 -1
- package/dist/fields/richtext/controls/DropdownPortal.js.map +0 -1
- package/dist/fields/richtext/controls/FontSizeControl.d.ts.map +0 -1
- package/dist/fields/richtext/controls/FontSizeControl.js.map +0 -1
- package/dist/fields/richtext/controls/HighlightControl.d.ts.map +0 -1
- package/dist/fields/richtext/controls/HighlightControl.js.map +0 -1
- package/dist/fields/richtext/controls/index.d.ts.map +0 -1
- package/dist/fields/richtext/controls/index.js.map +0 -1
- package/dist/fields/richtext/controls/shared.d.ts.map +0 -1
- package/dist/fields/richtext/controls/shared.js.map +0 -1
- package/dist/fields/richtext/createRichTextField.d.ts.map +0 -1
- package/dist/fields/richtext/createRichTextField.js.map +0 -1
- package/dist/fields/richtext/extensions/FontSize.d.ts.map +0 -1
- package/dist/fields/richtext/extensions/FontSize.js.map +0 -1
- package/dist/fields/richtext/extensions/index.d.ts.map +0 -1
- package/dist/fields/richtext/extensions/index.js.map +0 -1
- package/dist/fields/richtext/index.d.ts.map +0 -1
- package/dist/fields/richtext/index.js.map +0 -1
- package/dist/fields/shared.d.ts.map +0 -1
- package/dist/fields/shared.js.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/useResponsiveStyles.d.ts.map +0 -1
- package/dist/hooks/useResponsiveStyles.js.map +0 -1
- package/dist/hooks/useScrollAnimation.d.ts.map +0 -1
- package/dist/hooks/useScrollAnimation.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/layouts/LayoutWrapper.d.ts.map +0 -1
- package/dist/layouts/LayoutWrapper.js.map +0 -1
- package/dist/layouts/defaults.d.ts.map +0 -1
- package/dist/layouts/defaults.js.map +0 -1
- package/dist/layouts/index.d.ts.map +0 -1
- package/dist/layouts/index.js.map +0 -1
- package/dist/layouts/types.d.ts.map +0 -1
- package/dist/layouts/types.js.map +0 -1
- package/dist/layouts/utils.d.ts.map +0 -1
- package/dist/layouts/utils.js.map +0 -1
- package/dist/next/index.d.ts.map +0 -1
- package/dist/next/index.js.map +0 -1
- package/dist/plugin/collections/Pages.d.ts.map +0 -1
- package/dist/plugin/collections/Pages.js.map +0 -1
- package/dist/plugin/fields/index.d.ts.map +0 -1
- package/dist/plugin/fields/index.js.map +0 -1
- package/dist/plugin/fields/types.d.ts.map +0 -1
- package/dist/plugin/fields/types.js.map +0 -1
- package/dist/plugin/hooks/index.d.ts.map +0 -1
- package/dist/plugin/hooks/index.js.map +0 -1
- package/dist/plugin/hooks/isHomepageUnique.d.ts.map +0 -1
- package/dist/plugin/hooks/isHomepageUnique.js.map +0 -1
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js.map +0 -1
- package/dist/render/HybridPageRenderer.d.ts.map +0 -1
- package/dist/render/HybridPageRenderer.js.map +0 -1
- package/dist/render/PageRenderer.d.ts.map +0 -1
- package/dist/render/PageRenderer.js.map +0 -1
- package/dist/render/PuckEditor.client.d.ts.map +0 -1
- package/dist/render/PuckEditor.client.js.map +0 -1
- package/dist/render/index.d.ts.map +0 -1
- package/dist/render/index.js.map +0 -1
- package/dist/theme/context.d.ts.map +0 -1
- package/dist/theme/context.js.map +0 -1
- package/dist/theme/defaults.d.ts.map +0 -1
- package/dist/theme/defaults.js.map +0 -1
- package/dist/theme/example.d.ts.map +0 -1
- package/dist/theme/example.js.map +0 -1
- package/dist/theme/index.d.ts.map +0 -1
- package/dist/theme/index.js.map +0 -1
- package/dist/theme/types.d.ts.map +0 -1
- package/dist/theme/types.js.map +0 -1
- package/dist/theme/utils.d.ts.map +0 -1
- package/dist/theme/utils.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/migration.d.ts.map +0 -1
- package/dist/utils/migration.js.map +0 -1
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/validation.js.map +0 -1
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js.map +0 -1
- package/dist/views/PuckConfigContext.d.ts.map +0 -1
- package/dist/views/PuckConfigContext.js.map +0 -1
- package/dist/views/PuckEditorView.d.ts.map +0 -1
- package/dist/views/PuckEditorView.js.map +0 -1
- package/dist/views/index.d.ts.map +0 -1
- package/dist/views/index.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/GradientEditor.tsx"],"sourcesContent":["'use client'\n\n/**\n * GradientEditor - Component for editing gradient values\n *\n * This component provides:\n * - Type selector (linear/radial toggle)\n * - Angle slider for linear gradients (0-360)\n * - Shape and position selectors for radial gradients\n * - Gradient stops list with color pickers and position sliders\n * - Add/remove stop buttons\n * - Visual gradient preview bar\n */\n\nimport React, { useCallback, memo, useState, type CSSProperties } from 'react'\nimport { Plus, Trash2 } from 'lucide-react'\nimport type { GradientValue, GradientStop, ColorValue } from './shared.js'\nimport { colorValueToCSS } from './shared.js'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface GradientEditorProps {\n value: GradientValue | null\n onChange: (value: GradientValue) => void\n readOnly?: boolean\n}\n\n// =============================================================================\n// Default Values\n// =============================================================================\n\nconst DEFAULT_GRADIENT: GradientValue = {\n type: 'linear',\n angle: 90,\n stops: [\n { color: { hex: '#000000', opacity: 100 }, position: 0 },\n { color: { hex: '#ffffff', opacity: 100 }, position: 100 },\n ],\n radialShape: 'circle',\n radialPosition: 'center',\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: '16px',\n } as CSSProperties,\n preview: {\n height: '48px',\n borderRadius: '6px',\n border: '1px solid var(--theme-elevation-150)',\n } as CSSProperties,\n row: {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: '8px',\n } as CSSProperties,\n label: {\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n width: '48px',\n flexShrink: 0,\n } as CSSProperties,\n buttonGroup: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '4px',\n } as CSSProperties,\n button: {\n height: '28px',\n padding: '0 12px',\n fontSize: '12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-bg)',\n color: 'var(--theme-elevation-700)',\n cursor: 'pointer',\n } as CSSProperties,\n buttonActive: {\n height: '28px',\n padding: '0 12px',\n fontSize: '12px',\n border: '1px solid var(--theme-elevation-800)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-elevation-800)',\n color: 'var(--theme-bg)',\n cursor: 'pointer',\n } as CSSProperties,\n slider: {\n flex: 1,\n height: '6px',\n accentColor: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n } as CSSProperties,\n sliderValue: {\n fontSize: '12px',\n fontFamily: 'monospace',\n color: 'var(--theme-elevation-500)',\n width: '40px',\n textAlign: 'right',\n } as CSSProperties,\n select: {\n flex: 1,\n height: '32px',\n padding: '0 8px',\n fontSize: '12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n } as CSSProperties,\n stopsHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n } as CSSProperties,\n addButton: {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n height: '24px',\n padding: '0 8px',\n fontSize: '12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-bg)',\n color: 'var(--theme-elevation-700)',\n cursor: 'pointer',\n } as CSSProperties,\n stopsList: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n } as CSSProperties,\n stopItem: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n padding: '8px',\n backgroundColor: 'var(--theme-elevation-50)',\n borderRadius: '6px',\n overflow: 'hidden',\n } as CSSProperties,\n stopRow: {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: '8px',\n } as CSSProperties,\n colorPicker: {\n width: '28px',\n height: '28px',\n padding: 0,\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n cursor: 'pointer',\n flexShrink: 0,\n } as CSSProperties,\n hexInput: {\n width: '80px',\n minWidth: 0,\n height: '28px',\n padding: '0 6px',\n fontSize: '12px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n swatch: {\n width: '28px',\n height: '28px',\n borderRadius: '4px',\n border: '1px solid var(--theme-elevation-150)',\n flexShrink: 0,\n position: 'relative',\n overflow: 'hidden',\n } as CSSProperties,\n checkerboard: {\n position: 'absolute',\n inset: 0,\n backgroundImage: 'linear-gradient(45deg, #e0e0e0 25%, transparent 25%), linear-gradient(-45deg, #e0e0e0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #e0e0e0 75%), linear-gradient(-45deg, transparent 75%, #e0e0e0 75%)',\n backgroundSize: '8px 8px',\n backgroundPosition: '0 0, 0 4px, 4px -4px, -4px 0px',\n } as CSSProperties,\n colorOverlay: {\n position: 'absolute',\n inset: 0,\n } as CSSProperties,\n spacer: {\n flex: 1,\n minWidth: 0,\n } as CSSProperties,\n deleteButton: {\n padding: '4px',\n border: 'none',\n borderRadius: '4px',\n backgroundColor: 'transparent',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n flexShrink: 0,\n } as CSSProperties,\n stopLabel: {\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n width: '48px',\n flexShrink: 0,\n } as CSSProperties,\n rangeSlider: {\n flex: 1,\n height: '6px',\n minWidth: 0,\n accentColor: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n } as CSSProperties,\n rangeValue: {\n fontSize: '12px',\n fontFamily: 'monospace',\n color: 'var(--theme-elevation-500)',\n width: '32px',\n textAlign: 'right',\n flexShrink: 0,\n } as CSSProperties,\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Generates CSS gradient string for preview\n */\nfunction getGradientPreviewCSS(gradient: GradientValue): string {\n if (!gradient.stops || gradient.stops.length === 0) {\n return 'linear-gradient(90deg, #ccc 0%, #999 100%)'\n }\n\n const sortedStops = [...gradient.stops].sort((a, b) => a.position - b.position)\n const stopsCSS = sortedStops\n .map((stop) => {\n const color = colorValueToCSS(stop.color) || 'transparent'\n return `${color} ${stop.position}%`\n })\n .join(', ')\n\n if (gradient.type === 'radial') {\n const shape = gradient.radialShape || 'circle'\n const position = gradient.radialPosition || 'center'\n return `radial-gradient(${shape} at ${position}, ${stopsCSS})`\n }\n\n return `linear-gradient(${gradient.angle}deg, ${stopsCSS})`\n}\n\n// =============================================================================\n// GradientStopEditor Component\n// =============================================================================\n\ninterface GradientStopEditorProps {\n stop: GradientStop\n index: number\n canDelete: boolean\n onColorChange: (index: number, color: ColorValue) => void\n onPositionChange: (index: number, position: number) => void\n onDelete: (index: number) => void\n readOnly?: boolean\n}\n\nfunction GradientStopEditorInner({\n stop,\n index,\n canDelete,\n onColorChange,\n onPositionChange,\n onDelete,\n readOnly,\n}: GradientStopEditorProps) {\n const [hexInput, setHexInput] = useState(stop.color.hex)\n\n const handleColorPickerChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newHex = e.target.value\n setHexInput(newHex)\n onColorChange(index, { ...stop.color, hex: newHex })\n },\n [index, stop.color, onColorChange]\n )\n\n const handleHexInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const input = e.target.value\n setHexInput(input)\n\n // Validate hex format\n const clean = input.replace(/^#/, '')\n if (/^[0-9A-Fa-f]{6}$/.test(clean)) {\n onColorChange(index, { ...stop.color, hex: `#${clean.toLowerCase()}` })\n }\n },\n [index, stop.color, onColorChange]\n )\n\n const handleOpacityChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newOpacity = parseInt(e.target.value, 10)\n onColorChange(index, { ...stop.color, opacity: newOpacity })\n },\n [index, stop.color, onColorChange]\n )\n\n const handlePositionChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newPosition = parseInt(e.target.value, 10)\n onPositionChange(index, Math.max(0, Math.min(100, newPosition)))\n },\n [index, onPositionChange]\n )\n\n const previewColor = colorValueToCSS(stop.color) || 'transparent'\n const opacity = stop.color.opacity ?? 100\n\n return (\n <div style={styles.stopItem as CSSProperties}>\n {/* Row 1: Color picker + hex input + preview swatch + delete */}\n <div style={styles.stopRow}>\n {/* Color picker */}\n <input\n type=\"color\"\n value={stop.color.hex}\n onChange={handleColorPickerChange}\n disabled={readOnly}\n style={styles.colorPicker}\n />\n\n {/* Hex input */}\n <input\n type=\"text\"\n value={hexInput}\n onChange={handleHexInputChange}\n placeholder=\"#000000\"\n disabled={readOnly}\n style={styles.hexInput}\n />\n\n {/* Preview swatch with checkerboard for transparency */}\n <div\n style={styles.swatch as CSSProperties}\n title={`${previewColor} at ${opacity}% opacity`}\n >\n <div style={styles.checkerboard as CSSProperties} />\n <div style={{ ...styles.colorOverlay as CSSProperties, backgroundColor: previewColor }} />\n </div>\n\n {/* Spacer */}\n <div style={styles.spacer} />\n\n {/* Delete button */}\n {canDelete && !readOnly && (\n <button\n type=\"button\"\n onClick={() => onDelete(index)}\n style={styles.deleteButton}\n title=\"Remove stop\"\n >\n <Trash2 style={{ width: '16px', height: '16px' }} />\n </button>\n )}\n </div>\n\n {/* Row 2: Position slider */}\n <div style={styles.stopRow}>\n <label style={styles.stopLabel}>Pos</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={stop.position}\n onChange={handlePositionChange}\n disabled={readOnly}\n style={styles.rangeSlider}\n />\n <span style={styles.rangeValue as CSSProperties}>\n {stop.position}%\n </span>\n </div>\n\n {/* Row 3: Opacity slider */}\n <div style={styles.stopRow}>\n <label style={styles.stopLabel}>Alpha</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={opacity}\n onChange={handleOpacityChange}\n disabled={readOnly}\n style={styles.rangeSlider}\n />\n <span style={styles.rangeValue as CSSProperties}>\n {opacity}%\n </span>\n </div>\n </div>\n )\n}\n\nconst GradientStopEditor = memo(GradientStopEditorInner)\n\n// =============================================================================\n// GradientEditor Component\n// =============================================================================\n\nfunction GradientEditorInner({ value, onChange, readOnly }: GradientEditorProps) {\n const currentValue = value || DEFAULT_GRADIENT\n\n // Handle gradient type change\n const handleTypeChange = useCallback(\n (type: 'linear' | 'radial') => {\n onChange({ ...currentValue, type })\n },\n [currentValue, onChange]\n )\n\n // Handle angle change\n const handleAngleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const angle = parseInt(e.target.value, 10)\n onChange({ ...currentValue, angle })\n },\n [currentValue, onChange]\n )\n\n // Handle radial shape change\n const handleRadialShapeChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange({ ...currentValue, radialShape: e.target.value as 'circle' | 'ellipse' })\n },\n [currentValue, onChange]\n )\n\n // Handle radial position change\n const handleRadialPositionChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n onChange({ ...currentValue, radialPosition: e.target.value as GradientValue['radialPosition'] })\n },\n [currentValue, onChange]\n )\n\n // Handle stop color change\n const handleStopColorChange = useCallback(\n (index: number, color: ColorValue) => {\n const newStops = [...currentValue.stops]\n newStops[index] = { ...newStops[index], color }\n onChange({ ...currentValue, stops: newStops })\n },\n [currentValue, onChange]\n )\n\n // Handle stop position change\n const handleStopPositionChange = useCallback(\n (index: number, position: number) => {\n const newStops = [...currentValue.stops]\n newStops[index] = { ...newStops[index], position }\n onChange({ ...currentValue, stops: newStops })\n },\n [currentValue, onChange]\n )\n\n // Handle add stop\n const handleAddStop = useCallback(() => {\n const newPosition = currentValue.stops.length > 0 ? 50 : 0\n const newStop: GradientStop = {\n color: { hex: '#888888', opacity: 100 },\n position: newPosition,\n }\n onChange({ ...currentValue, stops: [...currentValue.stops, newStop] })\n }, [currentValue, onChange])\n\n // Handle delete stop\n const handleDeleteStop = useCallback(\n (index: number) => {\n const newStops = currentValue.stops.filter((_, i) => i !== index)\n onChange({ ...currentValue, stops: newStops })\n },\n [currentValue, onChange]\n )\n\n const previewCSS = getGradientPreviewCSS(currentValue)\n const canDeleteStops = currentValue.stops.length > 2\n\n return (\n <div style={styles.container as CSSProperties}>\n {/* Gradient Preview */}\n <div style={{ ...styles.preview, background: previewCSS }} />\n\n {/* Type Selector */}\n <div style={styles.row}>\n <label style={styles.label}>Type</label>\n <div style={styles.buttonGroup}>\n <button\n type=\"button\"\n onClick={() => handleTypeChange('linear')}\n disabled={readOnly}\n style={currentValue.type === 'linear' ? styles.buttonActive : styles.button}\n >\n Linear\n </button>\n <button\n type=\"button\"\n onClick={() => handleTypeChange('radial')}\n disabled={readOnly}\n style={currentValue.type === 'radial' ? styles.buttonActive : styles.button}\n >\n Radial\n </button>\n </div>\n </div>\n\n {/* Linear Options: Angle */}\n {currentValue.type === 'linear' && (\n <div style={styles.row}>\n <label style={styles.label}>Angle</label>\n <input\n type=\"range\"\n min=\"0\"\n max=\"360\"\n value={currentValue.angle}\n onChange={handleAngleChange}\n disabled={readOnly}\n style={styles.slider}\n />\n <span style={styles.sliderValue as CSSProperties}>\n {currentValue.angle}deg\n </span>\n </div>\n )}\n\n {/* Radial Options: Shape & Position */}\n {currentValue.type === 'radial' && (\n <>\n <div style={styles.row}>\n <label style={styles.label}>Shape</label>\n <select\n value={currentValue.radialShape || 'circle'}\n onChange={handleRadialShapeChange}\n disabled={readOnly}\n style={styles.select}\n >\n <option value=\"circle\">Circle</option>\n <option value=\"ellipse\">Ellipse</option>\n </select>\n </div>\n <div style={styles.row}>\n <label style={styles.label}>Position</label>\n <select\n value={currentValue.radialPosition || 'center'}\n onChange={handleRadialPositionChange}\n disabled={readOnly}\n style={styles.select}\n >\n <option value=\"center\">Center</option>\n <option value=\"top\">Top</option>\n <option value=\"bottom\">Bottom</option>\n <option value=\"left\">Left</option>\n <option value=\"right\">Right</option>\n </select>\n </div>\n </>\n )}\n\n {/* Color Stops */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <div style={styles.stopsHeader}>\n <label style={styles.label}>Color Stops</label>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={handleAddStop}\n style={styles.addButton}\n >\n <Plus style={{ width: '12px', height: '12px' }} />\n Add Stop\n </button>\n )}\n </div>\n <div style={styles.stopsList as CSSProperties}>\n {currentValue.stops.map((stop, index) => (\n <GradientStopEditor\n key={index}\n stop={stop}\n index={index}\n canDelete={canDeleteStops}\n onColorChange={handleStopColorChange}\n onPositionChange={handleStopPositionChange}\n onDelete={handleDeleteStop}\n readOnly={readOnly}\n />\n ))}\n </div>\n </div>\n </div>\n )\n}\n\nexport const GradientEditor = memo(GradientEditorInner)\n"],"names":["React","useCallback","memo","useState","Plus","Trash2","colorValueToCSS","DEFAULT_GRADIENT","type","angle","stops","color","hex","opacity","position","radialShape","radialPosition","styles","container","display","flexDirection","gap","preview","height","borderRadius","border","row","alignItems","flexWrap","label","fontSize","width","flexShrink","buttonGroup","button","padding","backgroundColor","cursor","buttonActive","slider","flex","accentColor","sliderValue","fontFamily","textAlign","select","stopsHeader","justifyContent","addButton","stopsList","stopItem","overflow","stopRow","colorPicker","hexInput","minWidth","swatch","checkerboard","inset","backgroundImage","backgroundSize","backgroundPosition","colorOverlay","spacer","deleteButton","stopLabel","rangeSlider","rangeValue","getGradientPreviewCSS","gradient","length","sortedStops","sort","a","b","stopsCSS","map","stop","join","shape","GradientStopEditorInner","index","canDelete","onColorChange","onPositionChange","onDelete","readOnly","setHexInput","handleColorPickerChange","e","newHex","target","value","handleHexInputChange","input","clean","replace","test","toLowerCase","handleOpacityChange","newOpacity","parseInt","handlePositionChange","newPosition","Math","max","min","previewColor","div","style","onChange","disabled","placeholder","title","onClick","span","GradientStopEditor","GradientEditorInner","currentValue","handleTypeChange","handleAngleChange","handleRadialShapeChange","handleRadialPositionChange","handleStopColorChange","newStops","handleStopPositionChange","handleAddStop","newStop","handleDeleteStop","filter","_","i","previewCSS","canDeleteStops","background","option","GradientEditor"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LockedField.d.ts","sourceRoot":"","sources":["../../src/fields/LockedField.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAmB,MAAM,OAAO,CAAA;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAOnD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAMD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,WAAW,EACX,cAAc,GACf,EAAE,oBAAoB,qBAuFtB;AAMD,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,OAAO,EACP,cAAc,GACf,EAAE,qBAAqB,qBA0FvB;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,WAAW,CAAC,MAAM,CAAC,CActB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,WAAW,CAAC,OAAO,CAAC,CAcvB;AAMD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAI9C,CAAA;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,OAAO,CAOnD,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/LockedField.tsx"],"sourcesContent":["'use client'\n\n/**\n * LockedField - Custom Puck field wrapper that prevents accidental edits\n *\n * Wraps a field with a lock/unlock toggle. When locked, the field is read-only.\n * Click the lock icon to toggle editing.\n *\n * Exports:\n * - LockedTextField: A text input with lock/unlock functionality\n * - LockedRadioField: A radio button group with lock/unlock functionality\n * - createLockedTextField: Factory for Puck field configuration\n * - createLockedRadioField: Factory for Puck field configuration\n */\n\nimport React, { useState } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport { Lock, Unlock } from 'lucide-react'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface LockedTextFieldProps {\n value: string\n onChange: (value: string) => void\n label?: string\n placeholder?: string\n warningMessage?: string\n}\n\ninterface LockedRadioFieldProps {\n value: boolean\n onChange: (value: boolean) => void\n label?: string\n options: { label: string; value: boolean }[]\n warningMessage?: string\n}\n\n// =============================================================================\n// LockedTextField Component\n// =============================================================================\n\nexport function LockedTextField({\n value,\n onChange,\n label,\n placeholder,\n warningMessage,\n}: LockedTextFieldProps) {\n const [isLocked, setIsLocked] = useState(true)\n\n return (\n <div className=\"puck-field\">\n {/* Field header with label and lock toggle */}\n <div className=\"puck-field-header\" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '8px' }}>\n {label && (\n <label style={{ fontSize: '14px', fontWeight: 500, color: 'var(--puck-color-grey-04)' }}>{label}</label>\n )}\n <button\n type=\"button\"\n onClick={() => setIsLocked(!isLocked)}\n style={{\n background: 'none',\n border: 'none',\n padding: '4px',\n cursor: 'pointer',\n color: isLocked ? 'var(--puck-color-grey-05)' : 'var(--puck-color-azure-04)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'all 0.15s ease',\n }}\n title={isLocked ? 'Click to unlock' : 'Click to lock'}\n >\n {isLocked ? (\n <Lock size={14} />\n ) : (\n <Unlock size={14} />\n )}\n </button>\n </div>\n\n {/* Input field - matches Puck's text input style */}\n <div style={{ position: 'relative' }}>\n <input\n type=\"text\"\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n disabled={isLocked}\n placeholder={placeholder}\n style={{\n width: '100%',\n padding: '8px 12px',\n paddingRight: isLocked ? '32px' : '12px',\n fontSize: '14px',\n border: '1px solid var(--puck-color-grey-09)',\n borderRadius: '6px',\n background: isLocked ? 'var(--puck-color-grey-11)' : 'var(--puck-color-white)',\n color: isLocked ? 'var(--puck-color-grey-05)' : 'var(--puck-color-grey-04)',\n cursor: isLocked ? 'not-allowed' : 'text',\n outline: 'none',\n transition: 'all 0.15s ease',\n }}\n />\n {isLocked && (\n <Lock\n size={14}\n style={{\n position: 'absolute',\n right: '10px',\n top: '50%',\n transform: 'translateY(-50%)',\n color: 'var(--puck-color-grey-07)',\n }}\n />\n )}\n </div>\n\n {/* Warning message when unlocked */}\n {!isLocked && warningMessage && (\n <p style={{\n marginTop: '6px',\n fontSize: '12px',\n color: 'var(--puck-color-grey-05)',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}>\n <span style={{ color: 'var(--puck-color-rose-07)' }}>⚠</span>\n {warningMessage}\n </p>\n )}\n </div>\n )\n}\n\n// =============================================================================\n// LockedRadioField Component\n// =============================================================================\n\nexport function LockedRadioField({\n value,\n onChange,\n label,\n options,\n warningMessage,\n}: LockedRadioFieldProps) {\n const [isLocked, setIsLocked] = useState(true)\n\n return (\n <div className=\"puck-field\">\n {/* Field header with label and lock toggle */}\n <div className=\"puck-field-header\" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '8px' }}>\n {label && (\n <label style={{ fontSize: '14px', fontWeight: 500, color: 'var(--puck-color-grey-04)' }}>{label}</label>\n )}\n <button\n type=\"button\"\n onClick={() => setIsLocked(!isLocked)}\n style={{\n background: 'none',\n border: 'none',\n padding: '4px',\n cursor: 'pointer',\n color: isLocked ? 'var(--puck-color-grey-05)' : 'var(--puck-color-azure-04)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'all 0.15s ease',\n }}\n title={isLocked ? 'Click to unlock' : 'Click to lock'}\n >\n {isLocked ? (\n <Lock size={14} />\n ) : (\n <Unlock size={14} />\n )}\n </button>\n </div>\n\n {/* Segmented button group - matches Puck's radio style */}\n <div\n style={{\n display: 'flex',\n border: '1px solid var(--puck-color-grey-09)',\n borderRadius: '6px',\n overflow: 'hidden',\n opacity: isLocked ? 0.6 : 1,\n pointerEvents: isLocked ? 'none' : 'auto',\n }}\n >\n {options.map((option, index) => (\n <button\n key={String(option.value)}\n type=\"button\"\n onClick={() => onChange(option.value)}\n disabled={isLocked}\n style={{\n flex: 1,\n padding: '8px 16px',\n fontSize: '14px',\n fontWeight: 500,\n border: 'none',\n borderRight: index < options.length - 1 ? '1px solid var(--puck-color-grey-09)' : 'none',\n background: value === option.value\n ? 'var(--puck-color-azure-12)'\n : 'var(--puck-color-white)',\n color: value === option.value\n ? 'var(--puck-color-azure-04)'\n : 'var(--puck-color-grey-05)',\n cursor: isLocked ? 'not-allowed' : 'pointer',\n transition: 'all 0.15s ease',\n }}\n >\n {option.label}\n </button>\n ))}\n </div>\n\n {/* Warning message when unlocked */}\n {!isLocked && warningMessage && (\n <p style={{\n marginTop: '6px',\n fontSize: '12px',\n color: 'var(--puck-color-grey-05)',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}>\n <span style={{ color: 'var(--puck-color-rose-07)' }}>⚠</span>\n {warningMessage}\n </p>\n )}\n </div>\n )\n}\n\n// =============================================================================\n// Field Configuration Factories\n// =============================================================================\n\n/**\n * Creates a Puck field configuration for a locked text input\n */\nexport function createLockedTextField(config: {\n label?: string\n placeholder?: string\n warningMessage?: string\n}): CustomField<string> {\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange }) => (\n <LockedTextField\n value={value}\n onChange={onChange}\n label={config.label}\n placeholder={config.placeholder}\n warningMessage={config.warningMessage}\n />\n ),\n }\n}\n\n/**\n * Creates a Puck field configuration for a locked radio button group\n */\nexport function createLockedRadioField(config: {\n label?: string\n options: { label: string; value: boolean }[]\n warningMessage?: string\n}): CustomField<boolean> {\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange }) => (\n <LockedRadioField\n value={value}\n onChange={onChange}\n label={config.label}\n options={config.options}\n warningMessage={config.warningMessage}\n />\n ),\n }\n}\n\n// =============================================================================\n// Pre-built Field Definitions\n// =============================================================================\n\n/**\n * Pre-built locked slug field - prevents accidental URL changes\n *\n * Use in Puck root config:\n * ```tsx\n * root: {\n * fields: {\n * slug: lockedSlugField,\n * }\n * }\n * ```\n */\nexport const lockedSlugField: CustomField<string> = createLockedTextField({\n label: 'Slug',\n placeholder: 'page-slug',\n warningMessage: 'Changing may break existing links',\n})\n\n/**\n * Pre-built locked isHomepage field - prevents accidental homepage changes\n *\n * Use in Puck root config:\n * ```tsx\n * root: {\n * fields: {\n * isHomepage: lockedHomepageField,\n * }\n * }\n * ```\n */\nexport const lockedHomepageField: CustomField<boolean> = createLockedRadioField({\n label: 'Homepage',\n options: [\n { label: 'No', value: false },\n { label: 'Yes', value: true },\n ],\n warningMessage: 'Only one page can be the homepage',\n})\n"],"names":["React","useState","Lock","Unlock","LockedTextField","value","onChange","label","placeholder","warningMessage","isLocked","setIsLocked","div","className","style","display","alignItems","justifyContent","marginBottom","fontSize","fontWeight","color","button","type","onClick","background","border","padding","cursor","borderRadius","transition","title","size","position","input","e","target","disabled","width","paddingRight","outline","right","top","transform","p","marginTop","gap","span","LockedRadioField","options","overflow","opacity","pointerEvents","map","option","index","flex","borderRight","length","String","createLockedTextField","config","render","createLockedRadioField","lockedSlugField","lockedHomepageField"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarginField.d.ts","sourceRoot":"","sources":["../../src/fields/MarginField.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAgD,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG/C,MAAM,MAAM,WAAW,GAAG,YAAY,CAAA;AAQtC,UAAU,gBAAgB;IACxB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAoJD,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,SAAgB,GACjB,EAAE,gBAAgB,qBAmJlB;AAED,eAAO,MAAM,WAAW,oDAAyB,CAAA;AAMjD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GAAG,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC,CAclC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/MarginField.tsx"],"sourcesContent":["'use client'\n\n/**\n * MarginField - Custom Puck field for component margin/spacing control\n *\n * Similar to PaddingField but specifically for outer margin.\n * Provides:\n * - 4 number inputs for top/right/bottom/left\n * - Link/unlink toggle button (when linked, all values sync)\n * - Unit selector (px, rem)\n */\n\nimport React, { useCallback, memo, type CSSProperties } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport { Link, Unlink } from 'lucide-react'\nimport type { PaddingValue } from './shared.js'\n\n// Re-use PaddingValue type for margin (same structure)\nexport type MarginValue = PaddingValue\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype SpacingUnit = 'px' | 'rem' | 'em' | '%'\n\ninterface MarginFieldProps {\n value: MarginValue | null\n onChange: (value: MarginValue | null) => void\n label?: string\n readOnly?: boolean\n showUnits?: boolean\n}\n\n// =============================================================================\n// Default Value\n// =============================================================================\n\nconst DEFAULT_VALUE: MarginValue = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n unit: 'px',\n linked: true,\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n } as CSSProperties,\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n } as CSSProperties,\n label: {\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n linkButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n padding: 0,\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-bg)',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n } as CSSProperties,\n linkButtonActive: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n padding: 0,\n border: '1px solid var(--theme-elevation-800)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-elevation-800)',\n color: 'var(--theme-bg)',\n cursor: 'pointer',\n } as CSSProperties,\n grid: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '8px',\n padding: '8px',\n backgroundColor: 'var(--theme-elevation-50)',\n borderRadius: '6px',\n } as CSSProperties,\n inputRow: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n } as CSSProperties,\n inputLabel: {\n fontSize: '10px',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n color: 'var(--theme-elevation-500)',\n width: '24px',\n textAlign: 'right',\n flexShrink: 0,\n } as CSSProperties,\n input: {\n height: '28px',\n width: '100%',\n padding: '0 4px',\n textAlign: 'center',\n fontSize: '14px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n footer: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: '8px',\n } as CSSProperties,\n unitGroup: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n } as CSSProperties,\n unitLabel: {\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n unitButtons: {\n display: 'flex',\n gap: '4px',\n } as CSSProperties,\n unitButton: {\n height: '28px',\n padding: '0 10px',\n fontSize: '12px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-bg)',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n } as CSSProperties,\n unitButtonActive: {\n height: '28px',\n padding: '0 10px',\n fontSize: '12px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-800)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-elevation-800)',\n color: 'var(--theme-bg)',\n cursor: 'pointer',\n } as CSSProperties,\n summary: {\n fontSize: '12px',\n fontFamily: 'monospace',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n}\n\n// =============================================================================\n// MarginField Component\n// =============================================================================\n\nfunction MarginFieldInner({\n value,\n onChange,\n label,\n readOnly,\n showUnits = true,\n}: MarginFieldProps) {\n // Use default if no value\n const currentValue = value || DEFAULT_VALUE\n\n // Use explicit linked state from value, default to true if not set\n const isLinked = currentValue.linked ?? true\n\n // Handle individual side change\n const handleSideChange = useCallback((\n side: 'top' | 'right' | 'bottom' | 'left',\n newValue: number\n ) => {\n if (isLinked) {\n // When linked, update all sides\n onChange({\n ...currentValue,\n top: newValue,\n right: newValue,\n bottom: newValue,\n left: newValue,\n linked: true,\n })\n } else {\n // When unlinked, update only the specific side\n onChange({\n ...currentValue,\n [side]: newValue,\n linked: false,\n })\n }\n }, [currentValue, onChange, isLinked])\n\n // Handle link toggle\n const handleLinkToggle = useCallback(() => {\n if (isLinked) {\n // Unlinking - keep current values but mark as unlinked\n onChange({\n ...currentValue,\n linked: false,\n })\n } else {\n // Linking - set all sides to the top value and mark as linked\n onChange({\n ...currentValue,\n top: currentValue.top,\n right: currentValue.top,\n bottom: currentValue.top,\n left: currentValue.top,\n linked: true,\n })\n }\n }, [currentValue, onChange, isLinked])\n\n // Handle unit change\n const handleUnitChange = useCallback((unit: SpacingUnit) => {\n onChange({\n ...currentValue,\n unit,\n })\n }, [currentValue, onChange])\n\n // Render a single side input - compact horizontal layout\n const renderSideInput = (\n side: 'top' | 'right' | 'bottom' | 'left',\n sideLabel: string\n ) => (\n <div style={styles.inputRow}>\n <label style={styles.inputLabel as CSSProperties}>\n {sideLabel.charAt(0)}\n </label>\n <input\n type=\"number\"\n min={0}\n value={currentValue[side]}\n onChange={(e) => handleSideChange(side, parseInt(e.target.value, 10) || 0)}\n disabled={readOnly}\n style={styles.input as CSSProperties}\n />\n </div>\n )\n\n return (\n <div className=\"puck-field\" style={styles.container}>\n {/* Header with label and link toggle */}\n <div style={styles.header}>\n {label && (\n <label style={styles.label}>\n {label}\n </label>\n )}\n {/* Link/Unlink toggle button */}\n {!readOnly && (\n <button\n type=\"button\"\n onClick={handleLinkToggle}\n style={isLinked ? styles.linkButtonActive : styles.linkButton}\n title={isLinked ? 'Click to unlink (set sides individually)' : 'Click to link (all sides same value)'}\n >\n {isLinked ? (\n <Link style={{ width: '16px', height: '16px' }} />\n ) : (\n <Unlink style={{ width: '16px', height: '16px' }} />\n )}\n </button>\n )}\n </div>\n\n {/* Compact 2x2 grid layout */}\n <div style={styles.grid}>\n {renderSideInput('top', 'Top')}\n {renderSideInput('right', 'Right')}\n {renderSideInput('bottom', 'Bottom')}\n {renderSideInput('left', 'Left')}\n </div>\n\n {/* Unit selector and summary */}\n {showUnits && !readOnly && (\n <div style={styles.footer}>\n <div style={styles.unitGroup}>\n <label style={styles.unitLabel}>Unit:</label>\n <div style={styles.unitButtons}>\n {(['px', 'rem'] as SpacingUnit[]).map((unit) => {\n const isActive = currentValue.unit === unit\n return (\n <button\n key={unit}\n type=\"button\"\n onClick={() => handleUnitChange(unit)}\n style={isActive ? styles.unitButtonActive : styles.unitButton}\n >\n {unit}\n </button>\n )\n })}\n </div>\n </div>\n {/* Current value summary */}\n <span style={styles.summary}>\n {isLinked\n ? `${currentValue.top}${currentValue.unit}`\n : `${currentValue.top} ${currentValue.right} ${currentValue.bottom} ${currentValue.left}${currentValue.unit}`\n }\n </span>\n </div>\n )}\n </div>\n )\n}\n\nexport const MarginField = memo(MarginFieldInner)\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\n/**\n * Creates a Puck field configuration for margin/spacing\n */\nexport function createMarginField(config: {\n label?: string\n showUnits?: boolean\n}): CustomField<MarginValue | null> {\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange, readOnly }) => (\n <MarginField\n value={value}\n onChange={onChange}\n label={config.label}\n readOnly={readOnly}\n showUnits={config.showUnits}\n />\n ),\n }\n}\n"],"names":["React","useCallback","memo","Link","Unlink","DEFAULT_VALUE","top","right","bottom","left","unit","linked","styles","container","display","flexDirection","gap","header","alignItems","justifyContent","label","fontSize","fontWeight","color","linkButton","width","height","padding","border","borderRadius","backgroundColor","cursor","linkButtonActive","grid","gridTemplateColumns","inputRow","inputLabel","textTransform","letterSpacing","textAlign","flexShrink","input","fontFamily","footer","flexWrap","unitGroup","unitLabel","unitButtons","unitButton","unitButtonActive","summary","MarginFieldInner","value","onChange","readOnly","showUnits","currentValue","isLinked","handleSideChange","side","newValue","handleLinkToggle","handleUnitChange","renderSideInput","sideLabel","div","style","charAt","type","min","e","parseInt","target","disabled","className","button","onClick","title","map","isActive","span","MarginField","createMarginField","config","render"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MediaField.d.ts","sourceRoot":"","sources":["../../src/fields/MediaField.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAqE,MAAM,OAAO,CAAA;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAOnD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAA;IAChD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAmaD,iBAAS,eAAe,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,WAA0B,GAC3B,EAAE,eAAe,qBA6mBjB;AAGD,eAAO,MAAM,UAAU,mDAAwB,CAAA;AAM/C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,WAAW,CAAC,cAAc,GAAG,IAAI,CAAC,CAcrC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/MediaField.tsx"],"sourcesContent":["'use client'\n\n/**\n * MediaField - Custom Puck field for selecting Payload CMS media\n *\n * This component provides a media picker that integrates with Payload's\n * media collection, allowing users to browse and select images.\n */\n\nimport React, { useState, useEffect, useCallback, memo, type CSSProperties } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport { Image, X, Search, Loader2, Upload, AlertCircle, Link } from 'lucide-react'\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MediaReference {\n id: string | number\n url: string\n alt?: string\n width?: number\n height?: number\n}\n\ninterface MediaFieldProps {\n value: MediaReference | null\n onChange: (value: MediaReference | null) => void\n label?: string\n readOnly?: boolean\n apiEndpoint?: string\n}\n\ninterface MediaItem {\n id: string | number\n url: string\n alt?: string\n filename?: string\n width?: number\n height?: number\n mimeType?: string\n}\n\ntype DialogTab = 'browse' | 'upload' | 'url'\n\ninterface UploadState {\n file: File | null\n preview: string | null\n uploading: boolean\n error: string | null\n}\n\ninterface UrlState {\n url: string\n loading: boolean\n error: string | null\n previewLoaded: boolean\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n label: {\n display: 'block',\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-700)',\n marginBottom: '8px',\n } as CSSProperties,\n previewContainer: {\n display: 'flex',\n alignItems: 'flex-start',\n gap: '16px',\n } as CSSProperties,\n imagePreview: {\n position: 'relative',\n } as CSSProperties,\n previewImage: {\n width: '96px',\n height: '96px',\n objectFit: 'cover',\n borderRadius: '6px',\n border: '1px solid var(--theme-elevation-200)',\n } as CSSProperties,\n removeButton: {\n position: 'absolute',\n top: '-8px',\n right: '-8px',\n padding: '4px',\n backgroundColor: 'var(--theme-error-500)',\n color: 'white',\n borderRadius: '50%',\n border: 'none',\n cursor: 'pointer',\n opacity: 0,\n transition: 'opacity 0.15s',\n } as CSSProperties,\n placeholder: {\n width: '96px',\n height: '96px',\n backgroundColor: 'var(--theme-elevation-100)',\n borderRadius: '6px',\n border: '1px dashed var(--theme-elevation-300)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n } as CSSProperties,\n actionsColumn: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n } as CSSProperties,\n buttonOutline: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '6px 12px',\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-700)',\n backgroundColor: 'var(--theme-bg)',\n border: '1px solid var(--theme-elevation-300)',\n borderRadius: '6px',\n cursor: 'pointer',\n transition: 'background-color 0.15s',\n } as CSSProperties,\n buttonGhost: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '6px 12px',\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-error-600)',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n transition: 'background-color 0.15s',\n } as CSSProperties,\n buttonPrimary: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '8px 16px',\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-bg)',\n backgroundColor: 'var(--theme-elevation-900)',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n transition: 'background-color 0.15s',\n } as CSSProperties,\n buttonDisabled: {\n opacity: 0.5,\n cursor: 'not-allowed',\n } as CSSProperties,\n urlDisplay: {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n marginTop: '8px',\n } as CSSProperties,\n // Dialog styles\n dialogOverlay: {\n position: 'fixed',\n inset: 0,\n zIndex: 9999,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n } as CSSProperties,\n dialogContent: {\n backgroundColor: 'var(--theme-bg)',\n borderRadius: '8px',\n boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',\n width: '100%',\n maxWidth: '800px',\n maxHeight: '90vh',\n margin: '16px',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n } as CSSProperties,\n dialogHeader: {\n padding: '16px 20px',\n borderBottom: '1px solid var(--theme-elevation-200)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexShrink: 0,\n } as CSSProperties,\n dialogTitle: {\n fontSize: '18px',\n fontWeight: 600,\n color: 'var(--theme-elevation-900)',\n margin: 0,\n } as CSSProperties,\n closeButton: {\n padding: '4px',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: 'var(--theme-elevation-500)',\n borderRadius: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n } as CSSProperties,\n tabBar: {\n display: 'flex',\n flexWrap: 'wrap',\n borderBottom: '1px solid var(--theme-elevation-200)',\n padding: '0 20px',\n flexShrink: 0,\n } as CSSProperties,\n tabButton: {\n padding: '12px 16px',\n fontSize: '14px',\n fontWeight: 500,\n backgroundColor: 'transparent',\n border: 'none',\n borderBottomWidth: '2px',\n borderBottomStyle: 'solid',\n borderBottomColor: 'transparent',\n cursor: 'pointer',\n transition: 'color 0.15s, border-color 0.15s',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n tabButtonActive: {\n color: 'var(--theme-elevation-900)',\n borderBottomColor: 'var(--theme-elevation-900)',\n } as CSSProperties,\n searchContainer: {\n padding: '16px 20px',\n position: 'relative',\n flexShrink: 0,\n } as CSSProperties,\n searchInput: {\n width: '100%',\n padding: '8px 12px 8px 40px',\n fontSize: '14px',\n border: '1px solid var(--theme-elevation-300)',\n borderRadius: '6px',\n outline: 'none',\n } as CSSProperties,\n searchIcon: {\n position: 'absolute',\n left: '32px',\n top: '50%',\n transform: 'translateY(-50%)',\n color: 'var(--theme-elevation-400)',\n pointerEvents: 'none',\n } as CSSProperties,\n contentArea: {\n flex: 1,\n overflowY: 'auto',\n padding: '16px 20px',\n } as CSSProperties,\n mediaGrid: {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(80px, 1fr))',\n gap: '12px',\n } as CSSProperties,\n mediaItem: {\n position: 'relative',\n aspectRatio: '1',\n overflow: 'hidden',\n borderRadius: '6px',\n border: '2px solid var(--theme-elevation-200)',\n cursor: 'pointer',\n transition: 'border-color 0.15s, box-shadow 0.15s',\n backgroundColor: 'var(--theme-elevation-100)',\n } as CSSProperties,\n mediaItemSelected: {\n borderColor: 'var(--theme-elevation-900)',\n boxShadow: '0 0 0 2px var(--theme-elevation-200)',\n } as CSSProperties,\n mediaItemImage: {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n } as CSSProperties,\n mediaItemAlt: {\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.6)',\n color: 'white',\n fontSize: '12px',\n padding: '4px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n } as CSSProperties,\n loadMoreContainer: {\n display: 'flex',\n justifyContent: 'center',\n marginTop: '16px',\n } as CSSProperties,\n emptyState: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '200px',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n skeleton: {\n backgroundColor: 'var(--theme-elevation-200)',\n borderRadius: '6px',\n aspectRatio: '1',\n animation: 'pulse 2s infinite',\n } as CSSProperties,\n uploadContainer: {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n padding: '20px',\n } as CSSProperties,\n uploadPreview: {\n width: '100%',\n maxWidth: '448px',\n display: 'flex',\n flexDirection: 'column',\n gap: '16px',\n } as CSSProperties,\n uploadImageContainer: {\n position: 'relative',\n aspectRatio: '16/9',\n backgroundColor: 'var(--theme-elevation-100)',\n borderRadius: '8px',\n overflow: 'hidden',\n } as CSSProperties,\n uploadImage: {\n width: '100%',\n height: '100%',\n objectFit: 'contain',\n } as CSSProperties,\n uploadMeta: {\n fontSize: '14px',\n color: 'var(--theme-elevation-500)',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n } as CSSProperties,\n errorBox: {\n padding: '12px',\n backgroundColor: 'var(--theme-error-50)',\n border: '1px solid var(--theme-error-200)',\n borderRadius: '6px',\n color: 'var(--theme-error-700)',\n fontSize: '14px',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '8px',\n } as CSSProperties,\n actionsRow: {\n display: 'flex',\n gap: '8px',\n } as CSSProperties,\n dropZone: {\n textAlign: 'center',\n } as CSSProperties,\n dropZoneIcon: {\n width: '64px',\n height: '64px',\n color: 'var(--theme-elevation-300)',\n margin: '0 auto 16px',\n } as CSSProperties,\n hiddenInput: {\n display: 'none',\n } as CSSProperties,\n urlContainer: {\n width: '100%',\n maxWidth: '448px',\n display: 'flex',\n flexDirection: 'column',\n gap: '16px',\n } as CSSProperties,\n urlIntro: {\n textAlign: 'center',\n marginBottom: '24px',\n } as CSSProperties,\n urlIcon: {\n width: '48px',\n height: '48px',\n color: 'var(--theme-elevation-400)',\n margin: '0 auto 8px',\n } as CSSProperties,\n inputGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n } as CSSProperties,\n inputLabel: {\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-700)',\n } as CSSProperties,\n input: {\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: '1px solid var(--theme-elevation-300)',\n borderRadius: '6px',\n outline: 'none',\n } as CSSProperties,\n previewLoading: {\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'var(--theme-elevation-100)',\n } as CSSProperties,\n icon: {\n width: '16px',\n height: '16px',\n } as CSSProperties,\n iconSmall: {\n width: '12px',\n height: '12px',\n flexShrink: 0,\n } as CSSProperties,\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\nfunction formatFileSize(bytes: number | undefined): string {\n if (!bytes) return 'Unknown'\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\n// =============================================================================\n// MediaField Component\n// =============================================================================\n\nfunction MediaFieldInner({\n value,\n onChange,\n label,\n readOnly,\n apiEndpoint = '/api/media',\n}: MediaFieldProps) {\n const [isOpen, setIsOpen] = useState(false)\n const [mediaList, setMediaList] = useState<MediaItem[]>([])\n const [loading, setLoading] = useState(false)\n const [searchQuery, setSearchQuery] = useState('')\n const [page, setPage] = useState(1)\n const [hasMore, setHasMore] = useState(true)\n const [activeTab, setActiveTab] = useState<DialogTab>('browse')\n const [hoveredItem, setHoveredItem] = useState<string | number | null>(null)\n const [previewHovered, setPreviewHovered] = useState(false)\n const [uploadState, setUploadState] = useState<UploadState>({\n file: null,\n preview: null,\n uploading: false,\n error: null,\n })\n const [urlState, setUrlState] = useState<UrlState>({\n url: '',\n loading: false,\n error: null,\n previewLoaded: false,\n })\n\n // Fetch media from Payload API\n const fetchMedia = useCallback(async (searchTerm: string = '', pageNum: number = 1) => {\n setLoading(true)\n try {\n const params = new URLSearchParams({\n limit: '24',\n page: pageNum.toString(),\n sort: '-createdAt',\n })\n\n params.set('where[mimeType][contains]', 'image')\n\n if (searchTerm) {\n params.set('where[alt][contains]', searchTerm)\n }\n\n const response = await fetch(`${apiEndpoint}?${params}`)\n if (!response.ok) throw new Error('Failed to fetch media')\n\n const data = await response.json()\n const items: MediaItem[] = (data.docs || []).map((doc: Record<string, unknown>) => ({\n id: doc.id as string | number,\n url: (doc.url as string) || '',\n alt: (doc.alt as string) || '',\n filename: (doc.filename as string) || '',\n width: doc.width as number | undefined,\n height: doc.height as number | undefined,\n mimeType: (doc.mimeType as string) || '',\n }))\n\n if (pageNum === 1) {\n setMediaList(items)\n } else {\n setMediaList((prev) => [...prev, ...items])\n }\n\n setHasMore(data.hasNextPage || false)\n } catch (error) {\n console.error('Error fetching media:', error)\n } finally {\n setLoading(false)\n }\n }, [apiEndpoint])\n\n // Load media when dialog opens\n useEffect(() => {\n if (isOpen) {\n setPage(1)\n fetchMedia(searchQuery, 1)\n }\n }, [isOpen, fetchMedia, searchQuery])\n\n // Handle search with debounce\n useEffect(() => {\n if (!isOpen) return\n\n const timer = setTimeout(() => {\n setPage(1)\n fetchMedia(searchQuery, 1)\n }, 300)\n\n return () => clearTimeout(timer)\n }, [searchQuery, isOpen, fetchMedia])\n\n // Handle media selection\n const handleSelect = (item: MediaItem) => {\n onChange({\n id: item.id,\n url: item.url,\n alt: item.alt,\n width: item.width,\n height: item.height,\n })\n setIsOpen(false)\n }\n\n // Handle remove\n const handleRemove = () => {\n onChange(null)\n }\n\n // Load more\n const handleLoadMore = () => {\n const nextPage = page + 1\n setPage(nextPage)\n fetchMedia(searchQuery, nextPage)\n }\n\n // Reset upload state\n const resetUploadState = useCallback(() => {\n setUploadState((prev) => {\n if (prev.preview) URL.revokeObjectURL(prev.preview)\n return { file: null, preview: null, uploading: false, error: null }\n })\n }, [])\n\n // Reset URL state\n const resetUrlState = useCallback(() => {\n setUrlState({ url: '', loading: false, error: null, previewLoaded: false })\n }, [])\n\n // Handle URL submission\n const handleUrlSubmit = useCallback(() => {\n const url = urlState.url.trim()\n if (!url) {\n setUrlState((prev) => ({ ...prev, error: 'Please enter a URL' }))\n return\n }\n\n try {\n new URL(url)\n } catch {\n setUrlState((prev) => ({ ...prev, error: 'Please enter a valid URL' }))\n return\n }\n\n onChange({\n id: `external-${Date.now()}`,\n url: url,\n alt: '',\n })\n setIsOpen(false)\n resetUrlState()\n }, [urlState.url, onChange, resetUrlState])\n\n const handleUrlPreviewLoad = useCallback(() => {\n setUrlState((prev) => ({ ...prev, previewLoaded: true, error: null }))\n }, [])\n\n const handleUrlPreviewError = useCallback(() => {\n setUrlState((prev) => ({\n ...prev,\n previewLoaded: false,\n error: 'Unable to load image from this URL',\n }))\n }, [])\n\n // Handle file selection\n const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file) return\n\n if (!file.type.startsWith('image/')) {\n setUploadState((prev) => ({ ...prev, error: 'Only image files are allowed' }))\n return\n }\n\n setUploadState((prev) => {\n if (prev.preview) URL.revokeObjectURL(prev.preview)\n return prev\n })\n\n const preview = URL.createObjectURL(file)\n setUploadState({ file, preview, uploading: false, error: null })\n }, [])\n\n // Handle upload\n const handleUpload = useCallback(async () => {\n if (!uploadState.file) return\n\n setUploadState((prev) => ({ ...prev, uploading: true, error: null }))\n\n try {\n const formData = new FormData()\n formData.append('file', uploadState.file)\n const altText = uploadState.file.name.replace(/\\.[^/.]+$/, '').replace(/[-_]/g, ' ')\n formData.append('alt', altText)\n\n const response = await fetch(apiEndpoint, {\n method: 'POST',\n body: formData,\n })\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Upload failed' }))\n throw new Error(error.message || error.errors?.[0]?.message || 'Upload failed')\n }\n\n const data = await response.json()\n const doc = data.doc || data\n onChange({\n id: doc.id,\n url: doc.url,\n alt: doc.alt,\n width: doc.width,\n height: doc.height,\n })\n setIsOpen(false)\n resetUploadState()\n } catch (error) {\n setUploadState((prev) => ({\n ...prev,\n uploading: false,\n error: error instanceof Error ? error.message : 'Upload failed',\n }))\n }\n }, [uploadState.file, apiEndpoint, onChange, resetUploadState])\n\n // Handle dialog close\n const handleDialogClose = useCallback(() => {\n setIsOpen(false)\n resetUploadState()\n resetUrlState()\n setActiveTab('browse')\n }, [resetUploadState, resetUrlState])\n\n // Handle escape key\n useEffect(() => {\n if (!isOpen) return\n\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n handleDialogClose()\n }\n }\n\n document.addEventListener('keydown', handleEscape)\n return () => document.removeEventListener('keydown', handleEscape)\n }, [isOpen, handleDialogClose])\n\n return (\n <div className=\"puck-field\">\n {label && <label style={styles.label}>{label}</label>}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <div style={styles.previewContainer}>\n {/* Preview */}\n {value?.url ? (\n <div\n style={styles.imagePreview}\n onMouseEnter={() => setPreviewHovered(true)}\n onMouseLeave={() => setPreviewHovered(false)}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={value.url}\n alt={value.alt || ''}\n style={styles.previewImage}\n />\n {!readOnly && (\n <button\n type=\"button\"\n onClick={handleRemove}\n style={{\n ...styles.removeButton,\n opacity: previewHovered ? 1 : 0,\n }}\n aria-label=\"Remove image\"\n >\n <X style={styles.iconSmall} />\n </button>\n )}\n </div>\n ) : (\n <div style={styles.placeholder}>\n <Image style={{ width: '32px', height: '32px', color: 'var(--theme-elevation-400)' }} />\n </div>\n )}\n\n {/* Actions */}\n {!readOnly && (\n <div style={styles.actionsColumn}>\n <button\n type=\"button\"\n onClick={() => setIsOpen(true)}\n style={styles.buttonOutline}\n >\n {value ? 'Change Image' : 'Select Image'}\n </button>\n {value && (\n <button\n type=\"button\"\n onClick={handleRemove}\n style={styles.buttonGhost}\n >\n Remove\n </button>\n )}\n </div>\n )}\n </div>\n\n {/* Current URL display */}\n {value?.url && (\n <div style={styles.urlDisplay}>\n <Link style={styles.iconSmall} />\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: '280px' }} title={value.url}>\n {value.url}\n </span>\n </div>\n )}\n </div>\n\n {/* Media Picker Dialog */}\n {isOpen && (\n <div style={styles.dialogOverlay} onClick={handleDialogClose}>\n <div style={styles.dialogContent} onClick={(e) => e.stopPropagation()}>\n {/* Header */}\n <div style={styles.dialogHeader}>\n <h2 style={styles.dialogTitle}>Select Media</h2>\n <button type=\"button\" onClick={handleDialogClose} style={styles.closeButton}>\n <X style={styles.icon} />\n </button>\n </div>\n\n {/* Tab Bar */}\n <div style={styles.tabBar}>\n <button\n type=\"button\"\n onClick={() => setActiveTab('browse')}\n style={{\n ...styles.tabButton,\n ...(activeTab === 'browse' ? styles.tabButtonActive : {}),\n }}\n >\n Browse Library\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('upload')}\n style={{\n ...styles.tabButton,\n ...(activeTab === 'upload' ? styles.tabButtonActive : {}),\n }}\n >\n Upload New\n </button>\n <button\n type=\"button\"\n onClick={() => setActiveTab('url')}\n style={{\n ...styles.tabButton,\n ...(activeTab === 'url' ? styles.tabButtonActive : {}),\n }}\n >\n From URL\n </button>\n </div>\n\n {/* Search (browse tab only) */}\n {activeTab === 'browse' && (\n <div style={styles.searchContainer}>\n <Search style={styles.searchIcon as CSSProperties} />\n <input\n type=\"text\"\n placeholder=\"Search by alt text...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={styles.searchInput}\n />\n </div>\n )}\n\n {/* Content Area */}\n <div style={styles.contentArea}>\n {activeTab === 'browse' ? (\n /* Browse Tab */\n loading && mediaList.length === 0 ? (\n <div style={styles.mediaGrid}>\n {[...Array(8)].map((_, i) => (\n <div key={i} style={styles.skeleton} />\n ))}\n </div>\n ) : mediaList.length === 0 ? (\n <div style={styles.emptyState}>No images found</div>\n ) : (\n <>\n <div style={styles.mediaGrid}>\n {mediaList.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => handleSelect(item)}\n onMouseEnter={() => setHoveredItem(item.id)}\n onMouseLeave={() => setHoveredItem(null)}\n style={{\n ...styles.mediaItem,\n ...(value?.id === item.id ? styles.mediaItemSelected : {}),\n ...(hoveredItem === item.id ? { borderColor: 'var(--theme-elevation-600)' } : {}),\n }}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={item.url}\n alt={item.alt || item.filename || ''}\n style={styles.mediaItemImage}\n loading=\"lazy\"\n />\n {item.alt && (\n <div style={styles.mediaItemAlt}>{item.alt}</div>\n )}\n </button>\n ))}\n </div>\n\n {hasMore && (\n <div style={styles.loadMoreContainer}>\n <button\n type=\"button\"\n onClick={handleLoadMore}\n disabled={loading}\n style={{\n ...styles.buttonOutline,\n ...(loading ? styles.buttonDisabled : {}),\n }}\n >\n {loading ? (\n <>\n <Loader2 style={{ ...styles.icon, marginRight: '8px', animation: 'spin 1s linear infinite' }} />\n Loading...\n </>\n ) : (\n 'Load More'\n )}\n </button>\n </div>\n )}\n </>\n )\n ) : activeTab === 'upload' ? (\n /* Upload Tab */\n <div style={styles.uploadContainer}>\n {uploadState.preview ? (\n <div style={styles.uploadPreview}>\n <div style={styles.uploadImageContainer}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={uploadState.preview}\n alt=\"Preview\"\n style={styles.uploadImage}\n />\n </div>\n\n <div style={styles.uploadMeta}>\n <p><span style={{ fontWeight: 500 }}>Filename:</span> {uploadState.file?.name}</p>\n <p><span style={{ fontWeight: 500 }}>Size:</span> {formatFileSize(uploadState.file?.size)}</p>\n </div>\n\n {uploadState.error && (\n <div style={styles.errorBox}>\n <AlertCircle style={{ ...styles.icon, flexShrink: 0, marginTop: '2px' }} />\n <span>{uploadState.error}</span>\n </div>\n )}\n\n <div style={styles.actionsRow}>\n <button\n type=\"button\"\n onClick={handleUpload}\n disabled={uploadState.uploading}\n style={{\n ...styles.buttonPrimary,\n ...(uploadState.uploading ? styles.buttonDisabled : {}),\n }}\n >\n {uploadState.uploading ? (\n <>\n <Loader2 style={{ ...styles.icon, marginRight: '8px', animation: 'spin 1s linear infinite' }} />\n Uploading...\n </>\n ) : (\n <>\n <Upload style={{ ...styles.icon, marginRight: '8px' }} />\n Upload & Select\n </>\n )}\n </button>\n <button\n type=\"button\"\n onClick={resetUploadState}\n disabled={uploadState.uploading}\n style={{\n ...styles.buttonOutline,\n ...(uploadState.uploading ? styles.buttonDisabled : {}),\n }}\n >\n Cancel\n </button>\n </div>\n </div>\n ) : (\n <div style={styles.dropZone}>\n <Image style={styles.dropZoneIcon} />\n <label style={{ cursor: 'pointer' }}>\n <span style={styles.buttonPrimary}>\n Select Image\n </span>\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n style={styles.hiddenInput}\n />\n </label>\n <p style={{ marginTop: '8px', fontSize: '14px', color: 'var(--theme-elevation-500)' }}>\n Select an image file to upload\n </p>\n {uploadState.error && (\n <div style={{ ...styles.errorBox, marginTop: '16px' }}>\n {uploadState.error}\n </div>\n )}\n </div>\n )}\n </div>\n ) : activeTab === 'url' ? (\n /* URL Tab */\n <div style={styles.uploadContainer}>\n <div style={styles.urlContainer}>\n <div style={styles.urlIntro as CSSProperties}>\n <Link style={styles.urlIcon} />\n <p style={{ fontSize: '14px', color: 'var(--theme-elevation-500)' }}>\n Enter an image URL from an external source\n </p>\n </div>\n\n <div style={styles.inputGroup as CSSProperties}>\n <label style={styles.inputLabel} htmlFor=\"image-url\">Image URL</label>\n <input\n id=\"image-url\"\n type=\"url\"\n placeholder=\"https://example.com/image.jpg\"\n value={urlState.url}\n onChange={(e) =>\n setUrlState((prev) => ({\n ...prev,\n url: e.target.value,\n error: null,\n previewLoaded: false,\n }))\n }\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n handleUrlSubmit()\n }\n }}\n style={styles.input}\n />\n </div>\n\n {urlState.url && !urlState.error && (\n <div style={styles.uploadImageContainer}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={urlState.url}\n alt=\"Preview\"\n style={styles.uploadImage}\n onLoad={handleUrlPreviewLoad}\n onError={handleUrlPreviewError}\n />\n {!urlState.previewLoaded && (\n <div style={styles.previewLoading}>\n <Loader2 style={{ width: '32px', height: '32px', animation: 'spin 1s linear infinite', color: 'var(--theme-elevation-400)' }} />\n </div>\n )}\n </div>\n )}\n\n {urlState.error && (\n <div style={styles.errorBox}>\n <AlertCircle style={{ ...styles.icon, flexShrink: 0, marginTop: '2px' }} />\n <span>{urlState.error}</span>\n </div>\n )}\n\n <div style={styles.actionsRow}>\n <button\n type=\"button\"\n onClick={handleUrlSubmit}\n disabled={!urlState.url || urlState.loading}\n style={{\n ...styles.buttonPrimary,\n ...((!urlState.url || urlState.loading) ? styles.buttonDisabled : {}),\n }}\n >\n <Link style={{ ...styles.icon, marginRight: '8px' }} />\n Use This URL\n </button>\n {urlState.url && (\n <button\n type=\"button\"\n onClick={resetUrlState}\n style={styles.buttonOutline}\n >\n Clear\n </button>\n )}\n </div>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n\n// Memoize to prevent unnecessary re-renders\nexport const MediaField = memo(MediaFieldInner)\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\n/**\n * Creates a Puck field configuration for media selection\n */\nexport function createMediaField(config: {\n label?: string\n apiEndpoint?: string\n}): CustomField<MediaReference | null> {\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange, readOnly }) => (\n <MediaField\n value={value}\n onChange={onChange}\n label={config.label}\n readOnly={readOnly}\n apiEndpoint={config.apiEndpoint}\n />\n ),\n }\n}\n"],"names":["React","useState","useEffect","useCallback","memo","Image","X","Search","Loader2","Upload","AlertCircle","Link","styles","label","display","fontSize","fontWeight","color","marginBottom","previewContainer","alignItems","gap","imagePreview","position","previewImage","width","height","objectFit","borderRadius","border","removeButton","top","right","padding","backgroundColor","cursor","opacity","transition","placeholder","justifyContent","actionsColumn","flexDirection","buttonOutline","buttonGhost","buttonPrimary","buttonDisabled","urlDisplay","marginTop","dialogOverlay","inset","zIndex","dialogContent","boxShadow","maxWidth","maxHeight","margin","overflow","dialogHeader","borderBottom","flexShrink","dialogTitle","closeButton","tabBar","flexWrap","tabButton","borderBottomWidth","borderBottomStyle","borderBottomColor","tabButtonActive","searchContainer","searchInput","outline","searchIcon","left","transform","pointerEvents","contentArea","flex","overflowY","mediaGrid","gridTemplateColumns","mediaItem","aspectRatio","mediaItemSelected","borderColor","mediaItemImage","mediaItemAlt","bottom","textOverflow","whiteSpace","loadMoreContainer","emptyState","skeleton","animation","uploadContainer","minHeight","uploadPreview","uploadImageContainer","uploadImage","uploadMeta","errorBox","actionsRow","dropZone","textAlign","dropZoneIcon","hiddenInput","urlContainer","urlIntro","urlIcon","inputGroup","inputLabel","input","previewLoading","icon","iconSmall","formatFileSize","bytes","toFixed","MediaFieldInner","value","onChange","readOnly","apiEndpoint","isOpen","setIsOpen","mediaList","setMediaList","loading","setLoading","searchQuery","setSearchQuery","page","setPage","hasMore","setHasMore","activeTab","setActiveTab","hoveredItem","setHoveredItem","previewHovered","setPreviewHovered","uploadState","setUploadState","file","preview","uploading","error","urlState","setUrlState","url","previewLoaded","fetchMedia","searchTerm","pageNum","params","URLSearchParams","limit","toString","sort","set","response","fetch","ok","Error","data","json","items","docs","map","doc","id","alt","filename","mimeType","prev","hasNextPage","console","timer","setTimeout","clearTimeout","handleSelect","item","handleRemove","handleLoadMore","nextPage","resetUploadState","URL","revokeObjectURL","resetUrlState","handleUrlSubmit","trim","Date","now","handleUrlPreviewLoad","handleUrlPreviewError","handleFileSelect","e","target","files","type","startsWith","createObjectURL","handleUpload","formData","FormData","append","altText","name","replace","method","body","catch","message","errors","handleDialogClose","handleEscape","key","document","addEventListener","removeEventListener","div","className","style","onMouseEnter","onMouseLeave","img","src","button","onClick","aria-label","span","title","stopPropagation","h2","length","Array","_","i","disabled","marginRight","p","size","accept","htmlFor","onKeyDown","preventDefault","onLoad","onError","MediaField","createMediaField","config","render"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PaddingField.d.ts","sourceRoot":"","sources":["../../src/fields/PaddingField.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAgD,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAQ/C,UAAU,iBAAiB;IACzB,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,KAAK,IAAI,CAAA;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAoJD,iBAAS,iBAAiB,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,SAAgB,GACjB,EAAE,iBAAiB,qBAmJnB;AAED,eAAO,MAAM,YAAY,qDAA0B,CAAA;AAMnD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GAAG,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,CAcnC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/PaddingField.tsx"],"sourcesContent":["'use client'\n\n/**\n * PaddingField - Custom Puck field for 4-sided padding/margin control\n *\n * This component provides:\n * - 4 number inputs for top/right/bottom/left\n * - Link/unlink toggle button (when linked, all values sync)\n * - Unit selector (px, rem)\n */\n\nimport React, { useCallback, memo, type CSSProperties } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport { Link, Unlink } from 'lucide-react'\nimport type { PaddingValue } from './shared.js'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype SpacingUnit = 'px' | 'rem' | 'em' | '%'\n\ninterface PaddingFieldProps {\n value: PaddingValue | null\n onChange: (value: PaddingValue | null) => void\n label?: string\n readOnly?: boolean\n showUnits?: boolean\n}\n\n// =============================================================================\n// Default Value\n// =============================================================================\n\nconst DEFAULT_VALUE: PaddingValue = {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n unit: 'px',\n linked: true,\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n } as CSSProperties,\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n } as CSSProperties,\n label: {\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n linkButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n padding: 0,\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-bg)',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n } as CSSProperties,\n linkButtonActive: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n padding: 0,\n border: '1px solid var(--theme-elevation-800)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-elevation-800)',\n color: 'var(--theme-bg)',\n cursor: 'pointer',\n } as CSSProperties,\n grid: {\n display: 'grid',\n gridTemplateColumns: '1fr 1fr',\n gap: '8px',\n padding: '8px',\n backgroundColor: 'var(--theme-elevation-50)',\n borderRadius: '6px',\n } as CSSProperties,\n inputRow: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n } as CSSProperties,\n inputLabel: {\n fontSize: '10px',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n color: 'var(--theme-elevation-500)',\n width: '24px',\n textAlign: 'right',\n flexShrink: 0,\n } as CSSProperties,\n input: {\n height: '28px',\n width: '100%',\n padding: '0 4px',\n textAlign: 'center',\n fontSize: '14px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-input-bg)',\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n footer: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: '8px',\n } as CSSProperties,\n unitGroup: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n } as CSSProperties,\n unitLabel: {\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n unitButtons: {\n display: 'flex',\n gap: '4px',\n } as CSSProperties,\n unitButton: {\n height: '28px',\n padding: '0 10px',\n fontSize: '12px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-bg)',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n } as CSSProperties,\n unitButtonActive: {\n height: '28px',\n padding: '0 10px',\n fontSize: '12px',\n fontFamily: 'monospace',\n border: '1px solid var(--theme-elevation-800)',\n borderRadius: '4px',\n backgroundColor: 'var(--theme-elevation-800)',\n color: 'var(--theme-bg)',\n cursor: 'pointer',\n } as CSSProperties,\n summary: {\n fontSize: '12px',\n fontFamily: 'monospace',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n}\n\n// =============================================================================\n// PaddingField Component\n// =============================================================================\n\nfunction PaddingFieldInner({\n value,\n onChange,\n label,\n readOnly,\n showUnits = true,\n}: PaddingFieldProps) {\n // Use default if no value\n const currentValue = value || DEFAULT_VALUE\n\n // Use explicit linked state from value, default to true if not set\n const isLinked = currentValue.linked ?? true\n\n // Handle individual side change\n const handleSideChange = useCallback((\n side: 'top' | 'right' | 'bottom' | 'left',\n newValue: number\n ) => {\n if (isLinked) {\n // When linked, update all sides\n onChange({\n ...currentValue,\n top: newValue,\n right: newValue,\n bottom: newValue,\n left: newValue,\n linked: true,\n })\n } else {\n // When unlinked, update only the specific side\n onChange({\n ...currentValue,\n [side]: newValue,\n linked: false,\n })\n }\n }, [currentValue, onChange, isLinked])\n\n // Handle link toggle\n const handleLinkToggle = useCallback(() => {\n if (isLinked) {\n // Unlinking - keep current values but mark as unlinked\n onChange({\n ...currentValue,\n linked: false,\n })\n } else {\n // Linking - set all sides to the top value and mark as linked\n onChange({\n ...currentValue,\n top: currentValue.top,\n right: currentValue.top,\n bottom: currentValue.top,\n left: currentValue.top,\n linked: true,\n })\n }\n }, [currentValue, onChange, isLinked])\n\n // Handle unit change\n const handleUnitChange = useCallback((unit: SpacingUnit) => {\n onChange({\n ...currentValue,\n unit,\n })\n }, [currentValue, onChange])\n\n // Render a single side input - compact horizontal layout\n const renderSideInput = (\n side: 'top' | 'right' | 'bottom' | 'left',\n sideLabel: string\n ) => (\n <div style={styles.inputRow}>\n <label style={styles.inputLabel as CSSProperties}>\n {sideLabel.charAt(0)}\n </label>\n <input\n type=\"number\"\n min={0}\n value={currentValue[side]}\n onChange={(e) => handleSideChange(side, parseInt(e.target.value, 10) || 0)}\n disabled={readOnly}\n style={styles.input as CSSProperties}\n />\n </div>\n )\n\n return (\n <div className=\"puck-field\" style={styles.container}>\n {/* Header with label and link toggle */}\n <div style={styles.header}>\n {label && (\n <label style={styles.label}>\n {label}\n </label>\n )}\n {/* Link/Unlink toggle button */}\n {!readOnly && (\n <button\n type=\"button\"\n onClick={handleLinkToggle}\n style={isLinked ? styles.linkButtonActive : styles.linkButton}\n title={isLinked ? 'Click to unlink (set sides individually)' : 'Click to link (all sides same value)'}\n >\n {isLinked ? (\n <Link style={{ width: '16px', height: '16px' }} />\n ) : (\n <Unlink style={{ width: '16px', height: '16px' }} />\n )}\n </button>\n )}\n </div>\n\n {/* Compact 2x2 grid layout */}\n <div style={styles.grid}>\n {renderSideInput('top', 'Top')}\n {renderSideInput('right', 'Right')}\n {renderSideInput('bottom', 'Bottom')}\n {renderSideInput('left', 'Left')}\n </div>\n\n {/* Unit selector and summary */}\n {showUnits && !readOnly && (\n <div style={styles.footer}>\n <div style={styles.unitGroup}>\n <label style={styles.unitLabel}>Unit:</label>\n <div style={styles.unitButtons}>\n {(['px', 'rem'] as SpacingUnit[]).map((unit) => {\n const isActive = currentValue.unit === unit\n return (\n <button\n key={unit}\n type=\"button\"\n onClick={() => handleUnitChange(unit)}\n style={isActive ? styles.unitButtonActive : styles.unitButton}\n >\n {unit}\n </button>\n )\n })}\n </div>\n </div>\n {/* Current value summary */}\n <span style={styles.summary}>\n {isLinked\n ? `${currentValue.top}${currentValue.unit}`\n : `${currentValue.top} ${currentValue.right} ${currentValue.bottom} ${currentValue.left}${currentValue.unit}`\n }\n </span>\n </div>\n )}\n </div>\n )\n}\n\nexport const PaddingField = memo(PaddingFieldInner)\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\n/**\n * Creates a Puck field configuration for padding/spacing\n */\nexport function createPaddingField(config: {\n label?: string\n showUnits?: boolean\n}): CustomField<PaddingValue | null> {\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange, readOnly }) => (\n <PaddingField\n value={value}\n onChange={onChange}\n label={config.label}\n readOnly={readOnly}\n showUnits={config.showUnits}\n />\n ),\n }\n}\n"],"names":["React","useCallback","memo","Link","Unlink","DEFAULT_VALUE","top","right","bottom","left","unit","linked","styles","container","display","flexDirection","gap","header","alignItems","justifyContent","label","fontSize","fontWeight","color","linkButton","width","height","padding","border","borderRadius","backgroundColor","cursor","linkButtonActive","grid","gridTemplateColumns","inputRow","inputLabel","textTransform","letterSpacing","textAlign","flexShrink","input","fontFamily","footer","flexWrap","unitGroup","unitLabel","unitButtons","unitButton","unitButtonActive","summary","PaddingFieldInner","value","onChange","readOnly","showUnits","currentValue","isLinked","handleSideChange","side","newValue","handleLinkToggle","handleUnitChange","renderSideInput","sideLabel","div","style","charAt","type","min","e","parseInt","target","disabled","className","button","onClick","title","map","isActive","span","PaddingField","createPaddingField","config","render"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PageSegmentField.d.ts","sourceRoot":"","sources":["../../src/fields/PageSegmentField.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAA;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAwBnD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,UAAU,2BAA4B,SAAQ,qBAAqB;IACjE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAMD,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,KAAsB,EACtB,WAA4B,GAC7B,EAAE,qBAAqB,qBAqFvB;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,WAAW,CAAC,MAAM,CAAC,CAatB;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,KAAK,EACL,QAAQ,EACR,KAAsB,EACtB,WAA4B,EAC5B,cAAoD,GACrD,EAAE,2BAA2B,qBA4I7B;AAMD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,CAAC,EAAE;IACpD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,WAAW,CAAC,MAAM,CAAC,CActB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/PageSegmentField.tsx"],"sourcesContent":["'use client'\n\n/**\n * PageSegmentField - Custom Puck field for page segment editing\n *\n * Provides an editable text field with automatic slugification.\n * Integrates with @delmaredigital/payload-page-tree plugin.\n *\n * Exports:\n * - PageSegmentField: Basic editable page segment field\n * - LockedPageSegmentField: Locked by default, requires clicking lock icon to edit\n * - createPageSegmentField: Factory for basic field\n * - createLockedPageSegmentField: Factory for locked field (recommended for page-tree)\n */\n\nimport React, { useState, useCallback, useEffect, useRef } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport { Lock, Unlock } from 'lucide-react'\n\n// =============================================================================\n// Slugify Utility\n// =============================================================================\n\n/**\n * Converts a string to a URL-safe slug\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '') // Remove special characters\n .replace(/[\\s_]+/g, '-') // Replace spaces and underscores with hyphens\n .replace(/-+/g, '-') // Remove consecutive hyphens\n .replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface PageSegmentFieldProps {\n value: string\n onChange: (value: string) => void\n label?: string\n placeholder?: string\n}\n\ninterface LockedPageSegmentFieldProps extends PageSegmentFieldProps {\n warningMessage?: string\n}\n\n// =============================================================================\n// PageSegmentField Component\n// =============================================================================\n\nexport function PageSegmentField({\n value,\n onChange,\n label = 'Page Segment',\n placeholder = 'page-segment',\n}: PageSegmentFieldProps) {\n const [localValue, setLocalValue] = useState(value)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n\n // Sync with external value changes\n useEffect(() => {\n if (!isFocused) {\n setLocalValue(value)\n }\n }, [value, isFocused])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value\n setLocalValue(newValue)\n }, [])\n\n const handleBlur = useCallback(() => {\n setIsFocused(false)\n // Slugify on blur\n const slugified = slugify(localValue)\n setLocalValue(slugified)\n onChange(slugified)\n }, [localValue, onChange])\n\n const handleFocus = useCallback(() => {\n setIsFocused(true)\n }, [])\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n inputRef.current?.blur()\n }\n }, [])\n\n return (\n <div className=\"puck-field\">\n {/* Label */}\n <label\n style={{\n display: 'block',\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--puck-color-grey-04)',\n marginBottom: '8px',\n }}\n >\n {label}\n </label>\n\n {/* Input */}\n <input\n ref={inputRef}\n type=\"text\"\n value={localValue}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n style={{\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: `1px solid ${isFocused ? 'var(--puck-color-azure-06)' : 'var(--puck-color-grey-09)'}`,\n borderRadius: '6px',\n backgroundColor: 'var(--puck-color-white)',\n color: 'var(--puck-color-grey-04)',\n outline: 'none',\n transition: 'border-color 0.15s ease',\n }}\n />\n\n {/* Helper text */}\n <p\n style={{\n marginTop: '6px',\n fontSize: '12px',\n color: 'var(--puck-color-grey-06)',\n }}\n >\n Auto-slugified on blur. Used in URL path.\n </p>\n </div>\n )\n}\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\n/**\n * Creates a Puck field configuration for page segment editing\n */\nexport function createPageSegmentField(config?: {\n label?: string\n placeholder?: string\n}): CustomField<string> {\n return {\n type: 'custom',\n label: config?.label ?? 'Page Segment',\n render: ({ value, onChange }) => (\n <PageSegmentField\n value={value || ''}\n onChange={onChange}\n label={config?.label}\n placeholder={config?.placeholder}\n />\n ),\n }\n}\n\n// =============================================================================\n// LockedPageSegmentField Component\n// =============================================================================\n\n/**\n * PageSegmentField with lock/unlock functionality.\n * Starts locked to prevent accidental URL changes.\n */\nexport function LockedPageSegmentField({\n value,\n onChange,\n label = 'Page Segment',\n placeholder = 'page-segment',\n warningMessage = 'Changing may break existing links',\n}: LockedPageSegmentFieldProps) {\n const [isLocked, setIsLocked] = useState(true)\n const [localValue, setLocalValue] = useState(value)\n const [isFocused, setIsFocused] = useState(false)\n const inputRef = useRef<HTMLInputElement>(null)\n\n // Sync with external value changes\n useEffect(() => {\n if (!isFocused) {\n setLocalValue(value)\n }\n }, [value, isFocused])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value\n setLocalValue(newValue)\n }, [])\n\n const handleBlur = useCallback(() => {\n setIsFocused(false)\n // Slugify on blur\n const slugified = slugify(localValue)\n setLocalValue(slugified)\n onChange(slugified)\n }, [localValue, onChange])\n\n const handleFocus = useCallback(() => {\n setIsFocused(true)\n }, [])\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n inputRef.current?.blur()\n }\n }, [])\n\n return (\n <div className=\"puck-field\">\n {/* Field header with label and lock toggle */}\n <div\n className=\"puck-field-header\"\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '8px',\n }}\n >\n <label\n style={{\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--puck-color-grey-04)',\n }}\n >\n {label}\n </label>\n <button\n type=\"button\"\n onClick={() => setIsLocked(!isLocked)}\n style={{\n background: 'none',\n border: 'none',\n padding: '4px',\n cursor: 'pointer',\n color: isLocked ? 'var(--puck-color-grey-05)' : 'var(--puck-color-azure-04)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '4px',\n transition: 'all 0.15s ease',\n }}\n title={isLocked ? 'Click to unlock' : 'Click to lock'}\n >\n {isLocked ? <Lock size={14} /> : <Unlock size={14} />}\n </button>\n </div>\n\n {/* Input field */}\n <div style={{ position: 'relative' }}>\n <input\n ref={inputRef}\n type=\"text\"\n value={localValue}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={isLocked}\n placeholder={placeholder}\n style={{\n width: '100%',\n padding: '8px 12px',\n paddingRight: isLocked ? '32px' : '12px',\n fontSize: '14px',\n border: `1px solid ${isFocused && !isLocked ? 'var(--puck-color-azure-06)' : 'var(--puck-color-grey-09)'}`,\n borderRadius: '6px',\n backgroundColor: isLocked ? 'var(--puck-color-grey-11)' : 'var(--puck-color-white)',\n color: isLocked ? 'var(--puck-color-grey-05)' : 'var(--puck-color-grey-04)',\n cursor: isLocked ? 'not-allowed' : 'text',\n outline: 'none',\n transition: 'all 0.15s ease',\n }}\n />\n {isLocked && (\n <Lock\n size={14}\n style={{\n position: 'absolute',\n right: '10px',\n top: '50%',\n transform: 'translateY(-50%)',\n color: 'var(--puck-color-grey-07)',\n }}\n />\n )}\n </div>\n\n {/* Helper text / Warning message */}\n <p\n style={{\n marginTop: '6px',\n fontSize: '12px',\n color: 'var(--puck-color-grey-06)',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n {!isLocked && warningMessage ? (\n <>\n <span style={{ color: 'var(--puck-color-rose-07)' }}>⚠</span>\n {warningMessage}\n </>\n ) : (\n 'Auto-slugified on blur. Used in URL path.'\n )}\n </p>\n </div>\n )\n}\n\n// =============================================================================\n// Locked Field Configuration Factory\n// =============================================================================\n\n/**\n * Creates a Puck field configuration for a locked page segment field.\n * Recommended for page-tree integration to prevent accidental URL changes.\n */\nexport function createLockedPageSegmentField(config?: {\n label?: string\n placeholder?: string\n warningMessage?: string\n}): CustomField<string> {\n return {\n type: 'custom',\n label: config?.label ?? 'Page Segment',\n render: ({ value, onChange }) => (\n <LockedPageSegmentField\n value={value || ''}\n onChange={onChange}\n label={config?.label}\n placeholder={config?.placeholder}\n warningMessage={config?.warningMessage}\n />\n ),\n }\n}\n"],"names":["React","useState","useCallback","useEffect","useRef","Lock","Unlock","slugify","text","toLowerCase","trim","replace","PageSegmentField","value","onChange","label","placeholder","localValue","setLocalValue","isFocused","setIsFocused","inputRef","handleChange","e","newValue","target","handleBlur","slugified","handleFocus","handleKeyDown","key","current","blur","div","className","style","display","fontSize","fontWeight","color","marginBottom","input","ref","type","onFocus","onBlur","onKeyDown","width","padding","border","borderRadius","backgroundColor","outline","transition","p","marginTop","createPageSegmentField","config","render","LockedPageSegmentField","warningMessage","isLocked","setIsLocked","alignItems","justifyContent","button","onClick","background","cursor","title","size","position","disabled","paddingRight","right","top","transform","gap","span","createLockedPageSegmentField"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ResetField.d.ts","sourceRoot":"","sources":["../../src/fields/ResetField.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAgD,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAYnD,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAqCD,iBAAS,eAAe,CAAC,EACvB,OAAO,EACP,KAA2B,EAC3B,QAAQ,GACT,EAAE,eAAe,qBA2BjB;AAED,eAAO,MAAM,UAAU,mDAAwB,CAAA;AA+C/C,UAAU,sBAAsB,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,CAAC,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAC/C,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAChC,WAAW,CAAC,OAAO,CAAC,CAuCtB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/ResetField.tsx"],"sourcesContent":["'use client'\n\n/**\n * ResetField - Custom Puck field for resetting component to defaults\n *\n * This field renders a reset button that clears all customizations\n * and restores the component to its default state.\n *\n * Uses Puck's usePuck hook and dispatch to properly update component data.\n */\n\nimport React, { memo, useCallback, type CSSProperties } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport { createUsePuck } from '@puckeditor/core'\nimport type { Data } from '@puckeditor/core'\nimport { RefreshCw } from 'lucide-react'\n\n// Create usePuck hook for accessing editor state\nconst usePuck = createUsePuck()\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface ResetFieldProps {\n onClick: () => void\n label?: string\n disabled?: boolean\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n } as CSSProperties,\n button: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '6px',\n width: '100%',\n padding: '6px 12px',\n fontSize: '14px',\n fontWeight: 500,\n border: 'none',\n borderRadius: '4px',\n backgroundColor: 'transparent',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n transition: 'all 0.15s',\n } as CSSProperties,\n buttonDisabled: {\n opacity: 0.5,\n cursor: 'not-allowed',\n } as CSSProperties,\n}\n\n// =============================================================================\n// ResetField Component\n// =============================================================================\n\nfunction ResetFieldInner({\n onClick,\n label = 'Reset to defaults',\n disabled,\n}: ResetFieldProps) {\n return (\n <div className=\"puck-field\" style={styles.container}>\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n style={{\n ...styles.button,\n ...(disabled ? styles.buttonDisabled : {}),\n }}\n onMouseOver={(e) => {\n if (!disabled) {\n e.currentTarget.style.color = 'var(--theme-error-500)'\n e.currentTarget.style.backgroundColor = 'rgba(239, 68, 68, 0.1)'\n }\n }}\n onMouseOut={(e) => {\n e.currentTarget.style.color = 'var(--theme-elevation-500)'\n e.currentTarget.style.backgroundColor = 'transparent'\n }}\n >\n <RefreshCw style={{ width: '14px', height: '14px' }} />\n {label}\n </button>\n </div>\n )\n}\n\nexport const ResetField = memo(ResetFieldInner)\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Recursively update a component's props in Puck data structure\n */\nfunction updateComponentInData(\n data: Data,\n componentId: string,\n newProps: Record<string, unknown>\n): Data {\n const updateItem = (item: { type: string; props: Record<string, unknown> }) => {\n if (item.props?.id === componentId) {\n return {\n ...item,\n props: {\n ...newProps,\n id: componentId,\n },\n }\n }\n return item\n }\n\n const updatedContent = data.content.map(updateItem)\n\n const updatedZones: Record<string, Array<{ type: string; props: Record<string, unknown> }>> = {}\n if (data.zones) {\n for (const [zoneName, zoneContent] of Object.entries(data.zones)) {\n updatedZones[zoneName] = (zoneContent as Array<{ type: string; props: Record<string, unknown> }>).map(updateItem)\n }\n }\n\n return {\n ...data,\n content: updatedContent,\n zones: Object.keys(updatedZones).length > 0 ? updatedZones : data.zones,\n }\n}\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\ninterface CreateResetFieldConfig<T> {\n label?: string\n defaultProps: T\n}\n\n/**\n * Creates a Puck field configuration for a reset button\n */\nexport function createResetField<T extends object>(\n config: CreateResetFieldConfig<T>\n): CustomField<unknown> {\n const ResetFieldWrapper = ({ readOnly }: { readOnly?: boolean }) => {\n const appState = usePuck((s) => s.appState)\n const dispatch = usePuck((s) => s.dispatch)\n const selectedItem = usePuck((s) => s.selectedItem)\n\n const handleReset = useCallback(() => {\n if (!selectedItem?.props?.id) {\n console.warn('ResetField: No selected item found')\n return\n }\n\n const componentId = selectedItem.props.id as string\n\n const updatedData = updateComponentInData(\n appState.data,\n componentId,\n config.defaultProps as unknown as Record<string, unknown>\n )\n\n dispatch({\n type: 'setData',\n data: updatedData,\n })\n }, [appState.data, dispatch, selectedItem])\n\n return (\n <ResetField\n onClick={handleReset}\n label={config.label}\n disabled={readOnly}\n />\n )\n }\n\n return {\n type: 'custom',\n render: ({ readOnly }) => <ResetFieldWrapper readOnly={readOnly} />,\n }\n}\n"],"names":["React","memo","useCallback","createUsePuck","RefreshCw","usePuck","styles","container","display","flexDirection","button","alignItems","justifyContent","gap","width","padding","fontSize","fontWeight","border","borderRadius","backgroundColor","color","cursor","transition","buttonDisabled","opacity","ResetFieldInner","onClick","label","disabled","div","className","style","type","onMouseOver","e","currentTarget","onMouseOut","height","ResetField","updateComponentInData","data","componentId","newProps","updateItem","item","props","id","updatedContent","content","map","updatedZones","zones","zoneName","zoneContent","Object","entries","keys","length","createResetField","config","ResetFieldWrapper","readOnly","appState","s","dispatch","selectedItem","handleReset","console","warn","updatedData","defaultProps","render"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ResponsiveField.d.ts","sourceRoot":"","sources":["../../src/fields/ResponsiveField.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAA0D,MAAM,OAAO,CAAA;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAQnD,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,aAAa,CAAA;AAO9D,UAAU,oBAAoB,CAAC,CAAC;IAC9B,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IACpD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,gBAAgB,EAAE,CAAC,KAAK,EAAE;QACxB,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;QACf,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;QAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;KACnB,KAAK,KAAK,CAAC,SAAS,CAAA;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,CAAC,CAAA;CACjB;AA4XD,eAAO,MAAM,eAAe,EAAiC,CAAC,CAAC,EAC7D,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAC3B,KAAK,CAAC,YAAY,CAAA;AAMvB,UAAU,2BAA2B,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IACjE,YAAY,CAAC,EAAE,CAAC,CAAA;CACjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACrC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CA6BxC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/ResponsiveField.tsx"],"sourcesContent":["'use client'\n\n/**\n * ResponsiveField - Generic wrapper for breakpoint-specific field overrides\n *\n * This component wraps any existing field to provide responsive overrides\n * at different breakpoints (xs, sm, md, lg, xl). It uses sparse storage,\n * only storing values for breakpoints that have explicit overrides.\n */\n\nimport React, { useState, useCallback, memo, type CSSProperties } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport {\n Smartphone,\n Tablet,\n Laptop,\n Monitor,\n X,\n} from 'lucide-react'\nimport type { Breakpoint, ResponsiveValue } from './shared.js'\nimport { BREAKPOINTS } from './shared.js'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface ResponsiveFieldProps<T> {\n value: ResponsiveValue<T> | null\n onChange: (value: ResponsiveValue<T> | null) => void\n label?: string\n readOnly?: boolean\n /** Render function for the inner field */\n renderInnerField: (props: {\n value: T | null\n onChange: (v: T | null) => void\n readOnly?: boolean\n }) => React.ReactNode\n /** Default value for the xs breakpoint */\n defaultValue?: T\n}\n\n// =============================================================================\n// Breakpoint Icons\n// =============================================================================\n\nconst BREAKPOINT_ICONS: Record<Breakpoint, React.ComponentType<{ style?: CSSProperties }>> = {\n xs: Smartphone,\n sm: Smartphone,\n md: Tablet,\n lg: Laptop,\n xl: Monitor,\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: '12px',\n } as CSSProperties,\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n } as CSSProperties,\n labelGroup: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n } as CSSProperties,\n label: {\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n overrideBadge: {\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n backgroundColor: 'var(--theme-elevation-100)',\n padding: '2px 6px',\n borderRadius: '4px',\n } as CSSProperties,\n clearButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: 0,\n border: 'none',\n borderRadius: '4px',\n backgroundColor: 'transparent',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n } as CSSProperties,\n tabsContainer: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '4px',\n padding: '4px',\n backgroundColor: 'var(--theme-elevation-50)',\n borderRadius: '8px',\n } as CSSProperties,\n tab: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n padding: '6px 8px',\n fontSize: '12px',\n fontWeight: 500,\n borderRadius: '6px',\n border: 'none',\n cursor: 'pointer',\n transition: 'all 0.15s',\n flex: '1 1 auto',\n minWidth: '52px',\n backgroundColor: 'var(--theme-elevation-100)',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n tabActive: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '4px',\n padding: '6px 8px',\n fontSize: '12px',\n fontWeight: 500,\n borderRadius: '6px',\n border: 'none',\n cursor: 'pointer',\n transition: 'all 0.15s',\n flex: '1 1 auto',\n minWidth: '52px',\n backgroundColor: 'var(--theme-elevation-800)',\n color: 'var(--theme-bg)',\n } as CSSProperties,\n tabDisabled: {\n opacity: 0.5,\n cursor: 'not-allowed',\n } as CSSProperties,\n overrideIndicator: {\n position: 'absolute',\n top: '-2px',\n right: '-2px',\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: 'var(--theme-elevation-800)',\n } as CSSProperties,\n infoRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n clearOverrideButton: {\n padding: '2px 8px',\n fontSize: '12px',\n border: 'none',\n borderRadius: '4px',\n backgroundColor: 'transparent',\n color: 'var(--theme-elevation-500)',\n cursor: 'pointer',\n } as CSSProperties,\n innerFieldContainer: {\n padding: '12px',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: '6px',\n } as CSSProperties,\n}\n\n// =============================================================================\n// Breakpoint Tab Button\n// =============================================================================\n\ninterface BreakpointTabProps {\n breakpoint: Breakpoint\n label: string\n minWidth: number | null\n isActive: boolean\n hasOverride: boolean\n onClick: () => void\n disabled?: boolean\n}\n\nfunction BreakpointTab({\n breakpoint,\n label,\n minWidth,\n isActive,\n hasOverride,\n onClick,\n disabled,\n}: BreakpointTabProps) {\n const Icon = BREAKPOINT_ICONS[breakpoint]\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n title={minWidth ? `${label} (${minWidth}px+)` : label}\n style={{\n ...(isActive ? styles.tabActive : styles.tab),\n ...(disabled ? styles.tabDisabled : {}),\n }}\n >\n <Icon style={{ width: '14px', height: '14px' }} />\n <span>{label}</span>\n {/* Override indicator dot */}\n {hasOverride && !isActive && (\n <span style={styles.overrideIndicator as CSSProperties} />\n )}\n </button>\n )\n}\n\n// =============================================================================\n// ResponsiveField Component\n// =============================================================================\n\nfunction ResponsiveFieldInner<T>({\n value,\n onChange,\n label,\n readOnly,\n renderInnerField,\n defaultValue,\n}: ResponsiveFieldProps<T>) {\n const [activeBreakpoint, setActiveBreakpoint] = useState<Breakpoint>('xs')\n\n // Get the current value for the active breakpoint\n const getCurrentValue = useCallback((): T | null => {\n if (!value) return null\n\n if (activeBreakpoint === 'xs') {\n return value.xs ?? defaultValue ?? null\n }\n\n const override = value[activeBreakpoint]\n if (override !== undefined) {\n return override\n }\n\n const breakpointOrder: Breakpoint[] = ['xl', 'lg', 'md', 'sm', 'xs']\n const activeIndex = breakpointOrder.indexOf(activeBreakpoint)\n\n for (let i = activeIndex + 1; i < breakpointOrder.length; i++) {\n const bp = breakpointOrder[i]\n const val = value[bp]\n if (val !== undefined) {\n return val\n }\n }\n\n return defaultValue ?? null\n }, [value, activeBreakpoint, defaultValue])\n\n const hasOverride = useCallback(\n (breakpoint: Breakpoint): boolean => {\n if (!value) return false\n if (breakpoint === 'xs') return false\n return value[breakpoint] !== undefined\n },\n [value]\n )\n\n const getInheritanceSource = useCallback((): Breakpoint | null => {\n if (!value || activeBreakpoint === 'xs') return null\n if (value[activeBreakpoint] !== undefined) return null\n\n const breakpointOrder: Breakpoint[] = ['xl', 'lg', 'md', 'sm', 'xs']\n const activeIndex = breakpointOrder.indexOf(activeBreakpoint)\n\n for (let i = activeIndex + 1; i < breakpointOrder.length; i++) {\n const bp = breakpointOrder[i]\n if (value[bp] !== undefined) {\n return bp\n }\n }\n\n return null\n }, [value, activeBreakpoint])\n\n const handleInnerChange = useCallback(\n (newValue: T | null) => {\n if (activeBreakpoint === 'xs') {\n if (newValue === null) {\n onChange(null)\n } else {\n onChange({ ...value, xs: newValue } as ResponsiveValue<T>)\n }\n } else {\n if (newValue === null) {\n if (!value) return\n const newResponsive = { ...value }\n delete newResponsive[activeBreakpoint]\n onChange(newResponsive)\n } else {\n const xs = value?.xs ?? defaultValue\n if (xs === undefined) return\n onChange({\n ...value,\n xs,\n [activeBreakpoint]: newValue,\n } as ResponsiveValue<T>)\n }\n }\n },\n [value, onChange, activeBreakpoint, defaultValue]\n )\n\n const handleClearOverride = useCallback(() => {\n if (activeBreakpoint === 'xs' || !value) return\n const newResponsive = { ...value }\n delete newResponsive[activeBreakpoint]\n onChange(newResponsive)\n }, [value, onChange, activeBreakpoint])\n\n const handleClearAll = useCallback(() => {\n onChange(null)\n }, [onChange])\n\n const currentValue = getCurrentValue()\n const isOverrideBreakpoint = activeBreakpoint !== 'xs'\n const currentHasOverride = hasOverride(activeBreakpoint)\n const inheritanceSource = getInheritanceSource()\n\n const overrideCount = value\n ? (['sm', 'md', 'lg', 'xl'] as Breakpoint[]).filter((bp) => value[bp] !== undefined).length\n : 0\n\n return (\n <div className=\"puck-field\" style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n {label && (\n <div style={styles.labelGroup}>\n <label style={styles.label}>{label}</label>\n {overrideCount > 0 && (\n <span style={styles.overrideBadge}>\n {overrideCount} override{overrideCount !== 1 ? 's' : ''}\n </span>\n )}\n </div>\n )}\n {value && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClearAll}\n style={styles.clearButton}\n title=\"Clear all values\"\n >\n <X style={{ width: '16px', height: '16px' }} />\n </button>\n )}\n </div>\n\n {/* Breakpoint Tabs */}\n <div style={styles.tabsContainer}>\n {BREAKPOINTS.map((bp) => (\n <BreakpointTab\n key={bp.key}\n breakpoint={bp.key}\n label={bp.label}\n minWidth={bp.minWidth}\n isActive={activeBreakpoint === bp.key}\n hasOverride={hasOverride(bp.key)}\n onClick={() => setActiveBreakpoint(bp.key)}\n disabled={readOnly}\n />\n ))}\n </div>\n\n {/* Active Breakpoint Info */}\n <div style={styles.infoRow}>\n <span>\n {activeBreakpoint === 'xs' ? (\n 'Extra small screens (0-639px)'\n ) : (\n <>\n {BREAKPOINTS.find((bp) => bp.key === activeBreakpoint)?.minWidth}px and up\n {!currentHasOverride && inheritanceSource && (\n <span style={{ color: 'var(--theme-elevation-400)' }}> (inheriting from {inheritanceSource.toUpperCase()})</span>\n )}\n </>\n )}\n </span>\n\n {isOverrideBreakpoint && currentHasOverride && !readOnly && (\n <button\n type=\"button\"\n onClick={handleClearOverride}\n style={styles.clearOverrideButton}\n >\n Clear override\n </button>\n )}\n </div>\n\n {/* Inner Field */}\n <div style={styles.innerFieldContainer}>\n {renderInnerField({\n value: currentValue,\n onChange: handleInnerChange,\n readOnly,\n })}\n </div>\n </div>\n )\n}\n\nexport const ResponsiveField = memo(ResponsiveFieldInner) as <T>(\n props: ResponsiveFieldProps<T>\n) => React.ReactElement\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\ninterface CreateResponsiveFieldConfig<T> {\n label?: string\n innerField: (config: { label?: string }) => CustomField<T | null>\n defaultValue?: T\n}\n\n/**\n * Creates a responsive wrapper around any Puck custom field.\n */\nexport function createResponsiveField<T>(\n config: CreateResponsiveFieldConfig<T>\n): CustomField<ResponsiveValue<T> | null> {\n const innerFieldConfig = config.innerField({ label: undefined })\n\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange, readOnly }) => (\n <ResponsiveField\n value={value}\n onChange={onChange}\n label={config.label}\n readOnly={readOnly}\n defaultValue={config.defaultValue}\n renderInnerField={(props) => {\n if (innerFieldConfig.type === 'custom' && innerFieldConfig.render) {\n return innerFieldConfig.render({\n field: innerFieldConfig,\n value: props.value,\n onChange: props.onChange,\n readOnly: props.readOnly,\n name: 'responsive-inner',\n id: 'responsive-inner',\n })\n }\n return null\n }}\n />\n ),\n }\n}\n"],"names":["React","useState","useCallback","memo","Smartphone","Tablet","Laptop","Monitor","X","BREAKPOINTS","BREAKPOINT_ICONS","xs","sm","md","lg","xl","styles","container","display","flexDirection","gap","header","alignItems","justifyContent","labelGroup","label","fontSize","fontWeight","color","overrideBadge","backgroundColor","padding","borderRadius","clearButton","width","height","border","cursor","tabsContainer","flexWrap","tab","position","transition","flex","minWidth","tabActive","tabDisabled","opacity","overrideIndicator","top","right","infoRow","clearOverrideButton","innerFieldContainer","BreakpointTab","breakpoint","isActive","hasOverride","onClick","disabled","Icon","button","type","title","style","span","ResponsiveFieldInner","value","onChange","readOnly","renderInnerField","defaultValue","activeBreakpoint","setActiveBreakpoint","getCurrentValue","override","undefined","breakpointOrder","activeIndex","indexOf","i","length","bp","val","getInheritanceSource","handleInnerChange","newValue","newResponsive","handleClearOverride","handleClearAll","currentValue","isOverrideBreakpoint","currentHasOverride","inheritanceSource","overrideCount","filter","div","className","map","key","find","toUpperCase","ResponsiveField","createResponsiveField","config","innerFieldConfig","innerField","render","props","field","name","id"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ResponsiveVisibilityField.d.ts","sourceRoot":"","sources":["../../src/fields/ResponsiveVisibilityField.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAgD,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AASnD,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,aAAa,CAAA;AAO9D,UAAU,8BAA8B;IACtC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAA;IACjD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AA8ID,iBAAS,8BAA8B,CAAC,EACtC,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,GACT,EAAE,8BAA8B,qBA+DhC;AAED,eAAO,MAAM,yBAAyB,kEAAuC,CAAA;AAM7E,UAAU,qCAAqC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,GAAE,qCAA0C,GACjD,WAAW,CAAC,eAAe,GAAG,IAAI,CAAC,CAarC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/ResponsiveVisibilityField.tsx"],"sourcesContent":["'use client'\n\n/**\n * ResponsiveVisibilityField - Show/hide elements at different breakpoints\n *\n * Provides a compact visual interface for toggling element visibility\n * at each breakpoint (xs, sm, md, lg, xl). Simple independent toggles\n * like Elementor/Divi - each breakpoint is just on or off.\n */\n\nimport React, { useCallback, memo, type CSSProperties } from 'react'\nimport type { CustomField } from '@puckeditor/core'\nimport {\n Smartphone,\n Tablet,\n Laptop,\n Monitor,\n Eye,\n EyeOff,\n} from 'lucide-react'\nimport type { Breakpoint, VisibilityValue } from './shared.js'\nimport { BREAKPOINTS, DEFAULT_VISIBILITY } from './shared.js'\n\n// =============================================================================\n// Types\n// =============================================================================\n\ninterface ResponsiveVisibilityFieldProps {\n value: VisibilityValue | null\n onChange: (value: VisibilityValue | null) => void\n label?: string\n readOnly?: boolean\n}\n\n// =============================================================================\n// Breakpoint Icons\n// =============================================================================\n\nconst BREAKPOINT_ICONS: Record<Breakpoint, React.ComponentType<{ className?: string; style?: CSSProperties }>> = {\n xs: Smartphone,\n sm: Smartphone,\n md: Tablet,\n lg: Laptop,\n xl: Monitor,\n}\n\n// =============================================================================\n// Styles\n// =============================================================================\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n } as CSSProperties,\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n } as CSSProperties,\n label: {\n fontSize: '14px',\n fontWeight: 500,\n color: 'var(--theme-elevation-800)',\n } as CSSProperties,\n warningBadge: {\n fontSize: '12px',\n color: 'var(--theme-warning-500)',\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n } as CSSProperties,\n toggleGrid: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '4px',\n } as CSSProperties,\n toggleButton: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '2px',\n padding: '6px 4px',\n borderRadius: '6px',\n flex: '1 1 auto',\n minWidth: '44px',\n cursor: 'pointer',\n transition: 'all 0.15s',\n border: '1px solid',\n } as CSSProperties,\n toggleVisible: {\n backgroundColor: 'rgba(16, 185, 129, 0.15)',\n color: 'rgb(16, 185, 129)',\n borderColor: 'rgba(16, 185, 129, 0.4)',\n } as CSSProperties,\n toggleHidden: {\n backgroundColor: 'rgba(239, 68, 68, 0.15)',\n color: 'rgb(239, 68, 68)',\n borderColor: 'rgba(239, 68, 68, 0.4)',\n } as CSSProperties,\n toggleDisabled: {\n opacity: 0.5,\n cursor: 'not-allowed',\n } as CSSProperties,\n toggleLabel: {\n fontSize: '10px',\n fontWeight: 500,\n } as CSSProperties,\n toggleIcon: {\n position: 'absolute',\n top: '4px',\n right: '4px',\n } as CSSProperties,\n helpText: {\n fontSize: '12px',\n color: 'var(--theme-elevation-500)',\n } as CSSProperties,\n}\n\n// =============================================================================\n// Visibility Toggle Button\n// =============================================================================\n\ninterface VisibilityToggleProps {\n breakpoint: Breakpoint\n label: string\n minWidth: number | null\n isVisible: boolean\n onClick: () => void\n disabled?: boolean\n}\n\nfunction VisibilityToggle({\n breakpoint,\n label,\n minWidth,\n isVisible,\n onClick,\n disabled,\n}: VisibilityToggleProps) {\n const DeviceIcon = BREAKPOINT_ICONS[breakpoint]\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n title={`${label}${minWidth ? ` (${minWidth}px+)` : ''}: ${isVisible ? 'Visible' : 'Hidden'}`}\n style={{\n ...styles.toggleButton,\n ...(isVisible ? styles.toggleVisible : styles.toggleHidden),\n ...(disabled ? styles.toggleDisabled : {}),\n }}\n >\n <DeviceIcon style={{ width: '16px', height: '16px' }} />\n <span style={styles.toggleLabel}>{label}</span>\n <div style={styles.toggleIcon as CSSProperties}>\n {isVisible ? (\n <Eye style={{ width: '12px', height: '12px' }} />\n ) : (\n <EyeOff style={{ width: '12px', height: '12px' }} />\n )}\n </div>\n </button>\n )\n}\n\n// =============================================================================\n// ResponsiveVisibilityField Component\n// =============================================================================\n\nfunction ResponsiveVisibilityFieldInner({\n value,\n onChange,\n label,\n readOnly,\n}: ResponsiveVisibilityFieldProps) {\n // Get visibility for a breakpoint (simple lookup, no cascade)\n const getVisibility = useCallback(\n (breakpoint: Breakpoint): boolean => {\n const val = value ?? DEFAULT_VISIBILITY\n // All breakpoints have explicit values, default to true if undefined\n return val[breakpoint] ?? true\n },\n [value]\n )\n\n // Toggle visibility for a breakpoint (simple toggle, no cascade)\n const toggleVisibility = useCallback(\n (breakpoint: Breakpoint) => {\n const currentVisible = getVisibility(breakpoint)\n const newValue: VisibilityValue = {\n ...(value ?? DEFAULT_VISIBILITY),\n [breakpoint]: !currentVisible,\n }\n onChange(newValue)\n },\n [value, onChange, getVisibility]\n )\n\n // Check if any breakpoint is hidden\n const hasHiddenBreakpoints = BREAKPOINTS.some((bp) => !getVisibility(bp.key))\n\n return (\n <div className=\"puck-field\" style={styles.container}>\n {/* Header */}\n <div style={styles.header}>\n {label && (\n <label style={styles.label}>{label}</label>\n )}\n {hasHiddenBreakpoints && (\n <span style={styles.warningBadge}>\n <EyeOff style={{ width: '12px', height: '12px' }} />\n Partially hidden\n </span>\n )}\n </div>\n\n {/* Visibility Grid */}\n <div style={styles.toggleGrid}>\n {BREAKPOINTS.map((bp) => (\n <VisibilityToggle\n key={bp.key}\n breakpoint={bp.key}\n label={bp.label}\n minWidth={bp.minWidth}\n isVisible={getVisibility(bp.key)}\n onClick={() => toggleVisibility(bp.key)}\n disabled={readOnly}\n />\n ))}\n </div>\n\n {/* Help text */}\n <p style={styles.helpText}>\n Toggle visibility per screen size. Each breakpoint is independent.\n </p>\n </div>\n )\n}\n\nexport const ResponsiveVisibilityField = memo(ResponsiveVisibilityFieldInner)\n\n// =============================================================================\n// Field Configuration Factory\n// =============================================================================\n\ninterface CreateResponsiveVisibilityFieldConfig {\n label?: string\n}\n\n/**\n * Creates a Puck custom field for responsive visibility control.\n *\n * @example\n * ```ts\n * fields: {\n * visibility: createResponsiveVisibilityField({ label: 'Visibility' }),\n * }\n * ```\n */\nexport function createResponsiveVisibilityField(\n config: CreateResponsiveVisibilityFieldConfig = {}\n): CustomField<VisibilityValue | null> {\n return {\n type: 'custom',\n label: config.label,\n render: ({ value, onChange, readOnly }) => (\n <ResponsiveVisibilityField\n value={value}\n onChange={onChange}\n label={config.label}\n readOnly={readOnly}\n />\n ),\n }\n}\n"],"names":["React","useCallback","memo","Smartphone","Tablet","Laptop","Monitor","Eye","EyeOff","BREAKPOINTS","DEFAULT_VISIBILITY","BREAKPOINT_ICONS","xs","sm","md","lg","xl","styles","container","display","flexDirection","gap","header","alignItems","justifyContent","label","fontSize","fontWeight","color","warningBadge","toggleGrid","flexWrap","toggleButton","position","padding","borderRadius","flex","minWidth","cursor","transition","border","toggleVisible","backgroundColor","borderColor","toggleHidden","toggleDisabled","opacity","toggleLabel","toggleIcon","top","right","helpText","VisibilityToggle","breakpoint","isVisible","onClick","disabled","DeviceIcon","button","type","title","style","width","height","span","div","ResponsiveVisibilityFieldInner","value","onChange","readOnly","getVisibility","val","toggleVisibility","currentVisible","newValue","hasHiddenBreakpoints","some","bp","key","className","map","p","ResponsiveVisibilityField","createResponsiveVisibilityField","config","render"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SizeField.d.ts","sourceRoot":"","sources":["../../src/fields/SizeField.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAgD,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKnD,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAA;AAEpB,OAAO,KAAK,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAA;AAEhE,UAAU,cAAc;IACtB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAA;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AA0KD,iBAAS,cAAc,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,KAAc,EACd,QAAQ,EACR,UAAiB,EACjB,YAAmB,GACpB,EAAE,cAAc,qBAuKhB;AAED,eAAO,MAAM,SAAS,kDAAuB,CAAA;AAM7C,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,GAAE,qBAA0B,GACjC,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,CAe/B"}
|