@visulima/tui-kit 0.0.0 → 1.0.1
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/CHANGELOG.md +13 -0
- package/LICENSE.md +2095 -0
- package/README.md +115 -29
- package/dist/accordion.d.ts +52 -0
- package/dist/accordion.js +1 -0
- package/dist/alert.d.ts +22 -0
- package/dist/alert.js +1 -0
- package/dist/animate-presence.d.ts +16 -0
- package/dist/animate-presence.js +1 -0
- package/dist/approval-prompt.d.ts +55 -0
- package/dist/approval-prompt.js +1 -0
- package/dist/area-chart.d.ts +56 -0
- package/dist/area-chart.js +1 -0
- package/dist/badge.d.ts +19 -0
- package/dist/badge.js +1 -0
- package/dist/bar-chart.d.ts +58 -0
- package/dist/bar-chart.js +1 -0
- package/dist/big-text.d.ts +71 -0
- package/dist/big-text.js +1 -0
- package/dist/blink-dot.d.ts +31 -0
- package/dist/blink-dot.js +1 -0
- package/dist/breadcrumb.d.ts +29 -0
- package/dist/breadcrumb.js +1 -0
- package/dist/button.d.ts +38 -0
- package/dist/button.js +1 -0
- package/dist/calendar.d.ts +60 -0
- package/dist/calendar.js +1 -0
- package/dist/card.d.ts +47 -0
- package/dist/card.js +1 -0
- package/dist/checkbox-group.d.ts +50 -0
- package/dist/checkbox-group.js +1 -0
- package/dist/checkbox.d.ts +40 -0
- package/dist/checkbox.js +1 -0
- package/dist/code.d.ts +41 -0
- package/dist/code.js +2 -0
- package/dist/collapsible.d.ts +44 -0
- package/dist/collapsible.js +1 -0
- package/dist/color-picker.d.ts +59 -0
- package/dist/color-picker.js +1 -0
- package/dist/command-block.d.ts +39 -0
- package/dist/command-block.js +4 -0
- package/dist/command-palette.d.ts +73 -0
- package/dist/command-palette.js +1 -0
- package/dist/confirm-dialog.d.ts +63 -0
- package/dist/confirm-dialog.js +1 -0
- package/dist/confirm-input.d.ts +32 -0
- package/dist/confirm-input.js +1 -0
- package/dist/console-overlay.d.ts +47 -0
- package/dist/console-overlay.js +1 -0
- package/dist/content-switcher.d.ts +49 -0
- package/dist/content-switcher.js +1 -0
- package/dist/controlled-scroll-view.d.ts +3 -0
- package/dist/controlled-scroll-view.js +1 -0
- package/dist/data-grid.d.ts +43 -0
- package/dist/data-grid.js +1 -0
- package/dist/date-picker.d.ts +54 -0
- package/dist/date-picker.js +1 -0
- package/dist/definition-list.d.ts +38 -0
- package/dist/definition-list.js +1 -0
- package/dist/dialog.d.ts +94 -0
- package/dist/dialog.js +1 -0
- package/dist/diff-view.d.ts +72 -0
- package/dist/diff-view.js +1 -0
- package/dist/digits.d.ts +26 -0
- package/dist/digits.js +1 -0
- package/dist/directory-tree.d.ts +44 -0
- package/dist/directory-tree.js +1 -0
- package/dist/divider.d.ts +41 -0
- package/dist/divider.js +1 -0
- package/dist/drawer.d.ts +45 -0
- package/dist/drawer.js +1 -0
- package/dist/file-change.d.ts +34 -0
- package/dist/file-change.js +1 -0
- package/dist/file-picker-entry.d.ts +2 -0
- package/dist/file-picker-entry.js +1 -0
- package/dist/form.d.ts +74 -0
- package/dist/form.js +1 -0
- package/dist/gauge.d.ts +76 -0
- package/dist/gauge.js +1 -0
- package/dist/gradient.d.ts +38 -0
- package/dist/gradient.js +1 -0
- package/dist/grid.d.ts +34 -0
- package/dist/grid.js +1 -0
- package/dist/heading.d.ts +28 -0
- package/dist/heading.js +1 -0
- package/dist/heatmap.d.ts +52 -0
- package/dist/heatmap.js +1 -0
- package/dist/help.d.ts +45 -0
- package/dist/help.js +1 -0
- package/dist/histogram.d.ts +52 -0
- package/dist/histogram.js +1 -0
- package/dist/image.d.ts +23 -0
- package/dist/image.js +1 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.js +1 -0
- package/dist/json.d.ts +51 -0
- package/dist/json.js +1 -0
- package/dist/kbd.d.ts +27 -0
- package/dist/kbd.js +1 -0
- package/dist/line-chart.d.ts +100 -0
- package/dist/line-chart.js +1 -0
- package/dist/link.d.ts +34 -0
- package/dist/link.js +1 -0
- package/dist/loading-indicator.d.ts +25 -0
- package/dist/loading-indicator.js +1 -0
- package/dist/log.d.ts +33 -0
- package/dist/log.js +1 -0
- package/dist/markdown.d.ts +35 -0
- package/dist/markdown.js +1 -0
- package/dist/masked-input.d.ts +42 -0
- package/dist/masked-input.js +1 -0
- package/dist/menu.d.ts +70 -0
- package/dist/menu.js +1 -0
- package/dist/message-bubble.d.ts +36 -0
- package/dist/message-bubble.js +1 -0
- package/dist/model-badge.d.ts +33 -0
- package/dist/model-badge.js +1 -0
- package/dist/model-selector.d.ts +45 -0
- package/dist/model-selector.js +1 -0
- package/dist/multi-progress.d.ts +48 -0
- package/dist/multi-progress.js +1 -0
- package/dist/multi-select.d.ts +55 -0
- package/dist/multi-select.js +1 -0
- package/dist/notification-badge.d.ts +40 -0
- package/dist/notification-badge.js +1 -0
- package/dist/number-input.d.ts +71 -0
- package/dist/number-input.js +1 -0
- package/dist/operation-tree.d.ts +46 -0
- package/dist/operation-tree.js +1 -0
- package/dist/option-list.d.ts +41 -0
- package/dist/option-list.js +1 -0
- package/dist/ordered-list.d.ts +22 -0
- package/dist/ordered-list.js +1 -0
- package/dist/packem_shared/ControlledScrollView-BzlbIUph.js +1 -0
- package/dist/packem_shared/FilePicker-V5H2fb-v.js +1 -0
- package/dist/packem_shared/ScrollBar-C9i3z3Ft.js +1 -0
- package/dist/packem_shared/ScrollBarBox-DZEC8YnV.js +1 -0
- package/dist/packem_shared/ScrollList-Djtb2vVy.js +1 -0
- package/dist/packem_shared/ScrollView-ESxpl6Hy.js +1 -0
- package/dist/packem_shared/TreeNodeMap-cJlYqckB.js +1 -0
- package/dist/packem_shared/TreeView-q0l446NV.js +1 -0
- package/dist/packem_shared/controlled-scroll-view-DerVKKv6.js +1 -0
- package/dist/packem_shared/controlled-scroll-view.d-D3kZZzjI.d.ts +43 -0
- package/dist/packem_shared/file-picker.d-CH7pccC7.d.ts +92 -0
- package/dist/packem_shared/line-chart-BbhMhcZg.js +1 -0
- package/dist/packem_shared/scroll-bar-box.d-CpTYEcTZ.d.ts +13 -0
- package/dist/packem_shared/scroll-bar.d-B4sD1hBR.d.ts +18 -0
- package/dist/packem_shared/scroll-list.d-CPCF0RwC.d.ts +12 -0
- package/dist/packem_shared/scroll-view.d-GZcgAHl4.d.ts +98 -0
- package/dist/packem_shared/treeViewTheme-Dq3ekRAC.js +1 -0
- package/dist/packem_shared/use-tree-view.d-DeMQ6G2r.d.ts +314 -0
- package/dist/packem_shared/useTreeView-D0JEqT6W.js +1 -0
- package/dist/packem_shared/useTreeViewState-BiTJakkh.js +1 -0
- package/dist/packem_shared/variant-config-BJqpNo7H.js +1 -0
- package/dist/packem_shared/variant-config.d-D5NnrrQK.d.ts +2 -0
- package/dist/paginator.d.ts +59 -0
- package/dist/paginator.js +1 -0
- package/dist/paragraph.d.ts +32 -0
- package/dist/paragraph.js +1 -0
- package/dist/path-input.d.ts +56 -0
- package/dist/path-input.js +1 -0
- package/dist/pie-chart.d.ts +44 -0
- package/dist/pie-chart.js +1 -0
- package/dist/placeholder.d.ts +47 -0
- package/dist/placeholder.js +1 -0
- package/dist/popover.d.ts +39 -0
- package/dist/popover.js +1 -0
- package/dist/progress-bar.d.ts +43 -0
- package/dist/progress-bar.js +1 -0
- package/dist/progress-circle.d.ts +50 -0
- package/dist/progress-circle.js +1 -0
- package/dist/qr-code.d.ts +39 -0
- package/dist/qr-code.js +1 -0
- package/dist/r/accordion.json +24 -0
- package/dist/r/alert.json +24 -0
- package/dist/r/animate-presence.json +22 -0
- package/dist/r/approval-prompt.json +24 -0
- package/dist/r/area-chart.json +27 -0
- package/dist/r/badge.json +24 -0
- package/dist/r/bar-chart.json +24 -0
- package/dist/r/big-text.json +23 -0
- package/dist/r/blink-dot.json +24 -0
- package/dist/r/breadcrumb.json +24 -0
- package/dist/r/button.json +24 -0
- package/dist/r/calendar.json +24 -0
- package/dist/r/card.json +26 -0
- package/dist/r/chart-utils.json +24 -0
- package/dist/r/checkbox-group.json +24 -0
- package/dist/r/checkbox.json +24 -0
- package/dist/r/code.json +23 -0
- package/dist/r/collapsible.json +24 -0
- package/dist/r/color-picker.json +24 -0
- package/dist/r/command-block.json +26 -0
- package/dist/r/command-palette.json +24 -0
- package/dist/r/confirm-dialog.json +24 -0
- package/dist/r/confirm-input.json +22 -0
- package/dist/r/console-overlay.json +22 -0
- package/dist/r/content-switcher.json +24 -0
- package/dist/r/controlled-scroll-view.json +24 -0
- package/dist/r/data-grid.json +24 -0
- package/dist/r/date-picker.json +26 -0
- package/dist/r/definition-list.json +24 -0
- package/dist/r/dialog.json +24 -0
- package/dist/r/diff-view.json +24 -0
- package/dist/r/digits.json +24 -0
- package/dist/r/directory-tree.json +24 -0
- package/dist/r/divider.json +24 -0
- package/dist/r/drawer.json +24 -0
- package/dist/r/file-change.json +24 -0
- package/dist/r/file-picker.json +44 -0
- package/dist/r/form.json +24 -0
- package/dist/r/gauge.json +24 -0
- package/dist/r/gradient.json +24 -0
- package/dist/r/grid.json +22 -0
- package/dist/r/heading.json +24 -0
- package/dist/r/heatmap.json +24 -0
- package/dist/r/help.json +22 -0
- package/dist/r/histogram.json +26 -0
- package/dist/r/image.json +24 -0
- package/dist/r/json.json +24 -0
- package/dist/r/kbd.json +24 -0
- package/dist/r/line-chart.json +26 -0
- package/dist/r/link.json +23 -0
- package/dist/r/loading-indicator.json +27 -0
- package/dist/r/log.json +24 -0
- package/dist/r/markdown.json +29 -0
- package/dist/r/masked-input.json +22 -0
- package/dist/r/menu.json +24 -0
- package/dist/r/message-bubble.json +24 -0
- package/dist/r/model-badge.json +24 -0
- package/dist/r/model-selector.json +24 -0
- package/dist/r/multi-progress.json +24 -0
- package/dist/r/multi-select.json +24 -0
- package/dist/r/notification-badge.json +24 -0
- package/dist/r/number-input.json +24 -0
- package/dist/r/operation-tree.json +26 -0
- package/dist/r/option-list.json +24 -0
- package/dist/r/ordered-list.json +22 -0
- package/dist/r/paginator.json +22 -0
- package/dist/r/paragraph.json +24 -0
- package/dist/r/path-input.json +26 -0
- package/dist/r/pie-chart.json +24 -0
- package/dist/r/placeholder.json +24 -0
- package/dist/r/popover.json +24 -0
- package/dist/r/progress-bar.json +22 -0
- package/dist/r/progress-circle.json +24 -0
- package/dist/r/qr-code.json +24 -0
- package/dist/r/radio-group.json +24 -0
- package/dist/r/registry.json +1051 -0
- package/dist/r/scatter-plot.json +27 -0
- package/dist/r/scroll-bar-box.json +24 -0
- package/dist/r/scroll-bar.json +24 -0
- package/dist/r/scroll-list.json +24 -0
- package/dist/r/scroll-view.json +24 -0
- package/dist/r/scroll.json +58 -0
- package/dist/r/search-input.json +26 -0
- package/dist/r/select-input-indicator.json +24 -0
- package/dist/r/select-input-item.json +24 -0
- package/dist/r/select-input.json +28 -0
- package/dist/r/shimmer-text.json +24 -0
- package/dist/r/sidebar.json +24 -0
- package/dist/r/slider.json +24 -0
- package/dist/r/sparkline.json +24 -0
- package/dist/r/spinner.json +23 -0
- package/dist/r/status-line.json +24 -0
- package/dist/r/status-message.json +24 -0
- package/dist/r/stepper.json +24 -0
- package/dist/r/stopwatch.json +22 -0
- package/dist/r/streaming-text.json +24 -0
- package/dist/r/switch.json +24 -0
- package/dist/r/tab.json +22 -0
- package/dist/r/table.json +23 -0
- package/dist/r/tabs.json +26 -0
- package/dist/r/tag-input.json +24 -0
- package/dist/r/tag.json +24 -0
- package/dist/r/text-input.json +22 -0
- package/dist/r/textarea.json +22 -0
- package/dist/r/thinking-block.json +24 -0
- package/dist/r/time-picker.json +24 -0
- package/dist/r/timer.json +22 -0
- package/dist/r/toast.json +24 -0
- package/dist/r/token-usage.json +24 -0
- package/dist/r/tool-call.json +24 -0
- package/dist/r/tooltip.json +24 -0
- package/dist/r/transition.json +22 -0
- package/dist/r/tree-select.json +24 -0
- package/dist/r/tree-view.json +64 -0
- package/dist/r/unordered-list.json +22 -0
- package/dist/r/use-linked-scroll.json +24 -0
- package/dist/r/variant-config.json +22 -0
- package/dist/radio-group.d.ts +63 -0
- package/dist/radio-group.js +1 -0
- package/dist/scatter-plot.d.ts +24 -0
- package/dist/scatter-plot.js +1 -0
- package/dist/scroll-bar-box.d.ts +3 -0
- package/dist/scroll-bar-box.js +1 -0
- package/dist/scroll-bar.d.ts +3 -0
- package/dist/scroll-bar.js +1 -0
- package/dist/scroll-list.d.ts +4 -0
- package/dist/scroll-list.js +1 -0
- package/dist/scroll-view.d.ts +3 -0
- package/dist/scroll-view.js +1 -0
- package/dist/search-input.d.ts +46 -0
- package/dist/search-input.js +1 -0
- package/dist/select-input-indicator.d.ts +28 -0
- package/dist/select-input-indicator.js +1 -0
- package/dist/select-input-item.d.ts +35 -0
- package/dist/select-input-item.js +1 -0
- package/dist/select-input.d.ts +97 -0
- package/dist/select-input.js +1 -0
- package/dist/shimmer-text.d.ts +41 -0
- package/dist/shimmer-text.js +1 -0
- package/dist/sidebar.d.ts +40 -0
- package/dist/sidebar.js +1 -0
- package/dist/slider.d.ts +87 -0
- package/dist/slider.js +1 -0
- package/dist/sparkline.d.ts +36 -0
- package/dist/sparkline.js +1 -0
- package/dist/spinner.d.ts +15 -0
- package/dist/spinner.js +1 -0
- package/dist/status-line.d.ts +31 -0
- package/dist/status-line.js +1 -0
- package/dist/status-message.d.ts +18 -0
- package/dist/status-message.js +1 -0
- package/dist/stepper.d.ts +42 -0
- package/dist/stepper.js +1 -0
- package/dist/stopwatch.d.ts +42 -0
- package/dist/stopwatch.js +1 -0
- package/dist/streaming-text.d.ts +39 -0
- package/dist/streaming-text.js +1 -0
- package/dist/switch.d.ts +46 -0
- package/dist/switch.js +1 -0
- package/dist/tab.d.ts +17 -0
- package/dist/tab.js +1 -0
- package/dist/table.d.ts +118 -0
- package/dist/table.js +1 -0
- package/dist/tabs.d.ts +96 -0
- package/dist/tabs.js +1 -0
- package/dist/tag-input.d.ts +59 -0
- package/dist/tag-input.js +1 -0
- package/dist/tag.d.ts +30 -0
- package/dist/tag.js +1 -0
- package/dist/text-input.d.ts +40 -0
- package/dist/text-input.js +1 -0
- package/dist/textarea.d.ts +57 -0
- package/dist/textarea.js +2 -0
- package/dist/thinking-block.d.ts +48 -0
- package/dist/thinking-block.js +1 -0
- package/dist/time-picker.d.ts +57 -0
- package/dist/time-picker.js +1 -0
- package/dist/timer.d.ts +50 -0
- package/dist/timer.js +1 -0
- package/dist/toast.d.ts +41 -0
- package/dist/toast.js +1 -0
- package/dist/token-usage.d.ts +43 -0
- package/dist/token-usage.js +1 -0
- package/dist/tool-call.d.ts +28 -0
- package/dist/tool-call.js +1 -0
- package/dist/tooltip.d.ts +37 -0
- package/dist/tooltip.js +1 -0
- package/dist/transition.d.ts +66 -0
- package/dist/transition.js +1 -0
- package/dist/tree-select.d.ts +55 -0
- package/dist/tree-select.js +1 -0
- package/dist/tree-view-entry.d.ts +4 -0
- package/dist/tree-view-entry.js +1 -0
- package/dist/unordered-list.d.ts +27 -0
- package/dist/unordered-list.js +1 -0
- package/dist/use-linked-scroll.d.ts +42 -0
- package/dist/use-linked-scroll.js +1 -0
- package/package.json +553 -7
package/dist/button.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type ButtonVariant = "ghost" | "outline" | "primary" | "secondary";
|
|
5
|
+
type Props = {
|
|
6
|
+
/**
|
|
7
|
+
* Accent color used when the button is focused.
|
|
8
|
+
* @default "blue"
|
|
9
|
+
*/
|
|
10
|
+
readonly accentColor?: LiteralUnion<AnsiColors, string>;
|
|
11
|
+
/**
|
|
12
|
+
* Focus this button when mounted if nothing else is focused.
|
|
13
|
+
*/
|
|
14
|
+
readonly autoFocus?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Button label.
|
|
17
|
+
*/
|
|
18
|
+
readonly children: ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* When true, the button ignores input and is rendered dim.
|
|
21
|
+
*/
|
|
22
|
+
readonly isDisabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Called when the user presses Enter or Space while the button has focus.
|
|
25
|
+
*/
|
|
26
|
+
readonly onPress?: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Visual style.
|
|
29
|
+
* @default "primary"
|
|
30
|
+
*/
|
|
31
|
+
readonly variant?: ButtonVariant;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Focusable button. Triggers `onPress` on Enter / Space.
|
|
35
|
+
* @returns A `ReactElement` rendering the button (bordered or ghost variant).
|
|
36
|
+
*/
|
|
37
|
+
declare function Button({ accentColor, autoFocus, children, isDisabled, onPress, variant }: Props): ReactElement;
|
|
38
|
+
export { Button, type Props as ButtonProps, ButtonVariant, Props, Button as default };
|
package/dist/button.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as s,jsxs as f}from"react/jsx-runtime";import c from"@visulima/tui/components/box";import e from"@visulima/tui/components/text";import p from"@visulima/tui/hooks/use-focus";import b from"@visulima/tui/hooks/use-input";import{useCallback as g}from"react";const h="round",y=(i,l,n,r)=>{if(!n){if(i==="primary"&&l)return"black";if(l)return r}};function A({accentColor:i="blue",autoFocus:l=!1,children:n,isDisabled:r=!1,onPress:t,variant:d="primary"}){const{isFocused:o}=p({autoFocus:l,isActive:!r});b(g((m,u)=>{o&&(u.return||m===" ")&&t?.()},[o,t]),{isActive:!r&&o});const a=y(d,o,r,i);return d==="ghost"?s(c,{paddingX:1,children:f(e,{bold:o,color:a,dimColor:r,children:[o?"▸ ":" ",n]})}):s(c,{backgroundColor:d==="primary"&&o?i:void 0,borderColor:d==="outline"?o?i:"gray":d==="secondary"||o?i:void 0,borderStyle:h,paddingX:1,children:s(e,{bold:o,color:a,dimColor:r,children:n})})}export{A as Button,A as default};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type Props = {
|
|
5
|
+
/**
|
|
6
|
+
* Accent color for today / the focused cell.
|
|
7
|
+
* @default "blue"
|
|
8
|
+
*/
|
|
9
|
+
readonly accentColor?: LiteralUnion<AnsiColors, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Auto-focus the grid on mount.
|
|
12
|
+
*/
|
|
13
|
+
readonly autoFocus?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Initial focused day when uncontrolled. Defaults to `value` or today.
|
|
16
|
+
*/
|
|
17
|
+
readonly defaultValue?: Date;
|
|
18
|
+
/**
|
|
19
|
+
* First day of the week: 0 = Sunday, 1 = Monday.
|
|
20
|
+
* @default 1
|
|
21
|
+
*/
|
|
22
|
+
readonly firstDayOfWeek?: 0 | 1;
|
|
23
|
+
/**
|
|
24
|
+
* When true, disable input and render the grid dim.
|
|
25
|
+
*/
|
|
26
|
+
readonly isDisabled?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Upper bound; days after `maxDate` cannot be selected.
|
|
29
|
+
*/
|
|
30
|
+
readonly maxDate?: Date;
|
|
31
|
+
/**
|
|
32
|
+
* Lower bound; days before `minDate` cannot be selected.
|
|
33
|
+
*/
|
|
34
|
+
readonly minDate?: Date;
|
|
35
|
+
/**
|
|
36
|
+
* Called whenever the user navigates or selects a day.
|
|
37
|
+
*/
|
|
38
|
+
readonly onChange?: (date: Date) => void;
|
|
39
|
+
/**
|
|
40
|
+
* Called when the user presses Enter.
|
|
41
|
+
*/
|
|
42
|
+
readonly onSubmit?: (date: Date) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Color used to mark the currently selected day.
|
|
45
|
+
* @default "green"
|
|
46
|
+
*/
|
|
47
|
+
readonly selectedColor?: LiteralUnion<AnsiColors, string>;
|
|
48
|
+
/**
|
|
49
|
+
* Controlled selected date.
|
|
50
|
+
*/
|
|
51
|
+
readonly value?: Date;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Month-grid date picker. Arrow keys move focus by one day, page up/down move
|
|
55
|
+
* by month. Enter submits; Space or Enter selects.
|
|
56
|
+
* @returns A bordered `ReactElement` containing the month header, weekday
|
|
57
|
+
* labels, and the day grid.
|
|
58
|
+
*/
|
|
59
|
+
declare function Calendar({ accentColor, autoFocus, defaultValue, firstDayOfWeek, isDisabled, maxDate, minDate, onChange, onSubmit, selectedColor, value }: Props): ReactElement;
|
|
60
|
+
export { Calendar, type Props as CalendarProps, Props, Calendar as default };
|
package/dist/calendar.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as y,jsx as u}from"react/jsx-runtime";import h from"@visulima/tui/components/box";import w from"@visulima/tui/components/text";import W from"@visulima/tui/hooks/use-focus";import I from"@visulima/tui/hooks/use-input";import{useMemo as F,useState as K,useRef as P,useCallback as S}from"react";const X=["January","February","March","April","May","June","July","August","September","October","November","December"],k=["Su","Mo","Tu","We","Th","Fr","Sa"],p=e=>new Date(e.getFullYear(),e.getMonth(),e.getDate()),x=(e,r)=>{const i=e.getFullYear(),l=e.getMonth()+r,g=new Date(i,l+1,0).getDate(),a=Math.min(e.getDate(),g);return new Date(i,l,a)},J=(e,r)=>e.getFullYear()===r.getFullYear()&&e.getMonth()===r.getMonth()&&e.getDate()===r.getDate(),T=(e,r,i)=>r!==void 0&&e<p(r)||i!==void 0&&e>p(i),$=(e,r,i)=>{const l=(new Date(e,r,1).getDay()-i+7)%7,g=new Date(e,r+1,0).getDate(),a=[];for(let o=0;o<l;o+=1)a.push(void 0);for(let o=1;o<=g;o+=1)a.push(new Date(e,r,o));for(;a.length%7!==0;)a.push(void 0);const D=[];for(let o=0;o<a.length;o+=7)D.push(a.slice(o,o+7));return D};function Z({accentColor:e="blue",autoFocus:r=!1,defaultValue:i,firstDayOfWeek:l=1,isDisabled:g=!1,maxDate:a,minDate:D,onChange:o,onSubmit:b,selectedColor:j="green",value:f}){const{isFocused:m}=W({autoFocus:r,isActive:!g}),M=F(()=>p(new Date),[]),O=p(f??i??M),[B,E]=K(O),c=f?p(f):B,v=P(c);v.current=c;const N=F(()=>[...k.slice(l),...k.slice(0,l)],[l]),R=F(()=>$(c.getFullYear(),c.getMonth(),l),[c,l]),d=S(s=>{const n=p(s);T(n,D,a)||(f===void 0&&E(n),o?.(n))},[f,o,D,a]);I(S((s,n)=>{if(!m)return;const{current:t}=v;n.leftArrow?d(new Date(t.getFullYear(),t.getMonth(),t.getDate()-1)):n.rightArrow?d(new Date(t.getFullYear(),t.getMonth(),t.getDate()+1)):n.upArrow?d(new Date(t.getFullYear(),t.getMonth(),t.getDate()-7)):n.downArrow?d(new Date(t.getFullYear(),t.getMonth(),t.getDate()+7)):n.pageUp?d(x(t,-1)):n.pageDown?d(x(t,1)):n.return&&b?.(t)},[m,d,b]),{isActive:!g&&m});const U=`${X[c.getMonth()]} ${c.getFullYear()}`;return y(h,{borderColor:m?e:void 0,borderStyle:"round",flexDirection:"column",paddingX:1,children:[u(h,{justifyContent:"center",children:u(w,{bold:!0,color:e,children:U})}),u(h,{marginTop:1,children:N.map(s=>u(h,{width:3,children:u(w,{dimColor:!0,children:s.padEnd(2," ")})},s))}),R.map((s,n)=>u(h,{children:s.map((t,C)=>{if(t===void 0)return u(h,{width:3,children:u(w,{children:" "})},C);const Y=J(t,M),A=J(t,c),V=T(t,D,a);return u(h,{width:3,children:y(w,{backgroundColor:A&&m?e:void 0,bold:Y,color:A&&m?"black":Y?j:void 0,dimColor:V||g,children:[String(t.getDate()).padStart(2," ")," "]})},C)})},n))]})}export{Z as Calendar,Z as default};
|
package/dist/card.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type Props = {
|
|
5
|
+
/**
|
|
6
|
+
* Border color.
|
|
7
|
+
*/
|
|
8
|
+
readonly borderColor?: LiteralUnion<AnsiColors, string>;
|
|
9
|
+
/**
|
|
10
|
+
* Border style name, passed through to `Box`.
|
|
11
|
+
* @default "round"
|
|
12
|
+
*/
|
|
13
|
+
readonly borderStyle?: "arrow" | "bold" | "classic" | "double" | "doubleSingle" | "round" | "single" | "singleDouble";
|
|
14
|
+
/**
|
|
15
|
+
* Card body.
|
|
16
|
+
*/
|
|
17
|
+
readonly children: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Optional footer rendered below body with a dim divider.
|
|
20
|
+
*/
|
|
21
|
+
readonly footer?: ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* Optional content rendered after the title on the same row.
|
|
24
|
+
*/
|
|
25
|
+
readonly headerRight?: ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Optional subtitle rendered below the title.
|
|
28
|
+
*/
|
|
29
|
+
readonly subtitle?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Optional title rendered in the header area.
|
|
32
|
+
*/
|
|
33
|
+
readonly title?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Color applied to the title.
|
|
36
|
+
*/
|
|
37
|
+
readonly titleColor?: LiteralUnion<AnsiColors, string>;
|
|
38
|
+
/**
|
|
39
|
+
* Fix the card width. When omitted the card grows to fill its parent.
|
|
40
|
+
*/
|
|
41
|
+
readonly width?: number | string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Bordered container with optional title, subtitle, and footer.
|
|
45
|
+
*/
|
|
46
|
+
declare function Card({ borderColor, borderStyle, children, footer, headerRight, subtitle, title, titleColor, width }: Props): ReactElement;
|
|
47
|
+
export { Card, type Props as CardProps, Props, Card as default };
|
package/dist/card.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as r,jsx as i}from"react/jsx-runtime";import o from"@visulima/tui/components/box";import c from"@visulima/tui/components/text";import{Divider as v}from"./divider.js";function x({borderColor:m,borderStyle:h="round",children:f,footer:n,headerRight:e,subtitle:d,title:t,titleColor:u,width:l}){return r(o,{borderColor:m,borderStyle:h,flexDirection:"column",paddingX:1,width:l,children:[t!==void 0||d!==void 0||e!==void 0?r(o,{flexDirection:"column",marginBottom:1,children:[r(o,{justifyContent:"space-between",children:[i(o,{children:t===void 0?void 0:i(c,{bold:!0,color:u,children:t})}),e===void 0?void 0:i(o,{children:e})]}),d===void 0?void 0:i(c,{dimColor:!0,children:d})]}):void 0,i(o,{flexDirection:"column",children:f}),n===void 0?void 0:r(o,{flexDirection:"column",marginTop:1,children:[i(v,{dimColor:!0,length:typeof l=="number"?Math.max(1,l-4):void 0}),i(o,{marginTop:1,children:n})]})]})}export{x as Card,x as default};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type CheckboxOption = {
|
|
5
|
+
readonly description?: string;
|
|
6
|
+
readonly isDisabled?: boolean;
|
|
7
|
+
readonly label: string;
|
|
8
|
+
readonly value: string;
|
|
9
|
+
};
|
|
10
|
+
type Props = {
|
|
11
|
+
/**
|
|
12
|
+
* Accent color for the focused row and checked marks.
|
|
13
|
+
* @default "blue"
|
|
14
|
+
*/
|
|
15
|
+
readonly accentColor?: LiteralUnion<AnsiColors, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Auto-focus on mount.
|
|
18
|
+
*/
|
|
19
|
+
readonly autoFocus?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Checked values when uncontrolled.
|
|
22
|
+
*/
|
|
23
|
+
readonly defaultValue?: ReadonlyArray<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Disable the whole group.
|
|
26
|
+
*/
|
|
27
|
+
readonly isDisabled?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Fires whenever the set of checked values changes.
|
|
30
|
+
*/
|
|
31
|
+
readonly onChange?: (values: ReadonlyArray<string>) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Fires on Enter with the current checked values.
|
|
34
|
+
*/
|
|
35
|
+
readonly onSubmit?: (values: ReadonlyArray<string>) => void;
|
|
36
|
+
/**
|
|
37
|
+
* The options to render.
|
|
38
|
+
*/
|
|
39
|
+
readonly options: ReadonlyArray<CheckboxOption>;
|
|
40
|
+
/**
|
|
41
|
+
* Controlled checked values. When provided, `defaultValue` is ignored.
|
|
42
|
+
*/
|
|
43
|
+
readonly value?: ReadonlyArray<string>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* A vertical list of checkboxes. ↑/↓ move focus, Space toggles the focused
|
|
47
|
+
* option, `a` toggles all, and Enter submits.
|
|
48
|
+
*/
|
|
49
|
+
declare function CheckboxGroup({ accentColor, autoFocus, defaultValue, isDisabled, onChange, onSubmit, options, value: controlledValue }: Props): ReactElement;
|
|
50
|
+
export { CheckboxGroup, type Props as CheckboxGroupProps, CheckboxOption, Props, CheckboxGroup as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as c,jsxs as g}from"react/jsx-runtime";import v from"@visulima/tui/components/box";import h from"@visulima/tui/components/text";import R from"@visulima/tui/hooks/use-focus";import E from"@visulima/tui/hooks/use-input";import{useState as F,useMemo as G,useRef as I,useCallback as j}from"react";const M=[];function k(u,s){return s===0?0:(u%s+s)%s}function K({accentColor:u="blue",autoFocus:s=!1,defaultValue:y=M,isDisabled:p=!1,onChange:b,onSubmit:D,options:t,value:d}){const{isFocused:C}=R({autoFocus:s,isActive:!p}),w=d!==void 0,[x,B]=F(y),n=G(()=>new Set(d??x),[d,x]),[f,A]=F(0),S=I(b);S.current=b;const m=j(r=>{const o=t.map(e=>e.value).filter(e=>r.has(e));return w||B(o),S.current?.(o),o},[w,t]),L=j((r,o)=>{if(o.upArrow){A(e=>k(e-1,t.length));return}if(o.downArrow){A(e=>k(e+1,t.length));return}if(r===" "){const e=t[f];if(e===void 0||e.isDisabled)return;const a=new Set(n);a.has(e.value)?a.delete(e.value):a.add(e.value),m(a);return}if(r==="a"){const e=t.filter(i=>!i.isDisabled),a=e.every(i=>n.has(i.value)),l=new Set(t.filter(i=>i.isDisabled&&n.has(i.value)).map(i=>i.value));if(!a)for(const i of e)l.add(i.value);m(l);return}o.return&&D?.(t.map(e=>e.value).filter(e=>n.has(e)))},[n,f,m,D,t]);return E(L,{isActive:C&&!p}),c(v,{flexDirection:"column",children:t.map((r,o)=>{const e=C&&o===f,a=n.has(r.value),l=a?"◉":"◯",i=!r.isDisabled&&(a||e)?u:void 0;return g(v,{children:[c(h,{color:e?u:void 0,children:e?"❯ ":" "}),g(h,{color:i,dimColor:r.isDisabled,children:[l," ",r.label]}),r.description===void 0?void 0:c(v,{marginLeft:1,children:c(h,{dimColor:!0,children:r.description})})]},o)})})}export{K as CheckboxGroup,K as default};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type Props = {
|
|
5
|
+
/**
|
|
6
|
+
* Accent color when focused.
|
|
7
|
+
* @default "blue"
|
|
8
|
+
*/
|
|
9
|
+
readonly accentColor?: LiteralUnion<AnsiColors, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Auto-focus when mounted if nothing else is focused.
|
|
12
|
+
*/
|
|
13
|
+
readonly autoFocus?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Label rendered next to the checkbox.
|
|
16
|
+
*/
|
|
17
|
+
readonly children?: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Initial checked state when uncontrolled.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
readonly defaultChecked?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Controlled checked state. When provided, `onChange` should update the parent.
|
|
25
|
+
*/
|
|
26
|
+
readonly isChecked?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Disable input and dim the label.
|
|
29
|
+
*/
|
|
30
|
+
readonly isDisabled?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Fired when the checkbox toggles.
|
|
33
|
+
*/
|
|
34
|
+
readonly onChange?: (checked: boolean) => void;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Focusable checkbox. Toggles with Space or Enter.
|
|
38
|
+
*/
|
|
39
|
+
declare function Checkbox({ accentColor, autoFocus, children, defaultChecked, isChecked, isDisabled, onChange }: Props): ReactElement;
|
|
40
|
+
export { Checkbox, type Props as CheckboxProps, Props, Checkbox as default };
|
package/dist/checkbox.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as l,jsx as v}from"react/jsx-runtime";import C from"@visulima/tui/components/box";import a from"@visulima/tui/components/text";import b from"@visulima/tui/hooks/use-focus";import k from"@visulima/tui/hooks/use-input";import{useState as x,useCallback as F}from"react";const g="☒",j="☐";function w({accentColor:s="blue",autoFocus:m=!1,children:c,defaultChecked:u=!1,isChecked:e,isDisabled:i=!1,onChange:t}){const{isFocused:o}=b({autoFocus:m,isActive:!i}),[f,n]=x(u),r=e??f;return k(F((h,p)=>{if(o&&(p.return||h===" ")){const d=!r;e===void 0&&n(d),t?.(d)}},[o,r,e,t]),{isActive:!i&&o}),l(C,{gap:1,children:[l(a,{color:o?s:void 0,dimColor:i,children:[o?"▸ ":" ",r?g:j]}),c===void 0?void 0:v(a,{color:o?s:void 0,dimColor:i,children:c})]})}export{w as Checkbox,w as default};
|
package/dist/code.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
/**
|
|
4
|
+
* The source code string to highlight.
|
|
5
|
+
*/
|
|
6
|
+
readonly code: string;
|
|
7
|
+
/**
|
|
8
|
+
* Set of line numbers to visually emphasize.
|
|
9
|
+
*/
|
|
10
|
+
readonly highlightLines?: ReadonlySet<number>;
|
|
11
|
+
/**
|
|
12
|
+
* Programming language for syntax highlighting.
|
|
13
|
+
* Falls back to plain text if the language is unknown.
|
|
14
|
+
*/
|
|
15
|
+
readonly language?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Whether to show line numbers in the gutter.
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
readonly showLineNumbers?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Starting line number (useful for code excerpts).
|
|
23
|
+
* @default 1
|
|
24
|
+
*/
|
|
25
|
+
readonly startLine?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Shiki theme name.
|
|
28
|
+
* @default "github-dark-default"
|
|
29
|
+
*/
|
|
30
|
+
readonly theme?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Render source code with syntax highlighting.
|
|
34
|
+
*
|
|
35
|
+
* ```tsx
|
|
36
|
+
* <Code code="const x = 42;" language="typescript" />
|
|
37
|
+
* <Code code={source} language="python" showLineNumbers />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function Code({ code, highlightLines, language, showLineNumbers, startLine, theme }: Props): ReactElement;
|
|
41
|
+
export { Code, type Props as CodeProps, Props, Code as default };
|
package/dist/code.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as m,jsxs as d}from"react/jsx-runtime";import p from"@visulima/tui/components/box";import L from"@visulima/tui/components/text";import{resolveLanguage as S,isLanguageSupported as w,getHighlighter as b,getCachedTokens as v,tokenLinesToElements as y}from"@visulima/tui/highlighter";import{useState as C,useRef as T,useEffect as j}from"react";function q({code:o,highlightLines:c,language:i,showLineNumbers:s=!1,startLine:l=1,theme:u="github-dark-default"}){const[h,a]=C(null),t=T(!1);j(()=>{t.current=!1;const e=i?S(i):"text";if(e!=="text"&&!w(e)){a(null);return}return(async()=>{try{const r=await b(e==="text"?[]:[e],u),n=v(r,o,e,u);t.current||a(n.tokens)}catch{t.current||a(null)}})(),()=>{t.current=!0}},[o,i,u]);const x={highlightLines:c,showLineNumbers:s,startLine:l};if(h)return y(h,x);const f=o.split(`
|
|
2
|
+
`),k=s?String(l+f.length-1).length:0;return m(p,{flexDirection:"column",children:f.map((e,r)=>{const n=l+r,g=c?.has(n)??!1;return d(p,{children:[s?d(L,{color:g?"yellow":void 0,dimColor:!g,children:[String(n).padStart(k)," "]}):void 0,m(L,{children:e})]},r)})})}export{q as Code,q as default};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type Props = {
|
|
5
|
+
/**
|
|
6
|
+
* Accent color when the header is focused.
|
|
7
|
+
* @default "blue"
|
|
8
|
+
*/
|
|
9
|
+
readonly accentColor?: LiteralUnion<AnsiColors, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Auto-focus the collapsible on mount.
|
|
12
|
+
*/
|
|
13
|
+
readonly autoFocus?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Child content rendered when open.
|
|
16
|
+
*/
|
|
17
|
+
readonly children: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the section starts expanded.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
readonly defaultOpen?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Disable interaction.
|
|
25
|
+
*/
|
|
26
|
+
readonly isDisabled?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Controlled open state.
|
|
29
|
+
*/
|
|
30
|
+
readonly isOpen?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Called when the user toggles the section.
|
|
33
|
+
*/
|
|
34
|
+
readonly onToggle?: (isOpen: boolean) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Header label.
|
|
37
|
+
*/
|
|
38
|
+
readonly title: ReactNode;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Focusable section that can be expanded or collapsed.
|
|
42
|
+
*/
|
|
43
|
+
declare function Collapsible({ accentColor, autoFocus, children, defaultOpen, isDisabled, isOpen, onToggle, title }: Props): ReactElement;
|
|
44
|
+
export { Collapsible, type Props as CollapsibleProps, Props, Collapsible as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as d,jsx as l}from"react/jsx-runtime";import t from"@visulima/tui/components/box";import m from"@visulima/tui/components/text";import C from"@visulima/tui/hooks/use-focus";import D from"@visulima/tui/hooks/use-input";import{useState as g,useCallback as F}from"react";function S({accentColor:c="blue",autoFocus:f=!1,children:a,defaultOpen:u=!1,isDisabled:o=!1,isOpen:r,onToggle:s,title:p}){const{isFocused:i}=C({autoFocus:f,isActive:!o}),[b,h]=g(u),e=r??b;return D(F((v,x)=>{if(x.return||v===" "){const n=!e;r===void 0&&h(n),s?.(n)}},[e,r,s]),{isActive:!o&&i}),d(t,{flexDirection:"column",children:[d(t,{children:[l(m,{color:i?c:void 0,dimColor:o,children:e?"▼ ":"▶ "}),l(m,{bold:i,color:i?c:void 0,dimColor:o,children:p})]}),e?l(t,{flexDirection:"column",marginLeft:2,children:a}):void 0]})}export{S as Collapsible,S as default};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type Color = LiteralUnion<AnsiColors, string>;
|
|
5
|
+
type Props = {
|
|
6
|
+
/**
|
|
7
|
+
* Accent color for the focused-cell outline.
|
|
8
|
+
* @default "blue"
|
|
9
|
+
*/
|
|
10
|
+
readonly accentColor?: Color;
|
|
11
|
+
/**
|
|
12
|
+
* Auto-focus on mount.
|
|
13
|
+
*/
|
|
14
|
+
readonly autoFocus?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Number of swatches per row.
|
|
17
|
+
* @default 8
|
|
18
|
+
*/
|
|
19
|
+
readonly columns?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Selected color when uncontrolled.
|
|
22
|
+
*/
|
|
23
|
+
readonly defaultValue?: Color;
|
|
24
|
+
/**
|
|
25
|
+
* Disable input and dim the grid.
|
|
26
|
+
*/
|
|
27
|
+
readonly isDisabled?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Fires when the highlighted swatch changes.
|
|
30
|
+
*/
|
|
31
|
+
readonly onChange?: (color: Color) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Fires on Enter with the highlighted swatch.
|
|
34
|
+
*/
|
|
35
|
+
readonly onSubmit?: (color: Color) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Colors to offer. Defaults to the 16 standard ANSI colors.
|
|
38
|
+
*/
|
|
39
|
+
readonly palette?: ReadonlyArray<Color>;
|
|
40
|
+
/**
|
|
41
|
+
* Render the highlighted color's name beneath the grid.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
readonly showName?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The two-cell glyph filled with each palette color (default `"██"`).
|
|
47
|
+
*/
|
|
48
|
+
readonly swatch?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Controlled selected color. When provided, `defaultValue` is ignored.
|
|
51
|
+
*/
|
|
52
|
+
readonly value?: Color;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* A grid of color swatches. Arrow keys move the highlight, Enter selects. The
|
|
56
|
+
* highlighted swatch's name is shown below the grid by default.
|
|
57
|
+
*/
|
|
58
|
+
declare function ColorPicker({ accentColor, autoFocus, columns, defaultValue, isDisabled, onChange, onSubmit, palette, showName, swatch, value: controlledValue }: Props): ReactElement;
|
|
59
|
+
export { ColorPicker, type Props as ColorPickerProps, Props, ColorPicker as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as C,jsx as n}from"react/jsx-runtime";import s from"@visulima/tui/components/box";import h from"@visulima/tui/components/text";import E from"@visulima/tui/hooks/use-focus";import H from"@visulima/tui/hooks/use-input";import{useState as L,useRef as P,useCallback as b}from"react";const R=["black","red","green","yellow","blue","magenta","cyan","white","gray","redBright","greenBright","yellowBright","blueBright","magentaBright","cyanBright","whiteBright"];function T(a,i){return i===0?0:(a%i+i)%i}function K({accentColor:a="blue",autoFocus:i=!1,columns:y=8,defaultValue:A,isDisabled:m=!1,onChange:f,onSubmit:p,palette:e=R,showName:k=!0,swatch:F="██",value:d}){const{isFocused:w}=E({autoFocus:i,isActive:!m}),g=d!==void 0,o=Math.max(1,y),M=Math.max(0,e.indexOf(d??A)),[D,S]=L(M),l=g?Math.max(0,e.indexOf(d)):D,x=P(f);x.current=f;const c=b(t=>{if(e.length===0)return;const r=T(l+t,e.length);g||S(r),x.current?.(e[r])},[l,g,e]),j=b((t,r)=>{r.leftArrow?c(-1):r.rightArrow?c(1):r.upArrow?c(-o):r.downArrow?c(o):r.return&&p?.(e[l])},[o,l,c,p,e]);H(j,{isActive:w&&!m});const B=[];for(let t=0;t<e.length;t+=o)B.push(e.slice(t,t+o));return C(s,{flexDirection:"column",children:[B.map((t,r)=>n(s,{children:t.map((N,v)=>{const O=r*o+v,u=w&&O===l;return C(s,{children:[n(h,{color:u?a:void 0,children:u?"[":" "}),n(h,{color:N,dimColor:m,children:F}),n(h,{color:u?a:void 0,children:u?"]":" "})]},v)})},r)),k?n(s,{marginTop:1,children:n(h,{dimColor:!0,children:String(e[l]??"")})}):void 0]})}export{K as ColorPicker,K as default};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ReactNode, ReactElement } from 'react';
|
|
2
|
+
type CommandStatus = "error" | "idle" | "running" | "success";
|
|
3
|
+
type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* Shell command rendered in the header.
|
|
6
|
+
*/
|
|
7
|
+
readonly command: string;
|
|
8
|
+
/**
|
|
9
|
+
* Optional working directory shown after the command name.
|
|
10
|
+
*/
|
|
11
|
+
readonly cwd?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Duration in ms; shown when finished.
|
|
14
|
+
*/
|
|
15
|
+
readonly durationMs?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Exit code of the completed command.
|
|
18
|
+
*/
|
|
19
|
+
readonly exitCode?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Max output rows rendered before truncation. Use `Infinity` to disable.
|
|
22
|
+
*/
|
|
23
|
+
readonly maxOutputRows?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Command output. Either a string (rendered as-is) or arbitrary children.
|
|
26
|
+
*/
|
|
27
|
+
readonly output?: ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* Lifecycle state. Controls the header icon and color.
|
|
30
|
+
* @default "idle"
|
|
31
|
+
*/
|
|
32
|
+
readonly status?: CommandStatus;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Renders a shell command with its output and a status header. Designed for
|
|
36
|
+
* coding-agent UIs that stream terminal operations.
|
|
37
|
+
*/
|
|
38
|
+
declare function CommandBlock({ command, cwd, durationMs, exitCode, maxOutputRows, output, status }: Props): ReactElement;
|
|
39
|
+
export { CommandBlock, type Props as CommandBlockProps, CommandStatus, Props, CommandBlock as default };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{jsxs as d,jsx as e}from"react/jsx-runtime";import l from"@visulima/tui/components/box";import o from"@visulima/tui/components/text";import{Spinner as a}from"./spinner.js";const f={error:"red",idle:"gray",running:"cyan",success:"green"},g=r=>r<1e3?`${Math.round(r)}ms`:`${(r/1e3).toFixed(2)}s`,x=r=>r==="running"?e(a,{type:"dots"}):{error:"✖",idle:"$",success:"✔"}[r],v=(r,i)=>{if(!Number.isFinite(i))return r;const n=r.split(`
|
|
2
|
+
`);if(n.length<=i)return r;const t=n.slice(0,i).join(`
|
|
3
|
+
`),c=n.length-i;return`${t}
|
|
4
|
+
… ${c} more line${c===1?"":"s"}`};function w({command:r,cwd:i,durationMs:n,exitCode:t,maxOutputRows:c=12,output:s,status:m="idle"}){const h=f[m],p=x(m),u=[];return n!==void 0&&u.push(d(o,{dimColor:!0,children:[" ",g(n)]},"duration")),t!==void 0&&m!=="running"&&u.push(d(o,{color:t===0?"green":"red",children:[" ","exit"," ",t]},"exit")),d(l,{borderColor:h,borderStyle:"round",flexDirection:"column",paddingX:1,children:[d(l,{children:[e(o,{color:h,children:p}),e(o,{children:" "}),e(l,{flexGrow:1,flexShrink:1,minWidth:0,children:e(o,{bold:!0,wrap:"truncate-end",children:r})}),i===void 0?void 0:d(o,{dimColor:!0,children:[" ","@",i]}),u.length===0?void 0:e(l,{flexShrink:0,children:u})]}),s===void 0?void 0:e(l,{flexDirection:"column",marginTop:1,children:typeof s=="string"?e(o,{children:v(s,c)}):s})]})}export{w as CommandBlock,w as default};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { AnsiColors } from '@visulima/colorize';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { LiteralUnion } from 'type-fest';
|
|
4
|
+
type CommandEntry = {
|
|
5
|
+
/**
|
|
6
|
+
* Optional description rendered under the label.
|
|
7
|
+
*/
|
|
8
|
+
readonly description?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Optional hotkey rendered on the right.
|
|
11
|
+
*/
|
|
12
|
+
readonly hotkey?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional icon rendered before the label.
|
|
15
|
+
*/
|
|
16
|
+
readonly icon?: ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Stable identifier returned by `onSelect`.
|
|
19
|
+
*/
|
|
20
|
+
readonly id: string;
|
|
21
|
+
/**
|
|
22
|
+
* Optional keywords to boost matching (not displayed).
|
|
23
|
+
*/
|
|
24
|
+
readonly keywords?: ReadonlyArray<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Label shown in the list (and used as the primary match target).
|
|
27
|
+
*/
|
|
28
|
+
readonly label: string;
|
|
29
|
+
};
|
|
30
|
+
type Props = {
|
|
31
|
+
/**
|
|
32
|
+
* Accent color for the border and focused row.
|
|
33
|
+
* @default "cyan"
|
|
34
|
+
*/
|
|
35
|
+
readonly accentColor?: LiteralUnion<AnsiColors, string>;
|
|
36
|
+
/**
|
|
37
|
+
* Auto-focus the palette on mount.
|
|
38
|
+
*/
|
|
39
|
+
readonly autoFocus?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Available commands to search.
|
|
42
|
+
*/
|
|
43
|
+
readonly commands: ReadonlyArray<CommandEntry>;
|
|
44
|
+
/**
|
|
45
|
+
* Empty-state text when nothing matches.
|
|
46
|
+
* @default "No results"
|
|
47
|
+
*/
|
|
48
|
+
readonly emptyText?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Max rows rendered in the list.
|
|
51
|
+
* @default 8
|
|
52
|
+
*/
|
|
53
|
+
readonly limit?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Called when the user presses Escape.
|
|
56
|
+
*/
|
|
57
|
+
readonly onCancel?: () => void;
|
|
58
|
+
/**
|
|
59
|
+
* Called when the user picks a command with Enter.
|
|
60
|
+
*/
|
|
61
|
+
readonly onSelect: (id: string, query: string) => void;
|
|
62
|
+
/**
|
|
63
|
+
* Placeholder inside the search field.
|
|
64
|
+
* @default "Type a command or search..."
|
|
65
|
+
*/
|
|
66
|
+
readonly placeholder?: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Ctrl-P style fuzzy command finder. Features a search input, ranked results,
|
|
70
|
+
* keyboard navigation, and Esc to cancel.
|
|
71
|
+
*/
|
|
72
|
+
declare function CommandPalette({ accentColor, autoFocus, commands, emptyText, limit, onCancel, onSelect, placeholder }: Props): ReactElement;
|
|
73
|
+
export { CommandEntry, CommandPalette, type Props as CommandPaletteProps, Props, CommandPalette as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as a,jsx as n}from"react/jsx-runtime";import d from"@visulima/tui/components/box";import t from"@visulima/tui/components/text";import M from"@visulima/tui/hooks/use-focus";import S from"@visulima/tui/hooks/use-input";import{isInsertableInput as T}from"@visulima/tui/input";import{useState as y,useRef as D,useMemo as F,useEffect as A,useCallback as L}from"react";const j=(m,f)=>{if(m.length===0)return 1;const p=[f.label,f.description??"",...f.keywords??[]].map(i=>i.toLowerCase()).filter(i=>i.length>0),h=m.toLowerCase();let s=0;for(const i of p){if(i.includes(h)){const u=i.indexOf(h);s=Math.max(s,100-u);continue}let x=0,g=0;for(const u of h){const c=i.indexOf(u,x);if(c===-1){g=0;break}g+=1,x=c+1}g===h.length&&(s=Math.max(s,20))}return s};function P({accentColor:m="cyan",autoFocus:f=!0,commands:p,emptyText:h="No results",limit:s=8,onCancel:i,onSelect:x,placeholder:g="Type a command or search..."}){const{isFocused:u}=M({autoFocus:f}),[c,k]=y(""),[w,C]=y(0),b=D(w);b.current=w;const l=F(()=>{const e=p.map(r=>({command:r,score:j(c,r)})).filter(({score:r})=>r>0);return e.sort((r,o)=>o.score-r.score),e.slice(0,s).map(({command:r})=>r)},[p,c,s]);return A(()=>{const e=Math.max(0,l.length-1);b.current>e&&(b.current=e,C(e))},[l]),S(L((e,r)=>{if(u){if(r.escape){i?.();return}if(r.downArrow){if(l.length===0)return;C(o=>Math.min(l.length-1,o+1));return}if(r.upArrow){C(o=>Math.max(0,o-1));return}if(r.return){const o=l[b.current];o&&x(o.id,c);return}if(r.backspace||r.delete){k(o=>o.slice(0,-1)),C(0);return}T(e,r)&&(k(o=>o+e),C(0))}},[u,l,c,x,i]),{isActive:u}),a(d,{borderColor:m,borderStyle:"round",flexDirection:"column",paddingX:1,children:[a(d,{children:[n(t,{color:m,children:"❯"}),a(t,{children:[" ",c.length===0?n(t,{dimColor:!0,children:g}):c]}),n(t,{inverse:!0,children:" "})]}),n(d,{marginTop:1,children:a(t,{dimColor:!0,children:[l.length," of ",p.length]})}),n(d,{flexDirection:"column",marginTop:1,children:l.length===0?n(t,{dimColor:!0,children:h}):l.map((e,r)=>{const o=r===w,v=o?m:void 0;return a(d,{flexDirection:"column",children:[a(d,{children:[n(t,{color:v,children:o?"▸ ":" "}),e.icon===void 0?void 0:a(t,{color:v,children:[e.icon," "]}),n(d,{flexGrow:1,flexShrink:1,minWidth:0,children:n(t,{bold:o,color:v,wrap:"truncate-end",children:e.label})}),e.hotkey===void 0?void 0:n(d,{flexShrink:0,children:a(t,{dimColor:!0,children:[" ",e.hotkey]})})]}),e.description===void 0?void 0:n(d,{marginLeft:2,children:n(t,{dimColor:!0,wrap:"truncate-end",children:e.description})})]},e.id)})})]})}export{P as CommandPalette,P as default};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ReactNode, ReactElement } from 'react';
|
|
2
|
+
type ConfirmTone = "danger" | "info" | "warning";
|
|
3
|
+
type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* Auto-focus the dialog on mount. Set `false` if a parent already owns
|
|
6
|
+
* focus and routes input here.
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
readonly autoFocus?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Label for the cancel button.
|
|
12
|
+
* @default "Cancel"
|
|
13
|
+
*/
|
|
14
|
+
readonly cancelLabel?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Body content (rendered between title and buttons).
|
|
17
|
+
*/
|
|
18
|
+
readonly children?: ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* Label for the confirm button.
|
|
21
|
+
* @default "Confirm"
|
|
22
|
+
*/
|
|
23
|
+
readonly confirmLabel?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Default button when opening the dialog.
|
|
26
|
+
* @default "confirm"
|
|
27
|
+
*/
|
|
28
|
+
readonly defaultFocus?: "cancel" | "confirm";
|
|
29
|
+
/**
|
|
30
|
+
* Disable input.
|
|
31
|
+
*/
|
|
32
|
+
readonly isDisabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Fired when the user declines.
|
|
35
|
+
*/
|
|
36
|
+
readonly onCancel: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Fired when the user confirms.
|
|
39
|
+
*/
|
|
40
|
+
readonly onConfirm: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Heading rendered at the top of the dialog.
|
|
43
|
+
*/
|
|
44
|
+
readonly title?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Controls the border color.
|
|
47
|
+
* @default "info"
|
|
48
|
+
*/
|
|
49
|
+
readonly tone?: ConfirmTone;
|
|
50
|
+
/**
|
|
51
|
+
* Dialog width.
|
|
52
|
+
*/
|
|
53
|
+
readonly width?: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Full-width modal-style confirm/cancel prompt. Unlike `ConfirmInput`, this
|
|
57
|
+
* renders a visible two-button UI: ← / → to toggle focus, Enter to activate,
|
|
58
|
+
* y/n as shortcuts, Esc to cancel.
|
|
59
|
+
* @returns A bordered `ReactElement` with optional title, body, and two
|
|
60
|
+
* buttons (cancel / confirm).
|
|
61
|
+
*/
|
|
62
|
+
declare function ConfirmDialog({ autoFocus, cancelLabel, children, confirmLabel, defaultFocus, isDisabled, onCancel, onConfirm, title, tone, width }: Props): ReactElement;
|
|
63
|
+
export { ConfirmDialog, type Props as ConfirmDialogProps, ConfirmTone, Props, ConfirmDialog as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as b,jsx as o}from"react/jsx-runtime";import n from"@visulima/tui/components/box";import s from"@visulima/tui/components/text";import x from"@visulima/tui/hooks/use-focus";import y from"@visulima/tui/hooks/use-input";import{useState as D,useCallback as A}from"react";const j={danger:"red",info:"blue",warning:"yellow"},p=({color:l,isFocused:r,label:i})=>o(n,{backgroundColor:r?l:void 0,borderColor:r?l:void 0,borderStyle:"round",paddingX:1,children:o(s,{bold:r,color:r?"black":void 0,children:i})});function Y({autoFocus:l=!0,cancelLabel:r="Cancel",children:i,confirmLabel:h="Confirm",defaultFocus:g="confirm",isDisabled:u=!1,onCancel:a,onConfirm:f,title:m,tone:v="info",width:C}){const[e,F]=D(g),c=j[v],{isFocused:w}=x({autoFocus:l,isActive:!u});return y(A((t,d)=>{if(d.leftArrow||d.rightArrow||t==="h"||t==="l"){F(e==="confirm"?"cancel":"confirm");return}if(d.return){e==="confirm"?f():a();return}if(d.escape||t==="n"){a();return}t==="y"&&f()},[e,f,a]),{isActive:!u&&w}),b(n,{borderColor:c,borderStyle:"round",flexDirection:"column",paddingX:1,paddingY:1,width:C,children:[m===void 0?void 0:o(n,{marginBottom:1,children:o(s,{bold:!0,color:c,children:m})}),i===void 0?void 0:o(n,{flexDirection:"column",marginBottom:1,children:typeof i=="string"?o(s,{children:i}):i}),b(n,{gap:2,justifyContent:"flex-end",children:[o(p,{color:c,isFocused:e==="cancel",label:r}),o(p,{color:c,isFocused:e==="confirm",label:h})]})]})}export{Y as ConfirmDialog,Y as default};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
/**
|
|
4
|
+
* The default action when pressing Enter without typing Y or N.
|
|
5
|
+
* @default "confirm"
|
|
6
|
+
*/
|
|
7
|
+
readonly defaultChoice?: "cancel" | "confirm";
|
|
8
|
+
/**
|
|
9
|
+
* Whether the input is disabled.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
readonly isDisabled?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Called when the user cancels (presses N).
|
|
15
|
+
*/
|
|
16
|
+
readonly onCancel: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Called when the user confirms (presses Y).
|
|
19
|
+
*/
|
|
20
|
+
readonly onConfirm: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Whether pressing Enter submits the default choice.
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
readonly submitOnEnter?: boolean;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Renders a Y/N confirmation prompt. Shows "Y/n" when default is confirm,
|
|
29
|
+
* or "y/N" when default is cancel.
|
|
30
|
+
*/
|
|
31
|
+
declare function ConfirmInput({ defaultChoice, isDisabled, onCancel, onConfirm, submitOnEnter }: Props): ReactElement;
|
|
32
|
+
export { ConfirmInput, type Props as ConfirmInputProps, Props, ConfirmInput as default };
|