@phatvu/web-component-poc 1.0.6 → 1.0.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.
Files changed (52) hide show
  1. package/dist/cjs/fast-button_6.cjs.entry.js +578 -0
  2. package/dist/cjs/{fast-button_4.cjs.entry.js → fast-carousel.cjs.entry.js} +1 -231
  3. package/dist/cjs/{index-B2BTpdbN.js → index-227GpI8K.js} +66 -2
  4. package/dist/cjs/job-card.cjs.entry.js +1 -1
  5. package/dist/cjs/loader.cjs.js +2 -2
  6. package/dist/cjs/web-component-poc.cjs.js +2 -2
  7. package/dist/collection/collection-manifest.json +4 -1
  8. package/dist/collection/components/button/button.css +14 -14
  9. package/dist/collection/components/button/button.js +12 -24
  10. package/dist/collection/components/fast-form/fast-form.css +5 -0
  11. package/dist/collection/components/fast-form/fast-form.js +99 -0
  12. package/dist/collection/components/fast-input/fast-input.css +45 -0
  13. package/dist/collection/components/fast-input/fast-input.js +359 -0
  14. package/dist/collection/components/jobs-list-only/jobs-list-only.js +180 -3
  15. package/dist/collection/components/jobs-list-reactive/jobs-list-reactive.css +8 -0
  16. package/dist/collection/components/jobs-list-reactive/jobs-list-reactive.js +203 -0
  17. package/dist/components/fast-button.js +1 -1
  18. package/dist/components/fast-carousel.js +1 -1
  19. package/dist/components/fast-form.d.ts +11 -0
  20. package/dist/components/fast-form.js +1 -0
  21. package/dist/components/fast-input.d.ts +11 -0
  22. package/dist/components/fast-input.js +1 -0
  23. package/dist/components/index.js +1 -1
  24. package/dist/components/job-card.js +1 -1
  25. package/dist/components/jobs-item.js +1 -1
  26. package/dist/components/jobs-list-only.js +1 -1
  27. package/dist/components/jobs-list-reactive.d.ts +11 -0
  28. package/dist/components/jobs-list-reactive.js +1 -0
  29. package/dist/components/p-Bb27ylcX.js +1 -0
  30. package/dist/components/{p-ClQDwJJB.js → p-CzgtwPsc.js} +1 -1
  31. package/dist/esm/fast-button_6.entry.js +571 -0
  32. package/dist/esm/{fast-button_4.entry.js → fast-carousel.entry.js} +2 -229
  33. package/dist/esm/{index-Dk5CvWmb.js → index-BqjrT3zA.js} +66 -2
  34. package/dist/esm/job-card.entry.js +1 -1
  35. package/dist/esm/loader.js +3 -3
  36. package/dist/esm/web-component-poc.js +3 -3
  37. package/dist/types/components/button/button.d.ts +1 -13
  38. package/dist/types/components/fast-form/fast-form.d.ts +10 -0
  39. package/dist/types/components/fast-input/fast-input.d.ts +35 -0
  40. package/dist/types/components/jobs-list-only/jobs-list-only.d.ts +22 -0
  41. package/dist/types/components/jobs-list-reactive/jobs-list-reactive.d.ts +26 -0
  42. package/dist/types/components.d.ts +256 -11
  43. package/dist/web-component-poc/{p-52c85341.entry.js → p-14247159.entry.js} +1 -1
  44. package/dist/web-component-poc/p-309a490b.entry.js +1 -0
  45. package/dist/web-component-poc/p-7ea9a87f.entry.js +1 -0
  46. package/dist/web-component-poc/{p-Dk5CvWmb.js → p-BqjrT3zA.js} +2 -2
  47. package/dist/web-component-poc/web-component-poc.esm.js +1 -1
  48. package/hydrate/index.js +457 -27
  49. package/hydrate/index.mjs +457 -27
  50. package/package.json +7 -3
  51. package/dist/components/p-UM9TUfe3.js +0 -1
  52. package/dist/web-component-poc/p-96761988.entry.js +0 -1
