@flyingrobots/bijou 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/adapters/test/index.d.ts +20 -0
  4. package/dist/adapters/test/index.d.ts.map +1 -0
  5. package/dist/adapters/test/index.js +17 -0
  6. package/dist/adapters/test/index.js.map +1 -0
  7. package/dist/adapters/test/io.d.ts +15 -0
  8. package/dist/adapters/test/io.d.ts.map +1 -0
  9. package/dist/adapters/test/io.js +51 -0
  10. package/dist/adapters/test/io.js.map +1 -0
  11. package/dist/adapters/test/runtime.d.ts +10 -0
  12. package/dist/adapters/test/runtime.d.ts.map +1 -0
  13. package/dist/adapters/test/runtime.js +13 -0
  14. package/dist/adapters/test/runtime.js.map +1 -0
  15. package/dist/adapters/test/style.d.ts +3 -0
  16. package/dist/adapters/test/style.d.ts.map +1 -0
  17. package/dist/adapters/test/style.js +17 -0
  18. package/dist/adapters/test/style.js.map +1 -0
  19. package/dist/context.d.ts +5 -0
  20. package/dist/context.d.ts.map +1 -0
  21. package/dist/context.js +16 -0
  22. package/dist/context.js.map +1 -0
  23. package/dist/core/components/accordion.d.ts +14 -0
  24. package/dist/core/components/accordion.d.ts.map +1 -0
  25. package/dist/core/components/accordion.js +44 -0
  26. package/dist/core/components/accordion.js.map +1 -0
  27. package/dist/core/components/alert.d.ts +8 -0
  28. package/dist/core/components/alert.d.ts.map +1 -0
  29. package/dist/core/components/alert.js +50 -0
  30. package/dist/core/components/alert.js.map +1 -0
  31. package/dist/core/components/badge.d.ts +9 -0
  32. package/dist/core/components/badge.d.ts.map +1 -0
  33. package/dist/core/components/badge.js +37 -0
  34. package/dist/core/components/badge.js.map +1 -0
  35. package/dist/core/components/box.d.ts +19 -0
  36. package/dist/core/components/box.d.ts.map +1 -0
  37. package/dist/core/components/box.js +71 -0
  38. package/dist/core/components/box.js.map +1 -0
  39. package/dist/core/components/breadcrumb.d.ts +7 -0
  40. package/dist/core/components/breadcrumb.d.ts.map +1 -0
  41. package/dist/core/components/breadcrumb.js +32 -0
  42. package/dist/core/components/breadcrumb.js.map +1 -0
  43. package/dist/core/components/index.d.ts +35 -0
  44. package/dist/core/components/index.d.ts.map +1 -0
  45. package/dist/core/components/index.js +18 -0
  46. package/dist/core/components/index.js.map +1 -0
  47. package/dist/core/components/kbd.d.ts +6 -0
  48. package/dist/core/components/kbd.d.ts.map +1 -0
  49. package/dist/core/components/kbd.js +18 -0
  50. package/dist/core/components/kbd.js.map +1 -0
  51. package/dist/core/components/logo.d.ts +18 -0
  52. package/dist/core/components/logo.d.ts.map +1 -0
  53. package/dist/core/components/logo.js +66 -0
  54. package/dist/core/components/logo.js.map +1 -0
  55. package/dist/core/components/paginator.d.ts +9 -0
  56. package/dist/core/components/paginator.d.ts.map +1 -0
  57. package/dist/core/components/paginator.js +32 -0
  58. package/dist/core/components/paginator.js.map +1 -0
  59. package/dist/core/components/progress.d.ts +25 -0
  60. package/dist/core/components/progress.d.ts.map +1 -0
  61. package/dist/core/components/progress.js +146 -0
  62. package/dist/core/components/progress.js.map +1 -0
  63. package/dist/core/components/separator.d.ts +10 -0
  64. package/dist/core/components/separator.d.ts.map +1 -0
  65. package/dist/core/components/separator.js +32 -0
  66. package/dist/core/components/separator.js.map +1 -0
  67. package/dist/core/components/skeleton.d.ts +8 -0
  68. package/dist/core/components/skeleton.d.ts.map +1 -0
  69. package/dist/core/components/skeleton.js +20 -0
  70. package/dist/core/components/skeleton.js.map +1 -0
  71. package/dist/core/components/spinner.d.ts +15 -0
  72. package/dist/core/components/spinner.d.ts.map +1 -0
  73. package/dist/core/components/spinner.js +67 -0
  74. package/dist/core/components/spinner.js.map +1 -0
  75. package/dist/core/components/stepper.d.ts +10 -0
  76. package/dist/core/components/stepper.d.ts.map +1 -0
  77. package/dist/core/components/stepper.js +45 -0
  78. package/dist/core/components/stepper.js.map +1 -0
  79. package/dist/core/components/table.d.ts +15 -0
  80. package/dist/core/components/table.d.ts.map +1 -0
  81. package/dist/core/components/table.js +66 -0
  82. package/dist/core/components/table.js.map +1 -0
  83. package/dist/core/components/tabs.d.ts +12 -0
  84. package/dist/core/components/tabs.d.ts.map +1 -0
  85. package/dist/core/components/tabs.js +47 -0
  86. package/dist/core/components/tabs.js.map +1 -0
  87. package/dist/core/components/timeline.d.ts +14 -0
  88. package/dist/core/components/timeline.d.ts.map +1 -0
  89. package/dist/core/components/timeline.js +47 -0
  90. package/dist/core/components/timeline.js.map +1 -0
  91. package/dist/core/components/tree.d.ts +13 -0
  92. package/dist/core/components/tree.d.ts.map +1 -0
  93. package/dist/core/components/tree.js +65 -0
  94. package/dist/core/components/tree.js.map +1 -0
  95. package/dist/core/detect/index.d.ts +3 -0
  96. package/dist/core/detect/index.d.ts.map +1 -0
  97. package/dist/core/detect/index.js +2 -0
  98. package/dist/core/detect/index.js.map +1 -0
  99. package/dist/core/detect/tty.d.ts +14 -0
  100. package/dist/core/detect/tty.d.ts.map +1 -0
  101. package/dist/core/detect/tty.js +28 -0
  102. package/dist/core/detect/tty.js.map +1 -0
  103. package/dist/core/forms/confirm.d.ts +7 -0
  104. package/dist/core/forms/confirm.d.ts.map +1 -0
  105. package/dist/core/forms/confirm.js +32 -0
  106. package/dist/core/forms/confirm.js.map +1 -0
  107. package/dist/core/forms/group.d.ts +19 -0
  108. package/dist/core/forms/group.d.ts.map +1 -0
  109. package/dist/core/forms/group.js +21 -0
  110. package/dist/core/forms/group.js.map +1 -0
  111. package/dist/core/forms/index.d.ts +8 -0
  112. package/dist/core/forms/index.d.ts.map +1 -0
  113. package/dist/core/forms/index.js +6 -0
  114. package/dist/core/forms/index.js.map +1 -0
  115. package/dist/core/forms/input.d.ts +8 -0
  116. package/dist/core/forms/input.d.ts.map +1 -0
  117. package/dist/core/forms/input.js +42 -0
  118. package/dist/core/forms/input.js.map +1 -0
  119. package/dist/core/forms/multiselect.d.ts +7 -0
  120. package/dist/core/forms/multiselect.d.ts.map +1 -0
  121. package/dist/core/forms/multiselect.js +114 -0
  122. package/dist/core/forms/multiselect.js.map +1 -0
  123. package/dist/core/forms/select.d.ts +7 -0
  124. package/dist/core/forms/select.d.ts.map +1 -0
  125. package/dist/core/forms/select.js +100 -0
  126. package/dist/core/forms/select.js.map +1 -0
  127. package/dist/core/forms/types.d.ts +32 -0
  128. package/dist/core/forms/types.d.ts.map +1 -0
  129. package/dist/core/forms/types.js +2 -0
  130. package/dist/core/forms/types.js.map +1 -0
  131. package/dist/core/theme/dtcg.d.ts +25 -0
  132. package/dist/core/theme/dtcg.d.ts.map +1 -0
  133. package/dist/core/theme/dtcg.js +182 -0
  134. package/dist/core/theme/dtcg.js.map +1 -0
  135. package/dist/core/theme/extend.d.ts +7 -0
  136. package/dist/core/theme/extend.d.ts.map +1 -0
  137. package/dist/core/theme/extend.js +9 -0
  138. package/dist/core/theme/extend.js.map +1 -0
  139. package/dist/core/theme/gradient.d.ts +9 -0
  140. package/dist/core/theme/gradient.d.ts.map +1 -0
  141. package/dist/core/theme/gradient.js +40 -0
  142. package/dist/core/theme/gradient.js.map +1 -0
  143. package/dist/core/theme/index.d.ts +11 -0
  144. package/dist/core/theme/index.d.ts.map +1 -0
  145. package/dist/core/theme/index.js +13 -0
  146. package/dist/core/theme/index.js.map +1 -0
  147. package/dist/core/theme/presets.d.ts +22 -0
  148. package/dist/core/theme/presets.d.ts.map +1 -0
  149. package/dist/core/theme/presets.js +219 -0
  150. package/dist/core/theme/presets.js.map +1 -0
  151. package/dist/core/theme/resolve.d.ts +41 -0
  152. package/dist/core/theme/resolve.d.ts.map +1 -0
  153. package/dist/core/theme/resolve.js +80 -0
  154. package/dist/core/theme/resolve.js.map +1 -0
  155. package/dist/core/theme/styled.d.ts +4 -0
  156. package/dist/core/theme/styled.d.ts.map +1 -0
  157. package/dist/core/theme/styled.js +15 -0
  158. package/dist/core/theme/styled.js.map +1 -0
  159. package/dist/core/theme/tokens.d.ts +65 -0
  160. package/dist/core/theme/tokens.d.ts.map +1 -0
  161. package/dist/core/theme/tokens.js +8 -0
  162. package/dist/core/theme/tokens.js.map +1 -0
  163. package/dist/factory.d.ts +15 -0
  164. package/dist/factory.d.ts.map +1 -0
  165. package/dist/factory.js +33 -0
  166. package/dist/factory.js.map +1 -0
  167. package/dist/index.d.ts +8 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +25 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/ports/context.d.ts +13 -0
  172. package/dist/ports/context.d.ts.map +1 -0
  173. package/dist/ports/context.js +2 -0
  174. package/dist/ports/context.js.map +1 -0
  175. package/dist/ports/index.d.ts +5 -0
  176. package/dist/ports/index.d.ts.map +1 -0
  177. package/dist/ports/index.js +2 -0
  178. package/dist/ports/index.js.map +1 -0
  179. package/dist/ports/io.d.ts +16 -0
  180. package/dist/ports/io.d.ts.map +1 -0
  181. package/dist/ports/io.js +2 -0
  182. package/dist/ports/io.js.map +1 -0
  183. package/dist/ports/runtime.d.ts +8 -0
  184. package/dist/ports/runtime.d.ts.map +1 -0
  185. package/dist/ports/runtime.js +2 -0
  186. package/dist/ports/runtime.js.map +1 -0
  187. package/dist/ports/style.d.ts +8 -0
  188. package/dist/ports/style.d.ts.map +1 -0
  189. package/dist/ports/style.js +2 -0
  190. package/dist/ports/style.js.map +1 -0
  191. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Flying Robots
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # @flyingrobots/bijou
2
+
3
+ Themed terminal components for CLIs, loggers, and scripts — graceful degradation included.
4
+
5
+ **Zero dependencies. Hexagonal architecture. Works everywhere.**
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @flyingrobots/bijou @flyingrobots/bijou-node
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { initDefaultContext } from '@flyingrobots/bijou-node';
17
+ import { box, headerBox, gradientText, table } from '@flyingrobots/bijou';
18
+
19
+ // Initialize Node.js adapters (auto-detects TTY, CI, NO_COLOR)
20
+ initDefaultContext();
21
+
22
+ // Use components
23
+ console.log(headerBox('My CLI', { detail: 'v1.0.0' }));
24
+ console.log(box('Hello, world!'));
25
+ ```
26
+
27
+ ## What's Inside
28
+
29
+ ### Layout
30
+ `box()`, `headerBox()`, `separator()` — unicode box-drawing with automatic ASCII fallback.
31
+
32
+ ### Elements
33
+ `badge()`, `alert()`, `kbd()`, `skeleton()` — status indicators and UI primitives.
34
+
35
+ ### Data
36
+ `table()`, `tree()`, `accordion()`, `timeline()` — structured data display.
37
+
38
+ ### Navigation
39
+ `tabs()`, `breadcrumb()`, `stepper()`, `paginator()` — wayfinding components.
40
+
41
+ ### Animation & Progress
42
+ `spinner()`, `progressBar()`, `gradientText()` — live-updating output with color gradients.
43
+
44
+ ### Forms
45
+ `input()`, `select()`, `multiselect()`, `confirm()`, `group()` — interactive prompts with validation that degrade to numbered-list selection in pipe/CI modes.
46
+
47
+ ### Theme Engine
48
+ DTCG (Design Tokens Community Group) interop. Built-in presets: `nord`, `catppuccin`, `cyan-magenta`. Load custom themes via `BIJOU_THEME` env var or `extendTheme()`.
49
+
50
+ ## Architecture
51
+
52
+ bijou uses a Ports and Adapters (hexagonal) architecture. The core is pure TypeScript with zero runtime dependencies — all platform concerns flow through three ports:
53
+
54
+ - **`RuntimePort`** — timers, environment
55
+ - **`IOPort`** — terminal I/O
56
+ - **`StylePort`** — color/formatting
57
+
58
+ This means your components work identically in Node.js, test harnesses, or any future runtime adapter.
59
+
60
+ ### Output Modes
61
+
62
+ bijou auto-detects the environment and adapts rendering:
63
+
64
+ | Mode | Trigger | Behavior |
65
+ | :--- | :--- | :--- |
66
+ | **Interactive** | TTY | Full RGB, unicode, animations |
67
+ | **Static** | `CI=true` | Single-frame, no animations |
68
+ | **Pipe** | Piped stdout | Plain text, ASCII fallbacks |
69
+ | **Accessible** | `BIJOU_ACCESSIBLE=1` | Screen-reader friendly |
70
+
71
+ ## Testing
72
+
73
+ Import test adapters for deterministic, mock-free component testing:
74
+
75
+ ```typescript
76
+ import { createTestContext } from '@flyingrobots/bijou/adapters/test';
77
+ import { box } from '@flyingrobots/bijou';
78
+
79
+ const ctx = createTestContext({ mode: 'interactive' });
80
+ const result = box('hello', { ctx });
81
+ // Assert on the string directly — no process mocking needed
82
+ ```
83
+
84
+ ## Related Packages
85
+
86
+ - [`@flyingrobots/bijou-node`](https://www.npmjs.com/package/@flyingrobots/bijou-node) — Node.js runtime adapter (chalk, readline, process)
87
+ - [`@flyingrobots/bijou-tui`](https://www.npmjs.com/package/@flyingrobots/bijou-tui) — TEA runtime for interactive terminal apps
88
+
89
+ ## License
90
+
91
+ MIT
@@ -0,0 +1,20 @@
1
+ import type { BijouContext } from '../../ports/context.js';
2
+ import type { OutputMode } from '../../core/detect/tty.js';
3
+ import { type MockRuntimeOptions } from './runtime.js';
4
+ import { type MockIOOptions, type MockIO } from './io.js';
5
+ import type { Theme } from '../../core/theme/tokens.js';
6
+ export { mockRuntime, type MockRuntimeOptions } from './runtime.js';
7
+ export { mockIO, type MockIOOptions, type MockIO } from './io.js';
8
+ export { plainStyle } from './style.js';
9
+ export interface TestContextOptions {
10
+ runtime?: MockRuntimeOptions;
11
+ io?: MockIOOptions;
12
+ theme?: Theme;
13
+ mode?: OutputMode;
14
+ noColor?: boolean;
15
+ }
16
+ export interface TestContext extends BijouContext {
17
+ readonly io: MockIO;
18
+ }
19
+ export declare function createTestContext(options?: TestContextOptions): TestContext;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAU,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAIlE,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;AAExC,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAQ/E"}
@@ -0,0 +1,17 @@
1
+ import { mockRuntime } from './runtime.js';
2
+ import { mockIO } from './io.js';
3
+ import { plainStyle } from './style.js';
4
+ import { createResolved } from '../../core/theme/resolve.js';
5
+ import { CYAN_MAGENTA } from '../../core/theme/presets.js';
6
+ export { mockRuntime } from './runtime.js';
7
+ export { mockIO } from './io.js';
8
+ export { plainStyle } from './style.js';
9
+ export function createTestContext(options = {}) {
10
+ const runtime = mockRuntime(options.runtime);
11
+ const io = mockIO(options.io);
12
+ const style = plainStyle();
13
+ const theme = createResolved(options.theme ?? CYAN_MAGENTA, options.noColor ?? false);
14
+ const mode = options.mode ?? 'interactive';
15
+ return { theme, mode, runtime, io, style };
16
+ }
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/test/index.ts"],"names":[],"mappings":"AAEA,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,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,OAAO,EAAE,WAAW,EAA2B,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAcxC,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,UAAU,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;IACtF,MAAM,IAAI,GAAe,OAAO,CAAC,IAAI,IAAI,aAAa,CAAC;IAEvD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { IOPort } from '../../ports/io.js';
2
+ export interface MockIOOptions {
3
+ answers?: string[];
4
+ keys?: string[];
5
+ files?: Record<string, string>;
6
+ dirs?: Record<string, string[]>;
7
+ }
8
+ export interface MockIO extends IOPort {
9
+ written: string[];
10
+ answerQueue: string[];
11
+ files: Record<string, string>;
12
+ dirs: Record<string, string[]>;
13
+ }
14
+ export declare function mockIO(options?: MockIOOptions): MockIO;
15
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +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;AAG7E,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,MAAO,SAAQ,MAAM;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAqD1D"}
@@ -0,0 +1,51 @@
1
+ import { join } from 'path';
2
+ export function mockIO(options = {}) {
3
+ const written = [];
4
+ const answerQueue = [...(options.answers ?? [])];
5
+ const files = { ...(options.files ?? {}) };
6
+ const dirs = { ...(options.dirs ?? {}) };
7
+ return {
8
+ written,
9
+ answerQueue,
10
+ files,
11
+ dirs,
12
+ write(data) {
13
+ written.push(data);
14
+ },
15
+ question(prompt) {
16
+ written.push(prompt);
17
+ return Promise.resolve(answerQueue.shift() ?? '');
18
+ },
19
+ rawInput(onKey) {
20
+ const keyQueue = [...(options.keys ?? [])];
21
+ let disposed = false;
22
+ function deliver() {
23
+ if (disposed || keyQueue.length === 0)
24
+ return;
25
+ const key = keyQueue.shift();
26
+ onKey(key);
27
+ if (keyQueue.length > 0)
28
+ queueMicrotask(deliver);
29
+ }
30
+ queueMicrotask(deliver);
31
+ return { dispose() { disposed = true; } };
32
+ },
33
+ setInterval(callback, ms) {
34
+ const id = globalThis.setInterval(callback, ms);
35
+ return { dispose() { clearInterval(id); } };
36
+ },
37
+ readFile(path) {
38
+ const content = files[path];
39
+ if (content === undefined)
40
+ throw new Error(`Mock: file not found: ${path}`);
41
+ return content;
42
+ },
43
+ readDir(path) {
44
+ return dirs[path] ?? [];
45
+ },
46
+ joinPath(...segments) {
47
+ return join(...segments);
48
+ },
49
+ };
50
+ }
51
+ //# sourceMappingURL=io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../../../src/adapters/test/io.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgB5B,MAAM,UAAU,MAAM,CAAC,UAAyB,EAAE;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,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;IAEzC,OAAO;QACL,OAAO;QACP,WAAW;QACX,KAAK;QACL,IAAI;QAEJ,KAAK,CAAC,IAAY;YAChB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAED,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,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,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,cAAc,CAAC,OAAO,CAAC,CAAC;YACnD,CAAC;YACD,cAAc,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,CAAC;QAED,WAAW,CAAC,QAAoB,EAAE,EAAU;YAC1C,MAAM,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAChD,OAAO,EAAE,OAAO,KAAK,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,CAAC;QAED,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,OAAO,CAAC,IAAY;YAClB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;QAED,QAAQ,CAAC,GAAG,QAAkB;YAC5B,OAAO,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { RuntimePort } from '../../ports/runtime.js';
2
+ export interface MockRuntimeOptions {
3
+ env?: Record<string, string>;
4
+ stdoutIsTTY?: boolean;
5
+ stdinIsTTY?: boolean;
6
+ columns?: number;
7
+ rows?: number;
8
+ }
9
+ export declare function mockRuntime(options?: MockRuntimeOptions): RuntimePort;
10
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +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,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAWzE"}
@@ -0,0 +1,13 @@
1
+ export function mockRuntime(options = {}) {
2
+ const envMap = options.env ?? {};
3
+ return {
4
+ env(key) {
5
+ return envMap[key];
6
+ },
7
+ stdoutIsTTY: options.stdoutIsTTY ?? true,
8
+ stdinIsTTY: options.stdinIsTTY ?? true,
9
+ columns: options.columns ?? 80,
10
+ rows: options.rows ?? 24,
11
+ };
12
+ }
13
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/adapters/test/runtime.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,WAAW,CAAC,UAA8B,EAAE;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;IACjC,OAAO;QACL,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;KACzB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { StylePort } from '../../ports/style.js';
2
+ export declare function plainStyle(): StylePort;
3
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../src/adapters/test/style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,wBAAgB,UAAU,IAAI,SAAS,CAetC"}
@@ -0,0 +1,17 @@
1
+ export function plainStyle() {
2
+ return {
3
+ styled(_token, text) {
4
+ return text;
5
+ },
6
+ rgb(_r, _g, _b, text) {
7
+ return text;
8
+ },
9
+ hex(_color, text) {
10
+ return text;
11
+ },
12
+ bold(text) {
13
+ return text;
14
+ },
15
+ };
16
+ }
17
+ //# sourceMappingURL=style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../../../src/adapters/test/style.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,MAAM,CAAC,MAAkB,EAAE,IAAY;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,CAAC,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,IAAY;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,GAAG,CAAC,MAAc,EAAE,IAAY;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,IAAY;YACf,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { BijouContext } from './ports/context.js';
2
+ export declare function getDefaultContext(): BijouContext;
3
+ export declare function setDefaultContext(ctx: BijouContext): void;
4
+ export declare function _resetDefaultContextForTesting(): void;
5
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,wBAAgB,iBAAiB,IAAI,YAAY,CAShD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAEzD;AAED,wBAAgB,8BAA8B,IAAI,IAAI,CAErD"}
@@ -0,0 +1,16 @@
1
+ let defaultContext = null;
2
+ export function getDefaultContext() {
3
+ if (defaultContext === null) {
4
+ throw new Error('[bijou] No default context configured. ' +
5
+ 'Import @flyingrobots/bijou-node to auto-configure, ' +
6
+ 'or call setDefaultContext() explicitly.');
7
+ }
8
+ return defaultContext;
9
+ }
10
+ export function setDefaultContext(ctx) {
11
+ defaultContext = ctx;
12
+ }
13
+ export function _resetDefaultContextForTesting() {
14
+ defaultContext = null;
15
+ }
16
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,IAAI,cAAc,GAAwB,IAAI,CAAC;AAE/C,MAAM,UAAU,iBAAiB;IAC/B,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,yCAAyC;YACzC,qDAAqD;YACrD,yCAAyC,CAC1C,CAAC;IACJ,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAiB;IACjD,cAAc,GAAG,GAAG,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,8BAA8B;IAC5C,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { BijouContext } from '../../ports/context.js';
2
+ import type { TokenValue } from '../theme/tokens.js';
3
+ export interface AccordionSection {
4
+ title: string;
5
+ content: string;
6
+ expanded?: boolean;
7
+ }
8
+ export interface AccordionOptions {
9
+ indicatorToken?: TokenValue;
10
+ titleToken?: TokenValue;
11
+ ctx?: BijouContext;
12
+ }
13
+ export declare function accordion(sections: AccordionSection[], options?: AccordionOptions): string;
14
+ //# sourceMappingURL=accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../../src/core/components/accordion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAOD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,gBAAgB,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAwC9F"}
@@ -0,0 +1,44 @@
1
+ import { getDefaultContext } from '../../context.js';
2
+ function resolveCtx(ctx) {
3
+ if (ctx)
4
+ return ctx;
5
+ return getDefaultContext();
6
+ }
7
+ export function accordion(sections, options = {}) {
8
+ const ctx = resolveCtx(options.ctx);
9
+ const mode = ctx.mode;
10
+ if (mode === 'pipe') {
11
+ return sections
12
+ .map((s) => `# ${s.title}\n${s.content}`)
13
+ .join('\n\n');
14
+ }
15
+ if (mode === 'accessible') {
16
+ return sections
17
+ .map((s) => {
18
+ if (s.expanded) {
19
+ return `[expanded] ${s.title}: ${s.content}`;
20
+ }
21
+ return `[collapsed] ${s.title}`;
22
+ })
23
+ .join('\n');
24
+ }
25
+ const indicatorToken = options.indicatorToken ?? ctx.theme.theme.semantic.accent;
26
+ const titleToken = options.titleToken ?? ctx.theme.theme.semantic.primary;
27
+ return sections
28
+ .map((s) => {
29
+ if (s.expanded) {
30
+ const indicator = ctx.style.styled(indicatorToken, '▼');
31
+ const title = ctx.style.styled(titleToken, s.title);
32
+ const indented = s.content
33
+ .split('\n')
34
+ .map((line) => ` ${line}`)
35
+ .join('\n');
36
+ return `${indicator} ${title}\n${indented}`;
37
+ }
38
+ const indicator = ctx.style.styled(indicatorToken, '▶');
39
+ const title = ctx.style.styled(titleToken, s.title);
40
+ return `${indicator} ${title}`;
41
+ })
42
+ .join('\n\n');
43
+ }
44
+ //# sourceMappingURL=accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accordion.js","sourceRoot":"","sources":["../../../src/core/components/accordion.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAcrD,SAAS,UAAU,CAAC,GAAkB;IACpC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAA4B,EAAE,UAA4B,EAAE;IACpF,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IAEtB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,QAAQ;aACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACxC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,OAAO,QAAQ;aACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO,cAAc,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YAC/C,CAAC;YACD,OAAO,eAAe,CAAC,CAAC,KAAK,EAAE,CAAC;QAClC,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;IACjF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;IAE1E,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACxD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACpD,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO;iBACvB,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;iBAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,OAAO,GAAG,SAAS,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,CAAC;QACD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC;IACjC,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { BijouContext } from '../../ports/context.js';
2
+ export type AlertVariant = 'success' | 'error' | 'warning' | 'info';
3
+ export interface AlertOptions {
4
+ variant?: AlertVariant;
5
+ ctx?: BijouContext;
6
+ }
7
+ export declare function alert(message: string, options?: AlertOptions): string;
8
+ //# sourceMappingURL=alert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAK3D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAmCD,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAkBzE"}
@@ -0,0 +1,50 @@
1
+ import { getDefaultContext } from '../../context.js';
2
+ import { box } from './box.js';
3
+ const ICONS = {
4
+ success: '\u2713',
5
+ error: '\u2717',
6
+ warning: '\u26A0',
7
+ info: '\u2139',
8
+ };
9
+ const PIPE_LABELS = {
10
+ success: 'SUCCESS',
11
+ error: 'ERROR',
12
+ warning: 'WARNING',
13
+ info: 'INFO',
14
+ };
15
+ const ACCESSIBLE_LABELS = {
16
+ success: 'Success',
17
+ error: 'Error',
18
+ warning: 'Warning',
19
+ info: 'Info',
20
+ };
21
+ const BORDER_TOKENS = {
22
+ success: 'success',
23
+ error: 'error',
24
+ warning: 'warning',
25
+ info: 'primary',
26
+ };
27
+ function resolveCtx(ctx) {
28
+ if (ctx)
29
+ return ctx;
30
+ return getDefaultContext();
31
+ }
32
+ export function alert(message, options = {}) {
33
+ const ctx = resolveCtx(options.ctx);
34
+ const mode = ctx.mode;
35
+ const variant = options.variant ?? 'info';
36
+ if (mode === 'pipe')
37
+ return `[${PIPE_LABELS[variant]}] ${message}`;
38
+ if (mode === 'accessible')
39
+ return `${ACCESSIBLE_LABELS[variant]}: ${message}`;
40
+ const icon = ICONS[variant];
41
+ const semanticToken = ctx.theme.theme.semantic[variant === 'info' ? 'info' : variant];
42
+ const borderToken = ctx.theme.theme.border[BORDER_TOKENS[variant]];
43
+ const coloredIcon = ctx.style.styled(semanticToken, icon);
44
+ return box(coloredIcon + ' ' + message, {
45
+ borderToken,
46
+ padding: { left: 1, right: 1 },
47
+ ctx,
48
+ });
49
+ }
50
+ //# sourceMappingURL=alert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert.js","sourceRoot":"","sources":["../../../src/core/components/alert.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAS/B,MAAM,KAAK,GAAiC;IAC1C,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,MAAM,WAAW,GAAiC;IAChD,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,MAAM,iBAAiB,GAAiC;IACtD,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,MAAM,aAAa,GAAyE;IAC1F,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;CAChB,CAAC;AAEF,SAAS,UAAU,CAAC,GAAkB;IACpC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAe,EAAE,UAAwB,EAAE;IAC/D,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAE1C,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC;IACnE,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC;IAE9E,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,aAAa,GAAe,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAClG,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAE1D,OAAO,GAAG,CAAC,WAAW,GAAG,GAAG,GAAG,OAAO,EAAE;QACtC,WAAW;QACX,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;QAC9B,GAAG;KACJ,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { BijouContext } from '../../ports/context.js';
2
+ import type { BaseStatusKey } from '../theme/tokens.js';
3
+ export type BadgeVariant = BaseStatusKey | 'accent' | 'primary';
4
+ export interface BadgeOptions {
5
+ variant?: BadgeVariant;
6
+ ctx?: BijouContext;
7
+ }
8
+ export declare function badge(text: string, options?: BadgeOptions): string;
9
+ //# sourceMappingURL=badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/core/components/badge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGpE,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAWD,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CA2BtE"}
@@ -0,0 +1,37 @@
1
+ import { getDefaultContext } from '../../context.js';
2
+ function resolveCtx(ctx) {
3
+ if (ctx)
4
+ return ctx;
5
+ try {
6
+ return getDefaultContext();
7
+ }
8
+ catch {
9
+ return undefined;
10
+ }
11
+ }
12
+ export function badge(text, options = {}) {
13
+ const ctx = resolveCtx(options.ctx);
14
+ if (!ctx)
15
+ return ` ${text} `;
16
+ const mode = ctx.mode;
17
+ if (mode === 'pipe')
18
+ return `[${text}]`;
19
+ if (mode === 'accessible')
20
+ return text;
21
+ const t = ctx.theme?.theme;
22
+ if (!t)
23
+ return ` ${text} `;
24
+ const variant = options.variant ?? 'info';
25
+ const status = (t.status || {});
26
+ const semantic = (t.semantic || {});
27
+ let baseToken = status[variant] || semantic[variant] || status.info;
28
+ if (!baseToken || typeof baseToken.hex !== 'string') {
29
+ baseToken = { hex: '#808080' };
30
+ }
31
+ const inverseToken = {
32
+ hex: baseToken.hex,
33
+ modifiers: [...(baseToken.modifiers ?? []), 'inverse'],
34
+ };
35
+ return ctx.style.styled(inverseToken, ` ${text} `);
36
+ }
37
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.js","sourceRoot":"","sources":["../../../src/core/components/badge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AASrD,SAAS,UAAU,CAAC,GAAkB;IACpC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,UAAwB,EAAE;IAC5D,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,IAAI,GAAG,CAAC;IAE7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,IAAI,GAAG,CAAC;IACxC,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,IAAI,GAAG,CAAC;IAE3B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAC1C,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAQ,CAAC;IACvC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAQ,CAAC;IAE3C,IAAI,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;IAEpE,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpD,SAAS,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,YAAY,GAAe;QAC/B,GAAG,EAAE,SAAS,CAAC,GAAG;QAClB,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC;KACvD,CAAC;IAEF,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { BijouContext } from '../../ports/context.js';
2
+ import type { TokenValue } from '../theme/tokens.js';
3
+ export interface BoxOptions {
4
+ borderToken?: TokenValue;
5
+ padding?: {
6
+ top?: number;
7
+ bottom?: number;
8
+ left?: number;
9
+ right?: number;
10
+ };
11
+ ctx?: BijouContext;
12
+ }
13
+ export declare function box(content: string, options?: BoxOptions): string;
14
+ export interface HeaderBoxOptions extends BoxOptions {
15
+ detail?: string;
16
+ labelToken?: TokenValue;
17
+ }
18
+ export declare function headerBox(label: string, options?: HeaderBoxOptions): string;
19
+ //# sourceMappingURL=box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/core/components/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,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,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAgDD,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM,CAmBrE;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAkB/E"}
@@ -0,0 +1,71 @@
1
+ import { getDefaultContext } from '../../context.js';
2
+ const BORDER = { tl: '\u250c', tr: '\u2510', bl: '\u2514', br: '\u2518', h: '\u2500', v: '\u2502' };
3
+ function stripAnsi(str) {
4
+ // eslint-disable-next-line no-control-regex
5
+ return str.replace(/\x1b\[[0-9;]*m/g, '');
6
+ }
7
+ function visibleLength(str) {
8
+ return stripAnsi(str).length;
9
+ }
10
+ function drawBox(content, borderColor, padding) {
11
+ const contentLines = content.split('\n');
12
+ const maxWidth = contentLines.reduce((max, line) => Math.max(max, visibleLength(line)), 0);
13
+ const innerWidth = maxWidth + padding.left + padding.right;
14
+ const pad = (line) => {
15
+ const visible = visibleLength(line);
16
+ const leftPad = ' '.repeat(padding.left);
17
+ const rightPad = ' '.repeat(padding.right + (maxWidth - visible));
18
+ return leftPad + line + rightPad;
19
+ };
20
+ const top = borderColor(BORDER.tl + BORDER.h.repeat(innerWidth) + BORDER.tr);
21
+ const bottom = borderColor(BORDER.bl + BORDER.h.repeat(innerWidth) + BORDER.br);
22
+ const emptyLine = borderColor(BORDER.v) + ' '.repeat(innerWidth) + borderColor(BORDER.v);
23
+ const lines = [top];
24
+ for (let i = 0; i < padding.top; i++)
25
+ lines.push(emptyLine);
26
+ for (const line of contentLines) {
27
+ lines.push(borderColor(BORDER.v) + pad(line) + borderColor(BORDER.v));
28
+ }
29
+ for (let i = 0; i < padding.bottom; i++)
30
+ lines.push(emptyLine);
31
+ lines.push(bottom);
32
+ return lines.join('\n');
33
+ }
34
+ function resolveCtx(ctx) {
35
+ if (ctx)
36
+ return ctx;
37
+ return getDefaultContext();
38
+ }
39
+ export function box(content, options = {}) {
40
+ const ctx = resolveCtx(options.ctx);
41
+ const mode = ctx.mode;
42
+ if (mode === 'pipe' || mode === 'accessible') {
43
+ return content;
44
+ }
45
+ const borderToken = options.borderToken ?? ctx.theme.theme.border.primary;
46
+ const padding = {
47
+ top: options.padding?.top ?? 0,
48
+ bottom: options.padding?.bottom ?? 0,
49
+ left: options.padding?.left ?? 1,
50
+ right: options.padding?.right ?? 1,
51
+ };
52
+ const colorize = (s) => ctx.style.styled(borderToken, s);
53
+ return drawBox(content, colorize, padding);
54
+ }
55
+ export function headerBox(label, options = {}) {
56
+ const ctx = resolveCtx(options.ctx);
57
+ const mode = ctx.mode;
58
+ const detail = options.detail ?? '';
59
+ if (mode === 'pipe') {
60
+ return detail ? `${label} ${detail}` : label;
61
+ }
62
+ if (mode === 'accessible') {
63
+ return detail ? `${label}: ${detail}` : label;
64
+ }
65
+ const labelToken = options.labelToken ?? ctx.theme.theme.semantic.primary;
66
+ const content = detail
67
+ ? ctx.style.styled(labelToken, label) + ctx.style.styled(ctx.theme.theme.semantic.muted, ` ${detail}`)
68
+ : ctx.style.styled(labelToken, label);
69
+ return box(content, options);
70
+ }
71
+ //# sourceMappingURL=box.js.map