stilo-editor 0.1.0 → 0.2.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.
Files changed (57) hide show
  1. package/README.md +61 -7
  2. package/dist/content.css +238 -1
  3. package/dist/core/editor.d.ts +15 -3
  4. package/dist/core/extension-manager.d.ts +3 -3
  5. package/dist/core/extension.d.ts +6 -1
  6. package/dist/core/helpers/block-style.d.ts +25 -0
  7. package/dist/core/helpers/input-rules.d.ts +8 -1
  8. package/dist/core/helpers/lists.d.ts +10 -2
  9. package/dist/core/helpers/marks.d.ts +14 -0
  10. package/dist/core/helpers/nodes.d.ts +12 -0
  11. package/dist/core/helpers/word-count.d.ts +14 -0
  12. package/dist/core/html/css.d.ts +16 -1
  13. package/dist/core/html/paste/base-styles.d.ts +7 -0
  14. package/dist/core/html/paste/google-docs.d.ts +7 -0
  15. package/dist/core/html/paste/index.d.ts +9 -0
  16. package/dist/core/html/paste/table-widths.d.ts +7 -0
  17. package/dist/core/html/paste/word.d.ts +8 -0
  18. package/dist/core/html/serialize.d.ts +2 -2
  19. package/dist/extensions/code-block/index.d.ts +24 -0
  20. package/dist/extensions/default-extensions/index.d.ts +11 -0
  21. package/dist/extensions/heading/index.d.ts +2 -1
  22. package/dist/extensions/image/image-view.d.ts +27 -0
  23. package/dist/extensions/image/index.d.ts +29 -0
  24. package/dist/extensions/index.d.ts +10 -1
  25. package/dist/extensions/line-height/index.d.ts +18 -0
  26. package/dist/extensions/list-item/index.d.ts +1 -1
  27. package/dist/extensions/paragraph/index.d.ts +4 -4
  28. package/dist/extensions/search/index.d.ts +55 -0
  29. package/dist/extensions/table/index.d.ts +70 -0
  30. package/dist/extensions/task-item/index.d.ts +24 -0
  31. package/dist/extensions/task-item/task-item-view.d.ts +24 -0
  32. package/dist/extensions/task-list/index.d.ts +11 -0
  33. package/dist/extensions/text-align/index.d.ts +18 -0
  34. package/dist/extensions/text-case/index.d.ts +14 -0
  35. package/dist/extensions/text-style/font-size.d.ts +21 -0
  36. package/dist/extensions/text-style/index.d.ts +18 -2
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.js +1 -1
  39. package/dist/src-CV6pgfTS.js +2662 -0
  40. package/dist/style.css +599 -1
  41. package/dist/ui/components/dropdown.d.ts +9 -0
  42. package/dist/ui/components/find-bar.d.ts +24 -0
  43. package/dist/ui/components/font-size-input.d.ts +21 -0
  44. package/dist/ui/components/icon-menu.d.ts +20 -0
  45. package/dist/ui/components/status-bar.d.ts +19 -0
  46. package/dist/ui/components/table-actions.d.ts +25 -0
  47. package/dist/ui/components/table-handles.d.ts +16 -0
  48. package/dist/ui/components/table-menu.d.ts +21 -0
  49. package/dist/ui/i18n/types.d.ts +1 -1
  50. package/dist/ui/index.d.ts +6 -2
  51. package/dist/ui/toolbar/fonts.d.ts +8 -0
  52. package/dist/ui/toolbar/items.d.ts +23 -2
  53. package/dist/ui/toolbar/types.d.ts +67 -4
  54. package/dist/ui.css +361 -0
  55. package/dist/ui.js +1361 -303
  56. package/package.json +18 -8
  57. package/dist/src-3tAxKI0c.js +0 -1316
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Cleans pasted HTML before it is sanitized (docs/ARCHITECTURE.md §8). The HTML is parsed with an
3
+ * inert `DOMParser` (no scripts run, no images load), then:
4
+ *
5
+ * - from Microsoft Word or Google Docs: their own cleanup, then {@link removeBaseStyles};
6
+ * - a heading that starts a list item becomes a paragraph (a list item starts with one);
7
+ * - tables keep the column widths they carry ({@link readTableWidths}).
8
+ */
9
+ export declare function cleanPastedHTML(html: string): string;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Writes the column widths a pasted table carries as `data-colwidth` on its cells
3
+ * (docs/decisions/0005): from its `<col>` elements (`width` attribute or `style="width"`), else
4
+ * from the cells that span one column. Only pixel widths count; a table without them, or whose
5
+ * cells already have `data-colwidth`, is left as it is.
6
+ */
7
+ export declare function readTableWidths(body: HTMLElement): void;
@@ -0,0 +1,8 @@
1
+ /** Markers of the HTML that Microsoft Word puts on the clipboard. */
2
+ export declare const WORD_HTML: RegExp;
3
+ /**
4
+ * Cleans the HTML of Microsoft Word: removes the `<o:p>` paragraph ends and turns its list
5
+ * paragraphs (`style="mso-list: l0 level1 lfo1"`, the marker in a `mso-list: Ignore` span) into
6
+ * nested `<ul>` / `<ol>`.
7
+ */
8
+ export declare function cleanWord(body: HTMLElement): void;
@@ -1,13 +1,13 @@
1
1
  import { DOMSerializer, type Fragment, type Schema } from 'prosemirror-model';
