@easybits.cloud/html-tailwind-generator 0.2.90 → 0.2.92

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.
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { S as Section3, I as IframeMessage } from './types-BIpbpCJr.js';
2
+ import { S as Section3, I as IframeMessage } from './types-BFNim4MH.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import { C as CustomColors, a as LandingTheme } from './themes-CWFZ6GB-.js';
5
5
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LANDING_THEMES,
3
3
  buildPreviewHtml
4
- } from "./chunk-DL5PA47F.js";
4
+ } from "./chunk-HHEQOFNP.js";
5
5
 
6
6
  // src/components/Canvas.tsx
7
7
  import { useRef, useEffect, useCallback, useState, forwardRef, useImperativeHandle } from "react";
@@ -124,7 +124,7 @@ var Canvas = forwardRef(function Canvas2({ sections, theme, onMessage, iframeRec
124
124
  sessionStorage.setItem("landing-v3-iframe-scrollY", String(data.y));
125
125
  return;
126
126
  }
127
- if (["element-selected", "text-edited", "element-deselected", "section-html-updated", "undo", "redo"].includes(
127
+ if (["element-selected", "element-contextmenu", "text-edited", "element-deselected", "section-html-updated", "undo", "redo"].includes(
128
128
  data.type
129
129
  )) {
130
130
  if (data.type === "section-html-updated" && data.sectionId && data.sectionHtml) {
@@ -358,6 +358,24 @@ var STYLE_PRESETS = [
358
358
  { label: "Glass", icon: "\u25C7", instruction: "Redisena esta seccion con glassmorphism: fondos translucidos con backdrop-blur, bordes sutiles blancos, sombras suaves. Usa un fondo oscuro o con gradiente detras. Manten el mismo contenido." },
359
359
  { label: "Dark", icon: "\u25CF", instruction: "Redisena esta seccion con fondo oscuro (#111 o similar), texto claro, acentos de color vibrantes. Manten el mismo contenido." }
360
360
  ];
361
+ var PaletteIcon = () => /* @__PURE__ */ jsxs3("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
362
+ /* @__PURE__ */ jsx3("circle", { cx: "13.5", cy: "6.5", r: "0.5", fill: "currentColor", stroke: "none" }),
363
+ /* @__PURE__ */ jsx3("circle", { cx: "17.5", cy: "10.5", r: "0.5", fill: "currentColor", stroke: "none" }),
364
+ /* @__PURE__ */ jsx3("circle", { cx: "8.5", cy: "7.5", r: "0.5", fill: "currentColor", stroke: "none" }),
365
+ /* @__PURE__ */ jsx3("circle", { cx: "6.5", cy: "12", r: "0.5", fill: "currentColor", stroke: "none" }),
366
+ /* @__PURE__ */ jsx3("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 011.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z" })
367
+ ] });
368
+ var RulerIcon = () => /* @__PURE__ */ jsxs3("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
369
+ /* @__PURE__ */ jsx3("path", { d: "M21.3 15.3a2.4 2.4 0 010 3.4l-2.6 2.6a2.4 2.4 0 01-3.4 0L2.7 8.7a2.4 2.4 0 010-3.4l2.6-2.6a2.4 2.4 0 013.4 0z" }),
370
+ /* @__PURE__ */ jsx3("path", { d: "M14.5 12.5l2-2" }),
371
+ /* @__PURE__ */ jsx3("path", { d: "M11.5 9.5l2-2" }),
372
+ /* @__PURE__ */ jsx3("path", { d: "M8.5 6.5l2-2" }),
373
+ /* @__PURE__ */ jsx3("path", { d: "M17.5 15.5l2-2" })
374
+ ] });
375
+ var LinkIcon = () => /* @__PURE__ */ jsxs3("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
376
+ /* @__PURE__ */ jsx3("path", { d: "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" }),
377
+ /* @__PURE__ */ jsx3("path", { d: "M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" })
378
+ ] });
361
379
  function FloatingToolbar({
362
380
  selection,
363
381
  iframeRect,
@@ -383,6 +401,7 @@ function FloatingToolbar({
383
401
  const fileInputRef = useRef3(null);
384
402
  const toolbarRef = useRef3(null);
385
403
  const [showTagPicker, setShowTagPicker] = useState3(false);
404
+ const [activeTab, setActiveTab] = useState3(null);
386
405
  const [imgSrc, setImgSrc] = useState3("");
387
406
  const [imgAlt, setImgAlt] = useState3("");
388
407
  const [linkHref, setLinkHref] = useState3("");
@@ -392,7 +411,8 @@ function FloatingToolbar({
392
411
  setRefImage(null);
393
412
  setRefImageName(null);
394
413
  setShowTagPicker(false);
395
- }, [selection?.sectionId]);
414
+ setActiveTab(null);
415
+ }, [selection?.sectionId, selection?.elementPath]);
396
416
  useEffect2(() => {
397
417
  if (selection?.attrs) {
398
418
  setImgSrc(selection.attrs.src || "");
@@ -594,11 +614,205 @@ function FloatingToolbar({
594
614
  }
595
615
  return null;
596
616
  })();
617
+ const hasStyleTab = true;
618
+ const hasSizeTab = sizePresets && !selection.isSectionRoot;
619
+ const hasAttrsTab = hasAttrEditing;
620
+ function toggleTab(tab) {
621
+ setActiveTab((prev) => prev === tab ? null : tab);
622
+ }
623
+ function renderColorPanel() {
624
+ if (selection.isSectionRoot) {
625
+ if (hideStylePresets) return null;
626
+ return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-1 pb-0.5", children: [
627
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider mr-1 shrink-0", children: "Estilo" }),
628
+ STYLE_PRESETS.map((preset) => /* @__PURE__ */ jsxs3(
629
+ "button",
630
+ {
631
+ onClick: () => onRefine(preset.instruction),
632
+ disabled: isRefining,
633
+ className: "px-2 py-0.5 text-[11px] font-medium rounded-md bg-gray-800 hover:bg-gray-700 disabled:opacity-30 transition-colors whitespace-nowrap",
634
+ title: preset.label,
635
+ children: [
636
+ /* @__PURE__ */ jsx3("span", { className: "mr-1", children: preset.icon }),
637
+ preset.label
638
+ ]
639
+ },
640
+ preset.label
641
+ ))
642
+ ] });
643
+ }
644
+ if (!onUpdateAttribute || selection.tagName === "IMG") return null;
645
+ const containerTags = ["DIV", "SECTION", "HEADER", "FOOTER", "NAV", "ASIDE", "MAIN", "ARTICLE"];
646
+ const isContainer = containerTags.includes(selection.tagName ?? "");
647
+ const TEXT_COLOR_PREFIXES = ["text-primary", "text-secondary", "text-accent", "text-on-surface", "text-on-primary", "text-on-surface-muted", "text-white", "text-black"];
648
+ const BG_COLOR_PREFIXES = ["bg-primary", "bg-primary-dark", "bg-secondary", "bg-accent", "bg-surface", "bg-surface-alt"];
649
+ const themeSwatches = themeColors ? [
650
+ { color: themeColors.primary, textCls: "text-primary", bgCls: "bg-primary", label: "Primary" },
651
+ { color: themeColors.secondary, textCls: "text-secondary", bgCls: "bg-secondary", label: "Secondary" },
652
+ { color: themeColors.accent, textCls: "text-accent", bgCls: "bg-accent", label: "Accent" },
653
+ { color: themeColors.surface, textCls: "text-on-surface", bgCls: "bg-surface", label: "Surface" }
654
+ ] : [];
655
+ const fixedSwatches = [
656
+ { color: "#ffffff", css: "#ffffff", label: "Blanco" },
657
+ { color: "#000000", css: "#000000", label: "Negro" },
658
+ { color: "transparent", css: "transparent", label: "Transparente" }
659
+ ];
660
+ const renderColorRow = (label, mode) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-0.5 pb-0.5", children: [
661
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider mr-1 shrink-0 w-10", children: label }),
662
+ fixedSwatches.map(({ color, css, label: swatchLabel }) => /* @__PURE__ */ jsx3(
663
+ "button",
664
+ {
665
+ onClick: () => {
666
+ handleReplaceClass(mode === "text" ? TEXT_COLOR_PREFIXES : BG_COLOR_PREFIXES, "");
667
+ const cssProp = mode === "text" ? "color" : "background-color";
668
+ handleSetAttr("style", `${cssProp}: ${css}`);
669
+ },
670
+ className: "w-5 h-5 rounded-full border border-gray-600 hover:scale-125 transition-transform shrink-0",
671
+ style: color === "transparent" ? {
672
+ backgroundImage: "repeating-conic-gradient(#808080 0% 25%, #c0c0c0 0% 50%)",
673
+ backgroundSize: "8px 8px"
674
+ } : { backgroundColor: color },
675
+ title: swatchLabel
676
+ },
677
+ swatchLabel
678
+ )),
679
+ themeSwatches.map(({ color, textCls, bgCls, label: swatchLabel }) => /* @__PURE__ */ jsx3(
680
+ "button",
681
+ {
682
+ onClick: () => {
683
+ const prefixes = mode === "text" ? TEXT_COLOR_PREFIXES : BG_COLOR_PREFIXES;
684
+ const cls = mode === "text" ? textCls : bgCls;
685
+ handleReplaceClass(prefixes, cls);
686
+ },
687
+ className: "w-5 h-5 rounded-full border border-gray-600 hover:scale-125 transition-transform shrink-0",
688
+ style: { backgroundColor: color },
689
+ title: swatchLabel
690
+ },
691
+ swatchLabel
692
+ )),
693
+ /* @__PURE__ */ jsx3(
694
+ "input",
695
+ {
696
+ type: "color",
697
+ onChange: (e) => {
698
+ handleReplaceClass(mode === "text" ? TEXT_COLOR_PREFIXES : BG_COLOR_PREFIXES, "");
699
+ const cssProp = mode === "text" ? "color" : "background-color";
700
+ handleSetAttr("style", `${cssProp}: ${e.target.value}`);
701
+ },
702
+ className: "w-5 h-5 rounded-full border border-gray-600 cursor-pointer shrink-0 p-0 bg-transparent [&::-webkit-color-swatch-wrapper]:p-0 [&::-webkit-color-swatch]:rounded-full [&::-webkit-color-swatch]:border-0",
703
+ title: "Color personalizado"
704
+ }
705
+ )
706
+ ] }, mode);
707
+ return /* @__PURE__ */ jsxs3("div", { className: "pt-1 pb-0.5", children: [
708
+ renderColorRow("Color", "text"),
709
+ isContainer && renderColorRow("Fondo", "bg")
710
+ ] });
711
+ }
712
+ function renderSizePanel() {
713
+ if (!sizePresets || selection.isSectionRoot) return null;
714
+ const groups = Object.entries(sizePresets).filter(([k]) => k !== "currentClasses");
715
+ const labels = { width: "Ancho", maxW: "Max", padding: "Padding", margin: "Margin", textSize: "Texto", fontWeight: "Peso", imgSize: "Tama\xF1o", rounded: "Borde" };
716
+ return /* @__PURE__ */ jsx3("div", { className: "pt-1 pb-0.5", children: groups.map(([key, options]) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-0.5 pb-0.5", children: [
717
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider mr-1 shrink-0 w-10", children: labels[key] || key }),
718
+ options.map((opt) => {
719
+ const isActive = sizePresets.currentClasses.includes(opt.cls);
720
+ return /* @__PURE__ */ jsx3(
721
+ "button",
722
+ {
723
+ onClick: () => handleReplaceClass(opt.prefixes, opt.cls),
724
+ className: `px-2 py-0.5 text-[10px] font-mono font-bold rounded-md transition-colors whitespace-nowrap ${isActive ? "bg-blue-600 text-white" : "bg-gray-800 hover:bg-gray-700 text-gray-300"}`,
725
+ children: opt.label
726
+ },
727
+ opt.cls
728
+ );
729
+ })
730
+ ] }, key)) });
731
+ }
732
+ function renderAttrsPanel() {
733
+ if (!hasAttrEditing) return null;
734
+ return /* @__PURE__ */ jsxs3("div", { className: "pt-1 pb-0.5", children: [
735
+ isImg && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
736
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
737
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider w-8 shrink-0", children: "src" }),
738
+ /* @__PURE__ */ jsx3(
739
+ "input",
740
+ {
741
+ type: "text",
742
+ value: imgSrc,
743
+ onChange: (e) => setImgSrc(e.target.value),
744
+ onKeyDown: (e) => {
745
+ if (e.key === "Enter") handleSetAttr("src", imgSrc);
746
+ },
747
+ className: "flex-1 bg-gray-800 text-xs text-white rounded px-2 py-1 outline-none min-w-0",
748
+ placeholder: "URL de imagen..."
749
+ }
750
+ ),
751
+ /* @__PURE__ */ jsx3(
752
+ "button",
753
+ {
754
+ onClick: () => handleSetAttr("src", imgSrc),
755
+ className: "px-2 py-1 text-[10px] font-bold rounded bg-blue-500 hover:bg-blue-600 transition-colors shrink-0",
756
+ children: "Set"
757
+ }
758
+ )
759
+ ] }),
760
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
761
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider w-8 shrink-0", children: "alt" }),
762
+ /* @__PURE__ */ jsx3(
763
+ "input",
764
+ {
765
+ type: "text",
766
+ value: imgAlt,
767
+ onChange: (e) => setImgAlt(e.target.value),
768
+ onKeyDown: (e) => {
769
+ if (e.key === "Enter") handleSetAttr("alt", imgAlt);
770
+ },
771
+ className: "flex-1 bg-gray-800 text-xs text-white rounded px-2 py-1 outline-none min-w-0",
772
+ placeholder: "Alt text..."
773
+ }
774
+ ),
775
+ /* @__PURE__ */ jsx3(
776
+ "button",
777
+ {
778
+ onClick: () => handleSetAttr("alt", imgAlt),
779
+ className: "px-2 py-1 text-[10px] font-bold rounded bg-blue-500 hover:bg-blue-600 transition-colors shrink-0",
780
+ children: "Set"
781
+ }
782
+ )
783
+ ] })
784
+ ] }),
785
+ isLink && /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
786
+ /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider w-8 shrink-0", children: "href" }),
787
+ /* @__PURE__ */ jsx3(
788
+ "input",
789
+ {
790
+ type: "text",
791
+ value: linkHref,
792
+ onChange: (e) => setLinkHref(e.target.value),
793
+ onKeyDown: (e) => {
794
+ if (e.key === "Enter") handleSetAttr("href", linkHref);
795
+ },
796
+ className: "flex-1 bg-gray-800 text-xs text-white rounded px-2 py-1 outline-none min-w-0",
797
+ placeholder: "URL del enlace..."
798
+ }
799
+ ),
800
+ /* @__PURE__ */ jsx3(
801
+ "button",
802
+ {
803
+ onClick: () => handleSetAttr("href", linkHref),
804
+ className: "px-2 py-1 text-[10px] font-bold rounded bg-blue-500 hover:bg-blue-600 transition-colors shrink-0",
805
+ children: "Set"
806
+ }
807
+ )
808
+ ] })
809
+ ] });
810
+ }
597
811
  return /* @__PURE__ */ jsxs3(
598
812
  "div",
599
813
  {
600
814
  ref: toolbarRef,
601
- className: "fixed z-50 flex flex-col gap-1.5 bg-gray-900 text-white rounded-xl shadow-2xl px-2 py-1.5 border border-gray-700",
815
+ className: "fixed z-50 flex flex-col bg-gray-900 text-white rounded-xl shadow-2xl px-2 py-1.5 border border-gray-700",
602
816
  style: { top: finalTop, left: clampedLeft, maxWidth: "min(600px, calc(100vw - 16px))" },
603
817
  children: [
604
818
  /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1.5", children: [
@@ -723,15 +937,6 @@ function FloatingToolbar({
723
937
  }
724
938
  )
725
939
  ] }),
