@lukso/web-components 1.48.0 → 1.49.1

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 (64) hide show
  1. package/dist/components/index.cjs +8 -3
  2. package/dist/components/index.d.ts +1 -0
  3. package/dist/components/index.d.ts.map +1 -1
  4. package/dist/components/index.js +4 -3
  5. package/dist/components/lukso-button/index.cjs +2 -2
  6. package/dist/components/lukso-button/index.js +2 -2
  7. package/dist/components/lukso-card/index.cjs +3 -3
  8. package/dist/components/lukso-card/index.js +3 -3
  9. package/dist/components/lukso-checkbox/index.cjs +3 -3
  10. package/dist/components/lukso-checkbox/index.js +3 -3
  11. package/dist/components/lukso-footer/index.cjs +1 -2
  12. package/dist/components/lukso-footer/index.d.ts.map +1 -1
  13. package/dist/components/lukso-footer/index.js +1 -2
  14. package/dist/components/lukso-icon/index.cjs +2 -2
  15. package/dist/components/lukso-icon/index.js +2 -2
  16. package/dist/components/lukso-input/index.cjs +2 -2
  17. package/dist/components/lukso-input/index.js +2 -2
  18. package/dist/components/lukso-modal/index.cjs +2 -2
  19. package/dist/components/lukso-modal/index.js +2 -2
  20. package/dist/components/lukso-navbar/index.cjs +3 -3
  21. package/dist/components/lukso-navbar/index.js +3 -3
  22. package/dist/components/lukso-profile/index.cjs +3 -3
  23. package/dist/components/lukso-profile/index.js +3 -3
  24. package/dist/components/lukso-progress/index.cjs +3 -3
  25. package/dist/components/lukso-progress/index.js +3 -3
  26. package/dist/components/lukso-sanitize/index.cjs +1 -1
  27. package/dist/components/lukso-sanitize/index.js +1 -1
  28. package/dist/components/lukso-search/index.cjs +4 -4
  29. package/dist/components/lukso-search/index.js +4 -4
  30. package/dist/components/lukso-select/index.cjs +315 -0
  31. package/dist/components/lukso-select/index.d.ts +50 -0
  32. package/dist/components/lukso-select/index.d.ts.map +1 -0
  33. package/dist/components/lukso-select/index.js +313 -0
  34. package/dist/components/lukso-select/lukso-select.stories.d.ts +9 -0
  35. package/dist/components/lukso-select/lukso-select.stories.d.ts.map +1 -0
  36. package/dist/components/lukso-share/index.cjs +1 -1
  37. package/dist/components/lukso-share/index.js +1 -1
  38. package/dist/components/lukso-switch/index.cjs +3 -3
  39. package/dist/components/lukso-switch/index.js +3 -3
  40. package/dist/components/lukso-tag/index.cjs +3 -3
  41. package/dist/components/lukso-tag/index.js +3 -3
  42. package/dist/components/lukso-terms/index.cjs +3 -3
  43. package/dist/components/lukso-terms/index.js +3 -3
  44. package/dist/components/lukso-test/index.cjs +1 -1
  45. package/dist/components/lukso-test/index.js +1 -1
  46. package/dist/components/lukso-username/index.cjs +3 -3
  47. package/dist/components/lukso-username/index.js +3 -3
  48. package/dist/components/lukso-wizard/index.cjs +2 -2
  49. package/dist/components/lukso-wizard/index.js +2 -2
  50. package/dist/index-5e194caf.js +18 -0
  51. package/dist/index-c04e4744.cjs +46 -0
  52. package/dist/index-cfea1b58.js +39 -0
  53. package/dist/index-e9668573.cjs +20 -0
  54. package/dist/index.cjs +2570 -42
  55. package/dist/index.js +2531 -3
  56. package/dist/shared/tailwind-element/index.cjs +1 -1
  57. package/dist/shared/tailwind-element/index.js +1 -1
  58. package/dist/{style-map-cd69bc0c.js → style-map-b2a337a1.js} +1 -1
  59. package/dist/{style-map-d09deecd.cjs → style-map-ea2513e4.cjs} +1 -1
  60. package/package.json +6 -1
  61. package/dist/index-944f6ebe.js +0 -2543
  62. package/dist/index-97750d66.cjs +0 -2546
  63. package/dist/index-a03613f8.cjs +0 -46
  64. package/dist/index-c72ac15f.js +0 -39