2
2
  /** Options of {@link serializeHTML}. */
3
3
  export interface SerializeOptions {
4
- /** Unwrap the single paragraph of list items. Default: `true`. */
4
+ /** Unwrap the single paragraph of list items and table cells. Default: `true`. */
5
5
  compactParagraphs?: boolean;
6
6
  }
7
7
  /**
8
8
  * Canonical post-processing of serialized HTML, in place (docs/ARCHITECTURE.md §8.1): styles
9
9
  * rewritten with `sanitizeStyle`, and with `compactParagraphs` (default) the single paragraph of
10
- * list items unwrapped (docs/decisions/0001).
10
+ * list items and table cells unwrapped (docs/decisions/0001).
11
11
  */
12
12
  export declare function canonicalizeDOM(root: Element | DocumentFragment, options?: SerializeOptions): void;
13
13
  /**
@@ -0,0 +1,24 @@
1
+ import { type Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /**
5
+ * Turns the selected textblocks into one code block (sibling blocks are joined, one line
6
+ * each), or sets the language of the code block.
7
+ */
8
+ setCodeBlock: (attrs?: CodeBlockAttributes) => Command;
9
+ /** Turns the selected code blocks into paragraphs, one per line. */
10
+ unsetCodeBlock: () => Command;
11
+ /** Removes the code block if active, otherwise adds it. */
12
+ toggleCodeBlock: (attrs?: CodeBlockAttributes) => Command;
13
+ }
14
+ }
15
+ /** Attributes of the `codeBlock` node. */
16
+ export interface CodeBlockAttributes {
17
+ /** The language, written as `class="language-<language>"`; `null` for none. */
18
+ language?: string | null;
19
+ }
20
+ /**
21
+ * The `codeBlock` node (`<pre><code class="language-x">`), plain text without marks,
22
+ * docs/SPEC.md F-306.
23
+ */
24
+ export declare const CodeBlock: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -2,7 +2,9 @@ import type { Extension } from '../../core/extension';
2
2
  import { type DropCursorOptions } from '../drop-cursor';
3
3
  import { type HeadingOptions } from '../heading';
4
4
  import { type HistoryOptions } from '../history';
5
+ import { type ImageOptions } from '../image';
5
6
  import { type PlaceholderOptions } from '../placeholder';
