@rathkit/rte-ui 0.1.0-alpha.4 → 0.1.0-alpha.5

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @rathkit/rte-ui
2
2
 
3
- > **Alpha** (0.1.0-alpha.0). Not for production: the APIs will change between releases. Published to the `next` tag only.
3
+ > **Alpha.** Not for production: the APIs will change between releases. Published to the `next` tag only.
4
4
 
5
5
  The styled interface: a toolbar, menus, dialogs, find bar, status line and tooltips on the headless layer, with an optional selection toolbar and context menu, themeable by preset, tokens, icons, classes and messages.
6
6
 
package/css/base.css CHANGED
@@ -1,272 +1,272 @@
1
1
  /* @rathkit/rte-ui base styles. Everything is in cascade layers, so any CSS you write outside a layer wins without a specificity fight.
2
- Parts are addressed by data-rk-part, never by class; the only class is .rk-root, which scopes everything to one editor.
3
- Colors, sizes and fonts come from the --rk-* tokens (see @rathkit/rte-themes). Nothing here reaches outside .rk-root. */
2
+ Parts are addressed by data-rte-part, never by class; the only class is .rte-root, which scopes everything to one editor.
3
+ Colors, sizes and fonts come from the --rte-* tokens (see @rathkit/rte-themes). Nothing here reaches outside .rte-root. */
4
4
  @layer rathkit.defaults, rathkit.base;
5
5
 
6
6
  /* Light values, used only when no theme is chosen, so the editor is never unstyled. A theme's tokens replace them. */
