@crustjs/style 0.0.1
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 +227 -0
- package/dist/index.d.ts +965 -0
- package/dist/index.js +721 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# @crustjs/style
|
|
2
|
+
|
|
3
|
+
Terminal styling foundation for the [Crust](https://crustjs.com) CLI framework.
|
|
4
|
+
|
|
5
|
+
`@crustjs/style` provides ANSI-safe styling primitives, terminal capability awareness, layout helpers, and a semantic markdown theme — so CLI output remains readable, aligned, and consistent across color and no-color environments.
|
|
6
|
+
|
|
7
|
+
Zero runtime dependencies.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
bun add @crustjs/style
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { style } from "@crustjs/style";
|
|
19
|
+
|
|
20
|
+
// The default `style` instance auto-detects color support
|
|
21
|
+
console.log(style.bold("Build succeeded"));
|
|
22
|
+
console.log(style.red("Error: missing argument"));
|
|
23
|
+
console.log(style.dim("hint: use --help for usage"));
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Primitive Styling
|
|
27
|
+
|
|
28
|
+
Direct styling functions that always emit ANSI codes (useful when you control output directly):
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { bold, red, italic, bgYellow } from "@crustjs/style";
|
|
32
|
+
|
|
33
|
+
console.log(bold("important"));
|
|
34
|
+
console.log(red("error"));
|
|
35
|
+
console.log(italic("note"));
|
|
36
|
+
console.log(bgYellow("highlighted"));
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Available Modifiers
|
|
40
|
+
|
|
41
|
+
`bold`, `dim`, `italic`, `underline`, `inverse`, `hidden`, `strikethrough`
|
|
42
|
+
|
|
43
|
+
### Available Colors
|
|
44
|
+
|
|
45
|
+
**Foreground:** `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `gray`, `brightRed`, `brightGreen`, `brightYellow`, `brightBlue`, `brightMagenta`, `brightCyan`, `brightWhite`
|
|
46
|
+
|
|
47
|
+
**Background:** `bgBlack`, `bgRed`, `bgGreen`, `bgYellow`, `bgBlue`, `bgMagenta`, `bgCyan`, `bgWhite`, `bgBrightBlack`, `bgBrightRed`, `bgBrightGreen`, `bgBrightYellow`, `bgBrightBlue`, `bgBrightMagenta`, `bgBrightCyan`, `bgBrightWhite`
|
|
48
|
+
|
|
49
|
+
### Composing Styles
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { applyStyle, composeStyles, boldCode, redCode } from "@crustjs/style";
|
|
53
|
+
|
|
54
|
+
const boldRed = composeStyles(boldCode, redCode);
|
|
55
|
+
console.log(applyStyle("critical error", boldRed));
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Nested styles are handled safely — no style bleed across boundaries.
|
|
59
|
+
|
|
60
|
+
## Color Modes
|
|
61
|
+
|
|
62
|
+
Control when ANSI codes are emitted using `createStyle`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { createStyle } from "@crustjs/style";
|
|
66
|
+
|
|
67
|
+
// Auto-detect (default) — respects NO_COLOR and TTY status
|
|
68
|
+
const auto = createStyle({ mode: "auto" });
|
|
69
|
+
|
|
70
|
+
// Always emit ANSI codes
|
|
71
|
+
const color = createStyle({ mode: "always" });
|
|
72
|
+
console.log(color.red("always red"));
|
|
73
|
+
|
|
74
|
+
// Never emit ANSI codes — returns plain text
|
|
75
|
+
const plain = createStyle({ mode: "never" });
|
|
76
|
+
console.log(plain.red("just text")); // "just text"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The default `style` export uses `"auto"` mode:
|
|
80
|
+
|
|
81
|
+
- Emits ANSI when stdout is a TTY and `NO_COLOR` is not set
|
|
82
|
+
- Returns plain text otherwise
|
|
83
|
+
|
|
84
|
+
### Deterministic Testing
|
|
85
|
+
|
|
86
|
+
Inject capability overrides for predictable test output:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const testStyle = createStyle({
|
|
90
|
+
mode: "auto",
|
|
91
|
+
overrides: { isTTY: true, noColor: undefined },
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Text Utilities
|
|
96
|
+
|
|
97
|
+
ANSI-aware text measurement and layout:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import {
|
|
101
|
+
stripAnsi,
|
|
102
|
+
visibleWidth,
|
|
103
|
+
wrapText,
|
|
104
|
+
padStart,
|
|
105
|
+
padEnd,
|
|
106
|
+
center,
|
|
107
|
+
} from "@crustjs/style";
|
|
108
|
+
|
|
109
|
+
// Strip ANSI escape sequences
|
|
110
|
+
stripAnsi("\x1b[1mhello\x1b[22m"); // "hello"
|
|
111
|
+
|
|
112
|
+
// Measure visible width (ignores ANSI codes, counts CJK as 2)
|
|
113
|
+
visibleWidth("\x1b[31mhello\x1b[39m"); // 5
|
|
114
|
+
|
|
115
|
+
// Wrap text to a visible width, preserving active styles across breaks
|
|
116
|
+
wrapText("a long line of styled text", 20);
|
|
117
|
+
wrapText("force break mode", 10, { wordBreak: false });
|
|
118
|
+
|
|
119
|
+
// ANSI-safe padding and alignment
|
|
120
|
+
padStart("42", 6); // " 42"
|
|
121
|
+
padEnd("name", 10); // "name "
|
|
122
|
+
center("title", 20); // " title "
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Block Helpers
|
|
126
|
+
|
|
127
|
+
Format structured blocks for terminal output:
|
|
128
|
+
|
|
129
|
+
### Lists
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import { unorderedList, orderedList, taskList } from "@crustjs/style";
|
|
133
|
+
|
|
134
|
+
unorderedList(["apples", "bananas", "cherries"]);
|
|
135
|
+
// • apples
|
|
136
|
+
// • bananas
|
|
137
|
+
// • cherries
|
|
138
|
+
|
|
139
|
+
orderedList(["first", "second", "third"]);
|
|
140
|
+
// 1. first
|
|
141
|
+
// 2. second
|
|
142
|
+
// 3. third
|
|
143
|
+
|
|
144
|
+
taskList([
|
|
145
|
+
{ text: "Write tests", checked: true },
|
|
146
|
+
{ text: "Update docs", checked: false },
|
|
147
|
+
]);
|
|
148
|
+
// [x] Write tests
|
|
149
|
+
// [ ] Update docs
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Lists support `indent` for nesting and custom markers.
|
|
153
|
+
|
|
154
|
+
### Tables
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { table } from "@crustjs/style";
|
|
158
|
+
|
|
159
|
+
table(
|
|
160
|
+
["Name", "Version", "Status"],
|
|
161
|
+
[
|
|
162
|
+
["core", "1.2.0", "stable"],
|
|
163
|
+
["style", "0.1.0", "new"],
|
|
164
|
+
],
|
|
165
|
+
);
|
|
166
|
+
// | Name | Version | Status |
|
|
167
|
+
// | ----- | ------- | ------ |
|
|
168
|
+
// | core | 1.2.0 | stable |
|
|
169
|
+
// | style | 0.1.0 | new |
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Tables support per-column alignment (`"left"`, `"right"`, `"center"`), custom padding, and ANSI-styled cell content with correct alignment.
|
|
173
|
+
|
|
174
|
+
## Markdown Theme
|
|
175
|
+
|
|
176
|
+
Semantic theme slots for styling GFM (GitHub Flavored Markdown) constructs:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { defaultTheme } from "@crustjs/style";
|
|
180
|
+
|
|
181
|
+
// Apply theme slots to extracted markdown content
|
|
182
|
+
console.log(defaultTheme.heading1("Getting Started"));
|
|
183
|
+
console.log(defaultTheme.strong("important"));
|
|
184
|
+
console.log(defaultTheme.inlineCode("npm install"));
|
|
185
|
+
console.log(defaultTheme.linkText("docs") + " " + defaultTheme.linkUrl("https://crustjs.com"));
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Custom Themes
|
|
189
|
+
|
|
190
|
+
Override specific slots while inheriting defaults:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { createTheme } from "@crustjs/style";
|
|
194
|
+
|
|
195
|
+
const theme = createTheme({
|
|
196
|
+
style: { mode: "always" },
|
|
197
|
+
overrides: {
|
|
198
|
+
heading1: (text) => `>>> ${text.toUpperCase()} <<<`,
|
|
199
|
+
strong: (text) => `**${text}**`,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Theme Slots
|
|
205
|
+
|
|
206
|
+
The `MarkdownTheme` interface covers 30 GFM slots:
|
|
207
|
+
|
|
208
|
+
| Category | Slots |
|
|
209
|
+
| --- | --- |
|
|
210
|
+
| Headings | `heading1` through `heading6` |
|
|
211
|
+
| Text | `text`, `emphasis`, `strong`, `strongEmphasis`, `strikethrough` |
|
|
212
|
+
| Code | `inlineCode`, `codeFence`, `codeInfo`, `codeText` |
|
|
213
|
+
| Links | `linkText`, `linkUrl`, `autolink` |
|
|
214
|
+
| Lists | `listMarker`, `orderedListMarker`, `taskChecked`, `taskUnchecked` |
|
|
215
|
+
| Blockquotes | `blockquoteMarker`, `blockquoteText` |
|
|
216
|
+
| Tables | `tableHeader`, `tableCell`, `tableBorder` |
|
|
217
|
+
| Other | `thematicBreak`, `imageAltText`, `imageUrl` |
|
|
218
|
+
|
|
219
|
+
Theme slots are parser-agnostic `string => string` functions. Markdown parsing and AST handling belong to a separate consumer package — `@crustjs/style` provides the presentation layer only.
|
|
220
|
+
|
|
221
|
+
## Documentation
|
|
222
|
+
|
|
223
|
+
See the full docs at [crustjs.com](https://crustjs.com).
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT
|