@web-atoms/web-controls 2.4.85 → 2.4.87

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.
Files changed (59) hide show
  1. package/dist/basic/AtomChips.d.ts.map +1 -1
  2. package/dist/basic/AtomChips.js +15 -14
  3. package/dist/basic/AtomChips.js.map +1 -1
  4. package/dist/basic/AtomRepeater.d.ts +3 -1
  5. package/dist/basic/AtomRepeater.d.ts.map +1 -1
  6. package/dist/basic/AtomRepeater.js +21 -58
  7. package/dist/basic/AtomRepeater.js.map +1 -1
  8. package/dist/basic/DateField.d.ts.map +1 -1
  9. package/dist/basic/DateField.js +13 -19
  10. package/dist/basic/DateField.js.map +1 -1
  11. package/dist/basic/InlinePopup.d.ts.map +1 -1
  12. package/dist/basic/InlinePopup.js +2 -1
  13. package/dist/basic/InlinePopup.js.map +1 -1
  14. package/dist/basic/InlinePopupButton.d.ts +12 -0
  15. package/dist/basic/InlinePopupButton.d.ts.map +1 -0
  16. package/dist/basic/InlinePopupButton.js +113 -0
  17. package/dist/basic/InlinePopupButton.js.map +1 -0
  18. package/dist/basic/PopupButton.d.ts +2 -8
  19. package/dist/basic/PopupButton.d.ts.map +1 -1
  20. package/dist/basic/PopupButton.js +4 -7
  21. package/dist/basic/PopupButton.js.map +1 -1
  22. package/dist/basic/Tooltip.d.ts +3 -3
  23. package/dist/basic/Tooltip.d.ts.map +1 -1
  24. package/dist/basic/Tooltip.js +27 -54
  25. package/dist/basic/Tooltip.js.map +1 -1
  26. package/dist/basic/elements/AtomPopover.css +2 -0
  27. package/dist/basic/elements/AtomPopover.css.map +1 -0
  28. package/dist/basic/elements/AtomPopover.d.ts +49 -0
  29. package/dist/basic/elements/AtomPopover.d.ts.map +1 -0
  30. package/dist/basic/elements/AtomPopover.js +343 -0
  31. package/dist/basic/elements/AtomPopover.js.map +1 -0
  32. package/dist/basic/styles/calendar.global.css +1 -1
  33. package/dist/basic/styles/calendar.global.css.map +1 -1
  34. package/dist/basic/styles/inline-popup.global.css +1 -1
  35. package/dist/basic/styles/inline-popup.global.css.map +1 -1
  36. package/dist/basic/styles/suggestion.global.css +1 -1
  37. package/dist/basic/styles/suggestion.global.css.map +1 -1
  38. package/dist/html-editor/commands/Align.d.ts +2 -3
  39. package/dist/html-editor/commands/Align.d.ts.map +1 -1
  40. package/dist/html-editor/commands/Align.js +4 -7
  41. package/dist/html-editor/commands/Align.js.map +1 -1
  42. package/dist/html-editor/commands/ChangeFont.local.css +1 -1
  43. package/dist/html-editor/commands/ChangeFont.local.css.map +1 -1
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +1 -1
  46. package/src/basic/AtomChips.tsx +9 -8
  47. package/src/basic/AtomRepeater.tsx +19 -67
  48. package/src/basic/DateField.tsx +14 -15
  49. package/src/basic/InlinePopup.tsx +3 -1
  50. package/src/basic/InlinePopupButton.tsx +111 -0
  51. package/src/basic/PopupButton.tsx +11 -10
  52. package/src/basic/Tooltip.tsx +28 -54
  53. package/src/basic/elements/AtomPopover.css +14 -0
  54. package/src/basic/elements/AtomPopover.tsx +414 -0
  55. package/src/basic/styles/calendar.global.css +1 -1
  56. package/src/basic/styles/inline-popup.global.css +0 -7
  57. package/src/basic/styles/suggestion.global.css +1 -1
  58. package/src/html-editor/commands/Align.tsx +3 -3
  59. package/src/html-editor/commands/ChangeFont.local.css +1 -1
