@statistikzh/leu 0.0.2 → 0.1.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.
Files changed (48) hide show
  1. package/.github/workflows/release-please.yml +20 -1
  2. package/CHANGELOG.md +12 -0
  3. package/babel.config.json +3 -0
  4. package/dist/{Button-83c6df93.js → Button.js} +58 -50
  5. package/dist/ButtonGroup.js +75 -0
  6. package/dist/Checkbox.js +60 -57
  7. package/dist/CheckboxGroup.js +35 -41
  8. package/dist/{Chip-60af1402.js → Chip-389013ff.js} +12 -13
  9. package/dist/ChipGroup.js +27 -34
  10. package/dist/ChipLink.js +18 -19
  11. package/dist/ChipRemovable.js +9 -13
  12. package/dist/ChipSelectable.js +42 -44
  13. package/dist/Dropdown.js +75 -0
  14. package/dist/Input.js +112 -122
  15. package/dist/Menu.js +33 -0
  16. package/dist/MenuItem.js +171 -0
  17. package/dist/Pagination.js +193 -0
  18. package/dist/Radio.js +26 -22
  19. package/dist/RadioGroup.js +75 -105
  20. package/dist/Select.js +103 -337
  21. package/dist/Table.js +294 -8
  22. package/dist/defineElement-ba770aed.js +44 -0
  23. package/dist/icon-03e86700.js +136 -0
  24. package/dist/index.js +14 -9
  25. package/dist/leu-button-group.js +8 -0
  26. package/dist/leu-button.js +7 -0
  27. package/dist/leu-checkbox-group.js +1 -1
  28. package/dist/leu-checkbox.js +2 -2
  29. package/dist/leu-chip-group.js +1 -1
  30. package/dist/leu-chip-link.js +2 -2
  31. package/dist/leu-chip-removable.js +3 -3
  32. package/dist/leu-chip-selectable.js +2 -2
  33. package/dist/leu-dropdown.js +10 -0
  34. package/dist/leu-input.js +2 -2
  35. package/dist/leu-menu-item.js +6 -0
  36. package/dist/leu-menu.js +5 -0
  37. package/dist/leu-pagination.js +8 -0
  38. package/dist/leu-radio-group.js +1 -1
  39. package/dist/leu-radio.js +1 -1
  40. package/dist/leu-select.js +5 -3
  41. package/dist/leu-table.js +5 -4
  42. package/index.js +7 -3
  43. package/package.json +3 -1
  44. package/rollup.config.js +26 -9
  45. package/.github/workflows/publish.yml +0 -19
  46. package/dist/Table-72d305d7.js +0 -506
  47. package/dist/defineElement-47d4f665.js +0 -15
  48. package/dist/icon-b68c7e1e.js +0 -202
package/dist/Select.js CHANGED
@@ -1,11 +1,13 @@
1
+ import { _ as _defineProperty, d as defineElement } from './defineElement-ba770aed.js';
1
2
  import { css, LitElement, html, nothing } from 'lit';
2
3
  import { classMap } from 'lit/directives/class-map.js';
3
4
  import { map } from 'lit/directives/map.js';
4
5
  import { ifDefined } from 'lit/directives/if-defined.js';
5
6
  import { createRef, ref } from 'lit/directives/ref.js';
6
- import { a as ICON_NAMES, I as Icon } from './icon-b68c7e1e.js';
7
- import { d as defineElement } from './defineElement-47d4f665.js';
8
- import { d as defineButtonElements } from './Button-83c6df93.js';
7
+ import { I as Icon } from './icon-03e86700.js';
8
+ import { defineButtonElements } from './Button.js';
9
+ import { defineMenuElements } from './Menu.js';
10
+ import { defineMenuItemElements } from './MenuItem.js';
9
11
  import { defineInputElements } from './Input.js';
10
12
 
11
13
  /**
@@ -19,9 +21,18 @@ import { defineInputElements } from './Input.js';
19
21
  */
