@threadlabs/looma 0.1.4 → 0.1.6

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.
@@ -1,5 +1,6 @@
1
- import { AnyExtension, Editor, Range } from '@tiptap/core';
2
- import { a as TableOverlayActionEventDetail } from '../table-overlay-DTr3KC9e.js';
1
+ import { AnyExtension, Editor, Range, Extension } from '@tiptap/core';
2
+ import { d as TableContextMenuActionEventDetail, f as TableOverlayActionEventDetail } from '../table-overlay-Bq0F5xPg.js';
3
+ export { a as TABLE_CELL_BACKGROUND_PRESETS } from '../table-overlay-Bq0F5xPg.js';
3
4
 
4
5
  /**
5
6
  * Default Tiptap extension preset for Looma editor.
@@ -11,12 +12,26 @@ interface DefaultEditorExtensionsOptions {
11
12
  linkOpenOnClick?: boolean;
12
13
  imageInline?: boolean;
13
14
  }
15
+ /** Complete Looma table support as one Tiptap extension. */
16
+ declare const LoomaTableKit: AnyExtension;
17
+ /** Individual table extensions for consumers that prefer an explicit extension list. */
18
+ declare function getLoomaTableExtensions(): AnyExtension[];
14
19
  /**
15
20
  * Returns the default Looma editor extensions (Vanilla Tiptap).
16
21
  * Use with new Editor({ extensions: getDefaultEditorExtensions(), ... }) or framework useEditor().
17
22
  */
18
23
  declare function getDefaultEditorExtensions(options?: DefaultEditorExtensionsOptions): AnyExtension[];
19
24
 
25
+ type TableCellAlignment = "left" | "center" | "right";
26
+ type TableCellBackground = string | null;
27
+ declare const LoomaTable: AnyExtension;
28
+ declare const LoomaTableHeader: AnyExtension;
29
+ declare const LoomaTableCell: AnyExtension;
30
+ declare function getActiveTableCellAlignment(editor: Editor): TableCellAlignment;
31
+ declare function getActiveTableCellBackground(editor: Editor): TableCellBackground;
32
+ declare function setActiveTableCellAlignment(editor: Editor, alignment: TableCellAlignment): boolean;
33
+ declare function setActiveTableCellBackground(editor: Editor, backgroundColor: TableCellBackground): boolean;
34
+
20
35
  /**
21
36
  * Table overlay action handler — maps boundaryIndex to Tiptap table commands.
22
37
  * Use with looma-editor-table-overlay-action: call this from the adapter's handler.
@@ -27,6 +42,30 @@ interface InsertTableAtRangeOptions {
27
42
  cols?: number;
28
43
  withHeaderRow?: boolean;
29
44
  }
45
+ interface TableActionCapabilities {
46
+ canAddRowBefore: boolean;
47
+ canAddRowAfter: boolean;
48
+ canAddColumnBefore: boolean;
49
+ canAddColumnAfter: boolean;
50
+ canDeleteRow: boolean;
51
+ canDeleteColumn: boolean;
52
+ canDeleteTable: boolean;
53
+ canMergeCells: boolean;
54
+ canSplitCell: boolean;
55
+ }
56
+ interface ActiveTableUiState {
57
+ active: boolean;
58
+ showToolbar: boolean;
59
+ cellAlignment: TableCellAlignment;
60
+ cellBackground: TableCellBackground;
61
+ capabilities: TableActionCapabilities;
62
+ }
63
+ /** Text formatting belongs to actual text selections, not table CellSelections. */
64
+ declare function shouldShowTextFormattingToolbar(editor: Editor, from?: number, to?: number): boolean;
65
+ /** Returns Looma's complete interaction state for the table containing the selection. */
66
+ declare function getActiveTableUiState(editor: Editor): ActiveTableUiState;
67
+ /** Executes a toolbar/context-menu action using Looma's table behavior policy. */
68
+ declare function handleTableAction(editor: Editor, detail: TableContextMenuActionEventDetail): boolean;
30
69
  /**
31
70
  * Deletes a slash-command range (or other inline trigger text) and inserts a table.
32
71
  * Use this when apps want a stable default `/table` behavior without owning table policy.
@@ -53,22 +92,37 @@ declare function normalizeActiveTableColumnWidths(editor: Editor, tableElement:
53
92
  */
54
93
  declare function handleTableOverlayAction(editor: Editor, detail: TableOverlayActionEventDetail): boolean;
