@lyfie/luthor 2.3.1 → 2.3.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.
package/README.md CHANGED
@@ -1,20 +1,14 @@
1
1
  # @lyfie/luthor
2
2
 
3
- Plug-and-play React editor preset package built on top of `@lyfie/luthor-headless`.
3
+ Plug-and-play preset package built on top of `@lyfie/luthor-headless`.
4
4
 
5
- ## Package responsibility
6
-
7
- - Owns preset UX/composition and plug-and-play defaults.
8
- - Reuses headless behavior APIs instead of re-implementing Lexical semantics.
9
- - Exposes headless namespace for advanced users who need lower-level control.
10
-
11
- ## Installation
5
+ ## Install
12
6
 
13
7
  ```bash
14
8
  pnpm add @lyfie/luthor react react-dom
15
9
  ```
16
10
 
17
- ## Quick Start
11
+ ## Usage
18
12
 
19
13
  ```tsx
20
14
  import { ExtensiveEditor } from "@lyfie/luthor";
@@ -25,296 +19,7 @@ export function App() {
25
19
  }
26
20
  ```
27
21
 
28
- ## What This Package Exposes
29
-
30
- - Preset editor component: `ExtensiveEditor`
31
- - Additional preset editors: `SimpleTextEditor`, `RichTextBoxEditor`, `ChatWindowEditor`, `EmailComposeEditor`, `MDTextEditor`, `NotionLikeEditor`, `HeadlessEditorPreset`, `NotesEditor`
32
- - Preset builder helpers: `extensivePreset`, `createExtensivePreset`, `presetRegistry`
33
- - Extension composition helpers: `createExtensiveExtensions`, `extensiveExtensions`
34
- - Feature flag helpers: `resolveFeatureFlags`, `isFeatureEnabled`, `DEFAULT_FEATURE_FLAGS`
35
- - Core UI + command utilities: `Toolbar`, `FloatingToolbar`, `generateCommands`, `registerKeyboardShortcuts`, and more
36
- - Full headless passthrough namespace: `headless`
37
-
38
- ```tsx
39
- import { headless } from "@lyfie/luthor";
40
-
41
- const { createEditorSystem, richTextExtension, boldExtension } = headless;
42
- ```
43
-
44
- ## Preset Catalog
45
-
46
- - `ExtensiveEditor`: full-feature visual/jsonb preset.
47
- - `SimpleTextEditor`: plain-text locked preset.
48
- - `RichTextBoxEditor`: inline formatting + list preset with optional compact toolbar.
49
- - `ChatWindowEditor`: chat composer with send action row.
50
- - `EmailComposeEditor`: compose shell (To/CC/BCC/Subject) + rich body.
51
- - `MDTextEditor`: visual/markdown mode switching.
52
- - `NotionLikeEditor`: slash-first + draggable defaults.
53
- - `HeadlessEditorPreset`: minimal plain-control reference.
54
- - `NotesEditor`: note-taking shell with title/actions callbacks.
55
-
56
- ## ExtensiveEditor API
57
-
58
- ### Props
59
-
60
- | Prop | Type | Default | Notes |
61
- |---|---|---|---|
62
- | `className` | `string` | `undefined` | Appended to wrapper root. |
63
- | `variantClassName` | `string` | `undefined` | Extra preset variant class on wrapper. |
64
- | `onReady` | `(methods: ExtensiveEditorRef) => void` | `undefined` | Called when editor methods are ready. |
65
- | `initialTheme` | `"light" \| "dark"` | `"light"` | Initial visual theme mode. |
66
- | `theme` | `Partial<LuthorTheme>` | `undefined` | Theme class/style overrides merged with default theme. |
67
- | `defaultContent` | `string` | `undefined` | If provided, injected as initial content (JSON parsed or plain text converted to JSONB). |
68
- | `showDefaultContent` | `boolean` | `true` | If `true` and `defaultContent` is not provided, loads built-in welcome content. |
69
- | `placeholder` | `string \| { visual?: string; jsonb?: string }` | `"Write anything..."` | String applies to visual mode; object lets you set visual and JSONB placeholders separately. |
70
- | `initialMode` | `"visual" \| "jsonb"` | `"visual"` | Initial open mode; clamped to `availableModes`. |
71
- | `availableModes` | `readonly ("visual" \| "jsonb")[]` | `["visual", "jsonb"]` | Visible mode tabs and allowed switching targets. |
72
- | `toolbarLayout` | `ToolbarLayout` | `TRADITIONAL_TOOLBAR_LAYOUT` | Custom toolbar sections/items order. |
73
- | `toolbarVisibility` | `Partial<Record<ToolbarItemType, boolean>>` | `undefined` | Per-item hide/show map. Unsupported items are auto-hidden. |
74
- | `toolbarPosition` | `"top" \| "bottom"` | `"top"` | Renders toolbar above or below visual editor. |
75
- | `toolbarAlignment` | `"left" \| "center" \| "right"` | `"left"` | Horizontal toolbar alignment class. |
76
- | `toolbarClassName` | `string` | `undefined` | Extra class for toolbar root (`.luthor-toolbar`). |
77
- | `toolbarStyleVars` | `ToolbarStyleVars` | `undefined` | Inline `--luthor-toolbar-*` CSS variable overrides. |
78
- | `isToolbarEnabled` | `boolean` | `true` | Hides toolbar UI only; keyboard/commands still exist unless feature-flagged off. |
79
- | `quoteClassName` | `string` | `undefined` | Appended to quote node class. |
80
- | `quoteStyleVars` | `QuoteStyleVars` | `undefined` | Inline `--luthor-quote-*` CSS variable overrides. |
81
- | `defaultSettings` | `DefaultSettings` | `undefined` | High-level style token API for common color settings. |
82
- | `editorThemeOverrides` | `LuthorEditorThemeOverrides` | `undefined` | Inline editor-wide `--luthor-*` token overrides. |
83
- | `fontFamilyOptions` | `readonly FontFamilyOption[]` | preset defaults | Sanitized: duplicates removed, invalid tokens removed, `default` auto-added if missing. |
84
- | `fontSizeOptions` | `readonly FontSizeOption[]` | preset defaults | Sanitized similarly to font family options. |
85
- | `minimumDefaultLineHeight` | `string \| number` | `1.5` | Sets the editor default line height and the minimum selectable/accepted line-height floor for the line-height feature; minimum accepted value is `1.0`. |
86
- | `lineHeightOptions` | `readonly LineHeightOption[]` | preset defaults | Uses unitless ratios (`"1.5"`) for non-default values; minimum allowed is `1.0`. |
87
- | `scaleByRatio` | `boolean` | `false` | Image resize behavior (`true` = keep ratio by default, Shift unlocks). |
88
- | `headingOptions` | `readonly ("h1"\|"h2"\|"h3"\|"h4"\|"h5"\|"h6")[]` | all headings | Invalid/duplicate entries are removed. |
89
- | `paragraphLabel` | `string` | `"Paragraph"` behavior | Label for paragraph entry in block format menu/commands. |
90
- | `syncHeadingOptionsWithCommands` | `boolean` | `true` | Syncs heading command generation with `headingOptions`. |
91
- | `slashCommandVisibility` | `SlashCommandVisibility` | `undefined` | Slash command filter using allowlist/denylist or enabled-ID selection array form. |
92
- | `shortcutConfig` | `ShortcutConfig` | `undefined` | Per-instance command shortcut config (disable/remap, collision and native conflict prevention). |
93
- | `commandPaletteShortcutOnly` | `boolean` | `false` | When `true`, command palette only shows commands that have a visible keyboard shortcut. |
94
- | `isDraggableBoxEnabled` | `boolean` | `undefined` | Shortcut for enabling/disabling draggable block UI (maps into `featureFlags.draggableBlock`). |
95
- | `featureFlags` | `Partial<Record<FeatureFlag, boolean>>` | all `true` | Central capability switchboard; affects extensions, toolbar, commands, shortcuts. |
96
- | `syntaxHighlighting` | `"auto" \| "disabled"` | extension default (`"auto"`) | Code block syntax highlighting strategy. |
97
- | `codeHighlightProvider` | `CodeHighlightProvider \| null` | `undefined` | Injected highlight provider instance. |
98
- | `loadCodeHighlightProvider` | `() => Promise<CodeHighlightProvider \| null>` | `undefined` | Lazy async provider loader. |
99
- | `maxAutoDetectCodeLength` | `number` | `12000` in code intelligence extension | Guard for auto language detection input size. |
100
- | `isCopyAllowed` | `boolean` | `true` | Enables/disables code block copy button and command path. |
101
- | `languageOptions` | `readonly string[] \| { mode?: "append"\|"replace"; values: readonly string[] }` | default language catalog | Controls visible code language options. |
102
-
103
- ### Ref Methods
22
+ ## Docs
104
23
 
