@flyingrobots/bijou 1.8.0 → 3.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/README.md +11 -11
- package/dist/adapters/test/index.d.ts +0 -1
- package/dist/adapters/test/index.d.ts.map +1 -1
- package/dist/adapters/test/index.js +4 -1
- package/dist/adapters/test/index.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/components/alert.d.ts +2 -4
- package/dist/core/components/alert.d.ts.map +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 +9 -0
- package/dist/core/components/box-v3.d.ts.map +1 -0
- package/dist/core/components/box-v3.js +91 -0
- package/dist/core/components/box-v3.js.map +1 -0
- package/dist/core/components/box.d.ts +4 -4
- package/dist/core/components/box.d.ts.map +1 -1
- package/dist/core/components/box.js +26 -4
- package/dist/core/components/box.js.map +1 -1
- package/dist/core/components/log.d.ts.map +1 -1
- package/dist/core/components/log.js +2 -1
- package/dist/core/components/log.js.map +1 -1
- 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/types.d.ts +15 -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/detect/tty.d.ts +5 -15
- package/dist/core/detect/tty.d.ts.map +1 -1
- package/dist/core/detect/tty.js +3 -13
- package/dist/core/detect/tty.js.map +1 -1
- 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/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 +4 -1
- package/dist/core/theme/index.d.ts.map +1 -1
- package/dist/core/theme/index.js +3 -1
- package/dist/core/theme/index.js.map +1 -1
- package/dist/core/theme/resolve.d.ts +8 -33
- package/dist/core/theme/resolve.d.ts.map +1 -1
- package/dist/core/theme/resolve.js +6 -39
- package/dist/core/theme/resolve.js.map +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +5 -0
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/ports/context.d.ts +9 -0
- package/dist/ports/context.d.ts.map +1 -1
- package/dist/ports/env.d.ts +7 -14
- package/dist/ports/env.d.ts.map +1 -1
- package/dist/ports/env.js +7 -16
- package/dist/ports/env.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
package/README.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# @flyingrobots/bijou
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The pure, zero-dependency core of Bijou.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@flyingrobots/bijou` is the degradation-first terminal toolkit in the Bijou stack. It contains components, prompts, themes, environment detection, test adapters, and the foundational `Surface` and `LayoutNode` primitives that the V3 runtime builds on.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## What's New in v3.0.0
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- Release-level changes live in the [CHANGELOG](https://github.com/flyingrobots/bijou/blob/main/docs/CHANGELOG.md)
|
|
9
|
+
- **Truthful core/runtime split** — the core package remains the right place for CLIs, prompts, logs, and portable terminal output, while `@flyingrobots/bijou-tui` owns the high-fidelity fullscreen runtime.
|
|
10
|
+
- **Surface primitives without abandoning strings** — V3 adds serious surface/layout infrastructure to the core package, but `3.0.0` does not pretend every component is now surface-native. String-oriented helpers remain first-class where they fit the toolkit identity.
|
|
11
|
+
- **Explicit compatibility boundaries** — when you mix surface-native helpers with legacy string APIs, you cross that seam explicitly with `surfaceToString(surface, ctx.style)`.
|
|
12
|
+
- **Same hexagonal core** — ports, themes, output-mode detection, and test adapters remain pure and dependency-free.
|
|
14
13
|
|
|
15
14
|
## Install
|
|
16
15
|
|
|
@@ -59,14 +58,14 @@ console.log(box('Hello, world!'));
|
|
|
59
58
|
`spinner()`, `progressBar()`, `gradientText()` — live-updating output with color gradients.
|
|
60
59
|
|
|
61
60
|
### Forms
|
|
62
|
-
`input()`, `select()`, `multiselect()`, `confirm()`, `group()`, `wizard()` — interactive prompts with validation that degrade to numbered-list selection in pipe/CI modes.
|
|
61
|
+
`input()`, `select()`, `multiselect()`, `confirm()`, `group()`, `wizard()`, `textarea()`, `filter()` — interactive prompts with validation that degrade to numbered-list selection in pipe/CI modes.
|
|
63
62
|
|
|
64
63
|
### Theme Engine
|
|
65
|
-
DTCG (Design Tokens Community Group) interop. Built-in presets: `nord`, `catppuccin`, `cyan-magenta`. Load custom themes via `BIJOU_THEME` env var or `extendTheme()`.
|
|
64
|
+
DTCG (Design Tokens Community Group) interop. Built-in presets: `nord`, `catppuccin`, `cyan-magenta`, `teal-orange-pink`. Load custom themes via `BIJOU_THEME` env var or `extendTheme()`.
|
|
66
65
|
|
|
67
66
|
## Architecture
|
|
68
67
|
|
|
69
|
-
bijou uses a Ports and Adapters (hexagonal) architecture. See [ARCHITECTURE.md](./ARCHITECTURE.md) for the
|
|
68
|
+
bijou uses a Ports and Adapters (hexagonal) architecture. See [ARCHITECTURE.md](./ARCHITECTURE.md) for the package-level design and [`../../docs/ARCHITECTURE.md`](../../docs/ARCHITECTURE.md) for the monorepo-wide architecture.
|
|
70
69
|
|
|
71
70
|
The core is pure TypeScript with zero runtime dependencies — all platform concerns flow through three ports:
|
|
72
71
|
|
|
@@ -99,6 +98,7 @@ const result = box('hello', { ctx });
|
|
|
99
98
|
```
|
|
100
99
|
|
|
101
100
|
See [GUIDE.md](./GUIDE.md) for more on testing, theming, and component usage.
|
|
101
|
+
For upgrading existing apps, see the monorepo migration guide at [`../../docs/MIGRATING_TO_V3.md`](../../docs/MIGRATING_TO_V3.md).
|
|
102
102
|
|
|
103
103
|
## Related Packages
|
|
104
104
|
|
|
@@ -20,7 +20,6 @@ export { auditStyle, type StyledCall, type AuditStylePort } from './audit-style.
|
|
|
20
20
|
export { expectNoAnsi, expectNoAnsiSgr, expectContainsAnsi, expectHiddenCursor, expectShownCursor, expectWritten, } from './assertions.js';
|
|
21
21
|
export { COLOR_OPTIONS, FRUIT_OPTIONS, MANY_OPTIONS } from './fixtures.js';
|
|
22
22
|
export { _resetDefaultContextForTesting } from '../../context.js';
|
|
23
|
-
export { _resetThemeForTesting } from '../../core/theme/resolve.js';
|
|
24
23
|
/**
|
|
25
24
|
* Configuration for {@link createTestContext}.
|
|
26
25
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAU,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAU,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAOtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EACL,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,wEAAwE;IACxE,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,oDAAoD;IACpD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gDAAgD;IAChD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAkB/E"}
|
|
@@ -4,6 +4,7 @@ import { plainStyle } from './style.js';
|
|
|
4
4
|
import { createResolved } from '../../core/theme/resolve.js';
|
|
5
5
|
import { CYAN_MAGENTA } from '../../core/theme/presets.js';
|
|
6
6
|
import { createThemeAccessors } from '../../core/theme/accessors.js';
|
|
7
|
+
import { createTokenGraph } from '../../core/theme/graph.js';
|
|
7
8
|
export { mockRuntime } from './runtime.js';
|
|
8
9
|
export { mockIO } from './io.js';
|
|
9
10
|
export { plainStyle } from './style.js';
|
|
@@ -11,7 +12,6 @@ export { auditStyle } from './audit-style.js';
|
|
|
11
12
|
export { expectNoAnsi, expectNoAnsiSgr, expectContainsAnsi, expectHiddenCursor, expectShownCursor, expectWritten, } from './assertions.js';
|
|
12
13
|
export { COLOR_OPTIONS, FRUIT_OPTIONS, MANY_OPTIONS } from './fixtures.js';
|
|
13
14
|
export { _resetDefaultContextForTesting } from '../../context.js';
|
|
14
|
-
export { _resetThemeForTesting } from '../../core/theme/resolve.js';
|
|
15
15
|
/**
|
|
16
16
|
* Create a fully-wired {@link BijouContext} for unit and integration tests.
|
|
17
17
|
*
|
|
@@ -27,6 +27,7 @@ export function createTestContext(options = {}) {
|
|
|
27
27
|
const io = mockIO(options.io);
|
|
28
28
|
const style = options.style ?? plainStyle();
|
|
29
29
|
const theme = createResolved(options.theme ?? CYAN_MAGENTA, options.noColor ?? false, options.colorScheme ?? 'dark');
|
|
30
|
+
const tokenGraph = createTokenGraph((options.theme ?? CYAN_MAGENTA));
|
|
30
31
|
const mode = options.mode ?? 'interactive';
|
|
31
32
|
return {
|
|
32
33
|
theme,
|
|
@@ -34,6 +35,8 @@ export function createTestContext(options = {}) {
|
|
|
34
35
|
runtime,
|
|
35
36
|
io,
|
|
36
37
|
style,
|
|
38
|
+
tokenGraph,
|
|
39
|
+
resolveBCSS: () => ({}),
|
|
37
40
|
...createThemeAccessors(theme),
|
|
38
41
|
};
|
|
39
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/test/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAA2B,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/test/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAA2B,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAI7D,OAAO,EAAE,WAAW,EAA2B,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,UAAU,EAAwC,MAAM,kBAAkB,CAAC;AACpF,OAAO,EACL,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AA+BlE;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA8B,EAAE;IAChE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,CAAC;IACrH,MAAM,UAAU,GAAG,gBAAgB,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAgC,CAAC,CAAC;IACpG,MAAM,IAAI,GAAe,OAAO,CAAC,IAAI,IAAI,aAAa,CAAC;IAEvD,OAAO;QACL,KAAK;QACL,IAAI;QACJ,OAAO;QACP,EAAE;QACF,KAAK;QACL,UAAU;QACV,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACvB,GAAG,oBAAoB,CAAC,KAAK,CAAC;KAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -13,6 +13,8 @@ export interface MockRuntimeOptions {
|
|
|
13
13
|
columns?: number;
|
|
14
14
|
/** Terminal height in rows. Defaults to `24`. */
|
|
15
15
|
rows?: number;
|
|
16
|
+
/** Refresh rate in FPS. Defaults to `60`. */
|
|
17
|
+
refreshRate?: number;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
20
|
* Create an in-memory {@link RuntimePort} for tests.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kDAAkD;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAiBzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/adapters/test/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/adapters/test/runtime.ts"],"names":[],"mappings":"AAoBA;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,UAA8B,EAAE;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;IACjC,OAAO;QACL;;;;WAIG;QACH,GAAG,CAAC,GAAW;YACb,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;QACxC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;QACtC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;QAC9B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;QACxB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;KACvC,CAAC;AACJ,CAAC"}
|
|
@@ -1,15 +1,13 @@
|
|
|
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
9
|
/** Background fill token for the alert box interior. Defaults to `surface.elevated`. */
|
|
10
10
|
bgToken?: TokenValue;
|
|
11
|
-
/** Bijou context for I/O, styling, and mode detection. */
|
|
12
|
-
ctx?: BijouContext;
|
|
13
11
|
}
|
|
14
12
|
/**
|
|
15
13
|
* 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,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 +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;AAcjD,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,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YACvD,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,9 @@
|
|
|
1
|
+
import { type Surface } from '../../ports/surface.js';
|
|
2
|
+
import { type BoxOptions } 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 boxV3(content: Surface | string, options?: BoxOptions): Surface;
|
|
9
|
+
//# 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;AAGhF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAK3C;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAwFlF"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createSurface } from '../../ports/surface.js';
|
|
2
|
+
import { resolveSafeCtx as resolveCtx } from '../resolve-ctx.js';
|
|
3
|
+
import { segmentGraphemes } from '../text/grapheme.js';
|
|
4
|
+
import { applyBCSSCellTextStyles } from './bcss-style.js';
|
|
5
|
+
const BORDER = { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│' };
|
|
6
|
+
/**
|
|
7
|
+
* Render a bordered box around a Surface.
|
|
8
|
+
*
|
|
9
|
+
* Returns a new Surface containing the box and the nested content.
|
|
10
|
+
*/
|
|
11
|
+
export function boxV3(content, options = {}) {
|
|
12
|
+
const ctx = resolveCtx(options.ctx);
|
|
13
|
+
const { title, width: fixedWidth, padding = {} } = options;
|
|
14
|
+
const bcss = ctx?.resolveBCSS({ type: 'Box', id: options.id, classes: options.class?.split(' ') }) ?? {};
|
|
15
|
+
const pt = padding.top ?? 0;
|
|
16
|
+
const pb = padding.bottom ?? 0;
|
|
17
|
+
const pl = padding.left ?? 0;
|
|
18
|
+
const pr = padding.right ?? 0;
|
|
19
|
+
let contentSurf;
|
|
20
|
+
if (typeof content === 'string') {
|
|
21
|
+
const lines = content.split(/\r?\n/);
|
|
22
|
+
const h = lines.length;
|
|
23
|
+
const w = Math.max(...lines.map(l => segmentGraphemes(l).length), 0);
|
|
24
|
+
contentSurf = createSurface(w, h);
|
|
25
|
+
lines.forEach((line, y) => {
|
|
26
|
+
const gs = segmentGraphemes(line);
|
|
27
|
+
gs.forEach((char, x) => {
|
|
28
|
+
contentSurf.set(x, y, { char });
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
contentSurf = content;
|
|
34
|
+
}
|
|
35
|
+
const innerW = contentSurf.width + pl + pr;
|
|
36
|
+
const innerH = contentSurf.height + pt + pb;
|
|
37
|
+
const outerW = fixedWidth ?? (innerW + 2);
|
|
38
|
+
const outerH = innerH + 2;
|
|
39
|
+
const surface = createSurface(outerW, outerH);
|
|
40
|
+
const fillStyle = applyBCSSCellTextStyles({
|
|
41
|
+
fg: undefined,
|
|
42
|
+
bg: undefined,
|
|
43
|
+
modifiers: undefined,
|
|
44
|
+
}, bcss);
|
|
45
|
+
surface.fill({
|
|
46
|
+
char: options.fillChar || ' ',
|
|
47
|
+
bg: fillStyle.bg,
|
|
48
|
+
fg: fillStyle.fg,
|
|
49
|
+
modifiers: fillStyle.modifiers,
|
|
50
|
+
empty: false,
|
|
51
|
+
});
|
|
52
|
+
const borderToken = options.borderToken || ctx?.border('primary');
|
|
53
|
+
const borderStyle = applyBCSSCellTextStyles({
|
|
54
|
+
fg: borderToken?.hex ?? '#ffffff',
|
|
55
|
+
bg: borderToken?.bg,
|
|
56
|
+
modifiers: borderToken?.modifiers,
|
|
57
|
+
}, bcss);
|
|
58
|
+
const borderCell = {
|
|
59
|
+
char: ' ',
|
|
60
|
+
fg: borderStyle.fg,
|
|
61
|
+
bg: borderStyle.bg,
|
|
62
|
+
modifiers: borderStyle.modifiers,
|
|
63
|
+
};
|
|
64
|
+
// Draw borders
|
|
65
|
+
for (let x = 0; x < outerW; x++) {
|
|
66
|
+
surface.set(x, 0, { ...borderCell, char: BORDER.h });
|
|
67
|
+
surface.set(x, outerH - 1, { ...borderCell, char: BORDER.h });
|
|
68
|
+
}
|
|
69
|
+
for (let y = 0; y < outerH; y++) {
|
|
70
|
+
surface.set(0, y, { ...borderCell, char: BORDER.v });
|
|
71
|
+
surface.set(outerW - 1, y, { ...borderCell, char: BORDER.v });
|
|
72
|
+
}
|
|
73
|
+
surface.set(0, 0, { ...borderCell, char: BORDER.tl });
|
|
74
|
+
surface.set(outerW - 1, 0, { ...borderCell, char: BORDER.tr });
|
|
75
|
+
surface.set(0, outerH - 1, { ...borderCell, char: BORDER.bl });
|
|
76
|
+
surface.set(outerW - 1, outerH - 1, { ...borderCell, char: BORDER.br });
|
|
77
|
+
// Draw title
|
|
78
|
+
if (title && outerW >= 4) {
|
|
79
|
+
const titleText = ` ${title} `;
|
|
80
|
+
const titleGs = segmentGraphemes(titleText);
|
|
81
|
+
const available = outerW - 4;
|
|
82
|
+
const titleLen = Math.min(titleGs.length, available);
|
|
83
|
+
for (let i = 0; i < titleLen; i++) {
|
|
84
|
+
surface.set(i + 2, 0, { ...borderCell, char: titleGs[i] });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Blit content
|
|
88
|
+
surface.blit(contentSurf, pl + 1, pt + 1);
|
|
89
|
+
return surface;
|
|
90
|
+
}
|
|
91
|
+
//# 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.
|
|
@@ -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;AAMrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,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;AAoGD;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM,CAuBrE;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"}
|
|
@@ -18,9 +18,10 @@ const BORDER = { tl: '\u250c', tr: '\u2510', bl: '\u2514', br: '\u2518', h: '\u2
|
|
|
18
18
|
* @param fixedWidth - If provided, lock the outer width and clip/pad content to fit.
|
|
19
19
|
* @param bgFill - Optional function to wrap interior content with background color styling.
|
|
20
20
|
* @param fillChar - Single-width character for padding areas (defaults to space).
|
|
21
|
+
* @param title - Optional title displayed in the top border.
|
|
21
22
|
* @returns The rendered box as a multiline string.
|
|
22
23
|
*/
|
|
23
|
-
function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = ' ') {
|
|
24
|
+
function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = ' ', title) {
|
|
24
25
|
const contentLines = content.split('\n');
|
|
25
26
|
let innerWidth;
|
|
26
27
|
let contentWidth;
|
|
@@ -31,9 +32,10 @@ function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = '
|
|
|
31
32
|
}
|
|
32
33
|
else {
|
|
33
34
|
// Auto width: measure content
|
|
35
|
+
const titleWidth = title ? graphemeWidth(title) + 2 : 0;
|
|
34
36
|
const maxWidth = contentLines.reduce((max, line) => Math.max(max, graphemeWidth(line)), 0);
|
|
35
37
|
contentWidth = maxWidth;
|
|
36
|
-
innerWidth = maxWidth + padding.left + padding.right;
|
|
38
|
+
innerWidth = Math.max(titleWidth, maxWidth + padding.left + padding.right);
|
|
37
39
|
}
|
|
38
40
|
// When fixed width, padding may exceed innerWidth — clamp to fit
|
|
39
41
|
const effectiveLeft = fixedWidth !== undefined ? Math.min(padding.left, innerWidth) : padding.left;
|
|
@@ -50,7 +52,27 @@ function drawBox(content, borderColor, padding, fixedWidth, bgFill, fillChar = '
|
|
|
50
52
|
return leftPad + processed + rightPad;
|
|
51
53
|
};
|
|
52
54
|
const fill = bgFill ?? ((s) => s);
|
|
53
|
-
|
|
55
|
+
// Render top border with optional title
|
|
56
|
+
let topBorder = BORDER.h.repeat(innerWidth);
|
|
57
|
+
if (title && innerWidth >= 4) {
|
|
58
|
+
const label = ` ${title} `;
|
|
59
|
+
const labelWidth = graphemeWidth(label);
|
|
60
|
+
if (labelWidth <= innerWidth - 2) {
|
|
61
|
+
const start = 1;
|
|
62
|
+
const before = BORDER.h.repeat(start);
|
|
63
|
+
const after = BORDER.h.repeat(innerWidth - start - labelWidth);
|
|
64
|
+
topBorder = before + label + after;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Title too long, clip it
|
|
68
|
+
const clippedLabel = clipToWidth(label, innerWidth - 2);
|
|
69
|
+
const start = 1;
|
|
70
|
+
const before = BORDER.h.repeat(start);
|
|
71
|
+
const after = BORDER.h.repeat(innerWidth - start - graphemeWidth(clippedLabel));
|
|
72
|
+
topBorder = before + clippedLabel + after;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const top = borderColor(BORDER.tl + topBorder + BORDER.tr);
|
|
54
76
|
const bottom = borderColor(BORDER.bl + BORDER.h.repeat(innerWidth) + BORDER.br);
|
|
55
77
|
const emptyLine = borderColor(BORDER.v) + fill(fillChar.repeat(innerWidth)) + borderColor(BORDER.v);
|
|
56
78
|
const lines = [top];
|
|
@@ -92,7 +114,7 @@ export function box(content, options = {}) {
|
|
|
92
114
|
const colorize = (s) => ctx.style.styled(borderToken, s);
|
|
93
115
|
const bgFill = makeBgFill(options.bgToken, ctx);
|
|
94
116
|
const resolvedFill = resolveFillChar(options.fillChar);
|
|
95
|
-
return drawBox(safeContent, colorize, padding, options.width, bgFill, resolvedFill);
|
|
117
|
+
return drawBox(safeContent, colorize, padding, options.width, bgFill, resolvedFill, options.title);
|
|
96
118
|
},
|
|
97
119
|
}, options);
|
|
98
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"box.js","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"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"}
|