@lynx-js/web-elements 0.12.9 → 0.12.10

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,18 @@
1
1
  # @lynx-js/web-elements
2
2
 
3
+ ## 0.12.10
4
+
5
+ ### Patch Changes
6
+
7
+ - Update markdown-it to ^15.0.1. ([#3749](https://github.com/lynx-family/lynx-stack/pull/3749))
8
+
9
+ - Add an optional `scroll-view` mouse-drag plugin for touchscreen-like scrolling ([#3594](https://github.com/lynx-family/lynx-stack/pull/3594))
10
+ on desktop browsers. Enable it by importing
11
+ `@lynx-js/web-core/plugins/scroll-view-mouse-drag` or
12
+ `@lynx-js/web-elements/plugins/scroll-view-mouse-drag` before registering the
13
+ web elements.
14
+ - Support the `bindselectionchange` event on `text` and `inline-text` in Lynx for Web. ([#3741](https://github.com/lynx-family/lynx-stack/pull/3741))
15
+
3
16
  ## 0.12.9
4
17
 
5
18
  ### Patch Changes
package/README.md CHANGED
@@ -37,6 +37,20 @@ document.body.innerHTML = `
37
37
  `;
38
38
  ```
39
39
 
40
+ ### Mouse-drag scrolling
41
+
42
+ To make `<scroll-view>` respond to mouse dragging like a touchscreen, load
43
+ the optional plugin before registering the elements:
44
+
45
+ ```javascript
46
+ import '@lynx-js/web-elements/plugins/scroll-view-mouse-drag';
47
+ import '@lynx-js/web-elements/all';
48
+ import '@lynx-js/web-elements/index.css';
49
+ ```
50
+
51
+ The plugin only changes `<scroll-view>` and leaves native touch scrolling
52
+ unchanged.
53
+
40
54
  ## Document
41
55
 
42
56
  See our website for more information.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,315 @@
1
+ // Copyright 2026 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ import { boostedQueueMicrotask } from '../../element-reactive/index.js';
5
+ const dragStartThreshold = 5;
6
+ const userScrollableOverflowValues = new Set(['auto', 'overlay', 'scroll']);
7
+ const blockingOverscrollBehaviorValues = new Set(['contain', 'none']);
8
+ function getScrollableAxes(dom, style) {
9
+ if (dom.getAttribute('enable-scroll') === 'false') {
10
+ return { x: false, y: false };
11
+ }
12
+ return {
13
+ x: userScrollableOverflowValues.has(style.overflowX)
14
+ && dom.scrollWidth - dom.clientWidth > 1,
15
+ y: userScrollableOverflowValues.has(style.overflowY)
16
+ && dom.scrollHeight - dom.clientHeight > 1,
17
+ };
18
+ }
19
+ function findScrollChain(event) {
20
+ let owner;
21
+ let ownerAxes;
22
+ const x = [];
23
+ const y = [];
24
+ for (const target of event.composedPath()) {
25
+ if (!(target instanceof HTMLElement) || target.localName !== 'scroll-view') {
26
+ continue;
27
+ }
28
+ const style = getComputedStyle(target);
29
+ const axes = getScrollableAxes(target, style);
30
+ if (!axes.x && !axes.y) {
31
+ continue;
32
+ }
33
+ if (!owner) {
34
+ owner = target;
35
+ ownerAxes = axes;
36
+ }
37
+ if (axes.x) {
38
+ x.push({
39
+ allowsChaining: !blockingOverscrollBehaviorValues.has(style.overscrollBehaviorX),
40
+ dom: target,
41
+ start: target.scrollLeft,
42
+ });
43
+ }
44
+ if (axes.y) {
45
+ y.push({
46
+ allowsChaining: !blockingOverscrollBehaviorValues.has(style.overscrollBehaviorY),
47
+ dom: target,
48
+ start: target.scrollTop,
49
+ });
50
+ }
51
+ }
52
+ return owner && ownerAxes ? { owner, ownerAxes, x, y } : undefined;
53
+ }
54
+ function selectDragAxes(chain, deltaX, deltaY) {
55
+ const absoluteX = Math.abs(deltaX);
56
+ const absoluteY = Math.abs(deltaY);
57
+ if (Math.hypot(deltaX, deltaY) <= dragStartThreshold) {
58
+ return undefined;
59
+ }
60
+ const hasX = chain.x.length > 0;
61
+ const hasY = chain.y.length > 0;
62
+ if (chain.ownerAxes.x && chain.ownerAxes.y) {
63
+ return { x: hasX, y: hasY };
64
+ }
65
+ if (hasX && hasY) {
66
+ if (absoluteX === absoluteY) {
67
+ return chain.ownerAxes.x
68
+ ? { x: true, y: false }
69
+ : { x: false, y: true };
70
+ }
71
+ return absoluteX > absoluteY
72
+ ? { x: true, y: false }
73
+ : { x: false, y: true };
74
+ }
75
+ if (hasX && absoluteX >= absoluteY) {
76
+ return { x: true, y: false };
77
+ }
78
+ if (hasY && absoluteY >= absoluteX) {
79
+ return { x: false, y: true };
80
+ }
81
+ return undefined;
82
+ }
83
+ function applyScrollDelta(candidates, delta, axis) {
84
+ let remaining = delta;
85
+ for (const candidate of candidates) {
86
+ const next = candidate.start + remaining;
87
+ if (axis === 'x') {
88
+ candidate.dom.scrollTo({
89
+ behavior: 'instant',
90
+ left: next,
91
+ top: candidate.dom.scrollTop,
92
+ });
93
+ remaining -= candidate.dom.scrollLeft - candidate.start;
94
+ }
95
+ else {
96
+ candidate.dom.scrollTo({
97
+ behavior: 'instant',
98
+ left: candidate.dom.scrollLeft,
99
+ top: next,
100
+ });
101
+ remaining -= candidate.dom.scrollTop - candidate.start;
102
+ }
103
+ if (!candidate.allowsChaining) {
104
+ return;
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * Makes a scroll-view follow mouse dragging in the same direction as touch
110
+ * scrolling. Pointer events from touchscreens are left to the browser.
111
+ */
112
+ class ScrollViewMouseDrag {
113
+ static observedAttributes = [];
114
+ #dom;
115
+ #connected = false;
116
+ #dragState;
117
+ #clickSuppression;
118
+ constructor(dom) {
119
+ this.#dom = dom;
120
+ }
121
+ #handlePointerDown = (event) => {
122
+ if (event.pointerType !== 'mouse'
123
+ || !event.isPrimary
124
+ || event.button !== 0
125
+ || this.#dragState) {
126
+ return;
127
+ }
128
+ const chain = findScrollChain(event);
129
+ if (!chain || chain.owner !== this.#dom) {
130
+ return;
131
+ }
132
+ const document = this.#dom.ownerDocument;
133
+ this.#dragState = {
134
+ chain,
135
+ document,
136
+ dragging: false,
137
+ pendingDeltaX: 0,
138
+ pendingDeltaY: 0,
139
+ pointerId: event.pointerId,
140
+ scrollUpdateQueued: false,
141
+ startClientX: event.clientX,
142
+ startClientY: event.clientY,
143
+ };
144
+ this.#trackPotentialClick(document);
145
+ document.addEventListener('pointermove', this.#handlePointerMove, {
146
+ capture: true,
147
+ passive: false,
148
+ });
149
+ document.addEventListener('pointerup', this.#handlePointerUp, true);
150
+ document.addEventListener('pointercancel', this.#handlePointerCancel, true);
151
+ document.defaultView?.addEventListener('blur', this.#handlePointerCancel);
152
+ };
153
+ #handlePointerMove = (event) => {
154
+ const state = this.#dragState;
155
+ if (!state || event.pointerId !== state.pointerId) {
156
+ return;
157
+ }
158
+ if ((event.buttons & 1) === 0) {
159
+ this.#stopDragging(false);
160
+ return;
161
+ }
162
+ const deltaX = event.clientX - state.startClientX;
163
+ const deltaY = event.clientY - state.startClientY;
164
+ if (!state.dragging) {
165
+ const activeAxes = selectDragAxes(state.chain, deltaX, deltaY);
166
+ if (!activeAxes) {
167
+ return;
168
+ }
169
+ state.activeAxes = activeAxes;
170
+ state.dragging = true;
171
+ state.previousUserSelect = this.#dom.style.userSelect;
172
+ this.#dom.style.userSelect = 'none';
173
+ state.document.getSelection()?.removeAllRanges();
174
+ this.#dom.setPointerCapture(event.pointerId);
175
+ }
176
+ if (event.cancelable) {
177
+ event.preventDefault();
178
+ }
179
+ state.pendingDeltaX = -deltaX;
180
+ state.pendingDeltaY = -deltaY;
181
+ if (!state.scrollUpdateQueued) {
182
+ state.scrollUpdateQueued = true;
183
+ boostedQueueMicrotask(() => this.#flushScrollUpdate(state));
184
+ }
185
+ };
186
+ #flushScrollUpdate(state) {
187
+ if (!state.scrollUpdateQueued) {
188
+ return;
189
+ }
190
+ state.scrollUpdateQueued = false;
191
+ if (state.activeAxes?.x) {
192
+ applyScrollDelta(state.chain.x, state.pendingDeltaX, 'x');
193
+ }
194
+ if (state.activeAxes?.y) {
195
+ applyScrollDelta(state.chain.y, state.pendingDeltaY, 'y');
196
+ }
197
+ }
198
+ #handlePointerUp = (event) => {
199
+ if (event.pointerId !== this.#dragState?.pointerId) {
200
+ return;
201
+ }
202
+ this.#stopDragging(this.#dragState.dragging);
203
+ };
204
+ #handlePointerCancel = (event) => {
205
+ if (event instanceof PointerEvent
206
+ && event.pointerId !== this.#dragState?.pointerId) {
207
+ return;
208
+ }
209
+ this.#stopDragging(false);
210
+ };
211
+ #handleDragStart = (event) => {
212
+ if (this.#dragState) {
213
+ event.preventDefault();
214
+ }
215
+ };
216
+ #handleClick = (event) => {
217
+ if (!this.#clickSuppression?.suppress
218
+ || !event.composedPath().includes(this.#dom)) {
219
+ return;
220
+ }
221
+ this.#clearClickSuppression();
222
+ event.preventDefault();
223
+ event.stopImmediatePropagation();
224
+ };
225
+ #stopDragging(suppressClick) {
226
+ const state = this.#dragState;
227
+ if (!state) {
228
+ return;
229
+ }
230
+ const { document } = state;
231
+ this.#flushScrollUpdate(state);
232
+ document.removeEventListener('pointermove', this.#handlePointerMove, true);
233
+ document.removeEventListener('pointerup', this.#handlePointerUp, true);
234
+ document.removeEventListener('pointercancel', this.#handlePointerCancel, true);
235
+ document.defaultView?.removeEventListener('blur', this.#handlePointerCancel);
236
+ if (this.#dom.hasPointerCapture(state.pointerId)) {
237
+ this.#dom.releasePointerCapture(state.pointerId);
238
+ }
239
+ if (state.dragging && this.#dom.style.userSelect === 'none') {
240
+ this.#dom.style.userSelect = state.previousUserSelect ?? '';
241
+ }
242
+ this.#dragState = undefined;
243
+ if (suppressClick) {
244
+ const clickSuppression = this.#clickSuppression;
245
+ if (clickSuppression) {
246
+ clickSuppression.suppress = true;
247
+ clearTimeout(clickSuppression.timer);
248
+ clickSuppression.timer = setTimeout(this.#clearClickSuppression, 0);
249
+ }
250
+ }
251
+ else {
252
+ this.#clearClickSuppression();
253
+ }
254
+ }
255
+ #trackPotentialClick(document) {
256
+ this.#clearClickSuppression();
257
+ const target = document.defaultView ?? document;
258
+ this.#clickSuppression = { suppress: false, target };
259
+ target.addEventListener('click', this.#handleClick, true);
260
+ }
261
+ #clearClickSuppression = () => {
262
+ const clickSuppression = this.#clickSuppression;
263
+ if (!clickSuppression) {
264
+ return;
265
+ }
266
+ clickSuppression.target.removeEventListener('click', this.#handleClick, true);
267
+ clearTimeout(clickSuppression.timer);
268
+ this.#clickSuppression = undefined;
269
+ };
270
+ connectedCallback() {
271
+ if (this.#connected) {
272
+ return;
273
+ }
274
+ this.#connected = true;
275
+ this.#dom.addEventListener('pointerdown', this.#handlePointerDown, true);
276
+ this.#dom.addEventListener('dragstart', this.#handleDragStart, true);
277
+ }
278
+ dispose() {
279
+ this.#connected = false;
280
+ this.#dom.removeEventListener('pointerdown', this.#handlePointerDown, true);
281
+ this.#dom.removeEventListener('dragstart', this.#handleDragStart, true);
282
+ this.#stopDragging(false);
283
+ this.#clearClickSuppression();
284
+ }
285
+ }
286
+ const scrollViewTagName = 'scroll-view';
287
+ const registeredClasses = new WeakSet();
288
+ function registerMouseDragPlugin(elementClass) {
289
+ if (registeredClasses.has(elementClass)) {
290
+ return;
291
+ }
292
+ const componentClass = elementClass;
293
+ if (!componentClass.registerPlugin) {
294
+ return;
295
+ }
296
+ componentClass.registerPlugin(ScrollViewMouseDrag);
297
+ registeredClasses.add(elementClass);
298
+ }
299
+ if (typeof customElements !== 'undefined') {
300
+ const registeredScrollView = customElements.get(scrollViewTagName);
301
+ if (registeredScrollView) {
302
+ registerMouseDragPlugin(registeredScrollView);
303
+ }
304
+ else {
305
+ const define = Reflect.get(customElements, 'define');
306
+ customElements.define = function (name, elementClass, options) {
307
+ if (name === scrollViewTagName) {
308
+ registerMouseDragPlugin(elementClass);
309
+ }
310
+ Reflect.apply(define, this, [name, elementClass, options]);
311
+ };
312
+ void customElements.whenDefined(scrollViewTagName).then(registerMouseDragPlugin);
313
+ }
314
+ }
315
+ //# sourceMappingURL=ScrollViewMouseDrag.js.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @deprecated you can use x-text instead in x-text.
2
+ * @deprecated Use x-text instead of inline-text.
3
3
  */
4
4
  export declare class InlineText extends HTMLElement {
5
5
  }
@@ -5,11 +5,12 @@ import { __esDecorate, __runInitializers } from "tslib";
5
5
  // LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { Component } from '../../element-reactive/index.js';
8
+ import { XTextSelectionEvents } from './XTextSelectionEvents.js';
8
9
  /**
9
- * @deprecated you can use x-text instead in x-text.
10
+ * @deprecated Use x-text instead of inline-text.
10
11
  */
11
12
  let InlineText = (() => {
12
- let _classDecorators = [Component('inline-text', [])];
13
+ let _classDecorators = [Component('inline-text', [XTextSelectionEvents])];
13
14
  let _classDescriptor;
14
15
  let _classExtraInitializers = [];
15
16
  let _classThis;
@@ -10,8 +10,14 @@ import { ScrollIntoView } from '../ScrollView/ScrollIntoView.js';
10
10
  import { RawTextAttributes } from './RawText.js';
11
11
  import { CommonEventsAndMethods, layoutChangeTarget, } from '../common/CommonEventsAndMethods.js';
12
12
  import { templateXText } from '../htmlTemplates.js';
13
+ import { XTextSelectionEvents } from './XTextSelectionEvents.js';
13
14
  let XText = (() => {
14
- let _classDecorators = [Component('x-text', [CommonEventsAndMethods, XTextTruncation, RawTextAttributes], templateXText)];
15
+ let _classDecorators = [Component('x-text', [
16
+ CommonEventsAndMethods,
17
+ XTextSelectionEvents,
18
+ XTextTruncation,
19
+ RawTextAttributes,
20
+ ], templateXText)];
15
21
  let _classDescriptor;
16
22
  let _classExtraInitializers = [];
17
23
  let _classThis;
@@ -0,0 +1,9 @@
1
+ import { type AttributeReactiveClass } from '../../element-reactive/index.js';
2
+ export declare class XTextSelectionEvents implements InstanceType<AttributeReactiveClass<typeof HTMLElement>> {
3
+ #private;
4
+ static observedAttributes: never[];
5
+ constructor(dom: HTMLElement);
6
+ connectedCallback(): void;
7
+ dispose(): void;
8
+ _handleEnableSelectionChangeEvent(status: boolean): void;
9
+ }
@@ -0,0 +1,134 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ /*
3
+ // Copyright 2026 The Lynx Authors. All rights reserved.
4
+ // Licensed under the Apache License Version 2.0 that can be found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { registerEventEnableStatusChangeHandler, } from '../../element-reactive/index.js';
8
+ import { commonComponentEventSetting } from '../common/commonEventInitConfiguration.js';
9
+ const emptySelection = () => ({
10
+ start: -1,
11
+ end: -1,
12
+ direction: 'forward',
13
+ });
14
+ /**
15
+ * Converts a selection boundary to an offset in the target's text. Using the
16
+ * range text length provides one offset space across nested text nodes.
17
+ */
18
+ const getTextOffset = (root, node, offset) => {
19
+ if (!node || !root.contains(node))
20
+ return null;
21
+ const range = root.ownerDocument.createRange();
22
+ range.selectNodeContents(root);
23
+ try {
24
+ range.setEnd(node, offset);
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ return range.toString().length;
30
+ };
31
+ /**
32
+ * Returns offsets relative to the target text. A -1 offset means the selection
33
+ * is collapsed, unavailable, or outside the target.
34
+ */
35
+ const getSelectionDetail = (dom) => {
36
+ const selection = dom.ownerDocument.getSelection();
37
+ if (!selection || selection.rangeCount === 0) {
38
+ return emptySelection();
39
+ }
40
+ const anchor = getTextOffset(dom, selection.anchorNode, selection.anchorOffset);
41
+ const focus = getTextOffset(dom, selection.focusNode, selection.focusOffset);
42
+ if (anchor !== null && focus !== null && anchor !== focus) {
43
+ return {
44
+ start: Math.min(anchor, focus),
45
+ end: Math.max(anchor, focus),
46
+ direction: anchor < focus ? 'forward' : 'backward',
47
+ };
48
+ }
49
+ // WebKit retargets selection endpoints outside a shadow tree. Ask for the
50
+ // composed range to recover the actual text nodes in that case.
51
+ const shadowRoots = [];
52
+ let root = dom.getRootNode();
53
+ while (root instanceof ShadowRoot) {
54
+ shadowRoots.push(root);
55
+ root = root.host.getRootNode();
56
+ }
57
+ const [range] = selection.getComposedRanges?.({ shadowRoots }) ?? [];
58
+ const start = range
59
+ ? getTextOffset(dom, range.startContainer, range.startOffset)
60
+ : null;
61
+ const end = range
62
+ ? getTextOffset(dom, range.endContainer, range.endOffset)
63
+ : null;
64
+ if (start === null || end === null || start === end)
65
+ return emptySelection();
66
+ return {
67
+ start,
68
+ end,
69
+ direction: selection.direction === 'backward' ? 'backward' : 'forward',
70
+ };
71
+ };
72
+ let XTextSelectionEvents = (() => {
73
+ let _instanceExtraInitializers = [];
74
+ let __handleEnableSelectionChangeEvent_decorators;
75
+ return class XTextSelectionEvents {
76
+ static {
77
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
78
+ __handleEnableSelectionChangeEvent_decorators = [registerEventEnableStatusChangeHandler('selectionchange')];
79
+ __esDecorate(this, null, __handleEnableSelectionChangeEvent_decorators, { kind: "method", name: "_handleEnableSelectionChangeEvent", static: false, private: false, access: { has: obj => "_handleEnableSelectionChangeEvent" in obj, get: obj => obj._handleEnableSelectionChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
80
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
81
+ }
82
+ static observedAttributes = [];
83
+ #dom = __runInitializers(this, _instanceExtraInitializers);
84
+ #enabled = false;
85
+ #connected = false;
86
+ #attachedDocument;
87
+ #lastSelectionSignature;
88
+ constructor(dom) {
89
+ this.#dom = dom;
90
+ }
91
+ connectedCallback() {
92
+ this.#connected = true;
93
+ this.#updateSelectionChangeListener();
94
+ }
95
+ dispose() {
96
+ this.#connected = false;
97
+ this.#updateSelectionChangeListener();
98
+ }
99
+ _handleEnableSelectionChangeEvent(status) {
100
+ this.#enabled = status;
101
+ if (!status)
102
+ this.#lastSelectionSignature = undefined;
103
+ this.#updateSelectionChangeListener();
104
+ }
105
+ #updateSelectionChangeListener() {
106
+ const document = this.#dom.ownerDocument;
107
+ const shouldAttach = this.#enabled && this.#connected;
108
+ if (shouldAttach && this.#attachedDocument === document)
109
+ return;
110
+ if (!shouldAttach && !this.#attachedDocument)
111
+ return;
112
+ this.#attachedDocument?.removeEventListener('selectionchange', this.#handleSelectionChange);
113
+ if (shouldAttach) {
114
+ document.addEventListener('selectionchange', this.#handleSelectionChange);
115
+ }
116
+ this.#attachedDocument = shouldAttach ? document : undefined;
117
+ }
118
+ #handleSelectionChange = () => {
119
+ const detail = getSelectionDetail(this.#dom);
120
+ const signature = `${detail.start}:${detail.end}:${detail.direction}`;
121
+ if (signature === this.#lastSelectionSignature
122
+ || (detail.start === -1 && this.#lastSelectionSignature === undefined)) {
123
+ return;
124
+ }
125
+ this.#lastSelectionSignature = signature;
126
+ this.#dom.dispatchEvent(new CustomEvent('selectionchange', {
127
+ ...commonComponentEventSetting,
128
+ detail,
129
+ }));
130
+ };
131
+ };
132
+ })();
133
+ export { XTextSelectionEvents };
134
+ //# sourceMappingURL=XTextSelectionEvents.js.map
@@ -14,6 +14,7 @@ export { RawText } from './RawText.js';
14
14
  *
15
15
  * Events:
16
16
  * - `layout`: Fired when text layout happens (if enabled). Detail provides line info.
17
+ * - `selectionchange`: Fired when the text selection changes. Detail provides start, end, and direction.
17
18
  *
18
19
  * CSS Variables:
19
20
  * - `--lynx-text-bg-color`: Inherited background color for nested text elements.
@@ -17,6 +17,7 @@ export { RawText } from './RawText.js';
17
17
  *
18
18
  * Events:
19
19
  * - `layout`: Fired when text layout happens (if enabled). Detail provides line info.
20
+ * - `selectionchange`: Fired when the text selection changes. Detail provides start, end, and direction.
20
21
  *
21
22
  * CSS Variables:
22
23
  * - `--lynx-text-bg-color`: Inherited background color for nested text elements.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-elements",
3
- "version": "0.12.9",
3
+ "version": "0.12.10",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,6 +34,11 @@
34
34
  "types": "./dist/elements/ScrollView/index.d.ts",
35
35
  "default": "./dist/elements/ScrollView/index.js"
36
36
  },
37
+ "./plugins/scroll-view-mouse-drag": {
38
+ "@lynx-js/source-field": "./src/elements/ScrollView/ScrollViewMouseDrag.ts",
39
+ "types": "./dist/elements/ScrollView/ScrollViewMouseDrag.d.ts",
40
+ "default": "./dist/elements/ScrollView/ScrollViewMouseDrag.js"
41
+ },
37
42
  "./XAudioTT": {
38
43
  "@lynx-js/source-field": "./src/elements/XAudioTT/index.ts",
39
44
  "types": "./dist/elements/XAudioTT/index.d.ts",
@@ -135,11 +140,11 @@
135
140
  ],
136
141
  "dependencies": {
137
142
  "dompurify": "^3.4.13",
138
- "markdown-it": "^15.0.0"
143
+ "markdown-it": "^15.0.1"
139
144
  },
140
145
  "devDependencies": {
141
146
  "@playwright/test": "^1.61.1",
142
- "@rsbuild/core": "2.1.10",
147
+ "@rsbuild/core": "2.2.3",
143
148
  "@rsbuild/plugin-source-build": "1.0.6",
144
149
  "@types/markdown-it": "^14.1.2",
145
150
  "@types/node": "^24.13.3",