55
94
 
56
- type TableCellAlignment = "left" | "center" | "right";
57
- type TableCellBackground = string | null;
58
- declare const TABLE_CELL_BACKGROUND_PRESETS: {
59
- readonly none: null;
60
- readonly gray: "#f3f4f6";
61
- readonly yellow: "#fef3c7";
62
- readonly blue: "#dbeafe";
63
- readonly green: "#dcfce7";
64
- readonly red: "#fee2e2";
65
- };
66
- declare const LoomaTable: AnyExtension;
67
- declare const LoomaTableHeader: AnyExtension;
68
- declare const LoomaTableCell: AnyExtension;
69
- declare function getActiveTableCellAlignment(editor: Editor): TableCellAlignment;
70
- declare function getActiveTableCellBackground(editor: Editor): TableCellBackground;
71
- declare function setActiveTableCellAlignment(editor: Editor, alignment: TableCellAlignment): boolean;
72
- declare function setActiveTableCellBackground(editor: Editor, backgroundColor: TableCellBackground): boolean;
95
+ interface LoomaSlashCommandContext {
96
+ editor: Editor;
97
+ range: Range;
98
+ }
99
+ interface LoomaSlashMenuSnapshot {
100
+ active: boolean;
101
+ items: LoomaSlashCommand[];
102
+ selectedIndex: number;
103
+ query: string;
104
+ rect: DOMRect | null;
105
+ select: ((index: number) => void) | null;
106
+ }
107
+ interface LoomaSlashCommandOptions {
108
+ commands: LoomaSlashCommand[];
109
+ onStateChange?: (state: LoomaSlashMenuSnapshot) => void;
110
+ onOpenImagePicker?: () => void;
111
+ }
112
+ declare function getDefaultSlashCommands(onOpenImagePicker?: () => void): LoomaSlashCommand[];
113
+ interface LoomaSlashCommand {
114
+ title: string;
115
+ description: string;
116
+ icon: string;
117
+ keywords: string[];
118
+ command: (context: LoomaSlashCommandContext) => void;
119
+ }
120
+ /**
121
+ * Framework-neutral slash-command extension used by the turnkey editor.
122
+ * Consumers embedding Looma into their own Tiptap instance can configure the
123
+ * same behavior and render any menu they choose from `onStateChange`.
124
+ */
125
+ declare const LoomaSlashCommand: Extension<LoomaSlashCommandOptions, any>;
126
+ declare function createLoomaSlashCommandExtension(options?: Partial<LoomaSlashCommandOptions>): Extension<LoomaSlashCommandOptions, any>;
73
127
 
74
- export { type DefaultEditorExtensionsOptions, type InsertTableAtRangeOptions, LoomaTable, LoomaTableCell, LoomaTableHeader, TABLE_CELL_BACKGROUND_PRESETS, type TableCellAlignment, type TableCellBackground, getActiveTableCellAlignment, getActiveTableCellBackground, getDefaultEditorExtensions, handleTableOverlayAction, insertTableAtRange, normalizeActiveTableColumnWidths, setActiveTableCellAlignment, setActiveTableCellBackground };
128
+ export { type ActiveTableUiState, type DefaultEditorExtensionsOptions, type InsertTableAtRangeOptions, LoomaSlashCommand, type LoomaSlashCommandContext, LoomaSlashCommand as LoomaSlashCommandItem, type LoomaSlashCommandOptions, type LoomaSlashMenuSnapshot, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, type TableActionCapabilities, type TableCellAlignment, type TableCellBackground, createLoomaSlashCommandExtension, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, handleTableAction, handleTableOverlayAction, insertTableAtRange, normalizeActiveTableColumnWidths, setActiveTableCellAlignment, setActiveTableCellBackground, shouldShowTextFormattingToolbar };
@@ -1,28 +1,46 @@
1
1
  import {
2
+ LoomaSlashCommand,
2
3
  LoomaTable,
3
4
  LoomaTableCell,
4
5
  LoomaTableHeader,
5
- TABLE_CELL_BACKGROUND_PRESETS,
6
+ LoomaTableKit,
7
+ createLoomaSlashCommandExtension,
6
8
  getActiveTableCellAlignment,
7
9
  getActiveTableCellBackground,
10
+ getActiveTableUiState,
8
11
  getDefaultEditorExtensions,
12
+ getDefaultSlashCommands,
13
+ getLoomaTableExtensions,
14
+ handleTableAction,
9
15
  handleTableOverlayAction,
10
16
  insertTableAtRange,
11
17
  normalizeActiveTableColumnWidths,
12
18
  setActiveTableCellAlignment,
13
- setActiveTableCellBackground
14
- } from "../chunk-YGJLGDQC.js";
19
+ setActiveTableCellBackground,
20
+ shouldShowTextFormattingToolbar
21
+ } from "../chunk-NJ2KAMS2.js";
22
+ import {
23
+ TABLE_CELL_BACKGROUND_PRESETS
24
+ } from "../chunk-CX4QDKSV.js";
15
25
  export {
26
+ LoomaSlashCommand,
16
27
  LoomaTable,
17
28
  LoomaTableCell,
18
29
  LoomaTableHeader,
30
+ LoomaTableKit,
19
31
  TABLE_CELL_BACKGROUND_PRESETS,
32
+ createLoomaSlashCommandExtension,
20
33
  getActiveTableCellAlignment,
21
34
  getActiveTableCellBackground,
35
+ getActiveTableUiState,
22
36
  getDefaultEditorExtensions,
37
+ getDefaultSlashCommands,
38
+ getLoomaTableExtensions,
39
+ handleTableAction,
23
40
  handleTableOverlayAction,
24
41
  insertTableAtRange,
25
42
  normalizeActiveTableColumnWidths,
26
43
  setActiveTableCellAlignment,
27
- setActiveTableCellBackground
44
+ setActiveTableCellBackground,
45
+ shouldShowTextFormattingToolbar
28
46
  };
