@prosekit/lit 0.0.21 → 0.0.23

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.
@@ -3,6 +3,7 @@ import { CommandArgs } from '@prosekit/core';
3
3
  import { ComputePositionConfig } from '@floating-ui/dom';
4
4
  import { CSSResult } from 'lit';
5
5
  import { Editor } from '@prosekit/core';
6
+ import type { EditorView } from '@prosekit/pm/view';
6
7
  import { Extension } from '@prosekit/core';
7
8
  import { ExtensionTyping } from '@prosekit/core';
8
9
  import { Keymap } from '@prosekit/core';
@@ -255,8 +256,13 @@ export declare const default_alias_1: UserProjectConfigExport;
255
256
  */
256
257
  export declare const defaultPopoverOptions: PopoverOptions;
257
258
 
259
+ /**
260
+ * Default popover options.
261
+ */
258
262
  export declare const defaultPopoverOptions_alias_1: PopoverOptions;
259
263
 
264
+ export declare const defaultPopoverOptions_alias_2: PopoverOptions;
265
+
260
266
  export declare function defaultQueryBuilder(match: RegExpExecArray): string;
261
267
 
262
268
  /**
@@ -272,6 +278,40 @@ export declare function defineCodeBlockSelect(options: {
272
278
  onDismiss: () => void;
273
279
  }): Extension<ExtensionTyping<string, string, CommandArgs>>;
274
280
 
281
+ export declare function getVirtualSelectionElement(view: EditorView): Range | undefined;
282
+
283
+ export declare class InlinePopover extends Popover implements Partial<InlinePopoverProps> {
284
+ /** @hidden */
285
+ private controller;
286
+ editor?: Editor;
287
+ popoverOptions: PopoverOptions;
288
+ constructor();
289
+ /** @hidden */
290
+ willUpdate(): void;
291
+ /** @hidden */
292
+ hide(): void;
293
+ }
294
+
295
+ export declare class InlinePopoverController implements ReactiveController {
296
+ private host;
297
+ reference?: VirtualElement;
298
+ private editor?;
299
+ private cleanupExtension?;
300
+ private cleanupEventListener?;
301
+ private mouseHovering;
302
+ constructor(host: ReactiveControllerHost);
303
+ setEditor(editor: Editor): void;
304
+ hostConnected(): void;
305
+ hostDisconnected(): void;
306
+ private update;
307
+ private defineExtension;
308
+ }
309
+
310
+ export declare interface InlinePopoverProps {
311
+ editor: Editor;
312
+ popoverOptions?: PopoverOptions;
313
+ }
314
+
275
315
  export declare function isAutocompleteItem(element?: Element | null): element is AutocompleteItem;
276
316
 
277
317
  export declare function isAutocompleteList(element?: Element | null): element is AutocompleteList;
@@ -361,6 +401,19 @@ export declare class Popover extends LightElement implements Partial<PopoverProp
361
401
  * the Floating UI documentation. This property is only used when the `autoUpdate` property is set to `true`.
362
402
  */
363
403
  autoUpdateOptions?: AutoUpdateOptions;
404
+ /**
405
+ * Controls whether the popover should be dismissed based on user interaction.
406
+ *
407
+ * Available options:
408
+ *
409
+ * - "off": The popover is not dismissed.
410
+ * - "on": The popover is dismissed when the user clicks outside of the popover or presses the escape key.
411
+ * - "click": The popover is dismissed when the user clicks outside of the popover.
412
+ * - "escape": The popover is dismissed when the user presses the escape key.
413
+ *
414
+ * @default "on"
415
+ */
416
+ dismiss: string;
364
417
  /** @hidden */
365
418
  private disposeAutoUpdate?;
366
419
  /** @hidden */
@@ -394,6 +447,7 @@ declare type PopoverOptions = ComputePositionConfig;
394
447
  export { PopoverOptions }
395
448
  export { PopoverOptions as PopoverOptions_alias_1 }
396
449
  export { PopoverOptions as PopoverOptions_alias_2 }
450
+ export { PopoverOptions as PopoverOptions_alias_3 }
397
451
 