7
7
  @layer rathkit.defaults {
8
- .rk-root:where(:not([data-rk-theme])) {
9
- --rk-bg: #ffffff; --rk-surface: #f4f6f9; --rk-surface-raised: #ffffff; --rk-fg: #14181f; --rk-fg-muted: #505b6b;
10
- --rk-border: #78849a; --rk-border-subtle: #d4dae3; --rk-accent: #17408b; --rk-accent-fg: #ffffff; --rk-accent-subtle: #e3ecfa;
11
- --rk-danger: #b3261e; --rk-selection-bg: #cddffa; --rk-control-hover: #e6ebf3; --rk-control-active: #d3dcec;
12
- --rk-brand: #b9812a; --rk-brand-text: #86590f; --rk-focus-color: #17408b;
13
- --rk-space-1: 4px; --rk-space-2: 8px; --rk-space-3: 12px; --rk-space-4: 16px; --rk-control-size: 32px;
14
- --rk-radius-s: 4px; --rk-radius-m: 8px; --rk-border-width: 1px; --rk-focus-width: 2px; --rk-focus-offset: 2px;
15
- --rk-font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --rk-font-content: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
16
- --rk-font-heading: system-ui, sans-serif; --rk-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
17
- --rk-font-size: 16px; --rk-line-height: 1.55; --rk-motion-duration: 120ms;
18
- --rk-shadow-popover: 0 6px 24px rgb(20 24 31 / 0.18), 0 1px 3px rgb(20 24 31 / 0.12);
8
+ .rte-root:where(:not([data-rte-theme])) {
9
+ --rte-bg: #ffffff; --rte-surface: #f4f6f9; --rte-surface-raised: #ffffff; --rte-fg: #14181f; --rte-fg-muted: #505b6b;
10
+ --rte-border: #78849a; --rte-border-subtle: #d4dae3; --rte-accent: #17408b; --rte-accent-fg: #ffffff; --rte-accent-subtle: #e3ecfa;
11
+ --rte-danger: #b3261e; --rte-selection-bg: #cddffa; --rte-control-hover: #e6ebf3; --rte-control-active: #d3dcec;
12
+ --rte-brand: #b9812a; --rte-brand-text: #86590f; --rte-focus-color: #17408b;
13
+ --rte-space-1: 4px; --rte-space-2: 8px; --rte-space-3: 12px; --rte-space-4: 16px; --rte-control-size: 32px;
14
+ --rte-radius-s: 4px; --rte-radius-m: 8px; --rte-border-width: 1px; --rte-focus-width: 2px; --rte-focus-offset: 2px;
15
+ --rte-font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --rte-font-content: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
16
+ --rte-font-heading: system-ui, sans-serif; --rte-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
17
+ --rte-font-size: 16px; --rte-line-height: 1.55; --rte-motion-duration: 120ms;
18
+ --rte-shadow-popover: 0 6px 24px rgb(20 24 31 / 0.18), 0 1px 3px rgb(20 24 31 / 0.12);
19
19
  color-scheme: light;
20
20
  }
21
21
  }
22
22
 
23
23
  @layer rathkit.base {
24
- .rk-root {
24
+ .rte-root {
25
25
  box-sizing: border-box;
26
26
  position: relative;
27
27
  display: flex;
28
28
  flex-direction: column;
29
- font: var(--rk-font-size) / var(--rk-line-height) var(--rk-font-ui);
30
- color: var(--rk-fg);
31
- background: var(--rk-bg);
32
- border: var(--rk-border-width) solid var(--rk-border);
33
- border-radius: var(--rk-radius-m);
29
+ font: var(--rte-font-size) / var(--rte-line-height) var(--rte-font-ui);
30
+ color: var(--rte-fg);
31
+ background: var(--rte-bg);
32
+ border: var(--rte-border-width) solid var(--rte-border);
33
+ border-radius: var(--rte-radius-m);
34
34
  }
35
- .rk-root *, .rk-root *::before, .rk-root *::after { box-sizing: inherit; }
35
+ .rte-root *, .rte-root *::before, .rte-root *::after { box-sizing: inherit; }
36
36
 
37
37
  /* ---- toolbar ---- */
38
- [data-rk-part="toolbar"] {
38
+ [data-rte-part="toolbar"] {
39
39
  display: flex;
40
40
  flex-wrap: wrap;
41
41
  align-items: center;
42
- gap: var(--rk-space-1);
43
- padding: var(--rk-space-2);
44
- background: var(--rk-surface);
45
- border-bottom: var(--rk-border-width) solid var(--rk-border);
46
- border-radius: calc(var(--rk-radius-m) - var(--rk-border-width)) calc(var(--rk-radius-m) - var(--rk-border-width)) 0 0;
42
+ gap: var(--rte-space-1);
43
+ padding: var(--rte-space-2);
44
+ background: var(--rte-surface);
45
+ border-bottom: var(--rte-border-width) solid var(--rte-border);
46
+ border-radius: calc(var(--rte-radius-m) - var(--rte-border-width)) calc(var(--rte-radius-m) - var(--rte-border-width)) 0 0;
47
47
  }
48
- [data-rk-part="separator"] {
48
+ [data-rte-part="separator"] {
49
49
  align-self: stretch;
50
- width: var(--rk-border-width);
51
- margin-inline: var(--rk-space-1);
52
- background: var(--rk-border-subtle);
50
+ width: var(--rte-border-width);
51
+ margin-inline: var(--rte-space-1);
52
+ background: var(--rte-border-subtle);
53
53
  }
54
- [data-rk-part="button"],
55
- [data-rk-part="select"] {
56
- min-width: var(--rk-control-size);
57
- height: var(--rk-control-size);
54
+ [data-rte-part="button"],
55
+ [data-rte-part="select"] {
56
+ min-width: var(--rte-control-size);
57
+ height: var(--rte-control-size);
58
58
  margin: 0;
59
- padding: 0 var(--rk-space-2);
59
+ padding: 0 var(--rte-space-2);
60
60
  font: inherit;
61
- color: var(--rk-fg);
61
+ color: var(--rte-fg);
62
62
  background: transparent;
63
- border: var(--rk-border-width) solid transparent;
64
- border-radius: var(--rk-radius-s);
63
+ border: var(--rte-border-width) solid transparent;
64
+ border-radius: var(--rte-radius-s);
65
65
  cursor: pointer;
66
- transition: background-color calc(var(--rk-motion-duration) * var(--rk-motion-scale, 1)) ease;
66
+ transition: background-color calc(var(--rte-motion-duration) * var(--rte-motion-scale, 1)) ease;
67
67
  }
68
- [data-rk-part="button"] { display: inline-flex; align-items: center; justify-content: center; gap: var(--rk-space-1); }
69
- [data-rk-part="select"] { background: var(--rk-surface-raised); border-color: var(--rk-border); }
70
- [data-rk-part="button"]:hover:not([aria-disabled="true"]),
71
- [data-rk-part="select"]:hover:not([aria-disabled="true"]) { background: var(--rk-control-hover); }
72
- [data-rk-part="button"]:active:not([aria-disabled="true"]) { background: var(--rk-control-active); }
68
+ [data-rte-part="button"] { display: inline-flex; align-items: center; justify-content: center; gap: var(--rte-space-1); }
69
+ [data-rte-part="select"] { background: var(--rte-surface-raised); border-color: var(--rte-border); }
70
+ [data-rte-part="button"]:hover:not([aria-disabled="true"]),
71
+ [data-rte-part="select"]:hover:not([aria-disabled="true"]) { background: var(--rte-control-hover); }
72
+ [data-rte-part="button"]:active:not([aria-disabled="true"]) { background: var(--rte-control-active); }
73
73
  /* On: a tint, an accent border all round, and a thicker bar underneath, so it never depends on color alone. */
74
- [data-rk-part="button"][aria-pressed="true"] {
75
- color: var(--rk-accent);
76
- background: var(--rk-accent-subtle);
77
- border-color: var(--rk-accent);
74
+ [data-rte-part="button"][aria-pressed="true"] {
75
+ color: var(--rte-accent);
76
+ background: var(--rte-accent-subtle);
77
+ border-color: var(--rte-accent);
78
78
  border-bottom-width: 3px;
79
79
  }
80
- [data-rk-part="button"][aria-disabled="true"],
81
- [data-rk-part="select"][aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
82
- [data-rk-part="icon"] { display: inline-flex; width: 20px; height: 20px; }
83
- [data-rk-part="icon"] svg { width: 100%; height: 100%; }
80
+ [data-rte-part="button"][aria-disabled="true"],
81
+ [data-rte-part="select"][aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
82
+ [data-rte-part="icon"] { display: inline-flex; width: 20px; height: 20px; }
83
+ [data-rte-part="icon"] svg { width: 100%; height: 100%; }
84
84
 
85
85
  /* ---- menus: a button that opens a list of commands ---- */
86
- [data-rk-part="menu-host"] { position: relative; display: inline-flex; }
87
- [data-rk-part="menu"] {
88
- position: absolute; z-index: 10; inset-block-start: calc(100% + var(--rk-space-1)); inset-inline-start: 0;
89
- min-width: 14rem; padding: var(--rk-space-1);
90
- background: var(--rk-surface-raised); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-m);
91
- box-shadow: var(--rk-shadow-popover); max-height: min(22rem, 60vh); overflow-y: auto;
86
+ [data-rte-part="menu-host"] { position: relative; display: inline-flex; }
87
+ [data-rte-part="menu"] {
88
+ position: absolute; z-index: 10; inset-block-start: calc(100% + var(--rte-space-1)); inset-inline-start: 0;
89
+ min-width: 14rem; padding: var(--rte-space-1);
90
+ background: var(--rte-surface-raised); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-m);
91
+ box-shadow: var(--rte-shadow-popover); max-height: min(22rem, 60vh); overflow-y: auto;
92
92
  }
93
- [data-rk-part="menu"][hidden] { display: none; }
94
- [data-rk-part="menu-item"] {
95
- display: flex; align-items: center; justify-content: space-between; gap: var(--rk-space-4); width: 100%; min-height: var(--rk-control-size);
96
- margin: 0; padding: 0 var(--rk-space-2) 0 calc(var(--rk-space-2) + 1.4em); font: inherit; text-align: start; color: var(--rk-fg);
97
- background: transparent; border: 0; border-radius: var(--rk-radius-s); cursor: pointer; position: relative;
93
+ [data-rte-part="menu"][hidden] { display: none; }
94
+ [data-rte-part="menu-item"] {
95
+ display: flex; align-items: center; justify-content: space-between; gap: var(--rte-space-4); width: 100%; min-height: var(--rte-control-size);
96
+ margin: 0; padding: 0 var(--rte-space-2) 0 calc(var(--rte-space-2) + 1.4em); font: inherit; text-align: start; color: var(--rte-fg);
97
+ background: transparent; border: 0; border-radius: var(--rte-radius-s); cursor: pointer; position: relative;
98
98
  }
99
- [data-rk-part="menu-item"]:hover:not([aria-disabled="true"]), [data-rk-part="menu-item"]:focus-visible { background: var(--rk-control-hover); }
100
- [data-rk-part="menu-item"][aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
99
+ [data-rte-part="menu-item"]:hover:not([aria-disabled="true"]), [data-rte-part="menu-item"]:focus-visible { background: var(--rte-control-hover); }
100
+ [data-rte-part="menu-item"][aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
101
101
  /* A switched-on entry has a check mark in front of it, so it never depends on color alone. */
102
- [data-rk-part="menu-item"][aria-checked="true"]::before { content: "\2713"; position: absolute; inset-inline-start: var(--rk-space-2); font-weight: 700; color: var(--rk-accent); }
102
+ [data-rte-part="menu-item"][aria-checked="true"]::before { content: "\2713"; position: absolute; inset-inline-start: var(--rte-space-2); font-weight: 700; color: var(--rte-accent); }
103
103
  /* A sample of a color, with a border so it shows on any background (a white swatch on white, say). */
104
- [data-rk-part="swatch"] { flex: none; width: 1em; height: 1em; margin-inline-end: var(--rk-space-2); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-s); }
105
- [data-rk-part="menu-item"]:has([data-rk-part="swatch"]) { justify-content: flex-start; }
106
- [data-rk-part="menu-item"]:has([data-rk-part="swatch"]) [data-rk-part="menu-keys"] { margin-inline-start: auto; }
107
- [data-rk-part="menu-keys"] { color: var(--rk-fg-muted); font-size: 0.85em; }
108
- [data-rk-part="menu-separator"] { height: var(--rk-border-width); margin: var(--rk-space-1) var(--rk-space-2); background: var(--rk-border-subtle); }
104
+ [data-rte-part="swatch"] { flex: none; width: 1em; height: 1em; margin-inline-end: var(--rte-space-2); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-s); }
105
+ [data-rte-part="menu-item"]:has([data-rte-part="swatch"]) { justify-content: flex-start; }
106
+ [data-rte-part="menu-item"]:has([data-rte-part="swatch"]) [data-rte-part="menu-keys"] { margin-inline-start: auto; }
107
+ [data-rte-part="menu-keys"] { color: var(--rte-fg-muted); font-size: 0.85em; }
108
+ [data-rte-part="menu-separator"] { height: var(--rte-border-width); margin: var(--rte-space-1) var(--rte-space-2); background: var(--rte-border-subtle); }
109
109
 
110
110
  /* ---- the selection toolbar: a short row of controls over selected text ---- */
111
- [data-rk-part="floating"] {
112
- position: absolute; z-index: 15; display: flex; align-items: center; gap: var(--rk-space-1); padding: var(--rk-space-1);
113
- background: var(--rk-surface-raised); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-m); box-shadow: var(--rk-shadow-popover);
111
+ [data-rte-part="floating"] {
112
+ position: absolute; z-index: 15; display: flex; align-items: center; gap: var(--rte-space-1); padding: var(--rte-space-1);
113
+ background: var(--rte-surface-raised); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-m); box-shadow: var(--rte-shadow-popover);
114
114
  }
115
- [data-rk-part="floating"][hidden] { display: none; }
116
- [data-rk-part="floating"] [data-rk-part="separator"] { align-self: stretch; margin-block: var(--rk-space-1); }
115
+ [data-rte-part="floating"][hidden] { display: none; }
116
+ [data-rte-part="floating"] [data-rte-part="separator"] { align-self: stretch; margin-block: var(--rte-space-1); }
117
117
 
118
118
  /* ---- tooltip: the control's name and key, shown near it on hover and keyboard focus ---- */
119
- [data-rk-part="tooltip"] {
120
- position: absolute; z-index: 20; max-width: 20rem; padding: var(--rk-space-1) var(--rk-space-2); font-size: 0.85em; line-height: 1.35;
121
- color: var(--rk-bg); background: var(--rk-fg); border-radius: var(--rk-radius-s); box-shadow: var(--rk-shadow-popover);
119
+ [data-rte-part="tooltip"] {
120
+ position: absolute; z-index: 20; max-width: 20rem; padding: var(--rte-space-1) var(--rte-space-2); font-size: 0.85em; line-height: 1.35;
121
+ color: var(--rte-bg); background: var(--rte-fg); border-radius: var(--rte-radius-s); box-shadow: var(--rte-shadow-popover);
122
122
  white-space: nowrap; pointer-events: auto;
123
123
  }
124
- [data-rk-part="tooltip"][hidden] { display: none; }
124
+ [data-rte-part="tooltip"][hidden] { display: none; }
125
125
 
126
- .rk-root :focus-visible {
127
- outline: var(--rk-focus-width) solid var(--rk-focus-color);
128
- outline-offset: var(--rk-focus-offset);
126
+ .rte-root :focus-visible {
127
+ outline: var(--rte-focus-width) solid var(--rte-focus-color);
128
+ outline-offset: var(--rte-focus-offset);
129
129
  }
130
130
 
131
131
  /* ---- the writing area ---- */
132
- [data-rk-part="content"] {
133
- padding: var(--rk-space-3) var(--rk-space-4);
134
- background: var(--rk-bg);
135
- border-radius: 0 0 var(--rk-radius-m) var(--rk-radius-m);
136
- font-family: var(--rk-font-content);
132
+ [data-rte-part="content"] {
133
+ padding: var(--rte-space-3) var(--rte-space-4);
134
+ background: var(--rte-bg);
135
+ border-radius: 0 0 var(--rte-radius-m) var(--rte-radius-m);
136
+ font-family: var(--rte-font-content);
137
137
  }
138
- [data-rk-part="content"] > :first-child { outline: none; min-height: 8em; }
139
- [data-rk-part="content"] ::selection { background: var(--rk-selection-bg); color: var(--rk-fg); }
140
- /* The hint shown while the document is empty (the editor sets data-rk-empty and --rk-placeholder). */
141
- [data-rk-part="content"] > [data-rk-empty] > :first-child::before { content: var(--rk-placeholder, none); color: var(--rk-fg-muted); pointer-events: none; }
142
- [data-rk-part="content"] > :first-child > :first-child { margin-top: 0; }
143
- [data-rk-part="content"] > :first-child > :last-child { margin-bottom: 0; }
144
- [data-rk-part="content"] p { margin: 0 0 0.75em; }
145
- [data-rk-part="content"] :is(h1, h2, h3, h4, h5, h6) { margin: 1.1em 0 0.4em; font-family: var(--rk-font-heading); line-height: 1.25; font-weight: 700; }
146
- [data-rk-part="content"] h1 { font-size: 1.9em; }
147
- [data-rk-part="content"] h2 { font-size: 1.5em; }
148
- [data-rk-part="content"] h3 { font-size: 1.25em; }
149
- [data-rk-part="content"] h4 { font-size: 1.1em; }
150
- [data-rk-part="content"] :is(h5, h6) { font-size: 1em; }
151
- [data-rk-part="content"] :is(ul, ol) { margin: 0 0 0.75em; padding-inline-start: 1.6em; }
152
- [data-rk-part="content"] :is(ul, ol) :is(ul, ol) { margin-bottom: 0; }
138
+ [data-rte-part="content"] > :first-child { outline: none; min-height: 8em; }
139
+ [data-rte-part="content"] ::selection { background: var(--rte-selection-bg); color: var(--rte-fg); }
140
+ /* The hint shown while the document is empty (the editor sets data-rte-empty and --rte-placeholder). */
141
+ [data-rte-part="content"] > [data-rte-empty] > :first-child::before { content: var(--rte-placeholder, none); color: var(--rte-fg-muted); pointer-events: none; }
142
+ [data-rte-part="content"] > :first-child > :first-child { margin-top: 0; }
143
+ [data-rte-part="content"] > :first-child > :last-child { margin-bottom: 0; }
144
+ [data-rte-part="content"] p { margin: 0 0 0.75em; }
145
+ [data-rte-part="content"] :is(h1, h2, h3, h4, h5, h6) { margin: 1.1em 0 0.4em; font-family: var(--rte-font-heading); line-height: 1.25; font-weight: 700; }
146
+ [data-rte-part="content"] h1 { font-size: 1.9em; }
147
+ [data-rte-part="content"] h2 { font-size: 1.5em; }
148
+ [data-rte-part="content"] h3 { font-size: 1.25em; }
149
+ [data-rte-part="content"] h4 { font-size: 1.1em; }
150
+ [data-rte-part="content"] :is(h5, h6) { font-size: 1em; }
151
+ [data-rte-part="content"] :is(ul, ol) { margin: 0 0 0.75em; padding-inline-start: 1.6em; }
152
+ [data-rte-part="content"] :is(ul, ol) :is(ul, ol) { margin-bottom: 0; }
153
153
  /* A task's checkbox is a glyph in front of its text; clicking it ticks the task. */
154
- [data-rk-part="content"] li[data-rk-task] { list-style: none; }
155
- [data-rk-part="content"] [data-rte-check] { display: inline-block; margin-inline-end: 0.4em; cursor: pointer; user-select: none; font-size: 1.1em; line-height: 1; color: var(--rk-accent); }
156
- [data-rk-part="content"] li[data-rk-task="open"] > [data-rte-check] { color: var(--rk-fg-muted); }
157
- [data-rk-part="content"] dt { font-weight: 700; }
158
- [data-rk-part="content"] dd { margin-inline-start: 1.6em; }
159
- [data-rk-part="content"] blockquote { margin: 0 0 0.75em; padding-inline-start: var(--rk-space-3); border-inline-start: 3px solid var(--rk-brand); color: var(--rk-fg-muted); }
160
- [data-rk-part="content"] pre { margin: 0 0 0.75em; padding: var(--rk-space-2) var(--rk-space-3); font-family: var(--rk-font-mono); font-size: 0.9em; background: var(--rk-surface); border: var(--rk-border-width) solid var(--rk-border-subtle); border-radius: var(--rk-radius-s); overflow-x: auto; }
161
- [data-rk-part="content"] code { font-family: var(--rk-font-mono); font-size: 0.9em; padding: 0.1em 0.3em; background: var(--rk-surface); border-radius: var(--rk-radius-s); }
162
- [data-rk-part="content"] pre code { padding: 0; background: none; }
163
- [data-rk-part="content"] a { color: var(--rk-accent); text-decoration: underline; text-underline-offset: 0.15em; }
164
- [data-rk-part="content"] hr { border: 0; border-top: var(--rk-border-width) solid var(--rk-border); margin: 1em 0; }
165
- [data-rk-part="content"] img { max-width: 100%; height: auto; }
154
+ [data-rte-part="content"] li[data-rte-task] { list-style: none; }
155
+ [data-rte-part="content"] [data-rte-check] { display: inline-block; margin-inline-end: 0.4em; cursor: pointer; user-select: none; font-size: 1.1em; line-height: 1; color: var(--rte-accent); }
156
+ [data-rte-part="content"] li[data-rte-task="open"] > [data-rte-check] { color: var(--rte-fg-muted); }
157
+ [data-rte-part="content"] dt { font-weight: 700; }
158
+ [data-rte-part="content"] dd { margin-inline-start: 1.6em; }
159
+ [data-rte-part="content"] blockquote { margin: 0 0 0.75em; padding-inline-start: var(--rte-space-3); border-inline-start: 3px solid var(--rte-brand); color: var(--rte-fg-muted); }
160
+ [data-rte-part="content"] pre { margin: 0 0 0.75em; padding: var(--rte-space-2) var(--rte-space-3); font-family: var(--rte-font-mono); font-size: 0.9em; background: var(--rte-surface); border: var(--rte-border-width) solid var(--rte-border-subtle); border-radius: var(--rte-radius-s); overflow-x: auto; }
161
+ [data-rte-part="content"] code { font-family: var(--rte-font-mono); font-size: 0.9em; padding: 0.1em 0.3em; background: var(--rte-surface); border-radius: var(--rte-radius-s); }
162
+ [data-rte-part="content"] pre code { padding: 0; background: none; }
163
+ [data-rte-part="content"] a { color: var(--rte-accent); text-decoration: underline; text-underline-offset: 0.15em; }
164
+ [data-rte-part="content"] hr { border: 0; border-top: var(--rte-border-width) solid var(--rte-border); margin: 1em 0; }
165
+ [data-rte-part="content"] img { max-width: 100%; height: auto; }
166
166
  /* An image from another site that the host has not allowed to load: a dashed box in its place, so it is plain that something is there. */
167
- [data-rk-part="content"] img[data-rte-remote-src] { display: inline-block; min-width: 6em; min-height: 3em; vertical-align: middle; border: 2px dashed var(--rk-border); border-radius: var(--rk-radius-s); background: var(--rk-surface); }
168
- [data-rk-part="content"] table { border-collapse: collapse; margin: 0 0 0.75em; }
169
- [data-rk-part="content"] :is(td, th) { padding: var(--rk-space-1) var(--rk-space-2); border: var(--rk-border-width) solid var(--rk-border); vertical-align: top; min-width: 2em; }
170
- [data-rk-part="content"] :is(td, th) > p { margin: 0; }
171
- [data-rk-part="content"] :is(td, th) > p + p { margin-top: 0.5em; }
172
- [data-rk-part="content"] th { background: var(--rk-surface); text-align: start; }
167
+ [data-rte-part="content"] img[data-rte-remote-src] { display: inline-block; min-width: 6em; min-height: 3em; vertical-align: middle; border: 2px dashed var(--rte-border); border-radius: var(--rte-radius-s); background: var(--rte-surface); }
168
+ [data-rte-part="content"] table { border-collapse: collapse; margin: 0 0 0.75em; }
169
+ [data-rte-part="content"] :is(td, th) { padding: var(--rte-space-1) var(--rte-space-2); border: var(--rte-border-width) solid var(--rte-border); vertical-align: top; min-width: 2em; }
170
+ [data-rte-part="content"] :is(td, th) > p { margin: 0; }
171
+ [data-rte-part="content"] :is(td, th) > p + p { margin-top: 0.5em; }
172
+ [data-rte-part="content"] th { background: var(--rte-surface); text-align: start; }
173
173
  /* Cells a selection runs across (the view marks them): a tint and an outline, so it is not color alone. */
174
- [data-rk-part="content"] [data-rk-cell-selected] { background: var(--rk-selection-bg); outline: 2px solid var(--rk-accent); outline-offset: -2px; }
175
- [data-rk-part="content"] img[data-rk-image-selected] { outline: 2px solid var(--rk-accent); outline-offset: 2px; }
174
+ [data-rte-part="content"] [data-rte-cell-selected] { background: var(--rte-selection-bg); outline: 2px solid var(--rte-accent); outline-offset: -2px; }
175
+ [data-rte-part="content"] img[data-rte-image-selected] { outline: 2px solid var(--rte-accent); outline-offset: 2px; }
176
176
  /* Focus inside the writing area shows on the whole editor, not as a box around the text. */
177
- .rk-root:focus-within { outline: var(--rk-focus-width) solid var(--rk-focus-color); outline-offset: var(--rk-focus-offset); }
178
- .rk-root:focus-within [data-rk-part="content"] :focus-visible,
179
- .rk-root [data-rk-part="content"] :focus-visible { outline: none; }
177
+ .rte-root:focus-within { outline: var(--rte-focus-width) solid var(--rte-focus-color); outline-offset: var(--rte-focus-offset); }
178
+ .rte-root:focus-within [data-rte-part="content"] :focus-visible,
179
+ .rte-root [data-rte-part="content"] :focus-visible { outline: none; }
180
180
 
181
181
  /* ---- HTML source view: the text box takes the place of the writing area ---- */
182
- [data-rk-part="content"][data-rk-source] > :not([data-rk-part="source"]) { display: none; }
183
- [data-rk-part="source"] {
184
- display: block; width: 100%; min-height: 14em; margin: 0; padding: 0; font: 0.9em / 1.5 var(--rk-font-mono); color: var(--rk-fg);
185
- background: var(--rk-bg); border: 0; outline: none; resize: vertical; tab-size: 2;
182
+ [data-rte-part="content"][data-rte-source] > :not([data-rte-part="source"]) { display: none; }
183
+ [data-rte-part="source"] {
184
+ display: block; width: 100%; min-height: 14em; margin: 0; padding: 0; font: 0.9em / 1.5 var(--rte-font-mono); color: var(--rte-fg);
185
+ background: var(--rte-bg); border: 0; outline: none; resize: vertical; tab-size: 2;
186
186
  }
187
- [data-rk-part="source"][hidden] { display: none; }
187
+ [data-rte-part="source"][hidden] { display: none; }
188
188
 
189
189
  /* ---- keyboard shortcuts list ---- */
190
- [data-rk-part="shortcuts"] { width: 100%; border-collapse: collapse; margin-bottom: var(--rk-space-2); }
191
- [data-rk-part="shortcuts"] :is(th, td) { padding: var(--rk-space-1) var(--rk-space-2); text-align: start; border-bottom: var(--rk-border-width) solid var(--rk-border-subtle); }
192
- [data-rk-part="shortcuts"] kbd { font: 0.9em var(--rk-font-mono); padding: 0.1em 0.4em; background: var(--rk-surface); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-s); }
190
+ [data-rte-part="shortcuts"] { width: 100%; border-collapse: collapse; margin-bottom: var(--rte-space-2); }
191
+ [data-rte-part="shortcuts"] :is(th, td) { padding: var(--rte-space-1) var(--rte-space-2); text-align: start; border-bottom: var(--rte-border-width) solid var(--rte-border-subtle); }
192
+ [data-rte-part="shortcuts"] kbd { font: 0.9em var(--rte-font-mono); padding: 0.1em 0.4em; background: var(--rte-surface); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-s); }
193
193
 
194
194
  /* ---- find and replace ---- */
195
- [data-rk-part="findbar"] { padding: var(--rk-space-2); background: var(--rk-surface); border-bottom: var(--rk-border-width) solid var(--rk-border); }
196
- [data-rk-part="findbar"][hidden] { display: none; }
197
- [data-rk-part="find-line"] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rk-space-1); }
198
- [data-rk-part="find-line"] + [data-rk-part="find-line"] { margin-top: var(--rk-space-1); }
199
- [data-rk-part="find-row"] { display: flex; align-items: center; gap: var(--rk-space-2); flex: 1 1 14rem; }
200
- [data-rk-part="find-label"] { min-width: 6.5em; font-weight: 600; }
201
- [data-rk-part="find-field"] {
202
- flex: 1; min-width: 6em; height: var(--rk-control-size); padding: 0 var(--rk-space-2); font: inherit; color: var(--rk-fg);
203
- background: var(--rk-bg); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-s);
195
+ [data-rte-part="findbar"] { padding: var(--rte-space-2); background: var(--rte-surface); border-bottom: var(--rte-border-width) solid var(--rte-border); }
196
+ [data-rte-part="findbar"][hidden] { display: none; }
197
+ [data-rte-part="find-line"] { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rte-space-1); }
198
+ [data-rte-part="find-line"] + [data-rte-part="find-line"] { margin-top: var(--rte-space-1); }
199
+ [data-rte-part="find-row"] { display: flex; align-items: center; gap: var(--rte-space-2); flex: 1 1 14rem; }
200
+ [data-rte-part="find-label"] { min-width: 6.5em; font-weight: 600; }
201
+ [data-rte-part="find-field"] {
202
+ flex: 1; min-width: 6em; height: var(--rte-control-size); padding: 0 var(--rte-space-2); font: inherit; color: var(--rte-fg);
203
+ background: var(--rte-bg); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-s);
204
204
  }
205
- [data-rk-part="find-count"] { min-width: 5.5em; color: var(--rk-fg-muted); font-size: 0.9em; }
206
- [data-rk-part="findbar"] [aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
205
+ [data-rte-part="find-count"] { min-width: 5.5em; color: var(--rte-fg-muted); font-size: 0.9em; }
206
+ [data-rte-part="findbar"] [aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
207
207
 
208
208
  /* ---- status line ---- */
209
- [data-rk-part="status"] {
210
- padding: var(--rk-space-1) var(--rk-space-3); font-size: 0.85em; color: var(--rk-fg-muted); background: var(--rk-surface);
211
- border-top: var(--rk-border-width) solid var(--rk-border-subtle); border-radius: 0 0 calc(var(--rk-radius-m) - var(--rk-border-width)) calc(var(--rk-radius-m) - var(--rk-border-width));
209
+ [data-rte-part="status"] {
210
+ padding: var(--rte-space-1) var(--rte-space-3); font-size: 0.85em; color: var(--rte-fg-muted); background: var(--rte-surface);
211
+ border-top: var(--rte-border-width) solid var(--rte-border-subtle); border-radius: 0 0 calc(var(--rte-radius-m) - var(--rte-border-width)) calc(var(--rte-radius-m) - var(--rte-border-width));
212
212
  }
213
- [data-rk-part="content"]:has(+ [data-rk-part="status"]) { border-radius: 0; }
213
+ [data-rte-part="content"]:has(+ [data-rte-part="status"]) { border-radius: 0; }
214
214
 
215
215
  /* ---- dialog ---- */
216
- [data-rk-part="dialog"] {
217
- width: min(26rem, calc(100vw - 2 * var(--rk-space-4)));
218
- padding: var(--rk-space-4);
219
- color: var(--rk-fg);
220
- background: var(--rk-surface-raised);
221
- border: var(--rk-border-width) solid var(--rk-border);
222
- border-radius: var(--rk-radius-m);
223
- box-shadow: var(--rk-shadow-popover);
224
- font: var(--rk-font-size) / var(--rk-line-height) var(--rk-font-ui);
216
+ [data-rte-part="dialog"] {
217
+ width: min(26rem, calc(100vw - 2 * var(--rte-space-4)));
218
+ padding: var(--rte-space-4);
219
+ color: var(--rte-fg);
220
+ background: var(--rte-surface-raised);
221
+ border: var(--rte-border-width) solid var(--rte-border);
222
+ border-radius: var(--rte-radius-m);
223
+ box-shadow: var(--rte-shadow-popover);
224
+ font: var(--rte-font-size) / var(--rte-line-height) var(--rte-font-ui);
225
225
  }
226
- [data-rk-part="dialog"]::backdrop { background: rgb(0 0 0 / 0.45); }
227
- [data-rk-part="dialog-title"] { margin: 0 0 var(--rk-space-3); font: 700 1.15em / 1.3 var(--rk-font-heading); }
228
- [data-rk-part="field-label"] { display: block; margin-bottom: var(--rk-space-1); font-weight: 600; }
229
- [data-rk-part="field"] {
230
- display: block; width: 100%; height: var(--rk-control-size); padding: 0 var(--rk-space-2); font: inherit; color: var(--rk-fg);
231
- background: var(--rk-bg); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-s);
226
+ [data-rte-part="dialog"]::backdrop { background: rgb(0 0 0 / 0.45); }
227
+ [data-rte-part="dialog-title"] { margin: 0 0 var(--rte-space-3); font: 700 1.15em / 1.3 var(--rte-font-heading); }
228
+ [data-rte-part="field-label"] { display: block; margin-bottom: var(--rte-space-1); font-weight: 600; }
229
+ [data-rte-part="field"] {
230
+ display: block; width: 100%; height: var(--rte-control-size); padding: 0 var(--rte-space-2); font: inherit; color: var(--rte-fg);
231
+ background: var(--rte-bg); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-s);
232
232
  }
233
- [data-rk-part="field"][aria-invalid="true"] { border-color: var(--rk-danger); border-width: 2px; }
234
- [data-rk-part="field-check"] { display: flex; align-items: center; gap: var(--rk-space-2); margin-top: var(--rk-space-2); }
235
- [data-rk-part="field-check"] [data-rk-part="field"] { width: 1.1em; height: 1.1em; padding: 0; accent-color: var(--rk-accent); }
236
- [data-rk-part="field-check"] [data-rk-part="field-label"] { display: inline; margin: 0; font-weight: 400; }
237
- [data-rk-part="field-error"] { display: block; min-height: 1.4em; margin-top: var(--rk-space-1); color: var(--rk-danger); font-size: 0.9em; }
238
- [data-rk-part="actions"] { display: flex; justify-content: flex-end; gap: var(--rk-space-2); margin-top: var(--rk-space-3); }
239
- [data-rk-part="action"] {
240
- min-width: 5rem; height: var(--rk-control-size); padding: 0 var(--rk-space-3); font: inherit; font-weight: 600; color: var(--rk-fg);
241
- background: var(--rk-surface-raised); border: var(--rk-border-width) solid var(--rk-border); border-radius: var(--rk-radius-s); cursor: pointer;
233
+ [data-rte-part="field"][aria-invalid="true"] { border-color: var(--rte-danger); border-width: 2px; }
234
+ [data-rte-part="field-check"] { display: flex; align-items: center; gap: var(--rte-space-2); margin-top: var(--rte-space-2); }
235
+ [data-rte-part="field-check"] [data-rte-part="field"] { width: 1.1em; height: 1.1em; padding: 0; accent-color: var(--rte-accent); }
236
+ [data-rte-part="field-check"] [data-rte-part="field-label"] { display: inline; margin: 0; font-weight: 400; }
237
+ [data-rte-part="field-error"] { display: block; min-height: 1.4em; margin-top: var(--rte-space-1); color: var(--rte-danger); font-size: 0.9em; }
238
+ [data-rte-part="actions"] { display: flex; justify-content: flex-end; gap: var(--rte-space-2); margin-top: var(--rte-space-3); }
239
+ [data-rte-part="action"] {
240
+ min-width: 5rem; height: var(--rte-control-size); padding: 0 var(--rte-space-3); font: inherit; font-weight: 600; color: var(--rte-fg);
241
+ background: var(--rte-surface-raised); border: var(--rte-border-width) solid var(--rte-border); border-radius: var(--rte-radius-s); cursor: pointer;
242
242
  }
243
- [data-rk-part="action"][data-primary] { color: var(--rk-accent-fg); background: var(--rk-accent); border-color: var(--rk-accent); }
243
+ [data-rte-part="action"][data-primary] { color: var(--rte-accent-fg); background: var(--rte-accent); border-color: var(--rte-accent); }
244
244
 
245
245
  /* Matches painted by the page's highlight registry (nothing in the document changes). Dark text on a strong tint reads on any theme. */
246
- ::highlight(rk-find) { background-color: #ffe08a; color: #14181f; }
247
- ::highlight(rk-find-current) { background-color: #ff9632; color: #14181f; }
246
+ ::highlight(rte-find) { background-color: #ffe08a; color: #14181f; }
247
+ ::highlight(rte-find-current) { background-color: #ff9632; color: #14181f; }
248
248
 
249
- @media (prefers-reduced-motion: reduce) { .rk-root { --rk-motion-scale: 0; } }
249
+ @media (prefers-reduced-motion: reduce) { .rte-root { --rte-motion-scale: 0; } }
250
250
 
251
251
  /* Forced colors (Windows high contrast): use the user's colors, and real borders and outlines, which survive where shadows and tints do not. */
252
252
  @media (forced-colors: active) {
253
- .rk-root { border-color: CanvasText; }
254
- [data-rk-part="toolbar"] { border-bottom-color: CanvasText; }
255
- [data-rk-part="button"], [data-rk-part="select"], [data-rk-part="field"], [data-rk-part="action"] { border-color: ButtonText; color: ButtonText; background: ButtonFace; }
256
- [data-rk-part="button"][aria-pressed="true"] { border-color: Highlight; color: HighlightText; background: Highlight; border-bottom-width: 4px; }
257
- [data-rk-part="button"][aria-disabled="true"], [data-rk-part="select"][aria-disabled="true"] { color: GrayText; border-color: GrayText; opacity: 1; }
258
- [data-rk-part="content"] a { color: LinkText; }
259
- [data-rk-part="content"] [data-rk-cell-selected] { outline-color: Highlight; background: Canvas; }
260
- [data-rk-part="content"] img[data-rk-image-selected] { outline-color: Highlight; }
261
- .rk-root :focus-visible, .rk-root:focus-within { outline-color: Highlight; }
262
- [data-rk-part="separator"], [data-rk-part="menu-separator"] { background: CanvasText; }
263
- [data-rk-part="menu"], [data-rk-part="floating"] { border-color: CanvasText; background: Canvas; }
264
- ::highlight(rk-find) { background-color: Mark; color: MarkText; }
265
- ::highlight(rk-find-current) { background-color: Highlight; color: HighlightText; }
266
- [data-rk-part="find-field"] { border-color: ButtonText; }
267
- [data-rk-part="tooltip"] { color: CanvasText; background: Canvas; border: 1px solid CanvasText; }
268
- [data-rk-part="menu-item"] { color: ButtonText; }
269
- [data-rk-part="menu-item"]:hover:not([aria-disabled="true"]), [data-rk-part="menu-item"]:focus-visible { background: Highlight; color: HighlightText; }
270
- [data-rk-part="menu-item"][aria-disabled="true"] { color: GrayText; opacity: 1; }
253
+ .rte-root { border-color: CanvasText; }
254
+ [data-rte-part="toolbar"] { border-bottom-color: CanvasText; }
255
+ [data-rte-part="button"], [data-rte-part="select"], [data-rte-part="field"], [data-rte-part="action"] { border-color: ButtonText; color: ButtonText; background: ButtonFace; }
256
+ [data-rte-part="button"][aria-pressed="true"] { border-color: Highlight; color: HighlightText; background: Highlight; border-bottom-width: 4px; }
257
+ [data-rte-part="button"][aria-disabled="true"], [data-rte-part="select"][aria-disabled="true"] { color: GrayText; border-color: GrayText; opacity: 1; }
258
+ [data-rte-part="content"] a { color: LinkText; }
259
+ [data-rte-part="content"] [data-rte-cell-selected] { outline-color: Highlight; background: Canvas; }
260
+ [data-rte-part="content"] img[data-rte-image-selected] { outline-color: Highlight; }
261
+ .rte-root :focus-visible, .rte-root:focus-within { outline-color: Highlight; }
262
+ [data-rte-part="separator"], [data-rte-part="menu-separator"] { background: CanvasText; }
263
+ [data-rte-part="menu"], [data-rte-part="floating"] { border-color: CanvasText; background: Canvas; }
264
+ ::highlight(rte-find) { background-color: Mark; color: MarkText; }
265
+ ::highlight(rte-find-current) { background-color: Highlight; color: HighlightText; }
266
+ [data-rte-part="find-field"] { border-color: ButtonText; }
267
+ [data-rte-part="tooltip"] { color: CanvasText; background: Canvas; border: 1px solid CanvasText; }
268
+ [data-rte-part="menu-item"] { color: ButtonText; }
269
+ [data-rte-part="menu-item"]:hover:not([aria-disabled="true"]), [data-rte-part="menu-item"]:focus-visible { background: Highlight; color: HighlightText; }
270
+ [data-rte-part="menu-item"][aria-disabled="true"] { color: GrayText; opacity: 1; }
271
271
  }
272
272
  }
@@ -1,2 +1,2 @@
1
- import { define } from "./element.js";
2
- define();
1
+ import { defineUi } from "./element.js";
2
+ defineUi();
package/dist/element.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { StyleProvider, Ui } from "./types.ts";
2
- export declare class RkUi extends HTMLElement {
2
+ export declare class RteUiElement extends HTMLElement {
3
3
  static observedAttributes: string[];
4
4
  private current;
5
5
  private extra;
@@ -19,5 +19,5 @@ export declare class RkUi extends HTMLElement {
19
19
  private attach;
20
20
  private detach;
21
21
  }
22
- /** Registers <rk-ui>. Safe to call more than once. */
23
- export declare function define(name?: string): void;
22
+ /** Registers <rte-ui>. Safe to call more than once. */
23
+ export declare function defineUi(name?: string): void;
package/dist/element.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import { createStandardUi } from "./standard.js";
2
2
  const STYLE_ATTRIBUTES = ["theme", "scheme", "density"];
3
- export class RkUi extends HTMLElement {
3
+ export class RteUiElement extends HTMLElement {
4
4
  static observedAttributes = [...STYLE_ATTRIBUTES, "selection-toolbar", "context-menu", "status"];
5
5
  current;
6
6
  extra = {};
7
7
  connectedCallback() {
8
- this.addEventListener("rk-ready", this.onReady);
8
+ this.addEventListener("rte-ready", this.onReady);
9
9
  this.attach();
10
10
  }
11
11
  disconnectedCallback() {
12
- this.removeEventListener("rk-ready", this.onReady);
12
+ this.removeEventListener("rte-ready", this.onReady);
13
13
  this.detach();
14
14
  }
15
15
  attributeChangedCallback(name) {
@@ -40,7 +40,7 @@ export class RkUi extends HTMLElement {
40
40
  return { ...this.extra, ...given };
41
41
  }
42
42
  attach() {
43
- const host = this.querySelector("rk-editor");
43
+ const host = this.querySelector("rte-editor");
44
44
  const editor = host?.editor;
45
45
  if (!host || !editor || this.current)
46
46
  return;
@@ -56,7 +56,7 @@ export class RkUi extends HTMLElement {
56
56
  this.current = undefined;
57
57
  }
58
58
  }
59
- export function define(name = "rk-ui") {
59
+ export function defineUi(name = "rte-ui") {
60
60
  if (!customElements.get(name))
61
- customElements.define(name, RkUi);
61
+ customElements.define(name, RteUiElement);
62
62
  }
package/dist/findbar.js CHANGED
@@ -9,7 +9,7 @@ export function createFindBar(options) {
9
9
  bar.setAttribute("role", "search");
10
10
  bar.hidden = true;
11
11
  const field = (label, name) => {
12
- const id = `rk-find-${++counter}`;
12
+ const id = `rte-find-${++counter}`;
13
13
  const wrap = part(document.createElement("div"), "find-row");
14
14
  const text = part(document.createElement("label"), "find-label");
15
15
  text.htmlFor = id;
@@ -33,7 +33,7 @@ export function createFindBar(options) {
33
33
  else
34
34
  b.textContent = label;
35
35
  b.setAttribute("aria-label", label);
36
- b.setAttribute("data-rk-tip", label);
36
+ b.setAttribute("data-rte-tip", label);
37
37
  return b;
38
38
  };
39
39
  const textButton = (label) => {
@@ -66,7 +66,7 @@ export function createFindBar(options) {
66
66
  replace.text.textContent = message("find.replaceWith");
67
67
  for (const [el, key] of [[previous, "find.previous"], [next, "find.next"], [close, "find.close"], [matchCase, "find.matchCase"], [wholeWord, "find.wholeWord"]]) {
68
68
  el.setAttribute("aria-label", message(key));
69
- el.setAttribute("data-rk-tip", message(key));
69
+ el.setAttribute("data-rte-tip", message(key));
70
70
  }
71
71
  replaceOne.textContent = message("find.replace");
72
72
  replaceAll.textContent = message("find.replaceAll");
@@ -82,8 +82,8 @@ export function createFindBar(options) {
82
82
  if (!highlights || !Highlight || !editor.rangeFor)
83
83
  return;
84
84
  if (!state.open || state.matches.length === 0) {
85
- highlights.delete("rk-find");
86
- highlights.delete("rk-find-current");
85
+ highlights.delete("rte-find");
86
+ highlights.delete("rte-find-current");
87
87
  return;
88
88
  }
89
89
  const ranges = [];
@@ -97,11 +97,11 @@ export function createFindBar(options) {
97
97
  else
98
98
  ranges.push(range);
99
99
  });
100
- highlights.set("rk-find", new Highlight(...ranges));
100
+ highlights.set("rte-find", new Highlight(...ranges));
101
101
  if (current)
102
- highlights.set("rk-find-current", new Highlight(current));
102
+ highlights.set("rte-find-current", new Highlight(current));
103
103
  else
104
- highlights.delete("rk-find-current");
104
+ highlights.delete("rte-find-current");
105
105
  };
106
106
  const render = () => {
107
107
  const state = info();
@@ -179,8 +179,8 @@ export function createFindBar(options) {
179
179
  if (announceTimer)
180
180
  clearTimeout(announceTimer);
181
181
  const highlights = registry();
182
- highlights?.delete("rk-find");
183
- highlights?.delete("rk-find-current");
182
+ highlights?.delete("rte-find");
183
+ highlights?.delete("rte-find-current");
184
184
  bar.remove();
185
185
  },
186
186
  };
package/dist/floating.js CHANGED
@@ -57,11 +57,11 @@ export function createFloating(options) {
57
57
  group = next;
58
58
  const button = part(document.createElement("button"), "button");
59
59
  button.type = "button";
60
- button.setAttribute("data-rk-item", item.id);
60
+ button.setAttribute("data-rte-item", item.id);
61
61
  const state = toolbar.state(item.id);
62
62
  const label = message(`item.${item.id}`, state?.label ?? item.id);
63
63
  button.setAttribute("aria-label", label);
64
- button.setAttribute("data-rk-tip", state?.shortcutLabel ? `${label} (${state.shortcutLabel})` : label);
64
+ button.setAttribute("data-rte-tip", state?.shortcutLabel ? `${label} (${state.shortcutLabel})` : label);
65
65
  if (!iconInto(button, state?.icon)) {
66
66
  const words = part(document.createElement("span"), "label");
67
67
  words.textContent = label;
@@ -77,7 +77,7 @@ export function createFloating(options) {
77
77
  let unbind;
78
78
  draw();
79
79
  const stopItems = toolbar.subscribe(() => {
80
- const drawn = [...bar.querySelectorAll("[data-rk-item]")].map((el) => el.getAttribute("data-rk-item")).join("\u0000");
80
+ const drawn = [...bar.querySelectorAll("[data-rte-item]")].map((el) => el.getAttribute("data-rte-item")).join("\u0000");
81
81
  if (drawn !== toolbar.items.filter((i) => i.kind === "button" || i.kind === "toggle" || i.kind === "dialog").map((i) => i.id).join("\u0000"))
82
82
  draw();
83
83
  });
@@ -148,7 +148,7 @@ export function createFloating(options) {
148
148
  touched = false;
149
149
  if (e.key === "F10" && e.altKey && !bar.hidden) {
150
150
  e.preventDefault();
151
- bar.querySelector("[data-rk-item][tabindex='0']")?.focus();
151
+ bar.querySelector("[data-rte-item][tabindex='0']")?.focus();
152
152
  }
153
153
  });
154
154
  on(bar, "keydown", (e) => { if (e.key === "Escape") {
@@ -165,12 +165,12 @@ export function createFloating(options) {
165
165
  seed(CONTEXT_SLOT, CONTEXT_DEFAULTS);
166
166
  const toolbar = createToolbar(editor, { slot: CONTEXT_SLOT });
167
167
  const popup = part(document.createElement("div"), "menu");
168
- popup.setAttribute("data-rk-context", "");
168
+ popup.setAttribute("data-rte-context", "");
169
169
  const anchor = document.createElement("button");
170
170
  anchor.type = "button";
171
171
  anchor.hidden = true;
172
172
  anchor.setAttribute("aria-label", message("context.label"));
173
- anchor.id = `rk-context-anchor-${++counter}`;
173
+ anchor.id = `rte-context-anchor-${++counter}`;
174
174
  anchor.focus = () => editor.focus();
175
175
  root.append(anchor, popup);
176
176
  const entries = new Map();
@@ -194,8 +194,8 @@ export function createFloating(options) {
194
194
  entries.set(item.id, item);
195
195
  const entry = part(document.createElement("button"), "menu-item");
196
196
  entry.type = "button";
197
- entry.setAttribute("data-rk-menuitem", "");
198
- entry.setAttribute("data-rk-menu-item", item.id);
197
+ entry.setAttribute("data-rte-menuitem", "");
198
+ entry.setAttribute("data-rte-menu-item", item.id);
199
199
  if (item.kind === "toggle")
200
200
  entry.setAttribute("role", "menuitemcheckbox");
201
201
  entry.append(part(document.createElement("span"), "label"), part(document.createElement("span"), "menu-keys"));
@@ -214,7 +214,7 @@ export function createFloating(options) {
214
214
  popup.style.top = `${Math.max(4, Math.min(at.y, view.clientHeight - h - 4))}px`;
215
215
  },
216
216
  onSelect: (entry) => {
217
- const id = entry.getAttribute("data-rk-menu-item") ?? "";
217
+ const id = entry.getAttribute("data-rte-menu-item") ?? "";
218
218
  const item = entries.get(id);
219
219
  if (item?.kind === "dialog") {
220
220
  options.openDialog(item, returnTo);
@@ -228,17 +228,17 @@ export function createFloating(options) {
228
228
  };
229
229
  const words = () => {
230
230
  anchor.setAttribute("aria-label", message("context.label"));
231
- for (const entry of popup.querySelectorAll("[data-rk-menu-item]")) {
232
- const id = entry.getAttribute("data-rk-menu-item") ?? "";
231
+ for (const entry of popup.querySelectorAll("[data-rte-menu-item]")) {
232
+ const id = entry.getAttribute("data-rte-menu-item") ?? "";
233
233
  const item = entries.get(id);
234
234
  const state = toolbar.state(id);
235
235
  if (!item || !state)
236
236
  continue;
237
237
  const label = message(`item.${id}`, state.label);
238
- const name = entry.querySelector('[data-rk-part="label"]');
238
+ const name = entry.querySelector('[data-rte-part="label"]');
239
239
  if (name)
240
240
  name.textContent = label;
241
- const keys = entry.querySelector('[data-rk-part="menu-keys"]');
241
+ const keys = entry.querySelector('[data-rte-part="menu-keys"]');
242
242
  if (keys)
243
243
  keys.textContent = state.shortcutLabel ?? "";
244
244
  entry.setAttribute("aria-disabled", String(state.disabled));
@@ -248,7 +248,7 @@ export function createFloating(options) {
248
248
  };
249
249
  draw();
250
250
  const stopState = toolbar.subscribe(() => {
251
- const drawn = [...popup.querySelectorAll("[data-rk-menu-item]")].map((el) => el.getAttribute("data-rk-menu-item")).join("\u0000");
251
+ const drawn = [...popup.querySelectorAll("[data-rte-menu-item]")].map((el) => el.getAttribute("data-rte-menu-item")).join("\u0000");
252
252
  if (drawn !== toolbar.items.filter((i) => i.kind === "button" || i.kind === "toggle" || i.kind === "dialog").map((i) => i.id).join("\u0000"))
253
253
  draw();
254
254
  else
package/dist/shortcuts.js CHANGED
@@ -3,9 +3,9 @@ let counter = 0;
3
3
  export function createShortcuts(options) {
4
4
  const { editor, root, message } = options;
5
5
  const element = options.part(document.createElement("dialog"), "dialog");
6
- const titleId = `rk-shortcuts-title-${++counter}`;
6
+ const titleId = `rte-shortcuts-title-${++counter}`;
7
7
  element.setAttribute("aria-labelledby", titleId);
8
- element.setAttribute("data-rk-shortcuts", "");
8
+ element.setAttribute("data-rte-shortcuts", "");
9
9
  const title = options.part(document.createElement("h2"), "dialog-title");
10
10
  title.id = titleId;
11
11
  const table = options.part(document.createElement("table"), "shortcuts");
package/dist/source.js CHANGED
@@ -8,25 +8,25 @@ export function createSourceView(options) {
8
8
  content.appendChild(area);
9
9
  let original = "";
10
10
  let opener;
11
- const button = () => toolbar.querySelector('[data-rk-item="source"]');
11
+ const button = () => toolbar.querySelector('[data-rte-item="source"]');
12
12
  const close = (apply) => {
13
13
  if (area.hidden)
14
14
  return;
15
15
  const changed = area.value !== original;
16
16
  area.hidden = true;
17
- content.removeAttribute("data-rk-source");
17
+ content.removeAttribute("data-rte-source");
18
18
  button()?.setAttribute("aria-pressed", "false");
19
19
  if (apply && changed)
20
20
  editor.commands.run("document.setHtml", { html: area.value });
21
21
  editor.focus();
22
- (opener ?? button())?.removeAttribute("data-rk-busy");
22
+ (opener ?? button())?.removeAttribute("data-rte-busy");
23
23
  };
24
24
  const open = (from) => {
25
25
  opener = from;
26
26
  original = editor.getHtml?.("\n") ?? "";
27
27
  area.value = original;
28
28
  area.hidden = false;
29
- content.setAttribute("data-rk-source", "");
29
+ content.setAttribute("data-rte-source", "");
30
30
  button()?.setAttribute("aria-pressed", "true");
31
31
  area.focus();
32
32
  area.setSelectionRange(0, 0);
@@ -34,8 +34,8 @@ export function createSourceView(options) {
34
34
  const guard = (e) => {
35
35
  if (area.hidden)
36
36
  return;
37
- const control = e.target?.closest("[data-rk-item]");
38
- if (!control || control.getAttribute("data-rk-item") === "source")
37
+ const control = e.target?.closest("[data-rte-item]");
38
+ if (!control || control.getAttribute("data-rte-item") === "source")
39
39
  return;
40
40
  if (e.type === "keydown" && !["Enter", " "].includes(e.key))
41
41
  return;
@@ -61,7 +61,7 @@ export function createSourceView(options) {
61
61
  toolbar.removeEventListener("click", guard, true);
62
62
  toolbar.removeEventListener("keydown", guard, true);
63
63
  area.remove();
64
- content.removeAttribute("data-rk-source");
64
+ content.removeAttribute("data-rte-source");
65
65
  },
66
66
  };
67
67
  }
@@ -1,5 +1,2 @@
1
- import { createUi } from "./ui.ts";
2
1
  import type { Ui, UiEditor, UiOptions } from "./types.ts";
3
2
  export declare function createStandardUi(editor: UiEditor, options: UiOptions): Ui;
4
- export { createUi };
5
- export type { Ui, UiEditor, UiOptions };
package/dist/standard.js CHANGED
@@ -3,4 +3,3 @@ import { createUi } from "./ui.js";
3
3
  export function createStandardUi(editor, options) {
4
4
  return createUi(editor, { ...options, defaults: { ...options.defaults, icons: { ...defaultIcons, ...options.defaults?.icons } } });
5
5
  }
6
- export { createUi };
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Toolbar, ItemState, HeadlessEditor } from "@rathkit/rte-headless";
2
2
  import type { Counts, UiItem } from "@rathkit/rte-core";
3
3
  import type { TokenName } from "@rathkit/rte-themes";
4
- /** The parts the interface is made of. Selectors and `classes` address them by these names (as `data-rk-part`). */
4
+ /** The parts the interface is made of. Selectors and `classes` address them by these names (as `data-rte-part`). */
5
5
  export type PartName = "root" | "toolbar" | "button" | "select" | "separator" | "icon" | "label" | "content" | "menu-host" | "menu" | "menu-item" | "menu-separator" | "menu-keys" | "swatch" | "tooltip" | "status" | "source" | "shortcuts" | "floating" | "findbar" | "find-line" | "find-row" | "find-label" | "find-field" | "find-count" | "dialog" | "dialog-title" | "field-label" | "field-check" | "field" | "field-error" | "actions" | "action";
6
6
  /** Words the interface says. Each has a default in English; this table is also the way to translate it. */
7
7
  export type MessageKey = "toolbar.label" | "floating.label" | "context.label" | "dialog.ok" | "dialog.cancel" | "field.required" | "field.url" | "toggle.on" | "toggle.off" | "status.word" | "status.words" | "status.characters" | "status.selection" | "source.label" | "shortcuts.title" | "shortcuts.action" | "shortcuts.keys" | "shortcuts.close" | "find.find" | "find.replaceWith" | "find.previous" | "find.next" | "find.close" | "find.matchCase" | "find.wholeWord" | "find.replace" | "find.replaceAll" | "find.none" | "find.count" | "find.total"
@@ -52,7 +52,7 @@ export type UiEditor = HeadlessEditor & {
52
52
  }): Range | null;
53
53
  };
54
54
  export interface UiOptions {
55
- /** The element the interface is built in. It gets the `rk-root` class. */
55
+ /** The element the interface is built in. It gets the `rte-root` class. */
56
56
  readonly root: HTMLElement;
57
57
  readonly style?: StyleProvider;
58
58
  /** A line under the writing area with the number of words and characters. Default: on, when the editor can count. */
package/dist/ui.js CHANGED
@@ -19,7 +19,7 @@ export function createUi(editor, options) {
19
19
  const appliedClasses = new Map();
20
20
  const parts = new Map();
21
21
  const part = (el, name) => {
22
- el.setAttribute("data-rk-part", name);
22
+ el.setAttribute("data-rte-part", name);
23
23
  let set = parts.get(name);
24
24
  if (!set)
25
25
  parts.set(name, (set = new Set()));
@@ -29,7 +29,7 @@ export function createUi(editor, options) {
29
29
  return el;
30
30
  };
31
31
  const message = (key, fallback = "", values = {}) => text(style.messages, key, fallback, values);
32
- root.classList.add("rk-root");
32
+ root.classList.add("rte-root");
33
33
  part(root, "root");
34
34
  const toolbarEl = part(document.createElement("div"), "toolbar");
35
35
  const contentEl = part(document.createElement("div"), "content");
@@ -82,9 +82,9 @@ export function createUi(editor, options) {
82
82
  : given;
83
83
  style = next;
84
84
  const set = (name, value) => (value === undefined ? root.removeAttribute(name) : root.setAttribute(name, value));
85
- set("data-rk-theme", next.theme);
86
- set("data-rk-scheme", next.scheme);
87
- set("data-rk-density", next.density);
85
+ set("data-rte-theme", next.theme);
86
+ set("data-rte-scheme", next.scheme);
87
+ set("data-rte-density", next.density);
88
88
  for (const name of [...appliedTokens])
89
89
  if (!(next.tokens && name in next.tokens)) {
90
90
  root.style.removeProperty(name);
@@ -130,7 +130,7 @@ export function createUi(editor, options) {
130
130
  return undefined;
131
131
  if (item.kind === "select") {
132
132
  const select = part(document.createElement("select"), "select");
133
- select.setAttribute("data-rk-item", item.id);
133
+ select.setAttribute("data-rte-item", item.id);
134
134
  for (const o of item.options) {
135
135
  const option = document.createElement("option");
136
136
  option.value = String(o.value);
@@ -144,14 +144,14 @@ export function createUi(editor, options) {
144
144
  const customize = style.parts?.button;
145
145
  if (customize) {
146
146
  const el = customize({ item, state, run: (value) => toolbar.activate(item.id, value) });
147
- el.setAttribute("data-rk-part", "button");
148
- el.setAttribute("data-rk-item", item.id);
147
+ el.setAttribute("data-rte-part", "button");
148
+ el.setAttribute("data-rte-item", item.id);
149
149
  (parts.get("button") ?? parts.set("button", new Set()).get("button"))?.add(el);
150
150
  return el;
151
151
  }
152
152
  const button = part(document.createElement("button"), "button");
153
153
  button.type = "button";
154
- button.setAttribute("data-rk-item", item.id);
154
+ button.setAttribute("data-rte-item", item.id);
155
155
  const icon = part(document.createElement("span"), "icon");
156
156
  icon.setAttribute("aria-hidden", "true");
157
157
  if (setIcon(icon, iconFor(state.icon))) {
@@ -171,7 +171,7 @@ export function createUi(editor, options) {
171
171
  const host = part(document.createElement("span"), "menu-host");
172
172
  const trigger = part(document.createElement("button"), "button");
173
173
  trigger.type = "button";
174
- trigger.setAttribute("data-rk-item", item.id);
174
+ trigger.setAttribute("data-rte-item", item.id);
175
175
  const icon = part(document.createElement("span"), "icon");
176
176
  icon.setAttribute("aria-hidden", "true");
177
177
  if (setIcon(icon, iconFor(state.icon))) {
@@ -200,8 +200,8 @@ export function createUi(editor, options) {
200
200
  menuItems.set(child.id, child);
201
201
  const entry = part(document.createElement("button"), "menu-item");
202
202
  entry.type = "button";
203
- entry.setAttribute("data-rk-menuitem", "");
204
- entry.setAttribute("data-rk-menu-item", child.id);
203
+ entry.setAttribute("data-rte-menuitem", "");
204
+ entry.setAttribute("data-rte-menu-item", child.id);
205
205
  const words = part(document.createElement("span"), "label");
206
206
  const keys = part(document.createElement("span"), "menu-keys");
207
207
  if (child.kind !== "dialog" && child.swatch) {
@@ -225,7 +225,7 @@ export function createUi(editor, options) {
225
225
  popup.style.translate = `${Math.round(dx)}px`;
226
226
  },
227
227
  onSelect: (entry) => {
228
- const id = entry.getAttribute("data-rk-menu-item") ?? "";
228
+ const id = entry.getAttribute("data-rte-menu-item") ?? "";
229
229
  const child = menuItems.get(id);
230
230
  if (child?.kind === "dialog") {
231
231
  openDialog(child, trigger);
@@ -238,25 +238,25 @@ export function createUi(editor, options) {
238
238
  editor.focus();
239
239
  },
240
240
  });
241
- for (const entry of popup.querySelectorAll("[data-rk-menu-item]")) {
242
- if (menuItems.get(entry.getAttribute("data-rk-menu-item") ?? "")?.kind === "toggle")
241
+ for (const entry of popup.querySelectorAll("[data-rte-menu-item]")) {
242
+ if (menuItems.get(entry.getAttribute("data-rte-menu-item") ?? "")?.kind === "toggle")
243
243
  entry.setAttribute("role", "menuitemcheckbox");
244
244
  }
245
245
  menus.push(menu);
246
246
  return host;
247
247
  }
248
248
  function menuEntries() {
249
- for (const entry of toolbarEl.querySelectorAll("[data-rk-menu-item]")) {
250
- const id = entry.getAttribute("data-rk-menu-item") ?? "";
249
+ for (const entry of toolbarEl.querySelectorAll("[data-rte-menu-item]")) {
250
+ const id = entry.getAttribute("data-rte-menu-item") ?? "";
251
251
  const child = menuItems.get(id);
252
252
  const state = toolbar.state(id);
253
253
  if (!child || !state)
254
254
  continue;
255
255
  const label = labelOf(child);
256
- const words = entry.querySelector('[data-rk-part="label"]');
256
+ const words = entry.querySelector('[data-rte-part="label"]');
257
257
  if (words)
258
258
  words.textContent = label;
259
- const keys = entry.querySelector('[data-rk-part="menu-keys"]');
259
+ const keys = entry.querySelector('[data-rte-part="menu-keys"]');
260
260
  if (keys)
261
261
  keys.textContent = state.shortcutLabel ?? "";
262
262
  if (state.shortcut)
@@ -305,17 +305,17 @@ export function createUi(editor, options) {
305
305
  menuEntries();
306
306
  }
307
307
  function names() {
308
- for (const el of toolbarEl.querySelectorAll("[data-rk-item]")) {
309
- const id = el.getAttribute("data-rk-item") ?? "";
308
+ for (const el of toolbarEl.querySelectorAll("[data-rte-item]")) {
309
+ const id = el.getAttribute("data-rte-item") ?? "";
310
310
  const item = toolbar.items.find((i) => i.id === id);
311
311
  const state = toolbar.state(id);
312
312
  if (!item || !state)
313
313
  continue;
314
314
  const label = labelOf(item);
315
315
  el.setAttribute("aria-label", label);
316
- el.setAttribute("data-rk-tip", state.shortcutLabel ? `${label} (${state.shortcutLabel})` : label);
316
+ el.setAttribute("data-rte-tip", state.shortcutLabel ? `${label} (${state.shortcutLabel})` : label);
317
317
  if (el.tagName === "BUTTON") {
318
- const word = el.querySelector('[data-rk-part="label"]');
318
+ const word = el.querySelector('[data-rte-part="label"]');
319
319
  if (word)
320
320
  word.textContent = label;
321
321
  }
@@ -332,10 +332,10 @@ export function createUi(editor, options) {
332
332
  });
333
333
  let drawn = "";
334
334
  const onToolbarClick = (e) => {
335
- const el = e.target?.closest("[data-rk-item]");
335
+ const el = e.target?.closest("[data-rte-item]");
336
336
  if (!el)
337
337
  return;
338
- const item = toolbar.items.find((i) => i.id === el.getAttribute("data-rk-item"));
338
+ const item = toolbar.items.find((i) => i.id === el.getAttribute("data-rte-item"));
339
339
  const state = item ? toolbar.state(item.id) : undefined;
340
340
  if (item?.kind === "toggle" && state && !state.disabled) {
341
341
  const group = item.group === "align" || item.group === "lists";
@@ -356,7 +356,7 @@ export function createUi(editor, options) {
356
356
  let entry = dialogs.get(item.id);
357
357
  if (!entry) {
358
358
  const element = part(document.createElement("dialog"), "dialog");
359
- const titleId = `rk-dialog-title-${++counter}`;
359
+ const titleId = `rte-dialog-title-${++counter}`;
360
360
  element.setAttribute("aria-labelledby", titleId);
361
361
  const form = document.createElement("form");
362
362
  form.noValidate = true;
@@ -364,7 +364,7 @@ export function createUi(editor, options) {
364
364
  title.id = titleId;
365
365
  form.appendChild(title);
366
366
  for (const field of item.fields) {
367
- const inputId = `rk-field-${++counter}`;
367
+ const inputId = `rte-field-${++counter}`;
368
368
  const label = part(document.createElement("label"), "field-label");
369
369
  label.htmlFor = inputId;
370
370
  label.textContent = field.label;
@@ -388,7 +388,7 @@ export function createUi(editor, options) {
388
388
  if (field.required)
389
389
  input.required = true;
390
390
  const error = part(document.createElement("span"), "field-error");
391
- error.setAttribute("data-rk-error", field.name);
391
+ error.setAttribute("data-rte-error", field.name);
392
392
  if (field.type === "checkbox") {
393
393
  const row = part(document.createElement("div"), "field-check");
394
394
  row.append(input, label);
@@ -436,7 +436,7 @@ export function createUi(editor, options) {
436
436
  for (const f of item.fields) {
437
437
  const bad = entry.form.querySelector(`[name="${f.name}"]`);
438
438
  bad?.removeAttribute("aria-invalid");
439
- const err = entry.form.querySelector(`[data-rk-error="${f.name}"]`);
439
+ const err = entry.form.querySelector(`[data-rte-error="${f.name}"]`);
440
440
  if (err)
441
441
  err.textContent = "";
442
442
  }
@@ -484,8 +484,8 @@ export function createUi(editor, options) {
484
484
  toolbar.destroy();
485
485
  toolbarEl.remove();
486
486
  contentEl.replaceWith(...contentEl.childNodes);
487
- root.classList.remove("rk-root");
488
- for (const name of ["data-rk-theme", "data-rk-scheme", "data-rk-density", "data-rk-part"])
487
+ root.classList.remove("rte-root");
488
+ for (const name of ["data-rte-theme", "data-rte-scheme", "data-rte-density", "data-rte-part"])
489
489
  root.removeAttribute(name);
490
490
  for (const t of appliedTokens)
491
491
  root.style.removeProperty(t);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rathkit/rte-ui",
3
- "version": "0.1.0-alpha.4",
3
+ "version": "0.1.0-alpha.5",
4
4
  "description": "The styled editor interface: a toolbar and dialogs on the headless layer, themeable with tokens, presets, icons and messages.",
5
5
  "keywords": [
6
6
  "rich-text",
@@ -61,10 +61,10 @@
61
61
  "./base.css": "./css/base.css"
62
62
  },
63
63
  "peerDependencies": {
64
- "@rathkit/rte-core": ">=0.1.0-alpha.4 <0.2.0",
65
- "@rathkit/rte-headless": ">=0.1.0-alpha.4 <0.2.0",
66
- "@rathkit/rte-themes": ">=0.1.0-alpha.4 <0.2.0",
67
- "@rathkit/rte-icons": ">=0.1.0-alpha.4 <0.2.0"
64
+ "@rathkit/rte-core": ">=0.1.0-alpha.5 <0.2.0",
65
+ "@rathkit/rte-headless": ">=0.1.0-alpha.5 <0.2.0",
66
+ "@rathkit/rte-themes": ">=0.1.0-alpha.5 <0.2.0",
67
+ "@rathkit/rte-icons": ">=0.1.0-alpha.5 <0.2.0"
68
68
  },
69
69
  "peerDependenciesMeta": {
70
70
  "@rathkit/rte-core": {