@crediblemark/build 0.25.15 → 0.25.17

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.
@@ -133,6 +133,12 @@ var HtmlModeRender = ({
133
133
  }) => {
134
134
  const id = useId().replace(/:/g, "");
135
135
  const [iframeHeight, setIframeHeight] = useState("100vh");
136
+ const [tailwindUrl, setTailwindUrl] = useState("https://cdn.tailwindcss.com");
137
+ useEffect(() => {
138
+ if (typeof window !== "undefined") {
139
+ setTailwindUrl(`${window.location.origin}/tailwind.js`);
140
+ }
141
+ }, []);
136
142
  useEffect(() => {
137
143
  const handleMessage = (event) => {
138
144
  if (event.data && event.data.type === "resize-iframe" && event.data.id === id) {
@@ -163,31 +169,43 @@ var HtmlModeRender = ({
163
169
  }
164
170
  </script>
165
171
  `;
166
- const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
172
+ const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwind.js") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
167
173
  htmlCode
168
174
  );
169
175
  const isStandalone = htmlCode.includes("<html") || htmlCode.includes("<!DOCTYPE") || htmlCode.includes("<body") || htmlCode.includes("<head>");
176
+ const scrollbarHideStyle = `
177
+ <style>
178
+ html, body {
179
+ overflow: hidden !important;
180
+ -ms-overflow-style: none !important;
181
+ scrollbar-width: none !important;
182
+ }
183
+ ::-webkit-scrollbar {
184
+ display: none !important;
185
+ }
186
+ </style>
187
+ `;
170
188
  let srcDoc = "";
171
189
  if (isStandalone) {
172
190
  let processed = htmlCode;
173
191
  if (processed.includes("</body>")) {
174
- processed = processed.replace("</body>", `${resizeScript}</body>`);
192
+ processed = processed.replace("</body>", `${resizeScript}${scrollbarHideStyle}</body>`);
175
193
  } else {
176
- processed = processed + resizeScript;
194
+ processed = processed + resizeScript + scrollbarHideStyle;
177
195
  }
178
- if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwindcss")) {
196
+ if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwind.js") && !processed.includes("tailwindcss")) {
179
197
  if (processed.includes("</head>")) {
180
198
  processed = processed.replace(
181
199
  "</head>",
182
- `<script src="https://cdn.tailwindcss.com"></script></head>`
200
+ `<script src="${tailwindUrl}"></script></head>`
183
201
  );
184
202
  } else if (processed.includes("<head>")) {
185
203
  processed = processed.replace(
186
204
  "<head>",
187
- `<head><script src="https://cdn.tailwindcss.com"></script>`
205
+ `<head><script src="${tailwindUrl}"></script>`
188
206
  );
189
207
  } else {
190
- processed = `<script src="https://cdn.tailwindcss.com"></script>` + processed;
208
+ processed = `<script src="${tailwindUrl}"></script>` + processed;
191
209
  }
192
210
  }
193
211
  srcDoc = processed;
@@ -196,13 +214,19 @@ var HtmlModeRender = ({
196
214
  <!DOCTYPE html>
197
215
  <html>
198
216
  <head>
199
- ${needsTailwind ? `<script src="https://cdn.tailwindcss.com"></script>` : ""}
217
+ ${needsTailwind ? `<script src="${tailwindUrl}"></script>` : ""}
200
218
  <style>
201
219
  *, *::before, *::after { box-sizing: border-box; }
202
- body {
220
+ html, body {
203
221
  margin: 0;
204
222
  padding: 0;
205
223
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
224
+ overflow: hidden !important;
225
+ -ms-overflow-style: none !important;
226
+ scrollbar-width: none !important;
227
+ }
228
+ ::-webkit-scrollbar {
229
+ display: none !important;
206
230
  }
207
231
  img, iframe, video {
208
232
  max-width: 100%;
@@ -220,6 +244,7 @@ var HtmlModeRender = ({
220
244
  "iframe",
221
245
  {
222
246
  srcDoc,
247
+ scrolling: "no",
223
248
  sandbox: "allow-scripts allow-same-origin allow-popups allow-forms",
224
249
  title: "Html Mode Sandboxed Canvas",
225
250
  loading: "lazy",
@@ -1415,11 +1440,12 @@ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-ru
1415
1440
  var getClassName9 = get_class_name_factory_default("CodePanel", styles_module_default9);
1416
1441
  var CodePanel = () => {
1417
1442
  const [copied, setCopied] = useState5(false);
1443
+ const [promptType, setPromptType] = useState5("with-header");
1418
1444
  const dispatch = useAppStore((s) => s.dispatch);
1419
1445
  const root = useAppStore((s) => s.state.data.root);
1420
1446
  const rootProps = root?.props || root;
1421
1447
  const currentMode = rootProps?.mode || "blocks";
1422
- const aiPrompt = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
1448
+ const aiPromptWithHeader = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
1423
1449
 
1424
1450
  Ketentuan penulisan kode:
1425
1451
  1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
@@ -1427,8 +1453,18 @@ Ketentuan penulisan kode:
1427
1453
  3. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
1428
1454
  4. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
1429
1455
  5. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
1456
+ const aiPromptNoHeader = `Buatkan desain landing page lengkap dan premium TANPA bagian Header/Navigation dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer (tanpa memuat menu navigasi atau header di bagian atas).
1457
+
1458
+ Ketentuan penulisan kode:
1459
+ 1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
1460
+ 2. TANPA HEADER: Pastikan sama sekali tidak ada bagian Header/Navbar/Navigation menu di bagian atas halaman. Desain harus langsung dimulai dengan Hero Section yang menarik dan berdampak tinggi.
1461
+ 3. MOBILE-FIRST & RESPONSIF: Desain harus sepenuhnya responsif. Mulai dari layout ponsel (default), lalu gunakan breakpoint (sm:, md:, lg:, xl:) secara terstruktur untuk layar yang lebih besar.
1462
+ 4. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
1463
+ 5. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
1464
+ 6. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
1430
1465
  const handleCopyPrompt = () => {
1431
- navigator.clipboard.writeText(aiPrompt);
1466
+ const selectedPrompt = promptType === "with-header" ? aiPromptWithHeader : aiPromptNoHeader;
1467
+ navigator.clipboard.writeText(selectedPrompt);
1432
1468
  setCopied(true);
1433
1469
  setTimeout(() => setCopied(false), 2e3);
1434
1470
  };
@@ -1533,7 +1569,37 @@ Ketentuan penulisan kode:
1533
1569
  }
1534
1570
  )
1535
1571
  ] }),
1536
- /* @__PURE__ */ jsx13("div", { className: getClassName9("promptText"), children: aiPrompt })
1572
+ /* @__PURE__ */ jsx13("div", { className: getClassName9("optionsSection"), style: { marginBottom: 12 }, children: /* @__PURE__ */ jsxs7("div", { className: getClassName9("radioGroup"), children: [
1573
+ /* @__PURE__ */ jsxs7("label", { className: getClassName9("radioLabel"), children: [
1574
+ /* @__PURE__ */ jsx13(
1575
+ "input",
1576
+ {
1577
+ type: "radio",
1578
+ name: "promptType",
1579
+ value: "with-header",
1580
+ checked: promptType === "with-header",
1581
+ onChange: () => setPromptType("with-header"),
1582
+ className: getClassName9("radioInput")
1583
+ }
1584
+ ),
1585
+ /* @__PURE__ */ jsx13("span", { children: "Dengan Header" })
1586
+ ] }),
1587
+ /* @__PURE__ */ jsxs7("label", { className: getClassName9("radioLabel"), children: [
1588
+ /* @__PURE__ */ jsx13(
1589
+ "input",
1590
+ {
1591
+ type: "radio",
1592
+ name: "promptType",
1593
+ value: "no-header",
1594
+ checked: promptType === "no-header",
1595
+ onChange: () => setPromptType("no-header"),
1596
+ className: getClassName9("radioInput")
1597
+ }
1598
+ ),
1599
+ /* @__PURE__ */ jsx13("span", { children: "Tanpa Header" })
1600
+ ] })
1601
+ ] }) }),
1602
+ /* @__PURE__ */ jsx13("div", { className: getClassName9("promptText"), children: promptType === "with-header" ? aiPromptWithHeader : aiPromptNoHeader })
1537
1603
  ] })