package/editor/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { InsertTableEventDetail, SlashMenuAnchorRect, SlashMenuHighlightEventDetail, SlashMenuItem, SlashMenuSelectEventDetail, TableContextMenuAction, TableContextMenuActionEventDetail, TableContextMenuActionEventDetail as TableToolbarActionEventDetail } from './ui.js';
2
- export { T as TableOverlayAction, a as TableOverlayActionEventDetail } from './table-overlay-DTr3KC9e.js';
3
- export { DefaultEditorExtensionsOptions, InsertTableAtRangeOptions, LoomaTable, LoomaTableCell, LoomaTableHeader, TABLE_CELL_BACKGROUND_PRESETS, TableCellAlignment, TableCellBackground, getActiveTableCellAlignment, getActiveTableCellBackground, getDefaultEditorExtensions, handleTableOverlayAction, insertTableAtRange, normalizeActiveTableColumnWidths, setActiveTableCellAlignment, setActiveTableCellBackground } from './extensions/index.js';
1
+ export { T as TABLE_CELL_BACKGROUND_OPTIONS, a as TABLE_CELL_BACKGROUND_PRESETS, b as TableCellBackgroundAction, c as TableContextMenuAction, d as TableContextMenuActionEventDetail, e as TableOverlayAction, f as TableOverlayActionEventDetail, d as TableToolbarActionEventDetail } from './table-overlay-Bq0F5xPg.js';
2
+ export { InsertTableEventDetail, SlashMenuAnchorRect, SlashMenuHighlightEventDetail, SlashMenuItem, SlashMenuSelectEventDetail } from './ui.js';
3
+ export { ActiveTableUiState, DefaultEditorExtensionsOptions, InsertTableAtRangeOptions, LoomaSlashCommand, LoomaSlashCommandContext, LoomaSlashCommand as LoomaSlashCommandItem, LoomaSlashCommandOptions, LoomaSlashMenuSnapshot, LoomaTable, LoomaTableCell, LoomaTableHeader, LoomaTableKit, TableActionCapabilities, TableCellAlignment, TableCellBackground, createLoomaSlashCommandExtension, getActiveTableCellAlignment, getActiveTableCellBackground, getActiveTableUiState, getDefaultEditorExtensions, getDefaultSlashCommands, getLoomaTableExtensions, handleTableAction, handleTableOverlayAction, insertTableAtRange, normalizeActiveTableColumnWidths, setActiveTableCellAlignment, setActiveTableCellBackground, shouldShowTextFormattingToolbar } from './extensions/index.js';
4
4
  import '@tiptap/core';
