@nectary/labs 2.3.3 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +354 -0
- package/color-select/index.d.ts +39 -0
- package/color-select/index.js +96 -0
- package/index.d.ts +2 -0
- package/index.js +3 -0
- package/package.json +2 -6
- package/{phone-preview.d.ts → phone-preview/index.d.ts} +18 -7
- package/phone-preview/index.js +94 -0
- package/phone-preview-rcs-channel/index.d.ts +49 -0
- package/phone-preview-rcs-channel/index.js +175 -0
- package/phone-preview-rcs-channel-actions/index.d.ts +37 -0
- package/phone-preview-rcs-channel-actions/index.js +126 -0
- package/phone-preview-rcs-channel-info/index.d.ts +29 -0
- package/phone-preview-rcs-channel-info/index.js +64 -0
- package/phone-preview-rcs-channel-info-option/index.d.ts +40 -0
- package/phone-preview-rcs-channel-info-option/index.js +106 -0
- package/phone-preview-rcs-channel-options/index.d.ts +27 -0
- package/phone-preview-rcs-channel-options/index.js +46 -0
- package/phone-preview-rcs-channel-tabs/index.d.ts +34 -0
- package/phone-preview-rcs-channel-tabs/index.js +79 -0
- package/{phone-preview-rcs-chat.d.ts → phone-preview-rcs-chat/index.d.ts} +20 -8
- package/phone-preview-rcs-chat/index.js +79 -0
- package/phone-preview-rcs-chat-message/index.d.ts +35 -0
- package/phone-preview-rcs-chat-message/index.js +48 -0
- package/utils/element.d.ts +9 -0
- package/utils/element.js +35 -0
- package/utils/index.d.ts +1 -1
- package/utils/index.js +1 -1
- package/Readme.md +0 -1
- package/color-select.d.ts +0 -34
- package/color-select.js +0 -79
- package/phone-preview-rcs-channel.d.ts +0 -50
- package/phone-preview-rcs-channel.js +0 -319
- package/phone-preview-rcs-chat.js +0 -162
- package/phone-preview.js +0 -120
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import '@nectary/components/icon';
|
|
2
|
-
import { customElement } from 'solid-element';
|
|
3
|
-
import { createSignal, For } from 'solid-js';
|
|
4
|
-
import html from 'solid-js/html';
|
|
5
|
-
import pkg from './package.json';
|
|
6
|
-
import { defineCustomElement } from './utils';
|
|
7
|
-
const style = `
|
|
8
|
-
:where(*, *::before, *::after) {
|
|
9
|
-
box-sizing: border-box;
|
|
10
|
-
padding: 0;
|
|
11
|
-
border: 0;
|
|
12
|
-
margin: 0;
|
|
13
|
-
font: inherit;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.root {
|
|
17
|
-
--banner-color: var(--sinch-sys-color-surface-tertiary-active);
|
|
18
|
-
--logo-color: var(--sinch-sys-color-surface-secondary-default);
|
|
19
|
-
display: flex;
|
|
20
|
-
flex-flow: column;
|
|
21
|
-
color: var(--sinch-sys-color-text-default);
|
|
22
|
-
|
|
23
|
-
& > img:first-of-type {
|
|
24
|
-
block-size: 70px;
|
|
25
|
-
margin-block-end: -40px;
|
|
26
|
-
background: var(--banner-color);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
& > img:last-of-type {
|
|
30
|
-
block-size: 64px;
|
|
31
|
-
inline-size: 64px;
|
|
32
|
-
border-radius: 100%;
|
|
33
|
-
background: var(--logo-color);
|
|
34
|
-
align-self: center;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
& > h1 {
|
|
38
|
-
padding: 8px 24px;
|
|
39
|
-
font: var(--sinch-sys-font-body-m);
|
|
40
|
-
text-align: center;
|
|
41
|
-
text-wrap: balance;
|
|
42
|
-
word-wrap: break-word;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
& > p {
|
|
46
|
-
padding-inline: 24px;
|
|
47
|
-
font: var(--sinch-sys-font-body-xs);
|
|
48
|
-
text-align: center;
|
|
49
|
-
text-wrap: balance;
|
|
50
|
-
word-wrap: break-word;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
& > .actions {
|
|
54
|
-
align-self: center;
|
|
55
|
-
padding-block: 32px 24px;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
& > .tabs {
|
|
59
|
-
padding-block-end: 8px;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.actions {
|
|
64
|
-
display: grid;
|
|
65
|
-
grid-auto-columns: 1fr;
|
|
66
|
-
grid-auto-flow: column;
|
|
67
|
-
gap: 24px;
|
|
68
|
-
font: var(--sinch-sys-font-body-xs);
|
|
69
|
-
|
|
70
|
-
& > a {
|
|
71
|
-
display: flex;
|
|
72
|
-
flex-flow: column;
|
|
73
|
-
align-items: center;
|
|
74
|
-
gap: 2px;
|
|
75
|
-
color: inherit;
|
|
76
|
-
text-decoration: none;
|
|
77
|
-
|
|
78
|
-
&[inert] {
|
|
79
|
-
--sinch-global-color-icon: currentColor;
|
|
80
|
-
color: var(--sinch-sys-color-text-muted);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
.info {
|
|
87
|
-
display: flex;
|
|
88
|
-
flex-flow: column;
|
|
89
|
-
font: var(--sinch-sys-font-body-xs);
|
|
90
|
-
|
|
91
|
-
& > a {
|
|
92
|
-
display: grid;
|
|
93
|
-
grid-template:
|
|
94
|
-
"icon contact" auto
|
|
95
|
-
"icon label " auto
|
|
96
|
-
/ auto 1fr;
|
|
97
|
-
align-items: center;
|
|
98
|
-
gap: 0 16px;
|
|
99
|
-
padding: 8px 16px;
|
|
100
|
-
border-block-end: 1px solid
|
|
101
|
-
var(--sinch-sys-color-surface-secondary-active);
|
|
102
|
-
color: currentColor;
|
|
103
|
-
word-break: break-all;
|
|
104
|
-
text-decoration: none;
|
|
105
|
-
|
|
106
|
-
& > .icon-link {
|
|
107
|
-
grid-area: icon;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
& > span {
|
|
111
|
-
grid-area: contact;
|
|
112
|
-
|
|
113
|
-
&::before {
|
|
114
|
-
content: "\\200b";
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
& > p {
|
|
119
|
-
grid-area: label;
|
|
120
|
-
|
|
121
|
-
&::before {
|
|
122
|
-
content: "\\200b";
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
&[inert] {
|
|
127
|
-
--sinch-global-color-icon: currentColor;
|
|
128
|
-
color: var(--sinch-sys-color-text-muted);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.tabs {
|
|
134
|
-
--highlight-color: var(--sinch-sys-color-text-default);
|
|
135
|
-
display: flex;
|
|
136
|
-
|
|
137
|
-
& > button {
|
|
138
|
-
flex: 1;
|
|
139
|
-
padding-block-end: 10px;
|
|
140
|
-
border-block-end: 2px solid transparent;
|
|
141
|
-
outline: none;
|
|
142
|
-
background: transparent;
|
|
143
|
-
color: var(--sinch-sys-color-text-disabled);
|
|
144
|
-
font: var(--sinch-sys-font-desktop-title-xs);
|
|
145
|
-
|
|
146
|
-
&.active {
|
|
147
|
-
color: var(--sinch-sys-color-primary-default);
|
|
148
|
-
border-block-end: 2px solid var(--highlight-color);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
.options {
|
|
155
|
-
display: flex;
|
|
156
|
-
flex-flow: column;
|
|
157
|
-
font: var(--sinch-sys-font-body-xs);
|
|
158
|
-
|
|
159
|
-
& > header {
|
|
160
|
-
padding-block-end: 8px;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
& > span {
|
|
164
|
-
font: var(--sinch-sys-font-body-xxs);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
& > button {
|
|
168
|
-
padding: 4px;
|
|
169
|
-
outline: none;
|
|
170
|
-
background: transparent;
|
|
171
|
-
text-align: start;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
& > hr {
|
|
175
|
-
border-color: var(--sinch-sys-color-surface-secondary-active);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
`;
|
|
179
|
-
const Actions = (props) => {
|
|
180
|
-
const number = () => props.phones.at(0)?.number ?? '';
|
|
181
|
-
const url = () => props.websites.at(0)?.url ?? '';
|
|
182
|
-
const email = () => props.emails.at(0)?.address ?? '';
|
|
183
|
-
const numberHref = () => `tel:${number()}`;
|
|
184
|
-
const urlHref = url;
|
|
185
|
-
const emailHref = () => `mailto:${email()}`;
|
|
186
|
-
return html `
|
|
187
|
-
<section class="actions">
|
|
188
|
-
<a inert=${() => number() === ''} target="_blank" href=${numberHref}>
|
|
189
|
-
<sinch-icon icons-version="2" name="fa-phone" class="icon-link" />
|
|
190
|
-
Call
|
|
191
|
-
</a>
|
|
192
|
-
<a inert=${() => url() === ''} target="_blank" href=${urlHref}>
|
|
193
|
-
<sinch-icon icons-version="2" name="fa-earth-americas" name="public" class="icon-link" />
|
|
194
|
-
Website
|
|
195
|
-
</a>
|
|
196
|
-
<a inert=${() => email() === ''} target="_blank" href=${emailHref}>
|
|
197
|
-
<sinch-icon icons-version="2" name="envelope" name="mail" class="icon-link" />
|
|
198
|
-
Email
|
|
199
|
-
</a>
|
|
200
|
-
</section>
|
|
201
|
-
`;
|
|
202
|
-
};
|
|
203
|
-
const Info = (props) => {
|
|
204
|
-
const phones = () => ((props.phones.length > 0)
|
|
205
|
-
? props.phones
|
|
206
|
-
: [{ label: 'Contact us', number: '+1234567890' }]);
|
|
207
|
-
const websites = () => ((props.websites.length > 0)
|
|
208
|
-
? props.websites
|
|
209
|
-
: [{ label: 'Contact us', url: 'https://company.com' }]);
|
|
210
|
-
const emails = () => ((props.emails.length > 0)
|
|
211
|
-
? props.emails
|
|
212
|
-
: [{ label: 'Contact us', address: 'mail@company.com' }]);
|
|
213
|
-
return html `
|
|
214
|
-
<section class="info">
|
|
215
|
-
<${For} each=${phones}>
|
|
216
|
-
${({ label, number }) => html `
|
|
217
|
-
<a
|
|
218
|
-
inert=${() => props.phones.length === 0}
|
|
219
|
-
target="_blank"
|
|
220
|
-
href=${`tel:${number}`}
|
|
221
|
-
>
|
|
222
|
-
<sinch-icon icons-version="2" name="fa-phone" class="icon-link" />
|
|
223
|
-
<span>${number}</span>
|
|
224
|
-
<p>${label}</p>
|
|
225
|
-
</a>
|
|
226
|
-
`}
|
|
227
|
-
<//>
|
|
228
|
-
<${For} each=${websites}>
|
|
229
|
-
${({ label, url }) => html `
|
|
230
|
-
<a inert=${() => props.websites.length === 0} target="_blank" href=${url}>
|
|
231
|
-
<sinch-icon icons-version="2" name="fa-earth-americas" name="public" class="icon-link" />
|
|
232
|
-
<span>${url}</span>
|
|
233
|
-
<p>${label}</p>
|
|
234
|
-
</a>
|
|
235
|
-
`}
|
|
236
|
-
<//>
|
|
237
|
-
<${For} each=${emails}>
|
|
238
|
-
${({ label, address }) => html `
|
|
239
|
-
<a
|
|
240
|
-
inert=${() => props.emails.length === 0}
|
|
241
|
-
target="_blank"
|
|
242
|
-
href=${`mailto:${address}`}
|
|
243
|
-
>
|
|
244
|
-
<sinch-icon icons-version="2" name="envelope" name="mail" class="icon-link" />
|
|
245
|
-
<span>${address}</span>
|
|
246
|
-
<p>${label}</p>
|
|
247
|
-
</a>
|
|
248
|
-
`}
|
|
249
|
-
<//>
|
|
250
|
-
</section>
|
|
251
|
-
`;
|
|
252
|
-
};
|
|
253
|
-
const Tabs = (props) => html `
|
|
254
|
-
<section class="tabs" style=${() => ({ '--highlight-color': props.color })}>
|
|
255
|
-
<${For} each=${['Info', 'Options']}>
|
|
256
|
-
${(label, i) => html `
|
|
257
|
-
<button
|
|
258
|
-
class=${() => (i() === props.tab ? 'active' : '')}
|
|
259
|
-
on:click=${() => props.onTab?.(i())}
|
|
260
|
-
>
|
|
261
|
-
${label}
|
|
262
|
-
</button>
|
|
263
|
-
`}
|
|
264
|
-
<//>
|
|
265
|
-
</section>
|
|
266
|
-
`;
|
|
267
|
-
const Options = () => html `
|
|
268
|
-
<section class="options">
|
|
269
|
-
<header>Notifications</header>
|
|
270
|
-
<span>Business</span>
|
|
271
|
-
<button>Block & report spam</button>
|
|
272
|
-
<hr />
|
|
273
|
-
<button>View Privacy Policy</button>
|
|
274
|
-
<hr />
|
|
275
|
-
<button>View Terms of Service</button>
|
|
276
|
-
<hr />
|
|
277
|
-
<button>Learn mode</button>
|
|
278
|
-
</section>
|
|
279
|
-
`;
|
|
280
|
-
/**
|
|
281
|
-
* RCS channel preview component.
|
|
282
|
-
*
|
|
283
|
-
* @param props.color Brand color, used in the banner (if no image provided) and tabs.
|
|
284
|
-
* @param props.name Brand name.
|
|
285
|
-
* @param props.description Brand description.
|
|
286
|
-
* @param props.banner Brand banner image.
|
|
287
|
-
* @param props.logo Brand logo image.
|
|
288
|
-
* @param props.phone Brand phone numbers.
|
|
289
|
-
* @param props.website Brand website URLs.
|
|
290
|
-
* @param props.email Brand email addresses.
|
|
291
|
-
*/
|
|
292
|
-
export const RcsChannelPreview = (props) => {
|
|
293
|
-
const [tab, setTab] = createSignal(0);
|
|
294
|
-
const transparentIcon = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
|
|
295
|
-
return html `
|
|
296
|
-
<style>
|
|
297
|
-
${style}
|
|
298
|
-
</style>
|
|
299
|
-
<section class="root" style=${() => ({ '--banner-color': props.color })}>
|
|
300
|
-
<img src=${() => (props.banner !== '' ? props.banner : transparentIcon)} alt="" />
|
|
301
|
-
<img src=${() => (props.logo !== '' ? props.logo : transparentIcon)} alt="" />
|
|
302
|
-
<h1>${() => (props.name !== '' ? props.name : 'Brand name')}</h1>
|
|
303
|
-
<p>${() => (props.description !== '' ? props.description : 'Brand description')}</p>
|
|
304
|
-
<${Actions} ...${props} />
|
|
305
|
-
<${Tabs} color=${() => props.color} tab=${tab} onTab=${setTab} />
|
|
306
|
-
${() => (tab() === 0 ? html `<${Info} ...${props} />` : html `<${Options} />`)}
|
|
307
|
-
</section>
|
|
308
|
-
`;
|
|
309
|
-
};
|
|
310
|
-
defineCustomElement('sinch-labs-phone-preview-rcs-channel', customElement(`sinch-labs-phone-preview-rcs-channel-${pkg.version}`, {
|
|
311
|
-
name: '',
|
|
312
|
-
description: '',
|
|
313
|
-
color: '',
|
|
314
|
-
banner: '',
|
|
315
|
-
logo: '',
|
|
316
|
-
phones: [],
|
|
317
|
-
websites: [],
|
|
318
|
-
emails: [],
|
|
319
|
-
}, RcsChannelPreview));
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import '@nectary/components/icon';
|
|
2
|
-
import { customElement } from 'solid-element';
|
|
3
|
-
import { For } from 'solid-js';
|
|
4
|
-
import html from 'solid-js/html';
|
|
5
|
-
import pkg from './package.json';
|
|
6
|
-
import { defineCustomElement } from './utils';
|
|
7
|
-
const style = `
|
|
8
|
-
:where(*, *::before, *::after) {
|
|
9
|
-
box-sizing: border-box;
|
|
10
|
-
padding: 0;
|
|
11
|
-
border: 0;
|
|
12
|
-
margin: 0;
|
|
13
|
-
font: inherit;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.root {
|
|
17
|
-
--logo-color: var(--sinch-sys-color-surface-secondary-default);
|
|
18
|
-
block-size: 100%;
|
|
19
|
-
display: flex;
|
|
20
|
-
flex-flow: column;
|
|
21
|
-
|
|
22
|
-
& > header {
|
|
23
|
-
display: flex;
|
|
24
|
-
gap: 8px;
|
|
25
|
-
padding: 12px 4px;
|
|
26
|
-
background: var(--sinch-sys-color-surface-tertiary-default);
|
|
27
|
-
font: var(--sinch-sys-font-body-m);
|
|
28
|
-
|
|
29
|
-
& > img {
|
|
30
|
-
block-size: 24px;
|
|
31
|
-
inline-size: 24px;
|
|
32
|
-
margin-inline-start: 8px;
|
|
33
|
-
border-radius: 100%;
|
|
34
|
-
background: var(--logo-color);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
& > h1 {
|
|
38
|
-
flex: 1;
|
|
39
|
-
overflow: hidden;
|
|
40
|
-
min-inline-size: 0;
|
|
41
|
-
text-wrap: nowrap;
|
|
42
|
-
text-overflow: ellipsis;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
& > div {
|
|
47
|
-
flex: 1;
|
|
48
|
-
overflow-y: auto;
|
|
49
|
-
scrollbar-width: none;
|
|
50
|
-
display: flex;
|
|
51
|
-
flex-flow: column;
|
|
52
|
-
gap: 8px;
|
|
53
|
-
padding: 8px;
|
|
54
|
-
margin-block-end: 8px;
|
|
55
|
-
|
|
56
|
-
& > img {
|
|
57
|
-
block-size: 64px;
|
|
58
|
-
inline-size: 64px;
|
|
59
|
-
border-radius: 100%;
|
|
60
|
-
align-self: center;
|
|
61
|
-
background: var(--logo-color);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
& > p {
|
|
65
|
-
padding-inline: 24px;
|
|
66
|
-
font: var(--sinch-sys-font-body-xs);
|
|
67
|
-
text-align: center;
|
|
68
|
-
text-wrap: balance;
|
|
69
|
-
word-wrap: break-word;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
& > hr {
|
|
73
|
-
border-block-end: 1px solid var(--sinch-sys-color-border-subtle);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
& > footer {
|
|
78
|
-
display: flex;
|
|
79
|
-
align-items: center;
|
|
80
|
-
gap: 8px;
|
|
81
|
-
font: var(--sinch-sys-font-body-xs);
|
|
82
|
-
|
|
83
|
-
& > div {
|
|
84
|
-
flex: 1;
|
|
85
|
-
display: flex;
|
|
86
|
-
align-items: center;
|
|
87
|
-
gap: 8px;
|
|
88
|
-
padding: 8px 16px;
|
|
89
|
-
border-radius: 24px;
|
|
90
|
-
background: var(--sinch-sys-color-surface-primary-active);
|
|
91
|
-
|
|
92
|
-
& > span {
|
|
93
|
-
flex: 1;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.message {
|
|
100
|
-
padding: 8px 12px;
|
|
101
|
-
margin-inline-end: 8px;
|
|
102
|
-
border-radius: 16px;
|
|
103
|
-
border-end-start-radius: 0;
|
|
104
|
-
background: var(--sinch-sys-color-feedback-info-subtle);
|
|
105
|
-
font: var(--sinch-sys-font-body-xs);
|
|
106
|
-
}
|
|
107
|
-
`;
|
|
108
|
-
const Message = (props) => html `<section class="message">${props.message}</section>`;
|
|
109
|
-
/**
|
|
110
|
-
* RCS chat preview component.
|
|
111
|
-
*
|
|
112
|
-
* @param props.name Brand name.
|
|
113
|
-
* @param props.description Brand description.
|
|
114
|
-
* @param props.logo Brand logo image.
|
|
115
|
-
* @param props.messages List of messages.
|
|
116
|
-
*/
|
|
117
|
-
export const RcsChatPreview = (props) => {
|
|
118
|
-
const transparentIcon = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
|
|
119
|
-
return html ` <style>
|
|
120
|
-
${style}
|
|
121
|
-
</style>
|
|
122
|
-
<section class="root">
|
|
123
|
-
<header>
|
|
124
|
-
<sinch-icon icons-version="2" name="fa-arrow-left"></sinch-icon>
|
|
125
|
-
<img
|
|
126
|
-
src=${() => (props.logo !== '' ? props.logo : transparentIcon)}
|
|
127
|
-
alt=""
|
|
128
|
-
/>
|
|
129
|
-
<h1>${() => (props.name !== '' ? props.name : 'Brand name')}</h1>
|
|
130
|
-
<sinch-icon icons-version="2" name="fa-shield-check" name="verified_user" />
|
|
131
|
-
<sinch-icon icons-version="2" name="fa-ellipsis-vertical" name="more_vert" />
|
|
132
|
-
</header>
|
|
133
|
-
<div>
|
|
134
|
-
<img
|
|
135
|
-
src=${() => (props.logo !== '' ? props.logo : transparentIcon)}
|
|
136
|
-
alt=""
|
|
137
|
-
/>
|
|
138
|
-
<p>
|
|
139
|
-
${() => (props.description !== '' ? props.description : 'Brand description')}
|
|
140
|
-
</p>
|
|
141
|
-
<hr />
|
|
142
|
-
<${For} each=${() => props.messages}>
|
|
143
|
-
${(message) => html `<${Message} message=${message} />`}
|
|
144
|
-
<//>
|
|
145
|
-
</div>
|
|
146
|
-
<footer>
|
|
147
|
-
<sinch-icon icons-version="2" name="fa-circle-plus" />
|
|
148
|
-
<sinch-icon icons-version="2" name="fa-camera" />
|
|
149
|
-
<div>
|
|
150
|
-
<span>RCS Message</span>
|
|
151
|
-
<sinch-icon icons-version="2" name="fa-face-smile" />
|
|
152
|
-
<sinch-icon icons-version="2" name="microphone" name="mic" />
|
|
153
|
-
</div>
|
|
154
|
-
</footer>
|
|
155
|
-
</section>`;
|
|
156
|
-
};
|
|
157
|
-
defineCustomElement('sinch-labs-phone-preview-rcs-chat', customElement(`sinch-labs-phone-preview-rcs-chat-${pkg.version}`, {
|
|
158
|
-
name: '',
|
|
159
|
-
description: '',
|
|
160
|
-
logo: '',
|
|
161
|
-
messages: [],
|
|
162
|
-
}, RcsChatPreview));
|
package/phone-preview.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { customElement } from 'solid-element';
|
|
2
|
-
import { createComputed, createMemo, createSignal, onCleanup, onMount, } from 'solid-js';
|
|
3
|
-
import html from 'solid-js/html';
|
|
4
|
-
import pkg from './package.json';
|
|
5
|
-
import { defineCustomElement } from './utils';
|
|
6
|
-
const style = `
|
|
7
|
-
:where(*, *::before, *::after) {
|
|
8
|
-
box-sizing: border-box;
|
|
9
|
-
padding: 0;
|
|
10
|
-
border: 0;
|
|
11
|
-
margin: 0;
|
|
12
|
-
font: inherit;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
:host {
|
|
16
|
-
--base-size: 288px; /* 18rem */
|
|
17
|
-
--aspect-ratio: 1 / 2.1;
|
|
18
|
-
--scale: 1;
|
|
19
|
-
inline-size: min(100%, var(--base-size));
|
|
20
|
-
aspect-ratio: var(--aspect-ratio);
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
display: block;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
section {
|
|
26
|
-
position: relative;
|
|
27
|
-
inline-size: var(--base-size);
|
|
28
|
-
aspect-ratio: var(--aspect-ratio);
|
|
29
|
-
scale: var(--scale);
|
|
30
|
-
transform-origin: top left;
|
|
31
|
-
overflow: hidden;
|
|
32
|
-
display: flex;
|
|
33
|
-
flex-flow: column;
|
|
34
|
-
padding: 12px;
|
|
35
|
-
border: 1px solid var(--sinch-sys-color-border-strong);
|
|
36
|
-
border-radius: 32px;
|
|
37
|
-
background: var(--sinch-sys-color-surface-primary-default);
|
|
38
|
-
|
|
39
|
-
& > header {
|
|
40
|
-
position: sticky;
|
|
41
|
-
inset-block-start: 0;
|
|
42
|
-
display: flex;
|
|
43
|
-
justify-content: space-between;
|
|
44
|
-
padding: 16px;
|
|
45
|
-
background: var(--sinch-sys-color-surface-primary-default);
|
|
46
|
-
font: var(--sinch-sys-font-body-xxs);
|
|
47
|
-
|
|
48
|
-
& > svg {
|
|
49
|
-
inline-size: 48px;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
& > div {
|
|
54
|
-
flex: 1;
|
|
55
|
-
overflow-y: auto;
|
|
56
|
-
scrollbar-width: none;
|
|
57
|
-
border-end-start-radius: 16px;
|
|
58
|
-
border-end-end-radius: 16px;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
`;
|
|
62
|
-
const StatusSvg = () => html `
|
|
63
|
-
<svg viewBox="0 0 50 12">
|
|
64
|
-
<path
|
|
65
|
-
d="M13.2 2.4h-.7c-.4 0-.7.3-.7.7v6.2c0 .4.3.8.7.8h.7c.4 0 .7-.4.7-.8V3.1c0-.4-.3-.7-.7-.7ZM9.4 4.2h.6c.4 0 .7.3.7.7v4.5c0 .3-.3.7-.7.7h-.6c-.4 0-.7-.4-.7-.7V4.9c0-.4.3-.7.7-.7ZM6.9 6h-.7c-.4 0-.7.3-.7.7v2.7c0 .4.3.7.7.7h.7c.4 0 .7-.3.7-.7V6.7c0-.4-.3-.7-.7-.7ZM3.7 7.3H3c-.3 0-.6.4-.6.7v1.4c0 .4.3.7.6.7h.7c.4 0 .7-.3.7-.7V8c0-.3-.3-.7-.7-.7Zm19.4-3.7c1.7 0 3.3.7 4.5 1.8h.3l.8-.9.1-.1-.1-.2a8 8 0 0 0-11.1 0l-.1.2.1.1.8.9h.3a6.7 6.7 0 0 1 4.4-1.8Zm0 2.8a4 4 0 0 1 2.5 1h.3l.9-.9v-.3a5.4 5.4 0 0 0-7.3 0v.3l.9.9h.3c.7-.6 1.5-1 2.4-1Zm1.8 1.9-.1.2-1.5 1.5-.2.1-.1-.1-1.5-1.5-.1-.2.1-.1c1-.8 2.3-.8 3.3 0l.1.1Z"
|
|
66
|
-
/>
|
|
67
|
-
<rect width="12.6" height="5.4" x="33.3" y="3.5" rx=".9" />
|
|
68
|
-
<path fill="#999" d="M48 4.9v2.7c.5-.3.9-.8.9-1.4 0-.6-.4-1.1-.9-1.3Z" />
|
|
69
|
-
<path
|
|
70
|
-
fill="none"
|
|
71
|
-
stroke="#999"
|
|
72
|
-
stroke-width=".7"
|
|
73
|
-
d="M32.3 4.4a2 2 0 0 1 1.9-1.9H45c1.1 0 2 .9 2 1.9V8c0 1.1-.9 1.9-2 1.9H34.2c-1 0-1.9-.8-1.9-1.9V4.4Z"
|
|
74
|
-
/>
|
|
75
|
-
</svg>
|
|
76
|
-
`;
|
|
77
|
-
/**
|
|
78
|
-
* Container for channel previews in a styled phone container.
|
|
79
|
-
* This container uses a custom scaling where the internal elements are scaled to fit the container from a fixed size.
|
|
80
|
-
* Because of the fixed size, absolute units (px) are preferred over relative units (rem, em) for the internal elements.
|
|
81
|
-
*
|
|
82
|
-
* @param props.locale Clock locale.
|
|
83
|
-
* @param props.clock Clock `Intl.DateTimeFormat` options.
|
|
84
|
-
* @param props.children Content to display in the phone container.
|
|
85
|
-
*/
|
|
86
|
-
const PhonePreview = (props, options) => {
|
|
87
|
-
const host = options.element;
|
|
88
|
-
const observer = new ResizeObserver(() => {
|
|
89
|
-
const style = getComputedStyle(host);
|
|
90
|
-
const baseSize = parseFloat(style.getPropertyValue('--base-size'));
|
|
91
|
-
const currentSize = host.getBoundingClientRect().width;
|
|
92
|
-
host.style.setProperty('--scale', `${currentSize / baseSize}`);
|
|
93
|
-
});
|
|
94
|
-
onMount(() => {
|
|
95
|
-
const section = host.shadowRoot.querySelector('section');
|
|
96
|
-
observer.observe(host);
|
|
97
|
-
observer.observe(section);
|
|
98
|
-
});
|
|
99
|
-
onCleanup(() => observer.disconnect());
|
|
100
|
-
const fmt = createMemo(() => Intl.DateTimeFormat(props.locale, props.clock));
|
|
101
|
-
const [clock, setClock] = createSignal();
|
|
102
|
-
const interval = setInterval(() => setClock(fmt().format()), 60000);
|
|
103
|
-
createComputed(() => setClock(fmt().format()));
|
|
104
|
-
onCleanup(() => clearInterval(interval));
|
|
105
|
-
return html `
|
|
106
|
-
<style>
|
|
107
|
-
${style}
|
|
108
|
-
</style>
|
|
109
|
-
<section>
|
|
110
|
-
<header>
|
|
111
|
-
<span>${clock}</span>
|
|
112
|
-
<${StatusSvg} />
|
|
113
|
-
</header>
|
|
114
|
-
<div>
|
|
115
|
-
<slot />
|
|
116
|
-
</div>
|
|
117
|
-
</section>
|
|
118
|
-
`;
|
|
119
|
-
};
|
|
120
|
-
defineCustomElement('sinch-labs-phone-preview', customElement(`sinch-labs-phone-preview-${pkg.version}`, { locale: 'en-US', clock: { hour: '2-digit', minute: '2-digit' } }, PhonePreview));
|