398
452
  export declare interface PopoverProps {
399
453
  active: boolean;
@@ -421,7 +475,9 @@ declare const propNames_5: never[];
421
475
  export { propNames_5 as propNames_alias_11 }
422
476
  export { propNames_5 as propNames_alias_12 }
423
477
 
424
- export declare const propNames_alias_13: readonly ["active", "reference", "options", "autoUpdate", "autoUpdateOptions"];
478
+ export declare const propNames_alias_13: readonly ["editor", "popoverOptions"];
479
+
480
+ export declare const propNames_alias_14: readonly ["active", "reference", "options", "autoUpdate", "autoUpdateOptions"];
425
481
 
426
482
  export declare const propNames_alias_5: readonly ["editor", "regex", "popoverOptions"];
427
483
 
@@ -17,7 +17,7 @@ function roundByDPR(value) {
17
17
  }
18
18
 
19
19
  // src/components/popover/default-popover-options.ts
20
- import { offset, shift } from "@floating-ui/dom";
20
+ import { offset, shift, size } from "@floating-ui/dom";
21
21
 
22
22
  // src/components/popover/options.ts
23
23
  import "@floating-ui/dom";
@@ -25,7 +25,23 @@ import "@floating-ui/dom";
25
25
  // src/components/popover/default-popover-options.ts
26
26
  var defaultPopoverOptions = {
27
27
  placement: "bottom",
28
- middleware: [offset(4), shift({ padding: 8 })]
28
+ middleware: [
29
+ offset({ mainAxis: 8, crossAxis: 8 }),
30
+ shift({ padding: 8 }),
31
+ size({
32
+ apply: ({ availableWidth, availableHeight, elements }) => {
33
+ elements.floating.style.setProperty(
34
+ "--prosekit-popover-available-width",
35
+ `${Math.floor(availableWidth)}px`
36
+ );
37
+ elements.floating.style.setProperty(
38
+ "--prosekit-popover-available-height",
39
+ `${Math.floor(availableHeight)}px`
40
+ );
41
+ },
42
+ padding: 8
43
+ })
44
+ ]
29
45
  };
30
46
 
31
47
  // src/components/popover/index.ts
@@ -42,6 +58,7 @@ var Popover = class extends LightElement {
42
58
  super();
43
59
  this.active = false;
44
60
  this.autoUpdate = false;
61
+ this.dismiss = "on";
45
62
  this.handleDocumentMouseDown = (event) => {
46
63
  const path = event.composedPath();
47
64
  if (!path.includes(this)) {
@@ -59,13 +76,15 @@ var Popover = class extends LightElement {
59
76
  /** @hidden */
60
77
  connectedCallback() {
61
78
  super.connectedCallback();
62
- const handleMouseDown = this.handleDocumentMouseDown.bind(this);
63
- const handleKeyDown = this.handleDocumentKeyDown.bind(this);
64
- document.addEventListener("mousedown", handleMouseDown);
65
- document.addEventListener("keydown", handleKeyDown);
79
+ const clickEnabled = this.dismiss === "on" || this.dismiss === "click";
80
+ const escapeEnabled = this.dismiss === "on" || this.dismiss === "escape";
81
+ const handleMouseDown = clickEnabled ? this.handleDocumentMouseDown.bind(this) : null;
82
+ const handleKeyDown = escapeEnabled ? this.handleDocumentKeyDown.bind(this) : null;
83
+ handleMouseDown && document.addEventListener("mousedown", handleMouseDown);
84
+ handleKeyDown && document.addEventListener("keydown", handleKeyDown);
66
85
  this.disposeEventListeners = () => {
67
- document.removeEventListener("mousedown", handleMouseDown);
68
- document.removeEventListener("keydown", handleKeyDown);
86
+ handleMouseDown && document.removeEventListener("mousedown", handleMouseDown);
87
+ handleKeyDown && document.removeEventListener("keydown", handleKeyDown);
69
88
  };
70
89
  }
71
90
  /** @hidden */
@@ -112,14 +131,18 @@ var Popover = class extends LightElement {
112
131
  if (!this.active)
113
132
  return;
114
133
  this.setHidden(false);
115
- this.style.position = (_b = (_a = this.options) == null ? void 0 : _a.strategy) != null ? _b : "absolute";
134
+ this.style.setProperty("top", "0");
135
+ this.style.setProperty("left", "0");
136
+ this.style.setProperty("position", (_b = (_a = this.options) == null ? void 0 : _a.strategy) != null ? _b : "absolute");
116
137
  const options = (_c = this.options) != null ? _c : defaultPopoverOptions;
117
138
  const computed = await computePosition(reference, this, options);
118
139
  const { x, y, strategy } = computed != null ? computed : { x: 0, y: 0, strategy: "absolute" };
119
- this.style.top = "0";
120
- this.style.left = "0";
121
- this.style.position = strategy;
122
- this.style.transform = `translate(${roundByDPR(x)}px,${roundByDPR(y)}px)`;
140
+ this.style.setProperty("opacity", "1");
141
+ this.style.setProperty("position", strategy);
142
+ this.style.setProperty(
143
+ "transform",
144
+ `translate(${roundByDPR(x)}px,${roundByDPR(y)}px)`
145
+ );
123
146
  }
124
147
  /** @hidden */
125
148
  hide() {
@@ -144,6 +167,12 @@ __decorateClass([
144
167
  __decorateClass([
145
168
  property({ type: Object })
146
169
  ], Popover.prototype, "autoUpdateOptions", 2);
170
+ __decorateClass([
171
+ property({
172
+ type: String,
173
+ reflect: true
174
+ })
175
+ ], Popover.prototype, "dismiss", 2);
147
176
  Popover = __decorateClass([
148
177
  customElement("prosekit-popover")
149
178
  ], Popover);
@@ -6,7 +6,7 @@ import "./chunk-6P3YKUWI.js";
6
6
  import "./chunk-PCXKL6TA.js";
7
7
  import {
8
8
  Popover
9
- } from "./chunk-P336E72L.js";
9
+ } from "./chunk-HNKGDXIJ.js";
10
10
  import {
11
11
  __decorateClass
12
12
  } from "./chunk-ZN7DMIEB.js";
@@ -123,24 +123,14 @@ var defaultDetectOverflowOptions = {
123
123
  var defaultPopoverOptions = {
124
124
  placement: "bottom-end",
125
125
  middleware: [
126
+ // Use the text caret as the reference point
127
+ inline(),
126
128
  offset(({ rects }) => ({
127
129
  // Put the popover at the bottom right corner
128
130
  alignmentAxis: -rects.floating.width,
129
131
  // Move down the popover by 4px
130
132
  mainAxis: 4
131
133
  })),
132
- size({
133
- apply: ({ availableHeight, elements }) => {
134
- const style = {
135
- // Minimum acceptable height is 100px.
136
- // `flip` will then take over.
137
- maxHeight: `${Math.max(100, availableHeight)}px`,
138
- overflowY: "auto"
139
- };
140
- Object.assign(elements.floating.style, style);
141
- },
142
- ...defaultDetectOverflowOptions
143
- }),
144
134
  // Flip the popover to the top if it's overflowing the viewport
145
135
  flip({
146
136
  fallbackStrategy: "initialPlacement",
@@ -148,11 +138,22 @@ var defaultPopoverOptions = {
148
138
  crossAxis: false,
149
139
  ...defaultDetectOverflowOptions
150
140
  }),
151
- shift({
141
+ size({
142
+ apply: ({ availableWidth, availableHeight, elements }) => {
143
+ elements.floating.style.setProperty(
144
+ "--prosekit-popover-available-width",
145
+ `${Math.floor(availableWidth)}px`
146
+ );
147
+ elements.floating.style.setProperty(
148
+ "--prosekit-popover-available-height",
149
+ `${Math.floor(availableHeight)}px`
150
+ );
151
+ },
152
152
  ...defaultDetectOverflowOptions
153
153
  }),
154
- // Use the text caret as the reference point
155
- inline()
154
+ shift({
155
+ ...defaultDetectOverflowOptions
156
+ })
156
157
  ]
157
158
  };
158
159
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Popover
3
- } from "./chunk-P336E72L.js";
3
+ } from "./chunk-HNKGDXIJ.js";
4
4
  import {
5
5
  __decorateClass
6
6
  } from "./chunk-ZN7DMIEB.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-PCXKL6TA.js";
5
5
  import {
6
6
  Popover
7
- } from "./chunk-P336E72L.js";
7
+ } from "./chunk-HNKGDXIJ.js";
8
8
  import {
9
9
  comboBoxContext
10
10
  } from "./chunk-C4MW43I4.js";
@@ -0,0 +1,4 @@
1
+ export { PopoverOptions_alias_1 as PopoverOptions } from './_tsup-dts-rollup';
2
+ export { propNames_alias_13 as propNames } from './_tsup-dts-rollup';
3
+ export { InlinePopoverProps } from './_tsup-dts-rollup';
4
+ export { InlinePopover } from './_tsup-dts-rollup';
@@ -0,0 +1,155 @@
1
+ import {
2
+ Popover
3
+ } from "./chunk-HNKGDXIJ.js";
4
+ import {
5
+ __decorateClass
6
+ } from "./chunk-ZN7DMIEB.js";
7
+
8
+ // src/components/inline-popover/index.ts
9
+ import "@prosekit/core";
10
+ import { customElement, property } from "lit/decorators.js";
11
+
12
+ // src/components/inline-popover/controller.ts
13
+ import { defineEventHandler } from "@prosekit/core";
14
+ import "lit";
15
+
16
+ // src/components/inline-popover/helpers.ts
17
+ import { isTextSelection } from "@prosekit/core";
18
+ function getVirtualSelectionElement(view) {
19
+ if (typeof window === "undefined" || view.isDestroyed) {
20
+ return;
21
+ }
22
+ const selection = view.state.selection;
23
+ if (selection.empty && !isTextSelection(selection)) {
24
+ return;
25
+ }
26
+ return getDomRange();
27
+ }
28
+ function getDomRange() {
29
+ const selection = window.getSelection();
30
+ if (!selection || selection.isCollapsed) {
31
+ return;
32
+ }
33
+ const range = typeof selection.rangeCount === "number" && selection.rangeCount > 0 && selection.getRangeAt(0);
34
+ if (!range) {
35
+ return;
36
+ }
37
+ return range;
38
+ }
39
+
40
+ // src/components/inline-popover/controller.ts
41
+ var InlinePopoverController = class {
42
+ constructor(host) {
43
+ this.host = host;
44
+ this.mouseHovering = false;
45
+ this.host.addController(this);
46
+ }
47
+ setEditor(editor) {
48
+ if (this.editor !== editor) {
49
+ this.editor = editor;
50
+ this.defineExtension();
51
+ this.host.requestUpdate();
52
+ }
53
+ }
54
+ hostConnected() {
55
+ var _a;
56
+ const handleMouseDown = () => {
57
+ this.mouseHovering = true;
58
+ };
59
+ const handleMouseUp = () => {
60
+ this.mouseHovering = false;
61
+ this.update();
62
+ };
63
+ document.addEventListener("mousedown", handleMouseDown);
64
+ document.addEventListener("mouseup", handleMouseUp);
65
+ (_a = this.cleanupEventListener) == null ? void 0 : _a.call(this);
66
+ this.cleanupEventListener = () => {
67
+ document.removeEventListener("mousedown", handleMouseDown);
68
+ document.removeEventListener("mouseup", handleMouseUp);
69
+ };
70
+ }
71
+ hostDisconnected() {
72
+ var _a, _b;
73
+ (_a = this.cleanupExtension) == null ? void 0 : _a.call(this);
74
+ this.cleanupExtension = void 0;
75
+ (_b = this.cleanupEventListener) == null ? void 0 : _b.call(this);
76
+ this.cleanupEventListener = void 0;
77
+ }
78
+ update() {
79
+ const editor = this.editor;
80
+ if (!editor || this.mouseHovering) {
81
+ return;
82
+ }
83
+ const reference = getVirtualSelectionElement(editor.view);
84
+ if (this.reference !== reference) {
85
+ this.reference = reference;
86
+ this.host.requestUpdate();
87
+ }
88
+ }
89
+ defineExtension() {
90
+ var _a;
91
+ const editor = this.editor;
92
+ if (!editor) {
93
+ return;
94
+ }
95
+ const extension = defineEventHandler({ update: () => this.update() });
96
+ (_a = this.cleanupExtension) == null ? void 0 : _a.call(this);
97
+ this.cleanupExtension = editor.use(extension);
98
+ }
99
+ };
100
+
101
+ // src/components/inline-popover/default-popover-options.ts
102
+ import { inline, offset, shift } from "@floating-ui/dom";
103
+ var defaultPopoverOptions = {
104
+ placement: "top",
105
+ strategy: "absolute",
106
+ middleware: [
107
+ inline(),
108
+ offset(8),
109
+ shift({ mainAxis: true, crossAxis: true, padding: 8 })
110
+ ]
111
+ };
112
+
113
+ // src/components/inline-popover/index.ts
114
+ var propNames = ["editor", "popoverOptions"];
115
+ var InlinePopover = class extends Popover {
116
+ constructor() {
117
+ super();
118
+ /** @hidden */
119
+ this.controller = new InlinePopoverController(this);
120
+ this.popoverOptions = defaultPopoverOptions;
121
+ this.dismiss = "escape";
122
+ }
123
+ /** @hidden */
124
+ willUpdate() {
125
+ var _a, _b;
126
+ if (this.editor) {
127
+ this.controller.setEditor(this.editor);
128
+ }
129
+ this.active = !!((_a = this.controller) == null ? void 0 : _a.reference);
130
+ this.reference = (_b = this.controller.reference) != null ? _b : void 0;
131
+ this.options = this.popoverOptions;
132
+ }
133
+ /** @hidden */
134
+ hide() {
135
+ var _a;
136
+ super.hide();
137
+ if ((_a = this.controller) == null ? void 0 : _a.reference) {
138
+ this.controller.reference = void 0;
139
+ this.reference = void 0;
140
+ }
141
+ }
142
+ };
143
+ __decorateClass([
144
+ property({ attribute: false })
145
+ ], InlinePopover.prototype, "editor", 2);
146
+ __decorateClass([
147
+ property({ attribute: false })
148
+ ], InlinePopover.prototype, "popoverOptions", 2);
149
+ InlinePopover = __decorateClass([
150
+ customElement("prosekit-inline-popover")
151
+ ], InlinePopover);
152
+ export {
153
+ InlinePopover,
154
+ propNames
155
+ };
@@ -1,5 +1,5 @@
1
1
  export { AutoUpdateOptions } from './_tsup-dts-rollup';
2
- export { PopoverOptions_alias_1 as PopoverOptions } from './_tsup-dts-rollup';
3
- export { propNames_alias_13 as propNames } from './_tsup-dts-rollup';
2
+ export { PopoverOptions_alias_2 as PopoverOptions } from './_tsup-dts-rollup';
3
+ export { propNames_alias_14 as propNames } from './_tsup-dts-rollup';
4
4
  export { PopoverProps } from './_tsup-dts-rollup';
5
5
  export { Popover } from './_tsup-dts-rollup';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Popover,
3
3
  propNames
4
- } from "./chunk-P336E72L.js";
4
+ } from "./chunk-HNKGDXIJ.js";
5
5
  import "./chunk-ZN7DMIEB.js";
6
6
  export {
7
7
  Popover,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/lit",
3
3
  "type": "module",
4
- "version": "0.0.21",
4
+ "version": "0.0.23",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -75,6 +75,11 @@
75
75
  "import": "./dist/prosekit-lit-combo-box-list.js",
76
76
  "default": "./dist/prosekit-lit-combo-box-list.js"
77
77
  },
78
+ "./inline-popover": {
79
+ "types": "./dist/prosekit-lit-inline-popover.d.ts",
80
+ "import": "./dist/prosekit-lit-inline-popover.js",
81
+ "default": "./dist/prosekit-lit-inline-popover.js"
82
+ },
78
83
  "./popover": {
79
84
  "types": "./dist/prosekit-lit-popover.d.ts",
80
85
  "import": "./dist/prosekit-lit-popover.js",
@@ -87,11 +92,11 @@
87
92
  "dependencies": {
88
93
  "@floating-ui/dom": "^1.5.3",
89
94
  "@lit/context": "^1.0.1",
90
- "@prosekit/core": "^0.0.17",
91
- "@prosekit/extensions": "^0.0.19",
95
+ "@prosekit/core": "^0.0.19",
96
+ "@prosekit/extensions": "^0.0.21",
92
97
  "@prosekit/pm": "^0.0.7",
93
98
  "@superhuman/command-score": "^0.5.0",
94
- "lit": "^3.0.1"
99
+ "lit": "^3.0.2"
95
100
  },
96
101
  "devDependencies": {
97
102
  "@prosekit/dev": "*",
@@ -138,6 +143,9 @@
138
143
  "combo-box-list": [
139
144
  "./dist/prosekit-lit-combo-box-list.d.ts"
140
145
  ],
146
+ "inline-popover": [
147
+ "./dist/prosekit-lit-inline-popover.d.ts"
148
+ ],
141
149
  "popover": [
142
150
  "./dist/prosekit-lit-popover.d.ts"
143
151
  ]