@paulpaulstudio/strapi-render 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { createContext, useContext, useState, useRef, useEffect, useCallback, useMemo, Children, isValidElement, cloneElement, createElement, Fragment as Fragment$1 } from 'react';
3
3
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
+ import TurndownService from 'turndown';
4
5
 
5
6
  var EDIT_SESSION_KEY = "__pp_edit_session";
6
7
  var noop = () => {
@@ -233,10 +234,24 @@ function resolveUrl(value, baseUrl) {
233
234
  return value.url;
234
235
  }
235
236
  var HOVER_OUTLINE_COLOR2 = "#FA501E";
236
- function StrapiImage({ path, value, baseUrl, alt, className, style, loading = "lazy", fallback, allowedTypes, multiple = false, width, height, draggable }) {
237
+ function StrapiImage({
238
+ path,
239
+ value,
240
+ baseUrl,
241
+ alt,
242
+ className,
243
+ style,
244
+ loading = "lazy",
245
+ fallback,
246
+ allowedTypes,
247
+ multiple = false,
248
+ width,
249
+ height,
250
+ draggable,
251
+ priority: _ignored
252
+ }) {
237
253
  const ctx = useStrapiEditMode();
238
254
  const scope = useContentScope();
239
- const containerRef = useRef(null);
240
255
  const imgRef = useRef(null);
241
256
  const handleClick = (e) => {
242
257
  if (!ctx.enabled) return;
@@ -254,40 +269,38 @@ function StrapiImage({ path, value, baseUrl, alt, className, style, loading = "l
254
269
  if (!value) {
255
270
  if (!ctx.enabled) return /* @__PURE__ */ jsx(Fragment, { children: fallback ?? null });
256
271
  return /* @__PURE__ */ jsx(
257
- "span",
272
+ "button",
258
273
  {
259
- ref: containerRef,
260
- "data-pp-edit": path,
261
- "data-pp-type": "media",
274
+ type: "button",
262
275
  onClick: handleClick,
263
- onMouseEnter: (e) => {
264
- e.currentTarget.style.outlineColor = HOVER_OUTLINE_COLOR2;
265
- },
266
- onMouseLeave: (e) => {
267
- e.currentTarget.style.outlineColor = "transparent";
268
- },
276
+ className,
269
277
  style: {
270
278
  display: "inline-flex",
271
279
  alignItems: "center",
272
280
  justifyContent: "center",
273
281
  background: "rgba(0,0,0,0.05)",
274
282
  border: "1px dashed rgba(0,0,0,0.3)",
275
- outline: "1px dashed transparent",
276
- outlineOffset: 2,
277
- cursor: "pointer",
278
283
  padding: "20px 28px",
279
284
  fontSize: 12,
280
285
  fontWeight: 700,
281
286
  textTransform: "uppercase",
282
287
  letterSpacing: "0.15em",
283
288
  color: "#000",
284
- transition: "outline-color 0.15s ease"
289
+ cursor: "pointer",
290
+ ...style
285
291
  },
286
292
  children: "+ Bild hinzuf\xFCgen"
287
293
  }
288
294
  );
289
295
  }
290
- const imgEl = /* @__PURE__ */ jsx(
296
+ const editStyle = ctx.enabled ? {
297
+ ...style,
298
+ outline: "1px dashed transparent",
299
+ outlineOffset: 2,
300
+ cursor: "pointer",
301
+ transition: "outline-color 0.15s ease"
302
+ } : style ?? {};
303
+ return /* @__PURE__ */ jsx(
291
304
  "img",
292
305
  {
293
306
  ref: imgRef,
@@ -297,74 +310,21 @@ function StrapiImage({ path, value, baseUrl, alt, className, style, loading = "l
297
310
  height: height ?? value.height,
298
311
  loading,
299
312
  className,
300
- style,
301
- draggable
302
- }
303
- );
304
- if (!ctx.enabled) return imgEl;
305
- return /* @__PURE__ */ jsxs(
306
- "span",
307
- {
308
- ref: containerRef,
309
- "data-pp-edit": path,
310
- "data-pp-type": "media",
311
- style: {
312
- position: "relative",
313
- display: "block",
314
- // Wrapper ist block-level damit das innere img mit className w-full / h-[60vh] etc.
315
- // die korrekte Größe ausfüllt. Im Read-Mode (kein Wrapper) hatte das img direkt
316
- // diese Größe — beim Wrap mit inline-block-span schrumpfte das.
317
- outline: "1px dashed transparent",
318
- outlineOffset: 2,
319
- transition: "outline-color 0.15s ease"
320
- },
321
- onMouseEnter: (e) => {
322
- e.currentTarget.style.outlineColor = HOVER_OUTLINE_COLOR2;
323
- const btn = e.currentTarget.querySelector("[data-pp-edit-btn]");
324
- if (btn) btn.style.opacity = "1";
325
- },
326
- onMouseLeave: (e) => {
327
- e.currentTarget.style.outlineColor = "transparent";
328
- const btn = e.currentTarget.querySelector("[data-pp-edit-btn]");
329
- if (btn) btn.style.opacity = "0";
330
- },
331
- children: [
332
- imgEl,
333
- /* @__PURE__ */ jsx(
334
- "button",
335
- {
336
- type: "button",
337
- "data-pp-edit-btn": true,
338
- onClick: handleClick,
339
- style: {
340
- position: "absolute",
341
- top: 8,
342
- right: 8,
343
- background: "#000",
344
- color: "#EBC6DF",
345
- border: "2px solid #000",
346
- padding: "6px 10px",
347
- fontSize: 11,
348
- fontWeight: 700,
349
- textTransform: "uppercase",
350
- letterSpacing: "0.15em",
351
- cursor: "pointer",
352
- opacity: 0,
353
- transition: "opacity 0.15s ease, background 0.15s ease",
354
- fontFamily: "system-ui, -apple-system, sans-serif"
355
- },
356
- onMouseEnter: (e) => {
357
- e.currentTarget.style.background = "#FA501E";
358
- e.currentTarget.style.color = "#000";
359
- },
360
- onMouseLeave: (e) => {
361
- e.currentTarget.style.background = "#000";
362
- e.currentTarget.style.color = "#EBC6DF";
363
- },
364
- children: "\xC4ndern"
365
- }
366
- )
367
- ]
313
+ style: editStyle,
314
+ draggable,
315
+ "data-pp-edit": ctx.enabled ? path : void 0,
316
+ "data-pp-type": ctx.enabled ? "media" : void 0,
317
+ onClick: ctx.enabled ? handleClick : void 0,
318
+ onMouseEnter: ctx.enabled ? (e) => {
319
+ const el = e.currentTarget;
320
+ el.style.outlineColor = HOVER_OUTLINE_COLOR2;
321
+ el.style.outlineStyle = "solid";
322
+ } : void 0,
323
+ onMouseLeave: ctx.enabled ? (e) => {
324
+ const el = e.currentTarget;
325
+ el.style.outlineColor = "transparent";
326
+ el.style.outlineStyle = "dashed";
327
+ } : void 0
368
328
  }
369
329
  );
370
330
  }
@@ -592,7 +552,171 @@ function StrapiMarkdownField({ path, value, render, className, minRows = 12 }) {
592
552
  }, children: "Markdown \u2014 **fett**, *kursiv*, ## \xDCberschrift, [link](url)" })
593
553
  ] });
594
554
  }
555
+ var HOVER_OUTLINE3 = "#FA501E";
556
+ function StrapiRichTextField({ path, value, render, className }) {
557
+ const ctx = useStrapiEditMode();
558
+ const scope = useContentScope();
559
+ const containerRef = useRef(null);
560
+ const turndownRef = useRef(null);
561
+ const initial = useRef(value ?? "");
562
+ const [, force] = useState({});
563
+ if (typeof window !== "undefined" && !turndownRef.current) {
564
+ const td = new TurndownService({
565
+ headingStyle: "atx",
566
+ hr: "---",
567
+ bulletListMarker: "-",
568
+ codeBlockStyle: "fenced",
569
+ emDelimiter: "*"
570
+ });
571
+ td.addRule("br", {
572
+ filter: "br",
573
+ replacement: () => "\n"
574
+ });
575
+ turndownRef.current = td;
576
+ }
577
+ useEffect(() => {
578
+ initial.current = value ?? "";
579
+ force({});
580
+ }, [value]);
581
+ if (!ctx.enabled) {
582
+ return /* @__PURE__ */ jsx("div", { className, children: render(value ?? "") });
583
+ }
584
+ return /* @__PURE__ */ jsx(
585
+ "div",
586
+ {
587
+ ref: containerRef,
588
+ className,
589
+ contentEditable: true,
590
+ suppressContentEditableWarning: true,
591
+ "data-pp-edit": path,
592
+ "data-pp-type": "richText",
593
+ style: {
594
+ outline: "1px dashed transparent",
595
+ outlineOffset: 4,
596
+ transition: "outline-color 0.15s ease",
597
+ cursor: "text"
598
+ },
599
+ onMouseEnter: (e) => {
600
+ e.currentTarget.style.outlineColor = HOVER_OUTLINE3;
601
+ },
602
+ onMouseLeave: (e) => {
603
+ if (document.activeElement !== e.currentTarget) {
604
+ e.currentTarget.style.outlineColor = "transparent";
605
+ }
606
+ },
607
+ onFocus: (e) => {
608
+ e.currentTarget.style.outlineColor = HOVER_OUTLINE3;
609
+ e.currentTarget.style.outlineStyle = "solid";
610
+ },
611
+ onBlur: (e) => {
612
+ const el = e.currentTarget;
613
+ el.style.outlineColor = "transparent";
614
+ el.style.outlineStyle = "dashed";
615
+ if (!turndownRef.current) return;
616
+ const html = el.innerHTML;
617
+ const md = turndownRef.current.turndown(html).trim();
618
+ if (md !== initial.current.trim()) {
619
+ postEditChange(scope, path, "richText", md);
620
+ }
621
+ },
622
+ onKeyDown: (e) => {
623
+ if (e.metaKey || e.ctrlKey) {
624
+ if (e.key === "b") {
625
+ e.preventDefault();
626
+ document.execCommand("bold");
627
+ } else if (e.key === "i") {
628
+ e.preventDefault();
629
+ document.execCommand("italic");
630
+ } else if (e.key === "u") {
631
+ e.preventDefault();
632
+ document.execCommand("underline");
633
+ } else if (e.key === "k") {
634
+ e.preventDefault();
635
+ const url = window.prompt("Link-URL:");
636
+ if (url) document.execCommand("createLink", false, url);
637
+ }
638
+ }
639
+ },
640
+ children: render(value ?? "")
641
+ }
642
+ );
643
+ }
644
+ function StrapiLink({ path, value, target, rel, className, children }) {
645
+ const ctx = useStrapiEditMode();
646
+ const scope = useContentScope();
647
+ const [hover, setHover] = useState(false);
648
+ if (!ctx.enabled) {
649
+ return /* @__PURE__ */ jsx("a", { href: value ?? "#", target, rel, className, children });
650
+ }
651
+ const handleEdit = (e) => {
652
+ e.preventDefault();
653
+ e.stopPropagation();
654
+ const next = window.prompt("Link-URL bearbeiten:", value ?? "");
655
+ if (next !== null && next !== value) {
656
+ postEditChange(scope, path, "text", next);
657
+ }
658
+ };
659
+ return /* @__PURE__ */ jsxs(
660
+ "span",
661
+ {
662
+ style: { position: "relative", display: "inline-block" },
663
+ onMouseEnter: () => setHover(true),
664
+ onMouseLeave: () => setHover(false),
665
+ children: [
666
+ /* @__PURE__ */ jsx(
667
+ "a",
668
+ {
669
+ href: value ?? "#",
670
+ target,
671
+ rel,
672
+ className,
673
+ onClick: (e) => {
674
+ e.preventDefault();
675
+ },
676
+ "data-pp-edit": path,
677
+ "data-pp-type": "text",
678
+ children
679
+ }
680
+ ),
681
+ /* @__PURE__ */ jsx(
682
+ "button",
683
+ {
684
+ type: "button",
685
+ onClick: handleEdit,
686
+ style: {
687
+ position: "absolute",
688
+ top: 8,
689
+ right: 8,
690
+ background: "#000",
691
+ color: "#EBC6DF",
692
+ border: "2px solid #000",
693
+ padding: "4px 8px",
694
+ fontSize: 10,
695
+ fontWeight: 700,
696
+ textTransform: "uppercase",
697
+ letterSpacing: "0.15em",
698
+ cursor: "pointer",
699
+ opacity: hover ? 1 : 0,
700
+ transition: "opacity 0.15s ease, background 0.15s ease",
701
+ fontFamily: "system-ui, sans-serif",
702
+ zIndex: 10
703
+ },
704
+ onMouseEnter: (e) => {
705
+ e.currentTarget.style.background = "#FA501E";
706
+ e.currentTarget.style.color = "#000";
707
+ },
708
+ onMouseLeave: (e) => {
709
+ e.currentTarget.style.background = "#000";
710
+ e.currentTarget.style.color = "#EBC6DF";
711
+ },
712
+ children: "\u{1F517} Link"
713
+ }
714
+ )
715
+ ]
716
+ }
717
+ );
718
+ }
595
719
 
596
- export { StrapiBlocks, StrapiContent, StrapiEditModeProvider, StrapiField, StrapiImage, StrapiList, StrapiMarkdownField, StrapiText, useContentScope, useStrapiEditMode };
720
+ export { StrapiBlocks, StrapiContent, StrapiEditModeProvider, StrapiField, StrapiImage, StrapiLink, StrapiList, StrapiMarkdownField, StrapiRichTextField, StrapiText, useContentScope, useStrapiEditMode };
597
721
  //# sourceMappingURL=index.js.map
598
722
  //# sourceMappingURL=index.js.map