@brunoalz/smartgesti-site-editor 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/editor/BlockSelector.js +5 -2
  2. package/dist/editor/BlockSelector.js.map +1 -1
  3. package/dist/editor/LandingPageEditor.d.ts.map +1 -1
  4. package/dist/editor/LandingPageEditor.js +199 -173
  5. package/dist/editor/LandingPageEditor.js.map +1 -1
  6. package/dist/editor/PaletteSelector.d.ts +3 -0
  7. package/dist/editor/PaletteSelector.d.ts.map +1 -1
  8. package/dist/editor/PaletteSelector.js +114 -25
  9. package/dist/editor/PaletteSelector.js.map +1 -1
  10. package/dist/editor/PropertyEditor/BlockPropertyEditor.d.ts.map +1 -1
  11. package/dist/editor/PropertyEditor/BlockPropertyEditor.js +86 -48
  12. package/dist/editor/PropertyEditor/BlockPropertyEditor.js.map +1 -1
  13. package/dist/editor/components/RightPanel.d.ts +2 -0
  14. package/dist/editor/components/RightPanel.d.ts.map +1 -1
  15. package/dist/editor/components/RightPanel.js +23 -22
  16. package/dist/editor/components/RightPanel.js.map +1 -1
  17. package/dist/engine/export/exporters/content/AvatarExporter.js +2 -2
  18. package/dist/engine/export/exporters/content/AvatarExporter.js.map +1 -1
  19. package/dist/engine/export/exporters/content/BadgeExporter.js +11 -11
  20. package/dist/engine/export/exporters/content/BadgeExporter.js.map +1 -1
  21. package/dist/engine/export/exporters/sections/AdminSectionExporters.d.ts +6 -0
  22. package/dist/engine/export/exporters/sections/AdminSectionExporters.d.ts.map +1 -0
  23. package/dist/engine/export/exporters/sections/AdminSectionExporters.js +157 -0
  24. package/dist/engine/export/exporters/sections/AdminSectionExporters.js.map +1 -0
  25. package/dist/engine/export/exporters/sections/BlogPostExporters.js +34 -34
  26. package/dist/engine/export/exporters/sections/BlogPostExporters.js.map +1 -1
  27. package/dist/engine/export/exporters/sections/ContentGridExporters.js +16 -16
  28. package/dist/engine/export/exporters/sections/ContentGridExporters.js.map +1 -1
  29. package/dist/engine/export/exporters/sections/MarketingExporters.js +4 -4
  30. package/dist/engine/export/exporters/sections/MarketingExporters.js.map +1 -1
  31. package/dist/engine/export/exporters/sections/index.d.ts.map +1 -1
  32. package/dist/engine/export/exporters/sections/index.js +37 -33
  33. package/dist/engine/export/exporters/sections/index.js.map +1 -1
  34. package/dist/engine/index.js +98 -95
  35. package/dist/engine/index.js.map +1 -1
  36. package/dist/engine/preview/Preview.d.ts.map +1 -1
  37. package/dist/engine/preview/Preview.js +165 -160
  38. package/dist/engine/preview/Preview.js.map +1 -1
  39. package/dist/engine/registry/blocks/sections/aboutSection.d.ts +3 -0
  40. package/dist/engine/registry/blocks/sections/aboutSection.d.ts.map +1 -0
  41. package/dist/engine/registry/blocks/sections/aboutSection.js +117 -0
  42. package/dist/engine/registry/blocks/sections/aboutSection.js.map +1 -0
  43. package/dist/engine/registry/blocks/sections/contactSection.d.ts +3 -0
  44. package/dist/engine/registry/blocks/sections/contactSection.d.ts.map +1 -0
  45. package/dist/engine/registry/blocks/sections/contactSection.js +118 -0
  46. package/dist/engine/registry/blocks/sections/contactSection.js.map +1 -0
  47. package/dist/engine/registry/blocks/sections/index.d.ts +3 -0
  48. package/dist/engine/registry/blocks/sections/index.d.ts.map +1 -1
  49. package/dist/engine/registry/blocks/sections/productShowcase.d.ts +3 -0
  50. package/dist/engine/registry/blocks/sections/productShowcase.d.ts.map +1 -0
  51. package/dist/engine/registry/blocks/sections/productShowcase.js +108 -0
  52. package/dist/engine/registry/blocks/sections/productShowcase.js.map +1 -0
  53. package/dist/engine/render/renderers/content/BadgeRenderer.js +12 -12
  54. package/dist/engine/render/renderers/content/BadgeRenderer.js.map +1 -1
  55. package/dist/engine/render/renderers/sections/AboutSectionRenderer.d.ts +3 -0
  56. package/dist/engine/render/renderers/sections/AboutSectionRenderer.d.ts.map +1 -0
  57. package/dist/engine/render/renderers/sections/AboutSectionRenderer.js +246 -0
  58. package/dist/engine/render/renderers/sections/AboutSectionRenderer.js.map +1 -0
  59. package/dist/engine/render/renderers/sections/ContactSectionRenderer.d.ts +3 -0
  60. package/dist/engine/render/renderers/sections/ContactSectionRenderer.d.ts.map +1 -0
  61. package/dist/engine/render/renderers/sections/ContactSectionRenderer.js +287 -0
  62. package/dist/engine/render/renderers/sections/ContactSectionRenderer.js.map +1 -0
  63. package/dist/engine/render/renderers/sections/FeatureGridRenderer.js +5 -5
  64. package/dist/engine/render/renderers/sections/FeatureGridRenderer.js.map +1 -1
  65. package/dist/engine/render/renderers/sections/FeatureRenderer.js +9 -9
  66. package/dist/engine/render/renderers/sections/FeatureRenderer.js.map +1 -1
  67. package/dist/engine/render/renderers/sections/PricingCardRenderer.js +5 -5
  68. package/dist/engine/render/renderers/sections/PricingCardRenderer.js.map +1 -1
  69. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.d.ts +3 -0
  70. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.d.ts.map +1 -0
  71. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.js +287 -0
  72. package/dist/engine/render/renderers/sections/ProductShowcaseRenderer.js.map +1 -0
  73. package/dist/engine/render/renderers/sections/index.js +26 -20
  74. package/dist/engine/render/renderers/sections/index.js.map +1 -1
  75. package/dist/engine/schema/siteDocument.d.ts +96 -2
  76. package/dist/engine/schema/siteDocument.d.ts.map +1 -1
  77. package/dist/engine/schema/siteDocument.js.map +1 -1
  78. package/dist/hooks/useEditorState.d.ts +2 -0
  79. package/dist/hooks/useEditorState.d.ts.map +1 -1
  80. package/dist/hooks/useEditorState.js +82 -77
  81. package/dist/hooks/useEditorState.js.map +1 -1
  82. package/dist/index.d.ts +1 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +109 -106
  85. package/dist/index.js.map +1 -1
  86. package/dist/shared/schema.d.ts +1 -1
  87. package/dist/shared/schema.d.ts.map +1 -1
  88. package/dist/shared/schema.js +7 -4
  89. package/dist/shared/schema.js.map +1 -1
  90. package/dist/shared/templates/index.d.ts +6 -0
  91. package/dist/shared/templates/index.d.ts.map +1 -1
  92. package/dist/shared/templates/index.js +49 -23
  93. package/dist/shared/templates/index.js.map +1 -1
  94. package/dist/shared/templates/smartgesti-admin.d.ts +3 -0
  95. package/dist/shared/templates/smartgesti-admin.d.ts.map +1 -0
  96. package/dist/shared/templates/smartgesti-admin.js +423 -0
  97. package/dist/shared/templates/smartgesti-admin.js.map +1 -0
  98. package/dist/utils/blockIcons.d.ts.map +1 -1
  99. package/dist/utils/blockIcons.js +3 -0
  100. package/dist/utils/blockIcons.js.map +1 -1
  101. package/dist/utils/colorUtils.d.ts +73 -16
  102. package/dist/utils/colorUtils.d.ts.map +1 -1
  103. package/dist/utils/colorUtils.js +95 -9
  104. package/dist/utils/colorUtils.js.map +1 -1
  105. package/dist/viewer/LandingPageViewer.d.ts.map +1 -1
  106. package/dist/viewer/LandingPageViewer.js +66 -65
  107. package/dist/viewer/LandingPageViewer.js.map +1 -1
  108. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"BlockPropertyEditor.js","sources":["../../../src/editor/PropertyEditor/BlockPropertyEditor.tsx"],"sourcesContent":["/**\n * Block Property Editor - Refatorado\n * Editor dinâmico de propriedades baseado em inspectorMeta\n */\n\nimport { memo, useMemo, useCallback } from \"react\";\nimport { Block, SiteDocument, componentRegistry, InspectorMeta, evaluateShowWhen, pluginRegistry } from \"../../engine\";\nimport type { ShowWhenContext } from \"../../engine\";\nimport { VariationSelector } from \"./VariationSelector\";\nimport { BlockHeader } from \"./BlockHeader\";\nimport { CollapsiblePropertyGroup } from \"./CollapsiblePropertyGroup\";\nimport type { UploadConfig } from \"../LandingPageEditor\";\n\ninterface BlockPropertyEditorProps {\n block: Block | null;\n document?: SiteDocument;\n currentPageId?: string;\n onUpdate: (updates: Record<string, any>) => void;\n uploadConfig?: UploadConfig;\n /** When set, the matching property group opens and scrolls into view */\n focusedGroup?: string | null;\n}\n\n/**\n * Componente principal do editor de propriedades\n * Memoizado para performance\n */\nexport const BlockPropertyEditor = memo(function BlockPropertyEditor({\n block,\n document,\n currentPageId,\n onUpdate,\n uploadConfig,\n focusedGroup,\n}: BlockPropertyEditorProps) {\n // Obter definição do bloco do registry\n const blockDefinition = useMemo(() => {\n if (!block) return null;\n return componentRegistry.get(block.type);\n }, [block]);\n\n // Contexto para cross-block showWhen\n const showWhenContext = useMemo<ShowWhenContext>(\n () => ({ document, currentPageId }),\n [document, currentPageId],\n );\n\n // Obter restrições de edição do plugin (se houver)\n const lockedFields = useMemo(() => {\n if (!block || !document) return new Set<string>();\n const restriction = pluginRegistry.getEditorRestrictions(document, block.type);\n if (!restriction?.lockedFields) return new Set<string>();\n return new Set(restriction.lockedFields);\n }, [block, document]);\n\n // Agrupar propriedades por grupo\n const groupedProps = useMemo(() => {\n if (!block || !blockDefinition?.inspectorMeta) return {};\n\n const props = block.props as Record<string, any>;\n const defaultProps = (blockDefinition.defaultProps || {}) as Record<string, any>;\n const groups: Record<\n string,\n Array<{ propName: string; meta: InspectorMeta; value: any }>\n > = {};\n\n for (const [propName, meta] of Object.entries(\n blockDefinition.inspectorMeta,\n )) {\n // Visibilidade condicional via showWhen\n if (meta.showWhen) {\n if (!evaluateShowWhen(meta.showWhen, props, defaultProps, showWhenContext)) {\n continue;\n }\n }\n\n const group = meta.group || \"Geral\";\n if (!groups[group]) {\n groups[group] = [];\n }\n\n // Usar valor atual ou fallback para defaultProps\n const currentValue = props[propName];\n // Para campos de cor, também fazer fallback se o valor for string vazia\n const isColorInput = meta.inputType === \"color\" || meta.inputType === \"color-advanced\";\n const shouldUseFallback = currentValue === undefined || (isColorInput && currentValue === \"\");\n const value = shouldUseFallback ? defaultProps[propName] : currentValue;\n\n // Aplicar readOnly de plugin restrictions\n const effectiveMeta = lockedFields.has(propName)\n ? { ...meta, readOnly: true }\n : meta;\n\n groups[group].push({\n propName,\n meta: effectiveMeta,\n value,\n });\n }\n\n return groups;\n }, [block, blockDefinition, showWhenContext, lockedFields]);\n\n // IMPORTANTE: todos os hooks devem ser chamados ANTES de qualquer early return\n const handlePropChange = useCallback((propName: string, value: any) => {\n // Se remover o logo (definir como undefined), resetar logoHeight para padrão\n if (propName === \"logo\" && (value === undefined || value === \"\")) {\n onUpdate({ [propName]: value, logoHeight: 70 });\n } else {\n onUpdate({ [propName]: value });\n }\n }, [onUpdate]);\n\n if (!block) {\n return (\n <div className=\"p-4 text-center text-gray-500 dark:text-gray-400 text-sm\">\n Selecione um bloco para editar\n </div>\n );\n }\n\n if (!blockDefinition) {\n return (\n <div className=\"p-4 text-center text-red-500 text-sm\">\n Tipo de bloco desconhecido: {block.type}\n </div>\n );\n }\n\n return (\n <div className=\"p-3 space-y-4\">\n {/* Header com ícone centralizado */}\n <BlockHeader\n type={block.type}\n name={blockDefinition.name}\n description={blockDefinition.description}\n />\n\n {/* Seletor de variações (Hero/Navbar) */}\n {blockDefinition.variations && (\n <VariationSelector block={block} onUpdate={onUpdate} />\n )}\n\n {/* Propriedades agrupadas com collapse */}\n {Object.keys(groupedProps).length === 0 ? (\n <div className=\"text-center text-gray-500 dark:text-gray-400 text-xs py-4\">\n Nenhuma propriedade configurável\n </div>\n ) : (\n Object.entries(groupedProps).map(([groupName, props]) => (\n <CollapsiblePropertyGroup\n key={groupName}\n groupName={groupName}\n props={props}\n onPropChange={handlePropChange}\n onMultiUpdate={onUpdate}\n allProps={block?.props as Record<string, any>}\n uploadConfig={uploadConfig}\n isFocused={groupName === focusedGroup}\n />\n ))\n )}\n </div>\n );\n});\n"],"names":["BlockPropertyEditor","memo","block","document","currentPageId","onUpdate","uploadConfig","focusedGroup","blockDefinition","useMemo","componentRegistry","showWhenContext","lockedFields","restriction","pluginRegistry","groupedProps","props","defaultProps","groups","propName","meta","evaluateShowWhen","group","currentValue","isColorInput","value","effectiveMeta","handlePropChange","useCallback","jsxs","jsx","BlockHeader","VariationSelector","groupName","CollapsiblePropertyGroup"],"mappings":"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"}
