@sofereditor/react 0.3.2 → 0.5.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 +250 -16
- 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 +262 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RefObject, JSX, ReactNode } from 'react';
|
|
2
|
-
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, AlignValue, ListKind, PageSettings, TableLocation, TableRect, ImageEmbed, EmbedLoc, SerializedBlock, DeltaOp, Position } from '@sofereditor/core';
|
|
2
|
+
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, AlignValue, TableBorderPreset, ListKind, PageSettings, TableLocation, AnswerLineSpacing, TableRect, ImageEmbed, EmbedLoc, SerializedBlock, DeltaOp, Position } from '@sofereditor/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Subconjunto mínimo da Awareness do y-protocols que o overlay usa. Tipar assim
|
|
@@ -180,6 +180,14 @@ interface UseEditorResult {
|
|
|
180
180
|
setCellBackground: (color: string | null) => void;
|
|
181
181
|
/** Cor de fundo da célula focada; undefined fora de tabela ou sem cor. */
|
|
182
182
|
getCellBackground: () => string | undefined;
|
|
183
|
+
/** Onde as linhas da grade da tabela focada aparecem. No-op fora de tabela. */
|
|
184
|
+
setTableBorderPreset: (preset: TableBorderPreset) => void;
|
|
185
|
+
/** Preset da tabela focada; "all" fora de tabela ou quando ausente. */
|
|
186
|
+
getTableBorderPreset: () => TableBorderPreset;
|
|
187
|
+
/** Cor das linhas da grade da tabela focada. `null` restaura o padrão. No-op fora de tabela. */
|
|
188
|
+
setTableBorderColor: (color: string | null) => void;
|
|
189
|
+
/** Cor da tabela focada; undefined fora de tabela ou quando usa o padrão. */
|
|
190
|
+
getTableBorderColor: () => string | undefined;
|
|
183
191
|
isListActive: (kind: ListKind) => boolean;
|
|
184
192
|
toggleList: (kind: ListKind) => void;
|
|
185
193
|
indentList: () => void;
|
|
@@ -214,6 +222,8 @@ interface UseEditorResult {
|
|
|
214
222
|
isInTable: () => boolean;
|
|
215
223
|
/** Returns `{blockIndex, row, col}` for the focus position, or null when outside a table. */
|
|
216
224
|
getTableLocation: () => TableLocation | null;
|
|
225
|
+
/** Insere `count` linhas de resposta pautadas depois do bloco focado. */
|
|
226
|
+
insertAnswerLines: (count: number, spacing: AnswerLineSpacing) => void;
|
|
217
227
|
insertTable: (rows: number, cols: number) => void;
|
|
218
228
|
/** Removes the table at `blockIndex`. Defaults to the current focus table. */
|
|
219
229
|
deleteTable: (blockIndex?: number) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RefObject, JSX, ReactNode } from 'react';
|
|
2
|
-
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, AlignValue, ListKind, PageSettings, TableLocation, TableRect, ImageEmbed, EmbedLoc, SerializedBlock, DeltaOp, Position } from '@sofereditor/core';
|
|
2
|
+
import { EditorDocument, EditorHistory, SerializedDocument, Selection, MarkName, MarkAttrs, BlockType, BlockAttrs, AlignValue, TableBorderPreset, ListKind, PageSettings, TableLocation, AnswerLineSpacing, TableRect, ImageEmbed, EmbedLoc, SerializedBlock, DeltaOp, Position } from '@sofereditor/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Subconjunto mínimo da Awareness do y-protocols que o overlay usa. Tipar assim
|
|
@@ -180,6 +180,14 @@ interface UseEditorResult {
|
|
|
180
180
|
setCellBackground: (color: string | null) => void;
|
|
181
181
|
/** Cor de fundo da célula focada; undefined fora de tabela ou sem cor. */
|
|
182
182
|
getCellBackground: () => string | undefined;
|
|
183
|
+
/** Onde as linhas da grade da tabela focada aparecem. No-op fora de tabela. */
|
|
184
|
+
setTableBorderPreset: (preset: TableBorderPreset) => void;
|
|
185
|
+
/** Preset da tabela focada; "all" fora de tabela ou quando ausente. */
|
|
186
|
+
getTableBorderPreset: () => TableBorderPreset;
|
|
187
|
+
/** Cor das linhas da grade da tabela focada. `null` restaura o padrão. No-op fora de tabela. */
|
|
188
|
+
setTableBorderColor: (color: string | null) => void;
|
|
189
|
+
/** Cor da tabela focada; undefined fora de tabela ou quando usa o padrão. */
|
|
190
|
+
getTableBorderColor: () => string | undefined;
|
|
183
191
|
isListActive: (kind: ListKind) => boolean;
|
|
184
192
|
toggleList: (kind: ListKind) => void;
|
|
185
193
|
indentList: () => void;
|
|
@@ -214,6 +222,8 @@ interface UseEditorResult {
|
|
|
214
222
|
isInTable: () => boolean;
|
|
215
223
|
/** Returns `{blockIndex, row, col}` for the focus position, or null when outside a table. */
|
|
216
224
|
getTableLocation: () => TableLocation | null;
|
|
225
|
+
/** Insere `count` linhas de resposta pautadas depois do bloco focado. */
|
|
226
|
+
insertAnswerLines: (count: number, spacing: AnswerLineSpacing) => void;
|
|
217
227
|
insertTable: (rows: number, cols: number) => void;
|
|
218
228
|
/** Removes the table at `blockIndex`. Defaults to the current focus table. */
|
|
219
229
|
deleteTable: (blockIndex?: number) => void;
|
package/dist/index.js
CHANGED
|
@@ -1708,11 +1708,19 @@ function RemoteCursorsOverlay({
|
|
|
1708
1708
|
|
|
1709
1709
|
// src/NodeView.tsx
|
|
1710
1710
|
import { useMemo as useMemo2, useRef as useRef7 } from "react";
|
|
1711
|
-
import {
|
|
1711
|
+
import {
|
|
1712
|
+
answerLineStyle,
|
|
1713
|
+
cellBorderStyle,
|
|
1714
|
+
tableRectSelection
|
|
1715
|
+
} from "@sofereditor/core";
|
|
1712
1716
|
|
|
1713
1717
|
// src/renderInline.tsx
|
|
1714
1718
|
import { Fragment as Fragment3, memo } from "react";
|
|
1715
|
-
import {
|
|
1719
|
+
import {
|
|
1720
|
+
BLANK_STYLE,
|
|
1721
|
+
isImageEmbed,
|
|
1722
|
+
splitUnderscoreRuns
|
|
1723
|
+
} from "@sofereditor/core";
|
|
1716
1724
|
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1717
1725
|
function renderInline(delta, keyPrefix) {
|
|
1718
1726
|
if (delta.length === 0 || delta.length === 1 && typeof delta[0].insert === "string" && delta[0].insert === "") {
|
|
@@ -1891,8 +1899,15 @@ function ImageEmbedViewImpl({
|
|
|
1891
1899
|
}
|
|
1892
1900
|
);
|
|
1893
1901
|
}
|
|
1902
|
+
function decorateBlanks(text) {
|
|
1903
|
+
const segs = splitUnderscoreRuns(text);
|
|
1904
|
+
if (segs.length === 1 && !segs[0].blank) return text;
|
|
1905
|
+
return segs.map(
|
|
1906
|
+
(s, i) => s.blank ? /* @__PURE__ */ jsx9("span", { "data-blank": "true", style: BLANK_STYLE, children: s.text }, i) : /* @__PURE__ */ jsx9(Fragment3, { children: s.text }, i)
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1894
1909
|
function wrap(text, attrs) {
|
|
1895
|
-
let node = text;
|
|
1910
|
+
let node = decorateBlanks(text);
|
|
1896
1911
|
if (!attrs) return node;
|
|
1897
1912
|
if (attrs.bold) node = /* @__PURE__ */ jsx9("strong", { children: node });
|
|
1898
1913
|
if (attrs.italic) node = /* @__PURE__ */ jsx9("em", { children: node });
|
|
@@ -1900,6 +1915,7 @@ function wrap(text, attrs) {
|
|
|
1900
1915
|
if (attrs.strike) node = /* @__PURE__ */ jsx9("s", { children: node });
|
|
1901
1916
|
const styleParts = {};
|
|
1902
1917
|
if (attrs.color) styleParts.color = attrs.color;
|
|
1918
|
+
if (attrs.highlight) styleParts.backgroundColor = attrs.highlight;
|
|
1903
1919
|
if (attrs.fontFamily) styleParts.fontFamily = attrs.fontFamily;
|
|
1904
1920
|
if (attrs.fontSize) styleParts.fontSize = attrs.fontSize;
|
|
1905
1921
|
if (Object.keys(styleParts).length > 0) {
|
|
@@ -2152,6 +2168,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
2152
2168
|
function commonBlockProps(attrs, index, type, fragment) {
|
|
2153
2169
|
const style = {};
|
|
2154
2170
|
if (attrs.align) style.textAlign = attrs.align;
|
|
2171
|
+
Object.assign(style, answerLineStyle(attrs) ?? {});
|
|
2155
2172
|
const base = {
|
|
2156
2173
|
"data-block-index": index,
|
|
2157
2174
|
"data-block-type": type,
|
|
@@ -2171,11 +2188,10 @@ function fragmentClass(f) {
|
|
|
2171
2188
|
function alignClass(a) {
|
|
2172
2189
|
return a ? ` ed-align-${a}` : "";
|
|
2173
2190
|
}
|
|
2174
|
-
function cellStyle(attrs) {
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
if (attrs
|
|
2178
|
-
if (attrs.bgColor) style.backgroundColor = attrs.bgColor;
|
|
2191
|
+
function cellStyle(attrs, border) {
|
|
2192
|
+
const style = { ...border };
|
|
2193
|
+
if (attrs?.align) style.textAlign = attrs.align;
|
|
2194
|
+
if (attrs?.bgColor) style.backgroundColor = attrs.bgColor;
|
|
2179
2195
|
return Object.keys(style).length > 0 ? style : void 0;
|
|
2180
2196
|
}
|
|
2181
2197
|
function clampLevel(l) {
|
|
@@ -2231,7 +2247,17 @@ function TableView({ block, index, tableFragment }) {
|
|
|
2231
2247
|
"data-cell-colspan": colspan,
|
|
2232
2248
|
rowSpan: rowspan > 1 ? rowspan : void 0,
|
|
2233
2249
|
colSpan: colspan > 1 ? colspan : void 0,
|
|
2234
|
-
style: cellStyle(
|
|
2250
|
+
style: cellStyle(
|
|
2251
|
+
cell?.attrs,
|
|
2252
|
+
// rowStart/rowEnd são os limites do FRAGMENTO: numa tabela
|
|
2253
|
+
// quebrada entre páginas, cada página fecha a própria caixa.
|
|
2254
|
+
cellBorderStyle(
|
|
2255
|
+
block.attrs.borderPreset,
|
|
2256
|
+
{ row: r, col: c, rowspan, colspan, cols, rowStart, rowEnd },
|
|
2257
|
+
"screen",
|
|
2258
|
+
block.attrs.borderColor
|
|
2259
|
+
)
|
|
2260
|
+
),
|
|
2235
2261
|
className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
|
|
2236
2262
|
children: renderInline(delta, `t${index}-c${flat}`)
|
|
2237
2263
|
},
|
|
@@ -2814,12 +2840,14 @@ import {
|
|
|
2814
2840
|
mergeRight as cmdMergeRight,
|
|
2815
2841
|
mergeSelection as cmdMergeSelection,
|
|
2816
2842
|
moveEmbedAnchor as cmdMoveEmbedAnchor,
|
|
2843
|
+
setBlockAttrAtIndex as cmdSetBlockAttrAtIndex,
|
|
2817
2844
|
setColumnWidth as cmdSetColumnWidth,
|
|
2818
2845
|
setImageAttrs as cmdSetImageAttrs,
|
|
2819
2846
|
splitCell as cmdSplitCell,
|
|
2820
2847
|
tableRectSelection as tableRectSelection2,
|
|
2821
2848
|
getMarksInRange,
|
|
2822
2849
|
indentList as cmdIndentList,
|
|
2850
|
+
insertAnswerLines as cmdInsertAnswerLines,
|
|
2823
2851
|
insertTable as cmdInsertTable,
|
|
2824
2852
|
insertTableColumn as cmdInsertColumn,
|
|
2825
2853
|
insertTableRow as cmdInsertRow,
|
|
@@ -3050,6 +3078,26 @@ function useEditor(opts = {}) {
|
|
|
3050
3078
|
if (sel.focus.cellIndex == null || !doc.isTable(sel.focus.blockIndex)) return void 0;
|
|
3051
3079
|
return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).bgColor;
|
|
3052
3080
|
}, [doc]);
|
|
3081
|
+
const setTableBorderPreset = useCallback6((preset) => {
|
|
3082
|
+
const sel = selectionRef.current;
|
|
3083
|
+
if (!doc.isTable(sel.focus.blockIndex)) return;
|
|
3084
|
+
cmdSetBlockAttrAtIndex(ctxRef.current, sel.focus.blockIndex, "borderPreset", preset);
|
|
3085
|
+
}, [doc]);
|
|
3086
|
+
const getTableBorderPreset = useCallback6(() => {
|
|
3087
|
+
const sel = selectionRef.current;
|
|
3088
|
+
if (!doc.isTable(sel.focus.blockIndex)) return "all";
|
|
3089
|
+
return doc.getBlockAttrs(sel.focus.blockIndex).borderPreset ?? "all";
|
|
3090
|
+
}, [doc]);
|
|
3091
|
+
const setTableBorderColor = useCallback6((color) => {
|
|
3092
|
+
const sel = selectionRef.current;
|
|
3093
|
+
if (!doc.isTable(sel.focus.blockIndex)) return;
|
|
3094
|
+
cmdSetBlockAttrAtIndex(ctxRef.current, sel.focus.blockIndex, "borderColor", color);
|
|
3095
|
+
}, [doc]);
|
|
3096
|
+
const getTableBorderColor = useCallback6(() => {
|
|
3097
|
+
const sel = selectionRef.current;
|
|
3098
|
+
if (!doc.isTable(sel.focus.blockIndex)) return void 0;
|
|
3099
|
+
return doc.getBlockAttrs(sel.focus.blockIndex).borderColor;
|
|
3100
|
+
}, [doc]);
|
|
3053
3101
|
const isListActive = useCallback6(
|
|
3054
3102
|
(kind) => {
|
|
3055
3103
|
const sel = selectionRef.current;
|
|
@@ -3083,6 +3131,9 @@ function useEditor(opts = {}) {
|
|
|
3083
3131
|
const insertTable = useCallback6((rows, cols) => {
|
|
3084
3132
|
cmdInsertTable(ctxRef.current, rows, cols);
|
|
3085
3133
|
}, []);
|
|
3134
|
+
const insertAnswerLines = useCallback6((count, spacing) => {
|
|
3135
|
+
cmdInsertAnswerLines(ctxRef.current, count, spacing);
|
|
3136
|
+
}, []);
|
|
3086
3137
|
const deleteTable = useCallback6((blockIndex) => {
|
|
3087
3138
|
const idx = blockIndex ?? selectionRef.current.focus.blockIndex;
|
|
3088
3139
|
cmdDeleteTable(ctxRef.current, idx);
|
|
@@ -3291,6 +3342,10 @@ function useEditor(opts = {}) {
|
|
|
3291
3342
|
getAlign,
|
|
3292
3343
|
setCellBackground,
|
|
3293
3344
|
getCellBackground,
|
|
3345
|
+
setTableBorderPreset,
|
|
3346
|
+
getTableBorderPreset,
|
|
3347
|
+
setTableBorderColor,
|
|
3348
|
+
getTableBorderColor,
|
|
3294
3349
|
isListActive,
|
|
3295
3350
|
toggleList,
|
|
3296
3351
|
indentList,
|
|
@@ -3301,6 +3356,7 @@ function useEditor(opts = {}) {
|
|
|
3301
3356
|
resolveLinkRequest,
|
|
3302
3357
|
isInTable,
|
|
3303
3358
|
getTableLocation,
|
|
3359
|
+
insertAnswerLines,
|
|
3304
3360
|
insertTable,
|
|
3305
3361
|
deleteTable,
|
|
3306
3362
|
insertRowAbove,
|
|
@@ -4260,6 +4316,7 @@ import {
|
|
|
4260
4316
|
useRef as useRef12,
|
|
4261
4317
|
useState as useState11
|
|
4262
4318
|
} from "react";
|
|
4319
|
+
import { ANSWER_LINE_MAX, TABLE_BORDER_COLOR } from "@sofereditor/core";
|
|
4263
4320
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4264
4321
|
var FONT_FAMILIES = ["Arial"];
|
|
4265
4322
|
var FONT_SIZES = ["8pt", "10pt", "11pt", "12pt", "14pt", "16pt", "18pt", "24pt", "32pt", "48pt"];
|
|
@@ -4281,6 +4338,15 @@ var ALIGN_OPTIONS = [
|
|
|
4281
4338
|
{ value: "justify", label: "\u2630", title: "Justificar" }
|
|
4282
4339
|
];
|
|
4283
4340
|
var IMAGE_ALIGN_VALUES = /* @__PURE__ */ new Set(["left", "center", "right"]);
|
|
4341
|
+
var NATIVE_CONTROL_TAGS = /* @__PURE__ */ new Set(["SELECT", "INPUT", "OPTION"]);
|
|
4342
|
+
function isNativeControl(t) {
|
|
4343
|
+
const el = t;
|
|
4344
|
+
return !!el && NATIVE_CONTROL_TAGS.has(el.tagName);
|
|
4345
|
+
}
|
|
4346
|
+
function keepsOwnMouseDown(t) {
|
|
4347
|
+
const el = t;
|
|
4348
|
+
return !!el && (NATIVE_CONTROL_TAGS.has(el.tagName) || el.tagName === "BUTTON");
|
|
4349
|
+
}
|
|
4284
4350
|
var IMAGE_LAYOUT_OPTIONS = [
|
|
4285
4351
|
{ value: "inline", label: "\u2194", title: "Inline (no fluxo do texto)" },
|
|
4286
4352
|
{ value: "wrap-left", label: "\u25E7", title: "Texto contorna \xE0 direita" },
|
|
@@ -4313,10 +4379,7 @@ function Toolbar({ className }) {
|
|
|
4313
4379
|
const blockAlign = getAlign();
|
|
4314
4380
|
const blockDir = getBlockAttr("dir");
|
|
4315
4381
|
const stop = (e) => {
|
|
4316
|
-
|
|
4317
|
-
if (t && (t.tagName === "SELECT" || t.tagName === "INPUT" || t.tagName === "OPTION")) {
|
|
4318
|
-
return;
|
|
4319
|
-
}
|
|
4382
|
+
if (isNativeControl(e.target)) return;
|
|
4320
4383
|
e.preventDefault();
|
|
4321
4384
|
};
|
|
4322
4385
|
const onToggle = (name) => (e) => {
|
|
@@ -4326,6 +4389,9 @@ function Toolbar({ className }) {
|
|
|
4326
4389
|
const onColorChange = (e) => {
|
|
4327
4390
|
setMark("color", e.target.value);
|
|
4328
4391
|
};
|
|
4392
|
+
const onHighlightChange = (e) => {
|
|
4393
|
+
setMark("highlight", e.target.value);
|
|
4394
|
+
};
|
|
4329
4395
|
const onFontFamilyChange = (e) => {
|
|
4330
4396
|
const v = e.target.value;
|
|
4331
4397
|
if (v === "") removeMark("fontFamily");
|
|
@@ -4390,6 +4456,7 @@ function Toolbar({ className }) {
|
|
|
4390
4456
|
[active.link, editor, removeMark, setMark]
|
|
4391
4457
|
);
|
|
4392
4458
|
const colorValue = typeof active.color === "string" ? active.color : "#000000";
|
|
4459
|
+
const highlightValue = typeof active.highlight === "string" ? active.highlight : "#fff176";
|
|
4393
4460
|
const fontFamilyValue = typeof active.fontFamily === "string" ? active.fontFamily : "";
|
|
4394
4461
|
const fontSizeValue = typeof active.fontSize === "string" ? active.fontSize : "";
|
|
4395
4462
|
const blockValue = blockSelectValue(blockType, blockLevel);
|
|
@@ -4453,6 +4520,40 @@ function Toolbar({ className }) {
|
|
|
4453
4520
|
},
|
|
4454
4521
|
children: "\u232B"
|
|
4455
4522
|
}
|
|
4523
|
+
),
|
|
4524
|
+
/* @__PURE__ */ jsxs12("label", { className: "ed-toolbar-label", title: "Marca-texto", children: [
|
|
4525
|
+
/* @__PURE__ */ jsx13(
|
|
4526
|
+
"span",
|
|
4527
|
+
{
|
|
4528
|
+
className: "ed-toolbar-swatch ed-toolbar-swatch--highlight",
|
|
4529
|
+
"aria-hidden": true,
|
|
4530
|
+
style: { background: highlightValue }
|
|
4531
|
+
}
|
|
4532
|
+
),
|
|
4533
|
+
/* @__PURE__ */ jsx13(
|
|
4534
|
+
"input",
|
|
4535
|
+
{
|
|
4536
|
+
type: "color",
|
|
4537
|
+
value: highlightValue,
|
|
4538
|
+
onChange: onHighlightChange,
|
|
4539
|
+
onMouseDown: stop,
|
|
4540
|
+
"aria-label": "Marca-texto"
|
|
4541
|
+
}
|
|
4542
|
+
)
|
|
4543
|
+
] }),
|
|
4544
|
+
/* @__PURE__ */ jsx13(
|
|
4545
|
+
"button",
|
|
4546
|
+
{
|
|
4547
|
+
type: "button",
|
|
4548
|
+
className: "ed-toolbar-btn",
|
|
4549
|
+
title: "Remover marca-texto",
|
|
4550
|
+
onMouseDown: stop,
|
|
4551
|
+
onClick: (e) => {
|
|
4552
|
+
e.preventDefault();
|
|
4553
|
+
removeMark("highlight");
|
|
4554
|
+
},
|
|
4555
|
+
children: "\u232B"
|
|
4556
|
+
}
|
|
4456
4557
|
)
|
|
4457
4558
|
] }),
|
|
4458
4559
|
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
@@ -4582,7 +4683,10 @@ function Toolbar({ className }) {
|
|
|
4582
4683
|
children: "\u{1F517}"
|
|
4583
4684
|
}
|
|
4584
4685
|
) }),
|
|
4585
|
-
/* @__PURE__ */
|
|
4686
|
+
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4687
|
+
/* @__PURE__ */ jsx13(TableMenu, {}),
|
|
4688
|
+
/* @__PURE__ */ jsx13(AnswerLinesMenu, {})
|
|
4689
|
+
] }),
|
|
4586
4690
|
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4587
4691
|
/* @__PURE__ */ jsx13(
|
|
4588
4692
|
"button",
|
|
@@ -4668,6 +4772,99 @@ function Toolbar({ className }) {
|
|
|
4668
4772
|
}
|
|
4669
4773
|
);
|
|
4670
4774
|
}
|
|
4775
|
+
function AnswerLinesMenu() {
|
|
4776
|
+
const editor = useEditorContext();
|
|
4777
|
+
const [open, setOpen] = useState11(false);
|
|
4778
|
+
const [count, setCount] = useState11(5);
|
|
4779
|
+
const [spacing, setSpacing] = useState11(1.5);
|
|
4780
|
+
const rootRef = useRef12(null);
|
|
4781
|
+
useEffect10(() => {
|
|
4782
|
+
if (!open) return;
|
|
4783
|
+
const onDown = (e) => {
|
|
4784
|
+
if (!rootRef.current) return;
|
|
4785
|
+
if (rootRef.current.contains(e.target)) return;
|
|
4786
|
+
setOpen(false);
|
|
4787
|
+
};
|
|
4788
|
+
document.addEventListener("mousedown", onDown);
|
|
4789
|
+
return () => document.removeEventListener("mousedown", onDown);
|
|
4790
|
+
}, [open]);
|
|
4791
|
+
const clamped = Math.max(1, Math.min(ANSWER_LINE_MAX, Math.trunc(count) || 1));
|
|
4792
|
+
return /* @__PURE__ */ jsxs12("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
|
|
4793
|
+
/* @__PURE__ */ jsx13(
|
|
4794
|
+
"button",
|
|
4795
|
+
{
|
|
4796
|
+
type: "button",
|
|
4797
|
+
className: "ed-toolbar-btn",
|
|
4798
|
+
title: "Linhas de resposta",
|
|
4799
|
+
"aria-pressed": open,
|
|
4800
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4801
|
+
onClick: (e) => {
|
|
4802
|
+
e.preventDefault();
|
|
4803
|
+
setOpen((v) => !v);
|
|
4804
|
+
},
|
|
4805
|
+
children: "\u2630"
|
|
4806
|
+
}
|
|
4807
|
+
),
|
|
4808
|
+
open && /* @__PURE__ */ jsxs12(
|
|
4809
|
+
"div",
|
|
4810
|
+
{
|
|
4811
|
+
className: "ed-table-popover ed-answerlines-popover",
|
|
4812
|
+
role: "menu",
|
|
4813
|
+
onMouseDown: (e) => {
|
|
4814
|
+
if (!keepsOwnMouseDown(e.target)) e.preventDefault();
|
|
4815
|
+
},
|
|
4816
|
+
children: [
|
|
4817
|
+
/* @__PURE__ */ jsxs12("label", { className: "ed-toolbar-label", children: [
|
|
4818
|
+
"Quantidade",
|
|
4819
|
+
/* @__PURE__ */ jsx13(
|
|
4820
|
+
"input",
|
|
4821
|
+
{
|
|
4822
|
+
type: "number",
|
|
4823
|
+
min: 1,
|
|
4824
|
+
max: ANSWER_LINE_MAX,
|
|
4825
|
+
value: count,
|
|
4826
|
+
onChange: (e) => setCount(Number(e.target.value)),
|
|
4827
|
+
"aria-label": "Quantidade de linhas"
|
|
4828
|
+
}
|
|
4829
|
+
)
|
|
4830
|
+
] }),
|
|
4831
|
+
/* @__PURE__ */ jsxs12("label", { className: "ed-toolbar-label", children: [
|
|
4832
|
+
"Entrelinha",
|
|
4833
|
+
/* @__PURE__ */ jsxs12(
|
|
4834
|
+
"select",
|
|
4835
|
+
{
|
|
4836
|
+
value: String(spacing),
|
|
4837
|
+
onChange: (e) => setSpacing(Number(e.target.value)),
|
|
4838
|
+
"aria-label": "Entrelinha",
|
|
4839
|
+
children: [
|
|
4840
|
+
/* @__PURE__ */ jsx13("option", { value: "1", children: "Simples" }),
|
|
4841
|
+
/* @__PURE__ */ jsx13("option", { value: "1.5", children: "1,5" }),
|
|
4842
|
+
/* @__PURE__ */ jsx13("option", { value: "2", children: "Duplo" })
|
|
4843
|
+
]
|
|
4844
|
+
}
|
|
4845
|
+
)
|
|
4846
|
+
] }),
|
|
4847
|
+
/* @__PURE__ */ jsxs12(
|
|
4848
|
+
"button",
|
|
4849
|
+
{
|
|
4850
|
+
type: "button",
|
|
4851
|
+
onClick: () => {
|
|
4852
|
+
setOpen(false);
|
|
4853
|
+
editor.insertAnswerLines(clamped, spacing);
|
|
4854
|
+
},
|
|
4855
|
+
children: [
|
|
4856
|
+
"Inserir ",
|
|
4857
|
+
clamped,
|
|
4858
|
+
" linha",
|
|
4859
|
+
clamped > 1 ? "s" : ""
|
|
4860
|
+
]
|
|
4861
|
+
}
|
|
4862
|
+
)
|
|
4863
|
+
]
|
|
4864
|
+
}
|
|
4865
|
+
)
|
|
4866
|
+
] });
|
|
4867
|
+
}
|
|
4671
4868
|
function TableMenu() {
|
|
4672
4869
|
const editor = useEditorContext();
|
|
4673
4870
|
const inTable = editor.isInTable();
|
|
@@ -4705,10 +4902,7 @@ function TableMenu() {
|
|
|
4705
4902
|
className: "ed-table-popover",
|
|
4706
4903
|
role: "menu",
|
|
4707
4904
|
onMouseDown: (e) => {
|
|
4708
|
-
|
|
4709
|
-
if (!t || t.tagName !== "INPUT" && t.tagName !== "BUTTON") {
|
|
4710
|
-
e.preventDefault();
|
|
4711
|
-
}
|
|
4905
|
+
if (!keepsOwnMouseDown(e.target)) e.preventDefault();
|
|
4712
4906
|
},
|
|
4713
4907
|
children: [
|
|
4714
4908
|
/* @__PURE__ */ jsx13(
|
|
@@ -4796,6 +4990,56 @@ function TableMenu() {
|
|
|
4796
4990
|
editor.setCellBackground(null);
|
|
4797
4991
|
}, children: "Remover cor de fundo" }),
|
|
4798
4992
|
/* @__PURE__ */ jsx13("hr", {}),
|
|
4993
|
+
/* @__PURE__ */ jsxs12("label", { className: "ed-toolbar-label", children: [
|
|
4994
|
+
"Bordas",
|
|
4995
|
+
/* @__PURE__ */ jsxs12(
|
|
4996
|
+
"select",
|
|
4997
|
+
{
|
|
4998
|
+
value: editor.getTableBorderPreset(),
|
|
4999
|
+
onChange: (e) => editor.setTableBorderPreset(e.target.value),
|
|
5000
|
+
"aria-label": "Bordas da tabela",
|
|
5001
|
+
children: [
|
|
5002
|
+
/* @__PURE__ */ jsx13("option", { value: "all", children: "Todas" }),
|
|
5003
|
+
/* @__PURE__ */ jsx13("option", { value: "outer", children: "S\xF3 externas" }),
|
|
5004
|
+
/* @__PURE__ */ jsx13("option", { value: "horizontal", children: "S\xF3 horizontais" }),
|
|
5005
|
+
/* @__PURE__ */ jsx13("option", { value: "vertical", children: "S\xF3 verticais" }),
|
|
5006
|
+
/* @__PURE__ */ jsx13("option", { value: "none", children: "Nenhuma" })
|
|
5007
|
+
]
|
|
5008
|
+
}
|
|
5009
|
+
)
|
|
5010
|
+
] }),
|
|
5011
|
+
/* @__PURE__ */ jsxs12("label", { className: "ed-toolbar-label ed-table-bgcolor", children: [
|
|
5012
|
+
/* @__PURE__ */ jsx13(
|
|
5013
|
+
"span",
|
|
5014
|
+
{
|
|
5015
|
+
className: "ed-toolbar-swatch",
|
|
5016
|
+
"aria-hidden": true,
|
|
5017
|
+
style: { background: editor.getTableBorderColor() ?? TABLE_BORDER_COLOR }
|
|
5018
|
+
}
|
|
5019
|
+
),
|
|
5020
|
+
"Cor da borda",
|
|
5021
|
+
/* @__PURE__ */ jsx13(
|
|
5022
|
+
"input",
|
|
5023
|
+
{
|
|
5024
|
+
type: "color",
|
|
5025
|
+
value: editor.getTableBorderColor() ?? TABLE_BORDER_COLOR,
|
|
5026
|
+
onChange: (e) => editor.setTableBorderColor(e.target.value),
|
|
5027
|
+
"aria-label": "Cor da borda"
|
|
5028
|
+
}
|
|
5029
|
+
)
|
|
5030
|
+
] }),
|
|
5031
|
+
/* @__PURE__ */ jsx13(
|
|
5032
|
+
"button",
|
|
5033
|
+
{
|
|
5034
|
+
type: "button",
|
|
5035
|
+
onClick: () => {
|
|
5036
|
+
setOpen(false);
|
|
5037
|
+
editor.setTableBorderColor(null);
|
|
5038
|
+
},
|
|
5039
|
+
children: "Restaurar cor padr\xE3o"
|
|
5040
|
+
}
|
|
5041
|
+
),
|
|
5042
|
+
/* @__PURE__ */ jsx13("hr", {}),
|
|
4799
5043
|
/* @__PURE__ */ jsx13(
|
|
4800
5044
|
"button",
|
|
4801
5045
|
{
|