@moldable-ai/ui 0.2.19 → 0.2.21
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/catalog/catalog-coverage.d.ts +15 -0
- package/dist/catalog/catalog-coverage.d.ts.map +1 -0
- package/dist/catalog/catalog-coverage.js +44 -0
- package/dist/catalog/catalog-manifest.d.ts +6 -0
- package/dist/catalog/catalog-manifest.d.ts.map +1 -0
- package/dist/catalog/catalog-manifest.js +117 -0
- package/dist/catalog/catalog-types.d.ts +64 -0
- package/dist/catalog/catalog-types.d.ts.map +1 -0
- package/dist/catalog/catalog-types.js +20 -0
- package/dist/catalog/component-catalog.d.ts +14 -0
- package/dist/catalog/component-catalog.d.ts.map +1 -0
- package/dist/catalog/component-catalog.js +49 -0
- package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
- package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
- package/dist/catalog/core-catalog-exclusions.js +151 -0
- package/dist/catalog/core-catalog.d.ts +2 -0
- package/dist/catalog/core-catalog.d.ts.map +1 -0
- package/dist/catalog/core-catalog.js +19 -0
- package/dist/catalog/core-collection-stories.d.ts +3 -0
- package/dist/catalog/core-collection-stories.d.ts.map +1 -0
- package/dist/catalog/core-collection-stories.js +42 -0
- package/dist/catalog/core-control-stories.d.ts +3 -0
- package/dist/catalog/core-control-stories.d.ts.map +1 -0
- package/dist/catalog/core-control-stories.js +94 -0
- package/dist/catalog/core-feedback-stories.d.ts +3 -0
- package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
- package/dist/catalog/core-feedback-stories.js +50 -0
- package/dist/catalog/core-foundation-stories.d.ts +3 -0
- package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
- package/dist/catalog/core-foundation-stories.js +53 -0
- package/dist/catalog/core-navigation-stories.d.ts +3 -0
- package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
- package/dist/catalog/core-navigation-stories.js +25 -0
- package/dist/catalog/core-overlay-stories.d.ts +3 -0
- package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
- package/dist/catalog/core-overlay-stories.js +20 -0
- package/dist/catalog/index.d.ts +7 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +6 -0
- package/dist/components/app-error-boundary.d.ts +1 -0
- package/dist/components/app-error-boundary.d.ts.map +1 -1
- package/dist/components/app-error-boundary.js +13 -0
- package/dist/components/chat/chat-image-lightbox.d.ts +9 -0
- package/dist/components/chat/chat-image-lightbox.d.ts.map +1 -0
- package/dist/components/chat/chat-image-lightbox.js +9 -0
- package/dist/components/chat/chat-message.d.ts +19 -1
- package/dist/components/chat/chat-message.d.ts.map +1 -1
- package/dist/components/chat/chat-message.js +66 -16
- package/dist/components/chat/chat-messages.d.ts +5 -2
- package/dist/components/chat/chat-messages.d.ts.map +1 -1
- package/dist/components/chat/chat-messages.js +61 -6
- package/dist/components/chat/chat-panel.d.ts +49 -6
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +196 -163
- package/dist/components/chat/conversation-history.d.ts +39 -5
- package/dist/components/chat/conversation-history.d.ts.map +1 -1
- package/dist/components/chat/conversation-history.js +192 -26
- package/dist/components/chat/index.d.ts +2 -2
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +1 -1
- package/dist/components/chat/tool-handlers.d.ts.map +1 -1
- package/dist/components/chat/tool-handlers.js +40 -2
- package/dist/components/chat/vertical-scroll-fade.d.ts +6 -0
- package/dist/components/chat/vertical-scroll-fade.d.ts.map +1 -0
- package/dist/components/chat/vertical-scroll-fade.js +12 -0
- package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts +9 -0
- package/dist/components/native-capabilities/bluetooth-panel-helpers.d.ts.map +1 -0
- package/dist/components/native-capabilities/bluetooth-panel-helpers.js +37 -0
- package/dist/components/native-capabilities/bluetooth-panel.d.ts +56 -0
- package/dist/components/native-capabilities/bluetooth-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/bluetooth-panel.js +470 -0
- package/dist/components/native-capabilities/camera-preview.d.ts +39 -0
- package/dist/components/native-capabilities/camera-preview.d.ts.map +1 -0
- package/dist/components/native-capabilities/camera-preview.js +228 -0
- package/dist/components/native-capabilities/capability-badge.d.ts +23 -0
- package/dist/components/native-capabilities/capability-badge.d.ts.map +1 -0
- package/dist/components/native-capabilities/capability-badge.js +39 -0
- package/dist/components/native-capabilities/capability-matrix.d.ts +14 -0
- package/dist/components/native-capabilities/capability-matrix.d.ts.map +1 -0
- package/dist/components/native-capabilities/capability-matrix.js +97 -0
- package/dist/components/native-capabilities/clipboard-button.d.ts +26 -0
- package/dist/components/native-capabilities/clipboard-button.d.ts.map +1 -0
- package/dist/components/native-capabilities/clipboard-button.js +99 -0
- package/dist/components/native-capabilities/device-io-controls.d.ts +4 -0
- package/dist/components/native-capabilities/device-io-controls.d.ts.map +1 -0
- package/dist/components/native-capabilities/device-io-controls.js +28 -0
- package/dist/components/native-capabilities/device-list.d.ts +20 -0
- package/dist/components/native-capabilities/device-list.d.ts.map +1 -0
- package/dist/components/native-capabilities/device-list.js +14 -0
- package/dist/components/native-capabilities/display-map.d.ts +23 -0
- package/dist/components/native-capabilities/display-map.d.ts.map +1 -0
- package/dist/components/native-capabilities/display-map.js +114 -0
- package/dist/components/native-capabilities/haptic-button.d.ts +26 -0
- package/dist/components/native-capabilities/haptic-button.d.ts.map +1 -0
- package/dist/components/native-capabilities/haptic-button.js +94 -0
- package/dist/components/native-capabilities/hid-panel.d.ts +40 -0
- package/dist/components/native-capabilities/hid-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/hid-panel.js +373 -0
- package/dist/components/native-capabilities/index.d.ts +27 -0
- package/dist/components/native-capabilities/index.d.ts.map +1 -0
- package/dist/components/native-capabilities/index.js +26 -0
- package/dist/components/native-capabilities/live-indicator.d.ts +15 -0
- package/dist/components/native-capabilities/live-indicator.d.ts.map +1 -0
- package/dist/components/native-capabilities/live-indicator.js +26 -0
- package/dist/components/native-capabilities/local-auth-button.d.ts +33 -0
- package/dist/components/native-capabilities/local-auth-button.d.ts.map +1 -0
- package/dist/components/native-capabilities/local-auth-button.js +115 -0
- package/dist/components/native-capabilities/location-panel.d.ts +29 -0
- package/dist/components/native-capabilities/location-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/location-panel.js +146 -0
- package/dist/components/native-capabilities/microphone-meter.d.ts +35 -0
- package/dist/components/native-capabilities/microphone-meter.d.ts.map +1 -0
- package/dist/components/native-capabilities/microphone-meter.js +244 -0
- package/dist/components/native-capabilities/midi-monitor.d.ts +54 -0
- package/dist/components/native-capabilities/midi-monitor.d.ts.map +1 -0
- package/dist/components/native-capabilities/midi-monitor.js +534 -0
- package/dist/components/native-capabilities/native-capability-panel.d.ts +11 -0
- package/dist/components/native-capabilities/native-capability-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/native-capability-panel.js +28 -0
- package/dist/components/native-capabilities/notification-panel.d.ts +24 -0
- package/dist/components/native-capabilities/notification-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/notification-panel.js +124 -0
- package/dist/components/native-capabilities/power-blocker-controller.d.ts +19 -0
- package/dist/components/native-capabilities/power-blocker-controller.d.ts.map +1 -0
- package/dist/components/native-capabilities/power-blocker-controller.js +83 -0
- package/dist/components/native-capabilities/power-panel.d.ts +67 -0
- package/dist/components/native-capabilities/power-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/power-panel.js +309 -0
- package/dist/components/native-capabilities/readout.d.ts +10 -0
- package/dist/components/native-capabilities/readout.d.ts.map +1 -0
- package/dist/components/native-capabilities/readout.js +11 -0
- package/dist/components/native-capabilities/screen-share-preview.d.ts +36 -0
- package/dist/components/native-capabilities/screen-share-preview.d.ts.map +1 -0
- package/dist/components/native-capabilities/screen-share-preview.js +191 -0
- package/dist/components/native-capabilities/secure-storage-panel.d.ts +36 -0
- package/dist/components/native-capabilities/secure-storage-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/secure-storage-panel.js +193 -0
- package/dist/components/native-capabilities/serial-console.d.ts +64 -0
- package/dist/components/native-capabilities/serial-console.d.ts.map +1 -0
- package/dist/components/native-capabilities/serial-console.js +399 -0
- package/dist/components/native-capabilities/shortcut-recorder.d.ts +35 -0
- package/dist/components/native-capabilities/shortcut-recorder.d.ts.map +1 -0
- package/dist/components/native-capabilities/shortcut-recorder.js +217 -0
- package/dist/components/native-capabilities/stream-log.d.ts +35 -0
- package/dist/components/native-capabilities/stream-log.d.ts.map +1 -0
- package/dist/components/native-capabilities/stream-log.js +65 -0
- package/dist/components/native-capabilities/system-audio-monitor.d.ts +34 -0
- package/dist/components/native-capabilities/system-audio-monitor.d.ts.map +1 -0
- package/dist/components/native-capabilities/system-audio-monitor.js +275 -0
- package/dist/components/native-capabilities/usb-panel.d.ts +54 -0
- package/dist/components/native-capabilities/usb-panel.d.ts.map +1 -0
- package/dist/components/native-capabilities/usb-panel.js +363 -0
- package/dist/components/native-capabilities/use-capability.d.ts +20 -0
- package/dist/components/native-capabilities/use-capability.d.ts.map +1 -0
- package/dist/components/native-capabilities/use-capability.js +61 -0
- package/dist/components/ui/alert-dialog.d.ts +7 -3
- package/dist/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog.js +9 -5
- package/dist/components/ui/alert.d.ts +19 -3
- package/dist/components/ui/alert.d.ts.map +1 -1
- package/dist/components/ui/alert.js +25 -8
- package/dist/components/ui/app-frame.d.ts +28 -0
- package/dist/components/ui/app-frame.d.ts.map +1 -0
- package/dist/components/ui/app-frame.js +95 -0
- package/dist/components/ui/button-group.d.ts +1 -1
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/collapsible.d.ts +9 -1
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/collapsible.js +13 -2
- package/dist/components/ui/collection-navigation.d.ts +8 -0
- package/dist/components/ui/collection-navigation.d.ts.map +1 -0
- package/dist/components/ui/collection-navigation.js +19 -0
- package/dist/components/ui/color-well.d.ts +13 -0
- package/dist/components/ui/color-well.d.ts.map +1 -0
- package/dist/components/ui/color-well.js +30 -0
- package/dist/components/ui/command.d.ts +5 -1
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/command.js +13 -1
- package/dist/components/ui/confirm-dialog.d.ts +19 -0
- package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
- package/dist/components/ui/confirm-dialog.js +45 -0
- package/dist/components/ui/date-field.d.ts +19 -0
- package/dist/components/ui/date-field.d.ts.map +1 -0
- package/dist/components/ui/date-field.js +54 -0
- package/dist/components/ui/date-picker.d.ts +24 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/date-picker.js +92 -0
- package/dist/components/ui/dialog.d.ts +4 -2
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog.js +8 -5
- package/dist/components/ui/edge-fade.d.ts +11 -0
- package/dist/components/ui/edge-fade.d.ts.map +1 -0
- package/dist/components/ui/edge-fade.js +41 -0
- package/dist/components/ui/empty.d.ts +7 -2
- package/dist/components/ui/empty.d.ts.map +1 -1
- package/dist/components/ui/empty.js +20 -7
- package/dist/components/ui/field.d.ts +1 -1
- package/dist/components/ui/grid.d.ts +24 -0
- package/dist/components/ui/grid.d.ts.map +1 -0
- package/dist/components/ui/grid.js +258 -0
- package/dist/components/ui/icon-button.d.ts +15 -0
- package/dist/components/ui/icon-button.d.ts.map +1 -0
- package/dist/components/ui/icon-button.js +15 -0
- package/dist/components/ui/index.d.ts +23 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +23 -0
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/inspector.d.ts +15 -0
- package/dist/components/ui/inspector.d.ts.map +1 -0
- package/dist/components/ui/inspector.js +26 -0
- package/dist/components/ui/kbd.d.ts +1 -1
- package/dist/components/ui/list.d.ts +28 -0
- package/dist/components/ui/list.d.ts.map +1 -0
- package/dist/components/ui/list.js +235 -0
- package/dist/components/ui/material.d.ts +34 -0
- package/dist/components/ui/material.d.ts.map +1 -0
- package/dist/components/ui/material.js +34 -0
- package/dist/components/ui/message-scroller-controller.d.ts +162 -0
- package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-controller.js +888 -0
- package/dist/components/ui/message-scroller-layout-stability.d.ts +33 -0
- package/dist/components/ui/message-scroller-layout-stability.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-layout-stability.js +153 -0
- package/dist/components/ui/message-scroller-policy.d.ts +74 -0
- package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-policy.js +129 -0
- package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
- package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-primitive.js +226 -0
- package/dist/components/ui/message-scroller.d.ts +11 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller.js +25 -0
- package/dist/components/ui/navigation-button-group.d.ts +16 -0
- package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
- package/dist/components/ui/navigation-button-group.js +9 -0
- package/dist/components/ui/notification-dot.d.ts +4 -0
- package/dist/components/ui/notification-dot.d.ts.map +1 -0
- package/dist/components/ui/notification-dot.js +7 -0
- package/dist/components/ui/number-input.d.ts +16 -0
- package/dist/components/ui/number-input.d.ts.map +1 -0
- package/dist/components/ui/number-input.js +56 -0
- package/dist/components/ui/panel.d.ts +18 -0
- package/dist/components/ui/panel.d.ts.map +1 -0
- package/dist/components/ui/panel.js +40 -0
- package/dist/components/ui/popover.d.ts +9 -2
- package/dist/components/ui/popover.d.ts.map +1 -1
- package/dist/components/ui/popover.js +14 -4
- package/dist/components/ui/scroll-area.d.ts +8 -2
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.js +6 -3
- package/dist/components/ui/search-field.d.ts +19 -0
- package/dist/components/ui/search-field.d.ts.map +1 -0
- package/dist/components/ui/search-field.js +64 -0
- package/dist/components/ui/segmented-control.d.ts +21 -0
- package/dist/components/ui/segmented-control.d.ts.map +1 -0
- package/dist/components/ui/segmented-control.js +62 -0
- package/dist/components/ui/sheet.d.ts +4 -2
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet.js +12 -9
- package/dist/components/ui/sidebar.js +1 -1
- package/dist/components/ui/sonner.d.ts +4 -3
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/sonner.js +7 -6
- package/dist/components/ui/split-view.d.ts +11 -0
- package/dist/components/ui/split-view.d.ts.map +1 -0
- package/dist/components/ui/split-view.js +13 -0
- package/dist/components/ui/status.d.ts +13 -0
- package/dist/components/ui/status.d.ts.map +1 -0
- package/dist/components/ui/status.js +36 -0
- package/dist/components/ui/table.d.ts +11 -2
- package/dist/components/ui/table.d.ts.map +1 -1
- package/dist/components/ui/table.js +33 -6
- package/dist/components/ui/text.d.ts +17 -0
- package/dist/components/ui/text.d.ts.map +1 -0
- package/dist/components/ui/text.js +55 -0
- package/dist/components/ui/toggle.d.ts +12 -4
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/components/ui/toggle.js +13 -2
- package/dist/components/ui/toolbar.d.ts +27 -0
- package/dist/components/ui/toolbar.d.ts.map +1 -0
- package/dist/components/ui/toolbar.js +71 -0
- package/dist/components/ui/tooltip.d.ts +8 -3
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +11 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/lib/frame-lifecycle.d.ts +29 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +85 -0
- package/dist/lib/native-capabilities/access.d.ts +13 -0
- package/dist/lib/native-capabilities/access.d.ts.map +1 -0
- package/dist/lib/native-capabilities/access.js +53 -0
- package/dist/lib/native-capabilities/bluetooth-access.d.ts +14 -0
- package/dist/lib/native-capabilities/bluetooth-access.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-access.js +43 -0
- package/dist/lib/native-capabilities/bluetooth-connection.d.ts +19 -0
- package/dist/lib/native-capabilities/bluetooth-connection.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-connection.js +88 -0
- package/dist/lib/native-capabilities/bluetooth-gatt.d.ts +7 -0
- package/dist/lib/native-capabilities/bluetooth-gatt.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-gatt.js +77 -0
- package/dist/lib/native-capabilities/bluetooth-internal.d.ts +10 -0
- package/dist/lib/native-capabilities/bluetooth-internal.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-internal.js +105 -0
- package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts +33 -0
- package/dist/lib/native-capabilities/bluetooth-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-native-fallback.js +214 -0
- package/dist/lib/native-capabilities/bluetooth-types.d.ts +85 -0
- package/dist/lib/native-capabilities/bluetooth-types.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth-types.js +2 -0
- package/dist/lib/native-capabilities/bluetooth.d.ts +7 -0
- package/dist/lib/native-capabilities/bluetooth.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bluetooth.js +4 -0
- package/dist/lib/native-capabilities/bridge.d.ts +23 -0
- package/dist/lib/native-capabilities/bridge.d.ts.map +1 -0
- package/dist/lib/native-capabilities/bridge.js +266 -0
- package/dist/lib/native-capabilities/capabilities.d.ts +7 -0
- package/dist/lib/native-capabilities/capabilities.d.ts.map +1 -0
- package/dist/lib/native-capabilities/capabilities.js +95 -0
- package/dist/lib/native-capabilities/clipboard.d.ts +11 -0
- package/dist/lib/native-capabilities/clipboard.d.ts.map +1 -0
- package/dist/lib/native-capabilities/clipboard.js +58 -0
- package/dist/lib/native-capabilities/device-io-errors.d.ts +11 -0
- package/dist/lib/native-capabilities/device-io-errors.d.ts.map +1 -0
- package/dist/lib/native-capabilities/device-io-errors.js +82 -0
- package/dist/lib/native-capabilities/displays.d.ts +38 -0
- package/dist/lib/native-capabilities/displays.d.ts.map +1 -0
- package/dist/lib/native-capabilities/displays.js +12 -0
- package/dist/lib/native-capabilities/global-shortcuts.d.ts +86 -0
- package/dist/lib/native-capabilities/global-shortcuts.d.ts.map +1 -0
- package/dist/lib/native-capabilities/global-shortcuts.js +351 -0
- package/dist/lib/native-capabilities/haptics.d.ts +25 -0
- package/dist/lib/native-capabilities/haptics.d.ts.map +1 -0
- package/dist/lib/native-capabilities/haptics.js +18 -0
- package/dist/lib/native-capabilities/hid-native.d.ts +26 -0
- package/dist/lib/native-capabilities/hid-native.d.ts.map +1 -0
- package/dist/lib/native-capabilities/hid-native.js +229 -0
- package/dist/lib/native-capabilities/hid.d.ts +52 -0
- package/dist/lib/native-capabilities/hid.d.ts.map +1 -0
- package/dist/lib/native-capabilities/hid.js +163 -0
- package/dist/lib/native-capabilities/index.d.ts +40 -0
- package/dist/lib/native-capabilities/index.d.ts.map +1 -0
- package/dist/lib/native-capabilities/index.js +21 -0
- package/dist/lib/native-capabilities/local-authentication.d.ts +32 -0
- package/dist/lib/native-capabilities/local-authentication.d.ts.map +1 -0
- package/dist/lib/native-capabilities/local-authentication.js +46 -0
- package/dist/lib/native-capabilities/location.d.ts +49 -0
- package/dist/lib/native-capabilities/location.d.ts.map +1 -0
- package/dist/lib/native-capabilities/location.js +114 -0
- package/dist/lib/native-capabilities/media-permissions.d.ts +28 -0
- package/dist/lib/native-capabilities/media-permissions.d.ts.map +1 -0
- package/dist/lib/native-capabilities/media-permissions.js +37 -0
- package/dist/lib/native-capabilities/media.d.ts +17 -0
- package/dist/lib/native-capabilities/media.d.ts.map +1 -0
- package/dist/lib/native-capabilities/media.js +104 -0
- package/dist/lib/native-capabilities/midi-access.d.ts +13 -0
- package/dist/lib/native-capabilities/midi-access.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-access.js +68 -0
- package/dist/lib/native-capabilities/midi-internal.d.ts +12 -0
- package/dist/lib/native-capabilities/midi-internal.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-internal.js +88 -0
- package/dist/lib/native-capabilities/midi-native-fallback.d.ts +27 -0
- package/dist/lib/native-capabilities/midi-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-native-fallback.js +127 -0
- package/dist/lib/native-capabilities/midi-ports.d.ts +6 -0
- package/dist/lib/native-capabilities/midi-ports.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-ports.js +115 -0
- package/dist/lib/native-capabilities/midi-types.d.ts +25 -0
- package/dist/lib/native-capabilities/midi-types.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi-types.js +1 -0
- package/dist/lib/native-capabilities/midi.d.ts +6 -0
- package/dist/lib/native-capabilities/midi.d.ts.map +1 -0
- package/dist/lib/native-capabilities/midi.js +3 -0
- package/dist/lib/native-capabilities/native-device-io.d.ts +28 -0
- package/dist/lib/native-capabilities/native-device-io.d.ts.map +1 -0
- package/dist/lib/native-capabilities/native-device-io.js +91 -0
- package/dist/lib/native-capabilities/native-device-lifecycle.d.ts +13 -0
- package/dist/lib/native-capabilities/native-device-lifecycle.d.ts.map +1 -0
- package/dist/lib/native-capabilities/native-device-lifecycle.js +40 -0
- package/dist/lib/native-capabilities/notifications.d.ts +38 -0
- package/dist/lib/native-capabilities/notifications.d.ts.map +1 -0
- package/dist/lib/native-capabilities/notifications.js +50 -0
- package/dist/lib/native-capabilities/power-session.d.ts +113 -0
- package/dist/lib/native-capabilities/power-session.d.ts.map +1 -0
- package/dist/lib/native-capabilities/power-session.js +264 -0
- package/dist/lib/native-capabilities/secure-storage.d.ts +36 -0
- package/dist/lib/native-capabilities/secure-storage.d.ts.map +1 -0
- package/dist/lib/native-capabilities/secure-storage.js +64 -0
- package/dist/lib/native-capabilities/serial-native.d.ts +23 -0
- package/dist/lib/native-capabilities/serial-native.d.ts.map +1 -0
- package/dist/lib/native-capabilities/serial-native.js +181 -0
- package/dist/lib/native-capabilities/serial.d.ts +76 -0
- package/dist/lib/native-capabilities/serial.d.ts.map +1 -0
- package/dist/lib/native-capabilities/serial.js +215 -0
- package/dist/lib/native-capabilities/system-audio.d.ts +127 -0
- package/dist/lib/native-capabilities/system-audio.d.ts.map +1 -0
- package/dist/lib/native-capabilities/system-audio.js +330 -0
- package/dist/lib/native-capabilities/types.d.ts +62 -0
- package/dist/lib/native-capabilities/types.d.ts.map +1 -0
- package/dist/lib/native-capabilities/types.js +27 -0
- package/dist/lib/native-capabilities/usb-native.d.ts +39 -0
- package/dist/lib/native-capabilities/usb-native.d.ts.map +1 -0
- package/dist/lib/native-capabilities/usb-native.js +217 -0
- package/dist/lib/native-capabilities/usb.d.ts +85 -0
- package/dist/lib/native-capabilities/usb.d.ts.map +1 -0
- package/dist/lib/native-capabilities/usb.js +225 -0
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/lib/theme.js +2 -1
- package/docs/README.md +39 -0
- package/docs/accessibility.md +32 -0
- package/docs/adaptive-materials.md +79 -0
- package/docs/app-anatomy.md +74 -0
- package/docs/component-catalog.md +82 -0
- package/docs/component-guide-template.md +37 -0
- package/docs/design-tokens.md +185 -0
- package/docs/foundations.md +58 -0
- package/docs/native-integration.md +33 -0
- package/docs/standalone-app-windows.md +136 -0
- package/package.json +8 -3
- package/src/components/ui/alert-dialog.md +31 -0
- package/src/components/ui/alert.md +77 -0
- package/src/components/ui/app-frame.md +38 -0
- package/src/components/ui/badge.md +57 -0
- package/src/components/ui/button.md +76 -0
- package/src/components/ui/collapsible.md +52 -0
- package/src/components/ui/color-well.md +11 -0
- package/src/components/ui/combobox.md +42 -0
- package/src/components/ui/command.md +54 -0
- package/src/components/ui/date-field.md +32 -0
- package/src/components/ui/date-picker.md +55 -0
- package/src/components/ui/dialog.md +40 -0
- package/src/components/ui/edge-fade.md +7 -0
- package/src/components/ui/empty.md +87 -0
- package/src/components/ui/field.md +77 -0
- package/src/components/ui/grid.md +109 -0
- package/src/components/ui/icon-button.md +36 -0
- package/src/components/ui/inspector.md +11 -0
- package/src/components/ui/item.md +87 -0
- package/src/components/ui/list.md +140 -0
- package/src/components/ui/material.md +51 -0
- package/src/components/ui/navigation-button-group.md +46 -0
- package/src/components/ui/notification-dot.md +7 -0
- package/src/components/ui/number-input.md +19 -0
- package/src/components/ui/panel.md +11 -0
- package/src/components/ui/popover.md +31 -0
- package/src/components/ui/resizable.md +66 -0
- package/src/components/ui/scroll-area.md +72 -0
- package/src/components/ui/search-field.md +33 -0
- package/src/components/ui/segmented-control.md +36 -0
- package/src/components/ui/sheet.md +30 -0
- package/src/components/ui/sidebar.md +113 -0
- package/src/components/ui/sonner.md +37 -0
- package/src/components/ui/split-view.md +15 -0
- package/src/components/ui/status.md +12 -0
- package/src/components/ui/table.md +37 -0
- package/src/components/ui/tabs.md +66 -0
- package/src/components/ui/text.md +17 -0
- package/src/components/ui/toggle-button.md +48 -0
- package/src/components/ui/toggle-group.md +80 -0
- package/src/components/ui/toggle.md +73 -0
- package/src/components/ui/toolbar.md +26 -0
- package/src/components/ui/tooltip.md +31 -0
- package/src/styles/index.css +704 -3
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Cable, CornerDownLeft, Plug, RefreshCw, ShieldX, Unplug, } from 'lucide-react';
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { closeMoldableSerialPort, forgetMoldableSerialPort, getMoldableSerialSignals, openMoldableSerialPort, readMoldableSerialPort, requestMoldableSerialPort, setMoldableSerialSignals, writeMoldableSerialPort, } from '../../lib/native-capabilities';
|
|
6
|
+
import { Button } from '../ui/button';
|
|
7
|
+
import { Input } from '../ui/input';
|
|
8
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../ui/select';
|
|
9
|
+
import { Spinner } from '../ui/spinner';
|
|
10
|
+
import { Switch } from '../ui/switch';
|
|
11
|
+
import { CapabilityBadge } from './capability-badge';
|
|
12
|
+
import { LiveIndicator } from './live-indicator';
|
|
13
|
+
import { NativeCapabilityPanel, NativeCapabilityPanelAction, NativeCapabilityPanelContent, NativeCapabilityPanelFooter, NativeCapabilityPanelHeader, NativeCapabilityPanelIcon, NativeCapabilityPanelTitle, } from './native-capability-panel';
|
|
14
|
+
import { StreamLog, useStreamLog } from './stream-log';
|
|
15
|
+
const BAUD_RATES = [9600, 19200, 38400, 57600, 115200, 230400];
|
|
16
|
+
const DEFAULT_BAUD_RATE = 115200;
|
|
17
|
+
function toError(cause) {
|
|
18
|
+
return cause instanceof Error ? cause : new Error(String(cause));
|
|
19
|
+
}
|
|
20
|
+
function formatHexId(value) {
|
|
21
|
+
return `0x${value.toString(16).padStart(4, '0')}`;
|
|
22
|
+
}
|
|
23
|
+
function formatSerialPortLabel(info) {
|
|
24
|
+
if (info?.usbVendorId !== undefined && info.usbProductId !== undefined) {
|
|
25
|
+
return `${formatHexId(info.usbVendorId)}:${formatHexId(info.usbProductId)}`;
|
|
26
|
+
}
|
|
27
|
+
if (info?.usbVendorId !== undefined)
|
|
28
|
+
return formatHexId(info.usbVendorId);
|
|
29
|
+
return 'Serial port';
|
|
30
|
+
}
|
|
31
|
+
function formatHexBytes(bytes) {
|
|
32
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join(' ');
|
|
33
|
+
}
|
|
34
|
+
const SIGNALS_OFF = {
|
|
35
|
+
dataTerminalReady: false,
|
|
36
|
+
requestToSend: false,
|
|
37
|
+
break: false,
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Serial state machine behind `SerialConsole`: request → open → streaming
|
|
41
|
+
* read loop with UTF-8 decode, line sends, DTR/RTS control, RX/TX log.
|
|
42
|
+
* Use directly to build custom serial UI on the same lifecycle handling.
|
|
43
|
+
*/
|
|
44
|
+
export function useMoldableSerial(options = {}) {
|
|
45
|
+
const [status, setStatus] = useState('idle');
|
|
46
|
+
const [port, setPort] = useState(null);
|
|
47
|
+
const [portInfo, setPortInfo] = useState(null);
|
|
48
|
+
const [error, setError] = useState(null);
|
|
49
|
+
const [signals, setSignalsState] = useState(SIGNALS_OFF);
|
|
50
|
+
const [inputSignals, setInputSignals] = useState(null);
|
|
51
|
+
const [rxBytes, setRxBytes] = useState(0);
|
|
52
|
+
const [txBytes, setTxBytes] = useState(0);
|
|
53
|
+
const { entries, append, clear: clearEntries, } = useStreamLog(options.maxEntries ?? 500);
|
|
54
|
+
const portRef = useRef(null);
|
|
55
|
+
const portOpenRef = useRef(false);
|
|
56
|
+
const abortRef = useRef(null);
|
|
57
|
+
const readLoopRef = useRef(null);
|
|
58
|
+
const disconnectListenerRef = useRef(null);
|
|
59
|
+
const tokenRef = useRef(0);
|
|
60
|
+
const signalsRef = useRef(SIGNALS_OFF);
|
|
61
|
+
const optionsRef = useRef(options);
|
|
62
|
+
optionsRef.current = options;
|
|
63
|
+
const clearPort = useCallback((active) => {
|
|
64
|
+
if (portRef.current !== active)
|
|
65
|
+
return;
|
|
66
|
+
const registered = disconnectListenerRef.current;
|
|
67
|
+
if (registered?.port === active) {
|
|
68
|
+
active.removeEventListener('disconnect', registered.listener);
|
|
69
|
+
disconnectListenerRef.current = null;
|
|
70
|
+
}
|
|
71
|
+
portRef.current = null;
|
|
72
|
+
portOpenRef.current = false;
|
|
73
|
+
signalsRef.current = SIGNALS_OFF;
|
|
74
|
+
setSignalsState(SIGNALS_OFF);
|
|
75
|
+
setInputSignals(null);
|
|
76
|
+
setPort(null);
|
|
77
|
+
setPortInfo(null);
|
|
78
|
+
}, []);
|
|
79
|
+
const teardown = useCallback(async (forgetPermission = false) => {
|
|
80
|
+
abortRef.current?.abort();
|
|
81
|
+
abortRef.current = null;
|
|
82
|
+
const loop = readLoopRef.current;
|
|
83
|
+
readLoopRef.current = null;
|
|
84
|
+
if (loop)
|
|
85
|
+
await loop.catch(() => undefined);
|
|
86
|
+
const active = portRef.current;
|
|
87
|
+
if (!active)
|
|
88
|
+
return;
|
|
89
|
+
if (portOpenRef.current) {
|
|
90
|
+
await closeMoldableSerialPort(active);
|
|
91
|
+
portOpenRef.current = false;
|
|
92
|
+
}
|
|
93
|
+
if (forgetPermission)
|
|
94
|
+
await forgetMoldableSerialPort(active);
|
|
95
|
+
clearPort(active);
|
|
96
|
+
}, [clearPort]);
|
|
97
|
+
const refreshSignals = useCallback(async () => {
|
|
98
|
+
const active = portRef.current;
|
|
99
|
+
if (!active || !portOpenRef.current)
|
|
100
|
+
return;
|
|
101
|
+
try {
|
|
102
|
+
setInputSignals(await getMoldableSerialSignals(active));
|
|
103
|
+
}
|
|
104
|
+
catch (cause) {
|
|
105
|
+
const failure = toError(cause);
|
|
106
|
+
setError(failure);
|
|
107
|
+
append({ direction: 'error', data: failure.message });
|
|
108
|
+
}
|
|
109
|
+
}, [append]);
|
|
110
|
+
const runReadLoop = useCallback(async (activePort, token, controller) => {
|
|
111
|
+
const decoder = new TextDecoder();
|
|
112
|
+
try {
|
|
113
|
+
for (;;) {
|
|
114
|
+
const result = await readMoldableSerialPort(activePort, {
|
|
115
|
+
signal: controller.signal,
|
|
116
|
+
});
|
|
117
|
+
if (tokenRef.current !== token)
|
|
118
|
+
return;
|
|
119
|
+
const bytes = result.value;
|
|
120
|
+
if (bytes && bytes.byteLength > 0) {
|
|
121
|
+
setRxBytes((count) => count + bytes.byteLength);
|
|
122
|
+
optionsRef.current.onData?.(bytes);
|
|
123
|
+
const text = decoder.decode(bytes, { stream: true });
|
|
124
|
+
if (text.length > 0)
|
|
125
|
+
append({ direction: 'in', data: text });
|
|
126
|
+
}
|
|
127
|
+
if (result.done) {
|
|
128
|
+
append({ direction: 'info', data: 'Serial stream ended' });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (cause) {
|
|
134
|
+
if (tokenRef.current !== token || controller.signal.aborted)
|
|
135
|
+
return;
|
|
136
|
+
const failure = toError(cause);
|
|
137
|
+
setError(failure);
|
|
138
|
+
setStatus('error');
|
|
139
|
+
append({ direction: 'error', data: failure.message });
|
|
140
|
+
}
|
|
141
|
+
}, [append]);
|
|
142
|
+
const connect = useCallback(async (overrides = {}) => {
|
|
143
|
+
const token = ++tokenRef.current;
|
|
144
|
+
setStatus('connecting');
|
|
145
|
+
setError(null);
|
|
146
|
+
try {
|
|
147
|
+
await teardown();
|
|
148
|
+
if (tokenRef.current !== token)
|
|
149
|
+
return;
|
|
150
|
+
const filters = overrides.filters ?? optionsRef.current.filters;
|
|
151
|
+
const requested = await requestMoldableSerialPort({
|
|
152
|
+
...(filters ? { filters } : {}),
|
|
153
|
+
...(optionsRef.current.selectNativePort
|
|
154
|
+
? { selectNativePort: optionsRef.current.selectNativePort }
|
|
155
|
+
: {}),
|
|
156
|
+
});
|
|
157
|
+
if (tokenRef.current !== token)
|
|
158
|
+
return;
|
|
159
|
+
const baudRate = overrides.baudRate ?? optionsRef.current.baudRate ?? DEFAULT_BAUD_RATE;
|
|
160
|
+
await openMoldableSerialPort(requested, {
|
|
161
|
+
baudRate,
|
|
162
|
+
dataBits: 8,
|
|
163
|
+
stopBits: 1,
|
|
164
|
+
parity: 'none',
|
|
165
|
+
flowControl: 'none',
|
|
166
|
+
});
|
|
167
|
+
if (tokenRef.current !== token) {
|
|
168
|
+
portRef.current = requested;
|
|
169
|
+
portOpenRef.current = true;
|
|
170
|
+
try {
|
|
171
|
+
await closeMoldableSerialPort(requested);
|
|
172
|
+
clearPort(requested);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
setPort(requested);
|
|
176
|
+
setPortInfo(requested.getInfo());
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const handleDisconnect = () => {
|
|
181
|
+
if (tokenRef.current !== token)
|
|
182
|
+
return;
|
|
183
|
+
tokenRef.current++;
|
|
184
|
+
abortRef.current?.abort();
|
|
185
|
+
abortRef.current = null;
|
|
186
|
+
const loop = readLoopRef.current;
|
|
187
|
+
readLoopRef.current = null;
|
|
188
|
+
void Promise.resolve(loop)
|
|
189
|
+
.catch(() => undefined)
|
|
190
|
+
.then(async () => {
|
|
191
|
+
try {
|
|
192
|
+
if (portOpenRef.current) {
|
|
193
|
+
await closeMoldableSerialPort(requested);
|
|
194
|
+
portOpenRef.current = false;
|
|
195
|
+
}
|
|
196
|
+
clearPort(requested);
|
|
197
|
+
const failure = new Error('Serial port disconnected.');
|
|
198
|
+
setError(failure);
|
|
199
|
+
setStatus('error');
|
|
200
|
+
append({ direction: 'error', data: failure.message });
|
|
201
|
+
}
|
|
202
|
+
catch (cause) {
|
|
203
|
+
const failure = toError(cause);
|
|
204
|
+
setError(failure);
|
|
205
|
+
setStatus('error');
|
|
206
|
+
append({ direction: 'error', data: failure.message });
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
requested.addEventListener('disconnect', handleDisconnect, {
|
|
211
|
+
once: true,
|
|
212
|
+
});
|
|
213
|
+
disconnectListenerRef.current = {
|
|
214
|
+
port: requested,
|
|
215
|
+
listener: handleDisconnect,
|
|
216
|
+
};
|
|
217
|
+
portRef.current = requested;
|
|
218
|
+
portOpenRef.current = true;
|
|
219
|
+
setPort(requested);
|
|
220
|
+
setPortInfo(requested.getInfo());
|
|
221
|
+
setStatus('connected');
|
|
222
|
+
append({ direction: 'info', data: `Connected · ${baudRate} baud` });
|
|
223
|
+
const controller = new AbortController();
|
|
224
|
+
abortRef.current = controller;
|
|
225
|
+
readLoopRef.current = runReadLoop(requested, token, controller);
|
|
226
|
+
void refreshSignals();
|
|
227
|
+
}
|
|
228
|
+
catch (cause) {
|
|
229
|
+
if (tokenRef.current !== token)
|
|
230
|
+
return;
|
|
231
|
+
const failure = toError(cause);
|
|
232
|
+
setError(failure);
|
|
233
|
+
setStatus('error');
|
|
234
|
+
append({ direction: 'error', data: failure.message });
|
|
235
|
+
}
|
|
236
|
+
}, [append, clearPort, refreshSignals, runReadLoop, teardown]);
|
|
237
|
+
const disconnect = useCallback(async () => {
|
|
238
|
+
tokenRef.current++;
|
|
239
|
+
try {
|
|
240
|
+
await teardown();
|
|
241
|
+
setStatus('idle');
|
|
242
|
+
setError(null);
|
|
243
|
+
}
|
|
244
|
+
catch (cause) {
|
|
245
|
+
const failure = toError(cause);
|
|
246
|
+
setError(failure);
|
|
247
|
+
setStatus('error');
|
|
248
|
+
append({ direction: 'error', data: failure.message });
|
|
249
|
+
}
|
|
250
|
+
}, [append, teardown]);
|
|
251
|
+
const forget = useCallback(async () => {
|
|
252
|
+
tokenRef.current++;
|
|
253
|
+
try {
|
|
254
|
+
await teardown(true);
|
|
255
|
+
setStatus('idle');
|
|
256
|
+
setError(null);
|
|
257
|
+
append({ direction: 'info', data: 'Serial permission forgotten' });
|
|
258
|
+
}
|
|
259
|
+
catch (cause) {
|
|
260
|
+
const failure = toError(cause);
|
|
261
|
+
setError(failure);
|
|
262
|
+
setStatus('error');
|
|
263
|
+
append({ direction: 'error', data: failure.message });
|
|
264
|
+
}
|
|
265
|
+
}, [append, teardown]);
|
|
266
|
+
const send = useCallback(async (data) => {
|
|
267
|
+
const active = portRef.current;
|
|
268
|
+
if (!active)
|
|
269
|
+
return;
|
|
270
|
+
const bytes = typeof data === 'string' ? new TextEncoder().encode(`${data}\n`) : data;
|
|
271
|
+
try {
|
|
272
|
+
await writeMoldableSerialPort(active, bytes);
|
|
273
|
+
setTxBytes((count) => count + bytes.byteLength);
|
|
274
|
+
append({
|
|
275
|
+
direction: 'out',
|
|
276
|
+
data: typeof data === 'string' ? data : formatHexBytes(data),
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
catch (cause) {
|
|
280
|
+
const failure = toError(cause);
|
|
281
|
+
setError(failure);
|
|
282
|
+
append({ direction: 'error', data: failure.message });
|
|
283
|
+
}
|
|
284
|
+
}, [append]);
|
|
285
|
+
const setSignals = useCallback(async (next) => {
|
|
286
|
+
const active = portRef.current;
|
|
287
|
+
if (!active)
|
|
288
|
+
return;
|
|
289
|
+
try {
|
|
290
|
+
await setMoldableSerialSignals(active, next);
|
|
291
|
+
signalsRef.current = {
|
|
292
|
+
dataTerminalReady: next.dataTerminalReady ?? signalsRef.current.dataTerminalReady,
|
|
293
|
+
requestToSend: next.requestToSend ?? signalsRef.current.requestToSend,
|
|
294
|
+
break: next.break ?? signalsRef.current.break,
|
|
295
|
+
};
|
|
296
|
+
setSignalsState(signalsRef.current);
|
|
297
|
+
void refreshSignals();
|
|
298
|
+
}
|
|
299
|
+
catch (cause) {
|
|
300
|
+
const failure = toError(cause);
|
|
301
|
+
setError(failure);
|
|
302
|
+
append({ direction: 'error', data: failure.message });
|
|
303
|
+
}
|
|
304
|
+
}, [append, refreshSignals]);
|
|
305
|
+
useEffect(() => () => {
|
|
306
|
+
tokenRef.current++;
|
|
307
|
+
abortRef.current?.abort();
|
|
308
|
+
abortRef.current = null;
|
|
309
|
+
const loop = readLoopRef.current;
|
|
310
|
+
readLoopRef.current = null;
|
|
311
|
+
const active = portRef.current;
|
|
312
|
+
if (active) {
|
|
313
|
+
const registered = disconnectListenerRef.current;
|
|
314
|
+
if (registered?.port === active) {
|
|
315
|
+
active.removeEventListener('disconnect', registered.listener);
|
|
316
|
+
disconnectListenerRef.current = null;
|
|
317
|
+
}
|
|
318
|
+
void Promise.resolve(loop)
|
|
319
|
+
.catch(() => undefined)
|
|
320
|
+
.then(async () => {
|
|
321
|
+
if (portOpenRef.current)
|
|
322
|
+
await closeMoldableSerialPort(active);
|
|
323
|
+
})
|
|
324
|
+
.catch(() => undefined);
|
|
325
|
+
}
|
|
326
|
+
}, []);
|
|
327
|
+
return {
|
|
328
|
+
status,
|
|
329
|
+
port,
|
|
330
|
+
portInfo,
|
|
331
|
+
error,
|
|
332
|
+
signals,
|
|
333
|
+
inputSignals,
|
|
334
|
+
entries,
|
|
335
|
+
rxBytes,
|
|
336
|
+
txBytes,
|
|
337
|
+
connect,
|
|
338
|
+
disconnect,
|
|
339
|
+
forget,
|
|
340
|
+
send,
|
|
341
|
+
setSignals,
|
|
342
|
+
refreshSignals,
|
|
343
|
+
clearEntries,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Serial console panel: baud-rate chooser, connect/disconnect lifecycle,
|
|
348
|
+
* auto-following RX/TX log, line composer, signal controls, byte counters.
|
|
349
|
+
*/
|
|
350
|
+
function SerialConsole({ className, baudRate = DEFAULT_BAUD_RATE, filters, selectNativePort, onData, ...props }) {
|
|
351
|
+
const [nativePortChoices, setNativePortChoices] = useState([]);
|
|
352
|
+
const pendingSelectionRef = useRef(null);
|
|
353
|
+
const selectPort = useCallback((ports) => {
|
|
354
|
+
if (selectNativePort)
|
|
355
|
+
return selectNativePort(ports);
|
|
356
|
+
return new Promise((resolve, reject) => {
|
|
357
|
+
pendingSelectionRef.current?.reject(new DOMException('Serial port selection was replaced.', 'AbortError'));
|
|
358
|
+
pendingSelectionRef.current = { resolve, reject };
|
|
359
|
+
setNativePortChoices(ports);
|
|
360
|
+
});
|
|
361
|
+
}, [selectNativePort]);
|
|
362
|
+
const serial = useMoldableSerial({
|
|
363
|
+
baudRate,
|
|
364
|
+
filters,
|
|
365
|
+
selectNativePort: selectPort,
|
|
366
|
+
onData,
|
|
367
|
+
});
|
|
368
|
+
const [baud, setBaud] = useState(() => String(baudRate));
|
|
369
|
+
const [draft, setDraft] = useState('');
|
|
370
|
+
const rates = BAUD_RATES.includes(baudRate)
|
|
371
|
+
? BAUD_RATES
|
|
372
|
+
: [...BAUD_RATES, baudRate].sort((left, right) => left - right);
|
|
373
|
+
const connected = serial.status === 'connected';
|
|
374
|
+
const connecting = serial.status === 'connecting';
|
|
375
|
+
const retainedPort = serial.port !== null;
|
|
376
|
+
useEffect(() => () => {
|
|
377
|
+
pendingSelectionRef.current?.reject(new DOMException('Serial port selection was cancelled.', 'AbortError'));
|
|
378
|
+
pendingSelectionRef.current = null;
|
|
379
|
+
}, []);
|
|
380
|
+
const chooseNativePort = (port) => {
|
|
381
|
+
pendingSelectionRef.current?.resolve(port);
|
|
382
|
+
pendingSelectionRef.current = null;
|
|
383
|
+
setNativePortChoices([]);
|
|
384
|
+
};
|
|
385
|
+
const cancelNativePortSelection = () => {
|
|
386
|
+
pendingSelectionRef.current?.reject(new DOMException('Serial port selection was cancelled.', 'AbortError'));
|
|
387
|
+
pendingSelectionRef.current = null;
|
|
388
|
+
setNativePortChoices([]);
|
|
389
|
+
};
|
|
390
|
+
const submitLine = (event) => {
|
|
391
|
+
event.preventDefault();
|
|
392
|
+
if (!connected)
|
|
393
|
+
return;
|
|
394
|
+
void serial.send(draft);
|
|
395
|
+
setDraft('');
|
|
396
|
+
};
|
|
397
|
+
return (_jsxs(NativeCapabilityPanel, { "data-slot": "serial-console", "data-status": serial.status, className: className, ...props, children: [_jsxs(NativeCapabilityPanelHeader, { children: [_jsx(NativeCapabilityPanelIcon, { children: _jsx(Cable, {}) }), _jsx(NativeCapabilityPanelTitle, { children: "Serial" }), _jsx(CapabilityBadge, { capability: "serial" }), _jsx(NativeCapabilityPanelAction, { children: retainedPort ? (_jsxs(_Fragment, { children: [_jsx("span", { "data-slot": "serial-console-port", className: "animate-in fade-in text-muted-foreground bg-muted/50 rounded-md border px-2 py-0.5 font-mono text-xs tabular-nums duration-200 motion-reduce:animate-none", children: formatSerialPortLabel(serial.portInfo) }), connected ? _jsx(LiveIndicator, {}) : null, _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void serial.disconnect(), children: [_jsx(Unplug, {}), " ", connected ? 'Disconnect' : 'Retry disconnect'] })] })) : (_jsxs(_Fragment, { children: [_jsxs(Select, { value: baud, onValueChange: setBaud, disabled: connecting, children: [_jsx(SelectTrigger, { size: "sm", "aria-label": "Baud rate", className: "w-28 font-mono text-xs tabular-nums", children: _jsx(SelectValue, { placeholder: "Baud" }) }), _jsx(SelectContent, { children: rates.map((rate) => (_jsx(SelectItem, { value: String(rate), children: rate }, rate))) })] }), _jsxs(Button, { size: "sm", disabled: connecting, onClick: () => void serial.connect({ baudRate: Number(baud) }), children: [connecting ? _jsx(Spinner, {}) : _jsx(Plug, {}), connecting ? 'Connecting…' : 'Connect'] })] })) })] }), _jsxs(NativeCapabilityPanelContent, { className: "space-y-3", children: [nativePortChoices.length > 0 ? (_jsxs("div", { "data-slot": "serial-console-port-chooser", className: "bg-muted/30 space-y-2 rounded-lg border p-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-xs font-medium", children: "Choose a serial port" }), _jsx(Button, { size: "xs", variant: "ghost", onClick: cancelNativePortSelection, children: "Cancel" })] }), _jsx("div", { className: "grid gap-1.5", children: nativePortChoices.map((choice, index) => (_jsxs(Button, { size: "sm", variant: "outline", className: "justify-start font-mono", onClick: () => chooseNativePort(choice), children: [_jsx(Cable, {}), " ", formatSerialPortLabel(choice.getInfo())] }, `${formatSerialPortLabel(choice.getInfo())}-${index}`))) })] })) : null, serial.error ? (_jsx("p", { className: "text-status-error text-xs", children: serial.error.message })) : null, _jsx(StreamLog, { entries: serial.entries, maxHeight: 260, emptyLabel: connected ? 'Waiting for data' : 'Connect a port to start streaming' }), _jsxs("form", { "data-slot": "serial-console-composer", className: "flex items-center gap-2", onSubmit: submitLine, children: [_jsx(Input, { value: draft, onChange: (event) => setDraft(event.target.value), placeholder: "Send a line\u2026", disabled: !connected, spellCheck: false, autoComplete: "off", className: "h-8 flex-1 font-mono text-xs" }), _jsx(Button, { type: "submit", size: "icon-sm", variant: "outline", disabled: !connected, "aria-label": "Send line", children: _jsx(CornerDownLeft, {}) })] })] }), _jsxs(NativeCapabilityPanelFooter, { className: "flex-wrap", children: [_jsxs("label", { "data-slot": "serial-console-signal", className: "flex items-center gap-1.5", children: [_jsx(Switch, { size: "sm", checked: serial.signals.dataTerminalReady, disabled: !connected, onCheckedChange: (checked) => void serial.setSignals({ dataTerminalReady: checked }), "aria-label": "Data terminal ready" }), _jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider", children: "DTR" })] }), _jsxs("label", { "data-slot": "serial-console-signal", className: "flex items-center gap-1.5", children: [_jsx(Switch, { size: "sm", checked: serial.signals.requestToSend, disabled: !connected, onCheckedChange: (checked) => void serial.setSignals({ requestToSend: checked }), "aria-label": "Request to send" }), _jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider", children: "RTS" })] }), _jsxs("label", { "data-slot": "serial-console-signal", className: "flex items-center gap-1.5", children: [_jsx(Switch, { size: "sm", checked: serial.signals.break, disabled: !connected, onCheckedChange: (checked) => void serial.setSignals({ break: checked }), "aria-label": "Break signal" }), _jsx("span", { className: "text-[10px] font-medium uppercase tracking-wider", children: "BRK" })] }), _jsx(Button, { size: "icon-xs", variant: "ghost", disabled: !connected, onClick: () => void serial.refreshSignals(), "aria-label": "Refresh input signals", title: "Refresh input signals", children: _jsx(RefreshCw, {}) }), serial.inputSignals ? (_jsxs("span", { "data-slot": "serial-console-input-signals", className: "font-mono text-[10px] tabular-nums", children: ["CTS ", serial.inputSignals.clearToSend ? '1' : '0', " \u00B7 DCD", ' ', serial.inputSignals.dataCarrierDetect ? '1' : '0', " \u00B7 DSR", ' ', serial.inputSignals.dataSetReady ? '1' : '0', " \u00B7 RI", ' ', serial.inputSignals.ringIndicator ? '1' : '0'] })) : null, retainedPort ? (_jsxs(Button, { size: "xs", variant: "ghost", onClick: () => void serial.forget(), children: [_jsx(ShieldX, {}), " Forget"] })) : null, _jsxs("span", { "data-slot": "serial-console-counters", className: "ml-auto shrink-0 font-mono tabular-nums", children: ["RX ", serial.rxBytes, " \u00B7 TX ", serial.txBytes] })] })] }));
|
|
398
|
+
}
|
|
399
|
+
export { SerialConsole };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MoldableGlobalShortcutEvent, type MoldableGlobalShortcutHandler } from '../../lib/native-capabilities';
|
|
3
|
+
/**
|
|
4
|
+
* Splits an Electron-style accelerator ("CommandOrControl+Shift+K") into
|
|
5
|
+
* display keys for `Kbd` chips — ['⌘', '⇧', 'K'] on macOS, ['Ctrl', 'Shift',
|
|
6
|
+
* 'K'] elsewhere.
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatShortcutKeys(accelerator: string): string[];
|
|
9
|
+
/**
|
|
10
|
+
* Registers a global shortcut while `shortcut` is set, unregistering on
|
|
11
|
+
* change and unmount. The handler is kept in a ref so it can change without
|
|
12
|
+
* re-registering.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useMoldableGlobalShortcut(shortcut: string | null, handler?: MoldableGlobalShortcutHandler): {
|
|
15
|
+
registered: boolean;
|
|
16
|
+
error: Error | null;
|
|
17
|
+
lastEvent: MoldableGlobalShortcutEvent | null;
|
|
18
|
+
};
|
|
19
|
+
export interface ShortcutRecorderProps extends Omit<React.ComponentProps<'div'>, 'onChange' | 'defaultValue'> {
|
|
20
|
+
/** Controlled accelerator value; `null` means no shortcut. */
|
|
21
|
+
value?: string | null;
|
|
22
|
+
defaultValue?: string | null;
|
|
23
|
+
onChange?: (shortcut: string | null) => void;
|
|
24
|
+
/** Fires when the registered global shortcut is pressed. */
|
|
25
|
+
onTrigger?: (event: MoldableGlobalShortcutEvent) => void;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Field-level global shortcut recorder: click to arm, press a modifier combo
|
|
30
|
+
* to capture it, and the accelerator registers system-wide. Registered chips
|
|
31
|
+
* pulse when the shortcut fires anywhere in the OS.
|
|
32
|
+
*/
|
|
33
|
+
declare function ShortcutRecorder({ value, defaultValue, onChange, onTrigger, disabled, className, ...props }: ShortcutRecorderProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export { ShortcutRecorder };
|
|
35
|
+
//# sourceMappingURL=shortcut-recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcut-recorder.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/shortcut-recorder.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAInC,MAAM,+BAA+B,CAAA;AAUtC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BhE;AA4CD;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,CAAC,EAAE,6BAA6B;;;;EA8CxC;AAED,MAAM,WAAW,qBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC;IACtE,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IAC5C,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAA;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,YAAmB,EACnB,QAAQ,EACR,SAAS,EACT,QAAgB,EAChB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,qBAAqB,2CA+IvB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { X } from 'lucide-react';
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { isMoldableGlobalShortcut, registerMoldableGlobalShortcut, } from '../../lib/native-capabilities';
|
|
6
|
+
import { cn } from '../../lib/utils';
|
|
7
|
+
import { Button } from '../ui/button';
|
|
8
|
+
import { Kbd, KbdGroup } from '../ui/kbd';
|
|
9
|
+
function isApplePlatform() {
|
|
10
|
+
if (typeof navigator === 'undefined')
|
|
11
|
+
return false;
|
|
12
|
+
return /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Splits an Electron-style accelerator ("CommandOrControl+Shift+K") into
|
|
16
|
+
* display keys for `Kbd` chips — ['⌘', '⇧', 'K'] on macOS, ['Ctrl', 'Shift',
|
|
17
|
+
* 'K'] elsewhere.
|
|
18
|
+
*/
|
|
19
|
+
export function formatShortcutKeys(accelerator) {
|
|
20
|
+
const apple = isApplePlatform();
|
|
21
|
+
return accelerator
|
|
22
|
+
.split('+')
|
|
23
|
+
.filter((part) => part.length > 0)
|
|
24
|
+
.map((part) => {
|
|
25
|
+
switch (part.toLowerCase()) {
|
|
26
|
+
case 'commandorcontrol':
|
|
27
|
+
case 'cmdorctrl':
|
|
28
|
+
return apple ? '⌘' : 'Ctrl';
|
|
29
|
+
case 'command':
|
|
30
|
+
case 'cmd':
|
|
31
|
+
case 'meta':
|
|
32
|
+
case 'super':
|
|
33
|
+
return apple ? '⌘' : 'Win';
|
|
34
|
+
case 'control':
|
|
35
|
+
case 'ctrl':
|
|
36
|
+
return apple ? '⌃' : 'Ctrl';
|
|
37
|
+
case 'alt':
|
|
38
|
+
case 'option':
|
|
39
|
+
return apple ? '⌥' : 'Alt';
|
|
40
|
+
case 'shift':
|
|
41
|
+
return apple ? '⇧' : 'Shift';
|
|
42
|
+
default:
|
|
43
|
+
return part.length === 1 ? part.toUpperCase() : part;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const MODIFIER_KEYS = new Set([
|
|
48
|
+
'Alt',
|
|
49
|
+
'AltGraph',
|
|
50
|
+
'CapsLock',
|
|
51
|
+
'Control',
|
|
52
|
+
'Dead',
|
|
53
|
+
'Fn',
|
|
54
|
+
'FnLock',
|
|
55
|
+
'Hyper',
|
|
56
|
+
'Meta',
|
|
57
|
+
'NumLock',
|
|
58
|
+
'OS',
|
|
59
|
+
'ScrollLock',
|
|
60
|
+
'Shift',
|
|
61
|
+
'Super',
|
|
62
|
+
'Symbol',
|
|
63
|
+
'SymbolLock',
|
|
64
|
+
]);
|
|
65
|
+
function acceleratorKeyFromEvent(event) {
|
|
66
|
+
if (MODIFIER_KEYS.has(event.key))
|
|
67
|
+
return null;
|
|
68
|
+
const code = event.code;
|
|
69
|
+
if (/^Key[A-Z]$/.test(code))
|
|
70
|
+
return code.slice(3);
|
|
71
|
+
if (/^Digit[0-9]$/.test(code))
|
|
72
|
+
return code.slice(5);
|
|
73
|
+
if (event.key === ' ')
|
|
74
|
+
return 'Space';
|
|
75
|
+
if (event.key.startsWith('Arrow'))
|
|
76
|
+
return event.key.slice(5);
|
|
77
|
+
if (/^[A-Za-z0-9]$/.test(event.key))
|
|
78
|
+
return event.key.toUpperCase();
|
|
79
|
+
if (/^[A-Za-z0-9]{2,32}$/.test(event.key))
|
|
80
|
+
return event.key;
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function acceleratorModifiersFromEvent(event) {
|
|
84
|
+
const apple = isApplePlatform();
|
|
85
|
+
const modifiers = [];
|
|
86
|
+
if (apple ? event.metaKey : event.ctrlKey)
|
|
87
|
+
modifiers.push('CommandOrControl');
|
|
88
|
+
if (apple && event.ctrlKey)
|
|
89
|
+
modifiers.push('Control');
|
|
90
|
+
if (!apple && event.metaKey)
|
|
91
|
+
modifiers.push('Super');
|
|
92
|
+
if (event.altKey)
|
|
93
|
+
modifiers.push('Alt');
|
|
94
|
+
if (event.shiftKey)
|
|
95
|
+
modifiers.push('Shift');
|
|
96
|
+
return modifiers;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Registers a global shortcut while `shortcut` is set, unregistering on
|
|
100
|
+
* change and unmount. The handler is kept in a ref so it can change without
|
|
101
|
+
* re-registering.
|
|
102
|
+
*/
|
|
103
|
+
export function useMoldableGlobalShortcut(shortcut, handler) {
|
|
104
|
+
const [registered, setRegistered] = useState(false);
|
|
105
|
+
const [error, setError] = useState(null);
|
|
106
|
+
const [lastEvent, setLastEvent] = useState(null);
|
|
107
|
+
const handlerRef = useRef(handler);
|
|
108
|
+
handlerRef.current = handler;
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
setRegistered(false);
|
|
111
|
+
setError(null);
|
|
112
|
+
setLastEvent(null);
|
|
113
|
+
if (!shortcut)
|
|
114
|
+
return;
|
|
115
|
+
let live = true;
|
|
116
|
+
let registration = null;
|
|
117
|
+
registerMoldableGlobalShortcut(shortcut, (event) => {
|
|
118
|
+
if (!live)
|
|
119
|
+
return;
|
|
120
|
+
setLastEvent(event);
|
|
121
|
+
handlerRef.current?.(event);
|
|
122
|
+
})
|
|
123
|
+
.then((result) => {
|
|
124
|
+
if (!live) {
|
|
125
|
+
void result.unregister().catch(() => {
|
|
126
|
+
// Host teardown remains the final cleanup boundary.
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
registration = result;
|
|
131
|
+
setRegistered(true);
|
|
132
|
+
})
|
|
133
|
+
.catch((cause) => {
|
|
134
|
+
if (!live)
|
|
135
|
+
return;
|
|
136
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
137
|
+
});
|
|
138
|
+
return () => {
|
|
139
|
+
live = false;
|
|
140
|
+
if (registration) {
|
|
141
|
+
void registration.unregister().catch(() => {
|
|
142
|
+
// Host teardown remains the final cleanup boundary.
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}, [shortcut]);
|
|
147
|
+
return { registered, error, lastEvent };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Field-level global shortcut recorder: click to arm, press a modifier combo
|
|
151
|
+
* to capture it, and the accelerator registers system-wide. Registered chips
|
|
152
|
+
* pulse when the shortcut fires anywhere in the OS.
|
|
153
|
+
*/
|
|
154
|
+
function ShortcutRecorder({ value, defaultValue = null, onChange, onTrigger, disabled = false, className, ...props }) {
|
|
155
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
156
|
+
const shortcut = value !== undefined ? value : internalValue;
|
|
157
|
+
const [recording, setRecording] = useState(false);
|
|
158
|
+
const [pulse, setPulse] = useState(false);
|
|
159
|
+
const pulseTimeoutRef = useRef(null);
|
|
160
|
+
const valueRef = useRef(value);
|
|
161
|
+
valueRef.current = value;
|
|
162
|
+
const onChangeRef = useRef(onChange);
|
|
163
|
+
onChangeRef.current = onChange;
|
|
164
|
+
const onTriggerRef = useRef(onTrigger);
|
|
165
|
+
onTriggerRef.current = onTrigger;
|
|
166
|
+
const commit = useCallback((next) => {
|
|
167
|
+
if (valueRef.current === undefined)
|
|
168
|
+
setInternalValue(next);
|
|
169
|
+
onChangeRef.current?.(next);
|
|
170
|
+
}, []);
|
|
171
|
+
const handleShortcutEvent = useCallback((event) => {
|
|
172
|
+
if (event.state !== 'Pressed')
|
|
173
|
+
return;
|
|
174
|
+
setPulse(true);
|
|
175
|
+
if (pulseTimeoutRef.current !== null) {
|
|
176
|
+
window.clearTimeout(pulseTimeoutRef.current);
|
|
177
|
+
}
|
|
178
|
+
pulseTimeoutRef.current = window.setTimeout(() => setPulse(false), 200);
|
|
179
|
+
onTriggerRef.current?.(event);
|
|
180
|
+
}, []);
|
|
181
|
+
const { registered, error } = useMoldableGlobalShortcut(shortcut, handleShortcutEvent);
|
|
182
|
+
useEffect(() => () => {
|
|
183
|
+
if (pulseTimeoutRef.current !== null) {
|
|
184
|
+
window.clearTimeout(pulseTimeoutRef.current);
|
|
185
|
+
}
|
|
186
|
+
}, []);
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
if (!recording)
|
|
189
|
+
return;
|
|
190
|
+
const handleKeyDown = (event) => {
|
|
191
|
+
event.preventDefault();
|
|
192
|
+
event.stopPropagation();
|
|
193
|
+
if (event.key === 'Escape') {
|
|
194
|
+
setRecording(false);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const key = acceleratorKeyFromEvent(event);
|
|
198
|
+
const modifiers = acceleratorModifiersFromEvent(event);
|
|
199
|
+
if (!key || modifiers.length === 0)
|
|
200
|
+
return;
|
|
201
|
+
const accelerator = [...modifiers, key].join('+');
|
|
202
|
+
if (!isMoldableGlobalShortcut(accelerator))
|
|
203
|
+
return;
|
|
204
|
+
setRecording(false);
|
|
205
|
+
commit(accelerator);
|
|
206
|
+
};
|
|
207
|
+
window.addEventListener('keydown', handleKeyDown, true);
|
|
208
|
+
return () => window.removeEventListener('keydown', handleKeyDown, true);
|
|
209
|
+
}, [recording, commit]);
|
|
210
|
+
const keys = shortcut ? formatShortcutKeys(shortcut) : [];
|
|
211
|
+
return (_jsxs("div", { "data-slot": "shortcut-recorder", "data-recording": recording || undefined, "data-registered": registered || undefined, className: cn('w-full min-w-0', className), ...props, children: [_jsxs("div", { className: "relative flex items-center", children: [_jsx("button", { type: "button", disabled: disabled, "aria-label": recording
|
|
212
|
+
? 'Recording shortcut, press keys'
|
|
213
|
+
: shortcut
|
|
214
|
+
? `Shortcut ${shortcut}, click to re-record`
|
|
215
|
+
: 'Record shortcut', onClick: () => setRecording(true), onBlur: () => setRecording(false), className: cn('border-input dark:bg-input/30 shadow-xs flex h-9 w-full min-w-0 items-center gap-2 rounded-md border bg-transparent px-3 text-left text-sm outline-none transition-[color,box-shadow]', 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]', recording && 'border-ring ring-ring/50 ring-[3px]', disabled && 'pointer-events-none cursor-not-allowed opacity-50', shortcut && !recording && 'pr-9'), children: recording ? (_jsxs(_Fragment, { children: [_jsxs("span", { className: "relative flex size-1.5 shrink-0", children: [_jsx("span", { className: "bg-destructive absolute inline-flex h-full w-full animate-ping rounded-full opacity-75 motion-reduce:animate-none" }), _jsx("span", { className: "bg-destructive relative inline-flex size-1.5 rounded-full" })] }), _jsx("span", { className: "text-muted-foreground", children: "Press keys\u2026" })] })) : keys.length > 0 ? (_jsx(KbdGroup, { "data-state": pulse ? 'triggered' : 'idle', className: "origin-left transition-transform duration-150 data-[state=triggered]:scale-110 motion-reduce:transition-none", children: keys.map((key, index) => (_jsx(Kbd, { children: key }, `${index}-${key}`))) })) : (_jsx("span", { className: "text-muted-foreground", children: "Click to record" })) }), shortcut && !recording ? (_jsx(Button, { variant: "ghost", size: "icon-xs", "aria-label": "Clear shortcut", disabled: disabled, className: "absolute right-1.5", onClick: () => commit(null), children: _jsx(X, {}) })) : null] }), error ? (_jsx("p", { "data-slot": "shortcut-recorder-error", className: "text-status-error mt-1.5 text-xs", children: error.message })) : null] }));
|
|
216
|
+
}
|
|
217
|
+
export { ShortcutRecorder };
|