1
+ {"version":3,"file":"BlockPropertyEditor.js","sources":["../../../src/editor/PropertyEditor/BlockPropertyEditor.tsx"],"sourcesContent":["/**\n * Block Property Editor - Refatorado\n * Editor dinâmico de propriedades baseado em inspectorMeta\n */\n\nimport { memo, useMemo, useCallback } from \"react\";\nimport { Block, SiteDocument, componentRegistry, InspectorMeta, evaluateShowWhen, pluginRegistry } from \"../../engine\";\nimport type { ShowWhenContext } from \"../../engine\";\nimport { VariationSelector } from \"./VariationSelector\";\nimport { BlockHeader } from \"./BlockHeader\";\nimport { CollapsiblePropertyGroup } from \"./CollapsiblePropertyGroup\";\nimport type { UploadConfig } from \"../LandingPageEditor\";\n\n// ============================================================================\n// Theme Color Fallback Map\n// Maps color property names → theme color token keys.\n// Used when block.props[colorProp] and defaultProps[colorProp] are both undefined,\n// so the editor shows the actual theme color instead of #000000.\n// ============================================================================\n\nconst THEME_COLOR_FALLBACKS: Record<string, string> = {\n // Buttons (primary)\n primaryButtonColor: \"primary\",\n buttonColor: \"primary\",\n primaryButtonTextColor: \"primaryText\",\n buttonTextColor: \"primaryText\",\n // Buttons (secondary)\n secondaryButtonColor: \"secondary\",\n secondaryButtonTextColor: \"primaryText\",\n // Badge\n badgeColor: \"accent\",\n badgeTextColor: \"primaryText\",\n // Links\n linkColor: \"linkColor\",\n linkHoverColor: \"primary\",\n // Border\n borderColor: \"border\",\n // Generic text\n color: \"text\",\n // Title/description\n titleColor: \"text\",\n subtitleColor: \"mutedText\",\n descriptionColor: \"mutedText\",\n // Background (generic)\n bg: \"bg\",\n};\n\n/**\n * Resolve theme color fallback for a color property.\n * Returns the theme color value if a mapping exists, undefined otherwise.\n */\nfunction resolveThemeColorFallback(\n propName: string,\n themeColors: Record<string, unknown>,\n): string | undefined {\n const themeKey = THEME_COLOR_FALLBACKS[propName];\n if (!themeKey) return undefined;\n const color = themeColors[themeKey];\n return typeof color === \"string\" ? color : undefined;\n}\n\ninterface BlockPropertyEditorProps {\n block: Block | null;\n document?: SiteDocument;\n currentPageId?: string;\n onUpdate: (updates: Record<string, any>) => void;\n uploadConfig?: UploadConfig;\n /** When set, the matching property group opens and scrolls into view */\n focusedGroup?: string | null;\n}\n\n/**\n * Componente principal do editor de propriedades\n * Memoizado para performance\n */\nexport const BlockPropertyEditor = memo(function BlockPropertyEditor({\n block,\n document,\n currentPageId,\n onUpdate,\n uploadConfig,\n focusedGroup,\n}: BlockPropertyEditorProps) {\n // Obter definição do bloco do registry\n const blockDefinition = useMemo(() => {\n if (!block) return null;\n return componentRegistry.get(block.type);\n }, [block]);\n\n // Contexto para cross-block showWhen\n const showWhenContext = useMemo<ShowWhenContext>(\n () => ({ document, currentPageId }),\n [document, currentPageId],\n );\n\n // Obter restrições de edição do plugin (se houver)\n const lockedFields = useMemo(() => {\n if (!block || !document) return new Set<string>();\n const restriction = pluginRegistry.getEditorRestrictions(document, block.type);\n if (!restriction?.lockedFields) return new Set<string>();\n return new Set(restriction.lockedFields);\n }, [block, document]);\n\n // Agrupar propriedades por grupo\n const groupedProps = useMemo(() => {\n if (!block || !blockDefinition?.inspectorMeta) return {};\n\n const props = block.props as Record<string, any>;\n const defaultProps = (blockDefinition.defaultProps || {}) as Record<string, any>;\n const groups: Record<\n string,\n Array<{ propName: string; meta: InspectorMeta; value: any }>\n > = {};\n\n for (const [propName, meta] of Object.entries(\n blockDefinition.inspectorMeta,\n )) {\n // Visibilidade condicional via showWhen\n if (meta.showWhen) {\n if (!evaluateShowWhen(meta.showWhen, props, defaultProps, showWhenContext)) {\n continue;\n }\n }\n\n const group = meta.group || \"Geral\";\n if (!groups[group]) {\n groups[group] = [];\n }\n\n // Usar valor atual ou fallback para defaultProps, e depois theme colors\n const currentValue = props[propName];\n // Para campos de cor, também fazer fallback se o valor for string vazia\n const isColorInput = meta.inputType === \"color\" || meta.inputType === \"color-advanced\";\n const shouldUseFallback = currentValue === undefined || (isColorInput && currentValue === \"\");\n let value = shouldUseFallback ? defaultProps[propName] : currentValue;\n\n // Para color inputs sem valor definido, tentar fallback para cor do theme\n if (value === undefined && isColorInput && document?.theme?.colors) {\n value = resolveThemeColorFallback(\n propName,\n document.theme.colors as unknown as Record<string, unknown>,\n );\n }\n\n // Aplicar readOnly de plugin restrictions\n const effectiveMeta = lockedFields.has(propName)\n ? { ...meta, readOnly: true }\n : meta;\n\n groups[group].push({\n propName,\n meta: effectiveMeta,\n value,\n });\n }\n\n return groups;\n }, [block, blockDefinition, document, showWhenContext, lockedFields]);\n\n // IMPORTANTE: todos os hooks devem ser chamados ANTES de qualquer early return\n const handlePropChange = useCallback((propName: string, value: any) => {\n // Se remover o logo (definir como undefined), resetar logoHeight para padrão\n if (propName === \"logo\" && (value === undefined || value === \"\")) {\n onUpdate({ [propName]: value, logoHeight: 70 });\n } else {\n onUpdate({ [propName]: value });\n }\n }, [onUpdate]);\n\n if (!block) {\n return (\n <div className=\"p-4 text-center text-gray-500 dark:text-gray-400 text-sm\">\n Selecione um bloco para editar\n </div>\n );\n }\n\n if (!blockDefinition) {\n return (\n <div className=\"p-4 text-center text-red-500 text-sm\">\n Tipo de bloco desconhecido: {block.type}\n </div>\n );\n }\n\n return (\n <div className=\"p-3 space-y-4\">\n {/* Header com ícone centralizado */}\n <BlockHeader\n type={block.type}\n name={blockDefinition.name}\n description={blockDefinition.description}\n />\n\n {/* Seletor de variações (Hero/Navbar) */}\n {blockDefinition.variations && (\n <VariationSelector block={block} onUpdate={onUpdate} />\n )}\n\n {/* Propriedades agrupadas com collapse */}\n {Object.keys(groupedProps).length === 0 ? (\n <div className=\"text-center text-gray-500 dark:text-gray-400 text-xs py-4\">\n Nenhuma propriedade configurável\n </div>\n ) : (\n Object.entries(groupedProps).map(([groupName, props]) => (\n <CollapsiblePropertyGroup\n key={groupName}\n groupName={groupName}\n props={props}\n onPropChange={handlePropChange}\n onMultiUpdate={onUpdate}\n allProps={block?.props as Record<string, any>}\n uploadConfig={uploadConfig}\n isFocused={groupName === focusedGroup}\n />\n ))\n )}\n </div>\n );\n});\n"],"names":["THEME_COLOR_FALLBACKS","resolveThemeColorFallback","propName","themeColors","themeKey","color","BlockPropertyEditor","memo","block","document","currentPageId","onUpdate","uploadConfig","focusedGroup","blockDefinition","useMemo","componentRegistry","showWhenContext","lockedFields","restriction","pluginRegistry","groupedProps","props","defaultProps","groups","meta","evaluateShowWhen","group","currentValue","isColorInput","value","effectiveMeta","handlePropChange","useCallback","jsxs","jsx","BlockHeader","VariationSelector","groupName","CollapsiblePropertyGroup"],"mappings":"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"}
@@ -1,9 +1,11 @@
1
1
  import { default as React } from 'react';
2
2
  import { UploadConfig } from '../LandingPageEditor';
3
3
  import { SiteDocument } from '../../engine';
