@kizmann/pico-js 2.0.6 → 2.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kizmann/pico-js",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "private": false,
@@ -130,6 +130,28 @@ export class PicoDomAttributeInstance
130
130
  value = { ...styles, ...value };
131
131
  }
132
132
 
133
+ if ( value.translate ) {
134
+ value.transform = `translate3d(${value.translate.join(',')}, 0)`;
135
+ }
136
+
137
+ delete value.translate;
138
+
139
+ if ( Mix.isNum(value.top) ) {
140
+ value.top += 'px';
141
+ }
142
+
143
+ if ( Mix.isNum(value.left) ) {
144
+ value.left += 'px';
145
+ }
146
+
147
+ if ( Mix.isNum(value.width) ) {
148
+ value.width += 'px';
149
+ }
150
+
151
+ if ( Mix.isNum(value.height) ) {
152
+ value.height += 'px';
153
+ }
154
+
133
155
  this.attr('style', value);
134
156
 
135
157
  return this;
@@ -100,9 +100,10 @@ export class PicoDomEventInstance
100
100
  options = { id: options };
101
101
  }
102
102
 
103
- if ( Mix.isArr(event) ) {
104
- return (Arr.each(event, (e) => this.on(e, ...arguments)), this);
105
- }
103
+ // geht so nicht
104
+ // if ( Mix.isArr(event) ) {
105
+ // return (Arr.each(event, (e) => this.on(e, cb, options, pause, selector)), this);
106
+ // }
106
107
 