1538
1604
  ] });
1539
1605
  };
@@ -3464,11 +3530,13 @@ var HeaderInner = ({
3464
3530
  /* @__PURE__ */ jsx23("span", { className: "PublishButton", children: /* @__PURE__ */ jsx23(
3465
3531
  Button,
3466
3532
  {
3533
+ type: "button",
3467
3534
  onClick: () => {
3468
3535
  const data = appStore.getState().state.data;
3469
- onPublish && onPublish(data);
3536
+ return onPublish ? onPublish(data) : void 0;
3470
3537
  },
3471
- icon: /* @__PURE__ */ jsx23(Zap, { size: 14, fill: "currentColor" }),
3538
+ variant: "secondary",
3539
+ icon: /* @__PURE__ */ jsx23(Zap, { size: 12 }),
3472
3540
  children: "Publish"
3473
3541
  }
3474
3542
  ) })
@@ -3684,11 +3752,13 @@ var HeaderInner = ({
3684
3752
  /* @__PURE__ */ jsx23("span", { className: "PublishButton", children: /* @__PURE__ */ jsx23(
3685
3753
  Button,
3686
3754
  {
3755
+ type: "button",
3687
3756
  onClick: () => {
3688
3757
  const data = appStore.getState().state.data;
3689
- onPublish && onPublish(data);
3758
+ return onPublish ? onPublish(data) : void 0;
3690
3759
  },
3691
- icon: /* @__PURE__ */ jsx23(Zap, { size: 14, fill: "currentColor" }),
3760
+ variant: "secondary",
3761
+ icon: /* @__PURE__ */ jsx23(Zap, { size: 12 }),
3692
3762
  children: "Publish"
3693
3763
  }
3694
3764
  ) })
package/dist/index.css CHANGED
@@ -244,11 +244,8 @@
244
244
  background-color: var(--cb-gold-faint);
245
245
  }
246
246
  .CredBuild [class*=Button--primary],
247
- .CredBuild [class*=PublishButton] [class*=Button],
248
247
  .CredBuild button[class*=primary],
249
- .CredBuild button[class*=Publish],
250
- .CredBuild button[class*=Button--primary],
251
- [class*=PublishButton] button {
248
+ .CredBuild button[class*=Button--primary] {
252
249
  background: var(--cb-gold) !important;
253
250
  color: var(--cb-bg-base) !important;
254
251
  border: none !important;
@@ -266,16 +263,67 @@
266
263
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
267
264
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
268
265
  }
269
- .CredBuild [class*=PublishButton]:hover [class*=Button],
270
- [class*=PublishButton]:hover button {
271
- filter: brightness(1.1);
272
- box-shadow: 0 0 20px var(--cb-gold-glow), 0 4px 15px rgba(0, 0, 0, 0.2);
266
+ .CredBuild [class*=PublishButton] button,
267
+ .CredBuild [class*=PublishButton] a,
268
+ .CredBuild button[class*=Publish],
269
+ [class*=PublishButton] button {
270
+ background-color: var(--cb-bg-surface) !important;
271
+ color: var(--cb-gold) !important;
272
+ border: 1px solid var(--cb-gold) !important;
273
+ padding: 4px 12px;
274
+ border-radius: 5px;
275
+ font-weight: 600;
276
+ text-transform: none;
277
+ letter-spacing: -0.01em;
278
+ font-size: 13px;
279
+ display: inline-flex;
280
+ align-items: center;
281
+ gap: 8px;
282
+ min-height: 28px;
283
+ box-sizing: border-box;
284
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
285
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
286
+ }
287
+ .CredBuild [class*=PublishButton]:hover button:not(:disabled),
288
+ .CredBuild [class*=PublishButton]:hover a:not([class*=disabled]),
289
+ [class*=PublishButton]:hover button:not(:disabled) {
290
+ background-color: var(--cb-gold-faint) !important;
291
+ border-color: var(--cb-gold) !important;
292
+ color: var(--cb-gold) !important;
293
+ filter: brightness(1.05);
294
+ box-shadow: 0 0 10px var(--cb-gold-glow), 0 2px 5px rgba(0, 0, 0, 0.1);
273
295
  transform: translateY(-1px) scale(1.02);
274
296
  }
275
- .CredBuild [class*=PublishButton] [class*=Button] svg,
297
+ .CredBuild [class*=PublishButton] button svg,
298
+ .CredBuild [class*=PublishButton] a svg,
276
299
  [class*=PublishButton] button svg {
277
- color: var(--cb-bg-base);
278
- stroke: var(--cb-bg-base);
300
+ color: var(--cb-gold) !important;
301
+ stroke: var(--cb-gold) !important;
302
+ }
303
+ .CredBuild [class*=PublishButton] button:disabled,
304
+ .CredBuild [class*=PublishButton] button[disabled],
305
+ .CredBuild [class*=PublishButton] a[class*=disabled],
306
+ [class*=PublishButton] button:disabled,
307
+ [class*=PublishButton] button[disabled] {
308
+ background-color: var(--cb-bg-surface) !important;
309
+ color: var(--cb-silver-muted) !important;
310
+ border-color: var(--cb-border) !important;
311
+ opacity: 0.6 !important;
312
+ cursor: not-allowed !important;
313
+ transform: none !important;
314
+ box-shadow: none !important;
315
+ }
316
+ .CredBuild [class*=PublishButton] button:disabled svg,
317
+ .CredBuild [class*=PublishButton] button[disabled] svg,
318
+ .CredBuild [class*=PublishButton] a[class*=disabled] svg,
319
+ [class*=PublishButton] button:disabled svg,
320
+ [class*=PublishButton] button[disabled] svg {
321
+ color: var(--cb-silver-muted) !important;
322
+ stroke: var(--cb-silver-muted) !important;
323
+ }
324
+ [class*=PublishButton] {
325
+ display: inline-flex !important;
326
+ align-items: center !important;
279
327
  }
280
328
  [class*=Button--secondary] {
281
329
  background-color: var(--cb-bg-surface);
package/dist/index.js CHANGED
@@ -12244,6 +12244,12 @@ var HtmlModeRender = ({
12244
12244
  }) => {
12245
12245
  const id = (0, import_react81.useId)().replace(/:/g, "");
12246
12246
  const [iframeHeight, setIframeHeight] = (0, import_react81.useState)("100vh");
12247
+ const [tailwindUrl, setTailwindUrl] = (0, import_react81.useState)("https://cdn.tailwindcss.com");
12248
+ (0, import_react81.useEffect)(() => {
12249
+ if (typeof window !== "undefined") {
12250
+ setTailwindUrl(`${window.location.origin}/tailwind.js`);
12251
+ }
12252
+ }, []);
12247
12253
  (0, import_react81.useEffect)(() => {
12248
12254
  const handleMessage = (event) => {
12249
12255
  if (event.data && event.data.type === "resize-iframe" && event.data.id === id) {
@@ -12274,31 +12280,43 @@ var HtmlModeRender = ({
12274
12280
  }
12275
12281
  </script>
12276
12282
  `;
12277
- const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
12283
+ const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwind.js") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
12278
12284
  htmlCode
12279
12285
  );
12280
12286
  const isStandalone = htmlCode.includes("<html") || htmlCode.includes("<!DOCTYPE") || htmlCode.includes("<body") || htmlCode.includes("<head>");
12287
+ const scrollbarHideStyle = `
12288
+ <style>
12289
+ html, body {
12290
+ overflow: hidden !important;
12291
+ -ms-overflow-style: none !important;
12292
+ scrollbar-width: none !important;
12293
+ }
12294
+ ::-webkit-scrollbar {
12295
+ display: none !important;
12296
+ }
12297
+ </style>
12298
+ `;
12281
12299
  let srcDoc = "";
12282
12300
  if (isStandalone) {
12283
12301
  let processed = htmlCode;
12284
12302
  if (processed.includes("</body>")) {
12285
- processed = processed.replace("</body>", `${resizeScript}</body>`);
12303
+ processed = processed.replace("</body>", `${resizeScript}${scrollbarHideStyle}</body>`);
12286
12304
  } else {
12287
- processed = processed + resizeScript;
12305
+ processed = processed + resizeScript + scrollbarHideStyle;
12288
12306
  }
12289
- if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwindcss")) {
12307
+ if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwind.js") && !processed.includes("tailwindcss")) {
12290
12308
  if (processed.includes("</head>")) {
12291
12309
  processed = processed.replace(
12292
12310
  "</head>",
12293
- `<script src="https://cdn.tailwindcss.com"></script></head>`
12311
+ `<script src="${tailwindUrl}"></script></head>`
12294
12312
  );
12295
12313
  } else if (processed.includes("<head>")) {
12296
12314
  processed = processed.replace(
12297
12315
  "<head>",
12298
- `<head><script src="https://cdn.tailwindcss.com"></script>`
12316
+ `<head><script src="${tailwindUrl}"></script>`
12299
12317
  );
12300
12318
  } else {
12301
- processed = `<script src="https://cdn.tailwindcss.com"></script>` + processed;
12319
+ processed = `<script src="${tailwindUrl}"></script>` + processed;
12302
12320
  }
12303
12321
  }
12304
12322
  srcDoc = processed;
@@ -12307,13 +12325,19 @@ var HtmlModeRender = ({
12307
12325
  <!DOCTYPE html>
12308
12326
  <html>
12309
12327
  <head>
12310
- ${needsTailwind ? `<script src="https://cdn.tailwindcss.com"></script>` : ""}
12328
+ ${needsTailwind ? `<script src="${tailwindUrl}"></script>` : ""}
12311
12329
  <style>
12312
12330
  *, *::before, *::after { box-sizing: border-box; }
12313
- body {
12331
+ html, body {
12314
12332
  margin: 0;
12315
12333
  padding: 0;
12316
12334
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
12335
+ overflow: hidden !important;
12336
+ -ms-overflow-style: none !important;
12337
+ scrollbar-width: none !important;
12338
+ }
12339
+ ::-webkit-scrollbar {
12340
+ display: none !important;
12317
12341
  }
12318
12342
  img, iframe, video {
12319
12343
  max-width: 100%;
@@ -12331,6 +12355,7 @@ var HtmlModeRender = ({
12331
12355
  "iframe",
12332
12356
  {
12333
12357
  srcDoc,
12358
+ scrolling: "no",
12334
12359
  sandbox: "allow-scripts allow-same-origin allow-popups allow-forms",
12335
12360
  title: "Html Mode Sandboxed Canvas",
12336
12361
  loading: "lazy",
@@ -14651,11 +14676,13 @@ var HeaderInner = ({
14651
14676
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "PublishButton", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
14652
14677
  Button,
14653
14678
  {
14679
+ type: "button",
14654
14680
  onClick: () => {
14655
14681
  const data = appStore.getState().state.data;
14656
- onPublish && onPublish(data);
14682
+ return onPublish ? onPublish(data) : void 0;
14657
14683
  },
14658
- icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 14, fill: "currentColor" }),
14684
+ variant: "secondary",
14685
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 12 }),
14659
14686
  children: "Publish"
14660
14687
  }
14661
14688
  ) })
@@ -14871,11 +14898,13 @@ var HeaderInner = ({
14871
14898
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "PublishButton", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
14872
14899
  Button,
14873
14900
  {
14901
+ type: "button",
14874
14902
  onClick: () => {
14875
14903
  const data = appStore.getState().state.data;
14876
- onPublish && onPublish(data);
14904
+ return onPublish ? onPublish(data) : void 0;
14877
14905
  },
14878
- icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 14, fill: "currentColor" }),
14906
+ variant: "secondary",
14907
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 12 }),
14879
14908
  children: "Publish"
14880
14909
  }
14881
14910
  ) })
@@ -15669,11 +15698,12 @@ var import_jsx_runtime99 = require("react/jsx-runtime");
15669
15698
  var getClassName44 = get_class_name_factory_default("CodePanel", styles_module_default36);
15670
15699
  var CodePanel = () => {
15671
15700
  const [copied, setCopied] = (0, import_react101.useState)(false);
15701
+ const [promptType, setPromptType] = (0, import_react101.useState)("with-header");
15672
15702
  const dispatch = useAppStore((s) => s.dispatch);
15673
15703
  const root = useAppStore((s) => s.state.data.root);
15674
15704
  const rootProps = root?.props || root;
15675
15705
  const currentMode = rootProps?.mode || "blocks";
15676
- const aiPrompt = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
15706
+ const aiPromptWithHeader = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
15677
15707
 
15678
15708
  Ketentuan penulisan kode:
15679
15709
  1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
@@ -15681,8 +15711,18 @@ Ketentuan penulisan kode:
15681
15711
  3. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
15682
15712
  4. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
15683
15713
  5. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
15714
+ const aiPromptNoHeader = `Buatkan desain landing page lengkap dan premium TANPA bagian Header/Navigation dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer (tanpa memuat menu navigasi atau header di bagian atas).
15715
+
15716
+ Ketentuan penulisan kode:
15717
+ 1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
15718
+ 2. TANPA HEADER: Pastikan sama sekali tidak ada bagian Header/Navbar/Navigation menu di bagian atas halaman. Desain harus langsung dimulai dengan Hero Section yang menarik dan berdampak tinggi.
15719
+ 3. MOBILE-FIRST & RESPONSIF: Desain harus sepenuhnya responsif. Mulai dari layout ponsel (default), lalu gunakan breakpoint (sm:, md:, lg:, xl:) secara terstruktur untuk layar yang lebih besar.
15720
+ 4. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
15721
+ 5. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
15722
+ 6. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
15684
15723
  const handleCopyPrompt = () => {
15685
- navigator.clipboard.writeText(aiPrompt);
15724
+ const selectedPrompt = promptType === "with-header" ? aiPromptWithHeader : aiPromptNoHeader;
15725
+ navigator.clipboard.writeText(selectedPrompt);
15686
15726
  setCopied(true);
15687
15727
  setTimeout(() => setCopied(false), 2e3);
15688
15728
  };
@@ -15787,7 +15827,37 @@ Ketentuan penulisan kode:
15787
15827
  }
15788
15828
  )
15789
15829
  ] }),
15790
- /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: getClassName44("promptText"), children: aiPrompt })
15830
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: getClassName44("optionsSection"), style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: getClassName44("radioGroup"), children: [
15831
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("label", { className: getClassName44("radioLabel"), children: [
15832
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
15833
+ "input",
15834
+ {
15835
+ type: "radio",
15836
+ name: "promptType",
15837
+ value: "with-header",
15838
+ checked: promptType === "with-header",
15839
+ onChange: () => setPromptType("with-header"),
15840
+ className: getClassName44("radioInput")
15841
+ }
15842
+ ),
15843
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { children: "Dengan Header" })
15844
+ ] }),
15845
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("label", { className: getClassName44("radioLabel"), children: [
15846
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
15847
+ "input",
15848
+ {
15849
+ type: "radio",
15850
+ name: "promptType",
15851
+ value: "no-header",
15852
+ checked: promptType === "no-header",
15853
+ onChange: () => setPromptType("no-header"),
15854
+ className: getClassName44("radioInput")
15855
+ }
15856
+ ),
15857
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { children: "Tanpa Header" })
15858
+ ] })
15859
+ ] }) }),
15860
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: getClassName44("promptText"), children: promptType === "with-header" ? aiPromptWithHeader : aiPromptNoHeader })
15791
15861
  ] })