package/editor/index.js CHANGED
@@ -1,29 +1,49 @@
1
- import "./chunk-CWCXYQMT.js";
1
+ import "./chunk-KQQTYVRW.js";
2
2
  import {
3
+ LoomaSlashCommand,
3
4
  LoomaTable,
4
5
  LoomaTableCell,
5
6
  LoomaTableHeader,
6
- TABLE_CELL_BACKGROUND_PRESETS,
7
+ LoomaTableKit,
8
+ createLoomaSlashCommandExtension,
7
9
  getActiveTableCellAlignment,
8
10
  getActiveTableCellBackground,
11
+ getActiveTableUiState,
9
12
  getDefaultEditorExtensions,
13
+ getDefaultSlashCommands,
14
+ getLoomaTableExtensions,
15
+ handleTableAction,
10
16
  handleTableOverlayAction,
11
17
  insertTableAtRange,
12
18
  normalizeActiveTableColumnWidths,
13
19
  setActiveTableCellAlignment,
14
- setActiveTableCellBackground
15
- } from "./chunk-YGJLGDQC.js";
20
+ setActiveTableCellBackground,
21
+ shouldShowTextFormattingToolbar
22
+ } from "./chunk-NJ2KAMS2.js";
23
+ import {
24
+ TABLE_CELL_BACKGROUND_OPTIONS,
25
+ TABLE_CELL_BACKGROUND_PRESETS
26
+ } from "./chunk-CX4QDKSV.js";
16
27
  export {
28
+ LoomaSlashCommand,
17
29
  LoomaTable,
18
30
  LoomaTableCell,
19
31
  LoomaTableHeader,
32
+ LoomaTableKit,
33
+ TABLE_CELL_BACKGROUND_OPTIONS,
20
34
  TABLE_CELL_BACKGROUND_PRESETS,
35
+ createLoomaSlashCommandExtension,
21
36
  getActiveTableCellAlignment,
22
37
  getActiveTableCellBackground,
38
+ getActiveTableUiState,
23
39
  getDefaultEditorExtensions,
40
+ getDefaultSlashCommands,
41
+ getLoomaTableExtensions,
42
+ handleTableAction,
24
43
  handleTableOverlayAction,
25
44
  insertTableAtRange,
26
45
  normalizeActiveTableColumnWidths,
27
46
  setActiveTableCellAlignment,
28
- setActiveTableCellBackground
47
+ setActiveTableCellBackground,
48
+ shouldShowTextFormattingToolbar
29
49
  };