4
+ import { ColorPalette } from '../PaletteSelector';
4
5
  interface RightPanelProps {
5
6
  isPaletteSelected: boolean;
6
7
  selectedBlock: any;
8
+ selectedPalette?: ColorPalette;
7
9
  onPaletteChange: (palette: any) => void;
8
10
  onUpdateBlock: (updates: Record<string, any>) => void;
9
11
  uploadConfig?: UploadConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"RightPanel.d.ts","sourceRoot":"","sources":["../../../src/editor/components/RightPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAUjD,UAAU,eAAe;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,GAAG,CAAC;IACnB,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACtD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,eAAO,MAAM,UAAU,6CA0CrB,CAAC"}
1
+ {"version":3,"file":"RightPanel.d.ts","sourceRoot":"","sources":["../../../src/editor/components/RightPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAUvD,UAAU,eAAe;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,GAAG,CAAC;IACnB,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACtD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,eAAO,MAAM,UAAU,6CA2CrB,CAAC"}
@@ -1,38 +1,39 @@
1
- import { jsx as e, jsxs as m } from "react/jsx-runtime";
2
- import f, { Suspense as h, lazy as o } from "react";
3
- import { LoadingSpinner as p } from "./LoadingSpinner.js";
4
- const x = o(
1
+ import { jsx as e, jsxs as f } from "react/jsx-runtime";
2
+ import h, { Suspense as p, lazy as o } from "react";
3
+ import { LoadingSpinner as x } from "./LoadingSpinner.js";
4
+ const g = o(
5
5
  () => import("../PropertyEditor/index.js").then((r) => ({ default: r.BlockPropertyEditor }))
6
- ), g = o(
6
+ ), y = o(
7
7
  () => import("../PaletteSelector.js").then((r) => ({ default: r.PaletteSelector }))
8
- ), v = f.memo(function({
8
+ ), v = h.memo(function({
9
9
  isPaletteSelected: a,
10
10
  selectedBlock: t,
11
- onPaletteChange: l,
12
- onUpdateBlock: d,
13
- uploadConfig: i,
14
- document: n,
15
- currentPageId: c,
16
- focusedGroup: s
11
+ selectedPalette: l,
12
+ onPaletteChange: d,
13
+ onUpdateBlock: i,
14
+ uploadConfig: n,
15
+ document: c,
16
+ currentPageId: s,
17
+ focusedGroup: m
17
18
  }) {
18
- return /* @__PURE__ */ e("div", { className: "w-80 flex-shrink-0 border-l border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 overflow-hidden flex flex-col", children: /* @__PURE__ */ e(h, { fallback: /* @__PURE__ */ e(p, {}), children: a ? /* @__PURE__ */ m("div", { className: "p-4 overflow-y-auto", children: [
19
+ return /* @__PURE__ */ e("div", { className: "w-80 flex-shrink-0 border-l border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 overflow-hidden flex flex-col", children: /* @__PURE__ */ e(p, { fallback: /* @__PURE__ */ e(x, {}), children: a ? /* @__PURE__ */ f("div", { className: "p-4 overflow-y-auto", children: [
19
20
  /* @__PURE__ */ e("h2", { className: "text-sm font-semibold text-gray-800 dark:text-gray-100 mb-4", children: "Escolha uma Paleta de Cores" }),
20
21
  /* @__PURE__ */ e(
21
- g,
22
+ y,
22
23
  {
23
- selectedPalette: void 0,
24
- onPaletteChange: l
24
+ selectedPalette: l,
25
+ onPaletteChange: d
25
26
  }
26
27
  )
27
28
  ] }) : t ? /* @__PURE__ */ e("div", { className: "overflow-y-auto overflow-x-hidden flex-1", children: /* @__PURE__ */ e(
28
- x,
29
+ g,
29
30
  {
30
31
  block: t,
31
- document: n,
32
- currentPageId: c,
33
- onUpdate: d,
34
- uploadConfig: i,
35
- focusedGroup: s
32
+ document: c,
33
+ currentPageId: s,
34
+ onUpdate: i,
35
+ uploadConfig: n,
36
+ focusedGroup: m
36
37
  }
37
38
  ) }) : /* @__PURE__ */ e("div", { className: "p-4 text-center text-gray-500 dark:text-gray-400", children: "Selecione um bloco para editar" }) }) });
38
39
  });
@@ -1 +1 @@
1
- {"version":3,"file":"RightPanel.js","sources":["../../../src/editor/components/RightPanel.tsx"],"sourcesContent":["import React, { lazy, Suspense } from \"react\";\nimport { LoadingSpinner } from \"./LoadingSpinner\";\nimport type { UploadConfig } from \"../LandingPageEditor\";\nimport type { SiteDocument } from \"../../engine\";\n\n// Lazy load componentes pesados do editor\nconst BlockPropertyEditor = lazy(() =>\n import(\"../PropertyEditor\").then(module => ({ default: module.BlockPropertyEditor }))\n);\nconst PaletteSelector = lazy(() =>\n import(\"../PaletteSelector\").then(module => ({ default: module.PaletteSelector }))\n);\n\ninterface RightPanelProps {\n isPaletteSelected: boolean;\n selectedBlock: any;\n onPaletteChange: (palette: any) => void;\n onUpdateBlock: (updates: Record<string, any>) => void;\n uploadConfig?: UploadConfig;\n document?: SiteDocument;\n currentPageId?: string;\n /** When set, the matching property group opens and scrolls into view */\n focusedGroup?: string | null;\n}\n\nexport const RightPanel = React.memo(function RightPanel({\n isPaletteSelected,\n selectedBlock,\n onPaletteChange,\n onUpdateBlock,\n uploadConfig,\n document,\n currentPageId,\n focusedGroup,\n}: RightPanelProps) {\n return (\n <div className=\"w-80 flex-shrink-0 border-l border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 overflow-hidden flex flex-col\">\n <Suspense fallback={<LoadingSpinner />}>\n {isPaletteSelected ? (\n <div className=\"p-4 overflow-y-auto\">\n <h2 className=\"text-sm font-semibold text-gray-800 dark:text-gray-100 mb-4\">\n Escolha uma Paleta de Cores\n </h2>\n <PaletteSelector\n selectedPalette={undefined}\n onPaletteChange={onPaletteChange}\n />\n </div>\n ) : selectedBlock ? (\n <div className=\"overflow-y-auto overflow-x-hidden flex-1\">\n <BlockPropertyEditor\n block={selectedBlock}\n document={document}\n currentPageId={currentPageId}\n onUpdate={onUpdateBlock}\n uploadConfig={uploadConfig}\n focusedGroup={focusedGroup}\n />\n </div>\n ) : (\n <div className=\"p-4 text-center text-gray-500 dark:text-gray-400\">\n Selecione um bloco para editar\n </div>\n )}\n </Suspense>\n </div>\n );\n});\n"],"names":["BlockPropertyEditor","lazy","module","PaletteSelector","RightPanel","React","isPaletteSelected","selectedBlock","onPaletteChange","onUpdateBlock","uploadConfig","document","currentPageId","focusedGroup","jsx","Suspense","LoadingSpinner","jsxs"],"mappings":";;;AAMA,MAAMA,IAAsBC;AAAA,EAAK,MAC/B,OAAO,4BAAmB,EAAE,KAAK,QAAW,EAAE,SAASC,EAAO,sBAAsB;AACtF,GACMC,IAAkBF;AAAA,EAAK,MAC3B,OAAO,uBAAoB,EAAE,KAAK,QAAW,EAAE,SAASC,EAAO,kBAAkB;AACnF,GAcaE,IAAaC,EAAM,KAAK,SAAoB;AAAA,EACvD,mBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AACF,GAAoB;AAClB,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAU,4HACb,4BAACC,GAAA,EAAS,UAAU,gBAAAD,EAACE,GAAA,CAAA,CAAe,GACjC,UAAAV,IACC,gBAAAW,EAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,IAAA,gBAAAH,EAAC,MAAA,EAAG,WAAU,+DAA8D,UAAA,+BAE5E;AAAA,IACA,gBAAAA;AAAA,MAACX;AAAA,MAAA;AAAA,QACC,iBAAiB;AAAA,QACjB,iBAAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF,IACED,IACF,gBAAAO,EAAC,OAAA,EAAI,WAAU,4CACb,UAAA,gBAAAA;AAAA,IAACd;AAAA,IAAA;AAAA,MACC,OAAOO;AAAA,MACP,UAAAI;AAAA,MACA,eAAAC;AAAA,MACA,UAAUH;AAAA,MACV,cAAAC;AAAA,MACA,cAAAG;AAAA,IAAA;AAAA,EAAA,EACF,CACF,IAEA,gBAAAC,EAAC,OAAA,EAAI,WAAU,oDAAmD,UAAA,iCAAA,CAElE,GAEJ,GACF;AAEJ,CAAC;"}
1
+ {"version":3,"file":"RightPanel.js","sources":["../../../src/editor/components/RightPanel.tsx"],"sourcesContent":["import React, { lazy, Suspense } from \"react\";\nimport { LoadingSpinner } from \"./LoadingSpinner\";\nimport type { UploadConfig } from \"../LandingPageEditor\";\nimport type { SiteDocument } from \"../../engine\";\nimport type { ColorPalette } from \"../PaletteSelector\";\n\n// Lazy load componentes pesados do editor\nconst BlockPropertyEditor = lazy(() =>\n import(\"../PropertyEditor\").then(module => ({ default: module.BlockPropertyEditor }))\n);\nconst PaletteSelector = lazy(() =>\n import(\"../PaletteSelector\").then(module => ({ default: module.PaletteSelector }))\n);\n\ninterface RightPanelProps {\n isPaletteSelected: boolean;\n selectedBlock: any;\n selectedPalette?: ColorPalette;\n onPaletteChange: (palette: any) => void;\n onUpdateBlock: (updates: Record<string, any>) => void;\n uploadConfig?: UploadConfig;\n document?: SiteDocument;\n currentPageId?: string;\n /** When set, the matching property group opens and scrolls into view */\n focusedGroup?: string | null;\n}\n\nexport const RightPanel = React.memo(function RightPanel({\n isPaletteSelected,\n selectedBlock,\n selectedPalette,\n onPaletteChange,\n onUpdateBlock,\n uploadConfig,\n document,\n currentPageId,\n focusedGroup,\n}: RightPanelProps) {\n return (\n <div className=\"w-80 flex-shrink-0 border-l border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 overflow-hidden flex flex-col\">\n <Suspense fallback={<LoadingSpinner />}>\n {isPaletteSelected ? (\n <div className=\"p-4 overflow-y-auto\">\n <h2 className=\"text-sm font-semibold text-gray-800 dark:text-gray-100 mb-4\">\n Escolha uma Paleta de Cores\n </h2>\n <PaletteSelector\n selectedPalette={selectedPalette}\n onPaletteChange={onPaletteChange}\n />\n </div>\n ) : selectedBlock ? (\n <div className=\"overflow-y-auto overflow-x-hidden flex-1\">\n <BlockPropertyEditor\n block={selectedBlock}\n document={document}\n currentPageId={currentPageId}\n onUpdate={onUpdateBlock}\n uploadConfig={uploadConfig}\n focusedGroup={focusedGroup}\n />\n </div>\n ) : (\n <div className=\"p-4 text-center text-gray-500 dark:text-gray-400\">\n Selecione um bloco para editar\n </div>\n )}\n </Suspense>\n </div>\n );\n});\n"],"names":["BlockPropertyEditor","lazy","module","PaletteSelector","RightPanel","React","isPaletteSelected","selectedBlock","selectedPalette","onPaletteChange","onUpdateBlock","uploadConfig","document","currentPageId","focusedGroup","jsx","Suspense","LoadingSpinner","jsxs"],"mappings":";;;AAOA,MAAMA,IAAsBC;AAAA,EAAK,MAC/B,OAAO,4BAAmB,EAAE,KAAK,QAAW,EAAE,SAASC,EAAO,sBAAsB;AACtF,GACMC,IAAkBF;AAAA,EAAK,MAC3B,OAAO,uBAAoB,EAAE,KAAK,QAAW,EAAE,SAASC,EAAO,kBAAkB;AACnF,GAeaE,IAAaC,EAAM,KAAK,SAAoB;AAAA,EACvD,mBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AACF,GAAoB;AAClB,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAU,4HACb,4BAACC,GAAA,EAAS,UAAU,gBAAAD,EAACE,GAAA,CAAA,CAAe,GACjC,UAAAX,IACC,gBAAAY,EAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,IAAA,gBAAAH,EAAC,MAAA,EAAG,WAAU,+DAA8D,UAAA,+BAE5E;AAAA,IACA,gBAAAA;AAAA,MAACZ;AAAA,MAAA;AAAA,QACC,iBAAAK;AAAA,QACA,iBAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF,IACEF,IACF,gBAAAQ,EAAC,OAAA,EAAI,WAAU,4CACb,UAAA,gBAAAA;AAAA,IAACf;AAAA,IAAA;AAAA,MACC,OAAOO;AAAA,MACP,UAAAK;AAAA,MACA,eAAAC;AAAA,MACA,UAAUH;AAAA,MACV,cAAAC;AAAA,MACA,cAAAG;AAAA,IAAA;AAAA,EAAA,EACF,CACF,IAEA,gBAAAC,EAAC,OAAA,EAAI,WAAU,oDAAmD,UAAA,iCAAA,CAElE,GAEJ,GACF;AAEJ,CAAC;"}
@@ -1,12 +1,12 @@
1
1
  import { dataBlockIdAttr as s, escapeHtml as o } from "../../shared/htmlHelpers.js";
2
- function h(e, m, l, p) {
2
+ function h(e, m, p, l) {
3
3
  const { src: i, name: r, size: n = "md" } = e.props, a = {
4
4
  sm: "2rem",
5
5
  md: "2.5rem",
6
6
  lg: "3rem",
7
7
  xl: "4rem"
8
8
  }, t = a[n] || a.md, c = r ? r.split(" ").map((d) => d[0]).join("").toUpperCase().slice(0, 2) : "?";
9
- return i ? `<img ${s(e.id)} src="${o(i)}" alt="${o(r || "Avatar")}" style="width: ${t}; height: ${t}; border-radius: 50%; object-fit: cover;" />` : `<div ${s(e.id)} style="width: ${t}; height: ${t}; border-radius: 50%; background-color: var(--sg-primary, #3b82f6); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: calc(${t} / 2.5);">${c}</div>`;
9
+ return i ? `<img ${s(e.id)} src="${o(i)}" alt="${o(r || "Avatar")}" style="width: ${t}; height: ${t}; border-radius: 50%; object-fit: cover;" />` : `<div ${s(e.id)} style="width: ${t}; height: ${t}; border-radius: 50%; background-color: var(--sg-primary, #3b82f6); color: var(--sg-primary-text, #fff); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: calc(${t} / 2.5);">${c}</div>`;
10
10
  }
11
11
  export {
12
12
  h as exportAvatar
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarExporter.js","sources":["../../../../../src/engine/export/exporters/content/AvatarExporter.ts"],"sourcesContent":["/**\n * Avatar Block Exporter\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr, escapeHtml } from \"../../shared/htmlHelpers\";\n\nexport function exportAvatar(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n): string {\n const { src, name, size = \"md\" } = (block as any).props;\n\n const sizeMap: Record<string, string> = {\n sm: \"2rem\",\n md: \"2.5rem\",\n lg: \"3rem\",\n xl: \"4rem\",\n };\n\n const avatarSize = sizeMap[size] || sizeMap.md;\n\n const initials = name\n ? name\n .split(\" \")\n .map((n: string) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2)\n : \"?\";\n\n if (src) {\n return `<img ${dataBlockIdAttr(block.id)} src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(name || \"Avatar\")}\" style=\"width: ${avatarSize}; height: ${avatarSize}; border-radius: 50%; object-fit: cover;\" />`;\n }\n\n return `<div ${dataBlockIdAttr(block.id)} style=\"width: ${avatarSize}; height: ${avatarSize}; border-radius: 50%; background-color: var(--sg-primary, #3b82f6); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: calc(${avatarSize} / 2.5);\">${initials}</div>`;\n}\n"],"names":["exportAvatar","block","depth","basePath","theme","src","name","size","sizeMap","avatarSize","initials","n","dataBlockIdAttr","escapeHtml"],"mappings":";AAQO,SAASA,EACdC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM,EAAE,KAAAC,GAAK,MAAAC,GAAM,MAAAC,IAAO,KAAA,IAAUN,EAAc,OAE5CO,IAAkC;AAAA,IACtC,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,GAGAC,IAAaD,EAAQD,CAAI,KAAKC,EAAQ,IAEtCE,IAAWJ,IACbA,EACG,MAAM,GAAG,EACT,IAAI,CAACK,MAAcA,EAAE,CAAC,CAAC,EACvB,KAAK,EAAE,EACP,cACA,MAAM,GAAG,CAAC,IACb;AAEJ,SAAIN,IACK,QAAQO,EAAgBX,EAAM,EAAE,CAAC,SAASY,EAAWR,CAAG,CAAC,UAAUQ,EAAWP,KAAQ,QAAQ,CAAC,mBAAmBG,CAAU,aAAaA,CAAU,iDAGrJ,QAAQG,EAAgBX,EAAM,EAAE,CAAC,kBAAkBQ,CAAU,aAAaA,CAAU,mLAAmLA,CAAU,aAAaC,CAAQ;AAC/S;"}
1
+ {"version":3,"file":"AvatarExporter.js","sources":["../../../../../src/engine/export/exporters/content/AvatarExporter.ts"],"sourcesContent":["/**\n * Avatar Block Exporter\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr, escapeHtml } from \"../../shared/htmlHelpers\";\n\nexport function exportAvatar(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n): string {\n const { src, name, size = \"md\" } = (block as any).props;\n\n const sizeMap: Record<string, string> = {\n sm: \"2rem\",\n md: \"2.5rem\",\n lg: \"3rem\",\n xl: \"4rem\",\n };\n\n const avatarSize = sizeMap[size] || sizeMap.md;\n\n const initials = name\n ? name\n .split(\" \")\n .map((n: string) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2)\n : \"?\";\n\n if (src) {\n return `<img ${dataBlockIdAttr(block.id)} src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(name || \"Avatar\")}\" style=\"width: ${avatarSize}; height: ${avatarSize}; border-radius: 50%; object-fit: cover;\" />`;\n }\n\n return `<div ${dataBlockIdAttr(block.id)} style=\"width: ${avatarSize}; height: ${avatarSize}; border-radius: 50%; background-color: var(--sg-primary, #3b82f6); color: var(--sg-primary-text, #fff); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: calc(${avatarSize} / 2.5);\">${initials}</div>`;\n}\n"],"names":["exportAvatar","block","depth","basePath","theme","src","name","size","sizeMap","avatarSize","initials","n","dataBlockIdAttr","escapeHtml"],"mappings":";AAQO,SAASA,EACdC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM,EAAE,KAAAC,GAAK,MAAAC,GAAM,MAAAC,IAAO,KAAA,IAAUN,EAAc,OAE5CO,IAAkC;AAAA,IACtC,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,GAGAC,IAAaD,EAAQD,CAAI,KAAKC,EAAQ,IAEtCE,IAAWJ,IACbA,EACG,MAAM,GAAG,EACT,IAAI,CAACK,MAAcA,EAAE,CAAC,CAAC,EACvB,KAAK,EAAE,EACP,cACA,MAAM,GAAG,CAAC,IACb;AAEJ,SAAIN,IACK,QAAQO,EAAgBX,EAAM,EAAE,CAAC,SAASY,EAAWR,CAAG,CAAC,UAAUQ,EAAWP,KAAQ,QAAQ,CAAC,mBAAmBG,CAAU,aAAaA,CAAU,iDAGrJ,QAAQG,EAAgBX,EAAM,EAAE,CAAC,kBAAkBQ,CAAU,aAAaA,CAAU,2MAA2MA,CAAU,aAAaC,CAAQ;AACvU;"}
@@ -1,23 +1,23 @@
1
- import { dataBlockIdAttr as o, escapeHtml as d } from "../../shared/htmlHelpers.js";
2
- function p(e, g, i, m) {
3
- const { text: s, variant: f = "default", size: n = "md" } = e.props, t = {
1
+ import { dataBlockIdAttr as n, escapeHtml as i } from "../../shared/htmlHelpers.js";
2
+ function c(r, o, d, m) {
3
+ const { text: s, variant: f = "default", size: g = "md" } = r.props, t = {
4
4
  default: {
5
5
  bg: "var(--sg-surface2, #f3f4f6)",
6
6
  text: "var(--sg-text, #1f2937)"
7
7
  },
8
- primary: { bg: "var(--sg-primary, #3b82f6)", text: "#fff" },
9
- secondary: { bg: "var(--sg-secondary, #6b7280)", text: "#fff" },
10
- success: { bg: "var(--sg-success, #10b981)", text: "#fff" },
11
- warning: { bg: "var(--sg-warning, #f59e0b)", text: "#fff" },
12
- danger: { bg: "var(--sg-danger, #ef4444)", text: "#fff" }
13
- }, r = {
8
+ primary: { bg: "var(--sg-primary, #3b82f6)", text: "var(--sg-primary-text, #fff)" },
9
+ secondary: { bg: "var(--sg-secondary, #6b7280)", text: "var(--sg-primary-text, #fff)" },
10
+ success: { bg: "var(--sg-success, #10b981)", text: "var(--sg-primary-text, #fff)" },
11
+ warning: { bg: "var(--sg-warning, #f59e0b)", text: "var(--sg-primary-text, #fff)" },
12
+ danger: { bg: "var(--sg-danger, #ef4444)", text: "var(--sg-primary-text, #fff)" }
13
+ }, e = {
14
14
  sm: "padding: 0.125rem 0.5rem; font-size: 0.625rem;",
15
15
  md: "padding: 0.25rem 0.75rem; font-size: 0.75rem;",
16
16
  lg: "padding: 0.375rem 1rem; font-size: 0.875rem;"
17
17
  }, a = t[f] || t.default;
18
- return `<span ${o(e.id)} style="display: inline-block; background-color: ${a.bg}; color: ${a.text}; border-radius: 9999px; font-weight: 500; ${r[n] || r.md}">${d(s)}</span>`;
18
+ return `<span ${n(r.id)} style="display: inline-block; background-color: ${a.bg}; color: ${a.text}; border-radius: 9999px; font-weight: 500; ${e[g] || e.md}">${i(s)}</span>`;
19
19
  }
20
20
  export {
21
- p as exportBadge
21
+ c as exportBadge
22
22
  };
23
23
  //# sourceMappingURL=BadgeExporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BadgeExporter.js","sources":["../../../../../src/engine/export/exporters/content/BadgeExporter.ts"],"sourcesContent":["/**\n * Badge Block Exporter\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr, escapeHtml } from \"../../shared/htmlHelpers\";\n\nexport function exportBadge(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n): string {\n const { text, variant = \"default\", size = \"md\" } = (block as any).props;\n\n const variantColors: Record<string, { bg: string; text: string }> = {\n default: {\n bg: \"var(--sg-surface2, #f3f4f6)\",\n text: \"var(--sg-text, #1f2937)\",\n },\n primary: { bg: \"var(--sg-primary, #3b82f6)\", text: \"#fff\" },\n secondary: { bg: \"var(--sg-secondary, #6b7280)\", text: \"#fff\" },\n success: { bg: \"var(--sg-success, #10b981)\", text: \"#fff\" },\n warning: { bg: \"var(--sg-warning, #f59e0b)\", text: \"#fff\" },\n danger: { bg: \"var(--sg-danger, #ef4444)\", text: \"#fff\" },\n };\n\n const sizeStyles: Record<string, string> = {\n sm: \"padding: 0.125rem 0.5rem; font-size: 0.625rem;\",\n md: \"padding: 0.25rem 0.75rem; font-size: 0.75rem;\",\n lg: \"padding: 0.375rem 1rem; font-size: 0.875rem;\",\n };\n\n const colors = variantColors[variant] || variantColors.default;\n\n return `<span ${dataBlockIdAttr(block.id)} style=\"display: inline-block; background-color: ${colors.bg}; color: ${colors.text}; border-radius: 9999px; font-weight: 500; ${sizeStyles[size] || sizeStyles.md}\">${escapeHtml(text)}</span>`;\n}\n"],"names":["exportBadge","block","depth","basePath","theme","text","variant","size","variantColors","sizeStyles","colors","dataBlockIdAttr","escapeHtml"],"mappings":";AAQO,SAASA,EACdC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM,EAAE,MAAAC,GAAM,SAAAC,IAAU,WAAW,MAAAC,IAAO,KAAA,IAAUN,EAAc,OAE5DO,IAA8D;AAAA,IAClE,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,MAAM;AAAA,IAAA;AAAA,IAER,SAAS,EAAE,IAAI,8BAA8B,MAAM,OAAA;AAAA,IACnD,WAAW,EAAE,IAAI,gCAAgC,MAAM,OAAA;AAAA,IACvD,SAAS,EAAE,IAAI,8BAA8B,MAAM,OAAA;AAAA,IACnD,SAAS,EAAE,IAAI,8BAA8B,MAAM,OAAA;AAAA,IACnD,QAAQ,EAAE,IAAI,6BAA6B,MAAM,OAAA;AAAA,EAAO,GAGpDC,IAAqC;AAAA,IACzC,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,GAGAC,IAASF,EAAcF,CAAO,KAAKE,EAAc;AAEvD,SAAO,SAASG,EAAgBV,EAAM,EAAE,CAAC,oDAAoDS,EAAO,EAAE,YAAYA,EAAO,IAAI,8CAA8CD,EAAWF,CAAI,KAAKE,EAAW,EAAE,KAAKG,EAAWP,CAAI,CAAC;AACnO;"}
1
+ {"version":3,"file":"BadgeExporter.js","sources":["../../../../../src/engine/export/exporters/content/BadgeExporter.ts"],"sourcesContent":["/**\n * Badge Block Exporter\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr, escapeHtml } from \"../../shared/htmlHelpers\";\n\nexport function exportBadge(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n): string {\n const { text, variant = \"default\", size = \"md\" } = (block as any).props;\n\n const variantColors: Record<string, { bg: string; text: string }> = {\n default: {\n bg: \"var(--sg-surface2, #f3f4f6)\",\n text: \"var(--sg-text, #1f2937)\",\n },\n primary: { bg: \"var(--sg-primary, #3b82f6)\", text: \"var(--sg-primary-text, #fff)\" },\n secondary: { bg: \"var(--sg-secondary, #6b7280)\", text: \"var(--sg-primary-text, #fff)\" },\n success: { bg: \"var(--sg-success, #10b981)\", text: \"var(--sg-primary-text, #fff)\" },\n warning: { bg: \"var(--sg-warning, #f59e0b)\", text: \"var(--sg-primary-text, #fff)\" },\n danger: { bg: \"var(--sg-danger, #ef4444)\", text: \"var(--sg-primary-text, #fff)\" },\n };\n\n const sizeStyles: Record<string, string> = {\n sm: \"padding: 0.125rem 0.5rem; font-size: 0.625rem;\",\n md: \"padding: 0.25rem 0.75rem; font-size: 0.75rem;\",\n lg: \"padding: 0.375rem 1rem; font-size: 0.875rem;\",\n };\n\n const colors = variantColors[variant] || variantColors.default;\n\n return `<span ${dataBlockIdAttr(block.id)} style=\"display: inline-block; background-color: ${colors.bg}; color: ${colors.text}; border-radius: 9999px; font-weight: 500; ${sizeStyles[size] || sizeStyles.md}\">${escapeHtml(text)}</span>`;\n}\n"],"names":["exportBadge","block","depth","basePath","theme","text","variant","size","variantColors","sizeStyles","colors","dataBlockIdAttr","escapeHtml"],"mappings":";AAQO,SAASA,EACdC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM,EAAE,MAAAC,GAAM,SAAAC,IAAU,WAAW,MAAAC,IAAO,KAAA,IAAUN,EAAc,OAE5DO,IAA8D;AAAA,IAClE,SAAS;AAAA,MACP,IAAI;AAAA,MACJ,MAAM;AAAA,IAAA;AAAA,IAER,SAAS,EAAE,IAAI,8BAA8B,MAAM,+BAAA;AAAA,IACnD,WAAW,EAAE,IAAI,gCAAgC,MAAM,+BAAA;AAAA,IACvD,SAAS,EAAE,IAAI,8BAA8B,MAAM,+BAAA;AAAA,IACnD,SAAS,EAAE,IAAI,8BAA8B,MAAM,+BAAA;AAAA,IACnD,QAAQ,EAAE,IAAI,6BAA6B,MAAM,+BAAA;AAAA,EAA+B,GAG5EC,IAAqC;AAAA,IACzC,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,GAGAC,IAASF,EAAcF,CAAO,KAAKE,EAAc;AAEvD,SAAO,SAASG,EAAgBV,EAAM,EAAE,CAAC,oDAAoDS,EAAO,EAAE,YAAYA,EAAO,IAAI,8CAA8CD,EAAWF,CAAI,KAAKE,EAAW,EAAE,KAAKG,EAAWP,CAAI,CAAC;AACnO;"}
@@ -0,0 +1,6 @@
1
+ import { Block } from '../../../schema/siteDocument';
2
+ import { ThemeTokens } from '../../../schema/themeTokens';
3
+ export declare function exportProductShowcase(block: Block, _depth: number, _basePath?: string, theme?: ThemeTokens): string;
4
+ export declare function exportAboutSection(block: Block, _depth: number, _basePath?: string, theme?: ThemeTokens): string;
5
+ export declare function exportContactSection(block: Block, _depth: number, _basePath?: string, theme?: ThemeTokens): string;
6
+ //# sourceMappingURL=AdminSectionExporters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminSectionExporters.d.ts","sourceRoot":"","sources":["../../../../../src/engine/export/exporters/sections/AdminSectionExporters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AA4F1D,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,WAAW,GAClB,MAAM,CA4GR;AAMD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,WAAW,GAClB,MAAM,CA2ER;AAkBD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,WAAW,GAClB,MAAM,CAwFR"}
@@ -0,0 +1,157 @@
1
+ import { escapeHtml as t, blockIdAttr as B, dataBlockIdAttr as I } from "../../shared/htmlHelpers.js";
2
+ import { generateScopedId as T } from "../../shared/idGenerator.js";
3
+ import { resolveResponsiveColumns as V, generateResponsiveGridStyles as K } from "../../shared/responsiveGridHelper.js";
4
+ import { generateButtonHoverStyles as D, generateButtonOverlayCSS as F, getButtonHoverKeyframes as Q } from "../../../shared/hoverEffects/buttonHover.js";
5
+ function q(e, $, R, x) {
6
+ const {
7
+ buttonHoverEffect: n,
8
+ buttonHoverIntensity: l,
9
+ buttonHoverOverlay: d,
10
+ buttonHoverIconName: m
11
+ } = R, a = x?.colors?.primary || "#6366f1", w = x?.colors?.primaryText || "#ffffff";
12
+ let s = "";
13
+ if (n !== "none") {
14
+ const c = D({
15
+ effect: n,
16
+ intensity: l,
17
+ buttonColor: a,
18
+ variant: "solid"
19
+ }), g = D({
20
+ effect: n,
21
+ intensity: l,
22
+ buttonColor: a,
23
+ variant: "outline"
24
+ });
25
+ c.base && (s += `${e} .${$}--primary { ${c.base} }`), g.base && (s += `${e} .${$}--secondary { ${g.base} }`), s += `${e} .${$}--primary:hover { ${c.hover} }`, s += `${e} .${$}--secondary:hover { ${g.hover} }`, s += Q();
26
+ }
27
+ return d && d !== "none" && (s += F(`${e} .${$}--primary`, {
28
+ overlay: d,
29
+ primaryColor: a,
30
+ iconName: m,
31
+ textColor: w
32
+ }), s += F(`${e} .${$}--secondary`, {
33
+ overlay: d,
34
+ primaryColor: a,
35
+ iconName: m,
36
+ textColor: a
37
+ })), s;
38
+ }
39
+ const E = "position: relative; overflow: hidden; transition: all 0.2s ease;";
40
+ function Y(e, $, R, x) {
41
+ const {
42
+ title: n,
43
+ subtitle: l,
44
+ products: d = [],
45
+ variant: m = "alternating",
46
+ bg: a,
47
+ buttonHoverEffect: w = "none",
48
+ buttonHoverIntensity: s = 50,
49
+ buttonHoverOverlay: c = "none",
50
+ buttonHoverIconName: g = "arrow-right"
51
+ } = e.props, _ = a ? `background-color: ${t(a)};` : "background-color: var(--sg-bg);", N = `[data-block-id="${e.id}"]`, S = q(N, "sg-showcase__btn", {
52
+ buttonHoverEffect: w,
53
+ buttonHoverIntensity: s,
54
+ buttonHoverOverlay: c,
55
+ buttonHoverIconName: g
56
+ }, x), O = l ? `<span style="display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.75rem;">${t(l)}</span>` : "", C = n ? `<h2 style="font-size: var(--sg-heading-h2); margin-bottom: 0.5rem;">${t(n)}</h2>` : "", z = n || l ? `<div data-block-group="Conteúdo" style="text-align: center; margin-bottom: 3rem;">${O}${C}</div>` : "", j = S ? `<style>${S}</style>` : "";
57
+ if (m === "grid") {
58
+ const r = T(e.id || "", "product-grid"), h = V(
59
+ Math.min(d.length, 3),
60
+ 1,
61
+ 2,
62
+ Math.min(d.length, 3)
63
+ ), { inlineStyles: k, mediaQueries: y } = K(r, h, "2rem"), H = d.map((i) => {
64
+ const b = i.image ? `<div style="width: 100%; height: 200px; background-image: url(${t(i.image)}); background-size: cover; background-position: center;"></div>` : "", p = i.badge ? `<span style="display: inline-block; padding: 0.125rem 0.5rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.7rem; font-weight: 600; margin-bottom: 0.5rem;">${t(i.badge)}</span>` : "", u = i.icon ? `<span style="margin-right: 0.5rem;">${t(i.icon)}</span>` : "", f = i.primaryButton ? `<a href="${t(i.primaryButton.href || "#")}" class="sg-showcase__btn sg-showcase__btn--primary" style="display: inline-block; margin-top: 1rem; padding: 0.5rem 1rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; font-size: 0.875rem; ${E}">${t(i.primaryButton.text)}</a>` : "";
65
+ return `<div style="background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); overflow: hidden; box-shadow: var(--sg-card-shadow);">${b}<div style="padding: 1.5rem;">${p}<h3 style="font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem;">${u}${t(i.name)}</h3><p style="color: var(--sg-muted-text); font-size: 0.875rem;">${t(i.description)}</p>${f}</div></div>`;
66
+ }).join("");
67
+ return `${j}<style>${y}</style><section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${_}"><div style="max-width: 1200px; margin: 0 auto; padding: 0 1rem;">${z}<div data-block-group="Layout" id="${r}" style="${k}">${H}</div></div></section>`;
68
+ }
69
+ const M = T(e.id || "", "product-showcase"), A = d.map((r, h) => {
70
+ const k = m === "alternating" && h % 2 === 1, y = r.image ? `<img src="${t(r.image)}" alt="${t(r.name)}" style="width: 100%; border-radius: var(--sg-card-radius, 0.75rem); object-fit: cover;" />` : `<div style="width: 100%; height: 300px; background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); display: flex; align-items: center; justify-content: center; font-size: 4rem;">${t(r.icon || "📦")}</div>`, H = r.badge ? `<span style="display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; margin-bottom: 0.75rem;">${t(r.badge)}</span>` : "", i = r.icon ? `<span style="margin-right: 0.5rem;">${t(r.icon)}</span>` : "", b = r.features && r.features.length > 0 ? `<ul style="list-style: none; padding: 0; margin: 0 0 1.5rem 0;">${r.features.map((v) => `<li style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;"><span style="color: #10b981; font-weight: 700;">✓</span>${t(v)}</li>`).join("")}</ul>` : "", p = r.primaryButton ? `<a href="${t(r.primaryButton.href || "#")}" class="sg-showcase__btn sg-showcase__btn--primary" style="display: inline-block; padding: 0.625rem 1.25rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; ${E}">${t(r.primaryButton.text)}</a>` : "", u = r.secondaryButton ? `<a href="${t(r.secondaryButton.href || "#")}" class="sg-showcase__btn sg-showcase__btn--secondary" style="display: inline-block; padding: 0.625rem 1.25rem; background-color: transparent; color: var(--sg-primary); border: 1px solid var(--sg-primary); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; ${E}">${t(r.secondaryButton.text)}</a>` : "", f = p || u ? `<div style="display: flex; gap: 0.75rem; flex-wrap: wrap;">${p}${u}</div>` : "", o = `${M}-item-${h}`;
71
+ return `<style>
72
+ #${o} { flex-direction: column; }
73
+ @media (min-width: 768px) { #${o} { flex-direction: ${k ? "row-reverse" : "row"}; } }
74
+ </style><div id="${o}" style="display: flex; gap: 3rem; align-items: center;"><div style="flex: 1 1 50%;">${y}</div><div style="flex: 1 1 50%;">${H}<h3 style="font-size: 1.5rem; font-weight: 700; margin-bottom: 0.75rem;">${i}${t(r.name)}</h3><p style="color: var(--sg-muted-text); margin-bottom: 1rem; line-height: 1.7;">${t(r.longDescription || r.description)}</p>${b}${f}</div></div>`;
75
+ }).join("");
76
+ return `${j}<section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${_}"><div style="max-width: 1200px; margin: 0 auto; padding: 0 1rem;">${z}<div data-block-group="Layout" style="display: flex; flex-direction: column; gap: 4rem;">${A}</div></div></section>`;
77
+ }
78
+ function tt(e, $, R, x) {
79
+ const {
80
+ title: n,
81
+ subtitle: l,
82
+ description: d,
83
+ secondaryDescription: m,
84
+ image: a,
85
+ achievements: w = [],
86
+ primaryButton: s,
87
+ variant: c = "image-left",
88
+ bg: g,
89
+ stats: _ = [],
90
+ buttonHoverEffect: N = "none",
91
+ buttonHoverIntensity: S = 50,
92
+ buttonHoverOverlay: O = "none",
93
+ buttonHoverIconName: C = "arrow-right"
94
+ } = e.props, z = g ? `background-color: ${t(g)};` : "background-color: var(--sg-bg);", j = c === "centered", M = c === "image-right", A = `[data-block-id="${e.id}"]`, r = q(A, "sg-about__btn", {
95
+ buttonHoverEffect: N,
96
+ buttonHoverIntensity: S,
97
+ buttonHoverOverlay: O,
98
+ buttonHoverIconName: C
99
+ }, x), h = l ? `<span style="display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.75rem;">${t(l)}</span>` : "", k = n ? `<h2 style="font-size: var(--sg-heading-h2); margin-bottom: 1rem;">${t(n)}</h2>` : "", y = d ? `<p style="color: var(--sg-muted-text); line-height: 1.7; margin-bottom: 1rem;">${t(d)}</p>` : "", H = m ? `<p style="color: var(--sg-muted-text); line-height: 1.7; margin-bottom: 1.5rem;">${t(m)}</p>` : "", i = w.length > 0 ? `<ul style="list-style: none; padding: 0; margin: 0 0 1.5rem 0;">${w.map((v) => `<li style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;"><span style="color: #10b981; font-weight: 700;">✓</span>${t(v.text)}</li>`).join("")}</ul>` : "", b = s ? `<a href="${t(s.href || "#")}" class="sg-about__btn sg-about__btn--primary" style="display: inline-block; padding: 0.75rem 1.5rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; ${E}">${t(s.text)}</a>` : "", p = r ? `<style>${r}</style>` : "";
100
+ if (j) {
101
+ const v = a ? `<div data-block-group="Mídia" style="margin: 2rem 0;"><img src="${t(a)}" alt="${t(n || "About")}" style="width: 100%; border-radius: var(--sg-card-radius, 0.75rem); object-fit: cover;" /></div>` : "";
102
+ return `${p}<section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${z}"><div style="max-width: 800px; margin: 0 auto; padding: 0 1rem; text-align: center;">${h}${k}${v}${y}${H}${i}${b}</div></section>`;
103
+ }
104
+ const u = T(e.id || "", "about"), f = a ? `<img src="${t(a)}" alt="${t(n || "About")}" style="width: 100%; border-radius: var(--sg-card-radius, 0.75rem); object-fit: cover;" />` : '<div style="width: 100%; height: 400px; background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); display: flex; align-items: center; justify-content: center; font-size: 1rem; color: var(--sg-muted-text);">Imagem</div>', o = _.length > 0 ? `<div style="display: flex; gap: 0.5rem; margin-top: 1rem;">${_.map((v) => `<div style="background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); padding: 0.75rem 1rem; border-radius: var(--sg-card-radius, 0.75rem); text-align: center; box-shadow: 0 4px 12px rgba(0,0,0,0.15); min-width: 80px;"><div style="font-size: 1.5rem; font-weight: 700;">${t(v.value)}</div><div style="font-size: 0.7rem; opacity: 0.9;">${t(v.label)}</div></div>`).join("")}</div>` : "";
105
+ return `${p}<style>
106
+ #${u} { flex-direction: column; }
107
+ @media (min-width: 768px) { #${u} { flex-direction: ${M ? "row-reverse" : "row"}; } }
108
+ </style><section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${z}"><div id="${u}" style="max-width: 1200px; margin: 0 auto; padding: 0 1rem; display: flex; gap: 3rem; align-items: center;"><div data-block-group="Mídia" style="flex: 1 1 50%; position: relative;">${f}${o}</div><div data-block-group="Conteúdo" style="flex: 1 1 50%;">${h}${k}${y}${H}${i}${b}</div></div></section>`;
109
+ }
110
+ const G = {
111
+ mail: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>',
112
+ phone: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>',
113
+ "map-pin": '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>',
114
+ clock: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',
115
+ globe: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>'
116
+ };
117
+ function Z(e) {
118
+ return G[e] || G.mail;
119
+ }
120
+ function et(e, $, R, x) {
121
+ const {
122
+ title: n,
123
+ subtitle: l,
124
+ description: d,
125
+ contactInfo: m = [],
126
+ formTitle: a,
127
+ formFields: w = [],
128
+ submitText: s = "Enviar",
129
+ variant: c = "split",
130
+ bg: g,
131
+ buttonHoverEffect: _ = "none",
132
+ buttonHoverIntensity: N = 50,
133
+ buttonHoverOverlay: S = "none",
134
+ buttonHoverIconName: O = "arrow-right"
135
+ } = e.props, C = g ? `background-color: ${t(g)};` : "background-color: var(--sg-bg);", z = c === "form-only", j = c === "stacked", M = `[data-block-id="${e.id}"]`, A = q(M, "sg-contact__btn", {
136
+ buttonHoverEffect: _,
137
+ buttonHoverIntensity: N,
138
+ buttonHoverOverlay: S,
139
+ buttonHoverIconName: O
140
+ }, x), r = l ? `<span style="display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.75rem;">${t(l)}</span>` : "", h = n ? `<h2 style="font-size: var(--sg-heading-h2); margin-bottom: 0.5rem;">${t(n)}</h2>` : "", k = d ? `<p style="color: var(--sg-muted-text);">${t(d)}</p>` : "", y = n || l ? `<div data-block-group="Conteúdo" style="text-align: center; margin-bottom: 3rem;">${r}${h}${k}</div>` : "", H = w.map((o) => {
141
+ const v = o.label ? `<label style="display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.375rem; color: var(--sg-text);">${t(o.label)}${o.required ? '<span style="color: #ef4444;"> *</span>' : ""}</label>` : "", L = "width: 100%; padding: 0.625rem 0.75rem; border: 1px solid var(--sg-border); border-radius: var(--sg-button-radius, 0.5rem); font-size: 0.875rem; background-color: var(--sg-bg); color: var(--sg-text); box-sizing: border-box;", P = o.type === "textarea" ? `<textarea name="${t(o.name)}" placeholder="${t(o.placeholder || "")}" rows="4" style="${L} resize: vertical;"${o.required ? " required" : ""}></textarea>` : `<input type="${t(o.type || "text")}" name="${t(o.name)}" placeholder="${t(o.placeholder || "")}" style="${L}"${o.required ? " required" : ""} />`;
142
+ return `<div style="margin-bottom: 1rem;">${v}${P}</div>`;
143
+ }).join(""), i = `width: 100%; padding: 0.75rem 1.5rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border: none; border-radius: var(--sg-button-radius, 0.5rem); font-weight: 500; cursor: pointer; font-size: 1rem; ${E}`, b = `<div data-block-group="Formulário" style="background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); padding: 2rem; box-shadow: var(--sg-card-shadow);">${a ? `<h3 style="font-size: 1.25rem; font-weight: 600; margin-bottom: 1.5rem;">${t(a)}</h3>` : ""}<form>${H}<button type="submit" class="sg-contact__btn sg-contact__btn--primary" style="${i}">${t(s)}</button></form></div>`, p = A ? `<style>${A}</style>` : "";
144
+ if (z)
145
+ return `${p}<section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${C}"><div style="max-width: 600px; margin: 0 auto; padding: 0 1rem;">${y}${b}</div></section>`;
146
+ const u = m.map((o) => `<div style="display: flex; align-items: flex-start; gap: 1rem; padding: 1.25rem; background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); box-shadow: var(--sg-card-shadow);"><div style="width: 2.5rem; height: 2.5rem; background-color: var(--sg-primary); border-radius: 0.5rem; display: flex; align-items: center; justify-content: center; color: var(--sg-primary-text, #fff); flex-shrink: 0;">${Z(o.icon || "mail")}</div><div><div style="font-weight: 600; font-size: 0.875rem; margin-bottom: 0.25rem;">${t(o.label)}</div><div style="color: var(--sg-muted-text); font-size: 0.875rem;">${t(o.value)}</div></div></div>`).join(""), f = T(e.id || "", "contact");
147
+ return j ? `${p}<section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${C}"><div style="max-width: 1200px; margin: 0 auto; padding: 0 1rem;">${y}${m.length > 0 ? `<div data-block-group="Info" style="display: flex; flex-direction: column; gap: 1rem; margin-bottom: 3rem;">${u}</div>` : ""}${b}</div></section>` : `${p}<style>
148
+ #${f} { flex-direction: column; }
149
+ @media (min-width: 768px) { #${f} { flex-direction: row; } }
150
+ </style><section ${B(e.id)} ${I(e.id)} style="padding: 4rem 0; ${C}"><div style="max-width: 1200px; margin: 0 auto; padding: 0 1rem;">${y}<div id="${f}" style="display: flex; gap: 3rem;">${m.length > 0 ? `<div data-block-group="Info" style="flex: 1 1 40%; display: flex; flex-direction: column; gap: 1rem;">${u}</div>` : ""}<div style="flex: 1 1 60%;">${b}</div></div></div></section>`;
151
+ }
152
+ export {
153
+ tt as exportAboutSection,
154
+ et as exportContactSection,
155
+ Y as exportProductShowcase
156
+ };
157
+ //# sourceMappingURL=AdminSectionExporters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminSectionExporters.js","sources":["../../../../../src/engine/export/exporters/sections/AdminSectionExporters.ts"],"sourcesContent":["/**\n * Admin Section Exporters\n * ProductShowcase, AboutSection, ContactSection\n * Mobile-first responsive layouts with media queries\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr, blockIdAttr, escapeHtml } from \"../../shared/htmlHelpers\";\nimport { generateScopedId } from \"../../shared/idGenerator\";\nimport {\n resolveResponsiveColumns,\n generateResponsiveGridStyles,\n} from \"../../shared/responsiveGridHelper\";\nimport {\n generateButtonHoverStyles,\n generateButtonOverlayCSS,\n getButtonHoverKeyframes,\n type ButtonHoverEffect,\n type ButtonHoverOverlay,\n} from \"../../../shared/hoverEffects\";\n\n// ============================================================================\n// Shared: button hover CSS generator for admin sections\n// ============================================================================\n\nfunction generateAdminButtonHoverCSS(\n scope: string,\n classPrefix: string,\n props: {\n buttonHoverEffect: string;\n buttonHoverIntensity: number;\n buttonHoverOverlay: string;\n buttonHoverIconName: string;\n },\n theme?: ThemeTokens,\n): string {\n const {\n buttonHoverEffect,\n buttonHoverIntensity,\n buttonHoverOverlay,\n buttonHoverIconName,\n } = props;\n\n const primaryColor = theme?.colors?.primary || \"#6366f1\";\n const primaryText = theme?.colors?.primaryText || \"#ffffff\";\n let css = \"\";\n\n if (buttonHoverEffect !== \"none\") {\n const primaryResult = generateButtonHoverStyles({\n effect: buttonHoverEffect as ButtonHoverEffect,\n intensity: buttonHoverIntensity,\n buttonColor: primaryColor,\n buttonTextColor: primaryText,\n variant: \"solid\",\n });\n const outlineResult = generateButtonHoverStyles({\n effect: buttonHoverEffect as ButtonHoverEffect,\n intensity: buttonHoverIntensity,\n buttonColor: primaryColor,\n buttonTextColor: primaryColor,\n variant: \"outline\",\n });\n\n if (primaryResult.base) {\n css += `${scope} .${classPrefix}--primary { ${primaryResult.base} }`;\n }\n if (outlineResult.base) {\n css += `${scope} .${classPrefix}--secondary { ${outlineResult.base} }`;\n }\n css += `${scope} .${classPrefix}--primary:hover { ${primaryResult.hover} }`;\n css += `${scope} .${classPrefix}--secondary:hover { ${outlineResult.hover} }`;\n css += getButtonHoverKeyframes();\n }\n\n if (buttonHoverOverlay && buttonHoverOverlay !== \"none\") {\n css += generateButtonOverlayCSS(`${scope} .${classPrefix}--primary`, {\n overlay: buttonHoverOverlay as ButtonHoverOverlay,\n primaryColor,\n iconName: buttonHoverIconName,\n textColor: primaryText,\n });\n css += generateButtonOverlayCSS(`${scope} .${classPrefix}--secondary`, {\n overlay: buttonHoverOverlay as ButtonHoverOverlay,\n primaryColor,\n iconName: buttonHoverIconName,\n textColor: primaryColor,\n });\n }\n\n return css;\n}\n\nconst BTN_HOVER_BASE = \"position: relative; overflow: hidden; transition: all 0.2s ease;\";\n\n// ============================================================================\n// ProductShowcase\n// ============================================================================\n\nexport function exportProductShowcase(\n block: Block,\n _depth: number,\n _basePath?: string,\n theme?: ThemeTokens,\n): string {\n const {\n title,\n subtitle,\n products = [],\n variant = \"alternating\",\n bg,\n buttonHoverEffect = \"none\",\n buttonHoverIntensity = 50,\n buttonHoverOverlay = \"none\",\n buttonHoverIconName = \"arrow-right\",\n } = (block as any).props;\n\n const bgStyle = bg ? `background-color: ${escapeHtml(bg)};` : \"background-color: var(--sg-bg);\";\n const scope = `[data-block-id=\"${block.id}\"]`;\n\n // Hover CSS\n const hoverCss = generateAdminButtonHoverCSS(scope, \"sg-showcase__btn\", {\n buttonHoverEffect,\n buttonHoverIntensity,\n buttonHoverOverlay,\n buttonHoverIconName,\n }, theme);\n\n // Header\n const subtitleHtml = subtitle\n ? `<span style=\"display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.75rem;\">${escapeHtml(subtitle)}</span>`\n : \"\";\n const titleHtml = title\n ? `<h2 style=\"font-size: var(--sg-heading-h2); margin-bottom: 0.5rem;\">${escapeHtml(title)}</h2>`\n : \"\";\n const headerHtml =\n title || subtitle\n ? `<div data-block-group=\"Conteúdo\" style=\"text-align: center; margin-bottom: 3rem;\">${subtitleHtml}${titleHtml}</div>`\n : \"\";\n\n const stylePreamble = hoverCss ? `<style>${hoverCss}</style>` : \"\";\n\n if (variant === \"grid\") {\n const gridId = generateScopedId(block.id || \"\", \"product-grid\");\n const responsiveConfig = resolveResponsiveColumns(\n Math.min(products.length, 3),\n 1,\n 2,\n Math.min(products.length, 3),\n );\n const { inlineStyles, mediaQueries } = generateResponsiveGridStyles(gridId, responsiveConfig, \"2rem\");\n\n const cardsHtml = products\n .map((p: any) => {\n const imgHtml = p.image\n ? `<div style=\"width: 100%; height: 200px; background-image: url(${escapeHtml(p.image)}); background-size: cover; background-position: center;\"></div>`\n : \"\";\n const badgeHtml = p.badge\n ? `<span style=\"display: inline-block; padding: 0.125rem 0.5rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.7rem; font-weight: 600; margin-bottom: 0.5rem;\">${escapeHtml(p.badge)}</span>`\n : \"\";\n const iconHtml = p.icon ? `<span style=\"margin-right: 0.5rem;\">${escapeHtml(p.icon)}</span>` : \"\";\n const btnHtml = p.primaryButton\n ? `<a href=\"${escapeHtml(p.primaryButton.href || \"#\")}\" class=\"sg-showcase__btn sg-showcase__btn--primary\" style=\"display: inline-block; margin-top: 1rem; padding: 0.5rem 1rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; font-size: 0.875rem; ${BTN_HOVER_BASE}\">${escapeHtml(p.primaryButton.text)}</a>`\n : \"\";\n return `<div style=\"background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); overflow: hidden; box-shadow: var(--sg-card-shadow);\">${imgHtml}<div style=\"padding: 1.5rem;\">${badgeHtml}<h3 style=\"font-size: 1.25rem; font-weight: 600; margin-bottom: 0.5rem;\">${iconHtml}${escapeHtml(p.name)}</h3><p style=\"color: var(--sg-muted-text); font-size: 0.875rem;\">${escapeHtml(p.description)}</p>${btnHtml}</div></div>`;\n })\n .join(\"\");\n\n return `${stylePreamble}<style>${mediaQueries}</style><section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div style=\"max-width: 1200px; margin: 0 auto; padding: 0 1rem;\">${headerHtml}<div data-block-group=\"Layout\" id=\"${gridId}\" style=\"${inlineStyles}\">${cardsHtml}</div></div></section>`;\n }\n\n // alternating / stacked\n const scopeId = generateScopedId(block.id || \"\", \"product-showcase\");\n const productsHtml = products\n .map((p: any, index: number) => {\n const isReversed = variant === \"alternating\" && index % 2 === 1;\n\n const imgHtml = p.image\n ? `<img src=\"${escapeHtml(p.image)}\" alt=\"${escapeHtml(p.name)}\" style=\"width: 100%; border-radius: var(--sg-card-radius, 0.75rem); object-fit: cover;\" />`\n : `<div style=\"width: 100%; height: 300px; background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); display: flex; align-items: center; justify-content: center; font-size: 4rem;\">${escapeHtml(p.icon || \"📦\")}</div>`;\n\n const badgeHtml = p.badge\n ? `<span style=\"display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; margin-bottom: 0.75rem;\">${escapeHtml(p.badge)}</span>`\n : \"\";\n const iconHtml = p.icon ? `<span style=\"margin-right: 0.5rem;\">${escapeHtml(p.icon)}</span>` : \"\";\n\n const featuresHtml =\n p.features && p.features.length > 0\n ? `<ul style=\"list-style: none; padding: 0; margin: 0 0 1.5rem 0;\">${p.features.map((f: string) => `<li style=\"display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;\"><span style=\"color: #10b981; font-weight: 700;\">✓</span>${escapeHtml(f)}</li>`).join(\"\")}</ul>`\n : \"\";\n\n const primaryBtnHtml = p.primaryButton\n ? `<a href=\"${escapeHtml(p.primaryButton.href || \"#\")}\" class=\"sg-showcase__btn sg-showcase__btn--primary\" style=\"display: inline-block; padding: 0.625rem 1.25rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; ${BTN_HOVER_BASE}\">${escapeHtml(p.primaryButton.text)}</a>`\n : \"\";\n const secondaryBtnHtml = p.secondaryButton\n ? `<a href=\"${escapeHtml(p.secondaryButton.href || \"#\")}\" class=\"sg-showcase__btn sg-showcase__btn--secondary\" style=\"display: inline-block; padding: 0.625rem 1.25rem; background-color: transparent; color: var(--sg-primary); border: 1px solid var(--sg-primary); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; ${BTN_HOVER_BASE}\">${escapeHtml(p.secondaryButton.text)}</a>`\n : \"\";\n const buttonsHtml =\n primaryBtnHtml || secondaryBtnHtml\n ? `<div style=\"display: flex; gap: 0.75rem; flex-wrap: wrap;\">${primaryBtnHtml}${secondaryBtnHtml}</div>`\n : \"\";\n\n const itemId = `${scopeId}-item-${index}`;\n\n return `<style>\n #${itemId} { flex-direction: column; }\n @media (min-width: 768px) { #${itemId} { flex-direction: ${isReversed ? \"row-reverse\" : \"row\"}; } }\n</style><div id=\"${itemId}\" style=\"display: flex; gap: 3rem; align-items: center;\"><div style=\"flex: 1 1 50%;\">${imgHtml}</div><div style=\"flex: 1 1 50%;\">${badgeHtml}<h3 style=\"font-size: 1.5rem; font-weight: 700; margin-bottom: 0.75rem;\">${iconHtml}${escapeHtml(p.name)}</h3><p style=\"color: var(--sg-muted-text); margin-bottom: 1rem; line-height: 1.7;\">${escapeHtml(p.longDescription || p.description)}</p>${featuresHtml}${buttonsHtml}</div></div>`;\n })\n .join(\"\");\n\n return `${stylePreamble}<section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div style=\"max-width: 1200px; margin: 0 auto; padding: 0 1rem;\">${headerHtml}<div data-block-group=\"Layout\" style=\"display: flex; flex-direction: column; gap: 4rem;\">${productsHtml}</div></div></section>`;\n}\n\n// ============================================================================\n// AboutSection\n// ============================================================================\n\nexport function exportAboutSection(\n block: Block,\n _depth: number,\n _basePath?: string,\n theme?: ThemeTokens,\n): string {\n const {\n title,\n subtitle,\n description,\n secondaryDescription,\n image,\n achievements = [],\n primaryButton,\n variant = \"image-left\",\n bg,\n stats = [],\n buttonHoverEffect = \"none\",\n buttonHoverIntensity = 50,\n buttonHoverOverlay = \"none\",\n buttonHoverIconName = \"arrow-right\",\n } = (block as any).props;\n\n const bgStyle = bg ? `background-color: ${escapeHtml(bg)};` : \"background-color: var(--sg-bg);\";\n const isCentered = variant === \"centered\";\n const isReversed = variant === \"image-right\";\n const scope = `[data-block-id=\"${block.id}\"]`;\n\n // Hover CSS\n const hoverCss = generateAdminButtonHoverCSS(scope, \"sg-about__btn\", {\n buttonHoverEffect,\n buttonHoverIntensity,\n buttonHoverOverlay,\n buttonHoverIconName,\n }, theme);\n\n const subtitleHtml = subtitle\n ? `<span style=\"display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.75rem;\">${escapeHtml(subtitle)}</span>`\n : \"\";\n const titleHtml = title\n ? `<h2 style=\"font-size: var(--sg-heading-h2); margin-bottom: 1rem;\">${escapeHtml(title)}</h2>`\n : \"\";\n const descHtml = description\n ? `<p style=\"color: var(--sg-muted-text); line-height: 1.7; margin-bottom: 1rem;\">${escapeHtml(description)}</p>`\n : \"\";\n const secondaryDescHtml = secondaryDescription\n ? `<p style=\"color: var(--sg-muted-text); line-height: 1.7; margin-bottom: 1.5rem;\">${escapeHtml(secondaryDescription)}</p>`\n : \"\";\n const achievementsHtml =\n achievements.length > 0\n ? `<ul style=\"list-style: none; padding: 0; margin: 0 0 1.5rem 0;\">${achievements.map((a: any) => `<li style=\"display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem;\"><span style=\"color: #10b981; font-weight: 700;\">✓</span>${escapeHtml(a.text)}</li>`).join(\"\")}</ul>`\n : \"\";\n const buttonHtml = primaryButton\n ? `<a href=\"${escapeHtml(primaryButton.href || \"#\")}\" class=\"sg-about__btn sg-about__btn--primary\" style=\"display: inline-block; padding: 0.75rem 1.5rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border-radius: var(--sg-button-radius, 0.5rem); text-decoration: none; font-weight: 500; ${BTN_HOVER_BASE}\">${escapeHtml(primaryButton.text)}</a>`\n : \"\";\n\n const stylePreamble = hoverCss ? `<style>${hoverCss}</style>` : \"\";\n\n if (isCentered) {\n const imgHtml = image\n ? `<div data-block-group=\"Mídia\" style=\"margin: 2rem 0;\"><img src=\"${escapeHtml(image)}\" alt=\"${escapeHtml(title || \"About\")}\" style=\"width: 100%; border-radius: var(--sg-card-radius, 0.75rem); object-fit: cover;\" /></div>`\n : \"\";\n return `${stylePreamble}<section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div style=\"max-width: 800px; margin: 0 auto; padding: 0 1rem; text-align: center;\">${subtitleHtml}${titleHtml}${imgHtml}${descHtml}${secondaryDescHtml}${achievementsHtml}${buttonHtml}</div></section>`;\n }\n\n // image-left / image-right\n const scopeId = generateScopedId(block.id || \"\", \"about\");\n const imgHtml = image\n ? `<img src=\"${escapeHtml(image)}\" alt=\"${escapeHtml(title || \"About\")}\" style=\"width: 100%; border-radius: var(--sg-card-radius, 0.75rem); object-fit: cover;\" />`\n : `<div style=\"width: 100%; height: 400px; background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); display: flex; align-items: center; justify-content: center; font-size: 1rem; color: var(--sg-muted-text);\">Imagem</div>`;\n\n const statsHtml =\n stats.length > 0\n ? `<div style=\"display: flex; gap: 0.5rem; margin-top: 1rem;\">${stats.map((s: any) => `<div style=\"background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); padding: 0.75rem 1rem; border-radius: var(--sg-card-radius, 0.75rem); text-align: center; box-shadow: 0 4px 12px rgba(0,0,0,0.15); min-width: 80px;\"><div style=\"font-size: 1.5rem; font-weight: 700;\">${escapeHtml(s.value)}</div><div style=\"font-size: 0.7rem; opacity: 0.9;\">${escapeHtml(s.label)}</div></div>`).join(\"\")}</div>`\n : \"\";\n\n return `${stylePreamble}<style>\n #${scopeId} { flex-direction: column; }\n @media (min-width: 768px) { #${scopeId} { flex-direction: ${isReversed ? \"row-reverse\" : \"row\"}; } }\n</style><section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div id=\"${scopeId}\" style=\"max-width: 1200px; margin: 0 auto; padding: 0 1rem; display: flex; gap: 3rem; align-items: center;\"><div data-block-group=\"Mídia\" style=\"flex: 1 1 50%; position: relative;\">${imgHtml}${statsHtml}</div><div data-block-group=\"Conteúdo\" style=\"flex: 1 1 50%;\">${subtitleHtml}${titleHtml}${descHtml}${secondaryDescHtml}${achievementsHtml}${buttonHtml}</div></div></section>`;\n}\n\n// ============================================================================\n// ContactSection\n// ============================================================================\n\nconst CONTACT_ICON_SVG: Record<string, string> = {\n mail: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"/><path d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\"/></svg>`,\n phone: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z\"/></svg>`,\n \"map-pin\": `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/></svg>`,\n clock: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><polyline points=\"12 6 12 12 16 14\"/></svg>`,\n globe: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\"/><path d=\"M2 12h20\"/></svg>`,\n};\n\nfunction getContactIconSvg(icon: string): string {\n return CONTACT_ICON_SVG[icon] || CONTACT_ICON_SVG.mail;\n}\n\nexport function exportContactSection(\n block: Block,\n _depth: number,\n _basePath?: string,\n theme?: ThemeTokens,\n): string {\n const {\n title,\n subtitle,\n description,\n contactInfo = [],\n formTitle,\n formFields = [],\n submitText = \"Enviar\",\n variant = \"split\",\n bg,\n buttonHoverEffect = \"none\",\n buttonHoverIntensity = 50,\n buttonHoverOverlay = \"none\",\n buttonHoverIconName = \"arrow-right\",\n } = (block as any).props;\n\n const bgStyle = bg ? `background-color: ${escapeHtml(bg)};` : \"background-color: var(--sg-bg);\";\n const isFormOnly = variant === \"form-only\";\n const isStacked = variant === \"stacked\";\n const scope = `[data-block-id=\"${block.id}\"]`;\n\n // Hover CSS — submit button uses --primary class\n const hoverCss = generateAdminButtonHoverCSS(scope, \"sg-contact__btn\", {\n buttonHoverEffect,\n buttonHoverIntensity,\n buttonHoverOverlay,\n buttonHoverIconName,\n }, theme);\n\n const subtitleHtml = subtitle\n ? `<span style=\"display: inline-block; padding: 0.25rem 0.75rem; background-color: var(--sg-primary); color: var(--sg-primary-text, #fff); border-radius: 9999px; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.75rem;\">${escapeHtml(subtitle)}</span>`\n : \"\";\n const titleHtml = title\n ? `<h2 style=\"font-size: var(--sg-heading-h2); margin-bottom: 0.5rem;\">${escapeHtml(title)}</h2>`\n : \"\";\n const descHtml = description\n ? `<p style=\"color: var(--sg-muted-text);\">${escapeHtml(description)}</p>`\n : \"\";\n const headerHtml =\n title || subtitle\n ? `<div data-block-group=\"Conteúdo\" style=\"text-align: center; margin-bottom: 3rem;\">${subtitleHtml}${titleHtml}${descHtml}</div>`\n : \"\";\n\n // Form HTML\n const fieldsHtml = formFields\n .map((field: any) => {\n const labelHtml = field.label\n ? `<label style=\"display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.375rem; color: var(--sg-text);\">${escapeHtml(field.label)}${field.required ? '<span style=\"color: #ef4444;\"> *</span>' : \"\"}</label>`\n : \"\";\n const inputStyle = `width: 100%; padding: 0.625rem 0.75rem; border: 1px solid var(--sg-border); border-radius: var(--sg-button-radius, 0.5rem); font-size: 0.875rem; background-color: var(--sg-bg); color: var(--sg-text); box-sizing: border-box;`;\n const inputHtml =\n field.type === \"textarea\"\n ? `<textarea name=\"${escapeHtml(field.name)}\" placeholder=\"${escapeHtml(field.placeholder || \"\")}\" rows=\"4\" style=\"${inputStyle} resize: vertical;\"${field.required ? \" required\" : \"\"}></textarea>`\n : `<input type=\"${escapeHtml(field.type || \"text\")}\" name=\"${escapeHtml(field.name)}\" placeholder=\"${escapeHtml(field.placeholder || \"\")}\" style=\"${inputStyle}\"${field.required ? \" required\" : \"\"} />`;\n return `<div style=\"margin-bottom: 1rem;\">${labelHtml}${inputHtml}</div>`;\n })\n .join(\"\");\n\n const submitBtnStyle = `width: 100%; padding: 0.75rem 1.5rem; background-color: var(--sg-primary); color: var(--sg-primary-text); border: none; border-radius: var(--sg-button-radius, 0.5rem); font-weight: 500; cursor: pointer; font-size: 1rem; ${BTN_HOVER_BASE}`;\n\n const formHtml = `<div data-block-group=\"Formulário\" style=\"background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); padding: 2rem; box-shadow: var(--sg-card-shadow);\">${formTitle ? `<h3 style=\"font-size: 1.25rem; font-weight: 600; margin-bottom: 1.5rem;\">${escapeHtml(formTitle)}</h3>` : \"\"}<form>${fieldsHtml}<button type=\"submit\" class=\"sg-contact__btn sg-contact__btn--primary\" style=\"${submitBtnStyle}\">${escapeHtml(submitText)}</button></form></div>`;\n\n const stylePreamble = hoverCss ? `<style>${hoverCss}</style>` : \"\";\n\n if (isFormOnly) {\n return `${stylePreamble}<section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div style=\"max-width: 600px; margin: 0 auto; padding: 0 1rem;\">${headerHtml}${formHtml}</div></section>`;\n }\n\n // Contact info cards\n const contactCardsHtml = contactInfo\n .map((info: any) => {\n const iconSvg = getContactIconSvg(info.icon || \"mail\");\n return `<div style=\"display: flex; align-items: flex-start; gap: 1rem; padding: 1.25rem; background-color: var(--sg-surface); border-radius: var(--sg-card-radius, 0.75rem); box-shadow: var(--sg-card-shadow);\"><div style=\"width: 2.5rem; height: 2.5rem; background-color: var(--sg-primary); border-radius: 0.5rem; display: flex; align-items: center; justify-content: center; color: var(--sg-primary-text, #fff); flex-shrink: 0;\">${iconSvg}</div><div><div style=\"font-weight: 600; font-size: 0.875rem; margin-bottom: 0.25rem;\">${escapeHtml(info.label)}</div><div style=\"color: var(--sg-muted-text); font-size: 0.875rem;\">${escapeHtml(info.value)}</div></div></div>`;\n })\n .join(\"\");\n\n const scopeId = generateScopedId(block.id || \"\", \"contact\");\n\n if (isStacked) {\n return `${stylePreamble}<section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div style=\"max-width: 1200px; margin: 0 auto; padding: 0 1rem;\">${headerHtml}${contactInfo.length > 0 ? `<div data-block-group=\"Info\" style=\"display: flex; flex-direction: column; gap: 1rem; margin-bottom: 3rem;\">${contactCardsHtml}</div>` : \"\"}${formHtml}</div></section>`;\n }\n\n // split layout\n return `${stylePreamble}<style>\n #${scopeId} { flex-direction: column; }\n @media (min-width: 768px) { #${scopeId} { flex-direction: row; } }\n</style><section ${blockIdAttr(block.id)} ${dataBlockIdAttr(block.id)} style=\"padding: 4rem 0; ${bgStyle}\"><div style=\"max-width: 1200px; margin: 0 auto; padding: 0 1rem;\">${headerHtml}<div id=\"${scopeId}\" style=\"display: flex; gap: 3rem;\">${contactInfo.length > 0 ? `<div data-block-group=\"Info\" style=\"flex: 1 1 40%; display: flex; flex-direction: column; gap: 1rem;\">${contactCardsHtml}</div>` : \"\"}<div style=\"flex: 1 1 60%;\">${formHtml}</div></div></div></section>`;\n}\n"],"names":["generateAdminButtonHoverCSS","scope","classPrefix","props","theme","buttonHoverEffect","buttonHoverIntensity","buttonHoverOverlay","buttonHoverIconName","primaryColor","primaryText","css","primaryResult","generateButtonHoverStyles","outlineResult","getButtonHoverKeyframes","generateButtonOverlayCSS","BTN_HOVER_BASE","exportProductShowcase","block","_depth","_basePath","title","subtitle","products","variant","bg","bgStyle","escapeHtml","hoverCss","subtitleHtml","titleHtml","headerHtml","stylePreamble","gridId","generateScopedId","responsiveConfig","resolveResponsiveColumns","inlineStyles","mediaQueries","generateResponsiveGridStyles","cardsHtml","p","imgHtml","badgeHtml","iconHtml","btnHtml","blockIdAttr","dataBlockIdAttr","scopeId","productsHtml","index","isReversed","featuresHtml","f","primaryBtnHtml","secondaryBtnHtml","buttonsHtml","itemId","exportAboutSection","description","secondaryDescription","image","achievements","primaryButton","stats","isCentered","descHtml","secondaryDescHtml","achievementsHtml","a","buttonHtml","statsHtml","s","CONTACT_ICON_SVG","getContactIconSvg","icon","exportContactSection","contactInfo","formTitle","formFields","submitText","isFormOnly","isStacked","fieldsHtml","field","labelHtml","inputStyle","inputHtml","submitBtnStyle","formHtml","contactCardsHtml","info"],"mappings":"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"}