@rezi-ui/core 0.1.0-alpha.60 → 0.1.0-alpha.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/createApp/breadcrumbs.d.ts +38 -0
- package/dist/app/createApp/breadcrumbs.d.ts.map +1 -0
- package/dist/app/createApp/breadcrumbs.js +65 -0
- package/dist/app/createApp/breadcrumbs.js.map +1 -0
- package/dist/app/createApp/config.d.ts +25 -0
- package/dist/app/createApp/config.d.ts.map +1 -0
- package/dist/app/createApp/config.js +130 -0
- package/dist/app/createApp/config.js.map +1 -0
- package/dist/app/createApp/eventLoop.d.ts +95 -0
- package/dist/app/createApp/eventLoop.d.ts.map +1 -0
- package/dist/app/createApp/eventLoop.js +384 -0
- package/dist/app/createApp/eventLoop.js.map +1 -0
- package/dist/app/createApp/guards.d.ts +21 -0
- package/dist/app/createApp/guards.d.ts.map +1 -0
- package/dist/app/createApp/guards.js +54 -0
- package/dist/app/createApp/guards.js.map +1 -0
- package/dist/app/createApp/keybindings.d.ts +28 -0
- package/dist/app/createApp/keybindings.d.ts.map +1 -0
- package/dist/app/createApp/keybindings.js +113 -0
- package/dist/app/createApp/keybindings.js.map +1 -0
- package/dist/app/createApp/renderLoop.d.ts +64 -0
- package/dist/app/createApp/renderLoop.d.ts.map +1 -0
- package/dist/app/createApp/renderLoop.js +305 -0
- package/dist/app/createApp/renderLoop.js.map +1 -0
- package/dist/app/createApp.d.ts +3 -39
- package/dist/app/createApp.d.ts.map +1 -1
- package/dist/app/createApp.js +403 -1205
- package/dist/app/createApp.js.map +1 -1
- package/dist/app/widgetRenderer/constraintState.d.ts +98 -0
- package/dist/app/widgetRenderer/constraintState.d.ts.map +1 -0
- package/dist/app/widgetRenderer/constraintState.js +563 -0
- package/dist/app/widgetRenderer/constraintState.js.map +1 -0
- package/dist/app/widgetRenderer/fileNodeCache.d.ts +2 -0
- package/dist/app/widgetRenderer/fileNodeCache.d.ts.map +1 -1
- package/dist/app/widgetRenderer/fileNodeCache.js +31 -0
- package/dist/app/widgetRenderer/fileNodeCache.js.map +1 -1
- package/dist/app/widgetRenderer/filePickerRouting.d.ts +12 -1
- package/dist/app/widgetRenderer/filePickerRouting.d.ts.map +1 -1
- package/dist/app/widgetRenderer/filePickerRouting.js +63 -14
- package/dist/app/widgetRenderer/filePickerRouting.js.map +1 -1
- package/dist/app/widgetRenderer/focusState.d.ts +46 -0
- package/dist/app/widgetRenderer/focusState.d.ts.map +1 -0
- package/dist/app/widgetRenderer/focusState.js +122 -0
- package/dist/app/widgetRenderer/focusState.js.map +1 -0
- package/dist/app/widgetRenderer/keyboardRouting.d.ts.map +1 -1
- package/dist/app/widgetRenderer/keyboardRouting.js.map +1 -1
- package/dist/app/widgetRenderer/mouseRouting.d.ts +5 -0
- package/dist/app/widgetRenderer/mouseRouting.d.ts.map +1 -1
- package/dist/app/widgetRenderer/mouseRouting.js +78 -8
- package/dist/app/widgetRenderer/mouseRouting.js.map +1 -1
- package/dist/app/widgetRenderer/overlayShortcuts.d.ts.map +1 -1
- package/dist/app/widgetRenderer/overlayShortcuts.js +14 -4
- package/dist/app/widgetRenderer/overlayShortcuts.js.map +1 -1
- package/dist/app/widgetRenderer/overlayState.d.ts +198 -0
- package/dist/app/widgetRenderer/overlayState.d.ts.map +1 -0
- package/dist/app/widgetRenderer/overlayState.js +590 -0
- package/dist/app/widgetRenderer/overlayState.js.map +1 -0
- package/dist/app/widgetRenderer/routeEngineEvent.d.ts +189 -0
- package/dist/app/widgetRenderer/routeEngineEvent.d.ts.map +1 -0
- package/dist/app/widgetRenderer/routeEngineEvent.js +527 -0
- package/dist/app/widgetRenderer/routeEngineEvent.js.map +1 -0
- package/dist/app/widgetRenderer.d.ts +2 -1
- package/dist/app/widgetRenderer.d.ts.map +1 -1
- package/dist/app/widgetRenderer.js +334 -1707
- package/dist/app/widgetRenderer.js.map +1 -1
- package/dist/forms/internal/arrayState.d.ts +35 -0
- package/dist/forms/internal/arrayState.d.ts.map +1 -0
- package/dist/forms/internal/arrayState.js +238 -0
- package/dist/forms/internal/arrayState.js.map +1 -0
- package/dist/forms/internal/bindings.d.ts +46 -0
- package/dist/forms/internal/bindings.d.ts.map +1 -0
- package/dist/forms/internal/bindings.js +161 -0
- package/dist/forms/internal/bindings.js.map +1 -0
- package/dist/forms/internal/dev.d.ts +4 -0
- package/dist/forms/internal/dev.d.ts.map +1 -0
- package/dist/forms/internal/dev.js +21 -0
- package/dist/forms/internal/dev.js.map +1 -0
- package/dist/forms/internal/state.d.ts +52 -0
- package/dist/forms/internal/state.d.ts.map +1 -0
- package/dist/forms/internal/state.js +240 -0
- package/dist/forms/internal/state.js.map +1 -0
- package/dist/forms/internal/submit.d.ts +43 -0
- package/dist/forms/internal/submit.d.ts.map +1 -0
- package/dist/forms/internal/submit.js +165 -0
- package/dist/forms/internal/submit.js.map +1 -0
- package/dist/forms/internal/wizard.d.ts +53 -0
- package/dist/forms/internal/wizard.d.ts.map +1 -0
- package/dist/forms/internal/wizard.js +311 -0
- package/dist/forms/internal/wizard.js.map +1 -0
- package/dist/forms/useForm.d.ts.map +1 -1
- package/dist/forms/useForm.js +90 -1117
- package/dist/forms/useForm.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keybindings/manager.d.ts.map +1 -1
- package/dist/keybindings/manager.js.map +1 -1
- package/dist/keybindings/parser.d.ts.map +1 -1
- package/dist/keybindings/parser.js +10 -5
- package/dist/keybindings/parser.js.map +1 -1
- package/dist/layout/dropdownGeometry.d.ts +8 -0
- package/dist/layout/dropdownGeometry.d.ts.map +1 -1
- package/dist/layout/dropdownGeometry.js +40 -0
- package/dist/layout/dropdownGeometry.js.map +1 -1
- package/dist/layout/engine/layoutEngine.js +1 -1
- package/dist/layout/engine/layoutEngine.js.map +1 -1
- package/dist/layout/kinds/overlays.d.ts.map +1 -1
- package/dist/layout/kinds/stack.d.ts +1 -3
- package/dist/layout/kinds/stack.d.ts.map +1 -1
- package/dist/layout/kinds/stack.js +11 -1523
- package/dist/layout/kinds/stack.js.map +1 -1
- package/dist/layout/kinds/stackParts/axis.d.ts +32 -0
- package/dist/layout/kinds/stackParts/axis.d.ts.map +1 -0
- package/dist/layout/kinds/stackParts/axis.js +61 -0
- package/dist/layout/kinds/stackParts/axis.js.map +1 -0
- package/dist/layout/kinds/stackParts/constraintPlan.d.ts +18 -0
- package/dist/layout/kinds/stackParts/constraintPlan.d.ts.map +1 -0
- package/dist/layout/kinds/stackParts/constraintPlan.js +434 -0
- package/dist/layout/kinds/stackParts/constraintPlan.js.map +1 -0
- package/dist/layout/kinds/stackParts/layout.d.ts +6 -0
- package/dist/layout/kinds/stackParts/layout.d.ts.map +1 -0
- package/dist/layout/kinds/stackParts/layout.js +376 -0
- package/dist/layout/kinds/stackParts/layout.js.map +1 -0
- package/dist/layout/kinds/stackParts/measure.d.ts +6 -0
- package/dist/layout/kinds/stackParts/measure.d.ts.map +1 -0
- package/dist/layout/kinds/stackParts/measure.js +212 -0
- package/dist/layout/kinds/stackParts/measure.js.map +1 -0
- package/dist/layout/kinds/stackParts/shared.d.ts +31 -0
- package/dist/layout/kinds/stackParts/shared.d.ts.map +1 -0
- package/dist/layout/kinds/stackParts/shared.js +94 -0
- package/dist/layout/kinds/stackParts/shared.js.map +1 -0
- package/dist/layout/kinds/stackParts/wrap.d.ts +26 -0
- package/dist/layout/kinds/stackParts/wrap.d.ts.map +1 -0
- package/dist/layout/kinds/stackParts/wrap.js +374 -0
- package/dist/layout/kinds/stackParts/wrap.js.map +1 -0
- package/dist/layout/validate/interactive.d.ts +106 -0
- package/dist/layout/validate/interactive.d.ts.map +1 -0
- package/dist/layout/validate/interactive.js +430 -0
- package/dist/layout/validate/interactive.js.map +1 -0
- package/dist/layout/validate/layoutConstraints.d.ts +51 -0
- package/dist/layout/validate/layoutConstraints.d.ts.map +1 -0
- package/dist/layout/validate/layoutConstraints.js +100 -0
- package/dist/layout/validate/layoutConstraints.js.map +1 -0
- package/dist/layout/validate/primitives.d.ts +31 -0
- package/dist/layout/validate/primitives.d.ts.map +1 -0
- package/dist/layout/validate/primitives.js +299 -0
- package/dist/layout/validate/primitives.js.map +1 -0
- package/dist/layout/validate/shared.d.ts +23 -0
- package/dist/layout/validate/shared.d.ts.map +1 -0
- package/dist/layout/validate/shared.js +32 -0
- package/dist/layout/validate/shared.js.map +1 -0
- package/dist/layout/validate/spacing.d.ts +21 -0
- package/dist/layout/validate/spacing.d.ts.map +1 -0
- package/dist/layout/validate/spacing.js +33 -0
- package/dist/layout/validate/spacing.js.map +1 -0
- package/dist/layout/validateProps.d.ts +5 -159
- package/dist/layout/validateProps.d.ts.map +1 -1
- package/dist/layout/validateProps.js +1 -832
- package/dist/layout/validateProps.js.map +1 -1
- package/dist/pipeline.js +1 -1
- package/dist/pipeline.js.map +1 -1
- package/dist/renderer/renderToDrawlist/renderTree.d.ts +1 -1
- package/dist/renderer/renderToDrawlist/renderTree.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/renderTree.js +3 -3
- package/dist/renderer/renderToDrawlist/renderTree.js.map +1 -1
- package/dist/renderer/renderToDrawlist/types.d.ts +2 -0
- package/dist/renderer/renderToDrawlist/types.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/containers.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/containers.js +1 -1
- package/dist/renderer/renderToDrawlist/widgets/containers.js.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/files.d.ts +2 -1
- package/dist/renderer/renderToDrawlist/widgets/files.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/files.js +30 -3
- package/dist/renderer/renderToDrawlist/widgets/files.js.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts +1 -1
- package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/overlays.js +26 -6
- package/dist/renderer/renderToDrawlist/widgets/overlays.js.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/renderFormWidgets.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/renderFormWidgets.js +52 -18
- package/dist/renderer/renderToDrawlist/widgets/renderFormWidgets.js.map +1 -1
- package/dist/renderer/renderToDrawlist.d.ts +0 -8
- package/dist/renderer/renderToDrawlist.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist.js +1 -9
- package/dist/renderer/renderToDrawlist.js.map +1 -1
- package/dist/runtime/commit/composite.d.ts +11 -0
- package/dist/runtime/commit/composite.d.ts.map +1 -0
- package/dist/runtime/commit/composite.js +238 -0
- package/dist/runtime/commit/composite.js.map +1 -0
- package/dist/runtime/commit/container.d.ts +7 -0
- package/dist/runtime/commit/container.d.ts.map +1 -0
- package/dist/runtime/commit/container.js +350 -0
- package/dist/runtime/commit/container.js.map +1 -0
- package/dist/runtime/commit/equality.d.ts +20 -0
- package/dist/runtime/commit/equality.d.ts.map +1 -0
- package/dist/runtime/commit/equality.js +436 -0
- package/dist/runtime/commit/equality.js.map +1 -0
- package/dist/runtime/commit/errorBoundary.d.ts +7 -0
- package/dist/runtime/commit/errorBoundary.d.ts.map +1 -0
- package/dist/runtime/commit/errorBoundary.js +53 -0
- package/dist/runtime/commit/errorBoundary.js.map +1 -0
- package/dist/runtime/commit/shared.d.ts +138 -0
- package/dist/runtime/commit/shared.d.ts.map +1 -0
- package/dist/runtime/commit/shared.js +11 -0
- package/dist/runtime/commit/shared.js.map +1 -0
- package/dist/runtime/commit/transitions.d.ts +9 -0
- package/dist/runtime/commit/transitions.d.ts.map +1 -0
- package/dist/runtime/commit/transitions.js +93 -0
- package/dist/runtime/commit/transitions.js.map +1 -0
- package/dist/runtime/commit/validation.d.ts +16 -0
- package/dist/runtime/commit/validation.d.ts.map +1 -0
- package/dist/runtime/commit/validation.js +157 -0
- package/dist/runtime/commit/validation.js.map +1 -0
- package/dist/runtime/commit.d.ts +7 -117
- package/dist/runtime/commit.d.ts.map +1 -1
- package/dist/runtime/commit.js +13 -1394
- package/dist/runtime/commit.js.map +1 -1
- package/dist/runtime/localState.d.ts +4 -0
- package/dist/runtime/localState.d.ts.map +1 -1
- package/dist/runtime/localState.js.map +1 -1
- package/dist/runtime/widgetMeta/collector.d.ts +77 -0
- package/dist/runtime/widgetMeta/collector.d.ts.map +1 -0
- package/dist/runtime/widgetMeta/collector.js +293 -0
- package/dist/runtime/widgetMeta/collector.js.map +1 -0
- package/dist/runtime/widgetMeta/focusContainers.d.ts +44 -0
- package/dist/runtime/widgetMeta/focusContainers.d.ts.map +1 -0
- package/dist/runtime/widgetMeta/focusContainers.js +190 -0
- package/dist/runtime/widgetMeta/focusContainers.js.map +1 -0
- package/dist/runtime/widgetMeta/focusInfo.d.ts +19 -0
- package/dist/runtime/widgetMeta/focusInfo.d.ts.map +1 -0
- package/dist/runtime/widgetMeta/focusInfo.js +172 -0
- package/dist/runtime/widgetMeta/focusInfo.js.map +1 -0
- package/dist/runtime/widgetMeta/helpers.d.ts +47 -0
- package/dist/runtime/widgetMeta/helpers.d.ts.map +1 -0
- package/dist/runtime/widgetMeta/helpers.js +182 -0
- package/dist/runtime/widgetMeta/helpers.js.map +1 -0
- package/dist/runtime/widgetMeta.d.ts +12 -175
- package/dist/runtime/widgetMeta.d.ts.map +1 -1
- package/dist/runtime/widgetMeta.js +6 -847
- package/dist/runtime/widgetMeta.js.map +1 -1
- package/dist/ui/capabilities.d.ts.map +1 -1
- package/dist/ui/designTokens.d.ts.map +1 -1
- package/dist/widgets/accordion.d.ts.map +1 -1
- package/dist/widgets/accordion.js +8 -13
- package/dist/widgets/accordion.js.map +1 -1
- package/dist/widgets/factories/advanced.d.ts +20 -0
- package/dist/widgets/factories/advanced.d.ts.map +1 -0
- package/dist/widgets/factories/advanced.js +75 -0
- package/dist/widgets/factories/advanced.js.map +1 -0
- package/dist/widgets/factories/basic.d.ts +14 -0
- package/dist/widgets/factories/basic.d.ts.map +1 -0
- package/dist/widgets/factories/basic.js +44 -0
- package/dist/widgets/factories/basic.js.map +1 -0
- package/dist/widgets/factories/feedback.d.ts +20 -0
- package/dist/widgets/factories/feedback.d.ts.map +1 -0
- package/dist/widgets/factories/feedback.js +102 -0
- package/dist/widgets/factories/feedback.js.map +1 -0
- package/dist/widgets/factories/helpers.d.ts +41 -0
- package/dist/widgets/factories/helpers.d.ts.map +1 -0
- package/dist/widgets/factories/helpers.js +72 -0
- package/dist/widgets/factories/helpers.js.map +1 -0
- package/dist/widgets/factories/interactive.d.ts +15 -0
- package/dist/widgets/factories/interactive.d.ts.map +1 -0
- package/dist/widgets/factories/interactive.js +46 -0
- package/dist/widgets/factories/interactive.js.map +1 -0
- package/dist/widgets/factories/layoutShell.d.ts +22 -0
- package/dist/widgets/factories/layoutShell.d.ts.map +1 -0
- package/dist/widgets/factories/layoutShell.js +190 -0
- package/dist/widgets/factories/layoutShell.js.map +1 -0
- package/dist/widgets/factories/media.d.ts +14 -0
- package/dist/widgets/factories/media.d.ts.map +1 -0
- package/dist/widgets/factories/media.js +25 -0
- package/dist/widgets/factories/media.js.map +1 -0
- package/dist/widgets/factories/navigation.d.ts +10 -0
- package/dist/widgets/factories/navigation.d.ts.map +1 -0
- package/dist/widgets/factories/navigation.js +24 -0
- package/dist/widgets/factories/navigation.js.map +1 -0
- package/dist/widgets/field.d.ts +6 -1
- package/dist/widgets/field.d.ts.map +1 -1
- package/dist/widgets/field.js +8 -2
- package/dist/widgets/field.js.map +1 -1
- package/dist/widgets/filePicker.d.ts +5 -0
- package/dist/widgets/filePicker.d.ts.map +1 -0
- package/dist/widgets/filePicker.js +136 -0
- package/dist/widgets/filePicker.js.map +1 -0
- package/dist/widgets/protocol.d.ts +0 -6
- package/dist/widgets/protocol.d.ts.map +1 -1
- package/dist/widgets/protocol.js +0 -6
- package/dist/widgets/protocol.js.map +1 -1
- package/dist/widgets/select.js +1 -1
- package/dist/widgets/select.js.map +1 -1
- package/dist/widgets/splitPane.d.ts.map +1 -1
- package/dist/widgets/splitPane.js.map +1 -1
- package/dist/widgets/table.d.ts.map +1 -1
- package/dist/widgets/table.js +43 -1
- package/dist/widgets/table.js.map +1 -1
- package/dist/widgets/tree.d.ts.map +1 -1
- package/dist/widgets/types/advanced.d.ts +611 -0
- package/dist/widgets/types/advanced.d.ts.map +1 -0
- package/dist/widgets/types/advanced.js +2 -0
- package/dist/widgets/types/advanced.js.map +1 -0
- package/dist/widgets/types/base.d.ts +933 -0
- package/dist/widgets/types/base.d.ts.map +1 -0
- package/dist/widgets/types/base.js +2 -0
- package/dist/widgets/types/base.js.map +1 -0
- package/dist/widgets/types/forms.d.ts +136 -0
- package/dist/widgets/types/forms.d.ts.map +1 -0
- package/dist/widgets/types/forms.js +2 -0
- package/dist/widgets/types/forms.js.map +1 -0
- package/dist/widgets/types/navigation.d.ts +83 -0
- package/dist/widgets/types/navigation.d.ts.map +1 -0
- package/dist/widgets/types/navigation.js +2 -0
- package/dist/widgets/types/navigation.js.map +1 -0
- package/dist/widgets/types/overlaysShell.d.ts +223 -0
- package/dist/widgets/types/overlaysShell.d.ts.map +1 -0
- package/dist/widgets/types/overlaysShell.js +2 -0
- package/dist/widgets/types/overlaysShell.js.map +1 -0
- package/dist/widgets/types/table.d.ts +104 -0
- package/dist/widgets/types/table.d.ts.map +1 -0
- package/dist/widgets/types/table.js +2 -0
- package/dist/widgets/types/table.js.map +1 -0
- package/dist/widgets/types/tree.d.ts +64 -0
- package/dist/widgets/types/tree.d.ts.map +1 -0
- package/dist/widgets/types/tree.js +2 -0
- package/dist/widgets/types/tree.js.map +1 -0
- package/dist/widgets/types.d.ts +14 -2123
- package/dist/widgets/types.d.ts.map +1 -1
- package/dist/widgets/ui.d.ts +37 -843
- package/dist/widgets/ui.d.ts.map +1 -1
- package/dist/widgets/ui.js +37 -1262
- package/dist/widgets/ui.js.map +1 -1
- package/package.json +2 -2
- package/dist/constraints/aggregation.d.ts +0 -17
- package/dist/constraints/aggregation.d.ts.map +0 -1
- package/dist/constraints/aggregation.js +0 -59
- package/dist/constraints/aggregation.js.map +0 -1
- package/dist/renderer/renderToDrawlist/overflowCulling.d.ts +0 -3
- package/dist/renderer/renderToDrawlist/overflowCulling.d.ts.map +0 -1
- package/dist/renderer/renderToDrawlist/overflowCulling.js +0 -81
- package/dist/renderer/renderToDrawlist/overflowCulling.js.map +0 -1
- package/dist/widgets/tests/protocol.test.d.ts +0 -2
- package/dist/widgets/tests/protocol.test.d.ts.map +0 -1
- package/dist/widgets/tests/protocol.test.js +0 -120
- package/dist/widgets/tests/protocol.test.js.map +0 -1
package/dist/widgets/ui.js
CHANGED
|
@@ -1,728 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* packages/core/src/widgets/ui.ts — Widget factory
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import { createAccordionWidgetVNode } from "./accordion.js";
|
|
12
|
-
import { createBreadcrumbWidgetVNode } from "./breadcrumb.js";
|
|
13
|
-
import { createPaginationWidgetVNode } from "./pagination.js";
|
|
14
|
-
import { createTabsWidgetVNode } from "./tabs.js";
|
|
15
|
-
function isUiChildren(value) {
|
|
16
|
-
return Array.isArray(value);
|
|
17
|
-
}
|
|
18
|
-
function filterChildren(children) {
|
|
19
|
-
const out = [];
|
|
20
|
-
for (const child of children) {
|
|
21
|
-
if (child === false || child === null || child === undefined)
|
|
22
|
-
continue;
|
|
23
|
-
if (isUiChildren(child)) {
|
|
24
|
-
out.push(...filterChildren(child));
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
out.push(child);
|
|
28
|
-
}
|
|
29
|
-
return out;
|
|
30
|
-
}
|
|
31
|
-
function maybeReverseChildren(children, reverse) {
|
|
32
|
-
if (reverse !== true || children.length <= 1)
|
|
33
|
-
return children;
|
|
34
|
-
return Object.freeze([...children].reverse());
|
|
35
|
-
}
|
|
36
|
-
function isTextProps(v) {
|
|
37
|
-
return (typeof v === "object" &&
|
|
38
|
-
v !== null &&
|
|
39
|
-
("style" in v ||
|
|
40
|
-
"id" in v ||
|
|
41
|
-
"key" in v ||
|
|
42
|
-
"variant" in v ||
|
|
43
|
-
"textOverflow" in v ||
|
|
44
|
-
"maxWidth" in v ||
|
|
45
|
-
"wrap" in v));
|
|
46
|
-
}
|
|
47
|
-
function resolveButtonIntent(props) {
|
|
48
|
-
if (props.intent === undefined || props.dsVariant !== undefined)
|
|
49
|
-
return props;
|
|
50
|
-
switch (props.intent) {
|
|
51
|
-
case "primary":
|
|
52
|
-
return { ...props, dsVariant: "solid", dsTone: props.dsTone ?? "primary" };
|
|
53
|
-
case "secondary":
|
|
54
|
-
return { ...props, dsVariant: "soft", dsTone: props.dsTone ?? "default" };
|
|
55
|
-
case "danger":
|
|
56
|
-
return { ...props, dsVariant: "outline", dsTone: props.dsTone ?? "danger" };
|
|
57
|
-
case "success":
|
|
58
|
-
return { ...props, dsVariant: "soft", dsTone: props.dsTone ?? "success" };
|
|
59
|
-
case "warning":
|
|
60
|
-
return { ...props, dsVariant: "soft", dsTone: props.dsTone ?? "warning" };
|
|
61
|
-
case "link":
|
|
62
|
-
return {
|
|
63
|
-
...props,
|
|
64
|
-
dsVariant: "ghost",
|
|
65
|
-
dsTone: props.dsTone ?? "default",
|
|
66
|
-
dsSize: props.dsSize ?? "sm",
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function resolveBoxPreset(props) {
|
|
71
|
-
const { preset, ...rest } = props;
|
|
72
|
-
if (preset === undefined)
|
|
73
|
-
return props;
|
|
74
|
-
switch (preset) {
|
|
75
|
-
case "card":
|
|
76
|
-
return { preset, border: "rounded", p: 1, ...rest };
|
|
77
|
-
case "surface":
|
|
78
|
-
return { preset, border: "none", p: 1, ...rest };
|
|
79
|
-
case "well":
|
|
80
|
-
return { preset, border: "single", p: 1, ...rest };
|
|
81
|
-
case "elevated":
|
|
82
|
-
return { preset, border: "single", p: 1, shadow: { density: "light" }, ...rest };
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const EMPTY_TEXT_PROPS = Object.freeze({});
|
|
86
|
-
function text(content, styleOrProps) {
|
|
87
|
-
if (styleOrProps === undefined)
|
|
88
|
-
return { kind: "text", text: content, props: EMPTY_TEXT_PROPS };
|
|
89
|
-
if (isTextProps(styleOrProps))
|
|
90
|
-
return { kind: "text", text: content, props: styleOrProps };
|
|
91
|
-
return { kind: "text", text: content, props: { style: styleOrProps } };
|
|
92
|
-
}
|
|
93
|
-
function box(props = {}, children = []) {
|
|
94
|
-
return { kind: "box", props: resolveBoxPreset(props), children: filterChildren(children) };
|
|
95
|
-
}
|
|
96
|
-
function row(props = {}, children = []) {
|
|
97
|
-
const resolved = props.gap === undefined ? { gap: DEFAULT_STACK_GAP, ...props } : props;
|
|
98
|
-
const filtered = filterChildren(children);
|
|
99
|
-
return {
|
|
100
|
-
kind: "row",
|
|
101
|
-
props: resolved,
|
|
102
|
-
children: maybeReverseChildren(filtered, resolved.reverse),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
function column(props = {}, children = []) {
|
|
106
|
-
const resolved = props.gap === undefined ? { gap: DEFAULT_STACK_GAP, ...props } : props;
|
|
107
|
-
const filtered = filterChildren(children);
|
|
108
|
-
return {
|
|
109
|
-
kind: "column",
|
|
110
|
-
props: resolved,
|
|
111
|
-
children: maybeReverseChildren(filtered, resolved.reverse),
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
function themed(themeOverride, children = []) {
|
|
115
|
-
return { kind: "themed", props: { theme: themeOverride }, children: filterChildren(children) };
|
|
116
|
-
}
|
|
117
|
-
function grid(props, ...children) {
|
|
118
|
-
return { kind: "grid", props, children: filterChildren(children) };
|
|
119
|
-
}
|
|
120
|
-
const DEFAULT_STACK_GAP = 1;
|
|
121
|
-
function spacer(props = {}) {
|
|
122
|
-
return { kind: "spacer", props };
|
|
123
|
-
}
|
|
124
|
-
function divider(props = {}) {
|
|
125
|
-
return { kind: "divider", props };
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Create an icon widget.
|
|
129
|
-
*
|
|
130
|
-
* @param iconPath - Icon path (e.g., "status.check", "arrow.right")
|
|
131
|
-
* @param props - Optional icon props
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```ts
|
|
135
|
-
* ui.icon("status.check")
|
|
136
|
-
* ui.icon("arrow.right", { style: { fg: rgb(0, 255, 0) } })
|
|
137
|
-
* ui.icon("ui.search", { fallback: true })
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
function icon(iconPath, props = {}) {
|
|
141
|
-
return { kind: "icon", props: { icon: iconPath, ...props } };
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Create a spinner widget (animated loading indicator).
|
|
145
|
-
*
|
|
146
|
-
* @param props - Spinner props
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```ts
|
|
150
|
-
* ui.spinner()
|
|
151
|
-
* ui.spinner({ variant: "dots", label: "Loading..." })
|
|
152
|
-
* ```
|
|
153
|
-
*/
|
|
154
|
-
function spinner(props = {}) {
|
|
155
|
-
return { kind: "spinner", props };
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Create a progress bar widget.
|
|
159
|
-
*
|
|
160
|
-
* @param value - Progress value from 0 to 1
|
|
161
|
-
* @param props - Optional progress bar props
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```ts
|
|
165
|
-
* ui.progress(0.75)
|
|
166
|
-
* ui.progress(0.5, { variant: "blocks", showPercent: true })
|
|
167
|
-
* ui.progress(0.3, { label: "Downloading:", width: 20 })
|
|
168
|
-
* ```
|
|
169
|
-
*/
|
|
170
|
-
function progress(value, props = {}) {
|
|
171
|
-
return { kind: "progress", props: { value, ...props } };
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Create a skeleton loading placeholder.
|
|
175
|
-
*
|
|
176
|
-
* @param width - Width in cells
|
|
177
|
-
* @param props - Optional skeleton props
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* ```ts
|
|
181
|
-
* ui.skeleton(20)
|
|
182
|
-
* ui.skeleton(10, { height: 3, variant: "rect" })
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
function skeleton(width, props = {}) {
|
|
186
|
-
return { kind: "skeleton", props: { width, ...props } };
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Create a rich text widget with multiple styled spans.
|
|
190
|
-
*
|
|
191
|
-
* @param spans - Array of text spans with optional styles
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```ts
|
|
195
|
-
* ui.richText([
|
|
196
|
-
* { text: "Error: ", style: { fg: rgb(255, 0, 0), bold: true } },
|
|
197
|
-
* { text: "File not found" },
|
|
198
|
-
* ])
|
|
199
|
-
* ```
|
|
200
|
-
*/
|
|
201
|
-
function richText(spans, props = {}) {
|
|
202
|
-
return { kind: "richText", props: { spans, ...props } };
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Create a keyboard shortcut display widget.
|
|
206
|
-
*
|
|
207
|
-
* @param keys - Key or keys to display
|
|
208
|
-
* @param props - Optional kbd props
|
|
209
|
-
*
|
|
210
|
-
* @example
|
|
211
|
-
* ```ts
|
|
212
|
-
* ui.kbd("Ctrl+S")
|
|
213
|
-
* ui.kbd(["Ctrl", "Shift", "P"])
|
|
214
|
-
* ui.kbd("Cmd+K", { separator: " " })
|
|
215
|
-
* ```
|
|
216
|
-
*/
|
|
217
|
-
function kbd(keys, props = {}) {
|
|
218
|
-
return { kind: "kbd", props: { keys, ...props } };
|
|
219
|
-
}
|
|
220
|
-
function keybindingSequenceToKbdInput(sequence) {
|
|
221
|
-
const normalized = sequence.trim();
|
|
222
|
-
if (normalized.length === 0)
|
|
223
|
-
return "";
|
|
224
|
-
const parts = normalized.split(/\s+/);
|
|
225
|
-
if (parts.length <= 1)
|
|
226
|
-
return normalized;
|
|
227
|
-
return Object.freeze(parts);
|
|
228
|
-
}
|
|
229
|
-
function keybindingComparator(a, b) {
|
|
230
|
-
const byMode = a.mode.localeCompare(b.mode);
|
|
231
|
-
if (byMode !== 0)
|
|
232
|
-
return byMode;
|
|
233
|
-
return a.sequence.localeCompare(b.sequence);
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Render keybindings as a formatted help table.
|
|
237
|
-
*
|
|
238
|
-
* Accepts output from `app.getBindings()` directly.
|
|
239
|
-
*/
|
|
240
|
-
function keybindingHelp(bindings, options = {}) {
|
|
241
|
-
const title = options.title ?? "Keyboard Shortcuts";
|
|
242
|
-
const emptyText = options.emptyText ?? "No shortcuts registered.";
|
|
243
|
-
const showMode = options.showMode ??
|
|
244
|
-
(() => {
|
|
245
|
-
const firstMode = bindings[0]?.mode;
|
|
246
|
-
if (firstMode === undefined)
|
|
247
|
-
return false;
|
|
248
|
-
return bindings.some((binding) => binding.mode !== firstMode);
|
|
249
|
-
})();
|
|
250
|
-
const rows = options.sort === false ? [...bindings] : [...bindings].sort(keybindingComparator);
|
|
251
|
-
return column({
|
|
252
|
-
gap: 1,
|
|
253
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
254
|
-
}, [
|
|
255
|
-
text(title, { style: { bold: true } }),
|
|
256
|
-
divider({ char: "·" }),
|
|
257
|
-
rows.length > 0
|
|
258
|
-
? column({ gap: 0 }, rows.map((binding, i) => {
|
|
259
|
-
const keyTokens = keybindingSequenceToKbdInput(binding.sequence);
|
|
260
|
-
const sequenceNode = Array.isArray(keyTokens)
|
|
261
|
-
? kbd(keyTokens, { separator: " " })
|
|
262
|
-
: kbd(keyTokens);
|
|
263
|
-
const descriptionNode = binding.description === undefined
|
|
264
|
-
? text("No description", { dim: true })
|
|
265
|
-
: text(binding.description);
|
|
266
|
-
return row({
|
|
267
|
-
key: `keybinding-help-${binding.mode}-${binding.sequence}-${String(i)}`,
|
|
268
|
-
gap: 1,
|
|
269
|
-
items: "center",
|
|
270
|
-
wrap: true,
|
|
271
|
-
}, [
|
|
272
|
-
sequenceNode,
|
|
273
|
-
showMode ? text(`[${binding.mode}]`, { dim: true }) : null,
|
|
274
|
-
descriptionNode,
|
|
275
|
-
]);
|
|
276
|
-
}))
|
|
277
|
-
: text(emptyText, { dim: true }),
|
|
278
|
-
]);
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Create a badge widget.
|
|
282
|
-
*
|
|
283
|
-
* @param text - Badge text
|
|
284
|
-
* @param props - Optional badge props
|
|
285
|
-
*
|
|
286
|
-
* @example
|
|
287
|
-
* ```ts
|
|
288
|
-
* ui.badge("New")
|
|
289
|
-
* ui.badge("Error", { variant: "error" })
|
|
290
|
-
* ui.badge("3", { variant: "info" })
|
|
291
|
-
* ```
|
|
292
|
-
*/
|
|
293
|
-
function badge(text, props = {}) {
|
|
294
|
-
return { kind: "badge", props: { text, ...props } };
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Create a status indicator widget.
|
|
298
|
-
*
|
|
299
|
-
* @param status - Status type (online, offline, away, busy, unknown)
|
|
300
|
-
* @param props - Optional status props
|
|
301
|
-
*
|
|
302
|
-
* @example
|
|
303
|
-
* ```ts
|
|
304
|
-
* ui.status("online")
|
|
305
|
-
* ui.status("busy", { label: "In a meeting" })
|
|
306
|
-
* ui.status("away", { showLabel: true })
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
function status(status, props = {}) {
|
|
310
|
-
return { kind: "status", props: { status, ...props } };
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Create a tag widget.
|
|
314
|
-
*
|
|
315
|
-
* @param text - Tag text
|
|
316
|
-
* @param props - Optional tag props
|
|
317
|
-
*
|
|
318
|
-
* @example
|
|
319
|
-
* ```ts
|
|
320
|
-
* ui.tag("TypeScript")
|
|
321
|
-
* ui.tag("Bug", { variant: "error" })
|
|
322
|
-
* ui.tag("Feature", { variant: "info", removable: true })
|
|
323
|
-
* ```
|
|
324
|
-
*/
|
|
325
|
-
function tag(text, props = {}) {
|
|
326
|
-
return { kind: "tag", props: { text, ...props } };
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* Create a gauge widget.
|
|
330
|
-
*
|
|
331
|
-
* @param value - Value from 0 to 1
|
|
332
|
-
* @param props - Optional gauge props
|
|
333
|
-
*
|
|
334
|
-
* @example
|
|
335
|
-
* ```ts
|
|
336
|
-
* ui.gauge(0.75)
|
|
337
|
-
* ui.gauge(0.42, { label: "CPU" })
|
|
338
|
-
* ui.gauge(0.9, {
|
|
339
|
-
* label: "Memory",
|
|
340
|
-
* thresholds: [
|
|
341
|
-
* { value: 0.8, variant: "warning" },
|
|
342
|
-
* { value: 0.95, variant: "error" }
|
|
343
|
-
* ]
|
|
344
|
-
* })
|
|
345
|
-
* ```
|
|
346
|
-
*/
|
|
347
|
-
function gauge(value, props = {}) {
|
|
348
|
-
return { kind: "gauge", props: { value, ...props } };
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Create an empty state widget.
|
|
352
|
-
*
|
|
353
|
-
* @param title - Main title text
|
|
354
|
-
* @param props - Optional empty state props
|
|
355
|
-
*
|
|
356
|
-
* @example
|
|
357
|
-
* ```ts
|
|
358
|
-
* ui.empty("No results")
|
|
359
|
-
* ui.empty("No messages", {
|
|
360
|
-
* icon: "ui.mail",
|
|
361
|
-
* description: "Messages will appear here",
|
|
362
|
-
* action: ui.button({ id: "compose", label: "Compose" })
|
|
363
|
-
* })
|
|
364
|
-
* ```
|
|
365
|
-
*/
|
|
366
|
-
function empty(title, props = {}) {
|
|
367
|
-
return { kind: "empty", props: { title, ...props } };
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Create an error display widget.
|
|
371
|
-
*
|
|
372
|
-
* @param message - Error message
|
|
373
|
-
* @param props - Optional error display props
|
|
374
|
-
*
|
|
375
|
-
* @example
|
|
376
|
-
* ```ts
|
|
377
|
-
* ui.errorDisplay("Failed to load data")
|
|
378
|
-
* ui.errorDisplay("Connection failed", {
|
|
379
|
-
* title: "Network Error",
|
|
380
|
-
* onRetry: () => refetch()
|
|
381
|
-
* })
|
|
382
|
-
* ui.errorDisplay("Unexpected error", {
|
|
383
|
-
* stack: error.stack,
|
|
384
|
-
* showStack: true
|
|
385
|
-
* })
|
|
386
|
-
* ```
|
|
387
|
-
*/
|
|
388
|
-
function errorDisplay(message, props = {}) {
|
|
389
|
-
return { kind: "errorDisplay", props: { message, ...props } };
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Create an error boundary widget.
|
|
393
|
-
*
|
|
394
|
-
* @param props - Boundary config with protected children and fallback renderer
|
|
395
|
-
*
|
|
396
|
-
* @example
|
|
397
|
-
* ```ts
|
|
398
|
-
* ui.errorBoundary({
|
|
399
|
-
* children: RiskyWidget(),
|
|
400
|
-
* fallback: (error) =>
|
|
401
|
-
* ui.column({}, [
|
|
402
|
-
* ui.errorDisplay(error.message, { title: error.code }),
|
|
403
|
-
* ui.button({ id: "retry", label: "Retry", onPress: error.retry }),
|
|
404
|
-
* ]),
|
|
405
|
-
* })
|
|
406
|
-
* ```
|
|
407
|
-
*/
|
|
408
|
-
function errorBoundary(props) {
|
|
409
|
-
return { kind: "errorBoundary", props };
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Create a callout/alert widget.
|
|
413
|
-
*
|
|
414
|
-
* @param message - Callout message
|
|
415
|
-
* @param props - Optional callout props
|
|
416
|
-
*
|
|
417
|
-
* @example
|
|
418
|
-
* ```ts
|
|
419
|
-
* ui.callout("This action cannot be undone", { variant: "warning" })
|
|
420
|
-
* ui.callout("Changes saved successfully", { variant: "success" })
|
|
421
|
-
* ui.callout("New feature available", {
|
|
422
|
-
* variant: "info",
|
|
423
|
-
* title: "What's New"
|
|
424
|
-
* })
|
|
425
|
-
* ```
|
|
426
|
-
*/
|
|
427
|
-
function callout(message, props = {}) {
|
|
428
|
-
return { kind: "callout", props: { message, ...props } };
|
|
429
|
-
}
|
|
430
|
-
function link(props) {
|
|
431
|
-
return { kind: "link", props };
|
|
432
|
-
}
|
|
433
|
-
function canvas(props) {
|
|
434
|
-
return { kind: "canvas", props };
|
|
435
|
-
}
|
|
436
|
-
function image(props) {
|
|
437
|
-
return { kind: "image", props };
|
|
438
|
-
}
|
|
439
|
-
function lineChart(props) {
|
|
440
|
-
return { kind: "lineChart", props };
|
|
441
|
-
}
|
|
442
|
-
function scatter(props) {
|
|
443
|
-
return { kind: "scatter", props };
|
|
444
|
-
}
|
|
445
|
-
function heatmap(props) {
|
|
446
|
-
return { kind: "heatmap", props };
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Create a sparkline widget (mini inline chart using block characters).
|
|
450
|
-
*
|
|
451
|
-
* @param data - Array of numeric data points
|
|
452
|
-
* @param props - Optional sparkline props
|
|
453
|
-
*
|
|
454
|
-
* @example
|
|
455
|
-
* ```ts
|
|
456
|
-
* ui.sparkline([10, 20, 15, 30, 25])
|
|
457
|
-
* ui.sparkline(cpuHistory, { width: 10 })
|
|
458
|
-
* ui.sparkline(prices, { min: 0, max: 100 })
|
|
459
|
-
* ```
|
|
460
|
-
*/
|
|
461
|
-
function sparkline(data, props = {}) {
|
|
462
|
-
return { kind: "sparkline", props: { data, ...props } };
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Create a bar chart widget.
|
|
466
|
-
*
|
|
467
|
-
* @param data - Array of bar chart items
|
|
468
|
-
* @param props - Optional bar chart props
|
|
469
|
-
*
|
|
470
|
-
* @example
|
|
471
|
-
* ```ts
|
|
472
|
-
* ui.barChart([
|
|
473
|
-
* { label: "TypeScript", value: 60 },
|
|
474
|
-
* { label: "JavaScript", value: 30 },
|
|
475
|
-
* { label: "Python", value: 10 },
|
|
476
|
-
* ])
|
|
477
|
-
* ui.barChart(stats, { orientation: "vertical", showValues: true })
|
|
478
|
-
* ```
|
|
479
|
-
*/
|
|
480
|
-
function barChart(data, props = {}) {
|
|
481
|
-
return { kind: "barChart", props: { data, ...props } };
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Create a mini chart widget for compact multi-value display.
|
|
485
|
-
*
|
|
486
|
-
* @param values - Array of labeled values
|
|
487
|
-
* @param props - Optional mini chart props
|
|
488
|
-
*
|
|
489
|
-
* @example
|
|
490
|
-
* ```ts
|
|
491
|
-
* ui.miniChart([
|
|
492
|
-
* { label: "CPU", value: 42, max: 100 },
|
|
493
|
-
* { label: "MEM", value: 78, max: 100 },
|
|
494
|
-
* ])
|
|
495
|
-
* ui.miniChart(metrics, { variant: "pills" })
|
|
496
|
-
* ```
|
|
497
|
-
*/
|
|
498
|
-
function miniChart(values, props = {}) {
|
|
499
|
-
return { kind: "miniChart", props: { values, ...props } };
|
|
500
|
-
}
|
|
501
|
-
function button(props) {
|
|
502
|
-
return { kind: "button", props: resolveButtonIntent(props) };
|
|
503
|
-
}
|
|
504
|
-
function input(props) {
|
|
505
|
-
return { kind: "input", props };
|
|
506
|
-
}
|
|
507
|
-
function textarea(props) {
|
|
508
|
-
return {
|
|
509
|
-
kind: "input",
|
|
510
|
-
props: {
|
|
511
|
-
...props,
|
|
512
|
-
multiline: true,
|
|
513
|
-
rows: props.rows ?? 3,
|
|
514
|
-
wordWrap: props.wordWrap ?? true,
|
|
515
|
-
},
|
|
516
|
-
};
|
|
517
|
-
}
|
|
518
|
-
function focusAnnouncer(props = {}) {
|
|
519
|
-
return { kind: "focusAnnouncer", props };
|
|
520
|
-
}
|
|
521
|
-
function focusZone(props, children = []) {
|
|
522
|
-
return { kind: "focusZone", props, children: filterChildren(children) };
|
|
523
|
-
}
|
|
524
|
-
function focusTrap(props, children = []) {
|
|
525
|
-
return { kind: "focusTrap", props, children: filterChildren(children) };
|
|
526
|
-
}
|
|
527
|
-
function virtualList(props) {
|
|
528
|
-
return { kind: "virtualList", props: props };
|
|
529
|
-
}
|
|
530
|
-
function layers(propsOrChildren, children = []) {
|
|
531
|
-
if (isUiChildren(propsOrChildren)) {
|
|
532
|
-
return { kind: "layers", props: {}, children: filterChildren(propsOrChildren) };
|
|
533
|
-
}
|
|
534
|
-
return { kind: "layers", props: propsOrChildren, children: filterChildren(children) };
|
|
535
|
-
}
|
|
536
|
-
function panel(titleOrOptions, children = []) {
|
|
537
|
-
const options = typeof titleOrOptions === "string" ? { title: titleOrOptions } : titleOrOptions;
|
|
538
|
-
const resolvedChildren = filterChildren(children);
|
|
539
|
-
const inner = resolvedChildren.length <= 1
|
|
540
|
-
? resolvedChildren
|
|
541
|
-
: [column({ gap: options.gap ?? 1 }, resolvedChildren)];
|
|
542
|
-
return box({
|
|
543
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
544
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
545
|
-
preset: "card",
|
|
546
|
-
...(options.title === undefined ? {} : { title: options.title }),
|
|
547
|
-
border: options.variant ?? "rounded",
|
|
548
|
-
p: options.p ?? 1,
|
|
549
|
-
...(options.style === undefined ? {} : { style: options.style }),
|
|
550
|
-
}, inner);
|
|
551
|
-
}
|
|
552
|
-
function form(optionsOrChildren, children = []) {
|
|
553
|
-
if (isUiChildren(optionsOrChildren)) {
|
|
554
|
-
return column({ gap: 1 }, optionsOrChildren);
|
|
555
|
-
}
|
|
556
|
-
const options = optionsOrChildren;
|
|
557
|
-
return column({
|
|
558
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
559
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
560
|
-
gap: options.gap ?? 1,
|
|
561
|
-
}, children);
|
|
562
|
-
}
|
|
563
|
-
function actions(optionsOrChildren, children = []) {
|
|
564
|
-
if (isUiChildren(optionsOrChildren)) {
|
|
565
|
-
return row({ justify: "end", gap: 1 }, optionsOrChildren);
|
|
566
|
-
}
|
|
567
|
-
const options = optionsOrChildren;
|
|
568
|
-
return row({
|
|
569
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
570
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
571
|
-
justify: "end",
|
|
572
|
-
gap: options.gap ?? 1,
|
|
573
|
-
}, children);
|
|
574
|
-
}
|
|
575
|
-
function center(child, options = {}) {
|
|
576
|
-
return column({
|
|
577
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
578
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
579
|
-
width: "full",
|
|
580
|
-
height: "full",
|
|
581
|
-
align: "center",
|
|
582
|
-
justify: "center",
|
|
583
|
-
...(options.p === undefined ? {} : { p: options.p }),
|
|
584
|
-
}, [child]);
|
|
585
|
-
}
|
|
586
|
-
function page(options) {
|
|
587
|
-
const { id, key, header, body, footer, gap, p, width, height, ...layoutConstraints } = options;
|
|
588
|
-
return column({
|
|
589
|
-
...(id === undefined ? {} : { id }),
|
|
590
|
-
...(key === undefined ? {} : { key }),
|
|
591
|
-
width: width ?? "full",
|
|
592
|
-
height: height ?? "full",
|
|
593
|
-
...layoutConstraints,
|
|
594
|
-
gap: gap ?? 1,
|
|
595
|
-
...(p === undefined ? {} : { p }),
|
|
596
|
-
}, [header ?? null, box({ border: "none", flex: 1 }, [body]), footer ?? null]);
|
|
597
|
-
}
|
|
598
|
-
function appShell(options) {
|
|
599
|
-
const { id, key, header, sidebar, body, footer, gap, p, ...layoutConstraints } = options;
|
|
600
|
-
const headerNode = header ? box({ border: "rounded", px: 1, py: 0 }, [header]) : null;
|
|
601
|
-
const bodyNode = sidebar
|
|
602
|
-
? row({ gap: 1, items: "stretch" }, [
|
|
603
|
-
box({ border: "rounded", width: sidebar.width ?? 25, p: 1 }, [sidebar.content]),
|
|
604
|
-
box({ flex: 1 }, [body]),
|
|
605
|
-
])
|
|
606
|
-
: body;
|
|
607
|
-
const footerNode = footer ? row({ gap: 1, items: "center", wrap: true }, [footer]) : null;
|
|
608
|
-
return page({
|
|
609
|
-
...(id === undefined ? {} : { id }),
|
|
610
|
-
...(key === undefined ? {} : { key }),
|
|
611
|
-
header: headerNode,
|
|
612
|
-
body: bodyNode,
|
|
613
|
-
footer: footerNode,
|
|
614
|
-
gap: gap ?? 1,
|
|
615
|
-
p: p ?? 1,
|
|
616
|
-
...layoutConstraints,
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
function card(optionsOrTitle, children = []) {
|
|
620
|
-
const options = typeof optionsOrTitle === "string" ? { title: optionsOrTitle } : optionsOrTitle;
|
|
621
|
-
const bodyChildren = filterChildren(children);
|
|
622
|
-
const headerActions = options.actions ?? [];
|
|
623
|
-
const cardChildren = [];
|
|
624
|
-
if (options.title !== undefined || headerActions.length > 0) {
|
|
625
|
-
cardChildren.push(row({ gap: 1, items: "center", wrap: true }, [
|
|
626
|
-
...(options.title === undefined ? [] : [text(options.title, { variant: "heading" })]),
|
|
627
|
-
...(headerActions.length === 0 ? [] : [spacer({ flex: 1 }), ...headerActions]),
|
|
628
|
-
]));
|
|
629
|
-
}
|
|
630
|
-
if (options.subtitle !== undefined) {
|
|
631
|
-
cardChildren.push(text(options.subtitle, { dim: true }));
|
|
632
|
-
}
|
|
633
|
-
cardChildren.push(...bodyChildren);
|
|
634
|
-
return box({
|
|
635
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
636
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
637
|
-
preset: "card",
|
|
638
|
-
border: options.border ?? "rounded",
|
|
639
|
-
p: options.p ?? 1,
|
|
640
|
-
...(options.style === undefined ? {} : { style: options.style }),
|
|
641
|
-
}, [column({ gap: options.gap ?? 1 }, cardChildren)]);
|
|
642
|
-
}
|
|
643
|
-
function toolbar(optionsOrChildren, children = []) {
|
|
644
|
-
if (isUiChildren(optionsOrChildren)) {
|
|
645
|
-
return row({ gap: 1, items: "center", wrap: true }, optionsOrChildren);
|
|
646
|
-
}
|
|
647
|
-
const options = optionsOrChildren;
|
|
648
|
-
return row({
|
|
649
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
650
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
651
|
-
gap: options.gap ?? 1,
|
|
652
|
-
items: "center",
|
|
653
|
-
wrap: true,
|
|
654
|
-
}, children);
|
|
655
|
-
}
|
|
656
|
-
function statusBar(options) {
|
|
657
|
-
return row({
|
|
658
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
659
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
660
|
-
width: "full",
|
|
661
|
-
items: "center",
|
|
662
|
-
...(options.style === undefined ? {} : { style: options.style }),
|
|
663
|
-
}, [...(options.left ?? []), spacer({ flex: 1 }), ...(options.right ?? [])]);
|
|
664
|
-
}
|
|
665
|
-
function header(options) {
|
|
666
|
-
return box({
|
|
667
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
668
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
669
|
-
border: "rounded",
|
|
670
|
-
px: 1,
|
|
671
|
-
py: 0,
|
|
672
|
-
}, [
|
|
673
|
-
row({ gap: 1, items: "center", wrap: true }, [
|
|
674
|
-
text(options.title, { variant: "heading" }),
|
|
675
|
-
options.subtitle ? text(options.subtitle, { dim: true }) : null,
|
|
676
|
-
spacer({ flex: 1 }),
|
|
677
|
-
...(options.actions ?? []),
|
|
678
|
-
]),
|
|
679
|
-
]);
|
|
680
|
-
}
|
|
681
|
-
function sidebar(options) {
|
|
682
|
-
const buttonNodes = options.items.map((item) => button({
|
|
683
|
-
id: `${options.id ?? "sidebar"}-${item.id}`,
|
|
684
|
-
label: item.icon ? `${item.icon} ${item.label}` : item.label,
|
|
685
|
-
onPress: () => {
|
|
686
|
-
options.onSelect?.(item.id);
|
|
687
|
-
},
|
|
688
|
-
dsVariant: options.selected === item.id ? "soft" : "ghost",
|
|
689
|
-
dsTone: options.selected === item.id ? "primary" : "default",
|
|
690
|
-
}));
|
|
691
|
-
return box({
|
|
692
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
693
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
694
|
-
border: "rounded",
|
|
695
|
-
width: options.width ?? 25,
|
|
696
|
-
p: 1,
|
|
697
|
-
}, [
|
|
698
|
-
column({ gap: 1 }, [
|
|
699
|
-
options.title ? text(options.title, { variant: "heading" }) : null,
|
|
700
|
-
column({ gap: 0 }, buttonNodes),
|
|
701
|
-
]),
|
|
702
|
-
]);
|
|
703
|
-
}
|
|
704
|
-
function masterDetail(options) {
|
|
705
|
-
return row({
|
|
706
|
-
...(options.id === undefined ? {} : { id: options.id }),
|
|
707
|
-
...(options.key === undefined ? {} : { key: options.key }),
|
|
708
|
-
gap: options.gap ?? 1,
|
|
709
|
-
items: "stretch",
|
|
710
|
-
}, [
|
|
711
|
-
box({ width: options.masterWidth ?? 30 }, [options.master]),
|
|
712
|
-
box({ flex: 1 }, [options.detail]),
|
|
713
|
-
]);
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Widget factory functions for building VNode trees.
|
|
717
|
-
*
|
|
718
|
-
* @example
|
|
719
|
-
* ```ts
|
|
720
|
-
* ui.column({ p: 1 }, [
|
|
721
|
-
* ui.text("Hello"),
|
|
722
|
-
* ui.button({ id: "ok", label: "OK" }),
|
|
723
|
-
* ])
|
|
724
|
-
* ```
|
|
725
|
-
*/
|
|
2
|
+
* packages/core/src/widgets/ui.ts — Widget factory public facade.
|
|
3
|
+
*/
|
|
4
|
+
import { codeEditor, commandPalette, dialog, diffViewer, dropdown, filePicker, fileTreeExplorer, layer, logsConsole, modal, panelGroup, resizablePanel, splitPane, table, toastContainer, toolApprovalDialog, tree, } from "./factories/advanced.js";
|
|
5
|
+
import { box, column, divider, grid, row, spacer, text, themed } from "./factories/basic.js";
|
|
6
|
+
import { badge, callout, empty, errorBoundary, errorDisplay, gauge, icon, kbd, keybindingHelp, link, progress, richText, skeleton, spinner, status, tag, } from "./factories/feedback.js";
|
|
7
|
+
import { button, checkbox, field, focusAnnouncer, focusTrap, focusZone, input, radioGroup, select, slider, textarea, virtualList, } from "./factories/interactive.js";
|
|
8
|
+
import { actions, appShell, card, center, form, header, layers, masterDetail, page, panel, sidebar, statusBar, toolbar, } from "./factories/layoutShell.js";
|
|
9
|
+
import { barChart, canvas, heatmap, image, lineChart, miniChart, scatter, sparkline, } from "./factories/media.js";
|
|
10
|
+
import { accordion, breadcrumb, pagination, routerBreadcrumb, routerTabs, tabs, } from "./factories/navigation.js";
|
|
726
11
|
export const ui = {
|
|
727
12
|
text,
|
|
728
13
|
box,
|
|
@@ -776,543 +61,33 @@ export const ui = {
|
|
|
776
61
|
header,
|
|
777
62
|
sidebar,
|
|
778
63
|
masterDetail,
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
return button({
|
|
808
|
-
id: action.id ?? `${modalProps.id}-action-${String(index)}`,
|
|
809
|
-
label: action.label,
|
|
810
|
-
onPress: action.onPress,
|
|
811
|
-
...intentProps,
|
|
812
|
-
...(action.disabled === true ? { disabled: true } : {}),
|
|
813
|
-
...(action.focusable === false ? { focusable: false } : {}),
|
|
814
|
-
});
|
|
815
|
-
}),
|
|
816
|
-
},
|
|
817
|
-
};
|
|
818
|
-
},
|
|
819
|
-
/**
|
|
820
|
-
* Create a modal overlay.
|
|
821
|
-
* Renders centered with optional backdrop and focus trap.
|
|
822
|
-
*
|
|
823
|
-
* @example
|
|
824
|
-
* ```ts
|
|
825
|
-
* ui.modal({
|
|
826
|
-
* id: "confirm",
|
|
827
|
-
* title: "Confirm Action",
|
|
828
|
-
* content: ui.text("Are you sure?"),
|
|
829
|
-
* actions: [
|
|
830
|
-
* ui.button({ id: "yes", label: "Yes" }),
|
|
831
|
-
* ui.button({ id: "no", label: "No" }),
|
|
832
|
-
* ],
|
|
833
|
-
* onClose: () => app.update({ showModal: false }),
|
|
834
|
-
* })
|
|
835
|
-
* ```
|
|
836
|
-
*/
|
|
837
|
-
modal(props) {
|
|
838
|
-
return { kind: "modal", props };
|
|
839
|
-
},
|
|
840
|
-
/**
|
|
841
|
-
* Create a dropdown menu positioned relative to an anchor.
|
|
842
|
-
* Automatically flips when near screen edge.
|
|
843
|
-
*
|
|
844
|
-
* @example
|
|
845
|
-
* ```ts
|
|
846
|
-
* ui.dropdown({
|
|
847
|
-
* id: "file-menu",
|
|
848
|
-
* anchorId: "file-button",
|
|
849
|
-
* position: "below-start",
|
|
850
|
-
* items: [
|
|
851
|
-
* { id: "new", label: "New", shortcut: "Ctrl+N" },
|
|
852
|
-
* { id: "open", label: "Open", shortcut: "Ctrl+O" },
|
|
853
|
-
* { id: "divider", label: "", divider: true },
|
|
854
|
-
* { id: "exit", label: "Exit" },
|
|
855
|
-
* ],
|
|
856
|
-
* onSelect: (item) => handleAction(item.id),
|
|
857
|
-
* onClose: () => app.update({ menuOpen: false }),
|
|
858
|
-
* })
|
|
859
|
-
* ```
|
|
860
|
-
*/
|
|
861
|
-
dropdown(props) {
|
|
862
|
-
return { kind: "dropdown", props };
|
|
863
|
-
},
|
|
864
|
-
/**
|
|
865
|
-
* Create a generic layer in the layer stack.
|
|
866
|
-
* Use for custom overlays that need z-order control.
|
|
867
|
-
*
|
|
868
|
-
* @example
|
|
869
|
-
* ```ts
|
|
870
|
-
* ui.layer({
|
|
871
|
-
* id: "tooltip",
|
|
872
|
-
* content: ui.text("Tooltip text"),
|
|
873
|
-
* zIndex: 100,
|
|
874
|
-
* })
|
|
875
|
-
* ```
|
|
876
|
-
*/
|
|
877
|
-
layer(props) {
|
|
878
|
-
return { kind: "layer", props };
|
|
879
|
-
},
|
|
880
|
-
/**
|
|
881
|
-
* Create a table widget for displaying tabular data.
|
|
882
|
-
* Supports sorting, selection, and virtualization for large datasets.
|
|
883
|
-
*
|
|
884
|
-
* @example
|
|
885
|
-
* ```ts
|
|
886
|
-
* ui.table({
|
|
887
|
-
* id: "files",
|
|
888
|
-
* columns: [
|
|
889
|
-
* { key: "name", header: "Name", flex: 1, sortable: true, overflow: "middle" },
|
|
890
|
-
* { key: "size", header: "Size", width: 10, align: "right", overflow: "clip" },
|
|
891
|
-
* { key: "actions", header: "", width: 8, render: (_, row) =>
|
|
892
|
-
* ui.button({ id: `del-${row.id}`, label: "Del" }) },
|
|
893
|
-
* ],
|
|
894
|
-
* data: files,
|
|
895
|
-
* getRowKey: (f) => f.id,
|
|
896
|
-
* selection: state.selected,
|
|
897
|
-
* selectionMode: "multi",
|
|
898
|
-
* onSelectionChange: (keys) => app.update({ selected: keys }),
|
|
899
|
-
* sortColumn: state.sortCol,
|
|
900
|
-
* sortDirection: state.sortDir,
|
|
901
|
-
* onSort: (col, dir) => app.update({ sortCol: col, sortDir: dir }),
|
|
902
|
-
* stripeStyle: { odd: rgb(30, 33, 41) },
|
|
903
|
-
* borderStyle: { variant: "double", color: rgb(130, 140, 150) },
|
|
904
|
-
* })
|
|
905
|
-
* ```
|
|
906
|
-
*/
|
|
907
|
-
table(props) {
|
|
908
|
-
return { kind: "table", props: props };
|
|
909
|
-
},
|
|
910
|
-
/**
|
|
911
|
-
* Create a tree widget for displaying hierarchical data.
|
|
912
|
-
* Supports expand/collapse, selection, and lazy loading.
|
|
913
|
-
*
|
|
914
|
-
* @example
|
|
915
|
-
* ```ts
|
|
916
|
-
* ui.tree<FileNode>({
|
|
917
|
-
* id: "file-tree",
|
|
918
|
-
* data: fileSystem,
|
|
919
|
-
* getKey: (n) => n.path,
|
|
920
|
-
* getChildren: (n) => n.children,
|
|
921
|
-
* hasChildren: (n) => n.type === "directory",
|
|
922
|
-
* expanded: state.expandedPaths,
|
|
923
|
-
* selected: state.selectedPath,
|
|
924
|
-
* onChange: (node, exp) => app.update(s => ({
|
|
925
|
-
* expandedPaths: exp
|
|
926
|
-
* ? [...s.expandedPaths, node.path]
|
|
927
|
-
* : s.expandedPaths.filter(p => p !== node.path)
|
|
928
|
-
* })),
|
|
929
|
-
* onSelect: (n) => app.update({ selectedPath: n.path }),
|
|
930
|
-
* onPress: (n) => n.type === "file" && openFile(n.path),
|
|
931
|
-
* renderNode: (node, depth, state) => ui.row({ gap: 1 }, [
|
|
932
|
-
* ui.text(state.expanded ? "▼" : state.hasChildren ? "▶" : " "),
|
|
933
|
-
* ui.text(node.type === "directory" ? "📁" : "📄"),
|
|
934
|
-
* ui.text(node.name),
|
|
935
|
-
* ]),
|
|
936
|
-
* showLines: true,
|
|
937
|
-
* })
|
|
938
|
-
* ```
|
|
939
|
-
*/
|
|
940
|
-
tree(props) {
|
|
941
|
-
return { kind: "tree", props: props };
|
|
942
|
-
},
|
|
943
|
-
/* ========== Form Widgets (GitHub issue #119) ========== */
|
|
944
|
-
/**
|
|
945
|
-
* Create a field wrapper for form inputs.
|
|
946
|
-
* Displays label, error message, and optional hint.
|
|
947
|
-
*
|
|
948
|
-
* @example
|
|
949
|
-
* ```ts
|
|
950
|
-
* ui.field({
|
|
951
|
-
* label: "Username",
|
|
952
|
-
* required: true,
|
|
953
|
-
* error: form.touched.username && form.errors.username,
|
|
954
|
-
* hint: "Enter your email address",
|
|
955
|
-
* children: ui.input(form.bind("username")),
|
|
956
|
-
* })
|
|
957
|
-
* ```
|
|
958
|
-
*/
|
|
959
|
-
field(props) {
|
|
960
|
-
return { kind: "field", props, children: Object.freeze([props.children]) };
|
|
961
|
-
},
|
|
962
|
-
/**
|
|
963
|
-
* Create a select dropdown widget.
|
|
964
|
-
* Supports keyboard navigation with ArrowUp/Down and Enter.
|
|
965
|
-
*
|
|
966
|
-
* @example
|
|
967
|
-
* ```ts
|
|
968
|
-
* ui.select({
|
|
969
|
-
* id: "country",
|
|
970
|
-
* value: form.values.country,
|
|
971
|
-
* options: [
|
|
972
|
-
* { value: "us", label: "United States" },
|
|
973
|
-
* { value: "uk", label: "United Kingdom" },
|
|
974
|
-
* { value: "ca", label: "Canada" },
|
|
975
|
-
* ],
|
|
976
|
-
* onChange: form.handleChange("country"),
|
|
977
|
-
* placeholder: "Select a country...",
|
|
978
|
-
* })
|
|
979
|
-
* ```
|
|
980
|
-
*/
|
|
981
|
-
select(props) {
|
|
982
|
-
return { kind: "select", props };
|
|
983
|
-
},
|
|
984
|
-
/**
|
|
985
|
-
* Create a slider widget.
|
|
986
|
-
* Supports keyboard adjustment with Left/Right (or Up/Down), Home/End, and PageUp/PageDown.
|
|
987
|
-
*
|
|
988
|
-
* @example
|
|
989
|
-
* ```ts
|
|
990
|
-
* ui.slider({
|
|
991
|
-
* id: "volume",
|
|
992
|
-
* value: state.volume,
|
|
993
|
-
* min: 0,
|
|
994
|
-
* max: 100,
|
|
995
|
-
* step: 5,
|
|
996
|
-
* onChange: (value) => app.update({ volume: value }),
|
|
997
|
-
* })
|
|
998
|
-
* ```
|
|
999
|
-
*/
|
|
1000
|
-
slider(props) {
|
|
1001
|
-
return { kind: "slider", props };
|
|
1002
|
-
},
|
|
1003
|
-
/**
|
|
1004
|
-
* Create a checkbox widget.
|
|
1005
|
-
* Toggles with Space key.
|
|
1006
|
-
*
|
|
1007
|
-
* @example
|
|
1008
|
-
* ```ts
|
|
1009
|
-
* ui.checkbox({
|
|
1010
|
-
* id: "remember",
|
|
1011
|
-
* checked: form.values.remember,
|
|
1012
|
-
* label: "Remember me",
|
|
1013
|
-
* onChange: (c) => form.setFieldValue("remember", c),
|
|
1014
|
-
* })
|
|
1015
|
-
* ```
|
|
1016
|
-
*/
|
|
1017
|
-
checkbox(props) {
|
|
1018
|
-
return { kind: "checkbox", props };
|
|
1019
|
-
},
|
|
1020
|
-
/**
|
|
1021
|
-
* Create a radio group widget.
|
|
1022
|
-
* Supports keyboard navigation with ArrowUp/Down for selection.
|
|
1023
|
-
*
|
|
1024
|
-
* @example
|
|
1025
|
-
* ```ts
|
|
1026
|
-
* ui.radioGroup({
|
|
1027
|
-
* id: "plan",
|
|
1028
|
-
* value: form.values.plan,
|
|
1029
|
-
* options: [
|
|
1030
|
-
* { value: "free", label: "Free" },
|
|
1031
|
-
* { value: "pro", label: "Pro" },
|
|
1032
|
-
* { value: "enterprise", label: "Enterprise" },
|
|
1033
|
-
* ],
|
|
1034
|
-
* onChange: form.handleChange("plan"),
|
|
1035
|
-
* direction: "vertical",
|
|
1036
|
-
* })
|
|
1037
|
-
* ```
|
|
1038
|
-
*/
|
|
1039
|
-
radioGroup(props) {
|
|
1040
|
-
return { kind: "radioGroup", props };
|
|
1041
|
-
},
|
|
1042
|
-
/* ========== Navigation Widgets ========== */
|
|
1043
|
-
/**
|
|
1044
|
-
* Create a tabs widget.
|
|
1045
|
-
* Supports Left/Right tab switching and scoped content focus.
|
|
1046
|
-
*/
|
|
1047
|
-
tabs(props) {
|
|
1048
|
-
return createTabsWidgetVNode(props);
|
|
1049
|
-
},
|
|
1050
|
-
/**
|
|
1051
|
-
* Create breadcrumbs from current router history.
|
|
1052
|
-
*/
|
|
1053
|
-
routerBreadcrumb(router, routes, props = {}) {
|
|
1054
|
-
return buildRouterBreadcrumb(router, routes, props);
|
|
1055
|
-
},
|
|
1056
|
-
/**
|
|
1057
|
-
* Create tabs from registered routes with current route selection.
|
|
1058
|
-
*/
|
|
1059
|
-
routerTabs(router, routes, props = {}) {
|
|
1060
|
-
return buildRouterTabs(router, routes, props);
|
|
1061
|
-
},
|
|
1062
|
-
/**
|
|
1063
|
-
* Create an accordion widget.
|
|
1064
|
-
* Supports Up/Down header navigation and Enter/Space toggles.
|
|
1065
|
-
*/
|
|
1066
|
-
accordion(props) {
|
|
1067
|
-
return createAccordionWidgetVNode(props);
|
|
1068
|
-
},
|
|
1069
|
-
/**
|
|
1070
|
-
* Create a breadcrumb widget.
|
|
1071
|
-
* The last item is rendered as the current page (non-clickable).
|
|
1072
|
-
*/
|
|
1073
|
-
breadcrumb(props) {
|
|
1074
|
-
return createBreadcrumbWidgetVNode(props);
|
|
1075
|
-
},
|
|
1076
|
-
/**
|
|
1077
|
-
* Create a pagination widget.
|
|
1078
|
-
* Supports Left/Right navigation and optional Home/End first/last jumps.
|
|
1079
|
-
*/
|
|
1080
|
-
pagination(props) {
|
|
1081
|
-
return createPaginationWidgetVNode(props);
|
|
1082
|
-
},
|
|
1083
|
-
/* ========== Advanced Widgets (GitHub issue #136) ========== */
|
|
1084
|
-
/**
|
|
1085
|
-
* Create a command palette widget for quick-access command execution.
|
|
1086
|
-
* Supports search, keyboard navigation, and multiple command sources.
|
|
1087
|
-
*
|
|
1088
|
-
* @example
|
|
1089
|
-
* ```ts
|
|
1090
|
-
* ui.commandPalette({
|
|
1091
|
-
* id: "cmd-palette",
|
|
1092
|
-
* open: state.paletteOpen,
|
|
1093
|
-
* query: state.query,
|
|
1094
|
-
* sources: [
|
|
1095
|
-
* { id: "cmds", name: "Commands", prefix: ">", getItems: getCommands },
|
|
1096
|
-
* { id: "files", name: "Files", getItems: searchFiles },
|
|
1097
|
-
* ],
|
|
1098
|
-
* selectedIndex: state.selectedIndex,
|
|
1099
|
-
* onChange: (q) => app.update({ query: q }),
|
|
1100
|
-
* onSelect: (item) => executeCommand(item),
|
|
1101
|
-
* onClose: () => app.update({ paletteOpen: false }),
|
|
1102
|
-
* })
|
|
1103
|
-
* ```
|
|
1104
|
-
*/
|
|
1105
|
-
commandPalette(props) {
|
|
1106
|
-
return { kind: "commandPalette", props };
|
|
1107
|
-
},
|
|
1108
|
-
/**
|
|
1109
|
-
* Create a file picker widget for browsing workspace files.
|
|
1110
|
-
* Supports expand/collapse, multi-select, and git status indicators.
|
|
1111
|
-
*
|
|
1112
|
-
* @example
|
|
1113
|
-
* ```ts
|
|
1114
|
-
* ui.filePicker({
|
|
1115
|
-
* id: "file-picker",
|
|
1116
|
-
* rootPath: "/workspace",
|
|
1117
|
-
* data: fileTree,
|
|
1118
|
-
* selectedPath: state.selectedFile,
|
|
1119
|
-
* expandedPaths: state.expanded,
|
|
1120
|
-
* modifiedPaths: state.gitModified,
|
|
1121
|
-
* onSelect: (path) => app.update({ selectedFile: path }),
|
|
1122
|
-
* onChange: (path, exp) => toggleExpanded(path, exp),
|
|
1123
|
-
* onPress: (path) => openFile(path),
|
|
1124
|
-
* })
|
|
1125
|
-
* ```
|
|
1126
|
-
*/
|
|
1127
|
-
filePicker(props) {
|
|
1128
|
-
return { kind: "filePicker", props };
|
|
1129
|
-
},
|
|
1130
|
-
/**
|
|
1131
|
-
* Create a file tree explorer widget.
|
|
1132
|
-
* Provides tree view with expand/collapse and custom node rendering.
|
|
1133
|
-
*
|
|
1134
|
-
* @example
|
|
1135
|
-
* ```ts
|
|
1136
|
-
* ui.fileTreeExplorer({
|
|
1137
|
-
* id: "explorer",
|
|
1138
|
-
* data: fileTree,
|
|
1139
|
-
* expanded: state.expanded,
|
|
1140
|
-
* selected: state.selected,
|
|
1141
|
-
* showIcons: true,
|
|
1142
|
-
* showStatus: true,
|
|
1143
|
-
* onChange: (node, exp) => toggleNode(node, exp),
|
|
1144
|
-
* onSelect: (node) => selectNode(node),
|
|
1145
|
-
* onPress: (node) => openNode(node),
|
|
1146
|
-
* })
|
|
1147
|
-
* ```
|
|
1148
|
-
*/
|
|
1149
|
-
fileTreeExplorer(props) {
|
|
1150
|
-
return { kind: "fileTreeExplorer", props };
|
|
1151
|
-
},
|
|
1152
|
-
/**
|
|
1153
|
-
* Create a split pane widget with draggable dividers.
|
|
1154
|
-
* Supports horizontal/vertical splits with resize constraints.
|
|
1155
|
-
*
|
|
1156
|
-
* @example
|
|
1157
|
-
* ```ts
|
|
1158
|
-
* ui.splitPane({
|
|
1159
|
-
* id: "main-split",
|
|
1160
|
-
* direction: "horizontal",
|
|
1161
|
-
* sizes: [25, 50, 25],
|
|
1162
|
-
* minSizes: [20, 30, 20],
|
|
1163
|
-
* onChange: (sizes) => app.update({ panelSizes: sizes }),
|
|
1164
|
-
* }, [
|
|
1165
|
-
* FileExplorer(),
|
|
1166
|
-
* Editor(),
|
|
1167
|
-
* LogsPanel(),
|
|
1168
|
-
* ])
|
|
1169
|
-
* ```
|
|
1170
|
-
*/
|
|
1171
|
-
splitPane(props, children = []) {
|
|
1172
|
-
return { kind: "splitPane", props, children };
|
|
1173
|
-
},
|
|
1174
|
-
/**
|
|
1175
|
-
* Create a panel group container for resizable panels.
|
|
1176
|
-
* Manages layout and resize state for child panels.
|
|
1177
|
-
*
|
|
1178
|
-
* @example
|
|
1179
|
-
* ```ts
|
|
1180
|
-
* ui.panelGroup({
|
|
1181
|
-
* id: "panel-group",
|
|
1182
|
-
* direction: "horizontal",
|
|
1183
|
-
* }, [
|
|
1184
|
-
* ui.resizablePanel({ defaultSize: 25 }, [Sidebar()]),
|
|
1185
|
-
* ui.resizablePanel({ defaultSize: 75, minSize: 50 }, [Content()]),
|
|
1186
|
-
* ])
|
|
1187
|
-
* ```
|
|
1188
|
-
*/
|
|
1189
|
-
panelGroup(props, children = []) {
|
|
1190
|
-
return { kind: "panelGroup", props, children };
|
|
1191
|
-
},
|
|
1192
|
-
/**
|
|
1193
|
-
* Create a resizable panel within a panel group.
|
|
1194
|
-
* Specifies size constraints for the panel.
|
|
1195
|
-
*
|
|
1196
|
-
* @example
|
|
1197
|
-
* ```ts
|
|
1198
|
-
* ui.resizablePanel({
|
|
1199
|
-
* defaultSize: 30,
|
|
1200
|
-
* minSize: 20,
|
|
1201
|
-
* maxSize: 50,
|
|
1202
|
-
* collapsible: true,
|
|
1203
|
-
* }, [PanelContent()])
|
|
1204
|
-
* ```
|
|
1205
|
-
*/
|
|
1206
|
-
resizablePanel(props = {}, children = []) {
|
|
1207
|
-
return { kind: "resizablePanel", props, children };
|
|
1208
|
-
},
|
|
1209
|
-
/**
|
|
1210
|
-
* Create a code editor widget for multiline text editing.
|
|
1211
|
-
* Supports selections, keyboard navigation, and undo/redo.
|
|
1212
|
-
*
|
|
1213
|
-
* @example
|
|
1214
|
-
* ```ts
|
|
1215
|
-
* ui.codeEditor({
|
|
1216
|
-
* id: "editor",
|
|
1217
|
-
* lines: state.lines,
|
|
1218
|
-
* cursor: state.cursor,
|
|
1219
|
-
* selection: state.selection,
|
|
1220
|
-
* scrollTop: state.scrollTop,
|
|
1221
|
-
* scrollLeft: state.scrollLeft,
|
|
1222
|
-
* syntaxLanguage: "typescript",
|
|
1223
|
-
* lineNumbers: true,
|
|
1224
|
-
* tabSize: 2,
|
|
1225
|
-
* onChange: (lines, cursor) => app.update({ lines, cursor }),
|
|
1226
|
-
* onSelectionChange: (sel) => app.update({ selection: sel }),
|
|
1227
|
-
* onScroll: (top, left) => app.update({ scrollTop: top, scrollLeft: left }),
|
|
1228
|
-
* })
|
|
1229
|
-
* ```
|
|
1230
|
-
*/
|
|
1231
|
-
codeEditor(props) {
|
|
1232
|
-
return { kind: "codeEditor", props };
|
|
1233
|
-
},
|
|
1234
|
-
/**
|
|
1235
|
-
* Create a diff viewer widget for displaying file changes.
|
|
1236
|
-
* Supports unified and side-by-side modes with hunk staging.
|
|
1237
|
-
*
|
|
1238
|
-
* @example
|
|
1239
|
-
* ```ts
|
|
1240
|
-
* ui.diffViewer({
|
|
1241
|
-
* id: "diff",
|
|
1242
|
-
* diff: fileDiff,
|
|
1243
|
-
* mode: "unified",
|
|
1244
|
-
* scrollTop: state.scrollTop,
|
|
1245
|
-
* lineNumbers: true,
|
|
1246
|
-
* contextLines: 3,
|
|
1247
|
-
* onScroll: (top) => app.update({ scrollTop: top }),
|
|
1248
|
-
* onStageHunk: (i) => stageHunk(i),
|
|
1249
|
-
* onRevertHunk: (i) => revertHunk(i),
|
|
1250
|
-
* })
|
|
1251
|
-
* ```
|
|
1252
|
-
*/
|
|
1253
|
-
diffViewer(props) {
|
|
1254
|
-
return { kind: "diffViewer", props };
|
|
1255
|
-
},
|
|
1256
|
-
/**
|
|
1257
|
-
* Create a tool approval dialog for reviewing tool execution.
|
|
1258
|
-
* Shows tool details, risk level, and approval actions.
|
|
1259
|
-
*
|
|
1260
|
-
* @example
|
|
1261
|
-
* ```ts
|
|
1262
|
-
* ui.toolApprovalDialog({
|
|
1263
|
-
* id: "approval",
|
|
1264
|
-
* open: state.pendingApproval !== null,
|
|
1265
|
-
* request: state.pendingApproval,
|
|
1266
|
-
* onPress: (action) => action === "allow"
|
|
1267
|
-
* ? executeTool(state.pendingApproval)
|
|
1268
|
-
* : app.update({ pendingApproval: null }),
|
|
1269
|
-
* onAllowForSession: () => allowForSession(state.pendingApproval),
|
|
1270
|
-
* onClose: () => app.update({ pendingApproval: null }),
|
|
1271
|
-
* })
|
|
1272
|
-
* ```
|
|
1273
|
-
*/
|
|
1274
|
-
toolApprovalDialog(props) {
|
|
1275
|
-
return { kind: "toolApprovalDialog", props };
|
|
1276
|
-
},
|
|
1277
|
-
/**
|
|
1278
|
-
* Create a logs console widget for streaming output.
|
|
1279
|
-
* Supports filtering, auto-scroll, and expandable entries.
|
|
1280
|
-
*
|
|
1281
|
-
* @example
|
|
1282
|
-
* ```ts
|
|
1283
|
-
* ui.logsConsole({
|
|
1284
|
-
* id: "logs",
|
|
1285
|
-
* entries: state.logs,
|
|
1286
|
-
* autoScroll: true,
|
|
1287
|
-
* levelFilter: ["info", "warn", "error"],
|
|
1288
|
-
* scrollTop: state.logsScrollTop,
|
|
1289
|
-
* showTimestamps: true,
|
|
1290
|
-
* onScroll: (top) => app.update({ logsScrollTop: top }),
|
|
1291
|
-
* onPress: () => app.update({ logs: [] }),
|
|
1292
|
-
* })
|
|
1293
|
-
* ```
|
|
1294
|
-
*/
|
|
1295
|
-
logsConsole(props) {
|
|
1296
|
-
return { kind: "logsConsole", props };
|
|
1297
|
-
},
|
|
1298
|
-
/**
|
|
1299
|
-
* Create a toast container for non-blocking notifications.
|
|
1300
|
-
* Manages toast stack and auto-dismiss.
|
|
1301
|
-
*
|
|
1302
|
-
* @example
|
|
1303
|
-
* ```ts
|
|
1304
|
-
* ui.toastContainer({
|
|
1305
|
-
* toasts: state.toasts,
|
|
1306
|
-
* position: "bottom-right",
|
|
1307
|
-
* maxVisible: 5,
|
|
1308
|
-
* onClose: (id) => app.update(s => ({
|
|
1309
|
-
* toasts: s.toasts.filter(t => t.id !== id)
|
|
1310
|
-
* })),
|
|
1311
|
-
* })
|
|
1312
|
-
* ```
|
|
1313
|
-
*/
|
|
1314
|
-
toastContainer(props) {
|
|
1315
|
-
return { kind: "toastContainer", props };
|
|
1316
|
-
},
|
|
64
|
+
dialog,
|
|
65
|
+
modal,
|
|
66
|
+
dropdown,
|
|
67
|
+
layer,
|
|
68
|
+
table,
|
|
69
|
+
tree,
|
|
70
|
+
field,
|
|
71
|
+
select,
|
|
72
|
+
slider,
|
|
73
|
+
checkbox,
|
|
74
|
+
radioGroup,
|
|
75
|
+
tabs,
|
|
76
|
+
routerBreadcrumb,
|
|
77
|
+
routerTabs,
|
|
78
|
+
accordion,
|
|
79
|
+
breadcrumb,
|
|
80
|
+
pagination,
|
|
81
|
+
commandPalette,
|
|
82
|
+
filePicker,
|
|
83
|
+
fileTreeExplorer,
|
|
84
|
+
splitPane,
|
|
85
|
+
panelGroup,
|
|
86
|
+
resizablePanel,
|
|
87
|
+
codeEditor,
|
|
88
|
+
diffViewer,
|
|
89
|
+
toolApprovalDialog,
|
|
90
|
+
logsConsole,
|
|
91
|
+
toastContainer,
|
|
1317
92
|
};
|
|
1318
93
|
//# sourceMappingURL=ui.js.map
|