@web-atoms/web-controls 2.1.98 → 2.1.102

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 (34) hide show
  1. package/dist/auto-complete/AutoCompleteBox.d.ts.map +1 -1
  2. package/dist/auto-complete/AutoCompleteBox.js +0 -1
  3. package/dist/auto-complete/AutoCompleteBox.js.map +1 -1
  4. package/dist/basic/AtomRepeater.d.ts.map +1 -1
  5. package/dist/basic/AtomRepeater.js +9 -2
  6. package/dist/basic/AtomRepeater.js.map +1 -1
  7. package/dist/basic/Calendar.d.ts +37 -0
  8. package/dist/basic/Calendar.d.ts.map +1 -0
  9. package/dist/basic/Calendar.js +252 -0
  10. package/dist/basic/Calendar.js.map +1 -0
  11. package/dist/basic/ComboBox.d.ts +1 -0
  12. package/dist/basic/ComboBox.d.ts.map +1 -1
  13. package/dist/basic/ComboBox.js +9 -1
  14. package/dist/basic/ComboBox.js.map +1 -1
  15. package/dist/basic/Form.d.ts +4 -2
  16. package/dist/basic/Form.d.ts.map +1 -1
  17. package/dist/basic/Form.js +9 -2
  18. package/dist/basic/Form.js.map +1 -1
  19. package/dist/html-editor/commands/AddImage.js +1 -1
  20. package/dist/html-editor/commands/AddImage.js.map +1 -1
  21. package/dist/html-editor/commands/AddLink.js +1 -1
  22. package/dist/html-editor/commands/AddLink.js.map +1 -1
  23. package/dist/html-editor/commands/Source.js +1 -1
  24. package/dist/html-editor/commands/Source.js.map +1 -1
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +2 -2
  27. package/src/auto-complete/AutoCompleteBox.tsx +363 -364
  28. package/src/basic/AtomRepeater.tsx +9 -2
  29. package/src/basic/Calendar.tsx +270 -0
  30. package/src/basic/ComboBox.tsx +10 -1
  31. package/src/basic/Form.tsx +12 -2
  32. package/src/html-editor/commands/AddImage.tsx +1 -1
  33. package/src/html-editor/commands/AddLink.tsx +1 -1
  34. package/src/html-editor/commands/Source.tsx +1 -1
