@nectary/labs 2.5.39 → 2.5.41

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.
@@ -1,79 +1,196 @@
1
- import '@nectary/components/icon';
2
- import { defineCustomElement, NectaryElement } from '../utils';
3
- import '../phone-preview-rcs-chat-message';
4
- import templateHTML from './template.html';
5
- const template = document.createElement('template');
1
+ import "@nectary/components/icon";
2
+ import { defineCustomElement, NectaryElement } from "../utils/element.js";
3
+ import "../phone-preview-rcs-chat-message/index.js";
4
+ const templateHTML = `<style>
5
+ :where(*, *::before, *::after) {
6
+ box-sizing: border-box;
7
+ padding: 0;
8
+ border: 0;
9
+ margin: 0;
10
+ font: inherit;
11
+ }
12
+
13
+ .root {
14
+ --logo-color: var(--sinch-sys-color-surface-secondary-default);
15
+
16
+ block-size: 100%;
17
+ display: flex;
18
+ flex-flow: column;
19
+ }
20
+
21
+ .root > header {
22
+ display: flex;
23
+ gap: 8px;
24
+ padding: 12px 4px;
25
+ background: var(--sinch-sys-color-surface-tertiary-default);
26
+ font: var(--sinch-sys-font-body-m);
27
+ }
28
+
29
+ .root > header > 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
+ .root > header > h1 {
38
+ flex: 1;
39
+ overflow: hidden;
40
+ min-inline-size: 0;
41
+ text-wrap: nowrap;
42
+ text-overflow: ellipsis;
43
+ }
44
+
45
+ .root > div {
46
+ flex: 1;
47
+ overflow-y: auto;
48
+ scrollbar-width: none;
49
+ display: flex;
50
+ flex-flow: column;
51
+ gap: 8px;
52
+ padding: 8px;
53
+ margin-block-end: 8px;
54
+ }
55
+
56
+ .root > div > 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
+ .root > div > 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
+ .root > div > hr {
73
+ border-block-end: 1px solid var(--sinch-sys-color-border-subtle);
74
+ }
75
+
76
+ .root > footer {
77
+ display: flex;
78
+ align-items: center;
79
+ gap: 8px;
80
+ font: var(--sinch-sys-font-body-xs);
81
+ }
82
+
83
+ .root > footer > 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
+
93
+ .root > footer > div > span {
94
+ flex: 1;
95
+ }
96
+ </style>
97
+ <section class="root">
98
+ <header>
99
+ <sinch-icon icons-version="2" name="fa-arrow-left"></sinch-icon>
100
+ <img id="header-logo" alt="" />
101
+ <h1 id="brand-name">Brand name</h1>
102
+ <sinch-icon icons-version="2" name="fa-shield-check"></sinch-icon>
103
+ <sinch-icon icons-version="2" name="fa-ellipsis-vertical"></sinch-icon>
104
+ </header>
105
+ <div>
106
+ <img id="main-logo" alt="" />
107
+ <p id="brand-description">Brand description</p>
108
+ <hr />
109
+ <slot name="messages">
110
+ <!-- Default messages when no slotted content -->
111
+ <sinch-labs-phone-preview-rcs-chat-message text="Hello! How can I help you today?"></sinch-labs-phone-preview-rcs-chat-message>
112
+ <sinch-labs-phone-preview-rcs-chat-message text="We're here to assist you."></sinch-labs-phone-preview-rcs-chat-message>
113
+ </slot>
114
+ </div>
115
+ <footer>
116
+ <sinch-icon icons-version="2" name="fa-circle-plus"></sinch-icon>
117
+ <sinch-icon icons-version="2" name="fa-camera"></sinch-icon>
118
+ <div>
119
+ <span>RCS Message</span>
120
+ <sinch-icon icons-version="2" name="fa-face-smile"></sinch-icon>
121
+ <sinch-icon icons-version="2" name="microphone"></sinch-icon>
122
+ </div>
123
+ </footer>
124
+ </section>
125
+ `;
126
+ const template = document.createElement("template");
6
127
  template.innerHTML = templateHTML;
