@ecsplico/editor 1.0.0 → 2.0.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/CHANGELOG.md +19 -0
- package/README.md +3 -4
- package/dist/core/notify.d.ts +1 -1
- package/dist/core/notify.js.map +1 -1
- package/dist/i18n/de/common.js +1 -2
- package/dist/i18n/de/common.js.map +1 -1
- package/dist/i18n/de.d.ts +0 -1
- package/dist/i18n/en/common.js +1 -2
- package/dist/i18n/en/common.js.map +1 -1
- package/dist/nuxt/module.d.ts +0 -6
- package/dist/nuxt/module.js +3 -5
- package/dist/nuxt/module.js.map +1 -1
- package/dist/nuxt/runtime/install-context.d.ts +2 -3
- package/dist/nuxt/runtime/install-context.js +2 -3
- package/dist/nuxt/runtime/install-context.js.map +1 -1
- package/dist/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts +1 -1
- package/dist/react/styles/ui-vars.css +2 -2
- package/dist/styles/ai.css +1 -1
- package/dist/styles/authors.css +1 -1
- package/dist/styles/block-ui.css +1 -1
- package/dist/styles/collab.css +1 -1
- package/dist/styles/comments.css +1 -1
- package/dist/styles/core.css +2 -2
- package/dist/styles/media.css +1 -1
- package/dist/styles/mentions.css +1 -1
- package/dist/styles/themes.css +1 -1
- package/dist/styles/transcript.css +1 -1
- package/dist/vue/context.d.ts +3 -3
- package/dist/vue/context.js +3 -2
- package/dist/vue/context.js.map +1 -1
- package/dist/vue/kit/types.d.ts +1 -1
- package/dist/vue/kit/use-ui-kit.d.ts +2 -2
- package/dist/vue/kit/use-ui-kit.js +3 -3
- package/dist/vue/kit/use-ui-kit.js.map +1 -1
- package/docs/integration.md +1 -1
- package/docs/llms.md +1 -1
- package/package.json +4 -19
- package/dist/nuxt/runtime/plugins/editor-context-primevue.client.ts +0 -8
- package/dist/vue/kit/primevue/Alert.js +0 -49
- package/dist/vue/kit/primevue/Alert.js.map +0 -1
- package/dist/vue/kit/primevue/Avatar.js +0 -54
- package/dist/vue/kit/primevue/Avatar.js.map +0 -1
- package/dist/vue/kit/primevue/Badge.js +0 -41
- package/dist/vue/kit/primevue/Badge.js.map +0 -1
- package/dist/vue/kit/primevue/Button.js +0 -112
- package/dist/vue/kit/primevue/Button.js.map +0 -1
- package/dist/vue/kit/primevue/Chip.js +0 -38
- package/dist/vue/kit/primevue/Chip.js.map +0 -1
- package/dist/vue/kit/primevue/DropdownMenu.js +0 -98
- package/dist/vue/kit/primevue/DropdownMenu.js.map +0 -1
- package/dist/vue/kit/primevue/FieldGroup.js +0 -22
- package/dist/vue/kit/primevue/FieldGroup.js.map +0 -1
- package/dist/vue/kit/primevue/FormField.js +0 -56
- package/dist/vue/kit/primevue/FormField.js.map +0 -1
- package/dist/vue/kit/primevue/Icon.js +0 -23
- package/dist/vue/kit/primevue/Icon.js.map +0 -1
- package/dist/vue/kit/primevue/Input.js +0 -96
- package/dist/vue/kit/primevue/Input.js.map +0 -1
- package/dist/vue/kit/primevue/InputMenu.js +0 -122
- package/dist/vue/kit/primevue/InputMenu.js.map +0 -1
- package/dist/vue/kit/primevue/Modal.js +0 -59
- package/dist/vue/kit/primevue/Modal.js.map +0 -1
- package/dist/vue/kit/primevue/Popover.js +0 -135
- package/dist/vue/kit/primevue/Popover.js.map +0 -1
- package/dist/vue/kit/primevue/RadioGroup.js +0 -58
- package/dist/vue/kit/primevue/RadioGroup.js.map +0 -1
- package/dist/vue/kit/primevue/Select.js +0 -68
- package/dist/vue/kit/primevue/Select.js.map +0 -1
- package/dist/vue/kit/primevue/SelectMenu.js +0 -94
- package/dist/vue/kit/primevue/SelectMenu.js.map +0 -1
- package/dist/vue/kit/primevue/Separator.js +0 -16
- package/dist/vue/kit/primevue/Separator.js.map +0 -1
- package/dist/vue/kit/primevue/Switch.js +0 -46
- package/dist/vue/kit/primevue/Switch.js.map +0 -1
- package/dist/vue/kit/primevue/Table.js +0 -54
- package/dist/vue/kit/primevue/Table.js.map +0 -1
- package/dist/vue/kit/primevue/Tabs.js +0 -49
- package/dist/vue/kit/primevue/Tabs.js.map +0 -1
- package/dist/vue/kit/primevue/Textarea.js +0 -55
- package/dist/vue/kit/primevue/Textarea.js.map +0 -1
- package/dist/vue/kit/primevue/Tooltip.js +0 -43
- package/dist/vue/kit/primevue/Tooltip.js.map +0 -1
- package/dist/vue/kit/primevue/Tree.js +0 -75
- package/dist/vue/kit/primevue/Tree.js.map +0 -1
- package/dist/vue/kit/primevue/select-options.js +0 -55
- package/dist/vue/kit/primevue/select-options.js.map +0 -1
- package/dist/vue/kit/primevue/shared.js +0 -49
- package/dist/vue/kit/primevue/shared.js.map +0 -1
- package/dist/vue/kit/primevue/trigger.js +0 -25
- package/dist/vue/kit/primevue/trigger.js.map +0 -1
- package/dist/vue/kit/primevue.css +0 -86
- package/dist/vue/kit/primevue.d.ts +0 -33
- package/dist/vue/kit/primevue.js +0 -96
- package/dist/vue/kit/primevue.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Removed (breaking)
|
|
6
|
+
|
|
7
|
+
- The PrimeVue kit: `@ecsplico/editor/vue/kit/primevue` (`primeVueKit()`) and the stylesheet `@ecsplico/editor/vue/kit/primevue.css`. The Vue binding renders through Nuxt UI only; hosts that used `primeVueKit()` move to `nuxtUiKit()` (`@ecsplico/editor/vue/kit/nuxt-ui`) and import `@ecsplico/editor/vue/kit/nuxt-ui.css`.
|
|
8
|
+
- The Nuxt module option `kit` (`tiptapEditor: { kit: 'nuxt-ui' | 'primevue' }`). The module always adds `vue/kit/nuxt-ui.css`, patches Nuxt UI's `ui.css` so Tailwind scans the package and registers the Nuxt UI context plugin; `@nuxt/ui` must be registered before it.
|
|
9
|
+
- The peer dependency `primevue` (and its optional peer metadata).
|
|
10
|
+
- The `advanced-primevue` bundle-isolation fixture and the `examples/vue-primevue` example.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `createEditor({ kit })`: `kit` is optional and defaults to `nuxtUiKit()`. `app.use(createEditor())` is enough; pass a `VueUiKit` only to render the chrome with another library.
|
|
15
|
+
- React: `react/styles/ui-vars.css` sets `--sk-success` from `--color-success` (the `@skaile/brand` token), falling back to the former `oklch(0.72 0.19 150)`.
|
|
16
|
+
|
|
17
|
+
## 1.0.0
|
|
18
|
+
|
|
19
|
+
First release on npmjs as `@ecsplico/editor` (Vue: Nuxt UI or PrimeVue kit; React: shadcn/ui; optional React and Vue peers).
|
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ Every entry is an explicit subpath of `package.json#exports`; there is no wildca
|
|
|
137
137
|
| `@ecsplico/editor/server`, `/server/handlers`, `/server/node`, `/nuxt` | Server side without a web framework: `createCollabServer`, `createAiModels`, `createRateLimiter`, `EditorAdapter`, one request handler per route (`/server/handlers`), `listenCollab` for a plain Node script (`/server/node`); the Nitro registry `setEditorAdapter`, `forgetCollabDocument`, `liveContent`, `collabStats`; the Nuxt module (config key `tiptapEditor`) wraps the same core. See the [integration guide](./docs/integration.md) |
|
|
138
138
|
| `@ecsplico/editor/styles/core.css` (required), `/composites.css`, `/media.css`, `/mentions.css`, `/tables.css`, `/authors.css`, `/comments.css`, `/transcript.css`, `/ai.css`, `/collab.css`, `/block-ui.css`, `/themes.css` | Feature CSS (import after Tailwind, Nuxt UI (Vue) or `ui-vars.css` (React) and `core.css`; `themes.css` after the feature sheets). The Nuxt module adds all of them itself |
|
|
139
139
|
|
|
140
|
-
Nuxt apps use the same entries; the Nuxt client plugin (`src/nuxt/runtime/plugins/editor-context
|
|
140
|
+
Nuxt apps use the same entries; the Nuxt client plugin (`src/nuxt/runtime/plugins/editor-context-nuxt-ui.client.ts`) installs the editor context with account-synced settings.
|
|
141
141
|
|
|
142
142
|
## Presets and features
|
|
143
143
|
|
|
@@ -167,9 +167,9 @@ Settings are stored as one inert, versioned JSON object shared by all editors of
|
|
|
167
167
|
|
|
168
168
|
## CSS and UI-provider requirements
|
|
169
169
|
|
|
170
|
-
- Design tokens: `@ecsplico/editor/styles/tokens.css` declares the shared `--sk-*` variables (`--sk-bg`, `--sk-fg`, `--sk-muted`, `--sk-border`, `--sk-primary`, `--sk-primary-fg`, `--sk-success`, `--sk-warning`, `--sk-danger`, `--sk-radius`, `--sk-font`) with light defaults under `:where(:root)` and dark values under `:where(.dark)`. Every feature stylesheet reads them; a UI kit maps them onto its own variables (Nuxt UI: `vue/kit/nuxt-ui.css`,
|
|
170
|
+
- Design tokens: `@ecsplico/editor/styles/tokens.css` declares the shared `--sk-*` variables (`--sk-bg`, `--sk-fg`, `--sk-muted`, `--sk-border`, `--sk-primary`, `--sk-primary-fg`, `--sk-success`, `--sk-warning`, `--sk-danger`, `--sk-radius`, `--sk-font`) with light defaults under `:where(:root)` and dark values under `:where(.dark)`. Every feature stylesheet reads them; a UI kit maps them onto its own variables (Nuxt UI: `vue/kit/nuxt-ui.css`, React/shadcn: `react/styles/ui-vars.css`), a host may override them once.
|
|
171
171
|
|
|
172
|
-
- Vue UI kit: the Vue chrome renders through the kit handed to `createEditor({ kit })
|
|
172
|
+
- Vue UI kit: the Vue binding is built on Nuxt UI. The chrome renders through the kit handed to `createEditor({ kit })`; `kit` is optional and defaults to `nuxtUiKit()` (`@ecsplico/editor/vue/kit/nuxt-ui`, needs `@nuxt/ui`, stylesheet `@ecsplico/editor/vue/kit/nuxt-ui.css`). `@ecsplico/editor/vue/kit` holds the `VueUiKit` contract and `useUiKit()`; pass your own `VueUiKit` only to render the chrome with another library. Only the `nuxt-ui` kit entry imports `@nuxt/ui`. The Nuxt module has no `kit` option: it always adds `vue/kit/nuxt-ui.css`, patches Nuxt UI's `ui.css` so Tailwind scans the package (`@nuxt/ui` must be registered before the module) and installs the Nuxt UI context plugin.
|
|
173
173
|
|
|
174
174
|
- Import the core CSS **after** Tailwind and Nuxt UI, and let Tailwind see the library's classes:
|
|
175
175
|
|
|
@@ -208,7 +208,6 @@ bun run --cwd examples/react-simple dev # http://localhost:3041
|
|
|
208
208
|
bun run --cwd examples/react-simple typecheck
|
|
209
209
|
bun run --cwd examples/react-advanced dev # http://localhost:3043, needs `bun run dev` (Nuxt host, port 3031)
|
|
210
210
|
bun run --cwd examples/react-advanced typecheck
|
|
211
|
-
bun run --cwd examples/vue-primevue dev # http://localhost:3044, the Vue surface on primeVueKit() (no Nuxt UI)
|
|
212
211
|
bun run --cwd examples/vue-markdown dev # http://localhost:3045, MarkdownSurface with frontmatter, tables and source mode
|
|
213
212
|
bun run typecheck:editor # vue-tsc --noEmit -p packages/editor/tsconfig.json (no Nuxt globals)
|
|
214
213
|
bun run check:editor-entries # production build per fixture, module-graph isolation rules
|
package/dist/core/notify.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/core/notify.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* A user-facing notice (toast). The framework layer renders it: the UI kit's notifier on the Vue surface (Nuxt UI
|
|
4
|
-
* `useToast
|
|
4
|
+
* `useToast`; `kind` maps to the kit's colour/severity), sonner on the React surface. `id` deduplicates: a notice with the id of a visible one replaces it.
|
|
5
5
|
*/
|
|
6
6
|
export interface Notice {
|
|
7
7
|
id?: string;
|
package/dist/core/notify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.js","names":[],"sources":["../../src/core/notify.ts"],"sourcesContent":["/**\n * A user-facing notice (toast). The framework layer renders it: the UI kit's notifier on the Vue surface (Nuxt UI\n * `useToast
|
|
1
|
+
{"version":3,"file":"notify.js","names":[],"sources":["../../src/core/notify.ts"],"sourcesContent":["/**\n * A user-facing notice (toast). The framework layer renders it: the UI kit's notifier on the Vue surface (Nuxt UI\n * `useToast`; `kind` maps to the kit's colour/severity), sonner on the React surface. `id` deduplicates: a notice with the id of a visible one replaces it.\n */\nexport interface Notice {\n id?: string\n title: string\n description?: string\n kind?: 'info' | 'success' | 'warning' | 'error'\n /** Iconify name (`i-lucide-…`). */\n icon?: string\n /** Milliseconds until it closes; 0 keeps it until a notice with the same `id` replaces it. Default: the framework's. */\n duration?: number\n /** One button on the notice (e.g. „Rückgängig“); activating it also closes the notice. */\n action?: { label: string, onClick: () => void }\n}\n\n/**\n * Shows a notice; features reach it through `FeatureContext.notify`, app-level models through `EditorContext.notify`.\n * `dismiss(id)` closes the visible notice with that id (a persistent `duration: 0` progress notice); absent on notifiers that cannot.\n */\nexport type Notifier = ((notice: Notice) => void) & { dismiss?: (id: string) => void }\n\n/** Drops every notice: the default of headless contexts. */\nexport const silentNotifier: Notifier = () => {}\n"],"mappings":";;AAwBA,MAAa,uBAAiC,CAAC"}
|
package/dist/i18n/de/common.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../../src/i18n/de/common.ts"],"sourcesContent":["export const de = {\n 'common.loading': 'Lädt …',\n 'common.close': 'Schließen',\n 'slash.empty': 'Kein Befehl gefunden',\n
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../src/i18n/de/common.ts"],"sourcesContent":["export const de = {\n 'common.loading': 'Lädt …',\n 'common.close': 'Schließen',\n 'slash.empty': 'Kein Befehl gefunden',\n} as const\n"],"mappings":";AAAA,MAAa,KAAK;CAChB,kBAAkB;CAClB,gBAAgB;CAChB,eAAe;AACjB"}
|
package/dist/i18n/de.d.ts
CHANGED
|
@@ -497,7 +497,6 @@ export declare const de: {
|
|
|
497
497
|
readonly 'common.loading': "Lädt …";
|
|
498
498
|
readonly 'common.close': "Schließen";
|
|
499
499
|
readonly 'slash.empty': "Kein Befehl gefunden";
|
|
500
|
-
readonly 'common.createItem': "„{value}“ erstellen";
|
|
501
500
|
};
|
|
502
501
|
//#endregion
|
|
503
502
|
//# sourceMappingURL=de.d.ts.map
|
package/dist/i18n/en/common.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../../src/i18n/en/common.ts"],"sourcesContent":["import type { de } from '../de/common'\n\nexport const en: { [K in keyof typeof de]: string } = {\n 'common.loading': 'Loading …',\n 'common.close': 'Close',\n 'slash.empty': 'No command found',\n
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../src/i18n/en/common.ts"],"sourcesContent":["import type { de } from '../de/common'\n\nexport const en: { [K in keyof typeof de]: string } = {\n 'common.loading': 'Loading …',\n 'common.close': 'Close',\n 'slash.empty': 'No command found',\n}\n"],"mappings":";AAEA,MAAa,KAAyC;CACpD,kBAAkB;CAClB,gBAAgB;CAChB,eAAe;AACjB"}
|
package/dist/nuxt/module.d.ts
CHANGED
|
@@ -3,12 +3,6 @@ import { ModelSlot } from "../settings/values.js";
|
|
|
3
3
|
import "../settings/index.js";
|
|
4
4
|
//#region src/nuxt/module.d.ts
|
|
5
5
|
export interface ModuleOptions {
|
|
6
|
-
/**
|
|
7
|
-
* The UI kit that renders the editor chrome. `'nuxt-ui'` (default): Nuxt UI, which must be registered before this
|
|
8
|
-
* module (its generated `ui.css` is patched so Tailwind scans the package). `'primevue'`: PrimeVue; the host installs
|
|
9
|
-
* PrimeVue (`app.use(PrimeVue, …)`, `ToastService`), mounts `<Toast />` and lets Tailwind scan the package.
|
|
10
|
-
*/
|
|
11
|
-
kit: 'nuxt-ui' | 'primevue';
|
|
12
6
|
/** Language of the editor's strings: `'de'` (default) or `'en'`. Set once per app; a host that switches languages at run time recreates the editor context. */
|
|
13
7
|
locale: Locale;
|
|
14
8
|
/** Overrides of single messages by key (see `MessageKey`), applied on top of the catalog of `locale`; must be JSON-serialisable. */
|
package/dist/nuxt/module.js
CHANGED
|
@@ -12,7 +12,6 @@ var module_default = defineNuxtModule({
|
|
|
12
12
|
configKey: "tiptapEditor"
|
|
13
13
|
},
|
|
14
14
|
defaults: {
|
|
15
|
-
kit: "nuxt-ui",
|
|
16
15
|
locale: "de",
|
|
17
16
|
collab: { authenticateUpgrade: false },
|
|
18
17
|
ai: {
|
|
@@ -43,14 +42,14 @@ var module_default = defineNuxtModule({
|
|
|
43
42
|
const { resolve } = createResolver(import.meta.url);
|
|
44
43
|
const packageSrc = resolve("..");
|
|
45
44
|
nuxt.options.build.transpile.push(packageSrc);
|
|
46
|
-
nuxt.options.css.push(resolve(
|
|
45
|
+
nuxt.options.css.push(resolve("../vue/kit/nuxt-ui.css"));
|
|
47
46
|
nuxt.options.css.push(resolve("../styles/core.css"), resolve("../styles/media.css"), resolve("../styles/mentions.css"), resolve("../styles/authors.css"), resolve("../styles/comments.css"), resolve("../styles/transcript.css"), resolve("../styles/composites.css"), resolve("../styles/ai.css"), resolve("../styles/collab.css"), resolve("../styles/block-ui.css"), resolve("../styles/themes.css"));
|
|
48
47
|
addPlugin({
|
|
49
|
-
src: resolve(
|
|
48
|
+
src: resolve("./runtime/plugins/editor-context-nuxt-ui.client.ts"),
|
|
50
49
|
mode: "client"
|
|
51
50
|
});
|
|
52
51
|
addServerScanDir(resolve("./runtime/server"));
|
|
53
|
-
|
|
52
|
+
nuxt.hook("modules:done", () => {
|
|
54
53
|
const uiCss = nuxt.options.build.templates.find((t) => t.filename === "ui.css");
|
|
55
54
|
if (!uiCss?.getContents) throw new Error("tiptap-editor: @nuxt/ui muss vor diesem Modul registriert sein (ui.css-Template fehlt)");
|
|
56
55
|
const getContents = uiCss.getContents;
|
|
@@ -86,7 +85,6 @@ var module_default = defineNuxtModule({
|
|
|
86
85
|
...nuxt.options.runtimeConfig.tiptapEditor
|
|
87
86
|
};
|
|
88
87
|
nuxt.options.runtimeConfig.public.tiptapEditor = {
|
|
89
|
-
kit: options.kit,
|
|
90
88
|
locale: options.locale,
|
|
91
89
|
...options.messages && { messages: options.messages },
|
|
92
90
|
ai: {
|
package/dist/nuxt/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","names":[],"sources":["../../src/nuxt/module.ts"],"sourcesContent":["import { addPlugin, addServerScanDir, createResolver, defineNuxtModule } from 'nuxt/kit'\nimport type { Locale, Messages } from '../i18n'\nimport type { ModelSlot } from '../settings'\n\nexport interface ModuleOptions {\n
|
|
1
|
+
{"version":3,"file":"module.js","names":[],"sources":["../../src/nuxt/module.ts"],"sourcesContent":["import { addPlugin, addServerScanDir, createResolver, defineNuxtModule } from 'nuxt/kit'\nimport type { Locale, Messages } from '../i18n'\nimport type { ModelSlot } from '../settings'\n\nexport interface ModuleOptions {\n /** Language of the editor's strings: `'de'` (default) or `'en'`. Set once per app; a host that switches languages at run time recreates the editor context. */\n locale: Locale\n /** Overrides of single messages by key (see `MessageKey`), applied on top of the catalog of `locale`; must be JSON-serialisable. */\n messages?: Partial<Messages>\n ai: {\n /**\n * Server-defined model presets (any OpenAI-compatible chat completions endpoint), keyed by preset id. The key is\n * per preset or the shared `apiKey`, both from env only: `NUXT_TIPTAP_EDITOR_AI_PRESETS_<ID>_API_KEY` (`<ID>` = the\n * preset id in upper snake case, e.g. `flashLite` → `FLASH_LITE`) or `NUXT_TIPTAP_EDITOR_AI_API_KEY`. Preset ids\n * must be camelCase so the env names map onto them.\n */\n presets: Record<string, { label: string, endpoint: string, model: string, apiKey?: string }>\n /** Default preset per slot; users may override in settings. The `complete` model must support assistant prefill. */\n slots: Record<ModelSlot, string>\n /** Per-user limit shared by all AI endpoints: at most `max` requests per sliding `windowMs`. */\n rateLimit: { max: number, windowMs: number }\n /**\n * Speech-to-text for audio/video `document` composites: any OpenAI-compatible `<endpoint>/audio/transcriptions`\n * (e.g. OpenAI `whisper-1`; OpenRouter presets do not provide one). Absent = the action and the endpoint are off.\n * The key comes from env only: `NUXT_TIPTAP_EDITOR_AI_TRANSCRIPTION_API_KEY`.\n */\n transcription?: { endpoint: string, model: string, apiKey?: string }\n }\n collab: {\n /**\n * Authenticate the `/collab/:id` websocket upgrade itself (`EditorAdapter.authenticate` with the upgrade request's\n * headers) and refuse it with HTTP 401 for an unknown user. Default `false`: the upgrade always succeeds, the user\n * is authenticated afterwards from the headers or the provider's `token`, and an unauthenticated socket is closed\n * with code 4401. Enable only when every client authenticates by cookie/headers: a client that sends its identity\n * as `collaboration.token` (no cookies) cannot connect then. Env override:\n * `NUXT_TIPTAP_EDITOR_COLLAB_AUTHENTICATE_UPGRADE=true`.\n */\n authenticateUpgrade: boolean\n }\n}\n\n/**\n * Nuxt/Nitro integration of the editor package: the client context plugin (settings persistence, AI configuration),\n * the Nitro API routes, the collaboration websocket and the AI configuration with its server-only secrets. The host\n * plugs in through `setEditorAdapter()` (`@ecsplico/editor/server`) in a Nitro plugin (auth, loading and storing\n * document content). Components are imported explicitly from the package entries; nothing is auto-registered.\n */\nexport default defineNuxtModule<ModuleOptions>({\n meta: { name: 'tiptap-editor', configKey: 'tiptapEditor' },\n defaults: {\n locale: 'de',\n collab: { authenticateUpgrade: false },\n ai: {\n presets: {\n sonnet: { label: 'Claude Sonnet 4.5 (OpenRouter)', endpoint: 'https://openrouter.ai/api/v1', model: 'anthropic/claude-sonnet-4.5' },\n flashLite: { label: 'Gemini 2.5 Flash Lite (OpenRouter)', endpoint: 'https://openrouter.ai/api/v1', model: 'google/gemini-2.5-flash-lite' },\n },\n slots: { complete: 'flashLite', rewrite: 'sonnet', generate: 'sonnet' },\n rateLimit: { max: 30, windowMs: 60_000 },\n },\n },\n setup(options, nuxt) {\n const { resolve } = createResolver(import.meta.url)\n // `resolve('..')` is the package root of the built output (`dist`) or of `src` in this repository's app: both\n // hold the stylesheets and the unbundled `nuxt/runtime` files, which Nuxt compiles for the client and Nitro for the server.\n const packageSrc = resolve('..')\n nuxt.options.build.transpile.push(packageSrc)\n // The Nuxt UI token map comes first: the feature sheets (and an Obsidian theme, `themes.css`, last) read and may override `--sk-*`.\n nuxt.options.css.push(resolve('../vue/kit/nuxt-ui.css'))\n nuxt.options.css.push(\n resolve('../styles/core.css'),\n resolve('../styles/media.css'),\n resolve('../styles/mentions.css'),\n resolve('../styles/authors.css'),\n resolve('../styles/comments.css'),\n resolve('../styles/transcript.css'),\n resolve('../styles/composites.css'),\n resolve('../styles/ai.css'),\n resolve('../styles/collab.css'),\n resolve('../styles/block-ui.css'),\n resolve('../styles/themes.css'),\n )\n addPlugin({ src: resolve('./runtime/plugins/editor-context-nuxt-ui.client.ts'), mode: 'client' })\n addServerScanDir(resolve('./runtime/server'))\n // Tailwind only scans the app layers listed in Nuxt UI's generated `ui.css` (`@source \"<layer>/app/**/*\"`), so the\n // utility classes used by the package's components would never be generated. Append its source. `@nuxt/ui` must be\n // registered before this module.\n nuxt.hook('modules:done', () => {\n const uiCss = nuxt.options.build.templates.find(t => t.filename === 'ui.css')\n if (!uiCss?.getContents) throw new Error('tiptap-editor: @nuxt/ui muss vor diesem Modul registriert sein (ui.css-Template fehlt)')\n const getContents = uiCss.getContents\n uiCss.getContents = async data => `@source \"${packageSrc}/**/*\";\\n${await getContents(data)}`\n })\n nuxt.options.nitro.experimental = { ...nuxt.options.nitro.experimental, websocket: true }\n // Nitro bundles the package (the runtime files import `h3` and `nitropack/runtime`, which the host's Nitro resolves): never leave it external.\n nuxt.options.nitro.externals = { ...nuxt.options.nitro.externals, inline: [...(nuxt.options.nitro.externals?.inline ?? []), '@ecsplico/editor', packageSrc] }\n nuxt.options.runtimeConfig.tiptapEditor = {\n collab: { authenticateUpgrade: options.collab.authenticateUpgrade },\n ai: {\n apiKey: '',\n // Every preset gets an empty `apiKey`, so its env variable has a key to override.\n presets: Object.fromEntries(Object.entries(options.ai.presets).map(([id, preset]) => [id, { ...preset, apiKey: preset.apiKey ?? '' }])),\n slots: options.ai.slots,\n rateLimit: options.ai.rateLimit,\n // `apiKey` defaults to '' so its env variable has a key to override.\n ...(options.ai.transcription && { transcription: { ...options.ai.transcription, apiKey: options.ai.transcription.apiKey ?? '' } }),\n },\n ...(nuxt.options.runtimeConfig.tiptapEditor as object | undefined),\n }\n // Default slot presets for the client before `GET /api/ai/models` has answered; read by the client context plugin.\n nuxt.options.runtimeConfig.public.tiptapEditor = {\n locale: options.locale,\n ...(options.messages && { messages: options.messages }),\n ai: { slots: options.ai.slots, transcription: Boolean(options.ai.transcription) },\n ...(nuxt.options.runtimeConfig.public.tiptapEditor as object | undefined),\n }\n },\n})\n"],"mappings":";;;;;;;;AA+CA,IAAA,iBAAe,iBAAgC;CAC7C,MAAM;EAAE,MAAM;EAAiB,WAAW;CAAe;CACzD,UAAU;EACR,QAAQ;EACR,QAAQ,EAAE,qBAAqB,MAAM;EACrC,IAAI;GACF,SAAS;IACP,QAAQ;KAAE,OAAO;KAAkC,UAAU;KAAgC,OAAO;IAA8B;IAClI,WAAW;KAAE,OAAO;KAAsC,UAAU;KAAgC,OAAO;IAA+B;GAC5I;GACA,OAAO;IAAE,UAAU;IAAa,SAAS;IAAU,UAAU;GAAS;GACtE,WAAW;IAAE,KAAK;IAAI,UAAU;GAAO;EACzC;CACF;CACA,MAAM,SAAS,MAAM;EACnB,MAAM,EAAE,YAAY,eAAe,YAAY,GAAG;EAGlD,MAAM,aAAa,QAAQ,IAAI;EAC/B,KAAK,QAAQ,MAAM,UAAU,KAAK,UAAU;EAE5C,KAAK,QAAQ,IAAI,KAAK,QAAQ,wBAAwB,CAAC;EACvD,KAAK,QAAQ,IAAI,KACf,QAAQ,oBAAoB,GAC5B,QAAQ,qBAAqB,GAC7B,QAAQ,wBAAwB,GAChC,QAAQ,uBAAuB,GAC/B,QAAQ,wBAAwB,GAChC,QAAQ,0BAA0B,GAClC,QAAQ,0BAA0B,GAClC,QAAQ,kBAAkB,GAC1B,QAAQ,sBAAsB,GAC9B,QAAQ,wBAAwB,GAChC,QAAQ,sBAAsB,CAChC;EACA,UAAU;GAAE,KAAK,QAAQ,oDAAoD;GAAG,MAAM;EAAS,CAAC;EAChG,iBAAiB,QAAQ,kBAAkB,CAAC;EAI5C,KAAK,KAAK,sBAAsB;GAC9B,MAAM,QAAQ,KAAK,QAAQ,MAAM,UAAU,MAAK,MAAK,EAAE,aAAa,QAAQ;GAC5E,IAAI,CAAC,OAAO,aAAa,MAAM,IAAI,MAAM,wFAAwF;GACjI,MAAM,cAAc,MAAM;GAC1B,MAAM,cAAc,OAAM,SAAQ,YAAY,WAAW,WAAW,MAAM,YAAY,IAAI;EAC5F,CAAC;EACD,KAAK,QAAQ,MAAM,eAAe;GAAE,GAAG,KAAK,QAAQ,MAAM;GAAc,WAAW;EAAK;EAExF,KAAK,QAAQ,MAAM,YAAY;GAAE,GAAG,KAAK,QAAQ,MAAM;GAAW,QAAQ;IAAC,GAAI,KAAK,QAAQ,MAAM,WAAW,UAAU,CAAC;IAAI;IAAoB;GAAU;EAAE;EAC5J,KAAK,QAAQ,cAAc,eAAe;GACxC,QAAQ,EAAE,qBAAqB,QAAQ,OAAO,oBAAoB;GAClE,IAAI;IACF,QAAQ;IAER,SAAS,OAAO,YAAY,OAAO,QAAQ,QAAQ,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,IAAI;KAAE,GAAG;KAAQ,QAAQ,OAAO,UAAU;IAAG,CAAC,CAAC,CAAC;IACtI,OAAO,QAAQ,GAAG;IAClB,WAAW,QAAQ,GAAG;IAEtB,GAAI,QAAQ,GAAG,iBAAiB,EAAE,eAAe;KAAE,GAAG,QAAQ,GAAG;KAAe,QAAQ,QAAQ,GAAG,cAAc,UAAU;IAAG,EAAE;GAClI;GACA,GAAI,KAAK,QAAQ,cAAc;EACjC;EAEA,KAAK,QAAQ,cAAc,OAAO,eAAe;GAC/C,QAAQ,QAAQ;GAChB,GAAI,QAAQ,YAAY,EAAE,UAAU,QAAQ,SAAS;GACrD,IAAI;IAAE,OAAO,QAAQ,GAAG;IAAO,eAAe,QAAQ,QAAQ,GAAG,aAAa;GAAE;GAChF,GAAI,KAAK,QAAQ,cAAc,OAAO;EACxC;CACF;AACF,CAAC"}
|
|
@@ -5,9 +5,8 @@ import { App } from "vue";
|
|
|
5
5
|
* Installs the editor context on a Nuxt app (client only: TipTap does not render on the server). Settings are kept per
|
|
6
6
|
* account through the host's `/api/editor/settings`; the AI configuration is the module's public runtime config,
|
|
7
7
|
* passed on as inert data. Features request through ofetch, which is what Nuxt's `$fetch` is on the client. `locale`
|
|
8
|
-
* and `messages` are the module's options of the same name. The kit
|
|
9
|
-
*
|
|
10
|
-
* `@nuxt/ui`, a Nuxt UI app never `primevue`). Only the Vue app is read, so the parameter is structural: a host's
|
|
8
|
+
* and `messages` are the module's options of the same name. The kit is passed in by the plugin file the module registers
|
|
9
|
+
* (`nuxtUiKit()`). Only the Vue app is read, so the parameter is structural: a host's
|
|
11
10
|
* augmented `NuxtApp` (plugins adding `$router`, `$auth`, ...) and the `_NuxtApp` a plugin receives both fit.
|
|
12
11
|
*/
|
|
13
12
|
export declare function installEditorContext(nuxtApp: {
|
|
@@ -5,9 +5,8 @@ import { useRuntimeConfig } from "#app";
|
|
|
5
5
|
* Installs the editor context on a Nuxt app (client only: TipTap does not render on the server). Settings are kept per
|
|
6
6
|
* account through the host's `/api/editor/settings`; the AI configuration is the module's public runtime config,
|
|
7
7
|
* passed on as inert data. Features request through ofetch, which is what Nuxt's `$fetch` is on the client. `locale`
|
|
8
|
-
* and `messages` are the module's options of the same name. The kit
|
|
9
|
-
*
|
|
10
|
-
* `@nuxt/ui`, a Nuxt UI app never `primevue`). Only the Vue app is read, so the parameter is structural: a host's
|
|
8
|
+
* and `messages` are the module's options of the same name. The kit is passed in by the plugin file the module registers
|
|
9
|
+
* (`nuxtUiKit()`). Only the Vue app is read, so the parameter is structural: a host's
|
|
11
10
|
* augmented `NuxtApp` (plugins adding `$router`, `$auth`, ...) and the `_NuxtApp` a plugin receives both fit.
|
|
12
11
|
*/
|
|
13
12
|
function installEditorContext(nuxtApp, kit) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-context.js","names":[],"sources":["../../../src/nuxt/runtime/install-context.ts"],"sourcesContent":["import type { App } from 'vue'\nimport { useRuntimeConfig } from '#app'\nimport type { EditorAiConfig } from '../../core/context'\nimport type { Locale, Messages } from '../../i18n'\nimport { createEditor } from '../../vue/context'\nimport type { VueUiKit } from '../../vue/kit/types'\n\n/**\n * Installs the editor context on a Nuxt app (client only: TipTap does not render on the server). Settings are kept per\n * account through the host's `/api/editor/settings`; the AI configuration is the module's public runtime config,\n * passed on as inert data. Features request through ofetch, which is what Nuxt's `$fetch` is on the client. `locale`\n * and `messages` are the module's options of the same name. The kit
|
|
1
|
+
{"version":3,"file":"install-context.js","names":[],"sources":["../../../src/nuxt/runtime/install-context.ts"],"sourcesContent":["import type { App } from 'vue'\nimport { useRuntimeConfig } from '#app'\nimport type { EditorAiConfig } from '../../core/context'\nimport type { Locale, Messages } from '../../i18n'\nimport { createEditor } from '../../vue/context'\nimport type { VueUiKit } from '../../vue/kit/types'\n\n/**\n * Installs the editor context on a Nuxt app (client only: TipTap does not render on the server). Settings are kept per\n * account through the host's `/api/editor/settings`; the AI configuration is the module's public runtime config,\n * passed on as inert data. Features request through ofetch, which is what Nuxt's `$fetch` is on the client. `locale`\n * and `messages` are the module's options of the same name. The kit is passed in by the plugin file the module registers\n * (`nuxtUiKit()`). Only the Vue app is read, so the parameter is structural: a host's\n * augmented `NuxtApp` (plugins adding `$router`, `$auth`, ...) and the `_NuxtApp` a plugin receives both fit.\n */\nexport function installEditorContext(nuxtApp: { vueApp: App }, kit: VueUiKit): void {\n const { ai, locale, messages } = useRuntimeConfig().public.tiptapEditor as { ai?: EditorAiConfig, locale?: Locale, messages?: Partial<Messages> }\n nuxtApp.vueApp.use(createEditor({ kit, settings: { remote: true }, ...(ai && { ai }), ...(locale && { locale }), ...(messages && { messages }) }))\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,qBAAqB,SAA0B,KAAqB;CAClF,MAAM,EAAE,IAAI,QAAQ,aAAa,iBAAiB,CAAC,CAAC,OAAO;CAC3D,QAAQ,OAAO,IAAI,aAAa;EAAE;EAAK,UAAU,EAAE,QAAQ,KAAK;EAAG,GAAI,MAAM,EAAE,GAAG;EAAI,GAAI,UAAU,EAAE,OAAO;EAAI,GAAI,YAAY,EAAE,SAAS;CAAG,CAAC,CAAC;AACnJ"}
|
|
@@ -2,7 +2,7 @@ import { nuxtUiKit } from '../../../vue/kit/nuxt-ui'
|
|
|
2
2
|
import { installEditorContext } from '../install-context'
|
|
3
3
|
import { defineNuxtPlugin } from '#app'
|
|
4
4
|
|
|
5
|
-
// Registered by the module
|
|
5
|
+
// Registered by the module; see `install-context.ts`.
|
|
6
6
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
7
7
|
installEditorContext(nuxtApp, nuxtUiKit())
|
|
8
8
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* The React surface's token map: the `--sk-*` variables the feature stylesheets (`styles/*.css`) read resolve to the
|
|
2
|
-
shadcn/ui theme tokens (the counterpart of `vue/kit/nuxt-ui.css`
|
|
2
|
+
shadcn/ui theme tokens (the counterpart of `vue/kit/nuxt-ui.css`). */
|
|
3
3
|
:root,
|
|
4
4
|
.dark {
|
|
5
5
|
--sk-bg: var(--background);
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
--sk-border-accented: var(--border);
|
|
13
13
|
--sk-primary: var(--primary);
|
|
14
14
|
--sk-primary-fg: var(--primary-foreground);
|
|
15
|
-
--sk-success: oklch(0.72 0.19 150);
|
|
15
|
+
--sk-success: var(--color-success, oklch(0.72 0.19 150));
|
|
16
16
|
--sk-danger: var(--destructive);
|
|
17
17
|
--sk-radius: var(--radius);
|
|
18
18
|
--sk-bg-elevated: var(--card);
|
package/dist/styles/ai.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* AI feature styles: ghost autocomplete, selection highlight, review decorations, previews. Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* AI feature styles: ghost autocomplete, selection highlight, review decorations, previews. Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
2
2
|
/* GhostAutocomplete: local AI suggestion after the caret (widget decoration, never in the document). */
|
|
3
3
|
@layer components {
|
|
4
4
|
.tiptap .ghost-autocomplete {
|
package/dist/styles/authors.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Authors feature styles (import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Authors feature styles (import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`)). AuthorMark: who wrote a text run; styled only while the colouring mode is on (the authors feature puts `author-colors` on the editor element). */
|
|
2
2
|
@layer components {
|
|
3
3
|
.tiptap.author-colors .author {
|
|
4
4
|
background: color-mix(in oklab, var(--author-color, var(--sk-muted)) 18%, transparent);
|
package/dist/styles/block-ui.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Block range selection of the block-ui feature (NodeRange). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Block range selection of the block-ui feature (NodeRange). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
2
2
|
@layer components {
|
|
3
3
|
/* NodeRange: block-range selection (Mod+drag, Shift+↑/↓). The native selection is hidden, blocks get a tint. */
|
|
4
4
|
.tiptap.ProseMirror-noderangeselection *::selection { background: transparent; }
|
package/dist/styles/collab.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Remote carets of the collab feature (CollaborationCaret). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Remote carets of the collab feature (CollaborationCaret). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
2
2
|
@layer components {
|
|
3
3
|
.tiptap .collaboration-carets__caret {
|
|
4
4
|
border-left: 1px solid;
|
package/dist/styles/comments.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Comments feature styles (import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Comments feature styles (import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`)). Comments: thread highlights are decorations driven by thread state (the `comment` mark only stores the range). */
|
|
2
2
|
@layer components {
|
|
3
3
|
.tiptap .comment-hl {
|
|
4
4
|
background: color-mix(in oklab, var(--sk-warning) 22%, transparent);
|
package/dist/styles/core.css
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* Core editor styles: the `.tiptap` surface, hand-written typography (@tailwindcss/typography is not installed) and
|
|
2
|
-
BlockFlash. Feature styles live in their own files. Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
2
|
+
BlockFlash. Feature styles live in their own files. Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
3
3
|
|
|
4
4
|
@import './tokens.css';
|
|
5
5
|
|
|
6
6
|
/* Editor tokens beyond the shared `--sk-*` set (`tokens.css`). Every stylesheet of the package reads `--sk-*` only; a UI
|
|
7
|
-
kit maps them onto its own variables (`vue/kit/nuxt-ui.css`: `--ui-*`,
|
|
7
|
+
kit maps them onto its own variables (`vue/kit/nuxt-ui.css`: `--ui-*`, the React
|
|
8
8
|
`react/styles/ui-vars.css`: shadcn). These defaults derive from the shared tokens, so an app without a kit sheet
|
|
9
9
|
still gets a coherent look. Declared under `:where()` (specificity 0), a kit's or the host's rule always wins. */
|
|
10
10
|
:where(:root) {
|
package/dist/styles/media.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Media feature styles: images and the audio/video/file blocks (AudioView, VideoView, FileView). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Media feature styles: images and the audio/video/file blocks (AudioView, VideoView, FileView). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
2
2
|
@layer components {
|
|
3
3
|
.tiptap img { max-width: 100%; height: auto; border-radius: var(--sk-radius); margin: 0.75em 0; display: block; }
|
|
4
4
|
.tiptap img.ProseMirror-selectednode { outline: 2px solid var(--sk-primary); outline-offset: 2px; }
|
package/dist/styles/mentions.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Mentions feature styles: the `@username` and `#tag` chips. Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Mentions feature styles: the `@username` and `#tag` chips. Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
2
2
|
@layer components {
|
|
3
3
|
/* @username mention chip, tinted with the mentioned user's colour (inline `--mention-color`). */
|
|
4
4
|
.tiptap .mention {
|
package/dist/styles/themes.css
CHANGED
|
@@ -386,7 +386,7 @@
|
|
|
386
386
|
|
|
387
387
|
/* ---- 2. Token bridge-------------------------------------------------------------------------------- */
|
|
388
388
|
.obsidian-theme {
|
|
389
|
-
/* The editor's own tokens (kit independent:
|
|
389
|
+
/* The editor's own tokens (kit independent: shadcn hosts read these, too). */
|
|
390
390
|
--sk-bg: var(--background-primary);
|
|
391
391
|
--sk-fg: var(--text-normal);
|
|
392
392
|
--sk-muted: var(--text-muted);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Transcript feature styles: speaker segments (TranscriptSegmentView). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css
|
|
1
|
+
/* Transcript feature styles: speaker segments (TranscriptSegmentView). Import after `tailwindcss` and the UI kit's stylesheet (`vue/kit/nuxt-ui.css`). */
|
|
2
2
|
@layer components {
|
|
3
3
|
/* The text column may shrink below its longest word (grid `1fr` alone would overflow instead). */
|
|
4
4
|
.tiptap .transcript-segment__text { min-width: 0; overflow-wrap: anywhere; }
|
package/dist/vue/context.d.ts
CHANGED
|
@@ -5,12 +5,12 @@ import { InjectionKey, Plugin } from "vue";
|
|
|
5
5
|
export declare const EDITOR_CONTEXT: InjectionKey<EditorContext>;
|
|
6
6
|
/** What `createEditor` takes: the framework-free context options plus the UI kit that renders the chrome. */
|
|
7
7
|
export interface VueEditorOptions extends EditorContextOptions {
|
|
8
|
-
/** The widgets the chrome components render: `nuxtUiKit()` (`/vue/kit/nuxt-ui`)
|
|
9
|
-
kit
|
|
8
|
+
/** The widgets the chrome components render. Default: `nuxtUiKit()` (`/vue/kit/nuxt-ui`), which needs `@nuxt/ui` set up in the host; pass your own `VueUiKit` to render the chrome with another library. */
|
|
9
|
+
kit?: VueUiKit;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* The editor context of a Vue app: the settings shared by all editors of the app, the HTTP client and the UI kit
|
|
13
|
-
* (`useUiKit()`). Install with `app.use(createEditor(
|
|
13
|
+
* (`useUiKit()`). Install with `app.use(createEditor())`. The settings are read from localStorage right away (client only) and every change is
|
|
14
14
|
* written back. With `settings.remote`, `GET /api/editor/settings` (on the first `useEditorSettings()`) answers: `200`
|
|
15
15
|
* replaces them with the user's account settings (`synced`), `204` (the host's adapter keeps no settings), `401` or a
|
|
16
16
|
* network error keep the local ones; once synced every change is also sent to the server (`PUT`, debounced). Watcher
|
package/dist/vue/context.js
CHANGED
|
@@ -2,19 +2,20 @@ import { createEditorContext } from "../core/context.js";
|
|
|
2
2
|
import { VUE_UI_KIT } from "./kit/use-ui-kit.js";
|
|
3
3
|
import { createQueuedNotifier } from "./notify.js";
|
|
4
4
|
import { createSettingsBridge } from "./settings.js";
|
|
5
|
+
import { nuxtUiKit } from "./kit/nuxt-ui.js";
|
|
5
6
|
import { inject } from "vue";
|
|
6
7
|
//#region src/vue/context.ts
|
|
7
8
|
const EDITOR_CONTEXT = Symbol("tiptap-editor:context");
|
|
8
9
|
/**
|
|
9
10
|
* The editor context of a Vue app: the settings shared by all editors of the app, the HTTP client and the UI kit
|
|
10
|
-
* (`useUiKit()`). Install with `app.use(createEditor(
|
|
11
|
+
* (`useUiKit()`). Install with `app.use(createEditor())`. The settings are read from localStorage right away (client only) and every change is
|
|
11
12
|
* written back. With `settings.remote`, `GET /api/editor/settings` (on the first `useEditorSettings()`) answers: `200`
|
|
12
13
|
* replaces them with the user's account settings (`synced`), `204` (the host's adapter keeps no settings), `401` or a
|
|
13
14
|
* network error keep the local ones; once synced every change is also sent to the server (`PUT`, debounced). Watcher
|
|
14
15
|
* and timer stop with the app. App-level notices (`options.notify`, default: queued until the first `EditorSurface`
|
|
15
16
|
* mounts and hands over the kit's `notifier()`) show as the kit's toasts.
|
|
16
17
|
*/
|
|
17
|
-
function createEditor({ kit, ...options }) {
|
|
18
|
+
function createEditor({ kit = nuxtUiKit(), ...options }) {
|
|
18
19
|
return { install(app) {
|
|
19
20
|
const ctx = createEditorContext({
|
|
20
21
|
notify: createQueuedNotifier(),
|
package/dist/vue/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../../src/vue/context.ts"],"sourcesContent":["import { type InjectionKey, inject, type Plugin } from 'vue'\nimport { createEditorContext, type EditorContext, type EditorContextOptions } from '../core/context'\nimport { createQueuedNotifier } from './notify'\nimport { createSettingsBridge } from './settings'\nimport { VUE_UI_KIT } from './kit/use-ui-kit'\nimport type { VueUiKit } from './kit/types'\n\nexport const EDITOR_CONTEXT: InjectionKey<EditorContext> = Symbol('tiptap-editor:context')\n\n/** What `createEditor` takes: the framework-free context options plus the UI kit that renders the chrome. */\nexport interface VueEditorOptions extends EditorContextOptions {\n /** The widgets the chrome components render: `nuxtUiKit()` (`/vue/kit/nuxt-ui`)
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../../src/vue/context.ts"],"sourcesContent":["import { type InjectionKey, inject, type Plugin } from 'vue'\nimport { createEditorContext, type EditorContext, type EditorContextOptions } from '../core/context'\nimport { createQueuedNotifier } from './notify'\nimport { createSettingsBridge } from './settings'\nimport { nuxtUiKit } from './kit/nuxt-ui'\nimport { VUE_UI_KIT } from './kit/use-ui-kit'\nimport type { VueUiKit } from './kit/types'\n\nexport const EDITOR_CONTEXT: InjectionKey<EditorContext> = Symbol('tiptap-editor:context')\n\n/** What `createEditor` takes: the framework-free context options plus the UI kit that renders the chrome. */\nexport interface VueEditorOptions extends EditorContextOptions {\n /** The widgets the chrome components render. Default: `nuxtUiKit()` (`/vue/kit/nuxt-ui`), which needs `@nuxt/ui` set up in the host; pass your own `VueUiKit` to render the chrome with another library. */\n kit?: VueUiKit\n}\n\n/**\n * The editor context of a Vue app: the settings shared by all editors of the app, the HTTP client and the UI kit\n * (`useUiKit()`). Install with `app.use(createEditor())`. The settings are read from localStorage right away (client only) and every change is\n * written back. With `settings.remote`, `GET /api/editor/settings` (on the first `useEditorSettings()`) answers: `200`\n * replaces them with the user's account settings (`synced`), `204` (the host's adapter keeps no settings), `401` or a\n * network error keep the local ones; once synced every change is also sent to the server (`PUT`, debounced). Watcher\n * and timer stop with the app. App-level notices (`options.notify`, default: queued until the first `EditorSurface`\n * mounts and hands over the kit's `notifier()`) show as the kit's toasts.\n */\nexport function createEditor({ kit = nuxtUiKit(), ...options }: VueEditorOptions): Plugin {\n return {\n install(app) {\n const ctx = createEditorContext({ notify: createQueuedNotifier(), ...options })\n app.provide(VUE_UI_KIT, kit)\n app.provide(EDITOR_CONTEXT, ctx)\n const bridge = createSettingsBridge(ctx)\n app.onUnmount(() => {\n bridge.dispose()\n ctx.dispose()\n })\n },\n }\n}\n\n/** The app's editor context; throws a descriptive error when `createEditor()` was not installed. */\nexport function useEditorContext(): EditorContext {\n const context = inject(EDITOR_CONTEXT, null)\n if (!context) throw new Error('@ecsplico/editor: no editor context; install it with app.use(createEditor())')\n return context\n}\n"],"mappings":";;;;;;;AAQA,MAAa,iBAA8C,OAAO,uBAAuB;;;;;;;;;;AAiBzF,SAAgB,aAAa,EAAE,MAAM,UAAU,GAAG,GAAG,WAAqC;CACxF,OAAO,EACL,QAAQ,KAAK;EACX,MAAM,MAAM,oBAAoB;GAAE,QAAQ,qBAAqB;GAAG,GAAG;EAAQ,CAAC;EAC9E,IAAI,QAAQ,YAAY,GAAG;EAC3B,IAAI,QAAQ,gBAAgB,GAAG;EAC/B,MAAM,SAAS,qBAAqB,GAAG;EACvC,IAAI,gBAAgB;GAClB,OAAO,QAAQ;GACf,IAAI,QAAQ;EACd,CAAC;CACH,EACF;AACF;;AAGA,SAAgB,mBAAkC;CAChD,MAAM,UAAU,OAAO,gBAAgB,IAAI;CAC3C,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,8EAA8E;CAC5G,OAAO;AACT"}
|
package/dist/vue/kit/types.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Component } from "vue";
|
|
|
3
3
|
//#region src/vue/kit/types.d.ts
|
|
4
4
|
/** Semantic colours. A kit maps them onto its own palette; `neutral` is the plain chrome colour. */
|
|
5
5
|
export type KitColor = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | 'neutral';
|
|
6
|
-
/** Control sizes, `xs` the densest. A kit may collapse neighbouring steps
|
|
6
|
+
/** Control sizes, `xs` the densest. A kit may collapse neighbouring steps. */
|
|
7
7
|
export type KitSize = '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
|
|
8
8
|
/** How a button or badge is filled: `solid` (primary fill), `outline`, `soft` (tinted), `subtle` (tinted + ring), `ghost` (text until hovered), `link`. */
|
|
9
9
|
export type KitVariant = 'solid' | 'outline' | 'soft' | 'subtle' | 'ghost' | 'link';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { VueUiKit } from "./types.js";
|
|
2
2
|
import { InjectionKey } from "vue";
|
|
3
3
|
//#region src/vue/kit/use-ui-kit.d.ts
|
|
4
|
-
/** Provided by `createEditor(
|
|
4
|
+
/** Provided by `createEditor()` (`kit`, default `nuxtUiKit()`): the widgets the chrome components render (see `VueUiKit`). */
|
|
5
5
|
export declare const VUE_UI_KIT: InjectionKey<VueUiKit>;
|
|
6
6
|
/**
|
|
7
7
|
* The UI kit of the app: every chrome component of the package takes its widgets from here, never from a UI library.
|
|
8
|
-
* Throws a descriptive error when `createEditor(
|
|
8
|
+
* Throws a descriptive error when `createEditor()` was not installed. Call during component setup.
|
|
9
9
|
*/
|
|
10
10
|
export declare function useUiKit(): VueUiKit;
|
|
11
11
|
//#endregion
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { inject } from "vue";
|
|
2
2
|
//#region src/vue/kit/use-ui-kit.ts
|
|
3
|
-
/** Provided by `createEditor(
|
|
3
|
+
/** Provided by `createEditor()` (`kit`, default `nuxtUiKit()`): the widgets the chrome components render (see `VueUiKit`). */
|
|
4
4
|
const VUE_UI_KIT = Symbol("tiptap-editor:ui-kit");
|
|
5
5
|
/**
|
|
6
6
|
* The UI kit of the app: every chrome component of the package takes its widgets from here, never from a UI library.
|
|
7
|
-
* Throws a descriptive error when `createEditor(
|
|
7
|
+
* Throws a descriptive error when `createEditor()` was not installed. Call during component setup.
|
|
8
8
|
*/
|
|
9
9
|
function useUiKit() {
|
|
10
10
|
const kit = inject(VUE_UI_KIT, null);
|
|
11
|
-
if (!kit) throw new Error("@ecsplico/editor: no UI kit; install
|
|
11
|
+
if (!kit) throw new Error("@ecsplico/editor: no UI kit; install the editor context with app.use(createEditor()) (the Nuxt UI kit, @ecsplico/editor/vue/kit/nuxt-ui, is the default)");
|
|
12
12
|
return kit;
|
|
13
13
|
}
|
|
14
14
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-ui-kit.js","names":[],"sources":["../../../src/vue/kit/use-ui-kit.ts"],"sourcesContent":["import { type InjectionKey, inject } from 'vue'\nimport type { VueUiKit } from './types'\n\n/** Provided by `createEditor(
|
|
1
|
+
{"version":3,"file":"use-ui-kit.js","names":[],"sources":["../../../src/vue/kit/use-ui-kit.ts"],"sourcesContent":["import { type InjectionKey, inject } from 'vue'\nimport type { VueUiKit } from './types'\n\n/** Provided by `createEditor()` (`kit`, default `nuxtUiKit()`): the widgets the chrome components render (see `VueUiKit`). */\nexport const VUE_UI_KIT: InjectionKey<VueUiKit> = Symbol('tiptap-editor:ui-kit')\n\n/**\n * The UI kit of the app: every chrome component of the package takes its widgets from here, never from a UI library.\n * Throws a descriptive error when `createEditor()` was not installed. Call during component setup.\n */\nexport function useUiKit(): VueUiKit {\n const kit = inject(VUE_UI_KIT, null)\n if (!kit) throw new Error('@ecsplico/editor: no UI kit; install the editor context with app.use(createEditor()) (the Nuxt UI kit, @ecsplico/editor/vue/kit/nuxt-ui, is the default)')\n return kit\n}\n"],"mappings":";;;AAIA,MAAa,aAAqC,OAAO,sBAAsB;;;;;AAM/E,SAAgB,WAAqB;CACnC,MAAM,MAAM,OAAO,YAAY,IAAI;CACnC,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,0JAA0J;CACpL,OAAO;AACT"}
|
package/docs/integration.md
CHANGED
|
@@ -111,7 +111,7 @@ export default defineNuxtConfig({
|
|
|
111
111
|
|
|
112
112
|
Add `"@ecsplico/editor"` to the host's dependencies (`workspace:*` in this repository, the registry version elsewhere). The package ships built ESM (`dist`); the module puts it into `build.transpile` for the client and Nitro's `externals.inline` for the server so the runtime files in `dist/nuxt/runtime` (they import `h3` and `nitropack/runtime` for the server and `#app` for the client explicitly) are compiled by the host. `h3` and `nitropack` are optional peers: a Nuxt app already provides them; only a strictly isolated install (pnpm without hoisting) may need them listed next to the package.
|
|
113
113
|
|
|
114
|
-
The module registers exactly one client plugin (`editor-context-nuxt-ui.client.ts
|
|
114
|
+
The module registers exactly one client plugin (`editor-context-nuxt-ui.client.ts`, which hands `nuxtUiKit()` to the context; the module has no `kit` option): it installs the editor context with account-synced settings and the public AI configuration. It auto-registers no component or composable: import everything from the package entries.
|
|
115
115
|
|
|
116
116
|
Without a registered adapter every route throws „tiptap-editor: setEditorAdapter() wurde in keinem Nitro-Plugin aufgerufen“.
|
|
117
117
|
|
package/docs/llms.md
CHANGED
|
@@ -46,7 +46,7 @@ Rules that follow from this table:
|
|
|
46
46
|
## Minimal integration: Nuxt
|
|
47
47
|
|
|
48
48
|
1. Install the package from npmjs (`npm install @ecsplico/editor`, no token needed) and the peers in the consuming app (`vue`, `@nuxt/ui`, `@tiptap/core`, `@tiptap/pm`, `@tiptap/vue-3`, `yjs`, `@hocuspocus/provider`, plus `tailwindcss` and `@iconify-json/lucide`). Inside this repository declare `"@ecsplico/editor": "workspace:*"`.
|
|
49
|
-
2. Register the module **after** `@nuxt/ui` (it patches Nuxt UI's generated `ui.css` template and throws if that template is missing). The module adds every feature stylesheet to `css` (`themes.css` last), puts the package into `build.transpile` and Nitro's `externals.inline`, enables Nitro websockets, installs the client plugin
|
|
49
|
+
2. Register the module **after** `@nuxt/ui` (it patches Nuxt UI's generated `ui.css` template and throws if that template is missing). The module adds every feature stylesheet to `css` (`themes.css` last), puts the package into `build.transpile` and Nitro's `externals.inline`, enables Nitro websockets, installs the client plugin `editor-context-nuxt-ui.client.ts` (`createEditor({ kit: nuxtUiKit(), settings: { remote: true } })`; the module has no `kit` option, the Vue binding is Nuxt UI) and scans the Nitro routes. It registers no component or composable.
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
// nuxt.config.ts
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecsplico/editor",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Vue and React editor library on TipTap v3 (Vue
|
|
5
|
+
"description": "Vue and React editor library on TipTap v3 (Vue: Nuxt UI; React: shadcn/ui): framework-free features with Vue and React bindings, simple and advanced presets, tree-shakeable entries. Built ESM with type declarations.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
16
|
"docs",
|
|
17
|
-
"README.md"
|
|
17
|
+
"README.md",
|
|
18
|
+
"CHANGELOG.md"
|
|
18
19
|
],
|
|
19
20
|
"publishConfig": {
|
|
20
21
|
"access": "public"
|
|
@@ -61,11 +62,6 @@
|
|
|
61
62
|
"types": "./dist/vue/kit/nuxt-ui.d.ts",
|
|
62
63
|
"import": "./dist/vue/kit/nuxt-ui.js"
|
|
63
64
|
},
|
|
64
|
-
"./vue/kit/primevue": {
|
|
65
|
-
"skaile-source": "./src/vue/kit/primevue.ts",
|
|
66
|
-
"types": "./dist/vue/kit/primevue.d.ts",
|
|
67
|
-
"import": "./dist/vue/kit/primevue.js"
|
|
68
|
-
},
|
|
69
65
|
"./vue/simple": {
|
|
70
66
|
"skaile-source": "./src/vue/simple.ts",
|
|
71
67
|
"types": "./dist/vue/simple.d.ts",
|
|
@@ -484,10 +480,6 @@
|
|
|
484
480
|
"./vue/kit/nuxt-ui.css": {
|
|
485
481
|
"skaile-source": "./src/vue/kit/nuxt-ui.css",
|
|
486
482
|
"default": "./dist/vue/kit/nuxt-ui.css"
|
|
487
|
-
},
|
|
488
|
-
"./vue/kit/primevue.css": {
|
|
489
|
-
"skaile-source": "./src/vue/kit/primevue.css",
|
|
490
|
-
"default": "./dist/vue/kit/primevue.css"
|
|
491
483
|
}
|
|
492
484
|
},
|
|
493
485
|
"peerDependencies": {
|
|
@@ -508,7 +500,6 @@
|
|
|
508
500
|
"h3": "^1.15.0",
|
|
509
501
|
"nitropack": "^2.13.0",
|
|
510
502
|
"nuxt": "^4.5.2",
|
|
511
|
-
"primevue": "^5.0.2",
|
|
512
503
|
"react": "^19.3.0",
|
|
513
504
|
"react-dom": "^19.3.0",
|
|
514
505
|
"vue": "^3.5.42",
|
|
@@ -560,8 +551,6 @@
|
|
|
560
551
|
"@iconify/react": "^6.0.2",
|
|
561
552
|
"@iconify/vue": "^5.0.3",
|
|
562
553
|
"@lezer/highlight": "^1.2.1",
|
|
563
|
-
"@primeuix/themes": "^3.0.1",
|
|
564
|
-
"@tailwindcss/vite": "4.3.3",
|
|
565
554
|
"@tiptap/react": "3.31.3",
|
|
566
555
|
"@types/react": "^19.3.0",
|
|
567
556
|
"@types/react-dom": "^19.3.0",
|
|
@@ -569,7 +558,6 @@
|
|
|
569
558
|
"@vitejs/plugin-vue": "^6.0.9",
|
|
570
559
|
"h3": "^1.15.11",
|
|
571
560
|
"nitropack": "^2.13.4",
|
|
572
|
-
"primevue": "^5.0.2",
|
|
573
561
|
"react": "^19.3.0",
|
|
574
562
|
"react-dom": "^19.3.0",
|
|
575
563
|
"tailwindcss": "^4.3.3",
|
|
@@ -602,9 +590,6 @@
|
|
|
602
590
|
"nuxt": {
|
|
603
591
|
"optional": true
|
|
604
592
|
},
|
|
605
|
-
"primevue": {
|
|
606
|
-
"optional": true
|
|
607
|
-
},
|
|
608
593
|
"react": {
|
|
609
594
|
"optional": true
|
|
610
595
|
},
|