@windoc/react 0.2.7 → 0.2.9

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.mjs CHANGED
@@ -232,8 +232,14 @@ function TitleTool() {
232
232
  import { useRef as useRef4 } from "react";
233
233
  import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
234
234
  var FONTS = [
235
- { family: "Arial", label: "Sans Serif" },
236
- { family: "Times New Roman", label: "Serif" }
235
+ { family: "Arial", label: "Arial" },
236
+ { family: "Times New Roman", label: "Times New Roman" },
237
+ { family: "Georgia", label: "Georgia" },
238
+ { family: "Verdana", label: "Verdana" },
239
+ { family: "Trebuchet MS", label: "Trebuchet MS" },
240
+ { family: "Courier New", label: "Courier New" },
241
+ { family: "Comic Sans MS", label: "Comic Sans MS" },
242
+ { family: "Impact", label: "Impact" }
237
243
  ];
238
244
  function FontTool() {
239
245
  const { editorRef, rangeStyle } = useEditor();
@@ -262,11 +268,11 @@ function FontTool() {
262
268
  // src/toolbar/FontSizeTool.tsx
263
269
  import { useRef as useRef5 } from "react";
264
270
  import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
265
- var SIZES = [56, 48, 34, 32, 29, 24, 21, 20, 18, 16, 14, 12, 10, 8];
271
+ var SIZES = [72, 48, 36, 24, 20, 18, 16, 14, 12, 11, 10, 9, 8];
266
272
  function FontSizeTool() {
267
273
  const { editorRef, rangeStyle } = useEditor();
268
274
  const optionsRef = useRef5(null);
269
- const activeSize = rangeStyle?.size ?? 16;
275
+ const activeSize = rangeStyle?.size ?? 11;
270
276
  const handleSize = (size) => {
271
277
  editorRef.current?.command.executeSize(size);
272
278
  };
@@ -951,6 +957,7 @@ function PaperDirectionTool() {
951
957
  }
952
958
 
953
959
  // src/footer/PaperMarginTool.tsx
960
+ import { pxToCm, cmToPx } from "@windoc/core";
954
961
  import { jsx as jsx35 } from "react/jsx-runtime";
955
962
  function PaperMarginTool() {
956
963
  const { editorRef } = useEditor();
@@ -961,10 +968,10 @@ function PaperMarginTool() {
961
968
  new Dialog({
962
969
  title: "Page Margins",
963
970
  data: [
964
- { type: "text", label: "Top Margin", name: "top", required: true, value: `${topMargin}`, placeholder: "Please enter top margin" },
965
- { type: "text", label: "Bottom Margin", name: "bottom", required: true, value: `${bottomMargin}`, placeholder: "Please enter bottom margin" },
966
- { type: "text", label: "Left Margin", name: "left", required: true, value: `${leftMargin}`, placeholder: "Please enter left margin" },
967
- { type: "text", label: "Right Margin", name: "right", required: true, value: `${rightMargin}`, placeholder: "Please enter right margin" }
971
+ { type: "text", label: "Top Margin (cm)", name: "top", required: true, value: `${pxToCm(topMargin)}`, placeholder: "e.g. 2.54" },
972
+ { type: "text", label: "Bottom Margin (cm)", name: "bottom", required: true, value: `${pxToCm(bottomMargin)}`, placeholder: "e.g. 2.54" },
973
+ { type: "text", label: "Left Margin (cm)", name: "left", required: true, value: `${pxToCm(leftMargin)}`, placeholder: "e.g. 2.54" },
974
+ { type: "text", label: "Right Margin (cm)", name: "right", required: true, value: `${pxToCm(rightMargin)}`, placeholder: "e.g. 2.54" }
968
975
  ],
969
976
  onConfirm: (payload) => {
970
977
  const top = payload.find((p) => p.name === "top")?.value;
@@ -976,10 +983,10 @@ function PaperMarginTool() {
976
983
  const right = payload.find((p) => p.name === "right")?.value;
977
984
  if (!right) return;
978
985
  editorRef.current?.command.executeSetPaperMargin([
979
- Number(top),
980
- Number(right),
981
- Number(bottom),
982
- Number(left)
986
+ cmToPx(Number(top)),
987
+ cmToPx(Number(right)),
988
+ cmToPx(Number(bottom)),
989
+ cmToPx(Number(left))
983
990
  ]);
984
991
  }
985
992
  });
@@ -1142,85 +1149,95 @@ function WatermarkFooterTool() {
1142
1149
  };
1143
1150
  return /* @__PURE__ */ jsxs21("div", { className: "watermark-footer", ref: containerRef, onClick: () => setVisible(!visible), children: [
1144
1151
  /* @__PURE__ */ jsx38("i", { title: "Watermark" }),
1145
- visible && /* @__PURE__ */ jsxs21("div", { className: "watermark-footer-panel", ref: panelRef, onClick: (e) => e.stopPropagation(), children: [
1146
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-tabs", children: [
1147
- /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "text" ? "active" : ""}`, onClick: () => setTab("text"), children: "Text" }),
1148
- /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "image" ? "active" : ""}`, onClick: () => setTab("image"), children: "Image" })
1149
- ] }),
1150
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-body", children: [
1151
- tab === "text" ? /* @__PURE__ */ jsxs21(Fragment3, { children: [
1152
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1153
- /* @__PURE__ */ jsx38("label", { children: "Text" }),
1154
- /* @__PURE__ */ jsx38("input", { type: "text", value: text, onChange: (e) => setText(e.target.value), placeholder: "Watermark text" })
1152
+ visible && /* @__PURE__ */ jsxs21(Fragment3, { children: [
1153
+ /* @__PURE__ */ jsx38("div", { className: "wm-panel-mask", onClick: (e) => {
1154
+ e.stopPropagation();
1155
+ setVisible(false);
1156
+ } }),
1157
+ /* @__PURE__ */ jsxs21("div", { className: "watermark-footer-panel", ref: panelRef, onClick: (e) => e.stopPropagation(), children: [
1158
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-title", children: [
1159
+ /* @__PURE__ */ jsx38("span", { children: "Watermark" }),
1160
+ /* @__PURE__ */ jsx38("i", { onClick: () => setVisible(false) })
1161
+ ] }),
1162
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-tabs", children: [
1163
+ /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "text" ? "active" : ""}`, onClick: () => setTab("text"), children: "Text" }),
1164
+ /* @__PURE__ */ jsx38("button", { className: `wm-panel-tab ${tab === "image" ? "active" : ""}`, onClick: () => setTab("image"), children: "Image" })
1165
+ ] }),
1166
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-body", children: [
1167
+ tab === "text" ? /* @__PURE__ */ jsxs21(Fragment3, { children: [
1168
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1169
+ /* @__PURE__ */ jsx38("label", { children: "Text" }),
1170
+ /* @__PURE__ */ jsx38("input", { type: "text", value: text, onChange: (e) => setText(e.target.value), placeholder: "Watermark text" })
1171
+ ] }),
1172
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1173
+ /* @__PURE__ */ jsx38("label", { children: "Font" }),
1174
+ /* @__PURE__ */ jsx38("select", { value: font, onChange: (e) => setFont(e.target.value), children: FONTS2.map((f) => /* @__PURE__ */ jsx38("option", { value: f.family, children: f.label }, f.family)) })
1175
+ ] }),
1176
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1177
+ /* @__PURE__ */ jsx38("label", { children: "Color" }),
1178
+ /* @__PURE__ */ jsx38("div", { className: "wm-panel-colors", children: COLOR_PALETTE2.flat().map((c) => /* @__PURE__ */ jsx38(
1179
+ "div",
1180
+ {
1181
+ className: `wm-panel-color ${color.toLowerCase() === c.toLowerCase() ? "active" : ""}`,
1182
+ style: { backgroundColor: c },
1183
+ onClick: () => setColor(c)
1184
+ },
1185
+ c
1186
+ )) })
1187
+ ] })
1188
+ ] }) : /* @__PURE__ */ jsxs21(Fragment3, { children: [
1189
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1190
+ /* @__PURE__ */ jsx38("label", { children: "Image" }),
1191
+ /* @__PURE__ */ jsxs21("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
1192
+ /* @__PURE__ */ jsx38("button", { className: "wm-panel-upload", onClick: () => fileInputRef.current?.click(), children: "Choose File" }),
1193
+ /* @__PURE__ */ jsx38("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: handleFileUpload }),
1194
+ imageData && /* @__PURE__ */ jsx38("span", { style: { fontSize: "11px", color: "#667085" }, children: "Loaded" })
1195
+ ] })
1196
+ ] }),
1197
+ imageData && /* @__PURE__ */ jsx38("div", { className: "wm-panel-field", children: /* @__PURE__ */ jsx38("div", { className: "wm-panel-preview", children: /* @__PURE__ */ jsx38("img", { src: imageData, alt: "preview", style: { maxWidth: "100%", maxHeight: "48px", objectFit: "contain" } }) }) }),
1198
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field-row", children: [
1199
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1200
+ /* @__PURE__ */ jsx38("label", { children: "W" }),
1201
+ /* @__PURE__ */ jsx38("input", { type: "number", value: imgWidth, min: 10, onChange: (e) => setImgWidth(Number(e.target.value)) })
1202
+ ] }),
1203
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1204
+ /* @__PURE__ */ jsx38("label", { children: "H" }),
1205
+ /* @__PURE__ */ jsx38("input", { type: "number", value: imgHeight, min: 10, onChange: (e) => setImgHeight(Number(e.target.value)) })
1206
+ ] })
1207
+ ] })
1155
1208
  ] }),
1156
1209
  /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1157
- /* @__PURE__ */ jsx38("label", { children: "Font" }),
1158
- /* @__PURE__ */ jsx38("select", { value: font, onChange: (e) => setFont(e.target.value), children: FONTS2.map((f) => /* @__PURE__ */ jsx38("option", { value: f.family, children: f.label }, f.family)) })
1210
+ /* @__PURE__ */ jsxs21("label", { children: [
1211
+ "Opacity ",
1212
+ /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1213
+ opacity,
1214
+ "%"
1215
+ ] })
1216
+ ] }),
1217
+ /* @__PURE__ */ jsx38("input", { type: "range", min: 0, max: 100, value: opacity, onChange: (e) => setOpacity(Number(e.target.value)), className: "wm-panel-slider" })
1159
1218
  ] }),
1160
1219
  /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1161
- /* @__PURE__ */ jsx38("label", { children: "Color" }),
1162
- /* @__PURE__ */ jsx38("div", { className: "wm-panel-colors", children: COLOR_PALETTE2.flat().map((c) => /* @__PURE__ */ jsx38(
1163
- "div",
1164
- {
1165
- className: `wm-panel-color ${color.toLowerCase() === c.toLowerCase() ? "active" : ""}`,
1166
- style: { backgroundColor: c },
1167
- onClick: () => setColor(c)
1168
- },
1169
- c
1170
- )) })
1171
- ] })
1172
- ] }) : /* @__PURE__ */ jsxs21(Fragment3, { children: [
1173
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1174
- /* @__PURE__ */ jsx38("label", { children: "Image" }),
1175
- /* @__PURE__ */ jsxs21("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
1176
- /* @__PURE__ */ jsx38("button", { className: "wm-panel-upload", onClick: () => fileInputRef.current?.click(), children: "Choose File" }),
1177
- /* @__PURE__ */ jsx38("input", { ref: fileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: handleFileUpload }),
1178
- imageData && /* @__PURE__ */ jsx38("span", { style: { fontSize: "11px", color: "#667085" }, children: "Loaded" })
1179
- ] })
1180
- ] }),
1181
- imageData && /* @__PURE__ */ jsx38("div", { className: "wm-panel-field", children: /* @__PURE__ */ jsx38("div", { className: "wm-panel-preview", children: /* @__PURE__ */ jsx38("img", { src: imageData, alt: "preview", style: { maxWidth: "100%", maxHeight: "48px", objectFit: "contain" } }) }) }),
1182
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field-row", children: [
1183
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1184
- /* @__PURE__ */ jsx38("label", { children: "W" }),
1185
- /* @__PURE__ */ jsx38("input", { type: "number", value: imgWidth, min: 10, onChange: (e) => setImgWidth(Number(e.target.value)) })
1220
+ /* @__PURE__ */ jsxs21("label", { children: [
1221
+ "Rotation ",
1222
+ /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1223
+ rotation,
1224
+ "\xB0"
1225
+ ] })
1186
1226
  ] }),
1187
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field wm-panel-field-half", children: [
1188
- /* @__PURE__ */ jsx38("label", { children: "H" }),
1189
- /* @__PURE__ */ jsx38("input", { type: "number", value: imgHeight, min: 10, onChange: (e) => setImgHeight(Number(e.target.value)) })
1190
- ] })
1191
- ] })
1192
- ] }),
1193
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1194
- /* @__PURE__ */ jsxs21("label", { children: [
1195
- "Opacity ",
1196
- /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1197
- opacity,
1198
- "%"
1199
- ] })
1227
+ /* @__PURE__ */ jsx38("input", { type: "range", min: -90, max: 90, value: rotation, onChange: (e) => setRotation(Number(e.target.value)), className: "wm-panel-slider" })
1200
1228
  ] }),
1201
- /* @__PURE__ */ jsx38("input", { type: "range", min: 0, max: 100, value: opacity, onChange: (e) => setOpacity(Number(e.target.value)), className: "wm-panel-slider" })
1202
- ] }),
1203
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1204
- /* @__PURE__ */ jsxs21("label", { children: [
1205
- "Rotation ",
1206
- /* @__PURE__ */ jsxs21("span", { className: "wm-panel-value", children: [
1207
- rotation,
1208
- "\xB0"
1229
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1230
+ /* @__PURE__ */ jsx38("label", { children: "Position" }),
1231
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-toggle", children: [
1232
+ /* @__PURE__ */ jsx38("button", { className: !inFront ? "active" : "", onClick: () => setInFront(false), children: "Behind" }),
1233
+ /* @__PURE__ */ jsx38("button", { className: inFront ? "active" : "", onClick: () => setInFront(true), children: "In Front" })
1209
1234
  ] })
1210
- ] }),
1211
- /* @__PURE__ */ jsx38("input", { type: "range", min: -90, max: 90, value: rotation, onChange: (e) => setRotation(Number(e.target.value)), className: "wm-panel-slider" })
1212
- ] }),
1213
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-field", children: [
1214
- /* @__PURE__ */ jsx38("label", { children: "Position" }),
1215
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-toggle", children: [
1216
- /* @__PURE__ */ jsx38("button", { className: !inFront ? "active" : "", onClick: () => setInFront(false), children: "Behind" }),
1217
- /* @__PURE__ */ jsx38("button", { className: inFront ? "active" : "", onClick: () => setInFront(true), children: "In Front" })
1218
1235
  ] })
1236
+ ] }),
1237
+ /* @__PURE__ */ jsxs21("div", { className: "wm-panel-actions", children: [
1238
+ /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-delete", onClick: handleDelete, children: "Remove" }),
1239
+ /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-apply", onClick: handleApply, children: "Apply" })
1219
1240
  ] })
1220
- ] }),
1221
- /* @__PURE__ */ jsxs21("div", { className: "wm-panel-actions", children: [
1222
- /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-delete", onClick: handleDelete, children: "Remove" }),
1223
- /* @__PURE__ */ jsx38("button", { className: "wm-panel-btn-apply", onClick: handleApply, children: "Apply" })
1224
1241
  ] })
1225
1242
  ] })
1226
1243
  ] });
@@ -1257,6 +1274,7 @@ function Editor({
1257
1274
  options: userOptions,
1258
1275
  onChange,
1259
1276
  onReady,
1277
+ onRangeStyleChange,
1260
1278
  toolbar = true,
1261
1279
  footer = true,
1262
1280
  renderToolbar,
@@ -1273,6 +1291,7 @@ function Editor({
1273
1291
  options: userOptions,
1274
1292
  onChange,
1275
1293
  onReady,
1294
+ onRangeStyleChange,
1276
1295
  toolbar,
1277
1296
  footer,
1278
1297
  renderToolbar,
@@ -1289,6 +1308,7 @@ function EditorInner({
1289
1308
  options: userOptions,
1290
1309
  onChange,
1291
1310
  onReady,
1311
+ onRangeStyleChange,
1292
1312
  toolbar = true,
1293
1313
  footer = true,
1294
1314
  renderToolbar,
@@ -1332,6 +1352,7 @@ function EditorInner({
1332
1352
  editorRef.current = instance;
1333
1353
  instance.listener.rangeStyleChange = (payload) => {
1334
1354
  setRangeStyle(payload);
1355
+ onRangeStyleChange?.(payload);
1335
1356
  const rangeContext = instance?.command.getRangeContext();
1336
1357
  if (rangeContext) {
1337
1358
  setRowNo(rangeContext.startRowNo + 1);
@@ -1423,7 +1444,9 @@ function EditorInner({
1423
1444
  ]);
1424
1445
  const closeDropdowns = (evt) => {
1425
1446
  const visibleDom = document.querySelector(".visible");
1426
- if (!visibleDom || visibleDom.contains(evt.target)) return;
1447
+ if (!visibleDom) return;
1448
+ const parent = visibleDom.parentElement;
1449
+ if (parent && parent.contains(evt.target)) return;
1427
1450
  visibleDom.classList.remove("visible");
1428
1451
  };
1429
1452
  window.addEventListener("click", closeDropdowns, { capture: true });