carnationpoints 1.0.0 → 1.0.4

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 CHANGED
@@ -1,29 +1,125 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta
7
- name="keywords"
8
- content="responsive breakpoints, responsive design, viewport Breakpoints, Adaptive Breakpoints, breakpoints, media queries, window resize,custom breakpoint, layout breakpoints, dynamic breakpoints javascript,mobile first,Flex Breakpoints"
9
- />
10
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/9000.0.1/themes/prism.min.css" />
11
- <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/9000.0.1/prism.min.js"></script>
12
- </head>
13
-
14
- <body>
15
- <h1 style>Carnation Breakpoints</h1>
16
- <h2>Notes</h2>
17
- <p>This is pure javascript plugin no require jquery dependance. this plugin help to easiest work with use. </p>
18
- <p>A lightweight JavaScript breakpoint solution to detect screen sizes, handle window resize events, and build responsive web layouts</p>
19
- <p>No need css</p>
20
- <div class="codebox box">
21
- <div class="use-snippet">
22
- <h3 class="section-title">Define carnationPoints()</h3>
23
- <pre class="language-javascript">
24
- const points = carnationPoints(".myBox");
25
- </pre>
26
- </div>
27
- </div>
28
- </body>
29
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta
7
+ name="keywords"
8
+ content="responsive breakpoints, responsive design, viewport Breakpoints, Adaptive Breakpoints, breakpoints, media queries, window resize,custom breakpoint, layout breakpoints, dynamic breakpoints javascript,mobile first,Flex Breakpoints"
9
+ />
10
+ </head>
11
+ <body>
12
+ <h1>Carnation Breakpoints</h1>
13
+ <h2>Notes</h2>
14
+ <p>This is pure javascript plugin no require jquery dependency. </p>
15
+ <p>Carnation Breakpoints is a lightweight JavaScript plugin that helps you manage responsive breakpoints in your web applications. It allows you to define custom breakpoints, listen for changes in viewport size, and execute callback functions when the viewport enters or exits specific breakpoints.</p>
16
+
17
+ <h3>Package Managers</h3>
18
+ <p>https://www.npmjs.com/package/carnationpoints</p>
19
+
20
+ ```js
21
+ # NPM
22
+ npm i carnationpoints
23
+ ```
24
+
25
+ <h3>Define carnationPoints()</h3>
26
+ <p>Returns detected layout points from the selected element.</p>
27
+
28
+ ```js
29
+ const points = carnationPoints(".myBox");
30
+ ```
31
+
32
+ <h3>Create Breakpoints</h3>
33
+ <p>Define your own breakpoints based on your layout requirements.</p>
34
+ <p>Supports custom min/max widths for mobile, tablet, desktop, or any device range.</p>
35
+
36
+ ```js
37
+ const points = carnationPoints(".myBox", {
38
+ breakpoints: [
39
+ { name: "mobile", max: 767 },
40
+ { name: "tablet", min: 768, max: 1023 },
41
+ { name: "desktop", min: 1024 },
42
+ ],
43
+ });
44
+ ```
45
+ <h3>Get Breakpoint on Init</h3>
46
+ <p>Initializes layout detection using custom breakpoints.</p>
47
+ <p>Triggers onInit callback with the active breakpoint on load.</p>
48
+
49
+ ```js
50
+ const points = carnationPoints(".myBox", {
51
+ breakpoints: [
52
+ { name: "mobile", max: 767 },
53
+ { name: "tablet", min: 768, max: 1023 },
54
+ { name: "desktop", min: 1024 },
55
+ ],
56
+ onInit(point) {
57
+ console.log("Init:", point.breakpoint);
58
+ },
59
+ });
60
+ ```
61
+
62
+ <h3>Get Breakpoint on Resize</h3>
63
+ <p>Detects layout changes using custom breakpoints.</p>
64
+ <p>Triggers onChange callback when the active breakpoint changes on resize.</p>
65
+
66
+ ```js
67
+ const points = carnationPoints(".myBox", {
68
+ breakpoints: [
69
+ { name: "mobile", max: 767 },
70
+ { name: "tablet", min: 768, max: 1023 },
71
+ { name: "desktop", min: 1024 },
72
+ ],
73
+ onChange(point) {
74
+ console.log("Resize:", point.breakpoint);
75
+ },
76
+ });
77
+ ```
78
+
79
+ <h3>Add new breakpoints</h3>
80
+ <p>Adds additional custom breakpoints dynamically using addPoint.</p>
81
+
82
+ ```js
83
+ const points = carnationPoints(".myBox", {
84
+ breakpoints: [
85
+ { name: "mobile", max: 767 },
86
+ { name: "tablet", min: 768, max: 1023 },
87
+ { name: "desktop", min: 1024 },
88
+ ],
89
+ });
90
+
91
+ points.addPoint([
92
+ { name: "lg", min: 1200 },
93
+ { name: "xl", min: 1600 },
94
+ ]);
95
+ ```
96
+
97
+ <h3>Destroy breakpoints</h3>
98
+ <p>Cleans up listeners and removes all breakpoint observers using destroy.</p>
99
+
100
+ ```js
101
+ const points = carnationPoints(".myBox", {
102
+ breakpoints: [
103
+ { name: "mobile", max: 767 },
104
+ { name: "tablet", min: 768, max: 1023 },
105
+ { name: "desktop", min: 1024 },
106
+ ],
107
+ });
108
+
109
+ points.destroy();
110
+ ```
111
+
112
+ <h3>Use Event</h3>
113
+ <p>Listens for breakpoint change events on the target element.</p>
114
+ <p>Executes logic when the active breakpoint changes.</p>
115
+
116
+ ```js
117
+ points.el.addEventListener("breakpoint:change", function (e) {
118
+ if (e.detail.breakpoint === "mobile") {
119
+ console.log("Mobile active");
120
+ }
121
+ });
122
+ ```
123
+
124
+ </body>
125
+ </html>
package/css/style.css CHANGED
@@ -117,4 +117,14 @@ code[class*=language-], pre[class*=language-] {
117
117
  -moz-tab-size: 1;
118
118
  -o-tab-size: 1;
119
119
  -webkit-tab-size: 1;
120
+ }
121
+ .description {
122
+ padding-bottom: 8px;
123
+ margin: 0
124
+ }
125
+ .description p{
126
+ text-align: center;
127
+ font-size: 16px;
128
+ padding: 0;
129
+ margin: 8px 0px;
120
130
  }
