@madgex/design-system 13.6.4 → 13.8.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 (33) hide show
  1. package/dist/assets/icons.json +1 -1
  2. package/dist/css/index.css +1 -1
  3. package/dist/js/index.js +1 -1
  4. package/package.json +1 -1
  5. package/src/components/inputs/_checkbox-elem/_template.njk +2 -0
  6. package/src/components/inputs/button-checkbox/_template.njk +2 -1
  7. package/src/components/inputs/button-checkbox/button-checkbox.njk +2 -1
  8. package/src/components/inputs/combobox/_template.njk +2 -0
  9. package/src/components/inputs/combobox/combobox.njk +2 -1
  10. package/src/components/inputs/file-upload/_template.njk +2 -0
  11. package/src/components/inputs/file-upload/file-upload.njk +2 -1
  12. package/src/components/inputs/input/_template.njk +2 -0
  13. package/src/components/inputs/input/input.njk +2 -1
  14. package/src/components/inputs/radio/_template.njk +3 -1
  15. package/src/components/inputs/radio/radio.njk +2 -1
  16. package/src/components/inputs/select/_template.njk +2 -0
  17. package/src/components/inputs/select/select.njk +2 -1
  18. package/src/components/inputs/single-checkbox/_template.njk +2 -1
  19. package/src/components/inputs/single-checkbox/single-checkbox.config.js +19 -0
  20. package/src/components/inputs/single-checkbox/single-checkbox.njk +2 -1
  21. package/src/components/inputs/text-editor/_template.njk +2 -0
  22. package/src/components/inputs/text-editor/text-editor.njk +2 -1
  23. package/src/components/inputs/textarea/_template.njk +2 -0
  24. package/src/components/inputs/textarea/textarea.njk +2 -1
  25. package/src/components/scroll-spy/README.md +34 -0
  26. package/src/components/scroll-spy/scroll-spy.js +127 -0
  27. package/src/components/scroll-spy/scroll-spy.njk +184 -0
  28. package/src/components/scroll-spy/scroll-spy.spec.js +462 -0
  29. package/src/js/index.js +4 -0
  30. package/src/scss/core/_lists.scss +21 -0
  31. package/src/scss/helpers/__index.scss +1 -0
  32. package/src/scss/helpers/_position.scss +4 -0
  33. package/src/typography/lists.njk +24 -11
