@kud/ink-ui 0.14.1 → 0.15.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/dist/index.d.ts +11 -2
- package/dist/index.js +94 -6
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -26,16 +26,25 @@ type SpinnerProps = {
|
|
|
26
26
|
};
|
|
27
27
|
declare const Spinner: ({ label }: SpinnerProps) => React__default.JSX.Element;
|
|
28
28
|
|
|
29
|
+
type ColumnAlign = "left" | "center" | "right";
|
|
30
|
+
type ColumnOverflow = "wrap" | "truncate";
|
|
31
|
+
|
|
29
32
|
type Column<T extends Record<string, unknown>> = {
|
|
30
33
|
key: keyof T & string;
|
|
31
34
|
header: string;
|
|
32
35
|
width?: number;
|
|
36
|
+
minWidth?: number;
|
|
37
|
+
align?: ColumnAlign;
|
|
38
|
+
overflow?: ColumnOverflow;
|
|
33
39
|
};
|
|
34
40
|
type TableProps<T extends Record<string, unknown>> = {
|
|
35
41
|
data: T[];
|
|
36
42
|
columns: Column<T>[];
|
|
43
|
+
gap?: number;
|
|
44
|
+
maxWidth?: number;
|
|
45
|
+
headerColor?: string;
|
|
37
46
|
};
|
|
38
|
-
declare const Table: <T extends Record<string, unknown>>({ data, columns, }: TableProps<T>) => React__default.JSX.Element;
|
|
47
|
+
declare const Table: <T extends Record<string, unknown>>({ data, columns, gap, maxWidth, headerColor, }: TableProps<T>) => React__default.JSX.Element;
|
|
39
48
|
|
|
40
49
|
type Hint = [key: string, label: string];
|
|
41
50
|
type FooterHintsProps = {
|
|
@@ -312,4 +321,4 @@ declare const spacing: {
|
|
|
312
321
|
};
|
|
313
322
|
type Spacing = (typeof spacing)[keyof typeof spacing];
|
|
314
323
|
|
|
315
|
-
export { Alert, Badge, type BadgeVariant, Banner, type Color, type Column, Columns, ConfirmInput, EmailInput, FooterHints, Header, type Hint, type IconMode, KeyValue, LoadingScreen, MultiSelect, type NotifyOptions, OrderedList, Panel, PasswordInput, ProgressBar, ScrollView, Select, type SelectOption, SelectableRow, type Spacing, type Span, Spinner, StatusMessage, type StatusVariant, type StyledLine, Switch, type SwitchValue, type TabItem, Table, Tabs, TextInput, Toast, Toggle, ToggleSwitch, UnorderedList, UpdateBanner, colors, getIconMode, notify, setIconMode, spacing, useListCursor, useTabs };
|
|
324
|
+
export { Alert, Badge, type BadgeVariant, Banner, type Color, type Column, type ColumnAlign, type ColumnOverflow, Columns, ConfirmInput, EmailInput, FooterHints, Header, type Hint, type IconMode, KeyValue, LoadingScreen, MultiSelect, type NotifyOptions, OrderedList, Panel, PasswordInput, ProgressBar, ScrollView, Select, type SelectOption, SelectableRow, type Spacing, type Span, Spinner, StatusMessage, type StatusVariant, type StyledLine, Switch, type SwitchValue, type TabItem, Table, Tabs, TextInput, Toast, Toggle, ToggleSwitch, UnorderedList, UpdateBanner, colors, getIconMode, notify, setIconMode, spacing, useListCursor, useTabs };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Box, Text, useInput, measureElement } from 'ink';
|
|
1
|
+
import { Box, Text, useStdout, useInput, measureElement } from 'ink';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import React8, { createContext, useContext, useState, useEffect, useRef, useLayoutEffect } from 'react';
|
|
4
4
|
import cliSpinners from 'cli-spinners';
|
|
5
|
+
import stringWidth from 'string-width';
|
|
5
6
|
import { glyphs } from '@kud/glyphs';
|
|
6
7
|
import { spawn } from 'child_process';
|
|
7
8
|
|
|
@@ -56,13 +57,100 @@ var Spinner = ({ label }) => {
|
|
|
56
57
|
label && /* @__PURE__ */ jsx(Text, { dimColor: true, children: label })
|
|
57
58
|
] });
|
|
58
59
|
};
|
|
60
|
+
var DEFAULT_MIN_WIDTH = 3;
|
|
61
|
+
var widestLine = (value) => value.split("\n").reduce((widest, line) => Math.max(widest, stringWidth(line)), 0);
|
|
62
|
+
var naturalWidth = (column, cells) => cells.reduce(
|
|
63
|
+
(widest, cell) => Math.max(widest, widestLine(cell)),
|
|
64
|
+
widestLine(column.header)
|
|
65
|
+
);
|
|
66
|
+
var floorFor = (column, width) => column.width !== void 0 ? width : Math.min(width, column.minWidth ?? DEFAULT_MIN_WIDTH);
|
|
67
|
+
var widestShrinkable = (widths, floors) => widths.reduce(
|
|
68
|
+
(best, width, index) => width > floors[index] && (best === -1 || width > widths[best]) ? index : best,
|
|
69
|
+
-1
|
|
70
|
+
);
|
|
71
|
+
var shrinkToFit = (widths, floors, excess) => {
|
|
72
|
+
const shrunk = [...widths];
|
|
73
|
+
let remaining = excess;
|
|
74
|
+
while (remaining > 0) {
|
|
75
|
+
const target = widestShrinkable(shrunk, floors);
|
|
76
|
+
if (target === -1) break;
|
|
77
|
+
shrunk[target] = shrunk[target] - 1;
|
|
78
|
+
remaining -= 1;
|
|
79
|
+
}
|
|
80
|
+
return shrunk;
|
|
81
|
+
};
|
|
82
|
+
var resolveColumnWidths = ({
|
|
83
|
+
columns,
|
|
84
|
+
rows,
|
|
85
|
+
gap,
|
|
86
|
+
maxWidth
|
|
87
|
+
}) => {
|
|
88
|
+
const widths = columns.map(
|
|
89
|
+
(column, index) => column.width ?? naturalWidth(
|
|
90
|
+
column,
|
|
91
|
+
rows.map((row) => row[index] ?? "")
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
const gaps = gap * Math.max(columns.length - 1, 0);
|
|
95
|
+
const excess = widths.reduce((total, width) => total + width, gaps) - maxWidth;
|
|
96
|
+
return excess > 0 ? shrinkToFit(
|
|
97
|
+
widths,
|
|
98
|
+
columns.map((column, index) => floorFor(column, widths[index])),
|
|
99
|
+
excess
|
|
100
|
+
) : widths;
|
|
101
|
+
};
|
|
102
|
+
var FALLBACK_TERMINAL_WIDTH = 80;
|
|
103
|
+
var justification = {
|
|
104
|
+
left: "flex-start",
|
|
105
|
+
center: "center",
|
|
106
|
+
right: "flex-end"
|
|
107
|
+
};
|
|
108
|
+
var cellText = (value) => String(value ?? "");
|
|
59
109
|
var Table = ({
|
|
60
110
|
data,
|
|
61
|
-
columns
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
111
|
+
columns,
|
|
112
|
+
gap = 2,
|
|
113
|
+
maxWidth,
|
|
114
|
+
headerColor = colors.muted
|
|
115
|
+
}) => {
|
|
116
|
+
const { stdout } = useStdout();
|
|
117
|
+
const rows = data.map(
|
|
118
|
+
(row) => columns.map((column) => cellText(row[column.key]))
|
|
119
|
+
);
|
|
120
|
+
const widths = resolveColumnWidths({
|
|
121
|
+
columns,
|
|
122
|
+
rows,
|
|
123
|
+
gap,
|
|
124
|
+
maxWidth: maxWidth ?? stdout?.columns ?? FALLBACK_TERMINAL_WIDTH
|
|
125
|
+
});
|
|
126
|
+
const cell = (column, index, content) => /* @__PURE__ */ jsx(
|
|
127
|
+
Box,
|
|
128
|
+
{
|
|
129
|
+
width: widths[index],
|
|
130
|
+
flexShrink: 0,
|
|
131
|
+
flexGrow: 0,
|
|
132
|
+
justifyContent: justification[column.align ?? "left"],
|
|
133
|
+
children: content
|
|
134
|
+
},
|
|
135
|
+
column.key
|
|
136
|
+
);
|
|
137
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
138
|
+
/* @__PURE__ */ jsx(Box, { gap, children: columns.map(
|
|
139
|
+
(column, index) => cell(
|
|
140
|
+
column,
|
|
141
|
+
index,
|
|
142
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: headerColor, wrap: "truncate-end", children: column.header })
|
|
143
|
+
)
|
|
144
|
+
) }),
|
|
145
|
+
rows.map((cells, rowIndex) => /* @__PURE__ */ jsx(Box, { gap, children: columns.map(
|
|
146
|
+
(column, index) => cell(
|
|
147
|
+
column,
|
|
148
|
+
index,
|
|
149
|
+
/* @__PURE__ */ jsx(Text, { wrap: column.overflow === "wrap" ? "wrap" : "truncate-end", children: cells[index] })
|
|
150
|
+
)
|
|
151
|
+
) }, rowIndex))
|
|
152
|
+
] });
|
|
153
|
+
};
|
|
66
154
|
var FooterHints = ({ hints }) => /* @__PURE__ */ jsx(Box, { columnGap: 2, rowGap: 0, flexWrap: "wrap", children: hints.map(([key, label]) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
67
155
|
/* @__PURE__ */ jsx(Text, { color: "white", children: key }),
|
|
68
156
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " + label })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/ink-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "React component library for Ink CLIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@kud/glyphs": "0.1.1",
|
|
34
34
|
"cli-spinners": "3.4.0",
|
|
35
|
-
"figures": "6.1.0"
|
|
35
|
+
"figures": "6.1.0",
|
|
36
|
+
"string-width": "8.2.2"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@types/node": "22.20.1",
|