@flyingrobots/bijou 2.1.0 → 3.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/README.md +28 -20
- 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 +24 -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/adapters/test/runtime.d.ts +2 -0
- package/dist/adapters/test/runtime.d.ts.map +1 -1
- package/dist/adapters/test/runtime.js +1 -0
- package/dist/adapters/test/runtime.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 +4 -4
- 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/badge.d.ts +6 -12
- package/dist/core/components/badge.d.ts.map +1 -1
- package/dist/core/components/badge.js +39 -24
- package/dist/core/components/badge.js.map +1 -1
- package/dist/core/components/bcss-style.d.ts +6 -0
- package/dist/core/components/bcss-style.d.ts.map +1 -0
- package/dist/core/components/bcss-style.js +44 -0
- package/dist/core/components/bcss-style.js.map +1 -0
- package/dist/core/components/box-v3.d.ts +17 -0
- package/dist/core/components/box-v3.d.ts.map +1 -0
- package/dist/core/components/box-v3.js +149 -0
- package/dist/core/components/box-v3.js.map +1 -0
- package/dist/core/components/box.d.ts +11 -4
- package/dist/core/components/box.d.ts.map +1 -1
- package/dist/core/components/box.js +37 -9
- 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 +6 -4
- 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/separator.d.ts +2 -4
- package/dist/core/components/separator.d.ts.map +1 -1
- package/dist/core/components/separator.js.map +1 -1
- 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 +19 -0
- package/dist/core/components/types.d.ts.map +1 -0
- package/dist/core/components/types.js +2 -0
- package/dist/core/components/types.js.map +1 -0
- package/dist/core/layout/flex.d.ts +28 -0
- package/dist/core/layout/flex.d.ts.map +1 -0
- package/dist/core/layout/flex.js +126 -0
- package/dist/core/layout/flex.js.map +1 -0
- package/dist/core/render/differ.d.ts +49 -0
- package/dist/core/render/differ.d.ts.map +1 -0
- package/dist/core/render/differ.js +271 -0
- package/dist/core/render/differ.js.map +1 -0
- 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/core/theme/accessors.d.ts.map +1 -1
- package/dist/core/theme/accessors.js +21 -5
- package/dist/core/theme/accessors.js.map +1 -1
- package/dist/core/theme/graph-types.d.ts +58 -0
- package/dist/core/theme/graph-types.d.ts.map +1 -0
- package/dist/core/theme/graph-types.js +2 -0
- package/dist/core/theme/graph-types.js.map +1 -0
- package/dist/core/theme/graph.d.ts +27 -0
- package/dist/core/theme/graph.d.ts.map +1 -0
- package/dist/core/theme/graph.js +155 -0
- package/dist/core/theme/graph.js.map +1 -0
- package/dist/core/theme/index.d.ts +3 -0
- package/dist/core/theme/index.d.ts.map +1 -1
- package/dist/core/theme/index.js +2 -0
- package/dist/core/theme/index.js.map +1 -1
- package/dist/core/theme/resolve.d.ts +3 -0
- package/dist/core/theme/resolve.d.ts.map +1 -1
- package/dist/core/theme/resolve.js +3 -0
- package/dist/core/theme/resolve.js.map +1 -1
- package/dist/factory.d.ts +3 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +8 -0
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -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 +12 -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/dist/ports/io.d.ts +6 -0
- package/dist/ports/io.d.ts.map +1 -1
- package/dist/ports/runtime.d.ts +5 -0
- package/dist/ports/runtime.d.ts.map +1 -1
- package/dist/ports/surface.d.ts +152 -0
- package/dist/ports/surface.d.ts.map +1 -0
- package/dist/ports/surface.js +199 -0
- package/dist/ports/surface.js.map +1 -0
- package/package.json +2 -2
|
@@ -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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { BijouContext } from '../../ports/context.js';
|
|
2
1
|
import type { TokenValue } from '../theme/tokens.js';
|
|
2
|
+
import type { BijouNodeOptions } from './types.js';
|
|
3
3
|
/** Alert severity level. */
|
|
4
4
|
export type AlertVariant = 'success' | 'error' | 'warning' | 'info';
|
|
5
5
|
/** Configuration for rendering an alert box. */
|
|
6
|
-
export interface AlertOptions {
|
|
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
|
-
/** Bijou context for I/O, styling, and mode detection. */
|
|
12
|
-
ctx?: BijouContext;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* Render an alert box with an icon and message.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
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":"
|
|
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,27 +1,21 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Surface } from '../../ports/surface.js';
|
|
2
2
|
import type { BaseStatusKey } from '../theme/tokens.js';
|
|
3
|
+
import type { BijouNodeOptions } from './types.js';
|
|
3
4
|
/** Badge color variant — any status key, plus `'accent'` and `'primary'`. */
|
|
4
5
|
export type BadgeVariant = BaseStatusKey | 'accent' | 'primary';
|
|
5
6
|
/** Configuration for rendering a badge. */
|
|
6
|
-
export interface BadgeOptions {
|
|
7
|
+
export interface BadgeOptions extends BijouNodeOptions {
|
|
7
8
|
/** Color variant (defaults to `'info'`). */
|
|
8
9
|
variant?: BadgeVariant;
|
|
9
|
-
/** Bijou context for I/O, styling, and mode detection. */
|
|
10
|
-
ctx?: BijouContext;
|
|
11
10
|
}
|
|
12
11
|
/**
|
|
13
12
|
* Render an inline badge (pill-shaped label) for the given text.
|
|
14
13
|
*
|
|
15
|
-
*
|
|
16
|
-
* - `interactive` / `static` — inverse-colored pill using the variant token.
|
|
17
|
-
* - `pipe` — bracketed text like `[OK]`.
|
|
18
|
-
* - `accessible` — plain text.
|
|
19
|
-
*
|
|
20
|
-
* Falls back to a plain space-padded string when no context or theme is available.
|
|
14
|
+
* Returns a Surface containing the styled badge.
|
|
21
15
|
*
|
|
22
16
|
* @param text - Label to display inside the badge.
|
|
23
17
|
* @param options - Badge configuration.
|
|
24
|
-
* @returns The rendered badge
|
|
18
|
+
* @returns The rendered badge Surface.
|
|
25
19
|
*/
|
|
26
|
-
export declare function badge(text: string, options?: BadgeOptions):
|
|
20
|
+
export declare function badge(text: string, options?: BadgeOptions): Surface;
|
|
27
21
|
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/core/components/badge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/core/components/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAa,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,6EAA6E;AAC7E,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhE,2CAA2C;AAC3C,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IACpD,4CAA4C;IAC5C,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CA2CvE"}
|
|
@@ -1,37 +1,52 @@
|
|
|
1
|
+
import { createSurface } from '../../ports/surface.js';
|
|
1
2
|
import { resolveSafeCtx as resolveCtx } from '../resolve-ctx.js';
|
|
2
|
-
import {
|
|
3
|
+
import { segmentGraphemes } from '../text/grapheme.js';
|
|
4
|
+
import { applyBCSSCellTextStyles } from './bcss-style.js';
|
|
3
5
|
/**
|
|
4
6
|
* Render an inline badge (pill-shaped label) for the given text.
|
|
5
7
|
*
|
|
6
|
-
*
|
|
7
|
-
* - `interactive` / `static` — inverse-colored pill using the variant token.
|
|
8
|
-
* - `pipe` — bracketed text like `[OK]`.
|
|
9
|
-
* - `accessible` — plain text.
|
|
10
|
-
*
|
|
11
|
-
* Falls back to a plain space-padded string when no context or theme is available.
|
|
8
|
+
* Returns a Surface containing the styled badge.
|
|
12
9
|
*
|
|
13
10
|
* @param text - Label to display inside the badge.
|
|
14
11
|
* @param options - Badge configuration.
|
|
15
|
-
* @returns The rendered badge
|
|
12
|
+
* @returns The rendered badge Surface.
|
|
16
13
|
*/
|
|
17
14
|
export function badge(text, options = {}) {
|
|
18
15
|
const ctx = resolveCtx(options.ctx);
|
|
19
|
-
if (!ctx)
|
|
20
|
-
return ` ${text} `;
|
|
21
16
|
const variant = options.variant ?? 'info';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
const paddedText = ` ${text} `;
|
|
18
|
+
const graphemes = segmentGraphemes(paddedText);
|
|
19
|
+
const width = graphemes.length;
|
|
20
|
+
const surface = createSurface(width, 1);
|
|
21
|
+
if (!ctx || ctx.mode === 'pipe' || ctx.mode === 'accessible') {
|
|
22
|
+
// Basic text output for non-rich modes
|
|
23
|
+
const char = ctx?.mode === 'pipe' ? `[${text}]` : paddedText;
|
|
24
|
+
return stringToSurface(char, char.length, 1);
|
|
25
|
+
}
|
|
26
|
+
// Resolve global CSS styles
|
|
27
|
+
const bcss = ctx.resolveBCSS({ type: 'Badge', id: options.id, classes: options.class?.split(' ') });
|
|
28
|
+
const baseToken = (variant === 'accent' || variant === 'primary')
|
|
29
|
+
? ctx.semantic(variant)
|
|
30
|
+
: ctx.status(variant);
|
|
31
|
+
const cell = {
|
|
32
|
+
char: ' ',
|
|
33
|
+
...applyBCSSCellTextStyles({
|
|
34
|
+
fg: baseToken.hex,
|
|
35
|
+
bg: undefined,
|
|
36
|
+
modifiers: [...(baseToken.modifiers ?? []), 'inverse'],
|
|
37
|
+
}, bcss),
|
|
38
|
+
empty: false
|
|
39
|
+
};
|
|
40
|
+
// If CSS background is set, we might want to disable 'inverse' modifier
|
|
41
|
+
// since the user is being explicit about the BG color.
|
|
42
|
+
if (bcss['background']) {
|
|
43
|
+
cell.modifiers = cell.modifiers?.filter(m => m !== 'inverse');
|
|
44
|
+
}
|
|
45
|
+
for (let i = 0; i < width; i++) {
|
|
46
|
+
surface.set(i, 0, { ...cell, char: graphemes[i] });
|
|
47
|
+
}
|
|
48
|
+
return surface;
|
|
36
49
|
}
|
|
50
|
+
// Helper needed for the fallback
|
|
51
|
+
import { stringToSurface } from '../render/differ.js';
|
|
37
52
|
//# sourceMappingURL=badge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge.js","sourceRoot":"","sources":["../../../src/core/components/badge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"badge.js","sourceRoot":"","sources":["../../../src/core/components/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA2B,MAAM,wBAAwB,CAAC;AAEhF,OAAO,EAAE,cAAc,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAW1D;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,UAAwB,EAAE;IAC5D,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAE1C,MAAM,UAAU,GAAG,IAAI,IAAI,GAAG,CAAC;IAC/B,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;IAC/B,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAExC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC7D,uCAAuC;QACvC,MAAM,IAAI,GAAG,GAAG,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;QAC7D,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,4BAA4B;IAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEpG,MAAM,SAAS,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS,CAAC;QAC/D,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAExB,MAAM,IAAI,GAAS;QACjB,IAAI,EAAE,GAAG;QACT,GAAG,uBAAuB,CAAC;YACzB,EAAE,EAAE,SAAS,CAAC,GAAG;YACjB,EAAE,EAAE,SAAS;YACb,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC;SACvD,EAAE,IAAI,CAAC;QACR,KAAK,EAAE,KAAK;KACb,CAAC;IAEF,yEAAyE;IACzE,uDAAuD;IACvD,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,iCAAiC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Cell } from '../../ports/surface.js';
|
|
2
|
+
type BCSSStyles = Record<string, string>;
|
|
3
|
+
export declare function mergeBCSSModifiers(base: readonly string[] | undefined, styles: BCSSStyles): string[] | undefined;
|
|
4
|
+
export declare function applyBCSSCellTextStyles(base: Pick<Cell, 'fg' | 'bg' | 'modifiers'>, styles: BCSSStyles): Pick<Cell, 'fg' | 'bg' | 'modifiers'>;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=bcss-style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bcss-style.d.ts","sourceRoot":"","sources":["../../../src/core/components/bcss-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEzC,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACnC,MAAM,EAAE,UAAU,GACjB,MAAM,EAAE,GAAG,SAAS,CAoCtB;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,WAAW,CAAC,EAC3C,MAAM,EAAE,UAAU,GACjB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,WAAW,CAAC,CAMvC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function mergeBCSSModifiers(base, styles) {
|
|
2
|
+
const modifiers = new Set(base ?? []);
|
|
3
|
+
const fontWeight = styles['font-weight']?.trim().toLowerCase();
|
|
4
|
+
if (fontWeight === 'bold' || fontWeight === '700' || fontWeight === '800' || fontWeight === '900') {
|
|
5
|
+
modifiers.add('bold');
|
|
6
|
+
}
|
|
7
|
+
else if (fontWeight === 'normal' || fontWeight === '400') {
|
|
8
|
+
modifiers.delete('bold');
|
|
9
|
+
}
|
|
10
|
+
const fontStyle = styles['font-style']?.trim().toLowerCase();
|
|
11
|
+
if (fontStyle === 'italic') {
|
|
12
|
+
modifiers.add('italic');
|
|
13
|
+
}
|
|
14
|
+
else if (fontStyle === 'normal') {
|
|
15
|
+
modifiers.delete('italic');
|
|
16
|
+
}
|
|
17
|
+
const decoration = styles['text-decoration']?.trim().toLowerCase();
|
|
18
|
+
if (decoration === 'none') {
|
|
19
|
+
modifiers.delete('underline');
|
|
20
|
+
modifiers.delete('curly-underline');
|
|
21
|
+
modifiers.delete('dotted-underline');
|
|
22
|
+
modifiers.delete('dashed-underline');
|
|
23
|
+
modifiers.delete('strikethrough');
|
|
24
|
+
modifiers.delete('strike');
|
|
25
|
+
}
|
|
26
|
+
else if (decoration) {
|
|
27
|
+
if (decoration.includes('underline')) {
|
|
28
|
+
modifiers.add('underline');
|
|
29
|
+
}
|
|
30
|
+
if (decoration.includes('line-through')) {
|
|
31
|
+
modifiers.add('strikethrough');
|
|
32
|
+
modifiers.delete('strike');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return modifiers.size > 0 ? Array.from(modifiers) : undefined;
|
|
36
|
+
}
|
|
37
|
+
export function applyBCSSCellTextStyles(base, styles) {
|
|
38
|
+
return {
|
|
39
|
+
fg: styles['color'] ?? base.fg,
|
|
40
|
+
bg: styles['background'] ?? base.bg,
|
|
41
|
+
modifiers: mergeBCSSModifiers(base.modifiers, styles),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=bcss-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bcss-style.js","sourceRoot":"","sources":["../../../src/core/components/bcss-style.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,kBAAkB,CAChC,IAAmC,EACnC,MAAkB;IAElB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAEtC,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/D,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QAClG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;SAAM,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QAC3D,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7D,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;SAAM,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnE,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9B,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACpC,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrC,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrC,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAClC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;SAAM,IAAI,UAAU,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACxC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC/B,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,IAA2C,EAC3C,MAAkB;IAElB,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE;QAC9B,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,EAAE;QACnC,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC;KACtD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Surface } from '../../ports/surface.js';
|
|
2
|
+
import { type BoxOptions, type HeaderBoxOptions } from './box.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render a bordered box around a Surface.
|
|
5
|
+
*
|
|
6
|
+
* Returns a new Surface containing the box and the nested content.
|
|
7
|
+
*/
|
|
8
|
+
export declare function boxSurface(content: Surface | string, options?: BoxOptions): Surface;
|
|
9
|
+
export declare const boxV3: typeof boxSurface;
|
|
10
|
+
/**
|
|
11
|
+
* Render a header box as a Surface for V3-native composition.
|
|
12
|
+
*
|
|
13
|
+
* Unlike {@link headerBox}, this always returns a Surface and is intended
|
|
14
|
+
* for use inside framed apps or other surface-first render paths.
|
|
15
|
+
*/
|
|
16
|
+
export declare function headerBoxSurface(label: string, options?: HeaderBoxOptions): Surface;
|
|
17
|
+
//# sourceMappingURL=box-v3.d.ts.map
|
|
@@ -0,0 +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;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;AAED,eAAO,MAAM,KAAK,mBAAa,CAAC;AAEhC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAmBvF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { createSurface } from '../../ports/surface.js';
|
|
2
|
+
import { resolveSafeCtx as resolveCtx } from '../resolve-ctx.js';
|
|
3
|
+
import { clipToWidth } from '../text/clip.js';
|
|
4
|
+
import { wrapToWidth } from '../text/wrap.js';
|
|
5
|
+
import { resolveFillChar } from './box.js';
|
|
6
|
+
import { applyBCSSCellTextStyles } from './bcss-style.js';
|
|
7
|
+
import { createSegmentSurface, createTextSurface, segmentSurfaceText, tokenToCellStyle, wrapSurfaceToWidth } from './surface-text.js';
|
|
8
|
+
import { resolveOverflowBehavior } from './overflow.js';
|
|
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
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Render a bordered box around a Surface.
|
|
33
|
+
*
|
|
34
|
+
* Returns a new Surface containing the box and the nested content.
|
|
35
|
+
*/
|
|
36
|
+
export function boxSurface(content, options = {}) {
|
|
37
|
+
const ctx = resolveCtx(options.ctx);
|
|
38
|
+
const { title, width: fixedWidth, padding = {} } = options;
|
|
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);
|
|
42
|
+
const pt = padding.top ?? 0;
|
|
43
|
+
const pb = padding.bottom ?? 0;
|
|
44
|
+
const pl = padding.left ?? 0;
|
|
45
|
+
const pr = padding.right ?? 0;
|
|
46
|
+
let contentSurf;
|
|
47
|
+
if (typeof content === 'string') {
|
|
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);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
contentSurf = normalizedFixedWidth !== undefined && overflow === 'wrap'
|
|
55
|
+
? wrapSurfaceToWidth(content, Math.max(0, normalizedFixedWidth - 2 - pl - pr))
|
|
56
|
+
: content;
|
|
57
|
+
}
|
|
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;
|
|
64
|
+
const innerH = contentSurf.height + pt + pb;
|
|
65
|
+
const outerW = normalizedFixedWidth ?? (innerW + 2);
|
|
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);
|
|
71
|
+
const surface = createSurface(outerW, outerH);
|
|
72
|
+
const resolvedFillChar = resolveFillChar(options.fillChar);
|
|
73
|
+
const fillStyle = applyBCSSCellTextStyles({
|
|
74
|
+
fg: undefined,
|
|
75
|
+
bg: options.bgToken?.bg,
|
|
76
|
+
modifiers: undefined,
|
|
77
|
+
}, bcss);
|
|
78
|
+
surface.fill({
|
|
79
|
+
char: resolvedFillChar,
|
|
80
|
+
bg: fillStyle.bg,
|
|
81
|
+
fg: fillStyle.fg,
|
|
82
|
+
modifiers: fillStyle.modifiers,
|
|
83
|
+
empty: false,
|
|
84
|
+
});
|
|
85
|
+
const borderToken = options.borderToken || ctx?.border('primary');
|
|
86
|
+
const borderStyle = applyBCSSCellTextStyles({
|
|
87
|
+
fg: borderToken?.hex ?? '#ffffff',
|
|
88
|
+
bg: borderToken?.bg,
|
|
89
|
+
modifiers: borderToken?.modifiers,
|
|
90
|
+
}, bcss);
|
|
91
|
+
const borderCell = {
|
|
92
|
+
char: ' ',
|
|
93
|
+
fg: borderStyle.fg,
|
|
94
|
+
bg: borderStyle.bg,
|
|
95
|
+
modifiers: borderStyle.modifiers,
|
|
96
|
+
};
|
|
97
|
+
// Draw borders
|
|
98
|
+
for (let x = 0; x < outerW; x++) {
|
|
99
|
+
surface.set(x, 0, { ...borderCell, char: BORDER.h });
|
|
100
|
+
surface.set(x, outerH - 1, { ...borderCell, char: BORDER.h });
|
|
101
|
+
}
|
|
102
|
+
for (let y = 0; y < outerH; y++) {
|
|
103
|
+
surface.set(0, y, { ...borderCell, char: BORDER.v });
|
|
104
|
+
surface.set(outerW - 1, y, { ...borderCell, char: BORDER.v });
|
|
105
|
+
}
|
|
106
|
+
surface.set(0, 0, { ...borderCell, char: BORDER.tl });
|
|
107
|
+
surface.set(outerW - 1, 0, { ...borderCell, char: BORDER.tr });
|
|
108
|
+
surface.set(0, outerH - 1, { ...borderCell, char: BORDER.bl });
|
|
109
|
+
surface.set(outerW - 1, outerH - 1, { ...borderCell, char: BORDER.br });
|
|
110
|
+
// Draw title
|
|
111
|
+
if (title && outerW >= 4) {
|
|
112
|
+
const available = Math.max(0, outerW - 4);
|
|
113
|
+
const titleText = clipToWidth(` ${title} `, available);
|
|
114
|
+
const titleGs = segmentSurfaceText(titleText, 'boxSurface title');
|
|
115
|
+
const titleLen = Math.min(titleGs.length, available);
|
|
116
|
+
for (let i = 0; i < titleLen; i++) {
|
|
117
|
+
surface.set(i + 2, 0, { ...borderCell, char: titleGs[i] });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Blit content
|
|
121
|
+
surface.blit(withInheritedBackground(contentSurf, fillStyle.bg), effectiveLeft + 1, pt + 1, 0, 0, contentBoxWidth, contentSurf.height);
|
|
122
|
+
return surface;
|
|
123
|
+
}
|
|
124
|
+
export const boxV3 = boxSurface;
|
|
125
|
+
/**
|
|
126
|
+
* Render a header box as a Surface for V3-native composition.
|
|
127
|
+
*
|
|
128
|
+
* Unlike {@link headerBox}, this always returns a Surface and is intended
|
|
129
|
+
* for use inside framed apps or other surface-first render paths.
|
|
130
|
+
*/
|
|
131
|
+
export function headerBoxSurface(label, options = {}) {
|
|
132
|
+
const ctx = resolveCtx(options.ctx);
|
|
133
|
+
const safeLabel = label ?? '';
|
|
134
|
+
const detail = options.detail ?? '';
|
|
135
|
+
const labelToken = options.labelToken ?? ctx?.semantic('primary');
|
|
136
|
+
const mutedToken = ctx?.semantic('muted');
|
|
137
|
+
const segments = [];
|
|
138
|
+
if (safeLabel.length > 0) {
|
|
139
|
+
segments.push({ text: safeLabel, style: tokenToCellStyle(labelToken) });
|
|
140
|
+
}
|
|
141
|
+
if (detail.length > 0) {
|
|
142
|
+
segments.push({
|
|
143
|
+
text: safeLabel.length > 0 ? ` ${detail}` : detail,
|
|
144
|
+
style: tokenToCellStyle(mutedToken),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return boxSurface(createSegmentSurface(segments), options);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=box-v3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box-v3.js","sourceRoot":"","sources":["../../../src/core/components/box-v3.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { BijouContext } from '../../ports/context.js';
|
|
2
1
|
import type { TokenValue } from '../theme/tokens.js';
|
|
2
|
+
import type { BijouNodeOptions } from './types.js';
|
|
3
3
|
/** Configuration for rendering a bordered box. */
|
|
4
|
-
export interface BoxOptions {
|
|
4
|
+
export interface BoxOptions extends BijouNodeOptions {
|
|
5
|
+
/** Optional title displayed in the top border. */
|
|
6
|
+
title?: string;
|
|
5
7
|
/** Theme token applied to border characters. */
|
|
6
8
|
borderToken?: TokenValue;
|
|
7
9
|
/** Background fill token. Interior spaces are styled with this token's bg color. */
|
|
@@ -21,8 +23,6 @@ export interface BoxOptions {
|
|
|
21
23
|
* are rejected and fall back to space.
|
|
22
24
|
*/
|
|
23
25
|
fillChar?: string;
|
|
24
|
-
/** Bijou context for I/O, styling, and mode detection. */
|
|
25
|
-
ctx?: BijouContext;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Render content inside a bordered box.
|
|
@@ -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,
|
|
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.
|
|
@@ -18,10 +20,11 @@ const BORDER = { tl: '\u250c', tr: '\u2510', bl: '\u2514', br: '\u2518', h: '\u2
|
|
|
18
20
|
* @param fixedWidth - If provided, lock the outer width and clip/pad content to fit.
|
|
19
21
|
* @param bgFill - Optional function to wrap interior content with background color styling.
|
|
20
22
|
* @param fillChar - Single-width character for padding areas (defaults to space).
|
|
23
|
+
* @param title - Optional title displayed in the top border.
|
|
21
24
|
* @returns The rendered box as a multiline string.
|
|
22
25
|
*/
|
|
23
|
-
function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = ' ') {
|
|
24
|
-
const
|
|
26
|
+
function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = ' ', title, overflow = 'wrap') {
|
|
27
|
+
const rawContentLines = content.split('\n');
|
|
25
28
|
let innerWidth;
|
|
26
29
|
let contentWidth;
|
|
27
30
|
if (fixedWidth !== undefined) {
|
|
@@ -31,13 +34,17 @@ function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = '
|
|
|
31
34
|
}
|
|
32
35
|
else {
|
|
33
36
|
// Auto width: measure content
|
|
34
|
-
const
|
|
37
|
+
const titleWidth = title ? graphemeWidth(title) + 2 : 0;
|
|
38
|
+
const maxWidth = rawContentLines.reduce((max, line) => Math.max(max, graphemeWidth(line)), 0);
|
|
35
39
|
contentWidth = maxWidth;
|
|
36
|
-
innerWidth = maxWidth + padding.left + padding.right;
|
|
40
|
+
innerWidth = Math.max(titleWidth, maxWidth + padding.left + padding.right);
|
|
37
41
|
}
|
|
38
42
|
// When fixed width, padding may exceed innerWidth — clamp to fit
|
|
39
43
|
const effectiveLeft = fixedWidth !== undefined ? Math.min(padding.left, innerWidth) : padding.left;
|
|
40
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;
|
|
41
48
|
const pad = (line) => {
|
|
42
49
|
const visible = graphemeWidth(line);
|
|
43
50
|
let processed = line;
|
|
@@ -50,7 +57,27 @@ function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = '
|
|
|
50
57
|
return leftPad + processed + rightPad;
|
|
51
58
|
};
|
|
52
59
|
const fill = bgFill ?? ((s) => s);
|
|
53
|
-
|
|
60
|
+
// Render top border with optional title
|
|
61
|
+
let topBorder = BORDER.h.repeat(innerWidth);
|
|
62
|
+
if (title && innerWidth >= 4) {
|
|
63
|
+
const label = ` ${title} `;
|
|
64
|
+
const labelWidth = graphemeWidth(label);
|
|
65
|
+
if (labelWidth <= innerWidth - 2) {
|
|
66
|
+
const start = 1;
|
|
67
|
+
const before = BORDER.h.repeat(start);
|
|
68
|
+
const after = BORDER.h.repeat(innerWidth - start - labelWidth);
|
|
69
|
+
topBorder = before + label + after;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Title too long, clip it
|
|
73
|
+
const clippedLabel = clipToWidth(label, innerWidth - 2);
|
|
74
|
+
const start = 1;
|
|
75
|
+
const before = BORDER.h.repeat(start);
|
|
76
|
+
const after = BORDER.h.repeat(innerWidth - start - graphemeWidth(clippedLabel));
|
|
77
|
+
topBorder = before + clippedLabel + after;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const top = borderColor(BORDER.tl + topBorder + BORDER.tr);
|
|
54
81
|
const bottom = borderColor(BORDER.bl + BORDER.h.repeat(innerWidth) + BORDER.br);
|
|
55
82
|
const emptyLine = borderColor(BORDER.v) + fill(fillChar.repeat(innerWidth)) + borderColor(BORDER.v);
|
|
56
83
|
const lines = [top];
|
|
@@ -92,7 +119,8 @@ export function box(content, options = {}) {
|
|
|
92
119
|
const colorize = (s) => ctx.style.styled(borderToken, s);
|
|
93
120
|
const bgFill = makeBgFill(options.bgToken, ctx);
|
|
94
121
|
const resolvedFill = resolveFillChar(options.fillChar);
|
|
95
|
-
|
|
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);
|
|
96
124
|
},
|
|
97
125
|
}, options);
|
|
98
126
|
}
|
|
@@ -133,7 +161,7 @@ export function headerBox(label, options = {}) {
|
|
|
133
161
|
* Returns the character if it is a single-width grapheme cluster,
|
|
134
162
|
* otherwise falls back to a space.
|
|
135
163
|
*/
|
|
136
|
-
function resolveFillChar(fillChar) {
|
|
164
|
+
export function resolveFillChar(fillChar) {
|
|
137
165
|
if (fillChar == null || fillChar.length === 0)
|
|
138
166
|
return ' ';
|
|
139
167
|
if (graphemeWidth(fillChar) !== 1)
|