726
- /* @__PURE__ */ jsx3(
727
- "button",
728
- {
729
- onClick: onViewCode,
730
- className: "w-7 h-7 flex items-center justify-center rounded-lg hover:bg-gray-800 transition-colors text-xs font-mono text-gray-400 hover:text-white",
731
- title: "Ver codigo",
732
- children: "</>"
733
- }
734
- ),
735
940
  selection.isSectionRoot ? /* @__PURE__ */ jsxs3(Fragment, { children: [
736
941
  /* @__PURE__ */ jsx3("div", { className: "w-px h-5 bg-gray-700" }),
737
942
  /* @__PURE__ */ jsx3(
@@ -791,201 +996,56 @@ function FloatingToolbar({
791
996
  }
792
997
  )
793
998
  ] }),
794
- selection.isSectionRoot && !hideStylePresets && /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-0.5 pb-0.5 border-t border-gray-700/50", children: [
795
- /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider mr-1 shrink-0", children: "Estilo" }),
796
- STYLE_PRESETS.map((preset) => /* @__PURE__ */ jsxs3(
999
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-1 border-t border-gray-700/50", children: [
1000
+ hasStyleTab && /* @__PURE__ */ jsxs3(
797
1001
  "button",
798
1002
  {
799
- onClick: () => onRefine(preset.instruction),
800
- disabled: isRefining,
801
- className: "px-2 py-0.5 text-[11px] font-medium rounded-md bg-gray-800 hover:bg-gray-700 disabled:opacity-30 transition-colors whitespace-nowrap",
802
- title: preset.label,
1003
+ onClick: () => toggleTab("style"),
1004
+ className: `flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium transition-colors ${activeTab === "style" ? "bg-blue-600 text-white" : "bg-gray-800 hover:bg-gray-700 text-gray-400"}`,
1005
+ title: "Estilo",
803
1006
  children: [
804
- /* @__PURE__ */ jsx3("span", { className: "mr-1", children: preset.icon }),
805
- preset.label
1007
+ /* @__PURE__ */ jsx3(PaletteIcon, {}),
1008
+ /* @__PURE__ */ jsx3("span", { children: "Estilo" })
806
1009
  ]
807
- },
808
- preset.label
809
- ))
810
- ] }),
811
- !selection.isSectionRoot && onUpdateAttribute && selection.tagName !== "IMG" && (() => {
812
- const containerTags = ["DIV", "SECTION", "HEADER", "FOOTER", "NAV", "ASIDE", "MAIN", "ARTICLE"];
813
- const isContainer = containerTags.includes(selection.tagName ?? "");
814
- const TEXT_COLOR_PREFIXES = ["text-primary", "text-secondary", "text-accent", "text-on-surface", "text-on-primary", "text-on-surface-muted", "text-white", "text-black"];
815
- const BG_COLOR_PREFIXES = ["bg-primary", "bg-primary-dark", "bg-secondary", "bg-accent", "bg-surface", "bg-surface-alt"];
816
- const themeSwatches = themeColors ? [
817
- { color: themeColors.primary, textCls: "text-primary", bgCls: "bg-primary", label: "Primary" },
818
- { color: themeColors.secondary, textCls: "text-secondary", bgCls: "bg-secondary", label: "Secondary" },
819
- { color: themeColors.accent, textCls: "text-accent", bgCls: "bg-accent", label: "Accent" },
820
- { color: themeColors.surface, textCls: "text-on-surface", bgCls: "bg-surface", label: "Surface" }
821
- ] : [];
822
- const fixedSwatches = [
823
- { color: "#ffffff", css: "#ffffff", label: "Blanco" },
824
- { color: "#000000", css: "#000000", label: "Negro" },
825
- { color: "transparent", css: "transparent", label: "Transparente" }
826
- ];
827
- const renderColorRow = (label, mode) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-0.5 pb-0.5 border-t border-gray-700/50", children: [
828
- /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider mr-1 shrink-0 w-10", children: label }),
829
- fixedSwatches.map(({ color, css, label: swatchLabel }) => /* @__PURE__ */ jsx3(
830
- "button",
831
- {
832
- onClick: () => {
833
- handleReplaceClass(mode === "text" ? TEXT_COLOR_PREFIXES : BG_COLOR_PREFIXES, "");
834
- const cssProp = mode === "text" ? "color" : "background-color";
835
- handleSetAttr("style", `${cssProp}: ${css}`);
836
- },
837
- className: "w-5 h-5 rounded-full border border-gray-600 hover:scale-125 transition-transform shrink-0",
838
- style: color === "transparent" ? {
839
- backgroundImage: "repeating-conic-gradient(#808080 0% 25%, #c0c0c0 0% 50%)",
840
- backgroundSize: "8px 8px"
841
- } : { backgroundColor: color },
842
- title: swatchLabel
843
- },
844
- swatchLabel
845
- )),
846
- themeSwatches.map(({ color, textCls, bgCls, label: swatchLabel }) => /* @__PURE__ */ jsx3(
847
- "button",
848
- {
849
- onClick: () => {
850
- const prefixes = mode === "text" ? TEXT_COLOR_PREFIXES : BG_COLOR_PREFIXES;
851
- const cls = mode === "text" ? textCls : bgCls;
852
- handleReplaceClass(prefixes, cls);
853
- },
854
- className: "w-5 h-5 rounded-full border border-gray-600 hover:scale-125 transition-transform shrink-0",
855
- style: { backgroundColor: color },
856
- title: swatchLabel
857
- },
858
- swatchLabel
859
- )),
860
- /* @__PURE__ */ jsx3(
861
- "input",
862
- {
863
- type: "color",
864
- onChange: (e) => {
865
- handleReplaceClass(mode === "text" ? TEXT_COLOR_PREFIXES : BG_COLOR_PREFIXES, "");
866
- const cssProp = mode === "text" ? "color" : "background-color";
867
- handleSetAttr("style", `${cssProp}: ${e.target.value}`);
868
- },
869
- className: "w-5 h-5 rounded-full border border-gray-600 cursor-pointer shrink-0 p-0 bg-transparent [&::-webkit-color-swatch-wrapper]:p-0 [&::-webkit-color-swatch]:rounded-full [&::-webkit-color-swatch]:border-0",
870
- title: "Color personalizado"
871
- }
872
- )
873
- ] }, mode);
874
- return isContainer ? /* @__PURE__ */ jsxs3(Fragment, { children: [
875
- renderColorRow("Color", "text"),
876
- renderColorRow("Fondo", "bg")
877
- ] }) : renderColorRow("Color", "text");
878
- })(),
879
- sizePresets && !selection.isSectionRoot && (() => {
880
- const groups = Object.entries(sizePresets).filter(([k]) => k !== "currentClasses");
881
- const labels = { width: "Ancho", maxW: "Max", padding: "Padding", margin: "Margin", textSize: "Texto", fontWeight: "Peso", imgSize: "Tama\xF1o", rounded: "Borde" };
882
- return groups.map(([key, options]) => /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-0.5 pb-0.5 border-t border-gray-700/50", children: [
883
- /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider mr-1 shrink-0 w-10", children: labels[key] || key }),
884
- options.map((opt) => {
885
- const isActive = sizePresets.currentClasses.includes(opt.cls);
886
- return /* @__PURE__ */ jsx3(
887
- "button",
888
- {
889
- onClick: () => handleReplaceClass(opt.prefixes, opt.cls),
890
- className: `px-2 py-0.5 text-[10px] font-mono font-bold rounded-md transition-colors whitespace-nowrap ${isActive ? "bg-blue-600 text-white" : "bg-gray-800 hover:bg-gray-700 text-gray-300"}`,
891
- children: opt.label
892
- },
893
- opt.cls
894
- );
895
- }),
896
- /* @__PURE__ */ jsx3(
897
- "input",
898
- {
899
- type: "text",
900
- placeholder: "clase...",
901
- className: "w-16 bg-gray-800 text-[10px] font-mono text-white rounded-md px-1.5 py-0.5 outline-none placeholder:text-gray-600 ml-1",
902
- onKeyDown: (e) => {
903
- if (e.key === "Enter") {
904
- const val = e.target.value.trim();
905
- if (val) {
906
- handleReplaceClass(options[0].prefixes, val);
907
- e.target.value = "";
908
- }
909
- }
910
- }
911
- }
912
- )
913
- ] }, key));
914
- })(),
915
- isImg && hasAttrEditing && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1 pt-0.5 pb-0.5 border-t border-gray-700/50", children: [
916
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
917
- /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider w-8 shrink-0", children: "src" }),
918
- /* @__PURE__ */ jsx3(
919
- "input",
920
- {
921
- type: "text",
922
- value: imgSrc,
923
- onChange: (e) => setImgSrc(e.target.value),
924
- onKeyDown: (e) => {
925
- if (e.key === "Enter") handleSetAttr("src", imgSrc);
926
- },
927
- className: "flex-1 bg-gray-800 text-xs text-white rounded px-2 py-1 outline-none min-w-0",
928
- placeholder: "URL de imagen..."
929
- }
930
- ),
931
- /* @__PURE__ */ jsx3(
932
- "button",
933
- {
934
- onClick: () => handleSetAttr("src", imgSrc),
935
- className: "px-2 py-1 text-[10px] font-bold rounded bg-blue-500 hover:bg-blue-600 transition-colors shrink-0",
936
- children: "Set"
937
- }
938
- )
939
- ] }),
940
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
941
- /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider w-8 shrink-0", children: "alt" }),
942
- /* @__PURE__ */ jsx3(
943
- "input",
944
- {
945
- type: "text",
946
- value: imgAlt,
947
- onChange: (e) => setImgAlt(e.target.value),
948
- onKeyDown: (e) => {
949
- if (e.key === "Enter") handleSetAttr("alt", imgAlt);
950
- },
951
- className: "flex-1 bg-gray-800 text-xs text-white rounded px-2 py-1 outline-none min-w-0",
952
- placeholder: "Alt text..."
953
- }
954
- ),
955
- /* @__PURE__ */ jsx3(
956
- "button",
957
- {
958
- onClick: () => handleSetAttr("alt", imgAlt),
959
- className: "px-2 py-1 text-[10px] font-bold rounded bg-blue-500 hover:bg-blue-600 transition-colors shrink-0",
960
- children: "Set"
961
- }
962
- )
963
- ] })
964
- ] }),
965
- isLink && hasAttrEditing && /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1 pt-0.5 pb-0.5 border-t border-gray-700/50", children: [
966
- /* @__PURE__ */ jsx3("span", { className: "text-[10px] text-gray-500 uppercase tracking-wider w-8 shrink-0", children: "href" }),
967
- /* @__PURE__ */ jsx3(
968
- "input",
1010
+ }
1011
+ ),
1012
+ hasSizeTab && /* @__PURE__ */ jsxs3(
1013
+ "button",
969
1014
  {
970
- type: "text",
971
- value: linkHref,
972
- onChange: (e) => setLinkHref(e.target.value),
973
- onKeyDown: (e) => {
974
- if (e.key === "Enter") handleSetAttr("href", linkHref);
975
- },
976
- className: "flex-1 bg-gray-800 text-xs text-white rounded px-2 py-1 outline-none min-w-0",
977
- placeholder: "URL del enlace..."
1015
+ onClick: () => toggleTab("size"),
1016
+ className: `flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium transition-colors ${activeTab === "size" ? "bg-blue-600 text-white" : "bg-gray-800 hover:bg-gray-700 text-gray-400"}`,
1017
+ title: "Tama\xF1o",
1018
+ children: [
1019
+ /* @__PURE__ */ jsx3(RulerIcon, {}),
1020
+ /* @__PURE__ */ jsx3("span", { children: "Tama\xF1o" })
1021
+ ]
1022
+ }
1023
+ ),
1024
+ hasAttrsTab && /* @__PURE__ */ jsxs3(
1025
+ "button",
1026
+ {
1027
+ onClick: () => toggleTab("attrs"),
1028
+ className: `flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium transition-colors ${activeTab === "attrs" ? "bg-blue-600 text-white" : "bg-gray-800 hover:bg-gray-700 text-gray-400"}`,
1029
+ title: "Atributos",
1030
+ children: [
1031
+ /* @__PURE__ */ jsx3(LinkIcon, {}),
1032
+ /* @__PURE__ */ jsx3("span", { children: "Attrs" })
1033
+ ]
978
1034
  }
979
1035
  ),
