termcast 1.3.10 → 1.3.18
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/apis/toast.d.ts +1 -5
- package/dist/apis/toast.d.ts.map +1 -1
- package/dist/apis/toast.js +23 -17
- package/dist/apis/toast.js.map +1 -1
- package/dist/build.d.ts +2 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +4 -3
- package/dist/build.js.map +1 -1
- package/dist/cli.js +42 -0
- package/dist/cli.js.map +1 -1
- package/dist/colors.d.ts +8 -1
- package/dist/colors.d.ts.map +1 -1
- package/dist/colors.js +12 -0
- package/dist/colors.js.map +1 -1
- package/dist/compile.d.ts +30 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +156 -0
- package/dist/compile.js.map +1 -0
- package/dist/components/actions.d.ts +1 -0
- package/dist/components/actions.d.ts.map +1 -1
- package/dist/components/actions.js +5 -2
- package/dist/components/actions.js.map +1 -1
- package/dist/components/command-arguments.d.ts +9 -0
- package/dist/components/command-arguments.d.ts.map +1 -0
- package/dist/components/command-arguments.js +21 -0
- package/dist/components/command-arguments.js.map +1 -0
- package/dist/components/detail.d.ts +1 -1
- package/dist/components/detail.d.ts.map +1 -1
- package/dist/components/detail.js +17 -39
- package/dist/components/detail.js.map +1 -1
- package/dist/components/dropdown.d.ts +1 -0
- package/dist/components/dropdown.d.ts.map +1 -1
- package/dist/components/dropdown.js +77 -21
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/extension-preferences.d.ts.map +1 -1
- package/dist/components/extension-preferences.js +19 -29
- package/dist/components/extension-preferences.js.map +1 -1
- package/dist/components/form/checkbox.d.ts.map +1 -1
- package/dist/components/form/checkbox.js +9 -2
- package/dist/components/form/checkbox.js.map +1 -1
- package/dist/components/form/date-picker.d.ts.map +1 -1
- package/dist/components/form/date-picker.js +15 -28
- package/dist/components/form/date-picker.js.map +1 -1
- package/dist/components/form/description.d.ts +2 -0
- package/dist/components/form/description.d.ts.map +1 -1
- package/dist/components/form/description.js +20 -2
- package/dist/components/form/description.js.map +1 -1
- package/dist/components/form/dropdown.d.ts.map +1 -1
- package/dist/components/form/dropdown.js +13 -28
- package/dist/components/form/dropdown.js.map +1 -1
- package/dist/components/form/file-autocomplete.d.ts +7 -4
- package/dist/components/form/file-autocomplete.d.ts.map +1 -1
- package/dist/components/form/file-autocomplete.js +54 -46
- package/dist/components/form/file-autocomplete.js.map +1 -1
- package/dist/components/form/file-picker.d.ts +5 -0
- package/dist/components/form/file-picker.d.ts.map +1 -1
- package/dist/components/form/file-picker.js +46 -49
- package/dist/components/form/file-picker.js.map +1 -1
- package/dist/components/form/form-ref.d.ts +43 -0
- package/dist/components/form/form-ref.d.ts.map +1 -0
- package/dist/components/form/form-ref.js +53 -0
- package/dist/components/form/form-ref.js.map +1 -0
- package/dist/components/form/index.d.ts +16 -0
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +86 -23
- package/dist/components/form/index.js.map +1 -1
- package/dist/components/form/password-field.d.ts.map +1 -1
- package/dist/components/form/password-field.js +32 -16
- package/dist/components/form/password-field.js.map +1 -1
- package/dist/components/form/text-area.d.ts.map +1 -1
- package/dist/components/form/text-area.js +32 -15
- package/dist/components/form/text-area.js.map +1 -1
- package/dist/components/form/text-field.d.ts.map +1 -1
- package/dist/components/form/text-field.js +37 -17
- package/dist/components/form/text-field.js.map +1 -1
- package/dist/components/form/use-form-navigation.d.ts +4 -0
- package/dist/components/form/use-form-navigation.d.ts.map +1 -1
- package/dist/components/form/use-form-navigation.js +35 -18
- package/dist/components/form/use-form-navigation.js.map +1 -1
- package/dist/components/form/with-left-border.d.ts.map +1 -1
- package/dist/components/form/with-left-border.js +2 -2
- package/dist/components/form/with-left-border.js.map +1 -1
- package/dist/components/icon.d.ts +3 -1
- package/dist/components/icon.d.ts.map +1 -1
- package/dist/components/icon.js +494 -469
- package/dist/components/icon.js.map +1 -1
- package/dist/components/list.d.ts +11 -7
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +170 -38
- package/dist/components/list.js.map +1 -1
- package/dist/components/loading-bar.js +1 -1
- package/dist/components/loading-bar.js.map +1 -1
- package/dist/descendants.d.ts.map +1 -1
- package/dist/descendants.js +8 -5
- package/dist/descendants.js.map +1 -1
- package/dist/examples/action-show-in-finder.js +1 -1
- package/dist/examples/action-show-in-finder.js.map +1 -1
- package/dist/examples/environment-test.js +1 -1
- package/dist/examples/environment-test.js.map +1 -1
- package/dist/examples/error-boundary.js +1 -1
- package/dist/examples/error-boundary.js.map +1 -1
- package/dist/examples/form-basic.d.ts.map +1 -1
- package/dist/examples/form-basic.js +2 -2
- package/dist/examples/form-basic.js.map +1 -1
- package/dist/examples/form-dropdown.js +1 -1
- package/dist/examples/form-dropdown.js.map +1 -1
- package/dist/examples/form-scroll.d.ts +2 -0
- package/dist/examples/form-scroll.d.ts.map +1 -0
- package/dist/examples/form-scroll.js +8 -0
- package/dist/examples/form-scroll.js.map +1 -0
- package/dist/examples/form-tagpicker.js +1 -1
- package/dist/examples/form-tagpicker.js.map +1 -1
- package/dist/examples/internal/descendants-filtering.js +8 -3
- package/dist/examples/internal/descendants-filtering.js.map +1 -1
- package/dist/examples/internal/descendants.js +10 -3
- package/dist/examples/internal/descendants.js.map +1 -1
- package/dist/examples/internal/rhf-custom-ref.d.ts +2 -0
- package/dist/examples/internal/rhf-custom-ref.d.ts.map +1 -0
- package/dist/examples/internal/rhf-custom-ref.js +67 -0
- package/dist/examples/internal/rhf-custom-ref.js.map +1 -0
- package/dist/examples/internal/scrollbox-demo.js +3 -7
- package/dist/examples/internal/scrollbox-demo.js.map +1 -1
- package/dist/examples/internal/scrollbox-with-descendants.d.ts +2 -0
- package/dist/examples/internal/scrollbox-with-descendants.d.ts.map +1 -0
- package/dist/examples/internal/scrollbox-with-descendants.js +63 -0
- package/dist/examples/internal/scrollbox-with-descendants.js.map +1 -0
- package/dist/examples/internal/simple-dialog.js +1 -1
- package/dist/examples/internal/simple-dialog.js.map +1 -1
- package/dist/examples/internal/simple-scrollbox.js +2 -3
- package/dist/examples/internal/simple-scrollbox.js.map +1 -1
- package/dist/examples/internal/text-stacking.js +4 -2
- package/dist/examples/internal/text-stacking.js.map +1 -1
- package/dist/examples/list-dropdown-default.js +1 -1
- package/dist/examples/list-dropdown-default.js.map +1 -1
- package/dist/examples/list-fetch-data.js +1 -1
- package/dist/examples/list-fetch-data.js.map +1 -1
- package/dist/examples/list-scrollbox.d.ts +2 -0
- package/dist/examples/list-scrollbox.d.ts.map +1 -0
- package/dist/examples/list-scrollbox.js +29 -0
- package/dist/examples/list-scrollbox.js.map +1 -0
- package/dist/examples/list-with-detail.js +1 -1
- package/dist/examples/list-with-detail.js.map +1 -1
- package/dist/examples/list-with-dropdown.js +1 -1
- package/dist/examples/list-with-dropdown.js.map +1 -1
- package/dist/examples/list-with-sections.js +3 -3
- package/dist/examples/list-with-sections.js.map +1 -1
- package/dist/examples/miscellaneous.js +1 -1
- package/dist/examples/miscellaneous.js.map +1 -1
- package/dist/examples/nested-navigation.js +4 -2
- package/dist/examples/nested-navigation.js.map +1 -1
- package/dist/examples/preferences-test.js +1 -1
- package/dist/examples/preferences-test.js.map +1 -1
- package/dist/examples/simple-dropdown.js +1 -1
- package/dist/examples/simple-dropdown.js.map +1 -1
- package/dist/examples/simple-file-picker.js +1 -1
- package/dist/examples/simple-file-picker.js.map +1 -1
- package/dist/examples/simple-grid.js +1 -1
- package/dist/examples/simple-grid.js.map +1 -1
- package/dist/examples/simple-hud.js +1 -1
- package/dist/examples/simple-hud.js.map +1 -1
- package/dist/examples/simple-list-search.js +1 -1
- package/dist/examples/simple-list-search.js.map +1 -1
- package/dist/examples/simple-list.js +1 -1
- package/dist/examples/simple-list.js.map +1 -1
- package/dist/examples/simple-navigation.js +4 -2
- package/dist/examples/simple-navigation.js.map +1 -1
- package/dist/examples/store.js +1 -1
- package/dist/examples/store.js.map +1 -1
- package/dist/examples/submodule-diff.d.ts +2 -0
- package/dist/examples/submodule-diff.d.ts.map +1 -0
- package/dist/examples/submodule-diff.js +99 -0
- package/dist/examples/submodule-diff.js.map +1 -0
- package/dist/examples/tanstack-demo.js +1 -1
- package/dist/examples/tanstack-demo.js.map +1 -1
- package/dist/examples/use-promise-demo.js +1 -1
- package/dist/examples/use-promise-demo.js.map +1 -1
- package/dist/extensions/dev.d.ts +8 -0
- package/dist/extensions/dev.d.ts.map +1 -1
- package/dist/extensions/dev.js +53 -28
- package/dist/extensions/dev.js.map +1 -1
- package/dist/extensions/home.d.ts.map +1 -1
- package/dist/extensions/home.js +16 -91
- package/dist/extensions/home.js.map +1 -1
- package/dist/globals.js +1 -1
- package/dist/globals.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/date-picker-widget.d.ts.map +1 -1
- package/dist/internal/date-picker-widget.js +56 -48
- package/dist/internal/date-picker-widget.js.map +1 -1
- package/dist/internal/dialog.d.ts.map +1 -1
- package/dist/internal/dialog.js +7 -7
- package/dist/internal/dialog.js.map +1 -1
- package/dist/internal/scrollbox.d.ts +2 -1
- package/dist/internal/scrollbox.d.ts.map +1 -1
- package/dist/internal/scrollbox.js +13 -7
- package/dist/internal/scrollbox.js.map +1 -1
- package/dist/release.d.ts +11 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +113 -0
- package/dist/release.js.map +1 -0
- package/dist/state.d.ts +1 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +1 -0
- package/dist/state.js.map +1 -1
- package/dist/theme.d.ts +11 -8
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +31 -8
- package/dist/theme.js.map +1 -1
- package/dist/utils/run-command.d.ts +22 -0
- package/dist/utils/run-command.d.ts.map +1 -0
- package/dist/utils/run-command.js +127 -0
- package/dist/utils/run-command.js.map +1 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +5 -3
- package/dist/utils.js.map +1 -1
- package/package.json +10 -7
- package/src/apis/toast.tsx +38 -17
- package/src/build.tsx +5 -3
- package/src/cli.tsx +46 -0
- package/src/colors.tsx +22 -1
- package/src/compile.tsx +219 -0
- package/src/components/actions.tsx +7 -1
- package/src/components/command-arguments.tsx +81 -0
- package/src/components/detail.tsx +26 -58
- package/src/components/dropdown.tsx +108 -23
- package/src/components/extension-preferences.tsx +55 -35
- package/src/components/form/checkbox.tsx +13 -5
- package/src/components/form/date-picker.tsx +24 -29
- package/src/components/form/description.tsx +35 -7
- package/src/components/form/dropdown.tsx +16 -30
- package/src/components/form/file-autocomplete.tsx +87 -77
- package/src/components/form/file-picker.tsx +69 -57
- package/src/components/form/form-ref.tsx +68 -0
- package/src/components/form/index.tsx +152 -41
- package/src/components/form/password-field.tsx +35 -22
- package/src/components/form/text-area.tsx +78 -58
- package/src/components/form/text-field.tsx +82 -61
- package/src/components/form/use-form-navigation.tsx +43 -23
- package/src/components/form/with-left-border.tsx +2 -1
- package/src/components/icon.tsx +497 -469
- package/src/components/list.tsx +279 -112
- package/src/components/loading-bar.tsx +1 -1
- package/src/descendants.tsx +15 -5
- package/src/examples/action-show-in-finder.tsx +1 -1
- package/src/examples/environment-test.tsx +1 -1
- package/src/examples/error-boundary.tsx +1 -1
- package/src/examples/file-autocomplete.vitest.tsx +245 -0
- package/src/examples/form-basic.tsx +12 -12
- package/src/examples/form-basic.vitest.tsx +297 -671
- package/src/examples/form-dropdown.tsx +1 -1
- package/src/examples/form-dropdown.vitest.tsx +353 -221
- package/src/examples/form-scroll.tsx +56 -0
- package/src/examples/form-scroll.vitest.tsx +228 -0
- package/src/examples/form-tagpicker.tsx +1 -1
- package/src/examples/form-tagpicker.vitest.tsx +438 -193
- package/src/examples/internal/descendants-filtering.tsx +13 -5
- package/src/examples/internal/descendants.tsx +17 -5
- package/src/examples/internal/rhf-custom-ref.tsx +152 -0
- package/src/examples/internal/scrollbox-demo.tsx +15 -7
- package/src/examples/internal/scrollbox-with-descendants.tsx +94 -0
- package/src/examples/internal/simple-dialog.tsx +1 -1
- package/src/examples/internal/simple-scrollbox.tsx +8 -5
- package/src/examples/internal/simple-scrollbox.vitest.tsx +47 -37
- package/src/examples/internal/text-stacking.tsx +4 -2
- package/src/examples/list-dropdown-default.tsx +1 -1
- package/src/examples/list-dropdown-default.vitest.tsx +136 -71
- package/src/examples/list-fetch-data.tsx +1 -1
- package/src/examples/list-fetch-data.vitest.tsx +42 -33
- package/src/examples/list-scrollbox.tsx +46 -0
- package/src/examples/list-scrollbox.vitest.tsx +103 -0
- package/src/examples/list-with-detail.tsx +1 -1
- package/src/examples/list-with-detail.vitest.tsx +290 -294
- package/src/examples/list-with-dropdown.tsx +1 -1
- package/src/examples/list-with-dropdown.vitest.tsx +190 -150
- package/src/examples/list-with-sections.tsx +12 -1
- package/src/examples/list-with-sections.vitest.tsx +390 -218
- package/src/examples/miscellaneous.tsx +1 -1
- package/src/examples/nested-navigation.tsx +4 -2
- package/src/examples/preferences-test.tsx +1 -1
- package/src/examples/simple-dropdown.tsx +1 -1
- package/src/examples/simple-file-picker.tsx +1 -1
- package/src/examples/simple-file-picker.vitest.tsx +538 -132
- package/src/examples/simple-grid.tsx +1 -1
- package/src/examples/simple-grid.vitest.tsx +258 -234
- package/src/examples/simple-hud.tsx +1 -1
- package/src/examples/simple-list-search.tsx +1 -1
- package/src/examples/simple-list.tsx +1 -1
- package/src/examples/simple-navigation.tsx +4 -2
- package/src/examples/simple-navigation.vitest.tsx +434 -238
- package/src/examples/store.tsx +1 -1
- package/src/examples/store.vitest.tsx +31 -10
- package/src/examples/submodule-diff.tsx +153 -0
- package/src/examples/tanstack-demo.tsx +1 -1
- package/src/examples/use-promise-demo.tsx +1 -1
- package/src/extensions/dev.tsx +74 -36
- package/src/extensions/dev.vitest.tsx +220 -0
- package/src/extensions/home.tsx +17 -118
- package/src/globals.ts +1 -1
- package/src/index.tsx +7 -1
- package/src/internal/date-picker-widget.tsx +56 -46
- package/src/internal/dialog.tsx +6 -6
- package/src/internal/scrollbox.tsx +15 -5
- package/src/release.tsx +159 -0
- package/src/state.tsx +2 -0
- package/src/store-api/search.test.tsx +4 -13
- package/src/theme.tsx +33 -8
- package/src/utils/run-command.tsx +204 -0
- package/src/utils.tsx +5 -3
- package/dist/ai.d.ts +0 -104
- package/dist/ai.d.ts.map +0 -1
- package/dist/ai.js +0 -135
- package/dist/ai.js.map +0 -1
- package/dist/apis/cache.test.d.ts +0 -2
- package/dist/apis/cache.test.d.ts.map +0 -1
- package/dist/apis/cache.test.js +0 -246
- package/dist/apis/cache.test.js.map +0 -1
- package/dist/apis/localstorage.test.d.ts +0 -2
- package/dist/apis/localstorage.test.d.ts.map +0 -1
- package/dist/apis/localstorage.test.js +0 -131
- package/dist/apis/localstorage.test.js.map +0 -1
- package/dist/apis/toast.test.d.ts +0 -2
- package/dist/apis/toast.test.d.ts.map +0 -1
- package/dist/apis/toast.test.js +0 -67
- package/dist/apis/toast.test.js.map +0 -1
- package/dist/build.test.d.ts +0 -2
- package/dist/build.test.d.ts.map +0 -1
- package/dist/build.test.js +0 -73
- package/dist/build.test.js.map +0 -1
- package/dist/cache.d.ts +0 -32
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js +0 -205
- package/dist/cache.js.map +0 -1
- package/dist/cache.test.d.ts +0 -2
- package/dist/cache.test.d.ts.map +0 -1
- package/dist/cache.test.js +0 -246
- package/dist/cache.test.js.map +0 -1
- package/dist/clipboard.d.ts +0 -36
- package/dist/clipboard.d.ts.map +0 -1
- package/dist/clipboard.js +0 -154
- package/dist/clipboard.js.map +0 -1
- package/dist/components/form/form-type-only.d.ts +0 -174
- package/dist/components/form/form-type-only.d.ts.map +0 -1
- package/dist/components/form/form-type-only.js +0 -2
- package/dist/components/form/form-type-only.js.map +0 -1
- package/dist/components/form/use-form-handling.d.ts +0 -4
- package/dist/components/form/use-form-handling.d.ts.map +0 -1
- package/dist/components/form/use-form-handling.js +0 -37
- package/dist/components/form/use-form-handling.js.map +0 -1
- package/dist/dev-ui.d.ts +0 -7
- package/dist/dev-ui.d.ts.map +0 -1
- package/dist/dev-ui.js +0 -118
- package/dist/dev-ui.js.map +0 -1
- package/dist/environment.d.ts +0 -63
- package/dist/environment.d.ts.map +0 -1
- package/dist/environment.js +0 -189
- package/dist/environment.js.map +0 -1
- package/dist/examples/datepicker.d.ts +0 -2
- package/dist/examples/datepicker.d.ts.map +0 -1
- package/dist/examples/datepicker.js +0 -344
- package/dist/examples/datepicker.js.map +0 -1
- package/dist/examples/form-basic-arrow-keys.vitest.d.ts +0 -2
- package/dist/examples/form-basic-arrow-keys.vitest.d.ts.map +0 -1
- package/dist/examples/form-basic-arrow-keys.vitest.js +0 -46
- package/dist/examples/form-basic-arrow-keys.vitest.js.map +0 -1
- package/dist/examples/form-basic.vitest.d.ts +0 -2
- package/dist/examples/form-basic.vitest.d.ts.map +0 -1
- package/dist/examples/form-basic.vitest.js +0 -995
- package/dist/examples/form-basic.vitest.js.map +0 -1
- package/dist/examples/form-dropdown-with-sections.d.ts +0 -2
- package/dist/examples/form-dropdown-with-sections.d.ts.map +0 -1
- package/dist/examples/form-dropdown-with-sections.js +0 -13
- package/dist/examples/form-dropdown-with-sections.js.map +0 -1
- package/dist/examples/form-dropdown-with-sections.vitest.d.ts +0 -2
- package/dist/examples/form-dropdown-with-sections.vitest.d.ts.map +0 -1
- package/dist/examples/form-dropdown-with-sections.vitest.js +0 -75
- package/dist/examples/form-dropdown-with-sections.vitest.js.map +0 -1
- package/dist/examples/form-dropdown.vitest.d.ts +0 -2
- package/dist/examples/form-dropdown.vitest.d.ts.map +0 -1
- package/dist/examples/form-dropdown.vitest.js +0 -722
- package/dist/examples/form-dropdown.vitest.js.map +0 -1
- package/dist/examples/form-multiselect-dropdown.d.ts +0 -2
- package/dist/examples/form-multiselect-dropdown.d.ts.map +0 -1
- package/dist/examples/form-multiselect-dropdown.js +0 -13
- package/dist/examples/form-multiselect-dropdown.js.map +0 -1
- package/dist/examples/form-tagpicker.vitest.d.ts +0 -2
- package/dist/examples/form-tagpicker.vitest.d.ts.map +0 -1
- package/dist/examples/form-tagpicker.vitest.js +0 -491
- package/dist/examples/form-tagpicker.vitest.js.map +0 -1
- package/dist/examples/internal/nested-boxes.d.ts +0 -2
- package/dist/examples/internal/nested-boxes.d.ts.map +0 -1
- package/dist/examples/internal/nested-boxes.js +0 -7
- package/dist/examples/internal/nested-boxes.js.map +0 -1
- package/dist/examples/internal/simple-scrollbox.vitest.d.ts +0 -2
- package/dist/examples/internal/simple-scrollbox.vitest.d.ts.map +0 -1
- package/dist/examples/internal/simple-scrollbox.vitest.js +0 -88
- package/dist/examples/internal/simple-scrollbox.vitest.js.map +0 -1
- package/dist/examples/internal/unicode-square-repro.d.ts +0 -2
- package/dist/examples/internal/unicode-square-repro.d.ts.map +0 -1
- package/dist/examples/internal/unicode-square-repro.js +0 -7
- package/dist/examples/internal/unicode-square-repro.js.map +0 -1
- package/dist/examples/list-dropdown-default.vitest.d.ts +0 -2
- package/dist/examples/list-dropdown-default.vitest.d.ts.map +0 -1
- package/dist/examples/list-dropdown-default.vitest.js +0 -164
- package/dist/examples/list-dropdown-default.vitest.js.map +0 -1
- package/dist/examples/list-fetch-data.vitest.d.ts +0 -2
- package/dist/examples/list-fetch-data.vitest.d.ts.map +0 -1
- package/dist/examples/list-fetch-data.vitest.js +0 -103
- package/dist/examples/list-fetch-data.vitest.js.map +0 -1
- package/dist/examples/list-filter-navigation.d.ts +0 -2
- package/dist/examples/list-filter-navigation.d.ts.map +0 -1
- package/dist/examples/list-filter-navigation.js +0 -8
- package/dist/examples/list-filter-navigation.js.map +0 -1
- package/dist/examples/list-with-detail.vitest.d.ts +0 -2
- package/dist/examples/list-with-detail.vitest.d.ts.map +0 -1
- package/dist/examples/list-with-detail.vitest.js +0 -438
- package/dist/examples/list-with-detail.vitest.js.map +0 -1
- package/dist/examples/list-with-dropdown.vitest.d.ts +0 -2
- package/dist/examples/list-with-dropdown.vitest.d.ts.map +0 -1
- package/dist/examples/list-with-dropdown.vitest.js +0 -297
- package/dist/examples/list-with-dropdown.vitest.js.map +0 -1
- package/dist/examples/list-with-sections.vitest.d.ts +0 -2
- package/dist/examples/list-with-sections.vitest.d.ts.map +0 -1
- package/dist/examples/list-with-sections.vitest.js +0 -441
- package/dist/examples/list-with-sections.vitest.js.map +0 -1
- package/dist/examples/simple-file-picker.vitest.d.ts +0 -2
- package/dist/examples/simple-file-picker.vitest.d.ts.map +0 -1
- package/dist/examples/simple-file-picker.vitest.js +0 -277
- package/dist/examples/simple-file-picker.vitest.js.map +0 -1
- package/dist/examples/simple-grid.vitest.d.ts +0 -2
- package/dist/examples/simple-grid.vitest.d.ts.map +0 -1
- package/dist/examples/simple-grid.vitest.js +0 -498
- package/dist/examples/simple-grid.vitest.js.map +0 -1
- package/dist/examples/simple-navigation.vitest.d.ts +0 -2
- package/dist/examples/simple-navigation.vitest.d.ts.map +0 -1
- package/dist/examples/simple-navigation.vitest.js +0 -522
- package/dist/examples/simple-navigation.vitest.js.map +0 -1
- package/dist/examples/store.vitest.d.ts +0 -2
- package/dist/examples/store.vitest.d.ts.map +0 -1
- package/dist/examples/store.vitest.js +0 -48
- package/dist/examples/store.vitest.js.map +0 -1
- package/dist/home-command.d.ts +0 -8
- package/dist/home-command.d.ts.map +0 -1
- package/dist/home-command.js +0 -181
- package/dist/home-command.js.map +0 -1
- package/dist/hooks/hooks.test.d.ts +0 -2
- package/dist/hooks/hooks.test.d.ts.map +0 -1
- package/dist/hooks/hooks.test.js +0 -37
- package/dist/hooks/hooks.test.js.map +0 -1
- package/dist/hover-repro.d.ts +0 -2
- package/dist/hover-repro.d.ts.map +0 -1
- package/dist/hover-repro.js +0 -20
- package/dist/hover-repro.js.map +0 -1
- package/dist/localstorage.d.ts +0 -13
- package/dist/localstorage.d.ts.map +0 -1
- package/dist/localstorage.js +0 -190
- package/dist/localstorage.js.map +0 -1
- package/dist/localstorage.test.d.ts +0 -2
- package/dist/localstorage.test.d.ts.map +0 -1
- package/dist/localstorage.test.js +0 -131
- package/dist/localstorage.test.js.map +0 -1
- package/dist/oauth.d.ts +0 -142
- package/dist/oauth.d.ts.map +0 -1
- package/dist/oauth.js +0 -551
- package/dist/oauth.js.map +0 -1
- package/dist/preferences.d.ts +0 -23
- package/dist/preferences.d.ts.map +0 -1
- package/dist/preferences.js +0 -105
- package/dist/preferences.js.map +0 -1
- package/dist/store-api/download.test.d.ts +0 -2
- package/dist/store-api/download.test.d.ts.map +0 -1
- package/dist/store-api/download.test.js +0 -36
- package/dist/store-api/download.test.js.map +0 -1
- package/dist/store-api/extension.test.d.ts +0 -2
- package/dist/store-api/extension.test.d.ts.map +0 -1
- package/dist/store-api/extension.test.js +0 -22
- package/dist/store-api/extension.test.js.map +0 -1
- package/dist/store-api/search.test.d.ts +0 -2
- package/dist/store-api/search.test.d.ts.map +0 -1
- package/dist/store-api/search.test.js +0 -45
- package/dist/store-api/search.test.js.map +0 -1
- package/dist/store.d.ts +0 -21
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -84
- package/dist/store.js.map +0 -1
- package/dist/toast.d.ts +0 -44
- package/dist/toast.d.ts.map +0 -1
- package/dist/toast.js +0 -221
- package/dist/toast.js.map +0 -1
- package/dist/utils.test.d.ts +0 -2
- package/dist/utils.test.d.ts.map +0 -1
- package/dist/utils.test.js +0 -152
- package/dist/utils.test.js.map +0 -1
- package/dist/window.d.ts +0 -12
- package/dist/window.d.ts.map +0 -1
- package/dist/window.js +0 -48
- package/dist/window.js.map +0 -1
package/src/components/list.tsx
CHANGED
|
@@ -1,58 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoxRenderable,
|
|
3
|
+
ScrollBoxRenderable,
|
|
4
|
+
TextAttributes,
|
|
5
|
+
TextareaRenderable,
|
|
6
|
+
} from '@opentui/core'
|
|
7
|
+
import { useKeyboard } from '@opentui/react'
|
|
1
8
|
import React, {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
useLayoutEffect,
|
|
12
|
-
createContext,
|
|
13
|
-
useContext,
|
|
9
|
+
ReactElement,
|
|
10
|
+
ReactNode,
|
|
11
|
+
createContext,
|
|
12
|
+
useContext,
|
|
13
|
+
useEffect,
|
|
14
|
+
useLayoutEffect,
|
|
15
|
+
useMemo,
|
|
16
|
+
useRef,
|
|
17
|
+
useState
|
|
14
18
|
} from 'react'
|
|
15
|
-
import { TextAttributes } from '@opentui/core'
|
|
16
|
-
import { useKeyboard } from '@opentui/react'
|
|
17
|
-
import { logger } from 'termcast/src/logger'
|
|
18
|
-
import { Theme } from 'termcast/src/theme'
|
|
19
|
-
import { Action, ActionPanel } from 'termcast/src/components/actions'
|
|
20
|
-
import { InFocus, useIsInFocus } from 'termcast/src/internal/focus-context'
|
|
21
|
-
import { CommonProps } from 'termcast/src/utils'
|
|
22
|
-
import { useStore } from 'termcast/src/state'
|
|
23
|
-
import { useDialog } from 'termcast/src/internal/dialog'
|
|
24
|
-
import { createDescendants } from 'termcast/src/descendants'
|
|
25
19
|
import { LoadingBar } from 'termcast/src/components/loading-bar'
|
|
20
|
+
import { createDescendants } from 'termcast/src/descendants'
|
|
21
|
+
import { useDialog } from 'termcast/src/internal/dialog'
|
|
22
|
+
import { useIsInFocus } from 'termcast/src/internal/focus-context'
|
|
26
23
|
import { useNavigationPending } from 'termcast/src/internal/navigation'
|
|
24
|
+
import { ScrollBox } from 'termcast/src/internal/scrollbox'
|
|
25
|
+
|
|
26
|
+
import { Color, resolveColor } from 'termcast/src/colors'
|
|
27
|
+
import { getIconEmoji } from 'termcast/src/components/icon'
|
|
28
|
+
import { Theme, markdownSyntaxStyle } from 'termcast/src/theme'
|
|
29
|
+
import { CommonProps } from 'termcast/src/utils'
|
|
30
|
+
|
|
31
|
+
export { Color }
|
|
32
|
+
|
|
33
|
+
function formatRelativeDate(date: Date): string {
|
|
34
|
+
const now = new Date()
|
|
35
|
+
const diffMs = now.getTime() - date.getTime()
|
|
36
|
+
const diffSec = Math.floor(diffMs / 1000)
|
|
37
|
+
const diffMin = Math.floor(diffSec / 60)
|
|
38
|
+
const diffHour = Math.floor(diffMin / 60)
|
|
39
|
+
const diffDay = Math.floor(diffHour / 24)
|
|
40
|
+
const diffWeek = Math.floor(diffDay / 7)
|
|
41
|
+
const diffMonth = Math.floor(diffDay / 30)
|
|
42
|
+
const diffYear = Math.floor(diffDay / 365)
|
|
43
|
+
|
|
44
|
+
if (diffSec < 60) {
|
|
45
|
+
return 'now'
|
|
46
|
+
}
|
|
47
|
+
if (diffMin < 60) {
|
|
48
|
+
return `${diffMin}m`
|
|
49
|
+
}
|
|
50
|
+
if (diffHour < 24) {
|
|
51
|
+
return `${diffHour}h`
|
|
52
|
+
}
|
|
53
|
+
if (diffDay < 7) {
|
|
54
|
+
return `${diffDay}d`
|
|
55
|
+
}
|
|
56
|
+
if (diffWeek < 4) {
|
|
57
|
+
return `${diffWeek}w`
|
|
58
|
+
}
|
|
59
|
+
if (diffMonth < 12) {
|
|
60
|
+
return `${diffMonth}mo`
|
|
61
|
+
}
|
|
62
|
+
return `${diffYear}y`
|
|
63
|
+
}
|
|
27
64
|
|
|
28
65
|
interface ActionsInterface {
|
|
29
66
|
actions?: ReactNode
|
|
30
67
|
}
|
|
31
68
|
|
|
32
69
|
function ListFooter(): any {
|
|
33
|
-
const toast = useStore((state) => state.toast)
|
|
34
|
-
|
|
35
|
-
if (toast) {
|
|
36
|
-
return (
|
|
37
|
-
<box
|
|
38
|
-
border={false}
|
|
39
|
-
style={{
|
|
40
|
-
paddingLeft: 1,
|
|
41
|
-
paddingRight: 1,
|
|
42
|
-
paddingTop: 1,
|
|
43
|
-
marginTop: 1,
|
|
44
|
-
}}
|
|
45
|
-
>
|
|
46
|
-
{toast}
|
|
47
|
-
</box>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
70
|
return (
|
|
52
71
|
<box
|
|
53
72
|
border={false}
|
|
54
73
|
style={{
|
|
55
74
|
paddingLeft: 1,
|
|
75
|
+
flexShrink: 0,
|
|
56
76
|
paddingRight: 1,
|
|
57
77
|
paddingTop: 1,
|
|
58
78
|
marginTop: 1,
|
|
@@ -64,11 +84,11 @@ function ListFooter(): any {
|
|
|
64
84
|
</text>
|
|
65
85
|
<text fg={Theme.textMuted}> select</text>
|
|
66
86
|
<text fg={Theme.text} attributes={TextAttributes.BOLD}>
|
|
67
|
-
{'
|
|
87
|
+
{' '}↑↓
|
|
68
88
|
</text>
|
|
69
89
|
<text fg={Theme.textMuted}> navigate</text>
|
|
70
90
|
<text fg={Theme.text} attributes={TextAttributes.BOLD}>
|
|
71
|
-
{'
|
|
91
|
+
{' '}^k
|
|
72
92
|
</text>
|
|
73
93
|
<text fg={Theme.textMuted}> actions</text>
|
|
74
94
|
</box>
|
|
@@ -96,10 +116,8 @@ interface PaginationInterface {
|
|
|
96
116
|
}
|
|
97
117
|
}
|
|
98
118
|
|
|
99
|
-
export type Color = string
|
|
100
|
-
|
|
101
119
|
export namespace Image {
|
|
102
|
-
export type ImageLike = string
|
|
120
|
+
export type ImageLike = string | { source: string; tintColor?: string }
|
|
103
121
|
}
|
|
104
122
|
|
|
105
123
|
export type ItemAccessory =
|
|
@@ -109,7 +127,7 @@ export type ItemAccessory =
|
|
|
109
127
|
| null
|
|
110
128
|
| {
|
|
111
129
|
value: string | null
|
|
112
|
-
color?: Color
|
|
130
|
+
color?: Color.ColorLike
|
|
113
131
|
}
|
|
114
132
|
}
|
|
115
133
|
| {
|
|
@@ -118,7 +136,7 @@ export type ItemAccessory =
|
|
|
118
136
|
| null
|
|
119
137
|
| {
|
|
120
138
|
value: Date | null
|
|
121
|
-
color?: Color
|
|
139
|
+
color?: Color.ColorLike
|
|
122
140
|
}
|
|
123
141
|
}
|
|
124
142
|
| {
|
|
@@ -126,7 +144,7 @@ export type ItemAccessory =
|
|
|
126
144
|
| string
|
|
127
145
|
| {
|
|
128
146
|
value: string
|
|
129
|
-
color?: Color
|
|
147
|
+
color?: Color.ColorLike
|
|
130
148
|
}
|
|
131
149
|
}
|
|
132
150
|
| {
|
|
@@ -245,7 +263,7 @@ interface ListItemDetailMetadataType {
|
|
|
245
263
|
|
|
246
264
|
interface ListItemDetailMetadataTagListType {
|
|
247
265
|
(props: { title: string; children: ReactNode }): any
|
|
248
|
-
Item: (props: { text?: string; color?: Color; icon?: Image.ImageLike; onAction?: () => void }) => any
|
|
266
|
+
Item: (props: { text?: string; color?: Color.ColorLike; icon?: Image.ImageLike; onAction?: () => void }) => any
|
|
249
267
|
}
|
|
250
268
|
|
|
251
269
|
interface ListDropdownType {
|
|
@@ -309,6 +327,7 @@ interface ListItemDescendant {
|
|
|
309
327
|
actions?: ReactNode
|
|
310
328
|
visible?: boolean
|
|
311
329
|
detail?: ReactNode
|
|
330
|
+
elementRef?: { y: number; height: number } | null
|
|
312
331
|
}
|
|
313
332
|
|
|
314
333
|
const {
|
|
@@ -355,7 +374,7 @@ interface ListDropdownDialogProps extends DropdownProps {
|
|
|
355
374
|
function ListDropdownDialog(props: ListDropdownDialogProps): any {
|
|
356
375
|
const [searchText, setSearchTextRaw] = useState('')
|
|
357
376
|
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
358
|
-
const inputRef = useRef<
|
|
377
|
+
const inputRef = useRef<TextareaRenderable>(null)
|
|
359
378
|
const descendantsContext = useDropdownDescendants()
|
|
360
379
|
|
|
361
380
|
// Wrapper function that updates search text
|
|
@@ -364,6 +383,7 @@ function ListDropdownDialog(props: ListDropdownDialogProps): any {
|
|
|
364
383
|
setSelectedIndex(0) // Reset selection when search changes
|
|
365
384
|
}
|
|
366
385
|
|
|
386
|
+
|
|
367
387
|
const move = (direction: -1 | 1) => {
|
|
368
388
|
// Get all visible items
|
|
369
389
|
const items = Object.values(descendantsContext.map.current)
|
|
@@ -433,12 +453,20 @@ function ListDropdownDialog(props: ListDropdownDialogProps): any {
|
|
|
433
453
|
<text fg={Theme.textMuted}>esc</text>
|
|
434
454
|
</box>
|
|
435
455
|
<box style={{ paddingTop: 1, paddingBottom: 1 }}>
|
|
436
|
-
<
|
|
456
|
+
<textarea
|
|
437
457
|
ref={inputRef}
|
|
438
|
-
|
|
458
|
+
height={1}
|
|
459
|
+
keyBindings={[
|
|
460
|
+
{ name: 'return', action: 'submit' },
|
|
461
|
+
{ name: 'linefeed', action: 'submit' },
|
|
462
|
+
]}
|
|
463
|
+
onContentChange={() => {
|
|
464
|
+
const value = inputRef.current?.plainText || ''
|
|
465
|
+
setSearchText(value)
|
|
466
|
+
}}
|
|
439
467
|
placeholder={props.placeholder || 'Search...'}
|
|
440
468
|
focused={inFocus}
|
|
441
|
-
|
|
469
|
+
initialValue={searchText}
|
|
442
470
|
focusedBackgroundColor={Theme.backgroundPanel}
|
|
443
471
|
cursorColor={Theme.primary}
|
|
444
472
|
focusedTextColor={Theme.textMuted}
|
|
@@ -499,16 +527,18 @@ function ListDropdownDialog(props: ListDropdownDialogProps): any {
|
|
|
499
527
|
function ListItemRow(props: {
|
|
500
528
|
title: string
|
|
501
529
|
subtitle?: string
|
|
530
|
+
icon?: string
|
|
531
|
+
iconColor?: string
|
|
502
532
|
accessories?: ItemAccessory[]
|
|
503
533
|
active?: boolean
|
|
504
534
|
isShowingDetail?: boolean
|
|
505
535
|
onMouseDown?: () => void
|
|
506
536
|
index?: number
|
|
537
|
+
ref?: React.Ref<BoxRenderable>
|
|
507
538
|
}) {
|
|
508
|
-
const { title, subtitle, accessories, active } = props
|
|
539
|
+
const { title, subtitle, icon, iconColor, accessories, active, ref } = props
|
|
509
540
|
const [isHovered, setIsHovered] = useState(false)
|
|
510
541
|
|
|
511
|
-
// Format accessories for display
|
|
512
542
|
const accessoryElements: ReactNode[] = []
|
|
513
543
|
if (accessories) {
|
|
514
544
|
accessories.forEach((accessory) => {
|
|
@@ -517,11 +547,14 @@ function ListItemRow(props: {
|
|
|
517
547
|
typeof accessory.text === 'string'
|
|
518
548
|
? accessory.text
|
|
519
549
|
: accessory.text?.value
|
|
550
|
+
const textColor =
|
|
551
|
+
typeof accessory.text === 'object' ? accessory.text?.color : undefined
|
|
520
552
|
if (textValue) {
|
|
521
553
|
accessoryElements.push(
|
|
522
554
|
<text
|
|
523
555
|
key={`text-${textValue}`}
|
|
524
|
-
fg={active ? Theme.background : Theme.info}
|
|
556
|
+
fg={active ? Theme.background : resolveColor(textColor) || Theme.info}
|
|
557
|
+
wrapMode="none"
|
|
525
558
|
>
|
|
526
559
|
{textValue}
|
|
527
560
|
</text>,
|
|
@@ -533,22 +566,48 @@ function ListItemRow(props: {
|
|
|
533
566
|
typeof accessory.tag === 'string'
|
|
534
567
|
? accessory.tag
|
|
535
568
|
: accessory.tag?.value
|
|
569
|
+
const tagColor =
|
|
570
|
+
typeof accessory.tag === 'object' ? accessory.tag?.color : undefined
|
|
536
571
|
if (tagValue) {
|
|
537
572
|
accessoryElements.push(
|
|
538
573
|
<text
|
|
539
574
|
key={`tag-${tagValue}`}
|
|
540
|
-
fg={active ? Theme.background : Theme.warning}
|
|
575
|
+
fg={active ? Theme.background : resolveColor(tagColor) || Theme.warning}
|
|
576
|
+
wrapMode="none"
|
|
541
577
|
>
|
|
542
578
|
[{tagValue}]
|
|
543
579
|
</text>,
|
|
544
580
|
)
|
|
545
581
|
}
|
|
546
582
|
}
|
|
583
|
+
if ('date' in accessory && accessory.date) {
|
|
584
|
+
const dateValue =
|
|
585
|
+
accessory.date instanceof Date
|
|
586
|
+
? accessory.date
|
|
587
|
+
: accessory.date?.value
|
|
588
|
+
const dateColor =
|
|
589
|
+
typeof accessory.date === 'object' && !(accessory.date instanceof Date)
|
|
590
|
+
? accessory.date?.color
|
|
591
|
+
: undefined
|
|
592
|
+
if (dateValue) {
|
|
593
|
+
const formatted = formatRelativeDate(dateValue)
|
|
594
|
+
accessoryElements.push(
|
|
595
|
+
<text
|
|
596
|
+
key={`date-${dateValue.getTime()}`}
|
|
597
|
+
fg={active ? Theme.background : resolveColor(dateColor) || Theme.success}
|
|
598
|
+
wrapMode="none"
|
|
599
|
+
>
|
|
600
|
+
{formatted}
|
|
601
|
+
</text>,
|
|
602
|
+
)
|
|
603
|
+
}
|
|
604
|
+
}
|
|
547
605
|
})
|
|
548
606
|
}
|
|
549
607
|
|
|
550
608
|
return (
|
|
551
609
|
<box
|
|
610
|
+
ref={ref}
|
|
552
611
|
style={{
|
|
553
612
|
flexDirection: 'row',
|
|
554
613
|
justifyContent: 'space-between',
|
|
@@ -557,39 +616,44 @@ function ListItemRow(props: {
|
|
|
557
616
|
: isHovered
|
|
558
617
|
? Theme.backgroundPanel
|
|
559
618
|
: undefined,
|
|
560
|
-
paddingLeft:
|
|
619
|
+
paddingLeft: 0,
|
|
561
620
|
paddingRight: 1,
|
|
621
|
+
gap: 1,
|
|
562
622
|
}}
|
|
563
623
|
border={false}
|
|
564
|
-
onMouseMove={() =>
|
|
565
|
-
|
|
624
|
+
onMouseMove={() => {
|
|
625
|
+
setIsHovered(true)
|
|
626
|
+
}}
|
|
627
|
+
onMouseOut={() => {
|
|
628
|
+
setIsHovered(false)
|
|
629
|
+
}}
|
|
566
630
|
onMouseDown={props.onMouseDown}
|
|
567
631
|
>
|
|
568
|
-
<box style={{ flexDirection: 'row', flexGrow: 1, flexShrink: 1 }}>
|
|
569
|
-
{
|
|
570
|
-
<text fg={Theme.
|
|
571
|
-
|
|
632
|
+
<box style={{ flexDirection: 'row', flexGrow: 1, flexShrink: 1, overflow: 'hidden', gap: 1 }}>
|
|
633
|
+
<box style={{ flexDirection: 'row', flexShrink: 0 }}>
|
|
634
|
+
<text fg={active ? Theme.background : Theme.text} attributes={active ? TextAttributes.BOLD : undefined} selectable={false} wrapMode="none">{active ? '›' : ' '}</text>
|
|
635
|
+
{icon && <text fg={active ? Theme.background : iconColor || Theme.text} selectable={false} wrapMode="none">{getIconEmoji(icon)} </text>}
|
|
636
|
+
<text
|
|
637
|
+
fg={active ? Theme.background : Theme.text}
|
|
638
|
+
attributes={active ? TextAttributes.BOLD : undefined}
|
|
639
|
+
selectable={false}
|
|
640
|
+
wrapMode="none"
|
|
641
|
+
>
|
|
642
|
+
{title}
|
|
572
643
|
</text>
|
|
573
|
-
|
|
574
|
-
<text
|
|
575
|
-
fg={active ? Theme.background : Theme.text}
|
|
576
|
-
attributes={active ? TextAttributes.BOLD : undefined}
|
|
577
|
-
selectable={false}
|
|
578
|
-
>
|
|
579
|
-
{title}
|
|
580
|
-
</text>
|
|
644
|
+
</box>
|
|
581
645
|
{subtitle && (
|
|
582
646
|
<text
|
|
583
647
|
fg={active ? Theme.background : Theme.textMuted}
|
|
584
648
|
selectable={false}
|
|
649
|
+
wrapMode="none"
|
|
585
650
|
>
|
|
586
|
-
{' '}
|
|
587
651
|
{subtitle}
|
|
588
652
|
</text>
|
|
589
653
|
)}
|
|
590
654
|
</box>
|
|
591
655
|
{accessoryElements.length > 0 && (
|
|
592
|
-
<box style={{ flexDirection: 'row' }}>
|
|
656
|
+
<box style={{ flexDirection: 'row', flexShrink: 0 }}>
|
|
593
657
|
{accessoryElements.map((elem, i) => (
|
|
594
658
|
<box key={i} style={{ flexDirection: 'row' }}>
|
|
595
659
|
{i > 0 && <text> </text>}
|
|
@@ -598,7 +662,6 @@ function ListItemRow(props: {
|
|
|
598
662
|
))}
|
|
599
663
|
</box>
|
|
600
664
|
)}
|
|
601
|
-
{/*{active && <text fg={Theme.textMuted}>‹</text>}*/}
|
|
602
665
|
</box>
|
|
603
666
|
)
|
|
604
667
|
}
|
|
@@ -623,7 +686,8 @@ export const List: ListType = (props) => {
|
|
|
623
686
|
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
624
687
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
|
|
625
688
|
const [currentDetail, setCurrentDetail] = useState<ReactNode>(null)
|
|
626
|
-
const inputRef = useRef<
|
|
689
|
+
const inputRef = useRef<TextareaRenderable>(null)
|
|
690
|
+
const scrollBoxRef = useRef<ScrollBoxRenderable>(null)
|
|
627
691
|
const descendantsContext = useListDescendants()
|
|
628
692
|
const navigationPending = useNavigationPending()
|
|
629
693
|
|
|
@@ -632,6 +696,15 @@ export const List: ListType = (props) => {
|
|
|
632
696
|
? controlledSearchText
|
|
633
697
|
: internalSearchText
|
|
634
698
|
|
|
699
|
+
// Sync controlled searchText → textarea (only when externally controlled)
|
|
700
|
+
useLayoutEffect(() => {
|
|
701
|
+
if (controlledSearchText === undefined) return
|
|
702
|
+
const textarea = inputRef.current
|
|
703
|
+
if (textarea && textarea.plainText !== controlledSearchText) {
|
|
704
|
+
textarea.setText(controlledSearchText)
|
|
705
|
+
}
|
|
706
|
+
}, [controlledSearchText])
|
|
707
|
+
|
|
635
708
|
// Determine if filtering is enabled
|
|
636
709
|
// List filters automatically when:
|
|
637
710
|
// - filtering is not specified (defaults to true) OR filtering is explicitly true
|
|
@@ -694,15 +767,36 @@ export const List: ListType = (props) => {
|
|
|
694
767
|
}
|
|
695
768
|
}, [selectedItemId])
|
|
696
769
|
|
|
770
|
+
const scrollToItem = (item: { props?: ListItemDescendant }) => {
|
|
771
|
+
const scrollBox = scrollBoxRef.current
|
|
772
|
+
const elementRef = item.props?.elementRef
|
|
773
|
+
if (!scrollBox || !elementRef) return
|
|
774
|
+
|
|
775
|
+
const contentY = scrollBox.content?.y || 0
|
|
776
|
+
const viewportHeight = scrollBox.viewport?.height || 10
|
|
777
|
+
const currentScrollTop = scrollBox.scrollTop || 0
|
|
778
|
+
|
|
779
|
+
const itemTop = elementRef.y - contentY
|
|
780
|
+
const itemBottom = itemTop + elementRef.height
|
|
781
|
+
|
|
782
|
+
const visibleTop = currentScrollTop
|
|
783
|
+
const visibleBottom = currentScrollTop + viewportHeight
|
|
784
|
+
|
|
785
|
+
if (itemTop < visibleTop) {
|
|
786
|
+
scrollBox.scrollTo(itemTop)
|
|
787
|
+
} else if (itemBottom > visibleBottom) {
|
|
788
|
+
scrollBox.scrollTo(itemBottom - viewportHeight)
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
697
792
|
const move = (direction: -1 | 1) => {
|
|
698
|
-
// Get all visible items
|
|
699
793
|
const items = Object.values(descendantsContext.map.current)
|
|
700
794
|
.filter((item) => item.index !== -1 && item.props?.visible !== false)
|
|
701
795
|
.sort((a, b) => a.index - b.index)
|
|
702
796
|
|
|
703
797
|
if (items.length === 0) return
|
|
704
798
|
|
|
705
|
-
|
|
799
|
+
|
|
706
800
|
let currentVisibleIndex = items.findIndex(
|
|
707
801
|
(item) => item.index === selectedIndex,
|
|
708
802
|
)
|
|
@@ -710,11 +804,11 @@ export const List: ListType = (props) => {
|
|
|
710
804
|
// If current selection is not visible, select first visible item
|
|
711
805
|
if (items[0]) {
|
|
712
806
|
setSelectedIndex(items[0].index)
|
|
807
|
+
scrollToItem(items[0])
|
|
713
808
|
}
|
|
714
809
|
return
|
|
715
810
|
}
|
|
716
811
|
|
|
717
|
-
// Calculate next visible index
|
|
718
812
|
let nextVisibleIndex = currentVisibleIndex + direction
|
|
719
813
|
if (nextVisibleIndex < 0) nextVisibleIndex = items.length - 1
|
|
720
814
|
if (nextVisibleIndex >= items.length) nextVisibleIndex = 0
|
|
@@ -722,10 +816,10 @@ export const List: ListType = (props) => {
|
|
|
722
816
|
const nextItem = items[nextVisibleIndex]
|
|
723
817
|
if (nextItem) {
|
|
724
818
|
setSelectedIndex(nextItem.index)
|
|
819
|
+
scrollToItem(nextItem)
|
|
725
820
|
}
|
|
726
821
|
}
|
|
727
822
|
|
|
728
|
-
// Handle keyboard navigation
|
|
729
823
|
const inFocus = useIsInFocus()
|
|
730
824
|
const dialog = useDialog()
|
|
731
825
|
|
|
@@ -808,7 +902,7 @@ export const List: ListType = (props) => {
|
|
|
808
902
|
)}
|
|
809
903
|
|
|
810
904
|
{/* Search bar with optional dropdown accessory */}
|
|
811
|
-
<box>
|
|
905
|
+
<box style={{ flexShrink: 0 }}>
|
|
812
906
|
<box
|
|
813
907
|
border={false}
|
|
814
908
|
style={{
|
|
@@ -818,7 +912,6 @@ export const List: ListType = (props) => {
|
|
|
818
912
|
marginBottom: 1,
|
|
819
913
|
flexDirection: 'row',
|
|
820
914
|
justifyContent: 'space-between',
|
|
821
|
-
|
|
822
915
|
alignItems: 'center',
|
|
823
916
|
}}
|
|
824
917
|
>
|
|
@@ -829,12 +922,20 @@ export const List: ListType = (props) => {
|
|
|
829
922
|
flexShrink: 1,
|
|
830
923
|
}}
|
|
831
924
|
>
|
|
832
|
-
<
|
|
925
|
+
<textarea
|
|
833
926
|
ref={inputRef}
|
|
927
|
+
height={1}
|
|
928
|
+
keyBindings={[
|
|
929
|
+
{ name: 'return', action: 'submit' },
|
|
930
|
+
{ name: 'linefeed', action: 'submit' },
|
|
931
|
+
]}
|
|
834
932
|
placeholder={searchBarPlaceholder}
|
|
835
933
|
focused={inFocus && !isDropdownOpen}
|
|
836
|
-
|
|
837
|
-
|
|
934
|
+
initialValue={searchText}
|
|
935
|
+
onContentChange={() => {
|
|
936
|
+
const value = inputRef.current?.plainText || ''
|
|
937
|
+
handleSearchChange(value)
|
|
938
|
+
}}
|
|
838
939
|
focusedBackgroundColor={Theme.backgroundPanel}
|
|
839
940
|
cursorColor={Theme.primary}
|
|
840
941
|
focusedTextColor={Theme.text}
|
|
@@ -845,16 +946,32 @@ export const List: ListType = (props) => {
|
|
|
845
946
|
</box>
|
|
846
947
|
|
|
847
948
|
{/* Main content area with optional detail view */}
|
|
848
|
-
<box style={{ flexDirection: 'row', flexGrow: 1 }}>
|
|
949
|
+
<box style={{ flexDirection: 'row', flexGrow: 1, flexShrink: 1 }}>
|
|
849
950
|
{/* List content - render children which will register themselves */}
|
|
850
|
-
<box style={{
|
|
851
|
-
|
|
951
|
+
<box style={{ width: isShowingDetail ? '50%' : '100%', flexGrow: isShowingDetail ? 0 : 1, flexShrink: 1, flexDirection: 'column' }}>
|
|
952
|
+
{/* Scrollable list items */}
|
|
953
|
+
<ScrollBox
|
|
954
|
+
ref={scrollBoxRef}
|
|
955
|
+
focused={false}
|
|
956
|
+
flexGrow={1}
|
|
957
|
+
flexShrink={1}
|
|
958
|
+
style={{
|
|
959
|
+
rootOptions: {
|
|
960
|
+
backgroundColor: undefined,
|
|
961
|
+
},
|
|
962
|
+
scrollbarOptions: {
|
|
963
|
+
|
|
964
|
+
showArrows: true,
|
|
965
|
+
|
|
966
|
+
},
|
|
967
|
+
}}
|
|
968
|
+
>
|
|
852
969
|
{/* Render children - they will register as descendants */}
|
|
853
970
|
<ListItemsRenderer>{children}</ListItemsRenderer>
|
|
971
|
+
</ScrollBox>
|
|
854
972
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
</>
|
|
973
|
+
{/* Footer with keyboard shortcuts or toast */}
|
|
974
|
+
<ListFooter />
|
|
858
975
|
</box>
|
|
859
976
|
|
|
860
977
|
{/* Detail panel on the right */}
|
|
@@ -907,6 +1024,7 @@ const ListItem: ListItemType = (props) => {
|
|
|
907
1024
|
const { sectionTitle } = listSectionContext
|
|
908
1025
|
const listContext = useContext(ListContext)
|
|
909
1026
|
const dialog = useDialog()
|
|
1027
|
+
const elementRef = useRef<BoxRenderable>(null)
|
|
910
1028
|
|
|
911
1029
|
// Extract text values for descendant registration
|
|
912
1030
|
const titleText =
|
|
@@ -942,6 +1060,7 @@ const ListItem: ListItemType = (props) => {
|
|
|
942
1060
|
actions: props.actions,
|
|
943
1061
|
visible: isVisible,
|
|
944
1062
|
detail: props.detail,
|
|
1063
|
+
elementRef: elementRef.current,
|
|
945
1064
|
})
|
|
946
1065
|
|
|
947
1066
|
// Get selected index from parent List context
|
|
@@ -974,16 +1093,40 @@ const ListItem: ListItemType = (props) => {
|
|
|
974
1093
|
// Don't show accessories if we're showing detail
|
|
975
1094
|
const showAccessories = !props.detail && props.accessories
|
|
976
1095
|
|
|
1096
|
+
// Get icon string and color from props.icon (can be string or object with value/tintColor)
|
|
1097
|
+
const { iconValue, iconColor } = (() => {
|
|
1098
|
+
if (!props.icon) return { iconValue: undefined, iconColor: undefined }
|
|
1099
|
+
if (typeof props.icon === 'string') return { iconValue: props.icon, iconColor: undefined }
|
|
1100
|
+
const iconObj = props.icon as Record<string, unknown>
|
|
1101
|
+
if ('source' in iconObj && typeof iconObj.source === 'string') {
|
|
1102
|
+
return { iconValue: iconObj.source, iconColor: iconObj.tintColor as string | undefined }
|
|
1103
|
+
}
|
|
1104
|
+
if ('value' in iconObj && iconObj.value) {
|
|
1105
|
+
const val = iconObj.value
|
|
1106
|
+
if (typeof val === 'string') return { iconValue: val, iconColor: undefined }
|
|
1107
|
+
if (typeof val === 'object' && val !== null) {
|
|
1108
|
+
const valObj = val as Record<string, unknown>
|
|
1109
|
+
if ('source' in valObj && typeof valObj.source === 'string') {
|
|
1110
|
+
return { iconValue: valObj.source, iconColor: valObj.tintColor as string | undefined }
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
return { iconValue: undefined, iconColor: undefined }
|
|
1115
|
+
})()
|
|
1116
|
+
|
|
977
1117
|
// Render the item row directly
|
|
978
1118
|
return (
|
|
979
1119
|
<ListItemRow
|
|
980
1120
|
title={titleText}
|
|
981
1121
|
subtitle={subtitleText}
|
|
1122
|
+
icon={iconValue}
|
|
1123
|
+
iconColor={iconColor}
|
|
982
1124
|
accessories={showAccessories ? props.accessories : undefined}
|
|
983
1125
|
active={isActive}
|
|
984
1126
|
isShowingDetail={props.detail !== undefined}
|
|
985
1127
|
onMouseDown={handleMouseDown}
|
|
986
1128
|
index={index}
|
|
1129
|
+
ref={elementRef}
|
|
987
1130
|
/>
|
|
988
1131
|
)
|
|
989
1132
|
}
|
|
@@ -999,22 +1142,37 @@ const ListItemDetail: ListItemDetailType = (props) => {
|
|
|
999
1142
|
</box>
|
|
1000
1143
|
)}
|
|
1001
1144
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1145
|
+
<ScrollBox
|
|
1146
|
+
focused={true}
|
|
1147
|
+
flexGrow={1}
|
|
1148
|
+
flexShrink={1}
|
|
1149
|
+
style={{
|
|
1150
|
+
rootOptions: {
|
|
1151
|
+
backgroundColor: undefined,
|
|
1152
|
+
},
|
|
1153
|
+
scrollbarOptions: {
|
|
1007
1154
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1155
|
+
showArrows: true,
|
|
1156
|
+
|
|
1157
|
+
},
|
|
1158
|
+
}}
|
|
1159
|
+
>
|
|
1160
|
+
<box style={{ flexDirection: 'column' }}>
|
|
1161
|
+
{markdown && (
|
|
1162
|
+
<code content={markdown} filetype="markdown" syntaxStyle={markdownSyntaxStyle} drawUnstyledText={false} />
|
|
1163
|
+
)}
|
|
1164
|
+
{metadata && (
|
|
1165
|
+
<box
|
|
1166
|
+
style={{ paddingTop: 1 }}
|
|
1167
|
+
border={['top']}
|
|
1168
|
+
borderStyle='single'
|
|
1169
|
+
borderColor={Theme.border}
|
|
1170
|
+
>
|
|
1171
|
+
{metadata}
|
|
1172
|
+
</box>
|
|
1173
|
+
)}
|
|
1016
1174
|
</box>
|
|
1017
|
-
|
|
1175
|
+
</ScrollBox>
|
|
1018
1176
|
</box>
|
|
1019
1177
|
)
|
|
1020
1178
|
}
|
|
@@ -1064,10 +1222,10 @@ const ListItemDetailMetadataTagList = (props: { title: string; children: ReactNo
|
|
|
1064
1222
|
)
|
|
1065
1223
|
}
|
|
1066
1224
|
|
|
1067
|
-
const ListItemDetailMetadataTagListItem = (props: { text?: string; color?: Color; icon?: Image.ImageLike; onAction?: () => void }) => {
|
|
1225
|
+
const ListItemDetailMetadataTagListItem = (props: { text?: string; color?: Color.ColorLike; icon?: Image.ImageLike; onAction?: () => void }) => {
|
|
1068
1226
|
return (
|
|
1069
1227
|
<box style={{ paddingRight: 1 }}>
|
|
1070
|
-
<text fg={props.color || Theme.accent}>[{props.text}]</text>
|
|
1228
|
+
<text fg={resolveColor(props.color) || Theme.accent}>[{props.text}]</text>
|
|
1071
1229
|
</box>
|
|
1072
1230
|
)
|
|
1073
1231
|
}
|
|
@@ -1382,6 +1540,11 @@ const ListSection = (props: SectionProps) => {
|
|
|
1382
1540
|
const listContext = useContext(ListContext)
|
|
1383
1541
|
const searchText = listContext?.searchText || ''
|
|
1384
1542
|
|
|
1543
|
+
// Don't render empty sections
|
|
1544
|
+
if (React.Children.count(props.children) === 0) {
|
|
1545
|
+
return null
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1385
1548
|
// Create new context with section title and search text
|
|
1386
1549
|
const sectionContextValue = useMemo(
|
|
1387
1550
|
() => ({
|
|
@@ -1396,14 +1559,13 @@ const ListSection = (props: SectionProps) => {
|
|
|
1396
1559
|
const showTitle = props.title && !searchText.trim()
|
|
1397
1560
|
|
|
1398
1561
|
return (
|
|
1399
|
-
|
|
1562
|
+
<box style={{ marginBottom: 1 }}>
|
|
1400
1563
|
{/* Render section title if provided and not searching */}
|
|
1401
1564
|
{showTitle && (
|
|
1402
1565
|
<box
|
|
1403
1566
|
border={false}
|
|
1404
1567
|
style={{
|
|
1405
1568
|
paddingLeft: 1,
|
|
1406
|
-
paddingTop: 1,
|
|
1407
1569
|
}}
|
|
1408
1570
|
>
|
|
1409
1571
|
<text fg={Theme.accent} attributes={TextAttributes.BOLD}>
|
|
@@ -1415,7 +1577,7 @@ const ListSection = (props: SectionProps) => {
|
|
|
1415
1577
|
<ListSectionContext.Provider value={sectionContextValue}>
|
|
1416
1578
|
{props.children}
|
|
1417
1579
|
</ListSectionContext.Provider>
|
|
1418
|
-
|
|
1580
|
+
</box>
|
|
1419
1581
|
)
|
|
1420
1582
|
}
|
|
1421
1583
|
|
|
@@ -1526,9 +1688,14 @@ Grid.Item = (props: GridItemProps) => {
|
|
|
1526
1688
|
const { content, getDetailMarkdown, ...itemProps } = props
|
|
1527
1689
|
|
|
1528
1690
|
// Extract image value and tooltip
|
|
1529
|
-
const imageValue =
|
|
1691
|
+
const imageValue = (() => {
|
|
1692
|
+
if (typeof content === 'string') return content
|
|
1693
|
+
if (content && 'source' in content) return content
|
|
1694
|
+
if (content && 'value' in content) return content.value
|
|
1695
|
+
return undefined
|
|
1696
|
+
})()
|
|
1530
1697
|
const imageTooltip =
|
|
1531
|
-
typeof content === 'object' ? content
|
|
1698
|
+
typeof content === 'object' && content && 'tooltip' in content ? content.tooltip : undefined
|
|
1532
1699
|
|
|
1533
1700
|
// Convert Grid.Item props to List.Item props
|
|
1534
1701
|
const listItemProps: ItemProps = {
|