@textui/widgets 0.1.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/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/chart/area-chart.d.ts +4 -0
- package/dist/chart/area-chart.d.ts.map +1 -0
- package/dist/chart/area-chart.js +3 -0
- package/dist/chart/bar-chart.d.ts +32 -0
- package/dist/chart/bar-chart.d.ts.map +1 -0
- package/dist/chart/bar-chart.js +32 -0
- package/dist/chart/gauge.d.ts +26 -0
- package/dist/chart/gauge.d.ts.map +1 -0
- package/dist/chart/gauge.js +26 -0
- package/dist/chart/heatmap.d.ts +13 -0
- package/dist/chart/heatmap.d.ts.map +1 -0
- package/dist/chart/heatmap.js +27 -0
- package/dist/chart/histogram.d.ts +12 -0
- package/dist/chart/histogram.d.ts.map +1 -0
- package/dist/chart/histogram.js +22 -0
- package/dist/chart/index.d.ts +20 -0
- package/dist/chart/index.d.ts.map +1 -0
- package/dist/chart/index.js +32 -0
- package/dist/chart/line-chart.d.ts +7 -0
- package/dist/chart/line-chart.d.ts.map +1 -0
- package/dist/chart/line-chart.js +75 -0
- package/dist/chart/shared.d.ts +34 -0
- package/dist/chart/shared.d.ts.map +1 -0
- package/dist/chart/shared.js +78 -0
- package/dist/chart/sparkline.d.ts +15 -0
- package/dist/chart/sparkline.d.ts.map +1 -0
- package/dist/chart/sparkline.js +22 -0
- package/dist/control/button.d.ts +27 -0
- package/dist/control/button.d.ts.map +1 -0
- package/dist/control/button.js +130 -0
- package/dist/control/checkbox.d.ts +10 -0
- package/dist/control/checkbox.d.ts.map +1 -0
- package/dist/control/checkbox.js +31 -0
- package/dist/control/index.d.ts +20 -0
- package/dist/control/index.d.ts.map +1 -0
- package/dist/control/index.js +36 -0
- package/dist/control/radio-group.d.ts +17 -0
- package/dist/control/radio-group.d.ts.map +1 -0
- package/dist/control/radio-group.js +32 -0
- package/dist/control/search-box.d.ts +7 -0
- package/dist/control/search-box.d.ts.map +1 -0
- package/dist/control/search-box.js +3 -0
- package/dist/control/select.d.ts +42 -0
- package/dist/control/select.d.ts.map +1 -0
- package/dist/control/select.js +166 -0
- package/dist/control/shared.d.ts +41 -0
- package/dist/control/shared.d.ts.map +1 -0
- package/dist/control/shared.js +1 -0
- package/dist/control/slider.d.ts +14 -0
- package/dist/control/slider.d.ts.map +1 -0
- package/dist/control/slider.js +45 -0
- package/dist/control/switch.d.ts +10 -0
- package/dist/control/switch.d.ts.map +1 -0
- package/dist/control/switch.js +32 -0
- package/dist/control/text-area.d.ts +87 -0
- package/dist/control/text-area.d.ts.map +1 -0
- package/dist/control/text-area.js +299 -0
- package/dist/control/text-input.d.ts +10 -0
- package/dist/control/text-input.d.ts.map +1 -0
- package/dist/control/text-input.js +129 -0
- package/dist/data/code-viewer.d.ts +71 -0
- package/dist/data/code-viewer.d.ts.map +1 -0
- package/dist/data/code-viewer.js +232 -0
- package/dist/data/feed.d.ts +43 -0
- package/dist/data/feed.d.ts.map +1 -0
- package/dist/data/feed.js +178 -0
- package/dist/data/index.d.ts +54 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +187 -0
- package/dist/data/list.d.ts +31 -0
- package/dist/data/list.d.ts.map +1 -0
- package/dist/data/list.js +104 -0
- package/dist/data/log-viewer.d.ts +26 -0
- package/dist/data/log-viewer.d.ts.map +1 -0
- package/dist/data/log-viewer.js +69 -0
- package/dist/data/markdown-view.d.ts +31 -0
- package/dist/data/markdown-view.d.ts.map +1 -0
- package/dist/data/markdown-view.js +139 -0
- package/dist/data/pagination.d.ts +9 -0
- package/dist/data/pagination.d.ts.map +1 -0
- package/dist/data/pagination.js +18 -0
- package/dist/data/scroll-thumb.d.ts +15 -0
- package/dist/data/scroll-thumb.d.ts.map +1 -0
- package/dist/data/scroll-thumb.js +32 -0
- package/dist/data/shared.d.ts +12 -0
- package/dist/data/shared.d.ts.map +1 -0
- package/dist/data/shared.js +17 -0
- package/dist/data/tree.d.ts +35 -0
- package/dist/data/tree.d.ts.map +1 -0
- package/dist/data/tree.js +158 -0
- package/dist/decorations.d.ts +88 -0
- package/dist/decorations.d.ts.map +1 -0
- package/dist/decorations.js +135 -0
- package/dist/display/alert.d.ts +8 -0
- package/dist/display/alert.d.ts.map +1 -0
- package/dist/display/alert.js +12 -0
- package/dist/display/badge.d.ts +10 -0
- package/dist/display/badge.d.ts.map +1 -0
- package/dist/display/badge.js +21 -0
- package/dist/display/card.d.ts +8 -0
- package/dist/display/card.d.ts.map +1 -0
- package/dist/display/card.js +12 -0
- package/dist/display/empty-state.d.ts +10 -0
- package/dist/display/empty-state.d.ts.map +1 -0
- package/dist/display/empty-state.js +5 -0
- package/dist/display/error-state.d.ts +9 -0
- package/dist/display/error-state.d.ts.map +1 -0
- package/dist/display/error-state.js +7 -0
- package/dist/display/heading.d.ts +6 -0
- package/dist/display/heading.d.ts.map +1 -0
- package/dist/display/heading.js +8 -0
- package/dist/display/index.d.ts +25 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.js +52 -0
- package/dist/display/key-value.d.ts +14 -0
- package/dist/display/key-value.d.ts.map +1 -0
- package/dist/display/key-value.js +11 -0
- package/dist/display/label.d.ts +6 -0
- package/dist/display/label.d.ts.map +1 -0
- package/dist/display/label.js +3 -0
- package/dist/display/marquee.d.ts +36 -0
- package/dist/display/marquee.d.ts.map +1 -0
- package/dist/display/marquee.js +55 -0
- package/dist/display/progress.d.ts +39 -0
- package/dist/display/progress.d.ts.map +1 -0
- package/dist/display/progress.js +46 -0
- package/dist/display/skeleton.d.ts +20 -0
- package/dist/display/skeleton.d.ts.map +1 -0
- package/dist/display/skeleton.js +20 -0
- package/dist/display/spinner.d.ts +7 -0
- package/dist/display/spinner.d.ts.map +1 -0
- package/dist/display/spinner.js +9 -0
- package/dist/display/status-dot.d.ts +8 -0
- package/dist/display/status-dot.d.ts.map +1 -0
- package/dist/display/status-dot.js +13 -0
- package/dist/display/timeline.d.ts +12 -0
- package/dist/display/timeline.d.ts.map +1 -0
- package/dist/display/timeline.js +22 -0
- package/dist/find.d.ts +74 -0
- package/dist/find.d.ts.map +1 -0
- package/dist/find.js +102 -0
- package/dist/form/danger-zone.d.ts +11 -0
- package/dist/form/danger-zone.d.ts.map +1 -0
- package/dist/form/danger-zone.js +15 -0
- package/dist/form/field.d.ts +19 -0
- package/dist/form/field.d.ts.map +1 -0
- package/dist/form/field.js +35 -0
- package/dist/form/form-actions.d.ts +11 -0
- package/dist/form/form-actions.d.ts.map +1 -0
- package/dist/form/form-actions.js +16 -0
- package/dist/form/form-section.d.ts +7 -0
- package/dist/form/form-section.d.ts.map +1 -0
- package/dist/form/form-section.js +5 -0
- package/dist/form/form.d.ts +7 -0
- package/dist/form/form.d.ts.map +1 -0
- package/dist/form/form.js +3 -0
- package/dist/form/index.d.ts +42 -0
- package/dist/form/index.d.ts.map +1 -0
- package/dist/form/index.js +140 -0
- package/dist/form/shared.d.ts +25 -0
- package/dist/form/shared.d.ts.map +1 -0
- package/dist/form/shared.js +9 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/layout/center.d.ts +7 -0
- package/dist/layout/center.d.ts.map +1 -0
- package/dist/layout/center.js +8 -0
- package/dist/layout/column.d.ts +3 -0
- package/dist/layout/column.d.ts.map +1 -0
- package/dist/layout/column.js +2 -0
- package/dist/layout/divider.d.ts +11 -0
- package/dist/layout/divider.d.ts.map +1 -0
- package/dist/layout/divider.js +13 -0
- package/dist/layout/grid.d.ts +10 -0
- package/dist/layout/grid.d.ts.map +1 -0
- package/dist/layout/grid.js +22 -0
- package/dist/layout/index.d.ts +19 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +36 -0
- package/dist/layout/panel.d.ts +37 -0
- package/dist/layout/panel.d.ts.map +1 -0
- package/dist/layout/panel.js +71 -0
- package/dist/layout/row.d.ts +7 -0
- package/dist/layout/row.d.ts.map +1 -0
- package/dist/layout/row.js +2 -0
- package/dist/layout/scroll-view.d.ts +27 -0
- package/dist/layout/scroll-view.d.ts.map +1 -0
- package/dist/layout/scroll-view.js +93 -0
- package/dist/layout/splitter.d.ts +10 -0
- package/dist/layout/splitter.d.ts.map +1 -0
- package/dist/layout/splitter.js +9 -0
- package/dist/layout/stack.d.ts +7 -0
- package/dist/layout/stack.d.ts.map +1 -0
- package/dist/layout/stack.js +5 -0
- package/dist/navigation/breadcrumb.d.ts +14 -0
- package/dist/navigation/breadcrumb.d.ts.map +1 -0
- package/dist/navigation/breadcrumb.js +24 -0
- package/dist/navigation/index.d.ts +17 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +30 -0
- package/dist/navigation/key-hints.d.ts +11 -0
- package/dist/navigation/key-hints.d.ts.map +1 -0
- package/dist/navigation/key-hints.js +13 -0
- package/dist/navigation/menu.d.ts +35 -0
- package/dist/navigation/menu.d.ts.map +1 -0
- package/dist/navigation/menu.js +88 -0
- package/dist/navigation/status-bar.d.ts +18 -0
- package/dist/navigation/status-bar.d.ts.map +1 -0
- package/dist/navigation/status-bar.js +12 -0
- package/dist/navigation/tabs.d.ts +20 -0
- package/dist/navigation/tabs.d.ts.map +1 -0
- package/dist/navigation/tabs.js +41 -0
- package/dist/navigation/toolbar.d.ts +14 -0
- package/dist/navigation/toolbar.d.ts.map +1 -0
- package/dist/navigation/toolbar.js +10 -0
- package/dist/navigation/wizard.d.ts +15 -0
- package/dist/navigation/wizard.d.ts.map +1 -0
- package/dist/navigation/wizard.js +17 -0
- package/dist/overlay/command-palette.d.ts +63 -0
- package/dist/overlay/command-palette.d.ts.map +1 -0
- package/dist/overlay/command-palette.js +415 -0
- package/dist/overlay/dialog.d.ts +16 -0
- package/dist/overlay/dialog.d.ts.map +1 -0
- package/dist/overlay/dialog.js +44 -0
- package/dist/overlay/index.d.ts +84 -0
- package/dist/overlay/index.d.ts.map +1 -0
- package/dist/overlay/index.js +157 -0
- package/dist/overlay/layer-scope.d.ts +21 -0
- package/dist/overlay/layer-scope.d.ts.map +1 -0
- package/dist/overlay/layer-scope.js +5 -0
- package/dist/overlay/path-picker.d.ts +14 -0
- package/dist/overlay/path-picker.d.ts.map +1 -0
- package/dist/overlay/path-picker.js +200 -0
- package/dist/overlay/prompt-dialog.d.ts +12 -0
- package/dist/overlay/prompt-dialog.d.ts.map +1 -0
- package/dist/overlay/prompt-dialog.js +29 -0
- package/dist/overlay/shared.d.ts +17 -0
- package/dist/overlay/shared.d.ts.map +1 -0
- package/dist/overlay/shared.js +17 -0
- package/dist/overlay/toast-host.d.ts +8 -0
- package/dist/overlay/toast-host.d.ts.map +1 -0
- package/dist/overlay/toast-host.js +19 -0
- package/dist/overlay/toast.d.ts +9 -0
- package/dist/overlay/toast.d.ts.map +1 -0
- package/dist/overlay/toast.js +20 -0
- package/dist/overlay/tooltip.d.ts +6 -0
- package/dist/overlay/tooltip.d.ts.map +1 -0
- package/dist/overlay/tooltip.js +11 -0
- package/dist/panel/index.d.ts +79 -0
- package/dist/panel/index.d.ts.map +1 -0
- package/dist/panel/index.js +256 -0
- package/dist/panel/resource-panel.d.ts +93 -0
- package/dist/panel/resource-panel.d.ts.map +1 -0
- package/dist/panel/resource-panel.js +213 -0
- package/dist/panel/shared.d.ts +6 -0
- package/dist/panel/shared.d.ts.map +1 -0
- package/dist/panel/shared.js +4 -0
- package/dist/shells/console-shell.d.ts +8 -0
- package/dist/shells/console-shell.d.ts.map +1 -0
- package/dist/shells/console-shell.js +30 -0
- package/dist/shells/index.d.ts +20 -0
- package/dist/shells/index.d.ts.map +1 -0
- package/dist/shells/index.js +61 -0
- package/dist/shells/paper-shell.d.ts +9 -0
- package/dist/shells/paper-shell.d.ts.map +1 -0
- package/dist/shells/paper-shell.js +23 -0
- package/dist/shells/plain-shell.d.ts +3 -0
- package/dist/shells/plain-shell.d.ts.map +1 -0
- package/dist/shells/plain-shell.js +11 -0
- package/dist/shells/shared.d.ts +12 -0
- package/dist/shells/shared.d.ts.map +1 -0
- package/dist/shells/shared.js +21 -0
- package/dist/shells/workbench-shell.d.ts +9 -0
- package/dist/shells/workbench-shell.d.ts.map +1 -0
- package/dist/shells/workbench-shell.js +43 -0
- package/dist/surface/bar-layout.d.ts +4 -0
- package/dist/surface/bar-layout.d.ts.map +1 -0
- package/dist/surface/bar-layout.js +7 -0
- package/dist/surface/index.d.ts +58 -0
- package/dist/surface/index.d.ts.map +1 -0
- package/dist/surface/index.js +48 -0
- package/dist/surface/inline-layout.d.ts +4 -0
- package/dist/surface/inline-layout.d.ts.map +1 -0
- package/dist/surface/inline-layout.js +7 -0
- package/dist/surface/mount-view.d.ts +7 -0
- package/dist/surface/mount-view.d.ts.map +1 -0
- package/dist/surface/mount-view.js +19 -0
- package/dist/surface/rail-layout.d.ts +4 -0
- package/dist/surface/rail-layout.d.ts.map +1 -0
- package/dist/surface/rail-layout.js +19 -0
- package/dist/surface/shared.d.ts +7 -0
- package/dist/surface/shared.d.ts.map +1 -0
- package/dist/surface/shared.js +1 -0
- package/dist/surface/single-layout.d.ts +4 -0
- package/dist/surface/single-layout.d.ts.map +1 -0
- package/dist/surface/single-layout.js +18 -0
- package/dist/surface/split-layout.d.ts +4 -0
- package/dist/surface/split-layout.d.ts.map +1 -0
- package/dist/surface/split-layout.js +7 -0
- package/dist/surface/stack-layout.d.ts +4 -0
- package/dist/surface/stack-layout.d.ts.map +1 -0
- package/dist/surface/stack-layout.js +22 -0
- package/dist/surface/surface-area.d.ts +16 -0
- package/dist/surface/surface-area.d.ts.map +1 -0
- package/dist/surface/surface-area.js +32 -0
- package/dist/surface/tabs-layout.d.ts +4 -0
- package/dist/surface/tabs-layout.d.ts.map +1 -0
- package/dist/surface/tabs-layout.js +24 -0
- package/dist/tone.d.ts +16 -0
- package/dist/tone.d.ts.map +1 -0
- package/dist/tone.js +45 -0
- package/dist/viewport.d.ts +30 -0
- package/dist/viewport.d.ts.map +1 -0
- package/dist/viewport.js +17 -0
- package/package.json +54 -0
- package/src/chart/area-chart.ts +9 -0
- package/src/chart/bar-chart.ts +74 -0
- package/src/chart/gauge.ts +60 -0
- package/src/chart/heatmap.ts +49 -0
- package/src/chart/histogram.ts +36 -0
- package/src/chart/index.ts +36 -0
- package/src/chart/line-chart.ts +100 -0
- package/src/chart/shared.ts +112 -0
- package/src/chart/sparkline.ts +46 -0
- package/src/control/button.ts +184 -0
- package/src/control/checkbox.ts +48 -0
- package/src/control/index.ts +40 -0
- package/src/control/radio-group.ts +60 -0
- package/src/control/search-box.ts +15 -0
- package/src/control/select.ts +230 -0
- package/src/control/shared.ts +41 -0
- package/src/control/slider.ts +63 -0
- package/src/control/switch.ts +39 -0
- package/src/control/text-area.ts +390 -0
- package/src/control/text-input.ts +150 -0
- package/src/data/code-viewer.ts +337 -0
- package/src/data/feed.ts +204 -0
- package/src/data/index.ts +243 -0
- package/src/data/list.ts +149 -0
- package/src/data/log-viewer.ts +105 -0
- package/src/data/markdown-view.ts +182 -0
- package/src/data/pagination.ts +31 -0
- package/src/data/scroll-thumb.ts +40 -0
- package/src/data/shared.ts +23 -0
- package/src/data/tree.ts +215 -0
- package/src/decorations.ts +176 -0
- package/src/display/alert.ts +28 -0
- package/src/display/badge.ts +40 -0
- package/src/display/card.ts +23 -0
- package/src/display/empty-state.ts +21 -0
- package/src/display/error-state.ts +23 -0
- package/src/display/heading.ts +17 -0
- package/src/display/index.ts +55 -0
- package/src/display/key-value.ts +32 -0
- package/src/display/label.ts +11 -0
- package/src/display/marquee.ts +88 -0
- package/src/display/progress.ts +92 -0
- package/src/display/skeleton.ts +34 -0
- package/src/display/spinner.ts +20 -0
- package/src/display/status-dot.ts +24 -0
- package/src/display/timeline.ts +47 -0
- package/src/find.ts +138 -0
- package/src/form/danger-zone.ts +34 -0
- package/src/form/field.ts +61 -0
- package/src/form/form-actions.ts +35 -0
- package/src/form/form-section.ts +16 -0
- package/src/form/form.ts +13 -0
- package/src/form/index.ts +191 -0
- package/src/form/shared.ts +36 -0
- package/src/index.ts +63 -0
- package/src/layout/center.ts +17 -0
- package/src/layout/column.ts +6 -0
- package/src/layout/divider.ts +31 -0
- package/src/layout/grid.ts +34 -0
- package/src/layout/index.ts +39 -0
- package/src/layout/panel.ts +114 -0
- package/src/layout/row.ts +11 -0
- package/src/layout/scroll-view.ts +115 -0
- package/src/layout/splitter.ts +24 -0
- package/src/layout/stack.ts +12 -0
- package/src/navigation/breadcrumb.ts +43 -0
- package/src/navigation/index.ts +33 -0
- package/src/navigation/key-hints.ts +25 -0
- package/src/navigation/menu.ts +134 -0
- package/src/navigation/status-bar.ts +43 -0
- package/src/navigation/tabs.ts +73 -0
- package/src/navigation/toolbar.ts +25 -0
- package/src/navigation/wizard.ts +43 -0
- package/src/overlay/command-palette.ts +485 -0
- package/src/overlay/dialog.ts +65 -0
- package/src/overlay/index.ts +232 -0
- package/src/overlay/layer-scope.ts +26 -0
- package/src/overlay/path-picker.ts +215 -0
- package/src/overlay/prompt-dialog.ts +45 -0
- package/src/overlay/shared.ts +19 -0
- package/src/overlay/toast-host.ts +30 -0
- package/src/overlay/toast.ts +35 -0
- package/src/overlay/tooltip.ts +17 -0
- package/src/panel/index.ts +317 -0
- package/src/panel/resource-panel.ts +304 -0
- package/src/panel/shared.ts +8 -0
- package/src/shells/console-shell.ts +47 -0
- package/src/shells/index.ts +66 -0
- package/src/shells/paper-shell.ts +31 -0
- package/src/shells/plain-shell.ts +19 -0
- package/src/shells/shared.ts +24 -0
- package/src/shells/workbench-shell.ts +62 -0
- package/src/surface/bar-layout.ts +11 -0
- package/src/surface/index.ts +53 -0
- package/src/surface/inline-layout.ts +11 -0
- package/src/surface/mount-view.ts +30 -0
- package/src/surface/rail-layout.ts +27 -0
- package/src/surface/shared.ts +7 -0
- package/src/surface/single-layout.ts +25 -0
- package/src/surface/split-layout.ts +11 -0
- package/src/surface/stack-layout.ts +32 -0
- package/src/surface/surface-area.ts +46 -0
- package/src/surface/tabs-layout.ts +30 -0
- package/src/tone.ts +48 -0
- package/src/viewport.ts +45 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { CommandPalette } from './command-palette.js';
|
|
2
|
+
import { Dialog } from './dialog.js';
|
|
3
|
+
import { LayerScope } from './layer-scope.js';
|
|
4
|
+
import { PathPicker } from './path-picker.js';
|
|
5
|
+
import { PromptDialog } from './prompt-dialog.js';
|
|
6
|
+
import { ToastHost } from './toast-host.js';
|
|
7
|
+
import { Toast } from './toast.js';
|
|
8
|
+
import { Tooltip } from './tooltip.js';
|
|
9
|
+
/**
|
|
10
|
+
* Overlays.
|
|
11
|
+
*
|
|
12
|
+
* Every one of these is a layer entry, not a component that draws itself over
|
|
13
|
+
* its neighbours - so focus trapping, dismissal and paint order are decided
|
|
14
|
+
* once by the layer manager rather than five times, slightly differently.
|
|
15
|
+
*/
|
|
16
|
+
export * from './command-palette.js';
|
|
17
|
+
export * from './dialog.js';
|
|
18
|
+
export * from './layer-scope.js';
|
|
19
|
+
export * from './path-picker.js';
|
|
20
|
+
export * from './prompt-dialog.js';
|
|
21
|
+
export * from './toast.js';
|
|
22
|
+
export * from './toast-host.js';
|
|
23
|
+
export * from './tooltip.js';
|
|
24
|
+
/**
|
|
25
|
+
* The composition rule the brief asks for: a dialog can be assembled by hand
|
|
26
|
+
* out of public components, and the common case gets a one-liner that returns
|
|
27
|
+
* a promise. Both go through the same layer manager.
|
|
28
|
+
*/
|
|
29
|
+
export function confirm(layers, options) {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
const id = `confirm:${options.message}`;
|
|
32
|
+
let settled = false;
|
|
33
|
+
const finish = (value) => {
|
|
34
|
+
if (settled)
|
|
35
|
+
return;
|
|
36
|
+
settled = true;
|
|
37
|
+
handle.dispose();
|
|
38
|
+
resolve(value);
|
|
39
|
+
};
|
|
40
|
+
const handle = layers.open({
|
|
41
|
+
id,
|
|
42
|
+
layer: 'modal',
|
|
43
|
+
scrim: true,
|
|
44
|
+
trapFocus: true,
|
|
45
|
+
dismissOnEscape: true,
|
|
46
|
+
onClose: () => finish(false),
|
|
47
|
+
node: {
|
|
48
|
+
component: 'Dialog',
|
|
49
|
+
title: options.title ?? 'Confirm',
|
|
50
|
+
width: 50,
|
|
51
|
+
children: { component: 'text', content: options.message, wrap: 'word' },
|
|
52
|
+
actions: [
|
|
53
|
+
{
|
|
54
|
+
id: 'confirm',
|
|
55
|
+
label: options.confirmLabel ?? 'Confirm',
|
|
56
|
+
tone: options.tone ?? 'primary',
|
|
57
|
+
onPress: () => finish(true),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: 'cancel',
|
|
61
|
+
label: options.cancelLabel ?? 'Cancel',
|
|
62
|
+
onPress: () => finish(false),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function prompt(layers, options) {
|
|
70
|
+
return new Promise((resolve) => {
|
|
71
|
+
let settled = false;
|
|
72
|
+
const finish = (value) => {
|
|
73
|
+
if (settled)
|
|
74
|
+
return;
|
|
75
|
+
settled = true;
|
|
76
|
+
handle.dispose();
|
|
77
|
+
resolve(value);
|
|
78
|
+
};
|
|
79
|
+
const handle = layers.open({
|
|
80
|
+
id: `prompt:${options.title ?? options.message ?? 'input'}`,
|
|
81
|
+
layer: 'modal',
|
|
82
|
+
scrim: true,
|
|
83
|
+
trapFocus: true,
|
|
84
|
+
dismissOnEscape: true,
|
|
85
|
+
onClose: () => finish(null),
|
|
86
|
+
node: {
|
|
87
|
+
component: 'PromptDialog',
|
|
88
|
+
title: options.title ?? 'Input',
|
|
89
|
+
message: options.message,
|
|
90
|
+
placeholder: options.placeholder,
|
|
91
|
+
initialValue: options.initialValue,
|
|
92
|
+
mask: options.mask,
|
|
93
|
+
onSubmit: { handler: (value) => finish(value) },
|
|
94
|
+
onCancel: { handler: () => finish(null) },
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export function pick(app, options) {
|
|
100
|
+
return new Promise((resolve) => {
|
|
101
|
+
let settled = false;
|
|
102
|
+
const finish = (value) => {
|
|
103
|
+
if (settled)
|
|
104
|
+
return;
|
|
105
|
+
settled = true;
|
|
106
|
+
handle.dispose();
|
|
107
|
+
resolve(value);
|
|
108
|
+
};
|
|
109
|
+
const handle = app.layers.open({
|
|
110
|
+
id: `pick:${options.start}`,
|
|
111
|
+
layer: 'modal',
|
|
112
|
+
scrim: true,
|
|
113
|
+
trapFocus: true,
|
|
114
|
+
dismissOnEscape: true,
|
|
115
|
+
onClose: () => finish(null),
|
|
116
|
+
node: {
|
|
117
|
+
component: 'PathPicker',
|
|
118
|
+
start: options.start,
|
|
119
|
+
wants: options.wants ?? 'file',
|
|
120
|
+
title: options.title,
|
|
121
|
+
placeholder: options.placeholder,
|
|
122
|
+
visibleRows: options.visibleRows,
|
|
123
|
+
width: options.width,
|
|
124
|
+
onPick: { handler: (uri) => finish(uri) },
|
|
125
|
+
onCancel: { handler: () => finish(null) },
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
let notifyCounter = 0;
|
|
131
|
+
export function notify(app, options) {
|
|
132
|
+
const { message, tone = 'info', title, icon, timeoutMs = 2500, id } = options;
|
|
133
|
+
return app.layers.open({
|
|
134
|
+
id: id ?? `toast-${++notifyCounter}`,
|
|
135
|
+
layer: 'notification',
|
|
136
|
+
timeoutMs: timeoutMs > 0 ? timeoutMs : undefined,
|
|
137
|
+
node: { component: 'Toast', message, tone, title, icon },
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
export function toastPosition(anchor) {
|
|
141
|
+
switch (anchor) {
|
|
142
|
+
case 'top': return { kind: 'screen', rect: { y: 1 } };
|
|
143
|
+
case 'top-right': return { kind: 'screen', rect: { y: 1 } };
|
|
144
|
+
case 'bottom': return { kind: 'screen', rect: { y: 0 } };
|
|
145
|
+
default: return { kind: 'screen', rect: {} };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
export const OVERLAY_COMPONENTS = [
|
|
149
|
+
{ component: 'Dialog', category: 'overlay', renderer: { kind: 'function', render: Dialog }, role: 'dialog', description: 'Modal box with actions; traps focus and restores it.' },
|
|
150
|
+
{ component: 'PromptDialog', category: 'overlay', renderer: { kind: 'function', render: PromptDialog }, role: 'dialog', description: 'One-field dialog behind the `prompt` helper.' },
|
|
151
|
+
{ component: 'PathPicker', category: 'overlay', renderer: { kind: 'function', render: PathPicker }, role: 'dialog', description: 'Walk the resource tree and pick a file or a folder.' },
|
|
152
|
+
{ component: 'Tooltip', category: 'overlay', renderer: { kind: 'function', render: Tooltip }, role: 'tooltip', description: 'Small anchored hint.' },
|
|
153
|
+
{ component: 'Toast', category: 'overlay', renderer: { kind: 'function', render: Toast }, role: 'status', description: 'Transient notification.' },
|
|
154
|
+
{ component: 'ToastHost', category: 'overlay', renderer: { kind: 'function', render: ToastHost }, description: 'Where toasts stack.' },
|
|
155
|
+
{ component: 'LayerScope', category: 'overlay', renderer: { kind: 'function', render: LayerScope }, description: 'The focus scope a layer lives in; makes `trapFocus` real.' },
|
|
156
|
+
{ component: 'CommandPalette', category: 'overlay', renderer: { kind: 'function', render: CommandPalette }, role: 'dialog', description: 'Fuzzy search over the command registry.' },
|
|
157
|
+
];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ComponentNode, RenderOutput } from '@textui/core';
|
|
2
|
+
/**
|
|
3
|
+
* The focus scope a layer lives in.
|
|
4
|
+
*
|
|
5
|
+
* `trapFocus` on a layer used to be a flag nothing read: `Dialog` and
|
|
6
|
+
* `CommandPalette` trapped because they each called `useFocusScope`
|
|
7
|
+
* themselves, and any layer built out of plain nodes - a menu dropdown, say -
|
|
8
|
+
* silently did not. Tab then walked straight out of the open thing and into
|
|
9
|
+
* whatever was behind it, and the next key went with it.
|
|
10
|
+
*
|
|
11
|
+
* Wrapping every layer in this makes the flag mean what it says, once, for all
|
|
12
|
+
* of them. It renders its child rather than a box of its own, so a layer's
|
|
13
|
+
* measurements are unchanged by being scoped.
|
|
14
|
+
*/
|
|
15
|
+
export interface LayerScopeProps {
|
|
16
|
+
scopeId: string;
|
|
17
|
+
trap?: boolean;
|
|
18
|
+
children?: ComponentNode | ComponentNode[];
|
|
19
|
+
}
|
|
20
|
+
export declare const LayerScope: (props: LayerScopeProps) => RenderOutput;
|
|
21
|
+
//# sourceMappingURL=layer-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer-scope.d.ts","sourceRoot":"","sources":["../../src/overlay/layer-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGhE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,aAAa,GAAG,aAAa,EAAE,CAAC;CAC5C;AAED,eAAO,MAAM,UAAU,0CAGrB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BoxProps } from '@textui/core';
|
|
2
|
+
export interface PathPickerProps extends BoxProps {
|
|
3
|
+
start: string;
|
|
4
|
+
wants?: 'file' | 'directory';
|
|
5
|
+
title?: string;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
visibleRows?: number;
|
|
8
|
+
onPick?(uri: string): void;
|
|
9
|
+
onCancel?(): void;
|
|
10
|
+
}
|
|
11
|
+
/** The parent of a directory URI, or null at the top of its scheme. */
|
|
12
|
+
export declare function parentOf(uri: string): string | null;
|
|
13
|
+
export declare const PathPicker: (props: PathPickerProps) => import("@textui/core").RenderOutput;
|
|
14
|
+
//# sourceMappingURL=path-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-picker.d.ts","sourceRoot":"","sources":["../../src/overlay/path-picker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAgB7C,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,IAAI,IAAI,CAAC;CACnB;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQnD;AAED,eAAO,MAAM,UAAU,iEAiLrB,CAAC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { defineComponent, h, nameOf, useEffect, useInput, useRuntime, useState, useTheme, } from '@textui/core';
|
|
2
|
+
import { TextInput } from '../control/index.js';
|
|
3
|
+
import { Menu } from '../navigation/index.js';
|
|
4
|
+
import { hint } from './shared.js';
|
|
5
|
+
/** The parent of a directory URI, or null at the top of its scheme. */
|
|
6
|
+
export function parentOf(uri) {
|
|
7
|
+
const at = uri.lastIndexOf('/');
|
|
8
|
+
if (at < 0)
|
|
9
|
+
return null;
|
|
10
|
+
const head = uri.slice(0, at);
|
|
11
|
+
// `scheme://` is a root, not a parent: trimming again would produce
|
|
12
|
+
// `scheme:/` and then `scheme:`, which are two URIs nothing can list.
|
|
13
|
+
if (head.endsWith('/') || head.endsWith(':'))
|
|
14
|
+
return null;
|
|
15
|
+
return head;
|
|
16
|
+
}
|
|
17
|
+
export const PathPicker = defineComponent('PathPicker', (props) => {
|
|
18
|
+
const { start, wants = 'file', title, placeholder, visibleRows = 10, width = 60, onPick, onCancel, ...rest } = props;
|
|
19
|
+
const theme = useTheme();
|
|
20
|
+
const runtime = useRuntime();
|
|
21
|
+
const app = runtime.app();
|
|
22
|
+
const [at, setAt] = useState(start);
|
|
23
|
+
const [query, setQuery] = useState('');
|
|
24
|
+
const [highlight, setHighlight] = useState(0);
|
|
25
|
+
const [entries, setEntries] = useState([]);
|
|
26
|
+
/*
|
|
27
|
+
* An empty folder and a folder still being read are different answers.
|
|
28
|
+
*
|
|
29
|
+
* "Nothing here" under a list that has not arrived is a lie the reader acts
|
|
30
|
+
* on - they press escape and go somewhere else. So the list says which.
|
|
31
|
+
*/
|
|
32
|
+
const [loading, setLoading] = useState(true);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
let live = true;
|
|
35
|
+
setLoading(true);
|
|
36
|
+
void (async () => {
|
|
37
|
+
const found = await app?.resources.list(at).catch(() => []) ?? [];
|
|
38
|
+
if (!live)
|
|
39
|
+
return;
|
|
40
|
+
setEntries(found.map((r) => ({
|
|
41
|
+
uri: r.uri,
|
|
42
|
+
name: r.metadata.name || nameOf(r.uri),
|
|
43
|
+
directory: r.capabilities.includes('list'),
|
|
44
|
+
})));
|
|
45
|
+
setLoading(false);
|
|
46
|
+
})();
|
|
47
|
+
return () => { live = false; };
|
|
48
|
+
}, [at]);
|
|
49
|
+
const parent = parentOf(at);
|
|
50
|
+
const q = query.trim().toLowerCase();
|
|
51
|
+
const shown = entries
|
|
52
|
+
// A folder cannot be *chosen* when a file is wanted, but it still has to
|
|
53
|
+
// be walked through - so both kinds are listed either way, and only what
|
|
54
|
+
// enter does about them differs.
|
|
55
|
+
.filter((e) => q === '' || e.name.toLowerCase().includes(q))
|
|
56
|
+
// Folders first, then by name: a list sorted only by name buries the way
|
|
57
|
+
// onward among the things at the end of the journey.
|
|
58
|
+
.sort((a, b) => (a.directory === b.directory
|
|
59
|
+
? a.name.localeCompare(b.name)
|
|
60
|
+
: (a.directory ? -1 : 1)));
|
|
61
|
+
const rows = [
|
|
62
|
+
// Picking the folder you are standing in needs a row, because there is no
|
|
63
|
+
// child to press enter on and a hidden chord for it is a chord nobody
|
|
64
|
+
// finds. It is first, since it is the answer most often wanted.
|
|
65
|
+
...(wants === 'directory'
|
|
66
|
+
? [{ id: '.', label: 'Use this folder', icon: theme.glyphs.check }]
|
|
67
|
+
: []),
|
|
68
|
+
...(parent !== null ? [{ id: '..', label: '..', icon: theme.glyphs.chevronUp }] : []),
|
|
69
|
+
...shown.map((e) => ({
|
|
70
|
+
id: e.uri,
|
|
71
|
+
label: e.name,
|
|
72
|
+
icon: e.directory ? theme.glyphs.chevronRight : ' ',
|
|
73
|
+
...(e.directory ? {} : { description: '' }),
|
|
74
|
+
})),
|
|
75
|
+
];
|
|
76
|
+
const index = Math.max(0, Math.min(highlight, rows.length - 1));
|
|
77
|
+
const up = () => {
|
|
78
|
+
if (parent === null)
|
|
79
|
+
return;
|
|
80
|
+
setAt(parent);
|
|
81
|
+
setQuery('');
|
|
82
|
+
setHighlight(0);
|
|
83
|
+
};
|
|
84
|
+
const choose = (id) => {
|
|
85
|
+
const chosen = id ?? rows[index]?.id;
|
|
86
|
+
if (chosen === undefined)
|
|
87
|
+
return;
|
|
88
|
+
if (chosen === '.') {
|
|
89
|
+
onPick?.(at);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (chosen === '..') {
|
|
93
|
+
up();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const entry = entries.find((e) => e.uri === chosen);
|
|
97
|
+
if (!entry)
|
|
98
|
+
return;
|
|
99
|
+
// A directory is a place to go when a file is wanted, and both a place to
|
|
100
|
+
// go and an answer when one is not - which is why enter descends and the
|
|
101
|
+
// row above is what picks.
|
|
102
|
+
if (entry.directory) {
|
|
103
|
+
setAt(entry.uri);
|
|
104
|
+
setQuery('');
|
|
105
|
+
setHighlight(0);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (wants === 'file')
|
|
109
|
+
onPick?.(entry.uri);
|
|
110
|
+
};
|
|
111
|
+
useInput((event) => {
|
|
112
|
+
const wrap = (n) => (rows.length === 0
|
|
113
|
+
? 0
|
|
114
|
+
: ((n % rows.length) + rows.length) % rows.length);
|
|
115
|
+
if (event.name === 'up') {
|
|
116
|
+
setHighlight(wrap(index - 1));
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
if (event.name === 'down') {
|
|
120
|
+
setHighlight(wrap(index + 1));
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
// Only when a caller gave one. `pick` mounts this on a dismissible layer
|
|
124
|
+
// and the layer closes itself on escape, so taking the key unconditionally
|
|
125
|
+
// would swallow escape for a caller that mounted the picker plainly and
|
|
126
|
+
// wired nothing to it.
|
|
127
|
+
if (event.name === 'escape' && onCancel) {
|
|
128
|
+
onCancel();
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}, { global: true });
|
|
133
|
+
const move = `${theme.glyphs.arrowUp}${theme.glyphs.arrowDown} move`;
|
|
134
|
+
return h('box', {
|
|
135
|
+
role: 'dialog',
|
|
136
|
+
label: title ?? 'Choose',
|
|
137
|
+
border: theme.border,
|
|
138
|
+
bg: 'overlay',
|
|
139
|
+
width,
|
|
140
|
+
direction: 'column',
|
|
141
|
+
...(theme.border === 'none' ? { padding: { left: 1, right: 1 } } : {}),
|
|
142
|
+
title: ` ${title ?? (wants === 'directory' ? 'choose a folder' : 'choose a file')} `,
|
|
143
|
+
...rest,
|
|
144
|
+
},
|
|
145
|
+
// Where you are. A column of bare names with no header is a list you can
|
|
146
|
+
// get lost in - and the tail is the part that changes, so it is the part
|
|
147
|
+
// kept when the path is too long for the dialog.
|
|
148
|
+
h('text', { content: at, fg: 'muted', truncate: 'start' }), h(TextInput, {
|
|
149
|
+
value: query,
|
|
150
|
+
onChange: (next) => { setQuery(next); setHighlight(0); },
|
|
151
|
+
onSubmit: () => choose(),
|
|
152
|
+
/*
|
|
153
|
+
* Leftwards is upwards, the way it is in every tree.
|
|
154
|
+
*
|
|
155
|
+
* Through `onEdge` rather than a key handler beside the others: the
|
|
156
|
+
* field has the keyboard, and it answers `left` itself until the caret
|
|
157
|
+
* runs out of text. A global handler for it never fires - the field
|
|
158
|
+
* reports the edge instead, which is the hook that exists for exactly
|
|
159
|
+
* this. It also means a typed filter keeps its own arrows, which is
|
|
160
|
+
* what you want while editing one.
|
|
161
|
+
*/
|
|
162
|
+
onEdge: (edge) => { if (edge === 'start')
|
|
163
|
+
up(); },
|
|
164
|
+
placeholder: placeholder ?? `Filter${theme.glyphs.ellipsis}`,
|
|
165
|
+
search: true,
|
|
166
|
+
autoFocus: true,
|
|
167
|
+
border: 'none',
|
|
168
|
+
}), h('box', { height: 1, fill: theme.borderChars().top, fg: 'borderSubtle' }), h(Menu, {
|
|
169
|
+
items: rows,
|
|
170
|
+
visibleRows,
|
|
171
|
+
interactive: false,
|
|
172
|
+
activeId: rows[index]?.id,
|
|
173
|
+
onSelect: (id) => { choose(id); },
|
|
174
|
+
}),
|
|
175
|
+
/*
|
|
176
|
+
* An empty folder and a folder still being read are different answers.
|
|
177
|
+
*
|
|
178
|
+
* "Nothing here" under a list that has not arrived is a lie the reader
|
|
179
|
+
* acts on - they press escape and go somewhere else. It is a line of its
|
|
180
|
+
* own rather than the menu's empty state because the menu is never empty:
|
|
181
|
+
* `..` and "Use this folder" are rows, and neither is a child.
|
|
182
|
+
*/
|
|
183
|
+
shown.length === 0
|
|
184
|
+
? h('text', {
|
|
185
|
+
content: loading
|
|
186
|
+
? `Reading${theme.glyphs.ellipsis}`
|
|
187
|
+
: (q === '' ? 'Nothing here.' : 'Nothing matches.'),
|
|
188
|
+
fg: 'muted',
|
|
189
|
+
})
|
|
190
|
+
: null, h('box', { height: 1, fill: theme.borderChars().top, fg: 'borderSubtle' }), h('text', {
|
|
191
|
+
content: hint(theme, [
|
|
192
|
+
move,
|
|
193
|
+
wants === 'directory' ? 'enter open' : 'enter choose',
|
|
194
|
+
`${theme.glyphs.chevronLeft} up`,
|
|
195
|
+
'esc cancel',
|
|
196
|
+
]),
|
|
197
|
+
fg: 'subtle',
|
|
198
|
+
truncate: 'end',
|
|
199
|
+
}));
|
|
200
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BoxProps } from '@textui/core';
|
|
2
|
+
export interface PromptDialogProps extends BoxProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
message?: string;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
initialValue?: string;
|
|
7
|
+
mask?: string;
|
|
8
|
+
onSubmit?(value: string): void;
|
|
9
|
+
onCancel?(): void;
|
|
10
|
+
}
|
|
11
|
+
export declare const PromptDialog: (props: PromptDialogProps) => import("@textui/core").RenderOutput;
|
|
12
|
+
//# sourceMappingURL=prompt-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-dialog.d.ts","sourceRoot":"","sources":["../../src/overlay/prompt-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAK7C,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,mEA6BvB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineComponent, h, useState } from '@textui/core';
|
|
2
|
+
import { TextInput } from '../control/index.js';
|
|
3
|
+
import { Dialog } from './dialog.js';
|
|
4
|
+
export const PromptDialog = defineComponent('PromptDialog', (props) => {
|
|
5
|
+
const { title, message, placeholder, initialValue = '', mask, onSubmit, onCancel, ...rest } = props;
|
|
6
|
+
const [value, setValue] = useState(initialValue);
|
|
7
|
+
return h(Dialog, {
|
|
8
|
+
title,
|
|
9
|
+
width: 50,
|
|
10
|
+
onClose: onCancel,
|
|
11
|
+
actions: [
|
|
12
|
+
{ id: 'ok', label: 'OK', tone: 'primary', onPress: () => onSubmit?.(value) },
|
|
13
|
+
{ id: 'cancel', label: 'Cancel', onPress: onCancel },
|
|
14
|
+
],
|
|
15
|
+
...rest,
|
|
16
|
+
}, message ? h('text', { content: message, wrap: 'word' }) : null, h(TextInput, {
|
|
17
|
+
value,
|
|
18
|
+
onChange: setValue,
|
|
19
|
+
placeholder,
|
|
20
|
+
mask,
|
|
21
|
+
// The message names the field: an unlabelled input is a focus stop
|
|
22
|
+
// nothing can describe, in the dialog whose whole job is one question.
|
|
23
|
+
// It is already on screen above, so it is not drawn twice.
|
|
24
|
+
label: message,
|
|
25
|
+
hideLabel: true,
|
|
26
|
+
autoFocus: true,
|
|
27
|
+
onSubmit: () => onSubmit?.(value),
|
|
28
|
+
}));
|
|
29
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ResolvedTheme } from '@textui/core';
|
|
2
|
+
/**
|
|
3
|
+
* Raise a toast.
|
|
4
|
+
*
|
|
5
|
+
* Exists because the alternative - every caller assembling a layer entry - is
|
|
6
|
+
* how two of them end up with different timeouts and one of them forgets the
|
|
7
|
+
* `notification` layer and lands under the dialog it is reporting on.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The footer of an overlay: what the keys do.
|
|
11
|
+
*
|
|
12
|
+
* Joined with the theme's separator rather than a `·` written here, because a
|
|
13
|
+
* terminal that cannot draw a middle dot draws a `?` instead - and the row it
|
|
14
|
+
* ruins is the one telling you how to get out.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hint(theme: ResolvedTheme, parts: string[]): string;
|
|
17
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/overlay/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;GAMG;AACH;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAElE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raise a toast.
|
|
3
|
+
*
|
|
4
|
+
* Exists because the alternative - every caller assembling a layer entry - is
|
|
5
|
+
* how two of them end up with different timeouts and one of them forgets the
|
|
6
|
+
* `notification` layer and lands under the dialog it is reporting on.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The footer of an overlay: what the keys do.
|
|
10
|
+
*
|
|
11
|
+
* Joined with the theme's separator rather than a `·` written here, because a
|
|
12
|
+
* terminal that cannot draw a middle dot draws a `?` instead - and the row it
|
|
13
|
+
* ruins is the one telling you how to get out.
|
|
14
|
+
*/
|
|
15
|
+
export function hint(theme, parts) {
|
|
16
|
+
return parts.join(` ${theme.glyphs.separator} `);
|
|
17
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BoxProps } from '@textui/core';
|
|
2
|
+
export interface ToastHostProps extends BoxProps {
|
|
3
|
+
/** Where the stack sits. Named `anchor` so it does not shadow `position`. */
|
|
4
|
+
anchor?: 'top-right' | 'bottom-right' | 'top' | 'bottom';
|
|
5
|
+
}
|
|
6
|
+
/** Renders whatever is on the notification layer. */
|
|
7
|
+
export declare const ToastHost: (props: ToastHostProps) => import("@textui/core").RenderOutput;
|
|
8
|
+
//# sourceMappingURL=toast-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-host.d.ts","sourceRoot":"","sources":["../../src/overlay/toast-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC1D;AAED,qDAAqD;AACrD,eAAO,MAAM,SAAS,gEAoBpB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineComponent, h, useEffect, useRuntime } from '@textui/core';
|
|
2
|
+
/** Renders whatever is on the notification layer. */
|
|
3
|
+
export const ToastHost = defineComponent('ToastHost', (props) => {
|
|
4
|
+
const runtime = useRuntime();
|
|
5
|
+
const { anchor = 'bottom-right', ...rest } = props;
|
|
6
|
+
const entries = runtime.layers.entries('notification');
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
// Re-render when the layer set changes; the manager already asks for a
|
|
9
|
+
// frame, this only keeps the subscription honest.
|
|
10
|
+
}, [entries.length]);
|
|
11
|
+
if (entries.length === 0)
|
|
12
|
+
return null;
|
|
13
|
+
return h('box', {
|
|
14
|
+
direction: 'column',
|
|
15
|
+
gap: 1,
|
|
16
|
+
align: anchor.endsWith('right') ? 'end' : 'stretch',
|
|
17
|
+
...rest,
|
|
18
|
+
}, ...entries.map((entry) => h('box', { key: entry.id }, entry.node)));
|
|
19
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BoxProps, SemanticVariant } from '@textui/core';
|
|
2
|
+
export interface ToastProps extends BoxProps {
|
|
3
|
+
message: string;
|
|
4
|
+
tone?: SemanticVariant;
|
|
5
|
+
title?: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const Toast: (props: ToastProps) => import("@textui/core").RenderOutput;
|
|
9
|
+
//# sourceMappingURL=toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/overlay/toast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG9D,MAAM,WAAW,UAAW,SAAQ,QAAQ;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,KAAK,4DAwBhB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineComponent, h, useTheme } from '@textui/core';
|
|
2
|
+
export const Toast = defineComponent('Toast', (props) => {
|
|
3
|
+
const theme = useTheme();
|
|
4
|
+
const { message, tone = 'info', title, icon, ...rest } = props;
|
|
5
|
+
const glyph = icon ?? {
|
|
6
|
+
success: theme.glyphs.check,
|
|
7
|
+
warning: theme.glyphs.warning,
|
|
8
|
+
danger: theme.glyphs.cross,
|
|
9
|
+
info: theme.glyphs.info,
|
|
10
|
+
}[tone] ?? theme.glyphs.info;
|
|
11
|
+
return h('box', {
|
|
12
|
+
role: 'status',
|
|
13
|
+
border: theme.border,
|
|
14
|
+
bg: 'overlay',
|
|
15
|
+
padding: [0, 1],
|
|
16
|
+
direction: 'row',
|
|
17
|
+
gap: 1,
|
|
18
|
+
...rest,
|
|
19
|
+
}, h('text', { content: glyph, fg: tone }), h('box', { direction: 'column' }, title ? h('text', { content: title, bold: true }) : null, h('text', { content: message, wrap: 'word' })));
|
|
20
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/overlay/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,OAAO,8DASlB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineComponent, h, useTheme } from '@textui/core';
|
|
2
|
+
export const Tooltip = defineComponent('Tooltip', ({ text, ...rest }) => {
|
|
3
|
+
const theme = useTheme();
|
|
4
|
+
return h('box', {
|
|
5
|
+
role: 'tooltip',
|
|
6
|
+
border: theme.border,
|
|
7
|
+
bg: 'overlay',
|
|
8
|
+
padding: [0, 1],
|
|
9
|
+
...rest,
|
|
10
|
+
}, h('text', { content: text }));
|
|
11
|
+
});
|