@signalwire/web-components 4.0.0-beta.11 → 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 (350) 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} +39 -7
  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} +13 -21
  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 +18 -12
  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 +55 -26
  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/utils/index.d.ts +2 -0
  277. package/dist/utils/index.d.ts.map +1 -1
  278. package/dist/utils/prism.d.ts +4 -0
  279. package/dist/utils/prism.d.ts.map +1 -0
  280. package/dist/utils/prism.js +34 -0
  281. package/dist/utils/prism.js.map +1 -0
  282. package/dist/utils/theme-loader.d.ts +11 -0
  283. package/dist/utils/theme-loader.d.ts.map +1 -0
  284. package/dist/utils/theme-loader.js +17 -0
  285. package/dist/utils/theme-loader.js.map +1 -0
  286. package/dist/utils/transcriptToMarkdown.d.ts +14 -0
  287. package/dist/utils/transcriptToMarkdown.d.ts.map +1 -0
  288. package/dist/utils/transcriptToMarkdown.js +59 -0
  289. package/dist/utils/transcriptToMarkdown.js.map +1 -0
  290. package/dist/utils/use-google-font.d.ts +18 -0
  291. package/dist/utils/use-google-font.d.ts.map +1 -0
  292. package/dist/utils/use-google-font.js +12 -0
  293. package/dist/utils/use-google-font.js.map +1 -0
  294. package/dist/utils/user-variables.d.ts +20 -0
  295. package/dist/utils/user-variables.d.ts.map +1 -0
  296. package/dist/utils/user-variables.js +37 -0
  297. package/dist/utils/user-variables.js.map +1 -0
  298. package/package.json +104 -41
  299. package/dist/components/audio-level.d.ts.map +0 -1
  300. package/dist/components/audio-level.js +0 -203
  301. package/dist/components/audio-level.js.map +0 -1
  302. package/dist/components/call-controls.d.ts +0 -183
  303. package/dist/components/call-controls.d.ts.map +0 -1
  304. package/dist/components/call-controls.js +0 -606
  305. package/dist/components/call-controls.js.map +0 -1
  306. package/dist/components/call-media.d.ts +0 -118
  307. package/dist/components/call-media.d.ts.map +0 -1
  308. package/dist/components/call-media.js +0 -219
  309. package/dist/components/call-media.js.map +0 -1
  310. package/dist/components/call-status.d.ts +0 -83
  311. package/dist/components/call-status.d.ts.map +0 -1
  312. package/dist/components/call-status.js +0 -255
  313. package/dist/components/call-status.js.map +0 -1
  314. package/dist/components/click-to-call.d.ts +0 -151
  315. package/dist/components/click-to-call.d.ts.map +0 -1
  316. package/dist/components/click-to-call.js +0 -428
  317. package/dist/components/click-to-call.js.map +0 -1
  318. package/dist/components/device-selector.d.ts +0 -238
  319. package/dist/components/device-selector.d.ts.map +0 -1
  320. package/dist/components/device-selector.js +0 -685
  321. package/dist/components/device-selector.js.map +0 -1
  322. package/dist/components/dialpad.d.ts +0 -74
  323. package/dist/components/dialpad.d.ts.map +0 -1
  324. package/dist/components/dialpad.js +0 -372
  325. package/dist/components/dialpad.js.map +0 -1
  326. package/dist/components/directory.d.ts.map +0 -1
  327. package/dist/components/directory.js +0 -503
  328. package/dist/components/directory.js.map +0 -1
  329. package/dist/components/example-button.d.ts +0 -21
  330. package/dist/components/example-button.d.ts.map +0 -1
  331. package/dist/components/example-button.js +0 -74
  332. package/dist/components/example-button.js.map +0 -1
  333. package/dist/components/participant-controls.d.ts +0 -123
  334. package/dist/components/participant-controls.d.ts.map +0 -1
  335. package/dist/components/participant-controls.js +0 -468
  336. package/dist/components/participant-controls.js.map +0 -1
  337. package/dist/components/participants.d.ts +0 -120
  338. package/dist/components/participants.d.ts.map +0 -1
  339. package/dist/components/participants.js +0 -394
  340. package/dist/components/participants.js.map +0 -1
  341. package/dist/components/self-media.d.ts +0 -78
  342. package/dist/components/self-media.d.ts.map +0 -1
  343. package/dist/components/self-media.js +0 -129
  344. package/dist/components/self-media.js.map +0 -1
  345. package/dist/context/call-context.d.ts +0 -13
  346. package/dist/context/call-context.d.ts.map +0 -1
  347. package/dist/context/call-context.js +0 -6
  348. package/dist/context/call-context.js.map +0 -1
  349. package/dist/types/index.js +0 -12
  350. package/dist/types/index.js.map +0 -1