@@ -0,0 +1,414 @@
1
+ const testNode = (node) => {
2
+ let test; let cs = getComputedStyle(node);
3
+ test = cs.getPropertyValue('position'); if ([
4
+ 'absolute', 'fixed'
5
+ ].includes(test)) { return true; }
6
+ test = cs.getPropertyValue('transform'); if (test != 'none') { return true; }
7
+ test = cs.getPropertyValue('perspective'); if (test != 'none') { return true; }
8
+ test = cs.getPropertyValue('perspective'); if (test != 'none') { return true; }
9
+ test = cs.getPropertyValue('filter'); if (test != 'none') { return true; }
10
+ test = cs.getPropertyValue('contain'); if (test == 'paint') { return true; }
11
+ test = cs.getPropertyValue('will-change'); if ([
12
+ 'transform', 'perspective', 'filter'
13
+ ].includes(test)) { return true; }
14
+ return false;
15
+ }
16
+
17
+ const getContainingBlock = (node) => {
18
+ if (node.parentElement) {
19
+ if (node.parentElement == document.body) {
20
+ return document.body;
21
+ } else if (testNode(node.parentElement) == false) {
22
+ return getContainingBlock(node.parentElement);
23
+ } else { return node.parentElement; }
24
+ } else { return null; }
25
+ }
26
+
27
+ import { AtomDisposableList } from "@web-atoms/core/dist/core/AtomDisposableList";
28
+ import { CancelToken } from "@web-atoms/core/dist/core/types";
29
+ import XNode, { IElementAttributes, xnodeSymbol } from "@web-atoms/core/dist/core/XNode";
30
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
31
+ import "./AtomPopover.css";
32
+
33
+ export interface IAnchorPopover extends IElementAttributes {
34
+ "anchor-left"?: "parent-left" | "parent-right",
35
+ "anchor-right"?: "parent-left" | "parent-right",
36
+ "anchor-top"?: "parent-top" | "parent-bottom",
37
+ "anchor-bottom"?: "parent-top" | "parent-bottom"
38
+ }
39
+
40
+ declare global {
41
+ namespace JSX {
42
+ interface IntrinsicElements {
43
+ "atom-pop-over": IAnchorPopover;
44
+ }
45
+ }
46
+ }
47
+
48
+ class AtomPopoverElement extends HTMLElement {
49
+
50
+
51
+ timer: any;
52
+
53
+ lastParent: HTMLElement;
54
+
55
+ result: any;
56
+ aborted = "cancel";
57
+
58
+ root: ShadowRoot;
59
+ slotElement: HTMLSlotElement;
60
+
61
+ connectedCallback() {
62
+
63
+ // set defaults...
64
+
65
+ if(!this.root) {
66
+
67
+ const root = this.root = this.attachShadow({ mode: "open" });
68
+ // const container = document.createElement("div");
69
+ const slot = document.createElement("slot");
70
+ slot.setAttribute("part", "container");
71
+ // slot.name = "container";
72
+ this.slotElement = slot;
73
+ // container.appendChild(slot);
74
+ root.appendChild(slot);
75
+ }
76
+ setTimeout(() => this.updatePosition(), 100);
77
+
78
+ window.addEventListener("scroll", this.updatePosition, { passive : true });
79
+ }
80
+
81
+ disconnectedCallback() {
82
+
83
+ if(this.lastParent?.isConnected) {
84
+ this.dispatchEvent(new CustomEvent("removed", {
85
+ detail: { result: this.result, aborted: this.aborted },
86
+ bubbles: true
87
+ }));
88
+ }
89
+
90
+ document.body.removeEventListener("click", this.closePopover);
91
+ window.removeEventListener("scroll", this.updatePosition);
92
+ clearInterval(this.timer);
93
+ }
94
+
95
+ closePopover = (e: Event) => {
96
+
97
+ const cancelOnBlur = /^(true|yes|1)$/i.test(this.getAttribute("cancel-on-blur") || "true");
98
+ if (!cancelOnBlur) {
99
+ return;
100
+ }
101
+ setTimeout(() => {
102
+ // this is to let other event handlers handle clicks
103
+ let target = e.target as HTMLElement;
104
+ while(target) {
105
+ if(target === this) {
106
+ return;
107
+ }
108
+ target = target.parentElement;
109
+ }
110
+ // click was outside
111
+ this.lastParent = null;
112
+ const ce = new CustomEvent("removing", {
113
+ detail: { result: this.result, aborted: this.aborted },
114
+ bubbles: true,
115
+ cancelable: true
116
+ });
117
+ this.dispatchEvent(ce);
118
+ if (ce.defaultPrevented) {
119
+ return;
120
+ }
121
+ this.dispatchEvent(new CustomEvent("removed", {
122
+ detail: { result: this.result, aborted: this.aborted },
123
+ bubbles: true,
124
+ }));
125
+ this.remove();
126
+ }, 10);
127
+ };
128
+
129
+ updatePosition = () => {
130
+
131
+ if (!this.parentElement) {
132
+ return;
133
+ }
134
+
135
+ const lastParent = this.lastParent = this.parentElement;
136
+ if (!lastParent) {
137
+ return;
138
+ }
139
+
140
+ // let start = this.firstElementChild;
141
+ // while(start) {
142
+ // start.setAttribute("slot", "container");
143
+ // start = start.nextElementSibling;
144
+ // }
145
+
146
+ const cb = getContainingBlock(lastParent) as HTMLElement;
147
+ if (!cb) {
148
+ return;
149
+ }
150
+
151
+ const rect = this.parentElement.getBoundingClientRect();
152
+
153
+ const thisRect = this.getBoundingClientRect();
154
+
155
+ const cbr = cb.getBoundingClientRect();
156
+
157
+ let selfLeft = Math.max(0, thisRect.x - cbr.x - (cb.scrollLeft + window.scrollX));
158
+ let parentLeft = Math.max(0, rect.x - cbr.x - (cb.scrollLeft + window.scrollX));
159
+ let t = Math.max(0, thisRect.y - cbr.y - (cb.scrollTop + window.scrollY));
160
+
161
+ const width = this.slotElement.offsetWidth;
162
+ const height = this.slotElement.offsetHeight;
163
+
164
+ if ((selfLeft + width) > cbr.width) {
165
+ selfLeft -= (selfLeft + width) - cbr.width;
166
+ }
167
+ if ((parentLeft + width) > cbr.width) {
168
+ parentLeft -= (parentLeft + width) - cbr.width;
169
+ }
170
+ if ((t + height) > cbr.height) {
171
+ t -= (t + height) - cbr.height;
172
+ }
173
+
174
+
175
+ const r = selfLeft + (rect.x - cbr.x);
176
+ const b = t + (rect.height);
177
+
178
+ const a = {
179
+ "parent-left": `${parentLeft}px`,
180
+ "parent-right": `${selfLeft}px`,
181
+ "parent-top": `${t}px`,
182
+ "parent-bottom": `${b}px`
183
+ };
184
+
185
+
186
+ let anchorBottom = this.getAttribute("anchor-bottom");
187
+ let anchorRight = this.getAttribute("anchor-right");
188
+ let anchorTop = this.getAttribute("anchor-top");
189
+ let anchorLeft = this.getAttribute("anchor-left");
190
+
191
+ const style = this.slotElement.style;
192
+ style.removeProperty("left");
193
+ style.removeProperty("top");
194
+ style.removeProperty("right");
195
+ style.removeProperty("bottom");
196
+
197
+ if (!anchorBottom) {
198
+ anchorTop ||= "parent-bottom";
199
+ }
200
+ if (!anchorRight) {
201
+ anchorLeft ||= "parent-right";
202
+ }
203
+
204
+ if (anchorTop) {
205
+ style.top = a[anchorTop];
206
+ }
207
+ if (anchorBottom) {
208
+ style.bottom = a[anchorBottom];
209
+ }
210
+ if (anchorLeft) {
211
+ style.left = a[anchorLeft];
212
+ }
213
+ if (anchorRight) {
214
+ style.right =a[anchorRight];
215
+ }
216
+
217
+
218
+ };
219
+
220
+ }
221
+
222
+ const existingPopup = Symbol("popup");
223
+
224
+ export interface IAtomPopoverOptions {
225
+ nodeFactory?: (data) => XNode | HTMLElement;
226
+ dataFactory?: () => any;
227
+ "anchor-left"?: "parent-left" | "parent-right";
228
+ "anchor-right"?: "parent-left" | "parent-right";
229
+ "anchor-top"?: "parent-top" | "parent-bottom";
230
+ "anchor-bottom"?: "parent-top" | "parent-bottom";
231
+ cancelToken?: CancelToken;
232
+ }
233
+
234
+ export default abstract class AtomPopover<T = any> {
235
+
236
+ owner: AtomControl;
237
+
238
+ popover: HTMLElement;
239
+
240
+ result: any;
241
+
242
+ disposables = new AtomDisposableList();
243
+
244
+ resultPromise: Promise<T>;
245
+ resultResolve: (value: T | PromiseLike<T>) => void;
246
+ resultReject: (reason?: any) => void;
247
+ parent: HTMLElement;
248
+ popoverContainer: HTMLElement;
249
+
250
+ static create(
251
+ parent: HTMLElement | AtomControl,
252
+ options: IAtomPopoverOptions = {},
253
+ ) {
254
+ return parent[existingPopup] ??= new (this as any)(parent, options);
255
+ }
256
+
257
+ static show<T1 = any>(
258
+ parent: HTMLElement | AtomControl,
259
+ options: IAtomPopoverOptions = {}
260
+ ) {
261
+ const p: AtomPopover<T1> = (parent[existingPopup] ??= new (this as any)(parent, options));
262
+ return p.resultPromise;
263
+ }
264
+
265
+ static menu(
266
+ parent: HTMLElement | AtomControl,
267
+ node: HTMLElement | XNode
268
+ ) {
269
+ const ct = new CancelToken();
270
+ const p: AtomPopover = new (this as any)(parent, ct, node);
271
+ p.result = 1;
272
+ p.disposables.add(p.owner.bindEvent(p.popover, "click", () => {
273
+ setTimeout(() => {
274
+ ct.cancel();
275
+ }, 10);
276
+ }));
277
+ return p;
278
+ }
279
+
280
+ set renderer(v: XNode | HTMLElement) {
281
+ const owner = this.owner;
282
+ let first = this.popoverContainer.firstElementChild as HTMLElement;
283
+ while (first) {
284
+ const next = first.nextElementSibling as HTMLElement;
285
+ owner.dispose(first);
286
+ first.remove();
287
+ first = next;
288
+ }
289
+ if (!v) {
290
+ return;
291
+ }
292
+ if (v[xnodeSymbol]) {
293
+ // @ts-expect-error
294
+ this.owner.render( <div> {v} </div>, this.popoverContainer, this.owner);
295
+ } else {
296
+ this.popoverContainer.appendChild(v as HTMLElement);
297
+ }
298
+
299
+ (this.popoverContainer as any).updatePosition?.();
300
+ }
301
+
302
+ constructor(
303
+ parent: HTMLElement | AtomControl,
304
+ options: IAtomPopoverOptions = {}
305
+ ) {
306
+
307
+ const p1 = parent;
308
+ this.disposables.add(() => p1[existingPopup] = null);
309
+
310
+ if (parent instanceof AtomControl) {
311
+ this.owner = parent;
312
+ parent = this.owner.element;
313
+ } else {
314
+ this.owner = AtomControl.from(parent);
315
+ }
316
+ const popover = this.popover = document.createElement("atom-pop-over");
317
+ this.popoverContainer = popover;
318
+ parent.appendChild(popover);
319
+
320
+ const {
321
+ cancelToken,
322
+ nodeFactory,
323
+ dataFactory,
324
+ "anchor-left": anchorLeft,
325
+ "anchor-right": anchorRight,
326
+ "anchor-top": anchorTop,
327
+ "anchor-bottom": anchorBottom
328
+ } = options;
329
+
330
+ cancelToken?.registerForCancel(this.removing as any);
331
+
332
+ if (anchorLeft) {
333
+ popover.setAttribute("anchor-left", anchorLeft);
334
+ }
335
+ if(anchorRight) {
336
+ popover.setAttribute("anchor-right", anchorRight);
337
+ }
338
+ if (anchorTop) {
339
+ popover.setAttribute("anchor-top", anchorTop);
340
+ }
341
+ if (anchorBottom) {
342
+ popover.setAttribute("anchor-bottom", anchorBottom);
343
+ }
344
+
345
+
346
+ popover.addEventListener("removing", this.removing);
347
+ popover.addEventListener("removed", this.remove);
348
+ this.disposables.add(() => {
349
+ popover.removeEventListener("removed", this.remove);
350
+ popover.removeEventListener("removing", this.removing);
351
+ });
352
+
353
+ this.init ??= (data) => {
354
+ if (nodeFactory) {
355
+ this.renderer = nodeFactory(data);
356
+ }
357
+ };
358
+
359
+ const p = this.init?.(dataFactory?.());
360
+ if (p?.then) {
361
+ p.then(() => void 0, console.warn);
362
+ }
363
+
364
+ this.resultPromise = new Promise((resolve, reject) => {
365
+ this.resultResolve = resolve;
366
+ this.resultReject = reject;
367
+ });
368
+
369
+ // ignore error
370
+ this.resultPromise.catch(() => void 0);
371
+ }
372
+
373
+ abstract init(data?: any);
374
+
375
+ close(r) {
376
+ (this.popover as any).result = r ?? null;
377
+ this.popover.remove();
378
+ }
379
+
380
+ async cancel() {
381
+ delete (this.popover as any).result;
382
+ this.popover.remove();
383
+ }
384
+
385
+ removing = (ce?: Event) => {
386
+ if (this.cancel) {
387
+ ce?.preventDefault();
388
+ const c = this.cancel?.();
389
+ if (c?.then) {
390
+ c.then(() => {
391
+ this.renderer = void 0;
392
+ this.remove();
393
+ }, console.warn);
394
+ }
395
+ }
396
+ };
397
+
398
+ remove = () => {
399
+
400
+ const { result } = this.popover as any;
401
+ if (result === void 0) {
402
+ this.resultReject?.();
403
+ } else {
404
+ this.resultResolve?.(result);
405
+ }
406
+
407
+ this.disposables.dispose();
408
+ // dispose
409
+ this.popover.remove();
410
+ }
411
+
412
+ }
413
+
414
+ customElements.define("atom-pop-over", AtomPopoverElement);
@@ -85,7 +85,7 @@
85
85
  opacity: 0.5;
