termcast 1.3.21 → 1.3.25
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/ai.d.ts +104 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +135 -0
- package/dist/ai.js.map +1 -0
- package/dist/apis/browser-extension.d.ts +18 -0
- package/dist/apis/browser-extension.d.ts.map +1 -0
- package/dist/apis/browser-extension.js +14 -0
- package/dist/apis/browser-extension.js.map +1 -0
- package/dist/apis/localstorage.d.ts.map +1 -1
- package/dist/apis/localstorage.js +4 -7
- package/dist/apis/localstorage.js.map +1 -1
- package/dist/apis/oauth.d.ts.map +1 -1
- package/dist/apis/oauth.js +5 -1
- package/dist/apis/oauth.js.map +1 -1
- package/dist/apis/preferences.d.ts.map +1 -1
- package/dist/apis/preferences.js +38 -19
- package/dist/apis/preferences.js.map +1 -1
- package/dist/apis/toast.d.ts +5 -0
- package/dist/apis/toast.d.ts.map +1 -1
- package/dist/apis/toast.js +7 -43
- package/dist/apis/toast.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +3 -1
- package/dist/build.js.map +1 -1
- package/dist/cache.d.ts +32 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +205 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +87 -41
- package/dist/cli.js.map +1 -1
- package/dist/clipboard.d.ts +36 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clipboard.js +154 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/compile.d.ts +2 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +31 -12
- package/dist/compile.js.map +1 -1
- package/dist/components/actions.d.ts.map +1 -1
- package/dist/components/actions.js +56 -30
- package/dist/components/actions.js.map +1 -1
- package/dist/components/detail.d.ts.map +1 -1
- package/dist/components/detail.js +4 -0
- package/dist/components/detail.js.map +1 -1
- package/dist/components/dropdown.d.ts.map +1 -1
- package/dist/components/dropdown.js +38 -15
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/extension-preferences.d.ts.map +1 -1
- package/dist/components/extension-preferences.js +40 -13
- 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 +5 -3
- 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 +5 -3
- package/dist/components/form/date-picker.js.map +1 -1
- package/dist/components/form/description.d.ts.map +1 -1
- package/dist/components/form/description.js +2 -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 +84 -80
- package/dist/components/form/dropdown.js.map +1 -1
- package/dist/components/form/file-autocomplete.d.ts +3 -6
- package/dist/components/form/file-autocomplete.d.ts.map +1 -1
- package/dist/components/form/file-autocomplete.js +61 -66
- package/dist/components/form/file-autocomplete.js.map +1 -1
- package/dist/components/form/file-picker.d.ts.map +1 -1
- package/dist/components/form/file-picker.js +33 -30
- package/dist/components/form/file-picker.js.map +1 -1
- package/dist/components/form/form-end.d.ts.map +1 -1
- package/dist/components/form/form-end.js +21 -1
- package/dist/components/form/form-end.js.map +1 -1
- package/dist/components/form/form-type-only.d.ts +174 -0
- package/dist/components/form/form-type-only.d.ts.map +1 -0
- package/dist/components/form/form-type-only.js +2 -0
- package/dist/components/form/form-type-only.js.map +1 -0
- package/dist/components/form/index.d.ts +3 -1
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/index.js +104 -30
- 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 +5 -3
- 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 +5 -3
- 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 +6 -4
- package/dist/components/form/text-field.js.map +1 -1
- package/dist/components/form/types.d.ts +5 -0
- package/dist/components/form/types.d.ts.map +1 -1
- package/dist/components/form/use-form-handling.d.ts +4 -0
- package/dist/components/form/use-form-handling.d.ts.map +1 -0
- package/dist/components/form/use-form-handling.js +37 -0
- package/dist/components/form/use-form-handling.js.map +1 -0
- package/dist/components/form/with-left-border.d.ts +2 -1
- package/dist/components/form/with-left-border.d.ts.map +1 -1
- package/dist/components/form/with-left-border.js +27 -3
- package/dist/components/form/with-left-border.js.map +1 -1
- package/dist/components/icon.d.ts +1 -0
- package/dist/components/icon.d.ts.map +1 -1
- package/dist/components/icon.js +24 -8
- package/dist/components/icon.js.map +1 -1
- package/dist/components/list.d.ts +2 -2
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +155 -70
- package/dist/components/list.js.map +1 -1
- package/dist/components/loading-bar.d.ts.map +1 -1
- package/dist/components/loading-bar.js +2 -2
- package/dist/components/loading-bar.js.map +1 -1
- package/dist/components/loading-text.d.ts +8 -0
- package/dist/components/loading-text.d.ts.map +1 -0
- package/dist/components/loading-text.js +58 -0
- package/dist/components/loading-text.js.map +1 -0
- package/dist/descendants.js +1 -1
- package/dist/descendants.js.map +1 -1
- package/dist/dev-ui.d.ts +7 -0
- package/dist/dev-ui.d.ts.map +1 -0
- package/dist/dev-ui.js +118 -0
- package/dist/dev-ui.js.map +1 -0
- package/dist/environment.d.ts +63 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +189 -0
- package/dist/environment.js.map +1 -0
- package/dist/examples/datepicker.d.ts +2 -0
- package/dist/examples/datepicker.d.ts.map +1 -0
- package/dist/examples/datepicker.js +344 -0
- package/dist/examples/datepicker.js.map +1 -0
- package/dist/examples/file-autocomplete.vitest.d.ts +2 -0
- package/dist/examples/file-autocomplete.vitest.d.ts.map +1 -0
- package/dist/examples/file-autocomplete.vitest.js +223 -0
- package/dist/examples/file-autocomplete.vitest.js.map +1 -0
- package/dist/examples/form-basic-arrow-keys.vitest.d.ts +2 -0
- package/dist/examples/form-basic-arrow-keys.vitest.d.ts.map +1 -0
- package/dist/examples/form-basic-arrow-keys.vitest.js +46 -0
- package/dist/examples/form-basic-arrow-keys.vitest.js.map +1 -0
- package/dist/examples/form-basic.vitest.d.ts +2 -0
- package/dist/examples/form-basic.vitest.d.ts.map +1 -0
- package/dist/examples/form-basic.vitest.js +630 -0
- package/dist/examples/form-basic.vitest.js.map +1 -0
- package/dist/examples/form-dropdown-with-sections.d.ts +2 -0
- package/dist/examples/form-dropdown-with-sections.d.ts.map +1 -0
- package/dist/examples/form-dropdown-with-sections.js +13 -0
- package/dist/examples/form-dropdown-with-sections.js.map +1 -0
- package/dist/examples/form-dropdown-with-sections.vitest.d.ts +2 -0
- package/dist/examples/form-dropdown-with-sections.vitest.d.ts.map +1 -0
- package/dist/examples/form-dropdown-with-sections.vitest.js +75 -0
- package/dist/examples/form-dropdown-with-sections.vitest.js.map +1 -0
- package/dist/examples/form-dropdown.vitest.d.ts +2 -0
- package/dist/examples/form-dropdown.vitest.d.ts.map +1 -0
- package/dist/examples/form-dropdown.vitest.js +854 -0
- package/dist/examples/form-dropdown.vitest.js.map +1 -0
- package/dist/examples/form-multiselect-dropdown.d.ts +2 -0
- package/dist/examples/form-multiselect-dropdown.d.ts.map +1 -0
- package/dist/examples/form-multiselect-dropdown.js +13 -0
- package/dist/examples/form-multiselect-dropdown.js.map +1 -0
- package/dist/examples/form-scroll.d.ts.map +1 -1
- package/dist/examples/form-scroll.js +7 -1
- package/dist/examples/form-scroll.js.map +1 -1
- package/dist/examples/form-scroll.vitest.d.ts +2 -0
- package/dist/examples/form-scroll.vitest.d.ts.map +1 -0
- package/dist/examples/form-scroll.vitest.js +211 -0
- package/dist/examples/form-scroll.vitest.js.map +1 -0
- package/dist/examples/form-tagpicker.vitest.d.ts +2 -0
- package/dist/examples/form-tagpicker.vitest.d.ts.map +1 -0
- package/dist/examples/form-tagpicker.vitest.js +736 -0
- package/dist/examples/form-tagpicker.vitest.js.map +1 -0
- package/dist/examples/internal/descendants-filtering.js +1 -1
- package/dist/examples/internal/descendants-filtering.js.map +1 -1
- package/dist/examples/internal/descendants.js +1 -1
- package/dist/examples/internal/descendants.js.map +1 -1
- package/dist/examples/internal/nested-boxes.d.ts +2 -0
- package/dist/examples/internal/nested-boxes.d.ts.map +1 -0
- package/dist/examples/internal/nested-boxes.js +7 -0
- package/dist/examples/internal/nested-boxes.js.map +1 -0
- package/dist/examples/internal/rhf-custom-ref.js +2 -2
- package/dist/examples/internal/rhf-custom-ref.js.map +1 -1
- package/dist/examples/internal/scrollbox-demo.js +3 -22
- package/dist/examples/internal/scrollbox-demo.js.map +1 -1
- package/dist/examples/internal/scrollbox-descendants.d.ts +2 -0
- package/dist/examples/internal/scrollbox-descendants.d.ts.map +1 -0
- package/dist/examples/internal/scrollbox-descendants.js +83 -0
- package/dist/examples/internal/scrollbox-descendants.js.map +1 -0
- package/dist/examples/internal/scrollbox-with-descendants.js +4 -8
- package/dist/examples/internal/scrollbox-with-descendants.js.map +1 -1
- package/dist/examples/internal/simple-scrollbox.vitest.d.ts +2 -0
- package/dist/examples/internal/simple-scrollbox.vitest.d.ts.map +1 -0
- package/dist/examples/internal/simple-scrollbox.vitest.js +96 -0
- package/dist/examples/internal/simple-scrollbox.vitest.js.map +1 -0
- package/dist/examples/internal/unicode-square-repro.d.ts +2 -0
- package/dist/examples/internal/unicode-square-repro.d.ts.map +1 -0
- package/dist/examples/internal/unicode-square-repro.js +7 -0
- package/dist/examples/internal/unicode-square-repro.js.map +1 -0
- package/dist/examples/list-detail-metadata.d.ts +2 -0
- package/dist/examples/list-detail-metadata.d.ts.map +1 -0
- package/dist/examples/list-detail-metadata.js +8 -0
- package/dist/examples/list-detail-metadata.js.map +1 -0
- package/dist/examples/list-dropdown-default.vitest.d.ts +2 -0
- package/dist/examples/list-dropdown-default.vitest.d.ts.map +1 -0
- package/dist/examples/list-dropdown-default.vitest.js +234 -0
- package/dist/examples/list-dropdown-default.vitest.js.map +1 -0
- package/dist/examples/list-fetch-data.vitest.d.ts +2 -0
- package/dist/examples/list-fetch-data.vitest.d.ts.map +1 -0
- package/dist/examples/list-fetch-data.vitest.js +111 -0
- package/dist/examples/list-fetch-data.vitest.js.map +1 -0
- package/dist/examples/list-filter-navigation.d.ts +2 -0
- package/dist/examples/list-filter-navigation.d.ts.map +1 -0
- package/dist/examples/list-filter-navigation.js +8 -0
- package/dist/examples/list-filter-navigation.js.map +1 -0
- package/dist/examples/list-scrollbox.vitest.d.ts +2 -0
- package/dist/examples/list-scrollbox.vitest.d.ts.map +1 -0
- package/dist/examples/list-scrollbox.vitest.js +93 -0
- package/dist/examples/list-scrollbox.vitest.js.map +1 -0
- package/dist/examples/list-with-detail-long.d.ts +2 -0
- package/dist/examples/list-with-detail-long.d.ts.map +1 -0
- package/dist/examples/list-with-detail-long.js +53 -0
- package/dist/examples/list-with-detail-long.js.map +1 -0
- package/dist/examples/list-with-detail.vitest.d.ts +2 -0
- package/dist/examples/list-with-detail.vitest.d.ts.map +1 -0
- package/dist/examples/list-with-detail.vitest.js +434 -0
- package/dist/examples/list-with-detail.vitest.js.map +1 -0
- package/dist/examples/list-with-dropdown.vitest.d.ts +2 -0
- package/dist/examples/list-with-dropdown.vitest.d.ts.map +1 -0
- package/dist/examples/list-with-dropdown.vitest.js +337 -0
- package/dist/examples/list-with-dropdown.vitest.js.map +1 -0
- package/dist/examples/list-with-sections.js +5 -1
- package/dist/examples/list-with-sections.js.map +1 -1
- package/dist/examples/list-with-sections.vitest.d.ts +2 -0
- package/dist/examples/list-with-sections.vitest.d.ts.map +1 -0
- package/dist/examples/list-with-sections.vitest.js +601 -0
- package/dist/examples/list-with-sections.vitest.js.map +1 -0
- package/dist/examples/scrollbox-vertical-centering.d.ts +6 -0
- package/dist/examples/scrollbox-vertical-centering.d.ts.map +1 -0
- package/dist/examples/scrollbox-vertical-centering.js +17 -0
- package/dist/examples/scrollbox-vertical-centering.js.map +1 -0
- package/dist/examples/simple-file-picker.vitest.d.ts +2 -0
- package/dist/examples/simple-file-picker.vitest.d.ts.map +1 -0
- package/dist/examples/simple-file-picker.vitest.js +678 -0
- package/dist/examples/simple-file-picker.vitest.js.map +1 -0
- package/dist/examples/simple-grid.vitest.d.ts +2 -0
- package/dist/examples/simple-grid.vitest.d.ts.map +1 -0
- package/dist/examples/simple-grid.vitest.js +521 -0
- package/dist/examples/simple-grid.vitest.js.map +1 -0
- package/dist/examples/simple-navigation.js +10 -4
- package/dist/examples/simple-navigation.js.map +1 -1
- package/dist/examples/simple-navigation.vitest.d.ts +2 -0
- package/dist/examples/simple-navigation.vitest.d.ts.map +1 -0
- package/dist/examples/simple-navigation.vitest.js +718 -0
- package/dist/examples/simple-navigation.vitest.js.map +1 -0
- package/dist/examples/store.vitest.d.ts +2 -0
- package/dist/examples/store.vitest.d.ts.map +1 -0
- package/dist/examples/store.vitest.js +69 -0
- package/dist/examples/store.vitest.js.map +1 -0
- package/dist/examples/toast-variations.d.ts +2 -0
- package/dist/examples/toast-variations.d.ts.map +1 -0
- package/dist/examples/toast-variations.js +122 -0
- package/dist/examples/toast-variations.js.map +1 -0
- package/dist/extensions/dev.d.ts +4 -2
- package/dist/extensions/dev.d.ts.map +1 -1
- package/dist/extensions/dev.js +61 -10
- package/dist/extensions/dev.js.map +1 -1
- package/dist/extensions/dev.vitest.d.ts +2 -0
- package/dist/extensions/dev.vitest.d.ts.map +1 -0
- package/dist/extensions/dev.vitest.js +197 -0
- package/dist/extensions/dev.vitest.js.map +1 -0
- package/dist/extensions/home.d.ts.map +1 -1
- package/dist/extensions/home.js +3 -0
- package/dist/extensions/home.js.map +1 -1
- package/dist/home-command.d.ts +8 -0
- package/dist/home-command.d.ts.map +1 -0
- package/dist/home-command.js +181 -0
- package/dist/home-command.js.map +1 -0
- package/dist/hover-repro.d.ts +2 -0
- package/dist/hover-repro.d.ts.map +1 -0
- package/dist/hover-repro.js +20 -0
- package/dist/hover-repro.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/dialog.d.ts +1 -0
- package/dist/internal/dialog.d.ts.map +1 -1
- package/dist/internal/dialog.js +27 -18
- package/dist/internal/dialog.js.map +1 -1
- package/dist/internal/navigation.d.ts +9 -1
- package/dist/internal/navigation.d.ts.map +1 -1
- package/dist/internal/navigation.js +5 -5
- package/dist/internal/navigation.js.map +1 -1
- package/dist/internal/offscreen.d.ts +6 -0
- package/dist/internal/offscreen.d.ts.map +1 -0
- package/dist/internal/offscreen.js +10 -0
- package/dist/internal/offscreen.js.map +1 -0
- package/dist/internal/providers.d.ts.map +1 -1
- package/dist/internal/providers.js +2 -2
- package/dist/internal/providers.js.map +1 -1
- package/dist/internal/scrollbox.d.ts +1 -10
- package/dist/internal/scrollbox.d.ts.map +1 -1
- package/dist/internal/scrollbox.js +2 -1
- package/dist/internal/scrollbox.js.map +1 -1
- package/dist/localstorage.d.ts +13 -0
- package/dist/localstorage.d.ts.map +1 -0
- package/dist/localstorage.js +190 -0
- package/dist/localstorage.js.map +1 -0
- package/dist/oauth.d.ts +142 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +551 -0
- package/dist/oauth.js.map +1 -0
- package/dist/preferences.d.ts +23 -0
- package/dist/preferences.d.ts.map +1 -0
- package/dist/preferences.js +105 -0
- package/dist/preferences.js.map +1 -0
- package/dist/release.d.ts +1 -1
- package/dist/release.d.ts.map +1 -1
- package/dist/release.js +29 -33
- package/dist/release.js.map +1 -1
- package/dist/state.d.ts +2 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +3 -0
- package/dist/state.js.map +1 -1
- package/dist/store.d.ts +21 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +84 -0
- package/dist/store.js.map +1 -0
- package/dist/swift-loader.d.ts +3 -0
- package/dist/swift-loader.d.ts.map +1 -0
- package/dist/swift-loader.js +193 -0
- package/dist/swift-loader.js.map +1 -0
- package/dist/swift-runtime.d.ts +2 -0
- package/dist/swift-runtime.d.ts.map +1 -0
- package/dist/swift-runtime.js +27 -0
- package/dist/swift-runtime.js.map +1 -0
- package/dist/toast.d.ts +44 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +221 -0
- package/dist/toast.js.map +1 -0
- package/dist/utils/file-system.d.ts +9 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +49 -0
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/run-command.d.ts +26 -1
- package/dist/utils/run-command.d.ts.map +1 -1
- package/dist/utils/run-command.js +53 -4
- package/dist/utils/run-command.js.map +1 -1
- package/dist/window.d.ts +12 -0
- package/dist/window.d.ts.map +1 -0
- package/dist/window.js +48 -0
- package/dist/window.js.map +1 -0
- package/package.json +12 -12
- package/src/apis/browser-extension.tsx +29 -0
- package/src/apis/localstorage.test.ts +14 -6
- package/src/apis/localstorage.tsx +8 -5
- package/src/apis/oauth.tsx +5 -1
- package/src/apis/preferences.tsx +48 -22
- package/src/apis/toast.tsx +37 -62
- package/src/build.test.tsx +52 -0
- package/src/build.tsx +3 -1
- package/src/cli.tsx +99 -48
- package/src/compile.tsx +32 -11
- package/src/components/actions.tsx +94 -32
- package/src/components/detail.tsx +4 -0
- package/src/components/dropdown.tsx +47 -14
- package/src/components/extension-preferences.tsx +44 -16
- package/src/components/form/checkbox.tsx +12 -6
- package/src/components/form/date-picker.tsx +12 -6
- package/src/components/form/description.tsx +7 -2
- package/src/components/form/dropdown.tsx +131 -119
- package/src/components/form/file-autocomplete.tsx +90 -108
- package/src/components/form/file-picker.tsx +54 -43
- package/src/components/form/form-end.tsx +23 -2
- package/src/components/form/index.tsx +168 -41
- package/src/components/form/password-field.tsx +12 -6
- package/src/components/form/text-area.tsx +13 -6
- package/src/components/form/text-field.tsx +13 -6
- package/src/components/form/types.tsx +6 -0
- package/src/components/form/with-left-border.tsx +41 -8
- package/src/components/icon.tsx +27 -8
- package/src/components/list.tsx +243 -101
- package/src/components/loading-bar.tsx +3 -2
- package/src/components/loading-text.tsx +79 -0
- package/src/descendants.tsx +1 -0
- package/src/examples/file-autocomplete.vitest.tsx +130 -125
- package/src/examples/form-basic.vitest.tsx +376 -176
- package/src/examples/form-dropdown.vitest.tsx +126 -126
- package/src/examples/form-scroll.tsx +2 -0
- package/src/examples/form-scroll.vitest.tsx +58 -58
- package/src/examples/form-tagpicker.vitest.tsx +99 -99
- package/src/examples/internal/descendants-filtering.tsx +1 -0
- package/src/examples/internal/descendants.tsx +1 -0
- package/src/examples/internal/rhf-custom-ref.tsx +2 -0
- package/src/examples/internal/scrollbox-demo.tsx +3 -27
- package/src/examples/internal/scrollbox-with-descendants.tsx +4 -7
- package/src/examples/internal/simple-scrollbox.vitest.tsx +7 -5
- package/src/examples/list-detail-metadata.tsx +49 -0
- package/src/examples/list-detail-metadata.vitest.tsx +88 -0
- package/src/examples/list-dropdown-default.vitest.tsx +51 -51
- package/src/examples/list-fetch-data.vitest.tsx +4 -4
- package/src/examples/list-scrollbox.vitest.tsx +73 -14
- package/src/examples/list-with-detail-long.tsx +70 -0
- package/src/examples/list-with-detail.vitest.tsx +191 -85
- package/src/examples/list-with-dropdown.vitest.tsx +53 -53
- package/src/examples/list-with-sections.tsx +1 -0
- package/src/examples/list-with-sections.vitest.tsx +221 -97
- package/src/examples/list-with-toast.vitest.tsx +16 -16
- package/src/examples/simple-file-picker.vitest.tsx +63 -469
- package/src/examples/simple-grid.vitest.tsx +238 -233
- package/src/examples/simple-navigation.tsx +15 -7
- package/src/examples/simple-navigation.vitest.tsx +130 -219
- package/src/examples/store.vitest.tsx +1 -1
- package/src/examples/swift-extension.vitest.tsx +148 -0
- package/src/examples/synonyms.vitest.tsx +159 -0
- package/src/examples/toast-variations.tsx +150 -0
- package/src/examples/toast-variations.vitest.tsx +370 -0
- package/src/extensions/dev.tsx +74 -7
- package/src/extensions/dev.vitest.tsx +102 -34
- package/src/extensions/home.tsx +6 -0
- package/src/index.tsx +3 -0
- package/src/internal/dialog.tsx +43 -30
- package/src/internal/navigation.tsx +3 -1
- package/src/internal/offscreen.tsx +15 -0
- package/src/internal/providers.tsx +4 -2
- package/src/internal/scrollbox.tsx +4 -8
- package/src/keyboard.test.tsx +69 -0
- package/src/release.tsx +32 -38
- package/src/state.tsx +7 -0
- package/src/swift-loader.tsx +239 -0
- package/src/swift-runtime.tsx +36 -0
- package/src/utils/file-system.ts +61 -0
- package/src/utils/run-command.tsx +82 -6
package/src/cli.tsx
CHANGED
|
@@ -2,10 +2,11 @@ import fs from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { execSync, spawn } from 'node:child_process'
|
|
4
4
|
import { cac } from 'cac'
|
|
5
|
-
import
|
|
5
|
+
import * as watcher from '@parcel/watcher'
|
|
6
6
|
import { buildExtensionCommands } from './build'
|
|
7
7
|
import { logger } from './logger'
|
|
8
8
|
import { installExtension } from './utils'
|
|
9
|
+
import { searchStoreListings } from './store-api/search'
|
|
9
10
|
import './globals'
|
|
10
11
|
import { startDevMode, triggerRebuild } from './extensions/dev'
|
|
11
12
|
import { compileExtension } from './compile'
|
|
@@ -66,13 +67,22 @@ checkForUpdates()
|
|
|
66
67
|
|
|
67
68
|
cli
|
|
68
69
|
.command('dev [path]', 'Run the extension in the current working directory')
|
|
69
|
-
.action(async (
|
|
70
|
+
.action(async (rawExtensionPath, options) => {
|
|
70
71
|
try {
|
|
71
|
-
|
|
72
|
+
// Check if the provided arg looks like a path (contains / or . or is existing dir)
|
|
73
|
+
const looksLikePath = rawExtensionPath && (
|
|
74
|
+
rawExtensionPath.includes('/') ||
|
|
75
|
+
rawExtensionPath.startsWith('.') ||
|
|
76
|
+
fs.existsSync(rawExtensionPath)
|
|
77
|
+
)
|
|
78
|
+
const extensionPath = path.resolve(looksLikePath ? rawExtensionPath : process.cwd())
|
|
72
79
|
let isBuilding = false
|
|
73
80
|
|
|
74
81
|
// Start dev mode with initial render
|
|
75
|
-
|
|
82
|
+
// Skip args up to and including "dev" subcommand, plus path if it looks like one
|
|
83
|
+
const devIndex = process.argv.findIndex((arg) => arg === 'dev')
|
|
84
|
+
const skipArgv = devIndex - 1 + (looksLikePath ? 1 : 0)
|
|
85
|
+
await startDevMode({ extensionPath, skipArgv })
|
|
76
86
|
|
|
77
87
|
logger.log(`dev mode started`)
|
|
78
88
|
// Only watch if running in a TTY (interactive terminal)
|
|
@@ -83,38 +93,18 @@ cli
|
|
|
83
93
|
|
|
84
94
|
console.log('\nWatching for file changes...')
|
|
85
95
|
|
|
86
|
-
// Watch entire extension directory
|
|
87
|
-
const watcher = chokidar.watch(extensionPath, {
|
|
88
|
-
persistent: true,
|
|
89
|
-
ignoreInitial: true,
|
|
90
|
-
awaitWriteFinish: {
|
|
91
|
-
stabilityThreshold: 300,
|
|
92
|
-
pollInterval: 100,
|
|
93
|
-
},
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
+
// Watch entire extension directory using @parcel/watcher
|
|
96
97
|
const ignoredPatterns = [
|
|
97
|
-
'node_modules',
|
|
98
|
-
'
|
|
99
|
-
'
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
'
|
|
98
|
+
'**/node_modules/**',
|
|
99
|
+
'**/.termcast-bundle/**',
|
|
100
|
+
'**/.git/**',
|
|
101
|
+
'**/.build/**', // Swift build output
|
|
102
|
+
'**/*.log',
|
|
103
|
+
'**/dist/**',
|
|
104
|
+
'**/build/**',
|
|
103
105
|
]
|
|
104
106
|
|
|
105
|
-
const shouldIgnore = (filePath: string) => {
|
|
106
|
-
const relativePath = path.relative(extensionPath, filePath)
|
|
107
|
-
return ignoredPatterns.some(
|
|
108
|
-
(pattern) =>
|
|
109
|
-
relativePath.includes(pattern) || filePath.endsWith('.log'),
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
107
|
const rebuild = async (filePath: string) => {
|
|
114
|
-
if (shouldIgnore(filePath)) {
|
|
115
|
-
return
|
|
116
|
-
}
|
|
117
|
-
|
|
118
108
|
if (isBuilding) {
|
|
119
109
|
logger.log('Build already in progress, skipping...')
|
|
120
110
|
return
|
|
@@ -133,11 +123,28 @@ cli
|
|
|
133
123
|
}
|
|
134
124
|
}
|
|
135
125
|
|
|
136
|
-
watcher
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
126
|
+
const subscription = await watcher.subscribe(
|
|
127
|
+
extensionPath,
|
|
128
|
+
(err, events) => {
|
|
129
|
+
if (err) {
|
|
130
|
+
logger.error('Watcher error:', err)
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
// Trigger rebuild for any event (create, update, delete)
|
|
134
|
+
if (events.length > 0) {
|
|
135
|
+
rebuild(events[0].path)
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{ ignore: ignoredPatterns }
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
// Clean up watcher on exit signals
|
|
142
|
+
const cleanup = async () => {
|
|
143
|
+
await subscription.unsubscribe()
|
|
144
|
+
process.exit(0)
|
|
145
|
+
}
|
|
146
|
+
process.on('SIGINT', cleanup)
|
|
147
|
+
process.on('SIGTERM', cleanup)
|
|
141
148
|
} catch (e: any) {
|
|
142
149
|
console.error('Failed to start dev mode:', e?.message || e)
|
|
143
150
|
logger.error(e)
|
|
@@ -215,7 +222,7 @@ cli
|
|
|
215
222
|
single: options.single,
|
|
216
223
|
})
|
|
217
224
|
|
|
218
|
-
console.log(`\nRelease complete:
|
|
225
|
+
console.log(`\nRelease complete: ${result.tag}`)
|
|
219
226
|
console.log(`Uploaded ${result.uploadedFiles.length} binaries`)
|
|
220
227
|
} catch (error: any) {
|
|
221
228
|
console.error('Release failed:', error.message)
|
|
@@ -365,17 +372,54 @@ cli
|
|
|
365
372
|
}
|
|
366
373
|
})
|
|
367
374
|
|
|
375
|
+
cli
|
|
376
|
+
.command('raycast-search <query>', 'Search for extensions in the Raycast store')
|
|
377
|
+
.option('-n, --limit <number>', 'Number of results to show', { default: '10' })
|
|
378
|
+
.action(async (query: string, options: { limit: string }) => {
|
|
379
|
+
try {
|
|
380
|
+
const limit = parseInt(options.limit, 10)
|
|
381
|
+
const result = await searchStoreListings({ query, perPage: limit })
|
|
382
|
+
|
|
383
|
+
if (result.data.length === 0) {
|
|
384
|
+
console.log(`No extensions found for "${query}"`)
|
|
385
|
+
process.exit(0)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
console.log(`Found ${result.data.length} extensions for "${query}":\n`)
|
|
389
|
+
|
|
390
|
+
for (const ext of result.data) {
|
|
391
|
+
const downloads = ext.download_count.toLocaleString()
|
|
392
|
+
const commands = ext.commands.map((c) => c.name).join(', ')
|
|
393
|
+
console.log(` ${ext.name}`)
|
|
394
|
+
console.log(` Path: extensions/${ext.relative_path.replace('extensions/', '')}`)
|
|
395
|
+
console.log(` Downloads: ${downloads}`)
|
|
396
|
+
console.log(` Commands: ${commands || 'none'}`)
|
|
397
|
+
console.log(` Description: ${ext.description.slice(0, 100)}${ext.description.length > 100 ? '...' : ''}`)
|
|
398
|
+
console.log()
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
console.log(`Download with: termcast download <extension-name>`)
|
|
402
|
+
process.exit(0)
|
|
403
|
+
} catch (error: any) {
|
|
404
|
+
console.error('Search failed:', error.message)
|
|
405
|
+
process.exit(1)
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
|
|
368
409
|
cli
|
|
369
410
|
.command('download <extensionName>', 'Download extension from Raycast extensions repo')
|
|
370
411
|
.option('-o, --output <path>', 'Output directory', { default: '.' })
|
|
371
|
-
.
|
|
412
|
+
.option('--no-dir', 'Put files directly in output directory instead of creating extension subdirectory')
|
|
413
|
+
.action(async (extensionName: string, options: { output: string; dir: boolean }) => {
|
|
372
414
|
try {
|
|
373
415
|
const destPath = path.resolve(options.output)
|
|
374
|
-
|
|
416
|
+
// When --no-dir is passed, dir is false; put files directly in destPath
|
|
417
|
+
const extensionDir = options.dir ? path.join(destPath, extensionName) : destPath
|
|
418
|
+
const tempCloneDir = path.join(destPath, `.tmp-${extensionName}-${Date.now()}`)
|
|
375
419
|
|
|
376
420
|
console.log(`Downloading extension '${extensionName}' from raycast/extensions...`)
|
|
377
421
|
|
|
378
|
-
if (fs.existsSync(extensionDir)) {
|
|
422
|
+
if (options.dir && fs.existsSync(extensionDir)) {
|
|
379
423
|
console.log(`Removing existing directory: ${extensionDir}`)
|
|
380
424
|
fs.rmSync(extensionDir, { recursive: true, force: true })
|
|
381
425
|
}
|
|
@@ -383,7 +427,8 @@ cli
|
|
|
383
427
|
fs.mkdirSync(destPath, { recursive: true })
|
|
384
428
|
|
|
385
429
|
const repoUrl = 'https://github.com/raycast/extensions.git'
|
|
386
|
-
const
|
|
430
|
+
const cloneDirName = path.basename(tempCloneDir)
|
|
431
|
+
const cloneCmd = `git clone -n --depth=1 --filter=tree:0 "${repoUrl}" "${cloneDirName}"`
|
|
387
432
|
console.log(`Running: ${cloneCmd}`)
|
|
388
433
|
try {
|
|
389
434
|
execSync(cloneCmd, {
|
|
@@ -399,11 +444,12 @@ cli
|
|
|
399
444
|
console.log(`Running: ${sparseCmd}`)
|
|
400
445
|
try {
|
|
401
446
|
execSync(sparseCmd, {
|
|
402
|
-
cwd:
|
|
447
|
+
cwd: tempCloneDir,
|
|
403
448
|
stdio: 'inherit',
|
|
404
449
|
})
|
|
405
450
|
} catch (error) {
|
|
406
451
|
console.error(`Failed to set sparse-checkout`)
|
|
452
|
+
fs.rmSync(tempCloneDir, { recursive: true, force: true })
|
|
407
453
|
process.exit(1)
|
|
408
454
|
}
|
|
409
455
|
|
|
@@ -411,22 +457,27 @@ cli
|
|
|
411
457
|
console.log(`Running: ${checkoutCmd}`)
|
|
412
458
|
try {
|
|
413
459
|
execSync(checkoutCmd, {
|
|
414
|
-
cwd:
|
|
460
|
+
cwd: tempCloneDir,
|
|
415
461
|
stdio: 'inherit',
|
|
416
462
|
})
|
|
417
463
|
} catch (error) {
|
|
418
464
|
console.error(`Failed to checkout files`)
|
|
465
|
+
fs.rmSync(tempCloneDir, { recursive: true, force: true })
|
|
419
466
|
process.exit(1)
|
|
420
467
|
}
|
|
421
468
|
|
|
422
|
-
const extensionPath = path.join(
|
|
469
|
+
const extensionPath = path.join(tempCloneDir, 'extensions', extensionName)
|
|
423
470
|
|
|
424
471
|
if (!fs.existsSync(extensionPath)) {
|
|
425
472
|
console.error(`Extension '${extensionName}' not found in raycast/extensions repo`)
|
|
426
|
-
fs.rmSync(
|
|
473
|
+
fs.rmSync(tempCloneDir, { recursive: true, force: true })
|
|
427
474
|
process.exit(1)
|
|
428
475
|
}
|
|
429
476
|
|
|
477
|
+
// Move files to final destination
|
|
478
|
+
if (options.dir) {
|
|
479
|
+
fs.mkdirSync(extensionDir, { recursive: true })
|
|
480
|
+
}
|
|
430
481
|
const filesToMove = fs.readdirSync(extensionPath)
|
|
431
482
|
for (const file of filesToMove) {
|
|
432
483
|
const src = path.join(extensionPath, file)
|
|
@@ -434,8 +485,8 @@ cli
|
|
|
434
485
|
fs.renameSync(src, dest)
|
|
435
486
|
}
|
|
436
487
|
|
|
437
|
-
|
|
438
|
-
fs.rmSync(
|
|
488
|
+
// Clean up temp clone directory
|
|
489
|
+
fs.rmSync(tempCloneDir, { recursive: true, force: true })
|
|
439
490
|
|
|
440
491
|
console.log(`\nInstalling dependencies...`)
|
|
441
492
|
execSync('npm install', {
|
package/src/compile.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'node:path'
|
|
|
3
3
|
import type { BunPlugin } from 'bun'
|
|
4
4
|
import { logger } from './logger'
|
|
5
5
|
import { getCommandsWithFiles } from './package-json'
|
|
6
|
+
import { swiftLoaderPlugin } from './swift-loader'
|
|
6
7
|
|
|
7
8
|
const raycastAliasPlugin: BunPlugin = {
|
|
8
9
|
name: 'raycast-to-termcast',
|
|
@@ -53,6 +54,7 @@ ${commandsArray}
|
|
|
53
54
|
await startCompiledExtension({
|
|
54
55
|
extensionPath: ${JSON.stringify(extensionPath)},
|
|
55
56
|
compiledCommands,
|
|
57
|
+
skipArgv: 0,
|
|
56
58
|
});
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -103,15 +105,15 @@ export function getArchiveExtension(target: CompileTarget): string {
|
|
|
103
105
|
export const ALL_TARGETS: CompileTarget[] = [
|
|
104
106
|
{ os: 'linux', arch: 'arm64' },
|
|
105
107
|
{ os: 'linux', arch: 'x64' },
|
|
106
|
-
{ os: 'linux', arch: 'x64', avx2: false },
|
|
107
|
-
{ os: 'linux', arch: 'arm64', abi: 'musl' },
|
|
108
|
-
{ os: 'linux', arch: 'x64', abi: 'musl' },
|
|
109
|
-
{ os: 'linux', arch: 'x64', abi: 'musl', avx2: false },
|
|
108
|
+
// { os: 'linux', arch: 'x64', avx2: false },
|
|
109
|
+
// { os: 'linux', arch: 'arm64', abi: 'musl' },
|
|
110
|
+
// { os: 'linux', arch: 'x64', abi: 'musl' },
|
|
111
|
+
// { os: 'linux', arch: 'x64', abi: 'musl', avx2: false },
|
|
110
112
|
{ os: 'darwin', arch: 'arm64' },
|
|
111
113
|
{ os: 'darwin', arch: 'x64' },
|
|
112
|
-
{ os: 'darwin', arch: 'x64', avx2: false },
|
|
114
|
+
// { os: 'darwin', arch: 'x64', avx2: false },
|
|
113
115
|
{ os: 'win32', arch: 'x64' },
|
|
114
|
-
{ os: 'win32', arch: 'x64', avx2: false },
|
|
116
|
+
// { os: 'win32', arch: 'x64', avx2: false },
|
|
115
117
|
]
|
|
116
118
|
|
|
117
119
|
export function getCurrentTarget(): CompileTarget {
|
|
@@ -125,6 +127,7 @@ export interface CompileOptions {
|
|
|
125
127
|
outfile?: string
|
|
126
128
|
minify?: boolean
|
|
127
129
|
target?: CompileTarget
|
|
130
|
+
version?: string
|
|
128
131
|
}
|
|
129
132
|
|
|
130
133
|
export interface CompileResult {
|
|
@@ -137,6 +140,7 @@ export async function compileExtension({
|
|
|
137
140
|
outfile,
|
|
138
141
|
minify = false,
|
|
139
142
|
target,
|
|
143
|
+
version,
|
|
140
144
|
}: CompileOptions): Promise<CompileResult> {
|
|
141
145
|
const resolvedPath = path.resolve(extensionPath)
|
|
142
146
|
|
|
@@ -162,6 +166,7 @@ export async function compileExtension({
|
|
|
162
166
|
if (!fs.existsSync(bundleDir)) {
|
|
163
167
|
fs.mkdirSync(bundleDir, { recursive: true })
|
|
164
168
|
}
|
|
169
|
+
fs.writeFileSync(path.join(bundleDir, '.gitignore'), '*\n')
|
|
165
170
|
|
|
166
171
|
const entryCode = generateEntryCode({
|
|
167
172
|
extensionPath: resolvedPath,
|
|
@@ -184,18 +189,34 @@ export async function compileExtension({
|
|
|
184
189
|
entrypoints: [tempEntryPath],
|
|
185
190
|
target: bunTarget as 'bun',
|
|
186
191
|
minify,
|
|
192
|
+
// bytecode: true, // TODO need to wait for opentui to support this removing top level await
|
|
193
|
+
sourcemap: 'external',
|
|
187
194
|
compile: {
|
|
188
195
|
outfile: defaultOutfile,
|
|
189
196
|
},
|
|
190
|
-
|
|
197
|
+
define: { 'process.env.VERSION': JSON.stringify(version || '') },
|
|
198
|
+
plugins: [raycastAliasPlugin, swiftLoaderPlugin],
|
|
191
199
|
throw: false,
|
|
192
200
|
} as Parameters<typeof Bun.build>[0])
|
|
193
201
|
|
|
194
202
|
if (!result.success) {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
.
|
|
198
|
-
|
|
203
|
+
const errorDetails = result.logs.map((log: any) => {
|
|
204
|
+
const parts = [log.message || String(log)]
|
|
205
|
+
if (log.position) {
|
|
206
|
+
parts.push(` at ${log.position.file}:${log.position.line}:${log.position.column}`)
|
|
207
|
+
}
|
|
208
|
+
if (log.notes) {
|
|
209
|
+
for (const note of log.notes) {
|
|
210
|
+
parts.push(` note: ${note.text}`)
|
|
211
|
+
if (note.location) {
|
|
212
|
+
parts.push(` at ${note.location.file}:${note.location.line}`)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return parts.join('\n')
|
|
217
|
+
})
|
|
218
|
+
logger.log('Compile errors:', JSON.stringify(result.logs, null, 2))
|
|
219
|
+
throw new Error(`Compile failed: ${errorDetails.join('\n\n') || 'Unknown error'}`)
|
|
199
220
|
}
|
|
200
221
|
|
|
201
222
|
logger.log('Build outputs:', result.outputs?.map((o) => o.path))
|
|
@@ -17,8 +17,12 @@ import {
|
|
|
17
17
|
moveToTrash,
|
|
18
18
|
} from 'termcast/src/action-utils'
|
|
19
19
|
import { useDialog } from 'termcast/src/internal/dialog'
|
|
20
|
+
import { useNavigation } from 'termcast/src/internal/navigation'
|
|
20
21
|
import { Dropdown } from 'termcast/src/components/dropdown'
|
|
22
|
+
import { ExtensionPreferences } from 'termcast/src/components/extension-preferences'
|
|
23
|
+
import { useStore } from 'termcast/src/state'
|
|
21
24
|
import { useIsInFocus } from 'termcast/src/internal/focus-context'
|
|
25
|
+
import { useIsOffscreen } from 'termcast/src/internal/offscreen'
|
|
22
26
|
import { CommonProps } from 'termcast/src/utils'
|
|
23
27
|
import type {
|
|
24
28
|
KeyboardShortcut,
|
|
@@ -180,7 +184,7 @@ const Action: ActionType = (props) => {
|
|
|
180
184
|
|
|
181
185
|
const isDestructive = props.style === ActionStyle.Destructive
|
|
182
186
|
|
|
183
|
-
// Render as Dropdown.Item
|
|
187
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
184
188
|
return (
|
|
185
189
|
<Dropdown.Item
|
|
186
190
|
title={props.title}
|
|
@@ -210,7 +214,7 @@ Action.Push = (props) => {
|
|
|
210
214
|
},
|
|
211
215
|
})
|
|
212
216
|
|
|
213
|
-
// Render as Dropdown.Item
|
|
217
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
214
218
|
return (
|
|
215
219
|
<Dropdown.Item
|
|
216
220
|
title={props.title}
|
|
@@ -243,7 +247,7 @@ Action.CopyToClipboard = (props) => {
|
|
|
243
247
|
},
|
|
244
248
|
})
|
|
245
249
|
|
|
246
|
-
// Render as Dropdown.Item
|
|
250
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
247
251
|
return (
|
|
248
252
|
<Dropdown.Item
|
|
249
253
|
title={props.title}
|
|
@@ -270,7 +274,7 @@ Action.OpenInBrowser = (props) => {
|
|
|
270
274
|
},
|
|
271
275
|
})
|
|
272
276
|
|
|
273
|
-
// Render as Dropdown.Item
|
|
277
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
274
278
|
return (
|
|
275
279
|
<Dropdown.Item
|
|
276
280
|
title={props.title}
|
|
@@ -298,7 +302,7 @@ Action.Open = (props) => {
|
|
|
298
302
|
},
|
|
299
303
|
})
|
|
300
304
|
|
|
301
|
-
// Render as Dropdown.Item
|
|
305
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
302
306
|
return (
|
|
303
307
|
<Dropdown.Item
|
|
304
308
|
title={props.title}
|
|
@@ -328,7 +332,7 @@ Action.Paste = (props) => {
|
|
|
328
332
|
},
|
|
329
333
|
})
|
|
330
334
|
|
|
331
|
-
// Render as Dropdown.Item
|
|
335
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
332
336
|
return (
|
|
333
337
|
<Dropdown.Item
|
|
334
338
|
title={props.title}
|
|
@@ -355,7 +359,7 @@ Action.ShowInFinder = (props) => {
|
|
|
355
359
|
},
|
|
356
360
|
})
|
|
357
361
|
|
|
358
|
-
// Render as Dropdown.Item
|
|
362
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
359
363
|
return (
|
|
360
364
|
<Dropdown.Item
|
|
361
365
|
title={props.title || 'Show in Finder'}
|
|
@@ -382,7 +386,7 @@ Action.OpenWith = (props) => {
|
|
|
382
386
|
},
|
|
383
387
|
})
|
|
384
388
|
|
|
385
|
-
// Render as Dropdown.Item
|
|
389
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
386
390
|
return (
|
|
387
391
|
<Dropdown.Item
|
|
388
392
|
title={props.title || `Open with ${props.application}`}
|
|
@@ -413,7 +417,7 @@ Action.Trash = (props) => {
|
|
|
413
417
|
},
|
|
414
418
|
})
|
|
415
419
|
|
|
416
|
-
// Render as Dropdown.Item
|
|
420
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
417
421
|
return (
|
|
418
422
|
<Dropdown.Item
|
|
419
423
|
title={props.title || 'Move to Trash'}
|
|
@@ -448,7 +452,7 @@ Action.SubmitForm = (props) => {
|
|
|
448
452
|
},
|
|
449
453
|
})
|
|
450
454
|
|
|
451
|
-
// Render as Dropdown.Item
|
|
455
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
452
456
|
return (
|
|
453
457
|
<Dropdown.Item
|
|
454
458
|
title={props.title || 'Submit'}
|
|
@@ -480,7 +484,7 @@ Action.CreateSnippet = (props) => {
|
|
|
480
484
|
},
|
|
481
485
|
})
|
|
482
486
|
|
|
483
|
-
// Render as Dropdown.Item
|
|
487
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
484
488
|
return (
|
|
485
489
|
<Dropdown.Item
|
|
486
490
|
title={props.title || 'Create Snippet'}
|
|
@@ -510,7 +514,7 @@ Action.CreateQuicklink = (props) => {
|
|
|
510
514
|
},
|
|
511
515
|
})
|
|
512
516
|
|
|
513
|
-
// Render as Dropdown.Item
|
|
517
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
514
518
|
return (
|
|
515
519
|
<Dropdown.Item
|
|
516
520
|
title={props.title || 'Create Quicklink'}
|
|
@@ -540,7 +544,7 @@ Action.ToggleQuickLook = (props) => {
|
|
|
540
544
|
},
|
|
541
545
|
})
|
|
542
546
|
|
|
543
|
-
// Render as Dropdown.Item
|
|
547
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
544
548
|
return (
|
|
545
549
|
<Dropdown.Item
|
|
546
550
|
title={props.title || 'Quick Look'}
|
|
@@ -552,8 +556,6 @@ Action.ToggleQuickLook = (props) => {
|
|
|
552
556
|
}
|
|
553
557
|
|
|
554
558
|
Action.PickDate = (props) => {
|
|
555
|
-
const dialog = useDialog()
|
|
556
|
-
|
|
557
559
|
// Register as descendant with execute function
|
|
558
560
|
useActionDescendant({
|
|
559
561
|
title: props.title || 'Pick Date',
|
|
@@ -570,7 +572,7 @@ Action.PickDate = (props) => {
|
|
|
570
572
|
},
|
|
571
573
|
})
|
|
572
574
|
|
|
573
|
-
// Render as Dropdown.Item
|
|
575
|
+
// Render as Dropdown.Item (handles offscreen check internally)
|
|
574
576
|
return (
|
|
575
577
|
<Dropdown.Item
|
|
576
578
|
title={props.title || 'Pick Date'}
|
|
@@ -631,31 +633,55 @@ function formatShortcut(
|
|
|
631
633
|
const ActionPanel: ActionPanelType = (props) => {
|
|
632
634
|
const { children, title } = props
|
|
633
635
|
const dialog = useDialog()
|
|
636
|
+
const { push } = useNavigation()
|
|
634
637
|
const inFocus = useIsInFocus()
|
|
638
|
+
const isOffscreen = useIsOffscreen()
|
|
635
639
|
const descendantsContext = useActionDescendants()
|
|
636
640
|
|
|
641
|
+
// Get extension and command info for configure actions
|
|
642
|
+
const extensionPackageJson = useStore((state) => state.extensionPackageJson)
|
|
643
|
+
const currentCommandName = useStore((state) => state.currentCommandName)
|
|
644
|
+
|
|
645
|
+
const hasExtensionPrefs =
|
|
646
|
+
(extensionPackageJson?.preferences?.length ?? 0) > 0
|
|
647
|
+
const currentCommand = extensionPackageJson?.commands?.find(
|
|
648
|
+
(c) => c.name === currentCommandName,
|
|
649
|
+
)
|
|
650
|
+
const hasCommandPrefs = (currentCommand?.preferences?.length ?? 0) > 0
|
|
651
|
+
|
|
637
652
|
// Create context value
|
|
638
653
|
const contextValue = useMemo<ActionPanelContextValue>(
|
|
639
654
|
() => ({ currentSection: undefined }),
|
|
640
655
|
[],
|
|
641
656
|
)
|
|
642
657
|
|
|
643
|
-
//
|
|
644
|
-
|
|
645
|
-
// if (!inFocus) return
|
|
646
|
-
|
|
647
|
-
// Check if there's only one action and execute it immediately
|
|
658
|
+
// Auto-execute first action if flag is set (triggered by enter/ctrl+enter)
|
|
659
|
+
// Also report first action title when rendered offscreen
|
|
648
660
|
useLayoutEffect(() => {
|
|
649
661
|
const allActions = Object.values(descendantsContext.map.current)
|
|
650
662
|
.filter((item: any) => item.index !== -1)
|
|
651
663
|
.map((item: any) => item.props as ActionDescendant)
|
|
652
664
|
|
|
653
|
-
|
|
654
|
-
|
|
665
|
+
// When offscreen, just report first action title for footer display
|
|
666
|
+
if (isOffscreen) {
|
|
667
|
+
useStore.setState({ firstActionTitle: allActions[0]?.title ?? '' })
|
|
668
|
+
return
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
const shouldExecute = useStore.getState().shouldAutoExecuteFirstAction
|
|
672
|
+
useStore.setState({ shouldAutoExecuteFirstAction: false })
|
|
673
|
+
|
|
674
|
+
if (!shouldExecute) return
|
|
675
|
+
|
|
676
|
+
if (allActions[0]) {
|
|
677
|
+
logger.log(`Auto-executing first action: ${allActions[0].title}`)
|
|
655
678
|
dialog.clear()
|
|
656
679
|
allActions[0].execute()
|
|
657
680
|
}
|
|
658
|
-
}, [descendantsContext.map, dialog])
|
|
681
|
+
}, [descendantsContext.map, dialog, isOffscreen])
|
|
682
|
+
|
|
683
|
+
// prevent showing actions if no dialog is shown (must be after hooks)
|
|
684
|
+
if (!dialog.stack.length && !isOffscreen) return null
|
|
659
685
|
|
|
660
686
|
// ActionPanel renders as Dropdown with children
|
|
661
687
|
return (
|
|
@@ -680,6 +706,38 @@ const ActionPanel: ActionPanelType = (props) => {
|
|
|
680
706
|
}}
|
|
681
707
|
>
|
|
682
708
|
{children}
|
|
709
|
+
{(hasExtensionPrefs || hasCommandPrefs) && (
|
|
710
|
+
<ActionPanel.Section title="Settings">
|
|
711
|
+
{hasExtensionPrefs && (
|
|
712
|
+
<Action
|
|
713
|
+
title="Configure Extension..."
|
|
714
|
+
shortcut={{ modifiers: ['cmd', 'shift'], key: ',' }}
|
|
715
|
+
onAction={() => {
|
|
716
|
+
dialog.clear()
|
|
717
|
+
push(
|
|
718
|
+
<ExtensionPreferences
|
|
719
|
+
extensionName={extensionPackageJson!.name}
|
|
720
|
+
/>,
|
|
721
|
+
)
|
|
722
|
+
}}
|
|
723
|
+
/>
|
|
724
|
+
)}
|
|
725
|
+
{hasCommandPrefs && (
|
|
726
|
+
<Action
|
|
727
|
+
title="Configure Command..."
|
|
728
|
+
onAction={() => {
|
|
729
|
+
dialog.clear()
|
|
730
|
+
push(
|
|
731
|
+
<ExtensionPreferences
|
|
732
|
+
extensionName={extensionPackageJson!.name}
|
|
733
|
+
commandName={currentCommandName!}
|
|
734
|
+
/>,
|
|
735
|
+
)
|
|
736
|
+
}}
|
|
737
|
+
/>
|
|
738
|
+
)}
|
|
739
|
+
</ActionPanel.Section>
|
|
740
|
+
)}
|
|
683
741
|
</Dropdown>
|
|
684
742
|
</ActionPanelContext.Provider>
|
|
685
743
|
</ActionDescendantsProvider>
|
|
@@ -698,11 +756,13 @@ ActionPanel.Section = (props) => {
|
|
|
698
756
|
[parentContext, props.title],
|
|
699
757
|
)
|
|
700
758
|
|
|
701
|
-
// Section provides context to its children
|
|
759
|
+
// Section renders Dropdown.Section and provides context to its children
|
|
702
760
|
return (
|
|
703
|
-
<
|
|
704
|
-
{
|
|
705
|
-
|
|
761
|
+
<Dropdown.Section title={props.title}>
|
|
762
|
+
<ActionPanelContext.Provider value={sectionContextValue}>
|
|
763
|
+
{props.children}
|
|
764
|
+
</ActionPanelContext.Provider>
|
|
765
|
+
</Dropdown.Section>
|
|
706
766
|
)
|
|
707
767
|
}
|
|
708
768
|
|
|
@@ -718,11 +778,13 @@ ActionPanel.Submenu = (props) => {
|
|
|
718
778
|
[parentContext, props.title],
|
|
719
779
|
)
|
|
720
780
|
|
|
721
|
-
// Submenu provides context to its children
|
|
781
|
+
// Submenu renders Dropdown.Section and provides context to its children
|
|
722
782
|
return (
|
|
723
|
-
<
|
|
724
|
-
{
|
|
725
|
-
|
|
783
|
+
<Dropdown.Section title={props.title}>
|
|
784
|
+
<ActionPanelContext.Provider value={submenuContextValue}>
|
|
785
|
+
{props.children}
|
|
786
|
+
</ActionPanelContext.Provider>
|
|
787
|
+
</Dropdown.Section>
|
|
726
788
|
)
|
|
727
789
|
}
|
|
728
790
|
|
|
@@ -9,6 +9,7 @@ import { Color, resolveColor } from 'termcast/src/colors'
|
|
|
9
9
|
|
|
10
10
|
import { useDialog } from 'termcast/src/internal/dialog'
|
|
11
11
|
import { ScrollBox } from 'termcast/src/internal/scrollbox'
|
|
12
|
+
import { useStore } from 'termcast/src/state'
|
|
12
13
|
|
|
13
14
|
interface ActionsInterface {
|
|
14
15
|
actions?: ReactNode
|
|
@@ -277,8 +278,11 @@ const Detail: DetailType = (props) => {
|
|
|
277
278
|
if (!inFocus) return
|
|
278
279
|
|
|
279
280
|
if (evt.name === 'k' && evt.ctrl && actions) {
|
|
281
|
+
// Ctrl+K shows actions (always show sheet)
|
|
280
282
|
dialog.push(actions, 'bottom-right')
|
|
281
283
|
} else if (evt.name === 'return' && actions) {
|
|
284
|
+
// Enter executes first action directly
|
|
285
|
+
useStore.setState({ shouldAutoExecuteFirstAction: true })
|
|
282
286
|
dialog.push(actions, 'bottom-right')
|
|
283
287
|
}
|
|
284
288
|
})
|