@estiva-app/ui 0.66.0 → 0.67.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/dist/EditorTableControls.d.ts +38 -0
- package/dist/EditorTableControls.d.ts.map +1 -0
- package/dist/NavItem.d.ts +11 -1
- package/dist/NavItem.d.ts.map +1 -1
- package/dist/RichText.d.ts.map +1 -1
- package/dist/editor.d.ts +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +165 -11
- package/dist/editor.js.map +4 -4
- package/dist/index.js +23 -14
- package/dist/index.js.map +2 -2
- package/package.json +2 -1
- package/registry.json +127 -4
- package/src/EditorTableControls.mdx +78 -0
- package/src/EditorTableControls.stories.tsx +63 -0
- package/src/EditorTableControls.test.tsx +288 -0
- package/src/EditorTableControls.tsx +255 -0
- package/src/NavItem.mdx +10 -0
- package/src/NavItem.stories.tsx +23 -1
- package/src/NavItem.test.tsx +36 -0
- package/src/NavItem.tsx +40 -16
- package/src/RichText.tsx +2 -1
- package/src/editor.ts +1 -0
- package/src/registry/registry.test.ts +6 -6
- package/src/registry/siblings.test.ts +2 -2
- package/stories/Choosing.mdx +1 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Editor } from '@tiptap/core';
|
|
3
|
+
export interface EditorTableControlsProps {
|
|
4
|
+
/** The editor, with TableKit (`@tiptap/extension-table`) in its extensions. Not editable, or not there yet: no controls. */
|
|
5
|
+
editor: Editor | null;
|
|
6
|
+
/** The `EditorContent`. */
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The cell's row, or the whole table when it is its only one: a table holds at
|
|
12
|
+
* least one row (prosemirror-tables refuses to delete it). Deleting the header
|
|
13
|
+
* row makes the next row the header, so the table still opens with one.
|
|
14
|
+
*/
|
|
15
|
+
export declare function deleteTableRow(editor: Editor, cell: HTMLTableCellElement): boolean;
|
|
16
|
+
/** The same for a column: the last one deletes the table. */
|
|
17
|
+
export declare function deleteTableColumn(editor: Editor, cell: HTMLTableCellElement): boolean;
|
|
18
|
+
/** A row after the last one: the ➕ under the table. */
|
|
19
|
+
export declare function appendTableRow(editor: Editor, table: HTMLTableElement): boolean;
|
|
20
|
+
/** A column after the last one: the ➕ right of the table. */
|
|
21
|
+
export declare function appendTableColumn(editor: Editor, table: HTMLTableElement): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* A table's own controls in an editor, as in Notion: point at a cell and a
|
|
24
|
+
* handle sits on its row's left edge and on its column's top edge; press one
|
|
25
|
+
* for Insert above and below (left and right), Delete, and Delete table. On
|
|
26
|
+
* the last row a ➕ bar under the table adds a row, and on the last column one
|
|
27
|
+
* right of it adds a column. Tab in
|
|
28
|
+
* the last cell adds a row too — that is TableKit's own.
|
|
29
|
+
*
|
|
30
|
+
* Deleting a table's only row or only column deletes the table, which cannot
|
|
31
|
+
* be left with none.
|
|
32
|
+
*
|
|
33
|
+
* Built on the editor library's own table commands; the controls are ours.
|
|
34
|
+
* Wrap the `EditorContent` in it, inside an `EditorBlockHandle` if there is
|
|
35
|
+
* one: the block handle stays the table's, in the gutter.
|
|
36
|
+
*/
|
|
37
|
+
export declare function EditorTableControls({ editor, children, className }: EditorTableControlsProps): import("react").JSX.Element;
|
|
38
|
+
//# sourceMappingURL=EditorTableControls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorTableControls.d.ts","sourceRoot":"","sources":["../src/EditorTableControls.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACjG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAS1C,MAAM,WAAW,wBAAwB;IACvC,4HAA4H;IAC5H,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,2BAA2B;IAC3B,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwCD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAMlF;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAGrF;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAG/E;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAIlF;AA2BD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,wBAAwB,+BA8H5F"}
|
package/dist/NavItem.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
2
|
+
import type { SectionAction } from './SectionHeader';
|
|
2
3
|
/**
|
|
3
4
|
* One row of a sidebar: a label, an optional count, an active state
|
|
4
5
|
* (Ship's NavItem, 2026-09-02, verbatim).
|
|
@@ -23,6 +24,13 @@ import { type ComponentPropsWithoutRef, type ReactNode } from 'react';
|
|
|
23
24
|
* link, like the ⋮. The rows slide as `CollapsibleSection`'s do, indented
|
|
24
25
|
* past the icon so their icons start under this row's label.
|
|
25
26
|
*
|
|
27
|
+
* `action` is one button of its own beside the ⋮ — any icon, with its tooltip
|
|
28
|
+
* (Katerina, 14 October: Peek's Open work keeps its ✕ "Remove from list" in
|
|
29
|
+
* sight, not inside a menu). The same shape as a `SectionHeader`'s actions,
|
|
30
|
+
* and drawn the same way: an `IconButton` that shows with the ⋮, in the
|
|
31
|
+
* count's place, before the ⋮ when there is one. One, never a row of them: a
|
|
32
|
+
* second thing to do goes in the menu.
|
|
33
|
+
*
|
|
26
34
|
* `hint` is shown only while the row is pointed at or focused, left of the
|
|
27
35
|
* count — a neutral `Chip`, typically. It takes its own room while it shows,
|
|
28
36
|
* so the label ends with "…" before it instead of running under it.
|
|
@@ -50,6 +58,8 @@ export interface NavItemProps extends Omit<ComponentPropsWithoutRef<'a'>, 'href'
|
|
|
50
58
|
menu?: ReactNode;
|
|
51
59
|
/** The ⋮'s accessible name and tooltip. Default "More options for {label}". */
|
|
52
60
|
menuLabel?: string;
|
|
61
|
+
/** One button beside the ⋮, shown with it: any 16px icon, its tooltip and its handler — a `SectionHeader` action's shape. With a menu too, it sits before the ⋮. */
|
|
62
|
+
action?: SectionAction;
|
|
53
63
|
/** Shown only while the row is pointed at or focused, left of the count: a neutral `Chip`, typically. */
|
|
54
64
|
hint?: ReactNode;
|
|
55
65
|
/** Something new here: brighter words, the label in medium, and the `UnreadDot` at the right. Say so in the row's own words for assistive tech too. */
|
|
@@ -65,5 +75,5 @@ export interface NavItemProps extends Omit<ComponentPropsWithoutRef<'a'>, 'href'
|
|
|
65
75
|
onOpenChange?: (open: boolean) => void;
|
|
66
76
|
className?: string;
|
|
67
77
|
}
|
|
68
|
-
export declare function NavItem({ label, href, count, countLabel, active, icon, menu, menuLabel, hint, unread, urgent, children, defaultOpen, open: openProp, onOpenChange, className, onClick, ...props }: NavItemProps): import("react").JSX.Element;
|
|
78
|
+
export declare function NavItem({ label, href, count, countLabel, active, icon, menu, menuLabel, action, hint, unread, urgent, children, defaultOpen, open: openProp, onOpenChange, className, onClick, ...props }: NavItemProps): import("react").JSX.Element;
|
|
69
79
|
//# sourceMappingURL=NavItem.d.ts.map
|
package/dist/NavItem.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavItem.d.ts","sourceRoot":"","sources":["../src/NavItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,wBAAwB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"NavItem.d.ts","sourceRoot":"","sources":["../src/NavItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,wBAAwB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5F,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,4GAA4G;IAC5G,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oKAAoK;IACpK,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,yGAAyG;IACzG,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,uJAAuJ;IACvJ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,6HAA6H;IAC7H,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kDAAkD;IAClD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,KAAK,EACL,UAAU,EACV,MAAc,EACd,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,MAAM,EACN,IAAI,EACJ,MAAc,EACd,MAAc,EACd,QAAQ,EACR,WAAkB,EAClB,IAAI,EAAE,QAAQ,EACd,YAAY,EACZ,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACT,EAAE,YAAY,+BAwKd"}
|
package/dist/RichText.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichText.d.ts","sourceRoot":"","sources":["../src/RichText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAA;AAMlD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kHAAkH;IAClH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,oGAAoG;IACpG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CACpC;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAA;IACxC,mEAAmE;IACnE,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,KAAK,SAAS,CAAA;IACpE;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,GAAG,SAAS,CAAA;IAC7D;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACrD;
|
|
1
|
+
{"version":3,"file":"RichText.d.ts","sourceRoot":"","sources":["../src/RichText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAA;AAMlD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kHAAkH;IAClH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,oGAAoG;IACpG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAC/B,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CACpC;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAA;AAE9C,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAA;IACxC,mEAAmE;IACnE,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,KAAK,SAAS,CAAA;IACpE;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,GAAG,SAAS,CAAA;IAC7D;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACrD;AA6CD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,YAAwB,EAAE,SAAS,CAAC,EAAE,MAAM,UAGnF;AAkDD,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAuMD,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,IAAgB,EAChB,UAA2B,EAC3B,eAA+C,EAC/C,WAAW,EACX,MAAM,GACP,EAAE,aAAa,sCAQf"}
|
package/dist/editor.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { PastedImages, pastedImages, pastedImageName, type PastedImagesOptions,
|
|
|
12
12
|
export { CodeBlockColours } from './CodeBlockColours';
|
|
13
13
|
export { suggestionPopup, isSuggestionActive, isSuggestionOpen, type SuggestionPopupOptions } from './suggestionPopup';
|
|
14
14
|
export { EditorBlockHandle, blockDropCursor, deleteBlock, moveBlock, duplicateBlock, startBlockDrag, type EditorBlockHandleProps, type BlockTurnInto } from './EditorBlockHandle';
|
|
15
|
+
export { EditorTableControls, appendTableRow, appendTableColumn, deleteTableRow, deleteTableColumn, type EditorTableControlsProps } from './EditorTableControls';
|
|
15
16
|
export { PersonMention, UrgentPersonMention, CaptionedReference, ReferenceTrigger, SlashCommands, peopleMenu, referenceMenu, filterPeople, urgentPubkeys, filterReferences, formatSection, applyFormat, typeTrigger, filterSlashSections, FORMATS, type MentionPerson, type PersonMentionOptions, type CaptionedItem, type CaptionedReferenceOptions, type ReferenceTriggerOptions, type ReferenceMenuOptions, type SlashCommand, type SlashSection, type SlashCommandsOptions, type FormatId, type FormatDef, type CodeFormat, } from './ComposerTriggers';
|
|
16
17
|
export { BlockId, Checklist, Callout, isChecklistTick, UnknownBlock, ReferenceNode, AttachmentNode, type ReferenceNodeOptions, type ReferenceViewProps, type AttachmentNodeOptions, type AttachmentViewProps, } from './BlockNodes';
|
|
17
18
|
//# sourceMappingURL=editor.d.ts.map
|
package/dist/editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,MAAM,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC5H,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC5H,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AACtH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACjL,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,OAAO,EACP,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,OAAO,EACP,SAAS,EACT,OAAO,EACP,eAAe,EACf,YAAY,EACZ,aAAa,EACb,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,MAAM,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC5H,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC5H,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AACtH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACjL,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAChK,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,OAAO,EACP,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,OAAO,EACP,SAAS,EACT,OAAO,EACP,eAAe,EACf,YAAY,EACZ,aAAa,EACb,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAA"}
|
package/dist/editor.js
CHANGED
|
@@ -580,6 +580,155 @@ function EditorBlockHandle({ editor, turnInto = [], actions, children, className
|
|
|
580
580
|
return /* @__PURE__ */ jsx3(BlockHandle, { editing, actions, className, children });
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
+
// src/EditorTableControls.tsx
|
|
584
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef3, useState as useState2 } from "react";
|
|
585
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
586
|
+
import { addColumnAfter, addColumnBefore, addRowAfter, addRowBefore, deleteColumn, deleteRow, deleteTable, toggleHeader } from "@tiptap/pm/tables";
|
|
587
|
+
import { IconColumnInsertLeft, IconColumnInsertRight, IconGripHorizontal, IconGripVertical, IconPlus, IconRowInsertBottom, IconRowInsertTop, IconTrash as IconTrash2 } from "@tabler/icons-react";
|
|
588
|
+
import { cn } from "@estiva-app/ui";
|
|
589
|
+
import { IconButton } from "@estiva-app/ui";
|
|
590
|
+
|
|
591
|
+
// src/looks.ts
|
|
592
|
+
var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
|
|
593
|
+
|
|
594
|
+
// src/EditorTableControls.tsx
|
|
595
|
+
import { Menu, MenuItem as MenuItem2, MenuSeparator } from "@estiva-app/ui";
|
|
596
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
597
|
+
function inCell(editor, cell, command) {
|
|
598
|
+
const { view } = editor;
|
|
599
|
+
if (!view.dom.contains(cell)) return false;
|
|
600
|
+
const at = view.posAtDOM(cell, 0);
|
|
601
|
+
view.dispatch(view.state.tr.setSelection(TextSelection.near(view.state.doc.resolve(at))));
|
|
602
|
+
const done = command(view.state, view.dispatch, view);
|
|
603
|
+
editor.commands.focus();
|
|
604
|
+
return done;
|
|
605
|
+
}
|
|
606
|
+
function isHeaderRow(row) {
|
|
607
|
+
return row.cells.length > 0 && Array.from(row.cells).every((c) => c.tagName === "TH");
|
|
608
|
+
}
|
|
609
|
+
function deleteTableRow(editor, cell) {
|
|
610
|
+
const row = cell.closest("tr");
|
|
611
|
+
const table = cell.closest("table");
|
|
612
|
+
if (!row || !table || table.rows.length <= 1) return inCell(editor, cell, deleteTable);
|
|
613
|
+
const header = isHeaderRow(row);
|
|
614
|
+
return inCell(editor, cell, header ? (state, dispatch, view) => deleteRow(state, dispatch) && (!view || toggleHeader("row")(view.state, view.dispatch)) : deleteRow);
|
|
615
|
+
}
|
|
616
|
+
function deleteTableColumn(editor, cell) {
|
|
617
|
+
const row = cell.closest("tr");
|
|
618
|
+
return inCell(editor, cell, row && row.cells.length > 1 ? deleteColumn : deleteTable);
|
|
619
|
+
}
|
|
620
|
+
function appendTableRow(editor, table) {
|
|
621
|
+
const last = table.rows[table.rows.length - 1]?.cells[0];
|
|
622
|
+
return !!last && inCell(editor, last, addRowAfter);
|
|
623
|
+
}
|
|
624
|
+
function appendTableColumn(editor, table) {
|
|
625
|
+
const first = table.rows[0];
|
|
626
|
+
const last = first?.cells[first.cells.length - 1];
|
|
627
|
+
return !!last && inCell(editor, last, addColumnAfter);
|
|
628
|
+
}
|
|
629
|
+
function place(frame, { table, row, cell }) {
|
|
630
|
+
const at = frame.getBoundingClientRect();
|
|
631
|
+
const t = table.getBoundingClientRect();
|
|
632
|
+
const r = row.getBoundingClientRect();
|
|
633
|
+
const c = cell.getBoundingClientRect();
|
|
634
|
+
return {
|
|
635
|
+
tableBox: { top: t.top - at.top, left: t.left - at.left, width: t.width, height: t.height },
|
|
636
|
+
rowBox: { top: r.top - at.top, height: r.height },
|
|
637
|
+
columnBox: { left: c.left - at.left, width: c.width }
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
var ICON = { size: 16, stroke: 1.5, className: "text-text-secondary" };
|
|
641
|
+
var keepFocus = (e) => e.preventDefault();
|
|
642
|
+
var HANDLE_BOX = cn(FLOATING_SURFACE_CLASSES, "shadow-none");
|
|
643
|
+
function EditorTableControls({ editor, children, className }) {
|
|
644
|
+
const frame = useRef3(null);
|
|
645
|
+
const [hovered, setHovered] = useState2(null);
|
|
646
|
+
const [menu, setMenu] = useState2(null);
|
|
647
|
+
const editable = !!editor && editor.isEditable;
|
|
648
|
+
const follow = useCallback2(
|
|
649
|
+
(target) => {
|
|
650
|
+
if (!editor || !frame.current || !(target instanceof Element)) return;
|
|
651
|
+
if (target.closest("[data-table-control]")) return;
|
|
652
|
+
const cell = target.closest("td, th");
|
|
653
|
+
const row = cell?.closest("tr");
|
|
654
|
+
const table = row?.closest("table");
|
|
655
|
+
if (!cell || !row || !table || !editor.view.dom.contains(table)) {
|
|
656
|
+
setHovered(null);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const next = { table, row, cell, ...place(frame.current, { table, row, cell }) };
|
|
660
|
+
setHovered((was) => was && was.cell === cell && JSON.stringify([was.tableBox, was.rowBox, was.columnBox]) === JSON.stringify([next.tableBox, next.rowBox, next.columnBox]) ? was : next);
|
|
661
|
+
},
|
|
662
|
+
[editor]
|
|
663
|
+
);
|
|
664
|
+
useEffect2(() => {
|
|
665
|
+
if (!editor) return;
|
|
666
|
+
const changed = ({ transaction }) => {
|
|
667
|
+
if (transaction.docChanged && !menu) setHovered(null);
|
|
668
|
+
};
|
|
669
|
+
editor.on("transaction", changed);
|
|
670
|
+
return () => {
|
|
671
|
+
editor.off("transaction", changed);
|
|
672
|
+
};
|
|
673
|
+
}, [editor, menu]);
|
|
674
|
+
const shown = editable ? hovered : null;
|
|
675
|
+
const run = (act) => () => {
|
|
676
|
+
if (editor) act();
|
|
677
|
+
setMenu(null);
|
|
678
|
+
setHovered(null);
|
|
679
|
+
};
|
|
680
|
+
return /* @__PURE__ */ jsxs3(
|
|
681
|
+
"div",
|
|
682
|
+
{
|
|
683
|
+
ref: frame,
|
|
684
|
+
className: cn("relative", className),
|
|
685
|
+
onMouseMove: (e) => {
|
|
686
|
+
if (!menu) follow(e.target);
|
|
687
|
+
},
|
|
688
|
+
onMouseLeave: () => {
|
|
689
|
+
if (!menu) setHovered(null);
|
|
690
|
+
},
|
|
691
|
+
children: [
|
|
692
|
+
children,
|
|
693
|
+
shown && editor && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
694
|
+
/* @__PURE__ */ jsx4("div", { "data-table-control": true, className: cn(HANDLE_BOX, "absolute -translate-x-1/2 -translate-y-1/2"), style: { left: shown.tableBox.left, top: shown.rowBox.top + shown.rowBox.height / 2 }, children: /* @__PURE__ */ jsxs3(
|
|
695
|
+
Menu,
|
|
696
|
+
{
|
|
697
|
+
open: menu === "row",
|
|
698
|
+
onOpenChange: (open) => setMenu(open ? "row" : null),
|
|
699
|
+
trigger: /* @__PURE__ */ jsx4(IconButton, { "aria-label": "Row menu", tooltip: "Row", className: "h-6 w-4 p-0", children: /* @__PURE__ */ jsx4(IconGripVertical, { size: 16, stroke: 1.5 }) }),
|
|
700
|
+
children: [
|
|
701
|
+
!isHeaderRow(shown.row) && /* @__PURE__ */ jsx4(MenuItem2, { label: "Insert above", leading: /* @__PURE__ */ jsx4(IconRowInsertTop, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addRowBefore)) }),
|
|
702
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Insert below", leading: /* @__PURE__ */ jsx4(IconRowInsertBottom, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addRowAfter)) }),
|
|
703
|
+
/* @__PURE__ */ jsx4(MenuSeparator, {}),
|
|
704
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Delete", destructive: true, leading: /* @__PURE__ */ jsx4(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => deleteTableRow(editor, shown.cell)) }),
|
|
705
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Delete table", destructive: true, leading: /* @__PURE__ */ jsx4(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => inCell(editor, shown.cell, deleteTable)) })
|
|
706
|
+
]
|
|
707
|
+
}
|
|
708
|
+
) }),
|
|
709
|
+
/* @__PURE__ */ jsx4("div", { "data-table-control": true, className: cn(HANDLE_BOX, "absolute -translate-x-1/2 -translate-y-1/2"), style: { left: shown.columnBox.left + shown.columnBox.width / 2, top: shown.tableBox.top }, children: /* @__PURE__ */ jsxs3(
|
|
710
|
+
Menu,
|
|
711
|
+
{
|
|
712
|
+
open: menu === "column",
|
|
713
|
+
onOpenChange: (open) => setMenu(open ? "column" : null),
|
|
714
|
+
trigger: /* @__PURE__ */ jsx4(IconButton, { "aria-label": "Column menu", tooltip: "Column", className: "h-4 w-6 p-0", children: /* @__PURE__ */ jsx4(IconGripHorizontal, { size: 16, stroke: 1.5 }) }),
|
|
715
|
+
children: [
|
|
716
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Insert left", leading: /* @__PURE__ */ jsx4(IconColumnInsertLeft, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addColumnBefore)) }),
|
|
717
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Insert right", leading: /* @__PURE__ */ jsx4(IconColumnInsertRight, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addColumnAfter)) }),
|
|
718
|
+
/* @__PURE__ */ jsx4(MenuSeparator, {}),
|
|
719
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Delete", destructive: true, leading: /* @__PURE__ */ jsx4(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => deleteTableColumn(editor, shown.cell)) }),
|
|
720
|
+
/* @__PURE__ */ jsx4(MenuItem2, { label: "Delete table", destructive: true, leading: /* @__PURE__ */ jsx4(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => inCell(editor, shown.cell, deleteTable)) })
|
|
721
|
+
]
|
|
722
|
+
}
|
|
723
|
+
) }),
|
|
724
|
+
shown.row === shown.table.rows[shown.table.rows.length - 1] && /* @__PURE__ */ jsx4("div", { "data-table-control": true, className: cn(HANDLE_BOX, "absolute flex h-4"), style: { left: shown.tableBox.left, top: shown.tableBox.top + shown.tableBox.height, width: shown.tableBox.width }, children: /* @__PURE__ */ jsx4(IconButton, { "aria-label": "Add row", tooltip: "Add row", className: "h-full w-full p-0", onMouseDown: keepFocus, onClick: run(() => appendTableRow(editor, shown.table)), children: /* @__PURE__ */ jsx4(IconPlus, { size: 12, stroke: 1.5 }) }) }),
|
|
725
|
+
shown.cell === shown.row.cells[shown.row.cells.length - 1] && /* @__PURE__ */ jsx4("div", { "data-table-control": true, className: cn(HANDLE_BOX, "absolute flex w-4"), style: { left: shown.tableBox.left + shown.tableBox.width, top: shown.tableBox.top, height: shown.tableBox.height }, children: /* @__PURE__ */ jsx4(IconButton, { "aria-label": "Add column", tooltip: "Add column", className: "h-full w-full p-0", onMouseDown: keepFocus, onClick: run(() => appendTableColumn(editor, shown.table)), children: /* @__PURE__ */ jsx4(IconPlus, { size: 12, stroke: 1.5 }) }) })
|
|
726
|
+
] })
|
|
727
|
+
]
|
|
728
|
+
}
|
|
729
|
+
);
|
|
730
|
+
}
|
|
731
|
+
|
|
583
732
|
// src/ComposerTriggers.tsx
|
|
584
733
|
import { Extension as Extension3 } from "@tiptap/core";
|
|
585
734
|
import { PluginKey as PluginKey3 } from "@tiptap/pm/state";
|
|
@@ -589,7 +738,7 @@ import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
|
|
|
589
738
|
import { Avatar } from "@estiva-app/ui";
|
|
590
739
|
import { EnterHint } from "@estiva-app/ui";
|
|
591
740
|
import { inlineChipClassName } from "@estiva-app/ui";
|
|
592
|
-
import { jsx as
|
|
741
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
593
742
|
var PEOPLE_LIMIT = 6;
|
|
594
743
|
function filterPeople(people, query) {
|
|
595
744
|
const q = query.toLowerCase();
|
|
@@ -607,8 +756,8 @@ function peopleMenu(urgent) {
|
|
|
607
756
|
row: (person) => ({
|
|
608
757
|
label: person.name,
|
|
609
758
|
description: person.description,
|
|
610
|
-
leading: person.avatar ?? /* @__PURE__ */
|
|
611
|
-
hint: /* @__PURE__ */
|
|
759
|
+
leading: person.avatar ?? /* @__PURE__ */ jsx5(Avatar, { size: 32, alt: person.name }),
|
|
760
|
+
hint: /* @__PURE__ */ jsx5(EnterHint, {}),
|
|
612
761
|
size: "tall"
|
|
613
762
|
})
|
|
614
763
|
};
|
|
@@ -735,9 +884,9 @@ var CaptionedReference = Mention.extend({
|
|
|
735
884
|
addNodeView() {
|
|
736
885
|
const { icon, iconFor } = this.options;
|
|
737
886
|
return ReactNodeViewRenderer(
|
|
738
|
-
({ node }) => /* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
740
|
-
/* @__PURE__ */
|
|
887
|
+
({ node }) => /* @__PURE__ */ jsxs4(NodeViewWrapper, { as: "span", className: inlineChipClassName("neutral", "max-w-[24ch] cursor-default"), children: [
|
|
888
|
+
/* @__PURE__ */ jsx5("span", { className: "flex items-center justify-center w-4 h-4 shrink-0 text-text-secondary", children: iconFor?.(node.attrs.uri ?? null) ?? icon }),
|
|
889
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: captionOf(node.attrs.label, node.attrs.snippet) })
|
|
741
890
|
] }),
|
|
742
891
|
{ as: "span" }
|
|
743
892
|
);
|
|
@@ -759,7 +908,7 @@ function referenceMenu({ ariaLabel, sectionLabel, icon, iconFor }) {
|
|
|
759
908
|
return groups;
|
|
760
909
|
},
|
|
761
910
|
itemKey: (item) => `reference-${item.id}`,
|
|
762
|
-
row: (item) => ({ leading: item.icon ?? iconFor?.(item.uri) ?? icon, label: captionOf(item.label, item.snippet), description: item.description, hint: /* @__PURE__ */
|
|
911
|
+
row: (item) => ({ leading: item.icon ?? iconFor?.(item.uri) ?? icon, label: captionOf(item.label, item.snippet), description: item.description, hint: /* @__PURE__ */ jsx5(EnterHint, {}) })
|
|
763
912
|
};
|
|
764
913
|
}
|
|
765
914
|
var listed = (options, query) => options.sections ? options.sections(query).flatMap((section) => section.items.map((item) => ({ ...item, section: section.label }))) : filterReferences(options.items(), query);
|
|
@@ -920,7 +1069,7 @@ import { Mapping, ReplaceAroundStep } from "@tiptap/pm/transform";
|
|
|
920
1069
|
import { NodeViewWrapper as NodeViewWrapper2, ReactNodeViewRenderer as ReactNodeViewRenderer2, ReactRenderer as ReactRenderer2 } from "@tiptap/react";
|
|
921
1070
|
import { Checkbox } from "@estiva-app/ui";
|
|
922
1071
|
import { calloutLook } from "@estiva-app/ui";
|
|
923
|
-
import { jsx as
|
|
1072
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
924
1073
|
var BLOCK_TYPES = [
|
|
925
1074
|
"paragraph",
|
|
926
1075
|
"heading",
|
|
@@ -1150,7 +1299,7 @@ var ReferenceNode = Node2.create({
|
|
|
1150
1299
|
addNodeView() {
|
|
1151
1300
|
const View = this.options.view;
|
|
1152
1301
|
if (!View) return null;
|
|
1153
|
-
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */
|
|
1302
|
+
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */ jsx6(NodeViewWrapper2, { as: "span", className: "inline", children: /* @__PURE__ */ jsx6(View, { uri: String(node.attrs.uri ?? "") }) }));
|
|
1154
1303
|
}
|
|
1155
1304
|
});
|
|
1156
1305
|
var UnknownBlock = Node2.create({
|
|
@@ -1178,7 +1327,7 @@ var UnknownBlock = Node2.create({
|
|
|
1178
1327
|
function UnknownBlockView({ node }) {
|
|
1179
1328
|
const source = node.attrs.source;
|
|
1180
1329
|
const text = String(node.attrs.text ?? "");
|
|
1181
|
-
return /* @__PURE__ */
|
|
1330
|
+
return /* @__PURE__ */ jsx6(
|
|
1182
1331
|
NodeViewWrapper2,
|
|
1183
1332
|
{
|
|
1184
1333
|
"data-block-id": source?.id,
|
|
@@ -1218,7 +1367,7 @@ var AttachmentNode = Node2.create({
|
|
|
1218
1367
|
addNodeView() {
|
|
1219
1368
|
const View = this.options.view;
|
|
1220
1369
|
if (!View) return null;
|
|
1221
|
-
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */
|
|
1370
|
+
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */ jsx6(NodeViewWrapper2, { className: "my-2", children: /* @__PURE__ */ jsx6(View, { attrs: node.attrs }) }));
|
|
1222
1371
|
}
|
|
1223
1372
|
});
|
|
1224
1373
|
var TICK = "checklistTick";
|
|
@@ -1385,6 +1534,7 @@ export {
|
|
|
1385
1534
|
Checklist,
|
|
1386
1535
|
CodeBlockColours,
|
|
1387
1536
|
EditorBlockHandle,
|
|
1537
|
+
EditorTableControls,
|
|
1388
1538
|
FORMATS,
|
|
1389
1539
|
KeptSelection,
|
|
1390
1540
|
PastedImages,
|
|
@@ -1395,9 +1545,13 @@ export {
|
|
|
1395
1545
|
SlashCommands,
|
|
1396
1546
|
UnknownBlock,
|
|
1397
1547
|
UrgentPersonMention,
|
|
1548
|
+
appendTableColumn,
|
|
1549
|
+
appendTableRow,
|
|
1398
1550
|
applyFormat,
|
|
1399
1551
|
blockDropCursor,
|
|
1400
1552
|
deleteBlock,
|
|
1553
|
+
deleteTableColumn,
|
|
1554
|
+
deleteTableRow,
|
|
1401
1555
|
duplicateBlock,
|
|
1402
1556
|
filterPeople,
|
|
1403
1557
|
filterReferences,
|