105
- ```ts
106
- type ExtensiveEditorRef = {
107
- injectJSONB: (content: string) => void;
108
- getJSONB: () => string;
109
- };
110
- ```
111
-
112
- ## Valid Argument Sets
113
-
114
- ### `ToolbarItemType`
115
-
116
- `"fontFamily"`, `"fontSize"`, `"lineHeight"`, `"textColor"`, `"textHighlight"`, `"bold"`, `"italic"`, `"underline"`, `"strikethrough"`, `"subscript"`, `"superscript"`, `"code"`, `"link"`, `"blockFormat"`, `"quote"`, `"alignLeft"`, `"alignCenter"`, `"alignRight"`, `"alignJustify"`, `"codeBlock"`, `"unorderedList"`, `"orderedList"`, `"checkList"`, `"indentList"`, `"outdentList"`, `"horizontalRule"`, `"table"`, `"image"`, `"emoji"`, `"embed"`, `"undo"`, `"redo"`, `"commandPalette"`, `"themeToggle"`.
117
-
118
- ### `FeatureFlag`
119
-
120
- `"bold"`, `"italic"`, `"underline"`, `"strikethrough"`, `"fontFamily"`, `"fontSize"`, `"lineHeight"`, `"textColor"`, `"textHighlight"`, `"subscript"`, `"superscript"`, `"link"`, `"horizontalRule"`, `"table"`, `"list"`, `"history"`, `"image"`, `"blockFormat"`, `"code"`, `"codeIntelligence"`, `"codeFormat"`, `"tabIndent"`, `"enterKeyBehavior"`, `"iframeEmbed"`, `"youTubeEmbed"`, `"floatingToolbar"`, `"contextMenu"`, `"commandPalette"`, `"slashCommand"`, `"emoji"`, `"draggableBlock"`, `"customNode"`, `"themeToggle"`.
121
-
122
- ## Usage Recipes
123
-
124
- ### 1) Minimal with defaults
125
-
126
- ```tsx
127
- import { ExtensiveEditor } from "@lyfie/luthor";
128
- import "@lyfie/luthor/styles.css";
129
-
130
- export function App() {
131
- return <ExtensiveEditor />;
132
- }
133
- ```
134
-
135
- ### 2) Placeholder per mode + restricted modes
136
-
137
- ```tsx
138
- <ExtensiveEditor
139
- initialMode="visual"
140
- availableModes={["visual", "jsonb"]}
141
- placeholder={{
142
- visual: "Write release notes...",
143
- jsonb: "Paste JSONB...",
144
- }}
145
- />
146
- ```
147
-
148
- ### 3) Feature-gated editor (product tiers)
149
-
150
- ```tsx
151
- <ExtensiveEditor
152
- featureFlags={{
153
- image: false,
154
- iframeEmbed: false,
155
- youTubeEmbed: false,
156
- emoji: false,
157
- commandPalette: false,
158
- }}
159
- toolbarVisibility={{
160
- embed: false,
161
- image: false,
162
- emoji: false,
163
- }}
164
- />
165
- ```
166
-
167
- ### 4) Slash command allowlist
168
-
169
- ```tsx
170
- <ExtensiveEditor
171
- slashCommandVisibility={{
172
- allowlist: [
173
- "block.paragraph",
174
- "block.heading1",
175
- "block.heading2",
176
- "insert.table",
177
- ],
178
- denylist: ["insert.image"],
179
- }}
180
- />
181
- ```
182
-
183
- ### 5) Code language list replacement
184
-
185
- ```tsx
186
- <ExtensiveEditor
187
- languageOptions={{
188
- mode: "replace",
189
- values: ["plaintext", "typescript", "javascript", "markdown", "sql"],
190
- }}
191
- syntaxHighlighting="auto"
192
- maxAutoDetectCodeLength={10000}
193
- />
194
- ```
195
-
196
- Optional: use highlight.js stylesheet for richer code colors
197
-
198
- ```bash
199
- pnpm add highlight.js
200
- ```
201
-
202
- ```tsx
203
- import { ExtensiveEditor } from "@lyfie/luthor";
204
- import "@lyfie/luthor/styles.css";
205
- import "highlight.js/styles/github.css"; // any highlight.js theme
206
-
207
- export function App() {
208
- return <ExtensiveEditor syntaxHighlighting="auto" />;
209
- }
210
- ```
211
-
212
- What happens:
213
-
214
- - Luthor does not auto-detect code language anymore. Language comes from the selected code language option.
215
- - Language options are normalized through Lexical/Prism aliases (`md` -> `markdown`, `js` -> `javascript` family, `ts` -> `typescript`).
216
- - Only Prism-supported loaded languages are accepted. Unsupported values (for example `yaml` without Prism YAML grammar loaded) fall back to plain text.
217
- - `plaintext` uses plain fallback syntax styling.
218
- - Non-plaintext languages emit `hljs-*` token classes.
219
- - If a highlight.js stylesheet is loaded, those `hljs-*` tokens use highlight.js colors.
220
- - Without highlight.js stylesheet, code uses the built-in muted/plain fallback.
221
-
222
- ### 6) Per-instance shortcut remap/disable
223
-
224
- ```tsx
225
- <ExtensiveEditor
226
- shortcutConfig={{
227
- disabledCommandIds: ["format.italic"],
228
- bindings: {
229
- "format.bold": { key: "m", ctrlKey: true },
230
- "palette.show": [
231
- { key: "k", ctrlKey: true, shiftKey: true },
232
- ],
233
- },
234
- }}
235
- />
236
- ```
237
-
238
- ### 7) Command palette shortcut-only mode
239
-
240
- ```tsx
241
- <ExtensiveEditor commandPaletteShortcutOnly />
242
- ```
243
-
244
- ### 8) Style token overrides
245
-
246
- ```tsx
247
- <ExtensiveEditor
248
- editorThemeOverrides={{
249
- "--luthor-bg": "#fffaf2",
250
- "--luthor-fg": "#431407",
251
- "--luthor-accent": "#c2410c",
252
- }}
253
- toolbarStyleVars={{
254
- "--luthor-toolbar-button-active-bg": "#ea580c",
255
- "--luthor-toolbar-button-active-fg": "#ffffff",
256
- }}
257
- quoteStyleVars={{
258
- "--luthor-quote-bg": "#fff7ed",
259
- "--luthor-quote-fg": "#7c2d12",
260
- "--luthor-quote-border": "#ea580c",
261
- }}
262
- />
263
- ```
264
-
265
- ### 9) Emoji library auto-detection (works in `apps/demo`)
266
-
267
- Install emoji-mart data in the app:
268
-
269
- ```bash
270
- pnpm add -F demo @emoji-mart/data
271
- ```
272
-
273
- Then use `ExtensiveEditor` normally:
274
-
275
- ```tsx
276
- import { ExtensiveEditor } from "@lyfie/luthor";
277
- import "@lyfie/luthor/styles.css";
278
-
279
- export function App() {
280
- return <ExtensiveEditor />;
281
- }
282
- ```
283
-
284
- What happens:
285
-
286
- - `:shortcode` suggestions and resolution use the detected emoji-mart dataset.
287
- - Emoji toolbar dropdown uses the detected emoji-mart catalog.
288
- - If the library is not installed/available, it automatically falls back to the built-in emoji list.
289
-
290
- ## Notes and Nuances
291
-
292
- - `featureFlags` are authoritative. If a feature is disabled, related toolbar items and commands are removed/no-op even if you attempt to show them.
293
- - `slashCommandVisibility` keeps original command ordering; it only filters visibility.
294
- - `shortcutConfig.disabledCommandIds` removes commands from keyboard handling and command UIs for that editor instance.
295
- - `shortcutConfig` drops duplicate bindings by default and blocks native editable conflicts by default.
296
- - `commandPaletteShortcutOnly` is optional; by default command palette can include command items without shortcuts.
297
- - `languageOptions` normalizes aliases (for example `js` becomes `javascript`) and rejects duplicates after normalization.
298
- - Emoji suggestions/tooling auto-detect external emoji-mart data when available, and otherwise use the built-in default emoji catalog.
299
- - `defaultSettings` is style-only; behavior is controlled by explicit props (for example `featureFlags`, `availableModes`).
300
- - `isToolbarEnabled={false}` hides toolbar UI, but editor shortcuts/features still work unless disabled via `featureFlags`.
301
-
302
- ## Which Package Should I Use?
303
-
304
- - Use `@lyfie/luthor` for fast onboarding and polished defaults.
305
- - Use `@lyfie/luthor-headless` for full extension/UI control.
306
-
307
- ## Documentation
308
-
309
- - Monorepo docs index: [../../documentation/index.md](../../documentation/index.md)
310
- - Headless package README: [../headless/README.md](../headless/README.md)
311
- - User docs: [../../documentation/user/luthor/getting-started.md](../../documentation/user/luthor/getting-started.md)
312
- - Developer docs: [../../documentation/developer/luthor/architecture.md](../../documentation/developer/luthor/architecture.md)
313
-
314
- ## Workspace Development
315
-
316
- ```bash
317
- pnpm --filter @lyfie/luthor dev
318
- pnpm --filter @lyfie/luthor build
319
- pnpm --filter @lyfie/luthor lint
320
- ```
24
+ - https://luthor-editor.vercel.app/docs/getting-started/luthor/
25
+ - https://luthor-editor.vercel.app/docs/luthor/presets/