@handlewithcare/react-prosemirror 2.4.10 → 2.4.12

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 (61) hide show
  1. package/README.md +16 -0
  2. package/dist/cjs/components/Editor.js +28 -0
  3. package/dist/cjs/components/NodeViews.js +73 -0
  4. package/dist/cjs/{contexts/__tests__/DeferredLayoutEffects.test.js → components/__tests__/LayoutGroup.test.js} +2 -2
  5. package/dist/cjs/components/__tests__/ProseMirror.test.js +136 -263
  6. package/dist/cjs/contexts/NodeViewsContext.js +10 -0
  7. package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +27 -28
  8. package/dist/cjs/hooks/__tests__/useNodeViews.test.js +159 -0
  9. package/dist/cjs/hooks/useEditor.js +2 -4
  10. package/dist/cjs/hooks/useEditorView.js +100 -0
  11. package/dist/cjs/hooks/useNodePos.js +69 -0
  12. package/dist/cjs/hooks/useNodeViews.js +100 -0
  13. package/dist/cjs/nodeViews/createReactNodeViewConstructor.js +244 -0
  14. package/dist/cjs/nodeViews/phrasingContentTags.js +57 -0
  15. package/dist/cjs/plugins/__tests__/react.test.js +139 -0
  16. package/dist/cjs/plugins/react.js +71 -0
  17. package/dist/esm/components/Editor.js +15 -0
  18. package/dist/esm/components/NodeViews.js +26 -0
  19. package/dist/esm/{contexts/__tests__/DeferredLayoutEffects.test.js → components/__tests__/LayoutGroup.test.js} +2 -2
  20. package/dist/esm/components/__tests__/ProseMirror.test.js +135 -267
  21. package/dist/esm/contexts/NodeViewsContext.js +9 -0
  22. package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +27 -28
  23. package/dist/esm/hooks/__tests__/useNodeViews.test.js +116 -0
  24. package/dist/esm/hooks/useEditor.js +2 -4
  25. package/dist/esm/hooks/useEditorView.js +99 -0
  26. package/dist/esm/hooks/useNodePos.js +16 -0
  27. package/dist/esm/hooks/useNodeViews.js +53 -0
  28. package/dist/esm/nodeViews/createReactNodeViewConstructor.js +214 -0
  29. package/dist/esm/nodeViews/phrasingContentTags.js +49 -0
  30. package/dist/esm/plugins/__tests__/react.test.js +135 -0
  31. package/dist/esm/plugins/react.js +64 -0
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/dist/types/components/Editor.d.ts +7 -0
  34. package/dist/types/components/NodeViews.d.ts +6 -0
  35. package/dist/types/components/__tests__/LayoutGroup.test.d.ts +1 -0
  36. package/dist/types/contexts/NodeViewsContext.d.ts +19 -0
  37. package/dist/types/decorations/ReactWidgetType.d.ts +1 -0
  38. package/dist/types/hooks/__tests__/useNodeViews.test.d.ts +1 -0
  39. package/dist/types/hooks/useEditorView.d.ts +23 -0
  40. package/dist/types/hooks/useNodePos.d.ts +9 -0
  41. package/dist/types/hooks/useNodeViews.d.ts +5 -0
  42. package/dist/types/nodeViews/createReactNodeViewConstructor.d.ts +48 -0
  43. package/dist/types/nodeViews/phrasingContentTags.d.ts +1 -0
  44. package/dist/types/plugins/__tests__/react.test.d.ts +1 -0
  45. package/dist/types/plugins/react.d.ts +21 -0
  46. package/dist/types/props.d.ts +27 -27
  47. package/package.json +1 -1
  48. package/dist/cjs/components/__tests__/ProseMirror.composition.test.js +0 -398
  49. package/dist/cjs/components/__tests__/ProseMirror.domchange.test.js +0 -270
  50. package/dist/cjs/components/__tests__/ProseMirror.draw-decoration.test.js +0 -1010
  51. package/dist/cjs/components/__tests__/ProseMirror.draw.test.js +0 -337
  52. package/dist/cjs/components/__tests__/ProseMirror.node-view.test.js +0 -315
  53. package/dist/cjs/components/__tests__/ProseMirror.selection.test.js +0 -444
  54. package/dist/cjs/plugins/__tests__/reactKeys.test.js +0 -81
  55. package/dist/esm/components/__tests__/ProseMirror.composition.test.js +0 -395
  56. package/dist/esm/components/__tests__/ProseMirror.domchange.test.js +0 -266
  57. package/dist/esm/components/__tests__/ProseMirror.draw-decoration.test.js +0 -967
  58. package/dist/esm/components/__tests__/ProseMirror.draw.test.js +0 -294
  59. package/dist/esm/components/__tests__/ProseMirror.node-view.test.js +0 -272
  60. package/dist/esm/components/__tests__/ProseMirror.selection.test.js +0 -440
  61. package/dist/esm/plugins/__tests__/reactKeys.test.js +0 -77
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from "react";
2
+ import type { UseEditorViewOptions } from "../hooks/useEditorView.js";
3
+ export interface EditorProps extends UseEditorViewOptions {
4
+ mount: HTMLElement | null;
5
+ children?: ReactNode | null;
6
+ }
7
+ export declare function Editor({ mount, children, ...options }: EditorProps): JSX.Element;
@@ -0,0 +1,6 @@
1
+ import type { NodeViewsContextValue } from "../contexts/NodeViewsContext.js";
2
+ type NodeViewsProps = {
3
+ portals: NodeViewsContextValue;
4
+ };
5
+ export declare function NodeViews({ portals }: NodeViewsProps): JSX.Element;
6
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { ReactPortal } from "react";
2
+ import type { NodeKey } from "../plugins/react";
3
+ type NodeViewRegistration = {
4
+ getPos: () => number;
5
+ portal: ReactPortal;
6
+ };
7
+ export interface NodeViewsContextValue {
8
+ [key: NodeKey]: NodeViewRegistration[];
9
+ }
10
+ /**
11
+ * A context containing a map of node view keys to portals.
12
+ *
13
+ * Each node view registers a portal under its parent's
14
+ * key. Each can then retrieve the list of portals under their
15
+ * key, allowing portals to be rendered with the appropriate
16
+ * hierarchy.
17
+ */
18
+ export declare const NodeViewsContext: import("react").Context<NodeViewsContextValue>;
19
+ export {};
@@ -20,6 +20,7 @@ type ReactWidgetSpec = {
20
20
  stopEvent?: (event: Event) => boolean;
21
21
  ignoreSelection?: boolean;
22
22
  key?: string;
23
+ [key: string]: unknown;
23
24
  };
