@web-atoms/web-controls 2.4.84 → 2.4.86
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/basic/AtomChips.d.ts.map +1 -1
- package/dist/basic/AtomChips.js +15 -14
- package/dist/basic/AtomChips.js.map +1 -1
- package/dist/basic/AtomRepeater.d.ts +3 -1
- package/dist/basic/AtomRepeater.d.ts.map +1 -1
- package/dist/basic/AtomRepeater.js +21 -58
- package/dist/basic/AtomRepeater.js.map +1 -1
- package/dist/basic/DateField.d.ts.map +1 -1
- package/dist/basic/DateField.js +13 -19
- package/dist/basic/DateField.js.map +1 -1
- package/dist/basic/InlinePopup.d.ts.map +1 -1
- package/dist/basic/InlinePopup.js +2 -1
- package/dist/basic/InlinePopup.js.map +1 -1
- package/dist/basic/InlinePopupButton.d.ts +12 -0
- package/dist/basic/InlinePopupButton.d.ts.map +1 -0
- package/dist/basic/InlinePopupButton.js +113 -0
- package/dist/basic/InlinePopupButton.js.map +1 -0
- package/dist/basic/PopupButton.d.ts +2 -2
- package/dist/basic/PopupButton.d.ts.map +1 -1
- package/dist/basic/PopupButton.js +4 -7
- package/dist/basic/PopupButton.js.map +1 -1
- package/dist/basic/Tooltip.d.ts +3 -3
- package/dist/basic/Tooltip.d.ts.map +1 -1
- package/dist/basic/Tooltip.js +27 -54
- package/dist/basic/Tooltip.js.map +1 -1
- package/dist/basic/elements/AtomPopover.css +2 -0
- package/dist/basic/elements/AtomPopover.css.map +1 -0
- package/dist/basic/elements/AtomPopover.d.ts +49 -0
- package/dist/basic/elements/AtomPopover.d.ts.map +1 -0
- package/dist/basic/elements/AtomPopover.js +343 -0
- package/dist/basic/elements/AtomPopover.js.map +1 -0
- package/dist/basic/styles/calendar.global.css +1 -1
- package/dist/basic/styles/calendar.global.css.map +1 -1
- package/dist/basic/styles/check-box-list.global.css +1 -1
- package/dist/basic/styles/chips.global.css +1 -1
- package/dist/basic/styles/chips.global.css.map +1 -1
- package/dist/basic/styles/date-field.global.css +1 -1
- package/dist/basic/styles/date-field.global.css.map +1 -1
- package/dist/basic/styles/expander.global.css +1 -1
- package/dist/basic/styles/expander.global.css.map +1 -1
- package/dist/basic/styles/form-field.global.css +1 -1
- package/dist/basic/styles/inline-popup.global.css +1 -1
- package/dist/basic/styles/inline-popup.global.css.map +1 -1
- package/dist/basic/styles/list-repeater.global.css +1 -1
- package/dist/basic/styles/list-repeater.global.css.map +1 -1
- package/dist/basic/styles/popup.global.css +1 -1
- package/dist/basic/styles/popup.global.css.map +1 -1
- package/dist/basic/styles/suggestion-popup.global.css +1 -1
- package/dist/basic/styles/suggestion-popup.global.css.map +1 -1
- package/dist/basic/styles/suggestion.global.css +1 -1
- package/dist/basic/styles/suggestion.global.css.map +1 -1
- package/dist/basic/styles/time-editor.global.css +1 -1
- package/dist/basic/styles/time-editor.global.css.map +1 -1
- package/dist/basic/styles/toggle-button-bar.global.css +1 -1
- package/dist/basic/styles/toggle-button-bar.global.css.map +1 -1
- package/dist/basic/styles/toggle-view.global.css +1 -1
- package/dist/basic/styles/toggle-view.global.css.map +1 -1
- package/dist/dev/Devhost.global.css +1 -1
- package/dist/dev/Devhost.global.css.map +1 -1
- package/dist/html-editor/commands/Align.d.ts +1 -3
- package/dist/html-editor/commands/Align.d.ts.map +1 -1
- package/dist/html-editor/commands/Align.js +2 -5
- package/dist/html-editor/commands/Align.js.map +1 -1
- package/dist/html-editor/commands/ChangeFont.local.css +1 -1
- package/dist/html-editor/commands/ChangeFont.local.css.map +1 -1
- package/dist/mobile-app/MasterDetailPage.global.css +1 -1
- package/dist/mobile-app/MasterDetailPage.global.css.map +1 -1
- package/dist/mobile-app/MobileApp.global.css +1 -1
- package/dist/mobile-app/MobileApp.global.css.map +1 -1
- package/dist/styles/atom-html-editor.global.css +1 -1
- package/dist/styles/atom-html-editor.global.css.map +1 -1
- package/dist/styles/form.global.css +1 -1
- package/dist/styles/form.global.css.map +1 -1
- package/dist/styles/html-editor-toolbar.global.css +1 -1
- package/dist/styles/html-editor-toolbar.global.css.map +1 -1
- package/dist/styles/inline-html-editor.global.css +1 -1
- package/dist/styles/inline-html-editor.global.css.map +1 -1
- package/dist/styles/resizable.global.css +1 -1
- package/dist/styles/resizable.global.css.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/postcss.config.cjs +4 -2
- package/src/basic/AtomChips.tsx +9 -8
- package/src/basic/AtomRepeater.tsx +19 -67
- package/src/basic/DateField.tsx +14 -15
- package/src/basic/InlinePopup.tsx +3 -1
- package/src/basic/InlinePopupButton.tsx +111 -0
- package/src/basic/PopupButton.tsx +5 -4
- package/src/basic/Tooltip.tsx +28 -54
- package/src/basic/elements/AtomPopover.css +14 -0
- package/src/basic/elements/AtomPopover.tsx +414 -0
- package/src/basic/styles/calendar.global.css +1 -1
- package/src/basic/styles/inline-popup.global.css +0 -7
- package/src/basic/styles/suggestion.global.css +1 -1
- package/src/html-editor/commands/Align.tsx +2 -3
- package/src/html-editor/commands/ChangeFont.local.css +1 -1
package/src/basic/AtomChips.tsx
CHANGED
|
@@ -6,10 +6,10 @@ import XNode from "@web-atoms/core/dist/core/XNode";
|
|
|
6
6
|
import AtomRepeater, { Match, MatchTrue } from "./AtomRepeater";
|
|
7
7
|
import type { IChip } from "./Chip";
|
|
8
8
|
export { default as Chip } from "./Chip";
|
|
9
|
-
import InlinePopup from "./InlinePopup";
|
|
10
9
|
|
|
11
10
|
import "./styles/chips.global.css";
|
|
12
11
|
import "./styles/item-suggestion.global.css";
|
|
12
|
+
import AtomPopover from "./elements/AtomPopover";
|
|
13
13
|
|
|
14
14
|
function getChips(target: HTMLElement): AtomChips {
|
|
15
15
|
let start = target;
|
|
@@ -51,17 +51,18 @@ function askSuggestionPopup<T>(
|
|
|
51
51
|
suggestionFilter: (item) => boolean,
|
|
52
52
|
cancelToken: CancelToken): Promise<T> {
|
|
53
53
|
|
|
54
|
-
class Suggestions extends
|
|
54
|
+
class Suggestions extends AtomPopover {
|
|
55
55
|
|
|
56
56
|
private opener: AtomChips;
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
init() {
|
|
59
|
+
// this.popover.setAttribute("cancel-on-blur", "0");
|
|
59
60
|
this.opener = opener;
|
|
60
|
-
this.
|
|
61
|
+
this.renderer = <div data-suggestion-popup="suggestion-popup">
|
|
61
62
|
<div class="items">
|
|
62
63
|
<AtomRepeater
|
|
63
64
|
class="presenter"
|
|
64
|
-
selectedItem={Bind.
|
|
65
|
+
selectedItem={Bind.source(opener, (x) => x.source.anchorItem)}
|
|
65
66
|
itemRenderer={itemRenderer}
|
|
66
67
|
eventDeleteSuggestion={(e) => opener.element.dispatchEvent(e) }
|
|
67
68
|
visibilityFilter={suggestionFilter ?? MatchTrue}
|
|
@@ -71,13 +72,13 @@ function askSuggestionPopup<T>(
|
|
|
71
72
|
e.stopPropagation();
|
|
72
73
|
this.close(e.detail);
|
|
73
74
|
}}
|
|
74
|
-
items={Bind.
|
|
75
|
+
items={Bind.source(opener, (x) => x.source.suggestions)}/>
|
|
75
76
|
</div>
|
|
76
|
-
</div
|
|
77
|
+
</div>;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
return Suggestions.
|
|
81
|
+
return Suggestions.show(host, { "anchor-top": "parent-bottom", "anchor-left": "parent-left", cancelToken });
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
export function Suggestion(
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { App } from "@web-atoms/core/dist/App";
|
|
2
1
|
import { AtomBinder } from "@web-atoms/core/dist/core/AtomBinder";
|
|
3
2
|
import Bind from "@web-atoms/core/dist/core/Bind";
|
|
4
3
|
import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
|
|
@@ -10,7 +9,6 @@ import WatchProperty from "@web-atoms/core/dist/core/WatchProperty";
|
|
|
10
9
|
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
11
10
|
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
12
11
|
import { IDialogOptions, PopupWindow } from "@web-atoms/core/dist/web/services/PopupService";
|
|
13
|
-
import InlinePopup from "./InlinePopup";
|
|
14
12
|
import MergeNode from "./MergeNode";
|
|
15
13
|
import ItemPath from "./ItemPath";
|
|
16
14
|
|
|
@@ -19,6 +17,7 @@ import "./styles/suggestion-popup.global.css";
|
|
|
19
17
|
import "./styles/repeater.global.css";
|
|
20
18
|
import { ChildEnumerator } from "@web-atoms/core/dist/web/core/AtomUI";
|
|
21
19
|
import DataAttributes from "../DataAttributes";
|
|
20
|
+
import AtomPopover from "./elements/AtomPopover";
|
|
22
21
|
|
|
23
22
|
export interface IItemPair<ParentItem = any, ChildItem = any> {
|
|
24
23
|
parent: ParentItem;
|
|
@@ -154,93 +153,46 @@ export function askSuggestion<T>(
|
|
|
154
153
|
* @returns selected item
|
|
155
154
|
*/
|
|
156
155
|
export function askSuggestionPopup<T>(
|
|
157
|
-
opener:
|
|
156
|
+
opener: AtomRepeater & { search: string },
|
|
158
157
|
items: T[],
|
|
159
158
|
itemRenderer: (item: T, index: number, repeater: AtomRepeater) => XNode,
|
|
160
159
|
match: Match<T>,
|
|
161
160
|
selectedItem: T): Promise<T> {
|
|
162
161
|
|
|
163
|
-
const updateSearch = "search" in opener;
|
|
164
162
|
const itemsInOpener = "items" in opener;
|
|
165
163
|
|
|
166
|
-
class Suggestions extends
|
|
164
|
+
class Suggestions extends AtomPopover {
|
|
167
165
|
|
|
168
|
-
|
|
166
|
+
anchorItem = null;
|
|
169
167
|
|
|
170
|
-
|
|
168
|
+
anchorIndex = null;
|
|
171
169
|
|
|
172
|
-
|
|
173
|
-
public search: string;
|
|
174
|
-
|
|
175
|
-
private opener: any;
|
|
176
|
-
|
|
177
|
-
private get items() {
|
|
178
|
-
return itemsInOpener ? this.opener.items : items;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
public onPropertyChanged(name: string): void {
|
|
182
|
-
if (updateSearch && name === "search") {
|
|
183
|
-
(opener as any).search = this.search;
|
|
184
|
-
}
|
|
185
|
-
super.onPropertyChanged(name);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
protected create(): void {
|
|
189
|
-
this.anchorItem = selectedItem;
|
|
190
|
-
this.opener = opener;
|
|
191
|
-
if (this.opener.search) {
|
|
192
|
-
this.search = this.opener.search;
|
|
193
|
-
}
|
|
194
|
-
if (selectedItem) {
|
|
195
|
-
this.anchorIndex = items.indexOf(selectedItem);
|
|
196
|
-
}
|
|
170
|
+
init() {
|
|
197
171
|
const disableSearch = (opener as any).disableSearch;
|
|
198
|
-
|
|
199
|
-
this.render(<div data-suggestion-popup="suggestion-popup">
|
|
200
|
-
{!disableSearch && <input
|
|
201
|
-
type="search"
|
|
202
|
-
value={Bind.twoWaysImmediate(() => this.search)}
|
|
203
|
-
eventKeydown={(e) => this.onKey(e)}
|
|
204
|
-
autofocus={true}/>}
|
|
205
|
-
<div class="items">
|
|
206
|
-
<AtomRepeater
|
|
207
|
-
class="presenter"
|
|
208
|
-
selectedItem={Bind.oneWay(() => this.anchorItem)}
|
|
209
|
-
itemRenderer={itemRenderer}
|
|
210
|
-
visibilityFilter={Bind.oneWay(() => match(this.search))}
|
|
211
|
-
eventItemClick={(e) => {
|
|
212
|
-
this.anchorItem = e.detail;
|
|
213
|
-
setTimeout(() =>
|
|
214
|
-
this.close(e.detail), 100);
|
|
215
|
-
}}
|
|
216
|
-
items={Bind.oneWay(() => this.opener.items)}/>
|
|
217
|
-
</div>
|
|
218
|
-
</div>);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
this.render(<div data-suggestion-popup="suggestion-popup">
|
|
172
|
+
this.renderer = <div data-suggestion-popup="suggestion-popup">
|
|
222
173
|
{!disableSearch && <input
|
|
223
174
|
type="search"
|
|
224
|
-
value={Bind.
|
|
175
|
+
value={Bind.sourceTwoWays(opener, (x) => x.source.search)}
|
|
225
176
|
eventKeydown={(e) => this.onKey(e)}
|
|
226
|
-
autofocus={true}/>
|
|
177
|
+
autofocus={true}/>}
|
|
227
178
|
<div class="items">
|
|
228
179
|
<AtomRepeater
|
|
229
180
|
class="presenter"
|
|
230
|
-
selectedItem={Bind.
|
|
181
|
+
selectedItem={Bind.source(this, (x) => x.source.anchorItem)}
|
|
231
182
|
itemRenderer={itemRenderer}
|
|
232
|
-
visibilityFilter={Bind.
|
|
233
|
-
scrollToSelection={true}
|
|
183
|
+
visibilityFilter={Bind.source(opener, (x) => match(x.source.search))}
|
|
234
184
|
eventItemClick={(e) => {
|
|
235
|
-
this.
|
|
185
|
+
this.anchorItem = e.detail;
|
|
186
|
+
setTimeout(() =>
|
|
187
|
+
this.close(e.detail), 100);
|
|
236
188
|
}}
|
|
237
|
-
items={items}/>
|
|
189
|
+
items={Bind.source(opener, (x) => x.source.items)}/>
|
|
238
190
|
</div>
|
|
239
|
-
</div
|
|
191
|
+
</div>;
|
|
240
192
|
}
|
|
241
193
|
|
|
242
194
|
protected onKey(e: KeyboardEvent) {
|
|
243
|
-
const suggested = match ?
|
|
195
|
+
const suggested = match ? opener.items?.filter(match(opener.search)) : opener.items;
|
|
244
196
|
switch (e.key) {
|
|
245
197
|
case "Enter":
|
|
246
198
|
// selection mode...
|
|
@@ -251,7 +203,7 @@ export function askSuggestionPopup<T>(
|
|
|
251
203
|
this.anchorIndex = 0;
|
|
252
204
|
this.close(anchorItem);
|
|
253
205
|
this.anchorItem = null;
|
|
254
|
-
|
|
206
|
+
opener.search = "";
|
|
255
207
|
break;
|
|
256
208
|
case "ArrowDown":
|
|
257
209
|
if (suggested) {
|
|
@@ -280,7 +232,7 @@ export function askSuggestionPopup<T>(
|
|
|
280
232
|
}
|
|
281
233
|
}
|
|
282
234
|
|
|
283
|
-
return Suggestions.
|
|
235
|
+
return Suggestions.show(opener.element, { });
|
|
284
236
|
|
|
285
237
|
}
|
|
286
238
|
|
package/src/basic/DateField.tsx
CHANGED
|
@@ -4,11 +4,11 @@ import XNode from "@web-atoms/core/dist/core/XNode";
|
|
|
4
4
|
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
5
5
|
import DateTime from "@web-atoms/date-time/dist/DateTime";
|
|
6
6
|
import Calendar, { ICalendarDate } from "./Calendar";
|
|
7
|
-
import InlinePopup, { InlinePopupButton } from "./InlinePopup";
|
|
8
7
|
import TimeEditor from "./TimeEditor";
|
|
9
8
|
import TimeSpan from "@web-atoms/date-time/dist/TimeSpan";
|
|
10
9
|
|
|
11
10
|
import "./styles/date-field.global.css";
|
|
11
|
+
import AtomPopover from "./elements/AtomPopover";
|
|
12
12
|
|
|
13
13
|
function hours() {
|
|
14
14
|
return [
|
|
@@ -103,7 +103,7 @@ export default class DateField extends AtomControl {
|
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
const owner = this;
|
|
106
|
-
class CalendarPopup extends
|
|
106
|
+
class CalendarPopup extends AtomPopover {
|
|
107
107
|
|
|
108
108
|
public owner: DateField;
|
|
109
109
|
|
|
@@ -111,16 +111,15 @@ export default class DateField extends AtomControl {
|
|
|
111
111
|
|
|
112
112
|
public time: TimeSpan;
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
init() {
|
|
115
115
|
this.owner = owner;
|
|
116
116
|
this.type = "AM";
|
|
117
117
|
const now = DateTime.from(owner.value ?? DateTime.today.addHours(owner.hour || 0).addMinutes(owner.minute || 0));
|
|
118
118
|
this.time = new TimeSpan(0, now.hour, now.minute);
|
|
119
|
-
super.create();
|
|
120
119
|
const yearStart = typeof this.owner.yearStart === "number" ? this.owner.yearStart : -10;
|
|
121
120
|
const yearEnd = typeof this.owner.yearEnd === "number" ? this.owner.yearEnd : 10;
|
|
122
121
|
const year = typeof this.owner.year === "number" ? this.owner.year : now.year;
|
|
123
|
-
this.
|
|
122
|
+
this.renderer = <div class="calendar-popup">
|
|
124
123
|
<Calendar
|
|
125
124
|
yearStart={yearStart}
|
|
126
125
|
yearEnd={yearEnd}
|
|
@@ -155,13 +154,13 @@ export default class DateField extends AtomControl {
|
|
|
155
154
|
e.stopPropagation();
|
|
156
155
|
this.save(DateTime.today.asJSDate);
|
|
157
156
|
}}/>
|
|
158
|
-
</div
|
|
157
|
+
</div>;
|
|
159
158
|
|
|
160
|
-
this.runAfterInit(() => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
});
|
|
159
|
+
// this.runAfterInit(() => {
|
|
160
|
+
// if (this.element) {
|
|
161
|
+
// (this.element as HTMLElement).scrollIntoView();
|
|
162
|
+
// }
|
|
163
|
+
// });
|
|
165
164
|
}
|
|
166
165
|
|
|
167
166
|
private save(d?: Date) {
|
|
@@ -179,12 +178,12 @@ export default class DateField extends AtomControl {
|
|
|
179
178
|
}
|
|
180
179
|
}
|
|
181
180
|
|
|
182
|
-
this.render(<
|
|
181
|
+
this.render(<div
|
|
183
182
|
data-layout="flex"
|
|
184
183
|
data-date-field="date-field"
|
|
185
|
-
text={Bind.oneWay(() => this.format?.(this.value, this.enableTime) || this.prompt)}
|
|
186
|
-
|
|
187
|
-
</
|
|
184
|
+
text={Bind.oneWay(() => this.format?.(this.value, this.enableTime) || this.prompt)}
|
|
185
|
+
event-click={() => CalendarPopup.show(this)}>
|
|
186
|
+
</div>);
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
}
|
|
@@ -105,7 +105,7 @@ export default class InlinePopup extends AtomControl {
|
|
|
105
105
|
container._logicalParent = targetElement;
|
|
106
106
|
|
|
107
107
|
// @ts-ignore
|
|
108
|
-
control.render(<div> {node} </div>, container, control);
|
|
108
|
+
control.render(<div> <atom-popup-container>{node}</atom-popup-container> </div>, container, control);
|
|
109
109
|
|
|
110
110
|
targetElement.insertAdjacentElement("beforeend", container);
|
|
111
111
|
|
|
@@ -296,6 +296,8 @@ export function InlinePopupButton(
|
|
|
296
296
|
|
|
297
297
|
alignment ||= anchorRight ? "bottomRight" : "bottomLeft";
|
|
298
298
|
|
|
299
|
+
console.warn(`Deprecated, use AtomPopover instead`);
|
|
300
|
+
|
|
299
301
|
if(!a["data-layout"]) {
|
|
300
302
|
if (icon && text) {
|
|
301
303
|
a["data-layout"] = "icon-button";
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
2
|
+
import type { IAnchorPopover } from "./elements/AtomPopover";
|
|
3
|
+
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
4
|
+
import { App } from "@web-atoms/core/dist/App";
|
|
5
|
+
import AtomPopover from "./elements/AtomPopover";
|
|
6
|
+
|
|
7
|
+
export type PopupFactory = (data) => XNode;
|
|
8
|
+
|
|
9
|
+
export interface IPopupButton extends IAnchorPopover {
|
|
10
|
+
icon?: string;
|
|
11
|
+
text?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
popup?: PopupFactory;
|
|
14
|
+
[k: string]: any;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export default function InlinePopupButton( { icon, text, label, popup, ... a }: IPopupButton, ... nodes: XNode[]) {
|
|
20
|
+
if(!a["anchor-right"]) {
|
|
21
|
+
a["anchor-left"] = "parent-right";
|
|
22
|
+
}
|
|
23
|
+
if (!a["anchor-bottom"]) {
|
|
24
|
+
a["anchor-top"] = "parent-top";
|
|
25
|
+
}
|
|
26
|
+
a["data-atom-popup-button"] = "popup-button";
|
|
27
|
+
if (!popup) {
|
|
28
|
+
const copy = nodes;
|
|
29
|
+
const div = <div>{ ... copy }</div>;
|
|
30
|
+
popup = () => div;
|
|
31
|
+
nodes = [];
|
|
32
|
+
}
|
|
33
|
+
a["popupFctory"] = popup;
|
|
34
|
+
|
|
35
|
+
if(!a["data-layout"]) {
|
|
36
|
+
if (icon && text) {
|
|
37
|
+
a["data-layout"] = "icon-button";
|
|
38
|
+
} else {
|
|
39
|
+
a["data-layout"] = "button";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return <button data-inline-popup-button="inline-popup-button" data-atom-popup-button="1" { ... a}>
|
|
44
|
+
{icon && <i class={icon}/>}
|
|
45
|
+
{text && <span text={text}/>}
|
|
46
|
+
{label && <label text={text}/>}
|
|
47
|
+
{ ... nodes }
|
|
48
|
+
</button>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
document.body.addEventListener("click", (e) => {
|
|
52
|
+
let start = e.target as HTMLElement;
|
|
53
|
+
while(start) {
|
|
54
|
+
if(start.hasAttribute("data-atom-popup-button")) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
start = start.parentElement as HTMLElement;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!start) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const pf = start["popupFctory"] as PopupFactory;
|
|
65
|
+
if (!pf) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const control = AtomControl.from(start) as any;
|
|
70
|
+
const app = control.app as App;
|
|
71
|
+
const target = start;
|
|
72
|
+
const element = control.element;
|
|
73
|
+
|
|
74
|
+
const dataFactory = () => {
|
|
75
|
+
|
|
76
|
+
let itemIndex;
|
|
77
|
+
|
|
78
|
+
let data;
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if (control.items && control.itemRenderer) {
|
|
82
|
+
// this is atom repeater
|
|
83
|
+
while (start && start !== element) {
|
|
84
|
+
itemIndex ??= start.getAttribute("data-item-index");
|
|
85
|
+
if (itemIndex) {
|
|
86
|
+
data = control.items[~~itemIndex];
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
start = start.parentElement;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!data) {
|
|
94
|
+
data = new Proxy(target, {
|
|
95
|
+
get(t, p, receiver) {
|
|
96
|
+
let s = target;
|
|
97
|
+
while (s) {
|
|
98
|
+
const v = s.dataset[p as string];
|
|
99
|
+
if (v !== void 0) {
|
|
100
|
+
return v;
|
|
101
|
+
}
|
|
102
|
+
s = s.parentElement;
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return data;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
AtomPopover.create(start, { nodeFactory: (data) => pf(data), dataFactory });
|
|
111
|
+
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
2
|
-
import { IInlinePopupButtonOptions, InlinePopupButton } from "./InlinePopup";
|
|
3
2
|
|
|
4
3
|
import "./styles/popup-button.global.css";
|
|
4
|
+
import InlinePopupButton from "./InlinePopupButton";
|
|
5
5
|
|
|
6
6
|
export interface IMenuItem {
|
|
7
7
|
label?: string;
|
|
@@ -41,11 +41,12 @@ export function MenuItem({
|
|
|
41
41
|
</div>;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
44
47
|
export default InlinePopupButton;
|
|
45
48
|
|
|
46
|
-
export function PopupActionButton(a
|
|
47
|
-
a.anchorRight = true;
|
|
48
|
-
a["data-alignment"] ??= "bottom-right";
|
|
49
|
+
export function PopupActionButton(a, ... nodes: XNode[]) {
|
|
49
50
|
return InlinePopupButton(a, ... nodes);
|
|
50
51
|
}
|
|
51
52
|
|
package/src/basic/Tooltip.tsx
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { CancelToken } from "@web-atoms/core/dist/core/types";
|
|
2
|
-
import XNode from "@web-atoms/core/dist/core/XNode";
|
|
2
|
+
import XNode, { xnodeSymbol } from "@web-atoms/core/dist/core/XNode";
|
|
3
3
|
import { AtomControl, ElementValueSetters } from "@web-atoms/core/dist/web/controls/AtomControl";
|
|
4
4
|
import { getParentRepeaterItem } from "./AtomRepeater";
|
|
5
|
-
import InlinePopup from "./InlinePopup";
|
|
6
5
|
|
|
7
6
|
import "./styles/tooltip.global.css";
|
|
7
|
+
import AtomPopover from "./elements/AtomPopover";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
type toolTipInfo = [{control: any, tooltip: CancelToken}, typeof AtomPopover];
|
|
10
|
+
|
|
11
|
+
const tooltips = new Map<HTMLElement, toolTipInfo>();
|
|
10
12
|
|
|
11
13
|
ElementValueSetters.tooltip = (control: AtomControl, e: HTMLElement, value: any) => {
|
|
12
14
|
tooltips.set(e, [{ control, tooltip: undefined }, value]);
|
|
@@ -34,64 +36,36 @@ document.body.addEventListener("pointerleave", (ev) => {
|
|
|
34
36
|
}, 250);
|
|
35
37
|
}, true);
|
|
36
38
|
|
|
37
|
-
export default class Tooltip extends
|
|
39
|
+
export default abstract class Tooltip extends AtomPopover {
|
|
38
40
|
|
|
39
|
-
public static showTooltip(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
public static showTooltip(target: HTMLElement) {
|
|
42
|
+
let item: toolTipInfo;
|
|
43
|
+
while(target) {
|
|
44
|
+
item = tooltips.get(target);
|
|
45
|
+
if(!item) {
|
|
46
|
+
target = target.parentElement;
|
|
44
47
|
continue;
|
|
45
48
|
}
|
|
46
|
-
const [host, node] = item;
|
|
47
|
-
if (!host.tooltip) {
|
|
48
|
-
host.tooltip = new CancelToken();
|
|
49
|
-
const reset = () => delete host.tooltip;
|
|
50
|
-
|
|
51
|
-
// find associated data/item
|
|
52
|
-
let data = getParentRepeaterItem(start);
|
|
53
|
-
if (data) {
|
|
54
|
-
data = data[2];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
class TooltipControl extends node {
|
|
58
|
-
|
|
59
|
-
private enterEventDisposable;
|
|
60
|
-
|
|
61
|
-
protected preCreate(): void {
|
|
62
|
-
this.element._logicalParent = start;
|
|
63
|
-
if (data) {
|
|
64
|
-
this.data = data;
|
|
65
|
-
}
|
|
66
|
-
const { element } = this;
|
|
67
|
-
// tooltips.set(element, [{ tooltip: this, control: null }, node]);
|
|
68
|
-
this.enterEventDisposable = this.bindEvent(element, "mouseenter", () => {
|
|
69
|
-
setTimeout(() => {
|
|
70
|
-
tooltips.set(element, [{ tooltip: host.tooltip, control: null}, null]);
|
|
71
|
-
delete host.tooltip;
|
|
72
|
-
this.enterEventDisposable.dispose();
|
|
73
|
-
}, 10);
|
|
74
|
-
});
|
|
75
|
-
this.registerDisposable({
|
|
76
|
-
dispose: () => {
|
|
77
|
-
tooltips.delete(element);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
49
|
|
|
83
|
-
TooltipControl.show(
|
|
84
|
-
start,
|
|
85
|
-
XNode.create(TooltipControl as any, {}),
|
|
86
|
-
{
|
|
87
|
-
cancelToken: host.tooltip,
|
|
88
|
-
alignment: "topRight"
|
|
89
|
-
}
|
|
90
|
-
).then(reset, reset) ;
|
|
91
|
-
}
|
|
92
50
|
break;
|
|
93
51
|
}
|
|
94
52
|
|
|
53
|
+
if (!item) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const [host, node] = item;
|
|
58
|
+
|
|
59
|
+
host.tooltip = node.create(target, {
|
|
60
|
+
dataFactory: () => {
|
|
61
|
+
let data = getParentRepeaterItem(target);
|
|
62
|
+
if (!data) {
|
|
63
|
+
return AtomControl.from(target).data;
|
|
64
|
+
}
|
|
65
|
+
data = data[2];
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
95
69
|
}
|
|
96
70
|
|
|
97
71
|
// public static show(start: HTMLElement) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
atom-pop-over {
|
|
2
|
+
position: relative;
|
|
3
|
+
&::part(container) {
|
|
4
|
+
display: block;
|
|
5
|
+
position: fixed;
|
|
6
|
+
border-radius: 5px;
|
|
7
|
+
padding: 5px;
|
|
8
|
+
box-shadow: rgba(50, 50, 105, 0.5) 0px 4px 6px 4px, rgba(0, 0, 0, 0.5) 0px 1px 1px 0px;
|
|
9
|
+
border: solid 1px rgba(0, 0, 0, 0.05);
|
|
10
|
+
z-index: 5000;
|
|
11
|
+
background-color: var(--popup-background-color, var(--default-background-color, canvas));
|
|
12
|
+
color: var(--popup-text-color, canvasText);
|
|
13
|
+
}
|
|
14
|
+
}
|