7
+ import { type SearchOptions } from '../search';
6
8
  /**
7
9
  * Options of {@link defaultExtensions}, by extension name: `false` disables the extension, an object
8
10
  * configures it. Extensions without options accept only `false`.
@@ -13,11 +15,16 @@ export interface DefaultExtensionsOptions {
13
15
  paragraph?: false;
14
16
  heading?: false | Partial<HeadingOptions>;
15
17
  blockquote?: false;
18
+ codeBlock?: false;
16
19
  horizontalRule?: false;
20
+ image?: false | Partial<ImageOptions>;
21
+ table?: false;
17
22
  hardBreak?: false;
18
23
  bulletList?: false;
19
24
  orderedList?: false;
20
25
  listItem?: false;
26
+ taskList?: false;
27
+ taskItem?: false;
21
28
  bold?: false;
22
29
  italic?: false;
23
30
  underline?: false;
@@ -27,11 +34,15 @@ export interface DefaultExtensionsOptions {
27
34
  code?: false;
28
35
  link?: false;
29
36
  textStyle?: false;
37
+ textAlign?: false;
38
+ lineHeight?: false;
30
39
  highlight?: false;
31
40
  clearFormatting?: false;
41
+ textCase?: false;
32
42
  history?: false | Partial<HistoryOptions>;
33
43
  moveBlock?: false;
34
44
  placeholder?: false | Partial<PlaceholderOptions>;
45
+ search?: false | Partial<SearchOptions>;
35
46
  dropCursor?: false | Partial<DropCursorOptions>;
36
47
  gapCursor?: false;
37
48
  }
@@ -19,6 +19,7 @@ export interface HeadingOptions {
19
19
  levels: HeadingLevel[];
20
20
  }
21
21
  /**
22
- * The `heading` node (`<h1>`…`<h6>`), docs/SPEC.md F-302.
22
+ * The `heading` node (`<h1>`…`<h6>`, with `style` for its alignment and line height),
23
+ * docs/SPEC.md F-302.
23
24
  */
24
25
  export declare const Heading: (options?: Partial<HeadingOptions> | undefined) => import("../..").Extension<HeadingOptions>;
@@ -0,0 +1,27 @@
1
+ import type { Node } from 'prosemirror-model';
2
+ import type { EditorView, NodeView } from 'prosemirror-view';
3
+ /** The HTML attributes of an `image` node, in output order, without the empty ones. */
4
+ export declare function imageAttributes(node: Node): Record<string, string>;
5
+ /**
6
+ * The `image` node in the editor: the `<img>` inside a `span.stilo-image` with two side handles,
7
+ * shown while the image is selected (docs/SPEC.md F-607). Dragging a handle changes the width
8
+ * and keeps the aspect ratio; releasing it sets `width` and `height` in one transaction.
9
+ */
10
+ export declare class ImageView implements NodeView {
11
+ private readonly view;
12
+ private readonly getPos;
13
+ readonly dom: HTMLElement;
14
+ private readonly img;
15
+ private node;
16
+ constructor(node: Node, view: EditorView, getPos: () => number | undefined);
17
+ update(node: Node): boolean;
18
+ /** The handles handle their own pointer events: ProseMirror must not select or drag. */
19
+ stopEvent(event: Event): boolean;
20
+ /** The view changes only the inline width of the `<img>` while a handle is dragged. */
21
+ ignoreMutation(): boolean;
22
+ private render;
23
+ private createHandle;
24
+ private startResize;
25
+ /** Sets `width` and `height`; attribute steps keep the image selected. */
26
+ private setSize;
27
+ }
@@ -0,0 +1,29 @@
1
+ import type { Editor } from '../../core/editor';
2
+ declare module '../../core/types' {
3
+ interface EditorEvents {
4
+ /**
5
+ * A pasted image file was not inserted: larger than `maxInlineBytes` (`tooLarge`), or not a
6
+ * PNG, JPEG, GIF or WebP image (`unsupportedType`).
7
+ */
8
+ imageRejected: {
9
+ editor: Editor;
10
+ file: File;
11
+ reason: 'tooLarge' | 'unsupportedType';
12
+ };
13
+ }
14
+ }
15
+ /** Options of {@link Image}. */
16
+ export interface ImageOptions {
17
+ /** Largest image file, in bytes, that paste inserts as a data URL. Default: 5 MB. */
18
+ maxInlineBytes: number;
19
+ }
20
+ /**
21
+ * The `image` node (`<img src alt title width height>`, inline), docs/SPEC.md F-601, with the
22
+ * paste of image files (F-603, F-608) and the resize handles (F-607).
23
+ *
24
+ * Paste: when the clipboard has HTML, ProseMirror pastes it (an image copied from a web page keeps
25
+ * its URL); otherwise each image file becomes an `image` with a base64 `data:` URL, in place of
26
+ * the selection at the time the files have been read. A file larger than `maxInlineBytes` or of
27
+ * another type is skipped and reported with the `imageRejected` event.
28
+ */
29
+ export declare const Image: (options?: Partial<ImageOptions> | undefined) => import("../..").Extension<ImageOptions>;
@@ -3,6 +3,7 @@ export { Bold } from './bold';
3
3
  export { BulletList } from './bullet-list';
