@dso-toolkit/core 29.0.1 → 31.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 (94) hide show
  1. package/dist/cjs/dso-alert.cjs.entry.js +1 -1
  2. package/dist/cjs/dso-autosuggest.cjs.entry.js +105 -75
  3. package/dist/cjs/dso-banner.cjs.entry.js +1 -1
  4. package/dist/cjs/dso-date-picker.cjs.entry.js +56 -16
  5. package/dist/cjs/dso-icon.cjs.entry.js +6 -4
  6. package/dist/cjs/dso-info-button.cjs.entry.js +26 -0
  7. package/dist/cjs/{dso-info_3.cjs.entry.js → dso-info_2.cjs.entry.js} +0 -20
  8. package/dist/cjs/dso-label.cjs.entry.js +1 -1
  9. package/dist/cjs/dso-ozon-content.cjs.entry.js +26 -13
  10. package/dist/cjs/dso-toggletip.cjs.entry.js +62 -0
  11. package/dist/cjs/dso-toolkit.cjs.js +1 -1
  12. package/dist/cjs/dso-tooltip.cjs.entry.js +33 -26
  13. package/dist/cjs/dso-tree-view.cjs.entry.js +180 -0
  14. package/dist/cjs/loader.cjs.js +1 -1
  15. package/dist/collection/collection-manifest.json +3 -1
  16. package/dist/collection/components/alert/alert.css +2 -0
  17. package/dist/collection/components/autosuggest/autosuggest.css +10 -0
  18. package/dist/collection/components/autosuggest/autosuggest.js +128 -98
  19. package/dist/collection/components/autosuggest/autosuggest.template.js +6 -6
  20. package/dist/collection/components/banner/banner.css +2 -0
  21. package/dist/collection/components/date-picker/date-localization.js +1 -1
  22. package/dist/collection/components/date-picker/date-picker.js +108 -14
  23. package/dist/collection/components/date-picker/date-picker.template.js +2 -1
  24. package/dist/collection/components/date-picker/date-utils.js +3 -3
  25. package/dist/collection/components/icon/icon.js +9 -7
  26. package/dist/collection/components/info-button/info-button.css +10 -3
  27. package/dist/collection/components/info-button/info-button.js +18 -1
  28. package/dist/collection/components/info-button/info-button.template.js +2 -1
  29. package/dist/collection/components/label/label.decorator.js +6 -0
  30. package/dist/collection/components/label/label.js +1 -0
  31. package/dist/collection/components/label/label.template.js +10 -2
  32. package/dist/collection/components/ozon-content/ozon-content.transformer.js +26 -13
  33. package/dist/collection/components/toggletip/toggletip.css +8 -0
  34. package/dist/collection/components/toggletip/toggletip.js +137 -0
  35. package/dist/collection/components/toggletip/toggletip.template.js +12 -0
  36. package/dist/collection/components/tooltip/tooltip.css +1 -1
  37. package/dist/collection/components/tooltip/tooltip.js +49 -25
  38. package/dist/collection/components/tree-view/tree-item.js +20 -0
  39. package/dist/collection/components/tree-view/tree-view.css +43 -0
  40. package/dist/collection/components/tree-view/tree-view.js +239 -0
  41. package/dist/collection/components/tree-view/tree-view.template.js +11 -0
  42. package/dist/custom-elements/index.d.ts +12 -0
  43. package/dist/custom-elements/index.js +472 -145
  44. package/dist/dso-toolkit/dso-toolkit.css +1 -1
  45. package/dist/dso-toolkit/dso-toolkit.esm.js +1 -1
  46. package/dist/dso-toolkit/{p-968d9e1d.entry.js → p-19de4cc7.entry.js} +1 -1
  47. package/dist/dso-toolkit/p-39dae284.entry.js +1 -0
  48. package/dist/dso-toolkit/p-5665f1ee.entry.js +1 -0
  49. package/dist/dso-toolkit/{p-eadba8c3.entry.js → p-5a67f3f7.entry.js} +1 -1
  50. package/dist/dso-toolkit/p-759920d0.entry.js +1 -0
  51. package/dist/dso-toolkit/{p-d748df48.entry.js → p-83f166b3.entry.js} +1 -1
  52. package/dist/dso-toolkit/p-9735f393.entry.js +1 -0
  53. package/dist/dso-toolkit/p-9e9f8bcf.entry.js +1 -0
  54. package/dist/dso-toolkit/p-a8a0e909.entry.js +1 -0
  55. package/dist/dso-toolkit/p-ad8f467f.entry.js +1 -0
  56. package/dist/dso-toolkit/p-e2dc97c4.entry.js +1 -0
  57. package/dist/dso-toolkit/p-faf19a1d.entry.js +1 -0
  58. package/dist/esm/dso-alert.entry.js +1 -1
  59. package/dist/esm/dso-autosuggest.entry.js +105 -75
  60. package/dist/esm/dso-banner.entry.js +1 -1
  61. package/dist/esm/dso-date-picker.entry.js +56 -16
  62. package/dist/esm/dso-icon.entry.js +6 -4
  63. package/dist/esm/dso-info-button.entry.js +22 -0
  64. package/dist/esm/{dso-info_3.entry.js → dso-info_2.entry.js} +1 -20
  65. package/dist/esm/dso-label.entry.js +1 -1
  66. package/dist/esm/dso-ozon-content.entry.js +26 -13
  67. package/dist/esm/dso-toggletip.entry.js +58 -0
  68. package/dist/esm/dso-toolkit.js +1 -1
  69. package/dist/esm/dso-tooltip.entry.js +33 -26
  70. package/dist/esm/dso-tree-view.entry.js +176 -0
  71. package/dist/esm/loader.js +1 -1
  72. package/dist/types/components/autosuggest/autosuggest.d.ts +19 -20
  73. package/dist/types/components/autosuggest/autosuggest.template.d.ts +3 -2
  74. package/dist/types/components/date-picker/date-picker.d.ts +20 -0
  75. package/dist/types/components/date-picker/date-picker.template.d.ts +1 -1
  76. package/dist/types/components/icon/icon.d.ts +1 -1
  77. package/dist/types/components/info-button/info-button.d.ts +1 -0
  78. package/dist/types/components/info-button/info-button.template.d.ts +1 -1
  79. package/dist/types/components/label/label.decorator.d.ts +3 -0
  80. package/dist/types/components/label/label.template.d.ts +1 -1
  81. package/dist/types/components/toggletip/toggletip.d.ts +17 -0
  82. package/dist/types/components/toggletip/toggletip.template.d.ts +2 -0
  83. package/dist/types/components/tooltip/tooltip.d.ts +6 -2
  84. package/dist/types/components/tree-view/tree-item.d.ts +13 -0
  85. package/dist/types/components/tree-view/tree-view.d.ts +36 -0
  86. package/dist/types/components/tree-view/tree-view.template.d.ts +2 -0
  87. package/dist/types/components.d.ts +95 -12
  88. package/package.json +2 -1
  89. package/dist/dso-toolkit/p-05a853b9.entry.js +0 -1
  90. package/dist/dso-toolkit/p-2c6e9460.entry.js +0 -1
  91. package/dist/dso-toolkit/p-43772cee.entry.js +0 -1
  92. package/dist/dso-toolkit/p-94500196.entry.js +0 -1
  93. package/dist/dso-toolkit/p-a2357726.entry.js +0 -1
  94. package/dist/dso-toolkit/p-c5acf7e2.entry.js +0 -1
