@kud/ink-ui 0.7.0 → 0.8.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 +36 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +21 -14
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -13,11 +13,18 @@
|
|
|
13
13
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
16
|
-
- **
|
|
16
|
+
- **25 ready-made components**, pre-styled and ready to drop in:
|
|
17
|
+
- **Inputs** — `TextInput`, `EmailInput` (domain completion), `PasswordInput` (masked), `ConfirmInput`
|
|
18
|
+
- **Lists** — `UnorderedList`, `OrderedList` (both nestable), `Table`
|
|
19
|
+
- **Selection & navigation** — `Select`, `MultiSelect`, `Tabs`, `Switch`, `Toggle`, `SelectableRow`
|
|
20
|
+
- **Status & feedback** — `Spinner`, `ProgressBar`, `StatusMessage`, `Alert`, `Badge`, `Toast`
|
|
21
|
+
- **Layout & chrome** — `Banner`, `Header`, `FooterHints`, `KeyValue`, `LoadingScreen`, `ScrollView`
|
|
22
|
+
- **Full [@inkjs/ui](https://github.com/vadimdemedes/ink-ui) parity** — every upstream component has an equivalent, plus a dozen more the design system adds on top
|
|
23
|
+
- **Colourblind-safe by design** — state is signalled by shape, case, and glyph, never colour alone
|
|
17
24
|
- **Design tokens included** — a shared colour palette (`colors`) and spacing scale (`spacing`) to keep every screen consistent
|
|
18
25
|
- **Full TypeScript support** — ships compiled output with `.d.ts` declarations for every component and token type
|
|
19
26
|
- **ESM only, zero config** — no runtime bundling step; just import and render
|
|
20
|
-
- **Peer-dependency light** — only requires `ink ≥
|
|
27
|
+
- **Peer-dependency light** — only requires `ink ≥ 7` and `react ≥ 19`
|
|
21
28
|
|
|
22
29
|
## Install
|
|
23
30
|
|
|
@@ -50,6 +57,33 @@ const App = () => (
|
|
|
50
57
|
render(<App />)
|
|
51
58
|
```
|
|
52
59
|
|
|
60
|
+
Inputs report their value through `onChange`/`onSubmit`, and lists nest with a shape-distinct marker per level:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { Text } from "ink"
|
|
64
|
+
import { EmailInput, PasswordInput, UnorderedList } from "@kud/ink-ui"
|
|
65
|
+
|
|
66
|
+
const SignUp = () => (
|
|
67
|
+
<>
|
|
68
|
+
<EmailInput placeholder="you@example.com" onSubmit={setEmail} />
|
|
69
|
+
<PasswordInput placeholder="Password" onSubmit={setPassword} />
|
|
70
|
+
<UnorderedList>
|
|
71
|
+
<UnorderedList.Item>
|
|
72
|
+
<Text>Choose a plan</Text>
|
|
73
|
+
<UnorderedList>
|
|
74
|
+
<UnorderedList.Item>
|
|
75
|
+
<Text>Free</Text>
|
|
76
|
+
</UnorderedList.Item>
|
|
77
|
+
<UnorderedList.Item>
|
|
78
|
+
<Text>Pro</Text>
|
|
79
|
+
</UnorderedList.Item>
|
|
80
|
+
</UnorderedList>
|
|
81
|
+
</UnorderedList.Item>
|
|
82
|
+
</UnorderedList>
|
|
83
|
+
</>
|
|
84
|
+
)
|
|
85
|
+
```
|
|
86
|
+
|
|
53
87
|
All components accept only the props they need — no theme provider or context required. Design tokens are plain objects:
|
|
54
88
|
|
|
55
89
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -160,8 +160,9 @@ type ScrollViewProps = {
|
|
|
160
160
|
lines: StyledLine[];
|
|
161
161
|
showIndicator?: boolean;
|
|
162
162
|
initialStart?: number;
|
|
163
|
+
isActive?: boolean;
|
|
163
164
|
};
|
|
164
|
-
declare const ScrollView: ({ lines, showIndicator, initialStart, }: ScrollViewProps) => React.JSX.Element;
|
|
165
|
+
declare const ScrollView: ({ lines, showIndicator, initialStart, isActive, }: ScrollViewProps) => React.JSX.Element;
|
|
165
166
|
|
|
166
167
|
type TabItem<T extends string = string> = {
|
|
167
168
|
value: T;
|
package/dist/index.js
CHANGED
|
@@ -115,7 +115,10 @@ var Select = ({
|
|
|
115
115
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
116
116
|
visible.map((option, i) => {
|
|
117
117
|
const active = start + i === cursor;
|
|
118
|
-
return /* @__PURE__ */
|
|
118
|
+
return /* @__PURE__ */ jsxs(SelectableRow, { active, children: [
|
|
119
|
+
/* @__PURE__ */ jsx(Text, { bold: active, color: active ? colors.info : void 0, children: option.label }),
|
|
120
|
+
active ? /* @__PURE__ */ jsx(Text, { color: colors.success, children: " \u2713" }) : null
|
|
121
|
+
] }, option.value);
|
|
119
122
|
}),
|
|
120
123
|
options.length > count && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2026 ${options.length} total` })
|
|
121
124
|
] });
|
|
@@ -159,8 +162,8 @@ var MultiSelect = ({
|
|
|
159
162
|
const active = start + i === cursor;
|
|
160
163
|
const on = selected.has(option.value);
|
|
161
164
|
return /* @__PURE__ */ jsxs(SelectableRow, { active, children: [
|
|
162
|
-
/* @__PURE__ */ jsx(Text, { color:
|
|
163
|
-
/* @__PURE__ */ jsx(Text, {
|
|
165
|
+
/* @__PURE__ */ jsx(Text, { bold: active, color: active ? colors.info : void 0, children: option.label }),
|
|
166
|
+
on ? /* @__PURE__ */ jsx(Text, { color: colors.success, children: " \u2713" }) : null
|
|
164
167
|
] }, option.value);
|
|
165
168
|
}),
|
|
166
169
|
options.length > count && /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2026 ${options.length} total` })
|
|
@@ -437,7 +440,8 @@ var OrderedList = Object.assign(OrderedListRoot, {
|
|
|
437
440
|
var ScrollView = ({
|
|
438
441
|
lines,
|
|
439
442
|
showIndicator = true,
|
|
440
|
-
initialStart = 0
|
|
443
|
+
initialStart = 0,
|
|
444
|
+
isActive = true
|
|
441
445
|
}) => {
|
|
442
446
|
const ref = useRef(null);
|
|
443
447
|
const [height, setHeight] = useState(1);
|
|
@@ -450,16 +454,19 @@ var ScrollView = ({
|
|
|
450
454
|
});
|
|
451
455
|
const maxStart = Math.max(0, lines.length - height);
|
|
452
456
|
const clamped = Math.min(start, maxStart);
|
|
453
|
-
useInput(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
457
|
+
useInput(
|
|
458
|
+
(input, key) => {
|
|
459
|
+
if (key.downArrow || input === "j")
|
|
460
|
+
setStart((s) => Math.min(maxStart, s + 1));
|
|
461
|
+
if (key.upArrow || input === "k") setStart((s) => Math.max(0, s - 1));
|
|
462
|
+
if (input === " " || key.pageDown || input === "f")
|
|
463
|
+
setStart((s) => Math.min(maxStart, s + height));
|
|
464
|
+
if (key.pageUp || input === "b") setStart((s) => Math.max(0, s - height));
|
|
465
|
+
if (input === "g") setStart(0);
|
|
466
|
+
if (input === "G") setStart(maxStart);
|
|
467
|
+
},
|
|
468
|
+
{ isActive }
|
|
469
|
+
);
|
|
463
470
|
const visible = lines.slice(clamped, clamped + height);
|
|
464
471
|
const hasMore = lines.length > height;
|
|
465
472
|
const atEnd = clamped >= maxStart;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/ink-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "React component library for Ink CLIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "tsup",
|
|
22
22
|
"dev": "tsup --watch",
|
|
23
|
+
"demo": "tsx src/demo/index.tsx",
|
|
23
24
|
"typecheck": "tsc --noEmit",
|
|
24
25
|
"test": "vitest run",
|
|
25
26
|
"test:watch": "vitest"
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"react": "19.2.7",
|
|
42
43
|
"react-devtools-core": "7.0.1",
|
|
43
44
|
"tsup": "8.5.1",
|
|
45
|
+
"tsx": "4.23.1",
|
|
44
46
|
"typescript": "5.9.3",
|
|
45
47
|
"vitest": "4.1.10"
|
|
46
48
|
},
|