4
4
  export { ClearFormatting } from './clear-formatting';
5
5
  export { Code } from './code';
6
+ export { CodeBlock, type CodeBlockAttributes } from './code-block';
6
7
  export { type DefaultExtensionsOptions, defaultExtensions } from './default-extensions';
7
8
  export { Document } from './document';
8
9
  export { DropCursor, type DropCursorOptions } from './drop-cursor';
@@ -12,16 +13,24 @@ export { Heading, type HeadingLevel, type HeadingOptions } from './heading';
12
13
  export { Highlight, type HighlightAttributes } from './highlight';
13
14
  export { History, type HistoryOptions } from './history';
14
15
  export { HorizontalRule } from './horizontal-rule';
16
+ export { Image, type ImageOptions } from './image';
15
17
  export { Italic } from './italic';
18
+ export { LineHeight } from './line-height';
16
19
  export { Link, type LinkAttributes } from './link';
17
20
  export { ListItem } from './list-item';
18
21
  export { MoveBlock } from './move-block';
19
22
  export { OrderedList } from './ordered-list';
20
23
  export { Paragraph } from './paragraph';
21
24
  export { Placeholder, type PlaceholderOptions } from './placeholder';
25
+ export { getSearchResults, Search, type SearchOptions, type SearchResults, type SearchTerm, } from './search';
22
26
  export { Strike } from './strike';
23
27
  export { Subscript } from './subscript';
24
28
  export { Superscript } from './superscript';
29
+ export { getTableHeaders, type InsertTableOptions, Table, type TableHeaders, } from './table';
30
+ export { TaskItem } from './task-item';
31
+ export { TaskList } from './task-list';
25
32
  export { Text } from './text';
26
- export { TextStyle } from './text-style';
33
+ export { TextAlign, type TextAlignment } from './text-align';
34
+ export { type LetterCase, TextCase } from './text-case';
35
+ export { type FontSizeUnit, getFontSize, TextStyle, toFontSize } from './text-style';
27
36
  export { Underline } from './underline';
