@basiclines/rampa-sdk 1.4.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 +333 -0
- package/dist/index.js +7908 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Rampa SDK
|
|
2
|
+
|
|
3
|
+
Programmatic JavaScript/TypeScript SDK for generating mathematically accurate, accessible color palettes. Same engine as the [Rampa CLI](../cli/README.md), designed for use in applications, build tools, and design systems.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @basiclines/rampa-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { rampa } from '@basiclines/rampa-sdk';
|
|
15
|
+
|
|
16
|
+
// Generate a 10-color palette from blue
|
|
17
|
+
const result = rampa('#3b82f6').generate();
|
|
18
|
+
|
|
19
|
+
// Custom size with lightness range
|
|
20
|
+
const palette = rampa('#3b82f6').size(5).lightness(10, 90).generate();
|
|
21
|
+
|
|
22
|
+
// Add complementary harmony
|
|
23
|
+
const harmonies = rampa('#3b82f6').add('complementary').generate();
|
|
24
|
+
|
|
25
|
+
// Output as CSS variables
|
|
26
|
+
const css = rampa('#3b82f6').toCSS();
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
### `rampa(baseColor)`
|
|
32
|
+
|
|
33
|
+
Creates a new builder for a color palette. Accepts any valid CSS color (hex, hsl, rgb, oklch, named colors).
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
const builder = rampa('#3b82f6');
|
|
37
|
+
const builder = rampa('rgb(59, 130, 246)');
|
|
38
|
+
const builder = rampa('hsl(217, 91%, 60%)');
|
|
39
|
+
const builder = rampa('oklch(62.3% 0.214 259)');
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Builder Methods
|
|
43
|
+
|
|
44
|
+
All builder methods return `this` for chaining.
|
|
45
|
+
|
|
46
|
+
#### `.size(steps)`
|
|
47
|
+
|
|
48
|
+
Number of colors in the palette (2-100, default: 10).
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
rampa('#3b82f6').size(5).generate();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### `.format(type)`
|
|
55
|
+
|
|
56
|
+
Color format for output values: `hex`, `hsl`, `rgb`, `oklch` (default: `hex`).
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
rampa('#3b82f6').format('hsl').generate();
|
|
60
|
+
// colors: ['hsl(0, 0%, 0%)', 'hsl(212, 69%, 25%)', ...]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### `.lightness(start, end)`
|
|
64
|
+
|
|
65
|
+
Lightness range 0-100 (default: 0, 100).
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
rampa('#3b82f6').lightness(10, 90).generate();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### `.saturation(start, end)`
|
|
72
|
+
|
|
73
|
+
Saturation range 0-100 (default: 100, 0).
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
rampa('#3b82f6').saturation(80, 20).generate();
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### `.hue(start, end)`
|
|
80
|
+
|
|
81
|
+
Hue shift in degrees (default: -10, 10).
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
rampa('#3b82f6').hue(-30, 30).generate();
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### `.lightnessScale(type)`, `.saturationScale(type)`, `.hueScale(type)`
|
|
88
|
+
|
|
89
|
+
Distribution curve for each channel (default: `linear`).
|
|
90
|
+
|
|
91
|
+
Available scales: `linear`, `geometric`, `fibonacci`, `golden-ratio`, `logarithmic`, `powers-of-2`, `musical-ratio`, `cielab-uniform`, `ease-in`, `ease-out`, `ease-in-out`
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
rampa('#3b82f6')
|
|
95
|
+
.lightnessScale('fibonacci')
|
|
96
|
+
.saturationScale('ease-out')
|
|
97
|
+
.hueScale('golden-ratio')
|
|
98
|
+
.generate();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### `.tint(color, opacity, blend?)`
|
|
102
|
+
|
|
103
|
+
Apply a tint color over the palette.
|
|
104
|
+
|
|
105
|
+
- `color` — Any valid CSS color
|
|
106
|
+
- `opacity` — Tint strength 0-100
|
|
107
|
+
- `blend` — Blend mode (default: `normal`)
|
|
108
|
+
|
|
109
|
+
Available blend modes: `normal`, `multiply`, `screen`, `overlay`, `darken`, `lighten`, `color-dodge`, `color-burn`, `hard-light`, `soft-light`, `difference`, `exclusion`, `hue`, `saturation`, `color`, `luminosity`
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
rampa('#3b82f6')
|
|
113
|
+
.tint('#FF0000', 15, 'overlay')
|
|
114
|
+
.generate();
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `.add(type)` / `.add('shift', degrees)`
|
|
118
|
+
|
|
119
|
+
Add a harmony ramp. Can be called multiple times.
|
|
120
|
+
|
|
121
|
+
Available harmony types:
|
|
122
|
+
- `complementary` — Opposite on color wheel (+180°)
|
|
123
|
+
- `triadic` — 3 colors, 120° apart
|
|
124
|
+
- `analogous` — Adjacent colors, 30° apart
|
|
125
|
+
- `split-complementary` — 2 colors near opposite
|
|
126
|
+
- `square` — 4 colors, 90° apart
|
|
127
|
+
- `compound` — Complementary + split
|
|
128
|
+
- `shift` — Custom hue rotation by N degrees
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
rampa('#3b82f6')
|
|
132
|
+
.add('complementary')
|
|
133
|
+
.add('triadic')
|
|
134
|
+
.add('shift', 45)
|
|
135
|
+
.generate();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Terminal Methods
|
|
139
|
+
|
|
140
|
+
These methods execute the builder and return results.
|
|
141
|
+
|
|
142
|
+
#### `.generate()`
|
|
143
|
+
|
|
144
|
+
Returns a `RampaResult` object with all generated ramps.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
const result = rampa('#3b82f6').size(5).add('complementary').generate();
|
|
148
|
+
// {
|
|
149
|
+
// ramps: [
|
|
150
|
+
// { name: 'base', baseColor: '#3b82f6', colors: ['#000000', '#143d6b', ...] },
|
|
151
|
+
// { name: 'complementary', baseColor: '#f6a43b', colors: ['#000000', '#6b4314', ...] }
|
|
152
|
+
// ]
|
|
153
|
+
// }
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### `.toCSS()`
|
|
157
|
+
|
|
158
|
+
Returns CSS custom properties string.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const css = rampa('#3b82f6').size(5).toCSS();
|
|
162
|
+
// :root {
|
|
163
|
+
// /* base */
|
|
164
|
+
// --base-0: #000000;
|
|
165
|
+
// --base-1: #143d6b;
|
|
166
|
+
// --base-2: #4572ba;
|
|
167
|
+
// --base-3: #b1b9ce;
|
|
168
|
+
// --base-4: #ffffff;
|
|
169
|
+
// }
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### `.toJSON()`
|
|
173
|
+
|
|
174
|
+
Returns formatted JSON string.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const json = rampa('#3b82f6').size(5).toJSON();
|
|
178
|
+
// {
|
|
179
|
+
// "ramps": [
|
|
180
|
+
// {
|
|
181
|
+
// "name": "base",
|
|
182
|
+
// "baseColor": "#3b82f6",
|
|
183
|
+
// "colors": ["#000000", "#143d6b", "#4572ba", "#b1b9ce", "#ffffff"]
|
|
184
|
+
// }
|
|
185
|
+
// ]
|
|
186
|
+
// }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### `rampa.readOnly(color)`
|
|
190
|
+
|
|
191
|
+
Read a color without generating a ramp — equivalent to `--read-only` in the CLI. Returns a `ReadOnlyBuilder` with chainable `.format()` and terminal `.generate()`.
|
|
192
|
+
|
|
193
|
+
Without a format, `.generate()` returns a `ColorInfo` object with all representations:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
rampa.readOnly('#fe0000').generate();
|
|
197
|
+
// {
|
|
198
|
+
// hex: '#fe0000',
|
|
199
|
+
// rgb: { r: 254, g: 0, b: 0 },
|
|
200
|
+
// hsl: { h: 0, s: 100, l: 50 },
|
|
201
|
+
// oklch: { l: 62.8, c: 0.257, h: 29 }
|
|
202
|
+
// }
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
With `.format()`, `.generate()` returns a formatted string:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
rampa.readOnly('#fe0000').format('hsl').generate(); // 'hsl(0, 100%, 50%)'
|
|
209
|
+
rampa.readOnly('#fe0000').format('rgb').generate(); // 'rgb(254, 0, 0)'
|
|
210
|
+
rampa.readOnly('#fe0000').format('oklch').generate(); // 'oklch(62.8% 0.257 29)'
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### `rampa.convert(color, format)`
|
|
214
|
+
|
|
215
|
+
Standalone utility to convert a color to a different format.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
rampa.convert('#fe0000', 'hsl'); // 'hsl(0, 100%, 50%)'
|
|
219
|
+
rampa.convert('#fe0000', 'rgb'); // 'rgb(254, 0, 0)'
|
|
220
|
+
rampa.convert('#fe0000', 'oklch'); // 'oklch(62.8% 0.257 29)'
|
|
221
|
+
rampa.convert('#fe0000', 'hex'); // '#fe0000'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Types
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import type {
|
|
228
|
+
ColorFormat, // 'hex' | 'hsl' | 'rgb' | 'oklch'
|
|
229
|
+
ScaleType, // 'linear' | 'fibonacci' | 'golden-ratio' | ...
|
|
230
|
+
BlendMode, // 'normal' | 'multiply' | 'screen' | ...
|
|
231
|
+
HarmonyType, // 'complementary' | 'triadic' | 'analogous' | ...
|
|
232
|
+
RampResult, // { name, baseColor, colors }
|
|
233
|
+
RampaResult, // { ramps: RampResult[] }
|
|
234
|
+
ColorInfo, // { hex, rgb, hsl, oklch } — returned by readOnly()
|
|
235
|
+
} from '@basiclines/rampa-sdk';
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Examples
|
|
239
|
+
|
|
240
|
+
### Design System Palette
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { rampa } from '@basiclines/rampa-sdk';
|
|
244
|
+
|
|
245
|
+
const primary = rampa('#3b82f6')
|
|
246
|
+
.size(10)
|
|
247
|
+
.lightness(5, 95)
|
|
248
|
+
.saturationScale('ease-out')
|
|
249
|
+
.generate();
|
|
250
|
+
|
|
251
|
+
const neutral = rampa('#64748b')
|
|
252
|
+
.size(10)
|
|
253
|
+
.saturation(20, 0)
|
|
254
|
+
.generate();
|
|
255
|
+
|
|
256
|
+
const danger = rampa('#ef4444')
|
|
257
|
+
.size(10)
|
|
258
|
+
.lightness(10, 90)
|
|
259
|
+
.generate();
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Full Palette with Harmonies
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
const palette = rampa('#3b82f6')
|
|
266
|
+
.size(10)
|
|
267
|
+
.lightness(5, 95)
|
|
268
|
+
.lightnessScale('ease-in-out')
|
|
269
|
+
.add('complementary')
|
|
270
|
+
.add('analogous')
|
|
271
|
+
.generate();
|
|
272
|
+
|
|
273
|
+
// palette.ramps[0] → base (blue)
|
|
274
|
+
// palette.ramps[1] → complementary (orange)
|
|
275
|
+
// palette.ramps[2] → analogous (purple)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### CSS Variables for a Theme
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const theme = rampa('#3b82f6')
|
|
282
|
+
.size(10)
|
|
283
|
+
.add('complementary')
|
|
284
|
+
.tint('#FFD700', 5, 'overlay')
|
|
285
|
+
.toCSS();
|
|
286
|
+
|
|
287
|
+
// Inject into page
|
|
288
|
+
const style = document.createElement('style');
|
|
289
|
+
style.textContent = theme;
|
|
290
|
+
document.head.appendChild(style);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Build Tool Integration
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { rampa } from '@basiclines/rampa-sdk';
|
|
297
|
+
import { writeFileSync } from 'fs';
|
|
298
|
+
|
|
299
|
+
const colors = rampa('#3b82f6')
|
|
300
|
+
.size(10)
|
|
301
|
+
.format('hsl')
|
|
302
|
+
.generate();
|
|
303
|
+
|
|
304
|
+
// Write to a tokens file
|
|
305
|
+
writeFileSync('tokens.json', JSON.stringify(colors, null, 2));
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## CLI Parity
|
|
309
|
+
|
|
310
|
+
The SDK produces identical output to the CLI. These are equivalent:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# CLI
|
|
314
|
+
rampa --color "#3b82f6" --size=5 --lightness 10:90 --add=complementary --output json
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
// SDK
|
|
319
|
+
rampa('#3b82f6').size(5).lightness(10, 90).add('complementary').toJSON();
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Development
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
cd sdk
|
|
326
|
+
bun install
|
|
327
|
+
|
|
328
|
+
# Run tests
|
|
329
|
+
bun test
|
|
330
|
+
|
|
331
|
+
# Build
|
|
332
|
+
bun run build
|
|
333
|
+
```
|