@@ -71,7 +71,7 @@ export function askSuggestion<T>(
71
71
  itemRenderer={itemRenderer}
72
72
  visibilityFilter={Bind.oneWay(() => match(this.search))}
73
73
  eventItemClick={(e) => {
74
- this.viewModel.close(e.detail);
74
+ this.close(e.detail);
75
75
  }}
76
76
  items={items}/>
77
77
  </div>
@@ -267,8 +267,12 @@ export default class AtomRepeater extends AtomControl {
267
267
  if (this.initialValue !== undefined) {
268
268
  return this.initialValue;
269
269
  }
270
+ const sp = this.selectedItem;
271
+ if (sp === undefined) {
272
+ return sp;
273
+ }
270
274
  const vp = this.valuePath ?? SameObjectValue;
271
- return vp(this.selectedItem);
275
+ return vp(sp);
272
276
  }
273
277
 
274
278
  public set value(v) {
@@ -587,6 +591,9 @@ function onElementClick(e: Event) {
587
591
  if (si) {
588
592
  index = si.indexOf(item);
589
593
  if (index === -1) {
594
+ if (!this.allowMultipleSelection) {
595
+ si.clear();
596
+ }
590
597
  si.add(item);
591
598
  } else {
592
599
  si.removeAt(index);
@@ -0,0 +1,270 @@
1
+ import Bind from "@web-atoms/core/dist/core/Bind";
2
+ import { BindableProperty } from "@web-atoms/core/dist/core/BindableProperty";
3
+ import Colors from "@web-atoms/core/dist/core/Colors";
4
+ import WatchProperty from "@web-atoms/core/dist/core/WatchProperty";
5
+ import XNode from "@web-atoms/core/dist/core/XNode";
6
+ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
7
+ import CSS from "@web-atoms/core/dist/web/styles/CSS";
8
+ import DateTime from "@web-atoms/date-time/dist/DateTime";
9
+ import AtomRepeater from "./AtomRepeater";
10
+ import ComboBox from "./ComboBox";
11
+
12
+ const start = DateTime.now;
13
+
14
+ const getWeekDays = (locale, type: "short" | "long") => {
15
+ const baseDate = new Date(Date.UTC(2017, 0, 2)); // just a Monday
16
+ const weekDays = [];
17
+ for (let i = 0; i < 7; i++) {
18
+ weekDays.push(baseDate.toLocaleDateString(locale, { weekday: type }));
19
+ baseDate.setDate(baseDate.getDate() + 1);
20
+ }
21
+ return weekDays;
22
+ };
23
+
24
+ const getMonths = (locale, type: "short" | "long") => {
25
+ const baseDate = new Date(Date.UTC(2017, 0, 2)); // just a Monday
26
+ const weekDays = [];
27
+ for (let i = 0; i < 12; i++) {
28
+ weekDays.push(baseDate.toLocaleDateString(locale, { month: type }));
29
+ baseDate.setMonth(i + 1);
30
+ }
31
+ return weekDays;
32
+ };
33
+
34
+ export const weekdays = {
35
+
36
+ short: getWeekDays(navigator.language, "short"),
37
+ long: getWeekDays(navigator.language, "long"),
38
+ };
39
+
40
+ export const months = {
41
+ short: getMonths(navigator.language, "short"),
42
+ long: getMonths(navigator.language, "long")
43
+ };
44
+
45
+ const monthItems = months.long.map((x, i) => ({
46
+ label: x,
47
+ value: i
48
+ }));
49
+
50
+ const css = CSS(StyleRule()
51
+ .display("inline-grid")
52
+ .gridTemplateRows("auto auto auto")
53
+ .gridTemplateColumns("auto auto auto auto")
54
+ .child(StyleRule(".fa-solid")
55
+ .padding(5)
56
+ .paddingLeft(10)
57
+ .paddingRight(10)
58
+ .cursor("pointer")
59
+ .hoverColor(Colors.blueViolet)
60
+ )
61
+ .child(StyleRule(".week")
62
+ .gridColumnStart("1")
63
+ .gridColumnEnd("span 4")
64
+ .gridRowStart("2")
65
+ .display("inline-grid")
66
+ .gridTemplateColumns("1fr 1fr 1fr 1fr 1fr 1fr 1fr")
67
+ .gap(0)
68
+ .child(StyleRule("*")
69
+ .fontSize("smaller")
70
+ .padding("5")
71
+ .paddingLeft("10")
72
+ .paddingRight("10")
73
+ .cursor("default")
74
+ .alignSelf("center")
75
+ .justifySelf("center")
76
+ )
77
+ )
78
+ .child(StyleRule(".dates")
79
+ .gridColumnStart("1")
80
+ .gridColumnEnd("span 4")
81
+ .gridRowStart("3")
82
+ .display("inline-grid")
83
+ .gap(0)
84
+ .child(StyleRule("[data-item-index]")
85
+ .alignSelf("stretch")
86
+ .justifySelf("stretch")
87
+ .padding(7)
88
+ .cursor("pointer")
89
+ .textAlign("center")
90
+ .hoverBackgroundColor(Colors.lightGray.withAlphaPercent(0.5))
91
+ .and(StyleRule("[data-selected-item=true]")
92
+ .backgroundColor(Colors.blueViolet)
93
+ .color(Colors.white)
94
+ )
95
+ .and(StyleRule("[data-is-today=true]")
96
+ .backgroundColor(Colors.lightGreen)
97
+ )
98
+ .and(StyleRule("[data-is-weekend=true]")
99
+ .backgroundColor(Colors.lightGray.withAlphaPercent(0.3))
100
+ )
101
+ .and(StyleRule("[data-is-other-month=true]")
102
+ .opacity("0.5")
103
+ )
104
+ )
105
+ )
106
+ );
107
+
108
+ export interface ICalendarDate {
109
+ label: string;
110
+ type: string;
111
+ value: DateTime;
112
+ isToday: boolean;
113
+ isOtherMonth: boolean;
114
+ isWeekend: boolean;
115
+ row: number;
116
+ column: number;
117
+ disabled: boolean;
118
+ }
119
+
120
+ export default class Calendar extends AtomRepeater {
121
+
122
+ @BindableProperty
123
+ public year: number;
124
+
125
+ @BindableProperty
126
+ public month: number;
127
+
128
+ @BindableProperty
129
+ public yearStart: number;
130
+
131
+ @BindableProperty
132
+ public yearEnd: number;
133
+
134
+ public enableFunc: (item: ICalendarDate) => boolean;
135
+
136
+ public dateRenderer: (item: ICalendarDate) => XNode;
137
+
138
+ @WatchProperty
139
+ public get dates() {
140
+ const year = this.year;
141
+ const month = this.month;
142
+ if (month === undefined) {
143
+ return [];
144
+ }
145
+ const today = DateTime.today;
146
+ let startDate = new DateTime(year, month, 1);
147
+ while (startDate.dayOfWeek !== 1) {
148
+ startDate = startDate.add(-1);
149
+ }
150
+ const a = [];
151
+ const y = startDate.year;
152
+ const m = startDate.month;
153
+ const ef = this.enableFunc;
154
+ for (let index = 0; index < 42; index++) {
155
+ const cd = startDate.add(index);
156
+ var item = {
157
+ label: cd.day + "",
158
+ row: Math.floor(index / 7),
159
+ column: index % 7,
160
+ type: null,
161
+ value: cd,
162
+ isToday: cd.equals(today),
163
+ isOtherMonth: month !== cd.month,
164
+ isWeekend: (cd.dayOfWeek === 0 || cd.dayOfWeek === 6),
165
+ disabled: false
166
+ };
167
+ if (ef) {
168
+ item.disabled = !(ef(item));
169
+ }
170
+ a.push(item);
171
+ }
172
+ return a;
173
+ }
174
+
175
+ @WatchProperty
176
+ public get years() {
177
+ const years = [];
178
+ const s = start.year + this.yearStart;
179
+ const e = start.year + this.yearEnd;
180
+ for (let index = s; index < e; index++) {
181
+ years.push({
182
+ label: index.toString(),
183
+ value: index
184
+ });
185
+ }
186
+ return years;
187
+ }
188
+
189
+ public onPropertyChanged(name: keyof Calendar): void {
190
+ super.onPropertyChanged(name);
191
+ switch (name) {
192
+ case "enableFunc":
193
+ case "dateRenderer":
194
+ this.updateItems();
195
+ break;
196
+ }
197
+ }
198
+
199
+ public next() {
200
+ if (this.month === 11) {
201
+ this.year++;
202
+ this.month = 0;
203
+ return;
204
+ }
205
+ this.month++;
206
+ }
207
+
208
+ public prev() {
209
+ if (this.month === 0) {
210
+ this.year--;
211
+ this.month = 11;
212
+ return;
213
+ }
214
+ this.month--;
215
+ }
216
+
217
+ protected preCreate(): void {
218
+ const now = new Date();
219
+ this.selectedItems = [];
220
+ this.valuePath = (i) => i.value;
221
+ this.yearStart = -10;
222
+ this.yearEnd = 10;
223
+ this.year = now.getFullYear();
224
+ this.month = now.getMonth();
225
+ this.render(<div
226
+ class={css}
227
+ items={Bind.oneWay(() => this.dates)}>
228
+ <i
229
+ event-click={() => this.prev()}
230
+ class="fa-solid fa-angle-left"
231
+ title="Previous Month"/>
232
+ <ComboBox
233
+ items={monthItems}
234
+ value={Bind.twoWays(() => this.month)} />
235
+ <ComboBox
236
+ items={this.years}
237
+ value={Bind.twoWays(() => this.year)}/>
238
+ <i
239
+ event-click={() => this.next()}
240
+ class="fa-solid fa-angle-right"
241
+ title="Next Month"/>
242
+ <div class="week"/>
243
+ <div class="dates"/>
244
+ </div>);
245
+ this.itemsPresenter = this.element.lastElementChild;
246
+ const week = this.element.lastElementChild.previousElementSibling;
247
+ let w = 1;
248
+ for (const iterator of weekdays.short) {
249
+ const text = document.createElement("span");
250
+ text.textContent = iterator;
251
+ week.appendChild(text);
252
+ text.style.gridColumnStart = `${w++}`;
253
+ }
254
+ this.dateRenderer = (item) => <div text={item.label}/>;
255
+ this.itemRenderer = (item: ICalendarDate) => {
256
+ const d = this.dateRenderer(item);
257
+ const a = d.attributes ??= {};
258
+ if (!a["data-click-event"]) {
259
+ a["data-click-event"] = "itemSelect";
260
+ }
261
+ a["data-is-today"] = item.isToday;
262
+ a["data-is-other-month"] = item.isOtherMonth;
263
+ a["data-is-weekend"] = item.isWeekend;
264
+ a.styleGridColumnStart = (item.column + 1);
265
+ a.styleGridRowStart = (item.row + 1);
266
+ return d;
267
+ };
268
+ }
269
+
270
+ }
@@ -11,13 +11,14 @@ export default class ComboBox extends AtomRepeater {
11
11
 
12
12
  constructor(app, e) {
13
13
  super(app, e ?? document.createElement("select"));
14
+ this.selectedItems = [];
14
15
  }
15
16
 
16
17
  public updateItems(container?: HTMLElement): void {
17
- super.updateItems(container);
18
18
  if (this.isChanging) {
19
19
  return;
20
20
  }
21
+ super.updateItems(container);
21
22
  const selectedItems = this.selectedItems;
22
23
  if (!selectedItems) {
23
24
  return;
@@ -31,6 +32,14 @@ export default class ComboBox extends AtomRepeater {
31
32
  this.isChanging = false;
32
33
  }
33
34
 
35
+ protected updateClasses(): void {
36
+ if (this.isChanging) {
37
+ return;
38
+ }
39
+ super.updateClasses();
40
+ this.updateItems();
41
+ }
42
+
34
43
  protected preCreate(): void {
35
44
  super.preCreate();
36
45
  this.labelPath = (item) => item?.label ?? item.toString();
@@ -22,12 +22,14 @@ export interface ISubmitButton {
22
22
 
23
23
  export interface ISubmitAction extends IElement {
24
24
  action: "submit";
25
- eventClick: any;
25
+ eventClick?: any;
26
+ "event-click"?: any;
26
27
  }
27
28
 
28
29
  export interface ICancelAction extends IElement{
29
30
  action: "cancel";
30
31
  eventClick?: any;
32
+ "event-click"?: any;
31
33
  }
32
34
 
33
35
  export type IFormAction = ISubmitAction | ICancelAction;
@@ -42,11 +44,19 @@ export function FormAction(
42
44
  {
43
45
  action = "submit",
44
46
  eventClick,
47
+ "event-click": eventClick2,
45
48
  ... a
46
49
  }: IFormAction, node: XNode) {
47
50
  const attributes = node.attributes ??= {};
48
51
  attributes["data-wa-form-action"] = action;
49
- if (action === "submit") {
52
+ const e = attributes["event-click"] || attributes["eventClick"]
53
+ if (e) {
54
+ attributes["event-submit"] = e;
55
+ delete attributes["event-click"];
56
+ delete attributes.eventClick;
57
+ }
58
+ eventClick ??= eventClick2;
59
+ if (action === "submit" && eventClick) {
50
60
  attributes.eventSubmit = eventClick;
51
61
  }
52
62
  node.attributes = { ... a, ... attributes};
@@ -27,7 +27,7 @@ class ImageDialog extends PopupWindow {
27
27
  </FormField>
28
28
  <div class="command-bar">
29
29
  <button
30
- eventClick={() => this.viewModel.close(this.createImage())}
30
+ eventClick={() => this.close(this.createImage())}
31
31
  text="Add"/>
32
32
  </div>
33
33
  </div>);
@@ -61,7 +61,7 @@ class LinkDialog extends PopupWindow {
61
61
  <div class="command-bar">
62
62
  <button
63
63
  text="Add"
64
- eventClick={Bind.event(() => this.viewModel.close(this.toLink(this.link)))} />
64
+ eventClick={Bind.event(() => this.close(this.toLink(this.link)))} />
65
65
  </div>
66
66
  </div>);
67
67
  }
@@ -28,7 +28,7 @@ async function showDialog(s: AtomHtmlEditor, e: Event): Promise<string> {
28
28
  <textarea value={Bind.twoWaysImmediate(() => this.source)}/>
29
29
  <div class="command-bar">
30
30
  <button
31
- eventClick={Bind.event(() => this.viewModel.close(this.source))}
31
+ eventClick={Bind.event(() => this.close(this.source))}
32
32
  text="Save"/>
33
33
  </div>
34
34
  </div>);