@byline/richtext-lexical 4.11.1 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/config.d.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  * `EditorField` / `Nodes` or the heavy *content* extension classes
16
16
  * (Table, InlineImage, Admonition, …), all of which statically pull React
17
17
  * plugins, nodes, and the Lexical core. Import from here at registration
18
- * sites (e.g. an admin/client config that you want to evaluate eagerly)
18
+ * sites (e.g. an admin/admin config that you want to evaluate eagerly)
19
19
  * so referencing the editor doesn't drag the editor module graph into the
20
20
  * importing bundle.
21
21
  *
@@ -79,11 +79,11 @@ function InlineImageComponent({ relation, src, position, altText, width, height,
79
79
  if (isSelected && $isNodeSelection(latestSelection) && 1 === latestSelection.getNodes().length) {
80
80
  if (showCaption) {
81
81
  $setSelection(null);
82
- event.preventDefault();
82
+ event?.preventDefault();
83
83
  caption.focus();
84
84
  return true;
85
85
  } else if (null !== buttonElem && buttonElem !== document.activeElement) {
86
- event.preventDefault();
86
+ event?.preventDefault();
87
87
  buttonElem.focus();
88
88
  return true;
89
89
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { LexicalCommand, NodeKey } from 'lexical';
3
- export declare const OPEN_INSERT_LAYOUT_MODAL_COMMAND: LexicalCommand<unknown>;
3
+ export declare const OPEN_INSERT_LAYOUT_MODAL_COMMAND: LexicalCommand<null>;
4
4
  export declare const INSERT_LAYOUT_COMMAND: LexicalCommand<string>;
5
5
  export declare const UPDATE_LAYOUT_COMMAND: LexicalCommand<{
6
6
  template: string;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useRef, useState } from "react";
4
- import { getClientConfig } from "@byline/core";
4
+ import { getAdminConfig } from "@byline/core";
5
5
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
6
6
  import { $findMatchingParent, mergeRegister } from "@lexical/utils";
7
7
  import { $getSelection, $isLineBreakNode, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_LOW, KEY_ESCAPE_COMMAND, SELECTION_CHANGE_COMMAND } from "lexical";
@@ -20,7 +20,7 @@ function FloatingLinkEditor({ editor, isLink, setIsLink, anchorElem }) {
20
20
  });
21
21
  const [linkModalData, setLinkModalData] = useState(void 0);
22
22
  const [modalOpen, setModalOpen] = useState(false);
23
- const adminRoute = getClientConfig().routes.admin;
23
+ const adminRoute = getAdminConfig().routes.admin;
24
24
  const $updateLinkEditor = useCallback(()=>{
25
25
  const selection = $getSelection();
26
26
  if ($isRangeSelection(selection)) {
@@ -2,7 +2,7 @@
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useMemo, useState } from "react";
4
4
  import { RelationPicker } from "@byline/admin/react";
5
- import { getClientConfig, getCollectionDefinition } from "@byline/core";
5
+ import { getAdminConfig, getCollectionDefinition } from "@byline/core";
6
6
  import { Button, Checkbox, CloseIcon, IconButton, Input, Label, Modal, RadioGroup, RadioGroupItem, Select } from "@byline/ui/react";
7
7
  import { useModalFormState } from "../../shared/useModalFormState.js";
8
8
  import { validateUrl } from "../../utils/url.js";
@@ -41,7 +41,7 @@ function fromLinkData(data, linkable) {
41
41
  };
42
42
  }
43
43
  const LinkModal = ({ isOpen = false, onSubmit, onClose, data: dataFromProps })=>{
44
- const linkable = useMemo(()=>getClientConfig().collections.filter((c)=>true === c.linksInEditor), []);
44
+ const linkable = useMemo(()=>getAdminConfig().collections.filter((c)=>true === c.linksInEditor), []);
45
45
  const [pickerOpen, setPickerOpen] = useState(false);
46
46
  const [urlError, setUrlError] = useState(null);
47
47
  const [state, setState] = useModalFormState(isOpen, ()=>fromLinkData(dataFromProps, linkable), ()=>setUrlError(null));
@@ -1,11 +1,11 @@
1
- import { getClientConfig } from "@byline/core";
1
+ import { getAdminConfig } from "@byline/core";
2
2
  import { addClassNamesToElement, isHTMLAnchorElement } from "@lexical/utils";
3
3
  import { $applyNodeReplacement, $createTextNode, $getSelection, $isElementNode, $isRangeSelection, ElementNode, createCommand } from "lexical";
4
4
  import { sanitizeUrl } from "../../utils/url.js";
5
5
  function adminHref(attrs) {
6
6
  if (null == attrs || 'internal' !== attrs.linkType) return '#';
7
7
  const internal = attrs;
8
- const { admin } = getClientConfig().routes;
8
+ const { admin } = getAdminConfig().routes;
9
9
  return `${admin}/collections/${internal.targetCollectionPath}/${internal.targetDocumentId}`;
10
10
  }
11
11
  class LinkNode extends ElementNode {
@@ -1,3 +1,3 @@
1
1
  import * as React from 'react';
2
- export declare const OPEN_TABLE_MODAL_COMMAND: import("lexical").LexicalCommand<unknown>;
2
+ export declare const OPEN_TABLE_MODAL_COMMAND: import("lexical").LexicalCommand<null>;
3
3
  export declare function TablePlugin(): React.JSX.Element;
@@ -46,7 +46,7 @@ type ConfigureFn = (config: LexicalEditorConfigureInput) => LexicalEditorConfigu
46
46
  * ```ts
47
47
  * import { lexicalEditor, TableExtension } from '@byline/richtext-lexical'
48
48
  *
49
- * defineClientConfig({
49
+ * defineAdminConfig({
50
50
  * fields: {
51
51
  * richText: {
52
52
  * editor: lexicalEditor((c) => {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "private": false,
4
4
  "type": "module",
5
5
  "license": "MPL-2.0",
6
- "version": "4.11.1",
6
+ "version": "4.12.0",
7
7
  "engines": {
8
8
  "node": ">=20.9.0"
9
9
  },
@@ -56,47 +56,47 @@
56
56
  }
57
57
  },
58
58
  "dependencies": {
59
- "@lexical/code": "0.48.0",
60
- "@lexical/extension": "0.48.0",
61
- "@lexical/headless": "0.48.0",
62
- "@lexical/link": "0.48.0",
63
- "@lexical/list": "0.48.0",
64
- "@lexical/mark": "0.48.0",
65
- "@lexical/markdown": "0.48.0",
66
- "@lexical/overflow": "0.48.0",
67
- "@lexical/react": "0.48.0",
68
- "@lexical/rich-text": "0.48.0",
69
- "@lexical/selection": "0.48.0",
70
- "@lexical/table": "0.48.0",
71
- "@lexical/utils": "0.48.0",
59
+ "@lexical/code": "0.49.0",
60
+ "@lexical/extension": "0.49.0",
61
+ "@lexical/headless": "0.49.0",
62
+ "@lexical/link": "0.49.0",
63
+ "@lexical/list": "0.49.0",
64
+ "@lexical/mark": "0.49.0",
65
+ "@lexical/markdown": "0.49.0",
66
+ "@lexical/overflow": "0.49.0",
67
+ "@lexical/react": "0.49.0",
68
+ "@lexical/rich-text": "0.49.0",
69
+ "@lexical/selection": "0.49.0",
70
+ "@lexical/table": "0.49.0",
71
+ "@lexical/utils": "0.49.0",
72
72
  "clsx": "^2.1.1",
73
- "lexical": "0.48.0",
73
+ "lexical": "0.49.0",
74
74
  "react-error-boundary": "^6.1.2",
75
- "@byline/admin": "4.11.1",
76
- "@byline/client": "4.11.1",
77
- "@byline/ui": "4.11.1",
78
- "@byline/core": "4.11.1"
75
+ "@byline/admin": "4.12.0",
76
+ "@byline/ui": "4.12.0",
77
+ "@byline/client": "4.12.0",
78
+ "@byline/core": "4.12.0"
79
79
  },
80
80
  "peerDependencies": {
81
81
  "react": "^19.0.0",
82
82
  "react-dom": "^19.0.0"
83
83
  },
84
84
  "devDependencies": {
85
- "@biomejs/biome": "2.5.4",
85
+ "@biomejs/biome": "2.5.6",
86
86
  "@rsbuild/plugin-react": "^2.1.0",
87
87
  "@rslib/core": "^0.23.2",
88
- "@types/node": "^26.1.1",
89
- "@types/react": "19.2.17",
90
- "@types/react-dom": "19.2.3",
91
- "@vitejs/plugin-react": "^6.0.3",
92
- "lightningcss": "^1.32.0",
88
+ "@types/node": "^26.1.2",
89
+ "@types/react": "19.2.18",
90
+ "@types/react-dom": "19.2.4",
91
+ "@vitejs/plugin-react": "^6.0.5",
92
+ "lightningcss": "^1.33.0",
93
93
  "npm-run-all": "^4.1.5",
94
- "react": "^19.2.7",
95
- "react-dom": "^19.2.7",
94
+ "react": "^19.2.8",
95
+ "react-dom": "^19.2.8",
96
96
  "rimraf": "^6.1.3",
97
97
  "typescript": "^7.0.2",
98
98
  "typescript-plugin-css-modules": "^5.2.0",
99
- "vite": "^8.1.5",
99
+ "vite": "^8.2.0",
100
100
  "vitest": "^4.1.10"
101
101
  },
102
102
  "publishConfig": {
package/src/config.ts CHANGED
@@ -16,7 +16,7 @@
16
16
  * `EditorField` / `Nodes` or the heavy *content* extension classes
17
17
  * (Table, InlineImage, Admonition, …), all of which statically pull React
18
18
  * plugins, nodes, and the Lexical core. Import from here at registration
19
- * sites (e.g. an admin/client config that you want to evaluate eagerly)
19
+ * sites (e.g. an admin/admin config that you want to evaluate eagerly)
20
20
  * so referencing the editor doesn't drag the editor module graph into the
21
21
  * importing bundle.
22
22
  *
@@ -158,7 +158,11 @@ export default function InlineImageComponent({
158
158
  )
159
159
 
160
160
  const onEnter = useCallback(
161
- (event: KeyboardEvent) => {
161
+ // KEY_ENTER_COMMAND carries `KeyboardEvent | null` — Lexical synthesises an
162
+ // Enter with a null event when an IME composition ends in a newline, and
163
+ // that path reaches node selections too. There is nothing to preventDefault
164
+ // in that case, but the focus move still applies.
165
+ (event: KeyboardEvent | null) => {
162
166
  const latestSelection = $getSelection()
163
167
  const buttonElem = buttonRef.current
164
168
  if (
@@ -169,11 +173,11 @@ export default function InlineImageComponent({
169
173
  if (showCaption) {
170
174
  // Move focus into nested editor
171
175
  $setSelection(null)
172
- event.preventDefault()
176
+ event?.preventDefault()
173
177
  caption.focus()
174
178
  return true
175
179
  } else if (buttonElem !== null && buttonElem !== document.activeElement) {
176
- event.preventDefault()
180
+ event?.preventDefault()
177
181
  buttonElem.focus()
178
182
  return true
179
183
  }
@@ -39,7 +39,9 @@ import {
39
39
  } from './layout-container-node'
40
40
  import { $createLayoutItemNode, $isLayoutItemNode, LayoutItemNode } from './layout-item-node'
41
41
 
42
- export const OPEN_INSERT_LAYOUT_MODAL_COMMAND = createCommand('OPEN_INSERT_LAYOUT_MODAL_COMMAND')
42
+ export const OPEN_INSERT_LAYOUT_MODAL_COMMAND = createCommand<null>(
43
+ 'OPEN_INSERT_LAYOUT_MODAL_COMMAND'
44
+ )
43
45
 
44
46
  export const INSERT_LAYOUT_COMMAND: LexicalCommand<string> = createCommand<string>()
45
47
 
@@ -13,7 +13,7 @@
13
13
  import type * as React from 'react'
14
14
  import { type Dispatch, useCallback, useEffect, useRef, useState } from 'react'
15
15
 
16
- import { getClientConfig } from '@byline/core'
16
+ import { getAdminConfig } from '@byline/core'
17
17
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
18
18
  import { $findMatchingParent, mergeRegister } from '@lexical/utils'
19
19
  import {
@@ -70,7 +70,7 @@ function FloatingLinkEditor({
70
70
  })
71
71
  const [linkModalData, setLinkModalData] = useState<LinkData | undefined>(undefined)
72
72
  const [modalOpen, setModalOpen] = useState(false)
73
- const adminRoute = getClientConfig().routes.admin
73
+ const adminRoute = getAdminConfig().routes.admin
74
74
 
75
75
  const $updateLinkEditor = useCallback(() => {
76
76
  const selection = $getSelection()
@@ -13,7 +13,7 @@ import { useMemo, useState } from 'react'
13
13
 
14
14
  import { RelationPicker } from '@byline/admin/react'
15
15
  import type { CollectionDefinition } from '@byline/core'
16
- import { getClientConfig, getCollectionDefinition } from '@byline/core'
16
+ import { getAdminConfig, getCollectionDefinition } from '@byline/core'
17
17
  import {
18
18
  Button,
19
19
  Checkbox,
@@ -102,7 +102,7 @@ export const LinkModal: React.FC<LinkModalProps> = ({
102
102
  data: dataFromProps,
103
103
  }) => {
104
104
  const linkable = useMemo<CollectionDefinition[]>(
105
- () => getClientConfig().collections.filter((c) => c.linksInEditor === true),
105
+ () => getAdminConfig().collections.filter((c) => c.linksInEditor === true),
106
106
  []
107
107
  )
108
108
 
@@ -6,7 +6,7 @@
6
6
  *
7
7
  */
8
8
 
9
- import { getClientConfig } from '@byline/core'
9
+ import { getAdminConfig } from '@byline/core'
10
10
  import { addClassNamesToElement, isHTMLAnchorElement } from '@lexical/utils'
11
11
  import {
12
12
  $applyNodeReplacement,
@@ -33,7 +33,7 @@ import type { InternalLinkAttributes, LinkAttributes, SerializedLinkNode } from
33
33
  function adminHref(attrs: LinkAttributes | null | undefined): string {
34
34
  if (attrs == null || attrs.linkType !== 'internal') return '#'
35
35
  const internal = attrs as InternalLinkAttributes
36
- const { admin } = getClientConfig().routes
36
+ const { admin } = getAdminConfig().routes
37
37
  return `${admin}/collections/${internal.targetCollectionPath}/${internal.targetDocumentId}`
38
38
  }
39
39
 
@@ -8,7 +8,7 @@ import { COMMAND_PRIORITY_NORMAL, createCommand } from 'lexical'
8
8
 
9
9
  import { TableModal } from './table-modal'
10
10
 
11
- export const OPEN_TABLE_MODAL_COMMAND = createCommand('OPEN_TABLE_MODAL_COMMAND')
11
+ export const OPEN_TABLE_MODAL_COMMAND = createCommand<null>('OPEN_TABLE_MODAL_COMMAND')
12
12
 
13
13
  export function TablePlugin(): React.JSX.Element {
14
14
  const [editor] = useLexicalComposerContext()
@@ -97,7 +97,7 @@ function loadEditorBundle(): Promise<EditorBundle> {
97
97
  * ```ts
98
98
  * import { lexicalEditor, TableExtension } from '@byline/richtext-lexical'
99
99
  *
100
- * defineClientConfig({
100
+ * defineAdminConfig({
101
101
  * fields: {
102
102
  * richText: {
103
103
  * editor: lexicalEditor((c) => {