@medcore-ua/concrete-css 1.4.0 → 1.4.2

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/concrete.js CHANGED
@@ -1,129 +1,114 @@
1
- /**
2
- * Concrete CSS - JavaScript Components
3
- * Minimal JavaScript for interactive components
4
- */
5
-
6
- (function() {
7
- 'use strict';
8
-
9
- const Concrete = {
10
- init: function() {
11
- this.initNavToggle();
12
- this.initAccordion();
13
- this.initDetailsAccordion();
14
- this.initSmoothScroll();
15
- },
16
-
17
- /**
18
- * Mobile Navigation Toggle
19
- */
20
- initNavToggle: function() {
21
- const toggles = document.querySelectorAll('.nav-toggle');
22
-
23
- toggles.forEach(toggle => {
24
- toggle.addEventListener('click', function() {
25
- const nav = this.parentElement.querySelector('.nav');
26
- if (nav) {
27
- nav.classList.toggle('open');
28
- this.setAttribute('aria-expanded',
29
- nav.classList.contains('open') ? 'true' : 'false'
30
- );
31
- }
32
- });
1
+ (() => {
2
+ // js/components/nav.js
3
+ function initNavToggle() {
4
+ const toggles = document.querySelectorAll(".nav-toggle");
5
+ toggles.forEach((toggle) => {
6
+ toggle.addEventListener("click", function() {
7
+ const nav = this.parentElement.querySelector(".nav");
8
+ if (nav) {
9
+ nav.classList.toggle("open");
10
+ this.setAttribute(
11
+ "aria-expanded",
12
+ nav.classList.contains("open") ? "true" : "false"
13
+ );
14
+ }
33
15
  });
16
+ });
17
+ document.addEventListener("click", function(e) {
18
+ const navs = document.querySelectorAll(".nav.open");
19
+ navs.forEach((nav) => {
20
+ const toggle = nav.parentElement.querySelector(".nav-toggle");
21
+ if (toggle && !nav.contains(e.target) && !toggle.contains(e.target)) {
22
+ nav.classList.remove("open");
23
+ toggle.setAttribute("aria-expanded", "false");
24
+ }
25
+ });
26
+ });
27
+ }
34
28
 
35
- document.addEventListener('click', function(e) {
36
- const navs = document.querySelectorAll('.nav.open');
37
- navs.forEach(nav => {
38
- const toggle = nav.parentElement.querySelector('.nav-toggle');
39
- if (toggle && !nav.contains(e.target) && !toggle.contains(e.target)) {
40
- nav.classList.remove('open');
41
- toggle.setAttribute('aria-expanded', 'false');
29
+ // js/components/accordion.js
30
+ function initAccordion() {
31
+ const triggers = document.querySelectorAll(".accordion-trigger");
32
+ triggers.forEach((trigger) => {
33
+ if (trigger.tagName === "BUTTON") {
34
+ trigger.addEventListener("click", function() {
35
+ const container = this.closest("[data-accordion-mode]") || this.closest(".accordion-container");
36
+ const mode = container ? container.getAttribute("data-accordion-mode") : "multiple";
37
+ let content = this.nextElementSibling;
38
+ if (!content || !content.classList.contains("accordion-content")) {
39
+ content = this.parentElement.querySelector(".accordion-content");
40
+ }
41
+ if (mode === "single") {
42
+ const allTriggers = container.querySelectorAll(".accordion-trigger");
43
+ allTriggers.forEach((t) => {
44
+ let c = t.nextElementSibling;
45
+ if (!c || !c.classList.contains("accordion-content")) {
46
+ c = t.parentElement.querySelector(".accordion-content");
47
+ }
48
+ if (c !== content) c.classList.remove("open");
49
+ });
50
+ content.classList.toggle("open");
51
+ } else {
52
+ content.classList.toggle("open");
42
53
  }
43
54
  });
55
+ }
56
+ });
57
+ }
58
+ function initDetailsAccordion() {
59
+ document.querySelectorAll("details").forEach((details) => {
60
+ details.addEventListener("toggle", function() {
61
+ if (this.open) {
62
+ const container = this.closest("[data-accordion-mode]");
63
+ const mode = container ? container.getAttribute("data-accordion-mode") : "multiple";
64
+ if (mode === "single") {
65
+ const all = container.querySelectorAll("details[open]");
66
+ all.forEach((d) => {
67
+ if (d !== this) d.removeAttribute("open");
68
+ });
69
+ }
70
+ }
44
71
  });
45
- },
72
+ });
73
+ }
46
74
 
47
- /**
48
- * Accordion Toggle (JS-based)
49
- * Works with .accordion-trigger and .accordion-content
50
- */
51
- initAccordion: function() {
52
- const triggers = document.querySelectorAll('.accordion-trigger');
53
-
54
- triggers.forEach(trigger => {
55
- if (trigger.tagName === 'BUTTON') {
56
- trigger.addEventListener('click', function() {
57
- const container = this.closest('[data-accordion-mode]') || this.closest('.accordion-container');
58
- const mode = container ? container.getAttribute('data-accordion-mode') : 'multiple';
59
-
60
- // Find the content element (next sibling or inside container)
61
- let content = this.nextElementSibling;
62
- if (!content || !content.classList.contains('accordion-content')) {
63
- content = this.parentElement.querySelector('.accordion-content');
64
- }
65
-
66
- if (mode === 'single') {
67
- const allTriggers = container.querySelectorAll('.accordion-trigger');
68
- allTriggers.forEach(t => {
69
- let c = t.nextElementSibling;
70
- if (!c || !c.classList.contains('accordion-content')) {
71
- c = t.parentElement.querySelector('.accordion-content');
72
- }
73
- if (c !== content) c.classList.remove('open');
74
- });
75
- content.classList.toggle('open');
76
- } else {
77
- content.classList.toggle('open');
78
- }
75
+ // js/components/smooth-scroll.js
76
+ function initSmoothScroll() {
77
+ document.querySelectorAll("[data-scroll-target]").forEach((anchor) => {
78
+ anchor.addEventListener("click", function(e) {
79
+ const targetId = this.getAttribute("data-scroll-target");
80
+ const target = document.querySelector(targetId);
81
+ if (target) {
82
+ e.preventDefault();
83
+ target.scrollIntoView({
84
+ behavior: "smooth",
85
+ block: "start"
79
86
  });
80
87
  }
81
88
  });
82
- },
83
-
84
- /**
85
- * Native Details Accordion
86
- * Single mode for details elements with .accordion-trigger
87
- */
88
- initDetailsAccordion: function() {
89
- document.querySelectorAll('details').forEach(details => {
90
- details.addEventListener('toggle', function() {
91
- if (this.open) {
92
- const container = this.closest('[data-accordion-mode]');
93
- const mode = container ? container.getAttribute('data-accordion-mode') : 'multiple';
94
-
95
- if (mode === 'single') {
96
- const all = container.querySelectorAll('details[open]');
97
- all.forEach(d => {
98
- if (d !== this) d.removeAttribute('open');
99
- });
100
- }
101
- }
102
- });
103
- });
104
- },
89
+ });
90
+ }
105
91
 
106
- /**
107
- * Smooth Scroll
108
- */
109
- initSmoothScroll: function() {
110
- document.querySelectorAll('[data-scroll-target]').forEach(anchor => {
111
- anchor.addEventListener('click', function(e) {
112
- const targetId = this.getAttribute('data-scroll-target');
113
- const target = document.querySelector(targetId);
114
-
115
- if (target) {
116
- e.preventDefault();
117
- target.scrollIntoView({
118
- behavior: 'smooth',
119
- block: 'start'
120
- });
121
- }
122
- });
123
- });
124
- }
92
+ // js/index.js
93
+ var Concrete = {
94
+ init: function() {
95
+ this.initNavToggle();
96
+ this.initAccordion();
97
+ this.initDetailsAccordion();
98
+ this.initSmoothScroll();
99
+ },
100
+ initNavToggle,
101
+ initAccordion,
102
+ initDetailsAccordion,
103
+ initSmoothScroll
125
104
  };
126
-
127
- Concrete.init();
128
- window.Concrete = Concrete;
105
+ if (typeof window !== "undefined") {
106
+ if (document.readyState === "loading") {
107
+ document.addEventListener("DOMContentLoaded", () => Concrete.init());
108
+ } else {
109
+ Concrete.init();
110
+ }
111
+ window.Concrete = Concrete;
112
+ }
113
+ var index_default = Concrete;
129
114
  })();
@@ -0,0 +1 @@
1
+ (()=>{function a(){document.querySelectorAll(".nav-toggle").forEach(t=>{t.addEventListener("click",function(){let o=this.parentElement.querySelector(".nav");o&&(o.classList.toggle("open"),this.setAttribute("aria-expanded",o.classList.contains("open")?"true":"false"))})}),document.addEventListener("click",function(t){document.querySelectorAll(".nav.open").forEach(n=>{let e=n.parentElement.querySelector(".nav-toggle");e&&!n.contains(t.target)&&!e.contains(t.target)&&(n.classList.remove("open"),e.setAttribute("aria-expanded","false"))})})}function s(){document.querySelectorAll(".accordion-trigger").forEach(t=>{t.tagName==="BUTTON"&&t.addEventListener("click",function(){let o=this.closest("[data-accordion-mode]")||this.closest(".accordion-container"),n=o?o.getAttribute("data-accordion-mode"):"multiple",e=this.nextElementSibling;(!e||!e.classList.contains("accordion-content"))&&(e=this.parentElement.querySelector(".accordion-content")),n==="single"&&o.querySelectorAll(".accordion-trigger").forEach(l=>{let c=l.nextElementSibling;(!c||!c.classList.contains("accordion-content"))&&(c=l.parentElement.querySelector(".accordion-content")),c!==e&&c.classList.remove("open")}),e.classList.toggle("open")})})}function d(){document.querySelectorAll("details").forEach(i=>{i.addEventListener("toggle",function(){if(this.open){let t=this.closest("[data-accordion-mode]");(t?t.getAttribute("data-accordion-mode"):"multiple")==="single"&&t.querySelectorAll("details[open]").forEach(e=>{e!==this&&e.removeAttribute("open")})}})})}function g(){document.querySelectorAll("[data-scroll-target]").forEach(i=>{i.addEventListener("click",function(t){let o=this.getAttribute("data-scroll-target"),n=document.querySelector(o);n&&(t.preventDefault(),n.scrollIntoView({behavior:"smooth",block:"start"}))})})}var r={init:function(){this.initNavToggle(),this.initAccordion(),this.initDetailsAccordion(),this.initSmoothScroll()},initNavToggle:a,initAccordion:s,initDetailsAccordion:d,initSmoothScroll:g};typeof window<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>r.init()):r.init(),window.Concrete=r);var A=r;})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medcore-ua/concrete-css",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "A utility-first CSS framework for brutalist and minimalist interfaces.",
5
5
  "main": "dist/concrete.css",
6
6
  "sass": "scss/main.scss",
@@ -12,12 +12,16 @@
12
12
  "README.md"
13
13
  ],
14
14
  "scripts": {
15
- "build": "npx sass scss/main.scss dist/concrete.css --style=expanded",
16
- "build:min": "npx sass scss/main.scss dist/concrete.min.css --style=compressed",
15
+ "build": "npm run build:css && npm run build:js",
16
+ "build:min": "npm run build:css:min && npm run build:js:min",
17
17
  "watch": "npx sass scss/main.scss dist/concrete.css --watch",
18
18
  "dev": "npm run watch",
19
19
  "lint": "stylelint 'scss/**/*.scss'",
20
- "test": "echo \"Tests coming soon\" && exit 0"
20
+ "test": "echo \"Tests coming soon\" && exit 0",
21
+ "build:js": "esbuild js/index.js --bundle --outfile=dist/concrete.js",
22
+ "build:js:min": "esbuild js/index.js --bundle --minify --outfile=dist/concrete.min.js",
23
+ "build:css": "npx sass scss/main.scss dist/concrete.css --style=expanded",
24
+ "build:css:min": "npx sass scss/main.scss dist/concrete.min.css --style=compressed"
21
25
  },
22
26
  "repository": {
23
27
  "type": "git",
@@ -40,6 +44,7 @@
40
44
  },
41
45
  "homepage": "https://github.com/medcore-ua/concrete-css#readme",
42
46
  "devDependencies": {
47
+ "esbuild": "^0.28.2",
43
48
  "sass": "^1.69.0",
44
49
  "stylelint": "^17.4.0",
45
50
  "stylelint-config-standard-scss": "^17.0.0"