react-os-shell 3.8.6 → 3.9.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 (30) hide show
  1. package/dist/{Browser-P7SNR5LU.js → Browser-Z6EGTCHG.js} +4 -4
  2. package/dist/{Browser-P7SNR5LU.js.map → Browser-Z6EGTCHG.js.map} +1 -1
  3. package/dist/{Documents-ADOY3W75.js → Documents-W3WVPHAM.js} +3 -3
  4. package/dist/{Documents-ADOY3W75.js.map → Documents-W3WVPHAM.js.map} +1 -1
  5. package/dist/Files-7TGZSJHD.js +12 -0
  6. package/dist/{Files-RN4J6XLJ.js.map → Files-7TGZSJHD.js.map} +1 -1
  7. package/dist/{Notepad-BK5LWKJD.js → Notepad-CVKD2JFL.js} +3 -3
  8. package/dist/{Notepad-BK5LWKJD.js.map → Notepad-CVKD2JFL.js.map} +1 -1
  9. package/dist/Preview-DVXWKJYX.js +8 -0
  10. package/dist/{Preview-7IAIHIKG.js.map → Preview-DVXWKJYX.js.map} +1 -1
  11. package/dist/{Spreadsheet-256IMVEN.js → Spreadsheet-26YE7FV7.js} +4 -4
  12. package/dist/{Spreadsheet-256IMVEN.js.map → Spreadsheet-26YE7FV7.js.map} +1 -1
  13. package/dist/apps/index.js +12 -12
  14. package/dist/{chunk-K4673QDA.js → chunk-2E474D7Q.js} +131 -27
  15. package/dist/chunk-2E474D7Q.js.map +1 -0
  16. package/dist/{chunk-TPVASTEY.js → chunk-H7K4IKB6.js} +3 -3
  17. package/dist/{chunk-TPVASTEY.js.map → chunk-H7K4IKB6.js.map} +1 -1
  18. package/dist/{chunk-XBV6Y6TT.js → chunk-R2M7SXLN.js} +4 -4
  19. package/dist/{chunk-XBV6Y6TT.js.map → chunk-R2M7SXLN.js.map} +1 -1
  20. package/dist/{chunk-WSSULY4B.js → chunk-RTHUQTNU.js} +3 -3
  21. package/dist/{chunk-WSSULY4B.js.map → chunk-RTHUQTNU.js.map} +1 -1
  22. package/dist/{chunk-NMZUO4FQ.js → chunk-SNIBFLLT.js} +3 -3
  23. package/dist/{chunk-NMZUO4FQ.js.map → chunk-SNIBFLLT.js.map} +1 -1
  24. package/dist/{chunk-K2EXGE4R.js → chunk-YFKCWZ3A.js} +4 -4
  25. package/dist/{chunk-K2EXGE4R.js.map → chunk-YFKCWZ3A.js.map} +1 -1
  26. package/dist/index.js +8 -8
  27. package/package.json +1 -1
  28. package/dist/Files-RN4J6XLJ.js +0 -12
  29. package/dist/Preview-7IAIHIKG.js +0 -8
  30. package/dist/chunk-K4673QDA.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { toast_default } from './chunk-VENYVK3L.js';
2
- import { AboutApp } from './chunk-WSSULY4B.js';
2
+ import { AboutApp } from './chunk-RTHUQTNU.js';
3
3
  import { WindowTitle, registerModalEscapeInterceptor, getActiveModalId } from './chunk-JXW7H3DU.js';
4
4
  import { forwardRef, useRef, useState, useMemo, useEffect, useImperativeHandle, createContext, useContext } from 'react';
5
5
  import { createPortal } from 'react-dom';
@@ -15,6 +15,7 @@ var FONTS = [
15
15
  ];
16
16
  var STROKE_DEFAULT = 4;
17
17
  var TEXT_SIZE_DEFAULT = 24;
18
+ var TEXT_PADDING_DEFAULT = 6;
18
19
  var RECT_RADIUS_DEFAULT = 12;
19
20
  var MOSAIC_BLOCK = 12;
20
21
  var ZOOM_MIN = 0.25;
@@ -34,6 +35,9 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
34
35
  const [textBold, setTextBold] = useState(true);
35
36
  const [textItalic, setTextItalic] = useState(false);