@@ -2,40 +2,47 @@
2
2
  "use strict";
3
3
 
4
4
  function carnationPoints(target, options = {}) {
5
- return new point(target, options);
5
+ return new Point(target, options);
6
6
  }
7
7
 
8
- function point(target, options) {
8
+ function Point(target, options) {
9
9
  this.el =
10
10
  typeof target === "string" ? document.querySelector(target) : target;
11
11
 
12
12
  if (!this.el) {
13
- console.warn("Breakpoints: element not found");
13
+ console.warn("Breakpoints: element not found ");
14
14
  return;
15
15
  }
16
16
 
17
+ // ---- defaults (CONFIG ONLY)
17
18
  this.defaults = {
18
19
  debug: false,
19
20
  speed: 300,
20
21
  onInit: null,
21
22
  onChange: null,
22
23
  breakpoints: [],
23
- destroyed: false,
24
24
  };
25
25
 
26
+ // ---- merge options
26
27
  this.options = { ...this.defaults, ...options };
27
28
 
29
+ // ---- runtime state
28
30
  this.state = {
29
31
  initialized: false,
32
+ destroyed: false,
33
+ breakpoint: null,
30
34
  };
31
35
 
36
+ // bind once
32
37
  this._onResize = this._onResize.bind(this);
33
38
 
34
39
  this.init();
35
40
  }
36
41
 
37
- point.prototype.init = function () {
38
- if (this.state.initialized || this.options.destroyed) return;
42
+ /* ---------------- INIT ---------------- */
43
+
44
+ Point.prototype.init = function () {
45
+ if (this.state.initialized || this.state.destroyed) return;
39
46
 
40
47
  this.state.initialized = true;
41
48
 
@@ -48,49 +55,66 @@
48
55
  width,
49
56
  breakpoint: this.state.breakpoint,
50
57
  element: this.el,
51
- destroyed: this.options.destroyed,
58
+ instance: this,
52
59
  });
53
60
 
54
61
  this._log("initialized");
55
62
  };
