@nectary/components 2.8.6 → 2.8.8
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/accordion/index.js +1 -1
- package/accordion-item/index.d.ts +1 -1
- package/accordion-item/index.js +1 -1
- package/package.json +1 -1
- package/select-menu/index.js +42 -10
- package/select-menu/types.d.ts +12 -0
- package/types.d.ts +1 -1
package/accordion/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineCustomElement, getAttribute, getBooleanAttribute,
|
|
1
|
+
import { NectaryElement, defineCustomElement, getAttribute, getBooleanAttribute, getFirstCsvValue, getReactEventHandler, getTargetByAttribute, unpackCsv, updateAttribute, updateBooleanAttribute, updateCsv } from '../utils';
|
|
2
2
|
const templateHTML = '<style>:host{display:block}#wrapper{display:flex;flex-direction:column;box-sizing:border-box;width:100%;height:100%}::slotted(sinch-accordion-item){flex-shrink:1}</style><div id="wrapper"><slot></slot></div>';
|
|
3
3
|
const template = document.createElement('template');
|
|
4
4
|
template.innerHTML = templateHTML;
|
package/accordion-item/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../icon';
|
|
2
|
-
import '../title';
|
|
3
2
|
import '../text';
|
|
3
|
+
import '../title';
|
|
4
4
|
import { defineCustomElement, getAttribute, getBooleanAttribute, getLiteralAttribute, isAttrEqual, isAttrTrue, NectaryElement, updateAttribute, updateBooleanAttribute, updateExplicitBooleanAttribute, updateLiteralAttribute } from '../utils';
|
|
5
5
|
const templateHTML = '<style>:host{display:block;outline:0;min-height:48px}#wrapper{display:flex;flex-direction:column;position:relative;width:100%;height:100%;box-sizing:border-box;overflow:hidden;border-bottom:1px solid var(--sinch-comp-accordion-color-default-border-initial)}:host(:last-child)>#wrapper{border-bottom:none}#button{all:initial;display:flex;position:relative;align-items:center;gap:8px;box-sizing:border-box;width:100%;height:48px;padding:0 4px 0 8px;cursor:pointer;--sinch-global-color-icon:var(--sinch-comp-accordion-color-default-icon-initial);--sinch-global-size-icon:var(--sinch-comp-accordion-size-icon)}#button>*{pointer-events:none}#button:disabled{cursor:initial;--sinch-global-color-icon:var(--sinch-comp-accordion-color-disabled-icon-initial)}#button:focus-visible::after{content:"";position:absolute;inset:0;border:2px solid var(--sinch-comp-accordion-color-default-outline-focus);pointer-events:none}#status-wrapper{display:none;width:18px;height:24px;padding:8px 8px 8px 2px;box-sizing:border-box}#status{width:8px;height:8px;border-radius:50%}:host([status]:not([status=""])) #status-wrapper{display:block}:host([status=success]) #status{background-color:var(--sinch-comp-accordion-color-default-status-success)}:host([status=warn]) #status{background-color:var(--sinch-comp-accordion-color-default-status-warning)}:host([status=error]) #status{background-color:var(--sinch-comp-accordion-color-default-status-error)}:host([status=info]) #status{background-color:var(--sinch-comp-accordion-color-default-status-info)}#title{flex:1;min-width:0;--sinch-comp-title-font:var(--sinch-comp-accordion-font-title);--sinch-global-color-text:var(--sinch-comp-accordion-color-default-title-initial)}#button:disabled>#title{--sinch-global-color-text:var(--sinch-comp-accordion-color-disabled-title-initial)}#content{display:none;overflow-y:auto;flex-shrink:1;min-height:0;padding:0 8px 12px}#dropdown-icon{transform:rotate(0);will-change:transform;transition:transform .25s ease-in-out}#button[aria-expanded=true]>#dropdown-icon{transform:rotate(180deg)}#button[aria-expanded=true]+#content{display:block}#optional{--sinch-comp-text-font:var(--sinch-comp-accordion-font-optional-text);--sinch-global-color-text:var(--sinch-comp-accordion-color-default-optional-text-initial)}#button:disabled>#optional{--sinch-global-color-text:var(--sinch-comp-accordion-color-disabled-optional-text-initial)}</style><div id="wrapper"><button id="button" aria-controls="content" aria-expanded="false"><div id="status-wrapper"><div id="status"></div></div><slot name="icon"></slot><sinch-title id="title" level="3" type="m" ellipsis></sinch-title><sinch-text id="optional" type="m"></sinch-text><sinch-icon id="dropdown-icon" name="keyboard_arrow_down"></sinch-icon></button><div id="content" role="region" aria-labelledby="button"><slot name="content"></slot></div></div>';
|
|
6
6
|
import { statusValues } from './utils';
|
package/package.json
CHANGED
package/select-menu/index.js
CHANGED
|
@@ -41,6 +41,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
41
41
|
this.#$search.addEventListener('-change', this.#onSearchChange, options);
|
|
42
42
|
this.#$searchClear.addEventListener('-click', this.#onSearchClearClick, options);
|
|
43
43
|
this.#$optionSlot.addEventListener('slotchange', this.#onOptionSlotChange, options);
|
|
44
|
+
this.addEventListener('-search-change', this.#onSearchChangeReactHandler, options);
|
|
44
45
|
this.addEventListener('-change', this.#onChangeReactHandler, options);
|
|
45
46
|
subscribeContext(this, 'keydown', this.#onContextKeyDown, this.#controller.signal);
|
|
46
47
|
subscribeContext(this, 'visibility', this.#onContextVisibility, this.#controller.signal);
|
|
@@ -52,7 +53,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
52
53
|
this.#controller = null;
|
|
53
54
|
}
|
|
54
55
|
static get observedAttributes() {
|
|
55
|
-
return ['value', 'rows', 'multiple'];
|
|
56
|
+
return ['value', 'rows', 'multiple', 'search-placeholder'];
|
|
56
57
|
}
|
|
57
58
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
58
59
|
switch (name) {
|
|
@@ -75,6 +76,11 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
75
76
|
});
|
|
76
77
|
break;
|
|
77
78
|
}
|
|
79
|
+
case 'search-placeholder':
|
|
80
|
+
{
|
|
81
|
+
updateAttribute(this.#$search, 'placeholder', newVal);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
set value(value) {
|
|
@@ -95,6 +101,19 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
95
101
|
get multiple() {
|
|
96
102
|
return getBooleanAttribute(this, 'multiple');
|
|
97
103
|
}
|
|
104
|
+
set searchable(isSearchable) {
|
|
105
|
+
updateBooleanAttribute(this, 'searchable', isSearchable);
|
|
106
|
+
}
|
|
107
|
+
get searchable() {
|
|
108
|
+
const searchableAttribute = this.getAttribute('searchable');
|
|
109
|
+
return searchableAttribute === null ? searchableAttribute : isAttrTrue(searchableAttribute);
|
|
110
|
+
}
|
|
111
|
+
set 'search-placeholder'(placeholder) {
|
|
112
|
+
updateAttribute(this.#$search, 'placeholder', placeholder);
|
|
113
|
+
}
|
|
114
|
+
get 'search-placeholder'() {
|
|
115
|
+
return getAttribute(this.#$search, 'placeholder', '');
|
|
116
|
+
}
|
|
98
117
|
get focusable() {
|
|
99
118
|
return true;
|
|
100
119
|
}
|
|
@@ -128,15 +147,22 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
128
147
|
};
|
|
129
148
|
#updateSearch = () => {
|
|
130
149
|
const searchValue = this.#$search.value.toLowerCase();
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
150
|
+
const searchChangedEvent = new CustomEvent('-search-change', {
|
|
151
|
+
detail: searchValue,
|
|
152
|
+
cancelable: true
|
|
153
|
+
});
|
|
154
|
+
this.dispatchEvent(searchChangedEvent);
|
|
155
|
+
if (!searchChangedEvent.defaultPrevented) {
|
|
156
|
+
const $options = this.#getOptionElements();
|
|
157
|
+
let someFound = false;
|
|
158
|
+
for (const $opt of $options) {
|
|
159
|
+
const isHidden = searchValue.length > 0 && !$opt.matchesSearch(searchValue);
|
|
160
|
+
someFound ||= !isHidden;
|
|
161
|
+
setClass($opt, 'hidden', isHidden);
|
|
162
|
+
}
|
|
163
|
+
setClass(this.#$notFound, 'active', !someFound);
|
|
164
|
+
this.#selectOption(null);
|
|
137
165
|
}
|
|
138
|
-
setClass(this.#$notFound, 'active', !someFound);
|
|
139
|
-
this.#selectOption(null);
|
|
140
166
|
};
|
|
141
167
|
#onContextKeyDown = e => {
|
|
142
168
|
this.#handleKeydown(e.detail);
|
|
@@ -179,7 +205,10 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
179
205
|
}
|
|
180
206
|
}
|
|
181
207
|
#onOptionSlotChange = () => {
|
|
182
|
-
const
|
|
208
|
+
const searchable = this.searchable;
|
|
209
|
+
const options = this.#$optionSlot.assignedElements();
|
|
210
|
+
const isEnoughOptions = options.length >= NUM_ITEMS_SEARCH;
|
|
211
|
+
const isSearchActive = isEnoughOptions && searchable !== false || Boolean(searchable);
|
|
183
212
|
if (!isSearchActive) {
|
|
184
213
|
updateAttribute(this.#$search, 'value', null);
|
|
185
214
|
}
|
|
@@ -304,4 +333,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
304
333
|
#onChangeReactHandler = e => {
|
|
305
334
|
getReactEventHandler(this, 'on-change')?.(e);
|
|
306
335
|
};
|
|
336
|
+
#onSearchChangeReactHandler = e => {
|
|
337
|
+
getReactEventHandler(this, 'on-search-change')?.(e);
|
|
338
|
+
};
|
|
307
339
|
});
|
package/select-menu/types.d.ts
CHANGED
|
@@ -6,8 +6,14 @@ export type TSinchSelectMenuElement = HTMLElement & {
|
|
|
6
6
|
rows: number | null;
|
|
7
7
|
/** Allows multiple selection */
|
|
8
8
|
multiple: boolean;
|
|
9
|
+
/** Enforce the search bar appearing, by default it appears above a certain number of options */
|
|
10
|
+
searchable: boolean | null;
|
|
11
|
+
/** Text for search bar's placeholder */
|
|
12
|
+
'search-placeholder': string;
|
|
9
13
|
/** Change value event */
|
|
10
14
|
addEventListener(type: '-change', listener: (e: CustomEvent<string>) => void): void;
|
|
15
|
+
/** Change value event */
|
|
16
|
+
addEventListener(type: '-search-change', listener: (e: CustomEvent<string>) => void): void;
|
|
11
17
|
/** Selected value, CSV when multiple */
|
|
12
18
|
setAttribute(name: 'value', value: string): void;
|
|
13
19
|
/** How many rows to show and scroll the rest */
|
|
@@ -22,8 +28,14 @@ export type TSinchSelectMenuReact = TSinchElementReact<TSinchSelectMenuElement>
|
|
|
22
28
|
rows?: number;
|
|
23
29
|
/** Allows multiple selection */
|
|
24
30
|
multiple?: boolean;
|
|
31
|
+
/** Enforce the search bar appearing, by default it appears above a certain number of options */
|
|
32
|
+
searchable?: boolean | null;
|
|
33
|
+
/** Text for search bar's placeholder */
|
|
34
|
+
'search-placeholder'?: string;
|
|
25
35
|
/** Label that is used for a11y */
|
|
26
36
|
'aria-label': string;
|
|
27
37
|
/** Change value handler */
|
|
38
|
+
'on-search-change'?: (e: CustomEvent<string>) => void;
|
|
39
|
+
/** Change value handler */
|
|
28
40
|
'on-change'?: (e: CustomEvent<string>) => void;
|
|
29
41
|
};
|
package/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClassAttributes, DOMAttributes, HTMLAttributes } from 'react'
|
|
1
|
+
import type { ClassAttributes, DOMAttributes, HTMLAttributes } from 'react';
|
|
2
2
|
|
|
3
3
|
export type TSinchElementReact<TElement> =
|
|
4
4
|
Pick<HTMLAttributes<HTMLElement>, 'id' | 'className' | 'style' | 'slot' | 'children'> &
|