@kud/ink-ui 0.1.0 → 0.3.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 +27 -237
- package/dist/index.d.ts +189 -10
- package/dist/index.js +414 -7
- package/package.json +24 -12
- package/dist/components/Badge.d.ts +0 -8
- package/dist/components/Badge.d.ts.map +0 -1
- package/dist/components/Badge.js +0 -11
- package/dist/components/Badge.js.map +0 -1
- package/dist/components/Banner.d.ts +0 -8
- package/dist/components/Banner.d.ts.map +0 -1
- package/dist/components/Banner.js +0 -5
- package/dist/components/Banner.js.map +0 -1
- package/dist/components/Header.d.ts +0 -7
- package/dist/components/Header.d.ts.map +0 -1
- package/dist/components/Header.js +0 -4
- package/dist/components/Header.js.map +0 -1
- package/dist/components/Spinner.d.ts +0 -6
- package/dist/components/Spinner.d.ts.map +0 -1
- package/dist/components/Spinner.js +0 -6
- package/dist/components/Spinner.js.map +0 -1
- package/dist/components/Table.d.ts +0 -12
- package/dist/components/Table.d.ts.map +0 -1
- package/dist/components/Table.js +0 -5
- package/dist/components/Table.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tokens.d.ts +0 -17
- package/dist/tokens.d.ts.map +0 -1
- package/dist/tokens.js +0 -15
- package/dist/tokens.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,284 +1,74 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
7
|
|
|
8
|
-
**
|
|
8
|
+
**React component library for Ink CLIs**
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
<a href="https://kud.io/projects/ink-ui">Website</a> · <a href="https://kud.io/projects/ink-ui/docs">Documentation</a>
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Features
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
- **Ten ready-made components** — Banner, Header, Badge, Spinner, Table, Tabs, FooterHints, LoadingScreen, KeyValue, and SelectableRow, pre-styled and ready to drop in
|
|
17
|
+
- **Design tokens included** — a shared colour palette (`colors`) and spacing scale (`spacing`) to keep every screen consistent
|
|
18
|
+
- **Full TypeScript support** — ships compiled output with `.d.ts` declarations for every component and token type
|
|
19
|
+
- **ESM only, zero config** — no runtime bundling step; just import and render
|
|
20
|
+
- **Peer-dependency light** — only requires `ink ≥ 4` and `react ≥ 18`; `ink-spinner` is the sole production dependency
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
- 🎨 **Design tokens included** — a shared colour palette and spacing scale to keep every screen consistent
|
|
20
|
-
- 🟠 **Accent-driven style** — a warm `#FF8C00` accent colour gives your CLI a distinctive, coherent identity
|
|
21
|
-
- ⚡ **ESM only, zero config** — ships compiled TypeScript with full type definitions; just import and render
|
|
22
|
-
- 🔒 **Peer-dep friendly** — works with any Ink ≥ 4 and React ≥ 18 setup, no version lock-in
|
|
23
|
-
- 🧩 **Composable** — every component accepts standard Ink primitives so you can mix them with your own layouts freely
|
|
24
|
-
- 🏷 **Typed throughout** — exported types (`BadgeVariant`, `Column`, `Color`, `Spacing`) make props self-documenting in any IDE
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 🚀 Quick Start
|
|
29
|
-
|
|
30
|
-
### Install
|
|
22
|
+
## Install
|
|
31
23
|
|
|
32
24
|
```sh
|
|
33
25
|
npm install @kud/ink-ui
|
|
34
26
|
```
|
|
35
27
|
|
|
36
|
-
`ink` and `react` are peer dependencies
|
|
28
|
+
`ink` and `react` are peer dependencies and must be installed separately:
|
|
37
29
|
|
|
38
30
|
```sh
|
|
39
31
|
npm install ink react
|
|
40
32
|
```
|
|
41
33
|
|
|
42
|
-
|
|
34
|
+
## Usage
|
|
43
35
|
|
|
44
36
|
```tsx
|
|
45
37
|
import React from "react"
|
|
46
38
|
import { render } from "ink"
|
|
47
|
-
import { Banner, Header, Badge, Spinner,
|
|
39
|
+
import { Banner, Header, Badge, Spinner, colors } from "@kud/ink-ui"
|
|
48
40
|
|
|
49
41
|
const App = () => (
|
|
50
42
|
<>
|
|
51
|
-
<Banner title="
|
|
52
|
-
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
<Badge variant="success">installed</Badge>
|
|
56
|
-
<Badge variant="warning">outdated</Badge>
|
|
57
|
-
|
|
43
|
+
<Banner title="my-tool" subtitle="v1.0.0" />
|
|
44
|
+
<Header subtitle="Synchronising files…">Status</Header>
|
|
45
|
+
<Badge variant="success">done</Badge>
|
|
58
46
|
<Spinner label="Loading…" />
|
|
59
|
-
|
|
60
|
-
<Table
|
|
61
|
-
columns={[
|
|
62
|
-
{ key: "name", header: "Package", width: 20 },
|
|
63
|
-
{ key: "version", header: "Version", width: 10 },
|
|
64
|
-
]}
|
|
65
|
-
data={[
|
|
66
|
-
{ name: "ink", version: "5.0.0" },
|
|
67
|
-
{ name: "react", version: "18.3.1" },
|
|
68
|
-
]}
|
|
69
|
-
/>
|
|
70
47
|
</>
|
|
71
48
|
)
|
|
72
49
|
|
|
73
50
|
render(<App />)
|
|
74
51
|
```
|
|
75
52
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
◆ My CLI v1.0.0
|
|
80
|
-
|
|
81
|
-
Dependencies
|
|
82
|
-
Fetching packages…
|
|
83
|
-
|
|
84
|
-
[installed] [outdated]
|
|
85
|
-
|
|
86
|
-
⠋ Loading…
|
|
87
|
-
|
|
88
|
-
Package Version
|
|
89
|
-
ink 5.0.0
|
|
90
|
-
react 18.3.1
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## 🧩 Components
|
|
96
|
-
|
|
97
|
-
### `<Banner>`
|
|
98
|
-
|
|
99
|
-
Full-width title block — ideal as an app header at the top of a screen.
|
|
100
|
-
|
|
101
|
-
| Prop | Type | Default | Description |
|
|
102
|
-
| ---------- | -------- | ------- | ---------------------------------------- |
|
|
103
|
-
| `title` | `string` | — | Bold title text |
|
|
104
|
-
| `subtitle` | `string` | — | Optional dimmed subtitle rendered inline |
|
|
105
|
-
| `icon` | `string` | `"◆"` | Leading icon rendered in accent colour |
|
|
106
|
-
|
|
107
|
-
```tsx
|
|
108
|
-
<Banner title="Deploy Tool" subtitle="production" icon="🚀" />
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
### `<Header>`
|
|
114
|
-
|
|
115
|
-
Bold, underlined section heading. Use it to separate logical groups within a screen.
|
|
116
|
-
|
|
117
|
-
| Prop | Type | Default | Description |
|
|
118
|
-
| ---------- | -------- | ------- | ------------------------------------------ |
|
|
119
|
-
| `children` | `string` | — | The heading text |
|
|
120
|
-
| `subtitle` | `string` | — | Optional dimmed subtitle below the heading |
|
|
121
|
-
|
|
122
|
-
```tsx
|
|
123
|
-
<Header subtitle="3 items">Results</Header>
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
### `<Badge>`
|
|
129
|
-
|
|
130
|
-
Inline `[label]` tag with semantic colour variants.
|
|
131
|
-
|
|
132
|
-
| Prop | Type | Default | Description |
|
|
133
|
-
| ---------- | -------------- | -------- | ------------------------------------ |
|
|
134
|
-
| `children` | `string` | — | Label text displayed inside brackets |
|
|
135
|
-
| `variant` | `BadgeVariant` | `"info"` | Colour variant (see table below) |
|
|
136
|
-
|
|
137
|
-
| Variant | Colour |
|
|
138
|
-
| --------- | ------ |
|
|
139
|
-
| `success` | green |
|
|
140
|
-
| `error` | red |
|
|
141
|
-
| `warning` | yellow |
|
|
142
|
-
| `info` | cyan |
|
|
143
|
-
|
|
144
|
-
```tsx
|
|
145
|
-
<Badge variant="error">failed</Badge>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
### `<Spinner>`
|
|
151
|
-
|
|
152
|
-
Animated dots spinner in accent colour, with an optional dimmed label.
|
|
153
|
-
|
|
154
|
-
| Prop | Type | Default | Description |
|
|
155
|
-
| ------- | -------- | ------- | ----------------------------------------- |
|
|
156
|
-
| `label` | `string` | — | Optional text rendered beside the spinner |
|
|
157
|
-
|
|
158
|
-
```tsx
|
|
159
|
-
<Spinner label="Building…" />
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
### `<Table>`
|
|
165
|
-
|
|
166
|
-
Structured data grid with bold muted column headers. Supports optional fixed column widths and truncates long values cleanly.
|
|
167
|
-
|
|
168
|
-
| Prop | Type | Description |
|
|
169
|
-
| --------- | ------------- | ------------------------------ |
|
|
170
|
-
| `data` | `T[]` | Array of row objects |
|
|
171
|
-
| `columns` | `Column<T>[]` | Column definitions (see below) |
|
|
172
|
-
|
|
173
|
-
**`Column<T>` shape:**
|
|
174
|
-
|
|
175
|
-
| Field | Type | Description |
|
|
176
|
-
| -------- | --------- | ---------------------------------- |
|
|
177
|
-
| `key` | `keyof T` | Object key to read for this column |
|
|
178
|
-
| `header` | `string` | Column heading text |
|
|
179
|
-
| `width` | `number` | Optional fixed character width |
|
|
180
|
-
|
|
181
|
-
```tsx
|
|
182
|
-
<Table
|
|
183
|
-
columns={[
|
|
184
|
-
{ key: "name", header: "Name", width: 16 },
|
|
185
|
-
{ key: "status", header: "Status" },
|
|
186
|
-
]}
|
|
187
|
-
data={[
|
|
188
|
-
{ name: "api", status: "ok" },
|
|
189
|
-
{ name: "db", status: "degraded" },
|
|
190
|
-
]}
|
|
191
|
-
/>
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## 🎨 Design Tokens
|
|
197
|
-
|
|
198
|
-
Import `colors` and `spacing` to keep your own components aligned with the design system.
|
|
53
|
+
All components accept only the props they need — no theme provider or context required. Design tokens are plain objects:
|
|
199
54
|
|
|
200
55
|
```ts
|
|
201
56
|
import { colors, spacing } from "@kud/ink-ui"
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### Colours
|
|
205
|
-
|
|
206
|
-
| Token | Value | Semantic use |
|
|
207
|
-
| ---------------- | --------- | ---------------------------------- |
|
|
208
|
-
| `colors.accent` | `#FF8C00` | Primary highlight, icons, spinners |
|
|
209
|
-
| `colors.muted` | `gray` | Dimmed text, table headers |
|
|
210
|
-
| `colors.success` | `green` | Positive states |
|
|
211
|
-
| `colors.error` | `red` | Failures and errors |
|
|
212
|
-
| `colors.warning` | `yellow` | Caution states |
|
|
213
|
-
| `colors.info` | `cyan` | Neutral informational |
|
|
214
|
-
|
|
215
|
-
### Spacing
|
|
216
|
-
|
|
217
|
-
| Token | Value | Description |
|
|
218
|
-
| ------------ | ----- | ---------------------------------- |
|
|
219
|
-
| `spacing.xs` | `1` | Tight gap between inline elements |
|
|
220
|
-
| `spacing.sm` | `2` | Small margin between grouped items |
|
|
221
|
-
| `spacing.md` | `3` | Standard section margin |
|
|
222
|
-
| `spacing.lg` | `4` | Large gap between major sections |
|
|
223
57
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
### Project structure
|
|
229
|
-
|
|
230
|
-
```
|
|
231
|
-
ink-ui/
|
|
232
|
-
├── src/
|
|
233
|
-
│ ├── components/
|
|
234
|
-
│ │ ├── Badge.tsx
|
|
235
|
-
│ │ ├── Banner.tsx
|
|
236
|
-
│ │ ├── Header.tsx
|
|
237
|
-
│ │ ├── Spinner.tsx
|
|
238
|
-
│ │ └── Table.tsx
|
|
239
|
-
│ ├── index.ts # public API
|
|
240
|
-
│ └── tokens.ts # colours + spacing
|
|
241
|
-
├── dist/ # compiled output (git-ignored)
|
|
242
|
-
├── tsconfig.json
|
|
243
|
-
└── package.json
|
|
58
|
+
// colors.accent → "#FF8C00"
|
|
59
|
+
// colors.success → "green"
|
|
60
|
+
// spacing.md → 3
|
|
244
61
|
```
|
|
245
62
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
| Script | Command | Description |
|
|
249
|
-
| ------- | ------------- | ------------------------------------ |
|
|
250
|
-
| `build` | `tsc` | Compile TypeScript to `dist/` |
|
|
251
|
-
| `dev` | `tsc --watch` | Watch mode — recompile on every save |
|
|
252
|
-
|
|
253
|
-
### Local setup
|
|
63
|
+
## Development
|
|
254
64
|
|
|
255
65
|
```sh
|
|
256
66
|
git clone https://github.com/kud/ink-ui.git
|
|
257
67
|
cd ink-ui
|
|
258
68
|
npm install
|
|
259
|
-
npm run
|
|
69
|
+
npm run dev
|
|
260
70
|
```
|
|
261
71
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
```sh
|
|
265
|
-
npm link
|
|
266
|
-
cd ../your-project
|
|
267
|
-
npm link @kud/ink-ui
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
## 🏗 Tech Stack
|
|
273
|
-
|
|
274
|
-
| Technology | Purpose |
|
|
275
|
-
| ---------------------------------------------------------- | -------------------------------------- |
|
|
276
|
-
| [TypeScript](https://www.typescriptlang.org/) | Strict typing, declaration file output |
|
|
277
|
-
| [Ink](https://github.com/vadimdemedes/ink) | React renderer for the terminal |
|
|
278
|
-
| [React](https://react.dev/) | Component model and JSX |
|
|
279
|
-
| [ink-spinner](https://github.com/vadimdemedes/ink-spinner) | Animated spinner primitive |
|
|
280
|
-
| ESM | Modern module format, no CommonJS |
|
|
281
|
-
|
|
282
|
-
---
|
|
72
|
+
`npm run build` compiles TypeScript to `dist/`. `npm run dev` runs the compiler in watch mode.
|
|
283
73
|
|
|
284
|
-
|
|
74
|
+
📚 **Full documentation → [ink-ui/docs](https://kud.io/projects/ink-ui/docs)**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,189 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type BannerProps = {
|
|
4
|
+
title: string;
|
|
5
|
+
subtitle?: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
};
|
|
8
|
+
declare const Banner: ({ title, subtitle, icon }: BannerProps) => React.JSX.Element;
|
|
9
|
+
|
|
10
|
+
type BadgeVariant = "success" | "error" | "warning" | "info";
|
|
11
|
+
type BadgeProps = {
|
|
12
|
+
children: string;
|
|
13
|
+
variant?: BadgeVariant;
|
|
14
|
+
};
|
|
15
|
+
declare const Badge: ({ children, variant }: BadgeProps) => React.JSX.Element;
|
|
16
|
+
|
|
17
|
+
type HeaderProps = {
|
|
18
|
+
children: string;
|
|
19
|
+
subtitle?: string;
|
|
20
|
+
};
|
|
21
|
+
declare const Header: ({ children, subtitle }: HeaderProps) => React.JSX.Element;
|
|
22
|
+
|
|
23
|
+
type SpinnerProps = {
|
|
24
|
+
label?: string;
|
|
25
|
+
};
|
|
26
|
+
declare const Spinner: ({ label }: SpinnerProps) => React.JSX.Element;
|
|
27
|
+
|
|
28
|
+
type Column<T extends Record<string, unknown>> = {
|
|
29
|
+
key: keyof T & string;
|
|
30
|
+
header: string;
|
|
31
|
+
width?: number;
|
|
32
|
+
};
|
|
33
|
+
type TableProps<T extends Record<string, unknown>> = {
|
|
34
|
+
data: T[];
|
|
35
|
+
columns: Column<T>[];
|
|
36
|
+
};
|
|
37
|
+
declare const Table: <T extends Record<string, unknown>>({ data, columns, }: TableProps<T>) => React.JSX.Element;
|
|
38
|
+
|
|
39
|
+
type Hint = [key: string, label: string];
|
|
40
|
+
type FooterHintsProps = {
|
|
41
|
+
hints: Hint[];
|
|
42
|
+
};
|
|
43
|
+
declare const FooterHints: ({ hints }: FooterHintsProps) => React.JSX.Element;
|
|
44
|
+
|
|
45
|
+
type KeyValueProps = {
|
|
46
|
+
label: string;
|
|
47
|
+
value: React.ReactNode;
|
|
48
|
+
labelWidth?: number;
|
|
49
|
+
};
|
|
50
|
+
declare const KeyValue: ({ label, value, labelWidth }: KeyValueProps) => React.JSX.Element;
|
|
51
|
+
|
|
52
|
+
type LoadingScreenProps = {
|
|
53
|
+
label: string;
|
|
54
|
+
};
|
|
55
|
+
declare const LoadingScreen: ({ label }: LoadingScreenProps) => React.JSX.Element;
|
|
56
|
+
|
|
57
|
+
type SelectableRowProps = {
|
|
58
|
+
active?: boolean;
|
|
59
|
+
marker?: string;
|
|
60
|
+
children: React.ReactNode;
|
|
61
|
+
};
|
|
62
|
+
declare const SelectableRow: ({ active, marker, children, }: SelectableRowProps) => React.JSX.Element;
|
|
63
|
+
|
|
64
|
+
type SelectOption<T extends string = string> = {
|
|
65
|
+
label: string;
|
|
66
|
+
value: T;
|
|
67
|
+
};
|
|
68
|
+
type SelectProps<T extends string> = {
|
|
69
|
+
options: SelectOption<T>[];
|
|
70
|
+
onChange?: (value: T) => void;
|
|
71
|
+
onSubmit?: (value: T) => void;
|
|
72
|
+
defaultValue?: T;
|
|
73
|
+
isDisabled?: boolean;
|
|
74
|
+
visibleOptionCount?: number;
|
|
75
|
+
};
|
|
76
|
+
declare const Select: <T extends string>({ options, onChange, onSubmit, defaultValue, isDisabled, visibleOptionCount, }: SelectProps<T>) => React.JSX.Element;
|
|
77
|
+
|
|
78
|
+
type MultiSelectProps<T extends string> = {
|
|
79
|
+
options: SelectOption<T>[];
|
|
80
|
+
onChange?: (values: T[]) => void;
|
|
81
|
+
onSubmit?: (values: T[]) => void;
|
|
82
|
+
defaultValue?: T[];
|
|
83
|
+
isDisabled?: boolean;
|
|
84
|
+
visibleOptionCount?: number;
|
|
85
|
+
};
|
|
86
|
+
declare const MultiSelect: <T extends string>({ options, onChange, onSubmit, defaultValue, isDisabled, visibleOptionCount, }: MultiSelectProps<T>) => React.JSX.Element;
|
|
87
|
+
|
|
88
|
+
type TextInputProps = {
|
|
89
|
+
placeholder?: string;
|
|
90
|
+
defaultValue?: string;
|
|
91
|
+
onChange?: (value: string) => void;
|
|
92
|
+
onSubmit?: (value: string) => void;
|
|
93
|
+
isDisabled?: boolean;
|
|
94
|
+
};
|
|
95
|
+
declare const TextInput: ({ placeholder, defaultValue, onChange, onSubmit, isDisabled, }: TextInputProps) => React.JSX.Element;
|
|
96
|
+
|
|
97
|
+
type ConfirmInputProps = {
|
|
98
|
+
defaultChoice?: "confirm" | "cancel";
|
|
99
|
+
onConfirm?: () => void;
|
|
100
|
+
onCancel?: () => void;
|
|
101
|
+
isDisabled?: boolean;
|
|
102
|
+
};
|
|
103
|
+
declare const ConfirmInput: ({ defaultChoice, onConfirm, onCancel, isDisabled, }: ConfirmInputProps) => React.JSX.Element;
|
|
104
|
+
|
|
105
|
+
type Span = {
|
|
106
|
+
text: string;
|
|
107
|
+
color?: string;
|
|
108
|
+
bold?: boolean;
|
|
109
|
+
dim?: boolean;
|
|
110
|
+
italic?: boolean;
|
|
111
|
+
};
|
|
112
|
+
type StyledLine = {
|
|
113
|
+
text: string;
|
|
114
|
+
color?: string;
|
|
115
|
+
bold?: boolean;
|
|
116
|
+
dim?: boolean;
|
|
117
|
+
spans?: Span[];
|
|
118
|
+
};
|
|
119
|
+
type ScrollViewProps = {
|
|
120
|
+
lines: StyledLine[];
|
|
121
|
+
showIndicator?: boolean;
|
|
122
|
+
};
|
|
123
|
+
declare const ScrollView: ({ lines, showIndicator, }: ScrollViewProps) => React.JSX.Element;
|
|
124
|
+
|
|
125
|
+
type TabItem<T extends string = string> = {
|
|
126
|
+
value: T;
|
|
127
|
+
label: string;
|
|
128
|
+
count?: number;
|
|
129
|
+
};
|
|
130
|
+
type TabsProps<T extends string> = {
|
|
131
|
+
active: T;
|
|
132
|
+
items: TabItem<T>[];
|
|
133
|
+
};
|
|
134
|
+
declare const Tabs: <T extends string>({ active, items }: TabsProps<T>) => React.JSX.Element;
|
|
135
|
+
|
|
136
|
+
type ProgressBarProps = {
|
|
137
|
+
value: number;
|
|
138
|
+
width?: number;
|
|
139
|
+
};
|
|
140
|
+
declare const ProgressBar: ({ value, width }: ProgressBarProps) => React.JSX.Element;
|
|
141
|
+
|
|
142
|
+
type StatusVariant = "success" | "error" | "warning" | "info";
|
|
143
|
+
|
|
144
|
+
type StatusMessageProps = {
|
|
145
|
+
variant?: StatusVariant;
|
|
146
|
+
children: React.ReactNode;
|
|
147
|
+
};
|
|
148
|
+
declare const StatusMessage: ({ variant, children, }: StatusMessageProps) => React.JSX.Element;
|
|
149
|
+
|
|
150
|
+
type AlertProps = {
|
|
151
|
+
variant?: StatusVariant;
|
|
152
|
+
title?: string;
|
|
153
|
+
children: React.ReactNode;
|
|
154
|
+
};
|
|
155
|
+
declare const Alert: ({ variant, title, children }: AlertProps) => React.JSX.Element;
|
|
156
|
+
|
|
157
|
+
type ToastProps = {
|
|
158
|
+
message: string;
|
|
159
|
+
variant?: StatusVariant;
|
|
160
|
+
duration?: number;
|
|
161
|
+
onDone?: () => void;
|
|
162
|
+
};
|
|
163
|
+
declare const Toast: ({ message, variant, duration, onDone, }: ToastProps) => React.JSX.Element | null;
|
|
164
|
+
|
|
165
|
+
type NotifyOptions = {
|
|
166
|
+
title?: string;
|
|
167
|
+
subtitle?: string;
|
|
168
|
+
sound?: boolean | string;
|
|
169
|
+
};
|
|
170
|
+
declare const notify: (message: string, options?: NotifyOptions) => void;
|
|
171
|
+
|
|
172
|
+
declare const colors: {
|
|
173
|
+
readonly accent: "#FF8C00";
|
|
174
|
+
readonly muted: "gray";
|
|
175
|
+
readonly success: "green";
|
|
176
|
+
readonly error: "red";
|
|
177
|
+
readonly warning: "yellow";
|
|
178
|
+
readonly info: "cyan";
|
|
179
|
+
};
|
|
180
|
+
type Color = (typeof colors)[keyof typeof colors];
|
|
181
|
+
declare const spacing: {
|
|
182
|
+
readonly xs: 1;
|
|
183
|
+
readonly sm: 2;
|
|
184
|
+
readonly md: 3;
|
|
185
|
+
readonly lg: 4;
|
|
186
|
+
};
|
|
187
|
+
type Spacing = (typeof spacing)[keyof typeof spacing];
|
|
188
|
+
|
|
189
|
+
export { Alert, Badge, type BadgeVariant, Banner, type Color, type Column, ConfirmInput, FooterHints, Header, type Hint, KeyValue, LoadingScreen, MultiSelect, type NotifyOptions, ProgressBar, ScrollView, Select, type SelectOption, SelectableRow, type Spacing, type Span, Spinner, StatusMessage, type StatusVariant, type StyledLine, type TabItem, Table, Tabs, TextInput, Toast, colors, notify, spacing };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,414 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Box, Text, useInput, measureElement } from 'ink';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useState, useEffect, useRef, useLayoutEffect } from 'react';
|
|
4
|
+
import cliSpinners from 'cli-spinners';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
|
|
7
|
+
// src/components/Banner.tsx
|
|
8
|
+
|
|
9
|
+
// src/tokens.ts
|
|
10
|
+
var colors = {
|
|
11
|
+
accent: "#FF8C00",
|
|
12
|
+
muted: "gray",
|
|
13
|
+
success: "green",
|
|
14
|
+
error: "red",
|
|
15
|
+
warning: "yellow",
|
|
16
|
+
info: "cyan"
|
|
17
|
+
};
|
|
18
|
+
var spacing = {
|
|
19
|
+
xs: 1,
|
|
20
|
+
sm: 2,
|
|
21
|
+
md: 3,
|
|
22
|
+
lg: 4
|
|
23
|
+
};
|
|
24
|
+
var Banner = ({ title, subtitle, icon = "\u25C6" }) => /* @__PURE__ */ jsxs(Box, { gap: 1, marginBottom: 1, children: [
|
|
25
|
+
/* @__PURE__ */ jsx(Text, { color: colors.accent, children: icon }),
|
|
26
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: title }),
|
|
27
|
+
subtitle && /* @__PURE__ */ jsx(Text, { dimColor: true, children: subtitle })
|
|
28
|
+
] });
|
|
29
|
+
var variantColor = {
|
|
30
|
+
success: colors.success,
|
|
31
|
+
error: colors.error,
|
|
32
|
+
warning: colors.warning,
|
|
33
|
+
info: colors.info
|
|
34
|
+
};
|
|
35
|
+
var Badge = ({ children, variant = "info" }) => /* @__PURE__ */ jsxs(Text, { color: variantColor[variant], children: [
|
|
36
|
+
"[",
|
|
37
|
+
children,
|
|
38
|
+
"]"
|
|
39
|
+
] });
|
|
40
|
+
var Header = ({ children, subtitle }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Text, { bold: true, underline: true, children }),
|
|
42
|
+
subtitle && /* @__PURE__ */ jsx(Text, { dimColor: true, children: subtitle })
|
|
43
|
+
] });
|
|
44
|
+
var dots = cliSpinners.dots;
|
|
45
|
+
var Spinner = ({ label }) => {
|
|
46
|
+
const [frame, setFrame] = useState(0);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
const timer = setInterval(() => {
|
|
49
|
+
setFrame((prev) => (prev + 1) % dots.frames.length);
|
|
50
|
+
}, dots.interval);
|
|
51
|
+
return () => clearInterval(timer);
|
|
52
|
+
}, []);
|
|
53
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
54
|
+
/* @__PURE__ */ jsx(Text, { color: colors.accent, children: dots.frames[frame] }),
|
|
55
|
+
label && /* @__PURE__ */ jsx(Text, { dimColor: true, children: label })
|
|
56
|
+
] });
|
|
57
|
+
};
|
|
58
|
+
var Table = ({
|
|
59
|
+
data,
|
|
60
|
+
columns
|
|
61
|
+
}) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
62
|
+
/* @__PURE__ */ jsx(Box, { gap: 2, children: columns.map((col) => /* @__PURE__ */ jsx(Box, { width: col.width, minWidth: col.width, children: /* @__PURE__ */ jsx(Text, { bold: true, color: colors.muted, children: col.header }) }, col.key)) }),
|
|
63
|
+
data.map((row, i) => /* @__PURE__ */ jsx(Box, { gap: 2, children: columns.map((col) => /* @__PURE__ */ jsx(Box, { width: col.width, minWidth: col.width, children: /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", children: String(row[col.key] ?? "") }) }, col.key)) }, i))
|
|
64
|
+
] });
|
|
65
|
+
var FooterHints = ({ hints }) => /* @__PURE__ */ jsx(Box, { gap: 2, flexWrap: "wrap", children: hints.map(([key, label]) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
66
|
+
/* @__PURE__ */ jsx(Text, { color: "white", children: key }),
|
|
67
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " + label })
|
|
68
|
+
] }, key)) });
|
|
69
|
+
var isTextValue = (value) => typeof value === "string" || typeof value === "number";
|
|
70
|
+
var KeyValue = ({ label, value, labelWidth = 12 }) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
71
|
+
/* @__PURE__ */ jsx(Box, { width: labelWidth, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: label }) }),
|
|
72
|
+
isTextValue(value) ? /* @__PURE__ */ jsx(Text, { children: value }) : value
|
|
73
|
+
] });
|
|
74
|
+
var LoadingScreen = ({ label }) => /* @__PURE__ */ jsx(Box, { padding: 1, children: /* @__PURE__ */ jsx(Spinner, { label }) });
|
|
75
|
+
var isTextValue2 = (value) => typeof value === "string" || typeof value === "number";
|
|
76
|
+
var SelectableRow = ({
|
|
77
|
+
active = false,
|
|
78
|
+
marker = "\u276F",
|
|
79
|
+
children
|
|
80
|
+
}) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
81
|
+
/* @__PURE__ */ jsx(Text, { color: colors.info, children: active ? ` ${marker} ` : " " }),
|
|
82
|
+
isTextValue2(children) ? /* @__PURE__ */ jsx(Text, { bold: active, children }) : children
|
|
83
|
+
] });
|
|
84
|
+
var windowStart = (cursor, total, count) => {
|
|
85
|
+
if (total <= count) return 0;
|
|
86
|
+
return Math.max(0, Math.min(cursor - Math.floor(count / 2), total - count));
|
|
87
|
+
};
|
|
88
|
+
var Select = ({
|
|
89
|
+
options,
|
|
90
|
+
onChange,
|
|
91
|
+
onSubmit,
|
|
92
|
+
defaultValue,
|
|
93
|
+
isDisabled = false,
|
|
94
|
+
visibleOptionCount
|
|
95
|
+
}) => {
|
|
96
|
+
const initial = options.findIndex((o) => o.value === defaultValue);
|
|
97
|
+
const [cursor, setCursor] = useState(initial === -1 ? 0 : initial);
|
|
98
|
+
const move = (delta) => {
|
|
99
|
+
const next = (cursor + delta + options.length) % options.length;
|
|
100
|
+
setCursor(next);
|
|
101
|
+
onChange?.(options[next].value);
|
|
102
|
+
};
|
|
103
|
+
useInput(
|
|
104
|
+
(_input, key) => {
|
|
105
|
+
if (key.upArrow) move(-1);
|
|
106
|
+
if (key.downArrow) move(1);
|
|
107
|
+
if (key.return) onSubmit?.(options[cursor].value);
|
|
108
|
+
},
|
|
109
|
+
{ isActive: !isDisabled && options.length > 0 }
|
|
110
|
+
);
|
|
111
|
+
const count = visibleOptionCount ?? options.length;
|
|
112
|
+
const start = windowStart(cursor, options.length, count);
|
|
113
|
+
const visible = options.slice(start, start + count);
|
|
114
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
115
|
+
visible.map((option, i) => {
|
|
116
|
+
const active = start + i === cursor;
|
|
117
|
+
return /* @__PURE__ */ jsx(SelectableRow, { active, children: /* @__PURE__ */ jsx(Text, { bold: active, color: active ? colors.accent : void 0, children: option.label }) }, option.value);
|
|
118
|
+
}),
|
|
119
|
+
options.length > count && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2026 ${options.length} total` })
|
|
120
|
+
] });
|
|
121
|
+
};
|
|
122
|
+
var windowStart2 = (cursor, total, count) => {
|
|
123
|
+
if (total <= count) return 0;
|
|
124
|
+
return Math.max(0, Math.min(cursor - Math.floor(count / 2), total - count));
|
|
125
|
+
};
|
|
126
|
+
var MultiSelect = ({
|
|
127
|
+
options,
|
|
128
|
+
onChange,
|
|
129
|
+
onSubmit,
|
|
130
|
+
defaultValue = [],
|
|
131
|
+
isDisabled = false,
|
|
132
|
+
visibleOptionCount
|
|
133
|
+
}) => {
|
|
134
|
+
const [cursor, setCursor] = useState(0);
|
|
135
|
+
const [selected, setSelected] = useState(new Set(defaultValue));
|
|
136
|
+
useInput(
|
|
137
|
+
(input, key) => {
|
|
138
|
+
if (key.upArrow)
|
|
139
|
+
setCursor((i) => (i - 1 + options.length) % options.length);
|
|
140
|
+
if (key.downArrow) setCursor((i) => (i + 1) % options.length);
|
|
141
|
+
if (input === " ") {
|
|
142
|
+
const value = options[cursor].value;
|
|
143
|
+
const next = new Set(selected);
|
|
144
|
+
if (next.has(value)) next.delete(value);
|
|
145
|
+
else next.add(value);
|
|
146
|
+
setSelected(next);
|
|
147
|
+
onChange?.([...next]);
|
|
148
|
+
}
|
|
149
|
+
if (key.return) onSubmit?.([...selected]);
|
|
150
|
+
},
|
|
151
|
+
{ isActive: !isDisabled && options.length > 0 }
|
|
152
|
+
);
|
|
153
|
+
const count = visibleOptionCount ?? options.length;
|
|
154
|
+
const start = windowStart2(cursor, options.length, count);
|
|
155
|
+
const visible = options.slice(start, start + count);
|
|
156
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
157
|
+
visible.map((option, i) => {
|
|
158
|
+
const active = start + i === cursor;
|
|
159
|
+
const on = selected.has(option.value);
|
|
160
|
+
return /* @__PURE__ */ jsxs(SelectableRow, { active, children: [
|
|
161
|
+
/* @__PURE__ */ jsx(Text, { color: on ? colors.success : void 0, children: on ? "\u25C9" : "\u25CB" }),
|
|
162
|
+
/* @__PURE__ */ jsx(Text, { bold: active, color: active ? colors.accent : void 0, children: " " + option.label })
|
|
163
|
+
] }, option.value);
|
|
164
|
+
}),
|
|
165
|
+
options.length > count && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2026 ${options.length} total` })
|
|
166
|
+
] });
|
|
167
|
+
};
|
|
168
|
+
var TextInput = ({
|
|
169
|
+
placeholder = "",
|
|
170
|
+
defaultValue = "",
|
|
171
|
+
onChange,
|
|
172
|
+
onSubmit,
|
|
173
|
+
isDisabled = false
|
|
174
|
+
}) => {
|
|
175
|
+
const [value, setValue] = useState(defaultValue);
|
|
176
|
+
const [cursor, setCursor] = useState(defaultValue.length);
|
|
177
|
+
const update = (nextValue, nextCursor) => {
|
|
178
|
+
setValue(nextValue);
|
|
179
|
+
setCursor(nextCursor);
|
|
180
|
+
onChange?.(nextValue);
|
|
181
|
+
};
|
|
182
|
+
useInput(
|
|
183
|
+
(input, key) => {
|
|
184
|
+
if (key.return) {
|
|
185
|
+
onSubmit?.(value);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (key.leftArrow) {
|
|
189
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (key.rightArrow) {
|
|
193
|
+
setCursor((c) => Math.min(value.length, c + 1));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (key.backspace || key.delete) {
|
|
197
|
+
if (cursor === 0) return;
|
|
198
|
+
update(value.slice(0, cursor - 1) + value.slice(cursor), cursor - 1);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (input && !key.ctrl && !key.meta && !key.tab) {
|
|
202
|
+
update(
|
|
203
|
+
value.slice(0, cursor) + input + value.slice(cursor),
|
|
204
|
+
cursor + input.length
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
{ isActive: !isDisabled }
|
|
209
|
+
);
|
|
210
|
+
if (value.length === 0) {
|
|
211
|
+
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
212
|
+
/* @__PURE__ */ jsx(Text, { inverse: true, children: " " }),
|
|
213
|
+
placeholder ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: placeholder }) : null
|
|
214
|
+
] });
|
|
215
|
+
}
|
|
216
|
+
const before = value.slice(0, cursor);
|
|
217
|
+
const at = value.slice(cursor, cursor + 1) || " ";
|
|
218
|
+
const after = value.slice(cursor + 1);
|
|
219
|
+
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
220
|
+
before,
|
|
221
|
+
/* @__PURE__ */ jsx(Text, { inverse: true, children: at }),
|
|
222
|
+
after
|
|
223
|
+
] });
|
|
224
|
+
};
|
|
225
|
+
var ConfirmInput = ({
|
|
226
|
+
defaultChoice = "confirm",
|
|
227
|
+
onConfirm,
|
|
228
|
+
onCancel,
|
|
229
|
+
isDisabled = false
|
|
230
|
+
}) => {
|
|
231
|
+
useInput(
|
|
232
|
+
(input, key) => {
|
|
233
|
+
if (input.toLowerCase() === "y") {
|
|
234
|
+
onConfirm?.();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (input.toLowerCase() === "n") {
|
|
238
|
+
onCancel?.();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (key.return) {
|
|
242
|
+
if (defaultChoice === "confirm") onConfirm?.();
|
|
243
|
+
else onCancel?.();
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{ isActive: !isDisabled }
|
|
247
|
+
);
|
|
248
|
+
const hint = defaultChoice === "confirm" ? "(Y/n)" : "(y/N)";
|
|
249
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint });
|
|
250
|
+
};
|
|
251
|
+
var ScrollView = ({
|
|
252
|
+
lines,
|
|
253
|
+
showIndicator = true
|
|
254
|
+
}) => {
|
|
255
|
+
const ref = useRef(null);
|
|
256
|
+
const [height, setHeight] = useState(1);
|
|
257
|
+
const [start, setStart] = useState(0);
|
|
258
|
+
useLayoutEffect(() => {
|
|
259
|
+
if (!ref.current) return;
|
|
260
|
+
const { height: h } = measureElement(ref.current);
|
|
261
|
+
if (h > 0 && h !== height) setHeight(h);
|
|
262
|
+
});
|
|
263
|
+
const maxStart = Math.max(0, lines.length - height);
|
|
264
|
+
const clamped = Math.min(start, maxStart);
|
|
265
|
+
useInput((input, key) => {
|
|
266
|
+
if (key.downArrow || input === "j")
|
|
267
|
+
setStart((s) => Math.min(maxStart, s + 1));
|
|
268
|
+
if (key.upArrow || input === "k") setStart((s) => Math.max(0, s - 1));
|
|
269
|
+
if (input === " " || key.pageDown || input === "f")
|
|
270
|
+
setStart((s) => Math.min(maxStart, s + height));
|
|
271
|
+
if (key.pageUp || input === "b") setStart((s) => Math.max(0, s - height));
|
|
272
|
+
if (input === "g") setStart(0);
|
|
273
|
+
if (input === "G") setStart(maxStart);
|
|
274
|
+
});
|
|
275
|
+
const visible = lines.slice(clamped, clamped + height);
|
|
276
|
+
const hasMore = lines.length > height;
|
|
277
|
+
const atEnd = clamped >= maxStart;
|
|
278
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
279
|
+
/* @__PURE__ */ jsx(Box, { ref, flexDirection: "column", flexGrow: 1, overflow: "hidden", children: visible.map(
|
|
280
|
+
(l, i) => l.spans ? /* @__PURE__ */ jsxs(Text, { wrap: "truncate-end", children: [
|
|
281
|
+
l.spans.map((s, j) => /* @__PURE__ */ jsx(
|
|
282
|
+
Text,
|
|
283
|
+
{
|
|
284
|
+
color: s.color,
|
|
285
|
+
bold: s.bold,
|
|
286
|
+
dimColor: s.dim,
|
|
287
|
+
italic: s.italic,
|
|
288
|
+
children: s.text
|
|
289
|
+
},
|
|
290
|
+
j
|
|
291
|
+
)),
|
|
292
|
+
l.spans.length === 0 ? " " : ""
|
|
293
|
+
] }, i) : /* @__PURE__ */ jsx(
|
|
294
|
+
Text,
|
|
295
|
+
{
|
|
296
|
+
color: l.color,
|
|
297
|
+
bold: l.bold,
|
|
298
|
+
dimColor: l.dim,
|
|
299
|
+
wrap: "truncate-end",
|
|
300
|
+
children: l.text || " "
|
|
301
|
+
},
|
|
302
|
+
i
|
|
303
|
+
)
|
|
304
|
+
) }),
|
|
305
|
+
showIndicator && hasMore && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${clamped + 1}\u2013${clamped + visible.length} / ${lines.length}` + (atEnd ? " (end)" : " \u2193 j/space") })
|
|
306
|
+
] });
|
|
307
|
+
};
|
|
308
|
+
var Tabs = ({ active, items }) => {
|
|
309
|
+
const cells = items.map((item) => ({
|
|
310
|
+
key: item.value,
|
|
311
|
+
text: item.count !== void 0 ? `${item.label} (${item.count})` : item.label,
|
|
312
|
+
isActive: item.value === active
|
|
313
|
+
}));
|
|
314
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
315
|
+
/* @__PURE__ */ jsx(Box, { gap: 2, children: cells.map((cell) => /* @__PURE__ */ jsx(
|
|
316
|
+
Text,
|
|
317
|
+
{
|
|
318
|
+
bold: cell.isActive,
|
|
319
|
+
color: cell.isActive ? colors.accent : void 0,
|
|
320
|
+
dimColor: !cell.isActive,
|
|
321
|
+
children: cell.text
|
|
322
|
+
},
|
|
323
|
+
cell.key
|
|
324
|
+
)) }),
|
|
325
|
+
/* @__PURE__ */ jsx(Box, { gap: 2, children: cells.map((cell) => /* @__PURE__ */ jsx(Text, { color: colors.accent, children: cell.isActive ? "\u2500".repeat(cell.text.length) : " ".repeat(cell.text.length) }, cell.key)) })
|
|
326
|
+
] });
|
|
327
|
+
};
|
|
328
|
+
var ProgressBar = ({ value, width = 20 }) => {
|
|
329
|
+
const clamped = Math.max(0, Math.min(100, value));
|
|
330
|
+
const filled = Math.round(clamped / 100 * width);
|
|
331
|
+
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
332
|
+
/* @__PURE__ */ jsx(Text, { color: colors.accent, children: "\u2588".repeat(filled) }),
|
|
333
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2591".repeat(width - filled) })
|
|
334
|
+
] });
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
// src/components/status-variants.ts
|
|
338
|
+
var STATUS_VARIANTS = {
|
|
339
|
+
success: { icon: "\u2713", color: colors.success },
|
|
340
|
+
error: { icon: "\u2717", color: colors.error },
|
|
341
|
+
warning: { icon: "\u26A0", color: colors.warning },
|
|
342
|
+
info: { icon: "\u2139", color: colors.info }
|
|
343
|
+
};
|
|
344
|
+
var StatusMessage = ({
|
|
345
|
+
variant = "info",
|
|
346
|
+
children
|
|
347
|
+
}) => {
|
|
348
|
+
const { icon, color } = STATUS_VARIANTS[variant];
|
|
349
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
350
|
+
/* @__PURE__ */ jsx(Text, { color, children: icon }),
|
|
351
|
+
/* @__PURE__ */ jsx(Text, { children })
|
|
352
|
+
] });
|
|
353
|
+
};
|
|
354
|
+
var Alert = ({ variant = "info", title, children }) => {
|
|
355
|
+
const { icon, color } = STATUS_VARIANTS[variant];
|
|
356
|
+
return /* @__PURE__ */ jsxs(
|
|
357
|
+
Box,
|
|
358
|
+
{
|
|
359
|
+
borderStyle: "round",
|
|
360
|
+
borderColor: color,
|
|
361
|
+
paddingX: 1,
|
|
362
|
+
flexDirection: "column",
|
|
363
|
+
children: [
|
|
364
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
365
|
+
/* @__PURE__ */ jsx(Text, { color, children: icon }),
|
|
366
|
+
title ? /* @__PURE__ */ jsx(Text, { bold: true, color, children: title }) : null
|
|
367
|
+
] }),
|
|
368
|
+
/* @__PURE__ */ jsx(Text, { children })
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
};
|
|
373
|
+
var Toast = ({
|
|
374
|
+
message,
|
|
375
|
+
variant = "info",
|
|
376
|
+
duration = 2e3,
|
|
377
|
+
onDone
|
|
378
|
+
}) => {
|
|
379
|
+
const [visible, setVisible] = useState(true);
|
|
380
|
+
useEffect(() => {
|
|
381
|
+
const timer = setTimeout(() => {
|
|
382
|
+
setVisible(false);
|
|
383
|
+
onDone?.();
|
|
384
|
+
}, duration);
|
|
385
|
+
return () => clearTimeout(timer);
|
|
386
|
+
}, [duration]);
|
|
387
|
+
if (!visible) return null;
|
|
388
|
+
const { icon, color } = STATUS_VARIANTS[variant];
|
|
389
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
390
|
+
/* @__PURE__ */ jsx(Text, { color, children: icon }),
|
|
391
|
+
/* @__PURE__ */ jsx(Text, { children: message })
|
|
392
|
+
] });
|
|
393
|
+
};
|
|
394
|
+
var escape = (value) => value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
395
|
+
var buildAppleScript = (message, options = {}) => {
|
|
396
|
+
const clauses = [
|
|
397
|
+
options.title && `title "${escape(options.title)}"`,
|
|
398
|
+
options.subtitle && `subtitle "${escape(options.subtitle)}"`,
|
|
399
|
+
options.sound && `sound name "${escape(typeof options.sound === "string" ? options.sound : "default")}"`
|
|
400
|
+
].filter(Boolean);
|
|
401
|
+
const suffix = clauses.length > 0 ? ` with ${clauses.join(" ")}` : "";
|
|
402
|
+
return `display notification "${escape(message)}"${suffix}`;
|
|
403
|
+
};
|
|
404
|
+
var notify = (message, options = {}) => {
|
|
405
|
+
if (process.platform !== "darwin") return;
|
|
406
|
+
const child = spawn("osascript", ["-e", buildAppleScript(message, options)], {
|
|
407
|
+
stdio: "ignore"
|
|
408
|
+
});
|
|
409
|
+
child.on("error", () => {
|
|
410
|
+
});
|
|
411
|
+
child.unref();
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
export { Alert, Badge, Banner, ConfirmInput, FooterHints, Header, KeyValue, LoadingScreen, MultiSelect, ProgressBar, ScrollView, Select, SelectableRow, Spinner, StatusMessage, Table, Tabs, TextInput, Toast, colors, notify, spacing };
|
package/package.json
CHANGED
|
@@ -1,35 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/ink-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "React component library for Ink CLIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20"
|
|
19
|
+
},
|
|
17
20
|
"scripts": {
|
|
18
|
-
"build": "
|
|
19
|
-
"dev": "
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"dev": "tsup --watch",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest"
|
|
20
26
|
},
|
|
21
27
|
"peerDependencies": {
|
|
22
|
-
"ink": ">=
|
|
23
|
-
"react": ">=
|
|
28
|
+
"ink": ">=7",
|
|
29
|
+
"react": ">=19"
|
|
24
30
|
},
|
|
25
31
|
"dependencies": {
|
|
26
|
-
"
|
|
32
|
+
"cli-spinners": "3.4.0",
|
|
33
|
+
"figures": "6.1.0"
|
|
27
34
|
},
|
|
28
35
|
"devDependencies": {
|
|
29
|
-
"@types/
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
36
|
+
"@types/node": "22.20.1",
|
|
37
|
+
"@types/react": "19.2.17",
|
|
38
|
+
"ink": "7.1.0",
|
|
39
|
+
"ink-testing-library": "4.0.0",
|
|
40
|
+
"react": "19.2.7",
|
|
41
|
+
"react-devtools-core": "7.0.1",
|
|
42
|
+
"tsup": "8.5.1",
|
|
43
|
+
"typescript": "5.9.3",
|
|
44
|
+
"vitest": "4.1.10"
|
|
33
45
|
},
|
|
34
46
|
"keywords": [
|
|
35
47
|
"ink",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export type BadgeVariant = "success" | "error" | "warning" | "info";
|
|
2
|
-
type BadgeProps = {
|
|
3
|
-
children: string;
|
|
4
|
-
variant?: BadgeVariant;
|
|
5
|
-
};
|
|
6
|
-
export declare const Badge: ({ children, variant }: BadgeProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=Badge.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/components/Badge.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAEnE,KAAK,UAAU,GAAG;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB,CAAA;AASD,eAAO,MAAM,KAAK,GAAI,uBAAgC,UAAU,4CAE/D,CAAA"}
|
package/dist/components/Badge.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Text } from "ink";
|
|
3
|
-
import { colors } from "../tokens.js";
|
|
4
|
-
const variantColor = {
|
|
5
|
-
success: colors.success,
|
|
6
|
-
error: colors.error,
|
|
7
|
-
warning: colors.warning,
|
|
8
|
-
info: colors.info,
|
|
9
|
-
};
|
|
10
|
-
export const Badge = ({ children, variant = "info" }) => (_jsxs(Text, { color: variantColor[variant], children: ["[", children, "]"] }));
|
|
11
|
-
//# sourceMappingURL=Badge.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.js","sourceRoot":"","sources":["../../src/components/Badge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AASrC,MAAM,YAAY,GAAiC;IACjD,OAAO,EAAE,MAAM,CAAC,OAAO;IACvB,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,OAAO,EAAE,MAAM,CAAC,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC,IAAI;CAClB,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAc,EAAE,EAAE,CAAC,CACnE,MAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,kBAAI,QAAQ,SAAS,CACxD,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../src/components/Banner.tsx"],"names":[],"mappings":"AAIA,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,2BAAiC,WAAW,4CAMlE,CAAA"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
import { colors } from "../tokens.js";
|
|
4
|
-
export const Banner = ({ title, subtitle, icon = "◆" }) => (_jsxs(Box, { gap: 1, marginBottom: 1, children: [_jsx(Text, { color: colors.accent, children: icon }), _jsx(Text, { bold: true, children: title }), subtitle && _jsx(Text, { dimColor: true, children: subtitle })] }));
|
|
5
|
-
//# sourceMappingURL=Banner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Banner.js","sourceRoot":"","sources":["../../src/components/Banner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAQrC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,GAAG,EAAe,EAAE,EAAE,CAAC,CACtE,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,aAC1B,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,YAAG,IAAI,GAAQ,EACzC,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACxB,QAAQ,IAAI,KAAC,IAAI,IAAC,QAAQ,kBAAE,QAAQ,GAAQ,IACzC,CACP,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/components/Header.tsx"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,wBAAwB,WAAW,4CAOzD,CAAA"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
export const Header = ({ children, subtitle }) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, underline: true, children: children }), subtitle && _jsx(Text, { dimColor: true, children: subtitle })] }));
|
|
4
|
-
//# sourceMappingURL=Header.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Header.js","sourceRoot":"","sources":["../../src/components/Header.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAO/B,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAe,EAAE,EAAE,CAAC,CAC7D,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aACzC,KAAC,IAAI,IAAC,IAAI,QAAC,SAAS,kBACjB,QAAQ,GACJ,EACN,QAAQ,IAAI,KAAC,IAAI,IAAC,QAAQ,kBAAE,QAAQ,GAAQ,IACzC,CACP,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/components/Spinner.tsx"],"names":[],"mappings":"AAKA,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,eAAO,MAAM,OAAO,GAAI,WAAW,YAAY,4CAO9C,CAAA"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
import InkSpinner from "ink-spinner";
|
|
4
|
-
import { colors } from "../tokens.js";
|
|
5
|
-
export const Spinner = ({ label }) => (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: colors.accent, children: _jsx(InkSpinner, { type: "dots" }) }), label && _jsx(Text, { dimColor: true, children: label })] }));
|
|
6
|
-
//# sourceMappingURL=Spinner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../src/components/Spinner.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,UAAU,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAMrC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,EAAgB,EAAE,EAAE,CAAC,CAClD,MAAC,GAAG,IAAC,GAAG,EAAE,CAAC,aACT,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,YACxB,KAAC,UAAU,IAAC,IAAI,EAAC,MAAM,GAAG,GACrB,EACN,KAAK,IAAI,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,IACnC,CACP,CAAA"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export type Column<T extends Record<string, unknown>> = {
|
|
2
|
-
key: keyof T & string;
|
|
3
|
-
header: string;
|
|
4
|
-
width?: number;
|
|
5
|
-
};
|
|
6
|
-
type TableProps<T extends Record<string, unknown>> = {
|
|
7
|
-
data: T[];
|
|
8
|
-
columns: Column<T>[];
|
|
9
|
-
};
|
|
10
|
-
export declare const Table: <T extends Record<string, unknown>>({ data, columns, }: TableProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
-
export {};
|
|
12
|
-
//# sourceMappingURL=Table.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/components/Table.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACtD,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACnD,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,oBAGtD,UAAU,CAAC,CAAC,CAAC,4CAqBf,CAAA"}
|
package/dist/components/Table.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
import { colors } from "../tokens.js";
|
|
4
|
-
export const Table = ({ data, columns, }) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { gap: 2, children: columns.map((col) => (_jsx(Box, { width: col.width, minWidth: col.width, children: _jsx(Text, { bold: true, color: colors.muted, children: col.header }) }, col.key))) }), data.map((row, i) => (_jsx(Box, { gap: 2, children: columns.map((col) => (_jsx(Box, { width: col.width, minWidth: col.width, children: _jsx(Text, { wrap: "truncate-end", children: String(row[col.key] ?? "") }) }, col.key))) }, i)))] }));
|
|
5
|
-
//# sourceMappingURL=Table.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../src/components/Table.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAarC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAoC,EACvD,IAAI,EACJ,OAAO,GACO,EAAE,EAAE,CAAC,CACnB,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,GAAG,IAAC,GAAG,EAAE,CAAC,YACR,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,KAAC,GAAG,IAAe,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,YACtD,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,MAAM,CAAC,KAAK,YAC3B,GAAG,CAAC,MAAM,GACN,IAHC,GAAG,CAAC,GAAG,CAIX,CACP,CAAC,GACE,EACL,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,KAAC,GAAG,IAAS,GAAG,EAAE,CAAC,YAChB,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,KAAC,GAAG,IAAe,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,YACtD,KAAC,IAAI,IAAC,IAAI,EAAC,cAAc,YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAQ,IADrD,GAAG,CAAC,GAAG,CAEX,CACP,CAAC,IALM,CAAC,CAML,CACP,CAAC,IACE,CACP,CAAA"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAC7C,YAAY,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAE7C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAE7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/tokens.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare const colors: {
|
|
2
|
-
readonly accent: "#FF8C00";
|
|
3
|
-
readonly muted: "gray";
|
|
4
|
-
readonly success: "green";
|
|
5
|
-
readonly error: "red";
|
|
6
|
-
readonly warning: "yellow";
|
|
7
|
-
readonly info: "cyan";
|
|
8
|
-
};
|
|
9
|
-
export type Color = (typeof colors)[keyof typeof colors];
|
|
10
|
-
export declare const spacing: {
|
|
11
|
-
readonly xs: 1;
|
|
12
|
-
readonly sm: 2;
|
|
13
|
-
readonly md: 3;
|
|
14
|
-
readonly lg: 4;
|
|
15
|
-
};
|
|
16
|
-
export type Spacing = (typeof spacing)[keyof typeof spacing];
|
|
17
|
-
//# sourceMappingURL=tokens.d.ts.map
|
package/dist/tokens.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM;;;;;;;CAOT,CAAA;AAEV,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,MAAM,CAAC,CAAA;AAExD,eAAO,MAAM,OAAO;;;;;CAKV,CAAA;AAEV,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAA"}
|
package/dist/tokens.js
DELETED
package/dist/tokens.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,MAAM;CACJ,CAAA;AAIV,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;IACL,EAAE,EAAE,CAAC;CACG,CAAA"}
|