@kubex/zinc 1.1.100 → 1.1.102
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/custom-elements.json +260 -81
- package/dist/vscode.html-custom-data.json +13 -13
- package/dist/web-types.json +25 -25
- package/dist/zn.d.ts +124 -4
- package/dist/zn.min.js +359 -282
- package/docs/pages/components/remarkd-editor.md +59 -0
- package/package.json +1 -1
- package/src/components/menu/menu.component.ts +4 -1
- package/src/components/menu/menu.scss +3 -0
- package/src/components/page/page.scss +14 -2
- package/src/components/remarkd-editor/actions.ts +159 -0
- package/src/components/remarkd-editor/feature-keys.ts +17 -0
- package/src/components/remarkd-editor/remarkd-editor.component.ts +509 -49
- package/src/components/remarkd-editor/remarkd-editor.scss +68 -1
- package/src/components/remarkd-editor/remarkd-editor.test.ts +675 -9
- package/src/components/slash-menu/slash-menu.scss +2 -0
- package/src/internal/toolbar-overflow.ts +100 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {ResizeController} from '@lit-labs/observers/resize-controller.js';
|
|
2
|
+
import type {ReactiveController, ReactiveControllerHost} from 'lit';
|
|
3
|
+
|
|
4
|
+
interface ToolbarOverflowOptions {
|
|
5
|
+
/** The measurable group elements, in toolbar order. */
|
|
6
|
+
groups: () => HTMLElement[];
|
|
7
|
+
/** The element whose width the groups have to fit inside. */
|
|
8
|
+
container: () => HTMLElement | null | undefined;
|
|
9
|
+
/** Space to keep for the overflow trigger. Defaults to 44px. */
|
|
10
|
+
reserve?: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Reports how many leading toolbar groups fit the container, so the host can render the
|
|
15
|
+
* rest into an overflow menu. Two passes: the first ignores the trigger, because when
|
|
16
|
+
* everything fits there is no trigger to make room for.
|
|
17
|
+
*/
|
|
18
|
+
export class ToolbarOverflowController implements ReactiveController {
|
|
19
|
+
visibleCount = Infinity;
|
|
20
|
+
|
|
21
|
+
private readonly host: ReactiveControllerHost & Element;
|
|
22
|
+
private readonly options: ToolbarOverflowOptions;
|
|
23
|
+
private resizeRafId = 0;
|
|
24
|
+
|
|
25
|
+
constructor(host: ReactiveControllerHost & Element, options: ToolbarOverflowOptions) {
|
|
26
|
+
this.host = host;
|
|
27
|
+
this.options = options;
|
|
28
|
+
host.addController(this);
|
|
29
|
+
// Deferred to a rAF rather than measuring inline: measure() mutates the display of
|
|
30
|
+
// elements inside the observed host, and doing that synchronously in the observer's own
|
|
31
|
+
// callback is what trips "ResizeObserver loop completed with undelivered notifications"
|
|
32
|
+
// (fatal in WebKit's test runner, not just a console warning). Same fix as button-menu.
|
|
33
|
+
// eslint-disable-next-line no-new -- ResizeController registers itself with the host.
|
|
34
|
+
new ResizeController(host, {
|
|
35
|
+
callback: () => {
|
|
36
|
+
if (this.resizeRafId) return;
|
|
37
|
+
this.resizeRafId = requestAnimationFrame(() => {
|
|
38
|
+
this.resizeRafId = 0;
|
|
39
|
+
this.measure();
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
hostUpdated() {
|
|
46
|
+
this.measure();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private measure() {
|
|
50
|
+
const groups = this.options.groups();
|
|
51
|
+
const container = this.options.container();
|
|
52
|
+
if (!groups.length || !container) return;
|
|
53
|
+
|
|
54
|
+
// clientWidth includes the container's own padding, so it has to come back out — and so
|
|
55
|
+
// does any non-group sibling (the raw-source toggle, or the trigger itself once it
|
|
56
|
+
// exists) that is really sitting in the same row and eating into the same space. Without
|
|
57
|
+
// this, `total <= available` can read true while a sibling's real footprint still clips
|
|
58
|
+
// trailing groups off-screen with no trigger rendered to reach them.
|
|
59
|
+
const style = getComputedStyle(container);
|
|
60
|
+
const paddingX = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
|
|
61
|
+
const siblingsWidth = [...container.children]
|
|
62
|
+
.filter(child => !child.classList.contains('toolbar__group'))
|
|
63
|
+
.reduce((sum, child) => sum + child.getBoundingClientRect().width, 0);
|
|
64
|
+
const available = container.clientWidth - paddingX - siblingsWidth;
|
|
65
|
+
if (available <= 0) return;
|
|
66
|
+
|
|
67
|
+
// Show everything before measuring: a collapsed group measures 0, which would let the
|
|
68
|
+
// next pass re-expand it and oscillate forever. Same reason the editor toolbar resets
|
|
69
|
+
// display before each pass. Reads and writes stay in this frame, so nothing flickers.
|
|
70
|
+
groups.forEach(group => (group.style.display = ''));
|
|
71
|
+
const widths = groups.map(group => group.getBoundingClientRect().width);
|
|
72
|
+
const total = widths.reduce((sum, width) => sum + width, 0);
|
|
73
|
+
|
|
74
|
+
const next = total <= available
|
|
75
|
+
? groups.length
|
|
76
|
+
: this.countThatFit(widths, available - (this.options.reserve ?? 44));
|
|
77
|
+
|
|
78
|
+
groups.forEach((group, index) => (group.style.display = index < next ? '' : 'none'));
|
|
79
|
+
|
|
80
|
+
if (next !== this.visibleCount) {
|
|
81
|
+
this.visibleCount = next;
|
|
82
|
+
this.host.requestUpdate();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private countThatFit(widths: number[], available: number): number {
|
|
87
|
+
let used = 0;
|
|
88
|
+
let count = 0;
|
|
89
|
+
for (const width of widths) {
|
|
90
|
+
if (used + width > available) break;
|
|
91
|
+
used += width;
|
|
92
|
+
count++;
|
|
93
|
+
}
|
|
94
|
+
// No `Math.max(count, 1)` floor here: forcing at least one group into the bar when even
|
|
95
|
+
// that group alone doesn't fit `available` pushed the trigger past the host's own
|
|
96
|
+
// `overflow: hidden` edge — clipped and unreachable, not just visually tight. Zero visible
|
|
97
|
+
// groups is the correct answer in that case; every action still reaches the menu.
|
|
98
|
+
return count;
|
|
99
|
+
}
|
|
100
|
+
}
|