@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,64 +1,62 @@
1
- import '@nectary/components/icon';
2
- import { defineCustomElement, NectaryElement } from '../utils';
3
- import '../phone-preview-rcs-channel-info-option';
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-channel-info-option/index.js";
4
+ const templateHTML = '<style>\n:where(*, *::before, *::after) {\n box-sizing: border-box;\n padding: 0;\n border: 0;\n margin: 0;\n font: inherit;\n}\n\n.info {\n display: flex;\n flex-flow: column;\n font: var(--sinch-sys-font-body-xs);\n}\n</style>\n\n<section class="info" id="info-container">\n <slot name="contacts"></slot>\n <slot></slot>\n</section>\n';
5
+ const template = document.createElement("template");
6
6
  template.innerHTML = templateHTML;
7
- export class PhonePreviewRcsChannelInfo extends NectaryElement {
8
- #optionSlot;
9
- #controller = null;
10
- constructor() {
11
- super();
12
- const shadowRoot = this.attachShadow();
13
- shadowRoot.appendChild(template.content.cloneNode(true));
14
- this.#optionSlot = shadowRoot.querySelector('slot');
15
- }
16
- connectedCallback() {
17
- super.connectedCallback();
18
- this.#controller = new AbortController();
19
- const { signal } = this.#controller;
20
- this.#optionSlot.addEventListener('slotchange', this.#onSlotChange, { signal });
21
- this.#onSlotChange();
22
- }
23
- disconnectedCallback() {
24
- super.disconnectedCallback();
25
- this.#controller?.abort();
26
- this.#controller = null;
27
- }
28
- static get observedAttributes() {
29
- return [];
30
- }
31
- attributeChangedCallback(name, oldVal, newVal) {
32
- if (oldVal === newVal) {
33
- // No change needed
34
- }
35
- }
36
- #onSlotChange = () => {
37
- const options = this.#getOptionElements();
38
- // If no options are provided, show placeholder data
39
- if (options.length === 0) {
40
- this.#showPlaceholders();
41
- }
42
- };
43
- #getOptionElements() {
44
- const assignedElements = this.#optionSlot.assignedElements();
45
- return assignedElements.filter((el) => el.tagName.toLowerCase() === 'sinch-labs-phone-preview-rcs-channel-info-option');
46
- }
47
- #showPlaceholders() {
48
- // Create placeholder options when no content is provided
49
- const placeholders = [
50
- { type: 'phone', contact: '+1234567890', label: 'Contact us' },
51
- { type: 'website', contact: 'https://company.com', label: 'Contact us' },
52
- { type: 'email', contact: 'mail@company.com', label: 'Contact us' },
53
- ];
54
- placeholders.forEach(({ type, contact, label }) => {
55
- const option = document.createElement('sinch-labs-phone-preview-rcs-channel-info-option');
56
- option.setAttribute('type', type);
57
- option.setAttribute('contact', contact);
58
- option.setAttribute('label', label);
59
- option.setAttribute('placeholder', '');
60
- this.appendChild(option);
61
- });
7
+ class PhonePreviewRcsChannelInfo extends NectaryElement {
8
+ #optionSlot;
9
+ #controller = null;
10
+ constructor() {
11
+ super();
12
+ const shadowRoot = this.attachShadow();
13
+ shadowRoot.appendChild(template.content.cloneNode(true));
14
+ this.#optionSlot = shadowRoot.querySelector("slot");
15
+ }
16
+ connectedCallback() {
17
+ super.connectedCallback();
18
+ this.#controller = new AbortController();
19
+ const { signal } = this.#controller;
20
+ this.#optionSlot.addEventListener("slotchange", this.#onSlotChange, { signal });
21
+ this.#onSlotChange();
22
+ }
23
+ disconnectedCallback() {
24
+ super.disconnectedCallback();
25
+ this.#controller?.abort();
26
+ this.#controller = null;
27
+ }
28
+ static get observedAttributes() {
29
+ return [];
30
+ }
31
+ attributeChangedCallback(name, oldVal, newVal) {
32
+ }
33
+ #onSlotChange = () => {
34
+ const options = this.#getOptionElements();
35
+ if (options.length === 0) {
36
+ this.#showPlaceholders();
62
37
  }
38
+ };
39
+ #getOptionElements() {
40
+ const assignedElements = this.#optionSlot.assignedElements();
41
+ return assignedElements.filter((el) => el.tagName.toLowerCase() === "sinch-labs-phone-preview-rcs-channel-info-option");
42
+ }
43
+ #showPlaceholders() {
44
+ const placeholders = [
45
+ { type: "phone", contact: "+1234567890", label: "Contact us" },
46
+ { type: "website", contact: "https://company.com", label: "Contact us" },
47
+ { type: "email", contact: "mail@company.com", label: "Contact us" }
48
+ ];
49
+ placeholders.forEach(({ type, contact, label }) => {
50
+ const option = document.createElement("sinch-labs-phone-preview-rcs-channel-info-option");
51
+ option.setAttribute("type", type);
52
+ option.setAttribute("contact", contact);
53
+ option.setAttribute("label", label);
54
+ option.setAttribute("placeholder", "");
55
+ this.appendChild(option);
56
+ });
57
+ }
63
58
  }
