smartrte-react 1.0.0-beta.10 → 1.0.0-beta.11

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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0-beta.11
4
+
5
+ - Fix toolbar dropdowns/popovers still landing far from their trigger inside a host container that uses CSS `contain: paint | strict | content` on an ancestor (a real gap in `1.0.0-beta.9`'s transform-only fix — `contain` also creates a `position: fixed` containing block, independent of `transform`). See `docs/bugs/toolbar-overlay-misplaced-inside-contain-ancestor.md`.
6
+
3
7
  ## 1.0.0-beta.10
4
8
 
5
9
  - Fix a table row resize regression: dragging a row boundary back to where it started (after an earlier drag hit a row's natural content floor) inflated the neighboring row instead of restoring the original layout — the only way back was Undo. Reversing a boundary drag now correctly shrinks the table's total height instead of growing a neighbor that never actually had slack to give.
@@ -1,22 +1,39 @@
1
1
  /**
2
- * A CSS `transform`, `perspective`, `filter`, `backdrop-filter`, or a
3
- * `will-change` naming one of those, on an ancestor makes that ancestor the
4
- * containing block for `position: fixed` descendants instead of the
5
- * viewport (CSS Transforms spec's rendering model) - most commonly a
6
- * Radix/shadcn `Dialog`'s centering transform (`translate-x-[-50%]
7
- * translate-y-[-50%]`), which any host may legitimately wrap this editor
8
- * in. When that happens, `left`/`top` set on a fixed-positioned menu/popover
9
- * are resolved against that ancestor's border box (as rendered,
10
- * post-transform) instead of the viewport, silently producing coordinates
11
- * that are internally consistent but land far from the trigger with no
12
- * error - confirmed live via a Sootr host rendering the editor inside such
13
- * a dialog.
2
+ * Several unrelated CSS mechanisms make an ancestor the containing block for
3
+ * `position: fixed` descendants instead of the viewport, all covered here
4
+ * since any of them can appear independently on a real host page:
5
+ *
6
+ * - `transform`, `perspective`, `filter`, `backdrop-filter` (non-`none`), or
7
+ * a `will-change` naming one of those (CSS Transforms' rendering model) -
8
+ * most commonly a Radix/shadcn `Dialog`'s centering transform
9
+ * (`translate-x-[-50%] translate-y-[-50%]`), confirmed live via a Sootr
10
+ * host rendering the editor inside such a dialog
11
+ * (docs/bugs/toolbar-menu-misplaced-inside-transformed-ancestor.md).
12
+ * - `contain: paint | strict | content` (CSS Containment) - a common
13
+ * perf/isolation optimization on large scrollable containers, e.g. a
14
+ * second, different Sootr dialog reported still misplacing every toolbar
15
+ * dropdown ("More list tools", "More to insert", "Save a copy", "More
16
+ * text styles") despite already running the transform-only fix above.
17
+ *
18
+ * Deliberately NOT checking bare `container-type` (CSS Containers) -
19
+ * despite implying `contain: layout style` per spec, verified directly in
20
+ * real Chromium that `container-type: inline-size` alone does *not* make
21
+ * an ancestor a `position: fixed` containing block in practice (a
22
+ * position already correctly computed without any special-casing stayed
23
+ * correct; adding a check for it actively broke that same case). Only
24
+ * `contain` itself is checked, matching what's actually verified to
25
+ * matter, not everything that could theoretically imply it.
26
+ *
27
+ * When any of these apply, `left`/`top` set on a fixed-positioned menu/
28
+ * popover are resolved against that ancestor's border box instead of the
29
+ * viewport, silently producing coordinates that are internally consistent
30
+ * but land far from the trigger with no error.
14
31
  *
15
32
  * `getBoundingClientRect()` always returns viewport-relative coordinates
16
- * regardless of transforms, so every placement calculation in this codebase
17
- * computes coordinates in viewport space first, then subtracts this
18
- * origin - the real containing block's own viewport-relative top-left - so
19
- * the applied `left`/`top` land correctly under either containing block.
33
+ * regardless of any of the above, so every placement calculation in this
34
+ * codebase computes coordinates in viewport space first, then subtracts
35
+ * this origin - the real containing block's own viewport-relative top-left -
36
+ * so the applied `left`/`top` land correctly under any containing block.
20
37
  */
21
38
  export declare function findFixedPositioningContainer(el: HTMLElement): HTMLElement | null;
22
39
  export declare function getFixedPositioningOrigin(el: HTMLElement): {
@@ -1,22 +1,39 @@
1
1
  /**
2
- * A CSS `transform`, `perspective`, `filter`, `backdrop-filter`, or a
3
- * `will-change` naming one of those, on an ancestor makes that ancestor the
4
- * containing block for `position: fixed` descendants instead of the
5
- * viewport (CSS Transforms spec's rendering model) - most commonly a
6
- * Radix/shadcn `Dialog`'s centering transform (`translate-x-[-50%]
7
- * translate-y-[-50%]`), which any host may legitimately wrap this editor
8
- * in. When that happens, `left`/`top` set on a fixed-positioned menu/popover
9
- * are resolved against that ancestor's border box (as rendered,
10
- * post-transform) instead of the viewport, silently producing coordinates
11
- * that are internally consistent but land far from the trigger with no
12
- * error - confirmed live via a Sootr host rendering the editor inside such
13
- * a dialog.
2
+ * Several unrelated CSS mechanisms make an ancestor the containing block for
3
+ * `position: fixed` descendants instead of the viewport, all covered here
4
+ * since any of them can appear independently on a real host page:
5
+ *
6
+ * - `transform`, `perspective`, `filter`, `backdrop-filter` (non-`none`), or
7
+ * a `will-change` naming one of those (CSS Transforms' rendering model) -
8
+ * most commonly a Radix/shadcn `Dialog`'s centering transform
9
+ * (`translate-x-[-50%] translate-y-[-50%]`), confirmed live via a Sootr
10
+ * host rendering the editor inside such a dialog
11
+ * (docs/bugs/toolbar-menu-misplaced-inside-transformed-ancestor.md).
12
+ * - `contain: paint | strict | content` (CSS Containment) - a common
13
+ * perf/isolation optimization on large scrollable containers, e.g. a
14
+ * second, different Sootr dialog reported still misplacing every toolbar
15
+ * dropdown ("More list tools", "More to insert", "Save a copy", "More
16
+ * text styles") despite already running the transform-only fix above.
17
+ *
18
+ * Deliberately NOT checking bare `container-type` (CSS Containers) -
19
+ * despite implying `contain: layout style` per spec, verified directly in
20
+ * real Chromium that `container-type: inline-size` alone does *not* make
21
+ * an ancestor a `position: fixed` containing block in practice (a
22
+ * position already correctly computed without any special-casing stayed
23
+ * correct; adding a check for it actively broke that same case). Only
24
+ * `contain` itself is checked, matching what's actually verified to
25
+ * matter, not everything that could theoretically imply it.
26
+ *
27
+ * When any of these apply, `left`/`top` set on a fixed-positioned menu/
28
+ * popover are resolved against that ancestor's border box instead of the
29
+ * viewport, silently producing coordinates that are internally consistent
30
+ * but land far from the trigger with no error.
14
31
  *
15
32
  * `getBoundingClientRect()` always returns viewport-relative coordinates
16
- * regardless of transforms, so every placement calculation in this codebase
17
- * computes coordinates in viewport space first, then subtracts this
18
- * origin - the real containing block's own viewport-relative top-left - so
19
- * the applied `left`/`top` land correctly under either containing block.
33
+ * regardless of any of the above, so every placement calculation in this
34
+ * codebase computes coordinates in viewport space first, then subtracts
35
+ * this origin - the real containing block's own viewport-relative top-left -
36
+ * so the applied `left`/`top` land correctly under any containing block.
20
37
  */
21
38
  export function findFixedPositioningContainer(el) {
22
39
  let node = el.parentElement;
@@ -26,7 +43,8 @@ export function findFixedPositioningContainer(el) {
26
43
  (style.perspective && style.perspective !== "none") ||
27
44
  (style.filter && style.filter !== "none") ||
28
45
  (style.backdropFilter && style.backdropFilter !== "none") ||
29
- (style.willChange && /transform|perspective|filter/.test(style.willChange))) {
46
+ (style.willChange && /transform|perspective|filter/.test(style.willChange)) ||
47
+ (style.contain && /\b(paint|strict|content)\b/.test(style.contain))) {
30
48
  return node;
31
49
  }
32
50
  node = node.parentElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smartrte-react",
3
- "version": "1.0.0-beta.10",
3
+ "version": "1.0.0-beta.11",
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.5"
87
+ "smartrte-core": "^1.0.0-beta.6"
88
88
  },
89
89
  "scripts": {
90
90
  "build": "rm -rf dist && tsc -p tsconfig.json",