56
63
 
57
- point.prototype._onResize = function () {
58
- if (this.options.destroyed === true) return;
64
+ /* ---------------- RESIZE ---------------- */
65
+
66
+ Point.prototype._onResize = function () {
67
+ if (this.state.destroyed) return;
59
68
 
60
69
  const width = this._getWidth();
61
70
  const newBreakpoint = this._getActiveBreakpoint(width);
62
71
 
63
- // Only react if breakpoint changed
64
72
  if (newBreakpoint !== this.state.breakpoint) {
65
73
  const prev = this.state.breakpoint;
66
74
  this.state.breakpoint = newBreakpoint;
67
75
 
76
+ const event = new CustomEvent("breakpoint:change", {
77
+ detail: {
78
+ breakpoint: newBreakpoint,
79
+ previous: prev,
80
+ width,
81
+ element: this.el,
82
+ instance: this,
83
+ },
84
+ bubbles: true,
85
+ });
86
+
87
+ this.el.dispatchEvent(event);
88
+
68
89
  this._emit("onChange", {
69
90
  width,
70
91
  breakpoint: newBreakpoint,
92
+ previous: prev,
71
93
  element: this.el,
72
- destroyed: this.options.destroyed,
94
+ instance: this,
73
95
  });
74
96
  }
75
97
  };
76
98
 
77
- point.prototype._emit = function (callbackName, data) {
99
+ /* ---------------- HELPERS ---------------- */
100
+
101
+ Point.prototype._emit = function (callbackName, data) {
78
102
  if (typeof this.options[callbackName] === "function") {
79
103
  this.options[callbackName](data);
80
104
  }
81
105
  };
82
106
 
83
- point.prototype._log = function (...args) {
107
+ Point.prototype._log = function (...args) {
84
108
  if (this.options.debug) {
85
109
  console.log("Breakpoints:", ...args);
86
110
  }
87
111
  };
88
112
 
89
- point.prototype._getWidth = function () {
113
+ Point.prototype._getWidth = function () {
90
114
  return window.innerWidth;
91
115
  };
92
116
 
93
- point.prototype._getActiveBreakpoint = function (width) {
117
+ Point.prototype._getActiveBreakpoint = function (width) {
94
118
  let active = null;
95
119
 
96
120
  this.options.breakpoints.forEach((bp) => {
@@ -105,13 +129,14 @@
105
129
  return active;
106
130
  };
107
131
 
108
- point.prototype.addPoint = function (bps = []) {
109
- //if (!bp || typeof bp !== "object") return;
132
+ /* ---------------- PUBLIC API ---------------- */
133
+
134
+ Point.prototype.addPoint = function (bps = []) {
135
+ if (this.state.destroyed) return;
110
136
  if (!Array.isArray(bps)) return;
111
137
 
112
138
  this.options.breakpoints.push(...bps);
113
139
 
114
- // Recalculate breakpoint
115
140
  const width = this._getWidth();
116
141
  const newBreakpoint = this._getActiveBreakpoint(width);
117
142
 
@@ -124,33 +149,37 @@
124
149
  breakpoint: newBreakpoint,
125
150
  previous: prev,
126
151
  element: this.el,
127
- destroyed: this.options.destroyed,
152
+ instance: this,
128
153
  });
129
154
  }
130
155
 
131
- this._log("point added", bps);
156
+ this._log("points added", bps);
132
157
  };
133
158
 
134
- point.prototype.destroy = function () {
135
- window.removeEventListener("resize", this._onResize);
159
+ Point.prototype.getBreakpoint = function () {
160
+ return this.state.breakpoint;
161
+ };
136
162
 
137
- this.options.breakpoints = [];
163
+ /* ---------------- DESTROY ---------------- */
138
164
 
139
- this.options.destroyed = true;
165
+ Point.prototype.destroy = function () {
166
+ if (this.state.destroyed) return;
140
167
 
141
- this.state.breakpoint = null;
168
+ window.removeEventListener("resize", this._onResize);
169
+
170
+ this.state.destroyed = true;
142
171
  this.state.initialized = false;
172
+ this.state.breakpoint = null;
143
173
 
174
+ this.options.breakpoints.length = 0;
144
175
  this.options.onChange = null;
145
176
  this.options.onInit = null;
146
177
 
147
- this._log("destroyed and breakpoints cleared");
148
- console.warn("Breakpoints: destroyed & cleared");
178
+ this._log("destroyed");
179
+ console.warn("Breakpoints: destroyed");
149
180
  };
150
181
 
151
- point.prototype.getBreakpoint = function () {
152
- return this.state.breakpoint;
153
- };
182
+ /* ---------------- EXPORT ---------------- */
154
183
 
155
184
  window.carnationPoints = carnationPoints;
156
185
  })(window, document);
@@ -0,0 +1 @@
1
+ ((e,i)=>{function n(t,e){this.el="string"==typeof t?i.querySelector(t):t,this.el?(this.defaults={debug:!1,speed:300,onInit:null,onChange:null,breakpoints:[]},this.options={...this.defaults,...e},this.state={initialized:!1,destroyed:!1,breakpoint:null},this._onResize=this._onResize.bind(this),this.init()):console.warn("Breakpoints: element not found ")}n.prototype.init=function(){var t;this.state.initialized||this.state.destroyed||(this.state.initialized=!0,t=this._getWidth(),this.state.breakpoint=this._getActiveBreakpoint(t),e.addEventListener("resize",this._onResize),this._emit("onInit",{width:t,breakpoint:this.state.breakpoint,element:this.el,instance:this}),this._log("initialized"))},n.prototype._onResize=function(){var t,e,i,n;this.state.destroyed||(t=this._getWidth(),(e=this._getActiveBreakpoint(t))!==this.state.breakpoint&&(i=this.state.breakpoint,this.state.breakpoint=e,n=new CustomEvent("breakpoint:change",{detail:{breakpoint:e,previous:i,width:t,element:this.el,instance:this},bubbles:!0}),this.el.dispatchEvent(n),this._emit("onChange",{width:t,breakpoint:e,previous:i,element:this.el,instance:this})))},n.prototype._emit=function(t,e){"function"==typeof this.options[t]&&this.options[t](e)},n.prototype._log=function(...t){this.options.debug&&console.log("Breakpoints:",...t)},n.prototype._getWidth=function(){return e.innerWidth},n.prototype._getActiveBreakpoint=function(n){let s=null;return this.options.breakpoints.forEach(t=>{var e=t.min??0,i=t.max??1/0;e<=n&&n<=i&&(s=t.name??e+"-"+i)}),s},n.prototype.addPoint=function(t=[]){var e,i,n;this.state.destroyed||Array.isArray(t)&&(this.options.breakpoints.push(...t),e=this._getWidth(),(i=this._getActiveBreakpoint(e))!==this.state.breakpoint&&(n=this.state.breakpoint,this.state.breakpoint=i,this._emit("onChange",{width:e,breakpoint:i,previous:n,element:this.el,instance:this})),this._log("points added",t))},n.prototype.getBreakpoint=function(){return this.state.breakpoint},n.prototype.destroy=function(){this.state.destroyed||(e.removeEventListener("resize",this._onResize),this.state.destroyed=!0,this.state.initialized=!1,this.state.breakpoint=null,this.options.breakpoints.length=0,this.options.onChange=null,this.options.onInit=null,this._log("destroyed"),console.warn("Breakpoints: destroyed"))},e.carnationPoints=function(t,e={}){return new n(t,e)}})(window,document);
package/index.html CHANGED
@@ -26,7 +26,7 @@
26
26
  “Responsive States — Know exactly where your layout stands.”
27
27
  </div>
28
28
  </header>
29
- <!-- INITIAL PHP RENDER -->
29
+
30
30
  <div class="myBox">
31
31
  <p>Resize window</p>
32
32
  <div id="myBox">Example: none</div>
@@ -42,10 +42,14 @@
42
42
  </h1>
43
43
  </blockquote>
44
44
  </div>
45
+
45
46
  <!-- codebox 1 -->
46
47
  <div class="codebox box">
47
48
  <div class="use-snippet">
48
49
  <h3 class="section-title">Define carnationPoints()</h3>
50
+ <div class="description">
51
+ <p>Returns detected layout points from the selected element.</p>
52
+ </div>
49
53
  <pre class="language-javascript">
50
54
  <code class="language-javascript">
51
55
  const points = carnationPoints(".myBox");
@@ -57,6 +61,13 @@
57
61
  <div class="codebox">
58
62
  <div class="use-snippet">
59
63
  <h3 class="section-title">Create Breakpoints</h3>
64
+ <div class="description">
65
+ <p>Define your own breakpoints based on your layout requirements.</p>
66
+ <p>
67
+ Supports custom min/max widths for mobile, tablet, desktop, or any
68
+ device range.
69
+ </p>
70
+ </div>
60
71
  <pre class="language-javascript">
61
72
  <code class="language-javascript">
62
73
  const points = carnationPoints(".myBox", {
@@ -74,6 +85,13 @@
74
85
  <div class="codebox">
75
86
  <div class="use-snippet">
76
87
  <h3 class="section-title">Get Breakpoint on Init</h3>
88
+ <div class="description">
89
+ <p>Initializes layout detection using custom breakpoints.</p>
90
+ <p>
91
+ Triggers <strong>onInit callback</strong> with the active breakpoint
92
+ on load.
93
+ </p>
94
+ </div>
77
95
  <pre class="language-javascript">
78
96
  <code class="language-javascript">
79
97
  const points = carnationPoints(".myBox", {
@@ -94,6 +112,13 @@
94
112
  <div class="codebox">
95
113
  <div class="use-snippet">
96
114
  <h3 class="section-title">Get Breakpoint on Resize</h3>
115
+ <div class="description">
116
+ <p>Detects layout changes using custom breakpoints.</p>
117
+ <p>
118
+ Triggers <strong>onChange callback</strong> when the active
119
+ breakpoint changes on resize.
120
+ </p>
121
+ </div>
97
122
  <pre class="language-javascript">
98
123
  <code class="language-javascript">
99
124
  const points = carnationPoints(".myBox", {
@@ -114,6 +139,9 @@
114
139
  <div class="codebox">
115
140
  <div class="use-snippet">
116
141
  <h3 class="section-title">Add new breakpoints</h3>
142
+ <div class="description">
143
+ <p>Adds additional custom breakpoints dynamically using addPoint.</p>
144
+ </div>
117
145
  <pre class="language-javascript">
118
146
  <code class="language-javascript">
119
147
  const points = carnationPoints(".myBox", {
@@ -136,6 +164,12 @@
136
164
  <div class="codebox">
137
165
  <div class="use-snippet">
138
166
  <h3 class="section-title">Destroy breakpoints</h3>
167
+ <div class="description">
168
+ <p>
169
+ Cleans up listeners and removes all breakpoint observers using
170
+ destroy.
171
+ </p>
172
+ </div>
139
173
  <pre class="language-javascript">
140
174
  <code class="language-javascript">
141
175
  const points = carnationPoints(".myBox", {
@@ -155,6 +189,12 @@
155
189
  <div class="codebox">
156
190
  <div class="use-snippet">
157
191
  <h3 class="section-title">Get Breakpoints</h3>
192
+ <div class="description">
193
+ <p>
194
+ Checks the current active breakpoint using
195
+ <strong>getBreakpoint()</strong>.
196
+ </p>
197
+ </div>
158
198
  <pre class="language-javascript">
159
199
  <code class="language-javascript">
160
200
  const points = carnationPoints(".myBox", {
@@ -177,39 +217,56 @@
177
217
  <!-- codebox 8 -->
178
218
  <div class="codebox">
179
219
  <div class="use-snippet">
180
- <h3 class="section-title">Different way usage</h3>
220
+ <h3 class="section-title">Use Event</h3>
221
+ <div class="description">
222
+ <p>Listens for breakpoint change events on the target element.</p>
223
+ <p>Executes logic when the active breakpoint changes.</p>
224
+ </div>
181
225
  <pre class="language-javascript">
182
226
  <code class="language-javascript">
183
- const points = carnationPoints("#myBox", {
184
- debug: true,
185
- breakpoints: [
186
- { name: "mobile", max: 767 },
187
- { name: "tablet", min: 768, max: 1023 },
188
- { name: "desktop", min: 1024 },
189
- ],
190
- onInit(point) {
191
- if (point.breakpoint) {
192
- document.querySelector(
193
- "#myBox"
194
- ).textContent = `Example: ${point.breakpoint}`;
195
- }
196
- },
197
- onChange(point) {
198
- document.querySelector(
199
- "#myBox"
200
- ).textContent = `Example: ${point.breakpoint}`;
201
- },
227
+ points.el.addEventListener("breakpoint:change", function (e) {
228
+ if (e.detail.breakpoint === "mobile") {
229
+ console.log("Mobile active");
230
+ }
202
231
  });
203
232
  </code>
204
233
  </pre>
205
234
  </div>
206
235
  </div>
236
+ <!-- codebox 9 -->
237
+ <div class="codebox box">
238
+ <div class="use-snippet">
239
+ <div class="description">
240
+ <h3 class="section-title">Github</h3>
241
+ <p>
242
+ <a
243
+ href="https://github.com/Hitesh82/carnationpoints"
244
+ target="_blank"
245
+ >https://github.com/Hitesh82/carnationpoints</a
246
+ >
247
+ </p>
248
+ <h3 class="section-title">Npm</h3>
249
+ <p>
250
+ <a
251
+ href="https://www.npmjs.com/package/carnationpoints"
252
+ target="_blank"
253
+ >https://www.npmjs.com/package/carnationpoints</a
254
+ >
255
+ </p>
256
+ </div>
257
+ <pre class="language-javascript">
258
+ <code class="language-javascript">
259
+ npm i carnationpoints
260
+ </code>
261
+ </pre>
262
+ </div>
263
+ </div>
207
264
  <footer class="footer">
208
265
  <p>Support</p>
209
266
  Hitesh R Patel :-
210
267
  <a href="mailto:hitesh.gopal@gmail.com">hitesh.gopal@gmail.com</a>
211
268
  </footer>
212
- <script src="./carnationpoints/carnationpoints.js"></script>
269
+ <script src="./dist/carnationpoints.js"></script>
213
270
  <script src="./js/script.js"></script>
214
271
  </body>
215
272
  </html>
package/js/script.js CHANGED
@@ -12,9 +12,9 @@ const points = carnationPoints("#myBox", {
12
12
  }
13
13
  },
14
14
  onChange(point) {
15
- //console.log("Breakpoint changed to:", point.breakpoint);
16
15
  document.querySelector(
17
16
  "#myBox"
18
17
  ).textContent = `Example: ${point.breakpoint}`;
19
18
  },
20
19
  });
20
+ //console.log()
package/package.json CHANGED
@@ -1,15 +1,25 @@
1
1
  {
2
2
  "name": "carnationpoints",
3
- "version": "1.0.0",
3
+ "version": "1.0.4",
4
4
  "description": "Responsive Breakpoints",
5
- "main": "index.js",
5
+ "main": "dist/carnationpoints.js",
6
6
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
7
+ "dev": "gulp",
8
+ "build": "gulp build",
9
+ "prepublishOnly": "npm run build"
8
10
  },
9
11
  "repository": {
10
12
  "type": "git",
11
13
  "url": "git+https://github.com/Hitesh82/carnationpoints.git"
12
14
  },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "index.html",
19
+ "css",
20
+ "js",
21
+ "src"
22
+ ],
13
23
  "keywords": [
14
24
  "responsive",
15
25
  "breakpoints",
@@ -36,10 +46,26 @@
36
46
  "Flex",
37
47
  "Breakpoints"
38
48
  ],
39
- "author": "Hitesh Patel",
49
+ "author": "Hitesh Patel <hitesh.gopal@gmail.com>",
50
+ "contributors": [
51
+ {
52
+ "name": "Hitesh Patel",
53
+ "email": "hitesh.gopal@gmail.com",
54
+ "url": "https://github.com/Hitesh82"
55
+ }
56
+ ],
40
57
  "license": "ISC",
41
58
  "bugs": {
42
59
  "url": "https://github.com/Hitesh82/carnationpoints/issues"
43
60
  },
44
- "homepage": "https://github.com/Hitesh82/carnationpoints#readme"
61
+ "homepage": "https://github.com/Hitesh82/carnationpoints#readme",
62
+ "devDependencies": {
63
+ "gulp": "^5.0.1",
64
+ "gulp-concat": "^2.6.1",
65
+ "gulp-plumber": "^1.2.1",
66
+ "gulp-rename": "^2.1.0",
67
+ "gulp-sass": "^6.0.1",
68
+ "gulp-uglify": "^3.0.2",
69
+ "sass": "^1.97.1"
70
+ }
45
71
  }
@@ -0,0 +1,185 @@
1
+ (function (window, document) {
2
+ "use strict";
3
+
4
+ function carnationPoints(target, options = {}) {
5
+ return new Point(target, options);
6
+ }
7
+
8
+ function Point(target, options) {
9
+ this.el =
10
+ typeof target === "string" ? document.querySelector(target) : target;
11
+
12
+ if (!this.el) {
13
+ console.warn("Breakpoints: element not found ");
14
+ return;
15
+ }
16
+
17
+ // ---- defaults (CONFIG ONLY)
18
+ this.defaults = {
19
+ debug: false,
20
+ speed: 300,
21
+ onInit: null,
22
+ onChange: null,
23
+ breakpoints: [],
24
+ };
25
+
26
+ // ---- merge options
27
+ this.options = { ...this.defaults, ...options };
28
+
29
+ // ---- runtime state
30
+ this.state = {
31
+ initialized: false,
32
+ destroyed: false,
33
+ breakpoint: null,
34
+ };
35
+
36
+ // bind once
37
+ this._onResize = this._onResize.bind(this);
38
+
39
+ this.init();
40
+ }
41
+
42
+ /* ---------------- INIT ---------------- */
43
+
44
+ Point.prototype.init = function () {
45
+ if (this.state.initialized || this.state.destroyed) return;
46
+
47
+ this.state.initialized = true;
48
+
49
+ const width = this._getWidth();
50
+ this.state.breakpoint = this._getActiveBreakpoint(width);
51
+
52
+ window.addEventListener("resize", this._onResize);
53
+
54
+ this._emit("onInit", {
55
+ width,
56
+ breakpoint: this.state.breakpoint,
57
+ element: this.el,
58
+ instance: this,
59
+ });
60
+
61
+ this._log("initialized");
62
+ };
63
+
64
+ /* ---------------- RESIZE ---------------- */
65
+
66
+ Point.prototype._onResize = function () {
67
+ if (this.state.destroyed) return;
68
+
69
+ const width = this._getWidth();
70
+ const newBreakpoint = this._getActiveBreakpoint(width);
71
+
72
+ if (newBreakpoint !== this.state.breakpoint) {
73
+ const prev = this.state.breakpoint;
74
+ this.state.breakpoint = newBreakpoint;
75
+
76
+ const event = new CustomEvent("breakpoint:change", {
77
+ detail: {
78
+ breakpoint: newBreakpoint,
79
+ previous: prev,
80
+ width,
81
+ element: this.el,
82
+ instance: this,
83
+ },
84
+ bubbles: true,
85
+ });
86
+
87
+ this.el.dispatchEvent(event);
88
+
89
+ this._emit("onChange", {
90
+ width,
91
+ breakpoint: newBreakpoint,
92
+ previous: prev,
93
+ element: this.el,
94
+ instance: this,
95
+ });
96
+ }
97
+ };
98
+
99
+ /* ---------------- HELPERS ---------------- */
100
+
101
+ Point.prototype._emit = function (callbackName, data) {
102
+ if (typeof this.options[callbackName] === "function") {
103
+ this.options[callbackName](data);
104
+ }
105
+ };
106
+
107
+ Point.prototype._log = function (...args) {
108
+ if (this.options.debug) {
109
+ console.log("Breakpoints:", ...args);
110
+ }
111
+ };
112
+
113
+ Point.prototype._getWidth = function () {
114
+ return window.innerWidth;
115
+ };
116
+
117
+ Point.prototype._getActiveBreakpoint = function (width) {
118
+ let active = null;
119
+
120
+ this.options.breakpoints.forEach((bp) => {
121
+ const min = bp.min ?? 0;
122
+ const max = bp.max ?? Infinity;
123
+
124
+ if (width >= min && width <= max) {
125
+ active = bp.name ?? `${min}-${max}`;
126
+ }
127
+ });
128
+
129
+ return active;
130
+ };
131
+
132
+ /* ---------------- PUBLIC API ---------------- */
133
+
134
+ Point.prototype.addPoint = function (bps = []) {
135
+ if (this.state.destroyed) return;
136
+ if (!Array.isArray(bps)) return;
137
+
138
+ this.options.breakpoints.push(...bps);
139
+
140
+ const width = this._getWidth();
141
+ const newBreakpoint = this._getActiveBreakpoint(width);
142
+
143
+ if (newBreakpoint !== this.state.breakpoint) {
144
+ const prev = this.state.breakpoint;
145
+ this.state.breakpoint = newBreakpoint;
146
+
147
+ this._emit("onChange", {
148
+ width,
149
+ breakpoint: newBreakpoint,
150
+ previous: prev,
151
+ element: this.el,
152
+ instance: this,
153
+ });
154
+ }
155
+
156
+ this._log("points added", bps);
157
+ };
158
+
159
+ Point.prototype.getBreakpoint = function () {
160
+ return this.state.breakpoint;
161
+ };
162
+
163
+ /* ---------------- DESTROY ---------------- */
164
+
165
+ Point.prototype.destroy = function () {
166
+ if (this.state.destroyed) return;
167
+
168
+ window.removeEventListener("resize", this._onResize);
169
+
170
+ this.state.destroyed = true;
171
+ this.state.initialized = false;
172
+ this.state.breakpoint = null;
173
+
174
+ this.options.breakpoints.length = 0;
175
+ this.options.onChange = null;
176
+ this.options.onInit = null;
177
+
178
+ this._log("destroyed");
179
+ console.warn("Breakpoints: destroyed");
180
+ };
181
+
182
+ /* ---------------- EXPORT ---------------- */
183
+
184
+ window.carnationPoints = carnationPoints;
185
+ })(window, document);