@@ -0,0 +1,64 @@
1
+ declare const TABLE_CELL_BACKGROUND_PRESETS: {
2
+ readonly none: null;
3
+ readonly gray: "#f3f4f6";
4
+ readonly yellow: "#fef3c7";
5
+ readonly blue: "#dbeafe";
6
+ readonly green: "#dcfce7";
7
+ readonly red: "#fee2e2";
8
+ };
9
+ declare const TABLE_CELL_BACKGROUND_OPTIONS: readonly [{
10
+ readonly action: "background-none";
11
+ readonly label: "Default";
12
+ readonly value: null;
13
+ readonly swatch: null;
14
+ }, {
15
+ readonly action: "background-gray";
16
+ readonly label: "Gray";
17
+ readonly value: "#f3f4f6";
18
+ readonly swatch: "#f3f4f6";
19
+ }, {
20
+ readonly action: "background-yellow";
21
+ readonly label: "Yellow";
22
+ readonly value: "#fef3c7";
23
+ readonly swatch: "#fef3c7";
24
+ }, {
25
+ readonly action: "background-blue";
26
+ readonly label: "Blue";
27
+ readonly value: "#dbeafe";
28
+ readonly swatch: "#dbeafe";
29
+ }, {
30
+ readonly action: "background-green";
31
+ readonly label: "Green";
32
+ readonly value: "#dcfce7";
33
+ readonly swatch: "#dcfce7";
34
+ }, {
35
+ readonly action: "background-red";
36
+ readonly label: "Red";
37
+ readonly value: "#fee2e2";
38
+ readonly swatch: "#fee2e2";
39
+ }];
40
+ type TableCellBackgroundAction = typeof TABLE_CELL_BACKGROUND_OPTIONS[number]["action"];
41
+
42
+ /**
43
+ * ui-editor-table-context-menu — web component for table cell context menu.
44
+ * Emits custom events for each action; the adapter (Vue/React) wires Tiptap commands.
45
+ * Domain-neutral: no Tiptap dependency.
46
+ */
47
+
48
+ type TableContextMenuAction = "align-left" | "align-center" | "align-right" | TableCellBackgroundAction | "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after" | "delete-row" | "delete-column" | "delete-table" | "merge-cells" | "split-cell";
49
+ interface TableContextMenuActionEventDetail {
50
+ action: TableContextMenuAction;
51
+ }
52
+
53
+ /**
54
+ * ui-editor-table-overlay — table edge controls for row/column insertion.
55
+ * Emits looma-editor-table-overlay-action with insertion intent.
56
+ * Domain-neutral: no Tiptap dependency.
57
+ */
58
+ type TableOverlayAction = "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after";
59
+ interface TableOverlayActionEventDetail {
60
+ action: TableOverlayAction;
61
+ boundaryIndex: number;
62
+ }
63
+
64
+ export { TABLE_CELL_BACKGROUND_OPTIONS as T, TABLE_CELL_BACKGROUND_PRESETS as a, type TableCellBackgroundAction as b, type TableContextMenuAction as c, type TableContextMenuActionEventDetail as d, type TableOverlayAction as e, type TableOverlayActionEventDetail as f };
package/editor/ui.d.ts CHANGED
@@ -1,14 +1,4 @@
1
- export { T as TableOverlayAction, a as TableOverlayActionEventDetail } from './table-overlay-DTr3KC9e.js';
2
-
3
- /**
4
- * ui-editor-table-context-menu — web component for table cell context menu.
5
- * Emits custom events for each action; the adapter (Vue/React) wires Tiptap commands.
6
- * Domain-neutral: no Tiptap dependency.
7
- */
8
- type TableContextMenuAction = "align-left" | "align-center" | "align-right" | "background-none" | "background-gray" | "background-yellow" | "background-blue" | "background-green" | "background-red" | "add-row-before" | "add-row-after" | "add-column-before" | "add-column-after" | "delete-row" | "delete-column" | "delete-table" | "merge-cells" | "split-cell";
9
- interface TableContextMenuActionEventDetail {
10
- action: TableContextMenuAction;
11
- }
1
+ export { T as TABLE_CELL_BACKGROUND_OPTIONS, a as TABLE_CELL_BACKGROUND_PRESETS, b as TableCellBackgroundAction, c as TableContextMenuAction, d as TableContextMenuActionEventDetail, e as TableOverlayAction, f as TableOverlayActionEventDetail, d as TableToolbarActionEventDetail } from './table-overlay-Bq0F5xPg.js';
12
2
 
13
3
  /**
14
4
  * ui-editor-insert-table-grid — web component for picking table dimensions.
@@ -45,4 +35,4 @@ interface SlashMenuSelectEventDetail {
45
35
  */
46
36
  type SlashMenuAnchorRect = Pick<DOMRectReadOnly, "left" | "top" | "right" | "bottom"> | Pick<DOMRectReadOnly, "x" | "y" | "width" | "height">;
47
37
 
48
- export type { InsertTableEventDetail, SlashMenuAnchorRect, SlashMenuHighlightEventDetail, SlashMenuItem, SlashMenuSelectEventDetail, TableContextMenuAction, TableContextMenuActionEventDetail, TableContextMenuActionEventDetail as TableToolbarActionEventDetail };
38
+ export type { InsertTableEventDetail, SlashMenuAnchorRect, SlashMenuHighlightEventDetail, SlashMenuItem, SlashMenuSelectEventDetail };
package/editor/ui.js CHANGED
@@ -1 +1,9 @@
1
- import "./chunk-CWCXYQMT.js";
1
+ import "./chunk-KQQTYVRW.js";
2
+ import {
3
+ TABLE_CELL_BACKGROUND_OPTIONS,
4
+ TABLE_CELL_BACKGROUND_PRESETS
5
+ } from "./chunk-CX4QDKSV.js";
6
+ export {
7
+ TABLE_CELL_BACKGROUND_OPTIONS,
8
+ TABLE_CELL_BACKGROUND_PRESETS
9
+ };
package/editor.css CHANGED
@@ -3,6 +3,230 @@
3
3
  * Tables, context menu, insert-table grid, slash menu. Use with ProseMirror/Tiptap content.
4
4
  */
5
5
 