107
108
  let fn = (e) => {
108
109
  cb.call(e.target, e, e.target);
@@ -127,10 +128,15 @@ export class PicoDomEventInstance
127
128
  */
128
129
  off(event, selector = null, options = {})
129
130
  {
130
- if ( Mix.isArr(event) ) {
131
- return (Arr.each(event, (e) => this.off(e, ...arguments)), this);
131
+ if ( Mix.isPrim(options) ) {
132
+ options = { id: options };
132
133
  }
133
134
 
135
+ // geht so nicht
136
+ // if ( Mix.isArr(event) ) {
137
+ // return (Arr.each(event, (e) => this.off(e, ...arguments)), this);
138
+ // }
139
+
134
140
  if ( Mix.isObj(selector) ) {
135
141
  (options = selector, selector = null);
136
142
  }
@@ -152,7 +158,7 @@ export class PicoDomEventInstance
152
158
  */
153
159
  optoff(options = {})
154
160
  {
155
- Run.idle(() => {
161
+ Run.async(() => {
156
162
  Arr.filterRemove(Dom.$events, { options });
157
163
  });
158
164
 
@@ -220,11 +226,12 @@ export class PicoDomEventInstance
220
226
  * @example Dom.find("div").fire("click")
221
227
  *
222
228
  * @param {string} event Event name
229
+ * @param {object} [detail] Event detail
223
230
  * @returns {PicoDom} Current instance
224
231
  */
225
- fire(event)
232
+ fire(event, detail = {})
226
233
  {
227
- let callback = new Event(event);
234
+ let callback = new CustomEvent(event, { detail });
228
235
 
229
236
  this.each((el) => {
230
237
  el.dispatchEvent(callback);
@@ -233,6 +240,30 @@ export class PicoDomEventInstance
233
240
  return this;
234
241
  }
235
242
 
243
+ pointerdown(button = 1)
244
+ {
245
+ const rect = this.rect();
246
+
247
+ const [x, y] = [
248
+ rect.left + rect.width / 2,
249
+ rect.top + rect.height / 2,
250
+ ];
251
+
252
+ const event = new PointerEvent('pointerdown', {
253
+ view: window,
254
+ bubbles: true,
255
+ cancelable: true,
256
+ buttons: 1,
257
+ clientX: x, clientY: y
258
+ });
259
+
260
+ this.each((el) => {
261
+ el.dispatchEvent(event);
262
+ });
263
+
264
+ return this;
265
+ }
266
+
236
267
  }
237
268
 
238
269
  /**
@@ -28,20 +28,25 @@ export class PicoDomFinderStatic
28
28
  *
29
29
  * @example Dom.getNodePoint(100, 100)
30
30
  *
31
- * @param {number} posx X position
32
- * @param {number} posy Y position
31
+ * @param {object} event Event data
33
32
  * @returns {Array<Element>} Nodes at point
34
33
  */
35
- static getNodePoint(posx, posy)
34
+ static getNodePoint(event)
36
35
  {
37
- let el = null;
36
+ if ( event.touches?.[0] ) {
37
+ // event = event.touches[0];
38
+ }
39
+
40
+ let [el, src] = [
41
+ null, [event.clientX, event.clientY]
42
+ ];
38
43
 
39
44
  if ( Dom.doc().elementsFromPoint != null ) {
40
- el = document.elementsFromPoint(posx, posy);
45
+ el = document.elementsFromPoint(src[0], src[1]);
41
46
  }
42
47
 
43
48
  if ( Dom.doc().msElementsFromPoint != null ) {
44
- el = document.msElementsFromPoint(posx, posy);
49
+ el = document.msElementsFromPoint(src[0], src[1]);
45
50
  }
46
51
 
47
52
  return el;
@@ -64,10 +69,10 @@ export class PicoDomFinderStatic
64
69
  target = event.target;
65
70
  }
66
71
 
67
- let { type, clientX, clientY } = event;
72
+ let { type } = event;
68
73
 
69
74
  if ( /^(drag[a-z]*|drop$)/.test(type) ) {
70
- target = Dom.getNodePoint(clientX, clientY);
75
+ target = Dom.getNodePoint(event);
71
76
  }
72
77
 
73
78
  if ( Mix.isArr(target) ) {
@@ -389,12 +394,10 @@ export class PicoDomFinderInstance
389
394
  * @param {number} [filter] Node type
390
395
  * @returns {PicoDom} Child instance
391
396
  */
392
- child(selector, filter = 1)
397
+ child(selector = null, filter = 1)
393
398
  {
394
- for ( let el of this.els ) {
395
- if ( el.nodeType === filter ) {
396
- return Dom.find(el);
397
- }
399
+ for ( let el of this.childs(selector, filter) ) {
400
+ return Dom.find(el);
398
401
  }
399
402
 
400
403
  return Dom.find(null);
@@ -443,6 +446,13 @@ export class PicoDomFinderInstance
443
446
  return null;
444
447
  }
445
448
 
449
+ upnode(selector)
450
+ {
451
+ return Dom.find(...[
452
+ this.closest(selector)
453
+ ]);
454
+ }
455
+
446
456
  /**
447
457
  * Get previous element
448
458
  *
@@ -499,16 +509,17 @@ export class PicoDomFinderInstance
499
509
  * @example Dom.find("div").is(".active") // => true
500
510
  *
501
511
  * @param {any} selector Test selector
512
+ * @param {boolean} [empty] Test selector
502
513
  * @returns {boolean} True if matches
503
514
  */
504
- is(selector)
515
+ is(selector, empty = false)
505
516
  {
506
517
  if ( this.el === selector ) {
507
518
  return true;
508
519
  }
509
520
 
510
521
  if ( this.el == null ) {
511
- return false;
522
+ return empty;
512
523
  }
513
524
 
514
525
  for ( let el of this.parent().find(selector).get() ) {
@@ -610,7 +621,7 @@ export class PicoDomFinderInstance
610
621
  contains(selector)
611
622
  {
612
623
  // Has child of selector
613
- return this.find(selector) != null;
624
+ return this.el.contains(selector);
614
625
  }
615
626
 
616
627
  }
@@ -15,28 +15,7 @@ export class PicoDomObserverStatic
15
15
  */
16
16
  export class PicoDomObserverInstance
17
17
  {
18
-
19
- /**
20
- * Get or set element value
21
- *
22
- * @example Dom.find("input").value("hello")
23
- *
24
- * @param {any} [value] New value
25
- * @returns {any|PicoDom} Value or instance
26
- */
27
- value(value = undefined)
28
- {
29
- if ( value === undefined ) {
30
- return this.el.value;
31
- }
32
-
33
- this.each((el) => {
34
- el.value = value;
35
- });
36
-
37
- return this;
38
- }
39
-
18
+ //
40
19
  }
41
20
 
42
21
  /**
@@ -0,0 +1,264 @@
1
+ import { Arr, Mix, Obj, Dom } from "../index.esm.js";
2
+ import { PicoDom } from "../utils/Dom.js";
3
+
4
+ /**
5
+ * @memberof PicoDom
6
+ */
7
+ export class PicoDomPopoverStatic
8
+ {
9
+ //
10
+ }
11
+
12
+ /**
13
+ * @memberof PicoDom
14
+ * @extends {PicoDom}
15
+ */
16
+ export class PicoDomPopoverInstance
17
+ {
18
+
19
+ popover(target, position = 'botttom-center', options = {})
20
+ {
21
+ if ( /^(top|bottom)-/.test(position) ) {
22
+ return this.popoverY(target, position, options);
23
+ }
24
+
25
+ if ( /^(left|right)-/.test(position) ) {
26
+ return this.popoverX(target, position, options);
27
+ }
28
+ }
29
+
30
+ popoverY(target, position = 'bottom-center', options = {})
31
+ {
32
+ target = Dom.find(target);
33
+
34
+ let [rect, self] = [
35
+ target.rect(), this.rect()
36
+ ];
37
+
38
+ if ( options.x ) {
39
+ rect = {...rect, left: options.x, width: 1 };
40
+ }
41
+
42
+ if ( options.y ) {
43
+ rect = {...rect, top: options.y, height: 1 };
44
+ }
45
+
46
+ if ( ! options.width ) {
47
+ // self.width = rect.width;
48
+ }
49
+
50
+ let [offset, recto] = [
51
+ { x: 0, y: 0 }, rect.width - self.width
52
+ ];
53
+
54
+ if ( /^top-/.test(position) ) {
55
+ offset.y = rect.top - self.height;
56
+ }
57
+
58
+ if ( /^bottom-/.test(position) ) {
59
+ offset.y = rect.top + rect.height;
60
+ }
61
+
62
+ if ( /-start$/.test(position) ) {
63
+ offset.x = rect.left;
64
+ }
65
+
66
+ if ( /-center$/.test(position) ) {
67
+ offset.x = rect.left + (recto * 0.5);
68
+ }
69
+
70
+ if ( /-end$/.test(position) ) {
71
+ offset.x = rect.left + recto;
72
+ }
73
+
74
+ let inverse = position;
75
+
76
+ if ( /^top-/.test(position) ) {
77
+ inverse = inverse.replace(/^top-/, 'bottom-');
78
+ }
79
+
80
+ if ( /^bottom-/.test(position) ) {
81
+ inverse = inverse.replace(/^bottom-/, 'top-');
82
+ }
83
+
84
+ let win = {
85
+ x: window.innerWidth, y: window.innerHeight
86
+ };
87
+
88
+ let broken = offset.y + self.height > win.y || offset.y < 0;
89
+
90
+ if ( offset.y < 0 ) {
91
+ broken = true;
92
+ }
93
+
94
+ const rebound = {
95
+ ...options, offset
96
+ };
97
+
98
+ if ( broken && ! options.offset ) {
99
+ return this.popoverY(target, inverse, rebound);
100
+ }
101
+
102
+ if ( broken && options.offset ) {
103
+ offset = options.offset;
104
+ }
105
+
106
+ if ( offset.y < 0 ) {
107
+ offset.y = 0;
108
+ }
109
+
110
+ if ( offset.y + self.height > win.height ) {
111
+ offset.y = win.height - self.height;
112
+ }
113
+
114
+ let result = this.popoverNormalize(...[
115
+ offset, self, rect, win
116
+ ]);
117
+
118
+ if ( broken ) {
119
+ position = 'auto';
120
+ }
121
+
122
+ return { ...result, position };
123
+ }
124
+
125
+ popoverX(target, position = 'left-center', options = {})
126
+ {
127
+ target = Dom.find(target);
128
+
129
+ let [rect, self] = [
130
+ target.rect(), this.rect()
131
+ ];
132
+
133
+ if ( ! options.height ) {
134
+ // self.height = rect.height;
135
+ }
136
+
137
+ let [offset, recto] = [
138
+ { x: 0, y: 0 }, rect.height - self.height
139
+ ];
140
+
141
+ if ( /^left-/.test(position) ) {
142
+ offset.x = rect.left - self.width;
143
+ }
144
+
145
+ if ( /^right-/.test(position) ) {
146
+ offset.x = rect.left + rect.width;
147
+ }
148
+
149
+ if ( /-start$/.test(position) ) {
150
+ offset.y = rect.top;
151
+ }
152
+
153
+ if ( /-center/.test(position) ) {
154
+ offset.y = rect.top + (recto * 0.5);
155
+ }
156
+
157
+ if ( /-end/.test(position) ) {
158
+ offset.y = rect.top + recto;
159
+ }
160
+
161
+ let inverse = position;
162
+
163
+ if ( /^left-/.test(position) ) {
164
+ inverse = inverse.replace(/^left-/, 'right-');
165
+ }
166
+
167
+ if ( /^right-/.test(position) ) {
168
+ inverse = inverse.replace(/^right-/, 'left-');
169
+ }
170
+
171
+ let win = {
172
+ x: window.innerWidth, y: window.innerHeight
173
+ };
174
+
175
+ let broken = offset.y + self.height > win.y;
176
+
177
+ if ( offset.y < 0 ) {
178
+ broken = true;
179
+ }
180
+
181
+ const rebound = {
182
+ ...options, offset
183
+ };
184
+
185
+ if ( broken && ! options.offset ) {
186
+ return this.popoverX(target, inverse, rebound);
187
+ }
188
+
189
+ if ( broken && options.offset ) {
190
+ offset = options.offset;
191
+ }
192
+
193
+ let result = this.popoverNormalize(...[
194
+ offset, self, rect, win
195
+ ]);
196
+
197
+ if ( broken ) {
198
+ position = 'auto';
199
+ }
200
+
201
+ return { ...result, position };
202
+ }
203
+
204
+ popoverNormalize(offset, self, rect, win)
205
+ {
206
+ const scroll = Dom.find(document.body).scroll();
207
+
208
+ if ( offset.y < 0 ) {
209
+ offset.y = 0;
210
+ }
211
+
212
+ if ( offset.y + self.height > win.y ) {
213
+ offset.y = win.y - self.height;
214
+ }
215
+
216
+ if ( offset.x < 0 ) {
217
+ offset.x = 0;
218
+ }
219
+
220
+ const dw = document.body.clientWidth;
221
+
222
+ if ( offset.x + self.width > win.x ) {
223
+ offset.x = win.x - self.width - (win.x - dw);
224
+ }
225
+
226
+ offset = {
227
+ x: offset.x + scroll.left, y: offset.y + scroll.top
228
+ }
229
+
230
+ Obj.each(offset, (v, k) => {
231
+ offset[k] = Math.round(v);
232
+ });
233
+
234
+ offset.self = {
235
+ width: self.width, height: self.height
236
+ };
237
+
238
+ offset.rect = {
239
+ width: rect.width, height: rect.height
240
+ };
241
+
242
+ return offset;
243
+ }
244
+
245
+ }
246
+
247
+ /**
248
+ * @param {typeof PicoDom} self
249
+ * @returns {typeof PicoDom}
250
+ */
251
+ export const PicoDomPopoverPlugin = function (self) {
252
+
253
+ Obj.each(Mix.class(PicoDomPopoverStatic), (fn, id) => {
254
+ self[id] = fn;
255
+ });
256
+
257
+ Obj.each(Mix.proto(PicoDomPopoverInstance), (fn, id) => {
258
+ self.prototype[id] = fn;
259
+ });
260
+
261
+ // self.init.push(PicoDomPopoverInstance.constructor);
262
+
263
+ return self;
264
+ }
@@ -30,6 +30,21 @@ export class PicoDomRectangleStatic
30
30
  */
31
31
  export class PicoDomRectangleInstance
32
32
  {
33
+ rect(fallback = { left: 0, top: 0, width: 0, height: 0 })
34
+ {
35
+ if ( ! this.el.getBoundingClientRect ) {
36
+ return fallback;
37
+ }
38
+
39
+ const rect = this.el.getBoundingClientRect();
40
+
41
+ if ( rect == null ) {
42
+ return fallback;
43
+ }
44
+
45
+ return rect.toJSON();
46
+ }
47
+
33
48
  /**
34
49
  * Get margin values
35
50
  *
@@ -30,7 +30,7 @@ export class PicoFormatOptionStatic
30
30
  return this.castOption(key, val, null, space);
31
31
  });
32
32
 
33
- return result.join(';') + ';';
33
+ return result.join(space ? '; ' : ';') + ';';
34
34
  }
35
35
 
36
36
  /**
@@ -57,10 +57,10 @@ export class PicoFormatOptionStatic
57
57
  }
58
58
 
59
59
  let result = Arr.map(value, (v, k) => {
60
- return this.castOption(k, v, key);
60
+ return this.castOption(k, v, key, space);
61
61
  });
62
62
 
63
- return result.join(';');
63
+ return result.join(space ? '; ' : ';');
64
64
  }
65
65
 
66
66
  /**
@@ -27,4 +27,10 @@ import * as pi from "./index.esm.js";
27
27
  /**
28
28
  * @type {PicoLibrary}
29
29
  */
30
- globalThis.pi = pi;
30
+ globalThis.pi = pi;
31
+
32
+ globalThis.addEventListener && globalThis.addEventListener('beforeunload', (e) => {
33
+ pi.Arr.map(pi.Dom.$events, ({ el, cb, event }) => {
34
+ return (el.removeEventListener(event, cb), null);
35
+ });
36
+ });
package/src/index.esm.js CHANGED
@@ -5,7 +5,7 @@ import { PicoArray, default as Arr } from "./utils/Array.js";
5
5
  import { PicoObject, default as Obj } from "./utils/Object.js";
6
6
  import { PicoMixed, default as Mix } from "./utils/Mixed.js";
7
7
  import { PicoHash, default as Hash } from "./utils/Hash.js";
8
- import { PicoEvent, default as Event } from "./utils/Event.js";
8
+ import { PicoSignal, default as Signal } from "./utils/Signal.js";
9
9
  import { PicoLocale, default as Locale } from "./utils/Locale.js";
10
10
  import { PicoCookie, default as Cookie } from "./utils/Cookie.js";
11
11
 
@@ -25,7 +25,7 @@ const Now = NowBuilder();
25
25
  const For = ForBuilder();
26
26
 
27
27
  export {
28
- Dom, Now, For, Run, Str, Num, Arr, Obj, Mix, Hash, Event, Locale, Cookie
28
+ Dom, Now, For, Run, Str, Num, Arr, Obj, Mix, Hash, Signal, Locale, Cookie
29
29
  }
30
30
 
31
31
  import { PicoDom, default as DomBuilder } from "./utils/Dom.js";
@@ -61,6 +61,16 @@ export const Any = new Proxy({}, {
61
61
  }
62
62
  });
63
63
 
64
+ /**
65
+ * @type {typeof PicoMixed}
66
+ */
67
+ export const Event = new Proxy({}, {
68
+ get: function (target, prop) {
69
+ console.warn(`Event.${prop} is deprecated, use Signal.${prop}() instead.`);
70
+ return (...args) => Signal[prop](...args);
71
+ }
72
+ });
73
+
64
74
  /**
65
75
  * @returns {string}
66
76
  */
@@ -5,7 +5,10 @@ export const NOW_FORMAT = {
5
5
  'L': 'DD/MM/YYYY',
6
6
  'LL': 'MMMM DD, YYYY',
7
7
  'LLL': 'MMMM DD, YYYY HH:mm',
8
- 'LLLL': 'dddd, MMMM DD, YYYY HH:mm'
8
+ 'LLLL': 'dddd, MMMM DD, YYYY HH:mm',
9
+ 'LT': 'HH:mm',
10
+ 'LTS': 'HH:mm:ss',
11
+ 'LTSD': 'DD/MM/YYYY HH:mm:ss',
9
12
  }
10
13
 
11
14
  export const NOW_PARSE = {
@@ -107,7 +110,7 @@ export class PicoNowFormatInstance
107
110
  format(format = 'YYYY-MM-DD HH:mm:ss')
108
111
  {
109
112
  if ( Obj.has(NOW_FORMAT, format) ) {
110
- format = Locale.trans(NOW_FORMAT[format]);
113
+ format = Locale.$text[format] ?? NOW_FORMAT[format];
111
114
  }
112
115
 
113
116
  format = format.replace('dddd', () => {