@prosekit/web 0.8.0-beta.0 → 0.8.0-beta.1

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.
Files changed (207) hide show
  1. package/dist/prosekit-web-autocomplete.d.ts +112 -90
  2. package/dist/prosekit-web-autocomplete.d.ts.map +1 -1
  3. package/dist/prosekit-web-autocomplete.js +292 -217
  4. package/dist/prosekit-web-autocomplete.js.map +1 -1
  5. package/dist/prosekit-web-block-handle.d.ts +95 -62
  6. package/dist/prosekit-web-block-handle.d.ts.map +1 -1
  7. package/dist/prosekit-web-block-handle.js +219 -114
  8. package/dist/prosekit-web-block-handle.js.map +1 -1
  9. package/dist/prosekit-web-drop-indicator.d.ts +13 -15
  10. package/dist/prosekit-web-drop-indicator.d.ts.map +1 -1
  11. package/dist/prosekit-web-drop-indicator.js +34 -30
  12. package/dist/prosekit-web-drop-indicator.js.map +1 -1
  13. package/dist/prosekit-web-inline-popover.d.ts +88 -54
  14. package/dist/prosekit-web-inline-popover.d.ts.map +1 -1
  15. package/dist/prosekit-web-inline-popover.js +129 -79
  16. package/dist/prosekit-web-inline-popover.js.map +1 -1
  17. package/dist/prosekit-web-menu.d.ts +13 -0
  18. package/dist/prosekit-web-menu.d.ts.map +1 -0
  19. package/dist/prosekit-web-menu.js +53 -0
  20. package/dist/prosekit-web-menu.js.map +1 -0
  21. package/dist/prosekit-web-popover.d.ts +7 -26
  22. package/dist/prosekit-web-popover.d.ts.map +1 -1
  23. package/dist/prosekit-web-popover.js +31 -29
  24. package/dist/prosekit-web-popover.js.map +1 -1
  25. package/dist/prosekit-web-resizable.d.ts +92 -51
  26. package/dist/prosekit-web-resizable.d.ts.map +1 -1
  27. package/dist/prosekit-web-resizable.js +139 -131
  28. package/dist/prosekit-web-resizable.js.map +1 -1
  29. package/dist/prosekit-web-table-handle.d.ts +166 -199
  30. package/dist/prosekit-web-table-handle.d.ts.map +1 -1
  31. package/dist/prosekit-web-table-handle.js +495 -496
  32. package/dist/prosekit-web-table-handle.js.map +1 -1
  33. package/dist/prosekit-web-tooltip.d.ts +7 -26
  34. package/dist/prosekit-web-tooltip.d.ts.map +1 -1
  35. package/dist/prosekit-web-tooltip.js +31 -29
  36. package/dist/prosekit-web-tooltip.js.map +1 -1
  37. package/dist/use-editor-extension.js +2 -2
  38. package/dist/use-editor-extension.js.map +1 -1
  39. package/dist/use-scrolling.js +17 -8
  40. package/dist/use-scrolling.js.map +1 -1
  41. package/package.json +28 -23
  42. package/src/components/autocomplete/autocomplete-empty.ts +45 -0
  43. package/src/components/autocomplete/autocomplete-item.ts +65 -0
  44. package/src/components/autocomplete/autocomplete-popup.ts +95 -0
  45. package/src/components/autocomplete/autocomplete-positioner.ts +98 -0
  46. package/src/components/autocomplete/autocomplete-root.ts +280 -0
  47. package/src/components/autocomplete/context.ts +16 -14
  48. package/src/components/autocomplete/index.ts +65 -0
  49. package/src/components/block-handle/block-handle-add.ts +71 -0
  50. package/src/components/block-handle/block-handle-draggable.ts +158 -0
  51. package/src/components/block-handle/block-handle-popup.ts +43 -0
  52. package/src/components/block-handle/block-handle-positioner.ts +89 -0
  53. package/src/components/block-handle/block-handle-root.ts +116 -0
  54. package/src/components/block-handle/context.ts +9 -18
  55. package/src/components/block-handle/hover-state.ts +16 -0
  56. package/src/components/block-handle/index.ts +59 -0
  57. package/src/components/block-handle/{block-handle-popover/pointer-move.ts → pointer-move.ts} +8 -7
  58. package/src/components/block-handle/{block-handle-draggable/set-drag-preview.ts → set-drag-preview.ts} +4 -4
  59. package/src/components/block-handle/use-hover-extension.ts +65 -0
  60. package/src/components/drop-indicator/drop-indicator.ts +128 -0
  61. package/src/components/drop-indicator/index.ts +18 -0
  62. package/src/components/inline-popover/index.ts +41 -0
  63. package/src/components/inline-popover/inline-popover-popup.ts +52 -0
  64. package/src/components/inline-popover/inline-popover-positioner.ts +98 -0
  65. package/src/components/inline-popover/inline-popover-root.ts +122 -0
  66. package/src/components/inline-popover/store.ts +6 -0
  67. package/src/components/menu/index.ts +92 -0
  68. package/src/components/popover/index.ts +53 -0
  69. package/src/components/resizable/{resizable-handle/calc-resize.ts → calc-resize.ts} +1 -1
  70. package/src/components/resizable/context.ts +3 -6
  71. package/src/components/resizable/index.ts +32 -0
  72. package/src/components/resizable/resizable-handle.ts +134 -0
  73. package/src/components/resizable/resizable-root.ts +184 -0
  74. package/src/components/table-handle/dnd.ts +16 -27
  75. package/src/components/table-handle/index.ts +125 -0
  76. package/src/components/table-handle/{table-handle-drag-preview/render-preview.ts → render-preview.ts} +5 -5
  77. package/src/components/table-handle/shared.ts +61 -0
  78. package/src/components/table-handle/store.ts +117 -0
  79. package/src/components/table-handle/table-handle-column-menu-root.ts +51 -0
  80. package/src/components/table-handle/table-handle-column-menu-trigger.ts +107 -0
  81. package/src/components/table-handle/table-handle-column-popup.ts +44 -0
  82. package/src/components/table-handle/table-handle-column-positioner.ts +67 -0
  83. package/src/components/table-handle/table-handle-drag-preview.ts +169 -0
  84. package/src/components/table-handle/table-handle-drop-indicator.ts +166 -0
  85. package/src/components/table-handle/table-handle-root.ts +103 -0
  86. package/src/components/table-handle/table-handle-row-menu-root.ts +51 -0
  87. package/src/components/table-handle/table-handle-row-menu-trigger.ts +107 -0
  88. package/src/components/table-handle/table-handle-row-popup.ts +42 -0
  89. package/src/components/table-handle/table-handle-row-positioner.ts +67 -0
  90. package/src/components/table-handle/use-drop.ts +74 -0
  91. package/src/components/table-handle/{hooks/use-empty-image.ts → use-empty-image.ts} +2 -3
  92. package/src/components/table-handle/utils.ts +0 -11
  93. package/src/components/tooltip/index.ts +52 -0
  94. package/src/hooks/use-editor-extension.ts +4 -4
  95. package/src/hooks/use-editor-focus-event.ts +4 -4
  96. package/src/hooks/use-editor-typing.ts +12 -16
  97. package/src/hooks/use-editor-update-event.ts +4 -4
  98. package/src/hooks/use-keymap.ts +4 -4
  99. package/src/hooks/use-scrolling.ts +11 -10
  100. package/src/hooks/use-selecting.ts +8 -15
  101. package/src/utils/event.ts +28 -0
  102. package/src/utils/lazy-signal.spec.ts +68 -0
  103. package/src/utils/lazy-signal.ts +17 -0
  104. package/src/utils/prefers-reduced-motion.ts +6 -0
  105. package/src/utils/prevent-default.ts +3 -0
  106. package/src/utils/use-html-element-at.ts +17 -0
  107. package/src/utils/use-no-focus.ts +7 -0
  108. package/dist/get-default-state.js +0 -11
  109. package/dist/get-default-state.js.map +0 -1
  110. package/src/components/autocomplete/autocomplete-empty/element.gen.ts +0 -18
  111. package/src/components/autocomplete/autocomplete-empty/setup.ts +0 -6
  112. package/src/components/autocomplete/autocomplete-empty/types.ts +0 -13
  113. package/src/components/autocomplete/autocomplete-item/element.gen.ts +0 -18
  114. package/src/components/autocomplete/autocomplete-item/setup.ts +0 -30
  115. package/src/components/autocomplete/autocomplete-item/types.ts +0 -25
  116. package/src/components/autocomplete/autocomplete-list/element.gen.ts +0 -18
  117. package/src/components/autocomplete/autocomplete-list/setup.ts +0 -125
  118. package/src/components/autocomplete/autocomplete-list/types.ts +0 -22
  119. package/src/components/autocomplete/autocomplete-popover/element.gen.ts +0 -18
  120. package/src/components/autocomplete/autocomplete-popover/setup.ts +0 -169
  121. package/src/components/autocomplete/autocomplete-popover/types.ts +0 -100
  122. package/src/components/autocomplete/index.gen.ts +0 -17
  123. package/src/components/block-handle/block-handle-add/element.gen.ts +0 -18
  124. package/src/components/block-handle/block-handle-add/setup.ts +0 -33
  125. package/src/components/block-handle/block-handle-add/types.ts +0 -23
  126. package/src/components/block-handle/block-handle-draggable/element.gen.ts +0 -18
  127. package/src/components/block-handle/block-handle-draggable/setup.ts +0 -113
  128. package/src/components/block-handle/block-handle-draggable/types.ts +0 -23
  129. package/src/components/block-handle/block-handle-popover/element.gen.ts +0 -18
  130. package/src/components/block-handle/block-handle-popover/setup.ts +0 -68
  131. package/src/components/block-handle/block-handle-popover/types.ts +0 -81
  132. package/src/components/block-handle/index.gen.ts +0 -13
  133. package/src/components/drop-indicator/drop-indicator/element.gen.ts +0 -18
  134. package/src/components/drop-indicator/drop-indicator/setup.ts +0 -75
  135. package/src/components/drop-indicator/drop-indicator/types.ts +0 -31
  136. package/src/components/drop-indicator/index.gen.ts +0 -5
  137. package/src/components/inline-popover/index.gen.ts +0 -5
  138. package/src/components/inline-popover/inline-popover/element.gen.ts +0 -18
  139. package/src/components/inline-popover/inline-popover/setup.ts +0 -111
  140. package/src/components/inline-popover/inline-popover/types.ts +0 -112
  141. package/src/components/popover/index.gen.ts +0 -13
  142. package/src/components/popover/popover-content/element.gen.ts +0 -18
  143. package/src/components/popover/popover-content/setup.ts +0 -1
  144. package/src/components/popover/popover-content/types.ts +0 -6
  145. package/src/components/popover/popover-root/element.gen.ts +0 -18
  146. package/src/components/popover/popover-root/setup.ts +0 -1
  147. package/src/components/popover/popover-root/types.ts +0 -6
  148. package/src/components/popover/popover-trigger/element.gen.ts +0 -18
  149. package/src/components/popover/popover-trigger/setup.ts +0 -1
  150. package/src/components/popover/popover-trigger/types.ts +0 -6
  151. package/src/components/resizable/index.gen.ts +0 -9
  152. package/src/components/resizable/resizable-handle/element.gen.ts +0 -18
  153. package/src/components/resizable/resizable-handle/setup.ts +0 -106
  154. package/src/components/resizable/resizable-handle/types.ts +0 -29
  155. package/src/components/resizable/resizable-root/element.gen.ts +0 -18
  156. package/src/components/resizable/resizable-root/setup.ts +0 -84
  157. package/src/components/resizable/resizable-root/types.ts +0 -59
  158. package/src/components/table-handle/context.ts +0 -43
  159. package/src/components/table-handle/hooks/use-drop.ts +0 -85
  160. package/src/components/table-handle/index.gen.ts +0 -37
  161. package/src/components/table-handle/table-handle-column-root/element.gen.ts +0 -18
  162. package/src/components/table-handle/table-handle-column-root/setup.ts +0 -60
  163. package/src/components/table-handle/table-handle-column-root/types.ts +0 -73
  164. package/src/components/table-handle/table-handle-column-trigger/element.gen.ts +0 -18
  165. package/src/components/table-handle/table-handle-column-trigger/setup.ts +0 -64
  166. package/src/components/table-handle/table-handle-column-trigger/types.ts +0 -20
  167. package/src/components/table-handle/table-handle-drag-preview/element.gen.ts +0 -18
  168. package/src/components/table-handle/table-handle-drag-preview/setup.ts +0 -57
  169. package/src/components/table-handle/table-handle-drag-preview/types.ts +0 -14
  170. package/src/components/table-handle/table-handle-drag-preview/updater.ts +0 -90
  171. package/src/components/table-handle/table-handle-drop-indicator/element.gen.ts +0 -18
  172. package/src/components/table-handle/table-handle-drop-indicator/setup.ts +0 -52
  173. package/src/components/table-handle/table-handle-drop-indicator/types.ts +0 -15
  174. package/src/components/table-handle/table-handle-drop-indicator/updater.ts +0 -96
  175. package/src/components/table-handle/table-handle-popover-content/element.gen.ts +0 -18
  176. package/src/components/table-handle/table-handle-popover-content/setup.ts +0 -83
  177. package/src/components/table-handle/table-handle-popover-content/types.ts +0 -32
  178. package/src/components/table-handle/table-handle-popover-item/element.gen.ts +0 -18
  179. package/src/components/table-handle/table-handle-popover-item/setup.ts +0 -17
  180. package/src/components/table-handle/table-handle-popover-item/types.ts +0 -16
  181. package/src/components/table-handle/table-handle-root/element.gen.ts +0 -18
  182. package/src/components/table-handle/table-handle-root/setup.ts +0 -86
  183. package/src/components/table-handle/table-handle-root/types.ts +0 -23
  184. package/src/components/table-handle/table-handle-row-root/element.gen.ts +0 -18
  185. package/src/components/table-handle/table-handle-row-root/setup.ts +0 -70
  186. package/src/components/table-handle/table-handle-row-root/types.ts +0 -68
  187. package/src/components/table-handle/table-handle-row-trigger/element.gen.ts +0 -18
  188. package/src/components/table-handle/table-handle-row-trigger/setup.ts +0 -63
  189. package/src/components/table-handle/table-handle-row-trigger/types.ts +0 -23
  190. package/src/components/tooltip/index.gen.ts +0 -13
  191. package/src/components/tooltip/tooltip-content/element.gen.ts +0 -18
  192. package/src/components/tooltip/tooltip-content/setup.ts +0 -1
  193. package/src/components/tooltip/tooltip-content/types.ts +0 -6
  194. package/src/components/tooltip/tooltip-root/element.gen.ts +0 -18
  195. package/src/components/tooltip/tooltip-root/setup.ts +0 -1
  196. package/src/components/tooltip/tooltip-root/types.ts +0 -6
  197. package/src/components/tooltip/tooltip-trigger/element.gen.ts +0 -18
  198. package/src/components/tooltip/tooltip-trigger/setup.ts +0 -1
  199. package/src/components/tooltip/tooltip-trigger/types.ts +0 -6
  200. package/src/hooks/use-first-rendering.ts +0 -15
  201. package/src/utils/get-default-state.spec.ts +0 -42
  202. package/src/utils/get-default-state.ts +0 -18
  203. /package/src/components/autocomplete/{autocomplete-popover/helpers.spec.ts → helpers.spec.ts} +0 -0
  204. /package/src/components/autocomplete/{autocomplete-popover/helpers.ts → helpers.ts} +0 -0
  205. /package/src/components/inline-popover/{inline-popover/virtual-selection-element.ts → virtual-selection-element.ts} +0 -0
  206. /package/src/components/resizable/{resizable-handle/calc-resize.spec.ts → calc-resize.spec.ts} +0 -0
  207. /package/src/components/table-handle/{table-handle-drop-indicator/calc-drag-over.ts → calc-drag-over.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"use-scrolling.js","names":[],"sources":["../src/utils/assign-styles.ts","../src/hooks/use-scrolling.ts"],"sourcesContent":["import type { ConditionalPick } from 'type-fest'\n\n// Only include CSS properties whose value type is `string`\ntype StringStyleDeclaration = Partial<ConditionalPick<CSSStyleDeclaration, string>>\n\n/**\n * A type-safe version of `Object.assign` for `element.style`.\n */\nexport function assignStyles(\n element: HTMLElement | SVGElement | MathMLElement,\n styles: StringStyleDeclaration,\n): void {\n Object.assign(element.style, styles)\n}\n","import { createSignal, useEffect, type ConnectableElement, type ReadonlySignal } from '@aria-ui/core'\nimport { getNearestOverflowAncestor } from '@zag-js/dom-query'\n\nexport function useScrolling(host: ConnectableElement): ReadonlySignal<boolean> {\n const scrolling = createSignal(false)\n\n useEffect(host, () => {\n const scrollableParent = getNearestOverflowAncestor(host)\n\n const handleScroll = () => {\n scrolling.set(true)\n }\n\n const handleMouseMove = () => {\n scrolling.set(false)\n }\n\n scrollableParent.addEventListener('scroll', handleScroll, { passive: true })\n window.addEventListener('mousemove', handleMouseMove, { passive: true })\n window.addEventListener('pointermove', handleMouseMove, { passive: true })\n\n return () => {\n scrollableParent.removeEventListener('scroll', handleScroll)\n window.removeEventListener('mousemove', handleMouseMove)\n window.removeEventListener('pointermove', handleMouseMove)\n }\n })\n\n return scrolling\n}\n"],"mappings":";;;;;;AAQA,SAAgB,aACd,SACA,QACM;AACN,QAAO,OAAO,QAAQ,OAAO,OAAO;;;;ACTtC,SAAgB,aAAa,MAAmD;CAC9E,MAAM,YAAY,aAAa,MAAM;AAErC,WAAU,YAAY;EACpB,MAAM,mBAAmB,2BAA2B,KAAK;EAEzD,MAAM,qBAAqB;AACzB,aAAU,IAAI,KAAK;;EAGrB,MAAM,wBAAwB;AAC5B,aAAU,IAAI,MAAM;;AAGtB,mBAAiB,iBAAiB,UAAU,cAAc,EAAE,SAAS,MAAM,CAAC;AAC5E,SAAO,iBAAiB,aAAa,iBAAiB,EAAE,SAAS,MAAM,CAAC;AACxE,SAAO,iBAAiB,eAAe,iBAAiB,EAAE,SAAS,MAAM,CAAC;AAE1E,eAAa;AACX,oBAAiB,oBAAoB,UAAU,aAAa;AAC5D,UAAO,oBAAoB,aAAa,gBAAgB;AACxD,UAAO,oBAAoB,eAAe,gBAAgB;;GAE5D;AAEF,QAAO"}