@@ -1,86 +1,61 @@
1
- import { Component, Element, h, Listen, Prop, State, Fragment, Event, } from "@stencil/core";
1
+ import { Component, Element, h, Listen, Prop, State, Fragment, Event, Watch, } from "@stencil/core";
2
2
  import debounce from "debounce";
3
3
  import { v4 } from "uuid";
4
+ import escapeStringRegexp from "escape-string-regexp";
4
5
  export class Autosuggest {
5
6
  constructor() {
7
+ /**
8
+ * The suggestions for the value of the slotted input element
9
+ */
10
+ this.suggestions = [];
6
11
  /**
7
12
  * Whether the previous suggestions will be presented when the input gets focus again.
8
13
  */
9
14
  this.suggestOnFocus = false;
10
- this.suggestions = [];
11
- this.selectedIndex = -1;
12
- this.terms = [];
13
15
  this.showSuggestions = false;
14
16
  this.listboxId = v4();
15
17
  this.inputId = v4();
16
18
  this.labelId = v4();
17
- this.debouncedFetchSuggestions = debounce((terms) => (this.fetchSuggestions ? this.fetchSuggestions(terms.join(" ")) : Promise.resolve([]))
18
- .then((result) => {
19
- this.suggestions = result.map((suggestion, index) => ({
20
- value: suggestion.value,
21
- type: suggestion.type,
22
- selected: false,
23
- id: `${index}-${this.inputId}`,
24
- }));
25
- this.terms = terms;
26
- this.openSuggestions();
27
- })
28
- .catch(() => {
29
- this.closeSuggestions();
30
- this.suggestions = [];
31
- }), 200);
19
+ this.debouncedEmitValue = debounce((value) => this.changeEmitter.emit(value), 200);
32
20
  this.onInput = (event) => {
33
- var _a;
34
21
  if (!(event.target instanceof HTMLInputElement)) {
35
- throw new Error("event.target not a instance of HTMLInputElement");
22
+ throw new Error("event.target is not instanceof HTMLInputElement");
36
23
  }
37
- this.debouncedFetchSuggestions((_a = `${event.target.value}`.match(/(\S+)/g)) !== null && _a !== void 0 ? _a : []);
24
+ this.debouncedEmitValue(event.target.value.match(/(\S+)/g) ? event.target.value : '');
38
25
  };
39
26
  this.onFocusIn = () => {
40
27
  if (this.suggestOnFocus) {
41
28
  this.openSuggestions();
42
29
  }
43
30
  };
44
- this.onMouseEnterOption = (event) => {
45
- if (event.target instanceof HTMLElement) {
46
- const id = event.target.id;
47
- this.setSelectedSuggestion(this.suggestions.findIndex((s) => s.id == id));
48
- }
49
- };
50
- this.onMouseLeaveOption = () => {
51
- this.setSelectedSuggestion(-1);
52
- };
53
- this.onClickOption = () => {
54
- this.pickSelectedValue();
55
- };
56
31
  this.onKeyDown = (event) => {
57
32
  if (event.defaultPrevented) {
58
33
  return;
59
34
  }
60
35
  switch (event.key) {
61
- case "ArrowDown":
36
+ case 'ArrowDown':
62
37
  if (!this.showSuggestions) {
63
- this.openSuggestions();
38
+ this.openSuggestions('first');
39
+ }
40
+ else {
41
+ this.selectNextSuggestion();
64
42
  }
65
- this.setSelectedSuggestion(this.selectedIndex >= this.suggestions.length - 1
66
- ? 0
67
- : this.selectedIndex + 1);
68
43
  break;
69
- case "ArrowUp":
44
+ case 'ArrowUp':
70
45
  if (!this.showSuggestions) {
71
- this.openSuggestions();
46
+ this.openSuggestions('last');
47
+ }
48
+ else {
49
+ this.selectPreviousSuggestion();
72
50
  }
73
- this.setSelectedSuggestion(this.selectedIndex <= 0
74
- ? this.suggestions.length - 1
75
- : this.selectedIndex - 1);
76
51
  break;
77
- case "Tab":
52
+ case 'Tab':
78
53
  this.closeSuggestions();
79
54
  return;
80
- case "Escape":
55
+ case 'Escape':
81
56
  this.closeSuggestions();
82
57
  break;
83
- case "Enter":
58
+ case 'Enter':
84
59
  this.pickSelectedValue();
85
60
  break;
86
61
  default:
@@ -89,6 +64,15 @@ export class Autosuggest {
89
64
  event.preventDefault();
90
65
  };
91
66
  }
67
+ suggestionsWatcher() {
68
+ this.resetSelectedSuggestion();
69
+ if (!this.showSuggestions && this.suggestions.length > 0) {
70
+ this.openSuggestions();
71
+ }
72
+ else if (this.showSuggestions && this.suggestions.length === 0) {
73
+ this.closeSuggestions();
74
+ }
75
+ }
92
76
  onDocumentClick(event) {
93
77
  if (this.showSuggestions &&
94
78
  this.listbox &&
@@ -99,7 +83,7 @@ export class Autosuggest {
99
83
  }
100
84
  }
101
85
  connectedCallback() {
102
- const input = this.host.querySelectorAll('input[type="text"]')[0];
86
+ const input = this.host.querySelector('input[type="text"]');
103
87
  if (!(input instanceof HTMLInputElement)) {
104
88
  throw new ReferenceError("Mandatory text input not found");
105
89
  }
@@ -137,62 +121,93 @@ export class Autosuggest {
137
121
  this.input.removeEventListener("focusin", this.onFocusIn);
138
122
  }
139
123
  markTerms(suggestionValue, terms) {
140
- if (!suggestionValue || !terms || terms.length == 0) {
141
- return [""];
124
+ if (!suggestionValue || !terms || terms.length === 0) {
125
+ return [''];
142
126
  }
143
- const termRegex = new RegExp(`(${terms[0]})`, "gi");
127
+ const termRegex = new RegExp(`(${escapeStringRegexp(terms[0])})`, 'gi');
144
128
  return suggestionValue.split(termRegex).map((valuePart) => {
145
129
  if (!valuePart) {
146
- return "";
130
+ return '';
147
131
  }
148
132
  if (termRegex.test(valuePart)) {
149
133
  return h("mark", null, valuePart);
150
134
  }
151
- if (terms.length == 1) {
135
+ if (terms.length === 1) {
152
136
  return h("span", null, valuePart);
153
137
  }
154
138
  return this.markTerms(valuePart, terms.slice(1));
155
139
  });
156
140
  }
157
- setSelectedSuggestion(index) {
158
- this.suggestions.forEach((suggestion) => (suggestion.selected = false));
159
- if (index < 0 || index >= this.suggestions.length) {
160
- this.selectedIndex = -1;
161
- this.input.setAttribute("aria-activedescendant", "");
141
+ selectSuggestion(suggestion) {
142
+ this.selectedSuggestion = suggestion;
143
+ this.input.setAttribute("aria-activedescendant", this.listboxItemId(suggestion));
144
+ }
145
+ selectFirstSuggestion() {
146
+ this.selectedSuggestion = this.suggestions[0];
147
+ if (this.selectedSuggestion) {
148
+ this.input.setAttribute('aria-activedescendant', this.listboxItemId(this.selectedSuggestion));
162
149
  }
163
- else {
164
- this.selectedIndex = index;
165
- this.suggestions[index].selected = true;
166
- this.input.setAttribute("aria-activedescendant", this.suggestions[index].id);
150
+ }
151
+ selectLastSuggestion() {
152
+ this.selectedSuggestion = this.suggestions[this.suggestions.length - 1];
153
+ if (this.selectedSuggestion) {
154
+ this.input.setAttribute('aria-activedescendant', this.listboxItemId(this.selectedSuggestion));
155
+ }
156
+ }
157
+ selectNextSuggestion() {
158
+ var _a;
159
+ const index = this.selectedSuggestion ? this.suggestions.indexOf(this.selectedSuggestion) : -1;
160
+ this.selectedSuggestion = (_a = this.suggestions[index + 1]) !== null && _a !== void 0 ? _a : this.suggestions[0];
161
+ if (this.selectedSuggestion) {
162
+ this.input.setAttribute('aria-activedescendant', this.listboxItemId(this.selectedSuggestion));
163
+ }
164
+ }
165
+ selectPreviousSuggestion() {
166
+ var _a;
167
+ const index = this.selectedSuggestion ? this.suggestions.indexOf(this.selectedSuggestion) : 0;
168
+ this.selectedSuggestion = (_a = this.suggestions[index - 1]) !== null && _a !== void 0 ? _a : this.suggestions[this.suggestions.length - 1];
169
+ if (this.selectedSuggestion) {
170
+ this.input.setAttribute('aria-activedescendant', this.listboxItemId(this.selectedSuggestion));
167
171
  }
168
- this.suggestions = [...this.suggestions];
169
172
  }
170
- openSuggestions() {
173
+ resetSelectedSuggestion() {
174
+ this.selectedSuggestion = undefined;
175
+ this.input.setAttribute('aria-activedescendant', '');
176
+ }
177
+ openSuggestions(selectSuggestion) {
171
178
  this.showSuggestions = this.suggestions.length > 0;
172
- this.input.setAttribute("aria-expanded", `${this.showSuggestions}`);
173
- this.setSelectedSuggestion(-1);
179
+ this.input.setAttribute("aria-expanded", this.showSuggestions.toString());
180
+ if (selectSuggestion === 'first') {
181
+ this.selectFirstSuggestion();
182
+ }
183
+ else if (selectSuggestion === 'last') {
184
+ this.selectLastSuggestion();
185
+ }
174
186
  }
175
187
  closeSuggestions() {
176
188
  this.showSuggestions = false;
177
189
  this.input.setAttribute("aria-expanded", "false");
178
- this.setSelectedSuggestion(-1);
190
+ this.selectFirstSuggestion();
179
191
  }
180
192
  pickSelectedValue() {
181
- var _a;
182
- if (this.selectedIndex >= 0) {
183
- this.input.value = this.suggestions[this.selectedIndex].value;
184
- (_a = this.selected) === null || _a === void 0 ? void 0 : _a.emit(this.input.value);
193
+ if (this.selectedSuggestion) {
194
+ this.selectEmitter.emit(this.selectedSuggestion);
185
195
  }
186
- this.suggestions = [];
187
196
  this.closeSuggestions();
188
197
  }
198
+ listboxItemId(suggestion) {
199
+ return `${this.inputId}-${this.suggestions.indexOf(suggestion) + 1}`;
200
+ }
189
201
  render() {
202
+ const terms = this.input.value.split(' ').filter(t => t);
190
203
  return (h(Fragment, null,
191
204
  h("slot", null),
192
- h("ul", { role: "listbox", id: this.listboxId, "aria-labelledby": this.labelId, ref: (e) => (this.listbox = e), style: { display: this.showSuggestions ? "block" : "none" } }, this.showSuggestions
193
- ? this.suggestions.map((suggestion) => (h("li", { role: "option", id: suggestion.id, key: suggestion.id, onMouseEnter: this.onMouseEnterOption, onMouseLeave: this.onMouseLeaveOption, onClick: this.onClickOption, "aria-selected": "" + suggestion.selected, "aria-label": suggestion.value },
194
- h("span", { class: "value" }, this.markTerms(suggestion.value, this.terms)),
195
- suggestion.type ? (h("span", { class: "type" }, suggestion.type)) : undefined)))
205
+ h("ul", { role: "listbox", id: this.listboxId, "aria-labelledby": this.labelId, ref: element => this.listbox = element, hidden: !this.showSuggestions }, this.showSuggestions
206
+ ? this.suggestions.map((suggestion) => (h("li", { role: "option", id: this.listboxItemId(suggestion), key: suggestion.value, onMouseEnter: () => this.selectSuggestion(suggestion), onMouseLeave: () => this.resetSelectedSuggestion(), onClick: () => this.pickSelectedValue(), "aria-selected": (suggestion === this.selectedSuggestion).toString(), "aria-label": suggestion.value },
207
+ h("span", { class: "value" }, this.markTerms(suggestion.value, terms)),
208
+ suggestion.type
209
+ ? (h("span", { class: "type" }, suggestion.type))
210
+ : undefined)))
196
211
  : undefined)));
197
212
  }
198
213
  static get is() { return "dso-autosuggest"; }
@@ -204,33 +219,25 @@ export class Autosuggest {
204
219
  "$": ["autosuggest.css"]
205
220
  }; }
206
221
  static get properties() { return {
207
- "fetchSuggestions": {
222
+ "suggestions": {
208
223
  "type": "unknown",
209
224
  "mutable": false,
210
225
  "complexType": {
211
- "original": "(value: string) => Promise<Array<Suggestion>>",
212
- "resolved": "((value: string) => Promise<Suggestion[]>) | undefined",
226
+ "original": "Suggestion[]",
227
+ "resolved": "Suggestion[]",
213
228
  "references": {
214
- "Promise": {
215
- "location": "global"
216
- },
217
- "Array": {
218
- "location": "global"
219
- },
220
229
  "Suggestion": {
221
230
  "location": "local"
222
231
  }
223
232
  }
224
233
  },
225
234
  "required": false,
226
- "optional": true,
235
+ "optional": false,
227
236
  "docs": {
228
- "tags": [{
229
- "text": "A promise with an array of `Suggestion`s. You should limit this array to ten items.",
230
- "name": "returns"
231
- }],
232
- "text": "A method that will be called debounced with the input value as its first parameter.\nThis method will also be called when the input is reduced to an empty string."
233
- }
237
+ "tags": [],
238
+ "text": "The suggestions for the value of the slotted input element"
239
+ },
240
+ "defaultValue": "[]"
234
241
  },
235
242
  "suggestOnFocus": {
236
243
  "type": "boolean",
@@ -252,12 +259,12 @@ export class Autosuggest {
252
259
  }
253
260
  }; }
254
261
  static get states() { return {
255
- "suggestions": {},
256
- "showSuggestions": {}
262
+ "showSuggestions": {},
263
+ "selectedSuggestion": {}
257
264
  }; }
258
265
  static get events() { return [{
259
- "method": "selected",
260
- "name": "selected",
266
+ "method": "selectEmitter",
267
+ "name": "dsoSelect",
261
268
  "bubbles": true,
262
269
  "cancelable": true,
263
270
  "composed": true,
@@ -266,12 +273,35 @@ export class Autosuggest {
266
273
  "text": "Emitted when a suggestion is selected.\nThe `detail` property of the `CustomEvent`\u00A0will contain the selected suggestion."
267
274
  },
268
275
  "complexType": {
269
- "original": "any",
270
- "resolved": "any",
276
+ "original": "Suggestion",
277
+ "resolved": "Suggestion",
278
+ "references": {
279
+ "Suggestion": {
280
+ "location": "local"
281
+ }
282
+ }
283
+ }
284
+ }, {
285
+ "method": "changeEmitter",
286
+ "name": "dsoChange",
287
+ "bubbles": true,
288
+ "cancelable": true,
289
+ "composed": true,
290
+ "docs": {
291
+ "tags": [],
292
+ "text": "This is emitted debounced for every change for the slotted input type=text element."
293
+ },
294
+ "complexType": {
295
+ "original": "string",
296
+ "resolved": "string",
271
297
  "references": {}
272
298
  }
273
299
  }]; }
274
300
  static get elementRef() { return "host"; }
301
+ static get watchers() { return [{
302
+ "propName": "suggestions",
303
+ "methodName": "suggestionsWatcher"
304
+ }]; }
275
305
  static get listeners() { return [{
276
306
  "name": "click",
277
307
  "method": "onDocumentClick",
@@ -1,13 +1,13 @@
1
- import { html } from "lit-html";
2
- export function autosuggestTemplate({ fetchSuggestions, onSelected, suggestOnFocus, }) {
1
+ import { html } from 'lit-html';
2
+ export function autosuggestTemplate({ suggestions, onSelect, onChange, suggestOnFocus }, children) {
3
3
  return html `
4
- <label for="autosuggestInputId">Label voor input</label>
5
4
  <dso-autosuggest
6
- @selected=${(e) => onSelected(e.detail)}
7
- .fetchSuggestions=${fetchSuggestions}
5
+ .suggestions=${suggestions}
6
+ @dsoSelect=${onSelect}
7
+ @dsoChange=${onChange}
8
8
  ?suggest-on-focus=${suggestOnFocus}
9
9
  >
10
- <input id="autosuggestInputId" type="text" class="form-control" />
10
+ ${children}
11
11
  </dso-autosuggest>
12
12
  `;
13
13
  }
@@ -5,6 +5,8 @@
5
5
  display: block;
6
6
  --di-status-danger: url("data:image/svg+xml,%3csvg id='status-danger-line' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e %3cg%3e %3cpath d='M22.6%2c18.51c.86%2c1.37.29%2c2.49-1.25%2c2.49H2.65C1.11%2c21%2c.54%2c19.88%2c1.4%2c18.51L10.44%2c4a1.7%2c1.7%2c0%2c0%2c1%2c3.12%2c0Z' style='fill: %23ce3f51'/%3e %3cpath d='M12%2c3a1.9%2c1.9%2c0%2c0%2c1%2c1.56%2c1l9%2c14.48c.86%2c1.37.29%2c2.49-1.25%2c2.49H2.65C1.11%2c21%2c.54%2c19.88%2c1.4%2c18.51L10.44%2c4A1.9%2c1.9%2c0%2c0%2c1%2c12%2c3m0-1A2.89%2c2.89%2c0%2c0%2c0%2c9.6%2c3.5L.55%2c18a2.75%2c2.75%2c0%2c0%2c0-.28%2c2.81A2.59%2c2.59%2c0%2c0%2c0%2c2.65%2c22h18.7a2.59%2c2.59%2c0%2c0%2c0%2c2.38-1.21A2.75%2c2.75%2c0%2c0%2c0%2c23.45%2c18L14.4%2c3.5A2.89%2c2.89%2c0%2c0%2c0%2c12%2c2Z' style='fill: white'/%3e %3c/g%3e %3cpath d='M12%2c16a1%2c1%2c0%2c0%2c1-1-.91V8.91a1%2c1%2c0%2c0%2c1%2c2%2c0v6.18A1%2c1%2c0%2c0%2c1%2c12%2c16Zm0%2c1a1%2c1%2c0%2c1%2c0%2c1%2c1A1%2c1%2c0%2c0%2c0%2c12%2c17Z' style='fill: white'/%3e %3c/svg%3e");
7
7
  --di-status-warning: url("data:image/svg+xml,%3csvg id='status-warning' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e %3cg%3e %3cpath d='M22.6%2c18.51c.86%2c1.37.29%2c2.49-1.25%2c2.49H2.65C1.11%2c21%2c.54%2c19.88%2c1.4%2c18.51L10.44%2c4a1.7%2c1.7%2c0%2c0%2c1%2c3.12%2c0Z' style='fill: %23dcd400'/%3e %3cpath d='M12%2c3a1.9%2c1.9%2c0%2c0%2c1%2c1.56%2c1l9%2c14.48c.86%2c1.37.29%2c2.49-1.25%2c2.49H2.65C1.11%2c21%2c.54%2c19.88%2c1.4%2c18.51L10.44%2c4A1.9%2c1.9%2c0%2c0%2c1%2c12%2c3m0-1A2.89%2c2.89%2c0%2c0%2c0%2c9.6%2c3.5L.55%2c18a2.75%2c2.75%2c0%2c0%2c0-.28%2c2.81A2.59%2c2.59%2c0%2c0%2c0%2c2.65%2c22h18.7a2.59%2c2.59%2c0%2c0%2c0%2c2.38-1.21A2.75%2c2.75%2c0%2c0%2c0%2c23.45%2c18L14.4%2c3.5A2.89%2c2.89%2c0%2c0%2c0%2c12%2c2Z' style='fill: white'/%3e %3c/g%3e %3cpath d='M11.73%2c15.85a1%2c1%2c0%2c0%2c1-1-.91V8.76a1%2c1%2c0%2c0%2c1%2c2%2c0v6.18A1%2c1%2c0%2c0%2c1%2c11.73%2c15.85Zm0%2c1a1%2c1%2c0%2c1%2c0%2c1%2c1A1%2c1%2c0%2c0%2c0%2c11.73%2c16.85Z'/%3e %3c/svg%3e");
8
+ --di-download-grijs90: url("data:image/svg+xml,%3csvg id='download' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' style='color: %23191919%3b'%3e %3cpath fill='currentColor' d='M18.72%2c10.44%2c12%2c17l-6.7-6.52C4.8%2c10%2c5%2c9.63%2c5.63%2c9.63H8.5V1.82A.8.8%2c0%2c0%2c1%2c9.28%2c1h5.44a.8.8%2c0%2c0%2c1%2c.78.82V9.61h2.87C19%2c9.6%2c19.2%2c10%2c18.72%2c10.44ZM1%2c17v6H23V17Zm16%2c3a2%2c2%2c0%2c1%2c1-2-2A2%2c2%2c0%2c0%2c1%2c17%2c20Zm5%2c0a2%2c2%2c0%2c1%2c1-2-2A2%2c2%2c0%2c0%2c1%2c22%2c20Z'/%3e %3c/svg%3e");
9
+ --di-external-link-grijs90: url("data:image/svg+xml,%3csvg id='external-link' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' style='color: %23191919%3b'%3e %3cpath fill='currentColor' d='M19%2c6V9.69c0%2c.33-.2.41-.43.17L17.06%2c8.35l-3.35%2c3.36a1%2c1%2c0%2c0%2c1-1.42%2c0%2c1%2c1%2c0%2c0%2c1%2c0-1.42l3.36-3.35L14.14%2c5.43C13.9%2c5.19%2c14%2c5%2c14.31%2c5H19V6ZM18%2c17V13a1%2c1%2c0%2c0%2c0-2%2c0v4a1%2c1%2c0%2c0%2c1-1%2c1H7a1%2c1%2c0%2c0%2c1-1-1V9A1%2c1%2c0%2c0%2c1%2c7%2c8h4a1%2c1%2c0%2c0%2c0%2c0-2H7A3%2c3%2c0%2c0%2c0%2c4%2c9v8a3%2c3%2c0%2c0%2c0%2c3%2c3h8A3%2c3%2c0%2c0%2c0%2c18%2c17Z'/%3e %3c/svg%3e");
8
10
  }
9
11
 
10
12
  *,
@@ -6,7 +6,7 @@ const localization = {
6
6
  nextMonthLabel: 'Volgende maand',
7
7
  monthSelectLabel: 'Maand',
8
8
  yearSelectLabel: 'Jaar',
9
- closeLabel: 'Sluit window',
9
+ closeLabel: 'Sluiten',
10
10
  keyboardInstruction: 'Gebruik de pijltjestoetsen om een dag te kiezen',
11
11
  calendarHeading: 'Kies een datum',
12
12
  dayNames: [
@@ -63,6 +63,10 @@ export class DsoDatePicker {
63
63
  * Should the input be marked as required?
64
64
  */
65
65
  this.required = false;
66
+ /**
67
+ * Should the input be focused on load?
68
+ */
69
+ this.dsoAutofocus = false;
66
70
  /**
67
71
  * Date value. Must be in Dutch date format: DD-MM-YYYY.
68
72
  */
@@ -91,6 +95,20 @@ export class DsoDatePicker {
91
95
  component: "dso-date-picker",
92
96
  });
93
97
  };
98
+ this.handleKeyUp = (event) => {
99
+ event.stopPropagation();
100
+ this.dsoKeyUp.emit({
101
+ component: "dso-date-picker",
102
+ originalEvent: event
103
+ });
104
+ };
105
+ this.handleKeyDown = (event) => {
106
+ event.stopPropagation();
107
+ this.dsoKeyDown.emit({
108
+ component: "dso-date-picker",
109
+ originalEvent: event
110
+ });
111
+ };
94
112
  this.handleFocus = (event) => {
95
113
  event.stopPropagation();
96
114
  this.dsoFocus.emit({
@@ -211,12 +229,8 @@ export class DsoDatePicker {
211
229
  };
212
230
  this.handleInputChange = (e) => {
213
231
  const target = e.target;
214
- // clean up any invalid characters
215
232
  target.value = target.value.replace(DISALLOWED_CHARACTERS, "");
216
- const parsed = parseDutchDate(target.value);
217
- if (parsed || target.value === "") {
218
- this.setValue(parsed);
219
- }
233
+ this.setValue(target.value);
220
234
  };
221
235
  this.processFocusedDayNode = (element) => {
222
236
  this.focusedDayNode = element;
@@ -308,13 +322,37 @@ export class DsoDatePicker {
308
322
  setFocusedDay(day) {
309
323
  this.focusedDay = clamp(day, parseDutchDate(this.min), parseDutchDate(this.max));
310
324
  }
311
- setValue(date) {
312
- this.value = printDutchDate(date);
313
- this.dateChange.emit({
325
+ setValue(value) {
326
+ var event = {
314
327
  component: "dso-date-picker",
315
- value: this.value,
316
- valueAsDate: date,
317
- });
328
+ value: "",
329
+ valueAsDate: undefined
330
+ };
331
+ if (value instanceof Date) {
332
+ event.valueAsDate = value;
333
+ }
334
+ else {
335
+ event.value = value;
336
+ event.valueAsDate = parseDutchDate(value);
337
+ }
338
+ if (event.valueAsDate) {
339
+ event.value = this.value = printDutchDate(event.valueAsDate);
340
+ }
341
+ else {
342
+ this.value = "";
343
+ }
344
+ if (!event.valueAsDate && this.required) {
345
+ event.error = "required";
346
+ }
347
+ if (event.value && !event.valueAsDate) {
348
+ event.error = "invalid";
349
+ }
350
+ this.dateChange.emit(event);
351
+ }
352
+ componentDidLoad() {
353
+ if (this.dsoAutofocus) {
354
+ this.setFocus();
355
+ }
318
356
  }
319
357
  /**
320
358
  * render() function
@@ -341,7 +379,7 @@ export class DsoDatePicker {
341
379
  return (h(Host, null,
342
380
  h("div", { class: "dso-date" },
343
381
  h("div", { class: "dso-date__input-wrapper" },
344
- h("input", { class: "dso-date__input", value: formattedDate, placeholder: this.localization.placeholder, id: this.identifier, disabled: this.disabled, role: this.role, required: this.required ? true : undefined, "aria-autocomplete": "none", onInput: this.handleInputChange, onFocus: this.handleFocus, onBlur: this.handleBlur, autoComplete: "off", ref: element => (this.datePickerInput = element) }),
382
+ h("input", { class: "dso-date__input", value: formattedDate, placeholder: this.localization.placeholder, id: this.identifier, disabled: this.disabled, role: this.role, required: this.required ? true : undefined, "aria-autocomplete": "none", onInput: this.handleInputChange, onFocus: this.handleFocus, onBlur: this.handleBlur, onKeyUp: this.handleKeyUp, onKeyDown: this.handleKeyDown, autoComplete: "off", ref: element => (this.datePickerInput = element) }),
345
383
  h("button", { type: "button", class: "dso-date__toggle", onClick: this.toggleOpen, disabled: this.disabled, ref: element => (this.datePickerButton = element) },
346
384
  h("span", { class: "dso-date__toggle-icon" },
347
385
  h("dso-icon", { icon: "calendar" })),
@@ -510,9 +548,27 @@ export class DsoDatePicker {
510
548
  "reflect": false,
511
549
  "defaultValue": "false"
512
550
  },
551
+ "dsoAutofocus": {
552
+ "type": "boolean",
553
+ "mutable": false,
554
+ "complexType": {
555
+ "original": "boolean",
556
+ "resolved": "boolean",
557
+ "references": {}
558
+ },
559
+ "required": false,
560
+ "optional": false,
561
+ "docs": {
562
+ "tags": [],
563
+ "text": "Should the input be focused on load?"
564
+ },
565
+ "attribute": "dso-autofocus",
566
+ "reflect": false,
567
+ "defaultValue": "false"
568
+ },
513
569
  "value": {
514
570
  "type": "string",
515
- "mutable": false,
571
+ "mutable": true,
516
572
  "complexType": {
517
573
  "original": "string",
518
574
  "resolved": "string",
@@ -580,7 +636,7 @@ export class DsoDatePicker {
580
636
  },
581
637
  "complexType": {
582
638
  "original": "DsoDatePickerChangeEvent",
583
- "resolved": "{ component: \"dso-date-picker\"; valueAsDate: Date | undefined; value: string; }",
639
+ "resolved": "{ component: \"dso-date-picker\"; valueAsDate: Date | undefined; value: string; error?: \"invalid\" | \"required\" | undefined; }",
584
640
  "references": {
585
641
  "DsoDatePickerChangeEvent": {
586
642
  "location": "local"
@@ -606,6 +662,44 @@ export class DsoDatePicker {
606
662
  }
607
663
  }
608
664
  }
665
+ }, {
666
+ "method": "dsoKeyUp",
667
+ "name": "dsoKeyUp",
668
+ "bubbles": true,
669
+ "cancelable": true,
670
+ "composed": true,
671
+ "docs": {
672
+ "tags": [],
673
+ "text": "Event emitted on key up in the date picker input."
674
+ },
675
+ "complexType": {
676
+ "original": "DsoDatePickerKeyboardEvent",
677
+ "resolved": "{ component: \"dso-date-picker\"; originalEvent: KeyboardEvent; }",
678
+ "references": {
679
+ "DsoDatePickerKeyboardEvent": {
680
+ "location": "local"
681
+ }
682
+ }
683
+ }
684
+ }, {
685
+ "method": "dsoKeyDown",
686
+ "name": "dsoKeyDown",
687
+ "bubbles": true,
688
+ "cancelable": true,
689
+ "composed": true,
690
+ "docs": {
691
+ "tags": [],
692
+ "text": "Event emitted on key down in the date picker input."
693
+ },
694
+ "complexType": {
695
+ "original": "DsoDatePickerKeyboardEvent",
696
+ "resolved": "{ component: \"dso-date-picker\"; originalEvent: KeyboardEvent; }",
697
+ "references": {
698
+ "DsoDatePickerKeyboardEvent": {
699
+ "location": "local"
700
+ }
701
+ }
702
+ }
609
703
  }, {
610
704
  "method": "dsoFocus",
611
705
  "name": "dsoFocus",
@@ -1,6 +1,6 @@
1
1
  import { html } from 'lit-html';
2
2
  import { ifDefined } from 'lit-html/directives/if-defined';
3
- export function datePickerTemplate({ id, onDateChange, value, min, max, disabled }) {
3
+ export function datePickerTemplate({ id, onDateChange, value, min, max, disabled, autofocus }) {
4
4
  return html `
5
5
  <dso-date-picker
6
6
  @dateChange=${(e) => onDateChange(e)}
@@ -8,6 +8,7 @@ export function datePickerTemplate({ id, onDateChange, value, min, max, disabled
8
8
  value=${ifDefined(value || undefined)}
9
9
  min=${ifDefined(min || undefined)}
10
10
  max=${ifDefined(max || undefined)}
11
+ dso-autofocus=${ifDefined(autofocus || undefined)}
11
12
  ?disabled=${disabled}
12
13
  ></dso-date-picker>
13
14
  `;
@@ -44,9 +44,9 @@ export function printDutchDate(date) {
44
44
  if (!date) {
45
45
  return '';
46
46
  }
47
- var d = date.getDate().toString(10);
48
- var m = (date.getMonth() + 1).toString(10);
49
- var y = date.getFullYear().toString(10);
47
+ var d = date.getDate().toString(10).padStart(2, '0');
48
+ var m = (date.getMonth() + 1).toString(10).padStart(2, '0');
49
+ var y = date.getFullYear().toString(10).padStart(2, '0');
50
50
  return `${d}-${m}-${y}`;
51
51
  }
52
52
  /**
@@ -179,11 +179,13 @@ const icons = [
179
179
  ];
180
180
  export class Icon {
181
181
  render() {
182
- const icon = icons.find(i => i.alias === this.icon);
183
- if (!icon) {
184
- throw new TypeError(`Unknown svg: ${this.icon}`);
182
+ if (this.icon) {
183
+ const icon = icons.find(i => i.alias === this.icon);
184
+ if (!icon) {
185
+ throw new TypeError(`Unknown svg: ${this.icon}`);
186
+ }
187
+ return h("span", { class: "icon-container", innerHTML: icon.svg });
185
188
  }
186
- return h("span", { class: "icon-container", innerHTML: icon.svg });
187
189
  }
188
190
  static get is() { return "dso-icon"; }
189
191
  static get encapsulation() { return "shadow"; }
@@ -199,11 +201,11 @@ export class Icon {
199
201
  "mutable": false,
200
202
  "complexType": {
201
203
  "original": "string",
202
- "resolved": "string",
204
+ "resolved": "string | undefined",
203
205
  "references": {}
204
206
  },
205
- "required": true,
206
- "optional": false,
207
+ "required": false,
208
+ "optional": true,
207
209
  "docs": {
208
210
  "tags": [],
209
211
  "text": ""