36
37
  const [textUnderline, setTextUnderline] = useState(false);
38
+ const [textBorderColor, setTextBorderColor] = useState(null);
39
+ const [textBg, setTextBg] = useState(null);
40
+ const [textPadding, setTextPadding] = useState(TEXT_PADDING_DEFAULT);
37
41
  const [rectRadius, setRectRadius] = useState(RECT_RADIUS_DEFAULT);
38
42
  const [annotations, setAnnotations] = useState([]);
39
43
  const [selectedId, setSelectedId] = useState(null);
@@ -65,6 +69,9 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
65
69
  setTextBold(selected.bold);
66
70
  setTextItalic(selected.italic);
67
71
  setTextUnderline(selected.underline);
72
+ setTextBorderColor(selected.borderColor);
73
+ setTextBg(selected.background);
74
+ setTextPadding(selected.padding);
68
75
  }
69
76
  }
70
77
  }, [selectedId]);
@@ -209,6 +216,10 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
209
216
  return;
210
217
  }
211
218
  if (tool === "text") {
219
+ if (pendingText) {
220
+ commitText();
221
+ return;
222
+ }
212
223
  const p = evToImage(e);
213
224
  setPendingText({ x: p.x, y: p.y, value: "" });
214
225
  return;
@@ -302,9 +313,30 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
302
313
  (a) => a.id === selectedId && a.type === "text" ? { ...a, [which]: next } : a
303
314
  ));
304
315
  };
305
- const commitText = () => {
316
+ const setTextBorderColorAndApply = (c) => {
317
+ setTextBorderColor(c);
318
+ if (!selectedId) return;
319
+ setAnnotations((prev) => prev.map(
320
+ (a) => a.id === selectedId && a.type === "text" ? { ...a, borderColor: c } : a
321
+ ));
322
+ };
323
+ const setTextBgAndApply = (c) => {
324
+ setTextBg(c);
325
+ if (!selectedId) return;
326
+ setAnnotations((prev) => prev.map(
327
+ (a) => a.id === selectedId && a.type === "text" ? { ...a, background: c } : a
328
+ ));
329
+ };
330
+ const setTextPaddingAndApply = (p) => {
331
+ setTextPadding(p);
332
+ if (!selectedId) return;
333
+ setAnnotations((prev) => prev.map(
334
+ (a) => a.id === selectedId && a.type === "text" ? { ...a, padding: p } : a
335
+ ));
336
+ };
337
+ const commitText = (explicitValue) => {
306
338
  if (!pendingText) return;
307
- const value = pendingText.value;
339
+ const value = explicitValue ?? pendingText.value;
308
340
  if (!value.trim()) {
309
341
  if (pendingText.editingId) {
310
342
  setAnnotations((prev) => prev.filter((a) => a.id !== pendingText.editingId));
@@ -328,7 +360,10 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
328
360
  font: textFont,
329
361
  bold: textBold,
330
362
  italic: textItalic,
331
- underline: textUnderline
363
+ underline: textUnderline,
364
+ borderColor: textBorderColor,
365
+ background: textBg,
366
+ padding: textPadding
332
367
  };
333
368
  setAnnotations((prev) => [...prev, anno]);
334
369
  setSelectedId(anno.id);
@@ -496,6 +531,43 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
496
531
  /* @__PURE__ */ jsx("span", { children: "Size" }),
497
532
  /* @__PURE__ */ jsx("input", { type: "range", min: 10, max: 96, step: 1, value: textSize, onChange: (e) => setTextSizeAndApply(Number(e.target.value)), className: "w-16 accent-blue-500" }),
498
533
  /* @__PURE__ */ jsx("span", { className: "tabular-nums w-7 text-right", children: textSize })
534
+ ] }),
535
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1 text-gray-600", children: [
536
+ /* @__PURE__ */ jsx("span", { children: "Border" }),
537
+ textBorderColor ? /* @__PURE__ */ jsxs(Fragment, { children: [
538
+ /* @__PURE__ */ jsx(
539
+ "input",
540
+ {
541
+ type: "color",
542
+ value: textBorderColor,
543
+ onChange: (e) => setTextBorderColorAndApply(e.target.value),
544
+ title: "Text-box border color",
545
+ className: "h-5 w-6 rounded border border-gray-300 bg-white p-0 cursor-pointer"
546
+ }
547
+ ),
548
+ /* @__PURE__ */ jsx("button", { onClick: () => setTextBorderColorAndApply(null), title: "Remove border", className: "px-0.5 text-gray-400 hover:text-gray-700", children: "\u2715" })
549
+ ] }) : /* @__PURE__ */ jsx("button", { onClick: () => setTextBorderColorAndApply(color), title: "Add a border", className: "px-1.5 py-0.5 rounded border border-gray-300 text-gray-600 hover:bg-gray-100", children: "Add" })
550
+ ] }),
551
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1 text-gray-600", children: [
552
+ /* @__PURE__ */ jsx("span", { children: "Fill" }),
553
+ textBg ? /* @__PURE__ */ jsxs(Fragment, { children: [
554
+ /* @__PURE__ */ jsx(
555
+ "input",
556
+ {
557
+ type: "color",
558
+ value: textBg,
559
+ onChange: (e) => setTextBgAndApply(e.target.value),
560
+ title: "Text-box background color",
561
+ className: "h-5 w-6 rounded border border-gray-300 bg-white p-0 cursor-pointer"
562
+ }
563
+ ),
564
+ /* @__PURE__ */ jsx("button", { onClick: () => setTextBgAndApply(null), title: "Remove fill", className: "px-0.5 text-gray-400 hover:text-gray-700", children: "\u2715" })
565
+ ] }) : /* @__PURE__ */ jsx("button", { onClick: () => setTextBgAndApply("#ffffff"), title: "Add a background fill", className: "px-1.5 py-0.5 rounded border border-gray-300 text-gray-600 hover:bg-gray-100", children: "Add" })
566
+ ] }),
567
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5 text-gray-600", children: [
568
+ /* @__PURE__ */ jsx("span", { children: "Pad" }),
569
+ /* @__PURE__ */ jsx("input", { type: "range", min: 0, max: 40, step: 1, value: textPadding, onChange: (e) => setTextPaddingAndApply(Number(e.target.value)), className: "w-14 accent-blue-500" }),
570
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums w-6 text-right", children: textPadding })
499
571
  ] })