24
25
  export declare class ReactWidgetType implements DecorationType {
25
26
  Component: ForwardRefExoticComponent<RefAttributes<HTMLElement> & WidgetViewComponentProps>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { EditorState } from "prosemirror-state";
2
+ import type { Plugin, Transaction } from "prosemirror-state";
3
+ import { EditorView } from "prosemirror-view";
4
+ import type { EditorProps } from "prosemirror-view";
5
+ import type { EditorContextValue } from "../contexts/EditorContext.js";
6
+ import type { ReactNodeViewConstructor } from "../nodeViews/createReactNodeViewConstructor.js";
7
+ export interface UseEditorViewOptions extends EditorProps {
8
+ nodeViews?: Record<string, ReactNodeViewConstructor>;
9
+ defaultState?: EditorState;
10
+ state?: EditorState;
11
+ plugins?: Plugin[];
12
+ view?: EditorView | null;
13
+ dispatchTransaction?(this: EditorView, tr: Transaction): void;
14
+ }
15
+ /**
16
+ * Creates, mounts, and manages a ProseMirror `EditorView`.
17
+ *
18
+ * All state and props updates are executed in a layout effect.
19
+ * To ensure that the EditorState and EditorView are never out of
20
+ * sync, it's important that the EditorView produced by this hook
21
+ * is only accessed through the provided hooks.
22
+ */
23
+ export declare function useEditorView<T extends HTMLElement = HTMLElement>(mount: T | null, options: UseEditorViewOptions): EditorContextValue;
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ import type { NodeKey } from "../plugins/react.js";
3
+ type Props = {
4
+ nodeKey: NodeKey;
5
+ children: ReactNode;
6
+ };
7
+ export declare function NodePosProvider({ nodeKey, children }: Props): JSX.Element;
8
+ export declare function useNodePos(): number;
9
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { ReactNodeViewConstructor } from "../nodeViews/createReactNodeViewConstructor.js";
2
+ export declare function useNodeViews(nodeViews?: Record<string, ReactNodeViewConstructor>): {
3
+ nodeViews: any;
4
+ nodeViewsComponent: JSX.Element;
5
+ };
@@ -0,0 +1,48 @@
1
+ import type { Node } from "prosemirror-model";
2
+ import type { Decoration, DecorationSource, EditorView, NodeView, NodeViewConstructor } from "prosemirror-view";
3
+ import type { ComponentType, ReactNode, ReactPortal } from "react";
4
+ import type { NodeKey } from "../plugins/react.js";
5
+ export interface NodeViewComponentProps {
6
+ decorations: readonly Decoration[];
7
+ node: Node;
8
+ children: ReactNode;
9
+ isSelected: boolean;
10
+ }
11
+ export type UnregisterElement = () => void;
12
+ export type RegisterPortal = (view: EditorView, getPos: () => number, portal: ReactPortal) => UnregisterElement;
13
+ export type ReactNodeView = NodeView & {
14
+ component?: ComponentType<NodeViewComponentProps>;
15
+ };
16
+ export type ReactNodeViewConstructor = (...args: Parameters<NodeViewConstructor>) => ReactNodeView;
17
+ /**
18
+ * Identifies a node view constructor as having been created
19
+ * by @nytimes/react-prosemirror
20
+ */
21
+ export declare const REACT_NODE_VIEW: unique symbol;
22
+ /**
23
+ * Searches upward for the nearest node with a node key,
24
+ * returning the first node key it finds associated with
25
+ * a React node view.
26
+ *
27
+ * Returns the root key if no ancestor nodes have node keys.
28
+ */
29
+ export declare function findNodeKeyUp(editorView: EditorView, pos: number): NodeKey;
30
+ /**
31
+ * Factory function for creating nodeViewConstructors that
32
+ * render as React components.
33
+ *
34
+ * `NodeView` can be any React component that takes
35
+ * `NodeViewComponentProps`. It will be passed all of the
36
+ * arguments to the `nodeViewConstructor` except for
37
+ * `editorView`. NodeView components that need access
38
+ * directly to the EditorView should use the
39
+ * `useEditorViewEvent` and `useEditorViewLayoutEffect`
40
+ * hooks to ensure safe access.
41
+ *
42
+ * For contentful Nodes, the NodeView component will also
43
+ * be passed a `children` prop containing an empty element.
44
+ * ProseMirror will render content nodes into this element.
45
+ */
46
+ export declare function createReactNodeViewConstructor(nodeViewConstructor: ReactNodeViewConstructor, registerPortal: RegisterPortal): ((node: Node, editorView: EditorView, getPos: () => number, decorations: readonly Decoration[], innerDecorations: DecorationSource) => NodeView) & {
47
+ [REACT_NODE_VIEW]: boolean;
48
+ };
@@ -0,0 +1 @@
1
+ export declare const phrasingContentTags: string[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import { Plugin, PluginKey } from "prosemirror-state";
2
+ /**
3
+ * This is a stand-in for the doc node itself, which doesn't have a
4
+ * unique position to map to.
5
+ */
6
+ export declare const ROOT_NODE_KEY: unique symbol;
7
+ export type NodeKey = string | symbol;
8
+ export declare function createNodeKey(): string;
9
+ export type ReactPluginState = {
10
+ posToKey: Map<number, string>;
11
+ keyToPos: Map<NodeKey, number>;
12
+ };
13
+ export declare const reactPluginKey: PluginKey<ReactPluginState>;
14
+ /**
15
+ * Tracks a unique key for each (non-text) node in the
16
+ * document, identified by its current position. Keys are
17
+ * (mostly) stable across transaction applications. The
18
+ * key for a given node can be accessed by that node's
19
+ * current position in the document, and vice versa.
20
+ */
21
+ export declare function react(): Plugin<ReactPluginState>;
@@ -904,22 +904,22 @@ export declare function mergeReactProps(a: HTMLProps<HTMLElement>, b: HTMLProps<
904
904
  suppressContentEditableWarning?: boolean | undefined;
905
905
  suppressHydrationWarning?: boolean | undefined;
906
906
  accessKey?: string | undefined;
907
- autoCapitalize?: "none" | (string & {}) | "off" | "on" | "sentences" | "words" | "characters" | undefined;
907
+ autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | (string & {}) | undefined;
908
908
  autoFocus?: boolean | undefined;
909
- contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
909
+ contentEditable?: (boolean | "false" | "true") | "inherit" | "plaintext-only" | undefined;
910
910
  contextMenu?: string | undefined;
911
911
  dir?: string | undefined;
912
- draggable?: (boolean | "true" | "false") | undefined;
913
- enterKeyHint?: "search" | "enter" | "done" | "go" | "next" | "previous" | "send" | undefined;
912
+ draggable?: (boolean | "false" | "true") | undefined;
913
+ enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined;
914
914
  hidden?: boolean | undefined;
915
915
  id?: string | undefined;
916
916
  lang?: string | undefined;
917
917
  nonce?: string | undefined;
918
918
  slot?: string | undefined;
919
- spellCheck?: (boolean | "true" | "false") | undefined;
919
+ spellCheck?: (boolean | "false" | "true") | undefined;
920
920
  tabIndex?: number | undefined;
921
921
  title?: string | undefined;
922
- translate?: "yes" | "no" | undefined;
922
+ translate?: "no" | "yes" | undefined;
923
923
  radioGroup?: string | undefined;
924
924
  role?: import("react").AriaRole | undefined;
925
925
  about?: string | undefined;
@@ -944,57 +944,57 @@ export declare function mergeReactProps(a: HTMLProps<HTMLElement>, b: HTMLProps<
944
944
  results?: number | undefined;
945
945
  security?: string | undefined;
946
946
  unselectable?: "off" | "on" | undefined;
947
- inputMode?: "search" | "text" | "none" | "email" | "tel" | "url" | "numeric" | "decimal" | undefined;
947
+ inputMode?: "none" | "search" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
948
948
  is?: string | undefined;
949
949
  exportparts?: string | undefined;
950
950
  part?: string | undefined;
951
951
  "aria-activedescendant"?: string | undefined;
952
- "aria-atomic"?: (boolean | "true" | "false") | undefined;
953
- "aria-autocomplete"?: "list" | "none" | "both" | "inline" | undefined;
952
+ "aria-atomic"?: (boolean | "false" | "true") | undefined;
953
+ "aria-autocomplete"?: "none" | "list" | "inline" | "both" | undefined;
954
954
  "aria-braillelabel"?: string | undefined;
955
955
  "aria-brailleroledescription"?: string | undefined;
956
- "aria-busy"?: (boolean | "true" | "false") | undefined;
957
- "aria-checked"?: boolean | "true" | "false" | "mixed" | undefined;
956
+ "aria-busy"?: (boolean | "false" | "true") | undefined;
957
+ "aria-checked"?: boolean | "false" | "true" | "mixed" | undefined;
958
958
  "aria-colcount"?: number | undefined;
959
959
  "aria-colindex"?: number | undefined;
960
960
  "aria-colindextext"?: string | undefined;
961
961
  "aria-colspan"?: number | undefined;
962
962
  "aria-controls"?: string | undefined;
963
- "aria-current"?: boolean | "time" | "step" | "date" | "true" | "false" | "page" | "location" | undefined;
963
+ "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined;
964
964
  "aria-describedby"?: string | undefined;
965
965
  "aria-description"?: string | undefined;
966
966
  "aria-details"?: string | undefined;
967
- "aria-disabled"?: (boolean | "true" | "false") | undefined;
968
- "aria-dropeffect"?: "link" | "none" | "copy" | "move" | "execute" | "popup" | undefined;
967
+ "aria-disabled"?: (boolean | "false" | "true") | undefined;
968
+ "aria-dropeffect"?: "copy" | "none" | "link" | "execute" | "move" | "popup" | undefined;
969
969
  "aria-errormessage"?: string | undefined;
970
- "aria-expanded"?: (boolean | "true" | "false") | undefined;
970
+ "aria-expanded"?: (boolean | "false" | "true") | undefined;
971
971
  "aria-flowto"?: string | undefined;
972
- "aria-grabbed"?: (boolean | "true" | "false") | undefined;
973
- "aria-haspopup"?: boolean | "dialog" | "menu" | "grid" | "listbox" | "tree" | "true" | "false" | undefined;
974
- "aria-hidden"?: (boolean | "true" | "false") | undefined;
975
- "aria-invalid"?: boolean | "true" | "false" | "grammar" | "spelling" | undefined;
972
+ "aria-grabbed"?: (boolean | "false" | "true") | undefined;
973
+ "aria-haspopup"?: boolean | "false" | "true" | "dialog" | "grid" | "listbox" | "menu" | "tree" | undefined;
974
+ "aria-hidden"?: (boolean | "false" | "true") | undefined;
975
+ "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined;
976
976
  "aria-keyshortcuts"?: string | undefined;
977
977
  "aria-label"?: string | undefined;
978
978
  "aria-labelledby"?: string | undefined;
979
979
  "aria-level"?: number | undefined;
980
980
  "aria-live"?: "off" | "assertive" | "polite" | undefined;
981
- "aria-modal"?: (boolean | "true" | "false") | undefined;
982
- "aria-multiline"?: (boolean | "true" | "false") | undefined;
983
- "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
981
+ "aria-modal"?: (boolean | "false" | "true") | undefined;
982
+ "aria-multiline"?: (boolean | "false" | "true") | undefined;
983
+ "aria-multiselectable"?: (boolean | "false" | "true") | undefined;
984
984
  "aria-orientation"?: "horizontal" | "vertical" | undefined;
985
985
  "aria-owns"?: string | undefined;
986
986
  "aria-placeholder"?: string | undefined;
987
987
  "aria-posinset"?: number | undefined;
988
- "aria-pressed"?: boolean | "true" | "false" | "mixed" | undefined;
989
- "aria-readonly"?: (boolean | "true" | "false") | undefined;
990
- "aria-relevant"?: "text" | "all" | "additions" | "additions removals" | "additions text" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | undefined;
991
- "aria-required"?: (boolean | "true" | "false") | undefined;
988
+ "aria-pressed"?: boolean | "false" | "true" | "mixed" | undefined;
989
+ "aria-readonly"?: (boolean | "false" | "true") | undefined;
990
+ "aria-relevant"?: "text" | "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | undefined;
991
+ "aria-required"?: (boolean | "false" | "true") | undefined;
992
992
  "aria-roledescription"?: string | undefined;
993
993
  "aria-rowcount"?: number | undefined;
994
994
  "aria-rowindex"?: number | undefined;
995
995
  "aria-rowindextext"?: string | undefined;
996
996
  "aria-rowspan"?: number | undefined;
997
- "aria-selected"?: (boolean | "true" | "false") | undefined;
997
+ "aria-selected"?: (boolean | "false" | "true") | undefined;
998
998
  "aria-setsize"?: number | undefined;
999
999
  "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined;
1000
1000
  "aria-valuemax"?: number | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handlewithcare/react-prosemirror",
3
- "version": "2.4.10",
3
+ "version": "2.4.12",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",