86
86
  }
87
87
 
88
- &[data-is-disabled] {
88
+ &[data-disabled] {
89
89
  text-decoration: line-through;
90
90
  }
91
91
 
@@ -1,10 +1,3 @@
1
1
  *[data-inline-popup=inline-popup] {
2
2
  position: absolute;
3
- border-radius: 5px;
4
- padding: 5px;
5
- box-shadow: rgba(50, 50, 105, 0.5) 0px 4px 6px 4px, rgba(0, 0, 0, 0.5) 0px 1px 1px 0px;
6
- border: solid 1px rgba(0, 0, 0, 0.05);
7
- z-index: 5000;
8
- background-color: var(--popup-background-color, white);
9
- color: var(--popup-text-color, rgba(0,0,0,0.8));
10
3
  }
@@ -2,7 +2,7 @@
2
2
  margin: 5px;
3
3
  display: flex;
4
4
  flex-direction: row;
5
- align-items: center;
5
+ align-items: flex-start;
6
6
  justify-content: space-around;
7
7
  gap: 4px;
8
8
  overflow: hidden;
@@ -3,14 +3,14 @@ import XNode from "@web-atoms/core/dist/core/XNode";
3
3
  import PopupButton, { MenuItem } from "../../basic/PopupButton";
4
4
  import type AtomHtmlEditor from "../AtomHtmlEditor";
5
5
  import { IPopupOptions } from "@web-atoms/core/dist/web/services/PopupService";
6
+ import { IPopupButton } from "../../basic/InlinePopupButton";
6
7
 
7
- export default function Align({ alignment = "bottomRight" as IPopupOptions["alignment"]}) {
8
+ export default function Align(a: IPopupButton) {
8
9
  return <PopupButton
9
10
  class="command"
10
11
  data-layout="toolbar-button"
11
12
  icon="ri-align-left"
12
- title="Change Alignment"
13
- alignment={alignment}>
13
+ title="Change Alignment" { ... a}>
14
14
  <MenuItem
15
15
  icon="ri-align-left"
16
16
  title="Align Left"
@@ -1,4 +1,4 @@
1
1
  .web-controls-html-editor-change-font {
2
2
  padding: 5px;
3
- width: 170px;
3
+ min-width: 170px;
4
4
  }