take4-console 0.15.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/CHANGELOG.md +287 -0
- package/LICENSE +21 -0
- package/README.md +986 -0
- package/dist/Screen/InterfaceBuilder.d.mts +43 -0
- package/dist/Screen/InterfaceBuilder.d.mts.map +1 -0
- package/dist/Screen/InterfaceBuilder.mjs +355 -0
- package/dist/Screen/InterfaceBuilder.mjs.map +1 -0
- package/dist/Screen/Pos.d.mts +52 -0
- package/dist/Screen/Pos.d.mts.map +1 -0
- package/dist/Screen/Pos.mjs +105 -0
- package/dist/Screen/Pos.mjs.map +1 -0
- package/dist/Screen/Region.d.mts +31 -0
- package/dist/Screen/Region.d.mts.map +1 -0
- package/dist/Screen/Region.mjs +73 -0
- package/dist/Screen/Region.mjs.map +1 -0
- package/dist/Screen/RegistryHolder.d.mts +6 -0
- package/dist/Screen/RegistryHolder.d.mts.map +1 -0
- package/dist/Screen/RegistryHolder.mjs +14 -0
- package/dist/Screen/RegistryHolder.mjs.map +1 -0
- package/dist/Screen/Screen.d.mts +25 -0
- package/dist/Screen/Screen.d.mts.map +1 -0
- package/dist/Screen/Screen.mjs +100 -0
- package/dist/Screen/Screen.mjs.map +1 -0
- package/dist/Screen/Size.d.mts +23 -0
- package/dist/Screen/Size.d.mts.map +1 -0
- package/dist/Screen/Size.mjs +48 -0
- package/dist/Screen/Size.mjs.map +1 -0
- package/dist/Screen/StyleRegistry.d.mts +32 -0
- package/dist/Screen/StyleRegistry.d.mts.map +1 -0
- package/dist/Screen/StyleRegistry.mjs +80 -0
- package/dist/Screen/StyleRegistry.mjs.map +1 -0
- package/dist/Screen/Window.d.mts +121 -0
- package/dist/Screen/Window.d.mts.map +1 -0
- package/dist/Screen/Window.mjs +407 -0
- package/dist/Screen/Window.mjs.map +1 -0
- package/dist/Screen/WindowManager.d.mts +86 -0
- package/dist/Screen/WindowManager.d.mts.map +1 -0
- package/dist/Screen/WindowManager.mjs +399 -0
- package/dist/Screen/WindowManager.mjs.map +1 -0
- package/dist/Screen/controls/BarChart.d.mts +29 -0
- package/dist/Screen/controls/BarChart.d.mts.map +1 -0
- package/dist/Screen/controls/BarChart.mjs +90 -0
- package/dist/Screen/controls/BarChart.mjs.map +1 -0
- package/dist/Screen/controls/Button.d.mts +16 -0
- package/dist/Screen/controls/Button.d.mts.map +1 -0
- package/dist/Screen/controls/Button.mjs +34 -0
- package/dist/Screen/controls/Button.mjs.map +1 -0
- package/dist/Screen/controls/Checkbox.d.mts +23 -0
- package/dist/Screen/controls/Checkbox.d.mts.map +1 -0
- package/dist/Screen/controls/Checkbox.mjs +55 -0
- package/dist/Screen/controls/Checkbox.mjs.map +1 -0
- package/dist/Screen/controls/LineChart.d.mts +29 -0
- package/dist/Screen/controls/LineChart.d.mts.map +1 -0
- package/dist/Screen/controls/LineChart.mjs +172 -0
- package/dist/Screen/controls/LineChart.mjs.map +1 -0
- package/dist/Screen/controls/ListBox.d.mts +34 -0
- package/dist/Screen/controls/ListBox.d.mts.map +1 -0
- package/dist/Screen/controls/ListBox.mjs +138 -0
- package/dist/Screen/controls/ListBox.mjs.map +1 -0
- package/dist/Screen/controls/ProgressBar.d.mts +26 -0
- package/dist/Screen/controls/ProgressBar.d.mts.map +1 -0
- package/dist/Screen/controls/ProgressBar.mjs +70 -0
- package/dist/Screen/controls/ProgressBar.mjs.map +1 -0
- package/dist/Screen/controls/ProgressBarV.d.mts +22 -0
- package/dist/Screen/controls/ProgressBarV.d.mts.map +1 -0
- package/dist/Screen/controls/ProgressBarV.mjs +61 -0
- package/dist/Screen/controls/ProgressBarV.mjs.map +1 -0
- package/dist/Screen/controls/Radio.d.mts +23 -0
- package/dist/Screen/controls/Radio.d.mts.map +1 -0
- package/dist/Screen/controls/Radio.mjs +55 -0
- package/dist/Screen/controls/Radio.mjs.map +1 -0
- package/dist/Screen/controls/Sparkline.d.mts +29 -0
- package/dist/Screen/controls/Sparkline.d.mts.map +1 -0
- package/dist/Screen/controls/Sparkline.mjs +82 -0
- package/dist/Screen/controls/Sparkline.mjs.map +1 -0
- package/dist/Screen/controls/Spinner.d.mts +37 -0
- package/dist/Screen/controls/Spinner.d.mts.map +1 -0
- package/dist/Screen/controls/Spinner.mjs +87 -0
- package/dist/Screen/controls/Spinner.mjs.map +1 -0
- package/dist/Screen/controls/StatusLED.d.mts +22 -0
- package/dist/Screen/controls/StatusLED.d.mts.map +1 -0
- package/dist/Screen/controls/StatusLED.mjs +51 -0
- package/dist/Screen/controls/StatusLED.mjs.map +1 -0
- package/dist/Screen/controls/Tabs.d.mts +42 -0
- package/dist/Screen/controls/Tabs.d.mts.map +1 -0
- package/dist/Screen/controls/Tabs.mjs +126 -0
- package/dist/Screen/controls/Tabs.mjs.map +1 -0
- package/dist/Screen/controls/TextArea.d.mts +41 -0
- package/dist/Screen/controls/TextArea.d.mts.map +1 -0
- package/dist/Screen/controls/TextArea.mjs +197 -0
- package/dist/Screen/controls/TextArea.mjs.map +1 -0
- package/dist/Screen/controls/TextBox.d.mts +35 -0
- package/dist/Screen/controls/TextBox.d.mts.map +1 -0
- package/dist/Screen/controls/TextBox.mjs +135 -0
- package/dist/Screen/controls/TextBox.mjs.map +1 -0
- package/dist/Screen/types.d.mts +399 -0
- package/dist/Screen/types.d.mts.map +1 -0
- package/dist/Screen/types.mjs +22 -0
- package/dist/Screen/types.mjs.map +1 -0
- package/dist/index.d.mts +26 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +41 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +72 -0
- package/src/Screen/InterfaceBuilder.mts +403 -0
- package/src/Screen/Pos.mts +119 -0
- package/src/Screen/Region.mts +88 -0
- package/src/Screen/RegistryHolder.mts +16 -0
- package/src/Screen/Screen.mts +103 -0
- package/src/Screen/Size.mts +55 -0
- package/src/Screen/StyleRegistry.mts +95 -0
- package/src/Screen/Window.mts +439 -0
- package/src/Screen/WindowManager.mts +472 -0
- package/src/Screen/controls/BarChart.mts +109 -0
- package/src/Screen/controls/Button.mts +40 -0
- package/src/Screen/controls/Checkbox.mts +66 -0
- package/src/Screen/controls/LineChart.mts +202 -0
- package/src/Screen/controls/ListBox.mts +154 -0
- package/src/Screen/controls/ProgressBar.mts +88 -0
- package/src/Screen/controls/ProgressBarV.mts +77 -0
- package/src/Screen/controls/Radio.mts +66 -0
- package/src/Screen/controls/Sparkline.mts +101 -0
- package/src/Screen/controls/Spinner.mts +102 -0
- package/src/Screen/controls/StatusLED.mts +65 -0
- package/src/Screen/controls/Tabs.mts +140 -0
- package/src/Screen/controls/TextArea.mts +194 -0
- package/src/Screen/controls/TextBox.mts +139 -0
- package/src/Screen/types.mts +416 -0
- package/src/demo.mts +171 -0
- package/src/index.mts +105 -0
- package/src/layout.yaml +236 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.15.0] – 2026-04-12
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- **Border defaults moved to `Window`** – each control now declares its default
|
|
7
|
+
border shape via `defaultBorder` in `WindowProperties` instead of overriding
|
|
8
|
+
`border: wp.border ?? { ... }` in the constructor. `Window` resolves the final
|
|
9
|
+
border as `wp.border ?? wp.defaultBorder`.
|
|
10
|
+
- **Border color synced automatically** – `Window.render()` calls a private
|
|
11
|
+
`syncBorderColor()` before painting the border. It updates the border color
|
|
12
|
+
based on the current `disabled`/`focused` state using `BUILTIN_BORDER_DISABLED`,
|
|
13
|
+
`BUILTIN_BORDER_FOCUSED`, and `BUILTIN_BORDER`. Controls no longer call
|
|
14
|
+
`updateBorder({ ..., color })` at the start of every `render()`.
|
|
15
|
+
- **Text style auto-picked in `writeText()`** – when no `style` option is
|
|
16
|
+
provided, `writeText()` automatically selects `disabledStyleId`, `focusedStyleId`,
|
|
17
|
+
or `normalStyleId` based on the current control state. Controls only pass an
|
|
18
|
+
explicit style for non-standard cases (e.g. `checkedStyleId`, `placeholderStyleId`).
|
|
19
|
+
- **`focusedStyleId` promoted to `Window`** – initialized from `BUILTIN_TEXT_FOCUSED`,
|
|
20
|
+
shared by all interactive controls; per-control `focusedStyleId` fields removed.
|
|
21
|
+
- **`Window` background default changed** – background now defaults to 0
|
|
22
|
+
(transparent) when not specified in `WindowProperties`; the BUILTIN_WINDOW_BG
|
|
23
|
+
fallback is the responsibility of each control that needs it.
|
|
24
|
+
|
|
25
|
+
## [0.14.0] – 2026-04-12
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- **Common control properties moved to `Window`** – `focused`, `disabled`,
|
|
29
|
+
`label`, `normalStyleId`, and `disabledStyleId` fields plus their
|
|
30
|
+
getters/setters (`setFocused`/`isFocused`, `setDisabled`/`isDisabled`,
|
|
31
|
+
`setLabel`/`getLabel`) now live in the `Window` base class as protected fields
|
|
32
|
+
with public accessors. All 14 controls no longer duplicate these declarations.
|
|
33
|
+
- `setDisabled()` automatically calls `setActive(!disabled)` to keep the two
|
|
34
|
+
flags in sync.
|
|
35
|
+
- Read-only controls (StatusLED, ProgressBar, ProgressBarV, LineChart, BarChart,
|
|
36
|
+
Sparkline, Spinner) no longer override `isFocused()`/`setFocused()`/`isDisabled()`
|
|
37
|
+
as no-ops — the inherited `Window` implementation is used instead.
|
|
38
|
+
- Renamed internal style fields for consistency: `TextBox`/`TextArea`
|
|
39
|
+
`textStyleId` → `normalStyleId`; `Tabs` `normalTextStyleId` → `normalStyleId`,
|
|
40
|
+
`disabledTextStyleId` → `disabledStyleId`.
|
|
41
|
+
|
|
42
|
+
## [0.13.0] – 2026-04-12
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- **Global StyleRegistry singleton** – eliminated the `registry?: StyleRegistry`
|
|
46
|
+
parameter from every constructor (`Window`, all 14 controls). Instead, a single
|
|
47
|
+
`StyleRegistry` is created by the `Screen` constructor and stored in a new
|
|
48
|
+
module-level singleton (`src/Screen/RegistryHolder.mts`). All windows and
|
|
49
|
+
controls automatically use that shared registry via `getRegistry()` without any
|
|
50
|
+
explicit wiring. `InterfaceBuilder` no longer threads a registry argument through
|
|
51
|
+
its internal `buildNode` helper.
|
|
52
|
+
- `Screen.getStyleRegistry()`, `Screen.registerStyle()`, and
|
|
53
|
+
`Screen.setBuiltinStyle()` are preserved and now delegate to the singleton.
|
|
54
|
+
- New internal module `RegistryHolder.mts` exports `getRegistry()` /
|
|
55
|
+
`setRegistry()` – avoids circular imports between `Screen` and `Window`.
|
|
56
|
+
|
|
57
|
+
## [0.12.0] – 2026-04-12
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- **Library packaging** – the project now ships as a reusable npm package:
|
|
61
|
+
- New `src/index.mts` barrel re-exports every public class, type, and
|
|
62
|
+
built-in style constant (`Screen`, `Window`, `WindowManager`, all 15
|
|
63
|
+
controls, `InterfaceBuilder`, `Pos`/`Size`/`Pct`/`pct`, all `*Options`
|
|
64
|
+
interfaces, YAML schema types, `BUILTIN_*` constants)
|
|
65
|
+
- `package.json` fields for publishing: `exports` map (ESM-only with
|
|
66
|
+
type-aware conditional exports), `types`, `module`, `files`,
|
|
67
|
+
`sideEffects: false`, `engines: node >= 18`, `keywords`, `repository`,
|
|
68
|
+
`bugs`, `homepage`, `license`, `author`, and a `prepublishOnly` script
|
|
69
|
+
that runs build + tests
|
|
70
|
+
- `LICENSE` file (MIT)
|
|
71
|
+
- `npm run demo` script – alias for the tsx-based dev command
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- **Demo entry point** moved from `src/index.mts` to `src/demo.mts`. The
|
|
75
|
+
library's `main`/`exports` now point at `dist/index.mjs` (the barrel),
|
|
76
|
+
so `import { Screen } from 'take4-console'` no longer accidentally runs
|
|
77
|
+
the demo — **breaking change for anyone importing the old internal
|
|
78
|
+
index.mts path**
|
|
79
|
+
- `tsconfig.json` excludes `src/demo.mts` from the library build (the demo
|
|
80
|
+
is tsx-only so `layout.yaml` keeps resolving from `src/` via
|
|
81
|
+
`import.meta.url`)
|
|
82
|
+
- README rewritten with an **Installation**, **Quick start**, **Public
|
|
83
|
+
API**, and **Running the bundled demo** section at the top; the
|
|
84
|
+
existing architecture / custom-control / YAML reference content is kept
|
|
85
|
+
below with a note that the example imports use relative paths because
|
|
86
|
+
they target in-repo extension
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## [0.11.0] – 2026-04-12
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
- **`ListBox`** – scrollable, focusable list of single-line items; supports ↑/↓, Home/End, PgUp/PgDn with automatic scrolling; emits `onChange(index, item)` when the selection moves
|
|
94
|
+
- **`Tabs`** – tabbed container that renders a header row and composites only the children tagged to the active tab; focusable with ←/→ to cycle tabs; new `addChildToTab(tabIndex, child)` API tags children without affecting standard `addChild()` semantics
|
|
95
|
+
- **`Sparkline`** – read-only one-row inline chart built from the eight-level block-character ramp (` ▁▂▃▄▅▆▇█`); supports width/data resampling via linear interpolation
|
|
96
|
+
- **`Spinner`** – read-only animated loader with five built-in frame styles (`braille`, `dots`, `line`, `circle`, `arrow`); advances via `step()` driven by an external clock; supports optional label to the right of the glyph
|
|
97
|
+
- New option interfaces: `ListBoxOptions`, `TabsOptions`, `SparklineOptions`, `SpinnerOptions`
|
|
98
|
+
- Extended `YamlWindowType` with `listbox`, `tabs`, `sparkline`, `spinner`
|
|
99
|
+
- New `YamlWindowDef.tab` field – when the parent is a `Tabs` control, children with a `tab:` field are routed through `addChildToTab()` automatically
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
- **`LineChart.render()`** – rewrote the plotting pipeline: every plot column now receives an interpolated row via linear interpolation between data samples, and vertical transitions are drawn as self-contained steps (`╯│╭` / `╮│╰`) instead of disjoint per-data-point cells. Fixes the "jagged" / disconnected appearance when plot width exceeds the data-point count. The buggy `selectLineChar` enter/exit lookup table (which had `up`/`down` corner characters swapped) has been removed entirely.
|
|
103
|
+
- **Demo (`index.mts` + `layout.yaml`)** – added a `LIVE` braille spinner to the header, replaced the bottom-right charts panel with a three-tab `Tabs` control (Charts / Trends / Events) showing the original `LineChart`+`BarChart` on tab 0, three stacked `Sparkline` histories on tab 1, and a scrolling `ListBox` event log on tab 2. The timer now advances the spinner, shifts rolling sparkline buffers in sync with the progress bars, and prepends timestamped log entries to the event list.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## [0.10.0] – 2026-04-12
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
- **`StatusLED`** – read-only coloured status indicator (states: `ok`/`warn`/`error`/`off`; auto-sizes to label width)
|
|
111
|
+
- **`ProgressBar`** – horizontal progress bar using `█`/`░` block characters with optional centred percentage label
|
|
112
|
+
- **`ProgressBarV`** – vertical progress bar filling from the bottom upward
|
|
113
|
+
- **`LineChart`** – line chart using box-drawing characters (`─`, `│`, `╭`, `╮`, `╯`, `╰`) with Y-axis labels and X-axis
|
|
114
|
+
- **`BarChart`** – vertical bar chart with `█` columns and single-character labels in the bottom row
|
|
115
|
+
- All five controls are read-only (`isFocused()` always `false`) and YAML-compatible via `InterfaceBuilder` using types `statusled`, `progressbar`, `progressbarv`, `linechart`, `barchart`
|
|
116
|
+
- New option interfaces in `types.mts`: `StatusLEDOptions`, `ProgressBarOptions`, `ProgressBarVOptions`, `LineChartOptions`, `BarChartOptions`
|
|
117
|
+
- Extended `YamlWindowType` and `YamlWindowDef` to support the new controls
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## [0.9.0] – 2026-04-12
|
|
122
|
+
|
|
123
|
+
### Added
|
|
124
|
+
- **Built-in named style system** – `Screen` pre-registers ten default styles under well-known names; controls look them up by name at render time and fall back to hardcoded defaults if the registry is fresh:
|
|
125
|
+
- `BUILTIN_WINDOW_BG` (`builtin:window-bg`) – default background for windows and controls
|
|
126
|
+
- `BUILTIN_BORDER` / `BUILTIN_BORDER_FOCUSED` / `BUILTIN_BORDER_DISABLED` – border foreground colours
|
|
127
|
+
- `BUILTIN_TEXT` / `BUILTIN_TEXT_FOCUSED` / `BUILTIN_TEXT_DISABLED` / `BUILTIN_TEXT_PLACEHOLDER` / `BUILTIN_TEXT_CHECKED` – text colour variants
|
|
128
|
+
- `BUILTIN_CURSOR` (`builtin:cursor`) – cursor inverse-highlight style
|
|
129
|
+
- **`StyleRegistry.registerNamed(name, attrs)`** – registers a style under a string name and returns its stable ID
|
|
130
|
+
- **`StyleRegistry.getNamed(name)`** – returns the StyleId associated with a name, or `undefined`
|
|
131
|
+
- **`StyleRegistry.getNamedForeground(name, fallback)`** – convenience helper that resolves the foreground `Color` of a named style (used by controls for border colours)
|
|
132
|
+
- **`Screen.setBuiltinStyle(name, attrs)`** – overrides any named style (built-in or custom) and returns the new ID; controls pick up the change on their next `render()` call
|
|
133
|
+
- **YAML `styles:` section** – `InterfaceBuilder` now parses an optional `styles:` list at the top of the layout document and registers each entry in `StyleRegistry` before building windows:
|
|
134
|
+
```yaml
|
|
135
|
+
styles:
|
|
136
|
+
- name: my-panel-bg
|
|
137
|
+
background: 235
|
|
138
|
+
- name: builtin:border-focused # override built-in
|
|
139
|
+
foreground: 214 # amber focused border
|
|
140
|
+
windows:
|
|
141
|
+
- background: my-panel-bg
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
- **`WindowOptions.background`** changed from `Color | false` to `StyleId | undefined` — pass a registered StyleId or omit for transparent (0 = no background); **breaking change**
|
|
146
|
+
- **`YamlWindowDef.background`** changed from `Color | false` to `string | number | undefined` — string values are resolved as named style names, numbers are used directly as StyleIds; **breaking change**
|
|
147
|
+
- **`YamlLayout`** now includes an optional `styles?: YamlStyleDef[]` field
|
|
148
|
+
- All controls (`Button`, `TextBox`, `TextArea`, `Checkbox`, `Radio`) now resolve their default colours from the built-in named styles instead of hardcoded ANSI numbers; hardcoded values remain as fallbacks when no Screen registry is present
|
|
149
|
+
|
|
150
|
+
### Tests
|
|
151
|
+
- `Window.test.mts` — background-option tests updated: register a StyleId via `StyleRegistry` instead of passing a raw color number; added `StyleId 0 background leaves region blank` case
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## [0.8.0] – 2026-04-11
|
|
156
|
+
|
|
157
|
+
### Added
|
|
158
|
+
- **`InterfaceBuilder`** (`src/Screen/InterfaceBuilder.mts`) – builds a window hierarchy from a YAML description:
|
|
159
|
+
- `build(yamlText, screen, wm?)` – parses YAML, adds all top-level windows to Screen, returns `Map<string, Window>` keyed by YAML `id`
|
|
160
|
+
- `buildFromFile(path, screen, wm?)` – async variant that reads a file first
|
|
161
|
+
- `registerCallback(id, fn)` – registers a named function for use with `onPress` / `onChange` in YAML
|
|
162
|
+
- Supports all widget types: `window`, `button`, `textbox`, `textarea`, `checkbox`, `radio`
|
|
163
|
+
- Position spec: `{x, y}` (absolute / negative edge-relative / `"N%"` percentage), named presets (`center`, `topLeft`, `topRight`, `bottomLeft`, `bottomRight`), edge presets (`{preset: top|left|right|bottom, offset?}`)
|
|
164
|
+
- Size spec: `{width, height}`, `"fill"`, `{fillWidth: N}`, `{fillHeight: N}`; `checkbox` and `radio` are auto-sized (no `size` needed)
|
|
165
|
+
- Passes shared `StyleRegistry` from Screen to all created windows
|
|
166
|
+
- When `wm` is provided, all focusable controls are automatically registered with `WindowManager` after the full tree is built (position resolution happens before registration)
|
|
167
|
+
- YAML schema types added to `types.mts`: `YamlAxisValue`, `YamlPosSpec`, `YamlSizeSpec`, `YamlWindowType`, `YamlWindowDef`, `YamlLayout`
|
|
168
|
+
- `yaml` package added as a runtime dependency
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## [0.7.0] – 2026-04-11
|
|
173
|
+
|
|
174
|
+
### Added
|
|
175
|
+
- **`WindowManager`** (`src/Screen/WindowManager.mts`) – application input manager:
|
|
176
|
+
- Captures raw stdin in TTY raw mode; parses escape sequences and SGR mouse events
|
|
177
|
+
- `register(control, ...parents)` – registers a focusable control for Tab-cycling; parent chain is used to compute absolute screen position for mouse hit-testing
|
|
178
|
+
- `unregister(control)` – removes a control from the focus list
|
|
179
|
+
- `getFocused()` / `setFocus(control)` – read/set current focus
|
|
180
|
+
- `openDialog(dialog, controls)` – pushes a modal dialog level; the dialog Window is added to Screen and its controls capture all focus until `closeDialog()` is called
|
|
181
|
+
- `closeDialog()` – pops the topmost dialog, removes it from Screen, and restores previous focus context
|
|
182
|
+
- `run()` – starts the event loop (raw mode, optional mouse tracking, hides cursor, initial render)
|
|
183
|
+
- `stop()` – restores terminal state and fires `onExit` callback
|
|
184
|
+
- Mouse support (SGR protocol): left-click focuses the clicked registered control (`mouse: true` option)
|
|
185
|
+
- `handleInput(Buffer)` – public method so tests can drive input without a real TTY
|
|
186
|
+
- **`Focusable`** interface (`types.mts`) – `{ isFocused, setFocused, isDisabled, handleKey? }` satisfied by all interactive controls
|
|
187
|
+
- **`TerminalMouseEvent`** interface (`types.mts`) – typed mouse event from the terminal
|
|
188
|
+
- **`WindowManagerOptions`** interface (`types.mts`) – `exitKeys`, `onExit`, `onKey`, `onMouse`, `mouse`
|
|
189
|
+
- **`Button.handleKey(key)`** – Enter or Space activates `onPress` callback
|
|
190
|
+
- **`Checkbox.handleKey(key)`** – Space toggles `checked` and fires `onChange`
|
|
191
|
+
- **`Radio.handleKey(key)`** – Space selects the button and fires `onChange`
|
|
192
|
+
- `onPress?: () => void` added to `ButtonOptions`
|
|
193
|
+
- `onChange?: (checked: boolean) => void` added to `CheckboxOptions` and `RadioOptions`
|
|
194
|
+
- **`Window.removeChild(child)`** – removes a previously added child (used internally by `closeDialog`)
|
|
195
|
+
- Demo (`src/index.mts`) updated to use `WindowManager` with mouse support; press `q` or Ctrl+C to exit
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## [0.6.0] – 2026-04-11
|
|
200
|
+
|
|
201
|
+
### Added
|
|
202
|
+
- **`Window.getInnerOffset()`** / **`Window.getInnerSize()`** – public methods returning the content area offset and dimensions after accounting for decorations (borders); used by `writeText`, `addChild`, `blitChild`
|
|
203
|
+
- **`Window.updateBorder()`** – protected method allowing subclasses to change the border config before each `render()` call (e.g. focus-state colour)
|
|
204
|
+
- **`Button`** (`src/Screen/controls/Button.mts`) – clickable button with rounded border, centred label, normal/focused/disabled states
|
|
205
|
+
- **`Checkbox`** (`src/Screen/controls/Checkbox.mts`) – `[✓]/[ ]` toggle; auto-sized to label width; checked/focused/disabled states
|
|
206
|
+
- **`Radio`** (`src/Screen/controls/Radio.mts`) – `(●)/( )` single-selection; auto-sized to label width; checked/focused/disabled states
|
|
207
|
+
- **`TextBox`** (`src/Screen/controls/TextBox.mts`) – single-line text input with scrolling, cursor, placeholder, `handleKey()` for terminal input
|
|
208
|
+
- **`TextArea`** (`src/Screen/controls/TextArea.mts`) – multi-line text input with 2-D cursor, scroll, placeholder, `handleKey()` for terminal input
|
|
209
|
+
- Control option types added to `types.mts`: `ControlOptions`, `ButtonOptions`, `TextBoxOptions`, `TextAreaOptions`, `CheckboxOptions`, `RadioOptions`
|
|
210
|
+
|
|
211
|
+
### Changed
|
|
212
|
+
- `Window.addChild()` now resolves child sizes and positions relative to the **inner content area** (excludes border cells) — **breaking change** for parents with borders
|
|
213
|
+
- `Window.writeText()` coordinates are now relative to the inner content area; text clips at inner boundaries, not full window edges — **breaking change** for windows with borders
|
|
214
|
+
- `Window.blitChild()` uses inner area dimensions for `Pos.resolve()` and offsets results by inner offset
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## [0.5.0] – 2026-04-11
|
|
219
|
+
|
|
220
|
+
### Added
|
|
221
|
+
- **`Pos`** class (`src/Screen/Pos.mts`) – encodes window position with support for:
|
|
222
|
+
- Absolute coordinates: `new Pos(5, 3)`
|
|
223
|
+
- From-right/bottom edge (negative): `new Pos(-5, -3)` — own edge at distance from parent edge
|
|
224
|
+
- Percentage of parent: `new Pos(pct(50), pct(25))`
|
|
225
|
+
- Named edge presets: `Pos.topLeft()`, `Pos.topRight()`, `Pos.bottomLeft()`, `Pos.bottomRight()`, `Pos.center()`, `Pos.left(y?)`, `Pos.right(y?)`, `Pos.top(x?)`, `Pos.bottom(x?)`
|
|
226
|
+
- **`Size`** class (`src/Screen/Size.mts`) – encodes window dimensions with support for:
|
|
227
|
+
- Absolute pixels: `new Size(30, 10)`
|
|
228
|
+
- Percentage of parent: `new Size(pct(50), pct(100))`
|
|
229
|
+
- Fill shortcuts: `Size.fill()`, `Size.fillWidth(h)`, `Size.fillHeight(w)`
|
|
230
|
+
- **`Pct`** class and **`pct(n)`** helper – wrap percentage values for use in `Pos` and `Size`
|
|
231
|
+
- `AxisSpec` and `DimSpec` type aliases added to `types.mts`
|
|
232
|
+
|
|
233
|
+
### Changed
|
|
234
|
+
- **`Window` constructor** signature changed from `(x, y, width, height, options?, registry?)` to `(pos: Pos, size: Size, options?, registry?)` — **breaking change**
|
|
235
|
+
- `Window.addChild()` now resolves percentage-based child sizes immediately against parent dimensions
|
|
236
|
+
- `Window` internal `blitChild()` re-resolves position via `Pos.resolve()` on every `render()` call
|
|
237
|
+
|
|
238
|
+
### Notes
|
|
239
|
+
- For windows with percentage-based sizes, call `parent.addChild(child)` before writing content.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## [0.4.0] - 2026-04-11
|
|
244
|
+
|
|
245
|
+
### Added
|
|
246
|
+
- `StyleRegistry` class (`src/Screen/StyleRegistry.mts`) – central style store with integer IDs and deduplication; `register()`, `get()`, `merge()`
|
|
247
|
+
- `StyleId = number` type alias (`src/Screen/types.mts`)
|
|
248
|
+
- `Screen.registerStyle(attrs): StyleId` – public API for registering styles
|
|
249
|
+
- `Screen.getStyleRegistry(): StyleRegistry` – returns the screen's registry for sharing with child Windows
|
|
250
|
+
- `Window.mergeStyle(x, y, styleId)` – replaces `setAttributes`; merges a style ID onto an existing cell
|
|
251
|
+
|
|
252
|
+
### Changed
|
|
253
|
+
- `Region` now stores `number[]` (style IDs) instead of `CellAttributes[]`; replaced `getAttrs()` with `getStyleIds()`, `setAttributes()` with `setStyleId()`, `getCell()` removed in favour of `getChar()` + `getStyleId()`
|
|
254
|
+
- `Window.setCell(x, y, char, styleId?)`, `fill(char, styleId?)`, `writeText(text, options?)` all accept `StyleId` instead of `CellAttributes`
|
|
255
|
+
- `WriteTextOptions` no longer extends `CellAttributes`; uses `style?: StyleId` field instead
|
|
256
|
+
- `Window` constructor gains optional `registry?: StyleRegistry` parameter for sharing ID spaces
|
|
257
|
+
- `tsconfig.json` – added `"types": ["node"]` to resolve `process` global
|
|
258
|
+
|
|
259
|
+
### Removed
|
|
260
|
+
- `Window.setAttributes()` (replaced by `mergeStyle()`)
|
|
261
|
+
- `Region.getAttrs()`, `Region.getCell()`, `Region.setAttributes()`
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## [0.3.0] - 2026-04-11
|
|
266
|
+
|
|
267
|
+
### Added
|
|
268
|
+
- `Window.writeText(text, options?)` – built-in text utility; position defaults to (0,0), supports `\n`, silently clips out-of-bounds characters (`src/Screen/Window.mts`)
|
|
269
|
+
- `WriteTextOptions` interface extending `CellAttributes` with optional `x`/`y` (`src/Screen/types.mts`)
|
|
270
|
+
|
|
271
|
+
### Changed
|
|
272
|
+
- `src/index.mts` – removed local `writeText` helper; all calls use `win.writeText()`
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## [0.2.0] - 2026-04-11
|
|
277
|
+
|
|
278
|
+
### Added
|
|
279
|
+
- `Screen` class with terminal cell grid (`src/Screen/Screen.mts`)
|
|
280
|
+
- Type declarations: `Color`, `CellAttributes`, `Cell`, `TerminalSize` (`src/Screen/types.mts`)
|
|
281
|
+
- Methods: `getSize`, `getCell`, `setChar`, `setCell`, `setAttributes`, `clear`, `fill`
|
|
282
|
+
- Unit tests for all `Screen` methods (`src/Screen/Screen.test.mts`)
|
|
283
|
+
|
|
284
|
+
## [0.1.0] - 2026-04-11
|
|
285
|
+
|
|
286
|
+
### Added
|
|
287
|
+
- Initial project setup (Node.js + TypeScript, ESM, Vitest)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jarosław Mężyk
|
|
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.
|