smartrte-react 1.0.0-beta.13 → 1.0.0-beta.15
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.15
|
|
4
|
+
|
|
5
|
+
- The Blockquote toolbar button now shows as active (pressed) when the caret is inside a blockquote, matching every other toggle-style tool (Bold, Bulleted list, etc.) — previously it never reflected caret/selection state at all.
|
|
6
|
+
|
|
7
|
+
## 1.0.0-beta.14
|
|
8
|
+
|
|
9
|
+
- Fix toolbar dropdowns still landing far from their trigger inside a dialog centered via the standalone CSS `translate` property (e.g. Tailwind's `translate-x-[-50%] translate-y-[-50%]` compiled to `translate` rather than the legacy `transform` property, depending on Tailwind/browser version) — `findFixedPositioningContainer` only checked `transform`, missing that `translate`/`rotate`/`scale` (CSS Transforms Level 2's independent transform properties) each independently establish a `position: fixed` containing block too. Root-caused via a live console diagnostic against the real page rather than guessing. See `docs/bugs/toolbar-overlay-misplaced-standalone-translate-property.md`.
|
|
10
|
+
|
|
3
11
|
## 1.0.0-beta.13
|
|
4
12
|
|
|
5
13
|
- Fix toolbar dropdowns still landing far from their trigger inside a dialog whose ancestor uses `contain: layout` without `paint` — `1.0.0-beta.11`'s `contain` fix only checked for `paint`/`strict`/`content`, missing that bare `layout` alone also establishes a `position: fixed` containing block per spec (confirmed directly in real Chromium). Menus rendered hundreds of pixels from their trigger, overlapping unrelated page content, with no error. See `docs/bugs/toolbar-overlay-misplaced-inside-contain-layout-ancestor.md`.
|
|
@@ -501,6 +501,10 @@ export const CanonicalAuthorityEditor = forwardRef(function CanonicalAuthorityEd
|
|
|
501
501
|
return "paragraph";
|
|
502
502
|
};
|
|
503
503
|
const currentBlockType = blockTypeAt(runtime.editor.selection.head);
|
|
504
|
+
// Mirrors toggleBlockquote's own ancestor lookup exactly, so "the button
|
|
505
|
+
// looks active" and "clicking it again unwraps" can never drift apart -
|
|
506
|
+
// same discipline as listStyleActive for the list toggle buttons.
|
|
507
|
+
const currentBlockquoteActive = Boolean([...runtime.editor.resolve({ pos: runtime.editor.selection.head }).ancestors].reverse().find((node) => node.type === "blockquote"));
|
|
504
508
|
const currentListPreset = currentListParts.length === 1 && typeof rootList?.attrs?.preset === "string"
|
|
505
509
|
? rootList.attrs.preset
|
|
506
510
|
: "";
|
|
@@ -1633,7 +1637,7 @@ export const CanonicalAuthorityEditor = forwardRef(function CanonicalAuthorityEd
|
|
|
1633
1637
|
} }), t.fontSize && _jsx(ToolbarButton, { icon: "fontSize", label: "Font size", disabled: readOnly, onClick: () => applyAttributedMark("fontSize"), widePromote: true }), t.fontFamily && _jsx(ToolbarButton, { icon: "fontFamily", label: "Font family", disabled: readOnly, onClick: () => applyAttributedMark("fontFamily"), widePromote: true }), showMoreTextStyles && _jsx(ToolbarDropdown, { icon: "textColor", label: "More text styles", priority: 2, children: textStylesMenuItems })] }), _jsxs(ToolbarGroup, { children: [t.blockType && _jsxs("select", { className: "srte-block-type-select", "aria-label": "Block type", title: "Block type", value: currentBlockType, disabled: readOnly, onChange: (event) => transactBlock(setBlockTypeCommand(runtime.editor.document, blockScope(), {
|
|
1634
1638
|
type: event.target.value === "paragraph" ? "paragraph" : event.target.value === "code_block" ? "code_block" : "heading",
|
|
1635
1639
|
attrs: event.target.value.startsWith("heading-") ? { level: Number(event.target.value.slice(8)) } : {},
|
|
1636
|
-
}, blockContext())), children: [_jsx("option", { value: "paragraph", children: "Paragraph" }), Array.from({ length: 6 }, (_, index) => _jsxs("option", { value: `heading-${index + 1}`, children: ["Heading ", index + 1] }, index + 1)), _jsx("option", { value: "code_block", children: "Code block" })] }), t.alignLeft && _jsx(ToolbarButton, { icon: "alignLeft", label: "Align left", ariaLabel: "Align left", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "left" } }, blockContext())) }), t.alignCenter && _jsx(ToolbarButton, { icon: "alignCenter", label: "Align center", ariaLabel: "Align center", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "center" } }, blockContext())) }), t.alignRight && _jsx(ToolbarButton, { icon: "alignRight", label: "Align right", ariaLabel: "Align right", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "right" } }, blockContext())) }), t.alignJustify && _jsx(ToolbarButton, { icon: "alignJustify", label: "Justify", ariaLabel: "Align justify", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "justify" } }, blockContext())) }), t.lineHeight && _jsx(ToolbarDropdown, { icon: "lineHeight", label: "Line spacing", priority: 2, children: lineHeightMenuItems }), t.quote && _jsx(ToolbarButton, { icon: "quote", label: "Quote", ariaLabel: "Blockquote", disabled: readOnly, onClick: toggleBlockquote }), _jsx(ToolbarDropdown, { icon: "moveUp", label: "More paragraph tools", priority: 2, children: paragraphToolsMenuItems })] }), _jsxs(ToolbarGroup, { children: [t.bulletedList && (t.listPreset ? _jsxs("span", { className: "srte-split-control", children: [_jsx(ToolbarButton, { icon: "bulletedList", label: "Bulleted list", ariaLabel: "Bulleted list", pressed: listStyleActive("disc"), disabled: readOnly, narrowIconOnly: true, onClick: () => toggleList("disc") }), _jsxs("select", { "aria-label": "Bulleted list style", title: "Bulleted list style", disabled: readOnly || (currentListScope.kind === "list-selection" && currentListParts.length !== 1), value: currentBulletPreset, onChange: (event) => { const preset = event.target.value; if (preset)
|
|
1640
|
+
}, blockContext())), children: [_jsx("option", { value: "paragraph", children: "Paragraph" }), Array.from({ length: 6 }, (_, index) => _jsxs("option", { value: `heading-${index + 1}`, children: ["Heading ", index + 1] }, index + 1)), _jsx("option", { value: "code_block", children: "Code block" })] }), t.alignLeft && _jsx(ToolbarButton, { icon: "alignLeft", label: "Align left", ariaLabel: "Align left", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "left" } }, blockContext())) }), t.alignCenter && _jsx(ToolbarButton, { icon: "alignCenter", label: "Align center", ariaLabel: "Align center", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "center" } }, blockContext())) }), t.alignRight && _jsx(ToolbarButton, { icon: "alignRight", label: "Align right", ariaLabel: "Align right", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "right" } }, blockContext())) }), t.alignJustify && _jsx(ToolbarButton, { icon: "alignJustify", label: "Justify", ariaLabel: "Align justify", iconOnly: true, disabled: readOnly, onClick: () => transactBlock(setBlockAttributes(runtime.editor.document, blockScope(), { attrs: { align: "justify" } }, blockContext())) }), t.lineHeight && _jsx(ToolbarDropdown, { icon: "lineHeight", label: "Line spacing", priority: 2, children: lineHeightMenuItems }), t.quote && _jsx(ToolbarButton, { icon: "quote", label: "Quote", ariaLabel: "Blockquote", pressed: currentBlockquoteActive, disabled: readOnly, onClick: toggleBlockquote }), _jsx(ToolbarDropdown, { icon: "moveUp", label: "More paragraph tools", priority: 2, children: paragraphToolsMenuItems })] }), _jsxs(ToolbarGroup, { children: [t.bulletedList && (t.listPreset ? _jsxs("span", { className: "srte-split-control", children: [_jsx(ToolbarButton, { icon: "bulletedList", label: "Bulleted list", ariaLabel: "Bulleted list", pressed: listStyleActive("disc"), disabled: readOnly, narrowIconOnly: true, onClick: () => toggleList("disc") }), _jsxs("select", { "aria-label": "Bulleted list style", title: "Bulleted list style", disabled: readOnly || (currentListScope.kind === "list-selection" && currentListParts.length !== 1), value: currentBulletPreset, onChange: (event) => { const preset = event.target.value; if (preset)
|
|
1637
1641
|
applyListPreset(preset); }, children: [_jsx("option", { value: "", children: "Bulleted list style" }), SMART_LIST_PRESETS.filter((preset) => preset.kind === "bullet").map((preset) => _jsx("option", { value: preset.id, children: preset.label }, preset.id))] })] }) : _jsx(ToolbarButton, { icon: "bulletedList", label: "Bulleted list", ariaLabel: "Bulleted list", pressed: listStyleActive("disc"), disabled: readOnly, narrowIconOnly: true, onClick: () => toggleList("disc") })), t.numberedList && (t.listPreset ? _jsxs("span", { className: "srte-split-control", children: [_jsx(ToolbarButton, { icon: "numberedList", label: "Numbered list", ariaLabel: "Numbered list", pressed: listStyleActive("decimal"), disabled: readOnly, narrowIconOnly: true, onClick: () => toggleList("decimal") }), _jsxs("select", { "aria-label": "Numbered list style", title: "Numbered list style", disabled: readOnly || (currentListScope.kind === "list-selection" && currentListParts.length !== 1), value: currentOrderedPreset, onChange: (event) => { const preset = event.target.value; if (preset)
|
|
1638
1642
|
applyListPreset(preset); }, children: [_jsx("option", { value: "", children: "Numbered list style" }), SMART_LIST_PRESETS.filter((preset) => preset.kind === "ordered").map((preset) => _jsx("option", { value: preset.id, children: preset.label }, preset.id))] })] }) : _jsx(ToolbarButton, { icon: "numberedList", label: "Numbered list", ariaLabel: "Numbered list", pressed: listStyleActive("decimal"), disabled: readOnly, narrowIconOnly: true, onClick: () => toggleList("decimal") })), t.checklist && _jsx(ToolbarButton, { icon: "checklist", label: "Checklist", ariaLabel: "Checklist", pressed: listStyleActive("disc", true), disabled: readOnly, narrowIconOnly: true, onClick: () => toggleList("disc", true) }), _jsxs(ToolbarDropdown, { icon: "restart", label: "More list tools", priority: 2, children: [listPresetSelect, t.listPreset && _jsx("div", { className: "srte-menu-separator" }), listToolsMenuItems] })] }), _jsxs(ToolbarGroup, { children: [t.link && _jsx(ToolbarButton, { icon: "link", label: "Link", ariaLabel: "Insert or edit link", disabled: readOnly, onClick: openLinkPopover }), showImageTool && _jsx(ToolbarButton, { icon: "image", label: "Image", ariaLabel: "Insert image", disabled: readOnly, onClick: () => setMediaKind("image") }), t.removeLink && _jsx(ToolbarButton, { icon: "unlink", label: "Remove link", disabled: readOnly, onClick: removeLink, widePromote: true }), t.insertFormula && _jsx(ToolbarButton, { icon: "formula", label: "Insert formula", disabled: readOnly, widePromote: true, onClick: (event) => {
|
|
1639
1643
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
* (`translate-x-[-50%] translate-y-[-50%]`), confirmed live via a Sootr
|
|
10
10
|
* host rendering the editor inside such a dialog
|
|
11
11
|
* (docs/bugs/toolbar-menu-misplaced-inside-transformed-ancestor.md).
|
|
12
|
+
* - `translate`, `rotate`, `scale` (CSS Transforms Level 2's *independent*
|
|
13
|
+
* transform properties, distinct from the legacy composite `transform`
|
|
14
|
+
* property) - a FOURTH real Sootr dialog kept misplacing every dropdown
|
|
15
|
+
* after all three fixes above shipped, still using the exact same
|
|
16
|
+
* `translate-x-[-50%] translate-y-[-50%]` Tailwind centering classes the
|
|
17
|
+
* very first fix (above) was written for - but a current Tailwind/browser
|
|
18
|
+
* combination compiles those classes to the standalone `translate: -50%
|
|
19
|
+
* -50%` CSS property, not `transform: translate(-50%, -50%)`. Confirmed
|
|
20
|
+
* directly in real Chromium: an ancestor with only `translate` set (its
|
|
21
|
+
* own computed `transform` reads `none`) still fully establishes a
|
|
22
|
+
* `position: fixed` containing block, per the CSS Transforms Level 2
|
|
23
|
+
* spec - the original fix's own doc comment described the right *symptom*
|
|
24
|
+
* (a Radix/shadcn Dialog's centering translate) but checked the wrong
|
|
25
|
+
* *property* for it, because at the time it was written the transform
|
|
26
|
+
* ended up composited into `transform` rather than emitted as `translate`
|
|
27
|
+
* directly. Both are checked now, since either can appear depending on
|
|
28
|
+
* the host's exact Tailwind/browser version.
|
|
12
29
|
* - `contain: layout | paint | strict | content` (CSS Containment) - a
|
|
13
30
|
* common perf/isolation optimization on large scrollable containers, e.g.
|
|
14
31
|
* a second, different Sootr dialog reported still misplacing every
|
|
@@ -69,8 +86,9 @@ export declare function getFixedPositioningOrigin(el: HTMLElement): {
|
|
|
69
86
|
* the actual, much narrower, clipping ancestor.
|
|
70
87
|
*
|
|
71
88
|
* Deliberately NOT applied for a containing block established only by
|
|
72
|
-
* `transform`/`perspective`/`filter
|
|
73
|
-
* `contain: layout` with no
|
|
89
|
+
* `transform`/`translate`/`rotate`/`scale`/`perspective`/`filter`/
|
|
90
|
+
* `backdrop-filter`/`will-change`, or by `contain: layout` with no
|
|
91
|
+
* `paint`/`strict`/`content` alongside it - none
|
|
74
92
|
* of those clip overflow (`layout` containment only isolates layout
|
|
75
93
|
* calculations, it does not imply paint containment - see the spec note
|
|
76
94
|
* above `findFixedPositioningContainer`), so a menu is free to visually
|
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
* (`translate-x-[-50%] translate-y-[-50%]`), confirmed live via a Sootr
|
|
10
10
|
* host rendering the editor inside such a dialog
|
|
11
11
|
* (docs/bugs/toolbar-menu-misplaced-inside-transformed-ancestor.md).
|
|
12
|
+
* - `translate`, `rotate`, `scale` (CSS Transforms Level 2's *independent*
|
|
13
|
+
* transform properties, distinct from the legacy composite `transform`
|
|
14
|
+
* property) - a FOURTH real Sootr dialog kept misplacing every dropdown
|
|
15
|
+
* after all three fixes above shipped, still using the exact same
|
|
16
|
+
* `translate-x-[-50%] translate-y-[-50%]` Tailwind centering classes the
|
|
17
|
+
* very first fix (above) was written for - but a current Tailwind/browser
|
|
18
|
+
* combination compiles those classes to the standalone `translate: -50%
|
|
19
|
+
* -50%` CSS property, not `transform: translate(-50%, -50%)`. Confirmed
|
|
20
|
+
* directly in real Chromium: an ancestor with only `translate` set (its
|
|
21
|
+
* own computed `transform` reads `none`) still fully establishes a
|
|
22
|
+
* `position: fixed` containing block, per the CSS Transforms Level 2
|
|
23
|
+
* spec - the original fix's own doc comment described the right *symptom*
|
|
24
|
+
* (a Radix/shadcn Dialog's centering translate) but checked the wrong
|
|
25
|
+
* *property* for it, because at the time it was written the transform
|
|
26
|
+
* ended up composited into `transform` rather than emitted as `translate`
|
|
27
|
+
* directly. Both are checked now, since either can appear depending on
|
|
28
|
+
* the host's exact Tailwind/browser version.
|
|
12
29
|
* - `contain: layout | paint | strict | content` (CSS Containment) - a
|
|
13
30
|
* common perf/isolation optimization on large scrollable containers, e.g.
|
|
14
31
|
* a second, different Sootr dialog reported still misplacing every
|
|
@@ -52,10 +69,13 @@ export function findFixedPositioningContainer(el) {
|
|
|
52
69
|
while (node) {
|
|
53
70
|
const style = window.getComputedStyle(node);
|
|
54
71
|
if ((style.transform && style.transform !== "none") ||
|
|
72
|
+
(style.translate && style.translate !== "none") ||
|
|
73
|
+
(style.rotate && style.rotate !== "none") ||
|
|
74
|
+
(style.scale && style.scale !== "none") ||
|
|
55
75
|
(style.perspective && style.perspective !== "none") ||
|
|
56
76
|
(style.filter && style.filter !== "none") ||
|
|
57
77
|
(style.backdropFilter && style.backdropFilter !== "none") ||
|
|
58
|
-
(style.willChange && /transform|perspective|filter/.test(style.willChange)) ||
|
|
78
|
+
(style.willChange && /transform|perspective|filter|translate|rotate|scale/.test(style.willChange)) ||
|
|
59
79
|
(style.contain && /\b(layout|paint|strict|content)\b/.test(style.contain))) {
|
|
60
80
|
return node;
|
|
61
81
|
}
|
|
@@ -87,8 +107,9 @@ export function getFixedPositioningOrigin(el) {
|
|
|
87
107
|
* the actual, much narrower, clipping ancestor.
|
|
88
108
|
*
|
|
89
109
|
* Deliberately NOT applied for a containing block established only by
|
|
90
|
-
* `transform`/`perspective`/`filter
|
|
91
|
-
* `contain: layout` with no
|
|
110
|
+
* `transform`/`translate`/`rotate`/`scale`/`perspective`/`filter`/
|
|
111
|
+
* `backdrop-filter`/`will-change`, or by `contain: layout` with no
|
|
112
|
+
* `paint`/`strict`/`content` alongside it - none
|
|
92
113
|
* of those clip overflow (`layout` containment only isolates layout
|
|
93
114
|
* calculations, it does not imply paint containment - see the spec note
|
|
94
115
|
* above `findFixedPositioningContainer`), so a menu is free to visually
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smartrte-react",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.15",
|
|
4
4
|
"description": "A powerful, feature-rich Rich Text Editor for React with support for tables, mathematical formulas (LaTeX/KaTeX), and media management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"lucide-react": "^1.35.0",
|
|
85
85
|
"mammoth": "^1.11.0",
|
|
86
86
|
"pdfjs-dist": "^5.4.530",
|
|
87
|
-
"smartrte-core": "^1.0.0-beta.
|
|
87
|
+
"smartrte-core": "^1.0.0-beta.8"
|
|
88
88
|
},
|
|
89
89
|
"scripts": {
|
|
90
90
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|