@@ -0,0 +1,315 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const shared_tailwindElement_index = require('../../index-c04e4744.cjs');
6
+ const queryAssignedElements = require('../../query-assigned-elements-1d5d9d4c.cjs');
7
+ const state = require('../../state-f73a8b4f.cjs');
8
+ const index = require('../../index-e9668573.cjs');
9
+ require('../lukso-icon/index.cjs');
10
+ require('../lukso-profile/index.cjs');
11
+ require('../lukso-username/index.cjs');
12
+ require('../../directive-8278ab14.cjs');
13
+ require('../../style-map-ea2513e4.cjs');
14
+
15
+ const style = ":host {\n\n display: inline-flex\n}\n\n:host([is-full-width]) {\n\n display: flex;\n\n width: 100%\n}";
16
+
17
+ var __defProp = Object.defineProperty;
18
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result)
25
+ __defProp(target, key, result);
26
+ return result;
27
+ };
28
+ exports.LuksoSelect = class LuksoSelect extends shared_tailwindElement_index.TailwindStyledElement(style) {
29
+ constructor() {
30
+ super(...arguments);
31
+ this.value = "";
32
+ this.placeholder = "";
33
+ this.label = "";
34
+ this.id = "";
35
+ this.description = "";
36
+ this.error = "";
37
+ this.isFullWidth = false;
38
+ this.isReadonly = false;
39
+ this.isDisabled = false;
40
+ this.borderless = false;
41
+ this.options = "";
42
+ this.selected = void 0;
43
+ this.isOpen = false;
44
+ this.openTop = false;
45
+ this.optionsParsed = [];
46
+ this.valueParsed = void 0;
47
+ this.defaultInputStyles = `bg-neutral-100 paragraph-inter-14-regular px-4 py-3 pr-11
48
+ border-solid h-[48px] placeholder:text-neutral-70 select-none whitespace-nowrap
49
+ outline-none transition transition-all duration-150 appearance-none rounded-12`;
50
+ }
51
+ connectedCallback() {
52
+ super.connectedCallback();
53
+ window.addEventListener("click", this.handleOutsideDropdownClick.bind(this));
54
+ window.addEventListener("keydown", this.handleDropdownKeydown.bind(this));
55
+ }
56
+ disconnectedCallback() {
57
+ super.disconnectedCallback();
58
+ window.removeEventListener("click", this.handleOutsideDropdownClick);
59
+ window.removeEventListener("keydown", this.handleDropdownKeydown);
60
+ }
61
+ willUpdate(changedProperties) {
62
+ if (changedProperties.has("selected")) {
63
+ const selectedOption = this.shadowRoot?.querySelector(
64
+ `[data-index="${changedProperties.get("selected")}"`
65
+ );
66
+ if (selectedOption) {
67
+ selectedOption.scrollIntoView({
68
+ behavior: "smooth",
69
+ block: "center"
70
+ });
71
+ }
72
+ }
73
+ if (changedProperties.has("options")) {
74
+ try {
75
+ this.optionsParsed = JSON.parse(this.options);
76
+ } catch (error) {
77
+ console.warn("Could not parse options", error);
78
+ }
79
+ }
80
+ if (changedProperties.has("value")) {
81
+ try {
82
+ this.valueParsed = JSON.parse(this.value);
83
+ } catch (error) {
84
+ console.warn("Could not parse value", error);
85
+ }
86
+ }
87
+ }
88
+ inputTemplate() {
89
+ return shared_tailwindElement_index.x`
90
+ <div
91
+ id=${this.id}
92
+ data-testid=${this.id ? `select-${this.id}` : "select"}
93
+ class=${index.customClassMap({
94
+ [this.defaultInputStyles]: true,
95
+ ["border-neutral-90 group-hover:border-neutral-35"]: !!!this.error && !this.isDisabled,
96
+ ["border-red-85 group-hover:border-red-65"]: !!this.error,
97
+ ["w-full"]: this.isFullWidth,
98
+ ["cursor-not-allowed text-neutral-60"]: this.isDisabled,
99
+ ["text-neutral-20 cursor-pointer"]: !this.isDisabled,
100
+ [this.borderless ? "border-0" : "border"]: true
101
+ })}
102
+ @blur=${this.handleBlur}
103
+ @click=${this.handleClick}
104
+ >
105
+ ${this.value ? this.selectedValue() : this.placeholder}
106
+ </div>
107
+ `;
108
+ }
109
+ labelTemplate() {
110
+ return shared_tailwindElement_index.x`
111
+ <div class="heading-inter-14-bold text-neutral-20 pb-2 block">
112
+ ${this.label}
113
+ </div>
114
+ `;
115
+ }
116
+ descriptionTemplate() {
117
+ return shared_tailwindElement_index.x`
118
+ <div class="paragraph-inter-12-regular text-neutral-20 pb-2">
119
+ ${this.description ?? shared_tailwindElement_index.A}
120
+ </div>
121
+ `;
122
+ }
123
+ errorTemplate() {
124
+ return shared_tailwindElement_index.x`<div class="paragraph-inter-12-regular text-red-65 pt-2">
125
+ ${this.error}
126
+ </div>`;
127
+ }
128
+ optionsTemplate() {
129
+ const optionTemplates = [];
130
+ for (const option of Object.entries(this.optionsParsed)) {
131
+ const index = Number(option[0]);
132
+ if ("value" in option[1]) {
133
+ optionTemplates.push(this.optionStringTemplate(option[1], index));
134
+ } else {
135
+ console.error("Unknown option type", option);
136
+ }
137
+ }
138
+ return shared_tailwindElement_index.x`${this.dropdownWrapperTemplate(optionTemplates)}`;
139
+ }
140
+ dropdownWrapperTemplate(innerTemplate) {
141
+ return shared_tailwindElement_index.x`<div
142
+ class="bg-neutral-100 border w-full border-neutral-90 shadow-1xl rounded-12 p-3 z-50 flex absolute flex-col gap-1 overflow-y-auto max-h-64 ${index.customClassMap(
143
+ {
144
+ ["bottom-[48px] mb-2"]: this.openTop,
145
+ ["mt-2"]: !this.openTop
146
+ }
147
+ )}
148
+ )}"
149
+ >
150
+ ${innerTemplate}
151
+ </div>`;
152
+ }
153
+ optionStringTemplate(option, index$1) {
154
+ return shared_tailwindElement_index.x`<div
155
+ data-id="${option.id}"
156
+ data-index="${index$1 + 1}"
157
+ class="paragraph-inter-14-regular text-neutral-20 cursor-pointer rounded-8 p-2 whitespace-nowrap ${index.customClassMap(
158
+ {
159
+ ["bg-neutral-95 hover:bg-neutral-95"]: this.valueParsed?.id === option.id,
160
+ ["bg-neutral-98"]: this.selected === index$1 + 1 && this.valueParsed?.id !== option.id,
161
+ ["hover:bg-neutral-98"]: this.valueParsed?.id !== option.id
162
+ }
163
+ )}"
164
+ @click=${() => this.handleSelect(option)}
165
+ >
166
+ ${option.value}
167
+ </div>`;
168
+ }
169
+ selectedValue() {
170
+ const foundValue = this.optionsParsed.find(
171
+ (option) => option.id === this.valueParsed?.id
172
+ );
173
+ if (foundValue) {
174
+ return foundValue.value;
175
+ }
176
+ return "";
177
+ }
178
+ handleOutsideDropdownClick(event) {
179
+ const element = event.target;
180
+ if (element.tagName === "LUKSO-SELECT") {
181
+ return;
182
+ }
183
+ this.isOpen = false;
184
+ }
185
+ async handleDropdownKeydown(event) {
186
+ if (event.key === "ArrowUp" && this.selected && this.selected > 1 && this.isOpen) {
187
+ event.preventDefault();
188
+ this.selected = this.selected - 1;
189
+ }
190
+ if (event.key === "ArrowDown" && this.optionsParsed?.length && this.isOpen) {
191
+ event.preventDefault();
192
+ if (!this.selected) {
193
+ this.selected = 1;
194
+ } else if (this.selected < this.optionsParsed.length) {
195
+ this.selected = this.selected + 1;
196
+ }
197
+ }
198
+ if (event.key === "Enter" && this.isOpen) {
199
+ if (this.optionsParsed?.length && this.selected) {
200
+ const selectedResult = this.optionsParsed[this.selected - 1];
201
+ await this.handleSelect(selectedResult);
202
+ }
203
+ }
204
+ }
205
+ async handleSelect(option) {
206
+ if (this.isReadonly || this.isDisabled) {
207
+ return;
208
+ }
209
+ await this.updateComplete;
210
+ this.isOpen = false;
211
+ const selectEvent = new CustomEvent("on-select", {
212
+ detail: {
213
+ value: option
214
+ },
215
+ bubbles: false,
216
+ composed: true
217
+ });
218
+ this.dispatchEvent(selectEvent);
219
+ }
220
+ async handleBlur(event) {
221
+ await this.updateComplete;
222
+ const target = event.target;
223
+ const blurEvent = new CustomEvent("on-blur", {
224
+ detail: {
225
+ value: target.value,
226
+ event
227
+ },
228
+ bubbles: false,
229
+ composed: true
230
+ });
231
+ this.dispatchEvent(blurEvent);
232
+ }
233
+ handleClick() {
234
+ if (this.isDisabled) {
235
+ return;
236
+ }
237
+ this.isOpen = !this.isOpen;
238
+ }
239
+ render() {
240
+ return shared_tailwindElement_index.x`
241
+ <div class="relative w-[inherit]">
242
+ ${this.label ? this.labelTemplate() : shared_tailwindElement_index.A}
243
+ ${this.description ? this.descriptionTemplate() : shared_tailwindElement_index.A}
244
+ <div class="group">
245
+ <div class="flex relative items-center">
246
+ ${this.inputTemplate()}<lukso-icon
247
+ name=${this.isFullWidth ? "arrow-down-lg" : "arrow-down-sm"}
248
+ class="absolute right-0 mr-3 transition ${index.customClassMap({
249
+ ["opacity-60 cursor-not-allowed"]: this.isDisabled,
250
+ ["cursor-pointer"]: !this.isDisabled,
251
+ ["rotate-180"]: this.isOpen
252
+ })}"
253
+ @click=${this.handleClick}
254
+ ></lukso-icon>
255
+ </div>
256
+ <!-- options dropdown -->
257
+ ${this.isOpen && this.optionsParsed.length > 0 ? this.optionsTemplate() : shared_tailwindElement_index.A}
258
+ </div>
259
+ <!-- error -->
260
+ ${this.error ? this.errorTemplate() : shared_tailwindElement_index.A}
261
+ </div>
262
+ `;
263
+ }
264
+ };
265
+ __decorateClass([
266
+ queryAssignedElements.n({ type: String })
267
+ ], exports.LuksoSelect.prototype, "value", 2);
268
+ __decorateClass([
269
+ queryAssignedElements.n({ type: String })
270
+ ], exports.LuksoSelect.prototype, "placeholder", 2);
271
+ __decorateClass([
272
+ queryAssignedElements.n({ type: String })
273
+ ], exports.LuksoSelect.prototype, "label", 2);
274
+ __decorateClass([
275
+ queryAssignedElements.n({ type: String })
276
+ ], exports.LuksoSelect.prototype, "id", 2);
277
+ __decorateClass([
278
+ queryAssignedElements.n({ type: String })
279
+ ], exports.LuksoSelect.prototype, "description", 2);
280
+ __decorateClass([
281
+ queryAssignedElements.n({ type: String })
282
+ ], exports.LuksoSelect.prototype, "error", 2);
283
+ __decorateClass([
284
+ queryAssignedElements.n({ type: Boolean, attribute: "is-full-width" })
285
+ ], exports.LuksoSelect.prototype, "isFullWidth", 2);
286
+ __decorateClass([
287
+ queryAssignedElements.n({ type: Boolean, attribute: "is-readonly" })
288
+ ], exports.LuksoSelect.prototype, "isReadonly", 2);
289
+ __decorateClass([
290
+ queryAssignedElements.n({ type: Boolean, attribute: "is-disabled" })
291
+ ], exports.LuksoSelect.prototype, "isDisabled", 2);
292
+ __decorateClass([
293
+ queryAssignedElements.n({ type: Boolean })
294
+ ], exports.LuksoSelect.prototype, "borderless", 2);
295
+ __decorateClass([
296
+ queryAssignedElements.n({ type: String })
297
+ ], exports.LuksoSelect.prototype, "options", 2);
298
+ __decorateClass([
299
+ queryAssignedElements.n({ type: Number })
300
+ ], exports.LuksoSelect.prototype, "selected", 2);
301
+ __decorateClass([
302
+ queryAssignedElements.n({ type: Boolean, attribute: "is-open" })
303
+ ], exports.LuksoSelect.prototype, "isOpen", 2);
304
+ __decorateClass([
305
+ queryAssignedElements.n({ type: Boolean, attribute: "open-top" })
306
+ ], exports.LuksoSelect.prototype, "openTop", 2);
307
+ __decorateClass([
308
+ state.t()
309
+ ], exports.LuksoSelect.prototype, "optionsParsed", 2);
310
+ __decorateClass([
311
+ state.t()
312
+ ], exports.LuksoSelect.prototype, "valueParsed", 2);
313
+ exports.LuksoSelect = __decorateClass([
314
+ queryAssignedElements.e("lukso-select")
315
+ ], exports.LuksoSelect);
@@ -0,0 +1,50 @@
1
+ import { PropertyValues, TemplateResult } from 'lit';
2
+ export type SelectStringOption = {
3
+ id?: string;
4
+ value: string;
5
+ };
6
+ export type SelectOption = SelectStringOption;
7
+ declare const LuksoSelect_base: typeof import("lit").LitElement;
8
+ export declare class LuksoSelect extends LuksoSelect_base {
9
+ value: string;
10
+ placeholder: string;
11
+ label: string;
12
+ id: string;
13
+ description: string;
14
+ error: string;
15
+ isFullWidth: boolean;
16
+ isReadonly: boolean;
17
+ isDisabled: boolean;
18
+ borderless: boolean;
19
+ options: string;
20
+ selected: any;
21
+ isOpen: boolean;
22
+ openTop: boolean;
23
+ private optionsParsed;
24
+ private valueParsed;
25
+ private defaultInputStyles;
26
+ connectedCallback(): void;
27
+ disconnectedCallback(): void;
28
+ willUpdate(changedProperties: PropertyValues<this>): void;
29
+ inputTemplate(): TemplateResult<1>;
30
+ labelTemplate(): TemplateResult<1>;
31
+ descriptionTemplate(): TemplateResult<1>;
32
+ errorTemplate(): TemplateResult<1>;
33
+ optionsTemplate(): TemplateResult<1>;
34
+ dropdownWrapperTemplate(innerTemplate: TemplateResult<1> | TemplateResult<1>[]): TemplateResult<1>;
35
+ optionStringTemplate(option: SelectStringOption, index: number): TemplateResult<1>;
36
+ private selectedValue;
37
+ private handleOutsideDropdownClick;
38
+ private handleDropdownKeydown;
39
+ private handleSelect;
40
+ private handleBlur;
41
+ private handleClick;
42
+ render(): TemplateResult<1>;
43
+ }
44
+ declare global {
45
+ interface HTMLElementTagNameMap {
46
+ 'lukso-select': LuksoSelect;
47
+ }
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/lukso-select/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAiB,MAAM,KAAK,CAAA;AAMnE,OAAO,yBAAyB,CAAA;AAChC,OAAO,4BAA4B,CAAA;AACnC,OAAO,6BAA6B,CAAA;AAEpC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAA;;AAE7C,qBACa,WAAY,SAAQ,gBAA4B;IAE3D,KAAK,SAAK;IAGV,WAAW,SAAK;IAGhB,KAAK,SAAK;IAGV,EAAE,SAAK;IAGP,WAAW,SAAK;IAGhB,KAAK,SAAK;IAGV,WAAW,UAAQ;IAGnB,UAAU,UAAQ;IAGlB,UAAU,UAAQ;IAGlB,UAAU,UAAQ;IAGlB,OAAO,SAAK;IAGZ,QAAQ,MAAY;IAGpB,MAAM,EAAE,OAAO,CAAQ;IAGvB,OAAO,EAAE,OAAO,CAAQ;IAGxB,OAAO,CAAC,aAAa,CAAqB;IAG1C,OAAO,CAAC,WAAW,CAAsC;IAEzD,OAAO,CAAC,kBAAkB,CAEuD;IAEjF,iBAAiB;IAKjB,oBAAoB;IAMpB,UAAU,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC;IAgClD,aAAa;IAuBb,aAAa;IAQb,mBAAmB;IAQnB,aAAa;IAMb,eAAe;IAgBf,uBAAuB,CACrB,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE;IAexD,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM;IAmB9D,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,0BAA0B;YAUpB,qBAAqB;YAiCrB,YAAY;YAiBZ,UAAU;IAcxB,OAAO,CAAC,WAAW;IAQnB,MAAM;CA2BP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,WAAW,CAAA;KAC5B;CACF"}
@@ -0,0 +1,313 @@
1
+ import { T as TailwindStyledElement, x, A } from '../../index-cfea1b58.js';
2
+ import { n, e } from '../../query-assigned-elements-5d94572f.js';
3
+ import { t } from '../../state-0a779257.js';
4
+ import { c as customClassMap } from '../../index-5e194caf.js';
5
+ import '../lukso-icon/index.js';
6
+ import '../lukso-profile/index.js';
7
+ import '../lukso-username/index.js';
8
+ import '../../directive-2bb7789e.js';
9
+ import '../../style-map-b2a337a1.js';
10
+
11
+ const style = ":host {\n\n display: inline-flex\n}\n\n:host([is-full-width]) {\n\n display: flex;\n\n width: 100%\n}";
12
+
13
+ var __defProp = Object.defineProperty;
14
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
+ var __decorateClass = (decorators, target, key, kind) => {
16
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
17
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
18
+ if (decorator = decorators[i])
19
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
20
+ if (kind && result)
21
+ __defProp(target, key, result);
22
+ return result;
23
+ };
24
+ let LuksoSelect = class extends TailwindStyledElement(style) {
25
+ constructor() {
26
+ super(...arguments);
27
+ this.value = "";
28
+ this.placeholder = "";
29
+ this.label = "";
30
+ this.id = "";
31
+ this.description = "";
32
+ this.error = "";
33
+ this.isFullWidth = false;
34
+ this.isReadonly = false;
35
+ this.isDisabled = false;
36
+ this.borderless = false;
37
+ this.options = "";
38
+ this.selected = void 0;
39
+ this.isOpen = false;
40
+ this.openTop = false;
41
+ this.optionsParsed = [];
42
+ this.valueParsed = void 0;
43
+ this.defaultInputStyles = `bg-neutral-100 paragraph-inter-14-regular px-4 py-3 pr-11
44
+ border-solid h-[48px] placeholder:text-neutral-70 select-none whitespace-nowrap
45
+ outline-none transition transition-all duration-150 appearance-none rounded-12`;
46
+ }
47
+ connectedCallback() {
48
+ super.connectedCallback();
49
+ window.addEventListener("click", this.handleOutsideDropdownClick.bind(this));
50
+ window.addEventListener("keydown", this.handleDropdownKeydown.bind(this));
51
+ }
52
+ disconnectedCallback() {
53
+ super.disconnectedCallback();
54
+ window.removeEventListener("click", this.handleOutsideDropdownClick);
55
+ window.removeEventListener("keydown", this.handleDropdownKeydown);
56
+ }
57
+ willUpdate(changedProperties) {
58
+ if (changedProperties.has("selected")) {
59
+ const selectedOption = this.shadowRoot?.querySelector(
60
+ `[data-index="${changedProperties.get("selected")}"`
61
+ );
62
+ if (selectedOption) {
63
+ selectedOption.scrollIntoView({
64
+ behavior: "smooth",
65
+ block: "center"
66
+ });
67
+ }
68
+ }
69
+ if (changedProperties.has("options")) {
70
+ try {
71
+ this.optionsParsed = JSON.parse(this.options);
72
+ } catch (error) {
73
+ console.warn("Could not parse options", error);
74
+ }
75
+ }
76
+ if (changedProperties.has("value")) {
77
+ try {
78
+ this.valueParsed = JSON.parse(this.value);
79
+ } catch (error) {
80
+ console.warn("Could not parse value", error);
81
+ }
82
+ }
83
+ }
84
+ inputTemplate() {
85
+ return x`
86
+ <div
87
+ id=${this.id}
88
+ data-testid=${this.id ? `select-${this.id}` : "select"}
89
+ class=${customClassMap({
90
+ [this.defaultInputStyles]: true,
91
+ ["border-neutral-90 group-hover:border-neutral-35"]: !!!this.error && !this.isDisabled,
92
+ ["border-red-85 group-hover:border-red-65"]: !!this.error,
93
+ ["w-full"]: this.isFullWidth,
94
+ ["cursor-not-allowed text-neutral-60"]: this.isDisabled,
95
+ ["text-neutral-20 cursor-pointer"]: !this.isDisabled,
96
+ [this.borderless ? "border-0" : "border"]: true
97
+ })}
98
+ @blur=${this.handleBlur}
99
+ @click=${this.handleClick}
100
+ >
101
+ ${this.value ? this.selectedValue() : this.placeholder}
102
+ </div>
103
+ `;
104
+ }
105
+ labelTemplate() {
106
+ return x`
107
+ <div class="heading-inter-14-bold text-neutral-20 pb-2 block">
108
+ ${this.label}
109
+ </div>
110
+ `;
111
+ }
112
+ descriptionTemplate() {
113
+ return x`
114
+ <div class="paragraph-inter-12-regular text-neutral-20 pb-2">
115
+ ${this.description ?? A}
116
+ </div>
117
+ `;
118
+ }
119
+ errorTemplate() {
120
+ return x`<div class="paragraph-inter-12-regular text-red-65 pt-2">
121
+ ${this.error}
122
+ </div>`;
123
+ }
124
+ optionsTemplate() {
125
+ const optionTemplates = [];
126
+ for (const option of Object.entries(this.optionsParsed)) {
127
+ const index = Number(option[0]);
128
+ if ("value" in option[1]) {
129
+ optionTemplates.push(this.optionStringTemplate(option[1], index));
130
+ } else {
131
+ console.error("Unknown option type", option);
132
+ }
133
+ }
134
+ return x`${this.dropdownWrapperTemplate(optionTemplates)}`;
135
+ }
136
+ dropdownWrapperTemplate(innerTemplate) {
137
+ return x`<div
138
+ class="bg-neutral-100 border w-full border-neutral-90 shadow-1xl rounded-12 p-3 z-50 flex absolute flex-col gap-1 overflow-y-auto max-h-64 ${customClassMap(
139
+ {
140
+ ["bottom-[48px] mb-2"]: this.openTop,
141
+ ["mt-2"]: !this.openTop
142
+ }
143
+ )}
144
+ )}"
145
+ >
146
+ ${innerTemplate}
147
+ </div>`;
148
+ }
149
+ optionStringTemplate(option, index) {
150
+ return x`<div
151
+ data-id="${option.id}"
152
+ data-index="${index + 1}"
153
+ class="paragraph-inter-14-regular text-neutral-20 cursor-pointer rounded-8 p-2 whitespace-nowrap ${customClassMap(
154
+ {
155
+ ["bg-neutral-95 hover:bg-neutral-95"]: this.valueParsed?.id === option.id,
156
+ ["bg-neutral-98"]: this.selected === index + 1 && this.valueParsed?.id !== option.id,
157
+ ["hover:bg-neutral-98"]: this.valueParsed?.id !== option.id
158
+ }
159
+ )}"
160
+ @click=${() => this.handleSelect(option)}
161
+ >
162
+ ${option.value}
163
+ </div>`;
164
+ }
165
+ selectedValue() {
166
+ const foundValue = this.optionsParsed.find(
167
+ (option) => option.id === this.valueParsed?.id
168
+ );
169
+ if (foundValue) {
170
+ return foundValue.value;
171
+ }
172
+ return "";
173
+ }
174
+ handleOutsideDropdownClick(event) {
175
+ const element = event.target;
176
+ if (element.tagName === "LUKSO-SELECT") {
177
+ return;
178
+ }
179
+ this.isOpen = false;
180
+ }
181
+ async handleDropdownKeydown(event) {
182
+ if (event.key === "ArrowUp" && this.selected && this.selected > 1 && this.isOpen) {
183
+ event.preventDefault();
184
+ this.selected = this.selected - 1;
185
+ }
186
+ if (event.key === "ArrowDown" && this.optionsParsed?.length && this.isOpen) {
187
+ event.preventDefault();
188
+ if (!this.selected) {
189
+ this.selected = 1;
190
+ } else if (this.selected < this.optionsParsed.length) {
191
+ this.selected = this.selected + 1;
192
+ }
193
+ }
194
+ if (event.key === "Enter" && this.isOpen) {
195
+ if (this.optionsParsed?.length && this.selected) {
196
+ const selectedResult = this.optionsParsed[this.selected - 1];
197
+ await this.handleSelect(selectedResult);
198
+ }
199
+ }
200
+ }
201
+ async handleSelect(option) {
202
+ if (this.isReadonly || this.isDisabled) {
203
+ return;
204
+ }
205
+ await this.updateComplete;
206
+ this.isOpen = false;
207
+ const selectEvent = new CustomEvent("on-select", {
208
+ detail: {
209
+ value: option
210
+ },
211
+ bubbles: false,
212
+ composed: true
213
+ });
214
+ this.dispatchEvent(selectEvent);
215
+ }
216
+ async handleBlur(event) {
217
+ await this.updateComplete;
218
+ const target = event.target;
219
+ const blurEvent = new CustomEvent("on-blur", {
220
+ detail: {
221
+ value: target.value,
222
+ event
223
+ },
224
+ bubbles: false,
225
+ composed: true
226
+ });
227
+ this.dispatchEvent(blurEvent);
228
+ }
229
+ handleClick() {
230
+ if (this.isDisabled) {
231
+ return;
232
+ }
233
+ this.isOpen = !this.isOpen;
234
+ }
235
+ render() {
236
+ return x`
237
+ <div class="relative w-[inherit]">
238
+ ${this.label ? this.labelTemplate() : A}
239
+ ${this.description ? this.descriptionTemplate() : A}
240
+ <div class="group">
241
+ <div class="flex relative items-center">
242
+ ${this.inputTemplate()}<lukso-icon
243
+ name=${this.isFullWidth ? "arrow-down-lg" : "arrow-down-sm"}
244
+ class="absolute right-0 mr-3 transition ${customClassMap({
245
+ ["opacity-60 cursor-not-allowed"]: this.isDisabled,
246
+ ["cursor-pointer"]: !this.isDisabled,
247
+ ["rotate-180"]: this.isOpen
248
+ })}"
249
+ @click=${this.handleClick}
250
+ ></lukso-icon>
251
+ </div>
252
+ <!-- options dropdown -->
253
+ ${this.isOpen && this.optionsParsed.length > 0 ? this.optionsTemplate() : A}
254
+ </div>
255
+ <!-- error -->
256
+ ${this.error ? this.errorTemplate() : A}
257
+ </div>
258
+ `;
259
+ }
260
+ };
261
+ __decorateClass([
262
+ n({ type: String })
263
+ ], LuksoSelect.prototype, "value", 2);
264
+ __decorateClass([
265
+ n({ type: String })
266
+ ], LuksoSelect.prototype, "placeholder", 2);
267
+ __decorateClass([
268
+ n({ type: String })
269
+ ], LuksoSelect.prototype, "label", 2);
270
+ __decorateClass([
271
+ n({ type: String })
272
+ ], LuksoSelect.prototype, "id", 2);
273
+ __decorateClass([
274
+ n({ type: String })
275
+ ], LuksoSelect.prototype, "description", 2);
276
+ __decorateClass([
277
+ n({ type: String })
278
+ ], LuksoSelect.prototype, "error", 2);
279
+ __decorateClass([
280
+ n({ type: Boolean, attribute: "is-full-width" })
281
+ ], LuksoSelect.prototype, "isFullWidth", 2);
282
+ __decorateClass([
283
+ n({ type: Boolean, attribute: "is-readonly" })
284
+ ], LuksoSelect.prototype, "isReadonly", 2);
285
+ __decorateClass([
286
+ n({ type: Boolean, attribute: "is-disabled" })
287
+ ], LuksoSelect.prototype, "isDisabled", 2);
288
+ __decorateClass([
289
+ n({ type: Boolean })
290
+ ], LuksoSelect.prototype, "borderless", 2);
291
+ __decorateClass([
292
+ n({ type: String })
293
+ ], LuksoSelect.prototype, "options", 2);
294
+ __decorateClass([
295
+ n({ type: Number })
296
+ ], LuksoSelect.prototype, "selected", 2);
297
+ __decorateClass([
298
+ n({ type: Boolean, attribute: "is-open" })
299
+ ], LuksoSelect.prototype, "isOpen", 2);
300
+ __decorateClass([
301
+ n({ type: Boolean, attribute: "open-top" })
302
+ ], LuksoSelect.prototype, "openTop", 2);
303
+ __decorateClass([
304
+ t()
305
+ ], LuksoSelect.prototype, "optionsParsed", 2);
306
+ __decorateClass([
307
+ t()
308
+ ], LuksoSelect.prototype, "valueParsed", 2);
309
+ LuksoSelect = __decorateClass([
310
+ e("lukso-select")
311
+ ], LuksoSelect);
312
+
313
+ export { LuksoSelect };
@@ -0,0 +1,9 @@
1
+ import { Meta } from '@storybook/web-components';
2
+ /** Documentation and examples of `lukso-select` component. */
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ /** Example of select with `string` values. */
6
+ export declare const DefaultSelect: any;
7
+ /** Example of select that open top. */
8
+ export declare const OpenTop: any;
9
+ //# sourceMappingURL=lukso-select.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lukso-select.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/lukso-select/lukso-select.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAA;AAGhD,OAAO,SAAS,CAAA;AAEhB,+DAA+D;AAC/D,QAAA,MAAM,IAAI,EAAE,IAiLX,CAAA;AAED,eAAe,IAAI,CAAA;AAgDnB,+CAA+C;AAC/C,eAAO,MAAM,aAAa,KAAoB,CAAA;AAK9C,wCAAwC;AACxC,eAAO,MAAM,OAAO,KAAoB,CAAA"}