@signalwire/web-components 4.0.0-beta.10 → 4.0.0-beta.12

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.
Files changed (352) hide show
  1. package/README.md +48 -55
  2. package/dist/_virtual/_commonjsHelpers.js +9 -0
  3. package/dist/_virtual/_commonjsHelpers.js.map +1 -0
  4. package/dist/_virtual/prism-python.js +28 -0
  5. package/dist/_virtual/prism-python.js.map +1 -0
  6. package/dist/_virtual/prism-python2.js +5 -0
  7. package/dist/_virtual/prism-python2.js.map +1 -0
  8. package/dist/_virtual/prism-typescript.js +28 -0
  9. package/dist/_virtual/prism-typescript.js.map +1 -0
  10. package/dist/_virtual/prism-typescript2.js +5 -0
  11. package/dist/_virtual/prism-typescript2.js.map +1 -0
  12. package/dist/_virtual/prism.js +28 -0
  13. package/dist/_virtual/prism.js.map +1 -0
  14. package/dist/_virtual/prism2.js +5 -0
  15. package/dist/_virtual/prism2.js.map +1 -0
  16. package/dist/assets/sw_background.webp.js +5 -0
  17. package/dist/assets/sw_background.webp.js.map +1 -0
  18. package/dist/components/UI/DEFAULT_BACKGROUND.d.ts +4 -0
  19. package/dist/components/UI/DEFAULT_BACKGROUND.d.ts.map +1 -0
  20. package/dist/components/UI/DEFAULT_BACKGROUND.js +5 -0
  21. package/dist/components/UI/DEFAULT_BACKGROUND.js.map +1 -0
  22. package/dist/components/UI/controls/sw-ui-control-bar.d.ts +114 -0
  23. package/dist/components/UI/controls/sw-ui-control-bar.d.ts.map +1 -0
  24. package/dist/components/UI/controls/sw-ui-control-bar.js +324 -0
  25. package/dist/components/UI/controls/sw-ui-control-bar.js.map +1 -0
  26. package/dist/components/UI/controls/sw-ui-dialpad.d.ts +67 -0
  27. package/dist/components/UI/controls/sw-ui-dialpad.d.ts.map +1 -0
  28. package/dist/components/UI/controls/sw-ui-dialpad.js +359 -0
  29. package/dist/components/UI/controls/sw-ui-dialpad.js.map +1 -0
  30. package/dist/components/UI/controls/sw-ui-dropup.d.ts +42 -0
  31. package/dist/components/UI/controls/sw-ui-dropup.d.ts.map +1 -0
  32. package/dist/components/UI/controls/sw-ui-dropup.js +137 -0
  33. package/dist/components/UI/controls/sw-ui-dropup.js.map +1 -0
  34. package/dist/components/UI/controls/sw-ui-split-button.d.ts +44 -0
  35. package/dist/components/UI/controls/sw-ui-split-button.d.ts.map +1 -0
  36. package/dist/components/UI/controls/sw-ui-split-button.js +177 -0
  37. package/dist/components/UI/controls/sw-ui-split-button.js.map +1 -0
  38. package/dist/components/UI/icons/backspace.svg.js +10 -0
  39. package/dist/components/UI/icons/backspace.svg.js.map +1 -0
  40. package/dist/components/UI/icons/camera-off.svg.js +8 -0
  41. package/dist/components/UI/icons/camera-off.svg.js.map +1 -0
  42. package/dist/components/UI/icons/camera-on.svg.js +8 -0
  43. package/dist/components/UI/icons/camera-on.svg.js.map +1 -0
  44. package/dist/components/UI/icons/check-circle.svg.js +6 -0
  45. package/dist/components/UI/icons/check-circle.svg.js.map +1 -0
  46. package/dist/components/UI/icons/chevron-up.svg.js +8 -0
  47. package/dist/components/UI/icons/chevron-up.svg.js.map +1 -0
  48. package/dist/components/UI/icons/close.svg.js +6 -0
  49. package/dist/components/UI/icons/close.svg.js.map +1 -0
  50. package/dist/components/UI/icons/copy.svg.js +6 -0
  51. package/dist/components/UI/icons/copy.svg.js.map +1 -0
  52. package/dist/components/UI/icons/download.svg.js +6 -0
  53. package/dist/components/UI/icons/download.svg.js.map +1 -0
  54. package/dist/components/UI/icons/fullscreen-exit.svg.js +8 -0
  55. package/dist/components/UI/icons/fullscreen-exit.svg.js.map +1 -0
  56. package/dist/components/UI/icons/fullscreen.svg.js +8 -0
  57. package/dist/components/UI/icons/fullscreen.svg.js.map +1 -0
  58. package/dist/components/UI/icons/hand-raise.svg.js +6 -0
  59. package/dist/components/UI/icons/hand-raise.svg.js.map +1 -0
  60. package/dist/components/UI/icons/icons.d.ts +31 -0
  61. package/dist/components/UI/icons/icons.d.ts.map +1 -0
  62. package/dist/components/UI/icons/icons.js +60 -0
  63. package/dist/components/UI/icons/icons.js.map +1 -0
  64. package/dist/components/UI/icons/index.d.ts +4 -0
  65. package/dist/components/UI/icons/index.d.ts.map +1 -0
  66. package/dist/components/UI/icons/info-circle.svg.js +6 -0
  67. package/dist/components/UI/icons/info-circle.svg.js.map +1 -0
  68. package/dist/components/UI/icons/mic-off.svg.js +8 -0
  69. package/dist/components/UI/icons/mic-off.svg.js.map +1 -0
  70. package/dist/components/UI/icons/mic-on.svg.js +8 -0
  71. package/dist/components/UI/icons/mic-on.svg.js.map +1 -0
  72. package/dist/components/UI/icons/person.svg.js +8 -0
  73. package/dist/components/UI/icons/person.svg.js.map +1 -0
  74. package/dist/components/UI/icons/phone-call.svg.js +8 -0
  75. package/dist/components/UI/icons/phone-call.svg.js.map +1 -0
  76. package/dist/components/UI/icons/phone-end.svg.js +8 -0
  77. package/dist/components/UI/icons/phone-end.svg.js.map +1 -0
  78. package/dist/components/UI/icons/room.svg.js +8 -0
  79. package/dist/components/UI/icons/room.svg.js.map +1 -0
  80. package/dist/components/UI/icons/screen-share-off.svg.js +9 -0
  81. package/dist/components/UI/icons/screen-share-off.svg.js.map +1 -0
  82. package/dist/components/UI/icons/screen-share.svg.js +9 -0
  83. package/dist/components/UI/icons/screen-share.svg.js.map +1 -0
  84. package/dist/components/UI/icons/sendIcon.svg.js +9 -0
  85. package/dist/components/UI/icons/sendIcon.svg.js.map +1 -0
  86. package/dist/components/UI/icons/settings.svg.js +8 -0
  87. package/dist/components/UI/icons/settings.svg.js.map +1 -0
  88. package/dist/components/UI/icons/speaker-off.svg.js +8 -0
  89. package/dist/components/UI/icons/speaker-off.svg.js.map +1 -0
  90. package/dist/components/UI/icons/speaker-on.svg.js +8 -0
  91. package/dist/components/UI/icons/speaker-on.svg.js.map +1 -0
  92. package/dist/components/UI/icons/spinner.svg.js +9 -0
  93. package/dist/components/UI/icons/spinner.svg.js.map +1 -0
  94. package/dist/components/UI/icons/sw-logo.svg.js +11 -0
  95. package/dist/components/UI/icons/sw-logo.svg.js.map +1 -0
  96. package/dist/components/UI/icons/sw-ui-icon.d.ts +28 -0
  97. package/dist/components/UI/icons/sw-ui-icon.d.ts.map +1 -0
  98. package/dist/components/UI/icons/sw-ui-icon.js +47 -0
  99. package/dist/components/UI/icons/sw-ui-icon.js.map +1 -0
  100. package/dist/components/UI/icons/transcript.svg.js +10 -0
  101. package/dist/components/UI/icons/transcript.svg.js.map +1 -0
  102. package/dist/components/UI/index.d.ts +18 -0
  103. package/dist/components/UI/index.d.ts.map +1 -0
  104. package/dist/components/UI/layout/sw-ui-background.d.ts +33 -0
  105. package/dist/components/UI/layout/sw-ui-background.d.ts.map +1 -0
  106. package/dist/components/UI/layout/sw-ui-background.js +106 -0
  107. package/dist/components/UI/layout/sw-ui-background.js.map +1 -0
  108. package/dist/components/UI/layout/sw-ui-call-layout.d.ts +69 -0
  109. package/dist/components/UI/layout/sw-ui-call-layout.d.ts.map +1 -0
  110. package/dist/components/UI/layout/sw-ui-call-layout.js +278 -0
  111. package/dist/components/UI/layout/sw-ui-call-layout.js.map +1 -0
  112. package/dist/components/UI/layout/sw-ui-content-drawer.d.ts +50 -0
  113. package/dist/components/UI/layout/sw-ui-content-drawer.d.ts.map +1 -0
  114. package/dist/components/UI/layout/sw-ui-content-drawer.js +413 -0
  115. package/dist/components/UI/layout/sw-ui-content-drawer.js.map +1 -0
  116. package/dist/components/UI/layout/sw-ui-modal.d.ts +31 -0
  117. package/dist/components/UI/layout/sw-ui-modal.d.ts.map +1 -0
  118. package/dist/components/UI/layout/sw-ui-modal.js +150 -0
  119. package/dist/components/UI/layout/sw-ui-modal.js.map +1 -0
  120. package/dist/components/UI/layout/sw-ui-responsive-container.d.ts +15 -0
  121. package/dist/components/UI/layout/sw-ui-responsive-container.d.ts.map +1 -0
  122. package/dist/components/UI/layout/sw-ui-responsive-container.js +78 -0
  123. package/dist/components/UI/layout/sw-ui-responsive-container.js.map +1 -0
  124. package/dist/components/UI/sw-ui-alert.d.ts +37 -0
  125. package/dist/components/UI/sw-ui-alert.d.ts.map +1 -0
  126. package/dist/components/UI/sw-ui-alert.js +126 -0
  127. package/dist/components/UI/sw-ui-alert.js.map +1 -0
  128. package/dist/components/UI/sw-ui-transcript-view.d.ts +56 -0
  129. package/dist/components/UI/sw-ui-transcript-view.d.ts.map +1 -0
  130. package/dist/components/UI/sw-ui-transcript-view.js +341 -0
  131. package/dist/components/UI/sw-ui-transcript-view.js.map +1 -0
  132. package/dist/components/{audio-level.d.ts → sw-audio-level.d.ts} +44 -4
  133. package/dist/components/sw-audio-level.d.ts.map +1 -0
  134. package/dist/components/sw-audio-level.js +252 -0
  135. package/dist/components/sw-audio-level.js.map +1 -0
  136. package/dist/components/sw-call-controls.d.ts +58 -0
  137. package/dist/components/sw-call-controls.d.ts.map +1 -0
  138. package/dist/components/sw-call-controls.js +186 -0
  139. package/dist/components/sw-call-controls.js.map +1 -0
  140. package/dist/components/sw-call-dialpad.d.ts +52 -0
  141. package/dist/components/sw-call-dialpad.d.ts.map +1 -0
  142. package/dist/components/sw-call-dialpad.js +70 -0
  143. package/dist/components/sw-call-dialpad.js.map +1 -0
  144. package/dist/components/sw-call-media.d.ts +68 -0
  145. package/dist/components/sw-call-media.d.ts.map +1 -0
  146. package/dist/components/sw-call-media.js +220 -0
  147. package/dist/components/sw-call-media.js.map +1 -0
  148. package/dist/components/sw-call-provider.d.ts +41 -0
  149. package/dist/components/sw-call-provider.d.ts.map +1 -0
  150. package/dist/components/sw-call-provider.js +37 -0
  151. package/dist/components/sw-call-provider.js.map +1 -0
  152. package/dist/components/sw-call-status.d.ts +50 -0
  153. package/dist/components/sw-call-status.d.ts.map +1 -0
  154. package/dist/components/sw-call-status.js +203 -0
  155. package/dist/components/sw-call-status.js.map +1 -0
  156. package/dist/components/sw-call-widget/client-factory.d.ts +6 -0
  157. package/dist/components/sw-call-widget/client-factory.d.ts.map +1 -0
  158. package/dist/components/sw-call-widget/client-factory.js +25 -0
  159. package/dist/components/sw-call-widget/client-factory.js.map +1 -0
  160. package/dist/components/sw-call-widget/sw-call-widget.d.ts +110 -0
  161. package/dist/components/sw-call-widget/sw-call-widget.d.ts.map +1 -0
  162. package/dist/components/sw-call-widget/sw-call-widget.js +250 -0
  163. package/dist/components/sw-call-widget/sw-call-widget.js.map +1 -0
  164. package/dist/components/sw-call-widget/sw-call-widget.templates.d.ts +17 -0
  165. package/dist/components/sw-call-widget/sw-call-widget.templates.d.ts.map +1 -0
  166. package/dist/components/sw-call-widget/sw-call-widget.templates.js +80 -0
  167. package/dist/components/sw-call-widget/sw-call-widget.templates.js.map +1 -0
  168. package/dist/components/sw-click-to-call.d.ts +39 -0
  169. package/dist/components/sw-click-to-call.d.ts.map +1 -0
  170. package/dist/components/sw-click-to-call.js +87 -0
  171. package/dist/components/sw-click-to-call.js.map +1 -0
  172. package/dist/components/sw-device-selector/index.d.ts +2 -0
  173. package/dist/components/sw-device-selector/index.d.ts.map +1 -0
  174. package/dist/components/sw-device-selector/sw-device-selector.d.ts +69 -0
  175. package/dist/components/sw-device-selector/sw-device-selector.d.ts.map +1 -0
  176. package/dist/components/sw-device-selector/sw-device-selector.js +277 -0
  177. package/dist/components/sw-device-selector/sw-device-selector.js.map +1 -0
  178. package/dist/components/sw-device-selector/sw-device-selector.styles.d.ts +2 -0
  179. package/dist/components/sw-device-selector/sw-device-selector.styles.d.ts.map +1 -0
  180. package/dist/components/sw-device-selector/sw-device-selector.styles.js +238 -0
  181. package/dist/components/sw-device-selector/sw-device-selector.styles.js.map +1 -0
  182. package/dist/components/{directory.d.ts → sw-directory.d.ts} +17 -3
  183. package/dist/components/sw-directory.d.ts.map +1 -0
  184. package/dist/components/sw-directory.js +434 -0
  185. package/dist/components/sw-directory.js.map +1 -0
  186. package/dist/components/sw-local-camera.d.ts +53 -0
  187. package/dist/components/sw-local-camera.d.ts.map +1 -0
  188. package/dist/components/sw-local-camera.js +147 -0
  189. package/dist/components/sw-local-camera.js.map +1 -0
  190. package/dist/components/sw-participant-controls.d.ts +58 -0
  191. package/dist/components/sw-participant-controls.d.ts.map +1 -0
  192. package/dist/components/sw-participant-controls.js +305 -0
  193. package/dist/components/sw-participant-controls.js.map +1 -0
  194. package/dist/components/sw-participants.d.ts +55 -0
  195. package/dist/components/sw-participants.d.ts.map +1 -0
  196. package/dist/components/sw-participants.js +319 -0
  197. package/dist/components/sw-participants.js.map +1 -0
  198. package/dist/components/sw-self-media.d.ts +46 -0
  199. package/dist/components/sw-self-media.d.ts.map +1 -0
  200. package/dist/components/sw-self-media.js +106 -0
  201. package/dist/components/sw-self-media.js.map +1 -0
  202. package/dist/context/CallStateContextController.d.ts +31 -0
  203. package/dist/context/CallStateContextController.d.ts.map +1 -0
  204. package/dist/context/CallStateContextController.js +125 -0
  205. package/dist/context/CallStateContextController.js.map +1 -0
  206. package/dist/context/DevicesContextController.d.ts +38 -0
  207. package/dist/context/DevicesContextController.d.ts.map +1 -0
  208. package/dist/context/DevicesContextController.js +124 -0
  209. package/dist/context/DevicesContextController.js.map +1 -0
  210. package/dist/context/TranscriptController.d.ts +32 -0
  211. package/dist/context/TranscriptController.d.ts.map +1 -0
  212. package/dist/context/TranscriptController.js +113 -0
  213. package/dist/context/TranscriptController.js.map +1 -0
  214. package/dist/context/UserEventController.d.ts +26 -0
  215. package/dist/context/UserEventController.d.ts.map +1 -0
  216. package/dist/context/UserEventController.js +55 -0
  217. package/dist/context/UserEventController.js.map +1 -0
  218. package/dist/context/call-state-context.d.ts +75 -0
  219. package/dist/context/call-state-context.d.ts.map +1 -0
  220. package/dist/context/call-state-context.js +39 -0
  221. package/dist/context/call-state-context.js.map +1 -0
  222. package/dist/context/chat-state.d.ts +41 -0
  223. package/dist/context/chat-state.d.ts.map +1 -0
  224. package/dist/context/chat-state.js +61 -0
  225. package/dist/context/chat-state.js.map +1 -0
  226. package/dist/context/devices-context.d.ts +28 -0
  227. package/dist/context/devices-context.d.ts.map +1 -0
  228. package/dist/context/devices-context.js +6 -0
  229. package/dist/context/devices-context.js.map +1 -0
  230. package/dist/context/index.d.ts +9 -1
  231. package/dist/context/index.d.ts.map +1 -1
  232. package/dist/context/transcript-context.d.ts +9 -0
  233. package/dist/context/transcript-context.d.ts.map +1 -0
  234. package/dist/context/transcript-context.js +6 -0
  235. package/dist/context/transcript-context.js.map +1 -0
  236. package/dist/context/types.d.ts +9 -0
  237. package/dist/context/types.d.ts.map +1 -0
  238. package/dist/embed/signalwire-web-components-embed.iife.js +3225 -0
  239. package/dist/embed/signalwire-web-components-embed.iife.js.map +1 -0
  240. package/dist/embed/signalwire-web-components-embed.umd.cjs +3225 -0
  241. package/dist/embed/signalwire-web-components-embed.umd.cjs.map +1 -0
  242. package/dist/embed.d.ts +20 -0
  243. package/dist/embed.d.ts.map +1 -0
  244. package/dist/index.d.ts +19 -13
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +83 -34
  247. package/dist/index.js.map +1 -1
  248. package/dist/node_modules/dompurify/dist/purify.es.js +597 -0
  249. package/dist/node_modules/dompurify/dist/purify.es.js.map +1 -0
  250. package/dist/node_modules/marked/lib/marked.esm.js +1475 -0
  251. package/dist/node_modules/marked/lib/marked.esm.js.map +1 -0
  252. package/dist/node_modules/prismjs/components/prism-bash.js +220 -0
  253. package/dist/node_modules/prismjs/components/prism-bash.js.map +1 -0
  254. package/dist/node_modules/prismjs/components/prism-css.js +56 -0
  255. package/dist/node_modules/prismjs/components/prism-css.js.map +1 -0
  256. package/dist/node_modules/prismjs/components/prism-javascript.js +138 -0
  257. package/dist/node_modules/prismjs/components/prism-javascript.js.map +1 -0
  258. package/dist/node_modules/prismjs/components/prism-json.js +26 -0
  259. package/dist/node_modules/prismjs/components/prism-json.js.map +1 -0
  260. package/dist/node_modules/prismjs/components/prism-markdown.js +301 -0
  261. package/dist/node_modules/prismjs/components/prism-markdown.js.map +1 -0
  262. package/dist/node_modules/prismjs/components/prism-python.js +69 -0
  263. package/dist/node_modules/prismjs/components/prism-python.js.map +1 -0
  264. package/dist/node_modules/prismjs/components/prism-sql.js +34 -0
  265. package/dist/node_modules/prismjs/components/prism-sql.js.map +1 -0
  266. package/dist/node_modules/prismjs/components/prism-typescript.js +53 -0
  267. package/dist/node_modules/prismjs/components/prism-typescript.js.map +1 -0
  268. package/dist/node_modules/prismjs/components/prism-yaml.js +67 -0
  269. package/dist/node_modules/prismjs/components/prism-yaml.js.map +1 -0
  270. package/dist/node_modules/prismjs/prism.js +1165 -0
  271. package/dist/node_modules/prismjs/prism.js.map +1 -0
  272. package/dist/react.d.ts +96 -46
  273. package/dist/theme.css +451 -0
  274. package/dist/theme.css.js +5 -0
  275. package/dist/theme.css.js.map +1 -0
  276. package/dist/types/index.d.ts +9 -33
  277. package/dist/types/index.d.ts.map +1 -1
  278. package/dist/utils/index.d.ts +2 -0
  279. package/dist/utils/index.d.ts.map +1 -1
  280. package/dist/utils/prism.d.ts +4 -0
  281. package/dist/utils/prism.d.ts.map +1 -0
  282. package/dist/utils/prism.js +34 -0
  283. package/dist/utils/prism.js.map +1 -0
  284. package/dist/utils/theme-loader.d.ts +11 -0
  285. package/dist/utils/theme-loader.d.ts.map +1 -0
  286. package/dist/utils/theme-loader.js +17 -0
  287. package/dist/utils/theme-loader.js.map +1 -0
  288. package/dist/utils/transcriptToMarkdown.d.ts +14 -0
  289. package/dist/utils/transcriptToMarkdown.d.ts.map +1 -0
  290. package/dist/utils/transcriptToMarkdown.js +59 -0
  291. package/dist/utils/transcriptToMarkdown.js.map +1 -0
  292. package/dist/utils/use-google-font.d.ts +18 -0
  293. package/dist/utils/use-google-font.d.ts.map +1 -0
  294. package/dist/utils/use-google-font.js +12 -0
  295. package/dist/utils/use-google-font.js.map +1 -0
  296. package/dist/utils/user-variables.d.ts +20 -0
  297. package/dist/utils/user-variables.d.ts.map +1 -0
  298. package/dist/utils/user-variables.js +37 -0
  299. package/dist/utils/user-variables.js.map +1 -0
  300. package/package.json +104 -41
  301. package/dist/components/audio-level.d.ts.map +0 -1
  302. package/dist/components/audio-level.js +0 -203
  303. package/dist/components/audio-level.js.map +0 -1
  304. package/dist/components/call-controls.d.ts +0 -163
  305. package/dist/components/call-controls.d.ts.map +0 -1
  306. package/dist/components/call-controls.js +0 -606
  307. package/dist/components/call-controls.js.map +0 -1
  308. package/dist/components/call-media.d.ts +0 -114
  309. package/dist/components/call-media.d.ts.map +0 -1
  310. package/dist/components/call-media.js +0 -219
  311. package/dist/components/call-media.js.map +0 -1
  312. package/dist/components/call-status.d.ts +0 -68
  313. package/dist/components/call-status.d.ts.map +0 -1
  314. package/dist/components/call-status.js +0 -254
  315. package/dist/components/call-status.js.map +0 -1
  316. package/dist/components/click-to-call.d.ts +0 -123
  317. package/dist/components/click-to-call.d.ts.map +0 -1
  318. package/dist/components/click-to-call.js +0 -428
  319. package/dist/components/click-to-call.js.map +0 -1
  320. package/dist/components/device-selector.d.ts +0 -224
  321. package/dist/components/device-selector.d.ts.map +0 -1
  322. package/dist/components/device-selector.js +0 -685
  323. package/dist/components/device-selector.js.map +0 -1
  324. package/dist/components/dialpad.d.ts +0 -60
  325. package/dist/components/dialpad.d.ts.map +0 -1
  326. package/dist/components/dialpad.js +0 -372
  327. package/dist/components/dialpad.js.map +0 -1
  328. package/dist/components/directory.d.ts.map +0 -1
  329. package/dist/components/directory.js +0 -503
  330. package/dist/components/directory.js.map +0 -1
  331. package/dist/components/example-button.d.ts +0 -20
  332. package/dist/components/example-button.d.ts.map +0 -1
  333. package/dist/components/example-button.js +0 -74
  334. package/dist/components/example-button.js.map +0 -1
  335. package/dist/components/participant-controls.d.ts +0 -94
  336. package/dist/components/participant-controls.d.ts.map +0 -1
  337. package/dist/components/participant-controls.js +0 -468
  338. package/dist/components/participant-controls.js.map +0 -1
  339. package/dist/components/participants.d.ts +0 -116
  340. package/dist/components/participants.d.ts.map +0 -1
  341. package/dist/components/participants.js +0 -394
  342. package/dist/components/participants.js.map +0 -1
  343. package/dist/components/self-media.d.ts +0 -78
  344. package/dist/components/self-media.d.ts.map +0 -1
  345. package/dist/components/self-media.js +0 -129
  346. package/dist/components/self-media.js.map +0 -1
  347. package/dist/context/call-context.d.ts +0 -13
  348. package/dist/context/call-context.d.ts.map +0 -1
  349. package/dist/context/call-context.js +0 -6
  350. package/dist/context/call-context.js.map +0 -1
  351. package/dist/types/index.js +0 -12
  352. package/dist/types/index.js.map +0 -1
