@ulu/frontend 0.6.28 → 0.6.30
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/dist/es/core/component.d.ts +40 -1
- package/dist/es/core/component.d.ts.map +1 -1
- package/dist/es/core/component.js +83 -28
- package/dist/es/ui/grid.d.ts.map +1 -1
- package/dist/es/ui/grid.js +10 -7
- package/dist/es/ui/overflow-scroller.d.ts +3 -0
- package/dist/es/ui/overflow-scroller.d.ts.map +1 -1
- package/dist/es/ui/overflow-scroller.js +52 -41
- package/dist/es/utils/dom.d.ts +7 -0
- package/dist/es/utils/dom.d.ts.map +1 -1
- package/dist/es/utils/dom.js +25 -18
- package/dist/mcp-data.json +865 -614
- package/dist/umd/frontend.css +1 -1
- package/dist/umd/ulu-frontend.umd.js +10 -10
- package/lib/js/core/component.js +70 -8
- package/lib/js/ui/grid.js +3 -0
- package/lib/js/ui/overflow-scroller.js +24 -2
- package/lib/js/utils/dom.js +62 -28
- package/lib/scss/components/_card-grid.demo.html +35 -21
- package/lib/scss/components/_modal.scss +7 -0
- package/package.json +1 -1
package/lib/js/utils/dom.js
CHANGED
|
@@ -13,6 +13,49 @@ export function dataAttributeToDatasetKey(attribute) {
|
|
|
13
13
|
return kebabToCamel(attribute.replace(/^data-/, ""));
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Groups a parent's children into rows based on their visual coordinates (top and left positions).
|
|
18
|
+
* Filters out hidden elements and sorts them visually to support CSS grid order properties.
|
|
19
|
+
* @param {HTMLElement} parent The grid/parent container
|
|
20
|
+
* @returns {HTMLElement[][]} A 2D array of rows, where each row is an array of elements in visual order.
|
|
21
|
+
*/
|
|
22
|
+
export function getVisualRows(parent) {
|
|
23
|
+
const children = [...parent.children];
|
|
24
|
+
|
|
25
|
+
// Map to bounding client rects and filter out hidden elements (e.g. display: none)
|
|
26
|
+
const items = children
|
|
27
|
+
.map(child => ({ child, rect: child.getBoundingClientRect() }))
|
|
28
|
+
.filter(item => item.rect.width !== 0 || item.rect.height !== 0);
|
|
29
|
+
|
|
30
|
+
if (items.length === 0) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Sort items visually: top-to-bottom, then left-to-right to support CSS order properties.
|
|
35
|
+
// Use Math.abs because comparison elements can be passed in either order; if a difference
|
|
36
|
+
// exists in either direction (> 1px threshold for sub-pixel rounding), sort by top offset.
|
|
37
|
+
items.sort((a, b) => {
|
|
38
|
+
if (Math.abs(a.rect.top - b.rect.top) > 1) {
|
|
39
|
+
return a.rect.top - b.rect.top;
|
|
40
|
+
}
|
|
41
|
+
return a.rect.left - b.rect.left;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const rows = [];
|
|
45
|
+
let currentY = null;
|
|
46
|
+
|
|
47
|
+
// Group into rows
|
|
48
|
+
items.forEach(({ child, rect }) => {
|
|
49
|
+
if (currentY === null || Math.abs(rect.top - currentY) > 1) {
|
|
50
|
+
rows.push([]);
|
|
51
|
+
currentY = rect.top;
|
|
52
|
+
}
|
|
53
|
+
rows[rows.length - 1].push(child);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return rows;
|
|
57
|
+
}
|
|
58
|
+
|
|
16
59
|
/**
|
|
17
60
|
* Sets up the positional classes that would come from the equal
|
|
18
61
|
* height module. Needs to be rerun by user when layout changes
|
|
@@ -24,37 +67,28 @@ export function dataAttributeToDatasetKey(attribute) {
|
|
|
24
67
|
* @param {Object} classes Override the default equal heights classes
|
|
25
68
|
*/
|
|
26
69
|
export function setPositionClasses(parent, classes = {
|
|
27
|
-
columnFirst:
|
|
28
|
-
columnLast:
|
|
29
|
-
rowFirst:
|
|
30
|
-
rowLast:
|
|
70
|
+
columnFirst: "position-column-first",
|
|
71
|
+
columnLast: "position-column-last",
|
|
72
|
+
rowFirst: "position-row-first",
|
|
73
|
+
rowLast: "position-row-last"
|
|
31
74
|
}) {
|
|
32
75
|
const children = [...parent.children];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
// Apply Classes
|
|
46
|
-
rows.forEach((row, index) => {
|
|
47
|
-
if (index === 0)
|
|
48
|
-
row.forEach(child => child.classList.add(classes.rowFirst));
|
|
49
|
-
if (index == rows.length - 1)
|
|
50
|
-
row.forEach(child => child.classList.add(classes.rowLast));
|
|
76
|
+
|
|
77
|
+
// Remove previously set classes from all children first to avoid stale states
|
|
78
|
+
children.forEach(child => child.classList.remove(...Object.values(classes)));
|
|
79
|
+
|
|
80
|
+
const rows = getVisualRows(parent);
|
|
81
|
+
|
|
82
|
+
if (rows.length === 0) return;
|
|
83
|
+
|
|
84
|
+
// Apply row classes
|
|
85
|
+
rows[0].forEach(child => child.classList.add(classes.rowFirst));
|
|
86
|
+
rows[rows.length - 1].forEach(child => child.classList.add(classes.rowLast));
|
|
51
87
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
child.classList.add(classes.columnLast);
|
|
57
|
-
});
|
|
88
|
+
// Apply column classes
|
|
89
|
+
rows.forEach((row) => {
|
|
90
|
+
row[0].classList.add(classes.columnFirst);
|
|
91
|
+
row[row.length - 1].classList.add(classes.columnLast);
|
|
58
92
|
});
|
|
59
93
|
}
|
|
60
94
|
|
|
@@ -3,15 +3,21 @@
|
|
|
3
3
|
description: A responsive grid that automatically fills rows with cards.
|
|
4
4
|
-->
|
|
5
5
|
<div class="card-grid">
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
<div class="card-grid__item">
|
|
7
|
+
<article class="card">
|
|
8
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Card 1</h3><p>Content for the first card.</p></div></div>
|
|
9
|
+
</article>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="card-grid__item">
|
|
12
|
+
<article class="card">
|
|
13
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Card 2</h3><p>Content for the second card.</p></div></div>
|
|
14
|
+
</article>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="card-grid__item">
|
|
17
|
+
<article class="card">
|
|
18
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Card 3</h3><p>Content for the third card.</p></div></div>
|
|
19
|
+
</article>
|
|
20
|
+
</div>
|
|
15
21
|
</div>
|
|
16
22
|
|
|
17
23
|
<!-- @ulu-demo
|
|
@@ -19,16 +25,24 @@
|
|
|
19
25
|
description: A grid with smaller minimum column widths and tighter gaps.
|
|
20
26
|
-->
|
|
21
27
|
<div class="card-grid card-grid--compact">
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
<div class="card-grid__item">
|
|
29
|
+
<article class="card">
|
|
30
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Compact 1</h3></div></div>
|
|
31
|
+
</article>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="card-grid__item">
|
|
34
|
+
<article class="card">
|
|
35
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Compact 2</h3></div></div>
|
|
36
|
+
</article>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="card-grid__item">
|
|
39
|
+
<article class="card">
|
|
40
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Compact 3</h3></div></div>
|
|
41
|
+
</article>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="card-grid__item">
|
|
44
|
+
<article class="card">
|
|
45
|
+
<div class="card__body"><div class="card__main"><h3 class="card__title">Compact 4</h3></div></div>
|
|
46
|
+
</article>
|
|
47
|
+
</div>
|
|
34
48
|
</div>
|
|
@@ -36,6 +36,10 @@ $-fallbacks: (
|
|
|
36
36
|
"function" : meta.get-function("get", false, "element"),
|
|
37
37
|
"property" : "icon-centered-vertical-offset",
|
|
38
38
|
),
|
|
39
|
+
"title-line-height" : (
|
|
40
|
+
"function" : meta.get-function("get", false, "typography"),
|
|
41
|
+
"property" : "line-height-dense",
|
|
42
|
+
)
|
|
39
43
|
);
|
|
40
44
|
|
|
41
45
|
/// Module Settings
|
|
@@ -79,6 +83,7 @@ $-fallbacks: (
|
|
|
79
83
|
/// @prop {CssValue} title-font-weight [bold] Font weight of the title.
|
|
80
84
|
/// @prop {CssValue} title-font-family [null] Font family for title
|
|
81
85
|
/// @prop {Dimension} title-icon-margin [0.5em] The margin of the title icon
|
|
86
|
+
/// @prop {Boolean|CssValue} title-line-height [true] If true will default to typography "line-height-dense", or set your own value
|
|
82
87
|
/// @prop {String} title-size [large] The font-size of the title. This uses typography.scss, so the value of this options should be a variable from typography.scss.
|
|
83
88
|
/// @prop {CssValue} title-text-transform [null] Transform option for the title.
|
|
84
89
|
/// @prop {Map} sizes [Map] Size options to enable unique stylings.
|
|
@@ -129,6 +134,7 @@ $config: (
|
|
|
129
134
|
"title-font-family" : null,
|
|
130
135
|
"title-icon-margin" : 0.5em,
|
|
131
136
|
"title-size" : "large",
|
|
137
|
+
"title-line-height" : true,
|
|
132
138
|
"title-text-transform" : null,
|
|
133
139
|
"breakpoint" : true,
|
|
134
140
|
"frame-aspect-ratio" : list.slash(16, 9),
|
|
@@ -239,6 +245,7 @@ $config: (
|
|
|
239
245
|
font-weight: get("title-font-weight");
|
|
240
246
|
font-family: get("title-font-family");
|
|
241
247
|
text-transform: get("title-text-transform");
|
|
248
|
+
line-height: get("title-line-height");
|
|
242
249
|
@if (get("title-size")) {
|
|
243
250
|
@include typography.size(get("title-size"), $only-font-size: true);
|
|
244
251
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulu/frontend",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.30",
|
|
4
4
|
"description": "A framework-agnostic frontend toolkit providing a modular, tree-shakable library of accessible components and utilities. Designed for seamless integration, it features a highly configurable SCSS system for any environment and vanilla JavaScript modules optimized for traditional websites and content management systems.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|