@sebgroup/green-core 3.4.0 → 3.5.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.
- package/components/form-summary/summary.component.d.ts +4 -2
- package/components/form-summary/summary.component.js +116 -55
- package/components/form-summary/summary.styles.js +16 -2
- package/custom-elements.json +35176 -35136
- package/gds-element.js +1 -1
- package/generated/locales/da.d.ts +1 -1
- package/generated/locales/da.js +1 -1
- package/generated/locales/de.d.ts +1 -1
- package/generated/locales/de.js +1 -1
- package/generated/locales/fi.d.ts +1 -1
- package/generated/locales/fi.js +1 -1
- package/generated/locales/fr.d.ts +1 -1
- package/generated/locales/fr.js +1 -1
- package/generated/locales/it.d.ts +1 -1
- package/generated/locales/it.js +1 -1
- package/generated/locales/nl.d.ts +1 -1
- package/generated/locales/nl.js +1 -1
- package/generated/locales/no.d.ts +1 -1
- package/generated/locales/no.js +1 -1
- package/generated/locales/sv.d.ts +1 -1
- package/generated/locales/sv.js +1 -1
- package/generated/mcp/components.json +1 -1
- package/generated/mcp/form-summary/angular.md +3 -1
- package/generated/mcp/form-summary/api.md +9 -2
- package/generated/mcp/form-summary/react.md +3 -1
- package/generated/mcp/icons.json +1 -1
- package/generated/mcp/index.json +1 -1
- package/generated/mcp/tokens.json +1 -1
- package/generated/react/index.d.ts +2 -2
- package/generated/react/index.js +2 -2
- package/package.json +1 -1
- package/utils/helpers/custom-element-scoping.js +1 -1
|
@@ -6,12 +6,14 @@ import { GdsElement } from '../../gds-element';
|
|
|
6
6
|
* When a user attempts to submit a form with errors, this component displays a summary of those errors.
|
|
7
7
|
* Including an error summary greatly assists users in promptly identifying and addressing multiple errors
|
|
8
8
|
* in a consolidated manner. It provides a clear indication of what went wrong and what needs to be corrected.
|
|
9
|
+
*
|
|
10
|
+
* @slot header - Optional slot for customizing the header of the summary.
|
|
9
11
|
*/
|
|
10
12
|
export declare class GdsFormSummary extends GdsElement {
|
|
11
13
|
#private;
|
|
12
14
|
static styles: (import("lit").CSSResult | import("lit").CSSResult[])[];
|
|
13
15
|
/**
|
|
14
|
-
*
|
|
16
|
+
* @deprecated This no longer has any effect, and will be removed in a future release.
|
|
15
17
|
*/
|
|
16
18
|
hideErrors: boolean;
|
|
17
19
|
/**
|
|
@@ -35,7 +37,7 @@ export declare class GdsFormSummary extends GdsElement {
|
|
|
35
37
|
connectedCallback(): void;
|
|
36
38
|
disconnectedCallback(): void;
|
|
37
39
|
/**
|
|
38
|
-
* Refresh the component to
|
|
40
|
+
* Refresh the component to reflect the current state of the form.
|
|
39
41
|
*/
|
|
40
42
|
refresh(): void;
|
|
41
43
|
render(): any;
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
__privateMethod,
|
|
6
6
|
__privateSet
|
|
7
7
|
} from "../../chunks/chunk.CAV4X6PU.js";
|
|
8
|
-
var _form, _formObserver, _getFormControls, getFormControls_fn, _getErrorControls, getErrorControls_fn, _renderArrowIcon, renderArrowIcon_fn;
|
|
8
|
+
var _form, _formObserver, _renderControlItem, renderControlItem_fn, _groupByFieldset, groupByFieldset_fn, _getFormControls, getFormControls_fn, _getErrorControls, getErrorControls_fn, _renderArrowIcon, renderArrowIcon_fn;
|
|
9
9
|
import { msg, str } from "@lit/localize";
|
|
10
10
|
import { nothing } from "lit";
|
|
11
11
|
import { property, queryAsync } from "lit/decorators.js";
|
|
@@ -14,15 +14,19 @@ import { when } from "lit/directives/when.js";
|
|
|
14
14
|
import { GdsElement } from "../../gds-element.js";
|
|
15
15
|
import { gdsCustomElement, html } from "../../scoping.js";
|
|
16
16
|
import { tokens } from "../../tokens.style.js";
|
|
17
|
+
import { GdsAlert } from "../alert/alert.component.js";
|
|
17
18
|
import { GdsButton } from "../button/button.component.js";
|
|
18
19
|
import { GdsCard } from "../card/card.component.js";
|
|
19
20
|
import { GdsDiv } from "../div/div.component.js";
|
|
20
21
|
import { GdsFlex } from "../flex/flex.component.js";
|
|
21
22
|
import { IconArrowUp } from "../icon/icons/arrow-up.component.js";
|
|
23
|
+
import { GdsText } from "../text/text.component.js";
|
|
22
24
|
import SummaryStyles from "./summary.styles.js";
|
|
23
25
|
let GdsFormSummary = class extends GdsElement {
|
|
24
26
|
constructor() {
|
|
25
27
|
super(...arguments);
|
|
28
|
+
__privateAdd(this, _renderControlItem);
|
|
29
|
+
__privateAdd(this, _groupByFieldset);
|
|
26
30
|
__privateAdd(this, _getFormControls);
|
|
27
31
|
__privateAdd(this, _getErrorControls);
|
|
28
32
|
__privateAdd(this, _renderArrowIcon);
|
|
@@ -70,75 +74,62 @@ let GdsFormSummary = class extends GdsElement {
|
|
|
70
74
|
__privateGet(this, _formObserver)?.disconnect();
|
|
71
75
|
}
|
|
72
76
|
/**
|
|
73
|
-
* Refresh the component to
|
|
77
|
+
* Refresh the component to reflect the current state of the form.
|
|
74
78
|
*/
|
|
75
79
|
refresh() {
|
|
76
80
|
this.requestUpdate();
|
|
77
81
|
}
|
|
78
82
|
render() {
|
|
79
83
|
const formControls = __privateMethod(this, _getFormControls, getFormControls_fn).call(this);
|
|
80
|
-
const
|
|
84
|
+
const errorCount = __privateMethod(this, _getErrorControls, getErrorControls_fn).call(this).length;
|
|
85
|
+
const groupedControls = __privateMethod(this, _groupByFieldset, groupByFieldset_fn).call(this, formControls);
|
|
81
86
|
return when(
|
|
82
|
-
|
|
87
|
+
errorCount > 0,
|
|
83
88
|
() => html`<gds-card
|
|
84
89
|
id="root"
|
|
85
90
|
role="navigation"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
padding="xs"
|
|
92
|
+
background="neutral-02"
|
|
93
|
+
border-color="negative-01"
|
|
94
|
+
border-radius="m"
|
|
90
95
|
overflow="hidden"
|
|
91
96
|
aria-describedby="description"
|
|
92
97
|
aria-label=${msg(`Form error summary`)}
|
|
93
98
|
>
|
|
94
99
|
<gds-flex gap="0" flex-direction="column">
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
<slot name="header">
|
|
101
|
+
<gds-alert
|
|
102
|
+
variant="negative"
|
|
103
|
+
label=${msg(
|
|
104
|
+
str`There are errors to correct before you can continue`
|
|
98
105
|
)}
|
|
99
|
-
|
|
106
|
+
>
|
|
107
|
+
${msg(str`There are errors to correct before you can continue`)}
|
|
108
|
+
</gds-alert>
|
|
109
|
+
</slot>
|
|
100
110
|
<ul>
|
|
101
|
-
${
|
|
102
|
-
(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
level="3"
|
|
111
|
-
color="negative-01"
|
|
112
|
-
background="transparent; hover: negative-01/.1"
|
|
113
|
-
style="cursor: pointer"
|
|
114
|
-
border-width="0"
|
|
115
|
-
border-radius="xs"
|
|
116
|
-
margin="0 -xs"
|
|
117
|
-
@click=${(e) => {
|
|
118
|
-
e.preventDefault();
|
|
119
|
-
el.focus();
|
|
120
|
-
}}
|
|
111
|
+
${groupedControls.map(
|
|
112
|
+
(entry) => when(
|
|
113
|
+
entry.fieldset,
|
|
114
|
+
// Render fieldset groups with legends if they exist
|
|
115
|
+
() => html`<li
|
|
116
|
+
class="group"
|
|
117
|
+
?inert=${!entry.controls.some(
|
|
118
|
+
(el) => el.ariaInvalid === "true" || el.invalid
|
|
119
|
+
)}
|
|
121
120
|
>
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
>${el.dataset.label || el.label || el.ariaLabel}</gds-div
|
|
125
|
-
>
|
|
126
|
-
${when(
|
|
127
|
-
!this.hideErrors,
|
|
128
|
-
() => html`<gds-div font="body-s-regular">
|
|
129
|
-
${el.dataset.errormessage || el.errorMessage || el.ariaErrorMessage}
|
|
130
|
-
</gds-div>`
|
|
131
|
-
)}
|
|
132
|
-
</div>
|
|
133
|
-
<gds-button
|
|
134
|
-
size="small"
|
|
135
|
-
variant="negative"
|
|
136
|
-
label=${`Move focus to ${el.label} field`}
|
|
121
|
+
<gds-text tag="span" font="heading-s" margin="0 s xs"
|
|
122
|
+
>${entry.legend}</gds-text
|
|
137
123
|
>
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
124
|
+
<ul>
|
|
125
|
+
${entry.controls.map(
|
|
126
|
+
(el) => __privateMethod(this, _renderControlItem, renderControlItem_fn).call(this, el)
|
|
127
|
+
)}
|
|
128
|
+
</ul>
|
|
129
|
+
</li>`,
|
|
130
|
+
// Render standalone controls without a fieldset
|
|
131
|
+
() => entry.controls.map((el) => __privateMethod(this, _renderControlItem, renderControlItem_fn).call(this, el))
|
|
132
|
+
)
|
|
142
133
|
)}
|
|
143
134
|
</ul>
|
|
144
135
|
</gds-flex>
|
|
@@ -148,12 +139,70 @@ let GdsFormSummary = class extends GdsElement {
|
|
|
148
139
|
};
|
|
149
140
|
_form = new WeakMap();
|
|
150
141
|
_formObserver = new WeakMap();
|
|
142
|
+
_renderControlItem = new WeakSet();
|
|
143
|
+
renderControlItem_fn = function(el) {
|
|
144
|
+
return html`<li
|
|
145
|
+
class="item"
|
|
146
|
+
?inert=${!(el.ariaInvalid === "true" || el.invalid)}
|
|
147
|
+
>
|
|
148
|
+
<gds-card
|
|
149
|
+
display="flex"
|
|
150
|
+
flex-direction="row"
|
|
151
|
+
align-items="center"
|
|
152
|
+
justify-content="space-between"
|
|
153
|
+
gap="xs"
|
|
154
|
+
level="3"
|
|
155
|
+
background="transparent; hover: neutral-02"
|
|
156
|
+
style="cursor: pointer"
|
|
157
|
+
border-width="0"
|
|
158
|
+
border-radius="xs"
|
|
159
|
+
padding="xs s"
|
|
160
|
+
@click=${(e) => {
|
|
161
|
+
e.preventDefault();
|
|
162
|
+
el.focus();
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
<div>
|
|
166
|
+
<gds-div font-weight="book"
|
|
167
|
+
>${el.dataset.label || el.label || el.ariaLabel}</gds-div
|
|
168
|
+
>
|
|
169
|
+
</div>
|
|
170
|
+
<gds-button
|
|
171
|
+
size="xs"
|
|
172
|
+
rank="secondary"
|
|
173
|
+
label=${`Move focus to ${el.label} field`}
|
|
174
|
+
>
|
|
175
|
+
${until(__privateMethod(this, _renderArrowIcon, renderArrowIcon_fn).call(this, el), nothing)}
|
|
176
|
+
</gds-button>
|
|
177
|
+
</gds-card>
|
|
178
|
+
</li>`;
|
|
179
|
+
};
|
|
180
|
+
_groupByFieldset = new WeakSet();
|
|
181
|
+
groupByFieldset_fn = function(controls) {
|
|
182
|
+
const groups = [];
|
|
183
|
+
for (const el of controls) {
|
|
184
|
+
const fieldset = el.closest("fieldset");
|
|
185
|
+
if (!fieldset) {
|
|
186
|
+
groups.push({ fieldset: null, legend: "", controls: [el] });
|
|
187
|
+
} else {
|
|
188
|
+
let group = groups.find((g) => g.fieldset === fieldset);
|
|
189
|
+
if (!group) {
|
|
190
|
+
const legend = fieldset.querySelector("legend")?.textContent?.trim() || "";
|
|
191
|
+
group = { fieldset, legend, controls: [] };
|
|
192
|
+
groups.push(group);
|
|
193
|
+
}
|
|
194
|
+
group.controls.push(el);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return groups;
|
|
198
|
+
};
|
|
151
199
|
_getFormControls = new WeakSet();
|
|
152
200
|
getFormControls_fn = function() {
|
|
153
201
|
return Array.from(__privateGet(this, _form)?.elements || []).filter(
|
|
154
202
|
// Individual checkboxes can be used as form controls, but they don't support error messages,
|
|
155
203
|
// so we filter them out here. Checkboxes needs to be wrapped in a group to work with form summary.
|
|
156
|
-
|
|
204
|
+
// Fieldsets are also listed in form.elements but are not actual controls.
|
|
205
|
+
(el) => el.gdsElementName !== "gds-checkbox" && el.tagName !== "FIELDSET"
|
|
157
206
|
);
|
|
158
207
|
};
|
|
159
208
|
_getErrorControls = new WeakSet();
|
|
@@ -167,9 +216,13 @@ renderArrowIcon_fn = async function(el) {
|
|
|
167
216
|
const selfTop = (await this._elRoot).getBoundingClientRect().top;
|
|
168
217
|
const elTop = el.getBoundingClientRect().top;
|
|
169
218
|
const isAbove = elTop < selfTop;
|
|
170
|
-
return
|
|
219
|
+
return when(
|
|
220
|
+
isAbove,
|
|
221
|
+
() => html`<gds-icon-arrow-up></gds-icon-arrow-up>`,
|
|
222
|
+
() => html`<gds-icon-arrow-up
|
|
171
223
|
style="transform: rotate(180deg)"
|
|
172
|
-
></gds-icon-arrow-up
|
|
224
|
+
></gds-icon-arrow-up>`
|
|
225
|
+
);
|
|
173
226
|
};
|
|
174
227
|
GdsFormSummary.styles = [tokens, SummaryStyles];
|
|
175
228
|
__decorateClass([
|
|
@@ -183,7 +236,15 @@ __decorateClass([
|
|
|
183
236
|
], GdsFormSummary.prototype, "_elRoot", 2);
|
|
184
237
|
GdsFormSummary = __decorateClass([
|
|
185
238
|
gdsCustomElement("gds-form-summary", {
|
|
186
|
-
dependsOn: [
|
|
239
|
+
dependsOn: [
|
|
240
|
+
GdsCard,
|
|
241
|
+
GdsFlex,
|
|
242
|
+
GdsDiv,
|
|
243
|
+
GdsButton,
|
|
244
|
+
IconArrowUp,
|
|
245
|
+
GdsAlert,
|
|
246
|
+
GdsText
|
|
247
|
+
]
|
|
187
248
|
})
|
|
188
249
|
], GdsFormSummary);
|
|
189
250
|
export {
|
|
@@ -9,6 +9,9 @@ var summary_styles_default = css`
|
|
|
9
9
|
margin: 1rem 0 0;
|
|
10
10
|
padding: 0;
|
|
11
11
|
}
|
|
12
|
+
ul ul {
|
|
13
|
+
margin: 0;
|
|
14
|
+
}
|
|
12
15
|
li {
|
|
13
16
|
margin: 0;
|
|
14
17
|
transition:
|
|
@@ -16,14 +19,25 @@ var summary_styles_default = css`
|
|
|
16
19
|
opacity 0.3s ease-in-out,
|
|
17
20
|
margin 0.3s ease-in-out;
|
|
18
21
|
}
|
|
19
|
-
li[inert] {
|
|
22
|
+
li.item[inert] {
|
|
20
23
|
max-height: 0;
|
|
21
24
|
opacity: 0;
|
|
22
25
|
}
|
|
23
|
-
li:not([inert]) {
|
|
26
|
+
li.item:not([inert]) {
|
|
24
27
|
max-height: 4rem;
|
|
25
28
|
opacity: 1;
|
|
26
29
|
}
|
|
30
|
+
li.group[inert] {
|
|
31
|
+
max-height: 0;
|
|
32
|
+
opacity: 0;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
border-top-width: 0;
|
|
35
|
+
padding-top: 0;
|
|
36
|
+
margin-top: 0;
|
|
37
|
+
}
|
|
38
|
+
li.group:not([inert]) {
|
|
39
|
+
padding-top: var(--gds-sys-space-m);
|
|
40
|
+
}
|
|
27
41
|
a {
|
|
28
42
|
color: inherit;
|
|
29
43
|
}
|