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

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 (79) hide show
  1. package/README.md +106 -101
  2. package/dist/components/audio-level.d.ts +106 -0
  3. package/dist/components/audio-level.d.ts.map +1 -0
  4. package/dist/components/audio-level.js +203 -0
  5. package/dist/components/audio-level.js.map +1 -0
  6. package/dist/components/call-controls.d.ts +163 -0
  7. package/dist/components/call-controls.d.ts.map +1 -0
  8. package/dist/components/call-controls.js +606 -0
  9. package/dist/components/call-controls.js.map +1 -0
  10. package/dist/components/call-media.d.ts +114 -0
  11. package/dist/components/call-media.d.ts.map +1 -0
  12. package/dist/components/call-media.js +219 -0
  13. package/dist/components/call-media.js.map +1 -0
  14. package/dist/components/call-status.d.ts +68 -0
  15. package/dist/components/call-status.d.ts.map +1 -0
  16. package/dist/components/call-status.js +254 -0
  17. package/dist/components/call-status.js.map +1 -0
  18. package/dist/components/click-to-call.d.ts +123 -0
  19. package/dist/components/click-to-call.d.ts.map +1 -0
  20. package/dist/components/click-to-call.js +428 -0
  21. package/dist/components/click-to-call.js.map +1 -0
  22. package/dist/components/device-selector.d.ts +224 -0
  23. package/dist/components/device-selector.d.ts.map +1 -0
  24. package/dist/components/device-selector.js +685 -0
  25. package/dist/components/device-selector.js.map +1 -0
  26. package/dist/components/dialpad.d.ts +60 -0
  27. package/dist/components/dialpad.d.ts.map +1 -0
  28. package/dist/components/dialpad.js +372 -0
  29. package/dist/components/dialpad.js.map +1 -0
  30. package/dist/components/directory.d.ts +103 -0
  31. package/dist/components/directory.d.ts.map +1 -0
  32. package/dist/components/directory.js +503 -0
  33. package/dist/components/directory.js.map +1 -0
  34. package/dist/components/example-button.d.ts +20 -0
  35. package/dist/components/example-button.d.ts.map +1 -0
  36. package/dist/components/example-button.js +74 -0
  37. package/dist/components/example-button.js.map +1 -0
  38. package/dist/components/participant-controls.d.ts +94 -0
  39. package/dist/components/participant-controls.d.ts.map +1 -0
  40. package/dist/components/participant-controls.js +468 -0
  41. package/dist/components/participant-controls.js.map +1 -0
  42. package/dist/components/participants.d.ts +116 -0
  43. package/dist/components/participants.d.ts.map +1 -0
  44. package/dist/components/participants.js +394 -0
  45. package/dist/components/participants.js.map +1 -0
  46. package/dist/components/self-media.d.ts +78 -0
  47. package/dist/components/self-media.d.ts.map +1 -0
  48. package/dist/components/self-media.js +129 -0
  49. package/dist/components/self-media.js.map +1 -0
  50. package/dist/constants.d.ts +10 -0
  51. package/dist/constants.d.ts.map +1 -0
  52. package/dist/constants.js +5 -0
  53. package/dist/constants.js.map +1 -0
  54. package/dist/context/call-context.d.ts +13 -0
  55. package/dist/context/call-context.d.ts.map +1 -0
  56. package/dist/context/call-context.js +6 -0
  57. package/dist/context/call-context.js.map +1 -0
  58. package/dist/context/index.d.ts +2 -0
  59. package/dist/context/index.d.ts.map +1 -0
  60. package/dist/index.d.ts +29 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +35 -5644
  63. package/dist/index.js.map +1 -1
  64. package/dist/react.d.ts +101 -0
  65. package/dist/types/index.d.ts +44 -0
  66. package/dist/types/index.d.ts.map +1 -0
  67. package/dist/types/index.js +12 -0
  68. package/dist/types/index.js.map +1 -0
  69. package/dist/utils/debounce.d.ts +10 -0
  70. package/dist/utils/debounce.d.ts.map +1 -0
  71. package/dist/utils/debounce.js +13 -0
  72. package/dist/utils/debounce.js.map +1 -0
  73. package/dist/utils/index.d.ts +3 -0
  74. package/dist/utils/index.d.ts.map +1 -0
  75. package/dist/utils/video.d.ts +34 -0
  76. package/dist/utils/video.d.ts.map +1 -0
  77. package/dist/utils/video.js +26 -0
  78. package/dist/utils/video.js.map +1 -0
  79. package/package.json +70 -3
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Directory Component
3
+ *
4
+ * A searchable list of addresses from the directory service.
5
+ * Supports filtering, selection, and pagination.
6
+ *
7
+ * @example
8
+ * ```html
9
+ * <sw-directory .directory=${directory}></sw-directory>
10
+ * ```
11
+ */
12
+ import { LitElement } from 'lit';
13
+ import type { Observable } from 'rxjs';
14
+ /**
15
+ * Address type from SDK
16
+ */
17
+ export interface Address {
18
+ id: string;
19
+ name: string;
20
+ displayName?: string;
21
+ type?: 'room' | 'person';
22
+ channels?: {
23
+ audio?: boolean;
24
+ video?: boolean;
25
+ messaging?: boolean;
26
+ };
27
+ }
28
+ /**
29
+ * Directory interface for component
30
+ */
31
+ export interface DirectoryService {
32
+ addresses$: Observable<Address[]>;
33
+ loading$?: Observable<boolean>;
34
+ hasMore$?: Observable<boolean>;
35
+ loadMore?(): Promise<void>;
36
+ }
37
+ export declare class DirectoryComponent extends LitElement {
38
+ static styles: import("lit").CSSResult;
39
+ /**
40
+ * Directory service with addresses$ observable
41
+ */
42
+ directory: DirectoryService | null;
43
+ /**
44
+ * Currently selected address
45
+ */
46
+ private selectedAddress;
47
+ /**
48
+ * Search filter query
49
+ */
50
+ private searchQuery;
51
+ /**
52
+ * List of addresses from directory
53
+ */
54
+ private addresses;
55
+ /**
56
+ * Loading state
57
+ */
58
+ private loading;
59
+ /**
60
+ * Has more addresses to load
61
+ */
62
+ private hasMore;
63
+ /**
64
+ * RxJS subscriptions for cleanup
65
+ */
66
+ private subscriptions;
67
+ /**
68
+ * Debounce timer for search
69
+ */
70
+ private searchDebounceTimer;
71
+ /**
72
+ * IntersectionObserver for infinite scroll
73
+ */
74
+ private intersectionObserver;
75
+ /**
76
+ * Flag to track if we're auto-loading for search
77
+ */
78
+ private isAutoLoadingForSearch;
79
+ connectedCallback(): void;
80
+ disconnectedCallback(): void;
81
+ private subscribeToDirectory;
82
+ private cleanup;
83
+ protected firstUpdated(): void;
84
+ private setupInfiniteScroll;
85
+ protected updated(changedProperties: Map<string, unknown>): void;
86
+ private checkAutoLoadForSearch;
87
+ private get filteredAddresses();
88
+ private handleSearchInput;
89
+ private handleItemClick;
90
+ private handleItemDoubleClick;
91
+ private handleDial;
92
+ private handleLoadMore;
93
+ private renderAddressIcon;
94
+ private renderChannelIcons;
95
+ private renderLoadingIndicator;
96
+ render(): import("lit-html").TemplateResult<1>;
97
+ }
98
+ declare global {
99
+ interface HTMLElementTagNameMap {
100
+ 'sw-directory': DirectoryComponent;
101
+ }
102
+ }
103
+ //# sourceMappingURL=directory.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,503 @@
1
+ import { LitElement as p, html as i, css as u } from "lit";
2
+ import { property as v, state as d, customElement as w } from "lit/decorators.js";
3
+ var b = Object.defineProperty, m = Object.getOwnPropertyDescriptor, c = (e, s, a, r) => {
4
+ for (var t = r > 1 ? void 0 : r ? m(s, a) : s, n = e.length - 1, l; n >= 0; n--)
5
+ (l = e[n]) && (t = (r ? l(s, a, t) : l(t)) || t);
6
+ return r && t && b(s, a, t), t;
7
+ };
8
+ let o = class extends p {
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((s) => {
22
+ this.addresses = s;
23
+ });
24
+ this.subscriptions.push(e);
25
+ }
26
+ if (this.directory.loading$) {
27
+ const e = this.directory.loading$.subscribe((s) => {
28
+ this.loading = s;
29
+ });
30
+ this.subscriptions.push(e);
31
+ }
32
+ if (this.directory.hasMore$) {
33
+ const e = this.directory.hasMore$.subscribe((s) => {
34
+ this.hasMore = s;
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 s, a;
49
+ const e = (s = this.shadowRoot) == null ? void 0 : s.querySelector(".scroll-sentinel");
50
+ e && (this.intersectionObserver = new IntersectionObserver(
51
+ (r) => {
52
+ const t = r[0];
53
+ t != null && t.isIntersecting && this.hasMore && !this.loading && this.handleLoadMore();
54
+ },
55
+ {
56
+ root: (a = this.shadowRoot) == null ? void 0 : a.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
+ (s) => s.name.toLowerCase().includes(e) || s.displayName && s.displayName.toLowerCase().includes(e)
74
+ );
75
+ }
76
+ handleSearchInput(e) {
77
+ const s = e.target;
78
+ this.searchDebounceTimer && clearTimeout(this.searchDebounceTimer), this.searchDebounceTimer = window.setTimeout(() => {
79
+ this.searchQuery = s.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
+ return e.type === "room" ? i`
109
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
110
+ <path
111
+ d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.93 0 3.5 1.57 3.5 3.5S13.93 13 12 13s-3.5-1.57-3.5-3.5S10.07 6 12 6zm7 13H5v-.23c0-.62.28-1.2.76-1.58C7.47 15.82 9.64 15 12 15s4.53.82 6.24 2.19c.48.38.76.97.76 1.58V19z"
112
+ />
113
+ </svg>
114
+ ` : i`
115
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
116
+ <path
117
+ d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"
118
+ />
119
+ </svg>
120
+ `;
121
+ }
122
+ renderChannelIcons(e) {
123
+ const s = e.channels || {};
124
+ return i`
125
+ <div class="item-channels">
126
+ <svg
127
+ xmlns="http://www.w3.org/2000/svg"
128
+ viewBox="0 0 24 24"
129
+ fill="currentColor"
130
+ class="${s.audio ? "active" : ""}"
131
+ title="Audio"
132
+ >
133
+ <path
134
+ d="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z"
135
+ />
136
+ </svg>
137
+ <svg
138
+ xmlns="http://www.w3.org/2000/svg"
139
+ viewBox="0 0 24 24"
140
+ fill="currentColor"
141
+ class="${s.video ? "active" : ""}"
142
+ title="Video"
143
+ >
144
+ <path
145
+ 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"
146
+ />
147
+ </svg>
148
+ </div>
149
+ `;
150
+ }
151
+ renderLoadingIndicator() {
152
+ return i`
153
+ <div class="scroll-loading">
154
+ <div class="spinner"></div>
155
+ <span>${this.isAutoLoadingForSearch ? "Searching..." : "Loading more..."}</span>
156
+ </div>
157
+ `;
158
+ }
159
+ render() {
160
+ const e = this.loading && this.addresses.length === 0, s = !this.loading && this.filteredAddresses.length === 0 && !this.hasMore, a = this.isAutoLoadingForSearch && this.filteredAddresses.length === 0;
161
+ return i`
162
+ <div class="container" part="container">
163
+ <div class="search" part="search">
164
+ <input
165
+ type="text"
166
+ class="search-input"
167
+ placeholder="Search addresses..."
168
+ @input=${this.handleSearchInput}
169
+ aria-label="Search addresses"
170
+ />
171
+ </div>
172
+
173
+ <div class="list" part="list" role="listbox">
174
+ ${e ? i`<div class="loading">Loading...</div>` : a ? this.renderLoadingIndicator() : s ? i`<div class="empty">No addresses found</div>` : i`
175
+ ${this.filteredAddresses.map(
176
+ (r) => {
177
+ var t, n, l;
178
+ return i`
179
+ <div
180
+ class="item ${((t = this.selectedAddress) == null ? void 0 : t.id) === r.id ? "selected" : ""}"
181
+ part="item ${((n = this.selectedAddress) == null ? void 0 : n.id) === r.id ? "item-selected" : ""}"
182
+ role="option"
183
+ aria-selected="${((l = this.selectedAddress) == null ? void 0 : l.id) === r.id}"
184
+ @click=${() => this.handleItemClick(r)}
185
+ @dblclick=${() => this.handleItemDoubleClick(r)}
186
+ >
187
+ <div class="item-icon">${this.renderAddressIcon(r)}</div>
188
+ <div class="item-content">
189
+ <div class="item-name" part="item-name">
190
+ ${r.displayName || r.name}
191
+ </div>
192
+ <div class="item-type" part="item-type">
193
+ ${r.type || "address"}
194
+ </div>
195
+ </div>
196
+ ${this.renderChannelIcons(r)}
197
+ <button
198
+ class="dial-button"
199
+ @click=${(h) => {
200
+ h.stopPropagation(), this.handleDial(r);
201
+ }}
202
+ aria-label="Call ${r.displayName || r.name}"
203
+ >
204
+ <svg
205
+ xmlns="http://www.w3.org/2000/svg"
206
+ viewBox="0 0 24 24"
207
+ fill="currentColor"
208
+ >
209
+ <path
210
+ 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"
211
+ />
212
+ </svg>
213
+ </button>
214
+ </div>
215
+ `;
216
+ }
217
+ )}
218
+ <!-- Scroll sentinel for infinite scroll -->
219
+ <div class="scroll-sentinel">
220
+ ${this.loading && !this.isAutoLoadingForSearch ? this.renderLoadingIndicator() : null}
221
+ </div>
222
+ `}
223
+ </div>
224
+ </div>
225
+ `;
226
+ }
227
+ };
228
+ o.styles = u`
229
+ :host {
230
+ /* CSS Custom Properties for theming */
231
+ --sw-color-primary: #044cf6;
232
+ --sw-color-primary-hover: #0339c4;
233
+ --sw-color-success: #10b981;
234
+ --sw-color-text: #1f2937;
235
+ --sw-color-text-muted: #6b7280;
236
+ --sw-color-background: #ffffff;
237
+ --sw-color-background-hover: #f3f4f6;
238
+ --sw-color-background-active: #e5e7eb;
239
+ --sw-color-border: #e5e7eb;
240
+ --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
241
+ --sw-font-size-sm: 12px;
242
+ --sw-font-size-base: 14px;
243
+ --sw-font-size-lg: 16px;
244
+ --sw-space-1: 4px;
245
+ --sw-space-2: 8px;
246
+ --sw-space-3: 12px;
247
+ --sw-space-4: 16px;
248
+ --sw-border-radius: 8px;
249
+
250
+ display: block;
251
+ font-family: var(--sw-font-family);
252
+ }
253
+
254
+ /* Dark mode support */
255
+ :host([data-theme='dark']) {
256
+ --sw-color-text: #f9fafb;
257
+ --sw-color-text-muted: #9ca3af;
258
+ --sw-color-background: #1f2937;
259
+ --sw-color-background-hover: #374151;
260
+ --sw-color-background-active: #4b5563;
261
+ --sw-color-border: #374151;
262
+ }
263
+
264
+ @media (prefers-color-scheme: dark) {
265
+ :host(:not([data-theme='light'])) {
266
+ --sw-color-text: #f9fafb;
267
+ --sw-color-text-muted: #9ca3af;
268
+ --sw-color-background: #1f2937;
269
+ --sw-color-background-hover: #374151;
270
+ --sw-color-background-active: #4b5563;
271
+ --sw-color-border: #374151;
272
+ }
273
+ }
274
+
275
+ .container {
276
+ display: flex;
277
+ flex-direction: column;
278
+ background: var(--sw-color-background);
279
+ border: 1px solid var(--sw-color-border);
280
+ border-radius: var(--sw-border-radius);
281
+ overflow: hidden;
282
+ }
283
+
284
+ .search {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: var(--sw-space-2);
288
+ padding: var(--sw-space-3);
289
+ border-bottom: 1px solid var(--sw-color-border);
290
+ }
291
+
292
+ .search-input {
293
+ flex: 1;
294
+ padding: var(--sw-space-2) var(--sw-space-3);
295
+ border: 1px solid var(--sw-color-border);
296
+ border-radius: var(--sw-border-radius);
297
+ background: var(--sw-color-background);
298
+ color: var(--sw-color-text);
299
+ font-family: var(--sw-font-family);
300
+ font-size: var(--sw-font-size-base);
301
+ outline: none;
302
+ transition: border-color 0.15s ease;
303
+ }
304
+
305
+ .search-input:focus {
306
+ border-color: var(--sw-color-primary);
307
+ }
308
+
309
+ .search-input::placeholder {
310
+ color: var(--sw-color-text-muted);
311
+ }
312
+
313
+ .list {
314
+ display: flex;
315
+ flex-direction: column;
316
+ max-height: 400px;
317
+ overflow-y: auto;
318
+ }
319
+
320
+ .item {
321
+ display: flex;
322
+ align-items: center;
323
+ gap: var(--sw-space-3);
324
+ padding: var(--sw-space-3) var(--sw-space-4);
325
+ border-bottom: 1px solid var(--sw-color-border);
326
+ cursor: pointer;
327
+ transition: background-color 0.15s ease;
328
+ }
329
+
330
+ .item:last-child {
331
+ border-bottom: none;
332
+ }
333
+
334
+ .item:hover {
335
+ background: var(--sw-color-background-hover);
336
+ }
337
+
338
+ .item:active {
339
+ background: var(--sw-color-background-active);
340
+ }
341
+
342
+ .item.selected {
343
+ background: var(--sw-color-primary);
344
+ color: white;
345
+ }
346
+
347
+ .item.selected .item-type,
348
+ .item.selected .item-channels {
349
+ color: rgba(255, 255, 255, 0.8);
350
+ }
351
+
352
+ .item-icon {
353
+ display: flex;
354
+ align-items: center;
355
+ justify-content: center;
356
+ width: 40px;
357
+ height: 40px;
358
+ border-radius: 50%;
359
+ background: var(--sw-color-background-hover);
360
+ color: var(--sw-color-text-muted);
361
+ flex-shrink: 0;
362
+ }
363
+
364
+ .item.selected .item-icon {
365
+ background: rgba(255, 255, 255, 0.2);
366
+ color: white;
367
+ }
368
+
369
+ .item-icon svg {
370
+ width: 20px;
371
+ height: 20px;
372
+ }
373
+
374
+ .item-content {
375
+ flex: 1;
376
+ min-width: 0;
377
+ }
378
+
379
+ .item-name {
380
+ font-size: var(--sw-font-size-base);
381
+ font-weight: 500;
382
+ color: inherit;
383
+ white-space: nowrap;
384
+ overflow: hidden;
385
+ text-overflow: ellipsis;
386
+ }
387
+
388
+ .item-type {
389
+ font-size: var(--sw-font-size-sm);
390
+ color: var(--sw-color-text-muted);
391
+ text-transform: capitalize;
392
+ }
393
+
394
+ .item-channels {
395
+ display: flex;
396
+ gap: var(--sw-space-1);
397
+ color: var(--sw-color-text-muted);
398
+ }
399
+
400
+ .item-channels svg {
401
+ width: 16px;
402
+ height: 16px;
403
+ }
404
+
405
+ .item-channels .active {
406
+ color: var(--sw-color-success);
407
+ }
408
+
409
+ .loading,
410
+ .empty {
411
+ display: flex;
412
+ align-items: center;
413
+ justify-content: center;
414
+ padding: var(--sw-space-4);
415
+ color: var(--sw-color-text-muted);
416
+ font-size: var(--sw-font-size-base);
417
+ }
418
+
419
+ .scroll-sentinel {
420
+ display: flex;
421
+ align-items: center;
422
+ justify-content: center;
423
+ padding: var(--sw-space-3);
424
+ min-height: 1px;
425
+ }
426
+
427
+ .scroll-loading {
428
+ display: flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ gap: var(--sw-space-2);
432
+ padding: var(--sw-space-3);
433
+ color: var(--sw-color-text-muted);
434
+ font-size: var(--sw-font-size-sm);
435
+ }
436
+
437
+ .spinner {
438
+ width: 16px;
439
+ height: 16px;
440
+ border: 2px solid var(--sw-color-border);
441
+ border-top-color: var(--sw-color-primary);
442
+ border-radius: 50%;
443
+ animation: spin 0.8s linear infinite;
444
+ }
445
+
446
+ @keyframes spin {
447
+ to {
448
+ transform: rotate(360deg);
449
+ }
450
+ }
451
+
452
+ .dial-button {
453
+ display: flex;
454
+ align-items: center;
455
+ justify-content: center;
456
+ width: 36px;
457
+ height: 36px;
458
+ background: var(--sw-color-success);
459
+ border: none;
460
+ border-radius: 50%;
461
+ color: white;
462
+ cursor: pointer;
463
+ flex-shrink: 0;
464
+ transition: background-color 0.15s ease;
465
+ }
466
+
467
+ .dial-button:hover {
468
+ background: #0ea472;
469
+ }
470
+
471
+ .dial-button svg {
472
+ width: 18px;
473
+ height: 18px;
474
+ }
475
+ `;
476
+ c([
477
+ v({ type: Object })
478
+ ], o.prototype, "directory", 2);
479
+ c([
480
+ d()
481
+ ], o.prototype, "selectedAddress", 2);
482
+ c([
483
+ d()
484
+ ], o.prototype, "searchQuery", 2);
485
+ c([
486
+ d()
487
+ ], o.prototype, "addresses", 2);
488
+ c([
489
+ d()
490
+ ], o.prototype, "loading", 2);
491
+ c([
492
+ d()
493
+ ], o.prototype, "hasMore", 2);
494
+ c([
495
+ d()
496
+ ], o.prototype, "isAutoLoadingForSearch", 2);
497
+ o = c([
498
+ w("sw-directory")
499
+ ], o);
500
+ export {
501
+ o as DirectoryComponent
502
+ };
503
+ //# sourceMappingURL=directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory.js","sources":["../../src/components/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\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { Subscription } from 'rxjs';\nimport type { Observable } from 'rxjs';\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 DirectoryComponent 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-success: #10b981;\n --sw-color-text: #1f2937;\n --sw-color-text-muted: #6b7280;\n --sw-color-background: #ffffff;\n --sw-color-background-hover: #f3f4f6;\n --sw-color-background-active: #e5e7eb;\n --sw-color-border: #e5e7eb;\n --sw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --sw-font-size-sm: 12px;\n --sw-font-size-base: 14px;\n --sw-font-size-lg: 16px;\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\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-background: #1f2937;\n --sw-color-background-hover: #374151;\n --sw-color-background-active: #4b5563;\n --sw-color-border: #374151;\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-background: #1f2937;\n --sw-color-background-hover: #374151;\n --sw-color-background-active: #4b5563;\n --sw-color-border: #374151;\n }\n }\n\n .container {\n display: flex;\n flex-direction: column;\n background: var(--sw-color-background);\n border: 1px solid var(--sw-color-border);\n border-radius: var(--sw-border-radius);\n overflow: hidden;\n }\n\n .search {\n display: flex;\n align-items: center;\n gap: var(--sw-space-2);\n padding: var(--sw-space-3);\n border-bottom: 1px solid var(--sw-color-border);\n }\n\n .search-input {\n flex: 1;\n padding: var(--sw-space-2) var(--sw-space-3);\n border: 1px solid var(--sw-color-border);\n border-radius: var(--sw-border-radius);\n background: var(--sw-color-background);\n color: var(--sw-color-text);\n font-family: var(--sw-font-family);\n font-size: var(--sw-font-size-base);\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .search-input:focus {\n border-color: var(--sw-color-primary);\n }\n\n .search-input::placeholder {\n color: var(--sw-color-text-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(--sw-space-3);\n padding: var(--sw-space-3) var(--sw-space-4);\n border-bottom: 1px solid var(--sw-color-border);\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(--sw-color-background-hover);\n }\n\n .item:active {\n background: var(--sw-color-background-active);\n }\n\n .item.selected {\n background: var(--sw-color-primary);\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(--sw-color-background-hover);\n color: var(--sw-color-text-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 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(--sw-font-size-base);\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(--sw-font-size-sm);\n color: var(--sw-color-text-muted);\n text-transform: capitalize;\n }\n\n .item-channels {\n display: flex;\n gap: var(--sw-space-1);\n color: var(--sw-color-text-muted);\n }\n\n .item-channels svg {\n width: 16px;\n height: 16px;\n }\n\n .item-channels .active {\n color: var(--sw-color-success);\n }\n\n .loading,\n .empty {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--sw-space-4);\n color: var(--sw-color-text-muted);\n font-size: var(--sw-font-size-base);\n }\n\n .scroll-sentinel {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--sw-space-3);\n min-height: 1px;\n }\n\n .scroll-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--sw-space-2);\n padding: var(--sw-space-3);\n color: var(--sw-color-text-muted);\n font-size: var(--sw-font-size-sm);\n }\n\n .spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--sw-color-border);\n border-top-color: var(--sw-color-primary);\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(--sw-color-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 svg {\n width: 18px;\n height: 18px;\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 if (address.type === 'room') {\n return html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 3c1.93 0 3.5 1.57 3.5 3.5S13.93 13 12 13s-3.5-1.57-3.5-3.5S10.07 6 12 6zm7 13H5v-.23c0-.62.28-1.2.76-1.58C7.47 15.82 9.64 15 12 15s4.53.82 6.24 2.19c.48.38.76.97.76 1.58V19z\"\n />\n </svg>\n `;\n }\n return html`\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path\n d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\"\n />\n </svg>\n `;\n }\n\n private renderChannelIcons(address: Address) {\n const channels = address.channels || {};\n return html`\n <div class=\"item-channels\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"${channels.audio ? 'active' : ''}\"\n title=\"Audio\"\n >\n <path\n d=\"M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z\"\n />\n </svg>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"${channels.video ? 'active' : ''}\"\n title=\"Video\"\n >\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 </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 <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\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 </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': DirectoryComponent;\n }\n}\n"],"names":["DirectoryComponent","LitElement","addressesSub","addresses","loadingSub","loading","hasMoreSub","hasMore","sub","sentinel","_a","entries","entry","_b","changedProperties","query","addr","input","address","html","channels","showInitialLoading","showEmptyState","showSearchingState","_c","e","css","__decorateClass","property","state","customElement"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { LitElement } from 'lit';
2
+ /**
3
+ * An example button component built with Lit
4
+ *
5
+ * @slot - Default slot for button content
6
+ * @csspart button - The button element
7
+ */
8
+ export declare class ExampleButton extends LitElement {
9
+ static styles: import("lit").CSSResult;
10
+ disabled: boolean;
11
+ variant: 'primary' | 'secondary';
12
+ private _handleClick;
13
+ render(): import("lit-html").TemplateResult<1>;
14
+ }
15
+ declare global {
16
+ interface HTMLElementTagNameMap {
17
+ 'sw-example-button': ExampleButton;
18
+ }
19
+ }
20
+ //# sourceMappingURL=example-button.d.ts.map