@sebgroup/green-core 3.4.0 → 3.5.1

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 (36) hide show
  1. package/components/dialog/dialog.component.js +5 -3
  2. package/components/form-summary/summary.component.d.ts +4 -2
  3. package/components/form-summary/summary.component.js +116 -55
  4. package/components/form-summary/summary.styles.js +16 -2
  5. package/components/segmented-control/segmented-control.component.js +9 -4
  6. package/custom-elements.json +18942 -18902
  7. package/gds-element.js +1 -1
  8. package/generated/locales/da.d.ts +1 -1
  9. package/generated/locales/da.js +1 -1
  10. package/generated/locales/de.d.ts +1 -1
  11. package/generated/locales/de.js +1 -1
  12. package/generated/locales/fi.d.ts +1 -1
  13. package/generated/locales/fi.js +1 -1
  14. package/generated/locales/fr.d.ts +1 -1
  15. package/generated/locales/fr.js +1 -1
  16. package/generated/locales/it.d.ts +1 -1
  17. package/generated/locales/it.js +1 -1
  18. package/generated/locales/nl.d.ts +1 -1
  19. package/generated/locales/nl.js +1 -1
  20. package/generated/locales/no.d.ts +1 -1
  21. package/generated/locales/no.js +1 -1
  22. package/generated/locales/sv.d.ts +1 -1
  23. package/generated/locales/sv.js +1 -1
  24. package/generated/mcp/components.json +1 -1
  25. package/generated/mcp/form-summary/angular.md +3 -1
  26. package/generated/mcp/form-summary/api.md +9 -2
  27. package/generated/mcp/form-summary/guidelines.md +6 -2
  28. package/generated/mcp/form-summary/react.md +3 -1
  29. package/generated/mcp/icons.json +1 -1
  30. package/generated/mcp/index.json +1 -1
  31. package/generated/mcp/pagination/guidelines.md +16 -6
  32. package/generated/mcp/tokens.json +1 -1
  33. package/generated/react/index.d.ts +2 -2
  34. package/generated/react/index.js +2 -2
  35. package/package.json +1 -1
  36. package/utils/helpers/custom-element-scoping.js +1 -1
@@ -205,16 +205,17 @@ let GdsDialog = class extends withSizeXProps(
205
205
  >
206
206
  <gds-card
207
207
  class="card"
208
- padding="xl"
208
+ padding="0"
209
209
  variant="neutral-02"
210
210
  box-shadow="xl"
211
211
  border-radius="m"
212
212
  max-width="100%"
213
213
  border-width="0"
214
+ gap="0"
214
215
  @mousedown=${() => __privateSet(this, _clickStartedInside, true)}
215
216
  >
216
217
  <slot name="dialog">
217
- <gds-flex justify-content="space-between">
218
+ <gds-flex justify-content="space-between" padding="xl xl s xl">
218
219
  <h2 id="heading">${this.heading}</h2>
219
220
  <gds-button
220
221
  id="close-btn"
@@ -232,6 +233,7 @@ let GdsDialog = class extends withSizeXProps(
232
233
  <gds-div
233
234
  id="content"
234
235
  flex="1"
236
+ padding="s xl"
235
237
  overflow=${ifDefined(this.scrollable) ? "auto" : nothing}
236
238
  >
237
239
  <slot></slot>
@@ -240,7 +242,7 @@ let GdsDialog = class extends withSizeXProps(
240
242
  class="footer"
241
243
  justify-content="center"
242
244
  gap="s"
243
- padding="s 0 0 0"
245
+ padding="s xl xl xl"
244
246
  flex-wrap="wrap"
245
247
  >
246
248
  <slot name="footer">
@@ -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
- * Whether to hide the error messages under the labels.
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 reflext the current state of the form.
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 reflext the current state of the form.
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 errorControls = __privateMethod(this, _getErrorControls, getErrorControls_fn).call(this);
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
- errorControls.length > 0,
87
+ errorCount > 0,
83
88
  () => html`<gds-card
84
89
  id="root"
85
90
  role="navigation"
86
- variant="negative"
87
- padding="l"
88
- background="negative-01"
89
- color="negative-01"
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
- <gds-text font="heading-xs" font-weight="book" id="description">
96
- ${msg(
97
- str`There are ${errorControls.length} errors to correct before you can continue:`
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
- </gds-text>
106
+ >
107
+ ${msg(str`There are errors to correct before you can continue`)}
108
+ </gds-alert>
109
+ </slot>
100
110
  <ul>
101
- ${formControls.map(
102
- (el, idx) => html`<li ?inert=${!(el.ariaInvalid === "true" || el.invalid)}>
103
- <gds-card
104
- display="flex"
105
- padding="s"
106
- flex-direction="row"
107
- align-items="center"
108
- justify-content="space-between"
109
- gap="xs"
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
- <div id=${`error-label-${idx}`}>
123
- <gds-div font-weight="book"
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
- ${until(__privateMethod(this, _renderArrowIcon, renderArrowIcon_fn).call(this, el), nothing)}
139
- </gds-button>
140
- </gds-card>
141
- </li>`
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
- (el) => el.gdsElementName !== "gds-checkbox"
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 isAbove ? html`<gds-icon-arrow-up></gds-icon-arrow-up>` : html`<gds-icon-arrow-up
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: [GdsCard, GdsFlex, GdsDiv, GdsButton, IconArrowUp]
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
  }
@@ -100,10 +100,15 @@ let GdsSegmentedControl = class extends withLayoutChildProps(
100
100
  if (selectedSegment) {
101
101
  this.segments.forEach((s) => s.selected = false);
102
102
  selectedSegment.selected = true;
103
- selectedSegment.scrollIntoView({
104
- block: "nearest",
105
- inline: "nearest"
106
- });
103
+ const segOffsetLeft = selectedSegment.offsetLeft;
104
+ const segOffsetRight = segOffsetLeft + selectedSegment.offsetWidth;
105
+ const trackScrollLeft = this._elTrack.scrollLeft;
106
+ const trackWidth = this._elTrack.offsetWidth;
107
+ if (segOffsetLeft < trackScrollLeft) {
108
+ this._elTrack.scrollLeft = segOffsetLeft;
109
+ } else if (segOffsetRight > trackScrollLeft + trackWidth) {
110
+ this._elTrack.scrollLeft = segOffsetRight - trackWidth;
111
+ }
107
112
  }
108
113
  });
109
114
  });