@@ -0,0 +1,18 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /**
5
+ * Sets the line height of the selected paragraphs and headings: a number (`1.5`) or a
6
+ * percentage (`'150%'`). `false` for another value, or when no selected block has one.
7
+ */
8
+ setLineHeight: (lineHeight: number | string) => Command;
9
+ /** Removes the line height of the selected paragraphs and headings. */
10
+ unsetLineHeight: () => Command;
11
+ }
12
+ }
13
+ /**
14
+ * Line spacing of paragraphs and headings (docs/SPEC.md F-312): the commands. The `lineHeight`
15
+ * attribute itself belongs to the `paragraph` and `heading` nodes, so content keeps its line
16
+ * spacing without this extension.
17
+ */
18
+ export declare const LineHeight: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -1,4 +1,4 @@
1
- import { type Command } from 'prosemirror-state';
1
+ import type { Command } from 'prosemirror-state';
2
2
  declare module '../../core/types' {
3
3
  interface Commands {
4
4
  /** Splits the list item at the cursor; in an empty item, lifts it out of the list. */
@@ -6,9 +6,9 @@ declare module '../../core/types' {
6
6
  }
7
7
  }
8
8
  /**
9
- * The `paragraph` node (`<p>`). Priority 1000 makes it the first block node, which ProseMirror
10
- * uses as the default block. `<div>` needs no parse rule: ProseMirror treats it as a block
11
- * wrapper and wraps its loose inline content in paragraphs (the `div` fallback of
12
- * docs/ARCHITECTURE.md §7.1).
9
+ * The `paragraph` node (`<p>`, with `style` for its alignment and line height). Priority 1000
10
+ * makes it the first block node, which ProseMirror uses as the default block. `<div>` needs no
11
+ * parse rule: ProseMirror treats it as a block wrapper and wraps its loose inline content in
12
+ * paragraphs (the `div` fallback of docs/ARCHITECTURE.md §7.1).
13
13
  */
14
14
  export declare const Paragraph: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,55 @@
1
+ import { type Command } from 'prosemirror-state';
2
+ import type { Editor } from '../../core/editor';
3
+ declare module '../../core/types' {
4
+ interface Commands {
5
+ /** Searches for `term` and highlights the matches; an empty `text` clears the search. */
6
+ setSearch: (term: SearchTerm) => Command;
7
+ /** Clears the search and its highlights. */
8
+ clearSearch: () => Command;
9
+ /** Selects the next match after the selection, wrapping at the end of the document. */
10
+ findNext: () => Command;
11
+ /** Selects the match before the selection, wrapping at the start of the document. */
12
+ findPrevious: () => Command;
13
+ /** Replaces the selected match with `replacement` and selects the next one. */
14
+ replaceNext: (replacement: string) => Command;
15
+ /** Replaces every match with `replacement`, in one undoable step. */
16
+ replaceAll: (replacement: string) => Command;
17
+ }
18
+ }
19
+ /** What {@link Search} looks for. */
20
+ export interface SearchTerm {
21
+ /** The text to find, taken literally. */
22
+ text: string;
23
+ /** Default: `false`. */
24
+ caseSensitive?: boolean;
25
+ /** Matches only whole words. Default: `false`. */
26
+ wholeWord?: boolean;
27
+ }
28
+ /** Options of {@link Search}. */
29
+ export interface SearchOptions {
30
+ /** Highlights at most the first this many matches; all are counted. Default: 1000. */
31
+ maxMatches: number;
32
+ }
33
+ /** The matches of the active search, from {@link getSearchResults}. */
34
+ export interface SearchResults {
35
+ /** The number of matches in the document. */
36
+ count: number;
37
+ /** `true` when only the first `maxMatches` matches are highlighted. */
38
+ limited: boolean;
39
+ /** The 1-based index of the selected match; 0 when the selection is not a match. */
40
+ current: number;
41
+ }
42
+ /**
43
+ * The matches of the active search of `editor`: how many there are, whether only some are
44
+ * highlighted, and which one is selected. All zero without a search or without the
45
+ * {@link Search} extension.
46
+ */
47
+ export declare function getSearchResults(editor: Editor): SearchResults;
48
+ /**
49
+ * Find and replace, docs/SPEC.md F-902 (ADR 0004). Matching follows `SearchQuery` of
50
+ * `prosemirror-search` (literal text, case, whole word); the matches get
51
+ * `class="stilo-search-match"`, the selected one also `stilo-search-match--current`.
52
+ * Setting a search scans and counts the whole document once; later edits rescan only the
53
+ * changed textblocks.
54
+ */
55
+ export declare const Search: (options?: Partial<SearchOptions> | undefined) => import("../..").Extension<SearchOptions>;
@@ -0,0 +1,70 @@
1
+ import { type Command } from 'prosemirror-state';
2
+ import { type Editor } from '../../core/editor';
3
+ declare module '../../core/types' {
4
+ interface Commands {
5
+ /**
6
+ * Inserts a table in place of the selection, the cursor in its first cell. `false` inside a
7
+ * table, or for `rows` / `cols` that are not whole numbers ≥ 1.
8
+ */
9
+ insertTable: (options?: InsertTableOptions) => Command;
10
+ /** Deletes the table around the selection. */
11
+ deleteTable: () => Command;
12
+ /** Adds a row above the selected cells. */
13
+ addRowBefore: () => Command;
14
+ /** Adds a row below the selected cells. */
15
+ addRowAfter: () => Command;
16
+ /** Deletes the rows of the selected cells; `false` when they are all the rows. */
17
+ deleteRow: () => Command;
18
+ /** Adds a column left of the selected cells. */
19
+ addColumnBefore: () => Command;
20
+ /** Adds a column right of the selected cells. */
21
+ addColumnAfter: () => Command;
22
+ /** Deletes the columns of the selected cells; `false` when they are all the columns. */
23
+ deleteColumn: () => Command;
24
+ /** Merges the selected cells into one (a rectangle of at least two cells). */
25
+ mergeCells: () => Command;
26
+ /** Splits a merged cell back into single cells. */
27
+ splitCell: () => Command;
28
+ /** Turns the first row into header cells (`<th>`), or back. */
29
+ toggleHeaderRow: () => Command;
30
+ /** Turns the first column into header cells (`<th>`), or back. */
31
+ toggleHeaderColumn: () => Command;
32
+ /**
33
+ * Selects the cells of the row of the cell around `pos` (default: the selection's head);
34
+ * `false` outside a table.
35
+ */
36
+ selectRow: (pos?: number) => Command;
37
+ /** Selects the cells of the column of the cell around `pos`, as `selectRow`. */
38
+ selectColumn: (pos?: number) => Command;
39
+ /** Selects every cell of the table around `pos`, as `selectRow`. */
40
+ selectTable: (pos?: number) => Command;
41
+ /** Moves the cursor to the next cell; in the last cell, adds a row first. */
42
+ goToNextCell: () => Command;
43
+ /** Moves the cursor to the previous cell. */
44
+ goToPreviousCell: () => Command;
45
+ }
46
+ }
47
+ /** Options of the `insertTable` command. */
48
+ export interface InsertTableOptions {
49
+ /** Number of rows, header row included. Default: 3. */
50
+ rows?: number;
51
+ /** Number of columns. Default: 3. */
52
+ cols?: number;
53
+ /** Makes the first row of header cells (`<th>`). Default: `true`. */
54
+ withHeaderRow?: boolean;
55
+ }
56
+ /** Whether the first row and the first column of a table are made of header cells. */
57
+ export interface TableHeaders {
58
+ row: boolean;
59
+ column: boolean;
60
+ }
61
+ /**
62
+ * Whether the first row and the first column of the table around the selection are made of
63
+ * header cells; `null` outside a table. For a UI showing the state of the header toggles.
64
+ */
65
+ export declare function getTableHeaders(editor: Editor): TableHeaders | null;
66
+ /**
67
+ * The `table`, `tableRow`, `tableCell` and `tableHeader` nodes (`<table><tbody><tr><td|th>`),
68
+ * on `prosemirror-tables`, docs/SPEC.md F-501…F-507. Column widths: docs/decisions/0005.
69
+ */
70
+ export declare const Table: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,24 @@
1
+ import { type Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /**
5
+ * Splits the task item at the cursor: the text keeps the item's state, a new empty item is
6
+ * unchecked. In an empty item, lifts it.
7
+ */
8
+ splitTaskItem: () => Command;
9
+ /** Nests the selected task items one level deeper. */
10
+ sinkTaskItem: () => Command;
11
+ /** Lifts the selected task items one level up (out of the list at the top level). */
12
+ liftTaskItem: () => Command;
13
+ /**
14
+ * Checks the selected task items, or unchecks them when all are checked. `false` outside a
15
+ * task item and in a code block.
16
+ */
17
+ toggleTaskChecked: () => Command;
18
+ }
19
+ }
20
+ /**
21
+ * The `taskItem` node (`<li data-checked="true|false">`), docs/SPEC.md F-406. Required by
22
+ * `TaskList`. In the editor, a node view draws the checkbox (`TaskItemView`).
23
+ */
24
+ export declare const TaskItem: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,24 @@
1
+ import type { Node } from 'prosemirror-model';
2
+ import type { EditorView, NodeView, ViewMutationRecord } from 'prosemirror-view';
3
+ /**
4
+ * The `taskItem` node in the editor: `<li data-checked>` holding a checkbox
5
+ * (`input.stilo-task-item__checkbox`) and the content (`div.stilo-task-item__content`). Clicking
6
+ * the checkbox sets `checked`; it leaves the focus in the editor and does nothing when the editor
7
+ * is not editable.
8
+ */
9
+ export declare class TaskItemView implements NodeView {
10
+ private readonly view;
11
+ private readonly getPos;
12
+ readonly dom: HTMLElement;
13
+ readonly contentDOM: HTMLElement;
14
+ private readonly checkbox;
15
+ private node;
16
+ constructor(node: Node, view: EditorView, getPos: () => number | undefined);
17
+ update(node: Node): boolean;
18
+ /** The checkbox handles its own events: ProseMirror must not move the selection. */
19
+ stopEvent(event: Event): boolean;
20
+ /** Only the content is ProseMirror's: the checkbox and the `data-checked` are the view's. */
21
+ ignoreMutation(mutation: ViewMutationRecord): boolean;
22
+ private render;
23
+ private setChecked;
24
+ }
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /** Wraps the selection in a task list, lifts it out, or converts another list type. */
5
+ toggleTaskList: () => Command;
6
+ }
7
+ }
8
+ /**
9
+ * The `taskList` node (`<ul data-type="taskList">`), docs/SPEC.md F-406. Requires `TaskItem`.
10
+ */
11
+ export declare const TaskList: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,18 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ import type { TextAlignment } from '../../core/helpers/block-style';
3
+ declare module '../../core/types' {
4
+ interface Commands {
5
+ /**
6
+ * Aligns the selected paragraphs and headings. `false` for another value, or when no
7
+ * selected block can be aligned.
8
+ */
9
+ setTextAlign: (alignment: TextAlignment) => Command;
10
+ }
11
+ }
12
+ /**
13
+ * Text alignment of paragraphs and headings (docs/SPEC.md F-308): the command and its
14
+ * shortcuts. The `textAlign` attribute itself belongs to the `paragraph` and `heading` nodes, so
15
+ * aligned content keeps its alignment without this extension.
16
+ */
17
+ export declare const TextAlign: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
18
+ export type { TextAlignment } from '../../core/helpers/block-style';
@@ -0,0 +1,14 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ /**
3
+ * A letter case: `upper` (UPPERCASE), `lower` (lowercase), `title` (Title Case), `sentence`
4
+ * (Sentence case), `toggle` (tOGGLE cASE).
5
+ */
6
+ export type LetterCase = 'upper' | 'lower' | 'title' | 'sentence' | 'toggle';
7
+ declare module '../../core/types' {
8
+ interface Commands {
9
+ /** Changes the case of the characters of the selection; marks are kept. */
10
+ setTextCase: (letterCase: LetterCase) => Command;
11
+ }
12
+ }
13
+ /** The `setTextCase` command, docs/SPEC.md F-213: changes the characters, not a style. */
14
+ export declare const TextCase: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,21 @@
1
+ import type { Editor } from '../../core/editor';
2
+ /**
3
+ * The unit of a font size control: the number it shows and the unit it writes. `rem` shows px
4
+ * and writes rem, so the text follows the base size of the page that displays it.
5
+ */
6
+ export type FontSizeUnit = 'pt' | 'px' | 'rem';
7
+ /**
8
+ * The font size of the text at `pos` in `unit`, rounded to one decimal: the size the browser
9
+ * renders, so it includes headings, `em` and the page's own base size. Without `pos`, the size
10
+ * at the start of the selection; for an empty selection, the size stored for the next typed text
11
+ * when there is one (the page does not show it yet). Where nothing can be measured (no layout, as
12
+ * in jsdom) it counts 16px (12pt).
13
+ */
14
+ export declare function getFontSize(editor: Editor, unit?: FontSizeUnit, pos?: number): number;
15
+ /** The CSS font size for `value` in `unit`: `12` → `12pt`; for `rem`, px divided by the base. */
16
+ export declare function toFontSize(editor: Editor, value: number, unit?: FontSizeUnit): string;
17
+ /**
18
+ * The size after a step of `delta` from `size`: up to the next whole number, or down to the
19
+ * previous one (`13.5` + 1 → `14`), kept between 1 and 400.
20
+ */
21
+ export declare function stepFontSizeValue(size: number, delta: number): number;
@@ -1,14 +1,30 @@
1
1
  import type { Command } from 'prosemirror-state';
