@ebrains/react 0.8.0-alpha.0 → 0.9.1-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/bookmark-c200037c.esm.js +16 -0
- package/color-primary-palette_6.entry.esm.js +163 -141
- package/{eds-components-section.entry.esm.js → components-section.entry.esm.js} +22 -18
- package/correct-use-of-colors.entry.esm.js +49 -49
- package/{eds-docs-palettes.entry.esm.js → docs-palettes.entry.esm.js} +3 -3
- package/{eds-docs-tokens.entry.esm.js → docs-tokens.entry.esm.js} +3 -3
- package/eds-accordion.entry.esm.js +132 -0
- package/eds-app-root.entry.esm.js +4 -4
- package/eds-avatar_26.entry.esm.js +306 -0
- package/{eds-card-desc_3.entry.esm.js → eds-card-desc_2.entry.esm.js} +1 -40
- package/eds-card-generic.entry.esm.js +3 -3
- package/eds-cookies-preference.entry.esm.js +2 -2
- package/eds-feedback.entry.esm.js +9 -9
- package/eds-frame.entry.esm.js +9 -15
- package/eds-icon-bluesky.entry.esm.js +1 -1
- package/eds-icon-bookmark.entry.esm.js +21 -0
- package/eds-icon-close.entry.esm.js +1 -1
- package/eds-icon-copy.entry.esm.js +1 -1
- package/eds-icon-eu.entry.esm.js +1 -1
- package/eds-icon-external.entry.esm.js +21 -0
- package/eds-icon-facebook.entry.esm.js +1 -1
- package/eds-icon-gitlab.entry.esm.js +1 -1
- package/eds-icon-linkedin.entry.esm.js +1 -1
- package/eds-icon-loader.entry.esm.js +1 -1
- package/eds-icon-mastodon.entry.esm.js +1 -1
- package/eds-icon-menu.entry.esm.js +1 -1
- package/eds-icon-minus.entry.esm.js +21 -0
- package/eds-icon-more.entry.esm.js +1 -1
- package/eds-icon-paper.entry.esm.js +21 -0
- package/eds-icon-plus.entry.esm.js +21 -0
- package/eds-icon-portal.entry.esm.js +21 -0
- package/eds-icon-private.entry.esm.js +21 -0
- package/eds-icon-public.entry.esm.js +21 -0
- package/eds-icon-search.entry.esm.js +1 -1
- package/eds-icon-star.entry.esm.js +1 -1
- package/eds-icon-success.entry.esm.js +1 -1
- package/eds-icon-thumbs-down.entry.esm.js +1 -1
- package/eds-icon-thumbs-up.entry.esm.js +1 -1
- package/eds-icon-tutorial.entry.esm.js +21 -0
- package/eds-icon-twitter.entry.esm.js +1 -1
- package/eds-icon-unknown.entry.esm.js +21 -0
- package/eds-icon-updown.entry.esm.js +21 -0
- package/eds-icon-user.entry.esm.js +1 -1
- package/eds-icon-youtube.entry.esm.js +1 -1
- package/eds-login_2.entry.esm.js +27 -15
- package/eds-matomo-notice.entry.esm.js +162 -0
- package/eds-modal.entry.esm.js +17 -17
- package/eds-pagination_2.entry.esm.js +12 -12
- package/eds-progress-bar.entry.esm.js +2 -2
- package/eds-rating.entry.esm.js +1 -1
- package/eds-section-core_2.entry.esm.js +5 -5
- package/eds-spinner.entry.esm.js +3 -3
- package/eds-switch.entry.esm.js +7 -7
- package/eds-tabs.entry.esm.js +8 -8
- package/eds-timeline.entry.esm.js +5 -5
- package/eds-toast-manager.entry.esm.js +1 -1
- package/eds-tooltip.entry.esm.js +3 -3
- package/eds-trl.entry.esm.js +2 -2
- package/incorrect-use-of-colors.entry.esm.js +9 -9
- package/index.esm.js +1 -1
- package/index.esm2.js +60 -36
- package/logo-space.entry.esm.js +28 -12
- package/logo-variations-horizontal_2.entry.esm.js +73 -66
- package/{eds-logo-variations.entry.esm.js → logo-variations-tabs.entry.esm.js} +3 -3
- package/logo-wrong-usage.entry.esm.js +71 -107
- package/minus-b30a7c71.esm.js +11 -0
- package/package.json +1 -1
- package/paper-8e74ea31.esm.js +15 -0
- package/plus-89c07be2.esm.js +12 -0
- package/portal-d6c8ce56.esm.js +18 -0
- package/private-1c25ff8e.esm.js +25 -0
- package/public-d4d8c585.esm.js +16 -0
- package/src/components.d.ts +0 -3
- package/{eds-svg-repository.entry.esm.js → svg-repository.entry.esm.js} +29 -28
- package/token-list_3.entry.esm.js +9 -9
- package/token-ratios.entry.esm.js +3 -3
- package/token-typography.entry.esm.js +10 -7
- package/tutotial-150ee1fd.esm.js +27 -0
- package/unknown-ed01a24c.esm.js +22 -0
- package/up-and-down-d747abee.esm.js +12 -0
- package/eds-accordion_17.entry.esm.js +0 -196
- package/eds-breadcrumb.entry.esm.js +0 -174
- package/eds-form.entry.esm.js +0 -473
- package/eds-input_7.entry.esm.js +0 -569
- package/token-spacing.entry.esm.js +0 -93
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { r as registerInstance, h, g as getElement } from './index.esm2.js';
|
|
2
|
-
import { p as parseData } from './sharedUtils-a550989c.esm.js';
|
|
3
|
-
import 'react';
|
|
4
|
-
import 'react/jsx-runtime';
|
|
5
|
-
import 'react-dom';
|
|
6
|
-
|
|
7
|
-
const edsBreadcrumbCss = "blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}.hidden{display:none}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.items-center{align-items:center}.justify-center{justify-content:center}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(0.125rem * var(--tw-space-x-reverse));margin-left:calc(0.125rem * calc(1 - var(--tw-space-x-reverse)))}.px-2{padding-left:0.125rem;padding-right:0.125rem}.w-20{width:1.25rem}.w-28{width:1.75rem}.w-32{width:2rem}.w-44{width:2.75rem}.h-20{height:1.25rem}.h-24{height:1.5rem}.h-28{height:1.75rem}.h-32{height:2rem}@media (min-width: 750px){.md\\:block{display:block}}";
|
|
8
|
-
const EdsBreadcrumbStyle0 = edsBreadcrumbCss;
|
|
9
|
-
const EdsBreadcrumb = class {
|
|
10
|
-
constructor(hostRef) {
|
|
11
|
-
registerInstance(this, hostRef);
|
|
12
|
-
/**
|
|
13
|
-
* Updates the maximum number of visible items and tracks if the screen is small.
|
|
14
|
-
*/
|
|
15
|
-
this.updateScreenSize = () => {
|
|
16
|
-
const width = window.innerWidth;
|
|
17
|
-
if (width < 769) {
|
|
18
|
-
this.maxVisibleItems = 3;
|
|
19
|
-
this.isSmallScreen = true;
|
|
20
|
-
} else if (width <= 1024) {
|
|
21
|
-
this.maxVisibleItems = 3;
|
|
22
|
-
this.isSmallScreen = true;
|
|
23
|
-
} else if (width <= 2200) {
|
|
24
|
-
this.maxVisibleItems = 4;
|
|
25
|
-
this.isSmallScreen = false;
|
|
26
|
-
} else {
|
|
27
|
-
this.maxVisibleItems = 6;
|
|
28
|
-
this.isSmallScreen = false;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
this.items = [];
|
|
32
|
-
this.intent = 'ghost';
|
|
33
|
-
this.parsedItems = [];
|
|
34
|
-
this.isSmallScreen = false;
|
|
35
|
-
this.maxVisibleItems = 6;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Watches for changes to the `items` prop and parses it.
|
|
39
|
-
*/
|
|
40
|
-
parseItems(newValue) {
|
|
41
|
-
this.parsedItems = parseData(newValue);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Lifecycle method that runs when the component is about to be loaded.
|
|
45
|
-
* It parses the initial `items` prop value.
|
|
46
|
-
*/
|
|
47
|
-
componentWillLoad() {
|
|
48
|
-
this.parseItems(this.items);
|
|
49
|
-
this.updateScreenSize();
|
|
50
|
-
window.addEventListener('resize', this.updateScreenSize);
|
|
51
|
-
}
|
|
52
|
-
disconnectedCallback() {
|
|
53
|
-
window.removeEventListener('resize', this.updateScreenSize);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Lifecycle method that runs when the component has fully loaded.
|
|
57
|
-
* It emits a custom event for each `eds-link` element contained within the breadcrumb.
|
|
58
|
-
*/
|
|
59
|
-
componentDidLoad() {
|
|
60
|
-
var _a;
|
|
61
|
-
const links = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('eds-link');
|
|
62
|
-
links === null || links === void 0 ? void 0 : links.forEach(link => {
|
|
63
|
-
this.emitContext(link);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Emits a custom event called `parentContext` for a given link element.
|
|
68
|
-
* This event provides context information about the breadcrumb component.
|
|
69
|
-
*
|
|
70
|
-
* @param linkElement - The link element to which the event will be dispatched.
|
|
71
|
-
*/
|
|
72
|
-
emitContext(linkElement) {
|
|
73
|
-
const event = new CustomEvent('parentContext', {
|
|
74
|
-
detail: {
|
|
75
|
-
componentName: this.el.tagName.toLowerCase(),
|
|
76
|
-
identifier: null
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
linkElement.dispatchEvent(event);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Returns breadcrumb items with potential truncation if there are too many.
|
|
83
|
-
* It inserts an ellipsis item where necessary.
|
|
84
|
-
*/
|
|
85
|
-
getTruncatedItems() {
|
|
86
|
-
const totalItems = this.parsedItems.length;
|
|
87
|
-
const ellipsis = {
|
|
88
|
-
label: '...',
|
|
89
|
-
url: '',
|
|
90
|
-
isHidden: true
|
|
91
|
-
};
|
|
92
|
-
if (totalItems > this.maxVisibleItems) {
|
|
93
|
-
const firstItem = this.parsedItems[0];
|
|
94
|
-
const lastItems = this.parsedItems.slice(-2);
|
|
95
|
-
if (this.maxVisibleItems === 3) {
|
|
96
|
-
return [firstItem, ellipsis, ...lastItems];
|
|
97
|
-
} else if (this.maxVisibleItems === 4) {
|
|
98
|
-
const middleItem = this.parsedItems[Math.floor(totalItems / 2)];
|
|
99
|
-
return [firstItem, middleItem, ellipsis, ...lastItems];
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return this.parsedItems;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Helper to determine the display label and full label.
|
|
106
|
-
* If the label is longer than 15 characters and the item is not the current (last) item,
|
|
107
|
-
* we display a truncated version but use the full label for aria attributes.
|
|
108
|
-
*/
|
|
109
|
-
getLabels(item, isCurrent) {
|
|
110
|
-
if (!isCurrent && item.label.length > 15) {
|
|
111
|
-
return {
|
|
112
|
-
displayLabel: `${item.label.slice(0, 15)}...`,
|
|
113
|
-
fullLabel: item.label
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
displayLabel: item.label,
|
|
118
|
-
fullLabel: item.label
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Render method for the breadcrumb component.
|
|
123
|
-
* It creates a navigation element with an ordered list of breadcrumb links.
|
|
124
|
-
* The last link is marked as the current page.
|
|
125
|
-
*/
|
|
126
|
-
render() {
|
|
127
|
-
const itemsToRender = this.getTruncatedItems();
|
|
128
|
-
return h("nav", {
|
|
129
|
-
key: '75bb5629a10de2a2a7bd0b2bbef04e5f699f5fe2',
|
|
130
|
-
"aria-label": "Breadcrumb"
|
|
131
|
-
}, h("ol", {
|
|
132
|
-
key: '7a5cc115b70d60bc878aa3d865802662f30948c1',
|
|
133
|
-
class: "flex items-center space-x-2"
|
|
134
|
-
}, itemsToRender.map((item, index) => {
|
|
135
|
-
const isLast = index === itemsToRender.length - 1;
|
|
136
|
-
return h("li", {
|
|
137
|
-
class: "flex items-center"
|
|
138
|
-
}, !item.isHidden ? (() => {
|
|
139
|
-
const {
|
|
140
|
-
displayLabel,
|
|
141
|
-
fullLabel
|
|
142
|
-
} = this.getLabels(item, isLast);
|
|
143
|
-
return h("eds-link", Object.assign({
|
|
144
|
-
label: displayLabel,
|
|
145
|
-
url: item.url,
|
|
146
|
-
intent: this.intent,
|
|
147
|
-
current: isLast,
|
|
148
|
-
"aria-label": fullLabel,
|
|
149
|
-
size: "small",
|
|
150
|
-
"icon-small": "false"
|
|
151
|
-
}, isLast ? {
|
|
152
|
-
'aria-current': 'page'
|
|
153
|
-
} : {}));
|
|
154
|
-
})() : h("span", {
|
|
155
|
-
class: "truncate px-2",
|
|
156
|
-
"aria-hidden": "true"
|
|
157
|
-
}, "..."), !isLast && !item.isHidden && h("eds-icon-wrapper", {
|
|
158
|
-
icon: "chevron-right",
|
|
159
|
-
class: "w-20 h-20"
|
|
160
|
-
}));
|
|
161
|
-
})));
|
|
162
|
-
}
|
|
163
|
-
get el() {
|
|
164
|
-
return getElement(this);
|
|
165
|
-
}
|
|
166
|
-
static get watchers() {
|
|
167
|
-
return {
|
|
168
|
-
"items": ["parseItems"]
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
EdsBreadcrumb.style = EdsBreadcrumbStyle0;
|
|
173
|
-
|
|
174
|
-
export { EdsBreadcrumb as eds_breadcrumb };
|
package/eds-form.entry.esm.js
DELETED
|
@@ -1,473 +0,0 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h, g as getElement } from './index.esm2.js';
|
|
2
|
-
import { s as sendAnalytics } from './analytics-44b1416b.esm.js';
|
|
3
|
-
import { p as parseData } from './sharedUtils-a550989c.esm.js';
|
|
4
|
-
import 'react';
|
|
5
|
-
import 'react/jsx-runtime';
|
|
6
|
-
import 'react-dom';
|
|
7
|
-
|
|
8
|
-
// utils/validators.ts
|
|
9
|
-
function validateField(name, value, type, required, maxLength) {
|
|
10
|
-
const errors = [];
|
|
11
|
-
if (required && !value) {
|
|
12
|
-
errors.push(`${name} is required.`);
|
|
13
|
-
}
|
|
14
|
-
if (maxLength && typeof value === 'string' && value.length > maxLength) {
|
|
15
|
-
errors.push(`${name} must be at most ${maxLength} characters.`);
|
|
16
|
-
}
|
|
17
|
-
if (type === 'email' && value && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.toString())) {
|
|
18
|
-
errors.push('Invalid email format.');
|
|
19
|
-
}
|
|
20
|
-
return errors;
|
|
21
|
-
}
|
|
22
|
-
function validateFieldGroup(name, required, formEl) {
|
|
23
|
-
// Find all eds-input-field components that contain inputs with the given name.
|
|
24
|
-
const groupFields = Array.from(formEl.querySelectorAll('eds-input-field')).filter(edsField => {
|
|
25
|
-
var _a, _b;
|
|
26
|
-
return ((_b = (_a = edsField.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`input[name="${name}"]`)) === null || _b === void 0 ? void 0 : _b.length) > 0;
|
|
27
|
-
});
|
|
28
|
-
// Collect all input elements with the matching name inside those components.
|
|
29
|
-
const groupElements = groupFields.flatMap(edsField => {
|
|
30
|
-
var _a;
|
|
31
|
-
return Array.from(((_a = edsField.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`input[name="${name}"]`)) || []);
|
|
32
|
-
});
|
|
33
|
-
// Check if at least one input is checked.
|
|
34
|
-
const isChecked = groupElements.some(el => el.checked);
|
|
35
|
-
const errors = [];
|
|
36
|
-
if (required && !isChecked) {
|
|
37
|
-
errors.push(`At least one option in ${name} is required.`);
|
|
38
|
-
}
|
|
39
|
-
return errors;
|
|
40
|
-
}
|
|
41
|
-
function validateSingleBox(name, required, formEl) {
|
|
42
|
-
var _a;
|
|
43
|
-
const errors = [];
|
|
44
|
-
// Find the eds-input-field component containing the input with the given name.
|
|
45
|
-
const edsField = Array.from(formEl.querySelectorAll('eds-input-field')).find(field => {
|
|
46
|
-
var _a;
|
|
47
|
-
return (_a = field.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[name="${name}"]`);
|
|
48
|
-
});
|
|
49
|
-
// If no such field is found and it's required, return an error.
|
|
50
|
-
if (!edsField) {
|
|
51
|
-
if (required) {
|
|
52
|
-
errors.push(`${name} is required.`);
|
|
53
|
-
}
|
|
54
|
-
return errors;
|
|
55
|
-
}
|
|
56
|
-
// Query within the component's shadow root.
|
|
57
|
-
const inputEl = (_a = edsField.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[name="${name}"]`);
|
|
58
|
-
if (required && inputEl && !inputEl.checked) {
|
|
59
|
-
errors.push(`${name} is required.`);
|
|
60
|
-
}
|
|
61
|
-
return errors;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Finds the first input element for a given field name inside eds-input-field components.
|
|
66
|
-
*/
|
|
67
|
-
function findFieldElement(formEl, name) {
|
|
68
|
-
const elements = Array.from(formEl.querySelectorAll('eds-input-field'));
|
|
69
|
-
for (const element of elements) {
|
|
70
|
-
if (element.shadowRoot) {
|
|
71
|
-
const input = element.shadowRoot.querySelector(`[name="${name}"]`);
|
|
72
|
-
if (input) {
|
|
73
|
-
return input;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Validates all fields and returns an object containing the errors and a flag indicating any errors.
|
|
81
|
-
*/
|
|
82
|
-
function validateFormFields(parsedFields, formEl, values,
|
|
83
|
-
// eslint-disable-next-line
|
|
84
|
-
isFieldVisible) {
|
|
85
|
-
const errors = {};
|
|
86
|
-
let hasError = false;
|
|
87
|
-
parsedFields.forEach(field => {
|
|
88
|
-
// Only validate fields that are visible.
|
|
89
|
-
if (!isFieldVisible(field, values)) {
|
|
90
|
-
// If a field is hidden, clear its error.
|
|
91
|
-
delete errors[field.name];
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
if (field.type !== 'hidden') {
|
|
95
|
-
if ((field.type === 'checkbox' || field.type === 'radio') && !field.options) {
|
|
96
|
-
// Single checkbox or radio without multiple options
|
|
97
|
-
const fieldErrors = validateSingleBox(field.name, field.required, formEl);
|
|
98
|
-
if (fieldErrors.length > 0) {
|
|
99
|
-
errors[field.name] = fieldErrors;
|
|
100
|
-
hasError = true;
|
|
101
|
-
}
|
|
102
|
-
} else if (field.options && (field.type === 'checkbox' || field.type === 'radio')) {
|
|
103
|
-
// Checkbox or radio group with options
|
|
104
|
-
const fieldErrors = validateFieldGroup(field.name, field.required, formEl);
|
|
105
|
-
if (fieldErrors.length > 0) {
|
|
106
|
-
errors[field.name] = fieldErrors;
|
|
107
|
-
hasError = true;
|
|
108
|
-
}
|
|
109
|
-
} else {
|
|
110
|
-
// For all other types, find the first matching element.
|
|
111
|
-
const inputEl = findFieldElement(formEl, field.name);
|
|
112
|
-
if (inputEl) {
|
|
113
|
-
const value = inputEl.value;
|
|
114
|
-
const fieldErrors = validateField(field.name, value, field.type, field.required, field.maxlength);
|
|
115
|
-
if (fieldErrors.length > 0) {
|
|
116
|
-
errors[field.name] = fieldErrors;
|
|
117
|
-
hasError = true;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
return {
|
|
124
|
-
errors,
|
|
125
|
-
hasError
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Validates a field based on its type and returns an array of error messages.
|
|
131
|
-
* @param field - The field configuration object.
|
|
132
|
-
* @param value - The input value (if applicable).
|
|
133
|
-
* @param formEl - The form element used for DOM queries.
|
|
134
|
-
*/
|
|
135
|
-
function validateInputField(field, value, formEl) {
|
|
136
|
-
if (field.type === 'checkbox' || field.type === 'radio') {
|
|
137
|
-
if (field.options) {
|
|
138
|
-
return validateFieldGroup(field.name, field.required, formEl);
|
|
139
|
-
}
|
|
140
|
-
return validateSingleBox(field.name, field.required, formEl);
|
|
141
|
-
}
|
|
142
|
-
return validateField(field.name, value, field.type, field.required, field.maxlength);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Updates state values based on draft data and, after a delay, updates the corresponding DOM inputs.
|
|
147
|
-
*/
|
|
148
|
-
function getFormInitData({
|
|
149
|
-
initData,
|
|
150
|
-
parsedFields,
|
|
151
|
-
currentValues,
|
|
152
|
-
formEl,
|
|
153
|
-
isFieldVisible
|
|
154
|
-
}) {
|
|
155
|
-
// Pass 1: Update state for all fields.
|
|
156
|
-
const updatedValues = Object.assign({}, currentValues);
|
|
157
|
-
parsedFields.forEach(field => {
|
|
158
|
-
const value = initData[field.name];
|
|
159
|
-
if (value !== undefined) {
|
|
160
|
-
updatedValues[field.name] = value;
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
// Pass 2: Delay DOM updates to ensure nested fields are rendered.
|
|
164
|
-
setTimeout(() => {
|
|
165
|
-
parsedFields.forEach(field => {
|
|
166
|
-
// Only update if the field is visible.
|
|
167
|
-
if (isFieldVisible(field, updatedValues)) {
|
|
168
|
-
const value = initData[field.name];
|
|
169
|
-
if (value !== undefined) {
|
|
170
|
-
if (field.type === 'checkbox' || field.type === 'radio') {
|
|
171
|
-
// Query all eds-input-field components and update matching inputs.
|
|
172
|
-
const elements = Array.from(formEl.querySelectorAll('eds-input-field'));
|
|
173
|
-
elements.forEach(element => {
|
|
174
|
-
if (element.shadowRoot) {
|
|
175
|
-
const inputs = Array.from(element.shadowRoot.querySelectorAll(`[name="${field.name}"]`));
|
|
176
|
-
// Convert stored comma-separated value into a trimmed array.
|
|
177
|
-
const valuesArray = value.split(',').map(v => v.trim());
|
|
178
|
-
inputs.forEach(inputEl => {
|
|
179
|
-
// eslint-disable-next-line
|
|
180
|
-
inputEl.checked = valuesArray.includes(inputEl.value);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
} else {
|
|
185
|
-
// For non-checkbox/radio inputs, update the first matching element using findFieldElement.
|
|
186
|
-
const inputEl = findFieldElement(formEl, field.name);
|
|
187
|
-
if (inputEl) {
|
|
188
|
-
inputEl.value = value;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
}, 50); // A 50ms delay to allow re-render
|
|
195
|
-
return {
|
|
196
|
-
updatedValues
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
const edsFormCss = ".mt-20{margin-top:1.25rem}";
|
|
200
|
-
const EdsFormStyle0 = edsFormCss;
|
|
201
|
-
const EdsForm = class {
|
|
202
|
-
constructor(hostRef) {
|
|
203
|
-
registerInstance(this, hostRef);
|
|
204
|
-
this.form = createEvent(this, "form", 7);
|
|
205
|
-
this.name = 'eds-form';
|
|
206
|
-
this.setFormUrl = true;
|
|
207
|
-
this.formBtn = true;
|
|
208
|
-
this.formBtnLabel = 'Submit';
|
|
209
|
-
this.errorMessage = 'Some fields in your form are incorrect.';
|
|
210
|
-
this.fields = [];
|
|
211
|
-
this.initData = {};
|
|
212
|
-
this.values = {};
|
|
213
|
-
this.isSubmitting = false;
|
|
214
|
-
this.hasError = false;
|
|
215
|
-
this.errors = {};
|
|
216
|
-
this.parsedFields = [];
|
|
217
|
-
}
|
|
218
|
-
componentWillLoad() {
|
|
219
|
-
this.parseFields(this.fields);
|
|
220
|
-
// Emit context for each eds-link element after the component is fully loaded
|
|
221
|
-
const links = this.el.querySelectorAll('eds-button');
|
|
222
|
-
links.forEach(link => {
|
|
223
|
-
this.emitContext(link);
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
componentDidLoad() {
|
|
227
|
-
if (this.shouldFormProcessInitData) {
|
|
228
|
-
this.populateFormWithInitData(this.initData);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
get shouldFormProcessInitData() {
|
|
232
|
-
var _a;
|
|
233
|
-
return !!((_a = this.initData) === null || _a === void 0 ? void 0 : _a._id);
|
|
234
|
-
}
|
|
235
|
-
parseFields(newValue) {
|
|
236
|
-
this.parsedFields = parseData(newValue);
|
|
237
|
-
}
|
|
238
|
-
emitContext(linkElement) {
|
|
239
|
-
const event = new CustomEvent('parentContext', {
|
|
240
|
-
detail: {
|
|
241
|
-
componentName: this.el.tagName.toLowerCase(),
|
|
242
|
-
identifier: null
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
linkElement.dispatchEvent(event);
|
|
246
|
-
}
|
|
247
|
-
isFieldVisible(field) {
|
|
248
|
-
if (!field.condition) {
|
|
249
|
-
return true;
|
|
250
|
-
}
|
|
251
|
-
const parentValue = this.values[field.condition.field];
|
|
252
|
-
return parentValue === field.condition.value;
|
|
253
|
-
}
|
|
254
|
-
validateForm() {
|
|
255
|
-
const {
|
|
256
|
-
errors,
|
|
257
|
-
hasError
|
|
258
|
-
} = validateFormFields(this.parsedFields, this.formEl, this.values, (field, values) => {
|
|
259
|
-
if (!field.condition) {
|
|
260
|
-
return true;
|
|
261
|
-
}
|
|
262
|
-
const parentValue = values[field.condition.field];
|
|
263
|
-
return parentValue === field.condition.value;
|
|
264
|
-
});
|
|
265
|
-
this.errors = errors;
|
|
266
|
-
this.hasError = hasError;
|
|
267
|
-
}
|
|
268
|
-
populateFormWithInitData(initData) {
|
|
269
|
-
const {
|
|
270
|
-
updatedValues
|
|
271
|
-
} = getFormInitData({
|
|
272
|
-
initData,
|
|
273
|
-
parsedFields: this.parsedFields,
|
|
274
|
-
currentValues: this.values,
|
|
275
|
-
formEl: this.formEl,
|
|
276
|
-
isFieldVisible: (field, values) => {
|
|
277
|
-
if (!field.condition) {
|
|
278
|
-
return true;
|
|
279
|
-
}
|
|
280
|
-
const parentValue = values[field.condition.field];
|
|
281
|
-
return parentValue === field.condition.value;
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
this.values = updatedValues;
|
|
285
|
-
}
|
|
286
|
-
getFormData() {
|
|
287
|
-
const formData = new FormData();
|
|
288
|
-
// Add the form name
|
|
289
|
-
formData.append('form_name', this.name);
|
|
290
|
-
// Add the form URL
|
|
291
|
-
if (this.setFormUrl && typeof window !== 'undefined') {
|
|
292
|
-
formData.set('form_url', window.location.href);
|
|
293
|
-
}
|
|
294
|
-
// Get all input elements within `eds-input-field`
|
|
295
|
-
const elements = Array.from(this.formEl.querySelectorAll('eds-input-field'));
|
|
296
|
-
elements.forEach(element => {
|
|
297
|
-
if (element.shadowRoot) {
|
|
298
|
-
// Get input/textarea/select from the shadow DOM
|
|
299
|
-
const input = element.shadowRoot.querySelector('input, textarea, select');
|
|
300
|
-
if (input && input.name) {
|
|
301
|
-
if (input.type === 'checkbox' || input.type === 'radio') {
|
|
302
|
-
// Handle checkboxes and radio buttons
|
|
303
|
-
const checkboxes = Array.from(element.shadowRoot.querySelectorAll(`input[name="${input.name}"]:checked`));
|
|
304
|
-
const values = checkboxes.map(checkbox => checkbox.value);
|
|
305
|
-
formData.append(input.name, values.join(',')); // Join multiple values with a comma
|
|
306
|
-
} else if (input.type === 'file') {
|
|
307
|
-
// Handle file uploads.
|
|
308
|
-
const fileInput = input;
|
|
309
|
-
if (fileInput.files && fileInput.files.length > 0) {
|
|
310
|
-
// If multiple files are allowed, you can append them all.
|
|
311
|
-
Array.from(fileInput.files).forEach(file => {
|
|
312
|
-
// You can either append each file under the same name (if your backend expects an array)
|
|
313
|
-
// or you can give them unique names. Here we use the same name.
|
|
314
|
-
formData.append(fileInput.name, file);
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
} else {
|
|
318
|
-
// Handle other input types
|
|
319
|
-
formData.append(input.name, input.value);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
return formData;
|
|
325
|
-
}
|
|
326
|
-
handleChange(e, field) {
|
|
327
|
-
const target = e.target;
|
|
328
|
-
this.values = Object.assign(Object.assign({}, this.values), {
|
|
329
|
-
[field.name]: target.value
|
|
330
|
-
});
|
|
331
|
-
// Emit an input event with message and current form values
|
|
332
|
-
this.form.emit({
|
|
333
|
-
event: 'change',
|
|
334
|
-
field: field.name,
|
|
335
|
-
value: target.value,
|
|
336
|
-
message: `${field.name} updated`,
|
|
337
|
-
data: this.getFormData()
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
handleInput(e, field) {
|
|
341
|
-
const target = e.target;
|
|
342
|
-
// Update the field's value in state.
|
|
343
|
-
this.values = Object.assign(Object.assign({}, this.values), {
|
|
344
|
-
[field.name]: target.value
|
|
345
|
-
});
|
|
346
|
-
// Create a copy of the current errors.
|
|
347
|
-
const newErrors = Object.assign({}, this.errors);
|
|
348
|
-
// Use the utility to validate the field.
|
|
349
|
-
const fieldErrors = validateInputField(field, target.value, this.formEl);
|
|
350
|
-
if (fieldErrors.length > 0) {
|
|
351
|
-
newErrors[field.name] = fieldErrors;
|
|
352
|
-
} else {
|
|
353
|
-
delete newErrors[field.name];
|
|
354
|
-
}
|
|
355
|
-
// Update the errors state and the hasError flag.
|
|
356
|
-
this.errors = newErrors;
|
|
357
|
-
this.hasError = Object.keys(newErrors).length > 0;
|
|
358
|
-
}
|
|
359
|
-
handleSubmit() {
|
|
360
|
-
var _a, _b;
|
|
361
|
-
if (this.isSubmitting) {
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
this.isSubmitting = true;
|
|
365
|
-
this.validateForm();
|
|
366
|
-
if (this.hasError) {
|
|
367
|
-
this.form.emit({
|
|
368
|
-
event: 'submit',
|
|
369
|
-
validated: false,
|
|
370
|
-
success: false,
|
|
371
|
-
message: this.errorMessage,
|
|
372
|
-
data: this.getFormData()
|
|
373
|
-
}); // Emit form status submit false validation error
|
|
374
|
-
sendAnalytics({
|
|
375
|
-
category: 'ui-component',
|
|
376
|
-
parentContext: null,
|
|
377
|
-
tag: this.el.tagName.toLowerCase(),
|
|
378
|
-
name: `${(_a = this.formBtnLabel) === null || _a === void 0 ? void 0 : _a.toLowerCase()}/non-validated` || '',
|
|
379
|
-
action: 'click'
|
|
380
|
-
});
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
// Log each entry in FormData to see file details
|
|
384
|
-
/*formData.forEach((value, key) => {
|
|
385
|
-
if (value instanceof File) {
|
|
386
|
-
console.log(`File field: ${key}, File name: ${value.name}, File size: ${value.size}`);
|
|
387
|
-
} else {
|
|
388
|
-
console.log(`Field: ${key}, Value: ${value}`);
|
|
389
|
-
}
|
|
390
|
-
});*/
|
|
391
|
-
this.form.emit({
|
|
392
|
-
event: 'submit',
|
|
393
|
-
success: true,
|
|
394
|
-
validated: true,
|
|
395
|
-
message: 'Form data validated successfully',
|
|
396
|
-
data: this.getFormData()
|
|
397
|
-
});
|
|
398
|
-
sendAnalytics({
|
|
399
|
-
category: 'ui-component',
|
|
400
|
-
parentContext: null,
|
|
401
|
-
tag: this.el.tagName.toLowerCase(),
|
|
402
|
-
name: `${(_b = this.formBtnLabel) === null || _b === void 0 ? void 0 : _b.toLowerCase()}/validated` || '',
|
|
403
|
-
action: 'click'
|
|
404
|
-
});
|
|
405
|
-
// Reset form states
|
|
406
|
-
this.errors = {};
|
|
407
|
-
this.formEl.reset();
|
|
408
|
-
this.isSubmitting = false;
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
render() {
|
|
412
|
-
const hiddenFields = this.parsedFields.filter(field => field.type === 'hidden');
|
|
413
|
-
const otherFields = this.parsedFields.filter(field => field.type !== 'hidden');
|
|
414
|
-
return h("form", {
|
|
415
|
-
key: '695438941134ef6a3c43b70008b1904b03700743',
|
|
416
|
-
ref: el => this.formEl = el,
|
|
417
|
-
autocomplete: "on",
|
|
418
|
-
onSubmit: this.handleSubmit
|
|
419
|
-
}, h("div", {
|
|
420
|
-
key: '870ff661aded11c890e4f144a970c5ab5120a61f'
|
|
421
|
-
}, h("slot", {
|
|
422
|
-
key: 'b1070ccc8984afe457d28a6bbf52255dcbbc9b33'
|
|
423
|
-
}), hiddenFields.map((field, index) => h("eds-input", {
|
|
424
|
-
key: index,
|
|
425
|
-
type: "hidden",
|
|
426
|
-
name: field.name,
|
|
427
|
-
value: field.value
|
|
428
|
-
})), otherFields.map((field, index) => {
|
|
429
|
-
var _a, _b;
|
|
430
|
-
if (!this.isFieldVisible(field)) {
|
|
431
|
-
return null;
|
|
432
|
-
}
|
|
433
|
-
return h("eds-input-field", {
|
|
434
|
-
key: index,
|
|
435
|
-
name: field.name,
|
|
436
|
-
id: `${this.name}_${field.name}`,
|
|
437
|
-
label: field.label,
|
|
438
|
-
type: field.type,
|
|
439
|
-
icon: field.icon || null,
|
|
440
|
-
required: field.required,
|
|
441
|
-
maxLength: field.maxlength,
|
|
442
|
-
hint: field.hint,
|
|
443
|
-
error: ((_a = this.errors[field.name]) === null || _a === void 0 ? void 0 : _a.length) > 0,
|
|
444
|
-
errorMessage: (_b = this.errors[field.name]) === null || _b === void 0 ? void 0 : _b.join('<br />'),
|
|
445
|
-
onInput: e => this.handleInput(e, field),
|
|
446
|
-
onChange: e => this.handleChange(e, field),
|
|
447
|
-
class: index > 0 ? 'mt-20' : '',
|
|
448
|
-
options: field.options
|
|
449
|
-
});
|
|
450
|
-
})), this.formBtn && h("div", {
|
|
451
|
-
key: '80e0af076f3c57124f8a1f6718a0d45cfd45c0cd',
|
|
452
|
-
class: "mt-20"
|
|
453
|
-
}, h("eds-button", {
|
|
454
|
-
key: '51dd28fb2a6610983e50ddb60409b3acf18dba1b',
|
|
455
|
-
intent: "primary",
|
|
456
|
-
label: this.formBtnLabel,
|
|
457
|
-
disabled: this.isSubmitting,
|
|
458
|
-
loading: this.isSubmitting,
|
|
459
|
-
onClick: () => this.handleSubmit()
|
|
460
|
-
})));
|
|
461
|
-
}
|
|
462
|
-
get el() {
|
|
463
|
-
return getElement(this);
|
|
464
|
-
}
|
|
465
|
-
static get watchers() {
|
|
466
|
-
return {
|
|
467
|
-
"fields": ["parseFields"]
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
};
|
|
471
|
-
EdsForm.style = EdsFormStyle0;
|
|
472
|
-
|
|
473
|
-
export { EdsForm as eds_form };
|