UNPKG

14.1 kBJavaScriptView Raw
1var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5 return c > 3 && r && Object.defineProperty(target, key, r), r;
6};
7var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11};
12var _DuoyunDatePanelElement_instances, _DuoyunDatePanelElement_currentPosition_get, _DuoyunDatePanelElement_prevPosition_get, _DuoyunDatePanelElement_highlights_get, _DuoyunDatePanelElement_increaseView, _DuoyunDatePanelElement_onChangeView, _DuoyunDatePanelElement_initState, _DuoyunDatePanelElement_onChange, _DuoyunDatePanelElement_onTimeChange, _DuoyunDatePanelElement_renderCurrentPosition, _DuoyunDatePanelElement_renderMonthList, _DuoyunDatePanelElement_renderYearList;
13import { adoptedStyle, customElement, emitter, globalemitter, property, boolattribute, } from '@mantou/gem/lib/decorators';
14import { GemElement, html } from '@mantou/gem/lib/element';
15import { createCSSSheet, css, classMap } from '@mantou/gem/lib/utils';
16import { isNotNullish } from '../lib/types';
17import { theme } from '../lib/theme';
18import { Time } from '../lib/time';
19import { icons } from '../lib/icons';
20import { commonHandle } from '../lib/hotkeys';
21import { focusStyle } from '../lib/styles';
22import './use';
23import './calendar';
24import './divider';
25import './action-text';
26import './time-panel';
27const style = createCSSSheet(css `
28 :host(:where(:not([hidden]))) {
29 font-size: 0.875em;
30 display: flex;
31 border: 1px solid ${theme.borderColor};
32 border-radius: ${theme.normalRound};
33 gap: 0.5em;
34 }
35 .datepanel {
36 width: 0;
37 flex-grow: 20;
38 }
39 .head {
40 aspect-ratio: 7 / 1;
41 display: flex;
42 align-items: center;
43 justify-content: center;
44 }
45 .current {
46 flex-grow: 1;
47 text-align: center;
48 }
49 .button {
50 max-width: 10%;
51 }
52 .button:hover {
53 background-color: ${theme.hoverBackgroundColor};
54 }
55 .container {
56 position: relative;
57 }
58 .calendar {
59 gap: 3px 1px;
60 }
61 .calendar.hidden {
62 visibility: hidden;
63 }
64 .list {
65 position: absolute;
66 inset: 0;
67 display: grid;
68 grid: auto-flow / 1fr 1fr 1fr;
69 }
70 .item {
71 display: flex;
72 align-items: center;
73 justify-content: center;
74 outline: 1px solid transparent;
75 outline-offset: -0.5em;
76 }
77 .item.highlight {
78 z-index: 1;
79 outline-color: ${theme.highlightColor};
80 }
81 .item:hover {
82 background: ${theme.hoverBackgroundColor};
83 }
84 .separate {
85 color: ${theme.lightBackgroundColor};
86 margin-inline: 0.5em;
87 }
88 .timepanelwrap {
89 width: 0;
90 flex-grow: 10;
91 display: flex;
92 flex-direction: column;
93 }
94 .time {
95 display: flex;
96 align-items: center;
97 justify-content: center;
98 height: 3em;
99 }
100 .timepanel {
101 height: 0;
102 flex-grow: 1;
103 }
104`);
105const modes = ['day', 'month', 'year'];
106/**
107 * @customElement dy-date-panel
108 * @attr time
109 * @fires change
110 * @fires datehover
111 */
112let DuoyunDatePanelElement = class DuoyunDatePanelElement extends GemElement {
113 constructor() {
114 super({ delegatesFocus: true });
115 _DuoyunDatePanelElement_instances.add(this);
116 this.state = {
117 year: 0,
118 month: 0,
119 mode: 'day',
120 };
121 _DuoyunDatePanelElement_increaseView.set(this, (number) => {
122 const date = __classPrivateFieldGet(this, _DuoyunDatePanelElement_instances, "a", _DuoyunDatePanelElement_currentPosition_get);
123 switch (this.state.mode) {
124 case 'day':
125 date.add(number, 'M');
126 break;
127 case 'month':
128 date.add(number, 'Y');
129 break;
130 case 'year':
131 date.add(number * 12, 'Y');
132 break;
133 }
134 __classPrivateFieldGet(this, _DuoyunDatePanelElement_initState, "f").call(this, date.valueOf());
135 });
136 _DuoyunDatePanelElement_onChangeView.set(this, (state) => {
137 this.setState({ ...state, mode: 'day' });
138 });
139 _DuoyunDatePanelElement_initState.set(this, (value) => {
140 const d = new Time(value);
141 this.setState({ year: d.getFullYear(), month: d.getMonth() });
142 });
143 _DuoyunDatePanelElement_onChange.set(this, (evt) => {
144 evt.stopPropagation();
145 const v = new Time(evt.detail);
146 if (this.time) {
147 const t = new Time(isNotNullish(this.value) ? this.value : new Time().startOf('d'));
148 v.setHours(t.getHours());
149 v.setMinutes(t.getMinutes());
150 v.setSeconds(t.getSeconds());
151 }
152 __classPrivateFieldGet(this, _DuoyunDatePanelElement_initState, "f").call(this, v.valueOf());
153 this.change(v.valueOf());
154 });
155 _DuoyunDatePanelElement_onTimeChange.set(this, (evt) => {
156 evt.stopPropagation();
157 __classPrivateFieldGet(this, _DuoyunDatePanelElement_initState, "f").call(this, evt.detail);
158 this.change(evt.detail);
159 });
160 _DuoyunDatePanelElement_renderCurrentPosition.set(this, () => {
161 switch (this.state.mode) {
162 case 'day':
163 return html `${__classPrivateFieldGet(this, _DuoyunDatePanelElement_instances, "a", _DuoyunDatePanelElement_currentPosition_get).formatToParts().map(({ type, value }) => {
164 if (modes.includes(type)) {
165 const mode = type;
166 return html `<dy-action-text @click=${() => this.setState({ mode })}>${value}</dy-action-text>`;
167 }
168 return value;
169 })}`;
170 default:
171 return html `
172 <dy-action-text @click=${() => this.setState({ mode: 'day' })}>
173 ${__classPrivateFieldGet(this, _DuoyunDatePanelElement_instances, "a", _DuoyunDatePanelElement_currentPosition_get).format('YYYY-MM-DD')}
174 </dy-action-text>
175 `;
176 }
177 });
178 _DuoyunDatePanelElement_renderMonthList.set(this, () => {
179 const start = new Time().startOf('Y');
180 const isCurrentYear = isNotNullish(this.value) && new Time(this.value).getFullYear() === this.state.year;
181 return html `
182 <div class="list">
183 ${Array.from({ length: 12 }).map((_, index) => html `
184 <span
185 class=${classMap({
186 item: true,
187 highlight: isCurrentYear && index === this.state.month,
188 })}
189 @click=${() => __classPrivateFieldGet(this, _DuoyunDatePanelElement_onChangeView, "f").call(this, { month: index })}
190 >
191 ${Object.fromEntries(new Time(start)
192 .add(index, 'M')
193 .formatToParts()
194 .map(({ type, value }) => [type, value])).month}
195 </span>
196 `)}
197 </div>
198 `;
199 });
200 _DuoyunDatePanelElement_renderYearList.set(this, () => {
201 const currentYear = isNotNullish(this.value) && new Time(this.value).getFullYear();
202 return html `
203 <div class="list">
204 ${Array.from({ length: 12 }, (_, index) => this.state.year - 7 + index).map((year) => html `
205 <span
206 class=${classMap({
207 item: true,
208 highlight: currentYear === year,
209 })}
210 @click=${() => __classPrivateFieldGet(this, _DuoyunDatePanelElement_onChangeView, "f").call(this, { year })}
211 >
212 ${year}
213 </span>
214 `)}
215 </div>
216 `;
217 });
218 this.willMount = () => {
219 __classPrivateFieldGet(this, _DuoyunDatePanelElement_initState, "f").call(this, isNotNullish(this.value) ? this.value : this.initValue || Time.now());
220 this.memo(() => {
221 if (this.state.mode !== 'day') {
222 this.state.old = {
223 month: this.state.month,
224 year: this.state.year,
225 };
226 }
227 else {
228 this.state.old = undefined;
229 }
230 }, () => [this.state.mode]);
231 };
232 this.mounted = () => {
233 this.effect(() => {
234 if (isNotNullish(this.initValue))
235 __classPrivateFieldGet(this, _DuoyunDatePanelElement_initState, "f").call(this, this.initValue);
236 }, () => [this.initValue]);
237 };
238 this.render = () => {
239 const { mode } = this.state;
240 return html `
241 <div class="datepanel">
242 <div class="head">
243 <dy-use
244 class="button"
245 tabindex="0"
246 role="button"
247 @keydown=${commonHandle}
248 @click=${() => __classPrivateFieldGet(this, _DuoyunDatePanelElement_increaseView, "f").call(this, -1)}
249 .element=${icons.left}
250 ></dy-use>
251 <div class="current">${__classPrivateFieldGet(this, _DuoyunDatePanelElement_renderCurrentPosition, "f").call(this)}</div>
252 <dy-use
253 class="button"
254 tabindex="0"
255 role="button"
256 @keydown=${commonHandle}
257 @click=${() => __classPrivateFieldGet(this, _DuoyunDatePanelElement_increaseView, "f").call(this, 1)}
258 .element=${icons.right}
259 ></dy-use>
260 </div>
261 <div class="container">
262 <dy-calendar
263 class=${classMap({ calendar: true, hidden: mode !== 'day' })}
264 borderless
265 today
266 .position=${mode === 'day' ? __classPrivateFieldGet(this, _DuoyunDatePanelElement_instances, "a", _DuoyunDatePanelElement_currentPosition_get).valueOf() : __classPrivateFieldGet(this, _DuoyunDatePanelElement_instances, "a", _DuoyunDatePanelElement_prevPosition_get).valueOf()}
267 .highlights=${__classPrivateFieldGet(this, _DuoyunDatePanelElement_instances, "a", _DuoyunDatePanelElement_highlights_get)}
268 @datehover=${({ detail }) => this.datehover(detail)}
269 @dateclick=${__classPrivateFieldGet(this, _DuoyunDatePanelElement_onChange, "f")}
270 ></dy-calendar>
271 ${mode === 'month' ? __classPrivateFieldGet(this, _DuoyunDatePanelElement_renderMonthList, "f").call(this) : ''} ${mode === 'year' ? __classPrivateFieldGet(this, _DuoyunDatePanelElement_renderYearList, "f").call(this) : ''}
272 </div>
273 </div>
274 ${this.time
275 ? html `
276 <dy-divider class="separate" orientation="vertical"></dy-divider>
277 <div class="timepanelwrap">
278 <div class="time">${isNotNullish(this.value) ? new Time(this.value).format('HH:mm:ss') : ''}</div>
279 <dy-divider class="separate"></dy-divider>
280 <dy-time-panel
281 class="timepanel"
282 .value=${this.value}
283 @change=${__classPrivateFieldGet(this, _DuoyunDatePanelElement_onTimeChange, "f")}
284 headless
285 ></dy-time-panel>
286 </div>
287 `
288 : ''}
289 `;
290 };
291 this.internals.role = 'widget';
292 }
293};
294_DuoyunDatePanelElement_increaseView = new WeakMap(), _DuoyunDatePanelElement_onChangeView = new WeakMap(), _DuoyunDatePanelElement_initState = new WeakMap(), _DuoyunDatePanelElement_onChange = new WeakMap(), _DuoyunDatePanelElement_onTimeChange = new WeakMap(), _DuoyunDatePanelElement_renderCurrentPosition = new WeakMap(), _DuoyunDatePanelElement_renderMonthList = new WeakMap(), _DuoyunDatePanelElement_renderYearList = new WeakMap(), _DuoyunDatePanelElement_instances = new WeakSet(), _DuoyunDatePanelElement_currentPosition_get = function _DuoyunDatePanelElement_currentPosition_get() {
295 return new Time(`${this.state.year}-${String(this.state.month + 1).padStart(2, '0')}`);
296}, _DuoyunDatePanelElement_prevPosition_get = function _DuoyunDatePanelElement_prevPosition_get() {
297 if (!this.state.old)
298 return 0;
299 return new Time(`${this.state.old.year}-${String(this.state.old.month + 1).padStart(2, '0')}`);
300}, _DuoyunDatePanelElement_highlights_get = function _DuoyunDatePanelElement_highlights_get() {
301 const highlights = [...(this.highlights || [])];
302 const value = this.value;
303 if (isNotNullish(value) && !highlights.some(([start, stop]) => value >= start && value <= stop)) {
304 const t = new Time(value);
305 highlights.push([t.startOf('d').valueOf(), t.endOf('d').valueOf()]);
306 }
307 return highlights;
308};
309__decorate([
310 boolattribute
311], DuoyunDatePanelElement.prototype, "time", void 0);
312__decorate([
313 globalemitter
314], DuoyunDatePanelElement.prototype, "change", void 0);
315__decorate([
316 emitter
317], DuoyunDatePanelElement.prototype, "datehover", void 0);
318__decorate([
319 property
320], DuoyunDatePanelElement.prototype, "value", void 0);
321__decorate([
322 property
323], DuoyunDatePanelElement.prototype, "highlights", void 0);
324__decorate([
325 property
326], DuoyunDatePanelElement.prototype, "initValue", void 0);
327DuoyunDatePanelElement = __decorate([
328 customElement('dy-date-panel'),
329 adoptedStyle(style),
330 adoptedStyle(focusStyle)
331], DuoyunDatePanelElement);
332export { DuoyunDatePanelElement };
333//# sourceMappingURL=date-panel.js.map
\No newline at end of file