2
+ import { type FontSizeUnit } from './font-size';
2
3
  declare module '../../core/types' {
3
4
  interface Commands {
4
5
  /** Colors the selection. Returns `false` when `color` is not a valid CSS color. */
5
6
  setColor: (color: string) => Command;
6
7
  /** Removes the text color from the selection. */
7
8
  unsetColor: () => Command;
9
+ /** Sets the font family list of the selection. Returns `false` when no name is valid. */
10
+ setFontFamily: (fontFamily: string) => Command;
11
+ /** Removes the font family from the selection. */
12
+ unsetFontFamily: () => Command;
13
+ /** Sets the font size of the selection (`px`, `pt`, `em`, `rem`, `%`); `false` if invalid. */
14
+ setFontSize: (fontSize: string) => Command;
15
+ /** Removes the font size from the selection. */
16
+ unsetFontSize: () => Command;
17
+ /**
18
+ * Changes the font size of each selected part (or of the next typed text) from the size it
19
+ * has on the page to the next whole number in `unit` (`delta` 1) or the previous one (`-1`),
20
+ * between 1 and 400. Default unit `pt`.
21
+ */
22
+ stepFontSize: (delta: number, unit?: FontSizeUnit) => Command;
8
23
  }
9
24
  }
10
25
  /**
11
- * The `textStyle` mark (`<span style="color: x">`), docs/SPEC.md F-208. Also parsed from
12
- * `<font color>`. Font family and size (F-210, F-211) will be further attributes of this mark.
26
+ * The `textStyle` mark (`<span style="font-family: x; font-size: y; color: z">`), docs/SPEC.md
27
+ * F-208, F-210, F-211. Also parsed from `<font face size color>`.
13
28
  */