6
+ /* Turnkey editor */
7
+ .looma-editor {
8
+ position: relative;
9
+ min-width: 0;
10
+ color: var(--ui-text-primary);
11
+ font-family: var(--ui-font-family-sans);
12
+ }
13
+
14
+ .looma-editor .ProseMirror {
15
+ min-height: var(--ui-editor-content-min-height, 300px);
16
+ padding:
17
+ var(--ui-editor-content-padding-block, var(--ui-space-4))
18
+ var(--ui-editor-content-padding-inline, var(--ui-space-6));
19
+ outline: none;
20
+ color: var(--ui-editor-content-color, var(--ui-text-primary));
21
+ caret-color: var(--ui-editor-caret-color, var(--ui-accent-solid));
22
+ font-family: var(--ui-editor-font-family, var(--ui-font-family-sans));
23
+ font-size: var(--ui-editor-font-size, var(--ui-font-size-md));
24
+ line-height: var(--ui-editor-line-height, var(--ui-line-height-relaxed));
25
+ }
26
+
27
+ @media (max-width: 767px) {
28
+ .looma-editor .ProseMirror {
29
+ padding-bottom: var(--ui-editor-mobile-bottom-space, 80px);
30
+ }
31
+ }
32
+
33
+ .looma-editor .ProseMirror p {
34
+ margin: 0 0 var(--ui-editor-paragraph-gap, var(--ui-space-3));
35
+ }
36
+
37
+ .looma-editor .ProseMirror h1,
38
+ .looma-editor .ProseMirror h2,
39
+ .looma-editor .ProseMirror h3 {
40
+ color: inherit;
41
+ line-height: var(--ui-line-height-tight);
42
+ }
43
+
44
+ .looma-editor .ProseMirror h1 {
45
+ margin: var(--ui-space-6) 0 var(--ui-space-3);
46
+ font-size: var(--ui-font-size-2xl);
47
+ font-weight: var(--ui-font-bold);
48
+ }
49
+
50
+ .looma-editor .ProseMirror h2 {
51
+ margin: var(--ui-space-5) 0 var(--ui-space-2);
52
+ font-size: var(--ui-font-size-xl);
53
+ font-weight: var(--ui-font-semibold);
54
+ }
55
+
56
+ .looma-editor .ProseMirror h3 {
57
+ margin: var(--ui-space-4) 0 var(--ui-space-2);
58
+ font-size: var(--ui-font-size-lg);
59
+ font-weight: var(--ui-font-semibold);
60
+ }
61
+
62
+ .looma-editor .ProseMirror ul,
63
+ .looma-editor .ProseMirror ol {
64
+ margin: 0 0 var(--ui-space-3);
65
+ padding-left: var(--ui-space-6);
66
+ }
67
+
68
+ .looma-editor .ProseMirror li {
69
+ margin-bottom: var(--ui-space-1);
70
+ }
71
+
72
+ .looma-editor .ProseMirror blockquote {
73
+ margin: var(--ui-space-4) 0;
74
+ padding-left: var(--ui-space-4);
75
+ border-left: 3px solid var(--ui-accent-solid);
76
+ color: var(--ui-text-secondary);
77
+ font-style: italic;
78
+ }
79
+
80
+ .looma-editor .ProseMirror pre {
81
+ margin: var(--ui-space-4) 0;
82
+ padding: var(--ui-space-4);
83
+ overflow-x: auto;
84
+ border: 1px solid var(--ui-border-default);
85
+ border-radius: var(--ui-radius-2);
86
+ background: var(--ui-surface-muted);
87
+ font-family: var(--ui-font-family-mono, ui-monospace, monospace);
88
+ font-size: var(--ui-font-size-sm);
89
+ }
90
+
91
+ .looma-editor .ProseMirror code {
92
+ padding: 0.1em 0.3em;
93
+ border-radius: var(--ui-radius-1);
94
+ background: var(--ui-surface-subtle);
95
+ font-family: var(--ui-font-family-mono, ui-monospace, monospace);
96
+ font-size: 0.9em;
97
+ }
98
+
99
+ .looma-editor .ProseMirror pre code {
100
+ padding: 0;
101
+ background: none;
102
+ }
103
+
104
+ .looma-editor .ProseMirror hr {
105
+ margin: var(--ui-space-6) 0;
106
+ border: 0;
107
+ border-top: 1px solid var(--ui-border-default);
108
+ }
109
+
110
+ .looma-editor .ProseMirror mark {
111
+ border-radius: var(--ui-radius-1);
112
+ background: var(--ui-editor-highlight-bg, var(--ui-warning-soft));
113
+ }
114
+
115
+ .looma-editor .ProseMirror a {
116
+ color: var(--ui-editor-link-color, var(--ui-accent-solid));
117
+ text-decoration: underline;
118
+ }
119
+
120
+ .looma-editor .ProseMirror ul[data-type="taskList"] {
121
+ padding-left: var(--ui-space-2);
122
+ list-style: none;
123
+ }
124
+
125
+ .looma-editor .ProseMirror ul[data-type="taskList"] li {
126
+ display: flex;
127
+ align-items: flex-start;
128
+ gap: var(--ui-space-2);
129
+ }
130
+
131
+ .looma-editor .ProseMirror ul[data-type="taskList"] li > label {
132
+ margin-top: 3px;
133
+ }
134
+
135
+ .looma-editor .ProseMirror ul[data-type="taskList"] input[type="checkbox"] {
136
+ width: 16px;
137
+ height: 16px;
138
+ accent-color: var(--ui-accent-solid);
139
+ cursor: pointer;
140
+ }
141
+
142
+ .looma-editor .ProseMirror .is-editor-empty:first-child::before {
143
+ float: left;
144
+ height: 0;
145
+ color: var(--ui-text-muted);
146
+ content: attr(data-placeholder);
147
+ pointer-events: none;
148
+ }
149
+
150
+ .looma-editor .ProseMirror img {
151
+ max-width: 100%;
152
+ margin: var(--ui-space-3) 0;
153
+ border-radius: var(--ui-radius-2);
154
+ }
155
+
156
+ .looma-editor__file-input {
157
+ position: absolute;
158
+ width: 0;
159
+ height: 0;
160
+ opacity: 0;
161
+ pointer-events: none;
162
+ }
163
+
164
+ .looma-editor__drop-overlay {
165
+ position: absolute;
166
+ z-index: var(--ui-editor-drop-overlay-z-index, 10);
167
+ inset: 0;
168
+ display: flex;
169
+ flex-direction: column;
170
+ align-items: center;
171
+ justify-content: center;
172
+ gap: var(--ui-space-3);
173
+ border: 2px dashed var(--ui-accent-solid);
174
+ border-radius: var(--ui-radius-2);
175
+ background: color-mix(in srgb, var(--ui-accent-soft) 92%, transparent);
176
+ color: var(--ui-accent-active);
177
+ font-size: var(--ui-font-size-sm);
178
+ font-weight: var(--ui-font-semibold);
179
+ pointer-events: none;
180
+ }
181
+
182
+ .looma-editor__drop-glyph {
183
+ font-size: var(--ui-font-size-2xl);
184
+ }
185
+
186
+ .looma-editor__toolbar-button {
187
+ --ui-icon-button-size-sm: var(--ui-editor-toolbar-button-size, 2rem);
188
+ --ui-icon-button-radius: var(--ui-editor-toolbar-button-radius, var(--ui-radius-1));
189
+ --ui-icon-button-icon-size: var(--ui-editor-toolbar-icon-size, 1rem);
190
+ }
191
+
192
+ .looma-editor__toolbar-glyph {
193
+ display: inline-flex;
194
+ align-items: center;
195
+ justify-content: center;
196
+ min-width: 1em;
197
+ color: inherit;
198
+ font-family: var(--ui-font-family-sans);
199
+ font-size: var(--ui-editor-toolbar-glyph-size, 0.75rem);
200
+ font-weight: var(--ui-font-semibold);
201
+ line-height: 1;
202
+ }
203
+
204
+ .looma-editor__table-picker-anchor {
205
+ display: inline-flex;
206
+ }
207
+
208
+ .looma-editor__table-picker-popover,
209
+ .looma-editor__table-toolbar-shell,
210
+ .looma-editor__table-menu-shell {
211
+ z-index: var(--ui-editor-popover-z-index, 300);
212
+ }
213
+
214
+ .looma-editor__table-picker-popover {
215
+ min-width: 220px;
216
+ }
217
+
218
+ .looma-editor__table-toolbar-shell,
219
+ .looma-editor__table-menu-shell,
220
+ .looma-editor__table-overlay-shell {
221
+ position: fixed;
222
+ }
223
+
224
+ .looma-editor__table-overlay-shell {
225
+ z-index: var(--ui-editor-overlay-z-index, 299);
226
+ overflow: visible;
227
+ pointer-events: none;
228
+ }
229
+
6
230
  /* Slash menu */