@@ -0,0 +1,99 @@
1
+ import { h } from "@stencil/core";
2
+ export class FastForm {
3
+ el;
4
+ searchExecuted;
5
+ handleInputSubmit() {
6
+ this.submit();
7
+ }
8
+ async submit() {
9
+ const inputs = this.el.querySelectorAll('fast-input');
10
+ const params = {};
11
+ for (const input of Array.from(inputs)) {
12
+ const paramName = await input.getParamName();
13
+ const value = await input.getValue();
14
+ if (value) {
15
+ params[paramName] = value;
16
+ }
17
+ }
18
+ this.updateUrlParams(params);
19
+ document.dispatchEvent(new CustomEvent('search-executed', {
20
+ detail: params,
21
+ bubbles: true,
22
+ composed: true,
23
+ }));
24
+ this.searchExecuted.emit(params);
25
+ }
26
+ updateUrlParams(params) {
27
+ const urlParams = new URLSearchParams(window.location.search);
28
+ // Get all param names from inputs and clear them first
29
+ const inputs = this.el.querySelectorAll('fast-input');
30
+ for (const input of Array.from(inputs)) {
31
+ const paramName = input.paramName;
32
+ if (paramName) {
33
+ urlParams.delete(paramName);
34
+ }
35
+ }
36
+ // Set new values
37
+ for (const [key, value] of Object.entries(params)) {
38
+ if (value) {
39
+ urlParams.set(key, value);
40
+ }
41
+ }
42
+ const qs = urlParams.toString();
43
+ const newUrl = qs
44
+ ? `${window.location.pathname}?${qs}`
45
+ : window.location.pathname;
46
+ history.pushState({}, '', newUrl);
47
+ }
48
+ handleFormSubmit = (e) => {
49
+ e.preventDefault();
50
+ this.submit();
51
+ };
52
+ render() {
53
+ return (h("form", { key: '50436bb904e8b175ae0c23158812a4e4756544c0', class: "fast-form", onSubmit: this.handleFormSubmit }, h("slot", { key: '2f76c4c42c15ebf389d6e0fdbcb9a2098bf1156a' })));
54
+ }
55
+ static get is() { return "fast-form"; }
56
+ static get originalStyleUrls() {
57
+ return {
58
+ "$": ["fast-form.css"]
59
+ };
60
+ }
61
+ static get styleUrls() {
62
+ return {
63
+ "$": ["fast-form.css"]
64
+ };
65
+ }
66
+ static get events() {
67
+ return [{
68
+ "method": "searchExecuted",
69
+ "name": "searchExecuted",
70
+ "bubbles": true,
71
+ "cancelable": true,
72
+ "composed": true,
73
+ "docs": {
74
+ "tags": [],
75
+ "text": ""
76
+ },
77
+ "complexType": {
78
+ "original": "Record<string, string>",
79
+ "resolved": "string",
80
+ "references": {
81
+ "Record": {
82
+ "location": "global",
83
+ "id": "global::Record"
84
+ }
85
+ }
86
+ }
87
+ }];
88
+ }
89
+ static get elementRef() { return "el"; }
90
+ static get listeners() {
91
+ return [{
92
+ "name": "inputSubmit",
93
+ "method": "handleInputSubmit",
94
+ "target": undefined,
95
+ "capture": false,
96
+ "passive": false
97
+ }];
98
+ }
99
+ }
@@ -0,0 +1,45 @@
1
+ .fast-input {
2
+ position: relative;
3
+ display: inline-block;
4
+ }
5
+
6
+ .fast-input__field {
7
+ padding: 0.5rem 0.75rem;
8
+ font-size: 1rem;
9
+ border: 1px solid #ccc;
10
+ border-radius: 4px;
11
+ width: 100%;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ .fast-input__dropdown {
16
+ position: absolute;
17
+ top: 100%;
18
+ left: 0;
19
+ right: 0;
20
+ margin: 0;
21
+ padding: 0;
22
+ list-style: none;
23
+ background: #fff;
24
+ border: 1px solid #ccc;
25
+ border-top: none;
26
+ border-radius: 0 0 4px 4px;
27
+ z-index: 100;
28
+ max-height: 200px;
29
+ overflow-y: auto;
30
+ }
31
+
32
+ .fast-input__dropdown-item {
33
+ padding: 0.5rem 0.75rem;
34
+ cursor: pointer;
35
+ }
36
+
37
+ .fast-input__dropdown-item:hover {
38
+ background: #f0f0f0;
39
+ }
40
+
41
+ .fast-input__dropdown-loading {
42
+ padding: 0.5rem 0.75rem;
43
+ color: #999;
44
+ font-style: italic;
45
+ }
@@ -0,0 +1,359 @@
1
+ import { h, } from "@stencil/core";
2
+ export class FastInput {
3
+ placeholder = 'Search...';
4
+ value = '';
5
+ paramName = 'keyword';
6
+ enableAutocomplete = false;
7
+ autocompleteUrl = '/api/jobs/autocomplete';
8
+ targetPath;
9
+ debounceMs = 300;
10
+ minChars = 3;
11
+ inputSubmit;
12
+ inputChanged;
13
+ inputValue = '';
14
+ suggestions = [];
15
+ showDropdown = false;
16
+ autocompleteLoading = false;
17
+ debounceTimer;
18
+ popstateHandler;
19
+ async getValue() {
20
+ return this.inputValue;
21
+ }
22
+ async getParamName() {
23
+ return this.paramName;
24
+ }
25
+ connectedCallback() {
26
+ const urlValue = this.getUrlParam();
27
+ this.inputValue = urlValue !== null ? urlValue : this.value;
28
+ this.popstateHandler = () => {
29
+ this.inputValue = this.getUrlParam() ?? '';
30
+ };
31
+ window.addEventListener('popstate', this.popstateHandler);
32
+ }
33
+ disconnectedCallback() {
34
+ window.removeEventListener('popstate', this.popstateHandler);
35
+ clearTimeout(this.debounceTimer);
36
+ }
37
+ getUrlParam() {
38
+ const params = new URLSearchParams(window.location.search);
39
+ return params.get(this.paramName);
40
+ }
41
+ handleInput = (e) => {
42
+ const value = e.target.value;
43
+ this.inputValue = value;
44
+ this.inputChanged.emit({ value });
45
+ if (this.enableAutocomplete) {
46
+ this.scheduleAutocomplete(value);
47
+ }
48
+ };
49
+ handleKeydown = (e) => {
50
+ if (e.key === 'Enter') {
51
+ e.preventDefault();
52
+ this.showDropdown = false;
53
+ this.inputSubmit.emit();
54
+ }
55
+ else if (e.key === 'Escape') {
56
+ this.showDropdown = false;
57
+ }
58
+ };
59
+ handleBlur = () => {
60
+ this.showDropdown = false;
61
+ };
62
+ scheduleAutocomplete(value) {
63
+ clearTimeout(this.debounceTimer);
64
+ if (value.length < this.minChars) {
65
+ this.showDropdown = false;
66
+ return;
67
+ }
68
+ this.debounceTimer = setTimeout(() => this.fetchSuggestions(value), this.debounceMs);
69
+ }
70
+ async fetchSuggestions(keyword) {
71
+ if (!this.targetPath) {
72
+ console.warn('[fast-input] target-path is required for autocomplete');
73
+ return;
74
+ }
75
+ this.autocompleteLoading = true;
76
+ this.showDropdown = true;
77
+ try {
78
+ const res = await fetch(this.autocompleteUrl, {
79
+ method: 'POST',
80
+ headers: { 'Content-Type': 'application/json' },
81
+ body: JSON.stringify({ keyword, target_path: this.targetPath }),
82
+ });
83
+ if (!res.ok)
84
+ throw new Error('autocomplete request failed');
85
+ const data = await res.json();
86
+ this.suggestions = data;
87
+ }
88
+ catch {
89
+ this.showDropdown = false;
90
+ this.suggestions = [];
91
+ }
92
+ finally {
93
+ this.autocompleteLoading = false;
94
+ }
95
+ }
96
+ selectSuggestion(title) {
97
+ this.inputValue = title;
98
+ this.showDropdown = false;
99
+ this.inputSubmit.emit();
100
+ }
101
+ render() {
102
+ return (h("div", { key: 'ea03f3dd68d0da4fc30cbc18a1ef66b5974a4f89', class: "fast-input" }, h("input", { key: '31d85c4c90dde0e10ea9424b960c5e4f4a3ca54a', type: "text", class: "fast-input__field", placeholder: this.placeholder, value: this.inputValue, onInput: this.handleInput, onKeyDown: this.handleKeydown, onBlur: this.handleBlur }), this.enableAutocomplete && this.showDropdown && (h("ul", { key: '0de6fd68709d906bafd2fec684f0a73045be3705', class: "fast-input__dropdown" }, this.autocompleteLoading ? (h("li", { class: "fast-input__dropdown-loading" }, "Loading...")) : (this.suggestions.map(s => (h("li", { class: "fast-input__dropdown-item", onMouseDown: e => {
103
+ e.preventDefault();
104
+ }, onClick: () => this.selectSuggestion(s.title) }, s.title))))))));
105
+ }
106
+ static get is() { return "fast-input"; }
107
+ static get originalStyleUrls() {
108
+ return {
109
+ "$": ["fast-input.css"]
110
+ };
111
+ }
112
+ static get styleUrls() {
113
+ return {
114
+ "$": ["fast-input.css"]
115
+ };
116
+ }
117
+ static get properties() {
118
+ return {
119
+ "placeholder": {
120
+ "type": "string",
121
+ "mutable": false,
122
+ "complexType": {
123
+ "original": "string",
124
+ "resolved": "string",
125
+ "references": {}
126
+ },
127
+ "required": false,
128
+ "optional": false,
129
+ "docs": {
130
+ "tags": [],
131
+ "text": ""
132
+ },
133
+ "getter": false,
134
+ "setter": false,
135
+ "reflect": false,
136
+ "attribute": "placeholder",
137
+ "defaultValue": "'Search...'"
138
+ },
139
+ "value": {
140
+ "type": "string",
141
+ "mutable": false,
142
+ "complexType": {
143
+ "original": "string",
144
+ "resolved": "string",
145
+ "references": {}
146
+ },
147
+ "required": false,
148
+ "optional": false,
149
+ "docs": {
150
+ "tags": [],
151
+ "text": ""
152
+ },
153
+ "getter": false,
154
+ "setter": false,
155
+ "reflect": false,
156
+ "attribute": "value",
157
+ "defaultValue": "''"
158
+ },
159
+ "paramName": {
160
+ "type": "string",
161
+ "mutable": false,
162
+ "complexType": {
163
+ "original": "string",
164
+ "resolved": "string",
165
+ "references": {}
166
+ },
167
+ "required": false,
168
+ "optional": false,
169
+ "docs": {
170
+ "tags": [],
171
+ "text": ""
172
+ },
173
+ "getter": false,
174
+ "setter": false,
175
+ "reflect": false,
176
+ "attribute": "param-name",
177
+ "defaultValue": "'keyword'"
178
+ },
179
+ "enableAutocomplete": {
180
+ "type": "boolean",
181
+ "mutable": false,
182
+ "complexType": {
183
+ "original": "boolean",
184
+ "resolved": "boolean",
185
+ "references": {}
186
+ },
187
+ "required": false,
188
+ "optional": false,
189
+ "docs": {
190
+ "tags": [],
191
+ "text": ""
192
+ },
193
+ "getter": false,
194
+ "setter": false,
195
+ "reflect": false,
196
+ "attribute": "enable-autocomplete",
197
+ "defaultValue": "false"
198
+ },
199
+ "autocompleteUrl": {
200
+ "type": "string",
201
+ "mutable": false,
202
+ "complexType": {
203
+ "original": "string",
204
+ "resolved": "string",
205
+ "references": {}
206
+ },
207
+ "required": false,
208
+ "optional": false,
209
+ "docs": {
210
+ "tags": [],
211
+ "text": ""
212
+ },
213
+ "getter": false,
214
+ "setter": false,
215
+ "reflect": false,
216
+ "attribute": "autocomplete-url",
217
+ "defaultValue": "'/api/jobs/autocomplete'"
218
+ },
219
+ "targetPath": {
220
+ "type": "string",
221
+ "mutable": false,
222
+ "complexType": {
223
+ "original": "string | undefined",
224
+ "resolved": "string",
225
+ "references": {}
226
+ },
227
+ "required": false,
228
+ "optional": false,
229
+ "docs": {
230
+ "tags": [],
231
+ "text": ""
232
+ },
233
+ "getter": false,
234
+ "setter": false,
235
+ "reflect": false,
236
+ "attribute": "target-path"
237
+ },
238
+ "debounceMs": {
239
+ "type": "number",
240
+ "mutable": false,
241
+ "complexType": {
242
+ "original": "number",
243
+ "resolved": "number",
244
+ "references": {}
245
+ },
246
+ "required": false,
247
+ "optional": false,
248
+ "docs": {
249
+ "tags": [],
250
+ "text": ""
251
+ },
252
+ "getter": false,
253
+ "setter": false,
254
+ "reflect": false,
255
+ "attribute": "debounce-ms",
256
+ "defaultValue": "300"
257
+ },
258
+ "minChars": {
259
+ "type": "number",
260
+ "mutable": false,
261
+ "complexType": {
262
+ "original": "number",
263
+ "resolved": "number",
264
+ "references": {}
265
+ },
266
+ "required": false,
267
+ "optional": false,
268
+ "docs": {
269
+ "tags": [],
270
+ "text": ""
271
+ },
272
+ "getter": false,
273
+ "setter": false,
274
+ "reflect": false,
275
+ "attribute": "min-chars",
276
+ "defaultValue": "3"
277
+ }
278
+ };
279
+ }
280
+ static get states() {
281
+ return {
282
+ "inputValue": {},
283
+ "suggestions": {},
284
+ "showDropdown": {},
285
+ "autocompleteLoading": {}
286
+ };
287
+ }
288
+ static get events() {
289
+ return [{
290
+ "method": "inputSubmit",
291
+ "name": "inputSubmit",
292
+ "bubbles": true,
293
+ "cancelable": true,
294
+ "composed": true,
295
+ "docs": {
296
+ "tags": [],
297
+ "text": ""
298
+ },
299
+ "complexType": {
300
+ "original": "void",
301
+ "resolved": "void",
302
+ "references": {}
303
+ }
304
+ }, {
305
+ "method": "inputChanged",
306
+ "name": "inputChanged",
307
+ "bubbles": true,
308
+ "cancelable": true,
309
+ "composed": true,
310
+ "docs": {
311
+ "tags": [],
312
+ "text": ""
313
+ },
314
+ "complexType": {
315
+ "original": "{ value: string }",
316
+ "resolved": "{ value: string; }",
317
+ "references": {}
318
+ }
319
+ }];
320
+ }
321
+ static get methods() {
322
+ return {
323
+ "getValue": {
324
+ "complexType": {
325
+ "signature": "() => Promise<string>",
326
+ "parameters": [],
327
+ "references": {
328
+ "Promise": {
329
+ "location": "global",
330
+ "id": "global::Promise"
331
+ }
332
+ },
333
+ "return": "Promise<string>"
334
+ },
335
+ "docs": {
336
+ "text": "",
337
+ "tags": []
338
+ }
339
+ },
340
+ "getParamName": {
341
+ "complexType": {
342
+ "signature": "() => Promise<string>",
343
+ "parameters": [],
344
+ "references": {
345
+ "Promise": {
346
+ "location": "global",
347
+ "id": "global::Promise"
348
+ }
349
+ },
350
+ "return": "Promise<string>"
351
+ },
352
+ "docs": {
353
+ "text": "",
354
+ "tags": []
355
+ }
356
+ }
357
+ };
358
+ }
359
+ }