@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.
@@ -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
@@ -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;AAWtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;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,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,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,+BA2Jd"}
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"}
@@ -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;AA4CD;;;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"}
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
@@ -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 jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
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__ */ jsx4(Avatar, { size: 32, alt: person.name }),
611
- hint: /* @__PURE__ */ jsx4(EnterHint, {}),
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__ */ jsxs3(NodeViewWrapper, { as: "span", className: inlineChipClassName("neutral", "max-w-[24ch] cursor-default"), children: [
739
- /* @__PURE__ */ jsx4("span", { className: "flex items-center justify-center w-4 h-4 shrink-0 text-text-secondary", children: iconFor?.(node.attrs.uri ?? null) ?? icon }),
740
- /* @__PURE__ */ jsx4("span", { className: "truncate", children: captionOf(node.attrs.label, node.attrs.snippet) })
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__ */ jsx4(EnterHint, {}) })
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 jsx5 } from "react/jsx-runtime";
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__ */ jsx5(NodeViewWrapper2, { as: "span", className: "inline", children: /* @__PURE__ */ jsx5(View, { uri: String(node.attrs.uri ?? "") }) }));
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__ */ jsx5(
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__ */ jsx5(NodeViewWrapper2, { className: "my-2", children: /* @__PURE__ */ jsx5(View, { attrs: node.attrs }) }));
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,