7
231
  ui-editor-slash-menu {
8
232
  user-select: none;
@@ -458,6 +682,36 @@ ui-editor-toolbar[floating] {
458
682
  text-align: left;
459
683
  }
460
684
 
685
+ .ui-editor-table-toolbar__swatches {
686
+ display: grid;
687
+ grid-template-columns: repeat(3, minmax(0, 1fr));
688
+ gap: 2px;
689
+ }
690
+
691
+ .ui-editor-table-toolbar__swatch-button {
692
+ gap: var(--ui-space-1, 4px);
693
+ justify-content: flex-start !important;
694
+ }
695
+
696
+ .ui-editor-table-toolbar__swatch {
697
+ width: 14px;
698
+ height: 14px;
699
+ flex: 0 0 14px;
700
+ border: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, #000);
701
+ border-radius: 3px;
702
+ background: var(--ui-editor-table-toolbar-swatch);
703
+ }
704
+
705
+ .ui-editor-table-toolbar__swatch--default {
706
+ background:
707
+ linear-gradient(135deg, transparent 44%, var(--ui-danger, #dc2626) 46% 54%, transparent 56%),
708
+ var(--ui-surface, #fff);
709
+ }
710
+
711
+ .ui-editor-table-toolbar__swatch-button[data-selected="true"] {
712
+ background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
713
+ }
714
+
461
715
  /* Insert table grid */
462
716
  .ui-editor-insert-table-grid {
463
717
  padding: var(--ui-space-3, 12px);
@@ -584,6 +838,7 @@ ui-editor-toolbar[floating] {
584
838
  }
585
839
 
586
840
  .ui-editor-table-overlay__control--row {
841
+ pointer-events: auto;
587
842
  left: 0;
588
843
  right: 0;
589
844
  top: calc(var(--ui-editor-table-overlay-boundary-index) * 100% / var(--ui-editor-table-overlay-segments));
@@ -662,6 +917,11 @@ ui-editor-toolbar[floating] {
662
917
  }
663
918
 
664
919
  /* ProseMirror table (for when Looma editor content is rendered) */
920
+ .ProseMirror:focus-visible {
921
+ outline: none;
922
+ box-shadow: none;
923
+ }
924
+
665
925
  .ProseMirror table {
666
926
  border-collapse: collapse;
667
927
  margin: 0;
@@ -686,6 +946,10 @@ ui-editor-toolbar[floating] {
686
946
  overflow-wrap: anywhere;
687
947
  }
688
948
 
949
+ .ProseMirror :is(th, td) > p:last-child {
950
+ margin-bottom: 0;
951
+ }
952
+
689
953
  .ProseMirror th {
690
954
  font-weight: 600;
691
955
  background: var(--ui-surface-hover, #f3f4f6);
package/layout/index.css CHANGED
@@ -8,7 +8,6 @@
8
8
  :where(ui-stack, ui-inline, ui-cluster, ui-grid, ui-center, ui-switcher, ui-sidebar, ui-reel, ui-separator) {
9
9
  all: revert-layer;
10
10
  box-sizing: border-box;
11
- margin: 0;
12
11
  font-family: var(--ui-font-family-sans);
13
12
  font-size: var(--ui-font-size-md);
14
13
  line-height: var(--ui-line-height-md);
@@ -31,6 +30,7 @@
31
30
  :where(ui-stack, ui-inline, ui-cluster, ui-grid, ui-center, ui-switcher, ui-sidebar, ui-reel, ui-separator) {
32
31
  min-inline-size: 0;
33
32
  max-inline-size: 100%;
33
+ margin: 0;
34
34
  }
35
35
  ui-stack {
36
36
  --ui-layout-gap: var(--ui-space-4, 1rem);
package/layout.css CHANGED
@@ -10,7 +10,6 @@
10
10
  /* Reveal Looma's component layer instead of reverting past it. */
11
11
  all: revert-layer;
12
12
  box-sizing: border-box;
13
- margin: 0;
14
13
  font-family: var(--ui-font-family-sans);
15
14
  font-size: var(--ui-font-size-md);
16
15
  line-height: var(--ui-line-height-md);
@@ -35,6 +34,7 @@
35
34
  :where(ui-stack, ui-inline, ui-cluster, ui-grid, ui-center, ui-switcher, ui-sidebar, ui-reel, ui-separator) {
36
35
  min-inline-size: 0;
37
36
  max-inline-size: 100%;
37
+ margin: 0;
38
38
  }
39
39
 
40
40
  ui-stack {