@moldable-ai/ui 0.2.18 → 0.2.20
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-manifest.d.ts +6 -0
- package/dist/catalog/catalog-manifest.d.ts.map +1 -0
- package/dist/catalog/catalog-manifest.js +105 -0
- package/dist/catalog/catalog-types.d.ts +54 -0
- package/dist/catalog/catalog-types.d.ts.map +1 -0
- package/dist/catalog/catalog-types.js +14 -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 +39 -0
- package/dist/catalog/core-catalog.d.ts +6 -0
- package/dist/catalog/core-catalog.d.ts.map +1 -0
- package/dist/catalog/core-catalog.js +105 -0
- package/dist/catalog/index.d.ts +5 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +4 -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 +67 -17
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +250 -159
- 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 +3 -2
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +3 -2
- package/dist/components/chat/model-effort-power-effects.d.ts +7 -0
- package/dist/components/chat/model-effort-power-effects.d.ts.map +1 -0
- package/dist/components/chat/model-effort-power-effects.js +54 -0
- package/dist/components/chat/model-effort-selector.d.ts +26 -0
- package/dist/components/chat/model-effort-selector.d.ts.map +1 -0
- package/dist/components/chat/model-effort-selector.js +179 -0
- package/dist/components/chat/model-effort-ultra-effects.d.ts +5 -0
- package/dist/components/chat/model-effort-ultra-effects.d.ts.map +1 -0
- package/dist/components/chat/model-effort-ultra-effects.js +56 -0
- 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/hardware/bluetooth-panel-helpers.d.ts +9 -0
- package/dist/components/hardware/bluetooth-panel-helpers.d.ts.map +1 -0
- package/dist/components/hardware/bluetooth-panel-helpers.js +37 -0
- package/dist/components/hardware/bluetooth-panel.d.ts +56 -0
- package/dist/components/hardware/bluetooth-panel.d.ts.map +1 -0
- package/dist/components/hardware/bluetooth-panel.js +470 -0
- package/dist/components/hardware/camera-preview.d.ts +39 -0
- package/dist/components/hardware/camera-preview.d.ts.map +1 -0
- package/dist/components/hardware/camera-preview.js +228 -0
- package/dist/components/hardware/capability-badge.d.ts +23 -0
- package/dist/components/hardware/capability-badge.d.ts.map +1 -0
- package/dist/components/hardware/capability-badge.js +39 -0
- package/dist/components/hardware/capability-matrix.d.ts +14 -0
- package/dist/components/hardware/capability-matrix.d.ts.map +1 -0
- package/dist/components/hardware/capability-matrix.js +97 -0
- package/dist/components/hardware/clipboard-button.d.ts +26 -0
- package/dist/components/hardware/clipboard-button.d.ts.map +1 -0
- package/dist/components/hardware/clipboard-button.js +114 -0
- package/dist/components/hardware/device-io-controls.d.ts +4 -0
- package/dist/components/hardware/device-io-controls.d.ts.map +1 -0
- package/dist/components/hardware/device-io-controls.js +28 -0
- package/dist/components/hardware/device-list.d.ts +20 -0
- package/dist/components/hardware/device-list.d.ts.map +1 -0
- package/dist/components/hardware/device-list.js +14 -0
- package/dist/components/hardware/display-map.d.ts +23 -0
- package/dist/components/hardware/display-map.d.ts.map +1 -0
- package/dist/components/hardware/display-map.js +114 -0
- package/dist/components/hardware/haptic-button.d.ts +26 -0
- package/dist/components/hardware/haptic-button.d.ts.map +1 -0
- package/dist/components/hardware/haptic-button.js +94 -0
- package/dist/components/hardware/hardware-panel.d.ts +11 -0
- package/dist/components/hardware/hardware-panel.d.ts.map +1 -0
- package/dist/components/hardware/hardware-panel.js +28 -0
- package/dist/components/hardware/hid-panel.d.ts +40 -0
- package/dist/components/hardware/hid-panel.d.ts.map +1 -0
- package/dist/components/hardware/hid-panel.js +373 -0
- package/dist/components/hardware/index.d.ts +27 -0
- package/dist/components/hardware/index.d.ts.map +1 -0
- package/dist/components/hardware/index.js +26 -0
- package/dist/components/hardware/live-indicator.d.ts +15 -0
- package/dist/components/hardware/live-indicator.d.ts.map +1 -0
- package/dist/components/hardware/live-indicator.js +26 -0
- package/dist/components/hardware/local-auth-button.d.ts +33 -0
- package/dist/components/hardware/local-auth-button.d.ts.map +1 -0
- package/dist/components/hardware/local-auth-button.js +115 -0
- package/dist/components/hardware/location-panel.d.ts +29 -0
- package/dist/components/hardware/location-panel.d.ts.map +1 -0
- package/dist/components/hardware/location-panel.js +154 -0
- package/dist/components/hardware/microphone-meter.d.ts +35 -0
- package/dist/components/hardware/microphone-meter.d.ts.map +1 -0
- package/dist/components/hardware/microphone-meter.js +244 -0
- package/dist/components/hardware/midi-monitor.d.ts +54 -0
- package/dist/components/hardware/midi-monitor.d.ts.map +1 -0
- package/dist/components/hardware/midi-monitor.js +534 -0
- package/dist/components/hardware/notification-panel.d.ts +24 -0
- package/dist/components/hardware/notification-panel.d.ts.map +1 -0
- package/dist/components/hardware/notification-panel.js +124 -0
- package/dist/components/hardware/power-blocker-controller.d.ts +19 -0
- package/dist/components/hardware/power-blocker-controller.d.ts.map +1 -0
- package/dist/components/hardware/power-blocker-controller.js +83 -0
- package/dist/components/hardware/power-panel.d.ts +67 -0
- package/dist/components/hardware/power-panel.d.ts.map +1 -0
- package/dist/components/hardware/power-panel.js +309 -0
- package/dist/components/hardware/readout.d.ts +10 -0
- package/dist/components/hardware/readout.d.ts.map +1 -0
- package/dist/components/hardware/readout.js +11 -0
- package/dist/components/hardware/screen-share-preview.d.ts +36 -0
- package/dist/components/hardware/screen-share-preview.d.ts.map +1 -0
- package/dist/components/hardware/screen-share-preview.js +191 -0
- package/dist/components/hardware/secure-storage-panel.d.ts +36 -0
- package/dist/components/hardware/secure-storage-panel.d.ts.map +1 -0
- package/dist/components/hardware/secure-storage-panel.js +193 -0
- package/dist/components/hardware/serial-console.d.ts +64 -0
- package/dist/components/hardware/serial-console.d.ts.map +1 -0
- package/dist/components/hardware/serial-console.js +399 -0
- package/dist/components/hardware/shortcut-recorder.d.ts +35 -0
- package/dist/components/hardware/shortcut-recorder.d.ts.map +1 -0
- package/dist/components/hardware/shortcut-recorder.js +217 -0
- package/dist/components/hardware/stream-log.d.ts +35 -0
- package/dist/components/hardware/stream-log.d.ts.map +1 -0
- package/dist/components/hardware/stream-log.js +65 -0
- package/dist/components/hardware/system-audio-monitor.d.ts +34 -0
- package/dist/components/hardware/system-audio-monitor.d.ts.map +1 -0
- package/dist/components/hardware/system-audio-monitor.js +275 -0
- package/dist/components/hardware/usb-panel.d.ts +54 -0
- package/dist/components/hardware/usb-panel.d.ts.map +1 -0
- package/dist/components/hardware/usb-panel.js +363 -0
- package/dist/components/hardware/use-capability.d.ts +20 -0
- package/dist/components/hardware/use-capability.d.ts.map +1 -0
- package/dist/components/hardware/use-capability.js +61 -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/app-frame.d.ts +22 -0
- package/dist/components/ui/app-frame.d.ts.map +1 -0
- package/dist/components/ui/app-frame.js +56 -0
- package/dist/components/ui/button-group.d.ts +1 -1
- package/dist/components/ui/button.js +1 -1
- 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/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/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.js +1 -1
- 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 +234 -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 +19 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +19 -0
- 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 +24 -0
- package/dist/components/ui/list.d.ts.map +1 -0
- package/dist/components/ui/list.js +224 -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.d.ts +11 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller.js +37 -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.js +1 -1
- 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 +61 -0
- package/dist/components/ui/sidebar.js +1 -1
- package/dist/components/ui/slider.d.ts +4 -1
- package/dist/components/ui/slider.d.ts.map +1 -1
- package/dist/components/ui/slider.js +2 -2
- 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 +28 -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.js +1 -1
- package/dist/components/ui/toolbar.d.ts +20 -0
- package/dist/components/ui/toolbar.d.ts.map +1 -0
- package/dist/components/ui/toolbar.js +52 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/lib/frame-lifecycle.d.ts +28 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +84 -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/native-hardware/bluetooth-access.d.ts +14 -0
- package/dist/lib/native-hardware/bluetooth-access.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-access.js +40 -0
- package/dist/lib/native-hardware/bluetooth-connection.d.ts +19 -0
- package/dist/lib/native-hardware/bluetooth-connection.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-connection.js +88 -0
- package/dist/lib/native-hardware/bluetooth-gatt.d.ts +7 -0
- package/dist/lib/native-hardware/bluetooth-gatt.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-gatt.js +77 -0
- package/dist/lib/native-hardware/bluetooth-internal.d.ts +10 -0
- package/dist/lib/native-hardware/bluetooth-internal.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-internal.js +105 -0
- package/dist/lib/native-hardware/bluetooth-native-fallback.d.ts +33 -0
- package/dist/lib/native-hardware/bluetooth-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-native-fallback.js +214 -0
- package/dist/lib/native-hardware/bluetooth-types.d.ts +85 -0
- package/dist/lib/native-hardware/bluetooth-types.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-types.js +2 -0
- package/dist/lib/native-hardware/bluetooth.d.ts +7 -0
- package/dist/lib/native-hardware/bluetooth.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth.js +4 -0
- package/dist/lib/native-hardware/bridge.d.ts +23 -0
- package/dist/lib/native-hardware/bridge.d.ts.map +1 -0
- package/dist/lib/native-hardware/bridge.js +266 -0
- package/dist/lib/native-hardware/capabilities.d.ts +7 -0
- package/dist/lib/native-hardware/capabilities.d.ts.map +1 -0
- package/dist/lib/native-hardware/capabilities.js +95 -0
- package/dist/lib/native-hardware/clipboard.d.ts +11 -0
- package/dist/lib/native-hardware/clipboard.d.ts.map +1 -0
- package/dist/lib/native-hardware/clipboard.js +55 -0
- package/dist/lib/native-hardware/device-io-errors.d.ts +11 -0
- package/dist/lib/native-hardware/device-io-errors.d.ts.map +1 -0
- package/dist/lib/native-hardware/device-io-errors.js +82 -0
- package/dist/lib/native-hardware/displays.d.ts +38 -0
- package/dist/lib/native-hardware/displays.d.ts.map +1 -0
- package/dist/lib/native-hardware/displays.js +12 -0
- package/dist/lib/native-hardware/global-shortcuts.d.ts +86 -0
- package/dist/lib/native-hardware/global-shortcuts.d.ts.map +1 -0
- package/dist/lib/native-hardware/global-shortcuts.js +351 -0
- package/dist/lib/native-hardware/haptics.d.ts +25 -0
- package/dist/lib/native-hardware/haptics.d.ts.map +1 -0
- package/dist/lib/native-hardware/haptics.js +18 -0
- package/dist/lib/native-hardware/hid-native.d.ts +26 -0
- package/dist/lib/native-hardware/hid-native.d.ts.map +1 -0
- package/dist/lib/native-hardware/hid-native.js +229 -0
- package/dist/lib/native-hardware/hid.d.ts +52 -0
- package/dist/lib/native-hardware/hid.d.ts.map +1 -0
- package/dist/lib/native-hardware/hid.js +160 -0
- package/dist/lib/native-hardware/index.d.ts +38 -0
- package/dist/lib/native-hardware/index.d.ts.map +1 -0
- package/dist/lib/native-hardware/index.js +20 -0
- package/dist/lib/native-hardware/local-authentication.d.ts +32 -0
- package/dist/lib/native-hardware/local-authentication.d.ts.map +1 -0
- package/dist/lib/native-hardware/local-authentication.js +46 -0
- package/dist/lib/native-hardware/location.d.ts +49 -0
- package/dist/lib/native-hardware/location.d.ts.map +1 -0
- package/dist/lib/native-hardware/location.js +114 -0
- package/dist/lib/native-hardware/media-permissions.d.ts +28 -0
- package/dist/lib/native-hardware/media-permissions.d.ts.map +1 -0
- package/dist/lib/native-hardware/media-permissions.js +37 -0
- package/dist/lib/native-hardware/media.d.ts +17 -0
- package/dist/lib/native-hardware/media.d.ts.map +1 -0
- package/dist/lib/native-hardware/media.js +99 -0
- package/dist/lib/native-hardware/midi-access.d.ts +13 -0
- package/dist/lib/native-hardware/midi-access.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-access.js +66 -0
- package/dist/lib/native-hardware/midi-internal.d.ts +12 -0
- package/dist/lib/native-hardware/midi-internal.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-internal.js +88 -0
- package/dist/lib/native-hardware/midi-native-fallback.d.ts +27 -0
- package/dist/lib/native-hardware/midi-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-native-fallback.js +127 -0
- package/dist/lib/native-hardware/midi-ports.d.ts +6 -0
- package/dist/lib/native-hardware/midi-ports.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-ports.js +115 -0
- package/dist/lib/native-hardware/midi-types.d.ts +25 -0
- package/dist/lib/native-hardware/midi-types.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-types.js +1 -0
- package/dist/lib/native-hardware/midi.d.ts +6 -0
- package/dist/lib/native-hardware/midi.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi.js +3 -0
- package/dist/lib/native-hardware/native-device-io.d.ts +28 -0
- package/dist/lib/native-hardware/native-device-io.d.ts.map +1 -0
- package/dist/lib/native-hardware/native-device-io.js +91 -0
- package/dist/lib/native-hardware/native-device-lifecycle.d.ts +13 -0
- package/dist/lib/native-hardware/native-device-lifecycle.d.ts.map +1 -0
- package/dist/lib/native-hardware/native-device-lifecycle.js +40 -0
- package/dist/lib/native-hardware/notifications.d.ts +38 -0
- package/dist/lib/native-hardware/notifications.d.ts.map +1 -0
- package/dist/lib/native-hardware/notifications.js +50 -0
- package/dist/lib/native-hardware/power-session.d.ts +113 -0
- package/dist/lib/native-hardware/power-session.d.ts.map +1 -0
- package/dist/lib/native-hardware/power-session.js +264 -0
- package/dist/lib/native-hardware/secure-storage.d.ts +36 -0
- package/dist/lib/native-hardware/secure-storage.d.ts.map +1 -0
- package/dist/lib/native-hardware/secure-storage.js +64 -0
- package/dist/lib/native-hardware/serial-native.d.ts +23 -0
- package/dist/lib/native-hardware/serial-native.d.ts.map +1 -0
- package/dist/lib/native-hardware/serial-native.js +181 -0
- package/dist/lib/native-hardware/serial.d.ts +76 -0
- package/dist/lib/native-hardware/serial.d.ts.map +1 -0
- package/dist/lib/native-hardware/serial.js +212 -0
- package/dist/lib/native-hardware/system-audio.d.ts +127 -0
- package/dist/lib/native-hardware/system-audio.d.ts.map +1 -0
- package/dist/lib/native-hardware/system-audio.js +330 -0
- package/dist/lib/native-hardware/types.d.ts +62 -0
- package/dist/lib/native-hardware/types.d.ts.map +1 -0
- package/dist/lib/native-hardware/types.js +27 -0
- package/dist/lib/native-hardware/usb-native.d.ts +39 -0
- package/dist/lib/native-hardware/usb-native.d.ts.map +1 -0
- package/dist/lib/native-hardware/usb-native.js +217 -0
- package/dist/lib/native-hardware/usb.d.ts +85 -0
- package/dist/lib/native-hardware/usb.d.ts.map +1 -0
- package/dist/lib/native-hardware/usb.js +222 -0
- package/docs/README.md +37 -0
- package/docs/accessibility.md +32 -0
- package/docs/app-anatomy.md +72 -0
- package/docs/component-catalog.md +59 -0
- package/docs/component-guide-template.md +37 -0
- package/docs/design-tokens.md +172 -0
- package/docs/foundations.md +56 -0
- package/docs/native-integration.md +33 -0
- package/docs/standalone-app-windows.md +128 -0
- package/package.json +9 -3
- package/src/components/ui/alert.md +55 -0
- package/src/components/ui/app-frame.md +33 -0
- package/src/components/ui/badge.md +57 -0
- package/src/components/ui/button.md +76 -0
- package/src/components/ui/color-well.md +11 -0
- package/src/components/ui/combobox.md +43 -0
- package/src/components/ui/date-field.md +32 -0
- package/src/components/ui/edge-fade.md +7 -0
- package/src/components/ui/empty.md +82 -0
- package/src/components/ui/field.md +77 -0
- package/src/components/ui/grid.md +105 -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 +107 -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/resizable.md +66 -0
- package/src/components/ui/scroll-area.md +68 -0
- package/src/components/ui/search-field.md +33 -0
- package/src/components/ui/segmented-control.md +39 -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 +35 -0
- package/src/components/ui/tabs.md +66 -0
- package/src/components/ui/text.md +17 -0
- package/src/components/ui/toggle-group.md +80 -0
- package/src/components/ui/toggle.md +73 -0
- package/src/components/ui/toolbar.md +21 -0
- package/src/styles/index.css +868 -3
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Camera, CameraOff, RefreshCw, Square } from 'lucide-react';
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { NativeCapabilityBridgeError, enumerateMoldableMediaDevices, getMoldableCameraStream, getMoldableMediaPermissionStatus, requestMoldableMediaPermission, stopMoldableMediaStream, } from '../../lib/native-capabilities';
|
|
6
|
+
import { cn } from '../../lib/utils';
|
|
7
|
+
import { Button } from '../ui/button';
|
|
8
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../ui/select';
|
|
9
|
+
import { Spinner } from '../ui/spinner';
|
|
10
|
+
import { LiveIndicator } from './live-indicator';
|
|
11
|
+
function isPermissionDenied(error) {
|
|
12
|
+
if (error instanceof NativeCapabilityBridgeError) {
|
|
13
|
+
return error.code === 'permission_denied';
|
|
14
|
+
}
|
|
15
|
+
return (error instanceof DOMException &&
|
|
16
|
+
(error.name === 'NotAllowedError' || error.name === 'SecurityError'));
|
|
17
|
+
}
|
|
18
|
+
function assertMediaPermissionGranted(status) {
|
|
19
|
+
if (status.status !== 'denied' && status.status !== 'restricted')
|
|
20
|
+
return;
|
|
21
|
+
throw new NativeCapabilityBridgeError({
|
|
22
|
+
code: 'permission_denied',
|
|
23
|
+
message: status.detail ?? 'Camera access was denied.',
|
|
24
|
+
retryable: false,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Camera state machine behind `CameraPreview`. Use directly to build custom
|
|
29
|
+
* camera UI on the same permission/device/stream handling.
|
|
30
|
+
*/
|
|
31
|
+
export function useMoldableCamera(options = {}) {
|
|
32
|
+
const [status, setStatus] = useState('idle');
|
|
33
|
+
const [stream, setStream] = useState(null);
|
|
34
|
+
const [devices, setDevices] = useState([]);
|
|
35
|
+
const [deviceId, setDeviceIdState] = useState(null);
|
|
36
|
+
const [error, setError] = useState(null);
|
|
37
|
+
const streamRef = useRef(null);
|
|
38
|
+
const deviceIdRef = useRef(null);
|
|
39
|
+
const tokenRef = useRef(0);
|
|
40
|
+
const constraintsRef = useRef(options.constraints);
|
|
41
|
+
const onStreamChangeRef = useRef(options.onStreamChange);
|
|
42
|
+
const detachTrackListenersRef = useRef(null);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
constraintsRef.current = options.constraints;
|
|
45
|
+
onStreamChangeRef.current = options.onStreamChange;
|
|
46
|
+
}, [options.constraints, options.onStreamChange]);
|
|
47
|
+
const dropStream = useCallback((updateState = true) => {
|
|
48
|
+
detachTrackListenersRef.current?.();
|
|
49
|
+
detachTrackListenersRef.current = null;
|
|
50
|
+
const previousStream = streamRef.current;
|
|
51
|
+
if (!previousStream)
|
|
52
|
+
return false;
|
|
53
|
+
streamRef.current = null;
|
|
54
|
+
stopMoldableMediaStream(previousStream);
|
|
55
|
+
if (updateState)
|
|
56
|
+
setStream(null);
|
|
57
|
+
onStreamChangeRef.current?.(null);
|
|
58
|
+
return true;
|
|
59
|
+
}, []);
|
|
60
|
+
const stop = useCallback(() => {
|
|
61
|
+
tokenRef.current++;
|
|
62
|
+
dropStream();
|
|
63
|
+
setStatus('idle');
|
|
64
|
+
}, [dropStream]);
|
|
65
|
+
const refreshDevices = useCallback(async () => {
|
|
66
|
+
try {
|
|
67
|
+
const all = await enumerateMoldableMediaDevices();
|
|
68
|
+
setDevices(all.filter((device) => device.kind === 'videoinput'));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Device labels are best-effort; enumeration can fail outside Moldable.
|
|
72
|
+
}
|
|
73
|
+
}, []);
|
|
74
|
+
const start = useCallback(async (nextDeviceId) => {
|
|
75
|
+
const token = ++tokenRef.current;
|
|
76
|
+
dropStream();
|
|
77
|
+
setStatus('starting');
|
|
78
|
+
setError(null);
|
|
79
|
+
try {
|
|
80
|
+
// Nudge the native permission first so macOS prompts before the
|
|
81
|
+
// webview does. Outside Moldable this fails and the browser prompt
|
|
82
|
+
// covers it on getUserMedia.
|
|
83
|
+
try {
|
|
84
|
+
const permission = await getMoldableMediaPermissionStatus('camera');
|
|
85
|
+
assertMediaPermissionGranted(permission);
|
|
86
|
+
if (permission.status === 'not-determined' && permission.canRequest) {
|
|
87
|
+
assertMediaPermissionGranted(await requestMoldableMediaPermission('camera'));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (cause) {
|
|
91
|
+
if (isPermissionDenied(cause))
|
|
92
|
+
throw cause;
|
|
93
|
+
// Not in Moldable — proceed straight to the stream request.
|
|
94
|
+
}
|
|
95
|
+
if (tokenRef.current !== token)
|
|
96
|
+
return;
|
|
97
|
+
const target = nextDeviceId ?? deviceIdRef.current;
|
|
98
|
+
const media = await getMoldableCameraStream({
|
|
99
|
+
width: { ideal: 1920 },
|
|
100
|
+
height: { ideal: 1080 },
|
|
101
|
+
...constraintsRef.current,
|
|
102
|
+
...(target ? { deviceId: { exact: target } } : {}),
|
|
103
|
+
});
|
|
104
|
+
if (tokenRef.current !== token) {
|
|
105
|
+
stopMoldableMediaStream(media);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
streamRef.current = media;
|
|
109
|
+
const [track] = media.getVideoTracks();
|
|
110
|
+
if (track) {
|
|
111
|
+
const handleEnded = () => {
|
|
112
|
+
if (tokenRef.current !== token)
|
|
113
|
+
return;
|
|
114
|
+
tokenRef.current++;
|
|
115
|
+
dropStream();
|
|
116
|
+
setStatus('idle');
|
|
117
|
+
};
|
|
118
|
+
const handleMute = () => {
|
|
119
|
+
if (tokenRef.current === token)
|
|
120
|
+
setStatus('muted');
|
|
121
|
+
};
|
|
122
|
+
const handleUnmute = () => {
|
|
123
|
+
if (tokenRef.current === token)
|
|
124
|
+
setStatus('live');
|
|
125
|
+
};
|
|
126
|
+
track.addEventListener('ended', handleEnded, { once: true });
|
|
127
|
+
track.addEventListener('mute', handleMute);
|
|
128
|
+
track.addEventListener('unmute', handleUnmute);
|
|
129
|
+
detachTrackListenersRef.current = () => {
|
|
130
|
+
track.removeEventListener('ended', handleEnded);
|
|
131
|
+
track.removeEventListener('mute', handleMute);
|
|
132
|
+
track.removeEventListener('unmute', handleUnmute);
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
setStream(media);
|
|
136
|
+
if (nextDeviceId !== undefined) {
|
|
137
|
+
deviceIdRef.current = nextDeviceId;
|
|
138
|
+
setDeviceIdState(nextDeviceId);
|
|
139
|
+
}
|
|
140
|
+
setStatus('live');
|
|
141
|
+
onStreamChangeRef.current?.(media);
|
|
142
|
+
void refreshDevices();
|
|
143
|
+
}
|
|
144
|
+
catch (cause) {
|
|
145
|
+
if (tokenRef.current !== token)
|
|
146
|
+
return;
|
|
147
|
+
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
148
|
+
setStatus(isPermissionDenied(cause) ? 'denied' : 'error');
|
|
149
|
+
}
|
|
150
|
+
}, [dropStream, refreshDevices]);
|
|
151
|
+
const selectDevice = useCallback((id) => {
|
|
152
|
+
deviceIdRef.current = id;
|
|
153
|
+
setDeviceIdState(id);
|
|
154
|
+
if (streamRef.current)
|
|
155
|
+
void start(id);
|
|
156
|
+
}, [start]);
|
|
157
|
+
useEffect(() => () => {
|
|
158
|
+
tokenRef.current++;
|
|
159
|
+
dropStream(false);
|
|
160
|
+
}, [dropStream]);
|
|
161
|
+
return {
|
|
162
|
+
status,
|
|
163
|
+
stream,
|
|
164
|
+
devices,
|
|
165
|
+
deviceId,
|
|
166
|
+
error,
|
|
167
|
+
start,
|
|
168
|
+
stop,
|
|
169
|
+
selectDevice,
|
|
170
|
+
refreshDevices,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Full-bleed live camera surface: black media well, hover scrim controls,
|
|
175
|
+
* device switching, permission and error states, optional snapshots.
|
|
176
|
+
*/
|
|
177
|
+
function CameraPreview({ className, constraints, mirrored = true, autoStart = false, onSnapshot, onStreamChange, ...props }) {
|
|
178
|
+
const camera = useMoldableCamera({ constraints, onStreamChange });
|
|
179
|
+
const videoRef = useRef(null);
|
|
180
|
+
const [flash, setFlash] = useState(false);
|
|
181
|
+
const autoStartedRef = useRef(false);
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
if (autoStart && !autoStartedRef.current) {
|
|
184
|
+
autoStartedRef.current = true;
|
|
185
|
+
void camera.start();
|
|
186
|
+
}
|
|
187
|
+
}, [autoStart, camera]);
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
const video = videoRef.current;
|
|
190
|
+
if (!video)
|
|
191
|
+
return;
|
|
192
|
+
video.srcObject = camera.stream;
|
|
193
|
+
if (camera.stream) {
|
|
194
|
+
void video.play().catch(() => {
|
|
195
|
+
// Autoplay rejections resolve once the stream attaches.
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}, [camera.stream]);
|
|
199
|
+
const capture = () => {
|
|
200
|
+
const video = videoRef.current;
|
|
201
|
+
if (!video || !onSnapshot || video.videoWidth === 0)
|
|
202
|
+
return;
|
|
203
|
+
const canvas = document.createElement('canvas');
|
|
204
|
+
canvas.width = video.videoWidth;
|
|
205
|
+
canvas.height = video.videoHeight;
|
|
206
|
+
const context = canvas.getContext('2d');
|
|
207
|
+
if (!context)
|
|
208
|
+
return;
|
|
209
|
+
if (mirrored) {
|
|
210
|
+
context.translate(canvas.width, 0);
|
|
211
|
+
context.scale(-1, 1);
|
|
212
|
+
}
|
|
213
|
+
context.drawImage(video, 0, 0);
|
|
214
|
+
setFlash(true);
|
|
215
|
+
window.setTimeout(() => setFlash(false), 160);
|
|
216
|
+
canvas.toBlob((blob) => {
|
|
217
|
+
if (blob)
|
|
218
|
+
onSnapshot(blob);
|
|
219
|
+
}, 'image/png');
|
|
220
|
+
};
|
|
221
|
+
const active = camera.status === 'live' || camera.status === 'muted';
|
|
222
|
+
const settings = active
|
|
223
|
+
? camera.stream?.getVideoTracks()[0]?.getSettings()
|
|
224
|
+
: undefined;
|
|
225
|
+
return (_jsxs("div", { "data-slot": "camera-preview", "data-status": camera.status, className: cn('group relative isolate aspect-video w-full overflow-hidden rounded-xl border', active ? 'bg-black' : 'bg-muted/30', className), ...props, children: [_jsx("video", { ref: videoRef, muted: true, playsInline: true, className: cn('absolute inset-0 size-full object-cover', mirrored && '-scale-x-100', !active && 'invisible') }), _jsx("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-0 z-30 bg-white transition-opacity duration-150", style: { opacity: flash ? 0.9 : 0 } }), active ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute left-3 top-3 z-20", children: _jsx(LiveIndicator, { variant: "rec", label: camera.status === 'muted' ? 'Paused' : 'Live' }) }), settings?.width && settings.height ? (_jsxs("div", { className: "absolute right-3 top-3 z-20 rounded-full border border-white/15 bg-black/60 px-2 py-0.5 font-mono text-[10px] tabular-nums text-white/90 backdrop-blur-sm", children: [settings.width, "\u00D7", settings.height] })) : null, _jsxs("div", { className: "absolute inset-x-0 bottom-0 z-20 flex items-end justify-between gap-3 bg-gradient-to-t from-black/70 via-black/25 to-transparent p-3 pt-10 opacity-0 transition-opacity duration-200 focus-within:opacity-100 group-hover:opacity-100", children: [_jsx("div", { className: "min-w-0", children: camera.devices.length > 1 ? (_jsxs(Select, { value: camera.deviceId ?? undefined, onValueChange: camera.selectDevice, children: [_jsx(SelectTrigger, { size: "sm", className: "h-7 w-auto max-w-56 border-white/15 bg-white/10 text-xs text-white backdrop-blur-md hover:bg-white/15 [&_svg]:text-white/70", children: _jsx(SelectValue, { placeholder: "Camera" }) }), _jsx(SelectContent, { children: camera.devices.map((device, index) => (_jsx(SelectItem, { value: device.deviceId, children: device.label || `Camera ${index + 1}` }, device.deviceId))) })] })) : null }), _jsxs("div", { className: "flex items-center gap-2", children: [onSnapshot ? (_jsx("button", { type: "button", onClick: capture, "aria-label": "Take snapshot", className: "size-9 rounded-full border-2 border-white/40 bg-white shadow-md transition-transform duration-150 hover:scale-105 active:scale-95 motion-reduce:transition-none" })) : null, _jsx(Button, { variant: "secondary", size: "icon-sm", "aria-label": "Stop camera", onClick: camera.stop, className: "border border-white/15 bg-white/10 text-white backdrop-blur-md hover:bg-white/20", children: _jsx(Square, { className: "fill-current" }) })] })] })] })) : (_jsx("div", { className: "animate-in fade-in absolute inset-0 z-10 flex flex-col items-center justify-center gap-3 p-6 text-center duration-300 motion-reduce:animate-none", children: camera.status === 'starting' ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { className: "text-muted-foreground" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Starting camera\u2026" })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground bg-background shadow-xs flex size-10 items-center justify-center rounded-lg border [&_svg]:size-5", children: camera.status === 'idle' ? _jsx(Camera, {}) : _jsx(CameraOff, {}) }), camera.status === 'idle' ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-muted-foreground text-sm", children: "Camera is off" }), _jsxs(Button, { size: "sm", onClick: () => void camera.start(), children: [_jsx(Camera, {}), " Start camera"] })] })) : camera.status === 'denied' ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-sm font-medium", children: "Camera access denied" }), _jsx("p", { className: "text-muted-foreground max-w-64 text-xs", children: "Enable camera access for Moldable in System Settings, then try again." }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void camera.start(), children: [_jsx(RefreshCw, {}), " Try again"] })] })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-sm font-medium", children: "Camera unavailable" }), _jsx("p", { className: "text-muted-foreground max-w-64 text-xs", children: camera.error?.message ??
|
|
226
|
+
'The camera could not be started.' }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => void camera.start(), children: [_jsx(RefreshCw, {}), " Try again"] })] }))] })) }))] }));
|
|
227
|
+
}
|
|
228
|
+
export { CameraPreview };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NativeCapabilityId } from '../../lib/native-capabilities';
|
|
3
|
+
import { type MoldableCapabilityStatus } from './use-capability';
|
|
4
|
+
declare function CapabilityDot({ status, className, ...props }: React.ComponentProps<'span'> & {
|
|
5
|
+
status: MoldableCapabilityStatus;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
interface CapabilityBadgeBaseProps extends React.ComponentProps<'span'> {
|
|
8
|
+
/** Override the automatic status label. */
|
|
9
|
+
label?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export interface CapabilityBadgeProps extends CapabilityBadgeBaseProps {
|
|
12
|
+
/** Self-manage: fetch the manifest and show this capability's support. */
|
|
13
|
+
capability?: NativeCapabilityId;
|
|
14
|
+
/** Controlled: render a specific status directly. */
|
|
15
|
+
status?: MoldableCapabilityStatus;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Support-status pill. Pass `capability` to let it fetch the manifest itself,
|
|
19
|
+
* or `status` to control it.
|
|
20
|
+
*/
|
|
21
|
+
declare function CapabilityBadge({ capability, status, ...props }: CapabilityBadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export { CapabilityBadge, CapabilityDot };
|
|
23
|
+
//# sourceMappingURL=capability-badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-badge.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/capability-badge.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAEvE,OAAO,EACL,KAAK,wBAAwB,EAE9B,MAAM,kBAAkB,CAAA;AAkBzB,iBAAS,aAAa,CAAC,EACrB,MAAM,EACN,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG;IAAE,MAAM,EAAE,wBAAwB,CAAA;CAAE,2CAcrE;AAED,UAAU,wBAAyB,SAAQ,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;IACrE,2CAA2C;IAC3C,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB;AAgCD,MAAM,WAAW,oBAAqB,SAAQ,wBAAwB;IACpE,0EAA0E;IAC1E,UAAU,CAAC,EAAE,kBAAkB,CAAA;IAC/B,qDAAqD;IACrD,MAAM,CAAC,EAAE,wBAAwB,CAAA;CAClC;AAED;;;GAGG;AACH,iBAAS,eAAe,CAAC,EACvB,UAAU,EACV,MAAM,EACN,GAAG,KAAK,EACT,EAAE,oBAAoB,2CAKtB;AAED,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
import { useMoldableCapability, } from './use-capability';
|
|
5
|
+
const STATUS_LABEL = {
|
|
6
|
+
checking: 'Checking',
|
|
7
|
+
supported: 'Supported',
|
|
8
|
+
partial: 'Partial',
|
|
9
|
+
unsupported: 'Unsupported',
|
|
10
|
+
unavailable: 'Unavailable',
|
|
11
|
+
};
|
|
12
|
+
const STATUS_DOT = {
|
|
13
|
+
checking: 'bg-muted-foreground/40 animate-pulse motion-reduce:animate-none',
|
|
14
|
+
supported: 'bg-status-running',
|
|
15
|
+
partial: 'bg-status-pending',
|
|
16
|
+
unsupported: 'bg-status-error',
|
|
17
|
+
unavailable: 'bg-status-stopped',
|
|
18
|
+
};
|
|
19
|
+
function CapabilityDot({ status, className, ...props }) {
|
|
20
|
+
return (_jsx("span", { "data-slot": "capability-dot", "data-status": status, "aria-hidden": true, className: cn('size-1.5 shrink-0 rounded-full', STATUS_DOT[status], className), ...props }));
|
|
21
|
+
}
|
|
22
|
+
function CapabilityBadgeBase({ status, label, className, ...props }) {
|
|
23
|
+
return (_jsxs("span", { "data-slot": "capability-badge", "data-status": status, className: cn('text-muted-foreground inline-flex w-fit shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-2 py-0.5 text-[11px] font-medium', className), ...props, children: [_jsx(CapabilityDot, { status: status }), label ?? STATUS_LABEL[status]] }));
|
|
24
|
+
}
|
|
25
|
+
function ManagedCapabilityBadge({ capability, ...props }) {
|
|
26
|
+
const { status } = useMoldableCapability(capability);
|
|
27
|
+
return _jsx(CapabilityBadgeBase, { status: status, ...props });
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Support-status pill. Pass `capability` to let it fetch the manifest itself,
|
|
31
|
+
* or `status` to control it.
|
|
32
|
+
*/
|
|
33
|
+
function CapabilityBadge({ capability, status, ...props }) {
|
|
34
|
+
if (capability && status === undefined) {
|
|
35
|
+
return _jsx(ManagedCapabilityBadge, { capability: capability, ...props });
|
|
36
|
+
}
|
|
37
|
+
return _jsx(CapabilityBadgeBase, { status: status ?? 'checking', ...props });
|
|
38
|
+
}
|
|
39
|
+
export { CapabilityBadge, CapabilityDot };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type NativeCapabilityId } from '../../lib/native-capabilities';
|
|
3
|
+
export interface CapabilityMatrixProps extends React.ComponentProps<'div'> {
|
|
4
|
+
/** Subset of capabilities to show; defaults to every known capability. */
|
|
5
|
+
capabilities?: NativeCapabilityId[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Responsive support grid for every native capability: icon, humanized name,
|
|
9
|
+
* status dot, support level, and transport. Renders skeleton cells while the
|
|
10
|
+
* manifest loads and a quiet note when it is unavailable outside Moldable.
|
|
11
|
+
*/
|
|
12
|
+
declare function CapabilityMatrix({ capabilities, className, ...props }: CapabilityMatrixProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export { CapabilityMatrix };
|
|
14
|
+
//# sourceMappingURL=capability-matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-matrix.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/capability-matrix.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,+BAA+B,CAAA;AAyDtC,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACxE,0EAA0E;IAC1E,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAA;CACpC;AAED;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,EACxB,YAAY,EACZ,SAAS,EACT,GAAG,KAAK,EACT,EAAE,qBAAqB,2CAiGvB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Activity, BatteryCharging, Bell, Bluetooth, Cable, Camera, Clipboard, ClipboardCopy, Fingerprint, Gamepad2, KeyRound, Keyboard, MapPin, Mic, Monitor, MonitorUp, Moon, Music, Timer, Usb, Vibrate, Volume2, } from 'lucide-react';
|
|
4
|
+
import { useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { NATIVE_CAPABILITY_IDS, } from '../../lib/native-capabilities';
|
|
6
|
+
import { cn } from '../../lib/utils';
|
|
7
|
+
import { Skeleton } from '../ui/skeleton';
|
|
8
|
+
import { CapabilityDot } from './capability-badge';
|
|
9
|
+
import { loadMoldableCapabilities, } from './use-capability';
|
|
10
|
+
const CAPABILITY_ICON = {
|
|
11
|
+
camera: Camera,
|
|
12
|
+
microphone: Mic,
|
|
13
|
+
'screen-capture': MonitorUp,
|
|
14
|
+
'system-audio': Volume2,
|
|
15
|
+
location: MapPin,
|
|
16
|
+
'clipboard-read': Clipboard,
|
|
17
|
+
'clipboard-write': ClipboardCopy,
|
|
18
|
+
notifications: Bell,
|
|
19
|
+
displays: Monitor,
|
|
20
|
+
'global-shortcuts': Keyboard,
|
|
21
|
+
'power-monitor': BatteryCharging,
|
|
22
|
+
'idle-state': Timer,
|
|
23
|
+
'session-events': Activity,
|
|
24
|
+
'sleep-blocker': Moon,
|
|
25
|
+
'local-authentication': Fingerprint,
|
|
26
|
+
haptics: Vibrate,
|
|
27
|
+
'secure-storage': KeyRound,
|
|
28
|
+
usb: Usb,
|
|
29
|
+
hid: Gamepad2,
|
|
30
|
+
serial: Cable,
|
|
31
|
+
midi: Music,
|
|
32
|
+
bluetooth: Bluetooth,
|
|
33
|
+
};
|
|
34
|
+
const SPECIAL_NAME = {
|
|
35
|
+
usb: 'USB',
|
|
36
|
+
hid: 'HID',
|
|
37
|
+
midi: 'MIDI',
|
|
38
|
+
};
|
|
39
|
+
const SUPPORT_LABEL = {
|
|
40
|
+
checking: 'Checking',
|
|
41
|
+
supported: 'Supported',
|
|
42
|
+
partial: 'Partial',
|
|
43
|
+
unsupported: 'Unsupported',
|
|
44
|
+
unavailable: 'Unavailable',
|
|
45
|
+
};
|
|
46
|
+
function humanizeCapabilityId(id) {
|
|
47
|
+
const special = SPECIAL_NAME[id];
|
|
48
|
+
if (special)
|
|
49
|
+
return special;
|
|
50
|
+
return id
|
|
51
|
+
.split('-')
|
|
52
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
53
|
+
.join(' ');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Responsive support grid for every native capability: icon, humanized name,
|
|
57
|
+
* status dot, support level, and transport. Renders skeleton cells while the
|
|
58
|
+
* manifest loads and a quiet note when it is unavailable outside Moldable.
|
|
59
|
+
*/
|
|
60
|
+
function CapabilityMatrix({ capabilities, className, ...props }) {
|
|
61
|
+
const [manifest, setManifest] = useState(null);
|
|
62
|
+
const [checking, setChecking] = useState(true);
|
|
63
|
+
const generationRef = useRef(0);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const generation = ++generationRef.current;
|
|
66
|
+
loadMoldableCapabilities()
|
|
67
|
+
.then((value) => {
|
|
68
|
+
if (generationRef.current !== generation)
|
|
69
|
+
return;
|
|
70
|
+
setManifest(value);
|
|
71
|
+
setChecking(false);
|
|
72
|
+
})
|
|
73
|
+
.catch(() => {
|
|
74
|
+
if (generationRef.current !== generation)
|
|
75
|
+
return;
|
|
76
|
+
setManifest(null);
|
|
77
|
+
setChecking(false);
|
|
78
|
+
});
|
|
79
|
+
const liveGeneration = generationRef;
|
|
80
|
+
return () => {
|
|
81
|
+
liveGeneration.current++;
|
|
82
|
+
};
|
|
83
|
+
}, []);
|
|
84
|
+
const ids = capabilities ?? NATIVE_CAPABILITY_IDS;
|
|
85
|
+
const unavailable = !checking && manifest === null;
|
|
86
|
+
return (_jsxs("div", { "data-slot": "capability-matrix", "data-status": checking ? 'checking' : unavailable ? 'unavailable' : 'ready', className: cn('grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4', className), ...props, children: [ids.map((id, index) => {
|
|
87
|
+
const Icon = CAPABILITY_ICON[id];
|
|
88
|
+
const descriptor = manifest?.capabilities[id] ?? null;
|
|
89
|
+
const status = checking
|
|
90
|
+
? 'checking'
|
|
91
|
+
: descriptor
|
|
92
|
+
? descriptor.support
|
|
93
|
+
: 'unavailable';
|
|
94
|
+
return (_jsx("div", { "data-slot": "capability-matrix-cell", "data-capability": id, "data-status": status, className: "animate-in fade-in slide-in-from-bottom-1 bg-card rounded-lg border p-3 duration-300 [animation-fill-mode:backwards] motion-reduce:animate-none", style: { animationDelay: `${index * 25}ms` }, children: checking ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-3.5 w-2/3" }), _jsx(Skeleton, { className: "h-3 w-1/2" })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Icon, { className: "text-muted-foreground size-3.5 shrink-0" }), _jsx("span", { className: "truncate text-xs font-medium", children: humanizeCapabilityId(id) }), _jsx(CapabilityDot, { status: status, className: "ml-auto" })] }), _jsxs("div", { className: "mt-1.5 flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-muted-foreground text-[10px]", children: SUPPORT_LABEL[status] }), descriptor ? (_jsx("span", { className: "text-muted-foreground/70 truncate font-mono text-[10px]", children: descriptor.transport.name })) : null] })] })) }, id));
|
|
95
|
+
}), unavailable ? (_jsx("p", { "data-slot": "capability-matrix-note", className: "text-muted-foreground/70 col-span-full text-center text-xs", children: "Native capabilities require the Moldable desktop app." })) : null] }));
|
|
96
|
+
}
|
|
97
|
+
export { CapabilityMatrix };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Button } from '../ui/button';
|
|
3
|
+
/**
|
|
4
|
+
* Clipboard state machine behind `ClipboardCopyButton`. The shared helpers
|
|
5
|
+
* enforce app access when embedded and use the plain web Clipboard API only
|
|
6
|
+
* outside Moldable.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMoldableClipboard(): {
|
|
9
|
+
writeText: (text: string) => Promise<boolean>;
|
|
10
|
+
readText: () => Promise<string | null>;
|
|
11
|
+
lastRead: string | null;
|
|
12
|
+
error: Error | null;
|
|
13
|
+
};
|
|
14
|
+
export interface ClipboardCopyButtonProps extends Omit<React.ComponentProps<typeof Button>, 'value'> {
|
|
15
|
+
/** Text to copy, or a resolver invoked at click time. */
|
|
16
|
+
value: string | (() => string | Promise<string>);
|
|
17
|
+
onCopied?: (text: string) => void;
|
|
18
|
+
onCopyError?: (error: Error) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Copy-to-clipboard button: resolves `value`, writes it, and morphs the copy
|
|
22
|
+
* icon into a success check for a moment.
|
|
23
|
+
*/
|
|
24
|
+
declare function ClipboardCopyButton({ value, onCopied, onCopyError, variant, size, onClick, children, ...props }: ClipboardCopyButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export { ClipboardCopyButton };
|
|
26
|
+
//# sourceMappingURL=clipboard-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard-button.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/clipboard-button.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC;;;;GAIG;AACH,wBAAgB,oBAAoB;sBAIS,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;oBAe7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;;;EAmB9D;AAED,MAAM,WAAW,wBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1D,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAChD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CACrC;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,WAAW,EACX,OAAiB,EACjB,IAAgB,EAChB,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,wBAAwB,2CAqE1B;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Check, Copy } from 'lucide-react';
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { readMoldableClipboardText, writeMoldableClipboardText, } from '../../lib/native-capabilities';
|
|
6
|
+
import { Button } from '../ui/button';
|
|
7
|
+
/**
|
|
8
|
+
* Clipboard state machine behind `ClipboardCopyButton`. The shared helpers
|
|
9
|
+
* enforce app access when embedded and use the plain web Clipboard API only
|
|
10
|
+
* outside Moldable.
|
|
11
|
+
*/
|
|
12
|
+
export function useMoldableClipboard() {
|
|
13
|
+
const [lastRead, setLastRead] = useState(null);
|
|
14
|
+
const [error, setError] = useState(null);
|
|
15
|
+
const writeText = useCallback(async (text) => {
|
|
16
|
+
setError(null);
|
|
17
|
+
try {
|
|
18
|
+
await writeMoldableClipboardText(text);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch (cause) {
|
|
22
|
+
setError(cause instanceof Error
|
|
23
|
+
? cause
|
|
24
|
+
: new Error('Could not write clipboard text.'));
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
28
|
+
const readText = useCallback(async () => {
|
|
29
|
+
setError(null);
|
|
30
|
+
let text;
|
|
31
|
+
try {
|
|
32
|
+
text = await readMoldableClipboardText();
|
|
33
|
+
}
|
|
34
|
+
catch (cause) {
|
|
35
|
+
setLastRead(null);
|
|
36
|
+
setError(cause instanceof Error
|
|
37
|
+
? cause
|
|
38
|
+
: new Error('Could not read clipboard text.'));
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
setLastRead(text);
|
|
42
|
+
return text;
|
|
43
|
+
}, []);
|
|
44
|
+
return { writeText, readText, lastRead, error };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Copy-to-clipboard button: resolves `value`, writes it, and morphs the copy
|
|
48
|
+
* icon into a success check for a moment.
|
|
49
|
+
*/
|
|
50
|
+
function ClipboardCopyButton({ value, onCopied, onCopyError, variant = 'ghost', size = 'icon-sm', onClick, children, ...props }) {
|
|
51
|
+
const { writeText } = useMoldableClipboard();
|
|
52
|
+
const [copied, setCopied] = useState(false);
|
|
53
|
+
const [copyFailed, setCopyFailed] = useState(false);
|
|
54
|
+
const tokenRef = useRef(0);
|
|
55
|
+
const timeoutRef = useRef(null);
|
|
56
|
+
useEffect(() => () => {
|
|
57
|
+
tokenRef.current++;
|
|
58
|
+
if (timeoutRef.current !== null)
|
|
59
|
+
window.clearTimeout(timeoutRef.current);
|
|
60
|
+
}, []);
|
|
61
|
+
const copy = useCallback(async () => {
|
|
62
|
+
const token = ++tokenRef.current;
|
|
63
|
+
setCopied(false);
|
|
64
|
+
setCopyFailed(false);
|
|
65
|
+
let text;
|
|
66
|
+
try {
|
|
67
|
+
const source = value;
|
|
68
|
+
text = typeof source === 'function' ? await source() : source;
|
|
69
|
+
}
|
|
70
|
+
catch (cause) {
|
|
71
|
+
if (tokenRef.current !== token)
|
|
72
|
+
return;
|
|
73
|
+
const error = cause instanceof Error ? cause : new Error('Could not resolve text.');
|
|
74
|
+
setCopyFailed(true);
|
|
75
|
+
onCopyError?.(error);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const written = await writeText(text);
|
|
79
|
+
if (tokenRef.current !== token)
|
|
80
|
+
return;
|
|
81
|
+
if (!written) {
|
|
82
|
+
const error = new Error('Could not write clipboard text.');
|
|
83
|
+
setCopyFailed(true);
|
|
84
|
+
onCopyError?.(error);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
onCopied?.(text);
|
|
88
|
+
setCopied(true);
|
|
89
|
+
if (timeoutRef.current !== null)
|
|
90
|
+
window.clearTimeout(timeoutRef.current);
|
|
91
|
+
timeoutRef.current = window.setTimeout(() => setCopied(false), 1500);
|
|
92
|
+
}, [onCopied, onCopyError, value, writeText]);
|
|
93
|
+
return (_jsxs(Button, { "data-slot": "clipboard-copy-button", "data-copied": copied || undefined, "data-copy-status": copied ? 'success' : copyFailed ? 'error' : 'idle', variant: variant, size: size, "aria-label": copied ? 'Copied' : copyFailed ? 'Copy failed; try again' : 'Copy', onClick: (event) => {
|
|
94
|
+
onClick?.(event);
|
|
95
|
+
if (!event.defaultPrevented)
|
|
96
|
+
void copy();
|
|
97
|
+
}, ...props, children: [copied ? (_jsx(Check, { className: "text-success animate-in zoom-in-50 duration-200 motion-reduce:animate-none" })) : (_jsx(Copy, {})), children] }));
|
|
98
|
+
}
|
|
99
|
+
export { ClipboardCopyButton };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function parseIntegerInput(value: string, label: string, minimum: number, maximum: number): number;
|
|
2
|
+
export declare function parseHexBytes(value: string): Uint8Array<ArrayBuffer>;
|
|
3
|
+
export declare function formatHexBytes(data: ArrayBufferView | null | undefined): string;
|
|
4
|
+
//# sourceMappingURL=device-io-controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-io-controls.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/device-io-controls.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CASR;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAepE;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACvC,MAAM,CAMR"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function parseIntegerInput(value, label, minimum, maximum) {
|
|
2
|
+
const normalized = value.trim();
|
|
3
|
+
const parsed = normalized.length > 0 ? Number(normalized) : Number.NaN;
|
|
4
|
+
if (!Number.isInteger(parsed) || parsed < minimum || parsed > maximum) {
|
|
5
|
+
throw new Error(`${label} must be an integer from ${minimum} to ${maximum}.`);
|
|
6
|
+
}
|
|
7
|
+
return parsed;
|
|
8
|
+
}
|
|
9
|
+
export function parseHexBytes(value) {
|
|
10
|
+
const normalized = value.trim();
|
|
11
|
+
if (normalized.length === 0)
|
|
12
|
+
return new Uint8Array(0);
|
|
13
|
+
const tokens = normalized.split(/[\s,]+/u);
|
|
14
|
+
const bytes = tokens.map((token) => {
|
|
15
|
+
const digits = token.replace(/^0x/iu, '');
|
|
16
|
+
if (!/^[\da-f]{1,2}$/iu.test(digits)) {
|
|
17
|
+
throw new Error('Payload must contain hexadecimal bytes such as 01 A0 FF.');
|
|
18
|
+
}
|
|
19
|
+
return Number.parseInt(digits, 16);
|
|
20
|
+
});
|
|
21
|
+
return new Uint8Array(bytes);
|
|
22
|
+
}
|
|
23
|
+
export function formatHexBytes(data) {
|
|
24
|
+
if (!data || data.byteLength === 0)
|
|
25
|
+
return '(empty)';
|
|
26
|
+
const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
27
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0').toUpperCase()).join(' ');
|
|
28
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
declare function DeviceList({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export interface DeviceListItemProps extends React.ComponentProps<'div'> {
|
|
4
|
+
/** Icon shown in the leading square well. */
|
|
5
|
+
icon?: React.ReactNode;
|
|
6
|
+
name: React.ReactNode;
|
|
7
|
+
/** Secondary line, rendered in mono (IDs, vendor codes, paths). */
|
|
8
|
+
description?: React.ReactNode;
|
|
9
|
+
/** Shows a green dot + "Connected" next to the name. */
|
|
10
|
+
connected?: boolean;
|
|
11
|
+
/** Trailing actions (buttons, badges). */
|
|
12
|
+
action?: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
declare function DeviceListItem({ icon, name, description, connected, action, className, children, ...props }: DeviceListItemProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export interface DeviceListEmptyProps extends React.ComponentProps<'div'> {
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
declare function DeviceListEmpty({ icon, className, children, ...props }: DeviceListEmptyProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export { DeviceList, DeviceListItem, DeviceListEmpty };
|
|
20
|
+
//# sourceMappingURL=device-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-list.d.ts","sourceRoot":"","sources":["../../../src/components/native-capabilities/device-list.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAYvE;AAED,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACtE,6CAA6C;IAC7C,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;IACrB,mEAAmE;IACnE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAED,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,WAAW,EACX,SAAiB,EACjB,MAAM,EACN,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,mBAAmB,2CA2DrB;AAED,MAAM,WAAW,oBAAqB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACvE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACvB;AAED,iBAAS,eAAe,CAAC,EACvB,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,oBAAoB,2CAkBtB;AAED,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
function DeviceList({ className, ...props }) {
|
|
5
|
+
return (_jsx("div", { "data-slot": "device-list", role: "list", className: cn('divide-border divide-y overflow-hidden rounded-lg border', className), ...props }));
|
|
6
|
+
}
|
|
7
|
+
function DeviceListItem({ icon, name, description, connected = false, action, className, children, ...props }) {
|
|
8
|
+
return (_jsxs("div", { "data-slot": "device-list-item", role: "listitem", className: cn('animate-in fade-in slide-in-from-bottom-1 flex items-center gap-3 px-3 py-2.5 duration-300 motion-reduce:animate-none', props.onClick &&
|
|
9
|
+
'hover:bg-muted/50 focus-visible:bg-muted/50 cursor-pointer outline-none transition-colors', className), ...props, children: [icon ? (_jsx("div", { "data-slot": "device-list-item-icon", className: "text-muted-foreground bg-muted/50 flex size-8 shrink-0 items-center justify-center rounded-md border [&_svg:not([class*='size-'])]:size-4", children: icon })) : null, _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { "data-slot": "device-list-item-name", className: "truncate text-sm font-medium", children: name }), connected ? (_jsxs("span", { "data-slot": "device-list-item-connected", className: "text-status-running inline-flex shrink-0 items-center gap-1 text-[10px] font-medium uppercase tracking-wide", children: [_jsx("span", { className: "bg-status-running size-1.5 rounded-full" }), "Connected"] })) : null] }), description ? (_jsx("div", { "data-slot": "device-list-item-description", className: "text-muted-foreground mt-0.5 truncate font-mono text-xs", children: description })) : null, children] }), action ? (_jsx("div", { "data-slot": "device-list-item-action", className: "flex shrink-0 items-center gap-1.5", children: action })) : null] }));
|
|
10
|
+
}
|
|
11
|
+
function DeviceListEmpty({ icon, className, children, ...props }) {
|
|
12
|
+
return (_jsxs("div", { "data-slot": "device-list-empty", className: cn('text-muted-foreground flex flex-col items-center gap-2 px-4 py-8 text-center text-sm', className), ...props, children: [icon ? (_jsx("div", { className: "opacity-60 [&_svg:not([class*='size-'])]:size-5", children: icon })) : null, children] }));
|
|
13
|
+
}
|
|
14
|
+
export { DeviceList, DeviceListItem, DeviceListEmpty };
|