@@ -0,0 +1,277 @@
1
+ import { LitElement as v, nothing as l, html as n } from "lit";
2
+ import { property as p, state as c, customElement as m } from "lit/decorators.js";
3
+ import { getLogger as b } from "@signalwire/js";
4
+ import { deviceSelectorStyles as w } from "./sw-device-selector.styles.js";
5
+ var k = Object.defineProperty, I = Object.getOwnPropertyDescriptor, a = (e, i, t, s) => {
6
+ for (var o = s > 1 ? void 0 : s ? I(i, t) : i, h = e.length - 1, d; h >= 0; h--)
7
+ (d = e[h]) && (o = (s ? d(i, t, o) : d(o)) || o);
8
+ return s && o && k(i, t, o), o;
9
+ };
10
+ const u = b();
11
+ let r = class extends v {
12
+ constructor() {
13
+ super(...arguments), this.showPreview = !1, this._videoStream = null, this._audioStream = null, this._testingSpeaker = !1, this._audioIn = [], this._videoIn = [], this._audioOut = [], this._selAudioIn = null, this._selVideoIn = null, this._selAudioOut = null, this._open = !1, this._subs = [], this._onDocumentClick = (e) => {
14
+ e.composedPath().includes(this) || (this._open = !1);
15
+ };
16
+ }
17
+ connectedCallback() {
18
+ super.connectedCallback(), document.addEventListener("click", this._onDocumentClick), this._subscribe();
19
+ }
20
+ updated(e) {
21
+ super.updated(e), e.has("deviceController") && (this._unsubscribe(), this._subscribe());
22
+ }
23
+ disconnectedCallback() {
24
+ super.disconnectedCallback(), document.removeEventListener("click", this._onDocumentClick), this._unsubscribe(), this._stopVideoPreview(), this._stopAudioPreview(), this._stopTestTone();
25
+ }
26
+ willUpdate(e) {
27
+ if (!this.showPreview) {
28
+ (e.has("showPreview") || e.has("_open")) && (this._stopVideoPreview(), this._stopAudioPreview());
29
+ return;
30
+ }
31
+ const i = e.has("_open") && this._open, t = e.has("_open") && !this._open, s = e.has("_selVideoIn"), o = e.has("_selAudioIn");
32
+ if (t) {
33
+ this._stopVideoPreview(), this._stopAudioPreview(), this._stopTestTone();
34
+ return;
35
+ }
36
+ this._open && (i || s) && this._selVideoIn && this._startVideoPreview(this._selVideoIn.deviceId), this._open && (i || o) && this._selAudioIn && this._startAudioPreview(this._selAudioIn.deviceId);
37
+ }
38
+ // ── subscriptions ──────────────────────────────────────────────────
39
+ _subscribe() {
40
+ const e = this.deviceController;
41
+ e && (this._subs.push(e.audioInputDevices$.subscribe((i) => {
42
+ this._audioIn = i;
43
+ })), this._subs.push(e.videoInputDevices$.subscribe((i) => {
44
+ this._videoIn = i;
45
+ })), this._subs.push(e.audioOutputDevices$.subscribe((i) => {
46
+ this._audioOut = i;
47
+ })), e.selectedAudioInputDevice$ && this._subs.push(e.selectedAudioInputDevice$.subscribe((i) => {
48
+ this._selAudioIn = i;
49
+ })), e.selectedVideoInputDevice$ && this._subs.push(e.selectedVideoInputDevice$.subscribe((i) => {
50
+ this._selVideoIn = i;
51
+ })), e.selectedAudioOutputDevice$ && this._subs.push(e.selectedAudioOutputDevice$.subscribe((i) => {
52
+ this._selAudioOut = i;
53
+ })));
54
+ }
55
+ _unsubscribe() {
56
+ this._subs.forEach((e) => e.unsubscribe()), this._subs = [];
57
+ }
58
+ // ── handlers ──────────────────────────────────────────────────────
59
+ _toggle(e) {
60
+ e.stopPropagation(), this._open = !this._open;
61
+ }
62
+ _selectMic(e) {
63
+ var t, s;
64
+ const i = this._audioIn.find((o) => o.deviceId === e) ?? null;
65
+ this._selAudioIn = i, (s = (t = this.deviceController) == null ? void 0 : t.selectAudioInputDevice) == null || s.call(t, i), i && this._emitChange("microphone", i);
66
+ }
67
+ _selectCamera(e) {
68
+ var t, s;
69
+ const i = this._videoIn.find((o) => o.deviceId === e) ?? null;
70
+ this._selVideoIn = i, (s = (t = this.deviceController) == null ? void 0 : t.selectVideoInputDevice) == null || s.call(t, i), i && this._emitChange("camera", i);
71
+ }
72
+ _selectSpeaker(e) {
73
+ var t, s;
74
+ const i = this._audioOut.find((o) => o.deviceId === e) ?? null;
75
+ this._selAudioOut = i, (s = (t = this.deviceController) == null ? void 0 : t.selectAudioOutputDevice) == null || s.call(t, i), i && this._emitChange("speaker", i);
76
+ }
77
+ // ── preview streams ───────────────────────────────────────────────
78
+ async _startVideoPreview(e) {
79
+ this._stopVideoPreview();
80
+ try {
81
+ this._videoStream = await navigator.mediaDevices.getUserMedia({
82
+ video: { deviceId: { exact: e } }
83
+ });
84
+ } catch (i) {
85
+ u.error("sw-device-selector: failed to start camera preview", i), this._videoStream = null;
86
+ }
87
+ }
88
+ _stopVideoPreview() {
89
+ var e;
90
+ (e = this._videoStream) == null || e.getTracks().forEach((i) => i.stop()), this._videoStream = null;
91
+ }
92
+ async _startAudioPreview(e) {
93
+ this._stopAudioPreview();
94
+ try {
95
+ this._audioStream = await navigator.mediaDevices.getUserMedia({
96
+ audio: { deviceId: { exact: e } }
97
+ });
98
+ } catch (i) {
99
+ u.error("sw-device-selector: failed to start microphone preview", i), this._audioStream = null;
100
+ }
101
+ }
102
+ _stopAudioPreview() {
103
+ var e;
104
+ (e = this._audioStream) == null || e.getTracks().forEach((i) => i.stop()), this._audioStream = null;
105
+ }
106
+ async _testSpeaker() {
107
+ var t;
108
+ if (this._testingSpeaker) {
109
+ this._stopTestTone();
110
+ return;
111
+ }
112
+ const e = new Audio(r._TEST_TONE_DATA_URI);
113
+ e.loop = !0, this._testAudio = e;
114
+ const i = (t = this._selAudioOut) == null ? void 0 : t.deviceId;
115
+ if (i && typeof e.setSinkId == "function")
116
+ try {
117
+ await e.setSinkId(i);
118
+ } catch (s) {
119
+ u.error("sw-device-selector: setSinkId failed", s);
120
+ }
121
+ e.addEventListener("ended", () => this._stopTestTone());
122
+ try {
123
+ await e.play(), this._testingSpeaker = !0;
124
+ } catch (s) {
125
+ u.error("sw-device-selector: failed to play test tone", s), this._stopTestTone();
126
+ }
127
+ }
128
+ _stopTestTone() {
129
+ this._testAudio && (this._testAudio.pause(), this._testAudio.src = "", this._testAudio = void 0), this._testingSpeaker = !1;
130
+ }
131
+ _emitChange(e, i) {
132
+ this.dispatchEvent(new CustomEvent("sw-device-change", {
133
+ detail: { type: e, device: i },
134
+ bubbles: !0,
135
+ composed: !0
136
+ }));
137
+ }
138
+ // ── render helpers ────────────────────────────────────────────────
139
+ _renderSection(e, i, t, s, o, h) {
140
+ return n`
141
+ <div class="section">
142
+ <div class="section-header">
143
+ <sw-ui-icon name=${e} size="13"></sw-ui-icon>
144
+ <span>${i}</span>
145
+ </div>
146
+ ${t.length === 0 ? n`<div class="no-devices">No devices found</div>` : t.map((d, _) => n`
147
+ <div
148
+ class="device-item ${d.deviceId === s ? "selected" : ""}"
149
+ role="option"
150
+ aria-selected=${d.deviceId === s}
151
+ @click=${() => o(d.deviceId)}
152
+ >
153
+ <svg class="check" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
154
+ <path d="M6.5 12L2 7.5l1.4-1.4 3.1 3.1 5.6-5.6 1.4 1.4z" />
155
+ </svg>
156
+ <span class="device-label">${d.label || `Device ${_ + 1}`}</span>
157
+ </div>
158
+ `)}
159
+ ${h ?? l}
160
+ </div>
161
+ `;
162
+ }
163
+ _renderCameraPreview() {
164
+ return this.showPreview ? n`
165
+ <div class="preview preview-camera" part="preview-camera">
166
+ ${this._videoStream ? n`<sw-local-camera .stream=${this._videoStream} mirror></sw-local-camera>` : n`<div class="preview-empty">Starting camera…</div>`}
167
+ </div>
168
+ ` : null;
169
+ }
170
+ _renderMicPreview() {
171
+ return this.showPreview ? n`
172
+ <div class="preview preview-mic" part="preview-mic">
173
+ ${this._audioStream ? n`<sw-audio-level
174
+ .stream=${this._audioStream}
175
+ bars="9"
176
+ orientation="horizontal"
177
+ maxSize="22"
178
+ ></sw-audio-level>` : n`<div class="preview-empty">Starting microphone…</div>`}
179
+ </div>
180
+ ` : null;
181
+ }
182
+ _renderSpeakerPreview() {
183
+ return this.showPreview ? n`
184
+ <div class="preview preview-speaker" part="preview-speaker">
185
+ <button
186
+ class="test-speaker"
187
+ part="test-speaker-button"
188
+ ?disabled=${!this._selAudioOut}
189
+ @click=${(e) => {
190
+ e.stopPropagation(), this._testSpeaker();
191
+ }}
192
+ >
193
+ <sw-ui-icon name=${this._testingSpeaker ? "speaker-off" : "speaker-on"} size="14"></sw-ui-icon>
194
+ <span>${this._testingSpeaker ? "Stop test" : "Test speaker"}</span>
195
+ </button>
196
+ </div>
197
+ ` : null;
198
+ }
199
+ // ── render ─────────────────────────────────────────────────────────
200
+ render() {
201
+ var i, t, s;
202
+ const e = this._audioIn.length > 0 || this._videoIn.length > 0 || this._audioOut.length > 0;
203
+ return n`
204
+ ${this._open ? n`
205
+ <div
206
+ class="panel"
207
+ role="listbox"
208
+ @keydown=${(o) => {
209
+ o.key === "Escape" && (this._open = !1);
210
+ }}
211
+ >
212
+ ${this._renderSection("mic-on", "Microphone", this._audioIn, (i = this._selAudioIn) == null ? void 0 : i.deviceId, (o) => this._selectMic(o), this._renderMicPreview())}
213
+ ${this._renderSection("camera-on", "Camera", this._videoIn, (t = this._selVideoIn) == null ? void 0 : t.deviceId, (o) => this._selectCamera(o), this._renderCameraPreview())}
214
+ ${this._renderSection("speaker-on", "Speaker", this._audioOut, (s = this._selAudioOut) == null ? void 0 : s.deviceId, (o) => this._selectSpeaker(o), this._renderSpeakerPreview())}
215
+ </div>
216
+ ` : l}
217
+
218
+ <button
219
+ class="trigger"
220
+ aria-label="Device settings"
221
+ aria-expanded=${this._open}
222
+ aria-haspopup="listbox"
223
+ ?disabled=${!e}
224
+ @click=${this._toggle}
225
+ part="button"
226
+ >
227
+ <sw-ui-icon name="settings" size="22"></sw-ui-icon>
228
+ </button>
229
+ <span class="label">Devices</span>
230
+ `;
231
+ }
232
+ };
233
+ r.styles = w;
234
+ r._TEST_TONE_DATA_URI = "data:audio/wav;base64,UklGRrQEAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YZAEAACAh46Sl5qcm5mWko2HgXp1cGxqaWlsb3R5gIaNk5icnp2bl5OOiIJ8dnFtamhoam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamlo";
235
+ a([
236
+ p({ type: Object })
237
+ ], r.prototype, "deviceController", 2);
238
+ a([
239
+ p({ type: Boolean, reflect: !0, attribute: "show-preview" })
240
+ ], r.prototype, "showPreview", 2);
241
+ a([
242
+ c()
243
+ ], r.prototype, "_videoStream", 2);
244
+ a([
245
+ c()
246
+ ], r.prototype, "_audioStream", 2);
247
+ a([
248
+ c()
249
+ ], r.prototype, "_testingSpeaker", 2);
250
+ a([
251
+ c()
252
+ ], r.prototype, "_audioIn", 2);
253
+ a([
254
+ c()
255
+ ], r.prototype, "_videoIn", 2);
256
+ a([
257
+ c()
258
+ ], r.prototype, "_audioOut", 2);
259
+ a([
260
+ c()
261
+ ], r.prototype, "_selAudioIn", 2);
262
+ a([
263
+ c()
264
+ ], r.prototype, "_selVideoIn", 2);
265
+ a([
266
+ c()
267
+ ], r.prototype, "_selAudioOut", 2);
268
+ a([
269
+ c()
270
+ ], r.prototype, "_open", 2);
271
+ r = a([
272
+ m("sw-device-selector")
273
+ ], r);
274
+ export {
275
+ r as SwDeviceSelector
276
+ };
277
+ //# sourceMappingURL=sw-device-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-device-selector.js","sources":["../../../src/components/sw-device-selector/sw-device-selector.ts"],"sourcesContent":["import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { Subscription } from 'rxjs';\nimport type { DeviceController } from '@signalwire/js';\nimport { getLogger } from '@signalwire/js';\nimport type { IconName } from '../UI/icons/icons.js';\nimport { deviceSelectorStyles } from './sw-device-selector.styles.js';\nimport '../UI/icons/sw-ui-icon.js';\nimport '../sw-local-camera.js';\nimport '../sw-audio-level.js';\n\nconst logger = getLogger();\n\ntype AudioElementWithSinkId = HTMLAudioElement & {\n setSinkId?: (sinkId: string) => Promise<void>;\n};\n\n/**\n * Single-button device settings popover. Opens a panel above the button\n * with sections for Microphone, Camera, and Speaker selection.\n *\n * When `show-preview` is enabled, the open panel also renders a live\n * camera preview, a microphone level meter for the currently selected\n * input devices, and a \"Test speaker\" button that plays a short tone\n * through the selected output.\n *\n * @fires sw-device-change - User picked a device. Detail: `{ type: 'microphone'|'camera'|'speaker', device: MediaDeviceInfo }`.\n * @cssprop --ctrl-* - all primitive ctrl tokens\n */\n@customElement('sw-device-selector')\nexport class SwDeviceSelector extends LitElement {\n static styles = deviceSelectorStyles;\n\n @property({ type: Object }) deviceController?: DeviceController;\n\n /**\n * Render inline previews (camera video, mic level, speaker test) inside\n * each section while the panel is open. Streams are acquired only while\n * the panel is open and stopped when it closes.\n */\n @property({ type: Boolean, reflect: true, attribute: 'show-preview' })\n showPreview = false;\n\n @state() private _videoStream: MediaStream | null = null;\n @state() private _audioStream: MediaStream | null = null;\n @state() private _testingSpeaker = false;\n\n @state() private _audioIn: MediaDeviceInfo[] = [];\n @state() private _videoIn: MediaDeviceInfo[] = [];\n @state() private _audioOut: MediaDeviceInfo[] = [];\n @state() private _selAudioIn: MediaDeviceInfo | null = null;\n @state() private _selVideoIn: MediaDeviceInfo | null = null;\n @state() private _selAudioOut: MediaDeviceInfo | null = null;\n @state() private _open = false;\n\n private _subs: Subscription[] = [];\n\n private _onDocumentClick = (e: MouseEvent) => {\n if (!e.composedPath().includes(this)) this._open = false;\n };\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener('click', this._onDocumentClick);\n this._subscribe();\n }\n\n protected updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has('deviceController')) {\n this._unsubscribe();\n this._subscribe();\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('click', this._onDocumentClick);\n this._unsubscribe();\n this._stopVideoPreview();\n this._stopAudioPreview();\n this._stopTestTone();\n }\n\n protected willUpdate(changed: Map<string, unknown>): void {\n if (!this.showPreview) {\n if (changed.has('showPreview') || changed.has('_open')) {\n this._stopVideoPreview();\n this._stopAudioPreview();\n }\n return;\n }\n\n const opened = changed.has('_open') && this._open;\n const closed = changed.has('_open') && !this._open;\n const cameraChanged = changed.has('_selVideoIn');\n const micChanged = changed.has('_selAudioIn');\n\n if (closed) {\n this._stopVideoPreview();\n this._stopAudioPreview();\n this._stopTestTone();\n return;\n }\n\n if (this._open && (opened || cameraChanged) && this._selVideoIn) {\n this._startVideoPreview(this._selVideoIn.deviceId);\n }\n if (this._open && (opened || micChanged) && this._selAudioIn) {\n this._startAudioPreview(this._selAudioIn.deviceId);\n }\n }\n\n // ── subscriptions ──────────────────────────────────────────────────\n\n private _subscribe(): void {\n const dc = this.deviceController;\n if (!dc) return;\n\n this._subs.push(dc.audioInputDevices$.subscribe((d) => { this._audioIn = d; }));\n this._subs.push(dc.videoInputDevices$.subscribe((d) => { this._videoIn = d; }));\n this._subs.push(dc.audioOutputDevices$.subscribe((d) => { this._audioOut = d; }));\n\n if (dc.selectedAudioInputDevice$)\n this._subs.push(dc.selectedAudioInputDevice$.subscribe((d) => { this._selAudioIn = d; }));\n if (dc.selectedVideoInputDevice$)\n this._subs.push(dc.selectedVideoInputDevice$.subscribe((d) => { this._selVideoIn = d; }));\n if (dc.selectedAudioOutputDevice$)\n this._subs.push(dc.selectedAudioOutputDevice$.subscribe((d) => { this._selAudioOut = d; }));\n }\n\n private _unsubscribe(): void {\n this._subs.forEach((s) => s.unsubscribe());\n this._subs = [];\n }\n\n // ── handlers ──────────────────────────────────────────────────────\n\n private _toggle(e: Event) {\n e.stopPropagation();\n this._open = !this._open;\n }\n\n private _selectMic(deviceId: string) {\n const device = this._audioIn.find((d) => d.deviceId === deviceId) ?? null;\n this._selAudioIn = device;\n this.deviceController?.selectAudioInputDevice?.(device);\n if (device) this._emitChange('microphone', device);\n }\n\n private _selectCamera(deviceId: string) {\n const device = this._videoIn.find((d) => d.deviceId === deviceId) ?? null;\n this._selVideoIn = device;\n this.deviceController?.selectVideoInputDevice?.(device);\n if (device) this._emitChange('camera', device);\n }\n\n private _selectSpeaker(deviceId: string) {\n const device = this._audioOut.find((d) => d.deviceId === deviceId) ?? null;\n this._selAudioOut = device;\n this.deviceController?.selectAudioOutputDevice?.(device);\n if (device) this._emitChange('speaker', device);\n }\n\n // ── preview streams ───────────────────────────────────────────────\n\n private async _startVideoPreview(deviceId: string): Promise<void> {\n this._stopVideoPreview();\n try {\n this._videoStream = await navigator.mediaDevices.getUserMedia({\n video: { deviceId: { exact: deviceId } }\n });\n } catch (error) {\n logger.error('sw-device-selector: failed to start camera preview', error);\n this._videoStream = null;\n }\n }\n\n private _stopVideoPreview(): void {\n this._videoStream?.getTracks().forEach((t) => t.stop());\n this._videoStream = null;\n }\n\n private async _startAudioPreview(deviceId: string): Promise<void> {\n this._stopAudioPreview();\n try {\n this._audioStream = await navigator.mediaDevices.getUserMedia({\n audio: { deviceId: { exact: deviceId } }\n });\n } catch (error) {\n logger.error('sw-device-selector: failed to start microphone preview', error);\n this._audioStream = null;\n }\n }\n\n private _stopAudioPreview(): void {\n this._audioStream?.getTracks().forEach((t) => t.stop());\n this._audioStream = null;\n }\n\n // ── speaker test ──────────────────────────────────────────────────\n\n private static readonly _TEST_TONE_DATA_URI =\n 'data:audio/wav;base64,UklGRrQEAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YZAEAACAh46Sl5qcm5mWko2HgXp1cGxqaWlsb3R5gIaNk5icnp2bl5OOiIJ8dnFtamhoam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamloam1xdnyChI+VmZ2enZqXkoyGgHt1cG1qaGhrbnJ4foSLkZianp6cmZWQioR+eHJuamlo';\n\n private _testAudio?: AudioElementWithSinkId;\n\n private async _testSpeaker(): Promise<void> {\n if (this._testingSpeaker) {\n this._stopTestTone();\n return;\n }\n const audio = new Audio(SwDeviceSelector._TEST_TONE_DATA_URI) as AudioElementWithSinkId;\n audio.loop = true;\n this._testAudio = audio;\n\n const sinkId = this._selAudioOut?.deviceId;\n if (sinkId && typeof audio.setSinkId === 'function') {\n try {\n await audio.setSinkId(sinkId);\n } catch (error) {\n logger.error('sw-device-selector: setSinkId failed', error);\n }\n }\n audio.addEventListener('ended', () => this._stopTestTone());\n try {\n await audio.play();\n this._testingSpeaker = true;\n } catch (error) {\n logger.error('sw-device-selector: failed to play test tone', error);\n this._stopTestTone();\n }\n }\n\n private _stopTestTone(): void {\n if (this._testAudio) {\n this._testAudio.pause();\n this._testAudio.src = '';\n this._testAudio = undefined;\n }\n this._testingSpeaker = false;\n }\n\n private _emitChange(type: 'microphone' | 'camera' | 'speaker', device: MediaDeviceInfo) {\n this.dispatchEvent(new CustomEvent('sw-device-change', {\n detail: { type, device },\n bubbles: true,\n composed: true\n }));\n }\n\n // ── render helpers ────────────────────────────────────────────────\n\n private _renderSection(\n iconName: IconName,\n title: string,\n devices: MediaDeviceInfo[],\n selectedId: string | undefined,\n onSelect: (id: string) => void,\n preview?: unknown\n ) {\n return html`\n <div class=\"section\">\n <div class=\"section-header\">\n <sw-ui-icon name=${iconName} size=\"13\"></sw-ui-icon>\n <span>${title}</span>\n </div>\n ${devices.length === 0\n ? html`<div class=\"no-devices\">No devices found</div>`\n : devices.map((d, i) => html`\n <div\n class=\"device-item ${d.deviceId === selectedId ? 'selected' : ''}\"\n role=\"option\"\n aria-selected=${d.deviceId === selectedId}\n @click=${() => onSelect(d.deviceId)}\n >\n <svg class=\"check\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M6.5 12L2 7.5l1.4-1.4 3.1 3.1 5.6-5.6 1.4 1.4z\" />\n </svg>\n <span class=\"device-label\">${d.label || `Device ${i + 1}`}</span>\n </div>\n `)\n }\n ${preview ?? nothing}\n </div>\n `;\n }\n\n private _renderCameraPreview() {\n if (!this.showPreview) return null;\n return html`\n <div class=\"preview preview-camera\" part=\"preview-camera\">\n ${this._videoStream\n ? html`<sw-local-camera .stream=${this._videoStream} mirror></sw-local-camera>`\n : html`<div class=\"preview-empty\">Starting camera…</div>`}\n </div>\n `;\n }\n\n private _renderMicPreview() {\n if (!this.showPreview) return null;\n return html`\n <div class=\"preview preview-mic\" part=\"preview-mic\">\n ${this._audioStream\n ? html`<sw-audio-level\n .stream=${this._audioStream}\n bars=\"9\"\n orientation=\"horizontal\"\n maxSize=\"22\"\n ></sw-audio-level>`\n : html`<div class=\"preview-empty\">Starting microphone…</div>`}\n </div>\n `;\n }\n\n private _renderSpeakerPreview() {\n if (!this.showPreview) return null;\n return html`\n <div class=\"preview preview-speaker\" part=\"preview-speaker\">\n <button\n class=\"test-speaker\"\n part=\"test-speaker-button\"\n ?disabled=${!this._selAudioOut}\n @click=${(e: Event) => { e.stopPropagation(); this._testSpeaker(); }}\n >\n <sw-ui-icon name=${this._testingSpeaker ? 'speaker-off' : 'speaker-on'} size=\"14\"></sw-ui-icon>\n <span>${this._testingSpeaker ? 'Stop test' : 'Test speaker'}</span>\n </button>\n </div>\n `;\n }\n\n // ── render ─────────────────────────────────────────────────────────\n\n render() {\n const hasDevices = this._audioIn.length > 0 || this._videoIn.length > 0 || this._audioOut.length > 0;\n\n return html`\n ${this._open ? html`\n <div\n class=\"panel\"\n role=\"listbox\"\n @keydown=${(e: KeyboardEvent) => { if (e.key === 'Escape') this._open = false; }}\n >\n ${this._renderSection('mic-on', 'Microphone', this._audioIn, this._selAudioIn?.deviceId, (id) => this._selectMic(id), this._renderMicPreview())}\n ${this._renderSection('camera-on', 'Camera', this._videoIn, this._selVideoIn?.deviceId, (id) => this._selectCamera(id), this._renderCameraPreview())}\n ${this._renderSection('speaker-on', 'Speaker', this._audioOut, this._selAudioOut?.deviceId, (id) => this._selectSpeaker(id), this._renderSpeakerPreview())}\n </div>\n ` : nothing}\n\n <button\n class=\"trigger\"\n aria-label=\"Device settings\"\n aria-expanded=${this._open}\n aria-haspopup=\"listbox\"\n ?disabled=${!hasDevices}\n @click=${this._toggle}\n part=\"button\"\n >\n <sw-ui-icon name=\"settings\" size=\"22\"></sw-ui-icon>\n </button>\n <span class=\"label\">Devices</span>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-device-selector': SwDeviceSelector;\n }\n}\n"],"names":["logger","getLogger","SwDeviceSelector","LitElement","changed","opened","closed","cameraChanged","micChanged","dc","d","s","deviceId","device","_b","_a","error","t","audio","sinkId","type","iconName","title","devices","selectedId","onSelect","preview","html","i","nothing","hasDevices","e","id","_c","deviceSelectorStyles","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const deviceSelectorStyles: import("lit").CSSResult;
2
+ //# sourceMappingURL=sw-device-selector.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-device-selector.styles.d.ts","sourceRoot":"","sources":["../../../src/components/sw-device-selector/sw-device-selector.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,yBAwOhC,CAAC"}
@@ -0,0 +1,238 @@
1
+ import { css as e } from "lit";
2
+ const i = e`
3
+ :host {
4
+ display: inline-flex;
5
+ flex-direction: column;
6
+ align-items: center;
7
+ gap: 4px;
8
+ position: relative;
9
+
10
+ /* ctrl primitive defaults (overridden by parent theme) */
11
+ --sw-device-selector-size: 44px;
12
+ --sw-device-selector-radius: 50%;
13
+ --sw-device-selector-bg: rgba(255, 255, 255, 0.12);
14
+ --sw-device-selector-bg-hover: rgba(255, 255, 255, 0.22);
15
+ --sw-device-selector-fg: #ffffff;
16
+ --sw-device-selector-focus-ring: #044cf6;
17
+ --sw-device-selector-label-color: rgba(255, 255, 255, 0.55);
18
+ --sw-device-selector-label-size: 10px;
19
+ --sw-device-selector-menu-bg: #1e1e2e;
20
+ --sw-device-selector-menu-border: rgba(255, 255, 255, 0.14);
21
+ --sw-device-selector-menu-item-hover: rgba(255, 255, 255, 0.1);
22
+ --sw-device-selector-menu-item-active: rgba(4, 76, 246, 0.35);
23
+ --sw-device-selector-menu-radius: 10px;
24
+ --sw-device-selector-menu-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
25
+ }
26
+
27
+ /* ── trigger button ─────────────────────────────────────────────── */
28
+
29
+ .trigger {
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: center;
33
+ width: var(--sw-device-selector-size);
34
+ height: var(--sw-device-selector-size);
35
+ min-width: 36px;
36
+ min-height: 36px;
37
+ padding: 0;
38
+ background: var(--sw-device-selector-bg);
39
+ color: var(--sw-device-selector-fg);
40
+ border: none;
41
+ border-radius: var(--sw-device-selector-radius);
42
+ cursor: pointer;
43
+ transition: background 0.15s ease, transform 0.1s ease;
44
+ }
45
+
46
+ .trigger:hover:not(:disabled) {
47
+ background: var(--sw-device-selector-bg-hover);
48
+ }
49
+
50
+ .trigger[aria-expanded='true'] {
51
+ background: var(--sw-device-selector-bg-hover);
52
+ }
53
+
54
+ .trigger:active:not(:disabled) {
55
+ transform: scale(0.93);
56
+ }
57
+
58
+ .trigger:focus-visible {
59
+ outline: 2px solid var(--sw-device-selector-focus-ring);
60
+ outline-offset: 2px;
61
+ }
62
+
63
+ .trigger:disabled {
64
+ opacity: 0.38;
65
+ cursor: not-allowed;
66
+ }
67
+
68
+ .trigger sw-ui-icon {
69
+ flex-shrink: 0;
70
+ pointer-events: none;
71
+ }
72
+
73
+ .label {
74
+ font-size: var(--sw-device-selector-label-size);
75
+ color: var(--sw-device-selector-label-color);
76
+ white-space: nowrap;
77
+ user-select: none;
78
+ line-height: 1.2;
79
+ }
80
+
81
+ /* ── popover panel ──────────────────────────────────────────────── */
82
+
83
+ .panel {
84
+ position: absolute;
85
+ bottom: calc(100% + 8px);
86
+ left: 50%;
87
+ transform: translateX(-50%);
88
+ min-width: 240px;
89
+ max-width: 320px;
90
+ background: var(--sw-device-selector-menu-bg);
91
+ border: 1px solid var(--sw-device-selector-menu-border);
92
+ border-radius: var(--sw-device-selector-menu-radius);
93
+ box-shadow: var(--sw-device-selector-menu-shadow);
94
+ padding: 6px;
95
+ z-index: 9999;
96
+ animation: panel-in 0.1s ease-out;
97
+ }
98
+
99
+ @keyframes panel-in {
100
+ from { opacity: 0; transform: translateX(-50%) translateY(4px); }
101
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
102
+ }
103
+
104
+ /* ── sections ───────────────────────────────────────────────────── */
105
+
106
+ .section {
107
+ padding: 4px 0;
108
+ }
109
+
110
+ .section + .section {
111
+ border-top: 1px solid var(--sw-device-selector-menu-border);
112
+ margin-top: 4px;
113
+ padding-top: 8px;
114
+ }
115
+
116
+ .section-header {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 6px;
120
+ padding: 2px 8px 5px;
121
+ font-size: 11px;
122
+ font-weight: 600;
123
+ color: var(--sw-device-selector-label-color);
124
+ text-transform: uppercase;
125
+ letter-spacing: 0.05em;
126
+ user-select: none;
127
+ }
128
+
129
+ .section-header sw-ui-icon {
130
+ flex-shrink: 0;
131
+ }
132
+
133
+ /* ── device items ───────────────────────────────────────────────── */
134
+
135
+ .device-item {
136
+ display: flex;
137
+ align-items: center;
138
+ gap: 8px;
139
+ padding: 8px 10px;
140
+ border-radius: calc(var(--sw-device-selector-menu-radius) - 2px);
141
+ cursor: pointer;
142
+ font-size: 13px;
143
+ color: var(--sw-device-selector-fg);
144
+ transition: background 0.1s ease;
145
+ }
146
+
147
+ .device-item:hover {
148
+ background: var(--sw-device-selector-menu-item-hover);
149
+ }
150
+
151
+ .device-item.selected {
152
+ background: var(--sw-device-selector-menu-item-active);
153
+ }
154
+
155
+ .check {
156
+ width: 14px;
157
+ height: 14px;
158
+ flex-shrink: 0;
159
+ opacity: 0;
160
+ }
161
+
162
+ .device-item.selected .check {
163
+ opacity: 1;
164
+ }
165
+
166
+ .device-label {
167
+ overflow: hidden;
168
+ text-overflow: ellipsis;
169
+ white-space: nowrap;
170
+ }
171
+
172
+ .no-devices {
173
+ padding: 6px 10px;
174
+ font-size: 12px;
175
+ color: var(--sw-device-selector-label-color);
176
+ }
177
+
178
+ /* ── previews (show-preview mode) ───────────────────────────────── */
179
+
180
+ :host([show-preview]) .panel {
181
+ min-width: 280px;
182
+ }
183
+
184
+ .preview {
185
+ margin: 8px 4px 2px;
186
+ }
187
+
188
+ .preview-camera sw-local-camera {
189
+ display: block;
190
+ width: 100%;
191
+ border-radius: 6px;
192
+ overflow: hidden;
193
+ }
194
+
195
+ .preview-mic {
196
+ display: flex;
197
+ align-items: center;
198
+ justify-content: center;
199
+ padding: 6px 8px;
200
+ background: rgba(255, 255, 255, 0.04);
201
+ border-radius: 6px;
202
+ min-height: 28px;
203
+ }
204
+
205
+ .preview-empty {
206
+ padding: 8px 4px;
207
+ font-size: 12px;
208
+ color: var(--sw-device-selector-label-color);
209
+ text-align: center;
210
+ }
211
+
212
+ .test-speaker {
213
+ display: inline-flex;
214
+ align-items: center;
215
+ gap: 6px;
216
+ padding: 6px 10px;
217
+ background: var(--sw-device-selector-menu-item-hover);
218
+ color: var(--sw-device-selector-fg);
219
+ border: 1px solid var(--sw-device-selector-menu-border);
220
+ border-radius: 6px;
221
+ font-size: 12px;
222
+ cursor: pointer;
223
+ transition: background 0.1s ease;
224
+ }
225
+
226
+ .test-speaker:hover:not(:disabled) {
227
+ background: var(--sw-device-selector-menu-item-active);
228
+ }
229
+
230
+ .test-speaker:disabled {
231
+ opacity: 0.4;
232
+ cursor: not-allowed;
233
+ }
234
+ `;
235
+ export {
236
+ i as deviceSelectorStyles
237
+ };
238
+ //# sourceMappingURL=sw-device-selector.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-device-selector.styles.js","sources":["../../../src/components/sw-device-selector/sw-device-selector.styles.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const deviceSelectorStyles = css`\n :host {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n position: relative;\n\n /* ctrl primitive defaults (overridden by parent theme) */\n --sw-device-selector-size: 44px;\n --sw-device-selector-radius: 50%;\n --sw-device-selector-bg: rgba(255, 255, 255, 0.12);\n --sw-device-selector-bg-hover: rgba(255, 255, 255, 0.22);\n --sw-device-selector-fg: #ffffff;\n --sw-device-selector-focus-ring: #044cf6;\n --sw-device-selector-label-color: rgba(255, 255, 255, 0.55);\n --sw-device-selector-label-size: 10px;\n --sw-device-selector-menu-bg: #1e1e2e;\n --sw-device-selector-menu-border: rgba(255, 255, 255, 0.14);\n --sw-device-selector-menu-item-hover: rgba(255, 255, 255, 0.1);\n --sw-device-selector-menu-item-active: rgba(4, 76, 246, 0.35);\n --sw-device-selector-menu-radius: 10px;\n --sw-device-selector-menu-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);\n }\n\n /* ── trigger button ─────────────────────────────────────────────── */\n\n .trigger {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--sw-device-selector-size);\n height: var(--sw-device-selector-size);\n min-width: 36px;\n min-height: 36px;\n padding: 0;\n background: var(--sw-device-selector-bg);\n color: var(--sw-device-selector-fg);\n border: none;\n border-radius: var(--sw-device-selector-radius);\n cursor: pointer;\n transition: background 0.15s ease, transform 0.1s ease;\n }\n\n .trigger:hover:not(:disabled) {\n background: var(--sw-device-selector-bg-hover);\n }\n\n .trigger[aria-expanded='true'] {\n background: var(--sw-device-selector-bg-hover);\n }\n\n .trigger:active:not(:disabled) {\n transform: scale(0.93);\n }\n\n .trigger:focus-visible {\n outline: 2px solid var(--sw-device-selector-focus-ring);\n outline-offset: 2px;\n }\n\n .trigger:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n }\n\n .trigger sw-ui-icon {\n flex-shrink: 0;\n pointer-events: none;\n }\n\n .label {\n font-size: var(--sw-device-selector-label-size);\n color: var(--sw-device-selector-label-color);\n white-space: nowrap;\n user-select: none;\n line-height: 1.2;\n }\n\n /* ── popover panel ──────────────────────────────────────────────── */\n\n .panel {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n min-width: 240px;\n max-width: 320px;\n background: var(--sw-device-selector-menu-bg);\n border: 1px solid var(--sw-device-selector-menu-border);\n border-radius: var(--sw-device-selector-menu-radius);\n box-shadow: var(--sw-device-selector-menu-shadow);\n padding: 6px;\n z-index: 9999;\n animation: panel-in 0.1s ease-out;\n }\n\n @keyframes panel-in {\n from { opacity: 0; transform: translateX(-50%) translateY(4px); }\n to { opacity: 1; transform: translateX(-50%) translateY(0); }\n }\n\n /* ── sections ───────────────────────────────────────────────────── */\n\n .section {\n padding: 4px 0;\n }\n\n .section + .section {\n border-top: 1px solid var(--sw-device-selector-menu-border);\n margin-top: 4px;\n padding-top: 8px;\n }\n\n .section-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 8px 5px;\n font-size: 11px;\n font-weight: 600;\n color: var(--sw-device-selector-label-color);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n user-select: none;\n }\n\n .section-header sw-ui-icon {\n flex-shrink: 0;\n }\n\n /* ── device items ───────────────────────────────────────────────── */\n\n .device-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n border-radius: calc(var(--sw-device-selector-menu-radius) - 2px);\n cursor: pointer;\n font-size: 13px;\n color: var(--sw-device-selector-fg);\n transition: background 0.1s ease;\n }\n\n .device-item:hover {\n background: var(--sw-device-selector-menu-item-hover);\n }\n\n .device-item.selected {\n background: var(--sw-device-selector-menu-item-active);\n }\n\n .check {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n opacity: 0;\n }\n\n .device-item.selected .check {\n opacity: 1;\n }\n\n .device-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .no-devices {\n padding: 6px 10px;\n font-size: 12px;\n color: var(--sw-device-selector-label-color);\n }\n\n /* ── previews (show-preview mode) ───────────────────────────────── */\n\n :host([show-preview]) .panel {\n min-width: 280px;\n }\n\n .preview {\n margin: 8px 4px 2px;\n }\n\n .preview-camera sw-local-camera {\n display: block;\n width: 100%;\n border-radius: 6px;\n overflow: hidden;\n }\n\n .preview-mic {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px 8px;\n background: rgba(255, 255, 255, 0.04);\n border-radius: 6px;\n min-height: 28px;\n }\n\n .preview-empty {\n padding: 8px 4px;\n font-size: 12px;\n color: var(--sw-device-selector-label-color);\n text-align: center;\n }\n\n .test-speaker {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n background: var(--sw-device-selector-menu-item-hover);\n color: var(--sw-device-selector-fg);\n border: 1px solid var(--sw-device-selector-menu-border);\n border-radius: 6px;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.1s ease;\n }\n\n .test-speaker:hover:not(:disabled) {\n background: var(--sw-device-selector-menu-item-active);\n }\n\n .test-speaker:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n`;\n"],"names":["deviceSelectorStyles","css"],"mappings":";AAEO,MAAMA,IAAuBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;"}
@@ -8,9 +8,23 @@
8
8
  * ```html
9
9
  * <sw-directory .directory=${directory}></sw-directory>
10
10
  * ```