1
+ {"version":3,"file":"use-scrolling.js","names":[],"sources":["../src/utils/assign-styles.ts","../src/hooks/use-scrolling.ts"],"sourcesContent":["import type { ConditionalPick } from 'type-fest'\n\n// Only include CSS properties whose value type is `string`\ntype StringStyleDeclaration = Partial<ConditionalPick<CSSStyleDeclaration, string>>\n\n/**\n * A type-safe version of `Object.assign` for `element.style`.\n */\nexport function assignStyles(\n element: HTMLElement | SVGElement | MathMLElement,\n styles: StringStyleDeclaration,\n): void {\n Object.assign(element.style, styles)\n}\n","import { createSignal, useEffect, type HostElement } from '@aria-ui/core'\nimport { getNearestOverflowAncestor } from '@aria-ui/utils'\n\nexport function useScrolling(host: HostElement): () => boolean {\n const scrolling = createSignal(false)\n\n useEffect(host, () => {\n const scrollableParent = getNearestOverflowAncestor(host)\n\n const handleScroll = () => {\n scrolling.set(true)\n }\n\n const handleMouseMove = () => {\n scrolling.set(false)\n }\n\n const abortController = new AbortController()\n const abortSignal = abortController.signal\n\n scrollableParent.addEventListener('scroll', handleScroll, { passive: true, signal: abortSignal })\n window.addEventListener('mousemove', handleMouseMove, { passive: true, signal: abortSignal })\n window.addEventListener('pointermove', handleMouseMove, { passive: true, signal: abortSignal })\n\n return () => {\n abortController.abort()\n }\n })\n\n return scrolling.get\n}\n"],"mappings":";;;;;;AAQA,SAAgB,aACd,SACA,QACM;AACN,QAAO,OAAO,QAAQ,OAAO,OAAO;;;;ACTtC,SAAgB,aAAa,MAAkC;CAC7D,MAAM,YAAY,aAAa,MAAM;AAErC,WAAU,YAAY;EACpB,MAAM,mBAAmB,2BAA2B,KAAK;EAEzD,MAAM,qBAAqB;AACzB,aAAU,IAAI,KAAK;;EAGrB,MAAM,wBAAwB;AAC5B,aAAU,IAAI,MAAM;;EAGtB,MAAM,kBAAkB,IAAI,iBAAiB;EAC7C,MAAM,cAAc,gBAAgB;AAEpC,mBAAiB,iBAAiB,UAAU,cAAc;GAAE,SAAS;GAAM,QAAQ;GAAa,CAAC;AACjG,SAAO,iBAAiB,aAAa,iBAAiB;GAAE,SAAS;GAAM,QAAQ;GAAa,CAAC;AAC7F,SAAO,iBAAiB,eAAe,iBAAiB;GAAE,SAAS;GAAM,QAAQ;GAAa,CAAC;AAE/F,eAAa;AACX,mBAAgB,OAAO;;GAEzB;AAEF,QAAO,UAAU"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/web",
3
3
  "type": "module",
4
- "version": "0.8.0-beta.0",
4
+ "version": "0.8.0-beta.1",
5
5
  "private": false,
6
6
  "description": "A collection of web components for ProseKit",
7
7
  "author": {
@@ -46,6 +46,10 @@
46
46
  "types": "./dist/prosekit-web-inline-popover.d.ts",
47
47
  "default": "./dist/prosekit-web-inline-popover.js"
48
48
  },
49
+ "./menu": {
50
+ "types": "./dist/prosekit-web-menu.d.ts",
51
+ "default": "./dist/prosekit-web-menu.js"
52
+ },
49
53
  "./popover": {
50
54
  "types": "./dist/prosekit-web-popover.d.ts",
51
55
  "default": "./dist/prosekit-web-popover.js"
@@ -68,28 +72,24 @@
68
72
  "src"
69
73
  ],
70
74
  "dependencies": {
71
- "@aria-ui/core": "^0.0.22",
72
- "@aria-ui/listbox": "^0.0.25",
73
- "@aria-ui/menu": "^0.0.21",
74
- "@aria-ui/overlay": "^0.0.25",
75
- "@aria-ui/popover": "^0.0.28",
76
- "@aria-ui/presence": "^0.0.20",
77
- "@aria-ui/tooltip": "^0.0.30",
75
+ "@aria-ui/core": "^0.1.0",
76
+ "@aria-ui/elements": "^0.1.1",
77
+ "@aria-ui/utils": "^0.1.0",
78
78
  "@floating-ui/dom": "^1.7.6",
79
79
  "@ocavue/utils": "^1.6.0",
80
- "@zag-js/dom-query": "^1.37.0",
81
80
  "prosemirror-tables": "^1.8.5",
82
- "@prosekit/extensions": "^0.16.0-beta.0",
83
81
  "@prosekit/core": "^0.12.0-beta.0",
84
- "@prosekit/pm": "^0.1.15"
82
+ "@prosekit/pm": "^0.1.15",
83
+ "@prosekit/extensions": "^0.16.0-beta.0"
85
84
  },
86
85
  "devDependencies": {
87
- "tsdown": "^0.21.4",
86
+ "@aria-ui/cli": "^0.1.0",
87
+ "tsdown": "^0.21.7",
88
88
  "type-fest": "^5.5.0",
89
89
  "typescript": "~5.9.3",
90
- "vitest": "^4.1.1",
91
- "@prosekit/config-tsdown": "0.0.0",
90
+ "vitest": "^4.1.4",
92
91
  "@prosekit/config-ts": "0.0.0",
92
+ "@prosekit/config-tsdown": "0.0.0",
93
93
  "@prosekit/config-vitest": "0.0.0"
94
94
  },
95
95
  "publishConfig": {
@@ -98,19 +98,21 @@
98
98
  "dev": {
99
99
  "entry": {
100
100
  "prosekit-web": "./src/index.ts",
101
- "prosekit-web-autocomplete": "./src/components/autocomplete/index.gen.ts",
102
- "prosekit-web-block-handle": "./src/components/block-handle/index.gen.ts",
103
- "prosekit-web-drop-indicator": "./src/components/drop-indicator/index.gen.ts",
104
- "prosekit-web-inline-popover": "./src/components/inline-popover/index.gen.ts",
105
- "prosekit-web-popover": "./src/components/popover/index.gen.ts",
106
- "prosekit-web-resizable": "./src/components/resizable/index.gen.ts",
107
- "prosekit-web-table-handle": "./src/components/table-handle/index.gen.ts",
108
- "prosekit-web-tooltip": "./src/components/tooltip/index.gen.ts"
101
+ "prosekit-web-autocomplete": "./src/components/autocomplete/index.ts",
102
+ "prosekit-web-block-handle": "./src/components/block-handle/index.ts",
103
+ "prosekit-web-drop-indicator": "./src/components/drop-indicator/index.ts",
104
+ "prosekit-web-inline-popover": "./src/components/inline-popover/index.ts",
105
+ "prosekit-web-menu": "./src/components/menu/index.ts",
106
+ "prosekit-web-popover": "./src/components/popover/index.ts",
107
+ "prosekit-web-resizable": "./src/components/resizable/index.ts",
108
+ "prosekit-web-table-handle": "./src/components/table-handle/index.ts",
109
+ "prosekit-web-tooltip": "./src/components/tooltip/index.ts"
109
110
  }
110
111
  },
111
112
  "scripts": {
112
113
  "build:tsc": "tsc -b tsconfig.json",
113
- "build:tsdown": "tsdown"
114
+ "build:tsdown": "tsdown",
115
+ "build:aria-ui": "node build.mjs"
114
116
  },
115
117
  "types": "./dist/prosekit-web.d.ts",
116
118
  "typesVersions": {
@@ -130,6 +132,9 @@
130
132
  "inline-popover": [
131
133
  "./dist/prosekit-web-inline-popover.d.ts"
132
134
  ],
135
+ "menu": [
136
+ "./dist/prosekit-web-menu.d.ts"
137
+ ],
133
138
  "popover": [
134
139
  "./dist/prosekit-web-popover.d.ts"
135
140
  ],
@@ -0,0 +1,45 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ type HostElement,
6
+ type HostElementConstructor,
7
+ type PropsDeclaration,
8
+ type State,
9
+ } from '@aria-ui/core'
10
+ import { setupListboxEmpty, type ListboxEmptyProps } from '@aria-ui/elements/listbox'
11
+
12
+ /**
13
+ * @internal
14
+ */
15
+ export interface AutocompleteEmptyProps extends ListboxEmptyProps {}
16
+
17
+ /** @internal */
18
+ export const AutocompleteEmptyPropsDeclaration: PropsDeclaration<AutocompleteEmptyProps> = /* @__PURE__ */ defineProps<
19
+ AutocompleteEmptyProps
20
+ >({})
21
+
22
+ /**
23
+ * @internal
24
+ */
25
+ export function setupAutocompleteEmpty(
26
+ host: HostElement,
27
+ props: State<AutocompleteEmptyProps>,
28
+ ): void {
29
+ setupListboxEmpty(host, props)
30
+ }
31
+
32
+ const AutocompleteEmptyElementBase: HostElementConstructor<AutocompleteEmptyProps> = defineCustomElement(
33
+ setupAutocompleteEmpty,
34
+ AutocompleteEmptyPropsDeclaration,
35
+ )
36
+
37
+ /**
38
+ * @public
39
+ */
40
+ export class AutocompleteEmptyElement extends AutocompleteEmptyElementBase {}
41
+
42
+ /** @internal */
43
+ export function registerAutocompleteEmptyElement(): void {
44
+ registerCustomElement('prosekit-autocomplete-empty', AutocompleteEmptyElement)
45
+ }
@@ -0,0 +1,65 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ useEventListener,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type State,
10
+ } from '@aria-ui/core'
11
+ import { SelectEvent, setupListboxItem, type ListboxItemEvents, type ListboxItemProps } from '@aria-ui/elements/listbox'
12
+
13
+ import { preventDefault } from '../../utils/prevent-default.ts'
14
+
15
+ export { SelectEvent }
16
+
17
+ export interface AutocompleteItemProps extends ListboxItemProps {
18
+ /**
19
+ * The value of the item, which will be matched against the query.
20
+ *
21
+ * If not provided, the value is the item's text content.
22
+ *
23
+ * @default ""
24
+ */
25
+ value: string
26
+ }
27
+
28
+ /** @internal */
29
+ export const AutocompleteItemPropsDeclaration: PropsDeclaration<AutocompleteItemProps> = /* @__PURE__ */ defineProps<AutocompleteItemProps>(
30
+ {
31
+ value: { default: '', attribute: 'value', type: 'string' },
32
+ disabled: { default: false, attribute: 'disabled', type: 'boolean' },
33
+ },
34
+ )
35
+
36
+ export interface AutocompleteItemEvents extends ListboxItemEvents {}
37
+
38
+ /**
39
+ * @internal
40
+ */
41
+ export function setupAutocompleteItem(
42
+ host: HostElement,
43
+ props: State<AutocompleteItemProps>,
44
+ ): void {
45
+ setupListboxItem(host, props)
46
+
47
+ // Prevent the editor from losing focus
48
+ useEventListener(host, 'pointerdown', preventDefault)
49
+ useEventListener(host, 'mousedown', preventDefault)
50
+ }
51
+
52
+ const AutocompleteItemElementBase: HostElementConstructor<AutocompleteItemProps> = defineCustomElement(
53
+ setupAutocompleteItem,
54
+ AutocompleteItemPropsDeclaration,
55
+ )
56
+
57
+ /**
58
+ * @public
59
+ */
60
+ export class AutocompleteItemElement extends AutocompleteItemElementBase {}
61
+
62
+ /** @internal */
63
+ export function registerAutocompleteItemElement(): void {
64
+ registerCustomElement('prosekit-autocomplete-item', AutocompleteItemElement)
65
+ }
@@ -0,0 +1,95 @@
1
+ import {
2
+ createSignal,
3
+ defineCustomElement,
4
+ defineProps,
5
+ registerCustomElement,
6
+ type HostElement,
7
+ type HostElementConstructor,
8
+ type PropsDeclaration,
9
+ type Signal,
10
+ type State,
11
+ } from '@aria-ui/core'
12
+ import {
13
+ defaultItemFilter,
14
+ setupListboxRoot,
15
+ type ItemFilter,
16
+ type ListboxRootEvents,
17
+ type ListboxRootProps,
18
+ } from '@aria-ui/elements/listbox'
19
+ import { OverlayPopupPropsDeclaration, setupOverlayPopup, type OverlayPopupProps } from '@aria-ui/elements/overlay'
20
+
21
+ import { createLazySignal } from '../../utils/lazy-signal.ts'
22
+ import { useNoFocus } from '../../utils/use-no-focus.ts'
23
+
24
+ import { autocompleteStoreContext } from './context.ts'
25
+
26
+ /**
27
+ * @public
28
+ */
29
+ export interface AutocompletePopupProps extends OverlayPopupProps {}
30
+
31
+ /**
32
+ * @public
33
+ */
34
+ export interface AutocompletePopupEvents extends ListboxRootEvents {}
35
+
36
+ /** @internal */
37
+ export const AutocompletePopupPropsDeclaration: PropsDeclaration<AutocompletePopupProps> = /* @__PURE__ */ defineProps<
38
+ AutocompletePopupProps
39
+ >(OverlayPopupPropsDeclaration)
40
+
41
+ /** @internal */
42
+ export function setupAutocompletePopup(
43
+ host: HostElement,
44
+ _props: State<AutocompletePopupProps>,
45
+ ): void {
46
+ const getStore = autocompleteStoreContext.consume(host)
47
+ const getOverlayStore = () => getStore()?.overlayStore
48
+
49
+ setupOverlayPopup(host, getOverlayStore)
50
+
51
+ const query = createLazySignal<string>(() => getStore()?.query, ' ')
52
+ const eventTarget = createLazySignal<EventTarget | null>(() => getStore()?.eventTarget, null)
53
+ const filter = createLazySignal<ItemFilter | null>(() => getStore()?.filter, defaultItemFilter)
54
+ const getDisabled = () => (!(getOverlayStore()?.getIsOpen?.()))
55
+ const disabled: Signal<boolean> = { get: getDisabled, set: () => {} }
56
+ const listboxProps = createPopupListboxProps(filter, query, eventTarget, disabled)
57
+
58
+ setupListboxRoot(host, listboxProps)
59
+ useNoFocus(host)
60
+ }
61
+
62
+ function createPopupListboxProps(
63
+ filter: Signal<ItemFilter | null>,
64
+ query: Signal<string>,
65
+ eventTarget: Signal<EventTarget | null>,
66
+ disabled: Signal<boolean>,
67
+ ): State<ListboxRootProps> {
68
+ return {
69
+ value: createSignal(''),
70
+ values: createSignal<string[]>([]),
71
+ multiple: createSignal(false),
72
+ disabled,
73
+ orientation: createSignal<'vertical' | 'horizontal'>('vertical'),
74
+ loop: createSignal(false),
75
+ autoHighlight: createSignal(true),
76
+ query,
77
+ eventTarget,
78
+ filter,
79
+ }
80
+ }
81
+
82
+ const AutocompletePopupElementBase: HostElementConstructor<AutocompletePopupProps> = defineCustomElement(
83
+ setupAutocompletePopup,
84
+ AutocompletePopupPropsDeclaration,
85
+ )
86
+
87
+ /**
88
+ * @public
89
+ */
90
+ export class AutocompletePopupElement extends AutocompletePopupElementBase {}
91
+
92
+ /** @internal */
93
+ export function registerAutocompletePopupElement(): void {
94
+ registerCustomElement('prosekit-autocomplete-popup', AutocompletePopupElement)
95
+ }
@@ -0,0 +1,98 @@
1
+ import {
2
+ defineCustomElement,
3
+ defineProps,
4
+ registerCustomElement,
5
+ type HostElement,
6
+ type HostElementConstructor,
7
+ type PropsDeclaration,
8
+ type State,
9
+ } from '@aria-ui/core'
10
+ import { OverlayPositionerPropsDeclaration, setupOverlayPositioner, type OverlayPositionerProps } from '@aria-ui/elements/overlay'
11
+
12
+ import { autocompleteStoreContext } from './context.ts'
13
+
14
+ const body = typeof document !== 'undefined' && document.querySelector('body')
15
+ const defaultBoundary = body || 'clippingAncestors'
16
+
17
+ /**
18
+ * @public
19
+ */
20
+ export interface AutocompletePositionerProps extends OverlayPositionerProps {
21
+ /**
22
+ * The placement of the popover, relative to the text cursor.
23
+ *
24
+ * @default "bottom-start"
25
+ */
26
+ placement: OverlayPositionerProps['placement']
27
+
28
+ /**
29
+ * The distance between the popover and the hovered block.
30
+ *
31
+ * @default 4
32
+ */
33
+ offset: OverlayPositionerProps['offset']
34
+
35
+ /**
36
+ * @default true
37
+ */
38
+ inline: OverlayPositionerProps['inline']
39
+
40
+ /**
41
+ * @default true
42
+ */
43
+ hoist: OverlayPositionerProps['hoist']
44
+
45
+ /**
46
+ * @default true
47
+ */
48
+ fitViewport: OverlayPositionerProps['fitViewport']
49
+
50
+ /**
51
+ * @default "The body element"
52
+ */
53
+ boundary: OverlayPositionerProps['boundary']
54
+
55
+ /**
56
+ * @default 8
57
+ */
58
+ overflowPadding: OverlayPositionerProps['overflowPadding']
59
+ }
60
+
61
+ /** @internal */
62
+ export const AutocompletePositionerPropsDeclaration: PropsDeclaration<AutocompletePositionerProps> = /* @__PURE__ */ defineProps<
63
+ AutocompletePositionerProps
64
+ >({
65
+ ...OverlayPositionerPropsDeclaration,
66
+ placement: { default: 'bottom-start', attribute: 'placement', type: 'string' },
67
+ offset: { default: 4, attribute: false, type: 'json' },
68
+ inline: { default: true, attribute: 'inline', type: 'boolean' },
69
+ hoist: { default: true, attribute: 'hoist', type: 'boolean' },
70
+ fitViewport: { default: true, attribute: 'fit-viewport', type: 'boolean' },
71
+ boundary: { default: defaultBoundary, attribute: false, type: 'json' },
72
+ overflowPadding: { default: 8, attribute: 'overflow-padding', type: 'number' },
73
+ })
74
+
75
+ /** @internal */
76
+ export function setupAutocompletePositioner(
77
+ host: HostElement,
78
+ props: State<AutocompletePositionerProps>,
79
+ ): void {
80
+ const getStore = autocompleteStoreContext.consume(host)
81
+ const getOverlayStore = () => getStore()?.overlayStore
82
+ setupOverlayPositioner(host, props as unknown as State<OverlayPositionerProps>, getOverlayStore)
83
+ }
84
+
85
+ const AutocompletePositionerElementBase: HostElementConstructor<AutocompletePositionerProps> = defineCustomElement(
86
+ setupAutocompletePositioner,
87
+ AutocompletePositionerPropsDeclaration,
88
+ )
89
+
90
+ /**
91
+ * @public
92
+ */
93
+ export class AutocompletePositionerElement extends AutocompletePositionerElementBase {}
94
+
95
+ /** @internal */
96
+ export function registerAutocompletePositionerElement(): void {
97
+ registerCustomElement('prosekit-autocomplete-positioner', AutocompletePositionerElement)
98
+ }
@@ -0,0 +1,280 @@
1
+ import {
2
+ createSignal,
3
+ defineCustomElement,
4
+ defineProps,
5
+ registerCustomElement,
6
+ useEffect,
7
+ useEventListener,
8
+ type HostElement,
9
+ type HostElementConstructor,
10
+ type PropsDeclaration,
11
+ type Signal,
12
+ type State,
13
+ } from '@aria-ui/core'
14
+ import { defaultItemFilter, type ItemFilter, type ListboxRootEvents } from '@aria-ui/elements/listbox'
15
+ import { createOverlayStore, OpenChangeEvent, type OverlayStore } from '@aria-ui/elements/overlay'
16
+ import { defineDOMEventHandler, defineKeymap, withPriority, type Editor, type Extension, type Priority } from '@prosekit/core'
17
+ import { AutocompleteRule, defineAutocomplete, type MatchHandler } from '@prosekit/extensions/autocomplete'
18
+
19
+ import { useEditorExtension } from '../../hooks/use-editor-extension.ts'
20
+ import { KeyboardEventTarget } from '../../utils/event.ts'
21
+ import { getSafeEditorView } from '../../utils/get-safe-editor-view.ts'
22
+
23
+ import { autocompleteStoreContext, type AutocompleteStore } from './context.ts'
24
+ import { defaultQueryBuilder } from './helpers.ts'
25
+
26
+ export { OpenChangeEvent }
27
+
28
+ export interface AutocompleteRootProps {
29
+ /**
30
+ * The ProseKit editor instance.
31
+ *
32
+ * @default null
33
+ * @hidden
34
+ */
35
+ editor: Editor | null
36
+
37
+ /**
38
+ * The regular expression to match the query text to autocomplete.
39
+ *
40
+ * @default null
41
+ */
42
+ regex: RegExp | null
43
+
44
+ /**
45
+ * The filter function to determine if an item should be shown in the
46
+ * listbox.
47
+ *
48
+ * @default defaultItemFilter
49
+ */
50
+ filter: ItemFilter | null
51
+ }
52
+
53
+ /** @internal */
54
+ export const AutocompleteRootPropsDeclaration: PropsDeclaration<AutocompleteRootProps> = /* @__PURE__ */ defineProps<
55
+ AutocompleteRootProps
56
+ >({
57
+ editor: { default: null, attribute: false, type: 'json' },
58
+ regex: { default: null, attribute: false, type: 'json' },
59
+ filter: { default: defaultItemFilter, attribute: false, type: 'json' },
60
+ })
61
+
62
+ /**
63
+ * @public
64
+ */
65
+ export class QueryChangeEvent extends Event {
66
+ /**
67
+ * The current query string.
68
+ */
69
+ readonly detail: string
70
+
71
+ constructor(query: string) {
72
+ super('queryChange', { bubbles: true })
73
+ this.detail = query
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @public
79
+ */
80
+ export interface AutocompleteRootEvents extends ListboxRootEvents {
81
+ /**
82
+ * Fired when the open state changes.
83
+ */
84
+ openChange: OpenChangeEvent
85
+
86
+ /**
87
+ * Fired when the query changes.
88
+ */
89
+ queryChange: QueryChangeEvent
90
+ }
91
+
92
+ interface RuleHandlers {
93
+ submit?: VoidFunction
94
+ dismiss?: VoidFunction
95
+ }
96
+
97
+ interface AutocompleteRuleDeps {
98
+ reference: Signal<Element | undefined>
99
+ handlers: RuleHandlers
100
+ setQuery: (next: string) => void
101
+ requestOpenChange: (open: boolean) => void
102
+ }
103
+
104
+ /**
105
+ * @internal
106
+ */
107
+ export function setupAutocompleteRoot(
108
+ host: HostElement,
109
+ props: State<AutocompleteRootProps>,
110
+ ): void {
111
+ const getEditor = props.editor.get
112
+
113
+ const reference = createSignal<Element | undefined>(undefined)
114
+ const open = createSignal(false)
115
+ const query = createSignal('')
116
+ const keyboardTarget = new KeyboardEventTarget()
117
+ const eventTarget = createSignal<EventTarget | null>(keyboardTarget)
118
+ const handlers: RuleHandlers = {}
119
+
120
+ // Create overlay store for positioning. The open state is managed by the
121
+ // overlay store via requestOpenChange(), which dispatches OpenChangeEvent and
122
+ // updates the open signal.
123
+ const overlayStore: OverlayStore = createOverlayStore(
124
+ open.get,
125
+ open.set,
126
+ () => false,
127
+ () => false,
128
+ (event) => host.dispatchEvent(event),
129
+ )
130
+
131
+ useEffect(host, () => {
132
+ overlayStore.setAnchorElement(reference.get())
133
+ })
134
+
135
+ const autocompleteStore: AutocompleteStore = {
136
+ overlayStore,
137
+ query,
138
+ eventTarget,
139
+ filter: props.filter,
140
+ }
141
+
142
+ autocompleteStoreContext.provide(host, autocompleteStore)
143
+
144
+ useEventListener(host, 'valueChange', () => {
145
+ handlers.submit?.()
146
+ })
147
+
148
+ useKeyboardBridge(host, getEditor, open.get, keyboardTarget)
149
+
150
+ useEscapeKeydown(host, getEditor, () => {
151
+ if (!open.get() || !handlers.dismiss) return false
152
+ handlers.dismiss()
153
+ return true
154
+ })
155
+
156
+ const setQuery = (next: string): void => {
157
+ if (query.get() === next) return
158
+ query.set(next)
159
+ host.dispatchEvent(new QueryChangeEvent(next))
160
+ }
161
+
162
+ useAutocompleteExtension(host, getEditor, props.regex.get, {
163
+ reference,
164
+ handlers,
165
+ setQuery,
166
+ requestOpenChange: (open) => overlayStore.requestOpenChange(open),
167
+ })
168
+ }
169
+
170
+ const EVENT_KEYS = [
171
+ 'ArrowDown',
172
+ 'ArrowRight',
173
+ 'ArrowUp',
174
+ 'ArrowLeft',
175
+ 'Home',
176
+ 'End',
177
+ 'Enter',
178
+ ] as const
179
+
180
+ function useKeyboardBridge(
181
+ host: HostElement,
182
+ getEditor: () => Editor | null,
183
+ getOpen: () => boolean,
184
+ target: EventTarget,
185
+ ): void {
186
+ const extension: Extension = defineDOMEventHandler('keydown', (view, event): boolean => {
187
+ if (
188
+ view.composing
189
+ || event.defaultPrevented
190
+ || !getOpen()
191
+ || !EVENT_KEYS.includes(event.key as (typeof EVENT_KEYS)[number])
192
+ ) {
193
+ return false
194
+ }
195
+ target.dispatchEvent(event)
196
+ return event.defaultPrevented
197
+ })
198
+ useEditorExtension(host, getEditor, withPriority(extension, 4 satisfies typeof Priority.highest))
199
+ }
200
+
201
+ function useAutocompleteExtension(
202
+ host: HostElement,
203
+ getEditor: () => Editor | null,
204
+ getRegex: () => RegExp | null,
205
+ deps: AutocompleteRuleDeps,
206
+ ) {
207
+ useEffect(host, () => {
208
+ const editor = getEditor()
209
+ const regex = getRegex()
210
+
211
+ if (!editor || !regex) {
212
+ return
213
+ }
214
+
215
+ const rule = createAutocompleteRule(editor, regex, deps)
216
+ const extension = defineAutocomplete(rule)
217
+ return editor.use(extension)
218
+ })
219
+ }
220
+
221
+ function createAutocompleteRule(
222
+ editor: Editor,
223
+ regex: RegExp,
224
+ deps: AutocompleteRuleDeps,
225
+ ) {
226
+ const { reference, handlers, setQuery, requestOpenChange } = deps
227
+
228
+ const handleEnter: MatchHandler = (options) => {
229
+ const view = getSafeEditorView(editor)
230
+ const span = view?.dom.querySelector('.prosekit-autocomplete-match')
231
+
232
+ if (span) {
233
+ reference.set(span)
234
+ }
235
+
236
+ handlers.submit = options.deleteMatch
237
+ handlers.dismiss = options.ignoreMatch
238
+ setQuery(defaultQueryBuilder(options.match))
239
+ requestOpenChange(true)
240
+ }
241
+
242
+ const handleLeave = () => {
243
+ reference.set(undefined)
244
+ setQuery('')
245
+ handlers.submit = undefined
246
+ handlers.dismiss = undefined
247
+ requestOpenChange(false)
248
+ }
249
+
250
+ return new AutocompleteRule({
251
+ regex,
252
+ onEnter: handleEnter,
253
+ onLeave: handleLeave,
254
+ })
255
+ }
256
+
257
+ function useEscapeKeydown(
258
+ host: HostElement,
259
+ getEditor: () => Editor | null,
260
+ handler: () => boolean,
261
+ ): void {
262
+ const keymap = { Escape: handler }
263
+ const extension = withPriority(defineKeymap(keymap), 4 satisfies typeof Priority.highest)
264
+ useEditorExtension(host, getEditor, extension)
265
+ }
266
+
267
+ const AutocompleteRootElementBase: HostElementConstructor<AutocompleteRootProps> = defineCustomElement(
268
+ setupAutocompleteRoot,
269
+ AutocompleteRootPropsDeclaration,
270
+ )
271
+
272
+ /**
273
+ * @public
274
+ */
275
+ export class AutocompleteRootElement extends AutocompleteRootElementBase {}
276
+
277
+ /** @internal */
278
+ export function registerAutocompleteRootElement(): void {
279
+ registerCustomElement('prosekit-autocomplete-root', AutocompleteRootElement)
280
+ }