Skip to content

Commit 82bae62

Browse files
authored
Merge pull request #3 from hyperweb-io/colors
yanse
2 parents 69a4a08 + 2001120 commit 82bae62

File tree

9 files changed

+3486
-5028
lines changed

9 files changed

+3486
-5028
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ jobs:
5757
- schema-sdk
5858
- schema-typescript
5959
- strfy-js
60+
- yanse
6061

6162
steps:
6263
- name: Checkout code

packages/yanse/README.md

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
# yanse
2+
3+
<p align="center">
4+
<img src="https://raw.githubusercontent.com/hyperweb-io/dev-utils/refs/heads/main/docs/img/logo.svg" width="80">
5+
<br />
6+
Yanse (颜色) - Fast terminal color styling
7+
<br />
8+
<a href="https://github.com/hyperweb-io/dev-utils/actions/workflows/ci.yml">
9+
<img height="20" src="https://github.com/hyperweb-io/dev-utils/actions/workflows/ci.yml/badge.svg" />
10+
</a>
11+
<a href="https://github.com/hyperweb-io/dev-utils/blob/main/LICENSE">
12+
<img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/>
13+
</a>
14+
</p>
15+
16+
Fast and lightweight terminal color styling library with a chalk-like API. Yanse (颜色, yánsè) means "color" in Chinese.
17+
18+
Why? We got tired of chalk's ESM-only errors and needed control over our dependencies. This utility is too simple to justify depending on chalk and wrestling with `module: true`.
19+
20+
## Features
21+
22+
- **Fast & Lightweight** - Zero dependencies, optimized for performance
23+
- **Chalk-like API** - Drop-in replacement for chalk with familiar syntax
24+
- **TypeScript Support** - Fully typed with comprehensive type definitions
25+
- **Nested Colors** - Proper handling of nested color styles without bugs
26+
- **Chained Styles** - Chain multiple colors and modifiers
27+
- **Toggle Support** - Easily enable/disable colors
28+
- **Themes & Aliases** - Create custom color themes and aliases
29+
30+
## Install
31+
32+
```sh
33+
npm install yanse
34+
```
35+
36+
## Usage
37+
38+
### Basic Colors
39+
40+
```typescript
41+
import yanse, { red, green, blue, yellow, cyan } from 'yanse';
42+
43+
console.log(red('Error message'));
44+
console.log(green('Success message'));
45+
console.log(blue('Info message'));
46+
console.log(yellow('Warning message'));
47+
console.log(cyan('Debug message'));
48+
```
49+
50+
### Chained Colors
51+
52+
```typescript
53+
import yanse from 'yanse';
54+
55+
console.log(yanse.bold.red('Bold red text'));
56+
console.log(yanse.bold.yellow.italic('Bold yellow italic text'));
57+
console.log(yanse.green.bold.underline('Bold green underlined text'));
58+
```
59+
60+
### Nested Colors
61+
62+
```typescript
63+
import { yellow, red, cyan } from 'yanse';
64+
65+
console.log(yellow(`foo ${red.bold('red')} bar ${cyan('cyan')} baz`));
66+
```
67+
68+
### Logger Example
69+
70+
Perfect for building loggers with colored output:
71+
72+
```typescript
73+
import yanse, { cyan, yellow, red, green, bold } from 'yanse';
74+
75+
type LogLevel = 'info' | 'warn' | 'error' | 'debug' | 'success';
76+
77+
const levelColors: Record<LogLevel, typeof cyan> = {
78+
info: cyan,
79+
warn: yellow,
80+
error: red,
81+
debug: yanse.gray,
82+
success: green
83+
};
84+
85+
class Logger {
86+
constructor(private scope: string) {}
87+
88+
log(level: LogLevel, message: string) {
89+
const tag = bold(`[${this.scope}]`);
90+
const color = levelColors[level];
91+
const prefix = color(`${level.toUpperCase()}:`);
92+
93+
console.log(`${tag} ${prefix} ${message}`);
94+
}
95+
}
96+
97+
const logger = new Logger('MyApp');
98+
logger.log('info', 'Application started');
99+
logger.log('success', 'Connection established');
100+
logger.log('warn', 'Deprecated API used');
101+
logger.log('error', 'Failed to connect');
102+
```
103+
104+
## Available Styles
105+
106+
### Colors
107+
108+
- `black`
109+
- `red`
110+
- `green`
111+
- `yellow`
112+
- `blue`
113+
- `magenta`
114+
- `cyan`
115+
- `white`
116+
- `gray` / `grey`
117+
118+
### Background Colors
119+
120+
- `bgBlack`
121+
- `bgRed`
122+
- `bgGreen`
123+
- `bgYellow`
124+
- `bgBlue`
125+
- `bgMagenta`
126+
- `bgCyan`
127+
- `bgWhite`
128+
129+
### Bright Colors
130+
131+
- `blackBright`, `redBright`, `greenBright`, `yellowBright`
132+
- `blueBright`, `magentaBright`, `cyanBright`, `whiteBright`
133+
134+
### Bright Background Colors
135+
136+
- `bgBlackBright`, `bgRedBright`, `bgGreenBright`, `bgYellowBright`
137+
- `bgBlueBright`, `bgMagentaBright`, `bgCyanBright`, `bgWhiteBright`
138+
139+
### Style Modifiers
140+
141+
- `bold`
142+
- `dim`
143+
- `italic`
144+
- `underline`
145+
- `inverse`
146+
- `hidden`
147+
- `strikethrough`
148+
- `reset`
149+
150+
## Toggle Color Support
151+
152+
```typescript
153+
import yanse from 'yanse';
154+
155+
// Disable colors
156+
yanse.enabled = false;
157+
console.log(yanse.red('This will not be colored'));
158+
159+
// Re-enable colors
160+
yanse.enabled = true;
161+
console.log(yanse.red('This will be red'));
162+
```
163+
164+
## Strip ANSI Codes
165+
166+
```typescript
167+
import yanse from 'yanse';
168+
169+
const styled = yanse.blue.bold('Hello World');
170+
console.log(yanse.unstyle(styled)); // 'Hello World'
171+
console.log(yanse.stripColor(styled)); // 'Hello World' (alias)
172+
```
173+
174+
## Themes & Aliases
175+
176+
### Create Aliases
177+
178+
```typescript
179+
import yanse from 'yanse';
180+
181+
yanse.alias('primary', yanse.blue);
182+
yanse.alias('secondary', yanse.gray);
183+
184+
console.log(yanse.primary('Primary text'));
185+
console.log(yanse.secondary('Secondary text'));
186+
```
187+
188+
### Create Themes
189+
190+
```typescript
191+
import yanse from 'yanse';
192+
193+
yanse.theme({
194+
danger: yanse.red,
195+
success: yanse.green,
196+
warning: yanse.yellow,
197+
info: yanse.cyan,
198+
primary: yanse.blue,
199+
muted: yanse.dim.gray
200+
});
201+
202+
console.log(yanse.danger('Error occurred!'));
203+
console.log(yanse.success('Operation successful!'));
204+
console.log(yanse.warning('Be careful!'));
205+
```
206+
207+
## Create Custom Instances
208+
209+
```typescript
210+
import { create } from 'yanse';
211+
212+
const customYanse = create();
213+
customYanse.enabled = false; // This instance has colors disabled
214+
215+
console.log(customYanse.red('Not colored'));
216+
```
217+
218+
## API
219+
220+
### Properties
221+
222+
- `enabled: boolean` - Enable/disable color output
223+
- `visible: boolean` - Make output visible/invisible
224+
- `ansiRegex: RegExp` - Regex for matching ANSI codes
225+
226+
### Methods
227+
228+
- `hasColor(str: string): boolean` - Check if string contains ANSI codes
229+
- `hasAnsi(str: string): boolean` - Alias for hasColor
230+
- `unstyle(str: string): string` - Remove ANSI codes from string
231+
- `stripColor(str: string): string` - Alias for unstyle
232+
- `alias(name: string, color: YanseColor): void` - Create color alias
233+
- `theme(colors: Record<string, YanseColor>): void` - Create color theme
234+
- `create(): YanseColors` - Create new yanse instance
235+
236+
## Why Yanse?
237+
238+
- **Zero Dependencies** - No external dependencies, minimal bundle size
239+
- **Fast** - Optimized for performance
240+
- **Correct Nested Colors** - Unlike some libraries, yanse correctly handles nested color styles
241+
- **TypeScript First** - Written in TypeScript with full type support
242+
- **Familiar API** - Drop-in replacement for chalk
243+
244+
## Developing
245+
246+
When first cloning the repo:
247+
248+
```sh
249+
pnpm install
250+
pnpm build
251+
```
252+
253+
## Testing
254+
255+
```sh
256+
pnpm test
257+
```
258+
259+
## Credits
260+
261+
Inspired by [chalk](https://github.com/chalk/chalk) and [ansi-colors](https://github.com/doowb/ansi-colors).

0 commit comments

Comments
 (0)