@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
@@ -1 +0,0 @@
1
- {"version":3,"file":"device-selector.js","sources":["../../src/components/device-selector.ts"],"sourcesContent":["/**\n * Device Selector Component\n *\n * Dropdown-based selector for choosing audio/video devices. Displays device lists from\n * DeviceController observables with labeled dropdowns for microphone, camera, and speaker.\n * Includes inline preview for video (camera) and audio level (microphone) using browser API.\n *\n * @example\n * ```html\n * <sw-device-selector .deviceController=${deviceController} show-preview></sw-device-selector>\n * ```\n */\n\nimport { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { Subscription } from 'rxjs';\nimport type { DeviceController } from '@signalwire/js';\nimport './audio-level.js';\n\ntype DeviceType = 'microphone' | 'camera' | 'speaker';\n\n@customElement('sw-device-selector')\nexport class DeviceSelector extends LitElement {\n static styles = css`\n :host {\n /* CSS Custom Properties for theming */\n --sw-color-primary: #044cf6;\n --sw-color-primary-hover: #0339c4;\n --sw-color-background: #1a1a1a;\n --sw-color-surface: #2a2a2a;\n --sw-color-surface-hover: #3a3a3a;\n --sw-color-text: #ffffff;\n --sw-color-text-muted: #a0a0a0;\n --sw-color-border: #404040;\n --sw-color-success: #10b981;\n --sw-border-radius: 8px;\n --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --sw-space-1: 4px;\n --sw-space-2: 8px;\n --sw-space-3: 12px;\n --sw-space-4: 16px;\n --sw-space-6: 24px;\n\n display: block;\n font-family: var(--sw-font-family);\n color: var(--sw-color-text);\n }\n\n .container {\n background: var(--sw-color-background);\n border-radius: var(--sw-border-radius);\n border: 1px solid var(--sw-color-border);\n overflow: hidden;\n min-width: 300px;\n padding: var(--sw-space-4);\n }\n\n .device-section {\n margin-bottom: var(--sw-space-4);\n }\n\n .device-section:last-of-type {\n margin-bottom: 0;\n }\n\n .device-label {\n display: flex;\n align-items: center;\n gap: var(--sw-space-2);\n font-size: 14px;\n font-weight: 500;\n color: var(--sw-color-text);\n margin-bottom: var(--sw-space-2);\n }\n\n .device-icon {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\n color: var(--sw-color-text-muted);\n }\n\n .device-select-wrapper {\n position: relative;\n }\n\n .device-select {\n width: 100%;\n padding: var(--sw-space-3) var(--sw-space-4);\n padding-right: 36px;\n background: var(--sw-color-surface);\n border: 1px solid var(--sw-color-border);\n border-radius: calc(var(--sw-border-radius) - 4px);\n color: var(--sw-color-text);\n font-size: 14px;\n font-family: var(--sw-font-family);\n cursor: pointer;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n transition:\n border-color 0.2s ease,\n background-color 0.2s ease;\n }\n\n .device-select:hover {\n background: var(--sw-color-surface-hover);\n }\n\n .device-select:focus {\n outline: none;\n border-color: var(--sw-color-primary);\n box-shadow: 0 0 0 2px rgba(4, 76, 246, 0.2);\n }\n\n .device-select:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .device-select option {\n background: var(--sw-color-surface);\n color: var(--sw-color-text);\n padding: var(--sw-space-2);\n }\n\n .select-arrow {\n position: absolute;\n right: var(--sw-space-3);\n top: 50%;\n transform: translateY(-50%);\n width: 16px;\n height: 16px;\n color: var(--sw-color-text-muted);\n pointer-events: none;\n }\n\n .no-devices {\n padding: var(--sw-space-3) var(--sw-space-4);\n background: var(--sw-color-surface);\n border: 1px solid var(--sw-color-border);\n border-radius: calc(var(--sw-border-radius) - 4px);\n color: var(--sw-color-text-muted);\n font-size: 14px;\n }\n\n .device-preview {\n margin-top: var(--sw-space-3);\n }\n\n .video-preview {\n width: 100%;\n aspect-ratio: 16/9;\n background: #000;\n border-radius: calc(var(--sw-border-radius) - 4px);\n overflow: hidden;\n }\n\n .video-preview video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transform: scaleX(-1);\n }\n\n .video-preview-placeholder {\n width: 100%;\n aspect-ratio: 16/9;\n background: var(--sw-color-surface);\n border-radius: calc(var(--sw-border-radius) - 4px);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--sw-color-text-muted);\n font-size: 14px;\n }\n\n .audio-preview {\n display: flex;\n align-items: center;\n gap: var(--sw-space-3);\n padding: var(--sw-space-3);\n background: var(--sw-color-surface);\n border-radius: calc(var(--sw-border-radius) - 4px);\n }\n\n .audio-preview-label {\n font-size: 12px;\n color: var(--sw-color-text-muted);\n flex-shrink: 0;\n }\n\n .audio-level-wrapper {\n flex: 1;\n display: flex;\n justify-content: center;\n }\n\n .test-speaker-btn {\n padding: var(--sw-space-2) var(--sw-space-4);\n background: var(--sw-color-primary);\n color: white;\n border: none;\n border-radius: calc(var(--sw-border-radius) - 4px);\n font-size: 14px;\n cursor: pointer;\n transition: background-color 0.2s ease;\n }\n\n .test-speaker-btn:hover {\n background: var(--sw-color-primary-hover);\n }\n\n .test-speaker-btn:focus {\n outline: none;\n box-shadow:\n 0 0 0 2px var(--sw-color-background),\n 0 0 0 4px var(--sw-color-primary);\n }\n\n .test-speaker-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Scrollbar styling for select on some browsers */\n .device-select::-webkit-scrollbar {\n width: 8px;\n }\n\n .device-select::-webkit-scrollbar-track {\n background: var(--sw-color-background);\n }\n\n .device-select::-webkit-scrollbar-thumb {\n background: var(--sw-color-border);\n border-radius: 4px;\n }\n\n .device-select::-webkit-scrollbar-thumb:hover {\n background: var(--sw-color-text-muted);\n }\n `;\n\n /**\n * Device controller with observables for device lists\n */\n @property({ type: Object }) deviceController?: DeviceController;\n\n /**\n * Whether to show the preview panel\n */\n @property({ type: Boolean, attribute: 'show-preview' }) showPreview = false;\n\n /**\n * Audio input devices\n */\n @state() private _audioInputDevices: MediaDeviceInfo[] = [];\n\n /**\n * Video input devices\n */\n @state() private _videoInputDevices: MediaDeviceInfo[] = [];\n\n /**\n * Audio output devices\n */\n @state() private _audioOutputDevices: MediaDeviceInfo[] = [];\n\n /**\n * Selected audio input device\n */\n @state() private _selectedAudioInput: MediaDeviceInfo | null = null;\n\n /**\n * Selected video input device\n */\n @state() private _selectedVideoInput: MediaDeviceInfo | null = null;\n\n /**\n * Selected audio output device\n */\n @state() private _selectedAudioOutput: MediaDeviceInfo | null = null;\n\n /**\n * Video preview stream from camera\n */\n @state() private _videoPreviewStream: MediaStream | null = null;\n\n /**\n * Audio preview stream from microphone\n */\n @state() private _audioPreviewStream: MediaStream | null = null;\n\n /**\n * Is test audio playing\n */\n @state() private _isTestingAudio = false;\n\n /**\n * Whether the component is currently visible (combines all visibility factors)\n */\n private _isComponentVisible = false;\n\n /**\n * Whether the component is in the viewport (IntersectionObserver)\n */\n private _isInViewport = false;\n\n /**\n * Whether the document/tab is visible\n */\n private _isDocumentVisible = true;\n\n /**\n * Whether the component is CSS-visible (display, visibility, opacity)\n */\n private _isCSSVisible = true;\n\n /**\n * Video element reference\n */\n private _videoElement?: HTMLVideoElement;\n\n /**\n * RxJS subscriptions for cleanup\n */\n private subscriptions: Subscription[] = [];\n\n /**\n * Audio element for speaker test\n */\n private _testAudioElement?: HTMLAudioElement;\n\n /**\n * IntersectionObserver for viewport visibility\n */\n private _intersectionObserver?: IntersectionObserver;\n\n /**\n * Bound handler for document visibility change\n */\n private _boundHandleDocumentVisibility = this.handleDocumentVisibilityChange.bind(this);\n\n /**\n * Interval ID for CSS visibility polling\n */\n private _cssVisibilityCheckInterval?: ReturnType<typeof setInterval>;\n\n /**\n * Flag to prevent concurrent preview initialization\n */\n private _isInitializingPreviews = false;\n\n /**\n * Interval in milliseconds for checking CSS visibility changes\n */\n private static readonly CSS_VISIBILITY_CHECK_INTERVAL_MS = 200;\n\n /**\n * Lifecycle: Component connected to DOM\n */\n connectedCallback() {\n super.connectedCallback();\n this.setupSubscriptions();\n this.setupVisibilityObservers();\n }\n\n /**\n * Lifecycle: React to property changes\n */\n protected updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if (changedProperties.has('deviceController')) {\n this.cleanupSubscriptions();\n this.setupSubscriptions();\n }\n if (changedProperties.has('showPreview')) {\n if (this.showPreview && this._isComponentVisible) {\n // Only initialize if component is visible\n this.initializePreviews();\n } else if (!this.showPreview) {\n // Always cleanup when showPreview is disabled\n this.cleanupVideoPreviewStream();\n this.cleanupAudioPreviewStream();\n }\n }\n }\n\n /**\n * Lifecycle: Component disconnected from DOM\n */\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanupSubscriptions();\n this.cleanupVisibilityObservers();\n this.cleanupVideoPreviewStream();\n this.cleanupAudioPreviewStream();\n this.stopTestAudio();\n }\n\n /**\n * Setup all visibility observers (IntersectionObserver, document visibility, CSS polling)\n */\n private setupVisibilityObservers(): void {\n // Defensive cleanup in case of multiple calls without disconnect\n this.cleanupVisibilityObservers();\n\n // Setup IntersectionObserver for viewport visibility\n this._intersectionObserver = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n if (entry) {\n this._isInViewport = entry.isIntersecting;\n this.updateVisibilityState();\n }\n },\n { threshold: 0 }\n );\n this._intersectionObserver.observe(this);\n\n // Setup document visibility change listener\n this._isDocumentVisible = document.visibilityState === 'visible';\n document.addEventListener('visibilitychange', this._boundHandleDocumentVisibility);\n\n // Setup CSS visibility polling (checks opacity, display, visibility)\n this._isCSSVisible = this.checkCSSVisibility();\n this._cssVisibilityCheckInterval = setInterval(() => {\n const wasVisible = this._isCSSVisible;\n this._isCSSVisible = this.checkCSSVisibility();\n if (wasVisible !== this._isCSSVisible) {\n this.updateVisibilityState();\n }\n }, DeviceSelector.CSS_VISIBILITY_CHECK_INTERVAL_MS);\n }\n\n /**\n * Cleanup all visibility observers\n */\n private cleanupVisibilityObservers(): void {\n if (this._intersectionObserver) {\n this._intersectionObserver.disconnect();\n this._intersectionObserver = undefined;\n }\n\n document.removeEventListener('visibilitychange', this._boundHandleDocumentVisibility);\n\n if (this._cssVisibilityCheckInterval) {\n clearInterval(this._cssVisibilityCheckInterval);\n this._cssVisibilityCheckInterval = undefined;\n }\n }\n\n /**\n * Handle document visibility change (tab switching)\n */\n private handleDocumentVisibilityChange(): void {\n this._isDocumentVisible = document.visibilityState === 'visible';\n this.updateVisibilityState();\n }\n\n /**\n * Check if the component is visible via CSS (display, visibility, opacity)\n * Traverses the DOM tree including shadow DOM boundaries\n */\n private checkCSSVisibility(): boolean {\n // Guard against being called when disconnected\n if (!this.isConnected) {\n return false;\n }\n\n let element: HTMLElement | null = this;\n while (element) {\n const style = getComputedStyle(element);\n if (\n style.display === 'none' ||\n style.visibility === 'hidden' ||\n parseFloat(style.opacity) === 0\n ) {\n return false;\n }\n\n // Handle shadow DOM boundaries by traversing through shadow hosts\n if (element.parentElement) {\n element = element.parentElement;\n } else {\n const root = element.getRootNode();\n element = root instanceof ShadowRoot ? (root.host as HTMLElement) : null;\n }\n }\n return true;\n }\n\n /**\n * Update the combined visibility state and manage preview streams accordingly\n */\n private updateVisibilityState(): void {\n const wasVisible = this._isComponentVisible;\n this._isComponentVisible = this._isInViewport && this._isDocumentVisible && this._isCSSVisible;\n\n // Only react if visibility actually changed\n if (wasVisible === this._isComponentVisible) {\n return;\n }\n\n if (this._isComponentVisible && this.showPreview) {\n // Component became visible - start previews\n this.initializePreviews();\n } else if (!this._isComponentVisible) {\n // Component became invisible - stop previews\n this.cleanupVideoPreviewStream();\n this.cleanupAudioPreviewStream();\n }\n }\n\n /**\n * Subscribe to device controller observables\n */\n private setupSubscriptions(): void {\n if (!this.deviceController) return;\n\n // Subscribe to audio input devices\n this.subscriptions.push(\n this.deviceController.audioInputDevices$.subscribe((devices) => {\n this._audioInputDevices = devices;\n })\n );\n\n // Subscribe to video input devices\n this.subscriptions.push(\n this.deviceController.videoInputDevices$.subscribe((devices) => {\n this._videoInputDevices = devices;\n })\n );\n\n // Subscribe to audio output devices\n this.subscriptions.push(\n this.deviceController.audioOutputDevices$.subscribe((devices) => {\n this._audioOutputDevices = devices;\n })\n );\n\n // Subscribe to selected devices if available\n if (this.deviceController.selectedAudioInputDevice$) {\n this.subscriptions.push(\n this.deviceController.selectedAudioInputDevice$.subscribe((device) => {\n this._selectedAudioInput = device;\n })\n );\n }\n\n if (this.deviceController.selectedVideoInputDevice$) {\n this.subscriptions.push(\n this.deviceController.selectedVideoInputDevice$.subscribe((device) => {\n this._selectedVideoInput = device;\n })\n );\n }\n\n if (this.deviceController.selectedAudioOutputDevice$) {\n this.subscriptions.push(\n this.deviceController.selectedAudioOutputDevice$.subscribe((device) => {\n this._selectedAudioOutput = device;\n })\n );\n }\n }\n\n /**\n * Cleanup all subscriptions\n */\n private cleanupSubscriptions(): void {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.subscriptions = [];\n }\n\n /**\n * Cleanup video preview stream\n * Best practice from SDK: Pause video, clear srcObject, remove tracks from stream, then stop tracks\n * @see https://webrtchacks.com/srcobject-intervention/\n */\n private cleanupVideoPreviewStream(): void {\n // Step 1: Pause and clear the video element\n if (this._videoElement) {\n this._videoElement.pause();\n this._videoElement.srcObject = null;\n this._videoElement = undefined;\n }\n\n // Also check for any video element in shadow DOM (in case _videoElement wasn't set)\n const videoElement = this.shadowRoot?.querySelector('video');\n if (videoElement) {\n videoElement.pause();\n videoElement.srcObject = null;\n }\n\n // Step 2: Remove tracks from stream before stopping (SDK pattern)\n if (this._videoPreviewStream) {\n const tracks = this._videoPreviewStream.getTracks();\n tracks.forEach((track: MediaStreamTrack) => {\n // Remove track from stream first (important for proper release)\n this._videoPreviewStream?.removeTrack(track);\n track.stop();\n });\n this._videoPreviewStream = null;\n }\n }\n\n /**\n * Cleanup audio preview stream\n * Best practice from SDK: Release audio components, remove tracks from stream, then stop tracks\n * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/stop\n */\n private cleanupAudioPreviewStream(): void {\n // Step 1: Release resources from all audio-level components synchronously\n // This closes their AudioContext and disconnects MediaStreamAudioSourceNode\n const audioLevelComponents = this.shadowRoot?.querySelectorAll('sw-audio-level');\n audioLevelComponents?.forEach((component) => {\n const audioLevel = component as HTMLElement & {\n releaseResources?: () => void;\n stream?: MediaStream;\n };\n if (audioLevel.releaseResources) {\n audioLevel.releaseResources();\n } else {\n // Fallback for older versions\n audioLevel.stream = undefined;\n }\n });\n\n // Step 2: Remove tracks from stream before stopping (SDK pattern)\n if (this._audioPreviewStream) {\n const tracks = this._audioPreviewStream.getTracks();\n tracks.forEach((track: MediaStreamTrack) => {\n // Remove track from stream first (important for proper release)\n this._audioPreviewStream?.removeTrack(track);\n track.stop();\n });\n this._audioPreviewStream = null;\n }\n }\n\n /**\n * Get video preview stream from browser API\n */\n private async getVideoPreviewStream(deviceId?: string): Promise<void> {\n this.cleanupVideoPreviewStream();\n\n if (!this.showPreview) return;\n\n try {\n const constraints: MediaStreamConstraints = {\n video: deviceId ? { deviceId: { exact: deviceId } } : true,\n audio: false\n };\n this._videoPreviewStream = await navigator.mediaDevices.getUserMedia(constraints);\n this.updateVideoElement();\n } catch (error) {\n console.warn('Failed to get video preview stream:', error);\n this._videoPreviewStream = null;\n }\n }\n\n /**\n * Get audio preview stream from browser API\n */\n private async getAudioPreviewStream(deviceId?: string): Promise<void> {\n this.cleanupAudioPreviewStream();\n\n if (!this.showPreview) return;\n\n try {\n const constraints: MediaStreamConstraints = {\n video: false,\n audio: deviceId ? { deviceId: { exact: deviceId } } : true\n };\n this._audioPreviewStream = await navigator.mediaDevices.getUserMedia(constraints);\n } catch (error) {\n console.warn('Failed to get audio preview stream:', error);\n this._audioPreviewStream = null;\n }\n }\n\n /**\n * Update video element with current stream\n */\n private updateVideoElement(): void {\n if (this._videoElement && this._videoPreviewStream) {\n this._videoElement.srcObject = this._videoPreviewStream;\n }\n }\n\n /**\n * Initialize previews when show-preview is enabled\n */\n private async initializePreviews(): Promise<void> {\n // Prevent concurrent initialization to avoid stream leaks on rapid visibility toggles\n if (!this.showPreview || this._isInitializingPreviews) return;\n\n this._isInitializingPreviews = true;\n try {\n // Get video preview if we have video devices\n if (this._videoInputDevices.length > 0) {\n const deviceId = this._selectedVideoInput?.deviceId;\n await this.getVideoPreviewStream(deviceId);\n }\n\n // Get audio preview if we have audio devices\n if (this._audioInputDevices.length > 0) {\n const deviceId = this._selectedAudioInput?.deviceId;\n await this.getAudioPreviewStream(deviceId);\n }\n } finally {\n this._isInitializingPreviews = false;\n }\n }\n\n /**\n * Handle device selection change from dropdown\n */\n private handleDeviceChange(event: Event, deviceType: DeviceType): void {\n if (!this.deviceController) return;\n\n const select = event.target as HTMLSelectElement;\n const deviceId = select.value;\n\n let device: MediaDeviceInfo | null = null;\n\n switch (deviceType) {\n case 'microphone':\n device = this._audioInputDevices.find((d) => d.deviceId === deviceId) || null;\n this._selectedAudioInput = device;\n this.deviceController.selectAudioInputDevice?.(device);\n // Update audio preview stream with new device\n if (this.showPreview) {\n this.getAudioPreviewStream(deviceId);\n }\n break;\n case 'camera':\n device = this._videoInputDevices.find((d) => d.deviceId === deviceId) || null;\n this._selectedVideoInput = device;\n this.deviceController.selectVideoInputDevice?.(device);\n // Update video preview stream with new device\n if (this.showPreview) {\n this.getVideoPreviewStream(deviceId);\n }\n break;\n case 'speaker':\n device = this._audioOutputDevices.find((d) => d.deviceId === deviceId) || null;\n this._selectedAudioOutput = device;\n this.deviceController.selectAudioOutputDevice?.(device);\n break;\n }\n\n if (device) {\n this.dispatchEvent(\n new CustomEvent('sw-device-change', {\n detail: { device, deviceType },\n bubbles: true,\n composed: true\n })\n );\n }\n }\n\n /**\n * Test speaker by playing a test tone\n */\n private async testSpeaker(): Promise<void> {\n if (this._isTestingAudio) {\n this.stopTestAudio();\n return;\n }\n\n try {\n this._isTestingAudio = true;\n\n // Create oscillator-based test tone\n const audioContext = new AudioContext();\n const oscillator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n\n oscillator.type = 'sine';\n oscillator.frequency.value = 440; // A4 note\n gainNode.gain.value = 0.3;\n\n oscillator.connect(gainNode);\n gainNode.connect(audioContext.destination);\n\n oscillator.start();\n\n // Stop after 1 second\n setTimeout(() => {\n oscillator.stop();\n audioContext.close();\n this._isTestingAudio = false;\n }, 1000);\n\n this.dispatchEvent(\n new CustomEvent('sw-test-speaker', {\n bubbles: true,\n composed: true\n })\n );\n } catch (error) {\n console.error('Failed to play test audio:', error);\n this._isTestingAudio = false;\n }\n }\n\n /**\n * Stop test audio\n */\n private stopTestAudio(): void {\n if (this._testAudioElement) {\n this._testAudioElement.pause();\n this._testAudioElement = undefined;\n }\n this._isTestingAudio = false;\n }\n\n /**\n * Render device icon\n */\n private renderDeviceIcon(deviceType: DeviceType) {\n switch (deviceType) {\n case 'microphone':\n return html`<svg class=\"device-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.91-3c-.49 0-.9.36-.98.85C16.52 14.2 14.47 16 12 16s-4.52-1.8-4.93-4.15c-.08-.49-.49-.85-.98-.85-.61 0-1.09.54-1 1.14.49 3 2.89 5.35 5.91 5.78V20c0 .55.45 1 1 1s1-.45 1-1v-2.08c3.02-.43 5.42-2.78 5.91-5.78.1-.6-.39-1.14-1-1.14z\"\n />\n </svg>`;\n case 'camera':\n return html`<svg class=\"device-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\"\n />\n </svg>`;\n case 'speaker':\n return html`<svg class=\"device-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\"\n />\n </svg>`;\n }\n }\n\n /**\n * Render dropdown arrow icon\n */\n private renderSelectArrow() {\n return html`<svg class=\"select-arrow\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M7 10l5 5 5-5z\" />\n </svg>`;\n }\n\n /**\n * Render a device selection section\n */\n private renderDeviceSection(\n deviceType: DeviceType,\n label: string,\n devices: MediaDeviceInfo[],\n selectedDevice: MediaDeviceInfo | null\n ) {\n return html`\n <div class=\"device-section\" part=\"device-section\">\n <label class=\"device-label\" for=\"select-${deviceType}\">\n ${this.renderDeviceIcon(deviceType)}\n <span>${label}</span>\n </label>\n ${devices.length === 0\n ? html`<div class=\"no-devices\">No ${label.toLowerCase()} found</div>`\n : html`\n <div class=\"device-select-wrapper\">\n <select\n id=\"select-${deviceType}\"\n class=\"device-select\"\n part=\"device-select\"\n aria-label=\"${label}\"\n .value=${selectedDevice?.deviceId || ''}\n @change=${(e: Event) => this.handleDeviceChange(e, deviceType)}\n >\n ${devices.map(\n (device) => html`\n <option\n value=\"${device.deviceId}\"\n ?selected=${selectedDevice?.deviceId === device.deviceId}\n >\n ${device.label || `Device ${device.deviceId.slice(0, 8)}`}\n </option>\n `\n )}\n </select>\n ${this.renderSelectArrow()}\n </div>\n `}\n </div>\n `;\n }\n\n /**\n * Render video preview for camera section\n */\n private renderVideoPreview() {\n if (!this.showPreview || this._videoInputDevices.length === 0) {\n return nothing;\n }\n\n return html`\n <div class=\"device-preview\">\n ${this._videoPreviewStream\n ? html`\n <div class=\"video-preview\">\n <video\n autoplay\n playsinline\n muted\n .srcObject=${this._videoPreviewStream}\n @loadedmetadata=${(e: Event) => {\n const video = e.target as HTMLVideoElement;\n this._videoElement = video;\n video.play().catch(() => {});\n }}\n ></video>\n </div>\n `\n : html` <div class=\"video-preview-placeholder\">Click to enable camera preview</div> `}\n </div>\n `;\n }\n\n /**\n * Render audio level preview for microphone section\n */\n private renderAudioPreview() {\n if (!this.showPreview || this._audioInputDevices.length === 0) {\n return nothing;\n }\n\n return html`\n <div class=\"device-preview\">\n <div class=\"audio-preview\">\n <span class=\"audio-preview-label\">Level:</span>\n <div class=\"audio-level-wrapper\">\n ${this._audioPreviewStream\n ? html`\n <sw-audio-level\n .stream=${this._audioPreviewStream}\n bars=\"10\"\n orientation=\"horizontal\"\n maxSize=\"20\"\n ></sw-audio-level>\n `\n : html`\n <span style=\"color: var(--sw-color-text-muted); font-size: 12px;\"\n >No audio input</span\n >\n `}\n </div>\n </div>\n </div>\n `;\n }\n\n /**\n * Render the component\n */\n render() {\n return html`\n <div class=\"container\" part=\"container\">\n ${this.renderDeviceSection(\n 'microphone',\n 'Microphone',\n this._audioInputDevices,\n this._selectedAudioInput\n )}\n ${this.renderAudioPreview()}\n ${this.renderDeviceSection(\n 'camera',\n 'Camera',\n this._videoInputDevices,\n this._selectedVideoInput\n )}\n ${this.renderVideoPreview()}\n ${this.renderDeviceSection(\n 'speaker',\n 'Speaker',\n this._audioOutputDevices,\n this._selectedAudioOutput\n )}\n\n <div class=\"device-section\">\n <button\n class=\"test-speaker-btn\"\n @click=${this.testSpeaker}\n ?disabled=${this._isTestingAudio}\n aria-label=\"Test speaker\"\n >\n ${this._isTestingAudio ? 'Playing...' : 'Test Speaker'}\n </button>\n </div>\n </div>\n `;\n }\n}\n\n/**\n * Declare global type for TypeScript\n */\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-device-selector': DeviceSelector;\n }\n}\n"],"names":["DeviceSelector","LitElement","changedProperties","entries","entry","wasVisible","element","style","root","devices","device","sub","videoElement","_a","track","audioLevelComponents","component","audioLevel","deviceId","constraints","error","_b","event","deviceType","d","_d","_c","_f","_e","audioContext","oscillator","gainNode","html","label","selectedDevice","e","nothing","video","css","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -1,60 +0,0 @@
1
- /**
2
- * Dialpad Component
3
- *
4
- * A 12-key telephone keypad (0-9, *, #) for entering phone numbers
5
- * and sending DTMF tones during active calls.
6
- *
7
- * @example
8
- * ```html
9
- * <sw-dialpad .call=${call}></sw-dialpad>
10
- * ```
11
- */
12
- import { LitElement } from 'lit';
13
- import type { Observable } from 'rxjs';
14
- /**
15
- * Call interface for dialpad component
16
- */
17
- export interface DialpadCall {
18
- sendDigits?(dtmf: string): Promise<void>;
19
- status$?: Observable<string>;
20
- }
21
- export declare class DialpadComponent extends LitElement {
22
- static styles: import("lit").CSSResult;
23
- /**
24
- * Call object with sendDigits method
25
- */
26
- call: DialpadCall | null;
27
- /**
28
- * Call from context (if nested in sw-call-media)
29
- */
30
- private contextCall?;
31
- /**
32
- * Current digits entered
33
- */
34
- private digits;
35
- /**
36
- * Currently pressed key (for visual feedback)
37
- */
38
- private pressedKey;
39
- /**
40
- * Whether to show the call button
41
- */
42
- showCallButton: boolean;
43
- /**
44
- * Placeholder text for display input
45
- */
46
- placeholder: string;
47
- private get activeCall();
48
- private handleKeyPress;
49
- private handleBackspace;
50
- private handleCall;
51
- private handleInputChange;
52
- private handleKeyDown;
53
- render(): import("lit-html").TemplateResult<1>;
54
- }
55
- declare global {
56
- interface HTMLElementTagNameMap {
57
- 'sw-dialpad': DialpadComponent;
58
- }
59
- }
60
- //# sourceMappingURL=dialpad.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dialpad.d.ts","sourceRoot":"","sources":["../../src/components/dialpad.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGvC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;CAC9B;AAoBD,qBACa,gBAAiB,SAAQ,UAAU;IAC9C,MAAM,CAAC,MAAM,0BA0MX;IAEF;;OAEG;IAEH,IAAI,EAAE,WAAW,GAAG,IAAI,CAAQ;IAEhC;;OAEG;IAGH,OAAO,CAAC,WAAW,CAAC,CAAc;IAElC;;OAEG;IAEH,OAAO,CAAC,MAAM,CAAc;IAE5B;;OAEG;IAEH,OAAO,CAAC,UAAU,CAAuB;IAEzC;;OAEG;IAEH,cAAc,EAAE,OAAO,CAAS;IAEhC;;OAEG;IAEH,WAAW,EAAE,MAAM,CAAkB;IAErC,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,aAAa;IAYrB,MAAM;CA0EP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,YAAY,EAAE,gBAAgB,CAAC;KAChC;CACF"}
@@ -1,372 +0,0 @@
1
- import { LitElement as u, html as c, css as h } from "lit";
2
- import { property as d, state as p, customElement as g } from "lit/decorators.js";
3
- import { consume as b } from "@lit/context";
4
- import { callContext as w } from "../context/call-context.js";
5
- var f = Object.defineProperty, v = Object.getOwnPropertyDescriptor, o = (e, t, a, i) => {
6
- for (var r = i > 1 ? void 0 : i ? v(t, a) : t, l = e.length - 1, n; l >= 0; l--)
7
- (n = e[l]) && (r = (i ? n(t, a, r) : n(r)) || r);
8
- return i && r && f(t, a, r), r;
9
- };
10
- const m = [
11
- { digit: "1", letters: "" },
12
- { digit: "2", letters: "ABC" },
13
- { digit: "3", letters: "DEF" },
14
- { digit: "4", letters: "GHI" },
15
- { digit: "5", letters: "JKL" },
16
- { digit: "6", letters: "MNO" },
17
- { digit: "7", letters: "PQRS" },
18
- { digit: "8", letters: "TUV" },
19
- { digit: "9", letters: "WXYZ" },
20
- { digit: "*", letters: "" },
21
- { digit: "0", letters: "+" },
22
- { digit: "#", letters: "" }
23
- ];
24
- let s = class extends u {
25
- constructor() {
26
- super(...arguments), this.call = null, this.digits = "", this.pressedKey = null, this.showCallButton = !1, this.placeholder = "Enter number";
27
- }
28
- get activeCall() {
29
- return this.call || this.contextCall || null;
30
- }
31
- handleKeyPress(e) {
32
- var t;
33
- this.digits += e, this.pressedKey = e, (t = this.activeCall) != null && t.sendDigits && this.activeCall.sendDigits(e).catch((a) => {
34
- console.error("Failed to send DTMF:", a);
35
- }), this.dispatchEvent(
36
- new CustomEvent("sw-digit-press", {
37
- detail: { digit: e, digits: this.digits },
38
- bubbles: !0,
39
- composed: !0
40
- })
41
- ), setTimeout(() => {
42
- this.pressedKey = null;
43
- }, 100);
44
- }
45
- handleBackspace() {
46
- this.digits.length > 0 && (this.digits = this.digits.slice(0, -1), this.dispatchEvent(
47
- new CustomEvent("sw-backspace", {
48
- detail: { digits: this.digits },
49
- bubbles: !0,
50
- composed: !0
51
- })
52
- ));
53
- }
54
- handleCall() {
55
- this.digits.length > 0 && this.dispatchEvent(
56
- new CustomEvent("sw-dial", {
57
- detail: { digits: this.digits },
58
- bubbles: !0,
59
- composed: !0
60
- })
61
- );
62
- }
63
- handleInputChange(e) {
64
- const t = e.target;
65
- this.digits = t.value.replace(/[^0-9*#]/g, "");
66
- }
67
- handleKeyDown(e) {
68
- const t = e.key;
69
- /^[0-9*#]$/.test(t) ? this.handleKeyPress(t) : t === "Backspace" ? this.handleBackspace() : t === "Enter" && this.showCallButton && this.handleCall();
70
- }
71
- render() {
72
- return c`
73
- <div class="container" part="container">
74
- <div class="display" part="display">
75
- <input
76
- type="tel"
77
- class="display-input"
78
- .value=${this.digits}
79
- placeholder=${this.placeholder}
80
- @input=${this.handleInputChange}
81
- @keydown=${this.handleKeyDown}
82
- aria-label="Phone number input"
83
- />
84
- <button
85
- class="backspace-button"
86
- @click=${this.handleBackspace}
87
- ?disabled=${this.digits.length === 0}
88
- aria-label="Delete last digit"
89
- >
90
- <svg
91
- xmlns="http://www.w3.org/2000/svg"
92
- width="24"
93
- height="24"
94
- viewBox="0 0 24 24"
95
- fill="none"
96
- stroke="currentColor"
97
- stroke-width="2"
98
- stroke-linecap="round"
99
- stroke-linejoin="round"
100
- >
101
- <path d="M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z"></path>
102
- <line x1="18" y1="9" x2="12" y2="15"></line>
103
- <line x1="12" y1="9" x2="18" y2="15"></line>
104
- </svg>
105
- </button>
106
- </div>
107
-
108
- <div class="keypad" part="keypad" role="group" aria-label="Telephone keypad">
109
- ${m.map(
110
- (e) => c`
111
- <button
112
- class="key ${this.pressedKey === e.digit ? "pressed" : ""}"
113
- part="key ${this.pressedKey === e.digit ? "key-pressed" : ""}"
114
- @click=${() => this.handleKeyPress(e.digit)}
115
- aria-label="${e.digit}${e.letters ? `, ${e.letters}` : ""}"
116
- >
117
- <span class="key-digit">${e.digit}</span>
118
- <span class="key-letters">${e.letters}</span>
119
- </button>
120
- `
121
- )}
122
- </div>
123
-
124
- ${this.showCallButton ? c`
125
- <button
126
- class="call-button"
127
- part="call-button"
128
- @click=${this.handleCall}
129
- ?disabled=${this.digits.length === 0}
130
- aria-label="Call ${this.digits}"
131
- >
132
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
133
- <path
134
- d="M6.62 10.79c1.44 2.83 3.76 5.15 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"
135
- />
136
- </svg>
137
- Call
138
- </button>
139
- ` : null}
140
- </div>
141
- `;
142
- }
143
- };
144
- s.styles = h`
145
- :host {
146
- /* CSS Custom Properties for theming */
147
- --sw-color-primary: #044cf6;
148
- --sw-color-primary-hover: #0339c4;
149
- --sw-color-primary-active: #022b92;
150
- --sw-color-success: #10b981;
151
- --sw-color-danger: #ef4444;
152
- --sw-color-text: #1f2937;
153
- --sw-color-text-muted: #6b7280;
154
- --sw-color-border: #e5e7eb;
155
- --sw-color-background: #ffffff;
156
- --sw-color-background-hover: #f3f4f6;
157
- --sw-color-background-active: #e5e7eb;
158
- --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
159
- --sw-font-size-sm: 12px;
160
- --sw-font-size-base: 16px;
161
- --sw-font-size-lg: 24px;
162
- --sw-font-size-xl: 32px;
163
- --sw-space-1: 4px;
164
- --sw-space-2: 8px;
165
- --sw-space-3: 12px;
166
- --sw-space-4: 16px;
167
- --sw-border-radius: 8px;
168
- --sw-border-radius-full: 9999px;
169
-
170
- display: block;
171
- font-family: var(--sw-font-family);
172
- }
173
-
174
- /* Dark mode support */
175
- :host([data-theme='dark']) {
176
- --sw-color-text: #f9fafb;
177
- --sw-color-text-muted: #9ca3af;
178
- --sw-color-border: #374151;
179
- --sw-color-background: #1f2937;
180
- --sw-color-background-hover: #374151;
181
- --sw-color-background-active: #4b5563;
182
- }
183
-
184
- @media (prefers-color-scheme: dark) {
185
- :host(:not([data-theme='light'])) {
186
- --sw-color-text: #f9fafb;
187
- --sw-color-text-muted: #9ca3af;
188
- --sw-color-border: #374151;
189
- --sw-color-background: #1f2937;
190
- --sw-color-background-hover: #374151;
191
- --sw-color-background-active: #4b5563;
192
- }
193
- }
194
-
195
- .container {
196
- display: flex;
197
- flex-direction: column;
198
- gap: var(--sw-space-3);
199
- padding: var(--sw-space-4);
200
- max-width: 280px;
201
- background: var(--sw-color-background);
202
- border-radius: var(--sw-border-radius);
203
- }
204
-
205
- .display {
206
- display: flex;
207
- align-items: center;
208
- justify-content: space-between;
209
- padding: var(--sw-space-3) var(--sw-space-4);
210
- background: var(--sw-color-background-hover);
211
- border-radius: var(--sw-border-radius);
212
- min-height: 48px;
213
- }
214
-
215
- .display-input {
216
- flex: 1;
217
- font-size: var(--sw-font-size-xl);
218
- font-weight: 500;
219
- font-family: var(--sw-font-family);
220
- color: var(--sw-color-text);
221
- background: transparent;
222
- border: none;
223
- outline: none;
224
- letter-spacing: 2px;
225
- text-align: center;
226
- }
227
-
228
- .display-input::placeholder {
229
- color: var(--sw-color-text-muted);
230
- font-size: var(--sw-font-size-base);
231
- letter-spacing: normal;
232
- }
233
-
234
- .backspace-button {
235
- display: flex;
236
- align-items: center;
237
- justify-content: center;
238
- width: 40px;
239
- height: 40px;
240
- background: transparent;
241
- border: none;
242
- border-radius: var(--sw-border-radius);
243
- cursor: pointer;
244
- color: var(--sw-color-text-muted);
245
- transition:
246
- background-color 0.15s ease,
247
- color 0.15s ease;
248
- }
249
-
250
- .backspace-button:hover {
251
- background: var(--sw-color-background-active);
252
- color: var(--sw-color-text);
253
- }
254
-
255
- .backspace-button:disabled {
256
- opacity: 0.3;
257
- cursor: not-allowed;
258
- }
259
-
260
- .keypad {
261
- display: grid;
262
- grid-template-columns: repeat(3, 1fr);
263
- gap: var(--sw-space-2);
264
- }
265
-
266
- .key {
267
- display: flex;
268
- flex-direction: column;
269
- align-items: center;
270
- justify-content: center;
271
- width: 72px;
272
- height: 72px;
273
- background: var(--sw-color-background);
274
- border: 1px solid var(--sw-color-border);
275
- border-radius: var(--sw-border-radius-full);
276
- cursor: pointer;
277
- transition:
278
- background-color 0.1s ease,
279
- transform 0.1s ease;
280
- user-select: none;
281
- -webkit-user-select: none;
282
- -webkit-tap-highlight-color: transparent;
283
- }
284
-
285
- .key:hover {
286
- background: var(--sw-color-background-hover);
287
- }
288
-
289
- .key:active,
290
- .key.pressed {
291
- background: var(--sw-color-background-active);
292
- transform: scale(0.95);
293
- }
294
-
295
- .key-digit {
296
- font-size: var(--sw-font-size-lg);
297
- font-weight: 500;
298
- color: var(--sw-color-text);
299
- line-height: 1;
300
- }
301
-
302
- .key-letters {
303
- font-size: var(--sw-font-size-sm);
304
- color: var(--sw-color-text-muted);
305
- text-transform: uppercase;
306
- letter-spacing: 1px;
307
- margin-top: 2px;
308
- min-height: 14px;
309
- }
310
-
311
- .call-button {
312
- display: flex;
313
- align-items: center;
314
- justify-content: center;
315
- width: 100%;
316
- height: 56px;
317
- background: var(--sw-color-success);
318
- border: none;
319
- border-radius: var(--sw-border-radius);
320
- cursor: pointer;
321
- color: white;
322
- font-size: var(--sw-font-size-base);
323
- font-weight: 600;
324
- font-family: var(--sw-font-family);
325
- transition: background-color 0.15s ease;
326
- gap: var(--sw-space-2);
327
- }
328
-
329
- .call-button:hover {
330
- background: #0ea472;
331
- }
332
-
333
- .call-button:active {
334
- background: #0d9668;
335
- }
336
-
337
- .call-button:disabled {
338
- opacity: 0.5;
339
- cursor: not-allowed;
340
- }
341
-
342
- .call-button svg {
343
- width: 20px;
344
- height: 20px;
345
- }
346
- `;
347
- o([
348
- d({ attribute: !1 })
349
- ], s.prototype, "call", 2);
350
- o([
351
- b({ context: w, subscribe: !0 }),
352
- p()
353
- ], s.prototype, "contextCall", 2);
354
- o([
355
- p()
356
- ], s.prototype, "digits", 2);
357
- o([
358
- p()
359
- ], s.prototype, "pressedKey", 2);
360
- o([
361
- d({ type: Boolean, attribute: "show-call-button" })
362
- ], s.prototype, "showCallButton", 2);
363
- o([
364
- d({ type: String })
365
- ], s.prototype, "placeholder", 2);
366
- s = o([
367
- g("sw-dialpad")
368
- ], s);
369
- export {
370
- s as DialpadComponent
371
- };
372
- //# sourceMappingURL=dialpad.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dialpad.js","sources":["../../src/components/dialpad.ts"],"sourcesContent":["/**\n * Dialpad Component\n *\n * A 12-key telephone keypad (0-9, *, #) for entering phone numbers\n * and sending DTMF tones during active calls.\n *\n * @example\n * ```html\n * <sw-dialpad .call=${call}></sw-dialpad>\n * ```\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { consume } from '@lit/context';\nimport type { Observable } from 'rxjs';\nimport { callContext } from '../context/index.js';\n\n/**\n * Call interface for dialpad component\n */\nexport interface DialpadCall {\n sendDigits?(dtmf: string): Promise<void>;\n status$?: Observable<string>;\n}\n\n/**\n * Key layout for standard telephone keypad\n */\nconst KEYS = [\n { digit: '1', letters: '' },\n { digit: '2', letters: 'ABC' },\n { digit: '3', letters: 'DEF' },\n { digit: '4', letters: 'GHI' },\n { digit: '5', letters: 'JKL' },\n { digit: '6', letters: 'MNO' },\n { digit: '7', letters: 'PQRS' },\n { digit: '8', letters: 'TUV' },\n { digit: '9', letters: 'WXYZ' },\n { digit: '*', letters: '' },\n { digit: '0', letters: '+' },\n { digit: '#', letters: '' }\n];\n\n@customElement('sw-dialpad')\nexport class DialpadComponent extends LitElement {\n static styles = css`\n :host {\n /* CSS Custom Properties for theming */\n --sw-color-primary: #044cf6;\n --sw-color-primary-hover: #0339c4;\n --sw-color-primary-active: #022b92;\n --sw-color-success: #10b981;\n --sw-color-danger: #ef4444;\n --sw-color-text: #1f2937;\n --sw-color-text-muted: #6b7280;\n --sw-color-border: #e5e7eb;\n --sw-color-background: #ffffff;\n --sw-color-background-hover: #f3f4f6;\n --sw-color-background-active: #e5e7eb;\n --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --sw-font-size-sm: 12px;\n --sw-font-size-base: 16px;\n --sw-font-size-lg: 24px;\n --sw-font-size-xl: 32px;\n --sw-space-1: 4px;\n --sw-space-2: 8px;\n --sw-space-3: 12px;\n --sw-space-4: 16px;\n --sw-border-radius: 8px;\n --sw-border-radius-full: 9999px;\n\n display: block;\n font-family: var(--sw-font-family);\n }\n\n /* Dark mode support */\n :host([data-theme='dark']) {\n --sw-color-text: #f9fafb;\n --sw-color-text-muted: #9ca3af;\n --sw-color-border: #374151;\n --sw-color-background: #1f2937;\n --sw-color-background-hover: #374151;\n --sw-color-background-active: #4b5563;\n }\n\n @media (prefers-color-scheme: dark) {\n :host(:not([data-theme='light'])) {\n --sw-color-text: #f9fafb;\n --sw-color-text-muted: #9ca3af;\n --sw-color-border: #374151;\n --sw-color-background: #1f2937;\n --sw-color-background-hover: #374151;\n --sw-color-background-active: #4b5563;\n }\n }\n\n .container {\n display: flex;\n flex-direction: column;\n gap: var(--sw-space-3);\n padding: var(--sw-space-4);\n max-width: 280px;\n background: var(--sw-color-background);\n border-radius: var(--sw-border-radius);\n }\n\n .display {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--sw-space-3) var(--sw-space-4);\n background: var(--sw-color-background-hover);\n border-radius: var(--sw-border-radius);\n min-height: 48px;\n }\n\n .display-input {\n flex: 1;\n font-size: var(--sw-font-size-xl);\n font-weight: 500;\n font-family: var(--sw-font-family);\n color: var(--sw-color-text);\n background: transparent;\n border: none;\n outline: none;\n letter-spacing: 2px;\n text-align: center;\n }\n\n .display-input::placeholder {\n color: var(--sw-color-text-muted);\n font-size: var(--sw-font-size-base);\n letter-spacing: normal;\n }\n\n .backspace-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: transparent;\n border: none;\n border-radius: var(--sw-border-radius);\n cursor: pointer;\n color: var(--sw-color-text-muted);\n transition:\n background-color 0.15s ease,\n color 0.15s ease;\n }\n\n .backspace-button:hover {\n background: var(--sw-color-background-active);\n color: var(--sw-color-text);\n }\n\n .backspace-button:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n .keypad {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--sw-space-2);\n }\n\n .key {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 72px;\n height: 72px;\n background: var(--sw-color-background);\n border: 1px solid var(--sw-color-border);\n border-radius: var(--sw-border-radius-full);\n cursor: pointer;\n transition:\n background-color 0.1s ease,\n transform 0.1s ease;\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n .key:hover {\n background: var(--sw-color-background-hover);\n }\n\n .key:active,\n .key.pressed {\n background: var(--sw-color-background-active);\n transform: scale(0.95);\n }\n\n .key-digit {\n font-size: var(--sw-font-size-lg);\n font-weight: 500;\n color: var(--sw-color-text);\n line-height: 1;\n }\n\n .key-letters {\n font-size: var(--sw-font-size-sm);\n color: var(--sw-color-text-muted);\n text-transform: uppercase;\n letter-spacing: 1px;\n margin-top: 2px;\n min-height: 14px;\n }\n\n .call-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 56px;\n background: var(--sw-color-success);\n border: none;\n border-radius: var(--sw-border-radius);\n cursor: pointer;\n color: white;\n font-size: var(--sw-font-size-base);\n font-weight: 600;\n font-family: var(--sw-font-family);\n transition: background-color 0.15s ease;\n gap: var(--sw-space-2);\n }\n\n .call-button:hover {\n background: #0ea472;\n }\n\n .call-button:active {\n background: #0d9668;\n }\n\n .call-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .call-button svg {\n width: 20px;\n height: 20px;\n }\n `;\n\n /**\n * Call object with sendDigits method\n */\n @property({ attribute: false })\n call: DialpadCall | null = null;\n\n /**\n * Call from context (if nested in sw-call-media)\n */\n @consume({ context: callContext, subscribe: true })\n @state()\n private contextCall?: DialpadCall;\n\n /**\n * Current digits entered\n */\n @state()\n private digits: string = '';\n\n /**\n * Currently pressed key (for visual feedback)\n */\n @state()\n private pressedKey: string | null = null;\n\n /**\n * Whether to show the call button\n */\n @property({ type: Boolean, attribute: 'show-call-button' })\n showCallButton: boolean = false;\n\n /**\n * Placeholder text for display input\n */\n @property({ type: String })\n placeholder: string = 'Enter number';\n\n private get activeCall(): DialpadCall | null {\n return this.call || this.contextCall || null;\n }\n\n private handleKeyPress(digit: string) {\n this.digits += digit;\n this.pressedKey = digit;\n\n // Send DTMF if call is active\n if (this.activeCall?.sendDigits) {\n this.activeCall.sendDigits(digit).catch((err) => {\n console.error('Failed to send DTMF:', err);\n });\n }\n\n // Dispatch event\n this.dispatchEvent(\n new CustomEvent('sw-digit-press', {\n detail: { digit, digits: this.digits },\n bubbles: true,\n composed: true\n })\n );\n\n // Reset pressed state after animation\n setTimeout(() => {\n this.pressedKey = null;\n }, 100);\n }\n\n private handleBackspace() {\n if (this.digits.length > 0) {\n this.digits = this.digits.slice(0, -1);\n this.dispatchEvent(\n new CustomEvent('sw-backspace', {\n detail: { digits: this.digits },\n bubbles: true,\n composed: true\n })\n );\n }\n }\n\n private handleCall() {\n if (this.digits.length > 0) {\n this.dispatchEvent(\n new CustomEvent('sw-dial', {\n detail: { digits: this.digits },\n bubbles: true,\n composed: true\n })\n );\n }\n }\n\n private handleInputChange(e: Event) {\n const input = e.target as HTMLInputElement;\n // Only allow valid DTMF characters\n this.digits = input.value.replace(/[^0-9*#]/g, '');\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n const key = e.key;\n // Handle keyboard input for digits\n if (/^[0-9*#]$/.test(key)) {\n this.handleKeyPress(key);\n } else if (key === 'Backspace') {\n this.handleBackspace();\n } else if (key === 'Enter' && this.showCallButton) {\n this.handleCall();\n }\n }\n\n render() {\n return html`\n <div class=\"container\" part=\"container\">\n <div class=\"display\" part=\"display\">\n <input\n type=\"tel\"\n class=\"display-input\"\n .value=${this.digits}\n placeholder=${this.placeholder}\n @input=${this.handleInputChange}\n @keydown=${this.handleKeyDown}\n aria-label=\"Phone number input\"\n />\n <button\n class=\"backspace-button\"\n @click=${this.handleBackspace}\n ?disabled=${this.digits.length === 0}\n aria-label=\"Delete last digit\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z\"></path>\n <line x1=\"18\" y1=\"9\" x2=\"12\" y2=\"15\"></line>\n <line x1=\"12\" y1=\"9\" x2=\"18\" y2=\"15\"></line>\n </svg>\n </button>\n </div>\n\n <div class=\"keypad\" part=\"keypad\" role=\"group\" aria-label=\"Telephone keypad\">\n ${KEYS.map(\n (key) => html`\n <button\n class=\"key ${this.pressedKey === key.digit ? 'pressed' : ''}\"\n part=\"key ${this.pressedKey === key.digit ? 'key-pressed' : ''}\"\n @click=${() => this.handleKeyPress(key.digit)}\n aria-label=\"${key.digit}${key.letters ? `, ${key.letters}` : ''}\"\n >\n <span class=\"key-digit\">${key.digit}</span>\n <span class=\"key-letters\">${key.letters}</span>\n </button>\n `\n )}\n </div>\n\n ${this.showCallButton\n ? html`\n <button\n class=\"call-button\"\n part=\"call-button\"\n @click=${this.handleCall}\n ?disabled=${this.digits.length === 0}\n aria-label=\"Call ${this.digits}\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M6.62 10.79c1.44 2.83 3.76 5.15 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z\"\n />\n </svg>\n Call\n </button>\n `\n : null}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-dialpad': DialpadComponent;\n }\n}\n"],"names":["KEYS","DialpadComponent","LitElement","digit","_a","err","input","key","html","css","__decorateClass","property","consume","callContext","state","customElement"],"mappings":";;;;;;;;;AA6BA,MAAMA,IAAO;AAAA,EACX,EAAE,OAAO,KAAK,SAAS,GAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,MAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,MAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,MAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,MAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,MAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,OAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,MAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,OAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,GAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,IAAA;AAAA,EACvB,EAAE,OAAO,KAAK,SAAS,GAAA;AACzB;AAGO,IAAMC,IAAN,cAA+BC,EAAW;AAAA,EAA1C,cAAA;AAAA,UAAA,GAAA,SAAA,GAiNL,KAAA,OAA2B,MAa3B,KAAQ,SAAiB,IAMzB,KAAQ,aAA4B,MAMpC,KAAA,iBAA0B,IAM1B,KAAA,cAAsB;AAAA,EAAA;AAAA,EAEtB,IAAY,aAAiC;AAC3C,WAAO,KAAK,QAAQ,KAAK,eAAe;AAAA,EAC1C;AAAA,EAEQ,eAAeC,GAAe;;AACpC,SAAK,UAAUA,GACf,KAAK,aAAaA,IAGdC,IAAA,KAAK,eAAL,QAAAA,EAAiB,cACnB,KAAK,WAAW,WAAWD,CAAK,EAAE,MAAM,CAACE,MAAQ;AAC/C,cAAQ,MAAM,wBAAwBA,CAAG;AAAA,IAC3C,CAAC,GAIH,KAAK;AAAA,MACH,IAAI,YAAY,kBAAkB;AAAA,QAChC,QAAQ,EAAE,OAAAF,GAAO,QAAQ,KAAK,OAAA;AAAA,QAC9B,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA,GAIH,WAAW,MAAM;AACf,WAAK,aAAa;AAAA,IACpB,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,kBAAkB;AACxB,IAAI,KAAK,OAAO,SAAS,MACvB,KAAK,SAAS,KAAK,OAAO,MAAM,GAAG,EAAE,GACrC,KAAK;AAAA,MACH,IAAI,YAAY,gBAAgB;AAAA,QAC9B,QAAQ,EAAE,QAAQ,KAAK,OAAA;AAAA,QACvB,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAGP;AAAA,EAEQ,aAAa;AACnB,IAAI,KAAK,OAAO,SAAS,KACvB,KAAK;AAAA,MACH,IAAI,YAAY,WAAW;AAAA,QACzB,QAAQ,EAAE,QAAQ,KAAK,OAAA;AAAA,QACvB,SAAS;AAAA,QACT,UAAU;AAAA,MAAA,CACX;AAAA,IAAA;AAAA,EAGP;AAAA,EAEQ,kBAAkB,GAAU;AAClC,UAAMG,IAAQ,EAAE;AAEhB,SAAK,SAASA,EAAM,MAAM,QAAQ,aAAa,EAAE;AAAA,EACnD;AAAA,EAEQ,cAAc,GAAkB;AACtC,UAAMC,IAAM,EAAE;AAEd,IAAI,YAAY,KAAKA,CAAG,IACtB,KAAK,eAAeA,CAAG,IACdA,MAAQ,cACjB,KAAK,gBAAA,IACIA,MAAQ,WAAW,KAAK,kBACjC,KAAK,WAAA;AAAA,EAET;AAAA,EAEA,SAAS;AACP,WAAOC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAMU,KAAK,MAAM;AAAA,0BACN,KAAK,WAAW;AAAA,qBACrB,KAAK,iBAAiB;AAAA,uBACpB,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKpB,KAAK,eAAe;AAAA,wBACjB,KAAK,OAAO,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAsBpCR,EAAK;AAAA,MACL,CAACO,MAAQC;AAAA;AAAA,6BAEQ,KAAK,eAAeD,EAAI,QAAQ,YAAY,EAAE;AAAA,4BAC/C,KAAK,eAAeA,EAAI,QAAQ,gBAAgB,EAAE;AAAA,yBACrD,MAAM,KAAK,eAAeA,EAAI,KAAK,CAAC;AAAA,8BAC/BA,EAAI,KAAK,GAAGA,EAAI,UAAU,KAAKA,EAAI,OAAO,KAAK,EAAE;AAAA;AAAA,0CAErCA,EAAI,KAAK;AAAA,4CACPA,EAAI,OAAO;AAAA;AAAA;AAAA,IAAA,CAG5C;AAAA;AAAA;AAAA,UAGD,KAAK,iBACHC;AAAA;AAAA;AAAA;AAAA,yBAIa,KAAK,UAAU;AAAA,4BACZ,KAAK,OAAO,WAAW,CAAC;AAAA,mCACjB,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAUlC,IAAI;AAAA;AAAA;AAAA,EAGd;AACF;AArYaP,EACJ,SAASQ;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;AAgNhBC,EAAA;AAAA,EADCC,EAAS,EAAE,WAAW,GAAA,CAAO;AAAA,GAhNnBV,EAiNX,WAAA,QAAA,CAAA;AAOQS,EAAA;AAAA,EAFPE,EAAQ,EAAE,SAASC,GAAa,WAAW,IAAM;AAAA,EACjDC,EAAA;AAAM,GAvNIb,EAwNH,WAAA,eAAA,CAAA;AAMAS,EAAA;AAAA,EADPI,EAAA;AAAM,GA7NIb,EA8NH,WAAA,UAAA,CAAA;AAMAS,EAAA;AAAA,EADPI,EAAA;AAAM,GAnOIb,EAoOH,WAAA,cAAA,CAAA;AAMRS,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,WAAW,oBAAoB;AAAA,GAzO/CV,EA0OX,WAAA,kBAAA,CAAA;AAMAS,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA/OfV,EAgPX,WAAA,eAAA,CAAA;AAhPWA,IAANS,EAAA;AAAA,EADNK,EAAc,YAAY;AAAA,GACdd,CAAA;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/components/directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC;;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,kBAAmB,SAAQ,UAAU;IAChD,MAAM,CAAC,MAAM,0BAuPX;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;IAmBzB,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,sBAAsB;IAS9B,MAAM;CA+EP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,kBAAkB,CAAC;KACpC;CACF"}