@sofereditor/react 0.3.1 → 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 +236 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +248 -5
- 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,6 +2182,12 @@ function fragmentClass(f) {
|
|
|
2173
2182
|
function alignClass(a) {
|
|
2174
2183
|
return a ? ` ed-align-${a}` : "";
|
|
2175
2184
|
}
|
|
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;
|
|
2189
|
+
return Object.keys(style).length > 0 ? style : void 0;
|
|
2190
|
+
}
|
|
2176
2191
|
function clampLevel(l) {
|
|
2177
2192
|
if (l === 2 || l === 3 || l === 4 || l === 5 || l === 6) return l;
|
|
2178
2193
|
return 1;
|
|
@@ -2226,7 +2241,16 @@ function TableView({ block, index, tableFragment }) {
|
|
|
2226
2241
|
"data-cell-colspan": colspan,
|
|
2227
2242
|
rowSpan: rowspan > 1 ? rowspan : void 0,
|
|
2228
2243
|
colSpan: colspan > 1 ? colspan : void 0,
|
|
2229
|
-
style:
|
|
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
|
+
),
|
|
2230
2254
|
className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
|
|
2231
2255
|
children: renderInline(delta, `t${index}-c${flat}`)
|
|
2232
2256
|
},
|
|
@@ -3001,6 +3025,24 @@ function useEditor(opts = {}) {
|
|
|
3001
3025
|
}
|
|
3002
3026
|
return getBlockAttr("align");
|
|
3003
3027
|
}, [doc, getBlockAttr]);
|
|
3028
|
+
const setCellBackground = (0, import_react13.useCallback)((color) => {
|
|
3029
|
+
(0, import_core5.setCellAttr)(ctxRef.current, "bgColor", color);
|
|
3030
|
+
}, []);
|
|
3031
|
+
const getCellBackground = (0, import_react13.useCallback)(() => {
|
|
3032
|
+
const sel = selectionRef.current;
|
|
3033
|
+
if (sel.focus.cellIndex == null || !doc.isTable(sel.focus.blockIndex)) return void 0;
|
|
3034
|
+
return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).bgColor;
|
|
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]);
|
|
3004
3046
|
const isListActive = (0, import_react13.useCallback)(
|
|
3005
3047
|
(kind) => {
|
|
3006
3048
|
const sel = selectionRef.current;
|
|
@@ -3034,6 +3076,9 @@ function useEditor(opts = {}) {
|
|
|
3034
3076
|
const insertTable = (0, import_react13.useCallback)((rows, cols) => {
|
|
3035
3077
|
(0, import_core5.insertTable)(ctxRef.current, rows, cols);
|
|
3036
3078
|
}, []);
|
|
3079
|
+
const insertAnswerLines = (0, import_react13.useCallback)((count, spacing) => {
|
|
3080
|
+
(0, import_core5.insertAnswerLines)(ctxRef.current, count, spacing);
|
|
3081
|
+
}, []);
|
|
3037
3082
|
const deleteTable = (0, import_react13.useCallback)((blockIndex) => {
|
|
3038
3083
|
const idx = blockIndex ?? selectionRef.current.focus.blockIndex;
|
|
3039
3084
|
(0, import_core5.deleteTable)(ctxRef.current, idx);
|
|
@@ -3240,6 +3285,10 @@ function useEditor(opts = {}) {
|
|
|
3240
3285
|
setBlockAttr,
|
|
3241
3286
|
setAlign,
|
|
3242
3287
|
getAlign,
|
|
3288
|
+
setCellBackground,
|
|
3289
|
+
getCellBackground,
|
|
3290
|
+
setTableBorderPreset,
|
|
3291
|
+
getTableBorderPreset,
|
|
3243
3292
|
isListActive,
|
|
3244
3293
|
toggleList,
|
|
3245
3294
|
indentList,
|
|
@@ -3250,6 +3299,7 @@ function useEditor(opts = {}) {
|
|
|
3250
3299
|
resolveLinkRequest,
|
|
3251
3300
|
isInTable,
|
|
3252
3301
|
getTableLocation,
|
|
3302
|
+
insertAnswerLines,
|
|
3253
3303
|
insertTable,
|
|
3254
3304
|
deleteTable,
|
|
3255
3305
|
insertRowAbove,
|
|
@@ -4204,6 +4254,7 @@ function caretRangeFromPoint(x, y) {
|
|
|
4204
4254
|
|
|
4205
4255
|
// src/Toolbar.tsx
|
|
4206
4256
|
var import_react15 = require("react");
|
|
4257
|
+
var import_core7 = require("@sofereditor/core");
|
|
4207
4258
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4208
4259
|
var FONT_FAMILIES = ["Arial"];
|
|
4209
4260
|
var FONT_SIZES = ["8pt", "10pt", "11pt", "12pt", "14pt", "16pt", "18pt", "24pt", "32pt", "48pt"];
|
|
@@ -4270,6 +4321,9 @@ function Toolbar({ className }) {
|
|
|
4270
4321
|
const onColorChange = (e) => {
|
|
4271
4322
|
setMark("color", e.target.value);
|
|
4272
4323
|
};
|
|
4324
|
+
const onHighlightChange = (e) => {
|
|
4325
|
+
setMark("highlight", e.target.value);
|
|
4326
|
+
};
|
|
4273
4327
|
const onFontFamilyChange = (e) => {
|
|
4274
4328
|
const v = e.target.value;
|
|
4275
4329
|
if (v === "") removeMark("fontFamily");
|
|
@@ -4334,6 +4388,7 @@ function Toolbar({ className }) {
|
|
|
4334
4388
|
[active.link, editor, removeMark, setMark]
|
|
4335
4389
|
);
|
|
4336
4390
|
const colorValue = typeof active.color === "string" ? active.color : "#000000";
|
|
4391
|
+
const highlightValue = typeof active.highlight === "string" ? active.highlight : "#fff176";
|
|
4337
4392
|
const fontFamilyValue = typeof active.fontFamily === "string" ? active.fontFamily : "";
|
|
4338
4393
|
const fontSizeValue = typeof active.fontSize === "string" ? active.fontSize : "";
|
|
4339
4394
|
const blockValue = blockSelectValue(blockType, blockLevel);
|
|
@@ -4397,6 +4452,40 @@ function Toolbar({ className }) {
|
|
|
4397
4452
|
},
|
|
4398
4453
|
children: "\u232B"
|
|
4399
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
|
+
}
|
|
4400
4489
|
)
|
|
4401
4490
|
] }),
|
|
4402
4491
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
@@ -4526,7 +4615,10 @@ function Toolbar({ className }) {
|
|
|
4526
4615
|
children: "\u{1F517}"
|
|
4527
4616
|
}
|
|
4528
4617
|
) }),
|
|
4529
|
-
/* @__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
|
+
] }),
|
|
4530
4622
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4531
4623
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4532
4624
|
"button",
|
|
@@ -4612,6 +4704,102 @@ function Toolbar({ className }) {
|
|
|
4612
4704
|
}
|
|
4613
4705
|
);
|
|
4614
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
|
+
}
|
|
4615
4803
|
function TableMenu() {
|
|
4616
4804
|
const editor = useEditorContext();
|
|
4617
4805
|
const inTable = editor.isInTable();
|
|
@@ -4714,6 +4902,51 @@ function TableMenu() {
|
|
|
4714
4902
|
setOpen(false);
|
|
4715
4903
|
editor.splitCell();
|
|
4716
4904
|
}, children: "Dividir c\xE9lulas mescladas" }),
|
|
4905
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
|
|
4906
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label ed-table-bgcolor", children: [
|
|
4907
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4908
|
+
"span",
|
|
4909
|
+
{
|
|
4910
|
+
className: "ed-toolbar-swatch",
|
|
4911
|
+
"aria-hidden": true,
|
|
4912
|
+
style: { background: editor.getCellBackground() ?? "#ffffff" }
|
|
4913
|
+
}
|
|
4914
|
+
),
|
|
4915
|
+
"Cor de fundo da c\xE9lula",
|
|
4916
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4917
|
+
"input",
|
|
4918
|
+
{
|
|
4919
|
+
type: "color",
|
|
4920
|
+
value: editor.getCellBackground() ?? "#ffffff",
|
|
4921
|
+
onChange: (e) => editor.setCellBackground(e.target.value),
|
|
4922
|
+
"aria-label": "Cor de fundo da c\xE9lula"
|
|
4923
|
+
}
|
|
4924
|
+
)
|
|
4925
|
+
] }),
|
|
4926
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
4927
|
+
setOpen(false);
|
|
4928
|
+
editor.setCellBackground(null);
|
|
4929
|
+
}, children: "Remover cor de fundo" }),
|
|
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", {}),
|
|
4717
4950
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
4718
4951
|
"button",
|
|
4719
4952
|
{
|