980
1036
  /* @__PURE__ */ jsx3(
981
1037
  "button",
982
1038
  {
983
- onClick: () => handleSetAttr("href", linkHref),
984
- className: "px-2 py-1 text-[10px] font-bold rounded bg-blue-500 hover:bg-blue-600 transition-colors shrink-0",
985
- children: "Set"
1039
+ onClick: onViewCode,
1040
+ className: "flex items-center gap-1 px-2 py-1 rounded-md text-[10px] font-medium bg-gray-800 hover:bg-gray-700 text-gray-400 transition-colors font-mono",
1041
+ title: "Ver c\xF3digo",
1042
+ children: "</>"
986
1043
  }
987
1044
  )
988
- ] })
1045
+ ] }),
1046
+ activeTab === "style" && renderColorPanel(),
1047
+ activeTab === "size" && renderSizePanel(),
1048
+ activeTab === "attrs" && renderAttrsPanel()
989
1049
  ]
990
1050
  }
991
1051
  );
@@ -1309,4 +1369,4 @@ export {
1309
1369
  ViewportToggle,
1310
1370
  useUndoStack
1311
1371
  };
1312
- //# sourceMappingURL=chunk-G4FYV7OF.js.map
1372
+ //# sourceMappingURL=chunk-AHGQBRAE.js.map