500
572
  ] }),
501
573
  /* @__PURE__ */ jsx("div", { className: "h-5 w-px bg-gray-300 mx-1" }),
@@ -589,6 +661,9 @@ var ImageAnnotator = forwardRef(function ImageAnnotator2({ src, filename, onAppl
589
661
  bold: textBold,
590
662
  italic: textItalic,
591
663
  underline: textUnderline,
664
+ borderColor: textBorderColor,
665
+ background: textBg,
666
+ padding: textPadding,
592
667
  scale,
593
668
  onChange: (value) => setPendingText({ ...pendingText, value }),
594
669
  onCommit: commitText,
@@ -671,23 +746,41 @@ function AnnotationView({ anno, selected, preview, zoom = 1, onPointerDown, onDo
671
746
  );
672
747
  } else {
673
748
  const font = FONTS.find((f) => f.id === anno.font)?.css ?? FONTS[0].css;
674
- body = /* @__PURE__ */ jsx(
675
- "text",
676
- {
677
- x: anno.x,
678
- y: anno.y + anno.size,
679
- fill: anno.color,
680
- fontSize: anno.size,
681
- fontWeight: anno.bold ? 700 : 400,
682
- fontStyle: anno.italic ? "italic" : "normal",
683
- textDecoration: anno.underline ? "underline" : void 0,
684
- fontFamily: font,
685
- style: { userSelect: "none" },
686
- ...interactive,
687
- ...dblc,
688
- children: anno.text.split("\n").map((line, i) => /* @__PURE__ */ jsx("tspan", { x: anno.x, dy: i === 0 ? 0 : anno.size * 1.2, children: line }, i))
689
- }
690
- );
749
+ const pad = anno.padding ?? 0;
750
+ const hasBox = !!anno.borderColor || !!anno.background;
751
+ const box = boundingBox(anno);
752
+ const borderW = anno.borderColor ? Math.max(1, Math.round(anno.size / 12)) : 0;
753
+ body = /* @__PURE__ */ jsxs("g", { ...interactive, ...dblc, children: [
754
+ hasBox && /* @__PURE__ */ jsx(
755
+ "rect",
756
+ {
757
+ x: box.x - pad,
758
+ y: box.y - pad,
759
+ width: Math.max(0, box.w) + pad * 2,
760
+ height: Math.max(0, box.h) + pad * 2,
761
+ rx: Math.min(8, pad),
762
+ ry: Math.min(8, pad),
763
+ fill: anno.background ?? "none",
764
+ stroke: anno.borderColor ?? "none",
765
+ strokeWidth: borderW
766
+ }
767
+ ),
768
+ /* @__PURE__ */ jsx(
769
+ "text",
770
+ {
771
+ x: anno.x,
772
+ y: anno.y + anno.size,
773
+ fill: anno.color,
774
+ fontSize: anno.size,
775
+ fontWeight: anno.bold ? 700 : 400,
776
+ fontStyle: anno.italic ? "italic" : "normal",
777
+ textDecoration: anno.underline ? "underline" : void 0,
778
+ fontFamily: font,
779
+ style: { userSelect: "none" },
780
+ children: anno.text.split("\n").map((line, i) => /* @__PURE__ */ jsx("tspan", { x: anno.x, dy: i === 0 ? 0 : anno.size * 1.2, children: line }, i))
781
+ }
782
+ )
783
+ ] });
691
784
  }
692
785
  return /* @__PURE__ */ jsxs("g", { children: [
693
786
  body,
@@ -798,6 +891,9 @@ function PendingTextEditor({
798
891
  bold,
799
892
  italic,
800
893
  underline,
894
+ borderColor,
895
+ background,
896
+ padding,
801
897
  scale,
802
898
  onChange,
803
899
  onCommit,
@@ -811,6 +907,8 @@ function PendingTextEditor({
811
907
  });
812
908
  return () => cancelAnimationFrame(id);
813
909
  }, []);
910
+ const commit = () => onCommit(ref.current?.value);
911
+ const borderW = borderColor ? Math.max(1, Math.round(size / 12)) : 0;
814
912
  return /* @__PURE__ */ jsx(
815
913
  "div",
816
914
  {
@@ -828,19 +926,19 @@ function PendingTextEditor({
828
926
  ref,
829
927
  value: pendingText.value,
830
928
  onChange: (e) => onChange(e.target.value),
831
- onBlur: onCommit,
929
+ onBlur: commit,
832
930
  onKeyDown: (e) => {
833
931
  if (e.key === "Escape") {
834
932
  e.preventDefault();
835
933
  onCancel();
836
934
  } else if (e.key === "Enter" && !e.shiftKey) {
837
935
  e.preventDefault();
838
- onCommit();
936
+ commit();
839
937
  }
840
938
  },
841
939
  placeholder: "Type then Enter\u2026",
842
940
  rows: 1,
843
- className: "bg-white/95 border border-blue-400 rounded px-1 py-0.5 outline-none resize-none shadow-md",
941
+ className: "outline-none resize-none shadow-md",
844
942
  style: {
845
943
  color,
846
944
  fontSize: `${size * scale}px`,
@@ -848,7 +946,13 @@ function PendingTextEditor({
848
946
  fontWeight: bold ? 700 : 400,
849
947
  fontStyle: italic ? "italic" : "normal",
850
948
  textDecoration: underline ? "underline" : void 0,
851
- minWidth: 80
949
+ minWidth: 80,
950
+ // Mirror the committed box so the editor is WYSIWYG. With no custom
951
+ // border, show a dashed hint so the edit box stays visible.
952
+ padding: `${padding * scale}px`,
953
+ borderRadius: `${Math.min(8, padding) * scale}px`,
954
+ border: borderColor ? `${borderW * scale}px solid ${borderColor}` : "1px dashed #60a5fa",
955
+ background: background ?? "rgba(255,255,255,0.95)"
852
956
  }
853
957
  }
854
958
  )
@@ -4285,5 +4389,5 @@ function ImagePanel({ url, filename, onDownload, onEmail }) {
4285
4389
  }
4286
4390
 
4287
4391
  export { ImageAnnotator_default, Preview, setPdfPreview };
4288
- //# sourceMappingURL=chunk-K4673QDA.js.map
4289
- //# sourceMappingURL=chunk-K4673QDA.js.map
4392
+ //# sourceMappingURL=chunk-2E474D7Q.js.map
4393
+ //# sourceMappingURL=chunk-2E474D7Q.js.map