unigrid.css 0.3.0 → 0.3.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.
- package/README.md +101 -101
- package/dist/dropdown.js +36 -36
- package/dist/scrollspy.js +57 -57
- package/dist/tabs.js +30 -30
- package/dist/unigrid.css +4501 -4501
- package/dist/unigrid.js +124 -124
- package/dist/unigrid.min.css +1 -1
- package/dist/unigrid.min.js +1 -1
- package/package.json +70 -41
- package/src/js/dropdown.js +49 -49
- package/src/js/index.js +19 -19
- package/src/js/scrollspy.js +87 -87
- package/src/js/tabs.js +58 -58
- package/src/scss/_accordion.scss +123 -123
- package/src/scss/_broadside.scss +125 -125
- package/src/scss/_buttons.scss +241 -241
- package/src/scss/_card.scss +168 -168
- package/src/scss/_components.scss +140 -140
- package/src/scss/_container.scss +53 -53
- package/src/scss/_dropdown.scss +178 -178
- package/src/scss/_footer.scss +147 -147
- package/src/scss/_formats.scss +64 -64
- package/src/scss/_forms.scss +192 -192
- package/src/scss/_grid.scss +114 -114
- package/src/scss/_header.scss +169 -169
- package/src/scss/_hero.scss +262 -262
- package/src/scss/_mixins.scss +120 -120
- package/src/scss/_modules.scss +238 -238
- package/src/scss/_navbar.scss +341 -341
- package/src/scss/_pagination.scss +160 -160
- package/src/scss/_prose.scss +393 -393
- package/src/scss/_reset.scss +82 -82
- package/src/scss/_scrollspy.scss +62 -62
- package/src/scss/_section.scss +91 -91
- package/src/scss/_sidebar.scss +147 -147
- package/src/scss/_table.scss +122 -122
- package/src/scss/_tabs.scss +178 -178
- package/src/scss/_typography.scss +105 -105
- package/src/scss/_utilities.scss +79 -79
- package/src/scss/_variables.scss +183 -183
- package/src/scss/unigrid.scss +49 -49
- package/dist/index.js +0 -5
package/package.json
CHANGED
|
@@ -1,41 +1,70 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "unigrid.css",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "A CSS grid framework inspired by Massimo Vignelli's Unigrid system for the National Park Service",
|
|
5
|
-
"main": "dist/unigrid.css",
|
|
6
|
-
"style": "dist/unigrid.css",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
}
|
|
41
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "unigrid.css",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "A CSS grid framework inspired by Massimo Vignelli's Unigrid system for the National Park Service. Vertical rhythm, square modules, BEM naming.",
|
|
5
|
+
"main": "dist/unigrid.css",
|
|
6
|
+
"style": "dist/unigrid.css",
|
|
7
|
+
"sass": "src/scss/unigrid.scss",
|
|
8
|
+
"unpkg": "dist/unigrid.min.css",
|
|
9
|
+
"jsdelivr": "dist/unigrid.min.css",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"style": "./dist/unigrid.css",
|
|
13
|
+
"sass": "./src/scss/unigrid.scss",
|
|
14
|
+
"default": "./dist/unigrid.css"
|
|
15
|
+
},
|
|
16
|
+
"./dist/*": "./dist/*",
|
|
17
|
+
"./src/*": "./src/*"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist/unigrid.css",
|
|
21
|
+
"dist/unigrid.min.css",
|
|
22
|
+
"dist/unigrid.js",
|
|
23
|
+
"dist/unigrid.min.js",
|
|
24
|
+
"dist/dropdown.js",
|
|
25
|
+
"dist/tabs.js",
|
|
26
|
+
"dist/scrollspy.js",
|
|
27
|
+
"src/scss/",
|
|
28
|
+
"src/js/"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"dev": "vite",
|
|
32
|
+
"build": "npm run build:css && npm run build:js",
|
|
33
|
+
"build:css": "sass src/scss/unigrid.scss dist/unigrid.css --style=expanded && sass src/scss/unigrid.scss dist/unigrid.min.css --style=compressed",
|
|
34
|
+
"build:js": "node scripts/build-js.mjs",
|
|
35
|
+
"watch": "npm run watch:css & npm run watch:js",
|
|
36
|
+
"watch:css": "sass src/scss/unigrid.scss dist/unigrid.css --style=expanded --watch",
|
|
37
|
+
"watch:js": "node scripts/build-js.mjs --watch",
|
|
38
|
+
"prepublishOnly": "npm run build",
|
|
39
|
+
"preview": "vite preview"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"css",
|
|
43
|
+
"scss",
|
|
44
|
+
"grid",
|
|
45
|
+
"unigrid",
|
|
46
|
+
"vignelli",
|
|
47
|
+
"design-system",
|
|
48
|
+
"nps",
|
|
49
|
+
"bem",
|
|
50
|
+
"vertical-rhythm",
|
|
51
|
+
"gutenberg",
|
|
52
|
+
"typography",
|
|
53
|
+
"responsive"
|
|
54
|
+
],
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"author": "tdascoli",
|
|
57
|
+
"homepage": "https://tdascoli.github.io/unigrid.css/",
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/tdascoli/unigrid.css.git"
|
|
61
|
+
},
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/tdascoli/unigrid.css/issues"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"esbuild": "^0.24.0",
|
|
67
|
+
"sass": "^1.80.0",
|
|
68
|
+
"vite": "^6.0.0"
|
|
69
|
+
}
|
|
70
|
+
}
|
package/src/js/dropdown.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unigrid Dropdown
|
|
3
|
-
*
|
|
4
|
-
* Toggles .ug-dropdown--open on click.
|
|
5
|
-
* Closes all dropdowns when clicking outside.
|
|
6
|
-
* Auto-initializes on DOMContentLoaded.
|
|
7
|
-
*/
|
|
8
|
-
(function () {
|
|
9
|
-
function init() {
|
|
10
|
-
document.addEventListener('click', function (e) {
|
|
11
|
-
var trigger = e.target.closest('.ug-dropdown__trigger');
|
|
12
|
-
|
|
13
|
-
if (trigger) {
|
|
14
|
-
e.preventDefault();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Close all other dropdowns (skip those inside .docs-example__preview)
|
|
18
|
-
document.querySelectorAll('.ug-dropdown--open').forEach(function (dd) {
|
|
19
|
-
if (dd.closest('.docs-example__preview')) return;
|
|
20
|
-
if (!trigger || dd !== trigger.closest('.ug-dropdown')) {
|
|
21
|
-
dd.classList.remove('ug-dropdown--open');
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// Toggle clicked dropdown
|
|
26
|
-
if (trigger) {
|
|
27
|
-
var dropdown = trigger.closest('.ug-dropdown');
|
|
28
|
-
if (dropdown) {
|
|
29
|
-
dropdown.classList.toggle('ug-dropdown--open');
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Close on Escape key
|
|
35
|
-
document.addEventListener('keydown', function (e) {
|
|
36
|
-
if (e.key === 'Escape') {
|
|
37
|
-
document.querySelectorAll('.ug-dropdown--open').forEach(function (dd) {
|
|
38
|
-
dd.classList.remove('ug-dropdown--open');
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (document.readyState === 'loading') {
|
|
45
|
-
document.addEventListener('DOMContentLoaded', init);
|
|
46
|
-
} else {
|
|
47
|
-
init();
|
|
48
|
-
}
|
|
49
|
-
})();
|
|
1
|
+
/**
|
|
2
|
+
* Unigrid Dropdown
|
|
3
|
+
*
|
|
4
|
+
* Toggles .ug-dropdown--open on click.
|
|
5
|
+
* Closes all dropdowns when clicking outside.
|
|
6
|
+
* Auto-initializes on DOMContentLoaded.
|
|
7
|
+
*/
|
|
8
|
+
(function () {
|
|
9
|
+
function init() {
|
|
10
|
+
document.addEventListener('click', function (e) {
|
|
11
|
+
var trigger = e.target.closest('.ug-dropdown__trigger');
|
|
12
|
+
|
|
13
|
+
if (trigger) {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Close all other dropdowns (skip those inside .docs-example__preview)
|
|
18
|
+
document.querySelectorAll('.ug-dropdown--open').forEach(function (dd) {
|
|
19
|
+
if (dd.closest('.docs-example__preview')) return;
|
|
20
|
+
if (!trigger || dd !== trigger.closest('.ug-dropdown')) {
|
|
21
|
+
dd.classList.remove('ug-dropdown--open');
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Toggle clicked dropdown
|
|
26
|
+
if (trigger) {
|
|
27
|
+
var dropdown = trigger.closest('.ug-dropdown');
|
|
28
|
+
if (dropdown) {
|
|
29
|
+
dropdown.classList.toggle('ug-dropdown--open');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Close on Escape key
|
|
35
|
+
document.addEventListener('keydown', function (e) {
|
|
36
|
+
if (e.key === 'Escape') {
|
|
37
|
+
document.querySelectorAll('.ug-dropdown--open').forEach(function (dd) {
|
|
38
|
+
dd.classList.remove('ug-dropdown--open');
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (document.readyState === 'loading') {
|
|
45
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
46
|
+
} else {
|
|
47
|
+
init();
|
|
48
|
+
}
|
|
49
|
+
})();
|
package/src/js/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unigrid.js — All interactive components bundled.
|
|
3
|
-
*
|
|
4
|
-
* Includes: dropdown, tabs, scrollspy
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* <script src="dist/unigrid.js"></script>
|
|
8
|
-
* or
|
|
9
|
-
* <script src="dist/unigrid.min.js"></script>
|
|
10
|
-
*
|
|
11
|
-
* Individual files also available:
|
|
12
|
-
* <script src="dist/dropdown.js"></script>
|
|
13
|
-
* <script src="dist/tabs.js"></script>
|
|
14
|
-
* <script src="dist/scrollspy.js"></script>
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import './dropdown.js';
|
|
18
|
-
import './tabs.js';
|
|
19
|
-
import './scrollspy.js';
|
|
1
|
+
/**
|
|
2
|
+
* Unigrid.js — All interactive components bundled.
|
|
3
|
+
*
|
|
4
|
+
* Includes: dropdown, tabs, scrollspy
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* <script src="dist/unigrid.js"></script>
|
|
8
|
+
* or
|
|
9
|
+
* <script src="dist/unigrid.min.js"></script>
|
|
10
|
+
*
|
|
11
|
+
* Individual files also available:
|
|
12
|
+
* <script src="dist/dropdown.js"></script>
|
|
13
|
+
* <script src="dist/tabs.js"></script>
|
|
14
|
+
* <script src="dist/scrollspy.js"></script>
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import './dropdown.js';
|
|
18
|
+
import './tabs.js';
|
|
19
|
+
import './scrollspy.js';
|
package/src/js/scrollspy.js
CHANGED
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unigrid Scrollspy
|
|
3
|
-
*
|
|
4
|
-
* Highlights navigation links based on which section is currently
|
|
5
|
-
* visible in the viewport using IntersectionObserver.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* <nav data-ug-scrollspy>
|
|
9
|
-
* <a class="ug-scrollspy__link" href="#intro">Intro</a>
|
|
10
|
-
* <a class="ug-scrollspy__link" href="#features">Features</a>
|
|
11
|
-
* </nav>
|
|
12
|
-
*
|
|
13
|
-
* <section id="intro">...</section>
|
|
14
|
-
* <section id="features">...</section>
|
|
15
|
-
*
|
|
16
|
-
* Options (via data attributes on [data-ug-scrollspy]):
|
|
17
|
-
* data-ug-scrollspy-offset="100" — top offset in px (default: 100)
|
|
18
|
-
* data-ug-scrollspy-class="custom" — active class (default: ug-scrollspy__link--active)
|
|
19
|
-
*/
|
|
20
|
-
(function () {
|
|
21
|
-
function init() {
|
|
22
|
-
document.querySelectorAll('[data-ug-scrollspy]').forEach(function (nav) {
|
|
23
|
-
var links = nav.querySelectorAll('.ug-scrollspy__link, [data-ug-spy]');
|
|
24
|
-
if (!links.length) return;
|
|
25
|
-
|
|
26
|
-
var offset = parseInt(nav.getAttribute('data-ug-scrollspy-offset') || '100', 10);
|
|
27
|
-
var activeClass = nav.getAttribute('data-ug-scrollspy-class') || 'ug-scrollspy__link--active';
|
|
28
|
-
|
|
29
|
-
// Collect target sections
|
|
30
|
-
var targets = [];
|
|
31
|
-
links.forEach(function (link) {
|
|
32
|
-
var href = link.getAttribute('href');
|
|
33
|
-
if (!href || href.charAt(0) !== '#') return;
|
|
34
|
-
var target = document.querySelector(href);
|
|
35
|
-
if (target) {
|
|
36
|
-
targets.push({ link: link, target: target });
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (!targets.length) return;
|
|
41
|
-
|
|
42
|
-
// Track which sections are visible
|
|
43
|
-
var visibleSections = new Set();
|
|
44
|
-
|
|
45
|
-
var observer = new IntersectionObserver(function (entries) {
|
|
46
|
-
entries.forEach(function (entry) {
|
|
47
|
-
if (entry.isIntersecting) {
|
|
48
|
-
visibleSections.add(entry.target.id);
|
|
49
|
-
} else {
|
|
50
|
-
visibleSections.delete(entry.target.id);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Find the first visible section (in DOM order)
|
|
55
|
-
var activeId = null;
|
|
56
|
-
for (var i = 0; i < targets.length; i++) {
|
|
57
|
-
if (visibleSections.has(targets[i].target.id)) {
|
|
58
|
-
activeId = targets[i].target.id;
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Update active states
|
|
64
|
-
targets.forEach(function (item) {
|
|
65
|
-
if (item.target.id === activeId) {
|
|
66
|
-
item.link.classList.add(activeClass);
|
|
67
|
-
} else {
|
|
68
|
-
item.link.classList.remove(activeClass);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
}, {
|
|
72
|
-
rootMargin: '-' + offset + 'px 0px -50% 0px',
|
|
73
|
-
threshold: 0
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
targets.forEach(function (item) {
|
|
77
|
-
observer.observe(item.target);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (document.readyState === 'loading') {
|
|
83
|
-
document.addEventListener('DOMContentLoaded', init);
|
|
84
|
-
} else {
|
|
85
|
-
init();
|
|
86
|
-
}
|
|
87
|
-
})();
|
|
1
|
+
/**
|
|
2
|
+
* Unigrid Scrollspy
|
|
3
|
+
*
|
|
4
|
+
* Highlights navigation links based on which section is currently
|
|
5
|
+
* visible in the viewport using IntersectionObserver.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* <nav data-ug-scrollspy>
|
|
9
|
+
* <a class="ug-scrollspy__link" href="#intro">Intro</a>
|
|
10
|
+
* <a class="ug-scrollspy__link" href="#features">Features</a>
|
|
11
|
+
* </nav>
|
|
12
|
+
*
|
|
13
|
+
* <section id="intro">...</section>
|
|
14
|
+
* <section id="features">...</section>
|
|
15
|
+
*
|
|
16
|
+
* Options (via data attributes on [data-ug-scrollspy]):
|
|
17
|
+
* data-ug-scrollspy-offset="100" — top offset in px (default: 100)
|
|
18
|
+
* data-ug-scrollspy-class="custom" — active class (default: ug-scrollspy__link--active)
|
|
19
|
+
*/
|
|
20
|
+
(function () {
|
|
21
|
+
function init() {
|
|
22
|
+
document.querySelectorAll('[data-ug-scrollspy]').forEach(function (nav) {
|
|
23
|
+
var links = nav.querySelectorAll('.ug-scrollspy__link, [data-ug-spy]');
|
|
24
|
+
if (!links.length) return;
|
|
25
|
+
|
|
26
|
+
var offset = parseInt(nav.getAttribute('data-ug-scrollspy-offset') || '100', 10);
|
|
27
|
+
var activeClass = nav.getAttribute('data-ug-scrollspy-class') || 'ug-scrollspy__link--active';
|
|
28
|
+
|
|
29
|
+
// Collect target sections
|
|
30
|
+
var targets = [];
|
|
31
|
+
links.forEach(function (link) {
|
|
32
|
+
var href = link.getAttribute('href');
|
|
33
|
+
if (!href || href.charAt(0) !== '#') return;
|
|
34
|
+
var target = document.querySelector(href);
|
|
35
|
+
if (target) {
|
|
36
|
+
targets.push({ link: link, target: target });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (!targets.length) return;
|
|
41
|
+
|
|
42
|
+
// Track which sections are visible
|
|
43
|
+
var visibleSections = new Set();
|
|
44
|
+
|
|
45
|
+
var observer = new IntersectionObserver(function (entries) {
|
|
46
|
+
entries.forEach(function (entry) {
|
|
47
|
+
if (entry.isIntersecting) {
|
|
48
|
+
visibleSections.add(entry.target.id);
|
|
49
|
+
} else {
|
|
50
|
+
visibleSections.delete(entry.target.id);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Find the first visible section (in DOM order)
|
|
55
|
+
var activeId = null;
|
|
56
|
+
for (var i = 0; i < targets.length; i++) {
|
|
57
|
+
if (visibleSections.has(targets[i].target.id)) {
|
|
58
|
+
activeId = targets[i].target.id;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Update active states
|
|
64
|
+
targets.forEach(function (item) {
|
|
65
|
+
if (item.target.id === activeId) {
|
|
66
|
+
item.link.classList.add(activeClass);
|
|
67
|
+
} else {
|
|
68
|
+
item.link.classList.remove(activeClass);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}, {
|
|
72
|
+
rootMargin: '-' + offset + 'px 0px -50% 0px',
|
|
73
|
+
threshold: 0
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
targets.forEach(function (item) {
|
|
77
|
+
observer.observe(item.target);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (document.readyState === 'loading') {
|
|
83
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
84
|
+
} else {
|
|
85
|
+
init();
|
|
86
|
+
}
|
|
87
|
+
})();
|
package/src/js/tabs.js
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unigrid Tabs
|
|
3
|
-
*
|
|
4
|
-
* Switches active tab link and panel on click.
|
|
5
|
-
* Auto-initializes on DOMContentLoaded.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* <div class="ug-tabs" data-ug-tabs>
|
|
9
|
-
* <ul class="ug-tabs__nav">
|
|
10
|
-
* <li class="ug-tabs__item">
|
|
11
|
-
* <button class="ug-tabs__link ug-tabs__link--active" data-ug-tab="tab1">Tab 1</button>
|
|
12
|
-
* </li>
|
|
13
|
-
* </ul>
|
|
14
|
-
* <div class="ug-tabs__content">
|
|
15
|
-
* <div class="ug-tabs__panel ug-tabs__panel--active" data-ug-panel="tab1">...</div>
|
|
16
|
-
* </div>
|
|
17
|
-
* </div>
|
|
18
|
-
*/
|
|
19
|
-
(function () {
|
|
20
|
-
function init() {
|
|
21
|
-
document.addEventListener('click', function (e) {
|
|
22
|
-
var link = e.target.closest('[data-ug-tab]');
|
|
23
|
-
if (!link) return;
|
|
24
|
-
|
|
25
|
-
e.preventDefault();
|
|
26
|
-
|
|
27
|
-
var tabs = link.closest('.ug-tabs');
|
|
28
|
-
if (!tabs) return;
|
|
29
|
-
|
|
30
|
-
var target = link.getAttribute('data-ug-tab');
|
|
31
|
-
|
|
32
|
-
// Deactivate all links
|
|
33
|
-
tabs.querySelectorAll('.ug-tabs__link').forEach(function (l) {
|
|
34
|
-
l.classList.remove('ug-tabs__link--active');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// Deactivate all panels
|
|
38
|
-
tabs.querySelectorAll('.ug-tabs__panel').forEach(function (p) {
|
|
39
|
-
p.classList.remove('ug-tabs__panel--active');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Activate clicked link
|
|
43
|
-
link.classList.add('ug-tabs__link--active');
|
|
44
|
-
|
|
45
|
-
// Activate matching panel
|
|
46
|
-
var panel = tabs.querySelector('[data-ug-panel="' + target + '"]');
|
|
47
|
-
if (panel) {
|
|
48
|
-
panel.classList.add('ug-tabs__panel--active');
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (document.readyState === 'loading') {
|
|
54
|
-
document.addEventListener('DOMContentLoaded', init);
|
|
55
|
-
} else {
|
|
56
|
-
init();
|
|
57
|
-
}
|
|
58
|
-
})();
|
|
1
|
+
/**
|
|
2
|
+
* Unigrid Tabs
|
|
3
|
+
*
|
|
4
|
+
* Switches active tab link and panel on click.
|
|
5
|
+
* Auto-initializes on DOMContentLoaded.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* <div class="ug-tabs" data-ug-tabs>
|
|
9
|
+
* <ul class="ug-tabs__nav">
|
|
10
|
+
* <li class="ug-tabs__item">
|
|
11
|
+
* <button class="ug-tabs__link ug-tabs__link--active" data-ug-tab="tab1">Tab 1</button>
|
|
12
|
+
* </li>
|
|
13
|
+
* </ul>
|
|
14
|
+
* <div class="ug-tabs__content">
|
|
15
|
+
* <div class="ug-tabs__panel ug-tabs__panel--active" data-ug-panel="tab1">...</div>
|
|
16
|
+
* </div>
|
|
17
|
+
* </div>
|
|
18
|
+
*/
|
|
19
|
+
(function () {
|
|
20
|
+
function init() {
|
|
21
|
+
document.addEventListener('click', function (e) {
|
|
22
|
+
var link = e.target.closest('[data-ug-tab]');
|
|
23
|
+
if (!link) return;
|
|
24
|
+
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
|
|
27
|
+
var tabs = link.closest('.ug-tabs');
|
|
28
|
+
if (!tabs) return;
|
|
29
|
+
|
|
30
|
+
var target = link.getAttribute('data-ug-tab');
|
|
31
|
+
|
|
32
|
+
// Deactivate all links
|
|
33
|
+
tabs.querySelectorAll('.ug-tabs__link').forEach(function (l) {
|
|
34
|
+
l.classList.remove('ug-tabs__link--active');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Deactivate all panels
|
|
38
|
+
tabs.querySelectorAll('.ug-tabs__panel').forEach(function (p) {
|
|
39
|
+
p.classList.remove('ug-tabs__panel--active');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Activate clicked link
|
|
43
|
+
link.classList.add('ug-tabs__link--active');
|
|
44
|
+
|
|
45
|
+
// Activate matching panel
|
|
46
|
+
var panel = tabs.querySelector('[data-ug-panel="' + target + '"]');
|
|
47
|
+
if (panel) {
|
|
48
|
+
panel.classList.add('ug-tabs__panel--active');
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (document.readyState === 'loading') {
|
|
54
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
55
|
+
} else {
|
|
56
|
+
init();
|
|
57
|
+
}
|
|
58
|
+
})();
|