@sofereditor/react 0.3.2 → 0.4.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.cjs +198 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +210 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1899,8 +1899,15 @@ function ImageEmbedViewImpl({
|
|
|
1899
1899
|
}
|
|
1900
1900
|
);
|
|
1901
1901
|
}
|
|
1902
|
+
function decorateBlanks(text) {
|
|
1903
|
+
const segs = (0, import_core3.splitUnderscoreRuns)(text);
|
|
1904
|
+
if (segs.length === 1 && !segs[0].blank) return text;
|
|
1905
|
+
return segs.map(
|
|
1906
|
+
(s, i) => s.blank ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-blank": "true", style: import_core3.BLANK_STYLE, children: s.text }, i) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react8.Fragment, { children: s.text }, i)
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1902
1909
|
function wrap(text, attrs) {
|
|
1903
|
-
let node = text;
|
|
1910
|
+
let node = decorateBlanks(text);
|
|
1904
1911
|
if (!attrs) return node;
|
|
1905
1912
|
if (attrs.bold) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: node });
|
|
1906
1913
|
if (attrs.italic) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("em", { children: node });
|
|
@@ -1908,6 +1915,7 @@ function wrap(text, attrs) {
|
|
|
1908
1915
|
if (attrs.strike) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { children: node });
|
|
1909
1916
|
const styleParts = {};
|
|
1910
1917
|
if (attrs.color) styleParts.color = attrs.color;
|
|
1918
|
+
if (attrs.highlight) styleParts.backgroundColor = attrs.highlight;
|
|
1911
1919
|
if (attrs.fontFamily) styleParts.fontFamily = attrs.fontFamily;
|
|
1912
1920
|
if (attrs.fontSize) styleParts.fontSize = attrs.fontSize;
|
|
1913
1921
|
if (Object.keys(styleParts).length > 0) {
|
|
@@ -2154,6 +2162,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
2154
2162
|
function commonBlockProps(attrs, index, type, fragment) {
|
|
2155
2163
|
const style = {};
|
|
2156
2164
|
if (attrs.align) style.textAlign = attrs.align;
|
|
2165
|
+
Object.assign(style, (0, import_core4.answerLineStyle)(attrs) ?? {});
|
|
2157
2166
|
const base = {
|
|
2158
2167
|
"data-block-index": index,
|
|
2159
2168
|
"data-block-type": type,
|
|
@@ -2173,11 +2182,10 @@ function fragmentClass(f) {
|
|
|
2173
2182
|
function alignClass(a) {
|
|
2174
2183
|
return a ? ` ed-align-${a}` : "";
|
|
2175
2184
|
}
|
|
2176
|
-
function cellStyle(attrs) {
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
if (attrs
|
|
2180
|
-
if (attrs.bgColor) style.backgroundColor = attrs.bgColor;
|
|
2185
|
+
function cellStyle(attrs, border) {
|
|
2186
|
+
const style = { ...border };
|
|
2187
|
+
if (attrs?.align) style.textAlign = attrs.align;
|
|
2188
|
+
if (attrs?.bgColor) style.backgroundColor = attrs.bgColor;
|
|
2181
2189
|
return Object.keys(style).length > 0 ? style : void 0;
|
|
2182
2190
|
}
|
|
2183
2191
|
function clampLevel(l) {
|
|
@@ -2233,7 +2241,16 @@ function TableView({ block, index, tableFragment }) {
|
|
|
2233
2241
|
"data-cell-colspan": colspan,
|
|
2234
2242
|
rowSpan: rowspan > 1 ? rowspan : void 0,
|
|
2235
2243
|
colSpan: colspan > 1 ? colspan : void 0,
|
|
2236
|
-
style: cellStyle(
|
|
2244
|
+
style: cellStyle(
|
|
2245
|
+
cell?.attrs,
|
|
2246
|
+
// rowStart/rowEnd são os limites do FRAGMENTO: numa tabela
|
|
2247
|
+
// quebrada entre páginas, cada página fecha a própria caixa.
|
|
2248
|
+
(0, import_core4.cellBorderStyle)(
|
|
2249
|
+
block.attrs.borderPreset,
|
|
2250
|
+
{ row: r, col: c, rowspan, colspan, cols, rowStart, rowEnd },
|
|
2251
|
+
"screen"
|
|
2252
|
+
)
|
|
2253
|
+
),
|
|
2237
2254
|
className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
|
|
2238
2255
|
children: renderInline(delta, `t${index}-c${flat}`)
|
|
2239
2256
|
},
|
|
@@ -3016,6 +3033,16 @@ function useEditor(opts = {}) {
|
|
|
3016
3033
|
if (sel.focus.cellIndex == null || !doc.isTable(sel.focus.blockIndex)) return void 0;
|
|
3017
3034
|
return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).bgColor;
|
|
3018
3035
|
}, [doc]);
|
|
3036
|
+
const setTableBorderPreset = (0, import_react13.useCallback)((preset) => {
|
|
3037
|
+
const sel = selectionRef.current;
|
|
3038
|
+
if (!doc.isTable(sel.focus.blockIndex)) return;
|
|
3039
|
+
(0, import_core5.setBlockAttrAtIndex)(ctxRef.current, sel.focus.blockIndex, "borderPreset", preset);
|
|
3040
|
+
}, [doc]);
|
|
3041
|
+
const getTableBorderPreset = (0, import_react13.useCallback)(() => {
|
|
3042
|
+
const sel = selectionRef.current;
|
|
3043
|
+
if (!doc.isTable(sel.focus.blockIndex)) return "all";
|
|
3044
|
+
return doc.getBlockAttrs(sel.focus.blockIndex).borderPreset ?? "all";
|
|
3045
|
+
}, [doc]);
|
|
3019
3046
|
const isListActive = (0, import_react13.useCallback)(
|
|
3020
3047
|
(kind) => {
|
|
3021
3048
|
const sel = selectionRef.current;
|
|
@@ -3049,6 +3076,9 @@ function useEditor(opts = {}) {
|
|
|
3049
3076
|
const insertTable = (0, import_react13.useCallback)((rows, cols) => {
|
|
3050
3077
|
(0, import_core5.insertTable)(ctxRef.current, rows, cols);
|
|
3051
3078
|
}, []);
|
|
3079
|
+
const insertAnswerLines = (0, import_react13.useCallback)((count, spacing) => {
|
|
3080
|
+
(0, import_core5.insertAnswerLines)(ctxRef.current, count, spacing);
|
|
3081
|
+
}, []);
|
|
3052
3082
|
const deleteTable = (0, import_react13.useCallback)((blockIndex) => {
|
|
3053
3083
|
const idx = blockIndex ?? selectionRef.current.focus.blockIndex;
|
|
3054
3084
|
(0, import_core5.deleteTable)(ctxRef.current, idx);
|
|
@@ -3257,6 +3287,8 @@ function useEditor(opts = {}) {
|
|
|
3257
3287
|
getAlign,
|
|
3258
3288
|
setCellBackground,
|
|
3259
3289
|
getCellBackground,
|
|
3290
|
+
setTableBorderPreset,
|
|
3291
|
+
getTableBorderPreset,
|
|
3260
3292
|
isListActive,
|
|
3261
3293
|
toggleList,
|
|
3262
3294
|
indentList,
|
|
@@ -3267,6 +3299,7 @@ function useEditor(opts = {}) {
|
|
|
3267
3299
|
resolveLinkRequest,
|
|
3268
3300
|
isInTable,
|
|
3269
3301
|
getTableLocation,
|
|
3302
|
+
insertAnswerLines,
|
|
3270
3303
|
insertTable,
|
|
3271
3304
|
deleteTable,
|
|
3272
3305
|
insertRowAbove,
|
|
@@ -4221,6 +4254,7 @@ function caretRangeFromPoint(x, y) {
|
|
|
4221
4254
|
|
|
4222
4255
|
// src/Toolbar.tsx
|
|
4223
4256
|
var import_react15 = require("react");
|
|
4257
|
+
var import_core7 = require("@sofereditor/core");
|
|
4224
4258
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4225
4259
|
var FONT_FAMILIES = ["Arial"];
|
|
4226
4260
|
var FONT_SIZES = ["8pt", "10pt", "11pt", "12pt", "14pt", "16pt", "18pt", "24pt", "32pt", "48pt"];
|
|
@@ -4287,6 +4321,9 @@ function Toolbar({ className }) {
|
|
|
4287
4321
|
const onColorChange = (e) => {
|
|
4288
4322
|
setMark("color", e.target.value);
|
|
4289
4323
|
};
|
|
4324
|
+
const onHighlightChange = (e) => {
|
|
4325
|
+
setMark("highlight", e.target.value);
|
|
4326
|
+
};
|
|
4290
4327
|
const onFontFamilyChange = (e) => {
|
|
4291
4328
|
const v = e.target.value;
|
|
4292
4329
|
if (v === "") removeMark("fontFamily");
|
|
@@ -4351,6 +4388,7 @@ function Toolbar({ className }) {
|
|
|
4351
4388
|
[active.link, editor, removeMark, setMark]
|
|
4352
4389
|
);
|
|
4353
4390
|
const colorValue = typeof active.color === "string" ? active.color : "#000000";
|
|
4391
|
+
const highlightValue = typeof active.highlight === "string" ? active.highlight : "#fff176";
|
|
4354
4392
|
const fontFamilyValue = typeof active.fontFamily === "string" ? active.fontFamily : "";
|
|
4355
4393
|
const fontSizeValue = typeof active.fontSize === "string" ? active.fontSize : "";
|
|
4356
4394
|
const blockValue = blockSelectValue(blockType, blockLevel);
|
|
@@ -4414,6 +4452,40 @@ function Toolbar({ className }) {
|
|
|
4414
4452
|
},
|
|
4415
4453
|
children: "\u232B"
|
|
4416
4454
|
}
|
|
4455
|
+
),
|
|
4456
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", title: "Marca-texto", children: [
|
|
4457
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4458
|
+
"span",
|
|
4459
|
+
{
|
|
4460
|
+
className: "ed-toolbar-swatch ed-toolbar-swatch--highlight",
|
|
4461
|
+
"aria-hidden": true,
|
|
4462
|
+
style: { background: highlightValue }
|
|
4463
|
+
}
|
|
4464
|
+
),
|
|
4465
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4466
|
+
"input",
|
|
4467
|
+
{
|
|
4468
|
+
type: "color",
|
|
4469
|
+
value: highlightValue,
|
|
4470
|
+
onChange: onHighlightChange,
|
|
4471
|
+
onMouseDown: stop,
|
|
4472
|
+
"aria-label": "Marca-texto"
|
|
4473
|
+
}
|
|
4474
|
+
)
|
|
4475
|
+
] }),
|
|
4476
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4477
|
+
"button",
|
|
4478
|
+
{
|
|
4479
|
+
type: "button",
|
|
4480
|
+
className: "ed-toolbar-btn",
|
|
4481
|
+
title: "Remover marca-texto",
|
|
4482
|
+
onMouseDown: stop,
|
|
4483
|
+
onClick: (e) => {
|
|
4484
|
+
e.preventDefault();
|
|
4485
|
+
removeMark("highlight");
|
|
4486
|
+
},
|
|
4487
|
+
children: "\u232B"
|
|
4488
|
+
}
|
|
4417
4489
|
)
|
|
4418
4490
|
] }),
|
|
4419
4491
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
@@ -4543,7 +4615,10 @@ function Toolbar({ className }) {
|
|
|
4543
4615
|
children: "\u{1F517}"
|
|
4544
4616
|
}
|
|
4545
4617
|
) }),
|
|
4546
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
4618
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4619
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TableMenu, {}),
|
|
4620
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AnswerLinesMenu, {})
|
|
4621
|
+
] }),
|
|
4547
4622
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4548
4623
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4549
4624
|
"button",
|
|
@@ -4629,6 +4704,102 @@ function Toolbar({ className }) {
|
|
|
4629
4704
|
}
|
|
4630
4705
|
);
|
|
4631
4706
|
}
|
|
4707
|
+
function AnswerLinesMenu() {
|
|
4708
|
+
const editor = useEditorContext();
|
|
4709
|
+
const [open, setOpen] = (0, import_react15.useState)(false);
|
|
4710
|
+
const [count, setCount] = (0, import_react15.useState)(5);
|
|
4711
|
+
const [spacing, setSpacing] = (0, import_react15.useState)(1.5);
|
|
4712
|
+
const rootRef = (0, import_react15.useRef)(null);
|
|
4713
|
+
(0, import_react15.useEffect)(() => {
|
|
4714
|
+
if (!open) return;
|
|
4715
|
+
const onDown = (e) => {
|
|
4716
|
+
if (!rootRef.current) return;
|
|
4717
|
+
if (rootRef.current.contains(e.target)) return;
|
|
4718
|
+
setOpen(false);
|
|
4719
|
+
};
|
|
4720
|
+
document.addEventListener("mousedown", onDown);
|
|
4721
|
+
return () => document.removeEventListener("mousedown", onDown);
|
|
4722
|
+
}, [open]);
|
|
4723
|
+
const clamped = Math.max(1, Math.min(import_core7.ANSWER_LINE_MAX, Math.trunc(count) || 1));
|
|
4724
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
|
|
4725
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4726
|
+
"button",
|
|
4727
|
+
{
|
|
4728
|
+
type: "button",
|
|
4729
|
+
className: "ed-toolbar-btn",
|
|
4730
|
+
title: "Linhas de resposta",
|
|
4731
|
+
"aria-pressed": open,
|
|
4732
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4733
|
+
onClick: (e) => {
|
|
4734
|
+
e.preventDefault();
|
|
4735
|
+
setOpen((v) => !v);
|
|
4736
|
+
},
|
|
4737
|
+
children: "\u2630"
|
|
4738
|
+
}
|
|
4739
|
+
),
|
|
4740
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4741
|
+
"div",
|
|
4742
|
+
{
|
|
4743
|
+
className: "ed-table-popover ed-answerlines-popover",
|
|
4744
|
+
role: "menu",
|
|
4745
|
+
onMouseDown: (e) => {
|
|
4746
|
+
const t = e.target;
|
|
4747
|
+
if (!t || t.tagName !== "INPUT" && t.tagName !== "BUTTON" && t.tagName !== "SELECT") {
|
|
4748
|
+
e.preventDefault();
|
|
4749
|
+
}
|
|
4750
|
+
},
|
|
4751
|
+
children: [
|
|
4752
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
|
|
4753
|
+
"Quantidade",
|
|
4754
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4755
|
+
"input",
|
|
4756
|
+
{
|
|
4757
|
+
type: "number",
|
|
4758
|
+
min: 1,
|
|
4759
|
+
max: import_core7.ANSWER_LINE_MAX,
|
|
4760
|
+
value: count,
|
|
4761
|
+
onChange: (e) => setCount(Number(e.target.value)),
|
|
4762
|
+
"aria-label": "Quantidade de linhas"
|
|
4763
|
+
}
|
|
4764
|
+
)
|
|
4765
|
+
] }),
|
|
4766
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
|
|
4767
|
+
"Entrelinha",
|
|
4768
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4769
|
+
"select",
|
|
4770
|
+
{
|
|
4771
|
+
value: String(spacing),
|
|
4772
|
+
onChange: (e) => setSpacing(Number(e.target.value)),
|
|
4773
|
+
"aria-label": "Entrelinha",
|
|
4774
|
+
children: [
|
|
4775
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "1", children: "Simples" }),
|
|
4776
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "1.5", children: "1,5" }),
|
|
4777
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "2", children: "Duplo" })
|
|
4778
|
+
]
|
|
4779
|
+
}
|
|
4780
|
+
)
|
|
4781
|
+
] }),
|
|
4782
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4783
|
+
"button",
|
|
4784
|
+
{
|
|
4785
|
+
type: "button",
|
|
4786
|
+
onClick: () => {
|
|
4787
|
+
setOpen(false);
|
|
4788
|
+
editor.insertAnswerLines(clamped, spacing);
|
|
4789
|
+
},
|
|
4790
|
+
children: [
|
|
4791
|
+
"Inserir ",
|
|
4792
|
+
clamped,
|
|
4793
|
+
" linha",
|
|
4794
|
+
clamped > 1 ? "s" : ""
|
|
4795
|
+
]
|
|
4796
|
+
}
|
|
4797
|
+
)
|
|
4798
|
+
]
|
|
4799
|
+
}
|
|
4800
|
+
)
|
|
4801
|
+
] });
|
|
4802
|
+
}
|
|
4632
4803
|
function TableMenu() {
|
|
4633
4804
|
const editor = useEditorContext();
|
|
4634
4805
|
const inTable = editor.isInTable();
|
|
@@ -4757,6 +4928,25 @@ function TableMenu() {
|
|
|
4757
4928
|
editor.setCellBackground(null);
|
|
4758
4929
|
}, children: "Remover cor de fundo" }),
|
|
4759
4930
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
|
|
4931
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
|
|
4932
|
+
"Bordas",
|
|
4933
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
4934
|
+
"select",
|
|
4935
|
+
{
|
|
4936
|
+
value: editor.getTableBorderPreset(),
|
|
4937
|
+
onChange: (e) => editor.setTableBorderPreset(e.target.value),
|
|
4938
|
+
"aria-label": "Bordas da tabela",
|
|
4939
|
+
children: [
|
|
4940
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "all", children: "Todas" }),
|
|
4941
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "outer", children: "S\xF3 externas" }),
|
|
4942
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "horizontal", children: "S\xF3 horizontais" }),
|
|
4943
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "vertical", children: "S\xF3 verticais" }),
|
|
4944
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "none", children: "Nenhuma" })
|
|
4945
|
+
]
|
|
4946
|
+
}
|
|
4947
|
+
)
|
|
4948
|
+
] }),
|
|
4949
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
|
|
4760
4950
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4761
4951
|
"button",
|
|
4762
4952
|
{
|