7
- /**
8
- * RCS chat preview component.
9
- *
10
- * @param props.name Brand name.
11
- * @param props.description Brand description.
12
- * @param props.logo Brand logo image.
13
- */
14
- export class RcsChatPreview extends NectaryElement {
15
- #headerLogo;
16
- #mainLogo;
17
- #brandName;
18
- #brandDescription;
19
- #transparentIcon = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
20
- constructor() {
21
- super();
22
- const shadowRoot = this.attachShadow();
23
- shadowRoot.appendChild(template.content.cloneNode(true));
24
- this.#headerLogo = shadowRoot.querySelector('#header-logo');
25
- this.#mainLogo = shadowRoot.querySelector('#main-logo');
26
- this.#brandName = shadowRoot.querySelector('#brand-name');
27
- this.#brandDescription = shadowRoot.querySelector('#brand-description');
128
+ class RcsChatPreview extends NectaryElement {
129
+ #headerLogo;
130
+ #mainLogo;
131
+ #brandName;
132
+ #brandDescription;
133
+ #transparentIcon = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";
134
+ constructor() {
135
+ super();
136
+ const shadowRoot = this.attachShadow();
137
+ shadowRoot.appendChild(template.content.cloneNode(true));
138
+ this.#headerLogo = shadowRoot.querySelector("#header-logo");
139
+ this.#mainLogo = shadowRoot.querySelector("#main-logo");
140
+ this.#brandName = shadowRoot.querySelector("#brand-name");
141
+ this.#brandDescription = shadowRoot.querySelector("#brand-description");
142
+ }
143
+ connectedCallback() {
144
+ super.connectedCallback();
145
+ this.#updateUI();
146
+ }
147
+ static get observedAttributes() {
148
+ return ["name", "description", "logo"];
149
+ }
150
+ attributeChangedCallback(name, oldVal, newVal) {
151
+ if (oldVal === newVal) {
152
+ return;
28
153
  }
29
- connectedCallback() {
30
- super.connectedCallback();
154
+ switch (name) {
155
+ case "name":
156
+ case "description":
157
+ case "logo":
31
158
  this.#updateUI();
159
+ break;
32
160
  }
33
- static get observedAttributes() {
34
- return ['name', 'description', 'logo'];
35
- }
36
- attributeChangedCallback(name, oldVal, newVal) {
37
- if (oldVal === newVal) {
38
- return;
39
- }
40
- switch (name) {
41
- case 'name':
42
- case 'description':
43
- case 'logo':
44
- this.#updateUI();
45
- break;
46
- }
47
- }
48
- get name() {
49
- return this.getAttribute('name') ?? '';
50
- }
51
- set name(value) {
52
- this.setAttribute('name', value);
53
- }
54
- get description() {
55
- return this.getAttribute('description') ?? '';
56
- }
57
- set description(value) {
58
- this.setAttribute('description', value);
59
- }
60
- get logo() {
61
- return this.getAttribute('logo') ?? '';
62
- }
63
- set logo(value) {
64
- this.setAttribute('logo', value);
65
- }
66
- #updateUI() {
67
- if (!this.isDomConnected) {
68
- return;
69
- }
70
- const logoSrc = this.logo !== '' ? this.logo : this.#transparentIcon;
71
- const displayName = this.name !== '' ? this.name : 'Brand name';
72
- const displayDescription = this.description !== '' ? this.description : 'Brand description';
73
- this.#headerLogo.src = logoSrc;
74
- this.#mainLogo.src = logoSrc;
75
- this.#brandName.textContent = displayName;
76
- this.#brandDescription.textContent = displayDescription;
161
+ }
162
+ get name() {
163
+ return this.getAttribute("name") ?? "";
164
+ }
165
+ set name(value) {
166
+ this.setAttribute("name", value);
167
+ }
168
+ get description() {
169
+ return this.getAttribute("description") ?? "";
170
+ }
171
+ set description(value) {
172
+ this.setAttribute("description", value);
173
+ }
174
+ get logo() {
175
+ return this.getAttribute("logo") ?? "";
176
+ }
177
+ set logo(value) {
178
+ this.setAttribute("logo", value);
179
+ }
180
+ #updateUI() {
181
+ if (!this.isDomConnected) {
182
+ return;
77
183
  }
184
+ const logoSrc = this.logo !== "" ? this.logo : this.#transparentIcon;
185
+ const displayName = this.name !== "" ? this.name : "Brand name";
186
+ const displayDescription = this.description !== "" ? this.description : "Brand description";
187
+ this.#headerLogo.src = logoSrc;
188
+ this.#mainLogo.src = logoSrc;
189
+ this.#brandName.textContent = displayName;
190
+ this.#brandDescription.textContent = displayDescription;
191
+ }
78
192
  }
79
- defineCustomElement('sinch-labs-phone-preview-rcs-chat', RcsChatPreview);
193
+ defineCustomElement("sinch-labs-phone-preview-rcs-chat", RcsChatPreview);
194
+ export {
195
+ RcsChatPreview
196
+ };
@@ -1,48 +1,46 @@
1
- import { defineCustomElement, NectaryElement } from '../utils';
2
- import templateHTML from './template.html';
3
- const template = document.createElement('template');
1
+ import { defineCustomElement, NectaryElement } from "../utils/element.js";
2
+ const templateHTML = '<style>\n:host {\n display: block;\n}\n\n.message {\n padding: 8px 12px;\n margin-inline-end: 8px;\n border-radius: 16px;\n border-end-start-radius: 0;\n background: var(--sinch-sys-color-feedback-info-subtle);\n font: var(--sinch-sys-font-body-xs);\n}\n</style>\n\n<section class="message">\n <span id="message-text">Sample message</span>\n</section>\n';
3
+ const template = document.createElement("template");
4
4
  template.innerHTML = templateHTML;
5
- /**
6
- * Individual RCS chat message component.
7
- *
8
- * @param props.text Message text content.
9
- */
10
- export class RcsChatMessage extends NectaryElement {
11
- #messageText;
12
- constructor() {
13
- super();
14
- const shadowRoot = this.attachShadow();
15
- shadowRoot.appendChild(template.content.cloneNode(true));
16
- this.#messageText = shadowRoot.querySelector('#message-text');
5
+ class RcsChatMessage extends NectaryElement {
6
+ #messageText;
7
+ constructor() {
8
+ super();
9
+ const shadowRoot = this.attachShadow();
10
+ shadowRoot.appendChild(template.content.cloneNode(true));
11
+ this.#messageText = shadowRoot.querySelector("#message-text");
12
+ }
13
+ connectedCallback() {
14
+ super.connectedCallback();
15
+ this.#updateUI();
16
+ }
17
+ static get observedAttributes() {
18
+ return ["text"];
19
+ }
20
+ attributeChangedCallback(name, oldVal, newVal) {
21
+ if (oldVal === newVal) {
22
+ return;
17
23
  }
18
- connectedCallback() {
19
- super.connectedCallback();
24
+ switch (name) {
25
+ case "text":
20
26
  this.#updateUI();
27
+ break;
21
28
  }
22
- static get observedAttributes() {
23
- return ['text'];
24
- }
25
- attributeChangedCallback(name, oldVal, newVal) {
26
- if (oldVal === newVal) {
27
- return;
28
- }
29
- switch (name) {
30
- case 'text':
31
- this.#updateUI();
32
- break;
33
- }
34
- }
35
- get text() {
36
- return this.getAttribute('text') ?? '';
37
- }
38
- set text(value) {
39
- this.setAttribute('text', value);
40
- }
41
- #updateUI() {
42
- if (!this.isDomConnected) {
43
- return;
44
- }
45
- this.#messageText.textContent = this.text !== '' ? this.text : 'Sample message';
29
+ }
30
+ get text() {
31
+ return this.getAttribute("text") ?? "";
32
+ }
33
+ set text(value) {
34
+ this.setAttribute("text", value);
35
+ }
36
+ #updateUI() {
37
+ if (!this.isDomConnected) {
38
+ return;
46
39
  }
40
+ this.#messageText.textContent = this.text !== "" ? this.text : "Sample message";
41
+ }
47
42
  }
48
- defineCustomElement('sinch-labs-phone-preview-rcs-chat-message', RcsChatMessage);
43
+ defineCustomElement("sinch-labs-phone-preview-rcs-chat-message", RcsChatMessage);
44
+ export {
45
+ RcsChatMessage
46
+ };
package/utils/element.js CHANGED
@@ -1,61 +1,70 @@
1
- import pkg from '../package.json';
2
- const nectaryDefinitions = new Map();
1
+ const version = "2.8.3";
2
+ const pkg = {
3
+ version
4
+ };
5
+ const nectaryDefinitions = /* @__PURE__ */ new Map();
3
6
  let nectaryRegistry = null;
4
- export const defineCustomElement = (name, constructor) => {
5
- console.log(`Defining custom element: ${name} nectaryRegistry`, nectaryRegistry);
6
- if (nectaryRegistry !== null) {
7
- if (nectaryRegistry.get(name) == null) {
8
- nectaryRegistry.define(name, constructor);
9
- console.log(`Custom element ${name} defined immediately`);
10
- }
11
- console.log(`Custom element ${name} already defined in registry`);
12
- return;
7
+ const defineCustomElement = (name, constructor) => {
8
+ console.log(`Defining custom element: ${name} nectaryRegistry`, nectaryRegistry);
9
+ if (nectaryRegistry !== null) {
10
+ if (nectaryRegistry.get(name) == null) {
11
+ nectaryRegistry.define(name, constructor);
12
+ console.log(`Custom element ${name} defined immediately`);
13
13
  }
14
- nectaryDefinitions.set(name, constructor);
15
- console.log(`Custom element ${name} queued for definition`);
16
- console.log(`Current definitions queue: ${Array.from(nectaryDefinitions.keys()).join(', ')}`);
14
+ console.log(`Custom element ${name} already defined in registry`);
15
+ return;
16
+ }
17
+ nectaryDefinitions.set(name, constructor);
18
+ console.log(`Custom element ${name} queued for definition`);
19
+ console.log(`Current definitions queue: ${Array.from(nectaryDefinitions.keys()).join(", ")}`);
17
20
  };
18
- export const setLabRegistry = (registry) => {
19
- if (nectaryRegistry !== null) {
20
- throw new Error('Nectary registry already set');
21
- }
22
- nectaryRegistry = registry;
23
- for (const [name, ctor] of nectaryDefinitions.entries()) {
24
- if (nectaryRegistry.get(name) == null) {
25
- nectaryRegistry.define(name, ctor);
26
- console.log(`Custom element ${name} defined in registry`);
27
- }
21
+ const setLabRegistry = (registry) => {
22
+ if (nectaryRegistry !== null) {
23
+ throw new Error("Nectary registry already set");
24
+ }
25
+ nectaryRegistry = registry;
26
+ for (const [name, ctor] of nectaryDefinitions.entries()) {
27
+ if (nectaryRegistry.get(name) == null) {
28
+ nectaryRegistry.define(name, ctor);
29
+ console.log(`Custom element ${name} defined in registry`);
28
30
  }
29
- nectaryDefinitions.clear();
31
+ }
32
+ nectaryDefinitions.clear();
30
33
  };
31
- export const resetLabRegistry = () => {
32
- nectaryRegistry = null;
34
+ const resetLabRegistry = () => {
35
+ nectaryRegistry = null;
33
36
  };
34
- export class NectaryElement extends HTMLElement {
35
- constructor() {
36
- super(...arguments);
37
- this.version = pkg.version;
38
- this.#isDomConnected = false;
39
- }
40
- attachShadow(options) {
41
- return super.attachShadow({
42
- mode: 'open',
43
- delegatesFocus: false,
44
- customElements: nectaryRegistry,
45
- ...options,
46
- });
47
- }
48
- get focusable() {
49
- return false;
50
- }
51
- #isDomConnected;
52
- connectedCallback() {
53
- this.#isDomConnected = true;
54
- }
55
- disconnectedCallback() {
56
- this.#isDomConnected = false;
57
- }
58
- get isDomConnected() {
59
- return this.#isDomConnected;
60
- }
37
+ class NectaryElement extends HTMLElement {
38
+ constructor() {
39
+ super(...arguments);
40
+ this.version = pkg.version;
41
+ this.#isDomConnected = false;
42
+ }
43
+ attachShadow(options) {
44
+ return super.attachShadow({
45
+ mode: "open",
46
+ delegatesFocus: false,
47
+ customElements: nectaryRegistry,
48
+ ...options
49
+ });
50
+ }
51
+ get focusable() {
52
+ return false;
53
+ }
54
+ #isDomConnected;
55
+ connectedCallback() {
56
+ this.#isDomConnected = true;
57
+ }
58
+ disconnectedCallback() {
59
+ this.#isDomConnected = false;
60
+ }
61
+ get isDomConnected() {
62
+ return this.#isDomConnected;
63
+ }
61
64
  }
65
+ export {
66
+ NectaryElement,
67
+ defineCustomElement,
68
+ resetLabRegistry,
69
+ setLabRegistry
70
+ };
package/utils/index.js CHANGED
@@ -1 +1,7 @@
1
- export { defineCustomElement, setLabRegistry, resetLabRegistry, NectaryElement } from './element';
1
+ import { NectaryElement, defineCustomElement, resetLabRegistry, setLabRegistry } from "./element.js";
2
+ export {
3
+ NectaryElement,
4
+ defineCustomElement,
5
+ resetLabRegistry,
6
+ setLabRegistry
7
+ };
package/vite.config.js ADDED
@@ -0,0 +1,66 @@
1
+ import { readFileSync } from 'fs'
2
+ import { resolve, dirname } from 'path'
3
+ import { fileURLToPath } from 'url'
4
+ import { glob } from 'glob'
5
+ import { defineConfig } from 'vite'
6
+
7
+ const __filename = fileURLToPath(import.meta.url)
8
+ const __dirname = dirname(__filename)
9
+
10
+ const tsFiles = glob.sync('**/*.ts', {
11
+ cwd: __dirname,
12
+ absolute: false,
13
+ ignore: ['**/*.d.ts'],
14
+ })
15
+
16
+ const input = {}
17
+
18
+ tsFiles.forEach((file) => {
19
+ const entryName = file.replace(/\.ts$/, '')
20
+
21
+ input[entryName] = resolve(__dirname, file)
22
+ })
23
+
24
+ if (Object.keys(input).length === 0) {
25
+ throw new Error('No TypeScript files found')
26
+ }
27
+
28
+ export default defineConfig({
29
+ plugins: [
30
+ {
31
+ name: 'html-raw-import',
32
+ enforce: 'pre',
33
+ resolveId(source, importer) {
34
+ if (source.endsWith('.html') && importer) {
35
+ const resolved = resolve(dirname(importer), source)
36
+
37
+ return `${resolved}?raw`
38
+ }
39
+ },
40
+ load(id) {
41
+ if (id.endsWith('.html?raw')) {
42
+ const filePath = id.replace(/\?raw$/, '')
43
+ const content = readFileSync(filePath, 'utf-8')
44
+
45
+ return `export default ${JSON.stringify(content)}`
46
+ }
47
+ },
48
+ },
49
+ ],
50
+ build: {
51
+ minify: false,
52
+ outDir: __dirname,
53
+ lib: {
54
+ entry: input,
55
+ formats: ['es'],
56
+ },
57
+ rollupOptions: {
58
+ external: [/^@nectary\/components/],
59
+ output: {
60
+ entryFileNames: '[name].js',
61
+ chunkFileNames: '[name].js',
62
+ assetFileNames: '[name].[ext]',
63
+ },
64
+ },
65
+ },
66
+ })