@byline/ai 2.7.0 → 3.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../src/plugins/lexical/extension.tsx"],"names":[],"mappings":"AAqCA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,mHAiB7B,CAAA"}
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../../src/plugins/lexical/extension.tsx"],"names":[],"mappings":"AA8DA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,mHAiB7B,CAAA"}
@@ -7,14 +7,25 @@ import { jsx as _jsx } from "react/jsx-runtime";
7
7
  *
8
8
  * Copyright (c) Infonomic Company Limited
9
9
  */
10
+ import { useEffect, useState } from 'react';
10
11
  import { BylineToolbarExtension, useToolbarActiveEditor, } from '@byline/richtext-lexical';
11
12
  import { AiIcon } from '@byline/ui/react';
12
13
  import { ReactExtension } from '@lexical/react/ReactExtension';
13
- import { configExtension, declarePeerDependency, defineExtension } from 'lexical';
14
- import { AiPluginLexical, TOGGLE_AI_DRAWER_COMMAND } from './plugin';
14
+ import { COMMAND_PRIORITY_LOW, configExtension, declarePeerDependency, defineExtension, } from 'lexical';
15
+ import { AI_DRAWER_STATE_COMMAND, AiPluginLexical, TOGGLE_AI_DRAWER_COMMAND } from './plugin';
15
16
  function AiToolbarButton() {
16
17
  const editor = useToolbarActiveEditor();
17
- return (_jsx("button", { type: "button", className: "toolbar-item spaced", "aria-label": "Toggle AI assistant", onClick: () => {
18
+ const [isOpen, setIsOpen] = useState(false);
19
+ // Reflect the drawer's open/closed state (broadcast by the drawer plugin
20
+ // via AI_DRAWER_STATE_COMMAND) so the button shows an `active` cue while
21
+ // the drawer is open — the same affordance Bold / Italic / etc. use.
22
+ useEffect(() => {
23
+ return editor.registerCommand(AI_DRAWER_STATE_COMMAND, (open) => {
24
+ setIsOpen(open);
25
+ return false;
26
+ }, COMMAND_PRIORITY_LOW);
27
+ }, [editor]);
28
+ return (_jsx("button", { type: "button", className: `toolbar-item spaced ${isOpen ? 'active' : ''}`, "aria-label": "Toggle AI assistant", "aria-pressed": isOpen, title: "AI assistant", onClick: () => {
18
29
  editor.dispatchCommand(TOGGLE_AI_DRAWER_COMMAND, undefined);
19
30
  }, children: _jsx(AiIcon, {}) }));
20
31
  }
@@ -7,5 +7,12 @@
7
7
  */
8
8
  import * as React from 'react';
9
9
  export declare const TOGGLE_AI_DRAWER_COMMAND: import("lexical").LexicalCommand<unknown>;
10
+ /**
11
+ * Broadcasts the AI drawer's open/closed state so contributed UI (the
12
+ * toolbar button) can show an active visual cue. Dispatched by the drawer
13
+ * plugin whenever `open` changes — including closes triggered from the
14
+ * drawer's own controls. Observers register a listener and return `false`.
15
+ */
16
+ export declare const AI_DRAWER_STATE_COMMAND: import("lexical").LexicalCommand<boolean>;
10
17
  export declare const AiPluginLexical: React.MemoExoticComponent<() => React.JSX.Element | undefined>;
11
18
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/lexical/plugin.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,eAAO,MAAM,wBAAwB,2CAA4C,CAAA;AAUjF,eAAO,MAAM,eAAe,kCAAmC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAkY1F,CAAA"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/lexical/plugin.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,eAAO,MAAM,wBAAwB,2CAA4C,CAAA;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,2CAAoD,CAAA;AAUxF,eAAO,MAAM,eAAe,kCAAmC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAyY1F,CAAA"}
@@ -19,6 +19,13 @@ import { AiPluginBase } from '../ai-plugin-base';
19
19
  import { createEmptyEditorState } from './create-empty-editor-state';
20
20
  import { importHtmlToSerializedEditorState } from './import-html';
21
21
  export const TOGGLE_AI_DRAWER_COMMAND = createCommand('TOGGLE_AI_DRAWER_COMMAND');
22
+ /**
23
+ * Broadcasts the AI drawer's open/closed state so contributed UI (the
24
+ * toolbar button) can show an active visual cue. Dispatched by the drawer
25
+ * plugin whenever `open` changes — including closes triggered from the
26
+ * drawer's own controls. Observers register a listener and return `false`.
27
+ */
28
+ export const AI_DRAWER_STATE_COMMAND = createCommand('AI_DRAWER_STATE_COMMAND');
22
29
  const emptyInstructionState = {
23
30
  prompt: '',
24
31
  editor: null,
@@ -297,6 +304,12 @@ export const AiPluginLexical = React.memo(function AiPlugin() {
297
304
  return true;
298
305
  }, COMMAND_PRIORITY_NORMAL));
299
306
  }, [editor]);
307
+ // Broadcast open/closed state so the contributed toolbar button can
308
+ // reflect it. Fires on mount (false) and on every change, so the cue
309
+ // also tracks closes triggered from the drawer's own controls.
310
+ useEffect(() => {
311
+ editor.dispatchCommand(AI_DRAWER_STATE_COMMAND, open);
312
+ }, [editor, open]);
300
313
  const helpContent = (_jsxs(_Fragment, { children: [_jsx("p", { style: { margin: '0.5rem 0', fontSize: '16px' }, children: "Byline's AI editing feature can currently be used to generate new content as well as translate, summarize, rephrase, check spelling, grammar and clarity in existing text." }), _jsx("p", { style: { margin: '0.5rem 0', fontSize: '16px' }, children: "Here are a few example prompts:" }), _jsxs("ul", { style: { margin: '0.5rem 0', fontSize: '16px' }, children: [_jsx("li", { children: "Check for spelling, grammar and clarity." }), _jsx("li", { children: "Translate into Thai (English, French, Spanish, Vietnamese, Laos, Khmer etc.)." }), _jsx("li", { children: "Rephrase to make this more engaging." }), _jsx("li", { children: "Write a haiku poem about the wind and trees." })] }), _jsxs("p", { style: { margin: '0.5rem 0', fontSize: '16px' }, children: [_jsx("strong", { style: { color: 'var(--primary-500)' }, children: "Important:" }), " The AI operates in three modes:"] }), _jsxs("ol", { style: { margin: '0.5rem 0', fontSize: '16px' }, children: [_jsxs("li", { children: [_jsx("strong", { children: "New:" }), " The AI will generate new content based solely on the prompt."] }), _jsxs("li", { children: [_jsx("strong", { children: "With Context:" }), " The AI will generate new content based on the prompt and the existing content."] }), _jsxs("li", { children: [_jsx("strong", { children: "Modify:" }), " The AI will suggest modifications to the existing content based on the prompt - preserving the original structure. Use this mode for translations, grammar, clarity, and tone edits."] })] }), _jsx("p", { className: "ai-plugin__disclaimer--modal", children: "Warning: AI-generated content may be inaccurate, incomplete, or misleading. Please use caution and verify information from reliable sources." })] }));
301
314
  return (_jsx(AiPluginBase, { helpTitle: "AI Help", helpContent: helpContent, onSubmit: handleOnSubmit, onSubmitStreaming: handleOnSubmitStreaming, onClear: handleOnClear, onDebug: handleOnDebug, open: open, onOpenChange: setOpen }));
302
315
  });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@byline/ai",
3
3
  "private": false,
4
4
  "license": "MPL-2.0",
5
- "version": "2.7.0",
5
+ "version": "3.0.1",
6
6
  "engines": {
7
7
  "node": ">=20.9.0"
8
8
  },
@@ -66,9 +66,9 @@
66
66
  "react-error-boundary": "^6.1.1",
67
67
  "uuid": "^14.0.0",
68
68
  "zod": "^4.4.3",
69
- "@byline/core": "2.7.0",
70
- "@byline/ui": "2.7.0",
71
- "@byline/richtext-lexical": "2.7.0"
69
+ "@byline/richtext-lexical": "3.0.1",
70
+ "@byline/core": "3.0.1",
71
+ "@byline/ui": "3.0.1"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@biomejs/biome": "2.4.15",