11
+ *
12
+ * @fires sw-address-select - Fired when an address is selected. Detail: `{ address: Address }`
13
+ * @fires sw-dial - Fired when the call button on an address is clicked. Detail: `{ address: Address, channel: string }`
14
+ *
15
+ * @cssprop [--interactive-button-primary-bg=#044ef4] - Primary brand color
16
+ * @cssprop [--interactive-button-primary-hover=#0342cf] - Primary color on hover
17
+ * @cssprop [--interactive-status-success=#22c55e] - Success/positive color
18
+ * @cssprop [--fg-default=#f0f0f4] - Primary text color
19
+ * @cssprop [--fg-muted=#a0a0aa] - Secondary/muted text color
20
+ * @cssprop [--bg-surface=#181a28] - Component background color
21
+ * @cssprop [--bg-surface-raised=#222436] - Background color on hover
22
+ * @cssprop [--interactive-dropdown-hover=#333338] - Background color on active/press
23
+ * @cssprop [--border-default=rgba(255,255,255,0.12)] - Border color
11
24
  */
12
25
  import { LitElement } from 'lit';
13
26
  import type { Observable } from 'rxjs';
27
+ import './UI/icons/sw-ui-icon.js';
14
28
  /**
15
29
  * Address type from SDK
16
30
  */
@@ -34,7 +48,7 @@ export interface DirectoryService {
34
48
  hasMore$?: Observable<boolean>;
35
49
  loadMore?(): Promise<void>;
36
50
  }
37
- export declare class DirectoryComponent extends LitElement {
51
+ export declare class SwDirectory extends LitElement {
38
52
  static styles: import("lit").CSSResult;
39
53
  /**
40
54
  * Directory service with addresses$ observable
@@ -97,7 +111,7 @@ export declare class DirectoryComponent extends LitElement {
97
111
  }
98
112
  declare global {
99
113
  interface HTMLElementTagNameMap {
100
- 'sw-directory': DirectoryComponent;
114
+ 'sw-directory': SwDirectory;
101
115
  }
102
116
  }
103
- //# sourceMappingURL=directory.d.ts.map
117
+ //# sourceMappingURL=sw-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-directory.d.ts","sourceRoot":"","sources":["../../src/components/sw-directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/B,QAAQ,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,qBACa,WAAY,SAAQ,UAAU;IACzC,MAAM,CAAC,MAAM,0BA+MX;IAEF;;OAEG;IAEH,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAE1C;;OAEG;IAEH,OAAO,CAAC,eAAe,CAAwB;IAE/C;;OAEG;IAEH,OAAO,CAAC,WAAW,CAAc;IAEjC;;OAEG;IAEH,OAAO,CAAC,SAAS,CAAiB;IAElC;;OAEG;IAEH,OAAO,CAAC,OAAO,CAAkB;IAEjC;;OAEG;IAEH,OAAO,CAAC,OAAO,CAAkB;IAEjC;;OAEG;IACH,OAAO,CAAC,aAAa,CAAsB;IAE3C;;OAEG;IACH,OAAO,CAAC,mBAAmB,CAAuB;IAElD;;OAEG;IACH,OAAO,CAAC,oBAAoB,CAAqC;IAEjE;;OAEG;IAEH,OAAO,CAAC,sBAAsB,CAAkB;IAEhD,iBAAiB;IAKjB,oBAAoB;IAKpB,OAAO,CAAC,oBAAoB;IAiC5B,OAAO,CAAC,OAAO;IAYf,SAAS,CAAC,YAAY;IAItB,OAAO,CAAC,mBAAmB;IAqB3B,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;YAyB3C,sBAAsB;IAiBpC,OAAO,KAAK,iBAAiB,GAU5B;IAED,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,UAAU;YAUJ,cAAc;IAM5B,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,sBAAsB;IAS9B,MAAM;CAuEP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,WAAW,CAAC;KAC7B;CACF"}