@signalcore/ui 0.1.0 → 1.0.0-beta.1
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/README.md +896 -513
- package/dist/AgentAbout.d.ts +186 -0
- package/dist/AgentAbout.js +1020 -0
- package/dist/AgentAbout.js.map +1 -0
- package/dist/AgentCard.d.ts +49 -0
- package/dist/AgentCard.js +77 -0
- package/dist/AgentCard.js.map +1 -0
- package/dist/AgentChat.d.ts +233 -0
- package/dist/AgentChat.js +1127 -0
- package/dist/AgentChat.js.map +1 -0
- package/dist/AgentSpace.d.ts +112 -0
- package/dist/AgentSpace.js +339 -0
- package/dist/AgentSpace.js.map +1 -0
- package/dist/AgentTasks.d.ts +48 -0
- package/dist/AgentTasks.js +120 -0
- package/dist/AgentTasks.js.map +1 -0
- package/dist/BrowserView.d.ts +52 -0
- package/dist/BrowserView.js +328 -0
- package/dist/BrowserView.js.map +1 -0
- package/dist/FileView.d.ts +63 -0
- package/dist/FileView.js +449 -0
- package/dist/FileView.js.map +1 -0
- package/dist/Modes.d.ts +13 -0
- package/dist/Modes.js +75 -0
- package/dist/Modes.js.map +1 -0
- package/dist/VoiceCall.d.ts +91 -0
- package/dist/VoiceCall.js +302 -0
- package/dist/VoiceCall.js.map +1 -0
- package/dist/about.d.ts +212 -0
- package/dist/about.js +136 -0
- package/dist/about.js.map +1 -0
- package/dist/agentIcons.d.ts +33 -0
- package/dist/agentIcons.js +36 -0
- package/dist/agentIcons.js.map +1 -0
- package/dist/automation/Automation.d.ts +35 -0
- package/dist/automation/Automation.js +268 -0
- package/dist/automation/Automation.js.map +1 -0
- package/dist/automation/RunView.d.ts +25 -0
- package/dist/automation/RunView.js +187 -0
- package/dist/automation/RunView.js.map +1 -0
- package/dist/automation/cron.d.ts +41 -0
- package/dist/automation/cron.js +169 -0
- package/dist/automation/cron.js.map +1 -0
- package/dist/automation/marks.js +121 -0
- package/dist/automation/marks.js.map +1 -0
- package/dist/automation/messages.d.ts +113 -0
- package/dist/automation/messages.js +113 -0
- package/dist/automation/messages.js.map +1 -0
- package/dist/automation/record.d.ts +47 -0
- package/dist/automation/record.js +177 -0
- package/dist/automation/record.js.map +1 -0
- package/dist/automation/types.d.ts +143 -0
- package/dist/automation/when.d.ts +36 -0
- package/dist/automation/when.js +168 -0
- package/dist/automation/when.js.map +1 -0
- package/dist/blocks.d.ts +185 -0
- package/dist/browser.js +292 -0
- package/dist/browser.js.map +1 -0
- package/dist/call.d.ts +89 -0
- package/dist/call.js +218 -0
- package/dist/call.js.map +1 -0
- package/dist/channelParts.js +26 -0
- package/dist/channelParts.js.map +1 -0
- package/dist/classes.js +8 -3
- package/dist/classes.js.map +1 -0
- package/dist/client.d.ts +146 -54
- package/dist/client.js +204 -1
- package/dist/client.js.map +1 -0
- package/dist/conversationFiles.js +46 -0
- package/dist/conversationFiles.js.map +1 -0
- package/dist/credentials.d.ts +45 -0
- package/dist/credentials.js +98 -0
- package/dist/credentials.js.map +1 -0
- package/dist/dev.js +17 -0
- package/dist/dev.js.map +1 -0
- package/dist/es.d.ts +17 -0
- package/dist/es.js +382 -0
- package/dist/es.js.map +1 -0
- package/dist/files.d.ts +21 -0
- package/dist/files.js +214 -0
- package/dist/files.js.map +1 -0
- package/dist/frames.d.ts +115 -0
- package/dist/frames.js +219 -0
- package/dist/frames.js.map +1 -0
- package/dist/icons.js +29 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +63 -60
- package/dist/index.js +59 -45
- package/dist/kit/AudioPlayer.d.ts +20 -0
- package/dist/kit/AudioPlayer.js +116 -0
- package/dist/kit/AudioPlayer.js.map +1 -0
- package/dist/kit/Button.d.ts +29 -0
- package/dist/kit/Button.js +59 -0
- package/dist/kit/Button.js.map +1 -0
- package/dist/kit/Card.d.ts +16 -0
- package/dist/kit/Card.js +36 -0
- package/dist/kit/Card.js.map +1 -0
- package/dist/kit/Chart.js +152 -0
- package/dist/kit/Chart.js.map +1 -0
- package/dist/kit/Choices.d.ts +21 -0
- package/dist/kit/Choices.js +99 -0
- package/dist/kit/Choices.js.map +1 -0
- package/dist/kit/Combobox.d.ts +26 -0
- package/dist/kit/Combobox.js +190 -0
- package/dist/kit/Combobox.js.map +1 -0
- package/dist/kit/DateField.d.ts +17 -0
- package/dist/kit/DateField.js +133 -0
- package/dist/kit/DateField.js.map +1 -0
- package/dist/kit/Field.d.ts +40 -0
- package/dist/kit/Field.js +98 -0
- package/dist/kit/Field.js.map +1 -0
- package/dist/kit/FileField.d.ts +113 -0
- package/dist/kit/FileField.js +341 -0
- package/dist/kit/FileField.js.map +1 -0
- package/dist/kit/FileMark.d.ts +15 -0
- package/dist/kit/FileMark.js +39 -0
- package/dist/kit/FileMark.js.map +1 -0
- package/dist/kit/Inputs.d.ts +59 -0
- package/dist/kit/Inputs.js +205 -0
- package/dist/kit/Inputs.js.map +1 -0
- package/dist/kit/List.d.ts +47 -0
- package/dist/kit/List.js +85 -0
- package/dist/kit/List.js.map +1 -0
- package/dist/kit/Mark.d.ts +30 -0
- package/dist/kit/Mark.js +27 -0
- package/dist/kit/Mark.js.map +1 -0
- package/dist/kit/MarkStack.d.ts +15 -0
- package/dist/kit/MarkStack.js +26 -0
- package/dist/kit/MarkStack.js.map +1 -0
- package/dist/kit/Note.d.ts +11 -0
- package/dist/kit/Note.js +31 -0
- package/dist/kit/Note.js.map +1 -0
- package/dist/kit/Popover.js +90 -0
- package/dist/kit/Popover.js.map +1 -0
- package/dist/kit/RangeField.d.ts +14 -0
- package/dist/kit/RangeField.js +47 -0
- package/dist/kit/RangeField.js.map +1 -0
- package/dist/kit/RatingField.d.ts +14 -0
- package/dist/kit/RatingField.js +50 -0
- package/dist/kit/RatingField.js.map +1 -0
- package/dist/kit/Stat.d.ts +26 -0
- package/dist/kit/Stat.js +46 -0
- package/dist/kit/Stat.js.map +1 -0
- package/dist/kit/Switch.d.ts +14 -0
- package/dist/kit/Switch.js +21 -0
- package/dist/kit/Switch.js.map +1 -0
- package/dist/kit/Tag.d.ts +16 -0
- package/dist/kit/Tag.js +20 -0
- package/dist/kit/Tag.js.map +1 -0
- package/dist/kit/Tile.d.ts +34 -0
- package/dist/kit/Tile.js +52 -0
- package/dist/kit/Tile.js.map +1 -0
- package/dist/kit/TimeField.d.ts +31 -0
- package/dist/kit/TimeField.js +109 -0
- package/dist/kit/TimeField.js.map +1 -0
- package/dist/kit/context.d.ts +22 -0
- package/dist/kit/context.js +46 -0
- package/dist/kit/context.js.map +1 -0
- package/dist/kit/dates.d.ts +14 -0
- package/dist/kit/dates.js +129 -0
- package/dist/kit/dates.js.map +1 -0
- package/dist/kit/messages.d.ts +99 -0
- package/dist/kit/messages.js +66 -0
- package/dist/kit/messages.js.map +1 -0
- package/dist/kit/numbers.d.ts +12 -0
- package/dist/kit/numbers.js +40 -0
- package/dist/kit/numbers.js.map +1 -0
- package/dist/kit/options.d.ts +10 -0
- package/dist/kit/options.js +23 -0
- package/dist/kit/options.js.map +1 -0
- package/dist/kit/uploads.d.ts +42 -0
- package/dist/kit/uploads.js +165 -0
- package/dist/kit/uploads.js.map +1 -0
- package/dist/kit/waveform.js +76 -0
- package/dist/kit/waveform.js.map +1 -0
- package/dist/locale.d.ts +1 -0
- package/dist/locale.js +1 -0
- package/dist/markdown.js +84 -0
- package/dist/markdown.js.map +1 -0
- package/dist/marks.js +217 -0
- package/dist/marks.js.map +1 -0
- package/dist/reveal.js +48 -0
- package/dist/reveal.js.map +1 -0
- package/dist/stepGlyphs.js +62 -0
- package/dist/stepGlyphs.js.map +1 -0
- package/dist/surface/Form.js +264 -0
- package/dist/surface/Form.js.map +1 -0
- package/dist/surface/Markdown.js +42 -0
- package/dist/surface/Markdown.js.map +1 -0
- package/dist/surface/Surface.d.ts +31 -17
- package/dist/surface/Surface.js +480 -57
- package/dist/surface/Surface.js.map +1 -0
- package/dist/surface/scope.d.ts +32 -0
- package/dist/surface/scope.js +23 -0
- package/dist/surface/scope.js.map +1 -0
- package/dist/surface/values.d.ts +44 -0
- package/dist/surface/values.js +237 -0
- package/dist/surface/values.js.map +1 -0
- package/dist/tint.d.ts +10 -0
- package/dist/tint.js +19 -0
- package/dist/tint.js.map +1 -0
- package/dist/types.d.ts +541 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/useAgentFace.d.ts +18 -0
- package/dist/useAgentFace.js +45 -0
- package/dist/useAgentFace.js.map +1 -0
- package/dist/useCall.d.ts +39 -0
- package/dist/useCall.js +273 -0
- package/dist/useCall.js.map +1 -0
- package/dist/useConversation.d.ts +77 -0
- package/dist/useConversation.js +523 -0
- package/dist/useConversation.js.map +1 -0
- package/dist/useDictation.d.ts +17 -0
- package/dist/useDictation.js +68 -0
- package/dist/useDictation.js.map +1 -0
- package/dist/useLive.d.ts +26 -0
- package/dist/useLive.js +88 -0
- package/dist/useLive.js.map +1 -0
- package/dist/usePolled.js +68 -0
- package/dist/usePolled.js.map +1 -0
- package/dist/voice/Orb.d.ts +10 -9
- package/dist/voice/Orb.js +43 -39
- package/dist/voice/Orb.js.map +1 -0
- package/dist/voice/StillOrb.js +33 -0
- package/dist/voice/StillOrb.js.map +1 -0
- package/dist/voice/WebGLOrb.js +98 -0
- package/dist/voice/WebGLOrb.js.map +1 -0
- package/dist/voice/fluidDots.js +161 -0
- package/dist/voice/fluidDots.js.map +1 -0
- package/dist/voice/motion.js +84 -0
- package/dist/voice/motion.js.map +1 -0
- package/dist/voice/orbs.d.ts +32 -0
- package/dist/voice/orbs.js +16 -0
- package/dist/voice/orbs.js.map +1 -0
- package/dist/voice/useReducedMotion.js +16 -16
- package/dist/voice/useReducedMotion.js.map +1 -0
- package/dist/voice/wave.js +116 -0
- package/dist/voice/wave.js.map +1 -0
- package/dist/voice/webgl.js +177 -0
- package/dist/voice/webgl.js.map +1 -0
- package/dist/widget.js +284 -8
- package/package.json +49 -39
- package/src/AgentAbout.tsx +1621 -0
- package/src/AgentCard.tsx +123 -0
- package/src/AgentChat.tsx +1812 -0
- package/src/AgentSpace.tsx +540 -0
- package/src/AgentTasks.tsx +163 -0
- package/src/BrowserView.tsx +442 -0
- package/src/FileView.tsx +620 -0
- package/src/Modes.tsx +112 -0
- package/src/VoiceCall.tsx +411 -0
- package/src/about.ts +355 -0
- package/src/agentIcons.ts +56 -0
- package/src/automation/Automation.tsx +308 -0
- package/src/automation/RunView.tsx +213 -0
- package/src/automation/cron.ts +196 -0
- package/src/automation/marks.tsx +144 -0
- package/src/automation/messages.ts +231 -0
- package/src/automation/record.ts +206 -0
- package/src/automation/types.ts +146 -0
- package/src/automation/when.ts +195 -0
- package/src/blocks.ts +249 -0
- package/src/browser.ts +334 -0
- package/src/call.ts +300 -0
- package/src/channelParts.ts +17 -0
- package/src/classes.ts +10 -0
- package/src/client.ts +397 -0
- package/src/conversationFiles.ts +54 -0
- package/src/credentials.ts +158 -0
- package/src/dev.ts +20 -0
- package/src/es.ts +423 -0
- package/src/files.ts +238 -0
- package/src/frames.ts +291 -0
- package/src/icons.tsx +49 -0
- package/src/index.ts +271 -0
- package/src/kit/AudioPlayer.tsx +129 -0
- package/src/kit/Button.tsx +97 -0
- package/src/kit/Card.tsx +47 -0
- package/src/kit/Chart.tsx +129 -0
- package/src/kit/Choices.tsx +131 -0
- package/src/kit/Combobox.tsx +247 -0
- package/src/kit/DateField.tsx +156 -0
- package/src/kit/Field.tsx +137 -0
- package/src/kit/FileField.tsx +492 -0
- package/src/kit/FileMark.tsx +56 -0
- package/src/kit/Inputs.tsx +250 -0
- package/src/kit/List.tsx +135 -0
- package/src/kit/Mark.tsx +64 -0
- package/src/kit/MarkStack.tsx +29 -0
- package/src/kit/Note.tsx +42 -0
- package/src/kit/Popover.tsx +121 -0
- package/src/kit/RangeField.tsx +53 -0
- package/src/kit/RatingField.tsx +62 -0
- package/src/kit/Stat.tsx +60 -0
- package/src/kit/Switch.tsx +28 -0
- package/src/kit/Tag.tsx +32 -0
- package/src/kit/Tile.tsx +74 -0
- package/src/kit/TimeField.tsx +157 -0
- package/src/kit/context.tsx +246 -0
- package/src/kit/dates.ts +150 -0
- package/src/kit/messages.ts +160 -0
- package/src/kit/numbers.ts +44 -0
- package/src/kit/options.ts +30 -0
- package/src/kit/uploads.ts +244 -0
- package/src/kit/waveform.ts +84 -0
- package/src/locale.ts +6 -0
- package/src/markdown.ts +69 -0
- package/src/marks.tsx +328 -0
- package/src/reveal.ts +52 -0
- package/src/stepGlyphs.ts +83 -0
- package/src/styles.css +6970 -0
- package/src/surface/Form.tsx +299 -0
- package/src/surface/Markdown.tsx +55 -0
- package/src/surface/Surface.tsx +605 -0
- package/src/surface/scope.ts +82 -0
- package/src/surface/values.ts +361 -0
- package/src/tint.ts +14 -0
- package/src/types.ts +604 -0
- package/src/useAgentFace.ts +47 -0
- package/src/useCall.ts +292 -0
- package/src/useConversation.ts +627 -0
- package/src/useDictation.ts +83 -0
- package/src/useLive.ts +115 -0
- package/src/usePolled.ts +60 -0
- package/src/voice/Orb.tsx +45 -0
- package/src/voice/StillOrb.tsx +29 -0
- package/src/voice/WebGLOrb.tsx +98 -0
- package/src/voice/fluidDots.tsx +171 -0
- package/src/voice/motion.ts +112 -0
- package/src/voice/orbs.ts +39 -0
- package/src/voice/useReducedMotion.ts +24 -0
- package/src/voice/wave.tsx +129 -0
- package/src/voice/webgl.ts +209 -0
- package/src/widget/css.d.ts +5 -0
- package/src/widget/element.tsx +535 -0
- package/src/widget/index.ts +10 -0
- package/src/widget/mount.ts +27 -0
- package/src/widget/widget.css +253 -0
- package/dist/SignalcoreProvider.d.ts +0 -113
- package/dist/SignalcoreProvider.js +0 -84
- package/dist/automations/AppMarks.d.ts +0 -11
- package/dist/automations/AppMarks.js +0 -18
- package/dist/automations/AutomationCard.d.ts +0 -27
- package/dist/automations/AutomationCard.js +0 -53
- package/dist/automations/AutomationsWindow.d.ts +0 -38
- package/dist/automations/AutomationsWindow.js +0 -57
- package/dist/automations/Card.d.ts +0 -46
- package/dist/automations/Card.js +0 -45
- package/dist/automations/ScheduleMarks.d.ts +0 -13
- package/dist/automations/ScheduleMarks.js +0 -24
- package/dist/automations/presentationIcons.d.ts +0 -7
- package/dist/automations/presentationIcons.js +0 -67
- package/dist/automations/schedule.d.ts +0 -25
- package/dist/automations/schedule.js +0 -59
- package/dist/automations/time.d.ts +0 -3
- package/dist/automations/time.js +0 -25
- package/dist/browser/BrowserView.d.ts +0 -43
- package/dist/browser/BrowserView.js +0 -94
- package/dist/browser/room.d.ts +0 -21
- package/dist/browser/room.js +0 -33
- package/dist/browser/useBrowserSession.d.ts +0 -17
- package/dist/browser/useBrowserSession.js +0 -67
- package/dist/builder/BuilderChat.d.ts +0 -32
- package/dist/builder/BuilderChat.js +0 -41
- package/dist/builder/BuilderTranscript.d.ts +0 -49
- package/dist/builder/BuilderTranscript.js +0 -62
- package/dist/builder/StatusLine.d.ts +0 -8
- package/dist/builder/StatusLine.js +0 -17
- package/dist/builder/answer.d.ts +0 -7
- package/dist/builder/answer.js +0 -8
- package/dist/builder/blocks.d.ts +0 -31
- package/dist/builder/blocks.js +0 -74
- package/dist/builder/items.d.ts +0 -15
- package/dist/builder/items.js +0 -21
- package/dist/builder/steps.d.ts +0 -20
- package/dist/builder/steps.js +0 -120
- package/dist/builder/time.d.ts +0 -4
- package/dist/builder/time.js +0 -24
- package/dist/builder/useBuildSession.d.ts +0 -36
- package/dist/builder/useBuildSession.js +0 -130
- package/dist/builder/workingOn.d.ts +0 -7
- package/dist/builder/workingOn.js +0 -15
- package/dist/chat/AgentChat.d.ts +0 -37
- package/dist/chat/AgentChat.js +0 -21
- package/dist/chat/ChatView.d.ts +0 -25
- package/dist/chat/ChatView.js +0 -34
- package/dist/chat/Composer.d.ts +0 -20
- package/dist/chat/Composer.js +0 -22
- package/dist/chat/MessageRow.d.ts +0 -22
- package/dist/chat/MessageRow.js +0 -32
- package/dist/chat/arrival.d.ts +0 -15
- package/dist/chat/arrival.js +0 -25
- package/dist/chat/history.d.ts +0 -24
- package/dist/chat/history.js +0 -45
- package/dist/chat/moments.d.ts +0 -25
- package/dist/chat/moments.js +0 -72
- package/dist/chat/types.d.ts +0 -12
- package/dist/chat/types.js +0 -1
- package/dist/chat/useComposer.d.ts +0 -46
- package/dist/chat/useComposer.js +0 -62
- package/dist/chat/useConversation.d.ts +0 -35
- package/dist/chat/useConversation.js +0 -71
- package/dist/chat/useStickToBottom.d.ts +0 -9
- package/dist/chat/useStickToBottom.js +0 -33
- package/dist/chat/useTurns.d.ts +0 -49
- package/dist/chat/useTurns.js +0 -111
- package/dist/classes.d.ts +0 -2
- package/dist/development.d.ts +0 -5
- package/dist/development.js +0 -8
- package/dist/flow/FlowWindow.d.ts +0 -42
- package/dist/flow/FlowWindow.js +0 -126
- package/dist/flow/index.d.ts +0 -16
- package/dist/flow/index.js +0 -16
- package/dist/flow/kinds.d.ts +0 -23
- package/dist/flow/kinds.js +0 -48
- package/dist/flow/map.d.ts +0 -44
- package/dist/flow/map.js +0 -225
- package/dist/flow/nodePaths.d.ts +0 -7
- package/dist/flow/nodePaths.js +0 -17
- package/dist/flow/relations.d.ts +0 -42
- package/dist/flow/relations.js +0 -174
- package/dist/host.d.ts +0 -124
- package/dist/host.js +0 -1
- package/dist/live/LiveView.d.ts +0 -28
- package/dist/live/LiveView.js +0 -55
- package/dist/live/capture.d.ts +0 -20
- package/dist/live/capture.js +0 -100
- package/dist/live/follow.d.ts +0 -26
- package/dist/live/follow.js +0 -72
- package/dist/live/paint.d.ts +0 -13
- package/dist/live/paint.js +0 -77
- package/dist/live/useLiveStream.d.ts +0 -16
- package/dist/live/useLiveStream.js +0 -57
- package/dist/look.d.ts +0 -33
- package/dist/look.js +0 -241
- package/dist/messages/en.d.ts +0 -3
- package/dist/messages/en.js +0 -251
- package/dist/messages/es.d.ts +0 -3
- package/dist/messages/es.js +0 -251
- package/dist/messages/index.d.ts +0 -16
- package/dist/messages/index.js +0 -33
- package/dist/messages/types.d.ts +0 -246
- package/dist/messages/types.js +0 -1
- package/dist/parts/Button.d.ts +0 -18
- package/dist/parts/Button.js +0 -17
- package/dist/parts/Icon.d.ts +0 -39
- package/dist/parts/Icon.js +0 -37
- package/dist/parts/Input.d.ts +0 -6
- package/dist/parts/Input.js +0 -11
- package/dist/parts/Spinner.d.ts +0 -2
- package/dist/parts/Spinner.js +0 -7
- package/dist/patterns.d.ts +0 -15
- package/dist/patterns.js +0 -5
- package/dist/presets.d.ts +0 -82
- package/dist/presets.js +0 -81
- package/dist/primitives.d.ts +0 -22
- package/dist/primitives.js +0 -58
- package/dist/request/RequestCard.d.ts +0 -34
- package/dist/request/RequestCard.js +0 -101
- package/dist/request/approval/ApprovalPreview.d.ts +0 -5
- package/dist/request/approval/ApprovalPreview.js +0 -27
- package/dist/request/approval/shapes.d.ts +0 -32
- package/dist/request/approval/shapes.js +0 -68
- package/dist/request/apps.d.ts +0 -11
- package/dist/request/apps.js +0 -27
- package/dist/request/cards.d.ts +0 -12
- package/dist/request/cards.js +0 -24
- package/dist/request/deliver.d.ts +0 -12
- package/dist/request/deliver.js +0 -21
- package/dist/request/handOver.d.ts +0 -18
- package/dist/request/handOver.js +0 -33
- package/dist/request/kinds/Approval.d.ts +0 -3
- package/dist/request/kinds/Approval.js +0 -9
- package/dist/request/kinds/Choice.d.ts +0 -3
- package/dist/request/kinds/Choice.js +0 -8
- package/dist/request/kinds/Connect.d.ts +0 -9
- package/dist/request/kinds/Connect.js +0 -119
- package/dist/request/kinds/FreeText.d.ts +0 -3
- package/dist/request/kinds/FreeText.js +0 -20
- package/dist/request/kinds/HandOver.d.ts +0 -13
- package/dist/request/kinds/HandOver.js +0 -20
- package/dist/request/kinds/Secret.d.ts +0 -7
- package/dist/request/kinds/Secret.js +0 -49
- package/dist/request/kinds/Upload.d.ts +0 -6
- package/dist/request/kinds/Upload.js +0 -47
- package/dist/request/types.d.ts +0 -83
- package/dist/request/types.js +0 -1
- package/dist/safeUrl.d.ts +0 -6
- package/dist/safeUrl.js +0 -8
- package/dist/stream/builder.d.ts +0 -176
- package/dist/stream/builder.js +0 -202
- package/dist/stream/reduce.d.ts +0 -51
- package/dist/stream/reduce.js +0 -58
- package/dist/stream/untilAborted.d.ts +0 -7
- package/dist/stream/untilAborted.js +0 -32
- package/dist/stream/useRunStream.d.ts +0 -26
- package/dist/stream/useRunStream.js +0 -137
- package/dist/styles.css +0 -2318
- package/dist/surface/HostNode.d.ts +0 -14
- package/dist/surface/HostNode.js +0 -30
- package/dist/surface/Node.d.ts +0 -7
- package/dist/surface/Node.js +0 -49
- package/dist/surface/SurfaceBoundary.d.ts +0 -26
- package/dist/surface/SurfaceBoundary.js +0 -20
- package/dist/surface/bindings.d.ts +0 -14
- package/dist/surface/bindings.js +0 -37
- package/dist/surface/check.d.ts +0 -27
- package/dist/surface/check.js +0 -102
- package/dist/surface/format.d.ts +0 -10
- package/dist/surface/format.js +0 -32
- package/dist/surface/hosts.d.ts +0 -6
- package/dist/surface/hosts.js +0 -11
- package/dist/surface/scene.d.ts +0 -21
- package/dist/surface/scene.js +0 -8
- package/dist/surface/templates/Browser.d.ts +0 -6
- package/dist/surface/templates/Browser.js +0 -11
- package/dist/surface/templates/Chart.d.ts +0 -6
- package/dist/surface/templates/Chart.js +0 -13
- package/dist/surface/templates/Choices.d.ts +0 -3
- package/dist/surface/templates/Choices.js +0 -12
- package/dist/surface/templates/Form.d.ts +0 -3
- package/dist/surface/templates/Form.js +0 -44
- package/dist/surface/templates/KeyValue.d.ts +0 -3
- package/dist/surface/templates/KeyValue.js +0 -7
- package/dist/surface/templates/Layout.d.ts +0 -5
- package/dist/surface/templates/Layout.js +0 -16
- package/dist/surface/templates/Live.d.ts +0 -6
- package/dist/surface/templates/Live.js +0 -9
- package/dist/surface/templates/Media.d.ts +0 -5
- package/dist/surface/templates/Media.js +0 -13
- package/dist/surface/templates/Slots.d.ts +0 -3
- package/dist/surface/templates/Slots.js +0 -19
- package/dist/surface/templates/Table.d.ts +0 -3
- package/dist/surface/templates/Table.js +0 -12
- package/dist/surface/templates/Text.d.ts +0 -4
- package/dist/surface/templates/Text.js +0 -15
- package/dist/surface/templates/index.d.ts +0 -7
- package/dist/surface/templates/index.js +0 -32
- package/dist/surface/types.d.ts +0 -68
- package/dist/surface/types.js +0 -6
- package/dist/theme.d.ts +0 -62
- package/dist/theme.js +0 -9
- package/dist/useTokens.d.ts +0 -7
- package/dist/useTokens.js +0 -41
- package/dist/voice/VoiceWindow.d.ts +0 -18
- package/dist/voice/VoiceWindow.js +0 -35
- package/dist/voice/index.d.ts +0 -13
- package/dist/voice/index.js +0 -12
- package/dist/voice/meter.d.ts +0 -16
- package/dist/voice/meter.js +0 -52
- package/dist/voice/orbColors.d.ts +0 -16
- package/dist/voice/orbColors.js +0 -75
- package/dist/voice/pushable.d.ts +0 -16
- package/dist/voice/pushable.js +0 -56
- package/dist/voice/useDictation.d.ts +0 -24
- package/dist/voice/useDictation.js +0 -60
- package/dist/voice/useReducedMotion.d.ts +0 -5
- package/dist/voice/useVoice.d.ts +0 -70
- package/dist/voice/useVoice.js +0 -197
- package/dist/voice/useVoicePrimitives.d.ts +0 -7
- package/dist/voice/useVoicePrimitives.js +0 -11
- package/dist/voice/voice.d.ts +0 -55
- package/dist/voice/voice.js +0 -9
- package/dist/voice/webSpeech.d.ts +0 -33
- package/dist/voice/webSpeech.js +0 -258
- package/dist/widget.js.map +0 -1
- package/dist/windows/AgentSpace.d.ts +0 -78
- package/dist/windows/AgentSpace.js +0 -135
- package/dist/windows/Captions.d.ts +0 -13
- package/dist/windows/Captions.js +0 -22
- package/dist/windows/Dock.d.ts +0 -37
- package/dist/windows/Dock.js +0 -22
- package/dist/windows/Journal.d.ts +0 -15
- package/dist/windows/Journal.js +0 -19
- package/dist/windows/KindMark.d.ts +0 -7
- package/dist/windows/KindMark.js +0 -31
- package/dist/windows/Pending.d.ts +0 -8
- package/dist/windows/Pending.js +0 -17
- package/dist/windows/Stage.d.ts +0 -18
- package/dist/windows/Stage.js +0 -21
- package/dist/windows/StatusLabel.d.ts +0 -9
- package/dist/windows/StatusLabel.js +0 -7
- package/dist/windows/Strip.d.ts +0 -17
- package/dist/windows/Strip.js +0 -42
- package/dist/windows/SurfaceWindow.d.ts +0 -20
- package/dist/windows/SurfaceWindow.js +0 -12
- package/dist/windows/WindowFrame.d.ts +0 -23
- package/dist/windows/WindowFrame.js +0 -22
- package/dist/windows/hearing.d.ts +0 -11
- package/dist/windows/hearing.js +0 -26
- package/dist/windows/kinds.d.ts +0 -47
- package/dist/windows/kinds.js +0 -28
- package/dist/windows/reduce.d.ts +0 -98
- package/dist/windows/reduce.js +0 -151
- package/dist/windows/registry.d.ts +0 -18
- package/dist/windows/registry.js +0 -61
- package/dist/windows/reveal.d.ts +0 -9
- package/dist/windows/reveal.js +0 -6
- package/dist/windows/space.d.ts +0 -21
- package/dist/windows/space.js +0 -6
- package/dist/windows/status.d.ts +0 -11
- package/dist/windows/status.js +0 -30
- package/dist/windows/types.d.ts +0 -15
- package/dist/windows/types.js +0 -1
- package/dist/windows/useLoaded.d.ts +0 -44
- package/dist/windows/useLoaded.js +0 -58
- package/dist/windows/useUnread.d.ts +0 -7
- package/dist/windows/useUnread.js +0 -21
- package/dist/windows/useWindows.d.ts +0 -70
- package/dist/windows/useWindows.js +0 -60
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { ArrowUpIcon, CheckIcon, PencilSimpleIcon } from "@phosphor-icons/react";
|
|
2
|
+
import { Component, useEffect, useRef, useState, type ComponentType, type ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
import { Automation } from "../automation/Automation";
|
|
5
|
+
import type {
|
|
6
|
+
AutomationBlock,
|
|
7
|
+
Block,
|
|
8
|
+
ButtonBlock,
|
|
9
|
+
ChoiceBlock,
|
|
10
|
+
FieldsBlock,
|
|
11
|
+
ImageBlock,
|
|
12
|
+
ListBlock,
|
|
13
|
+
Surface as Shown,
|
|
14
|
+
TableBlock,
|
|
15
|
+
} from "../blocks";
|
|
16
|
+
import { classes } from "../classes";
|
|
17
|
+
import { Button } from "../kit/Button";
|
|
18
|
+
import { formatSize } from "../about";
|
|
19
|
+
import { baseName } from "../files";
|
|
20
|
+
import { Card } from "../kit/Card";
|
|
21
|
+
import { Chart } from "../kit/Chart";
|
|
22
|
+
import { KitProvider, useKit, useParts } from "../kit/context";
|
|
23
|
+
import { FileMark } from "../kit/FileMark";
|
|
24
|
+
import { List, Row } from "../kit/List";
|
|
25
|
+
import { Mark } from "../kit/Mark";
|
|
26
|
+
import type { KitLocale, KitMessages } from "../kit/messages";
|
|
27
|
+
import type { FileHost } from "../kit/uploads";
|
|
28
|
+
import { AudioPlayer } from "../kit/AudioPlayer";
|
|
29
|
+
import { Note } from "../kit/Note";
|
|
30
|
+
import { Stat } from "../kit/Stat";
|
|
31
|
+
import type { Attachment, FileBlock } from "../types";
|
|
32
|
+
import { FormView } from "./Form";
|
|
33
|
+
import { Markdown } from "./Markdown";
|
|
34
|
+
import {
|
|
35
|
+
ScopeContext,
|
|
36
|
+
useScope,
|
|
37
|
+
useSurfaceParts,
|
|
38
|
+
type Scope,
|
|
39
|
+
type SurfaceClassNames,
|
|
40
|
+
type SurfaceComponents,
|
|
41
|
+
} from "./scope";
|
|
42
|
+
import { answeredIn, chosen, FIELD_KINDS, picked, pressed, type SurfaceAction } from "./values";
|
|
43
|
+
|
|
44
|
+
export interface SurfaceProps {
|
|
45
|
+
surface: Shown;
|
|
46
|
+
onAction: (action: SurfaceAction) => void;
|
|
47
|
+
/** False draws the inputs disabled: a surface already answered, or one from an older turn. */
|
|
48
|
+
active?: boolean | undefined;
|
|
49
|
+
/** What the person already did on it: the option picked, the button pressed, the form sent. */
|
|
50
|
+
answered?: SurfaceAction | undefined;
|
|
51
|
+
components?: SurfaceComponents | undefined;
|
|
52
|
+
classNames?: SurfaceClassNames;
|
|
53
|
+
/** The words its controls say, in the host's language; English by default. */
|
|
54
|
+
messages?: Partial<KitMessages> | undefined;
|
|
55
|
+
/** The language of its calendar, days, times and numbers; English by default. */
|
|
56
|
+
locale?: KitLocale | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Where its file fields' files go (uploaded as they are picked) and how the ones sent are found
|
|
59
|
+
* and opened: the conversation's. None: a file field takes no files.
|
|
60
|
+
*/
|
|
61
|
+
files?: FileHost | undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const BLOCKS: ReadonlySet<string> = new Set([
|
|
65
|
+
"card",
|
|
66
|
+
"stack",
|
|
67
|
+
"divider",
|
|
68
|
+
"text",
|
|
69
|
+
"fields",
|
|
70
|
+
"table",
|
|
71
|
+
"list",
|
|
72
|
+
"stat",
|
|
73
|
+
"chart",
|
|
74
|
+
"note",
|
|
75
|
+
"image",
|
|
76
|
+
"automation",
|
|
77
|
+
"file",
|
|
78
|
+
"button",
|
|
79
|
+
"choice",
|
|
80
|
+
"form",
|
|
81
|
+
]);
|
|
82
|
+
|
|
83
|
+
/** Whether every block down the tree, and every field of its forms, is one this renderer draws. */
|
|
84
|
+
export function known(blocks: Block[]): boolean {
|
|
85
|
+
return blocks.every((block) => {
|
|
86
|
+
if (!BLOCKS.has(block.type)) return false;
|
|
87
|
+
if (block.type === "form") return block.fields.every((field) => FIELD_KINDS.has(field.kind));
|
|
88
|
+
return "children" in block ? known(block.children) : true;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether a screen draws its own edge: one that is a single card (or an automation, a card of
|
|
94
|
+
* its own) needs no panel around it where it is shown.
|
|
95
|
+
*/
|
|
96
|
+
export function framesItself(surface: Shown): boolean {
|
|
97
|
+
const [only, ...more] = surface.blocks;
|
|
98
|
+
return more.length === 0 && (only?.type === "card" || only?.type === "automation");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* What the agent showed, drawn block by block with the kit's primitives (a `card` is a `Card`, a
|
|
103
|
+
* `list` a `List` of `Row`s, a form's fields its controls); a block or a field kind the API has
|
|
104
|
+
* grown since this renderer was written leaves the whole surface to its text twin, so nothing
|
|
105
|
+
* is half-drawn. Each block's action comes back through `onAction`; the host wraps it with the
|
|
106
|
+
* surface's id.
|
|
107
|
+
*/
|
|
108
|
+
export function Surface({
|
|
109
|
+
surface,
|
|
110
|
+
onAction,
|
|
111
|
+
active = true,
|
|
112
|
+
answered,
|
|
113
|
+
components,
|
|
114
|
+
classNames,
|
|
115
|
+
messages,
|
|
116
|
+
locale,
|
|
117
|
+
files,
|
|
118
|
+
}: SurfaceProps) {
|
|
119
|
+
const scope: Scope = { active, answered, onAction, components, classNames, files };
|
|
120
|
+
return (
|
|
121
|
+
<KitProvider classNames={classNames} messages={messages} locale={locale}>
|
|
122
|
+
<ScopeContext value={scope}>
|
|
123
|
+
<div className={`sc ${classes(classNames, "sc-surface")}`}>
|
|
124
|
+
<Whole twin={<p className={classes(classNames, "sc-surface__text")}>{surface.text}</p>}>
|
|
125
|
+
{known(surface.blocks)
|
|
126
|
+
? surface.blocks.map((block, index) => <Draw key={index} block={block} />)
|
|
127
|
+
: null}
|
|
128
|
+
</Whole>
|
|
129
|
+
</div>
|
|
130
|
+
</ScopeContext>
|
|
131
|
+
</KitProvider>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The surface drawn whole or not at all: what it can't draw (blocks it doesn't know, or one that
|
|
137
|
+
* fails as it draws) leaves its text twin in its place, never a broken page.
|
|
138
|
+
*/
|
|
139
|
+
class Whole extends Component<{ twin: ReactNode; children: ReactNode }, { failed: boolean }> {
|
|
140
|
+
override state = { failed: false };
|
|
141
|
+
|
|
142
|
+
static getDerivedStateFromError(): { failed: boolean } {
|
|
143
|
+
return { failed: true };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
override render() {
|
|
147
|
+
return this.state.failed || this.props.children === null
|
|
148
|
+
? this.props.twin
|
|
149
|
+
: this.props.children;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** One block: the host's own component for its type when it gave one, else the kit's. */
|
|
154
|
+
function Draw({ block }: { block: Block }) {
|
|
155
|
+
const { active, onAction, components } = useScope();
|
|
156
|
+
const part = useSurfaceParts();
|
|
157
|
+
const children =
|
|
158
|
+
"children" in block
|
|
159
|
+
? block.children.map((child, index) => <Draw key={index} block={child} />)
|
|
160
|
+
: undefined;
|
|
161
|
+
const Own = components?.[block.type];
|
|
162
|
+
if (Own) {
|
|
163
|
+
// Found by the block's own type, so its fields are the right props; the union is too wide
|
|
164
|
+
// for the compiler to see that pairing.
|
|
165
|
+
const Host = Own as ComponentType<Record<string, unknown>>;
|
|
166
|
+
return <Host {...block} active={active} onAction={onAction} children={children} />;
|
|
167
|
+
}
|
|
168
|
+
switch (block.type) {
|
|
169
|
+
case "card":
|
|
170
|
+
return (
|
|
171
|
+
<Card title={block.title} subtitle={block.subtitle} image={block.image}>
|
|
172
|
+
{children}
|
|
173
|
+
</Card>
|
|
174
|
+
);
|
|
175
|
+
case "stack":
|
|
176
|
+
return (
|
|
177
|
+
<div
|
|
178
|
+
part="stack"
|
|
179
|
+
className={part(
|
|
180
|
+
"sc-surface__stack",
|
|
181
|
+
...(block.direction === "row" ? (["sc-surface__stack--row"] as const) : []),
|
|
182
|
+
)}
|
|
183
|
+
>
|
|
184
|
+
{children}
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
case "divider":
|
|
188
|
+
return <hr part="divider" className={part("sc-surface__divider")} />;
|
|
189
|
+
case "text":
|
|
190
|
+
return (
|
|
191
|
+
<div part="text" className={part("sc-surface__text")}>
|
|
192
|
+
<Markdown text={block.text} />
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
case "fields":
|
|
196
|
+
return <Fields block={block} />;
|
|
197
|
+
case "table":
|
|
198
|
+
return <Table block={block} />;
|
|
199
|
+
case "list":
|
|
200
|
+
return <Listing block={block} />;
|
|
201
|
+
case "stat":
|
|
202
|
+
return <Stat label={block.label} value={block.value} hint={block.hint} tone={block.tone} />;
|
|
203
|
+
case "chart":
|
|
204
|
+
return <Chart kind={block.kind} points={block.points} />;
|
|
205
|
+
case "note":
|
|
206
|
+
return (
|
|
207
|
+
<Note tone={block.tone}>
|
|
208
|
+
<Markdown text={block.text} />
|
|
209
|
+
</Note>
|
|
210
|
+
);
|
|
211
|
+
case "image":
|
|
212
|
+
return <Picture block={block} />;
|
|
213
|
+
case "automation":
|
|
214
|
+
return <AutomationShown block={block} />;
|
|
215
|
+
case "file":
|
|
216
|
+
return <FileShown block={block} />;
|
|
217
|
+
case "button":
|
|
218
|
+
return <Pressable block={block} />;
|
|
219
|
+
case "choice":
|
|
220
|
+
return <Choice block={block} />;
|
|
221
|
+
case "form":
|
|
222
|
+
return <FormView block={block} />;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* A file the agent put in front of the person, compact: its kind's mark, its title (its name
|
|
228
|
+
* under it when the title is another), its size at the right; pressed, it opens whole in the
|
|
229
|
+
* host's viewer (`files.open`), whatever its kind. A picture, a video or a sound plays where it
|
|
230
|
+
* is instead, when the host can play it (`files.play`). Until the API has put it in the
|
|
231
|
+
* conversation it is only named, quietly.
|
|
232
|
+
*/
|
|
233
|
+
function FileShown({ block }: { block: FileBlock }) {
|
|
234
|
+
const { files } = useScope();
|
|
235
|
+
const { code } = useKit();
|
|
236
|
+
const { file } = block;
|
|
237
|
+
const name = file?.name ?? baseName(block.path);
|
|
238
|
+
const title = block.title ?? name;
|
|
239
|
+
const open = file !== null ? files?.open : undefined;
|
|
240
|
+
const played = file !== null ? playedAs(file.media_type) : null;
|
|
241
|
+
const src = usePlayed(file, played !== null ? files?.play : undefined);
|
|
242
|
+
if (file !== null && played !== null && src !== null) {
|
|
243
|
+
return (
|
|
244
|
+
<Played
|
|
245
|
+
kind={played}
|
|
246
|
+
src={src.url}
|
|
247
|
+
name={name}
|
|
248
|
+
caption={block.title}
|
|
249
|
+
onOpen={open ? () => open(file) : undefined}
|
|
250
|
+
onLost={src.again}
|
|
251
|
+
/>
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
return (
|
|
255
|
+
<List>
|
|
256
|
+
<Row
|
|
257
|
+
mark={<FileMark name={name} type={file?.media_type} />}
|
|
258
|
+
title={title}
|
|
259
|
+
subtitle={title === name ? undefined : name}
|
|
260
|
+
meta={file === null ? undefined : formatSize(file.size, code)}
|
|
261
|
+
quiet={file === null}
|
|
262
|
+
onPress={open && file !== null ? () => open(file) : undefined}
|
|
263
|
+
/>
|
|
264
|
+
</List>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
type PlayedKind = "image" | "video" | "audio";
|
|
269
|
+
|
|
270
|
+
/** How a file plays in the page: a picture, a video, a sound; null for any other kind. */
|
|
271
|
+
export function playedAs(mediaType: string): PlayedKind | null {
|
|
272
|
+
const family = mediaType.split("/")[0];
|
|
273
|
+
return family === "image" || family === "video" || family === "audio" ? family : null;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Where `file` plays from, asked of the host once (`play`): null until it answers, and when it
|
|
278
|
+
* can't. `again` asks for a new address, for a player whose address ran out.
|
|
279
|
+
*/
|
|
280
|
+
export function usePlayed(
|
|
281
|
+
file: Attachment | null,
|
|
282
|
+
play: ((file: Attachment) => Promise<string>) | undefined,
|
|
283
|
+
): { url: string; again: () => void } | null {
|
|
284
|
+
const [url, setUrl] = useState<string | null>(null);
|
|
285
|
+
const [asked, setAsked] = useState(0);
|
|
286
|
+
// The file and the host's way to play it as they are now: a block drawn again carries the
|
|
287
|
+
// same file anew, and the host its functions; what is asked for changes with the file's id.
|
|
288
|
+
const latest = useRef({ file, play });
|
|
289
|
+
latest.current = { file, play };
|
|
290
|
+
const id = file?.id;
|
|
291
|
+
const playable = play !== undefined;
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
const { file: now, play: player } = latest.current;
|
|
294
|
+
if (now === null || player === undefined) return;
|
|
295
|
+
let current = true;
|
|
296
|
+
player(now).then(
|
|
297
|
+
(address) => current && setUrl(address),
|
|
298
|
+
() => current && setUrl(null),
|
|
299
|
+
);
|
|
300
|
+
return () => {
|
|
301
|
+
current = false;
|
|
302
|
+
};
|
|
303
|
+
}, [id, playable, asked]);
|
|
304
|
+
return url === null ? null : { url, again: () => setAsked((times) => times + 1) };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* A picture, a video or a sound the agent put in front of the person, where it is: the
|
|
309
|
+
* browser's own player, streaming from the address it plays from; a picture pressed opens whole
|
|
310
|
+
* in the host's viewer. A player whose address ran out asks for a new one, once.
|
|
311
|
+
*/
|
|
312
|
+
function Played({
|
|
313
|
+
kind,
|
|
314
|
+
src,
|
|
315
|
+
name,
|
|
316
|
+
caption,
|
|
317
|
+
onOpen,
|
|
318
|
+
onLost,
|
|
319
|
+
}: {
|
|
320
|
+
kind: PlayedKind;
|
|
321
|
+
src: string;
|
|
322
|
+
name: string;
|
|
323
|
+
caption: string | undefined;
|
|
324
|
+
onOpen: (() => void) | undefined;
|
|
325
|
+
onLost: () => void;
|
|
326
|
+
}) {
|
|
327
|
+
const part = useSurfaceParts();
|
|
328
|
+
const lost = useRef(false);
|
|
329
|
+
const once = () => {
|
|
330
|
+
if (lost.current) return;
|
|
331
|
+
lost.current = true;
|
|
332
|
+
onLost();
|
|
333
|
+
};
|
|
334
|
+
return (
|
|
335
|
+
<figure part="media" className={part("sc-surface__media")} data-kind={kind}>
|
|
336
|
+
{kind === "image" ? (
|
|
337
|
+
onOpen ? (
|
|
338
|
+
<button type="button" onClick={onOpen} aria-label={name}>
|
|
339
|
+
<img src={src} alt={name} loading="lazy" onError={once} />
|
|
340
|
+
</button>
|
|
341
|
+
) : (
|
|
342
|
+
<img src={src} alt={name} loading="lazy" onError={once} />
|
|
343
|
+
)
|
|
344
|
+
) : kind === "video" ? (
|
|
345
|
+
<video src={src} controls playsInline preload="metadata" aria-label={name} onError={once} />
|
|
346
|
+
) : (
|
|
347
|
+
<AudioPlayer src={src} label={name} onError={once} />
|
|
348
|
+
)}
|
|
349
|
+
{caption !== undefined && <figcaption>{caption}</figcaption>}
|
|
350
|
+
</figure>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Labels and their values, a row each. */
|
|
355
|
+
function Fields({ block }: { block: FieldsBlock }) {
|
|
356
|
+
const part = useSurfaceParts();
|
|
357
|
+
return (
|
|
358
|
+
<dl part="fields" className={part("sc-surface__fields")}>
|
|
359
|
+
{block.items.map((item, index) => (
|
|
360
|
+
<div key={index}>
|
|
361
|
+
<dt>{item.label}</dt>
|
|
362
|
+
<dd>{item.value}</dd>
|
|
363
|
+
</div>
|
|
364
|
+
))}
|
|
365
|
+
</dl>
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/** Rows under named columns, scrolling across inside their own box when they are wide. */
|
|
370
|
+
function Table({ block }: { block: TableBlock }) {
|
|
371
|
+
const part = useSurfaceParts();
|
|
372
|
+
return (
|
|
373
|
+
<div part="table" className={part("sc-surface__table")}>
|
|
374
|
+
<table>
|
|
375
|
+
<thead>
|
|
376
|
+
<tr>
|
|
377
|
+
{block.columns.map((column, index) => (
|
|
378
|
+
<th key={index} scope="col">
|
|
379
|
+
{column}
|
|
380
|
+
</th>
|
|
381
|
+
))}
|
|
382
|
+
</tr>
|
|
383
|
+
</thead>
|
|
384
|
+
<tbody>
|
|
385
|
+
{block.rows.map((row, index) => (
|
|
386
|
+
<tr key={index}>
|
|
387
|
+
{block.columns.map((_, at) => (
|
|
388
|
+
<td key={at}>{row[at] ?? ""}</td>
|
|
389
|
+
))}
|
|
390
|
+
</tr>
|
|
391
|
+
))}
|
|
392
|
+
</tbody>
|
|
393
|
+
</table>
|
|
394
|
+
</div>
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/** A list block as the kit's `List`: a `Row` each; with an action, rows to pick, the picked checked. */
|
|
399
|
+
function Listing({ block }: { block: ListBlock }) {
|
|
400
|
+
const { active, answered, onAction } = useScope();
|
|
401
|
+
const { action } = block;
|
|
402
|
+
const pick = action !== undefined && answered?.name === action ? answered.data.item : undefined;
|
|
403
|
+
return (
|
|
404
|
+
<List>
|
|
405
|
+
{block.items.map((entry) => (
|
|
406
|
+
<Row
|
|
407
|
+
key={entry.id}
|
|
408
|
+
mark={
|
|
409
|
+
entry.image !== undefined && https(entry.image) ? (
|
|
410
|
+
<Mark src={entry.image} photo size={40} />
|
|
411
|
+
) : undefined
|
|
412
|
+
}
|
|
413
|
+
title={entry.title}
|
|
414
|
+
subtitle={entry.subtitle}
|
|
415
|
+
meta={entry.meta}
|
|
416
|
+
pressed={entry.id === pick}
|
|
417
|
+
disabled={!active}
|
|
418
|
+
onPress={
|
|
419
|
+
action === undefined ? undefined : () => onAction(chosen({ ...block, action }, entry))
|
|
420
|
+
}
|
|
421
|
+
/>
|
|
422
|
+
))}
|
|
423
|
+
</List>
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/** A picture from an https address, never sending the page's address along, with its caption. */
|
|
428
|
+
function Picture({ block }: { block: ImageBlock }) {
|
|
429
|
+
const part = useSurfaceParts();
|
|
430
|
+
if (!https(block.url)) return null;
|
|
431
|
+
return (
|
|
432
|
+
<figure part="image" className={part("sc-surface__image")}>
|
|
433
|
+
<img src={block.url} alt={block.alt} loading="lazy" referrerPolicy="no-referrer" />
|
|
434
|
+
{block.caption !== undefined && <figcaption>{block.caption}</figcaption>}
|
|
435
|
+
</figure>
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* An automation, read only: the agent's page is where it is switched and its runs opened. One
|
|
441
|
+
* that is not there (removed, renamed since) says so quietly.
|
|
442
|
+
*/
|
|
443
|
+
function AutomationShown({ block }: { block: AutomationBlock }) {
|
|
444
|
+
const part = useParts();
|
|
445
|
+
const { messages } = useKit();
|
|
446
|
+
// `null`: it is gone; missing: not filled in by the API, which a newer server always does.
|
|
447
|
+
if (block.view == null) {
|
|
448
|
+
return (
|
|
449
|
+
<p className={part("sc-automation", "sc-automation--gone")}>{messages.automation.gone}</p>
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
return <Automation automation={block.view} runs={block.view.runs} />;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* A button that sends its action, marked once it was the one pressed; or a link that opens its
|
|
457
|
+
* page apart (it stays usable on an older turn: it changes nothing here).
|
|
458
|
+
*/
|
|
459
|
+
function Pressable({ block }: { block: ButtonBlock }) {
|
|
460
|
+
const { active, answered, onAction } = useScope();
|
|
461
|
+
const { action, url, tone, label } = block;
|
|
462
|
+
if (url !== undefined) {
|
|
463
|
+
return https(url) ? (
|
|
464
|
+
<Button tone={tone} href={url}>
|
|
465
|
+
{label}
|
|
466
|
+
</Button>
|
|
467
|
+
) : null;
|
|
468
|
+
}
|
|
469
|
+
if (action === undefined) return null;
|
|
470
|
+
const done = answered?.name === action && answered.label === label;
|
|
471
|
+
return (
|
|
472
|
+
<Button
|
|
473
|
+
tone={tone}
|
|
474
|
+
icon={done ? CheckIcon : undefined}
|
|
475
|
+
pressed={done}
|
|
476
|
+
disabled={!active}
|
|
477
|
+
onClick={() => onAction(pressed({ ...block, action }))}
|
|
478
|
+
>
|
|
479
|
+
{label}
|
|
480
|
+
</Button>
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/** A few options to pick one of at once; the one picked keeps a ring and a check. */
|
|
485
|
+
function Choice({ block }: { block: ChoiceBlock }) {
|
|
486
|
+
const { active, answered, onAction } = useScope();
|
|
487
|
+
const part = useSurfaceParts();
|
|
488
|
+
const mine = answered?.name === block.action ? answered.data : undefined;
|
|
489
|
+
const chosenId = mine?.option;
|
|
490
|
+
const listed =
|
|
491
|
+
block.other === true ||
|
|
492
|
+
block.options.length > SHORT_CHOICE ||
|
|
493
|
+
block.options.some((option) => option.hint !== undefined || option.label.length > SHORT_LABEL);
|
|
494
|
+
return (
|
|
495
|
+
<div
|
|
496
|
+
role="group"
|
|
497
|
+
part="choice"
|
|
498
|
+
className={part(
|
|
499
|
+
"sc-surface__choice",
|
|
500
|
+
...(listed ? (["sc-surface__choice--list"] as const) : []),
|
|
501
|
+
)}
|
|
502
|
+
>
|
|
503
|
+
{block.options.map((option) => (
|
|
504
|
+
<button
|
|
505
|
+
key={option.id}
|
|
506
|
+
type="button"
|
|
507
|
+
disabled={!active}
|
|
508
|
+
aria-pressed={option.id === chosenId || undefined}
|
|
509
|
+
onClick={() => onAction(picked(block, option))}
|
|
510
|
+
part="option"
|
|
511
|
+
className={part("sc-surface__option")}
|
|
512
|
+
>
|
|
513
|
+
<span>
|
|
514
|
+
{option.label}
|
|
515
|
+
{option.hint !== undefined && <small>{option.hint}</small>}
|
|
516
|
+
</span>
|
|
517
|
+
{option.id === chosenId && <CheckIcon aria-hidden weight="bold" />}
|
|
518
|
+
</button>
|
|
519
|
+
))}
|
|
520
|
+
{block.other === true && (
|
|
521
|
+
<Other
|
|
522
|
+
active={active}
|
|
523
|
+
said={typeof mine?.text === "string" ? mine.text : undefined}
|
|
524
|
+
onSay={(text) => onAction(answeredIn(block, text))}
|
|
525
|
+
/>
|
|
526
|
+
)}
|
|
527
|
+
</div>
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/** Pills fit options this few and this short; more, longer or with a hint, they go one a row. */
|
|
532
|
+
const SHORT_CHOICE = 4;
|
|
533
|
+
const SHORT_LABEL = 28;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* A choice's last row, to answer in one's own words: pressed, it turns into a box with its send
|
|
537
|
+
* (Enter sends, Escape folds it back). Once said, the words stand in it, chosen.
|
|
538
|
+
*/
|
|
539
|
+
function Other({
|
|
540
|
+
active,
|
|
541
|
+
said,
|
|
542
|
+
onSay,
|
|
543
|
+
}: {
|
|
544
|
+
active: boolean;
|
|
545
|
+
said: string | undefined;
|
|
546
|
+
onSay: (text: string) => void;
|
|
547
|
+
}) {
|
|
548
|
+
const part = useSurfaceParts();
|
|
549
|
+
const { messages } = useKit();
|
|
550
|
+
const [writing, setWriting] = useState(false);
|
|
551
|
+
const [text, setText] = useState("");
|
|
552
|
+
if (said !== undefined || !writing) {
|
|
553
|
+
return (
|
|
554
|
+
<button
|
|
555
|
+
type="button"
|
|
556
|
+
disabled={!active}
|
|
557
|
+
aria-pressed={said !== undefined || undefined}
|
|
558
|
+
onClick={() => setWriting(true)}
|
|
559
|
+
part="option other"
|
|
560
|
+
className={part("sc-surface__option", "sc-surface__option--other")}
|
|
561
|
+
>
|
|
562
|
+
{said === undefined && <PencilSimpleIcon aria-hidden />}
|
|
563
|
+
<span>{said ?? messages.other}</span>
|
|
564
|
+
{said !== undefined && <CheckIcon aria-hidden weight="bold" />}
|
|
565
|
+
</button>
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
const send = () => {
|
|
569
|
+
const words = text.trim();
|
|
570
|
+
if (words !== "") onSay(words);
|
|
571
|
+
};
|
|
572
|
+
return (
|
|
573
|
+
<form
|
|
574
|
+
part="other"
|
|
575
|
+
className={part("sc-surface__other")}
|
|
576
|
+
onSubmit={(event) => {
|
|
577
|
+
event.preventDefault();
|
|
578
|
+
send();
|
|
579
|
+
}}
|
|
580
|
+
>
|
|
581
|
+
<input
|
|
582
|
+
// A person who pressed to write wants to write.
|
|
583
|
+
autoFocus
|
|
584
|
+
value={text}
|
|
585
|
+
aria-label={messages.other}
|
|
586
|
+
placeholder={messages.otherPlaceholder}
|
|
587
|
+
onChange={(event) => setText(event.target.value)}
|
|
588
|
+
onKeyDown={(event) => {
|
|
589
|
+
if (event.key === "Escape") {
|
|
590
|
+
event.stopPropagation();
|
|
591
|
+
setWriting(false);
|
|
592
|
+
}
|
|
593
|
+
}}
|
|
594
|
+
/>
|
|
595
|
+
<button type="submit" aria-label={messages.send} disabled={text.trim() === ""}>
|
|
596
|
+
<ArrowUpIcon aria-hidden weight="bold" />
|
|
597
|
+
</button>
|
|
598
|
+
</form>
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/** Only an https address is loaded or opened: never a script, never a local file. */
|
|
603
|
+
function https(url: string): boolean {
|
|
604
|
+
return /^https:\/\//i.test(url);
|
|
605
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createContext, useContext, type ComponentType, type ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import type { Block } from "../blocks";
|
|
4
|
+
import { classes } from "../classes";
|
|
5
|
+
import type { KitPart } from "../kit/context";
|
|
6
|
+
import type { FileHost } from "../kit/uploads";
|
|
7
|
+
import type { SurfaceAction } from "./values";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The surface's own parts, by the class each carries: the blocks that are not a kit primitive,
|
|
11
|
+
* and the form's layout. `classNames` takes these and the kit's (`KitPart`) under the same keys.
|
|
12
|
+
*/
|
|
13
|
+
export type SurfacePart =
|
|
14
|
+
| "sc-surface"
|
|
15
|
+
| "sc-surface__stack"
|
|
16
|
+
| "sc-surface__stack--row"
|
|
17
|
+
| "sc-surface__divider"
|
|
18
|
+
| "sc-surface__text"
|
|
19
|
+
| "sc-surface__fields"
|
|
20
|
+
| "sc-surface__table"
|
|
21
|
+
| "sc-surface__image"
|
|
22
|
+
| "sc-surface__media"
|
|
23
|
+
| "sc-surface__choice"
|
|
24
|
+
| "sc-surface__choice--list"
|
|
25
|
+
| "sc-surface__option"
|
|
26
|
+
| "sc-surface__option--other"
|
|
27
|
+
| "sc-surface__other"
|
|
28
|
+
| "sc-surface__form"
|
|
29
|
+
| "sc-surface__submit"
|
|
30
|
+
| "sc-surface__foot"
|
|
31
|
+
| "sc-surface__sent";
|
|
32
|
+
|
|
33
|
+
export type SurfaceClassNames = Partial<Record<SurfacePart | KitPart, string>> | undefined;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* What a host's component for a block type receives: the block itself, whether the surface still
|
|
37
|
+
* takes input, and `onAction` to send what the person did; a container's `children` come drawn.
|
|
38
|
+
*/
|
|
39
|
+
export type BlockProps<Type extends Block["type"]> = Omit<
|
|
40
|
+
Extract<Block, { type: Type }>,
|
|
41
|
+
"children"
|
|
42
|
+
> &
|
|
43
|
+
(Extract<Block, { type: Type }> extends { children: Block[] }
|
|
44
|
+
? { children: ReactNode }
|
|
45
|
+
: unknown) & {
|
|
46
|
+
active: boolean;
|
|
47
|
+
onAction: (action: SurfaceAction) => void;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** The host's own drawing of a block type, in place of the package's: `{ table: TheirTable }`. */
|
|
51
|
+
export type SurfaceComponents = { [Type in Block["type"]]?: ComponentType<BlockProps<Type>> };
|
|
52
|
+
|
|
53
|
+
/** What every block of one surface shares: whether it takes input, what was done on it. */
|
|
54
|
+
export interface Scope {
|
|
55
|
+
active: boolean;
|
|
56
|
+
/** What the person already did on the surface. */
|
|
57
|
+
answered: SurfaceAction | undefined;
|
|
58
|
+
onAction: (action: SurfaceAction) => void;
|
|
59
|
+
components: SurfaceComponents | undefined;
|
|
60
|
+
classNames: SurfaceClassNames;
|
|
61
|
+
/** Where its file fields' files go and are found; none: they take none. */
|
|
62
|
+
files: FileHost | undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const ScopeContext = createContext<Scope>({
|
|
66
|
+
active: false,
|
|
67
|
+
answered: undefined,
|
|
68
|
+
onAction: () => undefined,
|
|
69
|
+
components: undefined,
|
|
70
|
+
classNames: undefined,
|
|
71
|
+
files: undefined,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export function useScope(): Scope {
|
|
75
|
+
return useContext(ScopeContext);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The classes of the surface's own parts, with the host's own under each. */
|
|
79
|
+
export function useSurfaceParts(): (...parts: SurfacePart[]) => string {
|
|
80
|
+
const { classNames } = useScope();
|
|
81
|
+
return (...parts) => classes(classNames, ...parts);
|
|
82
|
+
}
|