@shadow-garden/bapbong-ui 0.1.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/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/index.cjs +1187 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1151 -0
- package/dist/lib/cell-properties.d.ts +35 -0
- package/dist/lib/cell-properties.d.ts.map +1 -0
- package/dist/lib/context-menu.d.ts +24 -0
- package/dist/lib/context-menu.d.ts.map +1 -0
- package/dist/lib/dialog.d.ts +55 -0
- package/dist/lib/dialog.d.ts.map +1 -0
- package/dist/lib/find.d.ts +53 -0
- package/dist/lib/find.d.ts.map +1 -0
- package/dist/lib/internal.d.ts +25 -0
- package/dist/lib/internal.d.ts.map +1 -0
- package/dist/lib/menubar.d.ts +56 -0
- package/dist/lib/menubar.d.ts.map +1 -0
- package/dist/lib/table-grid.d.ts +14 -0
- package/dist/lib/table-grid.d.ts.map +1 -0
- package/dist/lib/toolbar.d.ts +73 -0
- package/dist/lib/toolbar.d.ts.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BorderStyle } from '@shadow-garden/bapbong-contracts';
|
|
2
|
+
/** Which edges a border preset paints (Outside/Inside are position-dependent
|
|
3
|
+
* across a multi-cell block — the host resolves them per cell). */
|
|
4
|
+
export type BorderPreset = 'all' | 'none' | 'outside' | 'inside' | 'top' | 'bottom' | 'left' | 'right' | 'insideH' | 'insideV';
|
|
5
|
+
/** The chosen border pen + which preset to apply it with. */
|
|
6
|
+
export interface BorderChoice {
|
|
7
|
+
preset: BorderPreset;
|
|
8
|
+
/** Stroke width in CSS px (converted from the pt picker). */
|
|
9
|
+
width: number;
|
|
10
|
+
style: BorderStyle;
|
|
11
|
+
color: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CellPropsResult {
|
|
14
|
+
background: string | null;
|
|
15
|
+
vAlign: 'top' | 'center' | 'bottom';
|
|
16
|
+
/** Present only if the user picked a border preset (else borders untouched). */
|
|
17
|
+
border?: BorderChoice;
|
|
18
|
+
}
|
|
19
|
+
export interface CellPropertiesOptions {
|
|
20
|
+
initial: {
|
|
21
|
+
background: string | null;
|
|
22
|
+
vAlign: 'top' | 'center' | 'bottom';
|
|
23
|
+
};
|
|
24
|
+
/** Disable Inside / Inside-H / Inside-V (meaningless for a 1×1 selection). */
|
|
25
|
+
singleCell: boolean;
|
|
26
|
+
onApply: (result: CellPropsResult) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The cell-properties dialog (modal): fill, vertical alignment, and a Word/Docs
|
|
30
|
+
* style borders panel (10 presets + width / style / colour). Borders are
|
|
31
|
+
* action-based — pick the pen, click a preset, and on Apply the host paints
|
|
32
|
+
* that preset across the selected block. Untouched borders are left as-is.
|
|
33
|
+
*/
|
|
34
|
+
export declare function openCellProperties({ initial, singleCell, onApply }: CellPropertiesOptions): void;
|
|
35
|
+
//# sourceMappingURL=cell-properties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cell-properties.d.ts","sourceRoot":"","sources":["../../src/lib/cell-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAIpE;oEACoE;AACpE,MAAM,MAAM,YAAY,GACpB,KAAK,GACL,MAAM,GACN,SAAS,GACT,QAAQ,GACR,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,SAAS,GACT,SAAS,CAAC;AAEd,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACpC,gFAAgF;IAChF,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAA;KAAE,CAAC;IAC5E,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CAC5C;AAiFD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,qBAAqB,GAAG,IAAI,CAyLhG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** A one-shot context-menu row. */
|
|
2
|
+
export interface ContextMenuItem {
|
|
3
|
+
label: string;
|
|
4
|
+
run: () => void;
|
|
5
|
+
/** Render disabled when false. */
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
/** Optional right-aligned hint (e.g. '⌘X'). */
|
|
8
|
+
shortcut?: string;
|
|
9
|
+
}
|
|
10
|
+
export type ContextMenuEntry = ContextMenuItem | 'separator';
|
|
11
|
+
export interface ContextMenuHandle {
|
|
12
|
+
close(): void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Show a context menu at viewport point `at`. One-shot rows (label + run, with
|
|
16
|
+
* optional enabled/shortcut) and separators; closes on select, outside click,
|
|
17
|
+
* Escape, or scroll. Only one is open at a time. Reusable for any right-click
|
|
18
|
+
* surface — the editor's pointer hook gives the host the position + target.
|
|
19
|
+
*/
|
|
20
|
+
export declare function showContextMenu(entries: ContextMenuEntry[], at: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
}): ContextMenuHandle;
|
|
24
|
+
//# sourceMappingURL=context-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../src/lib/context-menu.ts"],"names":[],"mappings":"AAEA,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,WAAW,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAChC,KAAK,IAAI,IAAI,CAAC;CACf;AAuBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CA2E5G"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface DialogOptions {
|
|
2
|
+
title?: string;
|
|
3
|
+
/** Modal (backdrop + focus trap) vs non-modal floating panel. Default false. */
|
|
4
|
+
modal?: boolean;
|
|
5
|
+
/** Extra class on the `<dialog>` element. */
|
|
6
|
+
className?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Pin a non-modal dialog's top-right corner just inside this rect (e.g. the
|
|
9
|
+
* editor's canvas viewport) instead of the screen corner. Re-evaluated on
|
|
10
|
+
* open + scroll/resize. Return null to fall back to the default position.
|
|
11
|
+
*/
|
|
12
|
+
anchor?: () => DOMRect | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A generic, framework-agnostic dialog — a reusable overlay primitive built on
|
|
16
|
+
* the native `<dialog>` element (so modal mode gets focus-trapping, `Esc` and a
|
|
17
|
+
* backdrop for free). Drop any element into `body`; call `open()` / `close()`.
|
|
18
|
+
* Used by the find panel, the prompt helper, the keyboard-shortcuts popup, and
|
|
19
|
+
* (later) the cell-properties dialog — one primitive, not N bespoke widgets.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Dialog {
|
|
22
|
+
readonly el: HTMLDialogElement;
|
|
23
|
+
/** Content slot — put your element(s) here. */
|
|
24
|
+
readonly body: HTMLElement;
|
|
25
|
+
private readonly title;
|
|
26
|
+
private readonly modal;
|
|
27
|
+
private readonly anchor?;
|
|
28
|
+
private readonly closeListeners;
|
|
29
|
+
private readonly reposition;
|
|
30
|
+
constructor(options?: DialogOptions);
|
|
31
|
+
private attachReposition;
|
|
32
|
+
private detachReposition;
|
|
33
|
+
setTitle(text: string): void;
|
|
34
|
+
/** Replace the body content. */
|
|
35
|
+
setContent(node: HTMLElement): void;
|
|
36
|
+
open(): void;
|
|
37
|
+
close(): void;
|
|
38
|
+
get isOpen(): boolean;
|
|
39
|
+
/** Subscribe to close (Esc, ✕, backdrop, or `close()`); returns unsubscribe. */
|
|
40
|
+
onClose(cb: () => void): () => void;
|
|
41
|
+
destroy(): void;
|
|
42
|
+
}
|
|
43
|
+
export interface PromptOptions {
|
|
44
|
+
title: string;
|
|
45
|
+
placeholder?: string;
|
|
46
|
+
initial?: string;
|
|
47
|
+
confirm?: string;
|
|
48
|
+
cancel?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A one-line input modal built on {@link Dialog} — the vanilla replacement for
|
|
52
|
+
* `window.prompt`. Resolves to the trimmed value, or null if cancelled/closed.
|
|
53
|
+
*/
|
|
54
|
+
export declare function promptDialog(options: PromptOptions): Promise<string | null>;
|
|
55
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/lib/dialog.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;CAC/B;AAqBD;;;;;;GAMG;AACH,qBAAa,MAAM;IACjB,QAAQ,CAAC,EAAE,EAAE,iBAAiB,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAOzB;gBAEU,OAAO,GAAE,aAAkB;IA4CvC,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,gBAAgB;IAKxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI5B,gCAAgC;IAChC,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAInC,IAAI,IAAI,IAAI;IAUZ,KAAK,IAAI,IAAI;IAIb,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,gFAAgF;IAChF,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAKnC,OAAO,IAAI,IAAI;CAKhB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4C3E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Query / match-count snapshot the find plugin emits. */
|
|
2
|
+
export interface FindState {
|
|
3
|
+
query: string;
|
|
4
|
+
count: number;
|
|
5
|
+
/** 1-based index of the active match (0 when none). */
|
|
6
|
+
active: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The find/replace surface the panel binds to — the editor's `find` handle
|
|
10
|
+
* (FindPlugin) satisfies it structurally, so this package never imports the
|
|
11
|
+
* editor (same decoupling as {@link EditorHandle}).
|
|
12
|
+
*/
|
|
13
|
+
export interface FindHandle {
|
|
14
|
+
setQuery(q: string): void;
|
|
15
|
+
next(): void;
|
|
16
|
+
prev(): void;
|
|
17
|
+
clear(): void;
|
|
18
|
+
replaceCurrent(text: string): void;
|
|
19
|
+
replaceAll(text: string): void;
|
|
20
|
+
/** Subscribe to query/count/active changes; returns an unsubscribe. */
|
|
21
|
+
onState(cb: (s: FindState) => void): () => void;
|
|
22
|
+
}
|
|
23
|
+
export interface FindDialogOptions {
|
|
24
|
+
/** Modal vs non-modal (default false — keeps the document editable). */
|
|
25
|
+
modal?: boolean;
|
|
26
|
+
/** Pin the panel's top-right inside this rect (e.g. the canvas viewport). */
|
|
27
|
+
anchor?: () => DOMRect | null;
|
|
28
|
+
/** Open on Ctrl/Cmd+F (pre-empting the browser's native find). Default true. */
|
|
29
|
+
shortcut?: boolean;
|
|
30
|
+
/** Override the (English) default labels for i18n. */
|
|
31
|
+
labels?: Partial<{
|
|
32
|
+
title: string;
|
|
33
|
+
find: string;
|
|
34
|
+
replace: string;
|
|
35
|
+
prev: string;
|
|
36
|
+
next: string;
|
|
37
|
+
replaceOne: string;
|
|
38
|
+
replaceAll: string;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
export interface FindDialogHandle {
|
|
42
|
+
open(): void;
|
|
43
|
+
close(): void;
|
|
44
|
+
destroy(): void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Build a find/replace panel inside a {@link Dialog}, bound to `find`
|
|
48
|
+
* (`editor.find`). Returns open/close/destroy; opening focuses the query input,
|
|
49
|
+
* closing clears the search so highlights go away. The host (any framework)
|
|
50
|
+
* just opens it from a menu / shortcut.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createFindDialog(find: FindHandle, options?: FindDialogOptions): FindDialogHandle;
|
|
53
|
+
//# sourceMappingURL=find.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../src/lib/find.ts"],"names":[],"mappings":"AAGA,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,uEAAuE;IACvE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,IAAI,IAAI,CAAC;CACjB;AAuBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAuGpG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Collection, Command, Dispatch, EditorChange } from '@shadow-garden/bapbong-contracts';
|
|
2
|
+
/** The editor `run` state type, derived from the {@link Command} contract so
|
|
3
|
+
* this package needs no direct ProseMirror dependency. */
|
|
4
|
+
export type EditorStateOf = Parameters<Command['run']>[0];
|
|
5
|
+
/**
|
|
6
|
+
* The minimal editor surface every bapbong-ui widget binds to. `BapbongEditor`
|
|
7
|
+
* satisfies it structurally, so this package never imports the editor — both
|
|
8
|
+
* just speak the `contracts` vocabulary (the same decoupling as the plugin
|
|
9
|
+
* contract). A host framework only supplies the element + this handle.
|
|
10
|
+
*/
|
|
11
|
+
export interface EditorHandle {
|
|
12
|
+
/** Named command registry the UI renders + dispatches against. */
|
|
13
|
+
readonly commands: Collection<Command>;
|
|
14
|
+
/** Current document + selection (throws before a document is loaded). */
|
|
15
|
+
readonly state: EditorStateOf;
|
|
16
|
+
/** Apply a transaction. */
|
|
17
|
+
dispatch: Dispatch;
|
|
18
|
+
/** Return focus to the editor (after a control takes a click). */
|
|
19
|
+
focus(): void;
|
|
20
|
+
/** Subscribe to editor cycles; returns an unsubscribe. Drives active state. */
|
|
21
|
+
onChange(cb: (c: EditorChange) => void): () => void;
|
|
22
|
+
}
|
|
23
|
+
/** Inject a stylesheet once, keyed by `id` (idempotent across mounts). */
|
|
24
|
+
export declare function injectStyle(id: string, css: string): void;
|
|
25
|
+
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/lib/internal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEpG;2DAC2D;AAC3D,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,2BAA2B;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,kEAAkE;IAClE,KAAK,IAAI,IAAI,CAAC;IACd,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACrD;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAMzD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Collection, Command } from '@shadow-garden/bapbong-contracts';
|
|
2
|
+
import { type EditorHandle } from './internal.js';
|
|
3
|
+
/** Run a registry command (and read its active/enabled state). */
|
|
4
|
+
export interface CommandEntry {
|
|
5
|
+
command: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Run a host-supplied action (File ▸ Open, View ▸ comment mode, Help…). */
|
|
9
|
+
export interface ActionEntry {
|
|
10
|
+
label: string;
|
|
11
|
+
run: () => void;
|
|
12
|
+
isActive?: () => boolean;
|
|
13
|
+
isEnabled?: () => boolean;
|
|
14
|
+
shortcut?: string;
|
|
15
|
+
}
|
|
16
|
+
/** A nested dropdown. */
|
|
17
|
+
export interface SubmenuEntry {
|
|
18
|
+
label: string;
|
|
19
|
+
submenu: MenuEntry[];
|
|
20
|
+
}
|
|
21
|
+
/** Custom flyout content (e.g. a table size grid). `close` dismisses the menu. */
|
|
22
|
+
export interface WidgetEntry {
|
|
23
|
+
label: string;
|
|
24
|
+
widget: (close: () => void) => HTMLElement;
|
|
25
|
+
}
|
|
26
|
+
export type MenuEntry = 'separator' | CommandEntry | ActionEntry | SubmenuEntry | WidgetEntry;
|
|
27
|
+
/** A top-level menu (its title + dropdown entries). */
|
|
28
|
+
export interface Menu {
|
|
29
|
+
label: string;
|
|
30
|
+
entries: MenuEntry[];
|
|
31
|
+
}
|
|
32
|
+
export interface MenubarOptions {
|
|
33
|
+
/** Menus to render. Default: a single "Format" menu derived from the registry. */
|
|
34
|
+
menus?: Menu[];
|
|
35
|
+
/** Command-name → row label override, merged over the built-in labels. */
|
|
36
|
+
labels?: Record<string, string>;
|
|
37
|
+
/** `vertical` stacks the menu titles in a column and opens each dropdown to
|
|
38
|
+
* the right, bottom-aligned so it grows upward — for a menubar docked in a
|
|
39
|
+
* corner (e.g. bottom-left). Default `horizontal` (a classic top bar). */
|
|
40
|
+
orientation?: 'horizontal' | 'vertical';
|
|
41
|
+
}
|
|
42
|
+
export interface MenubarHandle {
|
|
43
|
+
destroy(): void;
|
|
44
|
+
}
|
|
45
|
+
/** Default menus: a "Format" menu of marks, a separator, then alignments —
|
|
46
|
+
* only the commands the registry actually has. */
|
|
47
|
+
export declare function defaultMenus(commands: Collection<Command>): Menu[];
|
|
48
|
+
/**
|
|
49
|
+
* Render a menubar into `host` and wire it to `editor`. Top-level titles open
|
|
50
|
+
* dropdowns; entries can be registry commands (with an active check), host
|
|
51
|
+
* actions, nested submenus, or custom widgets. The lib owns the DOM, styling,
|
|
52
|
+
* open/close and active state; the host framework only supplies the element +
|
|
53
|
+
* the editor handle, then calls `destroy()`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function mountMenubar(host: HTMLElement, editor: EditorHandle, options?: MenubarOptions): MenubarHandle;
|
|
56
|
+
//# sourceMappingURL=menubar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../../src/lib/menubar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,KAAK,YAAY,EAAmC,MAAM,eAAe,CAAC;AAEnF,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,yBAAyB;AACzB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AACD,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,WAAW,CAAC;CAC5C;AACD,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC;AAE9F,uDAAuD;AACvD,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;+EAE2E;IAC3E,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAmDD;mDACmD;AACnD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAUlE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CA0Lf"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface TableGridOptions {
|
|
2
|
+
/** Max selectable rows / columns (the grid size). Default 8 × 10. */
|
|
3
|
+
maxRows?: number;
|
|
4
|
+
maxCols?: number;
|
|
5
|
+
/** Called with the 1-based size when a cell is clicked. */
|
|
6
|
+
onPick: (rows: number, cols: number) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A Word/Docs-style table size picker: hover the grid to size, click to choose.
|
|
10
|
+
* Returns a detached element to drop into a menu widget flyout; calls
|
|
11
|
+
* `onPick(rows, cols)` (1-based) on click.
|
|
12
|
+
*/
|
|
13
|
+
export declare function tableGridPicker(options: TableGridOptions): HTMLElement;
|
|
14
|
+
//# sourceMappingURL=table-grid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-grid.d.ts","sourceRoot":"","sources":["../../src/lib/table-grid.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAUD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW,CAuCtE"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Collection, Command } from '@shadow-garden/bapbong-contracts';
|
|
2
|
+
import { type EditorHandle, type EditorStateOf } from './internal.js';
|
|
3
|
+
/** Presentation for one toolbar button — the headless {@link Command} carries
|
|
4
|
+
* no UI, so labels/icons live here. */
|
|
5
|
+
export interface ToolbarItem {
|
|
6
|
+
/** Tooltip + accessible label. */
|
|
7
|
+
title: string;
|
|
8
|
+
/** Text/glyph shown when `svg` is absent. */
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Inline SVG markup (used instead of `label`). */
|
|
11
|
+
svg?: string;
|
|
12
|
+
/** Extra class on the button (e.g. to render a bold "B"). */
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/** A dropdown control in the toolbar (e.g. font size / family). The host owns
|
|
16
|
+
* the command to run — the toolbar just renders the `<select>` and reports the
|
|
17
|
+
* current value, so the lib stays decoupled from specific commands. */
|
|
18
|
+
export interface ToolbarSelect {
|
|
19
|
+
kind: 'select';
|
|
20
|
+
/** Tooltip + accessible label. */
|
|
21
|
+
title: string;
|
|
22
|
+
options: {
|
|
23
|
+
label: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}[];
|
|
26
|
+
/** Current value to show from editor state (`''` = none / mixed). */
|
|
27
|
+
value: (state: EditorStateOf) => string;
|
|
28
|
+
/** Called when the user picks a value. */
|
|
29
|
+
onSelect: (value: string) => void;
|
|
30
|
+
/** Fixed width in px (defaults to auto). */
|
|
31
|
+
width?: number;
|
|
32
|
+
}
|
|
33
|
+
/** A colour-picker control: a button (a glyph over a colour bar) that opens a
|
|
34
|
+
* swatch palette. The host owns the command; the lib renders the popover. */
|
|
35
|
+
export interface ToolbarColor {
|
|
36
|
+
kind: 'color';
|
|
37
|
+
title: string;
|
|
38
|
+
/** Glyph above the colour bar (e.g. 'A' for text colour, '🖉' for highlight). */
|
|
39
|
+
glyph: string;
|
|
40
|
+
/** Swatch colours offered (hex). */
|
|
41
|
+
swatches: string[];
|
|
42
|
+
/** Offer a "None / automatic" entry that clears the colour. */
|
|
43
|
+
allowNone?: boolean;
|
|
44
|
+
/** Current colour from state (shown in the bar), or null. */
|
|
45
|
+
value: (state: EditorStateOf) => string | null;
|
|
46
|
+
/** Called with the picked colour (null = cleared). */
|
|
47
|
+
onSelect: (color: string | null) => void;
|
|
48
|
+
}
|
|
49
|
+
/** A toolbar group entry: a command name (button) or a control (select/colour). */
|
|
50
|
+
export type ToolbarEntry = string | ToolbarSelect | ToolbarColor;
|
|
51
|
+
export interface ToolbarOptions {
|
|
52
|
+
/** Groups rendered as separated clusters — command names (buttons) and/or
|
|
53
|
+
* controls (selects). Defaults to marks then alignments, from the registry. */
|
|
54
|
+
groups?: ToolbarEntry[][];
|
|
55
|
+
/** Presentation per command name, merged over the built-in defaults. */
|
|
56
|
+
items?: Record<string, ToolbarItem>;
|
|
57
|
+
}
|
|
58
|
+
/** Handle returned by {@link mountToolbar}. */
|
|
59
|
+
export interface ToolbarHandle {
|
|
60
|
+
destroy(): void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Default grouping: every non-`align-*` command, then the `align-*` commands —
|
|
64
|
+
* derived from the registry so new commands appear without config.
|
|
65
|
+
*/
|
|
66
|
+
export declare function defaultToolbarGroups(commands: Collection<Command>): string[][];
|
|
67
|
+
/**
|
|
68
|
+
* Render a toolbar into `host` and wire it to `editor`. The lib owns all the
|
|
69
|
+
* DOM, styling and active-state tracking; a host framework only provides the
|
|
70
|
+
* element and the editor handle, then calls `destroy()` on teardown.
|
|
71
|
+
*/
|
|
72
|
+
export declare function mountToolbar(host: HTMLElement, editor: EditorHandle, options?: ToolbarOptions): ToolbarHandle;
|
|
73
|
+
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar.d.ts","sourceRoot":"","sources":["../../src/lib/toolbar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAe,MAAM,eAAe,CAAC;AAEnF;wCACwC;AACxC,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;wEAEwE;AACxE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,qEAAqE;IACrE,KAAK,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,MAAM,CAAC;IACxC,0CAA0C;IAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;8EAC8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,KAAK,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/C,sDAAsD;IACtD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC1C;AAED,mFAAmF;AACnF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B;oFACgF;IAChF,MAAM,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC;IAC1B,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AA0ED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,EAAE,CAK9E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,cAAmB,GAC3B,aAAa,CA4Nf"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shadow-garden/bapbong-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "bapbong — framework-agnostic editor UI (toolbar/menubar) that mounts into a host element and binds to editor.commands",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/shadowgarden-app/bapbong.git",
|
|
9
|
+
"directory": "packages/ui"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.cjs",
|
|
13
|
+
"module": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
"./package.json": "./package.json",
|
|
17
|
+
".": {
|
|
18
|
+
"@shadow-garden/source": "./src/index.ts",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs",
|
|
22
|
+
"default": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"!**/*.tsbuildinfo"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"nx": {
|
|
33
|
+
"tags": [
|
|
34
|
+
"scope:app"
|
|
35
|
+
],
|
|
36
|
+
"targets": {
|
|
37
|
+
"build": {
|
|
38
|
+
"executor": "@nx/esbuild:esbuild",
|
|
39
|
+
"outputs": [
|
|
40
|
+
"{options.outputPath}"
|
|
41
|
+
],
|
|
42
|
+
"options": {
|
|
43
|
+
"outputPath": "packages/ui/dist",
|
|
44
|
+
"main": "packages/ui/src/index.ts",
|
|
45
|
+
"tsConfig": "packages/ui/tsconfig.lib.json",
|
|
46
|
+
"format": [
|
|
47
|
+
"esm",
|
|
48
|
+
"cjs"
|
|
49
|
+
],
|
|
50
|
+
"declarationRootDir": "packages/ui/src",
|
|
51
|
+
"external": [
|
|
52
|
+
"@shadow-garden/bapbong-contracts"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@shadow-garden/bapbong-contracts": "^0.1.0"
|
|
60
|
+
}
|
|
61
|
+
}
|