@prosekit/web 0.8.0-beta.2 → 0.8.0-beta.3

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.
@@ -116,6 +116,9 @@ declare const InlinePopoverRootPropsDeclaration: PropsDeclaration<InlinePopoverR
116
116
  * @public
117
117
  */
118
118
  interface InlinePopoverRootEvents {
119
+ /**
120
+ * Emitted when the open state of the popover changes.
121
+ */
119
122
  openChange: OpenChangeEvent$1;
120
123
  }
121
124
  /** @internal */
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-web-inline-popover.d.ts","names":[],"sources":["../src/components/inline-popover/inline-popover-popup.ts","../src/components/inline-popover/inline-popover-positioner.ts","../src/components/inline-popover/inline-popover-root.ts"],"mappings":";;;;;;;;UAkBiB,uBAAA,SAAgC,iBAAA;;cAGpC,kCAAA,EAAoC,gBAAA,CAAiB,uBAAA;;iBAGlD,uBAAA,CACd,IAAA,EAAM,WAAA,EACN,MAAA,EAAQ,KAAA,CAAM,uBAAA;AAAA,cAYV,6BAAA,EAA+B,sBAAA,CAAuB,uBAAA;;;;cAQ/C,yBAAA,SAAkC,6BAAA;;iBAG/B,iCAAA,CAAA;;;;;;UCjCC,4BAAA,SACf,IAAA,CACE,sBAAA;EDAqC;;;;AAGzC;ECYE,SAAA,EAAW,sBAAA;;;;ADTb;;ECgBE,MAAA,EAAQ,sBAAA;EDfF;;;;;;ECuBN,IAAA,EAAM,sBAAA;EDtBE;;;;;AAUT;ECoBC,KAAA;;;;ADVF;;;ECkBE,OAAA,EAAS,sBAAA;EDlBiE;AAG5E;;;;;ECuBE,MAAA,EAAQ,sBAAA;;;AAxDV;;;EA+DE,eAAA,EAAiB,sBAAA;AAAA;;cAIN,uCAAA,EAAyC,gBAAA,CAAiB,4BAAA;;iBAcvD,4BAAA,CACd,IAAA,EAAM,WAAA,EACN,KAAA,EAAO,KAAA,CAAM,4BAAA;AAAA,cAKT,kCAAA,EAAoC,sBAAA,CAAuB,4BAAA;;;;cAQpD,8BAAA,SAAuC,kCAAA;;iBAGpC,sCAAA,CAAA;;;;ADjGhB;;UEMiB,sBAAA,SAA+B,gBAAA;EFNC;;AAGjD;;;;EEUE,MAAA,EAAQ,MAAA;EFPM;;;;;;EEed,WAAA;EFba;;;;;;EEqBb,eAAA;AAAA;AFXD;AAAA,cEeY,iCAAA,EAAmC,gBAAA,CAAiB,sBAAA;;;;UAYhD,uBAAA;EACf,UAAA,EAAY,iBAAA;AAAA;;iBAIE,sBAAA,CACd,IAAA,EAAM,WAAA,EACN,KAAA,EAAO,KAAA,CAAM,sBAAA;AAAA,cAsCT,4BAAA,EAA8B,sBAAA,CAAuB,sBAAA;;;;cAQ9C,wBAAA,SAAiC,4BAAA;;iBAG9B,gCAAA,CAAA"}
1
+ {"version":3,"file":"prosekit-web-inline-popover.d.ts","names":[],"sources":["../src/components/inline-popover/inline-popover-popup.ts","../src/components/inline-popover/inline-popover-positioner.ts","../src/components/inline-popover/inline-popover-root.ts"],"mappings":";;;;;;;;UAkBiB,uBAAA,SAAgC,iBAAA;;cAGpC,kCAAA,EAAoC,gBAAA,CAAiB,uBAAA;;iBAGlD,uBAAA,CACd,IAAA,EAAM,WAAA,EACN,MAAA,EAAQ,KAAA,CAAM,uBAAA;AAAA,cAYV,6BAAA,EAA+B,sBAAA,CAAuB,uBAAA;;;;cAQ/C,yBAAA,SAAkC,6BAAA;;iBAG/B,iCAAA,CAAA;;;;;;UCjCC,4BAAA,SACf,IAAA,CACE,sBAAA;EDAqC;;;;AAGzC;ECYE,SAAA,EAAW,sBAAA;;;;ADTb;;ECgBE,MAAA,EAAQ,sBAAA;EDfF;;;;;;ECuBN,IAAA,EAAM,sBAAA;EDtBE;;;;;AAUT;ECoBC,KAAA;;;;ADVF;;;ECkBE,OAAA,EAAS,sBAAA;EDlBiE;AAG5E;;;;;ECuBE,MAAA,EAAQ,sBAAA;;;AAxDV;;;EA+DE,eAAA,EAAiB,sBAAA;AAAA;;cAIN,uCAAA,EAAyC,gBAAA,CAAiB,4BAAA;;iBAcvD,4BAAA,CACd,IAAA,EAAM,WAAA,EACN,KAAA,EAAO,KAAA,CAAM,4BAAA;AAAA,cAKT,kCAAA,EAAoC,sBAAA,CAAuB,4BAAA;;;;cAQpD,8BAAA,SAAuC,kCAAA;;iBAGpC,sCAAA,CAAA;;;;ADjGhB;;UEMiB,sBAAA,SAA+B,gBAAA;EFNC;;AAGjD;;;;EEUE,MAAA,EAAQ,MAAA;EFPM;;;;;;EEed,WAAA;EFba;;;;;;EEqBb,eAAA;AAAA;AFXD;AAAA,cEeY,iCAAA,EAAmC,gBAAA,CAAiB,sBAAA;;;;UAYhD,uBAAA;EFjBsB;;;EEqBrC,UAAA,EAAY,iBAAA;AAAA;;iBAIE,sBAAA,CACd,IAAA,EAAM,WAAA,EACN,KAAA,EAAO,KAAA,CAAM,sBAAA;AAAA,cAsCT,4BAAA,EAA8B,sBAAA,CAAuB,sBAAA;;;;cAQ9C,wBAAA,SAAiC,4BAAA;;iBAG9B,gCAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-web-inline-popover.js","names":[],"sources":["../src/components/inline-popover/store.ts","../src/components/inline-popover/inline-popover-popup.ts","../src/components/inline-popover/inline-popover-positioner.ts","../src/hooks/use-editor-focus-event.ts","../src/hooks/use-editor-update-event.ts","../src/hooks/use-keymap.ts","../src/components/inline-popover/virtual-selection-element.ts","../src/components/inline-popover/inline-popover-root.ts"],"sourcesContent":["import { createContext, type Context } from '@aria-ui/core'\nimport type { OverlayStore } from '@aria-ui/elements/overlay'\n\nexport const InlinePopoverStoreContext: Context<OverlayStore> = createContext<OverlayStore>(\n 'prosekit-inline-popover-store',\n)\n","import {\n computed,\n defineCustomElement,\n onMount,\n registerCustomElement,\n type HostElement,\n type HostElementConstructor,\n type PropsDeclaration,\n type State,\n} from '@aria-ui/core'\nimport { OverlayPopupPropsDeclaration, setupOverlayPopup, type OverlayPopupProps } from '@aria-ui/elements/overlay'\nimport { usePresence } from '@aria-ui/utils'\n\nimport { InlinePopoverStoreContext } from './store.ts'\n\n/**\n * @public\n */\nexport interface InlinePopoverPopupProps extends OverlayPopupProps {}\n\n/** @internal */\nexport const InlinePopoverPopupPropsDeclaration: PropsDeclaration<InlinePopoverPopupProps> = OverlayPopupPropsDeclaration\n\n/** @internal */\nexport function setupInlinePopoverPopup(\n host: HostElement,\n _props: State<InlinePopoverPopupProps>,\n): void {\n const getStore = InlinePopoverStoreContext.consume(host)\n setupOverlayPopup(host, getStore)\n const getOpen = computed(() => getStore()?.getIsOpen() ?? false)\n usePresence(host, getOpen)\n\n onMount(host, () => {\n host.role = 'dialog'\n })\n}\n\nconst InlinePopoverPopupElementBase: HostElementConstructor<InlinePopoverPopupProps> = defineCustomElement(\n setupInlinePopoverPopup,\n InlinePopoverPopupPropsDeclaration,\n)\n\n/**\n * @public\n */\nexport class InlinePopoverPopupElement extends InlinePopoverPopupElementBase {}\n\n/** @internal */\nexport function registerInlinePopoverPopupElement(): void {\n registerCustomElement('prosekit-inline-popover-popup', InlinePopoverPopupElement)\n}\n","import {\n defineCustomElement,\n defineProps,\n registerCustomElement,\n type HostElement,\n type HostElementConstructor,\n type PropsDeclaration,\n type State,\n} from '@aria-ui/core'\nimport { OverlayPositionerPropsDeclaration, setupOverlayPositioner, type OverlayPositionerProps } from '@aria-ui/elements/overlay'\n\nimport { InlinePopoverStoreContext } from './store.ts'\n\n/**\n * @public\n */\nexport interface InlinePopoverPositionerProps extends\n Omit<\n OverlayPositionerProps,\n | 'placement'\n | 'offset'\n | 'hide'\n | 'hoist'\n | 'overlap'\n | 'inline'\n | 'overflowPadding'\n >\n{\n /**\n * The initial placement of the floating element\n *\n * @default \"top\"\n */\n placement: OverlayPositionerProps['placement']\n\n /**\n * The distance between the reference and floating element.\n *\n * @default 12\n */\n offset: OverlayPositionerProps['offset']\n\n /**\n * Whether to hide the floating element when the reference element or the\n * floating element is fully clipped.\n *\n * @default true\n */\n hide: OverlayPositionerProps['hide']\n\n /**\n * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)\n * to place the floating element on top of other page content.\n *\n * @default false\n */\n hoist: boolean\n\n /**\n * Whether the floating element can overlap the reference element to keep it\n * in view.\n *\n * @default true\n */\n overlap: OverlayPositionerProps['overlap']\n\n /**\n * Whether to improve positioning for inline reference elements that span over\n * multiple lines.\n *\n * @default true\n */\n inline: OverlayPositionerProps['inline']\n\n /**\n * Describes the virtual padding around the boundary to check for overflow.\n *\n * @default 8\n */\n overflowPadding: OverlayPositionerProps['overflowPadding']\n}\n\n/** @internal */\nexport const InlinePopoverPositionerPropsDeclaration: PropsDeclaration<InlinePopoverPositionerProps> = /* @__PURE__ */ defineProps<\n InlinePopoverPositionerProps\n>({\n ...OverlayPositionerPropsDeclaration,\n placement: { default: 'top', attribute: 'placement', type: 'string' },\n offset: { default: 12, attribute: false, type: 'json' },\n hide: { default: true, attribute: 'hide', type: 'boolean' },\n hoist: { default: false, attribute: 'hoist', type: 'boolean' },\n overlap: { default: true, attribute: 'overlap', type: 'boolean' },\n inline: { default: true, attribute: 'inline', type: 'boolean' },\n overflowPadding: { default: 8, attribute: 'overflow-padding', type: 'number' },\n})\n\n/** @internal */\nexport function setupInlinePopoverPositioner(\n host: HostElement,\n props: State<InlinePopoverPositionerProps>,\n): void {\n setupOverlayPositioner(host, props, InlinePopoverStoreContext.consume(host))\n}\n\nconst InlinePopoverPositionerElementBase: HostElementConstructor<InlinePopoverPositionerProps> = defineCustomElement(\n setupInlinePopoverPositioner,\n InlinePopoverPositionerPropsDeclaration,\n)\n\n/**\n * @public\n */\nexport class InlinePopoverPositionerElement extends InlinePopoverPositionerElementBase {}\n\n/** @internal */\nexport function registerInlinePopoverPositionerElement(): void {\n registerCustomElement('prosekit-inline-popover-positioner', InlinePopoverPositionerElement)\n}\n","import type { HostElement } from '@aria-ui/core'\nimport { defineFocusChangeHandler, type Editor, type FocusChangeHandler } from '@prosekit/core'\n\nimport { useEditorExtension } from './use-editor-extension.ts'\n\n/**\n * @internal\n */\nexport function useEditorFocusChangeEvent(\n host: HostElement,\n getEditor: () => Editor | null,\n handler: FocusChangeHandler,\n): void {\n const extension = defineFocusChangeHandler(handler)\n useEditorExtension(host, getEditor, extension)\n}\n","import type { HostElement } from '@aria-ui/core'\nimport { defineUpdateHandler, type Editor, type UpdateHandler } from '@prosekit/core'\n\nimport { useEditorExtension } from './use-editor-extension.ts'\n\n/**\n * @internal\n */\nexport function useEditorUpdateEvent(\n host: HostElement,\n getEditor: () => Editor | null,\n handler: UpdateHandler,\n): void {\n const extension = defineUpdateHandler(handler)\n useEditorExtension(host, getEditor, extension)\n}\n","import type { HostElement } from '@aria-ui/core'\nimport { defineKeymap, type Editor, type Keymap } from '@prosekit/core'\n\nimport { useEditorExtension } from './use-editor-extension.ts'\n\nexport function useKeymap(\n host: HostElement,\n getEditor: () => Editor | null,\n keymap: Keymap,\n): void {\n const extension = defineKeymap(keymap)\n useEditorExtension(host, getEditor, extension)\n}\n","import type { ReferenceElement } from '@floating-ui/dom'\nimport { containsInlineNode, isInCodeBlock, isTextSelection } from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nexport function getVirtualSelectionElement(\n view: EditorView,\n): ReferenceElement | undefined {\n if (typeof window === 'undefined' || view.isDestroyed) {\n return\n }\n\n const selection = view.state.selection\n\n if (\n !selection.empty\n && !isInCodeBlock(selection)\n && isTextSelection(selection)\n && containsInlineNode(view.state.doc, selection.from, selection.to)\n ) {\n return getDomDecoration(view) || getInlineDecoration(view)\n }\n}\n\nfunction getDomDecoration(view: EditorView): ReferenceElement | undefined {\n const range = getDomRange(view)\n if (range) {\n // To get it work properly in Safari, we cannot return the range directly.\n // We have to return a contextElement.\n return {\n contextElement: view.dom,\n getBoundingClientRect: () => range.getBoundingClientRect(),\n getClientRects: () => range.getClientRects(),\n }\n }\n}\n\nfunction getDomRange(view: EditorView): Range | undefined {\n const win = view.dom.ownerDocument.defaultView\n const selection = win?.getSelection()\n if (!selection || selection.isCollapsed) {\n return\n }\n\n const range = typeof selection.rangeCount === 'number'\n && selection.rangeCount > 0\n && selection.getRangeAt(0)\n\n if (!range) {\n return\n }\n\n return range\n}\n\nfunction getInlineDecoration(view: EditorView): ReferenceElement | undefined {\n const match = view.dom.querySelectorAll('.prosekit-virtual-selection')\n\n if (match.length === 0) {\n return\n }\n if (match.length === 1) {\n return match[0]\n }\n\n const items = Array.from(match)\n return {\n contextElement: items[0],\n getBoundingClientRect: () => items[0].getBoundingClientRect(),\n getClientRects: () => items.map((item) => item.getBoundingClientRect()),\n }\n}\n","import {\n defineCustomElement,\n defineProps,\n registerCustomElement,\n type HostElement,\n type HostElementConstructor,\n type PropsDeclaration,\n type State,\n} from '@aria-ui/core'\nimport type { OpenChangeEvent } from '@aria-ui/elements/overlay'\nimport { OverlayRootPropsDeclaration, useOverlayStore, type OverlayRootProps } from '@aria-ui/elements/overlay'\nimport type { Editor } from '@prosekit/core'\nimport type { Selection } from '@prosekit/pm/state'\n\nimport { useEditorFocusChangeEvent } from '../../hooks/use-editor-focus-event.ts'\nimport { useEditorUpdateEvent } from '../../hooks/use-editor-update-event.ts'\nimport { useKeymap } from '../../hooks/use-keymap.ts'\n\nimport { InlinePopoverStoreContext } from './store.ts'\nimport { getVirtualSelectionElement } from './virtual-selection-element.ts'\n\n/**\n * @public\n */\nexport interface InlinePopoverRootProps extends OverlayRootProps {\n /**\n * The ProseKit editor instance.\n *\n * @default null\n * @hidden\n */\n editor: Editor | null\n\n /**\n * Whether the popover is open by default when some inline content is\n * selected.\n *\n * @default true\n */\n defaultOpen: boolean\n\n /**\n * Whether the inline popover should be dismissed when the editor receives an\n * Escape key press.\n *\n * @default true\n */\n dismissOnEscape: boolean\n}\n\n/** @internal */\nexport const InlinePopoverRootPropsDeclaration: PropsDeclaration<InlinePopoverRootProps> = /* @__PURE__ */ defineProps<\n InlinePopoverRootProps\n>({\n ...OverlayRootPropsDeclaration,\n editor: { default: null, attribute: false, type: 'json' },\n defaultOpen: { default: true, attribute: 'default-open', type: 'boolean' },\n dismissOnEscape: { default: true, attribute: 'dismiss-on-escape', type: 'boolean' },\n})\n\n/**\n * @public\n */\nexport interface InlinePopoverRootEvents {\n openChange: OpenChangeEvent\n}\n\n/** @internal */\nexport function setupInlinePopoverRoot(\n host: HostElement,\n props: State<InlinePopoverRootProps>,\n): void {\n const store = useOverlayStore(host, props)\n InlinePopoverStoreContext.provide(host, store)\n\n let editorFocused = false\n useEditorFocusChangeEvent(host, props.editor.get, (focus) => {\n editorFocused = focus\n })\n\n let prevSelection: Selection | undefined\n useEditorUpdateEvent(host, props.editor.get, (view) => {\n const isPopoverFocused = !editorFocused && host.contains(host.ownerDocument.activeElement)\n if (isPopoverFocused) return\n\n const { selection } = view.state\n if (prevSelection?.eq(selection)) return\n prevSelection = selection\n\n const reference = getVirtualSelectionElement(view)\n store.setAnchorElement(reference)\n\n if (reference && props.defaultOpen.get()) {\n store.requestOpenChange(true)\n } else if (!reference) {\n store.requestOpenChange(false)\n }\n })\n\n useKeymap(host, props.editor.get, {\n Escape: () => {\n if (!props.dismissOnEscape.get() || !store.getIsOpen()) return false\n store.requestOpenChange(false)\n return true\n },\n })\n}\n\nconst InlinePopoverRootElementBase: HostElementConstructor<InlinePopoverRootProps> = defineCustomElement(\n setupInlinePopoverRoot,\n InlinePopoverRootPropsDeclaration,\n)\n\n/**\n * @public\n */\nexport class InlinePopoverRootElement extends InlinePopoverRootElementBase {}\n\n/** @internal */\nexport function registerInlinePopoverRootElement(): void {\n registerCustomElement('prosekit-inline-popover-root', InlinePopoverRootElement)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"prosekit-web-inline-popover.js","names":[],"sources":["../src/components/inline-popover/store.ts","../src/components/inline-popover/inline-popover-popup.ts","../src/components/inline-popover/inline-popover-positioner.ts","../src/hooks/use-editor-focus-event.ts","../src/hooks/use-editor-update-event.ts","../src/hooks/use-keymap.ts","../src/components/inline-popover/virtual-selection-element.ts","../src/components/inline-popover/inline-popover-root.ts"],"sourcesContent":["import { createContext, type Context } from '@aria-ui/core'\nimport type { OverlayStore } from '@aria-ui/elements/overlay'\n\nexport const InlinePopoverStoreContext: Context<OverlayStore> = createContext<OverlayStore>(\n 'prosekit-inline-popover-store',\n)\n","import {\n computed,\n defineCustomElement,\n onMount,\n registerCustomElement,\n type HostElement,\n type HostElementConstructor,\n type PropsDeclaration,\n type State,\n} from '@aria-ui/core'\nimport { OverlayPopupPropsDeclaration, setupOverlayPopup, type OverlayPopupProps } from '@aria-ui/elements/overlay'\nimport { usePresence } from '@aria-ui/utils'\n\nimport { InlinePopoverStoreContext } from './store.ts'\n\n/**\n * @public\n */\nexport interface InlinePopoverPopupProps extends OverlayPopupProps {}\n\n/** @internal */\nexport const InlinePopoverPopupPropsDeclaration: PropsDeclaration<InlinePopoverPopupProps> = OverlayPopupPropsDeclaration\n\n/** @internal */\nexport function setupInlinePopoverPopup(\n host: HostElement,\n _props: State<InlinePopoverPopupProps>,\n): void {\n const getStore = InlinePopoverStoreContext.consume(host)\n setupOverlayPopup(host, getStore)\n const getOpen = computed(() => getStore()?.getIsOpen() ?? false)\n usePresence(host, getOpen)\n\n onMount(host, () => {\n host.role = 'dialog'\n })\n}\n\nconst InlinePopoverPopupElementBase: HostElementConstructor<InlinePopoverPopupProps> = defineCustomElement(\n setupInlinePopoverPopup,\n InlinePopoverPopupPropsDeclaration,\n)\n\n/**\n * @public\n */\nexport class InlinePopoverPopupElement extends InlinePopoverPopupElementBase {}\n\n/** @internal */\nexport function registerInlinePopoverPopupElement(): void {\n registerCustomElement('prosekit-inline-popover-popup', InlinePopoverPopupElement)\n}\n","import {\n defineCustomElement,\n defineProps,\n registerCustomElement,\n type HostElement,\n type HostElementConstructor,\n type PropsDeclaration,\n type State,\n} from '@aria-ui/core'\nimport { OverlayPositionerPropsDeclaration, setupOverlayPositioner, type OverlayPositionerProps } from '@aria-ui/elements/overlay'\n\nimport { InlinePopoverStoreContext } from './store.ts'\n\n/**\n * @public\n */\nexport interface InlinePopoverPositionerProps extends\n Omit<\n OverlayPositionerProps,\n | 'placement'\n | 'offset'\n | 'hide'\n | 'hoist'\n | 'overlap'\n | 'inline'\n | 'overflowPadding'\n >\n{\n /**\n * The initial placement of the floating element\n *\n * @default \"top\"\n */\n placement: OverlayPositionerProps['placement']\n\n /**\n * The distance between the reference and floating element.\n *\n * @default 12\n */\n offset: OverlayPositionerProps['offset']\n\n /**\n * Whether to hide the floating element when the reference element or the\n * floating element is fully clipped.\n *\n * @default true\n */\n hide: OverlayPositionerProps['hide']\n\n /**\n * Whether to use the browser [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API)\n * to place the floating element on top of other page content.\n *\n * @default false\n */\n hoist: boolean\n\n /**\n * Whether the floating element can overlap the reference element to keep it\n * in view.\n *\n * @default true\n */\n overlap: OverlayPositionerProps['overlap']\n\n /**\n * Whether to improve positioning for inline reference elements that span over\n * multiple lines.\n *\n * @default true\n */\n inline: OverlayPositionerProps['inline']\n\n /**\n * Describes the virtual padding around the boundary to check for overflow.\n *\n * @default 8\n */\n overflowPadding: OverlayPositionerProps['overflowPadding']\n}\n\n/** @internal */\nexport const InlinePopoverPositionerPropsDeclaration: PropsDeclaration<InlinePopoverPositionerProps> = /* @__PURE__ */ defineProps<\n InlinePopoverPositionerProps\n>({\n ...OverlayPositionerPropsDeclaration,\n placement: { default: 'top', attribute: 'placement', type: 'string' },\n offset: { default: 12, attribute: false, type: 'json' },\n hide: { default: true, attribute: 'hide', type: 'boolean' },\n hoist: { default: false, attribute: 'hoist', type: 'boolean' },\n overlap: { default: true, attribute: 'overlap', type: 'boolean' },\n inline: { default: true, attribute: 'inline', type: 'boolean' },\n overflowPadding: { default: 8, attribute: 'overflow-padding', type: 'number' },\n})\n\n/** @internal */\nexport function setupInlinePopoverPositioner(\n host: HostElement,\n props: State<InlinePopoverPositionerProps>,\n): void {\n setupOverlayPositioner(host, props, InlinePopoverStoreContext.consume(host))\n}\n\nconst InlinePopoverPositionerElementBase: HostElementConstructor<InlinePopoverPositionerProps> = defineCustomElement(\n setupInlinePopoverPositioner,\n InlinePopoverPositionerPropsDeclaration,\n)\n\n/**\n * @public\n */\nexport class InlinePopoverPositionerElement extends InlinePopoverPositionerElementBase {}\n\n/** @internal */\nexport function registerInlinePopoverPositionerElement(): void {\n registerCustomElement('prosekit-inline-popover-positioner', InlinePopoverPositionerElement)\n}\n","import type { HostElement } from '@aria-ui/core'\nimport { defineFocusChangeHandler, type Editor, type FocusChangeHandler } from '@prosekit/core'\n\nimport { useEditorExtension } from './use-editor-extension.ts'\n\n/**\n * @internal\n */\nexport function useEditorFocusChangeEvent(\n host: HostElement,\n getEditor: () => Editor | null,\n handler: FocusChangeHandler,\n): void {\n const extension = defineFocusChangeHandler(handler)\n useEditorExtension(host, getEditor, extension)\n}\n","import type { HostElement } from '@aria-ui/core'\nimport { defineUpdateHandler, type Editor, type UpdateHandler } from '@prosekit/core'\n\nimport { useEditorExtension } from './use-editor-extension.ts'\n\n/**\n * @internal\n */\nexport function useEditorUpdateEvent(\n host: HostElement,\n getEditor: () => Editor | null,\n handler: UpdateHandler,\n): void {\n const extension = defineUpdateHandler(handler)\n useEditorExtension(host, getEditor, extension)\n}\n","import type { HostElement } from '@aria-ui/core'\nimport { defineKeymap, type Editor, type Keymap } from '@prosekit/core'\n\nimport { useEditorExtension } from './use-editor-extension.ts'\n\nexport function useKeymap(\n host: HostElement,\n getEditor: () => Editor | null,\n keymap: Keymap,\n): void {\n const extension = defineKeymap(keymap)\n useEditorExtension(host, getEditor, extension)\n}\n","import type { ReferenceElement } from '@floating-ui/dom'\nimport { containsInlineNode, isInCodeBlock, isTextSelection } from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nexport function getVirtualSelectionElement(\n view: EditorView,\n): ReferenceElement | undefined {\n if (typeof window === 'undefined' || view.isDestroyed) {\n return\n }\n\n const selection = view.state.selection\n\n if (\n !selection.empty\n && !isInCodeBlock(selection)\n && isTextSelection(selection)\n && containsInlineNode(view.state.doc, selection.from, selection.to)\n ) {\n return getDomDecoration(view) || getInlineDecoration(view)\n }\n}\n\nfunction getDomDecoration(view: EditorView): ReferenceElement | undefined {\n const range = getDomRange(view)\n if (range) {\n // To get it work properly in Safari, we cannot return the range directly.\n // We have to return a contextElement.\n return {\n contextElement: view.dom,\n getBoundingClientRect: () => range.getBoundingClientRect(),\n getClientRects: () => range.getClientRects(),\n }\n }\n}\n\nfunction getDomRange(view: EditorView): Range | undefined {\n const win = view.dom.ownerDocument.defaultView\n const selection = win?.getSelection()\n if (!selection || selection.isCollapsed) {\n return\n }\n\n const range = typeof selection.rangeCount === 'number'\n && selection.rangeCount > 0\n && selection.getRangeAt(0)\n\n if (!range) {\n return\n }\n\n return range\n}\n\nfunction getInlineDecoration(view: EditorView): ReferenceElement | undefined {\n const match = view.dom.querySelectorAll('.prosekit-virtual-selection')\n\n if (match.length === 0) {\n return\n }\n if (match.length === 1) {\n return match[0]\n }\n\n const items = Array.from(match)\n return {\n contextElement: items[0],\n getBoundingClientRect: () => items[0].getBoundingClientRect(),\n getClientRects: () => items.map((item) => item.getBoundingClientRect()),\n }\n}\n","import {\n defineCustomElement,\n defineProps,\n registerCustomElement,\n type HostElement,\n type HostElementConstructor,\n type PropsDeclaration,\n type State,\n} from '@aria-ui/core'\nimport type { OpenChangeEvent } from '@aria-ui/elements/overlay'\nimport { OverlayRootPropsDeclaration, useOverlayStore, type OverlayRootProps } from '@aria-ui/elements/overlay'\nimport type { Editor } from '@prosekit/core'\nimport type { Selection } from '@prosekit/pm/state'\n\nimport { useEditorFocusChangeEvent } from '../../hooks/use-editor-focus-event.ts'\nimport { useEditorUpdateEvent } from '../../hooks/use-editor-update-event.ts'\nimport { useKeymap } from '../../hooks/use-keymap.ts'\n\nimport { InlinePopoverStoreContext } from './store.ts'\nimport { getVirtualSelectionElement } from './virtual-selection-element.ts'\n\n/**\n * @public\n */\nexport interface InlinePopoverRootProps extends OverlayRootProps {\n /**\n * The ProseKit editor instance.\n *\n * @default null\n * @hidden\n */\n editor: Editor | null\n\n /**\n * Whether the popover is open by default when some inline content is\n * selected.\n *\n * @default true\n */\n defaultOpen: boolean\n\n /**\n * Whether the inline popover should be dismissed when the editor receives an\n * Escape key press.\n *\n * @default true\n */\n dismissOnEscape: boolean\n}\n\n/** @internal */\nexport const InlinePopoverRootPropsDeclaration: PropsDeclaration<InlinePopoverRootProps> = /* @__PURE__ */ defineProps<\n InlinePopoverRootProps\n>({\n ...OverlayRootPropsDeclaration,\n editor: { default: null, attribute: false, type: 'json' },\n defaultOpen: { default: true, attribute: 'default-open', type: 'boolean' },\n dismissOnEscape: { default: true, attribute: 'dismiss-on-escape', type: 'boolean' },\n})\n\n/**\n * @public\n */\nexport interface InlinePopoverRootEvents {\n /**\n * Emitted when the open state of the popover changes.\n */\n openChange: OpenChangeEvent\n}\n\n/** @internal */\nexport function setupInlinePopoverRoot(\n host: HostElement,\n props: State<InlinePopoverRootProps>,\n): void {\n const store = useOverlayStore(host, props)\n InlinePopoverStoreContext.provide(host, store)\n\n let editorFocused = false\n useEditorFocusChangeEvent(host, props.editor.get, (focus) => {\n editorFocused = focus\n })\n\n let prevSelection: Selection | undefined\n useEditorUpdateEvent(host, props.editor.get, (view) => {\n const isPopoverFocused = !editorFocused && host.contains(host.ownerDocument.activeElement)\n if (isPopoverFocused) return\n\n const { selection } = view.state\n if (prevSelection?.eq(selection)) return\n prevSelection = selection\n\n const reference = getVirtualSelectionElement(view)\n store.setAnchorElement(reference)\n\n if (reference && props.defaultOpen.get()) {\n store.requestOpenChange(true)\n } else if (!reference) {\n store.requestOpenChange(false)\n }\n })\n\n useKeymap(host, props.editor.get, {\n Escape: () => {\n if (!props.dismissOnEscape.get() || !store.getIsOpen()) return false\n store.requestOpenChange(false)\n return true\n },\n })\n}\n\nconst InlinePopoverRootElementBase: HostElementConstructor<InlinePopoverRootProps> = defineCustomElement(\n setupInlinePopoverRoot,\n InlinePopoverRootPropsDeclaration,\n)\n\n/**\n * @public\n */\nexport class InlinePopoverRootElement extends InlinePopoverRootElementBase {}\n\n/** @internal */\nexport function registerInlinePopoverRootElement(): void {\n registerCustomElement('prosekit-inline-popover-root', InlinePopoverRootElement)\n}\n"],"mappings":"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"}
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.2",
4
+ "version": "0.8.0-beta.3",
5
5
  "private": false,
6
6
  "description": "A collection of web components for ProseKit",
7
7
  "author": {
@@ -78,18 +78,18 @@
78
78
  "@floating-ui/dom": "^1.7.6",
79
79
  "@ocavue/utils": "^1.6.0",
80
80
  "prosemirror-tables": "^1.8.5",
81
- "@prosekit/core": "^0.12.0-beta.0",
82
81
  "@prosekit/extensions": "^0.16.0-beta.0",
82
+ "@prosekit/core": "^0.12.0-beta.0",
83
83
  "@prosekit/pm": "^0.1.15"
84
84
  },
85
85
  "devDependencies": {
86
- "@aria-ui/cli": "^0.1.0",
86
+ "@aria-ui/cli": "^0.1.3",
87
87
  "tsdown": "^0.21.7",
88
88
  "type-fest": "^5.5.0",
89
89
  "typescript": "~5.9.3",
90
90
  "vitest": "^4.1.4",
91
- "@prosekit/config-tsdown": "0.0.0",
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": {
@@ -62,6 +62,9 @@ export const InlinePopoverRootPropsDeclaration: PropsDeclaration<InlinePopoverRo
62
62
  * @public
63
63
  */
64
64
  export interface InlinePopoverRootEvents {
65
+ /**
66
+ * Emitted when the open state of the popover changes.
67
+ */
65
68
  openChange: OpenChangeEvent
66
69
  }
67
70