@web-atoms/web-controls 2.3.56 → 2.3.58

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.
@@ -12,6 +12,8 @@ import ComboBox from "./ComboBox";
12
12
  import InlinePopup, { InlinePopupButton } from "./InlinePopup";
13
13
  import PopupButton from "./PopupButton";
14
14
  import ToggleButtonBar from "./ToggleButtonBar";
15
+ import TimeEditor from "./TimeEditor";
16
+ import TimeSpan from "@web-atoms/date-time/dist/TimeSpan";
15
17
 
16
18
  CSS(StyleRule()
17
19
  .display("inline-block")
@@ -165,24 +167,16 @@ export default class DateField extends AtomControl {
165
167
 
166
168
  public owner: DateField;
167
169
 
168
- public hour: any;
169
-
170
- public minute: any;
171
-
172
170
  public type;
173
171
 
172
+ public time: TimeSpan;
173
+
174
174
  protected create(): void {
175
175
  this.owner = owner;
176
176
  this.type = "AM";
177
- let h = this.owner.hour;
178
- if (h > 12) {
179
- h -= 12;
180
- this.type = "PM";
181
- }
182
- this.hour = h || 9;
183
- this.minute = this.owner.minute || 0;
177
+ const now = DateTime.from(owner.value ?? DateTime.today.addHours(owner.hour || 0).addMinutes(owner.minute || 0));
178
+ this.time = new TimeSpan(0, now.hour, now.minute);
184
179
  super.create();
185
- const now = DateTime.utcNow;
186
180
  const yearStart = typeof this.owner.yearStart === "number" ? this.owner.yearStart : -10;
187
181
  const yearEnd = typeof this.owner.yearEnd === "number" ? this.owner.yearEnd : 10;
188
182
  const year = typeof this.owner.year === "number" ? this.owner.year : now.year;
@@ -200,22 +194,9 @@ export default class DateField extends AtomControl {
200
194
  enableFunc={Bind.oneTime(() => this.owner.enableFunc)}
201
195
  value={Bind.oneWay(() => this.owner.value)}
202
196
  />
203
- { this.owner.enableTime && <div class="time-editor">
204
- <span text="Time"/>
205
- <ComboBox
206
- prompt="-"
207
- items={hours()}
208
- value={Bind.twoWays(() => this.hour)}
209
- />
210
- <ComboBox
211
- prompt="-"
212
- items={minutes()}
213
- value={Bind.twoWays(() => this.minute)}
214
- />
215
- <ToggleButtonBar
216
- value={Bind.twoWays(() => this.type)}
217
- items={[{ label: "AM", value: "AM"}, { label: "PM", value: "PM"}]}/>
218
- </div> }
197
+ { this.owner.enableTime && <TimeEditor
198
+ time={Bind.twoWays(() => this.time)}
199
+ /> }
219
200
  <button
220
201
  class="clear"
221
202
  text="Clear"
@@ -251,11 +232,7 @@ export default class DateField extends AtomControl {
251
232
  }
252
233
  let date = DateTime.from((d));
253
234
  if (this.owner.enableTime) {
254
- date = date.addHours(this.hour)
255
- .addMinutes(this.minute);
256
- if (this.type === "PM") {
257
- date = date.addHours(12);
258
- }
235
+ date = date.add(this.time);
259
236
  }
260
237
  this.owner.value = date.asJSDate;
261
238
  this.close(date);
@@ -0,0 +1,74 @@
1
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
2
+ import IElement from "./IElement";
3
+ import XNode from "@web-atoms/core/dist/core/XNode";
4
+
5
+ const labelPathSetter = AtomControl.registerProperty("data-items", "value", (ctrl, element, value) => {
6
+ element["labelPath"] = value;
7
+ });
8
+
9
+ const valuePathSetter = AtomControl.registerProperty("data-items", "value", (ctrl, element, value) => {
10
+ element["valuePath"] = value;
11
+ });
12
+
13
+ const valueSetter = AtomControl.registerProperty("data-items", "value", (ctrl, element, value) => {
14
+ element["initialValue"] = value;
15
+ setTimeout(refreshItems, 1, element);
16
+ });
17
+
18
+ const refreshItems = (element: HTMLSelectElement, items?: any[]) => {
19
+ items ??= element["items"];
20
+ (element as any).update = true;
21
+ element.options.length = 0;
22
+ const cv = element["initialValue"];
23
+ const lp = element["labelPath"] ?? ((item) => item?.label ?? item);
24
+ const vp = element["valuePath"] ?? ((item) => item?.value ?? item);
25
+ let i = 0;
26
+ let si = -1;
27
+ for (const iterator of items) {
28
+ const option = document.createElement("option");
29
+ const label = lp(iterator);
30
+ const value = vp(iterator);
31
+ option.text = label;
32
+ option.value = value;
33
+ element.options.add(option);
34
+ if(cv !== void 0) {
35
+ if (cv == value) {
36
+ si = i;
37
+ }
38
+ }
39
+ i++;
40
+ }
41
+ if (si != -1) {
42
+ element.selectedIndex = si;
43
+ }
44
+ (element as any).update = false;
45
+
46
+ };
47
+
48
+
49
+ const itemsSetter = AtomControl.registerProperty("data-items", "value", (ctrl, element: HTMLSelectElement, value) => {
50
+ element["items"] = value;
51
+ setTimeout(refreshItems, 1, element, value);
52
+ });
53
+
54
+ export interface ISelect extends IElement {
55
+ items: any[];
56
+ labelPath?: (item) => any;
57
+ valuePath?: (item) => any;
58
+ value?: any;
59
+ }
60
+ export default function Select({
61
+ items,
62
+ labelPath,
63
+ valuePath,
64
+ value
65
+ }: ISelect) {
66
+ const p = {};
67
+ p[labelPathSetter.property] = labelPath;
68
+ p[valuePathSetter.property] = valuePath;
69
+ p[valueSetter.property] = value;
70
+ p[itemsSetter.property] = items;
71
+ return <select
72
+ { ... p}
73
+ ></select>;
74
+ }
@@ -0,0 +1,135 @@
1
+ import { AtomBinder } from "@web-atoms/core/dist/core/AtomBinder";
2
+ import XNode from "@web-atoms/core/dist/core/XNode";
3
+ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
4
+ import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
5
+ import { descendentElementIterator } from "@web-atoms/core/dist/web/core/AtomUI";
6
+ import CSS from "@web-atoms/core/dist/web/styles/CSS";
7
+ import TimeSpan from "@web-atoms/date-time/dist/TimeSpan";
8
+ import Select from "./Select";
9
+ import Bind from "@web-atoms/core/dist/core/Bind";
10
+
11
+ function hours() {
12
+ return [
13
+ { label: "01", value: 1 },
14
+ { label: "02", value: 2 },
15
+ { label: "03", value: 3 },
16
+ { label: "04", value: 4 },
17
+ { label: "05", value: 5 },
18
+ { label: "06", value: 6 },
19
+ { label: "07", value: 7 },
20
+ { label: "08", value: 8 },
21
+ { label: "09", value: 9 },
22
+ { label: "10", value: 10 },
23
+ { label: "11", value: 11 },
24
+ { label: "12", value: 12 },
25
+ ];
26
+ }
27
+
28
+ function minutes() {
29
+ const items = [];
30
+ for (let index = 0; index < 10; index++) {
31
+ items.push({ label: "0" + index, value: index });
32
+ }
33
+ for (let index = 10; index < 60; index++) {
34
+ items.push({ label: index.toString(), value: index });
35
+ }
36
+ return items;
37
+ }
38
+
39
+ CSS(StyleRule()
40
+ .paddingLeft(5)
41
+ .gridRow("2")
42
+ .flexLayout({ direction: "row", alignItems: "center", justifyContent: "start" as any, gap: 0})
43
+ .child(StyleRule("[data-element=hour]")
44
+ .marginLeft(5)
45
+ .marginRight(5)
46
+ )
47
+ .child(StyleRule("[data-element=minute]")
48
+ .marginRight(5)
49
+ )
50
+ .child(StyleRule("[data-element=pm]")
51
+ .marginRight(5)
52
+ )
53
+ .child(StyleRule("button")
54
+ .borderRadius(9999)
55
+ .outline("none")
56
+ .border("none")
57
+ .backgroundColor("transparent")
58
+ .and(StyleRule("[data-selected=true]")
59
+ .backgroundColor("var(--accent-color, blue)")
60
+ .color("var(--accent-text-color, white)")
61
+ )
62
+ )
63
+ .child(StyleRule("button[data-element=am]")
64
+ .borderTopRightRadius(0)
65
+ .borderBottomRightRadius(0)
66
+ )
67
+ .child(StyleRule("button[data-element=pm]")
68
+ .borderTopLeftRadius(0)
69
+ .borderBottomLeftRadius(0)
70
+ )
71
+ .child(StyleRule("select")
72
+ .border("none")
73
+ .outline("none")
74
+ ),"[data-time-editor]");
75
+
76
+ export default class TimeEditor extends AtomControl {
77
+
78
+ // private time: TimeSpan;
79
+
80
+ public get time(): TimeSpan {
81
+ let t = new TimeSpan(0, this.hour, this.minute);
82
+ if (this.isPM) {
83
+ t = t.add(TimeSpan.fromHours(12));
84
+ }
85
+ return t;
86
+ }
87
+
88
+ public set time(v: TimeSpan) {
89
+ if(!v) {
90
+ v = TimeSpan.fromSeconds(0);
91
+ }
92
+ let h = v.hours;
93
+ if (h > 12) {
94
+ h -= 12;
95
+ this.isPM = true;
96
+ }
97
+ this.hour = h;
98
+ this.minute = v.minutes;
99
+ AtomBinder.refreshValue(this, "time");
100
+ }
101
+
102
+ public hour: number;
103
+
104
+ public minute: number;
105
+
106
+ public isPM: boolean;
107
+
108
+ protected create(): void {
109
+ this.isPM = false;
110
+ this.hour = 12;
111
+ this.minute = 0;
112
+ this.render(<div
113
+ data-time-editor="time-editor"
114
+ event-change={() => setTimeout(() => AtomBinder.refreshValue(this, "time"), 1)}>
115
+ <Select
116
+ data-element="hour"
117
+ items={hours()}
118
+ value={Bind.twoWays(() => this.hour)}/>
119
+ <Select
120
+ data-element="minute" items={minutes()}
121
+ value={Bind.twoWays(() => this.minute)}/>
122
+ <button
123
+ event-click={() => (this.isPM = false, AtomBinder.refreshValue(this, "time"))}
124
+ data-selected={Bind.oneWay(() => !this.isPM)}
125
+ data-element="am"
126
+ text="AM"/>
127
+ <button
128
+ event-click={() => (this.isPM = true, AtomBinder.refreshValue(this, "time"))}
129
+ data-selected={Bind.oneWay(() => this.isPM)}
130
+ data-element="pm"
131
+ text="PM"/>
132
+ </div>);
133
+ }
134
+
135
+ }