20
22
  class HasSlotController {
21
23
  constructor(host, slotNames) {
24
+ /**
25
+ * @private
26
+ * @param {Event} event
27
+ */
28
+ _defineProperty(this, "handleSlotChange", event => {
29
+ const slot = event.target;
30
+ if (this.slotNames.includes("[default]") && !slot.name || slot.name && this.slotNames.includes(slot.name)) {
31
+ this.host.requestUpdate();
32
+ }
33
+ });
22
34
  this.host = host;
23
35
  host.addController(this);
24
-
25
36
  this.slotNames = slotNames;
26
37
  }
27
38
 
@@ -30,22 +41,20 @@ class HasSlotController {
30
41
  * @returns {Boolean}
31
42
  */
32
43
  hasDefaultSlot() {
33
- return [...this.host.childNodes].some((node) => {
44
+ return [...this.host.childNodes].some(node => {
34
45
  if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== "") {
35
- return true
46
+ return true;
36
47
  }
37
-
38
48
  if (node.nodeType === node.ELEMENT_NODE) {
39
49
  const el = node;
40
50
 
41
51
  // If it doesn't have a slot attribute, it's part of the default slot
42
52
  if (!el.hasAttribute("slot")) {
43
- return true
53
+ return true;
44
54
  }
45
55
  }
46
-
47
- return false
48
- })
56
+ return false;
57
+ });
49
58
  }
50
59
 
51
60
  /**
@@ -54,7 +63,7 @@ class HasSlotController {
54
63
  * @returns {Boolean}
55
64
  */
56
65
  hasNamedSlot(name) {
57
- return this.host.querySelector(`:scope > [slot="${name}"]`) !== null
66
+ return this.host.querySelector(`:scope > [slot="${name}"]`) !== null;
58
67
  }
59
68
 
60
69
  /**
@@ -62,235 +71,16 @@ class HasSlotController {
62
71
  * @returns {Boolean}
63
72
  */
64
73
  test(slotName) {
65
- return slotName === "[default]"
66
- ? this.hasDefaultSlot()
67
- : this.hasNamedSlot(slotName)
74
+ return slotName === "[default]" ? this.hasDefaultSlot() : this.hasNamedSlot(slotName);
68
75
  }
69
-
70
76
  hostConnected() {
71
77
  this.host.shadowRoot.addEventListener("slotchange", this.handleSlotChange);
72
78
  }
73
-
74
79
  hostDisconnected() {
75
- this.host.shadowRoot.removeEventListener(
76
- "slotchange",
77
- this.handleSlotChange
78
- );
79
- }
80
-
81
- /**
82
- * @private
83
- * @param {Event} event
84
- */
85
- handleSlotChange = (event) => {
86
- const slot = event.target;
87
-
88
- if (
89
- (this.slotNames.includes("[default]") && !slot.name) ||
90
- (slot.name && this.slotNames.includes(slot.name))
91
- ) {
92
- this.host.requestUpdate();
93
- }
94
- }
95
- }
96
-
97
- var css_248z$2 = css`:host,
98
- :host * {
99
- box-sizing: border-box;
100
- }
101
-
102
- :host {
103
- --menu-divider-color: var(--leu-color-black-transp-20);
104
- }
105
-
106
- :host ::slotted(hr) {
107
- border: 0;
108
- border-top: 1px solid var(--menu-divider-color);
109
- margin: 0.5rem 0;
110
- }
111
- `;
112
-
113
- /**
114
- * @tagname leu-menu
115
- */
116
- class LeuMenu extends LitElement {
117
- static styles = css_248z$2
118
-
119
- render() {
120
- return html`<slot></slot>`
80
+ this.host.shadowRoot.removeEventListener("slotchange", this.handleSlotChange);
121
81
  }
122
82
  }
123
83
 