64
- defineCustomElement('sinch-labs-phone-preview-rcs-channel-info', PhonePreviewRcsChannelInfo);
59
+ defineCustomElement("sinch-labs-phone-preview-rcs-channel-info", PhonePreviewRcsChannelInfo);
60
+ export {
61
+ PhonePreviewRcsChannelInfo
62
+ };
@@ -1,106 +1,101 @@
1
- import '@nectary/components/icon';
2
- import { defineCustomElement, NectaryElement } from '../utils';
3
- import templateHTML from './template.html';
4
- const template = document.createElement('template');
1
+ import "@nectary/components/icon";
2
+ import { defineCustomElement, NectaryElement } from "../utils/element.js";
3
+ const templateHTML = '<style>\n:where(*, *::before, *::after) {\n box-sizing: border-box;\n padding: 0;\n border: 0;\n margin: 0;\n font: inherit;\n}\n\na {\n display: grid;\n grid-template:\n "icon contact" auto\n "icon label " auto\n / auto 1fr;\n align-items: center;\n gap: 0 16px;\n padding: 8px 16px;\n border-block-end:\n 1px solid\n var(--sinch-sys-color-surface-secondary-active);\n color: currentcolor;\n word-break: break-all;\n text-decoration: none;\n}\n\na > sinch-icon {\n grid-area: icon;\n}\n\na > #contact {\n grid-area: contact;\n}\n\na > #contact::before {\n content: "\\200b";\n}\n\na > #label {\n grid-area: label;\n}\n\na > #label::before {\n content: "\\200b";\n}\n\na[inert] {\n --sinch-global-color-icon: currentcolor;\n\n color: var(--sinch-sys-color-text-muted);\n}\n</style>\n\n<a target="_blank">\n <sinch-icon icons-version="2"></sinch-icon>\n <span id="contact"></span>\n <p id="label"></p>\n</a>\n';
4
+ const template = document.createElement("template");
5
5
  template.innerHTML = templateHTML;