@@ -0,0 +1,127 @@
1
+ export class MdsScrollSpy extends HTMLElement {
2
+ #observer;
3
+
4
+ constructor() {
5
+ super();
6
+ }
7
+
8
+ #parseObserverThreshold(threshold) {
9
+ const defaultThreshold = [0, 0.25, 0.5, 0.75, 1];
10
+
11
+ if (threshold == null || threshold.trim() === '') {
12
+ return defaultThreshold;
13
+ }
14
+
15
+ const numericThreshold = Number(threshold);
16
+ if (!Number.isNaN(numericThreshold)) {
17
+ return numericThreshold;
18
+ }
19
+
20
+ const isValidThresholdArray = (value) =>
21
+ Array.isArray(value) &&
22
+ value.length > 0 &&
23
+ value.every((item) => typeof item === 'number' && !Number.isNaN(item));
24
+
25
+ try {
26
+ const parsedThreshold = JSON.parse(threshold);
27
+ if (isValidThresholdArray(parsedThreshold)) {
28
+ return parsedThreshold;
29
+ }
30
+ } catch {
31
+ // Will use fallback instead
32
+ }
33
+ console.warn(
34
+ `${this.constructor.name}: Invalid observer-threshold "${threshold}". Falling back to default thresholds.`,
35
+ );
36
+ return defaultThreshold;
37
+ }
38
+
39
+ #setObserver() {
40
+ const sectionVisibilityRatios = new Map();
41
+
42
+ /** @argument {Array<IntersectionObserverEntry>} entries */
43
+ const handleIntersect = (entries) => {
44
+ // get visibility ratio for each section
45
+ entries.forEach((entry) => {
46
+ if (entry.intersectionRatio === 0) {
47
+ sectionVisibilityRatios.delete(entry.target.id);
48
+ } else {
49
+ sectionVisibilityRatios.set(entry.target.id, entry.intersectionRatio);
50
+ }
51
+ });
52
+
53
+ // if no sections are visible, remove aria-current from all links
54
+ if (sectionVisibilityRatios.size === 0) {
55
+ this.#links.forEach((link) => link.removeAttribute('aria-current'));
56
+ return;
57
+ }
58
+
59
+ // get section with highest visibility ratio
60
+ const mostVisibleSection = sectionVisibilityRatios
61
+ .entries()
62
+ .reduce((previousSection, currentSection) =>
63
+ currentSection[1] > previousSection[1] ? currentSection : previousSection,
64
+ );
65
+
66
+ const activeSectionId = mostVisibleSection[0];
67
+ const activeSectionRatio = mostVisibleSection[1];
68
+
69
+ // Update aria-current
70
+ this.#links.forEach((link) => link.removeAttribute('aria-current'));
71
+ if (activeSectionId && activeSectionRatio > 0) {
72
+ this.querySelector(`[href="#${CSS.escape(activeSectionId)}"]`)?.setAttribute(
73
+ 'aria-current',
74
+ this.#ariaCurrentValue,
75
+ );
76
+ }
77
+ };
78
+
79
+ this.#observer = new IntersectionObserver(handleIntersect, this.#observerOptions);
80
+ this.#sections.forEach((section) => this.#observer.observe(section));
81
+ }
82
+
83
+ connectedCallback() {
84
+ if (this.#sections.length > 0) {
85
+ this.#setObserver();
86
+ }
87
+ }
88
+ disconnectedCallback() {
89
+ this.#observer?.disconnect();
90
+ }
91
+
92
+ get #links() {
93
+ return Array.from(this.querySelectorAll('a'));
94
+ }
95
+
96
+ get #sections() {
97
+ const sections = [];
98
+ this.#links.forEach((link) => {
99
+ if (new URL(link.href).host !== window.location.host) return;
100
+ if (!link.hash) return;
101
+
102
+ const section = document.querySelector(`#${CSS.escape(link.hash.substring(1))}`);
103
+
104
+ if (!section) {
105
+ console.warn(`${this.constructor.name}: Element with id "${link.hash}" doesn't exist on this page.`);
106
+ return;
107
+ }
108
+
109
+ sections.push(section);
110
+ });
111
+ return sections;
112
+ }
113
+
114
+ get #ariaCurrentValue() {
115
+ return this.getAttribute('aria-current-value') || 'step';
116
+ }
117
+
118
+ get #observerOptions() {
119
+ const root = this.getAttribute('observer-root');
120
+ const threshold = this.getAttribute('observer-threshold');
121
+
122
+ return {
123
+ root: document.querySelector(root),
124
+ threshold: this.#parseObserverThreshold(threshold),
125
+ };
126
+ }
127
+ }
@@ -0,0 +1,184 @@
1
+ <div class="mds-grid-row">
2
+ <div class="mds-grid-col-12 mds-grid-col-md-4 mds-grid-col-lg-3 mds-display-none mds-display-md-block">
3
+ <nav aria-label="Page sections" class="mds-position-sticky">
4
+ <ol class="mds-step-list">
5
+ <li class="mds-step-list__item">
6
+ <a href="/">Previous page</a>
7
+ </li>
8
+ <li class="mds-step-list__item mds-step-list__item--current mds-step-list__item--has-subnav" aria-current="page">Current
9
+ page
10
+ <mds-scroll-spy>
11
+ <ul class="mds-step-list-subnav">
12
+ <li class="mds-step-list-subnav__item">
13
+ <a class="mds-step-list-subnav__link" href="#section-1">Section 1</a>
14
+ </li>
15
+ <li class="mds-step-list-subnav__item">
16
+ <a class="mds-step-list-subnav__link" href="#section-2">Section 2</a>
17
+ </li>
18
+ <li class="mds-step-list-subnav__item">
19
+ <a class="mds-step-list-subnav__link" href="#section-3">Section 3</a>
20
+ </li>
21
+ </ul>
22
+ </mds-scroll-spy>
23
+ </li>
24
+ <li class="mds-step-list__item mds-step-list__item--future">
25
+ <a href="/">Next page</a>
26
+ </li>
27
+ </ol>
28
+ </nav>
29
+ </div>
30
+ <div class="mds-grid-col-12 mds-grid-col-md-8 mds-grid-col-lg-9">
31
+ <section id="section-1">
32
+ <h2>Section 1</h2>
33
+ <p>
34
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris elit sem, mollis ut dui ac, ultricies posuere dolor.
35
+ Pellentesque tincidunt interdum justo et tempor. Mauris varius ac dolor accumsan pellentesque. Suspendisse varius leo
36
+ quis lorem aliquet, ut eleifend turpis malesuada. Duis maximus cursus sem vel iaculis. Nullam bibendum massa et orci
37
+ scelerisque vulputate. Aenean dignissim tempus urna. Fusce vel faucibus lectus, commodo fringilla sem.
38
+ </p>
39
+ <p>
40
+ Nam venenatis a dui nec efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia
41
+ curae; Integer vel tincidunt risus, et eleifend nisl. Nullam imperdiet ex sit amet sapien iaculis, sit amet consectetur
42
+ justo sollicitudin. Sed vitae tristique arcu, a commodo urna. Curabitur in vulputate magna. Duis iaculis placerat
43
+ consequat.
44
+ </p>
45
+ <p>
46
+ Vestibulum neque erat, pellentesque ut lectus et, tincidunt tincidunt magna. Nam tristique, urna eu dignissim ultricies,
47
+ dui turpis rutrum odio, et fringilla sapien quam vitae nulla. Nulla facilisi. Maecenas gravida, quam in elementum
48
+ sodales, justo magna rutrum mi, et ultricies arcu diam et dolor. Sed sit amet odio vitae urna eleifend sodales et congue
49
+ libero. Etiam sit amet dolor tincidunt, porttitor mi et, ullamcorper tortor. Aenean tellus odio, posuere in condimentum
50
+ vitae, eleifend vel ligula. Donec luctus dolor eu massa luctus pellentesque.
51
+ </p>
52
+ <p>
53
+ Aenean dictum urna at lorem accumsan aliquam. Donec molestie, ante ac consectetur pharetra, nulla dolor tristique odio,
54
+ sit amet dictum elit libero eu velit. Etiam non accumsan lacus, sit amet condimentum eros. Aliquam erat volutpat. Etiam
55
+ rutrum porttitor tortor, ac convallis libero maximus interdum. Nullam ut tellus pulvinar, viverra ex vitae, sodales dui.
56
+ Nulla molestie, lacus eget condimentum vulputate, odio metus feugiat ex, ac consectetur nibh odio in erat. Nunc eget
57
+ justo ac ante euismod tempor. Integer nisi urna, bibendum vitae quam sit amet, laoreet vulputate nisi. Suspendisse
58
+ aliquam ex sit amet turpis iaculis, quis venenatis nibh dignissim.
59
+ </p>
60
+ <p>
61
+ Aliquam semper metus dolor, ac luctus dui posuere id. In facilisis tincidunt rutrum. Nam fermentum purus ante, vel
62
+ elementum lectus vehicula vel. Mauris eu dignissim lectus, quis ultrices turpis. Pellentesque eget accumsan sem, sit
63
+ amet porta tellus. Curabitur sit amet neque et mi porttitor ultricies. Duis eu ipsum finibus, fringilla diam eget,
64
+ fermentum nisl. Ut augue tortor, cursus a congue vel, maximus facilisis massa. Ut gravida, velit eu feugiat faucibus,
65
+ eros magna tincidunt ipsum, sed pellentesque elit diam a ligula. Cras vel viverra massa, laoreet auctor justo. Quisque
66
+ gravida bibendum lorem, at laoreet nisi fermentum a.
67
+ </p>
68
+ </section>
69
+ <section id="section-2">
70
+ <h2>Section 2</h2>
71
+ <p>
72
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris elit sem, mollis ut dui ac, ultricies posuere dolor.
73
+ Pellentesque tincidunt interdum justo et tempor. Mauris varius ac dolor accumsan pellentesque. Suspendisse varius leo
74
+ quis lorem aliquet, ut eleifend turpis malesuada. Duis maximus cursus sem vel iaculis. Nullam bibendum massa et orci
75
+ scelerisque vulputate. Aenean dignissim tempus urna. Fusce vel faucibus lectus, commodo fringilla sem.
76
+ </p>
77
+ <p>
78
+ Nam venenatis a dui nec efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia
79
+ curae; Integer vel tincidunt risus, et eleifend nisl. Nullam imperdiet ex sit amet sapien iaculis, sit amet consectetur
80
+ justo sollicitudin. Sed vitae tristique arcu, a commodo urna. Curabitur in vulputate magna. Duis iaculis placerat
81
+ consequat.
82
+ </p>
83
+ <p>
84
+ Vestibulum neque erat, pellentesque ut lectus et, tincidunt tincidunt magna. Nam tristique, urna eu dignissim ultricies,
85
+ dui turpis rutrum odio, et fringilla sapien quam vitae nulla. Nulla facilisi. Maecenas gravida, quam in elementum
86
+ sodales, justo magna rutrum mi, et ultricies arcu diam et dolor. Sed sit amet odio vitae urna eleifend sodales et congue
87
+ libero. Etiam sit amet dolor tincidunt, porttitor mi et, ullamcorper tortor. Aenean tellus odio, posuere in condimentum
88
+ vitae, eleifend vel ligula. Donec luctus dolor eu massa luctus pellentesque.
89
+ </p>
90
+ <p>
91
+ Aenean dictum urna at lorem accumsan aliquam. Donec molestie, ante ac consectetur pharetra, nulla dolor tristique odio,
92
+ sit amet dictum elit libero eu velit. Etiam non accumsan lacus, sit amet condimentum eros. Aliquam erat volutpat. Etiam
93
+ rutrum porttitor tortor, ac convallis libero maximus interdum. Nullam ut tellus pulvinar, viverra ex vitae, sodales dui.
94
+ Nulla molestie, lacus eget condimentum vulputate, odio metus feugiat ex, ac consectetur nibh odio in erat. Nunc eget
95
+ justo ac ante euismod tempor. Integer nisi urna, bibendum vitae quam sit amet, laoreet vulputate nisi. Suspendisse
96
+ aliquam ex sit amet turpis iaculis, quis venenatis nibh dignissim.
97
+ </p>
98
+ <p>
99
+ Aliquam semper metus dolor, ac luctus dui posuere id. In facilisis tincidunt rutrum. Nam fermentum purus ante, vel
100
+ elementum lectus vehicula vel. Mauris eu dignissim lectus, quis ultrices turpis. Pellentesque eget accumsan sem, sit
101
+ amet porta tellus. Curabitur sit amet neque et mi porttitor ultricies. Duis eu ipsum finibus, fringilla diam eget,
102
+ fermentum nisl. Ut augue tortor, cursus a congue vel, maximus facilisis massa. Ut gravida, velit eu feugiat faucibus,
103
+ eros magna tincidunt ipsum, sed pellentesque elit diam a ligula. Cras vel viverra massa, laoreet auctor justo. Quisque
104
+ gravida bibendum lorem, at laoreet nisi fermentum a.
105
+ </p>
106
+ </section>
107
+ <section id="section-3">
108
+ <h2>Section 3</h2>
109
+ <p>
110
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris elit sem, mollis ut dui ac, ultricies posuere dolor.
111
+ Pellentesque tincidunt interdum justo et tempor. Mauris varius ac dolor accumsan pellentesque. Suspendisse varius leo
112
+ quis lorem aliquet, ut eleifend turpis malesuada. Duis maximus cursus sem vel iaculis. Nullam bibendum massa et orci
113
+ scelerisque vulputate. Aenean dignissim tempus urna. Fusce vel faucibus lectus, commodo fringilla sem.
114
+ </p>
115
+ <p>
116
+ Nam venenatis a dui nec efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia
117
+ curae; Integer vel tincidunt risus, et eleifend nisl. Nullam imperdiet ex sit amet sapien iaculis, sit amet consectetur
118
+ justo sollicitudin. Sed vitae tristique arcu, a commodo urna. Curabitur in vulputate magna. Duis iaculis placerat
119
+ consequat.
120
+ </p>
121
+ <p>
122
+ Vestibulum neque erat, pellentesque ut lectus et, tincidunt tincidunt magna. Nam tristique, urna eu dignissim ultricies,
123
+ dui turpis rutrum odio, et fringilla sapien quam vitae nulla. Nulla facilisi. Maecenas gravida, quam in elementum
124
+ sodales, justo magna rutrum mi, et ultricies arcu diam et dolor. Sed sit amet odio vitae urna eleifend sodales et congue
125
+ libero. Etiam sit amet dolor tincidunt, porttitor mi et, ullamcorper tortor. Aenean tellus odio, posuere in condimentum
126
+ vitae, eleifend vel ligula. Donec luctus dolor eu massa luctus pellentesque.
127
+ </p>
128
+ <p>
129
+ Aenean dictum urna at lorem accumsan aliquam. Donec molestie, ante ac consectetur pharetra, nulla dolor tristique odio,
130
+ sit amet dictum elit libero eu velit. Etiam non accumsan lacus, sit amet condimentum eros. Aliquam erat volutpat. Etiam
131
+ rutrum porttitor tortor, ac convallis libero maximus interdum. Nullam ut tellus pulvinar, viverra ex vitae, sodales dui.
132
+ Nulla molestie, lacus eget condimentum vulputate, odio metus feugiat ex, ac consectetur nibh odio in erat. Nunc eget
133
+ justo ac ante euismod tempor. Integer nisi urna, bibendum vitae quam sit amet, laoreet vulputate nisi. Suspendisse
134
+ aliquam ex sit amet turpis iaculis, quis venenatis nibh dignissim.
135
+ </p>
136
+ <p>
137
+ Aliquam semper metus dolor, ac luctus dui posuere id. In facilisis tincidunt rutrum. Nam fermentum purus ante, vel
138
+ elementum lectus vehicula vel. Mauris eu dignissim lectus, quis ultrices turpis. Pellentesque eget accumsan sem, sit
139
+ amet porta tellus. Curabitur sit amet neque et mi porttitor ultricies. Duis eu ipsum finibus, fringilla diam eget,
140
+ fermentum nisl. Ut augue tortor, cursus a congue vel, maximus facilisis massa. Ut gravida, velit eu feugiat faucibus,
141
+ eros magna tincidunt ipsum, sed pellentesque elit diam a ligula. Cras vel viverra massa, laoreet auctor justo. Quisque
142
+ gravida bibendum lorem, at laoreet nisi fermentum a.
143
+ </p>
144
+ </section>
145
+ <section id="section-no-scrollspy">
146
+ <h2>Section outside of Scroll Spy</h2>
147
+ <p>
148
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris elit sem, mollis ut dui ac, ultricies posuere dolor.
149
+ Pellentesque tincidunt interdum justo et tempor. Mauris varius ac dolor accumsan pellentesque. Suspendisse varius leo
150
+ quis lorem aliquet, ut eleifend turpis malesuada. Duis maximus cursus sem vel iaculis. Nullam bibendum massa et orci
151
+ scelerisque vulputate. Aenean dignissim tempus urna. Fusce vel faucibus lectus, commodo fringilla sem.
152
+ </p>
153
+ <p>
154
+ Nam venenatis a dui nec efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia
155
+ curae; Integer vel tincidunt risus, et eleifend nisl. Nullam imperdiet ex sit amet sapien iaculis, sit amet consectetur
156
+ justo sollicitudin. Sed vitae tristique arcu, a commodo urna. Curabitur in vulputate magna. Duis iaculis placerat
157
+ consequat.
158
+ </p>
159
+ <p>
160
+ Vestibulum neque erat, pellentesque ut lectus et, tincidunt tincidunt magna. Nam tristique, urna eu dignissim ultricies,
161
+ dui turpis rutrum odio, et fringilla sapien quam vitae nulla. Nulla facilisi. Maecenas gravida, quam in elementum
162
+ sodales, justo magna rutrum mi, et ultricies arcu diam et dolor. Sed sit amet odio vitae urna eleifend sodales et congue
163
+ libero. Etiam sit amet dolor tincidunt, porttitor mi et, ullamcorper tortor. Aenean tellus odio, posuere in condimentum
164
+ vitae, eleifend vel ligula. Donec luctus dolor eu massa luctus pellentesque.
165
+ </p>
166
+ <p>
167
+ Aenean dictum urna at lorem accumsan aliquam. Donec molestie, ante ac consectetur pharetra, nulla dolor tristique odio,
168
+ sit amet dictum elit libero eu velit. Etiam non accumsan lacus, sit amet condimentum eros. Aliquam erat volutpat. Etiam
169
+ rutrum porttitor tortor, ac convallis libero maximus interdum. Nullam ut tellus pulvinar, viverra ex vitae, sodales dui.
170
+ Nulla molestie, lacus eget condimentum vulputate, odio metus feugiat ex, ac consectetur nibh odio in erat. Nunc eget
171
+ justo ac ante euismod tempor. Integer nisi urna, bibendum vitae quam sit amet, laoreet vulputate nisi. Suspendisse
172
+ aliquam ex sit amet turpis iaculis, quis venenatis nibh dignissim.
173
+ </p>
174
+ <p>
175
+ Aliquam semper metus dolor, ac luctus dui posuere id. In facilisis tincidunt rutrum. Nam fermentum purus ante, vel
176
+ elementum lectus vehicula vel. Mauris eu dignissim lectus, quis ultrices turpis. Pellentesque eget accumsan sem, sit
177
+ amet porta tellus. Curabitur sit amet neque et mi porttitor ultricies. Duis eu ipsum finibus, fringilla diam eget,
178
+ fermentum nisl. Ut augue tortor, cursus a congue vel, maximus facilisis massa. Ut gravida, velit eu feugiat faucibus,
179
+ eros magna tincidunt ipsum, sed pellentesque elit diam a ligula. Cras vel viverra massa, laoreet auctor justo. Quisque
180
+ gravida bibendum lorem, at laoreet nisi fermentum a.
181
+ </p>
182
+ </section>
183
+ </div>
184
+ </div>