124
- function defineMenuElements() {
125
- defineElement("menu", LeuMenu);
126
- }
127
-
128
- var css_248z$1 = css`:host,
129
- :host * {
130
- box-sizing: border-box;
131
- }
132
-
133
- :host {
134
- --background: var(--leu-color-black-0);
135
- --background-hover: var(--leu-color-black-10);
136
- --background-active: var(--leu-color-func-cyan);
137
- --background-disabled: var(--leu-color-black-0);
138
- --color: var(--leu-color-black-transp-60);
139
- --font-regular: var(--leu-font-regular);
140
- --font-black: var(--leu-font-black);
141
-
142
- font-family: var(--chip-font-regular);
143
- }
144
-
145
- .button {
146
- -webkit-appearance: none;
147
- -moz-appearance: none;
148
- appearance: none;
149
- border: none;
150
- cursor: pointer;
151
-
152
- display: flex;
153
- align-items: center;
154
- gap: 0.5rem;
155
- width: 100%;
156
-
157
- padding: 0.75rem;
158
-
159
- font-size: 1rem;
160
- line-height: 1.5;
161
- text-align: left;
162
-
163
- background: var(--background);
164
- color: var(--color);
165
- }
166
-
167
- .button:focus-visible {
168
- outline: 2px solid var(--leu-color-func-cyan);
169
- outline-offset: 2px;
170
- }
171
-
172
- .button:hover,
173
- :host([highlighted]) .button {
174
- --background: var(--background-hover);
175
- }
176
-
177
- :host([active]) .button {
178
- --background: var(--background-active);
179
- }
180
-
181
- :host([disabled]) .button {
182
- --background: var(--background-disabled);
183
- cursor: default;
184
- }
185
-
186
- .before svg, .after svg {
187
- display: block;
188
- }
189
-
190
- .label {
191
- flex: 1;
192
- overflow: hidden;
193
- text-overflow: ellipsis;
194
- white-space: nowrap;
195
- }
196
-
197
- .icon-placeholder {
198
- display: block;
199
- width: 1.5rem;
200
- aspect-ratio: 1;
201
- }
202
- `;
203
-
204
- /**
205
- * @tagname leu-menu-item
206
- * @slot - The label of the menu item
207
- */
208
- class LeuMenuItem extends LitElement {
209
- static styles = css_248z$1
210
-
211
- /**
212
- * @internal
213
- */
214
- static shadowRootOptions = {
215
- ...LitElement.shadowRootOptions,
216
- delegatesFocus: true,
217
- }
218
-
219
- static properties = {
220
- /**
221
- * Can be either an icon name or a text
222
- * If no icon with this value is found, it will be displayed as text.
223
- * If the value is "EMPTY", an empty placeholder with the size of an icon will be displayed.
224
- */
225
- before: { type: String },
226
- /**
227
- * Can be either an icon name or a text
228
- * If no icon with this value is found, it will be displayed as text
229
- * If the value is "EMPTY", an empty placeholder with the size of an icon will be displayed.
230
- */
231
- after: { type: String },
232
- active: { type: Boolean, reflect: true },
233
- highlighted: { type: Boolean, reflect: true },
234
- disabled: { type: Boolean, reflect: true },
235
- }
236
-
237
- constructor() {
238
- super();
239
-
240
- this.active = false;
241
- this.disabled = false;
242
- this.before = "";
243
- this.after = "";
244
-
245
- /**
246
- * A programmatic way to highlight the menu item like it is hovered.
247
- * This is just a visual effect and does not change the active state.
248
- */
249
- this.highlighted = false;
250
- }
251
-
252
- static getIconOrText(name) {
253
- if (ICON_NAMES.includes(name)) {
254
- return Icon(name)
255
- }
256
-
257
- if (name === "EMPTY") {
258
- return html`<div class="icon-placeholder"></div>`
259
- }
260
-
261
- return name
262
- }
263
-
264
- renderBefore() {
265
- if (this.before !== "") {
266
- const content = LeuMenuItem.getIconOrText(this.before);
267
- return html`<span class="before">${content}</span>`
268
- }
269
-
270
- return nothing
271
- }
272
-
273
- renderAfter() {
274
- if (this.after !== "") {
275
- const content = LeuMenuItem.getIconOrText(this.after);
276
- return html`<span class="after">${content}</span>`
277
- }
278
-
279
- return nothing
280
- }
281
-
282
- render() {
283
- return html`<button class="button" ?disabled=${this.disabled}>
284
- ${this.renderBefore()}<span class="label"><slot></slot></span
285
- >${this.renderAfter()}
286
- </button>`
287
- }
288
- }
289
-
290
- function defineMenuItemElements() {
291
- defineElement("menu-item", LeuMenuItem);
292
- }
293
-
294
84
  var css_248z = css`:host,
295
85
  :host * {
296
86
  box-sizing: border-box;
@@ -528,37 +318,66 @@ var css_248z = css`:host,
528
318
  * @slot after - Optional content the appears after the option list