14
29
  export declare const TextStyle: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
30
+ export { type FontSizeUnit, getFontSize, toFontSize } from './font-size';
package/dist/index.d.ts CHANGED
@@ -9,5 +9,6 @@ export { toggleList } from './core/helpers/lists';
9
9
  export { setMark, toggleMark, unsetMark } from './core/helpers/marks';
10
10
  export { insertBlock, insertBlockNode } from './core/helpers/nodes';
11
11
  export { textDecorationRules } from './core/helpers/parse-rules';
12
+ export { getWordCount, type WordCount } from './core/helpers/word-count';
12
13
  export type { CommandFactories, CommandFactory, CommandName, CommandRunner, CommandRunners, Commands, EditorEvents, EditorOptions, JSONContent, SetContentOptions, } from './core/types';
13
14
  export * from './extensions';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export { D as Blockquote, E as Bold, T as BulletList, w as ClearFormatting, C as Code, I as DEFAULT_PRIORITY, S as Document, x as DropCursor, R as Editor, b as GapCursor, y as HardBreak, v as Heading, _ as Highlight, g as History, h as HorizontalRule, m as Italic, p as Link, f as ListItem, d as MoveBlock, u as OrderedList, l as Paragraph, c as Placeholder, H as StiloError, s as Strike, o as Subscript, a as Superscript, i as Text, r as TextStyle, n as Underline, z as attrsMatch, t as defaultExtensions, L as defineExtension, k as insertBlock, A as insertBlockNode, B as isMarkActive, V as isNodeActive, F as markInputRule, j as setMark, O as textDecorationRules, P as toggleList, M as toggleMark, N as unsetMark } from "./src-3tAxKI0c.js";
1
+ export { B as Blockquote, z as Bold, R as BulletList, L as ClearFormatting, I as Code, F as CodeBlock, X as DEFAULT_PRIORITY, P as Document, N as DropCursor, Q as Editor, M as GapCursor, j as HardBreak, A as Heading, k as Highlight, O as History, D as HorizontalRule, E as Image, T as Italic, w as LineHeight, C as Link, S as ListItem, x as MoveBlock, b as OrderedList, y as Paragraph, v as Placeholder, g as Search, nt as StiloError, h as Strike, m as Subscript, p as Superscript, d as Table, u as TaskItem, l as TaskList, c as Text, s as TextAlign, o as TextCase, r as TextStyle, n as Underline, $ as attrsMatch, t as defaultExtensions, Z as defineExtension, i as getFontSize, _ as getSearchResults, f as getTableHeaders, V as getWordCount, U as insertBlock, W as insertBlockNode, et as isMarkActive, tt as isNodeActive, Y as markInputRule, G as setMark, H as textDecorationRules, a as toFontSize, J as toggleList, K as toggleMark, q as unsetMark } from "./src-CV6pgfTS.js";