15792
15862
  ] });
15793
15863
  };
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  overrideKeys,
11
11
  useCredBuild,
12
12
  useGetCredBuild
13
- } from "./chunk-CKELXGDW.mjs";
13
+ } from "./chunk-W3JRA22A.mjs";
14
14
  import {
15
15
  ColorPickerField,
16
16
  Drawer,
@@ -12244,6 +12244,12 @@ var HtmlModeRender = ({
12244
12244
  }) => {
12245
12245
  const id = (0, import_react81.useId)().replace(/:/g, "");
12246
12246
  const [iframeHeight, setIframeHeight] = (0, import_react81.useState)("100vh");
12247
+ const [tailwindUrl, setTailwindUrl] = (0, import_react81.useState)("https://cdn.tailwindcss.com");
12248
+ (0, import_react81.useEffect)(() => {
12249
+ if (typeof window !== "undefined") {
12250
+ setTailwindUrl(`${window.location.origin}/tailwind.js`);
12251
+ }
12252
+ }, []);
12247
12253
  (0, import_react81.useEffect)(() => {
12248
12254
  const handleMessage = (event) => {
12249
12255
  if (event.data && event.data.type === "resize-iframe" && event.data.id === id) {
@@ -12274,31 +12280,43 @@ var HtmlModeRender = ({
12274
12280
  }
12275
12281
  </script>
12276
12282
  `;
12277
- const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
12283
+ const needsTailwind = htmlCode.includes("cdn.tailwindcss.com") || htmlCode.includes("tailwind.js") || htmlCode.includes("tailwindcss") || /\b(bg-|text-|p[xy]?[-0-9]|m[xy]?[-0-9]|flex|grid|border-|rounded-|shadow-|justify-|items-|gap-|relative|absolute|hidden|w-|h-|leading-|tracking-|font-|transition|duration-|ease-|hover:|focus:|sm:|md:|lg:|xl:)/.test(
12278
12284
  htmlCode
12279
12285
  );
12280
12286
  const isStandalone = htmlCode.includes("<html") || htmlCode.includes("<!DOCTYPE") || htmlCode.includes("<body") || htmlCode.includes("<head>");
12287
+ const scrollbarHideStyle = `
12288
+ <style>
12289
+ html, body {
12290
+ overflow: hidden !important;
12291
+ -ms-overflow-style: none !important;
12292
+ scrollbar-width: none !important;
12293
+ }
12294
+ ::-webkit-scrollbar {
12295
+ display: none !important;
12296
+ }
12297
+ </style>
12298
+ `;
12281
12299
  let srcDoc = "";
12282
12300
  if (isStandalone) {
12283
12301
  let processed = htmlCode;
12284
12302
  if (processed.includes("</body>")) {
12285
- processed = processed.replace("</body>", `${resizeScript}</body>`);
12303
+ processed = processed.replace("</body>", `${resizeScript}${scrollbarHideStyle}</body>`);
12286
12304
  } else {
12287
- processed = processed + resizeScript;
12305
+ processed = processed + resizeScript + scrollbarHideStyle;
12288
12306
  }
12289
- if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwindcss")) {
12307
+ if (needsTailwind && !processed.includes("cdn.tailwindcss.com") && !processed.includes("tailwind.js") && !processed.includes("tailwindcss")) {
12290
12308
  if (processed.includes("</head>")) {
12291
12309
  processed = processed.replace(
12292
12310
  "</head>",
12293
- `<script src="https://cdn.tailwindcss.com"></script></head>`
12311
+ `<script src="${tailwindUrl}"></script></head>`
12294
12312
  );
12295
12313
  } else if (processed.includes("<head>")) {
12296
12314
  processed = processed.replace(
12297
12315
  "<head>",
12298
- `<head><script src="https://cdn.tailwindcss.com"></script>`
12316
+ `<head><script src="${tailwindUrl}"></script>`
12299
12317
  );
12300
12318
  } else {
12301
- processed = `<script src="https://cdn.tailwindcss.com"></script>` + processed;
12319
+ processed = `<script src="${tailwindUrl}"></script>` + processed;
12302
12320
  }
12303
12321
  }
12304
12322
  srcDoc = processed;
@@ -12307,13 +12325,19 @@ var HtmlModeRender = ({
12307
12325
  <!DOCTYPE html>
12308
12326
  <html>
12309
12327
  <head>
12310
- ${needsTailwind ? `<script src="https://cdn.tailwindcss.com"></script>` : ""}
12328
+ ${needsTailwind ? `<script src="${tailwindUrl}"></script>` : ""}
12311
12329
  <style>
12312
12330
  *, *::before, *::after { box-sizing: border-box; }
12313
- body {
12331
+ html, body {
12314
12332
  margin: 0;
12315
12333
  padding: 0;
12316
12334
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
12335
+ overflow: hidden !important;
12336
+ -ms-overflow-style: none !important;
12337
+ scrollbar-width: none !important;
12338
+ }
12339
+ ::-webkit-scrollbar {
12340
+ display: none !important;
12317
12341
  }
12318
12342
  img, iframe, video {
12319
12343
  max-width: 100%;
@@ -12331,6 +12355,7 @@ var HtmlModeRender = ({
12331
12355
  "iframe",
12332
12356
  {
12333
12357
  srcDoc,
12358
+ scrolling: "no",
12334
12359
  sandbox: "allow-scripts allow-same-origin allow-popups allow-forms",
12335
12360
  title: "Html Mode Sandboxed Canvas",
12336
12361
  loading: "lazy",
@@ -14651,11 +14676,13 @@ var HeaderInner = ({
14651
14676
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "PublishButton", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
14652
14677
  Button,
14653
14678
  {
14679
+ type: "button",
14654
14680
  onClick: () => {
14655
14681
  const data = appStore.getState().state.data;
14656
- onPublish && onPublish(data);
14682
+ return onPublish ? onPublish(data) : void 0;
14657
14683
  },
14658
- icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 14, fill: "currentColor" }),
14684
+ variant: "secondary",
14685
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 12 }),
14659
14686
  children: "Publish"
14660
14687
  }
14661
14688
  ) })
@@ -14871,11 +14898,13 @@ var HeaderInner = ({
14871
14898
  /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "PublishButton", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
14872
14899
  Button,
14873
14900
  {
14901
+ type: "button",
14874
14902
  onClick: () => {
14875
14903
  const data = appStore.getState().state.data;
14876
- onPublish && onPublish(data);
14904
+ return onPublish ? onPublish(data) : void 0;
14877
14905
  },
14878
- icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 14, fill: "currentColor" }),
14906
+ variant: "secondary",
14907
+ icon: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Zap, { size: 12 }),
14879
14908
  children: "Publish"
14880
14909
  }
14881
14910
  ) })
@@ -15669,11 +15698,12 @@ var import_jsx_runtime99 = require("react/jsx-runtime");
15669
15698
  var getClassName44 = get_class_name_factory_default("CodePanel", styles_module_default36);
15670
15699
  var CodePanel = () => {
15671
15700
  const [copied, setCopied] = (0, import_react101.useState)(false);
15701
+ const [promptType, setPromptType] = (0, import_react101.useState)("with-header");
15672
15702
  const dispatch = useAppStore((s) => s.dispatch);
15673
15703
  const root = useAppStore((s) => s.state.data.root);
15674
15704
  const rootProps = root?.props || root;
15675
15705
  const currentMode = rootProps?.mode || "blocks";
15676
- const aiPrompt = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
15706
+ const aiPromptWithHeader = `Buatkan desain landing page lengkap dan premium dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Header/Navigation, Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer.
15677
15707
 
15678
15708
  Ketentuan penulisan kode:
15679
15709
  1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
@@ -15681,8 +15711,18 @@ Ketentuan penulisan kode:
15681
15711
  3. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
15682
15712
  4. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
15683
15713
  5. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
15714
+ const aiPromptNoHeader = `Buatkan desain landing page lengkap dan premium TANPA bagian Header/Navigation dengan pendekatan mobile-first, modern, rapi, dan compact (padat & elegan) menggunakan HTML murni dan utilitas kelas Tailwind CSS. Halaman harus memuat struktur lengkap seperti Hero Section, Features/Layanan, Testimoni, Call-to-Action (CTA), dan Footer (tanpa memuat menu navigasi atau header di bagian atas).
15715
+
15716
+ Ketentuan penulisan kode:
15717
+ 1. STRUKTUR BERSIH: Gunakan elemen semantik HTML5 seperti <section>, <header>, atau <div> sebagai wrapper utama per seksi. JANGAN sertakan tag <html>, <body>, <head>, atau <script>.
15718
+ 2. TANPA HEADER: Pastikan sama sekali tidak ada bagian Header/Navbar/Navigation menu di bagian atas halaman. Desain harus langsung dimulai dengan Hero Section yang menarik dan berdampak tinggi.
15719
+ 3. MOBILE-FIRST & RESPONSIF: Desain harus sepenuhnya responsif. Mulai dari layout ponsel (default), lalu gunakan breakpoint (sm:, md:, lg:, xl:) secara terstruktur untuk layar yang lebih besar.
15720
+ 4. ESTETIKA MODERN & PREMIUM: Gunakan skema warna harmonis (misal: warna gelap bernuansa glassmorphism, gradasi halus, border tipis semi-transparan, efek hover mikro interaktif).
15721
+ 5. COMPACT & EFISIEN: Hindari padding/margin berlebih yang membuat halaman kosong melompong. Pastikan konten padat, terbaca dengan baik, dan memiliki rasio grid/flexbox yang rapi.
15722
+ 6. BEBAS JAVASCRIPT: Seluruh interaktivitas dasar (seperti hover, focus, state) harus ditangani murni menggunakan utilitas kelas CSS Tailwind.`;
15684
15723
  const handleCopyPrompt = () => {
15685
- navigator.clipboard.writeText(aiPrompt);
15724
+ const selectedPrompt = promptType === "with-header" ? aiPromptWithHeader : aiPromptNoHeader;
15725
+ navigator.clipboard.writeText(selectedPrompt);
15686
15726
  setCopied(true);
15687
15727
  setTimeout(() => setCopied(false), 2e3);
15688
15728
  };
@@ -15787,7 +15827,37 @@ Ketentuan penulisan kode:
15787
15827
  }
15788
15828
  )
15789
15829
  ] }),
15790
- /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: getClassName44("promptText"), children: aiPrompt })
15830
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: getClassName44("optionsSection"), style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: getClassName44("radioGroup"), children: [
15831
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("label", { className: getClassName44("radioLabel"), children: [
15832
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
15833
+ "input",
15834
+ {
15835
+ type: "radio",
15836
+ name: "promptType",
15837
+ value: "with-header",
15838
+ checked: promptType === "with-header",
15839
+ onChange: () => setPromptType("with-header"),
15840
+ className: getClassName44("radioInput")
15841
+ }
15842
+ ),
15843
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { children: "Dengan Header" })
15844
+ ] }),
15845
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("label", { className: getClassName44("radioLabel"), children: [
15846
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
15847
+ "input",
15848
+ {
15849
+ type: "radio",
15850
+ name: "promptType",
15851
+ value: "no-header",
15852
+ checked: promptType === "no-header",
15853
+ onChange: () => setPromptType("no-header"),
15854
+ className: getClassName44("radioInput")
15855
+ }
15856
+ ),
15857
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { children: "Tanpa Header" })
15858
+ ] })
15859
+ ] }) }),
15860
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: getClassName44("promptText"), children: promptType === "with-header" ? aiPromptWithHeader : aiPromptNoHeader })
15791
15861
  ] })
15792
15862
  ] });
15793
15863
  };
@@ -10,7 +10,7 @@ import {
10
10
  overrideKeys,
11
11
  useCredBuild,
12
12
  useGetCredBuild
13
- } from "./chunk-CKELXGDW.mjs";
13
+ } from "./chunk-W3JRA22A.mjs";
14
14
  import {
15
15
  ColorPickerField,
16
16
  Drawer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crediblemark/build",
3
- "version": "0.25.15",
3
+ "version": "0.25.17",
4
4
  "description": "The open-source visual editor for React",
5
5
  "author": "Rasyiqi Crediblemark",
6
6
  "repository": {