529
319
  */
530
320
  class LeuSelect extends LitElement {
531
- static styles = css_248z
532
-
533
321
  static get properties() {
534
322
  return {
535
- open: { type: Boolean, attribute: "open" },
536
-
537
- label: { type: String },
538
- options: { type: Array },
539
- value: { type: Array },
540
- clearable: { type: Boolean, reflect: true },
541
- disabled: { type: Boolean, reflect: true },
542
- filterable: { type: Boolean, reflect: true },
543
- multiple: { type: Boolean, reflect: true },
544
- optionFilter: { type: String, state: true },
545
- }
323
+ open: {
324
+ type: Boolean,
325
+ attribute: "open"
326
+ },
327
+ label: {
328
+ type: String
329
+ },
330
+ options: {
331
+ type: Array
332
+ },
333
+ value: {
334
+ type: Array
335
+ },
336
+ clearable: {
337
+ type: Boolean,
338
+ reflect: true
339
+ },
340
+ disabled: {
341
+ type: Boolean,
342
+ reflect: true
343
+ },
344
+ filterable: {
345
+ type: Boolean,
346
+ reflect: true
347
+ },
348
+ multiple: {
349
+ type: Boolean,
350
+ reflect: true
351
+ },
352
+ optionFilter: {
353
+ type: String,
354
+ state: true
355
+ }
356
+ };
546
357
  }
547
-
548
358
  static getOptionLabel(option) {
549
359
  if (typeof option === "object" && option !== null) {
550
- return option.label
360
+ return option.label;
551
361
  }
552
- return option
362
+ return option;
553
363
  }
554
364
 
555
365
  /**
556
366
  * @internal
557
367
  */
558
- hasSlotController = new HasSlotController(this, ["before", "after"])
559
368
 