6
- export class PhonePreviewRcsChannelInfoOption extends NectaryElement {
7
- #link;
8
- #icon;
9
- #contact;
10
- #label;
11
- constructor() {
12
- super();
13
- const shadowRoot = this.attachShadow();
14
- shadowRoot.appendChild(template.content.cloneNode(true));
15
- this.#link = shadowRoot.querySelector('a');
16
- this.#icon = shadowRoot.querySelector('sinch-icon');
17
- this.#contact = shadowRoot.querySelector('#contact');
18
- this.#label = shadowRoot.querySelector('#label');
6
+ class PhonePreviewRcsChannelInfoOption extends NectaryElement {
7
+ #link;
8
+ #icon;
9
+ #contact;
10
+ #label;
11
+ constructor() {
12
+ super();
13
+ const shadowRoot = this.attachShadow();
14
+ shadowRoot.appendChild(template.content.cloneNode(true));
15
+ this.#link = shadowRoot.querySelector("a");
16
+ this.#icon = shadowRoot.querySelector("sinch-icon");
17
+ this.#contact = shadowRoot.querySelector("#contact");
18
+ this.#label = shadowRoot.querySelector("#label");
19
+ }
20
+ connectedCallback() {
21
+ super.connectedCallback();
22
+ this.#updateUI();
23
+ }
24
+ static get observedAttributes() {
25
+ return ["type", "contact", "label", "placeholder"];
26
+ }
27
+ attributeChangedCallback(name, oldVal, newVal) {
28
+ if (oldVal === newVal) {
29
+ return;
19
30
  }
20
- connectedCallback() {
21
- super.connectedCallback();
22
- this.#updateUI();
31
+ this.#updateUI();
32
+ }
33
+ get type() {
34
+ return this.getAttribute("type") ?? "phone";
35
+ }
36
+ set type(value) {
37
+ this.setAttribute("type", value);
38
+ }
39
+ get contact() {
40
+ return this.getAttribute("contact") ?? "";
41
+ }
42
+ set contact(value) {
43
+ this.setAttribute("contact", value);
44
+ }
45
+ get label() {
46
+ return this.getAttribute("label") ?? "";
47
+ }
48
+ set label(value) {
49
+ this.setAttribute("label", value);
50
+ }
51
+ get placeholder() {
52
+ return this.hasAttribute("placeholder");
53
+ }
54
+ set placeholder(value) {
55
+ if (value) {
56
+ this.setAttribute("placeholder", "");
57
+ } else {
58
+ this.removeAttribute("placeholder");
23
59
  }
24
- static get observedAttributes() {
25
- return ['type', 'contact', 'label', 'placeholder'];
60
+ }
61
+ #updateUI() {
62
+ if (!this.isDomConnected) {
63
+ return;
26
64
  }
27
- attributeChangedCallback(name, oldVal, newVal) {
28
- if (oldVal === newVal) {
29
- return;
30
- }
31
- this.#updateUI();
65
+ const type = this.type;
66
+ const contact = this.contact;
67
+ const label = this.label;
68
+ const isPlaceholder = this.placeholder;
69
+ let iconName = "fa-phone";
70
+ let href = `tel:${contact}`;
71
+ switch (type) {
72
+ case "website":
73
+ iconName = "fa-earth-americas";
74
+ href = contact;
75
+ break;
76
+ case "email":
77
+ iconName = "envelope";
78
+ href = `mailto:${contact}`;
79
+ break;
80
+ case "phone":
81
+ default:
82
+ iconName = "fa-phone";
83
+ href = `tel:${contact}`;
84
+ break;
32
85
  }
33
- get type() {
34
- return this.getAttribute('type') ?? 'phone';
35
- }
36
- set type(value) {
37
- this.setAttribute('type', value);
38
- }
39
- get contact() {
40
- return this.getAttribute('contact') ?? '';
41
- }
42
- set contact(value) {
43
- this.setAttribute('contact', value);
44
- }
45
- get label() {
46
- return this.getAttribute('label') ?? '';
47
- }
48
- set label(value) {
49
- this.setAttribute('label', value);
50
- }
51
- get placeholder() {
52
- return this.hasAttribute('placeholder');
53
- }
54
- set placeholder(value) {
55
- if (value) {
56
- this.setAttribute('placeholder', '');
57
- }
58
- else {
59
- this.removeAttribute('placeholder');
60
- }
61
- }
62
- #updateUI() {
63
- if (!this.isDomConnected) {
64
- return;
65
- }
66
- const type = this.type;
67
- const contact = this.contact;
68
- const label = this.label;
69
- const isPlaceholder = this.placeholder;
70
- // Set icon based on type
71
- let iconName = 'fa-phone';
72
- let href = `tel:${contact}`;
73
- switch (type) {
74
- case 'website':
75
- iconName = 'fa-earth-americas';
76
- href = contact;
77
- break;
78
- case 'email':
79
- iconName = 'envelope';
80
- href = `mailto:${contact}`;
81
- break;
82
- case 'phone':
83
- default:
84
- iconName = 'fa-phone';
85
- href = `tel:${contact}`;
86
- break;
87
- }
88
- // Update icon
89
- this.#icon.setAttribute('name', iconName);
90
- // Update link
91
- this.#link.href = href;
92
- this.#link.target = '_blank';
93
- // Set inert if it's a placeholder
94
- if (isPlaceholder) {
95
- this.#link.setAttribute('inert', '');
96
- }
97
- else {
98
- this.#link.removeAttribute('inert');
99
- }
100
- // Update contact text
101
- this.#contact.textContent = contact;
102
- // Update label text
103
- this.#label.textContent = label;
86
+ this.#icon.setAttribute("name", iconName);
87
+ this.#link.href = href;
88
+ this.#link.target = "_blank";
89
+ if (isPlaceholder) {
90
+ this.#link.setAttribute("inert", "");
91
+ } else {
92
+ this.#link.removeAttribute("inert");
104
93
  }
94
+ this.#contact.textContent = contact;
95
+ this.#label.textContent = label;
96
+ }
105
97
  }
106
- defineCustomElement('sinch-labs-phone-preview-rcs-channel-info-option', PhonePreviewRcsChannelInfoOption);
98
+ defineCustomElement("sinch-labs-phone-preview-rcs-channel-info-option", PhonePreviewRcsChannelInfoOption);
99
+ export {
100
+ PhonePreviewRcsChannelInfoOption
101
+ };
@@ -1,46 +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:where(*, *::before, *::after) {\n box-sizing: border-box;\n padding: 0;\n border: 0;\n margin: 0;\n font: inherit;\n}\n\n.options {\n display: flex;\n flex-flow: column;\n font: var(--sinch-sys-font-body-xs);\n}\n\n.options > header {\n padding-block-end: 8px;\n}\n\n.options > span {\n font: var(--sinch-sys-font-body-xxs);\n}\n\n.options > button {\n padding: 4px;\n outline: none;\n background: transparent;\n text-align: start;\n}\n\n.options > hr {\n border-color: var(--sinch-sys-color-surface-secondary-active);\n}\n</style>\n\n<section class="options" id="options-container">\n <header>Notifications</header>\n <span>Business</span>\n <button>Block & report spam</button>\n <hr />\n <button>View Privacy Policy</button>\n <hr />\n <button>View Terms of Service</button>\n <hr />\n <button>Learn mode</button>\n</section>\n';
3
+ const template = document.createElement("template");
4
4
  template.innerHTML = templateHTML;
5
- export class PhonePreviewRcsChannelOptions extends NectaryElement {
6
- #optionsContainer;
7
- #controller = null;
8
- constructor() {
9
- super();
10
- const shadowRoot = this.attachShadow();
11
- shadowRoot.appendChild(template.content.cloneNode(true));
12
- this.#optionsContainer = shadowRoot.querySelector('#options-container');
13
- }
14
- connectedCallback() {
15
- super.connectedCallback();
16
- this.#controller = new AbortController();
17
- const { signal } = this.#controller;
18
- this.#optionsContainer.addEventListener('click', this.#onOptionClick, { signal });
19
- }
20
- disconnectedCallback() {
21
- super.disconnectedCallback();
22
- this.#controller?.abort();
23
- this.#controller = null;
24
- }
25
- static get observedAttributes() {
26
- return [];
27
- }
28
- attributeChangedCallback(name, oldVal, newVal) {
29
- if (oldVal === newVal) {
30
- // No change needed
5
+ class PhonePreviewRcsChannelOptions extends NectaryElement {
6
+ #optionsContainer;
7
+ #controller = null;
8
+ constructor() {
9
+ super();
10
+ const shadowRoot = this.attachShadow();
11
+ shadowRoot.appendChild(template.content.cloneNode(true));
12
+ this.#optionsContainer = shadowRoot.querySelector("#options-container");
13
+ }
14
+ connectedCallback() {
15
+ super.connectedCallback();
16
+ this.#controller = new AbortController();
17
+ const { signal } = this.#controller;
18
+ this.#optionsContainer.addEventListener("click", this.#onOptionClick, { signal });
19
+ }
20
+ disconnectedCallback() {
21
+ super.disconnectedCallback();
22
+ this.#controller?.abort();
23
+ this.#controller = null;
24
+ }
25
+ static get observedAttributes() {
26
+ return [];
27
+ }
28
+ attributeChangedCallback(name, oldVal, newVal) {
29
+ }
30
+ #onOptionClick = (event) => {
31
+ const target = event.target;
32
+ if (target.tagName === "BUTTON") {
33
+ const buttonText = target.textContent?.trim();
34
+ this.dispatchEvent(new CustomEvent("-option-click", {
35
+ detail: {
36
+ action: buttonText,
37
+ element: target
31
38
  }
39
+ }));
32
40
  }
33
- #onOptionClick = (event) => {
34
- const target = event.target;
35
- if (target.tagName === 'BUTTON') {
36
- const buttonText = target.textContent?.trim();
37
- this.dispatchEvent(new CustomEvent('-option-click', {
38
- detail: {
39
- action: buttonText,
40
- element: target,
41
- },
42
- }));
43
- }
44
- };
41
+ };
45
42
  }
46
- defineCustomElement('sinch-labs-phone-preview-rcs-channel-options', PhonePreviewRcsChannelOptions);
43
+ defineCustomElement("sinch-labs-phone-preview-rcs-channel-options", PhonePreviewRcsChannelOptions);
44
+ export {
45
+ PhonePreviewRcsChannelOptions
46
+ };
@@ -1,79 +1,79 @@
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:where(*, *::before, *::after) {\n box-sizing: border-box;\n padding: 0;\n border: 0;\n margin: 0;\n font: inherit;\n}\n\n.tabs {\n --highlight-color: var(--sinch-sys-color-text-default);\n\n display: flex;\n}\n\n.tabs > button {\n flex: 1;\n padding-block-end: 10px;\n border-block-end: 2px solid transparent;\n outline: none;\n background: transparent;\n color: var(--sinch-sys-color-text-disabled);\n font: var(--sinch-sys-font-desktop-title-xs);\n}\n\n.tabs > button.active {\n color: var(--sinch-sys-color-primary-default);\n border-block-end: 2px solid var(--highlight-color);\n}\n</style>\n\n<section class="tabs" id="tabs-container">\n <button>Info</button>\n <button>Options</button>\n</section>\n';
3
+ const template = document.createElement("template");
4
4
  template.innerHTML = templateHTML;
5
- export class PhonePreviewRcsChannelTabs extends NectaryElement {
6
- #tabsContainer;
7
- #controller = null;
8
- constructor() {
9
- super();
10
- const shadowRoot = this.attachShadow();
11
- shadowRoot.appendChild(template.content.cloneNode(true));
12
- this.#tabsContainer = shadowRoot.querySelector('#tabs-container');
5
+ class PhonePreviewRcsChannelTabs extends NectaryElement {
6
+ #tabsContainer;
7
+ #controller = null;
8
+ constructor() {
9
+ super();
10
+ const shadowRoot = this.attachShadow();
11
+ shadowRoot.appendChild(template.content.cloneNode(true));
12
+ this.#tabsContainer = shadowRoot.querySelector("#tabs-container");
13
+ }
14
+ connectedCallback() {
15
+ super.connectedCallback();
16
+ this.#controller = new AbortController();
17
+ const { signal } = this.#controller;
18
+ this.#tabsContainer.addEventListener("click", this.#onTabClick, { signal });
19
+ this.#updateUI();
20
+ }
21
+ disconnectedCallback() {
22
+ super.disconnectedCallback();
23
+ this.#controller?.abort();
24
+ this.#controller = null;
25
+ }
26
+ static get observedAttributes() {
27
+ return ["color", "active-tab"];
28
+ }
29
+ attributeChangedCallback(name, oldVal, newVal) {
30
+ if (oldVal === newVal) {
31
+ return;
13
32
  }
14
- connectedCallback() {
15
- super.connectedCallback();
16
- this.#controller = new AbortController();
17
- const { signal } = this.#controller;
18
- this.#tabsContainer.addEventListener('click', this.#onTabClick, { signal });
19
- this.#updateUI();
33
+ this.#updateUI();
34
+ }
35
+ get color() {
36
+ return this.getAttribute("color") ?? "var(--sinch-sys-color-primary-default)";
37
+ }
38
+ set color(value) {
39
+ this.setAttribute("color", value);
40
+ }
41
+ get activeTab() {
42
+ const value = this.getAttribute("active-tab");
43
+ return value !== null ? parseInt(value, 10) : 0;
44
+ }
45
+ set activeTab(value) {
46
+ this.setAttribute("active-tab", value.toString());
47
+ }
48
+ #updateUI() {
49
+ if (!this.isDomConnected) {
50
+ return;
20
51
  }
21
- disconnectedCallback() {
22
- super.disconnectedCallback();
23
- this.#controller?.abort();
24
- this.#controller = null;
52
+ this.#tabsContainer.style.setProperty("--highlight-color", this.color);
53
+ const buttons = this.#tabsContainer.querySelectorAll("button");
54
+ buttons.forEach((button, index) => {
55
+ if (index === this.activeTab) {
56
+ button.classList.add("active");
57
+ } else {
58
+ button.classList.remove("active");
59
+ }
60
+ });
61
+ }
62
+ #onTabClick = (event) => {
63
+ const target = event.target;
64
+ if (target.tagName === "BUTTON") {
65
+ const buttons = Array.from(this.#tabsContainer.querySelectorAll("button"));
66
+ const clickedIndex = buttons.indexOf(target);
67
+ if (clickedIndex !== -1) {
68
+ this.activeTab = clickedIndex;
69
+ this.dispatchEvent(new CustomEvent("-tab-change", {
70
+ detail: clickedIndex
71
+ }));
72
+ }
25
73
  }
26
- static get observedAttributes() {
27
- return ['color', 'active-tab'];
28
- }
29
- attributeChangedCallback(name, oldVal, newVal) {
30
- if (oldVal === newVal) {
31
- return;
32
- }
33
- this.#updateUI();
34
- }
35
- get color() {
36
- return this.getAttribute('color') ?? 'var(--sinch-sys-color-primary-default)';
37
- }
38
- set color(value) {
39
- this.setAttribute('color', value);
40
- }
41
- get activeTab() {
42
- const value = this.getAttribute('active-tab');
43
- return (value !== null) ? parseInt(value, 10) : 0;
44
- }
45
- set activeTab(value) {
46
- this.setAttribute('active-tab', value.toString());
47
- }
48
- #updateUI() {
49
- if (!this.isDomConnected) {
50
- return;
51
- }
52
- // Update CSS custom property for highlight color
53
- this.#tabsContainer.style.setProperty('--highlight-color', this.color);
54
- // Update active tab state
55
- const buttons = this.#tabsContainer.querySelectorAll('button');
56
- buttons.forEach((button, index) => {
57
- if (index === this.activeTab) {
58
- button.classList.add('active');
59
- }
60
- else {
61
- button.classList.remove('active');
62
- }
63
- });
64
- }
65
- #onTabClick = (event) => {
66
- const target = event.target;
67
- if (target.tagName === 'BUTTON') {
68
- const buttons = Array.from(this.#tabsContainer.querySelectorAll('button'));
69
- const clickedIndex = buttons.indexOf(target);
70
- if (clickedIndex !== -1) {
71
- this.activeTab = clickedIndex;
72
- this.dispatchEvent(new CustomEvent('-tab-change', {
73
- detail: clickedIndex,
74
- }));
75
- }
76
- }
77
- };
74
+ };
78
75
  }
79
- defineCustomElement('sinch-labs-phone-preview-rcs-channel-tabs', PhonePreviewRcsChannelTabs);
76
+ defineCustomElement("sinch-labs-phone-preview-rcs-channel-tabs", PhonePreviewRcsChannelTabs);
77
+ export {
78
+ PhonePreviewRcsChannelTabs
79
+ };