@@ -0,0 +1,434 @@
1
+ import { LitElement as u, html as a, css as p } from "lit";
2
+ import { property as m, state as l, customElement as b } from "lit/decorators.js";
3
+ var v = Object.defineProperty, f = Object.getOwnPropertyDescriptor, n = (e, i, o, t) => {
4
+ for (var s = t > 1 ? void 0 : t ? f(i, o) : i, c = e.length - 1, d; c >= 0; c--)
5
+ (d = e[c]) && (s = (t ? d(i, o, s) : d(s)) || s);
6
+ return t && s && v(i, o, s), s;
7
+ };
8
+ let r = class extends u {
9
+ constructor() {
10
+ super(...arguments), this.directory = null, this.selectedAddress = null, this.searchQuery = "", this.addresses = [], this.loading = !1, this.hasMore = !1, this.subscriptions = [], this.searchDebounceTimer = null, this.intersectionObserver = null, this.isAutoLoadingForSearch = !1;
11
+ }
12
+ connectedCallback() {
13
+ super.connectedCallback(), this.subscribeToDirectory();
14
+ }
15
+ disconnectedCallback() {
16
+ super.disconnectedCallback(), this.cleanup();
17
+ }
18
+ subscribeToDirectory() {
19
+ if (this.directory) {
20
+ if (this.directory.addresses$) {
21
+ const e = this.directory.addresses$.subscribe((i) => {
22
+ this.addresses = i;
23
+ });
24
+ this.subscriptions.push(e);
25
+ }
26
+ if (this.directory.loading$) {
27
+ const e = this.directory.loading$.subscribe((i) => {
28
+ this.loading = i;
29
+ });
30
+ this.subscriptions.push(e);
31
+ }
32
+ if (this.directory.hasMore$) {
33
+ const e = this.directory.hasMore$.subscribe((i) => {
34
+ this.hasMore = i;
35
+ });
36
+ this.subscriptions.push(e);
37
+ }
38
+ this.directory.loadMore && this.directory.loadMore();
39
+ }
40
+ }
41
+ cleanup() {
42
+ this.subscriptions.forEach((e) => e.unsubscribe()), this.subscriptions = [], this.searchDebounceTimer && clearTimeout(this.searchDebounceTimer), this.intersectionObserver && (this.intersectionObserver.disconnect(), this.intersectionObserver = null);
43
+ }
44
+ firstUpdated() {
45
+ this.setupInfiniteScroll();
46
+ }
47
+ setupInfiniteScroll() {
48
+ var i, o;
49
+ const e = (i = this.shadowRoot) == null ? void 0 : i.querySelector(".scroll-sentinel");
50
+ e && (this.intersectionObserver = new IntersectionObserver(
51
+ (t) => {
52
+ const s = t[0];
53
+ s != null && s.isIntersecting && this.hasMore && !this.loading && this.handleLoadMore();
54
+ },
55
+ {
56
+ root: (o = this.shadowRoot) == null ? void 0 : o.querySelector(".list"),
57
+ rootMargin: "100px",
58
+ threshold: 0
59
+ }
60
+ ), this.intersectionObserver.observe(e));
61
+ }
62
+ updated(e) {
63
+ super.updated(e), e.has("directory") && (this.cleanup(), this.subscribeToDirectory()), this.intersectionObserver || this.setupInfiniteScroll(), (e.has("addresses") || e.has("searchQuery") || e.has("loading")) && this.checkAutoLoadForSearch();
64
+ }
65
+ async checkAutoLoadForSearch() {
66
+ this.searchQuery.trim() && this.filteredAddresses.length === 0 && this.hasMore && !this.loading ? (this.isAutoLoadingForSearch = !0, await this.handleLoadMore()) : (this.filteredAddresses.length > 0 || !this.hasMore) && (this.isAutoLoadingForSearch = !1);
67
+ }
68
+ get filteredAddresses() {
69
+ if (!this.searchQuery.trim())
70
+ return this.addresses;
71
+ const e = this.searchQuery.toLowerCase();
72
+ return this.addresses.filter(
73
+ (i) => i.name.toLowerCase().includes(e) || i.displayName && i.displayName.toLowerCase().includes(e)
74
+ );
75
+ }
76
+ handleSearchInput(e) {
77
+ const i = e.target;
78
+ this.searchDebounceTimer && clearTimeout(this.searchDebounceTimer), this.searchDebounceTimer = window.setTimeout(() => {
79
+ this.searchQuery = i.value;
80
+ }, 200);
81
+ }
82
+ handleItemClick(e) {
83
+ this.selectedAddress = e, this.dispatchEvent(
84
+ new CustomEvent("sw-address-select", {
85
+ detail: { address: e },
86
+ bubbles: !0,
87
+ composed: !0
88
+ })
89
+ );
90
+ }
91
+ handleItemDoubleClick(e) {
92
+ this.handleDial(e);
93
+ }
94
+ handleDial(e) {
95
+ this.dispatchEvent(
96
+ new CustomEvent("sw-dial", {
97
+ detail: { address: e },
98
+ bubbles: !0,
99
+ composed: !0
100
+ })
101
+ );
102
+ }
103
+ async handleLoadMore() {
104
+ var e;
105
+ (e = this.directory) != null && e.loadMore && await this.directory.loadMore();
106
+ }
107
+ renderAddressIcon(e) {
108
+ const i = e.type === "room" ? "room" : "person";
109
+ return a`<sw-ui-icon name=${i} size="20"></sw-ui-icon>`;
110
+ }
111
+ renderChannelIcons(e) {
112
+ const i = e.channels || {};
113
+ return a`
114
+ <div class="item-channels">
115
+ <sw-ui-icon
116
+ name="mic-on"
117
+ size="16"
118
+ class="${i.audio ? "active" : ""}"
119
+ title="Audio"
120
+ ></sw-ui-icon>
121
+ <sw-ui-icon
122
+ name="camera-on"
123
+ size="16"
124
+ class="${i.video ? "active" : ""}"
125
+ title="Video"
126
+ ></sw-ui-icon>
127
+ </div>
128
+ `;
129
+ }
130
+ renderLoadingIndicator() {
131
+ return a`
132
+ <div class="scroll-loading">
133
+ <div class="spinner"></div>
134
+ <span>${this.isAutoLoadingForSearch ? "Searching..." : "Loading more..."}</span>
135
+ </div>
136
+ `;
137
+ }
138
+ render() {
139
+ const e = this.loading && this.addresses.length === 0, i = !this.loading && this.filteredAddresses.length === 0 && !this.hasMore, o = this.isAutoLoadingForSearch && this.filteredAddresses.length === 0;
140
+ return a`
141
+ <div class="container" part="container">
142
+ <div class="search" part="search">
143
+ <input
144
+ type="text"
145
+ class="search-input"
146
+ placeholder="Search addresses..."
147
+ @input=${this.handleSearchInput}
148
+ aria-label="Search addresses"
149
+ />
150
+ </div>
151
+
152
+ <div class="list" part="list" role="listbox">
153
+ ${e ? a`<div class="loading">Loading...</div>` : o ? this.renderLoadingIndicator() : i ? a`<div class="empty">No addresses found</div>` : a`
154
+ ${this.filteredAddresses.map(
155
+ (t) => {
156
+ var s, c, d;
157
+ return a`
158
+ <div
159
+ class="item ${((s = this.selectedAddress) == null ? void 0 : s.id) === t.id ? "selected" : ""}"
160
+ part="item ${((c = this.selectedAddress) == null ? void 0 : c.id) === t.id ? "item-selected" : ""}"
161
+ role="option"
162
+ aria-selected="${((d = this.selectedAddress) == null ? void 0 : d.id) === t.id}"
163
+ @click=${() => this.handleItemClick(t)}
164
+ @dblclick=${() => this.handleItemDoubleClick(t)}
165
+ >
166
+ <div class="item-icon">${this.renderAddressIcon(t)}</div>
167
+ <div class="item-content">
168
+ <div class="item-name" part="item-name">
169
+ ${t.displayName || t.name}
170
+ </div>
171
+ <div class="item-type" part="item-type">
172
+ ${t.type || "address"}
173
+ </div>
174
+ </div>
175
+ ${this.renderChannelIcons(t)}
176
+ <button
177
+ class="dial-button"
178
+ @click=${(h) => {
179
+ h.stopPropagation(), this.handleDial(t);
180
+ }}
181
+ aria-label="Call ${t.displayName || t.name}"
182
+ >
183
+ <sw-ui-icon name="phone-call" size="18"></sw-ui-icon>
184
+ </button>
185
+ </div>
186
+ `;
187
+ }
188
+ )}
189
+ <!-- Scroll sentinel for infinite scroll -->
190
+ <div class="scroll-sentinel">
191
+ ${this.loading && !this.isAutoLoadingForSearch ? this.renderLoadingIndicator() : null}
192
+ </div>
193
+ `}
194
+ </div>
195
+ </div>
196
+ `;
197
+ }
198
+ };
199
+ r.styles = p`
200
+ :host {
201
+ display: block;
202
+ font-family: var(--type-family-body);
203
+ color: var(--fg-default);
204
+ }
205
+
206
+ .container {
207
+ display: flex;
208
+ flex-direction: column;
209
+ background: var(--bg-surface);
210
+ border: 1px solid var(--border-default);
211
+ border-radius: var(--radius-md);
212
+ overflow: hidden;
213
+ }
214
+
215
+ .search {
216
+ display: flex;
217
+ align-items: center;
218
+ gap: var(--sp-2);
219
+ padding: var(--sp-3);
220
+ border-bottom: 1px solid var(--border-default);
221
+ }
222
+
223
+ .search-input {
224
+ flex: 1;
225
+ padding: var(--sp-2) var(--sp-3);
226
+ border: 1px solid var(--border-default);
227
+ border-radius: var(--radius-md);
228
+ background: var(--bg-surface);
229
+ color: var(--fg-default);
230
+ font-family: var(--type-family-body);
231
+ font-size: var(--type-size-small);
232
+ outline: none;
233
+ transition: border-color 0.15s ease;
234
+ }
235
+
236
+ .search-input:focus {
237
+ border-color: var(--interactive-button-primary-bg);
238
+ }
239
+
240
+ .search-input::placeholder {
241
+ color: var(--fg-muted);
242
+ }
243
+
244
+ .list {
245
+ display: flex;
246
+ flex-direction: column;
247
+ max-height: 400px;
248
+ overflow-y: auto;
249
+ }
250
+
251
+ .item {
252
+ display: flex;
253
+ align-items: center;
254
+ gap: var(--sp-3);
255
+ padding: var(--sp-3) var(--sp-4);
256
+ border-bottom: 1px solid var(--border-default);
257
+ cursor: pointer;
258
+ transition: background-color 0.15s ease;
259
+ }
260
+
261
+ .item:last-child {
262
+ border-bottom: none;
263
+ }
264
+
265
+ .item:hover {
266
+ background: var(--bg-surface-raised);
267
+ }
268
+
269
+ .item:active {
270
+ background: var(--interactive-dropdown-hover);
271
+ }
272
+
273
+ .item.selected {
274
+ background: var(--interactive-button-primary-bg);
275
+ color: white;
276
+ }
277
+
278
+ .item.selected .item-type,
279
+ .item.selected .item-channels {
280
+ color: rgba(255, 255, 255, 0.8);
281
+ }
282
+
283
+ .item-icon {
284
+ display: flex;
285
+ align-items: center;
286
+ justify-content: center;
287
+ width: 40px;
288
+ height: 40px;
289
+ border-radius: 50%;
290
+ background: var(--bg-surface-raised);
291
+ color: var(--fg-muted);
292
+ flex-shrink: 0;
293
+ }
294
+
295
+ .item.selected .item-icon {
296
+ background: rgba(255, 255, 255, 0.2);
297
+ color: white;
298
+ }
299
+
300
+ .item-icon svg,
301
+ .item-icon sw-ui-icon {
302
+ width: 20px;
303
+ height: 20px;
304
+ }
305
+
306
+ .item-content {
307
+ flex: 1;
308
+ min-width: 0;
309
+ }
310
+
311
+ .item-name {
312
+ font-size: var(--type-size-small);
313
+ font-weight: 500;
314
+ color: inherit;
315
+ white-space: nowrap;
316
+ overflow: hidden;
317
+ text-overflow: ellipsis;
318
+ }
319
+
320
+ .item-type {
321
+ font-size: var(--type-size-caption);
322
+ color: var(--fg-muted);
323
+ text-transform: capitalize;
324
+ }
325
+
326
+ .item-channels {
327
+ display: flex;
328
+ gap: var(--sp-1);
329
+ color: var(--fg-muted);
330
+ }
331
+
332
+ .item-channels sw-ui-icon {
333
+ width: 16px;
334
+ height: 16px;
335
+ }
336
+
337
+ .item-channels sw-ui-icon.active {
338
+ color: var(--interactive-status-success);
339
+ }
340
+
341
+ .loading,
342
+ .empty {
343
+ display: flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ padding: var(--sp-4);
347
+ color: var(--fg-muted);
348
+ font-size: var(--type-size-small);
349
+ }
350
+
351
+ .scroll-sentinel {
352
+ display: flex;
353
+ align-items: center;
354
+ justify-content: center;
355
+ padding: var(--sp-3);
356
+ min-height: 1px;
357
+ }
358
+
359
+ .scroll-loading {
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: center;
363
+ gap: var(--sp-2);
364
+ padding: var(--sp-3);
365
+ color: var(--fg-muted);
366
+ font-size: var(--type-size-caption);
367
+ }
368
+
369
+ .spinner {
370
+ width: 16px;
371
+ height: 16px;
372
+ border: 2px solid var(--border-default);
373
+ border-top-color: var(--interactive-button-primary-bg);
374
+ border-radius: 50%;
375
+ animation: spin 0.8s linear infinite;
376
+ }
377
+
378
+ @keyframes spin {
379
+ to {
380
+ transform: rotate(360deg);
381
+ }
382
+ }
383
+
384
+ .dial-button {
385
+ display: flex;
386
+ align-items: center;
387
+ justify-content: center;
388
+ width: 36px;
389
+ height: 36px;
390
+ background: var(--interactive-status-success);
391
+ border: none;
392
+ border-radius: 50%;
393
+ color: white;
394
+ cursor: pointer;
395
+ flex-shrink: 0;
396
+ transition: background-color 0.15s ease;
397
+ }
398
+
399
+ .dial-button:hover {
400
+ background: #0ea472;
401
+ }
402
+
403
+ .dial-button sw-ui-icon {
404
+ pointer-events: none;
405
+ }
406
+ `;
407
+ n([
408
+ m({ type: Object })
409
+ ], r.prototype, "directory", 2);
410
+ n([
411
+ l()
412
+ ], r.prototype, "selectedAddress", 2);
413
+ n([
414
+ l()
415
+ ], r.prototype, "searchQuery", 2);
416
+ n([
417
+ l()
418
+ ], r.prototype, "addresses", 2);
419
+ n([
420
+ l()
421
+ ], r.prototype, "loading", 2);
422
+ n([
423
+ l()
424
+ ], r.prototype, "hasMore", 2);
425
+ n([
426
+ l()
427
+ ], r.prototype, "isAutoLoadingForSearch", 2);
428
+ r = n([
429
+ b("sw-directory")
430
+ ], r);
431
+ export {
432
+ r as SwDirectory
433
+ };
434
+ //# sourceMappingURL=sw-directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-directory.js","sources":["../../src/components/sw-directory.ts"],"sourcesContent":["/**\n * Directory Component\n *\n * A searchable list of addresses from the directory service.\n * Supports filtering, selection, and pagination.\n *\n * @example\n * ```html\n * <sw-directory .directory=${directory}></sw-directory>\n * ```\n *\n * @fires sw-address-select - Fired when an address is selected. Detail: `{ address: Address }`\n * @fires sw-dial - Fired when the call button on an address is clicked. Detail: `{ address: Address, channel: string }`\n *\n * @cssprop [--interactive-button-primary-bg=#044ef4] - Primary brand color\n * @cssprop [--interactive-button-primary-hover=#0342cf] - Primary color on hover\n * @cssprop [--interactive-status-success=#22c55e] - Success/positive color\n * @cssprop [--fg-default=#f0f0f4] - Primary text color\n * @cssprop [--fg-muted=#a0a0aa] - Secondary/muted text color\n * @cssprop [--bg-surface=#181a28] - Component background color\n * @cssprop [--bg-surface-raised=#222436] - Background color on hover\n * @cssprop [--interactive-dropdown-hover=#333338] - Background color on active/press\n * @cssprop [--border-default=rgba(255,255,255,0.12)] - Border color\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { Subscription } from 'rxjs';\nimport type { Observable } from 'rxjs';\nimport './UI/icons/sw-ui-icon.js';\n\n/**\n * Address type from SDK\n */\nexport interface Address {\n id: string;\n name: string;\n displayName?: string;\n type?: 'room' | 'person';\n channels?: {\n audio?: boolean;\n video?: boolean;\n messaging?: boolean;\n };\n}\n\n/**\n * Directory interface for component\n */\nexport interface DirectoryService {\n addresses$: Observable<Address[]>;\n loading$?: Observable<boolean>;\n hasMore$?: Observable<boolean>;\n loadMore?(): Promise<void>;\n}\n\n@customElement('sw-directory')\nexport class SwDirectory extends LitElement {\n static styles = css`\n :host {\n display: block;\n font-family: var(--type-family-body);\n color: var(--fg-default);\n }\n\n .container {\n display: flex;\n flex-direction: column;\n background: var(--bg-surface);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n overflow: hidden;\n }\n\n .search {\n display: flex;\n align-items: center;\n gap: var(--sp-2);\n padding: var(--sp-3);\n border-bottom: 1px solid var(--border-default);\n }\n\n .search-input {\n flex: 1;\n padding: var(--sp-2) var(--sp-3);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n color: var(--fg-default);\n font-family: var(--type-family-body);\n font-size: var(--type-size-small);\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .search-input:focus {\n border-color: var(--interactive-button-primary-bg);\n }\n\n .search-input::placeholder {\n color: var(--fg-muted);\n }\n\n .list {\n display: flex;\n flex-direction: column;\n max-height: 400px;\n overflow-y: auto;\n }\n\n .item {\n display: flex;\n align-items: center;\n gap: var(--sp-3);\n padding: var(--sp-3) var(--sp-4);\n border-bottom: 1px solid var(--border-default);\n cursor: pointer;\n transition: background-color 0.15s ease;\n }\n\n .item:last-child {\n border-bottom: none;\n }\n\n .item:hover {\n background: var(--bg-surface-raised);\n }\n\n .item:active {\n background: var(--interactive-dropdown-hover);\n }\n\n .item.selected {\n background: var(--interactive-button-primary-bg);\n color: white;\n }\n\n .item.selected .item-type,\n .item.selected .item-channels {\n color: rgba(255, 255, 255, 0.8);\n }\n\n .item-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: var(--bg-surface-raised);\n color: var(--fg-muted);\n flex-shrink: 0;\n }\n\n .item.selected .item-icon {\n background: rgba(255, 255, 255, 0.2);\n color: white;\n }\n\n .item-icon svg,\n .item-icon sw-ui-icon {\n width: 20px;\n height: 20px;\n }\n\n .item-content {\n flex: 1;\n min-width: 0;\n }\n\n .item-name {\n font-size: var(--type-size-small);\n font-weight: 500;\n color: inherit;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .item-type {\n font-size: var(--type-size-caption);\n color: var(--fg-muted);\n text-transform: capitalize;\n }\n\n .item-channels {\n display: flex;\n gap: var(--sp-1);\n color: var(--fg-muted);\n }\n\n .item-channels sw-ui-icon {\n width: 16px;\n height: 16px;\n }\n\n .item-channels sw-ui-icon.active {\n color: var(--interactive-status-success);\n }\n\n .loading,\n .empty {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--sp-4);\n color: var(--fg-muted);\n font-size: var(--type-size-small);\n }\n\n .scroll-sentinel {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--sp-3);\n min-height: 1px;\n }\n\n .scroll-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--sp-2);\n padding: var(--sp-3);\n color: var(--fg-muted);\n font-size: var(--type-size-caption);\n }\n\n .spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--border-default);\n border-top-color: var(--interactive-button-primary-bg);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n }\n\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .dial-button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: var(--interactive-status-success);\n border: none;\n border-radius: 50%;\n color: white;\n cursor: pointer;\n flex-shrink: 0;\n transition: background-color 0.15s ease;\n }\n\n .dial-button:hover {\n background: #0ea472;\n }\n\n .dial-button sw-ui-icon {\n pointer-events: none;\n }\n `;\n\n /**\n * Directory service with addresses$ observable\n */\n @property({ type: Object })\n directory: DirectoryService | null = null;\n\n /**\n * Currently selected address\n */\n @state()\n private selectedAddress: Address | null = null;\n\n /**\n * Search filter query\n */\n @state()\n private searchQuery: string = '';\n\n /**\n * List of addresses from directory\n */\n @state()\n private addresses: Address[] = [];\n\n /**\n * Loading state\n */\n @state()\n private loading: boolean = false;\n\n /**\n * Has more addresses to load\n */\n @state()\n private hasMore: boolean = false;\n\n /**\n * RxJS subscriptions for cleanup\n */\n private subscriptions: Subscription[] = [];\n\n /**\n * Debounce timer for search\n */\n private searchDebounceTimer: number | null = null;\n\n /**\n * IntersectionObserver for infinite scroll\n */\n private intersectionObserver: IntersectionObserver | null = null;\n\n /**\n * Flag to track if we're auto-loading for search\n */\n @state()\n private isAutoLoadingForSearch: boolean = false;\n\n connectedCallback() {\n super.connectedCallback();\n this.subscribeToDirectory();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanup();\n }\n\n private subscribeToDirectory() {\n if (!this.directory) return;\n\n // Subscribe to addresses\n if (this.directory.addresses$) {\n const addressesSub = this.directory.addresses$.subscribe((addresses) => {\n this.addresses = addresses;\n });\n this.subscriptions.push(addressesSub);\n }\n\n // Subscribe to loading state\n if (this.directory.loading$) {\n const loadingSub = this.directory.loading$.subscribe((loading) => {\n this.loading = loading;\n });\n this.subscriptions.push(loadingSub);\n }\n\n // Subscribe to hasMore\n if (this.directory.hasMore$) {\n const hasMoreSub = this.directory.hasMore$.subscribe((hasMore) => {\n this.hasMore = hasMore;\n });\n this.subscriptions.push(hasMoreSub);\n }\n\n // Load initial data\n if (this.directory.loadMore) {\n this.directory.loadMore();\n }\n }\n\n private cleanup() {\n this.subscriptions.forEach((sub) => sub.unsubscribe());\n this.subscriptions = [];\n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n }\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n this.intersectionObserver = null;\n }\n }\n\n protected firstUpdated() {\n this.setupInfiniteScroll();\n }\n\n private setupInfiniteScroll() {\n const sentinel = this.shadowRoot?.querySelector('.scroll-sentinel');\n if (!sentinel) return;\n\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n if (entry?.isIntersecting && this.hasMore && !this.loading) {\n this.handleLoadMore();\n }\n },\n {\n root: this.shadowRoot?.querySelector('.list'),\n rootMargin: '100px',\n threshold: 0\n }\n );\n\n this.intersectionObserver.observe(sentinel);\n }\n\n protected updated(changedProperties: Map<string, unknown>) {\n super.updated(changedProperties);\n\n // Handle directory property changes\n if (changedProperties.has('directory')) {\n this.cleanup();\n this.subscribeToDirectory();\n }\n\n // Re-setup infinite scroll if needed\n if (!this.intersectionObserver) {\n this.setupInfiniteScroll();\n }\n\n // Auto-load more when searching and no results found but more available\n // Also check when loading state changes so we can trigger subsequent loads\n if (\n changedProperties.has('addresses') ||\n changedProperties.has('searchQuery') ||\n changedProperties.has('loading')\n ) {\n this.checkAutoLoadForSearch();\n }\n }\n\n private async checkAutoLoadForSearch() {\n // If we have a search query, no filtered results, but more to load, keep loading\n // Note: !this.loading prevents concurrent loads, isAutoLoadingForSearch is for UI state only\n if (\n this.searchQuery.trim() &&\n this.filteredAddresses.length === 0 &&\n this.hasMore &&\n !this.loading\n ) {\n this.isAutoLoadingForSearch = true;\n await this.handleLoadMore();\n // The updated() will be called again when addresses/loading change, continuing the loop\n } else if (this.filteredAddresses.length > 0 || !this.hasMore) {\n this.isAutoLoadingForSearch = false;\n }\n }\n\n private get filteredAddresses(): Address[] {\n if (!this.searchQuery.trim()) {\n return this.addresses;\n }\n const query = this.searchQuery.toLowerCase();\n return this.addresses.filter(\n (addr) =>\n addr.name.toLowerCase().includes(query) ||\n (addr.displayName && addr.displayName.toLowerCase().includes(query))\n );\n }\n\n private handleSearchInput(e: Event) {\n const input = e.target as HTMLInputElement;\n\n // Debounce search\n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n }\n\n this.searchDebounceTimer = window.setTimeout(() => {\n this.searchQuery = input.value;\n }, 200);\n }\n\n private handleItemClick(address: Address) {\n this.selectedAddress = address;\n\n this.dispatchEvent(\n new CustomEvent('sw-address-select', {\n detail: { address },\n bubbles: true,\n composed: true\n })\n );\n }\n\n private handleItemDoubleClick(address: Address) {\n this.handleDial(address);\n }\n\n private handleDial(address: Address) {\n this.dispatchEvent(\n new CustomEvent('sw-dial', {\n detail: { address },\n bubbles: true,\n composed: true\n })\n );\n }\n\n private async handleLoadMore() {\n if (this.directory?.loadMore) {\n await this.directory.loadMore();\n }\n }\n\n private renderAddressIcon(address: Address) {\n const name = address.type === 'room' ? 'room' : 'person';\n return html`<sw-ui-icon name=${name} size=\"20\"></sw-ui-icon>`;\n }\n\n private renderChannelIcons(address: Address) {\n const channels = address.channels || {};\n return html`\n <div class=\"item-channels\">\n <sw-ui-icon\n name=\"mic-on\"\n size=\"16\"\n class=\"${channels.audio ? 'active' : ''}\"\n title=\"Audio\"\n ></sw-ui-icon>\n <sw-ui-icon\n name=\"camera-on\"\n size=\"16\"\n class=\"${channels.video ? 'active' : ''}\"\n title=\"Video\"\n ></sw-ui-icon>\n </div>\n `;\n }\n\n private renderLoadingIndicator() {\n return html`\n <div class=\"scroll-loading\">\n <div class=\"spinner\"></div>\n <span>${this.isAutoLoadingForSearch ? 'Searching...' : 'Loading more...'}</span>\n </div>\n `;\n }\n\n render() {\n const showInitialLoading = this.loading && this.addresses.length === 0;\n const showEmptyState = !this.loading && this.filteredAddresses.length === 0 && !this.hasMore;\n const showSearchingState = this.isAutoLoadingForSearch && this.filteredAddresses.length === 0;\n\n return html`\n <div class=\"container\" part=\"container\">\n <div class=\"search\" part=\"search\">\n <input\n type=\"text\"\n class=\"search-input\"\n placeholder=\"Search addresses...\"\n @input=${this.handleSearchInput}\n aria-label=\"Search addresses\"\n />\n </div>\n\n <div class=\"list\" part=\"list\" role=\"listbox\">\n ${showInitialLoading\n ? html`<div class=\"loading\">Loading...</div>`\n : showSearchingState\n ? this.renderLoadingIndicator()\n : showEmptyState\n ? html`<div class=\"empty\">No addresses found</div>`\n : html`\n ${this.filteredAddresses.map(\n (address) => html`\n <div\n class=\"item ${this.selectedAddress?.id === address.id ? 'selected' : ''}\"\n part=\"item ${this.selectedAddress?.id === address.id\n ? 'item-selected'\n : ''}\"\n role=\"option\"\n aria-selected=\"${this.selectedAddress?.id === address.id}\"\n @click=${() => this.handleItemClick(address)}\n @dblclick=${() => this.handleItemDoubleClick(address)}\n >\n <div class=\"item-icon\">${this.renderAddressIcon(address)}</div>\n <div class=\"item-content\">\n <div class=\"item-name\" part=\"item-name\">\n ${address.displayName || address.name}\n </div>\n <div class=\"item-type\" part=\"item-type\">\n ${address.type || 'address'}\n </div>\n </div>\n ${this.renderChannelIcons(address)}\n <button\n class=\"dial-button\"\n @click=${(e: Event) => {\n e.stopPropagation();\n this.handleDial(address);\n }}\n aria-label=\"Call ${address.displayName || address.name}\"\n >\n <sw-ui-icon name=\"phone-call\" size=\"18\"></sw-ui-icon>\n </button>\n </div>\n `\n )}\n <!-- Scroll sentinel for infinite scroll -->\n <div class=\"scroll-sentinel\">\n ${this.loading && !this.isAutoLoadingForSearch\n ? this.renderLoadingIndicator()\n : null}\n </div>\n `}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sw-directory': SwDirectory;\n }\n}\n"],"names":["SwDirectory","LitElement","addressesSub","addresses","loadingSub","loading","hasMoreSub","hasMore","sub","sentinel","_a","entries","entry","_b","changedProperties","query","addr","input","address","name","html","channels","showInitialLoading","showEmptyState","showSearchingState","_c","e","css","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { LitElement } from 'lit';
2
+ import type { Call } from '../types/index.js';
3
+ import './UI/icons/sw-ui-icon.js';
4
+ /**
5
+ * Local camera preview. Adapts its aspect-ratio to match the actual
6
+ * video track (landscape or portrait).
7
+ *
8
+ * Input precedence : `.stream`/`.videoMuted` > `.call` > context.
9
+ *
10
+ * @prop {MediaStream|null} stream - explicit stream (overrides .call and context)
11
+ * @prop {boolean} videoMuted - explicit muted flag (overrides context)
12
+ * @prop {Call} call - explicit Call object (overrides context)
13
+ * @prop {boolean} mirror - mirror the video horizontally
14
+ *
15
+ * @csspart video - The `<video>` element.
16
+ * @csspart placeholder - Camera-off overlay shown while muted.
17
+ *
18
+ * @cssprop [--sw-local-camera-aspect=16/9] - Aspect ratio; auto-set from track settings when available.
19
+ */
20
+ export declare class SwLocalCamera extends LitElement {
21
+ /** Explicit stream — highest precedence. */
22
+ stream: MediaStream | null;
23
+ /** Explicit muted flag — overrides devicesContext.videoMuted. */
24
+ videoMuted?: boolean;
25
+ /** Explicit Call — used when `.stream` is not set. Bypasses context. */
26
+ call?: Call;
27
+ mirror: boolean;
28
+ private _callState?;
29
+ private _devicesState?;
30
+ private _directLocalStream;
31
+ private _directSubscriptions;
32
+ /** Detected aspect ratio from the video track, e.g. "16 / 9" or "9 / 16". */
33
+ private _aspectRatio;
34
+ /** Last stream reference attached to the video element — used to skip no-op re-attaches. */
35
+ private _attachedStream;
36
+ static styles: import("lit").CSSResult;
37
+ private get _effectiveStream();
38
+ private get _effectiveMuted();
39
+ protected firstUpdated(): void;
40
+ protected updated(changedProperties: Map<string, unknown>): void;
41
+ disconnectedCallback(): void;
42
+ private _setupDirect;
43
+ private _teardownDirect;
44
+ /** Read the video track settings and set the CSS custom property. */
45
+ private _detectAspectRatio;
46
+ render(): import("lit-html").TemplateResult<1>;
47
+ }
48
+ declare global {
49
+ interface HTMLElementTagNameMap {
50
+ 'sw-local-camera': SwLocalCamera;
51
+ }
52
+ }
53
+ //# sourceMappingURL=sw-local-camera.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sw-local-camera.d.ts","sourceRoot":"","sources":["../../src/components/sw-local-camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAO5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;GAeG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,4CAA4C;IACZ,MAAM,EAAE,WAAW,GAAG,IAAI,CAAQ;IAElE,iEAAiE;IACK,UAAU,CAAC,EAAE,OAAO,CAAC;IAE3F,wEAAwE;IAC5C,IAAI,CAAC,EAAE,IAAI,CAAC;IAEI,MAAM,UAAS;IAI3D,OAAO,CAAC,UAAU,CAAC,CAAY;IAI/B,OAAO,CAAC,aAAa,CAAC,CAAe;IAE5B,OAAO,CAAC,kBAAkB,CAA4B;IAE/D,OAAO,CAAC,oBAAoB,CAAsB;IAElD,6EAA6E;IACpE,OAAO,CAAC,YAAY,CAAY;IAEzC,4FAA4F;IAC5F,OAAO,CAAC,eAAe,CAA4B;IAEnD,MAAM,CAAC,MAAM,0BAoCX;IAEF,OAAO,KAAK,gBAAgB,GAI3B;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,SAAS,CAAC,YAAY,IAAI,IAAI;IAa9B,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA8ChE,oBAAoB,IAAI,IAAI;IAO5B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,eAAe;IAMvB,qEAAqE;IACrE,OAAO,CAAC,kBAAkB;IAiB1B,MAAM;CAUP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
@@ -0,0 +1,147 @@
1
+ import { LitElement as p, html as n, css as m } from "lit";
2
+ import { property as l, state as d, customElement as f } from "lit/decorators.js";
3
+ import { consume as h } from "@lit/context";
4
+ import { attachMediaStream as v, detachMediaStream as _ } from "../utils/video.js";
5
+ import { callStateContext as S } from "../context/call-state-context.js";
6
+ import { devicesContext as b } from "../context/devices-context.js";
7
+ var y = Object.defineProperty, w = Object.getOwnPropertyDescriptor, c = (t, e, s, r) => {
8
+ for (var i = r > 1 ? void 0 : r ? w(e, s) : e, o = t.length - 1, u; o >= 0; o--)
9
+ (u = t[o]) && (i = (r ? u(e, s, i) : u(i)) || i);
10
+ return r && i && y(e, s, i), i;
11
+ };
12
+ let a = class extends p {
13
+ constructor() {
14
+ super(...arguments), this.stream = null, this.mirror = !1, this._directLocalStream = null, this._directSubscriptions = [], this._aspectRatio = "16 / 9", this._attachedStream = null;
15
+ }
16
+ get _effectiveStream() {
17
+ var t;
18
+ return this.stream ? this.stream : this.call ? this._directLocalStream : ((t = this._callState) == null ? void 0 : t.localStream) ?? null;
19
+ }
20
+ get _effectiveMuted() {
21
+ var t;
22
+ return this.videoMuted ?? ((t = this._devicesState) == null ? void 0 : t.videoMuted) ?? !1;
23
+ }
24
+ firstUpdated() {
25
+ var e;
26
+ const t = (e = this.shadowRoot) == null ? void 0 : e.querySelector("video");
27
+ t && t.addEventListener("pause", () => {
28
+ this._effectiveMuted || t.play().catch(() => {
29
+ });
30
+ });
31
+ }
32
+ updated(t) {
33
+ var r, i;
34
+ super.updated(t), t.has("call") && (this._teardownDirect(), this.call && this._setupDirect(this.call));
35
+ const e = this._effectiveStream, s = t.has("stream") || t.has("call") || t.has("_directLocalStream") || t.has("_callState") && e !== this._attachedStream;
36
+ if (s) {
37
+ const o = (r = this.shadowRoot) == null ? void 0 : r.querySelector("video");
38
+ o && (this._attachedStream = e, v(o, e), this._detectAspectRatio());
39
+ }
40
+ if ((t.has("videoMuted") || t.has("_devicesState") || s) && !this._effectiveMuted) {
41
+ const o = (i = this.shadowRoot) == null ? void 0 : i.querySelector("video");
42
+ o && o.play().catch(() => {
43
+ });
44
+ }
45
+ }
46
+ disconnectedCallback() {
47
+ var e;
48
+ super.disconnectedCallback();
49
+ const t = (e = this.shadowRoot) == null ? void 0 : e.querySelector("video");
50
+ t && _(t), this._teardownDirect();
51
+ }
52
+ _setupDirect(t) {
53
+ this._directSubscriptions.push(
54
+ t.localStream$.subscribe((e) => this._directLocalStream = e)
55
+ );
56
+ }
57
+ _teardownDirect() {
58
+ this._directSubscriptions.forEach((t) => t.unsubscribe()), this._directSubscriptions = [], this._directLocalStream = null;
59
+ }
60
+ /** Read the video track settings and set the CSS custom property. */
61
+ _detectAspectRatio() {
62
+ const t = this._effectiveStream;
63
+ if (!t) return;
64
+ const e = t.getVideoTracks()[0];
65
+ if (!e) return;
66
+ const s = e.getSettings(), r = s.width, i = s.height;
67
+ r && i && r > 0 && i > 0 && (this._aspectRatio = `${r} / ${i}`, this.style.setProperty("--sw-local-camera-aspect", this._aspectRatio));
68
+ }
69
+ render() {
70
+ return n`
71
+ <video part="video" autoplay playsinline muted></video>
72
+ ${this._effectiveMuted ? n`<div part="placeholder" class="muted-overlay">
73
+ <sw-ui-icon name="camera-off" size="28"></sw-ui-icon>
74
+ </div>` : null}
75
+ `;
76
+ }
77
+ };
78
+ a.styles = m`
79
+ :host {
80
+ display: block;
81
+ width: 100%;
82
+ aspect-ratio: var(--sw-local-camera-aspect, 16 / 9);
83
+ position: relative;
84
+ background: #000;
85
+ border-radius: inherit;
86
+ }
87
+
88
+ video {
89
+ width: 100%;
90
+ height: 100%;
91
+ object-fit: cover;
92
+ display: block;
93
+ border-radius: inherit;
94
+ }
95
+
96
+ :host([mirror]) video {
97
+ transform: scaleX(-1);
98
+ }
99
+
100
+ .muted-overlay {
101
+ position: absolute;
102
+ inset: 0;
103
+ z-index: 1;
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: center;
107
+ background: var(--bg-page);
108
+ border-radius: inherit;
109
+ }
110
+
111
+ .muted-overlay sw-ui-icon {
112
+ color: var(--bg-surface-raised);
113
+ }
114
+ `;
115
+ c([
116
+ l({ attribute: !1 })
117
+ ], a.prototype, "stream", 2);
118
+ c([
119
+ l({ type: Boolean, reflect: !0, attribute: "video-muted" })
120
+ ], a.prototype, "videoMuted", 2);
121
+ c([
122
+ l({ type: Object })
123
+ ], a.prototype, "call", 2);
124
+ c([
125
+ l({ type: Boolean, reflect: !0 })
126
+ ], a.prototype, "mirror", 2);
127
+ c([
128
+ h({ context: S, subscribe: !0 }),
129
+ d()
130
+ ], a.prototype, "_callState", 2);
131
+ c([
132
+ h({ context: b, subscribe: !0 }),
133
+ d()
134
+ ], a.prototype, "_devicesState", 2);
135
+ c([
136
+ d()
137
+ ], a.prototype, "_directLocalStream", 2);
138
+ c([
139
+ d()
140
+ ], a.prototype, "_aspectRatio", 2);
141
+ a = c([
142
+ f("sw-local-camera")
143
+ ], a);
144
+ export {
145
+ a as SwLocalCamera
146
+ };
147
+ //# sourceMappingURL=sw-local-camera.js.map