@flyingrobots/bijou 3.0.0 → 4.0.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 +159 -21
- package/README.md +100 -13
- package/dist/adapters/test/clock.d.ts +36 -0
- package/dist/adapters/test/clock.d.ts.map +1 -0
- package/dist/adapters/test/clock.js +132 -0
- package/dist/adapters/test/clock.js.map +1 -0
- package/dist/adapters/test/index.d.ts +8 -1
- package/dist/adapters/test/index.d.ts.map +1 -1
- package/dist/adapters/test/index.js +20 -2
- package/dist/adapters/test/index.js.map +1 -1
- package/dist/adapters/test/io.d.ts +3 -0
- package/dist/adapters/test/io.d.ts.map +1 -1
- package/dist/adapters/test/io.js +5 -4
- package/dist/adapters/test/io.js.map +1 -1
- package/dist/core/ansi.d.ts +2 -0
- package/dist/core/ansi.d.ts.map +1 -1
- package/dist/core/ansi.js +2 -0
- package/dist/core/ansi.js.map +1 -1
- package/dist/core/clock.d.ts +12 -0
- package/dist/core/clock.d.ts.map +1 -0
- package/dist/core/clock.js +59 -0
- package/dist/core/clock.js.map +1 -0
- package/dist/core/components/alert-v3.d.ts +7 -0
- package/dist/core/components/alert-v3.d.ts.map +1 -0
- package/dist/core/components/alert-v3.js +37 -0
- package/dist/core/components/alert-v3.js.map +1 -0
- package/dist/core/components/alert.d.ts +2 -0
- package/dist/core/components/alert.d.ts.map +1 -1
- package/dist/core/components/alert.js +1 -1
- package/dist/core/components/alert.js.map +1 -1
- package/dist/core/components/box-v3.d.ts +9 -2
- package/dist/core/components/box-v3.d.ts.map +1 -1
- package/dist/core/components/box-v3.js +78 -21
- package/dist/core/components/box-v3.js.map +1 -1
- package/dist/core/components/box.d.ts +7 -0
- package/dist/core/components/box.d.ts.map +1 -1
- package/dist/core/components/box.js +13 -7
- package/dist/core/components/box.js.map +1 -1
- package/dist/core/components/index.d.ts +6 -0
- package/dist/core/components/index.d.ts.map +1 -1
- package/dist/core/components/index.js +4 -0
- package/dist/core/components/index.js.map +1 -1
- package/dist/core/components/log.d.ts.map +1 -1
- package/dist/core/components/log.js +4 -3
- package/dist/core/components/log.js.map +1 -1
- package/dist/core/components/overflow.d.ts +3 -0
- package/dist/core/components/overflow.d.ts.map +1 -0
- package/dist/core/components/overflow.js +33 -0
- package/dist/core/components/overflow.js.map +1 -0
- package/dist/core/components/progress.d.ts.map +1 -1
- package/dist/core/components/progress.js +3 -1
- package/dist/core/components/progress.js.map +1 -1
- package/dist/core/components/separator-v3.d.ts +7 -0
- package/dist/core/components/separator-v3.d.ts.map +1 -0
- package/dist/core/components/separator-v3.js +46 -0
- package/dist/core/components/separator-v3.js.map +1 -0
- package/dist/core/components/spinner.d.ts.map +1 -1
- package/dist/core/components/spinner.js +3 -1
- package/dist/core/components/spinner.js.map +1 -1
- package/dist/core/components/surface-text.d.ts +14 -0
- package/dist/core/components/surface-text.d.ts.map +1 -0
- package/dist/core/components/surface-text.js +95 -0
- package/dist/core/components/surface-text.js.map +1 -0
- package/dist/core/components/table-v3.d.ts +11 -0
- package/dist/core/components/table-v3.d.ts.map +1 -0
- package/dist/core/components/table-v3.js +148 -0
- package/dist/core/components/table-v3.js.map +1 -0
- package/dist/core/components/table.d.ts +2 -1
- package/dist/core/components/table.d.ts.map +1 -1
- package/dist/core/components/table.js +40 -11
- package/dist/core/components/table.js.map +1 -1
- package/dist/core/components/timer.d.ts.map +1 -1
- package/dist/core/components/timer.js +11 -9
- package/dist/core/components/timer.js.map +1 -1
- package/dist/core/components/types.d.ts +4 -0
- package/dist/core/components/types.d.ts.map +1 -1
- package/dist/core/render/differ.d.ts +3 -3
- package/dist/core/render/differ.d.ts.map +1 -1
- package/dist/core/render/differ.js +33 -14
- package/dist/core/render/differ.js.map +1 -1
- package/dist/core/runtime-viewport.d.ts +34 -0
- package/dist/core/runtime-viewport.d.ts.map +1 -0
- package/dist/core/runtime-viewport.js +74 -0
- package/dist/core/runtime-viewport.js.map +1 -0
- package/dist/core/text/index.d.ts +1 -0
- package/dist/core/text/index.d.ts.map +1 -1
- package/dist/core/text/index.js +1 -0
- package/dist/core/text/index.js.map +1 -1
- package/dist/core/text/wrap.d.ts +11 -0
- package/dist/core/text/wrap.d.ts.map +1 -0
- package/dist/core/text/wrap.js +90 -0
- package/dist/core/text/wrap.js.map +1 -0
- package/dist/factory.d.ts +3 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +3 -0
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/ports/clock.d.ts +29 -0
- package/dist/ports/clock.d.ts.map +1 -0
- package/dist/ports/clock.js +2 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/context.d.ts +3 -0
- package/dist/ports/context.d.ts.map +1 -1
- package/dist/ports/index.d.ts +1 -0
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ClockPort } from '../../ports/clock.js';
|
|
1
2
|
import type { IOPort } from '../../ports/io.js';
|
|
2
3
|
/**
|
|
3
4
|
* Configuration for {@link mockIO}.
|
|
@@ -7,6 +8,8 @@ export interface MockIOOptions {
|
|
|
7
8
|
answers?: string[];
|
|
8
9
|
/** Pre-loaded keypress strings delivered by {@link MockIO.rawInput} via microtasks. */
|
|
9
10
|
keys?: string[];
|
|
11
|
+
/** Clock override for deterministic timer and microtask scheduling in tests. */
|
|
12
|
+
clock?: ClockPort;
|
|
10
13
|
/** Virtual filesystem entries (path to content) for {@link MockIO.readFile}. */
|
|
11
14
|
files?: Record<string, string>;
|
|
12
15
|
/** Virtual directory listings (path to entries) for {@link MockIO.readDir}. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/io.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAA+B,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/io.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAA+B,MAAM,mBAAmB,CAAC;AAI7E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,gFAAgF;IAChF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,MAAO,SAAQ,MAAM;IACpC,yFAAyF;IACzF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gDAAgD;IAChD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mEAAmE;IACnE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAiH1D"}
|
package/dist/adapters/test/io.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveClock } from '../../core/clock.js';
|
|
1
2
|
import { join } from 'path';
|
|
2
3
|
/**
|
|
3
4
|
* Create an in-memory {@link IOPort} for tests.
|
|
@@ -15,6 +16,7 @@ export function mockIO(options = {}) {
|
|
|
15
16
|
const answerQueue = [...(options.answers ?? [])];
|
|
16
17
|
const files = { ...(options.files ?? {}) };
|
|
17
18
|
const dirs = { ...(options.dirs ?? {}) };
|
|
19
|
+
const clock = resolveClock(options.clock);
|
|
18
20
|
return {
|
|
19
21
|
written,
|
|
20
22
|
writtenErr,
|
|
@@ -63,9 +65,9 @@ export function mockIO(options = {}) {
|
|
|
63
65
|
const key = keyQueue.shift();
|
|
64
66
|
onKey(key);
|
|
65
67
|
if (keyQueue.length > 0)
|
|
66
|
-
queueMicrotask(deliver);
|
|
68
|
+
clock.queueMicrotask(deliver);
|
|
67
69
|
}
|
|
68
|
-
queueMicrotask(deliver);
|
|
70
|
+
clock.queueMicrotask(deliver);
|
|
69
71
|
return { dispose() { disposed = true; } };
|
|
70
72
|
},
|
|
71
73
|
/**
|
|
@@ -83,8 +85,7 @@ export function mockIO(options = {}) {
|
|
|
83
85
|
* @returns A handle whose `dispose()` cancels the timer.
|
|
84
86
|
*/
|
|
85
87
|
setInterval(callback, ms) {
|
|
86
|
-
|
|
87
|
-
return { dispose() { clearInterval(id); } };
|
|
88
|
+
return clock.setInterval(callback, ms);
|
|
88
89
|
},
|
|
89
90
|
/**
|
|
90
91
|
* Read a file from the virtual filesystem.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../../src/adapters/test/io.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../../src/adapters/test/io.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAqC5B;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CAAC,UAAyB,EAAE;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3C,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE1C,OAAO;QACL,OAAO;QACP,UAAU;QACV,WAAW;QACX,KAAK;QACL,IAAI;QAEJ;;;WAGG;QACH,KAAK,CAAC,IAAY;YAChB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAED;;;WAGG;QACH,UAAU,CAAC,IAAY;YACrB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAED;;;;WAIG;QACH,QAAQ,CAAC,MAAc;YACrB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QAED;;;;;;;;WAQG;QACH,QAAQ,CAAC,KAA4B;YACnC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3C,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,mEAAmE;YACnE,SAAS,OAAO;gBACd,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO;gBAC9C,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAG,CAAC;gBAC9B,KAAK,CAAC,GAAG,CAAC,CAAC;gBACX,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;oBAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACzD,CAAC;YACD,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,CAAC;QAED;;;;WAIG;QACH,QAAQ,CAAC,SAA+C;YACtD,OAAO,EAAE,OAAO,KAAI,CAAC,EAAE,CAAC;QAC1B,CAAC;QAED;;;;;WAKG;QACH,WAAW,CAAC,QAAoB,EAAE,EAAU;YAC1C,OAAO,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACzC,CAAC;QAED;;;;;WAKG;QACH,QAAQ,CAAC,IAAY;YACnB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,OAAO,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;YAC5E,OAAO,OAAO,CAAC;QACjB,CAAC;QAED;;;;WAIG;QACH,OAAO,CAAC,IAAY;YAClB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;QAED;;;;WAIG;QACH,QAAQ,CAAC,GAAG,QAAkB;YAC5B,OAAO,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/core/ansi.d.ts
CHANGED
|
@@ -12,4 +12,6 @@ export declare const CLEAR_LINE_RETURN = "\r\u001B[K";
|
|
|
12
12
|
export declare const HIDE_CURSOR = "\u001B[?25l";
|
|
13
13
|
/** ANSI escape: show the text cursor (DEC Private Mode 25). */
|
|
14
14
|
export declare const SHOW_CURSOR = "\u001B[?25h";
|
|
15
|
+
/** ANSI escape: reset SGR style state. */
|
|
16
|
+
export declare const RESET_SGR = "\u001B[0m";
|
|
15
17
|
//# sourceMappingURL=ansi.d.ts.map
|
package/dist/core/ansi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ansi.d.ts","sourceRoot":"","sources":["../../src/core/ansi.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yGAAyG;AACzG,eAAO,MAAM,iBAAiB,eAAa,CAAC;AAE5C,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAc,CAAC;AAEvC,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"ansi.d.ts","sourceRoot":"","sources":["../../src/core/ansi.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yGAAyG;AACzG,eAAO,MAAM,iBAAiB,eAAa,CAAC;AAE5C,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAc,CAAC;AAEvC,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAc,CAAC;AAEvC,0CAA0C;AAC1C,eAAO,MAAM,SAAS,cAAY,CAAC"}
|
package/dist/core/ansi.js
CHANGED
|
@@ -12,4 +12,6 @@ export const CLEAR_LINE_RETURN = '\r\x1b[K';
|
|
|
12
12
|
export const HIDE_CURSOR = '\x1b[?25l';
|
|
13
13
|
/** ANSI escape: show the text cursor (DEC Private Mode 25). */
|
|
14
14
|
export const SHOW_CURSOR = '\x1b[?25h';
|
|
15
|
+
/** ANSI escape: reset SGR style state. */
|
|
16
|
+
export const RESET_SGR = '\x1b[0m';
|
|
15
17
|
//# sourceMappingURL=ansi.js.map
|
package/dist/core/ansi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ansi.js","sourceRoot":"","sources":["../../src/core/ansi.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yGAAyG;AACzG,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE5C,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEvC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"ansi.js","sourceRoot":"","sources":["../../src/core/ansi.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,yGAAyG;AACzG,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE5C,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEvC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEvC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ClockPort } from '../ports/clock.js';
|
|
2
|
+
/** Return the shared system-backed clock. */
|
|
3
|
+
export declare function systemClock(): ClockPort;
|
|
4
|
+
/** Resolve a clock from an explicit port or a context-like object. */
|
|
5
|
+
export declare function resolveClock(value?: ClockPort | {
|
|
6
|
+
clock?: ClockPort;
|
|
7
|
+
}): ClockPort;
|
|
8
|
+
/** Sleep for `ms` milliseconds using the provided clock port. */
|
|
9
|
+
export declare function sleep(clock: ClockPort, ms: number): Promise<void>;
|
|
10
|
+
/** Yield to the next microtask using the provided clock port. */
|
|
11
|
+
export declare function defer(clock: ClockPort): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=clock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../../src/core/clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAwCnD,6CAA6C;AAC7C,wBAAgB,WAAW,IAAI,SAAS,CAEvC;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG;IAAE,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAMjF;AAED,iEAAiE;AACjE,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;AAED,iEAAiE;AACjE,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default system-backed clock implementation.
|
|
3
|
+
*
|
|
4
|
+
* This remains the runtime default, while tests can inject a deterministic
|
|
5
|
+
* implementation through `BijouContext.clock`.
|
|
6
|
+
*/
|
|
7
|
+
const SYSTEM_CLOCK = {
|
|
8
|
+
now() {
|
|
9
|
+
return Date.now();
|
|
10
|
+
},
|
|
11
|
+
date(ms) {
|
|
12
|
+
return new Date(ms ?? Date.now());
|
|
13
|
+
},
|
|
14
|
+
setTimeout(callback, ms) {
|
|
15
|
+
const id = globalThis.setTimeout(callback, ms);
|
|
16
|
+
return {
|
|
17
|
+
dispose() {
|
|
18
|
+
globalThis.clearTimeout(id);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
setInterval(callback, ms) {
|
|
23
|
+
const id = globalThis.setInterval(callback, ms);
|
|
24
|
+
return {
|
|
25
|
+
dispose() {
|
|
26
|
+
globalThis.clearInterval(id);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
queueMicrotask(callback) {
|
|
31
|
+
globalThis.queueMicrotask(callback);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/** Return the shared system-backed clock. */
|
|
35
|
+
export function systemClock() {
|
|
36
|
+
return SYSTEM_CLOCK;
|
|
37
|
+
}
|
|
38
|
+
/** Resolve a clock from an explicit port or a context-like object. */
|
|
39
|
+
export function resolveClock(value) {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
return SYSTEM_CLOCK;
|
|
42
|
+
if (typeof value === 'object' && value !== null && 'now' in value) {
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
return value.clock ?? SYSTEM_CLOCK;
|
|
46
|
+
}
|
|
47
|
+
/** Sleep for `ms` milliseconds using the provided clock port. */
|
|
48
|
+
export function sleep(clock, ms) {
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
clock.setTimeout(resolve, ms);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/** Yield to the next microtask using the provided clock port. */
|
|
54
|
+
export function defer(clock) {
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
clock.queueMicrotask(resolve);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=clock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/core/clock.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,YAAY,GAAc;IAC9B,GAAG;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,EAAW;QACd,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,UAAU,CAAC,QAAoB,EAAE,EAAU;QACzC,MAAM,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO;YACL,OAAO;gBACL,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAC9B,CAAC;SACF,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,QAAoB,EAAE,EAAU;QAC1C,MAAM,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChD,OAAO;YACL,OAAO;gBACL,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;SACF,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,QAAoB;QACjC,UAAU,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;CACF,CAAC;AAEF,6CAA6C;AAC7C,MAAM,UAAU,WAAW;IACzB,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAAC,KAAyC;IACpE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,YAAY,CAAC;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QAClE,OAAO,KAAkB,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,IAAI,YAAY,CAAC;AACrC,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,KAAK,CAAC,KAAgB,EAAE,EAAU;IAChD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,KAAK,CAAC,KAAgB;IACpC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Surface } from '../../ports/surface.js';
|
|
2
|
+
import { type AlertOptions } from './alert.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render an alert box as a Surface for V3-native composition.
|
|
5
|
+
*/
|
|
6
|
+
export declare function alertSurface(message: string | Surface, options?: AlertOptions): Surface;
|
|
7
|
+
//# sourceMappingURL=alert-v3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-v3.d.ts","sourceRoot":"","sources":["../../../src/core/components/alert-v3.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,YAAY,CAAC;AAkBlE;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAkB3F"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createSurface } from '../../ports/surface.js';
|
|
2
|
+
import { resolveSafeCtx as resolveCtx } from '../resolve-ctx.js';
|
|
3
|
+
import { boxSurface } from './box-v3.js';
|
|
4
|
+
import { createTextSurface, tokenToCellStyle } from './surface-text.js';
|
|
5
|
+
const ICONS = {
|
|
6
|
+
success: '\u2713',
|
|
7
|
+
error: '\u2717',
|
|
8
|
+
warning: '\u26A0',
|
|
9
|
+
info: '\u2139',
|
|
10
|
+
};
|
|
11
|
+
const BORDER_TOKENS = {
|
|
12
|
+
success: 'success',
|
|
13
|
+
error: 'error',
|
|
14
|
+
warning: 'warning',
|
|
15
|
+
info: 'primary',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Render an alert box as a Surface for V3-native composition.
|
|
19
|
+
*/
|
|
20
|
+
export function alertSurface(message, options = {}) {
|
|
21
|
+
const ctx = resolveCtx(options.ctx);
|
|
22
|
+
const variant = options.variant ?? 'info';
|
|
23
|
+
const iconSurface = createTextSurface(ICONS[variant], tokenToCellStyle(ctx?.semantic(variant)));
|
|
24
|
+
const messageSurface = typeof message === 'string' ? createTextSurface(message) : message;
|
|
25
|
+
const width = iconSurface.width + 1 + messageSurface.width;
|
|
26
|
+
const height = Math.max(iconSurface.height, messageSurface.height, 1);
|
|
27
|
+
const content = createSurface(width, height, { char: ' ', empty: false });
|
|
28
|
+
content.blit(iconSurface, 0, 0);
|
|
29
|
+
content.set(iconSurface.width, 0, { char: ' ', empty: false });
|
|
30
|
+
content.blit(messageSurface, iconSurface.width + 1, 0);
|
|
31
|
+
return boxSurface(content, {
|
|
32
|
+
...options,
|
|
33
|
+
borderToken: options.borderToken ?? ctx?.border(BORDER_TOKENS[variant]),
|
|
34
|
+
bgToken: options.bgToken ?? ctx?.surface('elevated'),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=alert-v3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-v3.js","sourceRoot":"","sources":["../../../src/core/components/alert-v3.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,cAAc,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAExE,MAAM,KAAK,GAAiC;IAC1C,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,MAAM,aAAa,GAAsE;IACvF,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAyB,EAAE,UAAwB,EAAE;IAChF,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAC1C,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChG,MAAM,cAAc,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1F,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC;IAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAE1E,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvD,OAAO,UAAU,CAAC,OAAO,EAAE;QACzB,GAAG,OAAO;QACV,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,GAAG,EAAE,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACvE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC;KACrD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -6,6 +6,8 @@ export type AlertVariant = 'success' | 'error' | 'warning' | 'info';
|
|
|
6
6
|
export interface AlertOptions extends BijouNodeOptions {
|
|
7
7
|
/** Severity variant (defaults to `'info'`). */
|
|
8
8
|
variant?: AlertVariant;
|
|
9
|
+
/** Theme token applied to alert borders. Defaults to a variant-specific border token. */
|
|
10
|
+
borderToken?: TokenValue;
|
|
9
11
|
/** Background fill token for the alert box interior. Defaults to `surface.elevated`. */
|
|
10
12
|
bgToken?: TokenValue;
|
|
11
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAI5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,4BAA4B;AAC5B,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpE,gDAAgD;AAChD,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,wFAAwF;IACxF,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAsBzE"}
|
|
1
|
+
{"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAI5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,4BAA4B;AAC5B,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpE,gDAAgD;AAChD,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,yFAAyF;IACzF,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,wFAAwF;IACxF,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAsBzE"}
|
|
@@ -51,7 +51,7 @@ export function alert(message, options = {}) {
|
|
|
51
51
|
interactive: () => {
|
|
52
52
|
const icon = ICONS[variant];
|
|
53
53
|
const semanticToken = ctx.semantic(variant);
|
|
54
|
-
const borderToken = ctx.border(BORDER_TOKENS[variant]);
|
|
54
|
+
const borderToken = options.borderToken ?? ctx.border(BORDER_TOKENS[variant]);
|
|
55
55
|
const coloredIcon = ctx.style.styled(semanticToken, icon);
|
|
56
56
|
return box(coloredIcon + ' ' + safeMessage, {
|
|
57
57
|
borderToken,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgBjD,sDAAsD;AACtD,MAAM,KAAK,GAAiC;IAC1C,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,iDAAiD;AACjD,MAAM,WAAW,GAAiC;IAChD,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,yDAAyD;AACzD,MAAM,iBAAiB,GAAiC;IACtD,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,8EAA8E;AAC9E,MAAM,aAAa,GAAgD;IACjE,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;CAChB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,OAAe,EAAE,UAAwB,EAAE;IAC/D,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAC1C,MAAM,WAAW,GAAG,OAAO,IAAI,EAAE,CAAC;IAElC,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE;QAC5B,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,KAAK,WAAW,EAAE;QACtD,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,WAAW,EAAE;QACjE,WAAW,EAAE,GAAG,EAAE;YAChB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5B,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9E,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAE1D,OAAO,GAAG,CAAC,WAAW,GAAG,GAAG,GAAG,WAAW,EAAE;gBAC1C,WAAW;gBACX,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC;gBACnD,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;gBAC9B,GAAG;aACJ,CAAC,CAAC;QACL,CAAC;KACF,EAAE,OAAO,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { type Surface } from '../../ports/surface.js';
|
|
2
|
-
import { type BoxOptions } from './box.js';
|
|
2
|
+
import { type BoxOptions, type HeaderBoxOptions } from './box.js';
|
|
3
3
|
/**
|
|
4
4
|
* Render a bordered box around a Surface.
|
|
5
5
|
*
|
|
6
6
|
* Returns a new Surface containing the box and the nested content.
|
|
7
7
|
*/
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function boxSurface(content: Surface | string, options?: BoxOptions): Surface;
|
|
9
|
+
/**
|
|
10
|
+
* Render a header box as a Surface for V3-native composition.
|
|
11
|
+
*
|
|
12
|
+
* Unlike {@link headerBox}, this always returns a Surface and is intended
|
|
13
|
+
* for use inside framed apps or other surface-first render paths.
|
|
14
|
+
*/
|
|
15
|
+
export declare function headerBoxSurface(label: string, options?: HeaderBoxOptions): Surface;
|
|
9
16
|
//# sourceMappingURL=box-v3.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box-v3.d.ts","sourceRoot":"","sources":["../../../src/core/components/box-v3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAa,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"box-v3.d.ts","sourceRoot":"","sources":["../../../src/core/components/box-v3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAa,MAAM,wBAAwB,CAAC;AAIhF,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AA4BnF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAwGvF;AACD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAmBvF"}
|
|
@@ -1,49 +1,82 @@
|
|
|
1
1
|
import { createSurface } from '../../ports/surface.js';
|
|
2
2
|
import { resolveSafeCtx as resolveCtx } from '../resolve-ctx.js';
|
|
3
|
-
import {
|
|
3
|
+
import { clipToWidth } from '../text/clip.js';
|
|
4
|
+
import { wrapToWidth } from '../text/wrap.js';
|
|
5
|
+
import { resolveFillChar } from './box.js';
|
|
4
6
|
import { applyBCSSCellTextStyles } from './bcss-style.js';
|
|
7
|
+
import { createSegmentSurface, createTextSurface, segmentSurfaceText, tokenToCellStyle, wrapSurfaceToWidth } from './surface-text.js';
|
|
8
|
+
import { resolveOverflowBehavior } from './overflow.js';
|
|
5
9
|
const BORDER = { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│' };
|
|
10
|
+
function normalizeFixedWidth(width) {
|
|
11
|
+
if (width == null)
|
|
12
|
+
return undefined;
|
|
13
|
+
if (!Number.isFinite(width))
|
|
14
|
+
return undefined;
|
|
15
|
+
return Math.max(2, Math.floor(width));
|
|
16
|
+
}
|
|
17
|
+
function withInheritedBackground(surface, background) {
|
|
18
|
+
if (background == null)
|
|
19
|
+
return surface;
|
|
20
|
+
const next = surface.clone();
|
|
21
|
+
for (let y = 0; y < next.height; y++) {
|
|
22
|
+
for (let x = 0; x < next.width; x++) {
|
|
23
|
+
const cell = next.get(x, y);
|
|
24
|
+
if (cell.empty || cell.bg != null)
|
|
25
|
+
continue;
|
|
26
|
+
next.set(x, y, { ...cell, bg: background });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
6
31
|
/**
|
|
7
32
|
* Render a bordered box around a Surface.
|
|
8
33
|
*
|
|
9
34
|
* Returns a new Surface containing the box and the nested content.
|
|
10
35
|
*/
|
|
11
|
-
export function
|
|
36
|
+
export function boxSurface(content, options = {}) {
|
|
12
37
|
const ctx = resolveCtx(options.ctx);
|
|
13
38
|
const { title, width: fixedWidth, padding = {} } = options;
|
|
14
39
|
const bcss = ctx?.resolveBCSS({ type: 'Box', id: options.id, classes: options.class?.split(' ') }) ?? {};
|
|
40
|
+
const overflow = resolveOverflowBehavior(options.overflow, bcss);
|
|
41
|
+
const normalizedFixedWidth = normalizeFixedWidth(fixedWidth);
|
|
15
42
|
const pt = padding.top ?? 0;
|
|
16
43
|
const pb = padding.bottom ?? 0;
|
|
17
44
|
const pl = padding.left ?? 0;
|
|
18
45
|
const pr = padding.right ?? 0;
|
|
19
46
|
let contentSurf;
|
|
20
47
|
if (typeof content === 'string') {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
contentSurf =
|
|
25
|
-
lines.forEach((line, y) => {
|
|
26
|
-
const gs = segmentGraphemes(line);
|
|
27
|
-
gs.forEach((char, x) => {
|
|
28
|
-
contentSurf.set(x, y, { char });
|
|
29
|
-
});
|
|
30
|
-
});
|
|
48
|
+
const wrapped = normalizedFixedWidth !== undefined && overflow === 'wrap'
|
|
49
|
+
? wrapToWidth(content, Math.max(0, normalizedFixedWidth - 2 - pl - pr)).join('\n')
|
|
50
|
+
: content;
|
|
51
|
+
contentSurf = createTextSurface(wrapped);
|
|
31
52
|
}
|
|
32
53
|
else {
|
|
33
|
-
contentSurf =
|
|
54
|
+
contentSurf = normalizedFixedWidth !== undefined && overflow === 'wrap'
|
|
55
|
+
? wrapSurfaceToWidth(content, Math.max(0, normalizedFixedWidth - 2 - pl - pr))
|
|
56
|
+
: content;
|
|
34
57
|
}
|
|
35
|
-
const
|
|
58
|
+
const autoTitleWidth = normalizedFixedWidth === undefined && title
|
|
59
|
+
? segmentSurfaceText(` ${title} `, 'boxSurface title').length
|
|
60
|
+
: 0;
|
|
61
|
+
const innerW = normalizedFixedWidth === undefined
|
|
62
|
+
? Math.max(contentSurf.width + pl + pr, autoTitleWidth)
|
|
63
|
+
: contentSurf.width + pl + pr;
|
|
36
64
|
const innerH = contentSurf.height + pt + pb;
|
|
37
|
-
const outerW =
|
|
65
|
+
const outerW = normalizedFixedWidth ?? (innerW + 2);
|
|
38
66
|
const outerH = innerH + 2;
|
|
67
|
+
const boundedInnerW = Math.max(0, outerW - 2);
|
|
68
|
+
const effectiveLeft = normalizedFixedWidth !== undefined ? Math.min(pl, boundedInnerW) : pl;
|
|
69
|
+
const effectiveRight = normalizedFixedWidth !== undefined ? Math.min(pr, Math.max(0, boundedInnerW - effectiveLeft)) : pr;
|
|
70
|
+
const contentBoxWidth = Math.max(0, boundedInnerW - effectiveLeft - effectiveRight);
|
|
39
71
|
const surface = createSurface(outerW, outerH);
|
|
72
|
+
const resolvedFillChar = resolveFillChar(options.fillChar);
|
|
40
73
|
const fillStyle = applyBCSSCellTextStyles({
|
|
41
74
|
fg: undefined,
|
|
42
|
-
bg:
|
|
75
|
+
bg: options.bgToken?.bg,
|
|
43
76
|
modifiers: undefined,
|
|
44
77
|
}, bcss);
|
|
45
78
|
surface.fill({
|
|
46
|
-
char:
|
|
79
|
+
char: resolvedFillChar,
|
|
47
80
|
bg: fillStyle.bg,
|
|
48
81
|
fg: fillStyle.fg,
|
|
49
82
|
modifiers: fillStyle.modifiers,
|
|
@@ -76,16 +109,40 @@ export function boxV3(content, options = {}) {
|
|
|
76
109
|
surface.set(outerW - 1, outerH - 1, { ...borderCell, char: BORDER.br });
|
|
77
110
|
// Draw title
|
|
78
111
|
if (title && outerW >= 4) {
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
112
|
+
const available = Math.max(0, outerW - 4);
|
|
113
|
+
const titleText = clipToWidth(` ${title} `, available);
|
|
114
|
+
const titleGs = segmentSurfaceText(titleText, 'boxSurface title');
|
|
82
115
|
const titleLen = Math.min(titleGs.length, available);
|
|
83
116
|
for (let i = 0; i < titleLen; i++) {
|
|
84
117
|
surface.set(i + 2, 0, { ...borderCell, char: titleGs[i] });
|
|
85
118
|
}
|
|
86
119
|
}
|
|
87
120
|
// Blit content
|
|
88
|
-
surface.blit(contentSurf,
|
|
121
|
+
surface.blit(withInheritedBackground(contentSurf, fillStyle.bg), effectiveLeft + 1, pt + 1, 0, 0, contentBoxWidth, contentSurf.height);
|
|
89
122
|
return surface;
|
|
90
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Render a header box as a Surface for V3-native composition.
|
|
126
|
+
*
|
|
127
|
+
* Unlike {@link headerBox}, this always returns a Surface and is intended
|
|
128
|
+
* for use inside framed apps or other surface-first render paths.
|
|
129
|
+
*/
|
|
130
|
+
export function headerBoxSurface(label, options = {}) {
|
|
131
|
+
const ctx = resolveCtx(options.ctx);
|
|
132
|
+
const safeLabel = label ?? '';
|
|
133
|
+
const detail = options.detail ?? '';
|
|
134
|
+
const labelToken = options.labelToken ?? ctx?.semantic('primary');
|
|
135
|
+
const mutedToken = ctx?.semantic('muted');
|
|
136
|
+
const segments = [];
|
|
137
|
+
if (safeLabel.length > 0) {
|
|
138
|
+
segments.push({ text: safeLabel, style: tokenToCellStyle(labelToken) });
|
|
139
|
+
}
|
|
140
|
+
if (detail.length > 0) {
|
|
141
|
+
segments.push({
|
|
142
|
+
text: safeLabel.length > 0 ? ` ${detail}` : detail,
|
|
143
|
+
style: tokenToCellStyle(mutedToken),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return boxSurface(createSegmentSurface(segments), options);
|
|
147
|
+
}
|
|
91
148
|
//# sourceMappingURL=box-v3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box-v3.js","sourceRoot":"","sources":["../../../src/core/components/box-v3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA2B,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,cAAc,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"box-v3.js","sourceRoot":"","sources":["../../../src/core/components/box-v3.ts"],"names":[],"mappings":"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"}
|
|
@@ -55,4 +55,11 @@ export interface HeaderBoxOptions extends BoxOptions {
|
|
|
55
55
|
* @returns The rendered header box string.
|
|
56
56
|
*/
|
|
57
57
|
export declare function headerBox(label: string, options?: HeaderBoxOptions): string;
|
|
58
|
+
/**
|
|
59
|
+
* Validate and resolve a fill character option.
|
|
60
|
+
*
|
|
61
|
+
* Returns the character if it is a single-width grapheme cluster,
|
|
62
|
+
* otherwise falls back to a space.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveFillChar(fillChar: string | undefined): string;
|
|
58
65
|
//# sourceMappingURL=box.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,kDAAkD;AAClD,MAAM,WAAW,UAAW,SAAQ,gBAAgB;IAClD,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,oFAAoF;IACpF,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,0EAA0E;IAC1E,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3E,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAwGD;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM,CA2BrE;AAED,4FAA4F;AAC5F,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAqB/E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIpE"}
|
|
@@ -2,15 +2,17 @@ import { resolveCtx } from '../resolve-ctx.js';
|
|
|
2
2
|
import { makeBgFill } from '../bg-fill.js';
|
|
3
3
|
import { graphemeWidth } from '../text/grapheme.js';
|
|
4
4
|
import { clipToWidth } from '../text/clip.js';
|
|
5
|
+
import { wrapToWidth } from '../text/wrap.js';
|
|
5
6
|
import { renderByMode } from '../mode-render.js';
|
|
7
|
+
import { resolveOverflowBehavior } from './overflow.js';
|
|
6
8
|
/** Unicode box-drawing characters for single-line borders. */
|
|
7
9
|
const BORDER = { tl: '\u250c', tr: '\u2510', bl: '\u2514', br: '\u2518', h: '\u2500', v: '\u2502' };
|
|
8
10
|
/**
|
|
9
11
|
* Draw a unicode box around the given content string.
|
|
10
12
|
*
|
|
11
13
|
* Supports both auto-width (measured from content) and fixed-width modes.
|
|
12
|
-
* Content lines wider than the available space
|
|
13
|
-
* `
|
|
14
|
+
* Content lines wider than the available space wrap by default. Set
|
|
15
|
+
* `overflow: 'truncate'` to preserve the previous hard-clipping behavior.
|
|
14
16
|
*
|
|
15
17
|
* @param content - Multiline string to place inside the box.
|
|
16
18
|
* @param borderColor - Function that wraps border characters with color styling.
|
|
@@ -21,8 +23,8 @@ const BORDER = { tl: '\u250c', tr: '\u2510', bl: '\u2514', br: '\u2518', h: '\u2
|
|
|
21
23
|
* @param title - Optional title displayed in the top border.
|
|
22
24
|
* @returns The rendered box as a multiline string.
|
|
23
25
|
*/
|
|
24
|
-
function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = ' ', title) {
|
|
25
|
-
const
|
|
26
|
+
function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = ' ', title, overflow = 'wrap') {
|
|
27
|
+
const rawContentLines = content.split('\n');
|
|
26
28
|
let innerWidth;
|
|
27
29
|
let contentWidth;
|
|
28
30
|
if (fixedWidth !== undefined) {
|
|
@@ -33,13 +35,16 @@ function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = '
|
|
|
33
35
|
else {
|
|
34
36
|
// Auto width: measure content
|
|
35
37
|
const titleWidth = title ? graphemeWidth(title) + 2 : 0;
|
|
36
|
-
const maxWidth =
|
|
38
|
+
const maxWidth = rawContentLines.reduce((max, line) => Math.max(max, graphemeWidth(line)), 0);
|
|
37
39
|
contentWidth = maxWidth;
|
|
38
40
|
innerWidth = Math.max(titleWidth, maxWidth + padding.left + padding.right);
|
|
39
41
|
}
|
|
40
42
|
// When fixed width, padding may exceed innerWidth — clamp to fit
|
|
41
43
|
const effectiveLeft = fixedWidth !== undefined ? Math.min(padding.left, innerWidth) : padding.left;
|
|
42
44
|
const effectiveRight = fixedWidth !== undefined ? Math.min(padding.right, Math.max(0, innerWidth - effectiveLeft)) : padding.right;
|
|
45
|
+
const contentLines = fixedWidth !== undefined && overflow === 'wrap'
|
|
46
|
+
? rawContentLines.flatMap((line) => wrapToWidth(line, contentWidth))
|
|
47
|
+
: rawContentLines;
|
|
43
48
|
const pad = (line) => {
|
|
44
49
|
const visible = graphemeWidth(line);
|
|
45
50
|
let processed = line;
|
|
@@ -114,7 +119,8 @@ export function box(content, options = {}) {
|
|
|
114
119
|
const colorize = (s) => ctx.style.styled(borderToken, s);
|
|
115
120
|
const bgFill = makeBgFill(options.bgToken, ctx);
|
|
116
121
|
const resolvedFill = resolveFillChar(options.fillChar);
|
|
117
|
-
|
|
122
|
+
const overflow = resolveOverflowBehavior(options.overflow, ctx.resolveBCSS({ type: 'Box', id: options.id, classes: options.class?.split(' ') }));
|
|
123
|
+
return drawBox(safeContent, colorize, padding, options.width, bgFill, resolvedFill, options.title, overflow);
|
|
118
124
|
},
|
|
119
125
|
}, options);
|
|
120
126
|
}
|
|
@@ -155,7 +161,7 @@ export function headerBox(label, options = {}) {
|
|
|
155
161
|
* Returns the character if it is a single-width grapheme cluster,
|
|
156
162
|
* otherwise falls back to a space.
|
|
157
163
|
*/
|
|
158
|
-
function resolveFillChar(fillChar) {
|
|
164
|
+
export function resolveFillChar(fillChar) {
|
|
159
165
|
if (fillChar == null || fillChar.length === 0)
|
|
160
166
|
return ' ';
|
|
161
167
|
if (graphemeWidth(fillChar) !== 1)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"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"}
|