nuvra 0.2.0 → 0.3.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/README.md +231 -217
- package/dist/components/document-editor.vue.d.ts +3 -0
- package/dist/components/editor-canvas.vue.d.ts +22 -1
- package/dist/components/editor-context-menu.vue.d.ts +14 -0
- package/dist/components/editor-header-footer.vue.d.ts +12 -0
- package/dist/components/editor-ruler.vue.d.ts +21 -0
- package/dist/components/editor-toolbar.vue.d.ts +5 -1
- package/dist/core/engine/blocks.d.ts +25 -0
- package/dist/core/engine/clipboard.d.ts +5 -0
- package/dist/core/engine/engine.d.ts +46 -2
- package/dist/core/engine/marks.d.ts +9 -0
- package/dist/core/engine/schema.d.ts +4 -0
- package/dist/core/export.d.ts +14 -4
- package/dist/core/icons.d.ts +1 -1
- package/dist/core/labels.d.ts +42 -0
- package/dist/core/page.d.ts +51 -0
- package/dist/core/pagination.d.ts +6 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/core/ui-state.d.ts +13 -1
- package/dist/export-VeTfgCEp.js +117 -0
- package/dist/export-VeTfgCEp.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3010 -1909
- package/dist/index.js.map +1 -1
- package/dist/{page-CEEleKNI.js → page-DL7Oj2o8.js} +23 -4
- package/dist/page-DL7Oj2o8.js.map +1 -0
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/dist/export-cyOnlakM.js +0 -59
- package/dist/export-cyOnlakM.js.map +0 -1
- package/dist/page-CEEleKNI.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,217 +1,231 @@
|
|
|
1
|
-
# nuvra
|
|
2
|
-
|
|
3
|
-
Word-style document editor for Vue 3. A real page view with paper sizes and margins, a lighter web view for
|
|
4
|
-
forms, tables, images, lists, find & replace, HTML source mode, printing and export to HTML or Word (`.doc`).
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
###
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
| `focus
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
setEditorTranslator((key, named) =>
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
|
184
|
-
|
|
|
185
|
-
| `--nuvra-
|
|
186
|
-
| `--nuvra-
|
|
187
|
-
| `--nuvra-border
|
|
188
|
-
| `--nuvra-
|
|
189
|
-
| `--nuvra-
|
|
190
|
-
| `--nuvra-
|
|
191
|
-
| `--nuvra-
|
|
192
|
-
| `--nuvra-
|
|
193
|
-
| `--nuvra-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
1
|
+
# nuvra
|
|
2
|
+
|
|
3
|
+
Word-style document editor for Vue 3. A real page view with paper sizes and margins, a lighter web view for
|
|
4
|
+
forms, tables, images, lists, find & replace, HTML source mode, printing and export to HTML or Word (`.doc`).
|
|
5
|
+
|
|
6
|
+
**[Documentation and live demo →](https://nuvra-docs.vercel.app)**
|
|
7
|
+
|
|
8
|
+
- No editor framework underneath: its own small editing engine with a sanitizing schema.
|
|
9
|
+
- No UI framework either: native HTML controls, built-in SVG icons and plain CSS variables. Vue is the only
|
|
10
|
+
dependency.
|
|
11
|
+
- Pagination in the page view (A4, A5, Letter, …, portrait or landscape).
|
|
12
|
+
- Tables with merge / split, images with resize and alignment, task lists, links, colors, fonts.
|
|
13
|
+
- Undo / redo, keyboard shortcuts that work with non-Latin keyboard layouts, Markdown-like input rules.
|
|
14
|
+
- Office tools: format painter, letter case, paragraph spacing, formatting marks, a right-click menu and
|
|
15
|
+
Ctrl + wheel zoom.
|
|
16
|
+
- Headers and footers with page number, page count, date and title tokens; printing breaks the pages exactly where
|
|
17
|
+
the editor shows them, and the Word export uses Word's own header, footer and page fields.
|
|
18
|
+
- A ruler above the page for the margins and for the first line, left and right indents of a paragraph.
|
|
19
|
+
- A page watermark such as DRAFT or COPY, drawn behind the text of every page and carried into print, HTML and Word.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pnpm add nuvra
|
|
25
|
+
# or
|
|
26
|
+
npm install nuvra
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`vue` (3.5+) is the only peer dependency.
|
|
30
|
+
|
|
31
|
+
Import the styles once, for example in `main.ts`:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import 'nuvra/style.css';
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Document editor
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<script setup lang="ts">
|
|
43
|
+
import { ref } from 'vue';
|
|
44
|
+
import { DocumentEditor, type PageSettings, createPageSettings } from 'nuvra';
|
|
45
|
+
|
|
46
|
+
const html = ref('');
|
|
47
|
+
const page = ref<PageSettings>(createPageSettings());
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<DocumentEditor v-model="html" v-model:page="page" height="100%" title="Contract" />
|
|
52
|
+
</template>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Form field
|
|
56
|
+
|
|
57
|
+
`Editor` is the same editor in the web view, growing with its content between `minHeight` and `maxHeight`:
|
|
58
|
+
|
|
59
|
+
```vue
|
|
60
|
+
<script setup lang="ts">
|
|
61
|
+
import { ref } from 'vue';
|
|
62
|
+
import { Editor } from 'nuvra';
|
|
63
|
+
|
|
64
|
+
const description = ref('');
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<template>
|
|
68
|
+
<Editor v-model="description" placeholder="Description" :max-length="2000" />
|
|
69
|
+
</template>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Image upload
|
|
73
|
+
|
|
74
|
+
Without an upload handler images are embedded as data URLs. Pass `uploadImage` to store them on your server:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import type { DocumentImageUploadHandler } from 'nuvra';
|
|
78
|
+
|
|
79
|
+
const uploadImage: DocumentImageUploadHandler = async file => {
|
|
80
|
+
const body = new FormData();
|
|
81
|
+
body.append('file', file);
|
|
82
|
+
const response = await fetch('/api/files', { method: 'POST', body });
|
|
83
|
+
return (await response.json()).url;
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## API
|
|
88
|
+
|
|
89
|
+
### `DocumentEditor` props
|
|
90
|
+
|
|
91
|
+
| Prop | Type | Default | Description |
|
|
92
|
+
| ----------------- | --------------------------------- | -------- | -------------------------------------------------------------------------- |
|
|
93
|
+
| `v-model` | `string` | `''` | Document HTML; an empty document is an empty string. |
|
|
94
|
+
| `v-model:page` | `PageSettings` | A4 | Paper size, orientation and margins. |
|
|
95
|
+
| `autofocus` | `boolean` | `false` | Places the caret at the end of the document once ready. |
|
|
96
|
+
| `canvasPadding` | `number \| string` | `50` | Gray space around the page or web sheet. |
|
|
97
|
+
| `defaultViewMode` | `'page' \| 'web'` | `'page'` | View shown first. |
|
|
98
|
+
| `disabled` | `boolean` | `false` | Read-only document, disabled controls. |
|
|
99
|
+
| `height` | `number \| string` | `760` | Height of the editor, or `'auto'` to grow between `minHeight`/`maxHeight`. |
|
|
100
|
+
| `minHeight` | `number \| string` | `240` | Smallest height of an auto-height editor. |
|
|
101
|
+
| `maxHeight` | `number \| string` | `600` | Largest height of an auto-height editor. |
|
|
102
|
+
| `maxImageSizeMb` | `number` | `10` | Largest accepted image file. |
|
|
103
|
+
| `maxLength` | `number` | `0` | Character limit; `0` means unlimited. |
|
|
104
|
+
| `placeholder` | `string` | `''` | Text shown while the document is empty. |
|
|
105
|
+
| `title` | `string` | `''` | Print title and exported file name. |
|
|
106
|
+
| `uploadImage` | `(file: File) => Promise<string>` | — | Uploads an image and resolves with its URL. |
|
|
107
|
+
|
|
108
|
+
`Editor` accepts the same props except `v-model:page`, `defaultViewMode`, `height` and `title`.
|
|
109
|
+
|
|
110
|
+
Numbers are pixels; strings are used as CSS lengths (`'100%'`, `'50vh'`).
|
|
111
|
+
|
|
112
|
+
### Events
|
|
113
|
+
|
|
114
|
+
| Event | Payload | Description |
|
|
115
|
+
| ------------- | ---------------- | ------------------------------------------------- |
|
|
116
|
+
| `focus` | — | The document received focus. |
|
|
117
|
+
| `blur` | — | The document lost focus; the model is up to date. |
|
|
118
|
+
| `uploadError` | `error: unknown` | An image was rejected or its upload failed. |
|
|
119
|
+
|
|
120
|
+
### Exposed methods (`DocumentEditor` ref)
|
|
121
|
+
|
|
122
|
+
| Method | Description |
|
|
123
|
+
| -------------- | ---------------------------------------------------------------- |
|
|
124
|
+
| `focus()` | Moves keyboard focus into the document. |
|
|
125
|
+
| `getHTML()` | Returns the document HTML, including edits not yet in the model. |
|
|
126
|
+
| `print()` | Opens the browser print dialog. |
|
|
127
|
+
| `exportHtml()` | Downloads the document as an HTML page. |
|
|
128
|
+
| `exportWord()` | Downloads the document as a Word-compatible `.doc` file. |
|
|
129
|
+
| `engine` | The editing engine, for advanced integrations. |
|
|
130
|
+
|
|
131
|
+
### Keyboard shortcuts
|
|
132
|
+
|
|
133
|
+
`Ctrl/⌘+B`, `I`, `U` — bold, italic, underline · `Ctrl/⌘+Shift+H` — highlight · `Ctrl/⌘+Z`, `Ctrl/⌘+Shift+Z` — undo,
|
|
134
|
+
redo · `Ctrl/⌘+F` — find · `Ctrl/⌘+H` — replace · `Ctrl/⌘+K` — link · `Ctrl/⌘+P` — print.
|
|
135
|
+
|
|
136
|
+
The full list, with Markdown-like input rules, is in the
|
|
137
|
+
[keyboard shortcuts guide](https://nuvra-docs.vercel.app/docs/keyboard-shortcuts).
|
|
138
|
+
|
|
139
|
+
## Translations
|
|
140
|
+
|
|
141
|
+
Built-in labels are in Uzbek. Every label has a key such as `editor.bold`; the full list with default texts is
|
|
142
|
+
exported as `editorMessages`. Register a translator once, before the app mounts. Returning `undefined` keeps the
|
|
143
|
+
built-in text for that key.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { setEditorTranslator } from 'nuvra';
|
|
147
|
+
|
|
148
|
+
const en: Record<string, string> = {
|
|
149
|
+
'editor.bold': 'Bold',
|
|
150
|
+
'editor.status.words': '{count} words'
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
setEditorTranslator((key, named) =>
|
|
154
|
+
en[key]?.replace(/\{(\w+)\}/g, (_, name) => String(named?.[name] ?? ''))
|
|
155
|
+
);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
With `vue-i18n`, labels follow the active locale:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { setEditorTranslator } from 'nuvra';
|
|
162
|
+
import { i18n } from './i18n';
|
|
163
|
+
|
|
164
|
+
setEditorTranslator((key, named) => (i18n.global.te(key) ? i18n.global.t(key, named ?? {}) : undefined));
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Theming
|
|
168
|
+
|
|
169
|
+
Colors come from CSS variables declared on `.document-editor` with zero specificity, so any rule that targets
|
|
170
|
+
`.document-editor` overrides them, whatever order the stylesheets load in. Set them on the editor element itself:
|
|
171
|
+
values on an ancestor such as `body` do not apply, because the editor declares its own.
|
|
172
|
+
|
|
173
|
+
```css
|
|
174
|
+
.document-editor {
|
|
175
|
+
--nuvra-color-primary: #7c3aed;
|
|
176
|
+
--nuvra-color-primary-hover: #8b5cf6;
|
|
177
|
+
--nuvra-color-primary-border: #c4b5fd;
|
|
178
|
+
--nuvra-color-primary-muted: #ddd6fe;
|
|
179
|
+
--nuvra-color-primary-soft: #f5f3ff;
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| Variable | Used for |
|
|
184
|
+
| ------------------------------- | ---------------------------------------------------- |
|
|
185
|
+
| `--nuvra-color-primary` | Active buttons, focus, primary buttons, selection |
|
|
186
|
+
| `--nuvra-color-primary-hover` | Hovered primary buttons |
|
|
187
|
+
| `--nuvra-color-primary-border` | Focused editor frame, disabled primary buttons |
|
|
188
|
+
| `--nuvra-color-primary-muted` | Table size preview, hovered button borders |
|
|
189
|
+
| `--nuvra-color-primary-soft` | Active button and menu item backgrounds |
|
|
190
|
+
| `--nuvra-color-on-primary` | Text on primary buttons |
|
|
191
|
+
| `--nuvra-color-danger` | Destructive actions, character limit reached |
|
|
192
|
+
| `--nuvra-color-danger-soft` | Hovered destructive actions |
|
|
193
|
+
| `--nuvra-text-strong` | Headings in forms |
|
|
194
|
+
| `--nuvra-text` | Regular text and icons |
|
|
195
|
+
| `--nuvra-text-muted` | Labels, captions, status bar |
|
|
196
|
+
| `--nuvra-text-placeholder` | Placeholders, shortcut hints |
|
|
197
|
+
| `--nuvra-text-disabled` | Disabled buttons |
|
|
198
|
+
| `--nuvra-border` | Editor frame, inputs |
|
|
199
|
+
| `--nuvra-border-hover` | Hovered inputs |
|
|
200
|
+
| `--nuvra-border-light` | Popovers and floating panels |
|
|
201
|
+
| `--nuvra-border-lighter` | Dividers |
|
|
202
|
+
| `--nuvra-fill` | Hovered buttons, segmented controls |
|
|
203
|
+
| `--nuvra-bg` | Toolbar, status bar, inputs |
|
|
204
|
+
| `--nuvra-bg-overlay` | Popovers, menus, find bar |
|
|
205
|
+
| `--nuvra-shadow` | Popovers and floating panels |
|
|
206
|
+
| `--nuvra-fullscreen-z-index` | Stacking order of the fullscreen editor (`2000`) |
|
|
207
|
+
|
|
208
|
+
A dark palette is applied when an ancestor (usually `<html>`) has the `dark` class or `data-theme="dark"`. To change
|
|
209
|
+
dark values separately, target `.dark .document-editor`.
|
|
210
|
+
|
|
211
|
+
To follow an Element Plus theme, map the variables to its own:
|
|
212
|
+
|
|
213
|
+
```css
|
|
214
|
+
.document-editor {
|
|
215
|
+
--nuvra-color-primary: var(--el-color-primary);
|
|
216
|
+
--nuvra-color-primary-soft: var(--el-color-primary-light-9);
|
|
217
|
+
--nuvra-text: var(--el-text-color-regular);
|
|
218
|
+
--nuvra-border: var(--el-border-color);
|
|
219
|
+
--nuvra-bg: var(--el-bg-color);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Browser support
|
|
224
|
+
|
|
225
|
+
Popovers, menus and bubble toolbars use the [Popover API](https://developer.mozilla.org/docs/Web/API/Popover_API)
|
|
226
|
+
(Chrome/Edge 114+, Safari 17+, Firefox 125+), which keeps them above dialogs and the fullscreen editor. Older browsers
|
|
227
|
+
show them as fixed elements instead. Search highlighting uses the CSS Custom Highlight API.
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
[MIT](./LICENSE). Icon shapes come from [Lucide](https://lucide.dev) (ISC).
|
|
@@ -26,6 +26,8 @@ interface Props {
|
|
|
26
26
|
minHeight?: CssSize;
|
|
27
27
|
/** Text shown while the document is empty; falls back to the translated default placeholder. */
|
|
28
28
|
placeholder?: string;
|
|
29
|
+
/** Shows the ruler above the sheet in the page view; users can also toggle it in the document menu. */
|
|
30
|
+
ruler?: boolean;
|
|
29
31
|
/** Used as the print title and the exported file name. */
|
|
30
32
|
title?: string;
|
|
31
33
|
/** Uploads an inserted image and resolves with its URL; without it images are embedded as data URLs. */
|
|
@@ -67,6 +69,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
67
69
|
}>, {
|
|
68
70
|
title: string;
|
|
69
71
|
height: CssSize;
|
|
72
|
+
ruler: boolean;
|
|
70
73
|
placeholder: string;
|
|
71
74
|
disabled: boolean;
|
|
72
75
|
minHeight: CssSize;
|
|
@@ -1,16 +1,31 @@
|
|
|
1
|
+
import type { ParagraphIndents } from '../core/engine/blocks';
|
|
1
2
|
import type { DocumentEngine } from '../core/engine/engine';
|
|
2
|
-
import type
|
|
3
|
+
import { type DocumentViewMode, type PageHeaderFooter, type PageMargins, type PageMetrics, type PageWatermark } from '../core/page';
|
|
3
4
|
interface Props {
|
|
4
5
|
/** Grow with the content between the editor's min and max height instead of filling a fixed height. */
|
|
5
6
|
autoHeight: boolean;
|
|
7
|
+
/** Read-only document: the ruler is shown but cannot be dragged. */
|
|
8
|
+
disabled: boolean | undefined;
|
|
9
|
+
/** Document title, used by the `{title}` token of the header and footer. */
|
|
10
|
+
documentTitle: string;
|
|
6
11
|
/** Engine working on the editable element; `null` until the parent has created it. */
|
|
7
12
|
engine: DocumentEngine | null;
|
|
13
|
+
/** Text repeated in the bottom margin of every sheet. */
|
|
14
|
+
footer?: PageHeaderFooter;
|
|
15
|
+
/** Text repeated in the top margin of every sheet. */
|
|
16
|
+
header?: PageHeaderFooter;
|
|
17
|
+
/** Indents of the paragraph at the caret, shown by the ruler. */
|
|
18
|
+
indents: ParagraphIndents;
|
|
8
19
|
/** Page size and margins in pixels. */
|
|
9
20
|
metrics: PageMetrics;
|
|
10
21
|
/** Number of sheets drawn behind the content in page view. */
|
|
11
22
|
pageCount: number;
|
|
23
|
+
/** Whether the ruler is drawn above the sheet; it is only ever shown in the page view. */
|
|
24
|
+
rulerVisible: boolean;
|
|
12
25
|
/** Paginated sheets or a single web sheet. */
|
|
13
26
|
viewMode: DocumentViewMode;
|
|
27
|
+
/** Watermark drawn behind the text of every sheet. */
|
|
28
|
+
watermark?: PageWatermark;
|
|
14
29
|
/** Zoom in percent. */
|
|
15
30
|
zoom: number;
|
|
16
31
|
}
|
|
@@ -23,8 +38,14 @@ declare const __VLS_export: import("vue").DefineComponent<Props, {
|
|
|
23
38
|
scrollElement: import("vue").Ref<HTMLElement | undefined, HTMLElement | undefined>;
|
|
24
39
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
25
40
|
resize: (contentWidth: number) => any;
|
|
41
|
+
zoom: (delta: number) => any;
|
|
42
|
+
updateMargins: (margins: Pick<PageMargins, "right" | "left">) => any;
|
|
43
|
+
updateIndents: (indents: Partial<ParagraphIndents>) => any;
|
|
26
44
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
27
45
|
onResize?: ((contentWidth: number) => any) | undefined;
|
|
46
|
+
onZoom?: ((delta: number) => any) | undefined;
|
|
47
|
+
onUpdateMargins?: ((margins: Pick<PageMargins, "right" | "left">) => any) | undefined;
|
|
48
|
+
onUpdateIndents?: ((indents: Partial<ParagraphIndents>) => any) | undefined;
|
|
28
49
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
29
50
|
declare const _default: typeof __VLS_export;
|
|
30
51
|
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DocumentEngine } from '../core/engine/engine';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** A read-only document only offers copying and selecting. */
|
|
4
|
+
disabled: boolean | undefined;
|
|
5
|
+
/** Engine the entries act on. */
|
|
6
|
+
engine: DocumentEngine;
|
|
7
|
+
}
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
editLink: () => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
11
|
+
onEditLink?: (() => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type PageSettings } from '../core/page';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Settings currently applied to the document. */
|
|
4
|
+
page: PageSettings;
|
|
5
|
+
}
|
|
6
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
7
|
+
change: (page: PageSettings) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
9
|
+
onChange?: ((page: PageSettings) => any) | undefined;
|
|
10
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
|
+
declare const _default: typeof __VLS_export;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ParagraphIndents } from '../core/engine/blocks';
|
|
2
|
+
import type { PageMargins, PageMetrics } from '../core/page';
|
|
3
|
+
interface Props {
|
|
4
|
+
/** Read-only documents show the ruler but do not let it be dragged. */
|
|
5
|
+
disabled: boolean | undefined;
|
|
6
|
+
/** Indents of the paragraph at the caret, in pixels. */
|
|
7
|
+
indents: ParagraphIndents;
|
|
8
|
+
/** Page geometry in pixels. */
|
|
9
|
+
metrics: PageMetrics;
|
|
10
|
+
/** Zoom in percent, which the ruler is drawn at. */
|
|
11
|
+
zoom: number;
|
|
12
|
+
}
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
updateMargins: (margins: Pick<PageMargins, "right" | "left">) => any;
|
|
15
|
+
updateIndents: (indents: Partial<ParagraphIndents>) => any;
|
|
16
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
17
|
+
onUpdateMargins?: ((margins: Pick<PageMargins, "right" | "left">) => any) | undefined;
|
|
18
|
+
onUpdateIndents?: ((indents: Partial<ParagraphIndents>) => any) | undefined;
|
|
19
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
declare const _default: typeof __VLS_export;
|
|
21
|
+
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DocumentEngine } from '../core/engine/engine';
|
|
2
|
-
import type
|
|
2
|
+
import { type PageSettings } from '../core/page';
|
|
3
3
|
import type { DocumentMenuAction } from '../core/types';
|
|
4
4
|
import { type EditorUiState } from '../core/ui-state';
|
|
5
5
|
interface Props {
|
|
@@ -11,8 +11,12 @@ interface Props {
|
|
|
11
11
|
findOpen: boolean;
|
|
12
12
|
/** Whether the editor is in fullscreen, used for the menu item label. */
|
|
13
13
|
fullscreen: boolean;
|
|
14
|
+
/** Whether the formatting marks (pilcrows) are shown in the document. */
|
|
15
|
+
marksVisible: boolean;
|
|
14
16
|
/** Current page settings, edited in the page setup popover. */
|
|
15
17
|
page: PageSettings;
|
|
18
|
+
/** Whether the ruler is shown above the sheet. */
|
|
19
|
+
rulerVisible: boolean;
|
|
16
20
|
/** Whether the HTML source is shown; formatting controls are disabled meanwhile. */
|
|
17
21
|
sourceMode: boolean;
|
|
18
22
|
/** Formatting at the caret, used for active states and labels. */
|
|
@@ -23,6 +23,31 @@ export declare const setTextAlign: (root: HTMLElement, range: Range, align: Text
|
|
|
23
23
|
export declare const setLineHeight: (root: HTMLElement, range: Range, lineHeight: string | null) => void;
|
|
24
24
|
/** Sets the writing direction of the selected blocks; `auto` lets each paragraph follow its own text. */
|
|
25
25
|
export declare const setTextDirection: (root: HTMLElement, range: Range, direction: TextDirection) => void;
|
|
26
|
+
/** Side of a paragraph that can keep extra space, as in the paragraph settings of office suites. */
|
|
27
|
+
export type SpacingSide = 'before' | 'after';
|
|
28
|
+
/** Space a block keeps on one side, in points; `0` when it uses the document default. */
|
|
29
|
+
export declare const paragraphSpacing: (block: HTMLElement, side: SpacingSide) => number;
|
|
30
|
+
/**
|
|
31
|
+
* Sets the space before or after the selected paragraphs, in points; `null` restores the document default. The gap
|
|
32
|
+
* pagination may have added is dropped, because it is written into the same margin and is recomputed anyway.
|
|
33
|
+
*/
|
|
34
|
+
export declare const setParagraphSpacing: (root: HTMLElement, range: Range, side: SpacingSide, points: number | null) => void;
|
|
35
|
+
/** Paragraph indents in CSS pixels, the exact distances the ruler drags. */
|
|
36
|
+
export interface ParagraphIndents {
|
|
37
|
+
/** Distance the paragraph keeps from the left text edge. */
|
|
38
|
+
left: number;
|
|
39
|
+
/** Distance it keeps from the right text edge. */
|
|
40
|
+
right: number;
|
|
41
|
+
/** Extra distance of its first line; a negative value hangs the first line out to the left. */
|
|
42
|
+
firstLine: number;
|
|
43
|
+
}
|
|
44
|
+
/** Indents of a block; a block without them uses zero. */
|
|
45
|
+
export declare const paragraphIndents: (block: HTMLElement) => ParagraphIndents;
|
|
46
|
+
/**
|
|
47
|
+
* Sets exact indents on the selected paragraphs; a side left out of `patch` keeps its value. Exact indents replace
|
|
48
|
+
* the stepped indentation of the toolbar buttons, so the step attribute is dropped with them.
|
|
49
|
+
*/
|
|
50
|
+
export declare const setParagraphIndents: (root: HTMLElement, range: Range, patch: Partial<ParagraphIndents>) => void;
|
|
26
51
|
/**
|
|
27
52
|
* Moves the selected paragraphs outside lists by whole indentation steps.
|
|
28
53
|
* @returns whether any block's indentation changed.
|