560
369
  constructor() {
561
370
  super();
371
+ _defineProperty(this, "hasSlotController", new HasSlotController(this, ["before", "after"]));
372
+ /**
373
+ * @internal
374
+ * @param {KeyboardEvent} e
375
+ */
376
+ _defineProperty(this, "handleKeyDown", event => {
377
+ if (event.key === "Escape") {
378
+ this.closeDropdown();
379
+ }
380
+ });
562
381
  this.open = false;
563
382
  this.clearable = false;
564
383
  this.value = [];
@@ -575,12 +394,10 @@ class LeuSelect extends LitElement {
575
394
 
576
395
  /** @internal */
577
396
  this.deferedChangeEvent = false;
578
-
579
397
  this.menuRef = createRef();
580
398
  this.optionFilterRef = createRef();
581
399
  this.toggleButtonRef = createRef();
582
400
  }
583
-
584
401
  updated(changedProperties) {
585
402
  if (changedProperties.has("open") && this.open) {
586
403
  if (this.multiple) {
@@ -592,83 +409,58 @@ class LeuSelect extends LitElement {
592
409
  this.toggleButtonRef.value.focus();
593
410
  }
594
411
  }
595
-
596
- /**
597
- * @internal
598
- * @param {KeyboardEvent} e
599
- */
600
- handleKeyDown = (event) => {
601
- if (event.key === "Escape") {
602
- this.closeDropdown();
603
- }
604
- }
605
-
606
412
  getDisplayValue(value) {
607
413
  if (this.multiple) {
608
- return value.length === 0 ? `` : `${value.length} gewählt`
414
+ return value.length === 0 ? `` : `${value.length} gewählt`;
609
415
  }
610
-
611
- return LeuSelect.getOptionLabel(value[0])
416
+ return LeuSelect.getOptionLabel(value[0]);
612
417
  }
613
-
614
418
  getFilteredOptions() {
615
- return this.filterable && this.optionFilter.length > 0
616
- ? this.options.filter((option) => {
617
- const label = LeuSelect.getOptionLabel(option);
618
- return label.toLowerCase().includes(this.optionFilter.toLowerCase())
619
- })
620
- : this.options
419
+ return this.filterable && this.optionFilter.length > 0 ? this.options.filter(option => {
420
+ const label = LeuSelect.getOptionLabel(option);
421
+ return label.toLowerCase().includes(this.optionFilter.toLowerCase());
422
+ }) : this.options;
621
423
  }
622
-
623
424
  emitUpdateEvents() {
624
425
  this.emitInputEvent();
625
426
  this.emitChangeEvent();
626
427
  }
627
-
628
428
  emitInputEvent() {
629
429
  const inputevent = new CustomEvent("input", {
630
430
  composed: true,
631
- bubbles: true,
431
+ bubbles: true
632
432
  });
633
433
  this.dispatchEvent(inputevent);
634
434
  }
635
-
636
435
  emitChangeEvent() {
637
436
  const changeevent = new CustomEvent("change", {
638
437
  composed: true,
639
- bubbles: true,
438
+ bubbles: true
640
439
  });
641
440
  this.dispatchEvent(changeevent);
642
441
  }
643
-
644
442
  clearValue(event) {
645
443
  if (!this.disabled) {
646
444
  event.stopPropagation();
647
445
  this.value = [];
648
446
  }
649
-
650
447
  this.emitUpdateEvents();
651
448
  }
652
-
653
449
  clearOptionFilter() {
654
450
  // refocus before removing the button, otherwise closeDropdown is triggered
655
451
  this.optionFilterRef.value.focus();
656
452
  this.optionFilter = "";
657
453
  }
658
-
659
454
  toggleDropdown() {
660
455
  if (!this.disabled) {
661
456
  this.open = !this.open;
662
457
  }
663
458
  }
664
-
665
459
  openDropdown() {
666
460
  this.open = true;
667
461
  }
668
-
669
462
  closeDropdown() {
670
463
  this.open = false;
671
-
672
464
  if (this.deferedChangeEvent) {
673
465
  this.emitChangeEvent();
674
466
  this.deferedChangeEvent = false;
@@ -682,44 +474,32 @@ class LeuSelect extends LitElement {
682
474
  */
683
475
  selectOption(option) {
684
476
  const isSelected = this.isSelected(option);
685
-
686
477
  if (this.multiple) {
687
- this.value = isSelected
688
- ? this.value.filter((v) => v !== option)
689
- : this.value.concat(option);
690
-
478
+ this.value = isSelected ? this.value.filter(v => v !== option) : this.value.concat(option);
691
479
  this.deferedChangeEvent = true;
692
480
  } else {
693
481
  this.value = isSelected ? [] : [option];
694
482
  }
695
-
696
483
  this.emitInputEvent();
697
-
698
484
  if (!this.multiple) {
699
485
  this.closeDropdown();
700
486
  }
701
487
  }
702
-
703
488
  handleApplyClick() {
704
489
  this.closeDropdown();
705
490
  }
706
-
707
491
  handleFilterInput(event) {
708
492
  this.optionFilter = event.target.value;
709
493
  }
710
-
711
494
  isSelected(option) {
712
- return this.value.includes(option)
495
+ return this.value.includes(option);
713
496
  }
714
-
715
497
  renderMenu() {
716
498
  const menuClasses = {
717
499
  "select-menu": true,
718
- multiple: this.multiple,
500
+ multiple: this.multiple
719
501
  };
720
-
721
502
  const filteredOptions = this.getFilteredOptions();
722
-
723
503
  return html`
724
504
  <leu-menu
725
505
  role="listbox"
@@ -728,18 +508,15 @@ class LeuSelect extends LitElement {
728
508
  aria-labelledby="select-label"
729
509
  ref=${ref(this.menuRef)}
730
510
  >
731
- ${filteredOptions.length > 0
732
- ? map(this.getFilteredOptions(), (option) => {
733
- const isSelected = this.isSelected(option);
734
- let beforeIcon;
735
-
736
- if (this.multiple && isSelected) {
737
- beforeIcon = "check";
738
- } else if (this.multiple) {
739
- beforeIcon = "EMPTY";
740
- }
741
-
742
- return html`<leu-menu-item
511
+ ${filteredOptions.length > 0 ? map(this.getFilteredOptions(), option => {
512
+ const isSelected = this.isSelected(option);
513
+ let beforeIcon;
514
+ if (this.multiple && isSelected) {
515
+ beforeIcon = "check";
516
+ } else if (this.multiple) {
517
+ beforeIcon = "EMPTY";
518
+ }
519
+ return html`<leu-menu-item
743
520
  before=${ifDefined(beforeIcon)}
744
521
  @click=${() => this.selectOption(option)}
745
522
  role="option"
@@ -747,13 +524,11 @@ class LeuSelect extends LitElement {
747
524
  aria-selected=${isSelected}
748
525
  >
749
526
  ${LeuSelect.getOptionLabel(option)}
750
- </leu-menu-item>`
751
- })
752
- : html`<leu-menu-item disabled>Keine Resultate</leu-menu-item>`}
527
+ </leu-menu-item>`;
528
+ }) : html`<leu-menu-item disabled>Keine Resultate</leu-menu-item>`}
753
529
  </leu-menu>
754
- `
530
+ `;
755
531
  }
756
-
757
532
  renderFilterInput() {
758
533
  if (this.filterable) {
759
534
  return html` <leu-input
@@ -762,12 +537,10 @@ class LeuSelect extends LitElement {
762
537
  @input=${this.handleFilterInput}
763
538
  clearable
764
539
  >Nach Stichwort filtern</leu-input
765
- >`
540
+ >`;
766
541
  }
767
-
768
- return nothing
542
+ return nothing;
769
543
  }
770
-
771
544
  renderApplyButton() {
772
545
  if (this.multiple) {
773
546
  return html`
@@ -778,20 +551,17 @@ class LeuSelect extends LitElement {
778
551
  label="Anwenden"
779
552
  fluid
780
553
  ></leu-button>
781
- `
554
+ `;
782
555
  }
783
-
784
- return nothing
556
+ return nothing;
785
557
  }
786
-
787
558
  renderToggleButton() {
788
559
  const toggleClasses = {
789
560
  "select-toggle": true,
790
561
  open: this.open,
791
562
  filled: this.value.length !== 0 && this.value !== null,
792
- labeled: this.label !== "",
563
+ labeled: this.label !== ""
793
564
  };
794
-
795
565
  return html`<button
796
566
  type="button"
797
567
  class=${classMap(toggleClasses)}
@@ -805,8 +575,7 @@ class LeuSelect extends LitElement {
805
575
  <span class="label" id="select-label">${this.label}</span>
806
576
  <span class="value"> ${this.getDisplayValue(this.value)} </span>
807
577
  <span class="arrow-icon"> ${this._arrowIcon} </span>
808
- ${this.clearable && this.value !== "" && this.value.length !== 0
809
- ? html`<button
578
+ ${this.clearable && this.value !== "" && this.value.length !== 0 ? html`<button
810
579
  type="button"
811
580
  class="clear-button"
812
581
  @click=${this.clearValue}
@@ -814,18 +583,15 @@ class LeuSelect extends LitElement {
814
583
  ?disabled=${this.disabled}
815
584
  >
816
585
  ${this._clearIcon}
817
- </button>`
818
- : nothing}
819
- </button>`
586
+ </button>` : nothing}
587
+ </button>`;
820
588
  }
821
-
822
589
  render() {
823
590
  const selectClasses = {
824
591
  select: true,
825
592
  "select--has-before": this.hasSlotController.test("before"),
826
- "select--has-after": this.hasSlotController.test("after"),
593
+ "select--has-after": this.hasSlotController.test("after")
827
594
  };
828
-
829
595
  return html`<div
830
596
  class=${classMap(selectClasses)}
831
597
  ?disabled=${this.disabled}
@@ -844,10 +610,10 @@ class LeuSelect extends LitElement {
844
610
  ${this.renderApplyButton()}
845
611
  <slot name="after" class="after"></slot>
846
612
  </dialog>
847
- </div> `
613
+ </div> `;
848
614
  }
849
615
  }
850
-
616
+ _defineProperty(LeuSelect, "styles", css_248z);
851
617
  function defineSelectElements() {
852
618
  defineButtonElements();
853
619
  defineMenuElements();