cdui-js 1.0.20 → 1.0.22

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.
@@ -3,8 +3,8 @@
3
3
  height: 320px;
4
4
  border-radius: 12px;
5
5
  padding: 16px;
6
- font-size: 12px;
7
6
  user-select: none;
7
+ font-size: 16px;
8
8
  }
9
9
 
10
10
  .datewidget-header {
@@ -30,10 +30,16 @@
30
30
  cursor: pointer;
31
31
  }
32
32
 
33
+ .datewidget-body {
34
+ height: calc(100% - 36px);
35
+ }
36
+
33
37
  .datewidget-item {
34
38
  display: inline-flex;
35
39
  justify-content: center;
36
40
  align-items: center;
41
+ width: 25%;
42
+ height: 25%;
37
43
  cursor: pointer;
38
44
  }
39
45
 
@@ -50,9 +56,9 @@
50
56
  .datewidget-item.selected::before {
51
57
  position: absolute;
52
58
  content: '';
53
- width: 40px;
54
- height: 40px;
55
- border-radius: 40px;
59
+ width: 60px;
60
+ height: 60px;
61
+ border-radius: 60px;
56
62
  z-index: -1;
57
63
  }
58
64
 
@@ -64,9 +70,16 @@
64
70
 
65
71
  .canlendar-body {
66
72
  height: calc(100% - 72px);
73
+ font-size: 12px;
67
74
  }
68
75
 
69
76
  .canlendar-body .datewidget-item {
70
77
  width: 14.28%;
71
78
  height: 16.66%;
72
79
  }
80
+
81
+ .canlendar-body .datewidget-item.today::before,
82
+ .canlendar-body .datewidget-item.selected::before {
83
+ width: 40px;
84
+ height: 40px;
85
+ }
package/demo/css/css.md CHANGED
@@ -292,13 +292,14 @@
292
292
  .datewidget { border: 1px solid #e4e4e4; }
293
293
  .datewidget-header > .icon { stroke: #1b212d; }
294
294
  .datewidget-item.disabled { color: #e4e4e4; }
295
- .datewidget-item.prev-month, .datewidget-item.next-month { color: #888f97; }
295
+ .datewidget-item.prev-block, .datewidget-item.next-block { color: #888f97; }
296
296
  .datewidget-item.today::before { background: #f5f5f5; }
297
297
  .datewidget-item.selected { color: white; }
298
298
  .datewidget-item.selected::before { background: #ff4000; }
299
299
 
300
300
  .canlendar-weeks > span { color: #888f97; }
301
301
 
302
+
302
303
  # datepicker 日期选择
303
304
 
304
305
  .datepicker { border: 1px solid #e4e4e4; background: white; }
@@ -916,7 +916,7 @@ body { stroke: #A2A7AD; fill: #A2A7AD; }
916
916
  .datewidget { border: 1px solid #e4e4e4; }
917
917
  .datewidget-header > .icon { stroke: #1b212d; }
918
918
  .datewidget-item.disabled { color: #e4e4e4; }
919
- .datewidget-item.prev-month, .datewidget-item.next-month { color: #888f97; }
919
+ .datewidget-item.prev-block, .datewidget-item.next-block { color: #888f97; }
920
920
  .datewidget-item.today::before { background: #f5f5f5; }
921
921
  .datewidget-item.selected { color: white; }
922
922
  .datewidget-item.selected::before { background: #ff4000; }
@@ -1,5 +1,6 @@
1
1
  import { Canlendar } from '../../../src/components/Canlendar';
2
2
  import { MonthWidget } from '../../../src/components/MonthWidget';
3
+ import { YearWidget } from '../../../src/components/YearWidget';
3
4
 
4
5
  export const CanlendarPage = () => {
5
6
  return (
@@ -11,6 +12,7 @@ export const CanlendarPage = () => {
11
12
  }}
12
13
  ></Canlendar>
13
14
  <MonthWidget></MonthWidget>
15
+ <YearWidget></YearWidget>
14
16
  </div>
15
17
  );
16
18
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdui-js",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -51,7 +51,7 @@ const renderPrevMonthItems = (
51
51
  month = 11;
52
52
  }
53
53
 
54
- renderDates(items, year, month, days - index + 1, days, ' prev-month', todayValue, selectedValue, disableFn);
54
+ renderDates(items, year, month, days - index + 1, days, ' prev-block', todayValue, selectedValue, disableFn);
55
55
  };
56
56
 
57
57
  const renderNextMonthItems = (
@@ -70,7 +70,7 @@ const renderNextMonthItems = (
70
70
  month = 0;
71
71
  }
72
72
 
73
- renderDates(items, year, month, 1, days, ' next-month', todayValue, selectedValue, disableFn);
73
+ renderDates(items, year, month, 1, days, ' next-block', todayValue, selectedValue, disableFn);
74
74
  };
75
75
 
76
76
  const renderItems = (
@@ -139,6 +139,9 @@ const formatMonth = (value: Date) => {
139
139
 
140
140
  const OMIT_PROPS = ['class', 'value', 'onValueChange', 'disableFn'] as const;
141
141
 
142
+ /**
143
+ * 日历组件
144
+ */
142
145
  export const Canlendar = (
143
146
  props: Omit<JSX.HTMLAttributes<never>, 'children'> & {
144
147
  /**
@@ -158,14 +161,14 @@ export const Canlendar = (
158
161
  let domTitle: HTMLElement;
159
162
  let domBody: HTMLElement;
160
163
 
161
- const [selectedValue, setSelectedDate] = createSignal(parseDate(props.value));
164
+ const [selectedValue, setSelectedValue] = createSignal(parseDate(props.value));
162
165
  const [currentValue, setCurrentValue] = createSignal(selectedValue() || new Date());
163
166
 
164
167
  return (
165
168
  <div class={combineClass('canlendar datewidget', props.class)} {...omitProps(props, OMIT_PROPS)}>
166
169
  <div class="datewidget-header canlendar-header">
167
170
  <div ref={domTitle as any} class="datewidget-title">
168
- {replaceTemplate(i18n.Month, currentValue().getFullYear(), formatMonth(currentValue()))}
171
+ {replaceTemplate(i18n.Title, currentValue().getFullYear(), formatMonth(currentValue()))}
169
172
  </div>
170
173
  <svg class="icon icon-s" aria-hidden={true} onclick={() => setCurrentValue(switchMonth(currentValue(), -1))}>
171
174
  <use href="#icon-backward"></use>
@@ -182,17 +185,22 @@ export const Canlendar = (
182
185
  class="datewidget-body canlendar-body"
183
186
  onclick={(event) => {
184
187
  let target = event.target as HTMLElement;
185
- let date, onValueChange;
186
-
187
- if (target && (date = target.dataset.date) && (onValueChange = props.onValueChange)) {
188
- let dom = domBody.querySelector('.selected') as HTMLElement;
189
-
190
- if (dom !== target) {
191
- date = date.split('|');
192
- date = new Date(date[0] | 0, date[1] | 0, date[2] | 0);
193
-
194
- setSelectedDate(date);
195
- onValueChange(date);
188
+ let date;
189
+
190
+ while (target && target !== domBody) {
191
+ if ((date = target.dataset.date)) {
192
+ // 没有选中
193
+ if (!target.classList.contains('selected')) {
194
+ date = date.split('|');
195
+ date = new Date(date[0] | 0, date[1] | 0, date[2] | 0);
196
+
197
+ setSelectedValue(date);
198
+ props.onValueChange && props.onValueChange(date);
199
+ }
200
+
201
+ break;
202
+ } else {
203
+ target = target.parentNode as HTMLElement;
196
204
  }
197
205
  }
198
206
  }}
@@ -1,36 +1,61 @@
1
- import { createSignal, combineClass } from '../reactive';
2
-
3
1
  import { JSX } from '../jsx';
4
- import { Canleandar as i18n } from '../i18n';
2
+ import { MonthWidget as i18n } from '../i18n';
5
3
  import { replaceTemplate } from '../template';
4
+ import { createSignal, combineClass } from '../reactive';
6
5
  import { For } from './For';
7
6
 
8
- const formatMonth = (month: number) => {
9
- return month > 9 ? month : '0' + month;
10
- };
11
-
12
7
  const getCurrentMonth = () => {
13
8
  let date = new Date();
14
- return [date.getFullYear(), date.getMonth() + 1];
9
+ return [date.getFullYear(), date.getMonth() + 1] as [year: number, month: number];
15
10
  };
16
11
 
17
- const switchMonth = (value: [year: number, month: number], offset: 1 | -1) => {
18
- let year = value[0];
19
- let month = value[1] + offset;
12
+ const MONTH_LIST = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
20
13
 
21
- if (month === 0) {
22
- month = 12;
23
- year--;
24
- } else if (month > 12) {
25
- month = 1;
26
- year++;
14
+ const MonthItem = (props: {
15
+ value: number;
16
+ selectedValue: [year: number, month: number];
17
+ currentValue: [year: number, month: number];
18
+ onclick: (event: Event) => void;
19
+ disableFn?: (year: number, month: number) => boolean;
20
+ }) => {
21
+ let year = 0;
22
+ let month = props.value;
23
+
24
+ if (month > 12) {
25
+ year = 1;
26
+ month -= 12;
27
27
  }
28
28
 
29
- return [year, month];
30
- };
29
+ const checkCurrent = () => {
30
+ const today = new Date();
31
+ const currentValue = props.currentValue;
32
+
33
+ return today.getFullYear() === currentValue[0] + year && today.getMonth() + 1 === month;
34
+ };
31
35
 
32
- const MONTH_LIST = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4];
36
+ const checkSelected = () => {
37
+ let selectedValue = props.selectedValue;
38
+ const currentValue = props.currentValue;
33
39
 
40
+ return selectedValue && selectedValue[0] === currentValue[0] + year && selectedValue[1] === month;
41
+ };
42
+
43
+ return (
44
+ <span
45
+ class={`datewidget-item${year ? ' next-block' : ''}${checkCurrent() ? ' today' : ''}${
46
+ checkSelected() ? ' selected' : ''
47
+ }${props.disableFn && props.disableFn(props.currentValue[0] + year, month) ? ' disabled' : ''}`}
48
+ data-month={`${year}|${month}`}
49
+ onclick={props.onclick}
50
+ >
51
+ {replaceTemplate(i18n.Format, month)}
52
+ </span>
53
+ );
54
+ };
55
+
56
+ /**
57
+ * 月份组件
58
+ */
34
59
  export const MonthWidget = (
35
60
  props: Omit<JSX.HTMLAttributes<never>, 'children'> & {
36
61
  /**
@@ -44,48 +69,61 @@ export const MonthWidget = (
44
69
  /**
45
70
  * 禁用函数
46
71
  */
47
- disableFn?: (year: number, month: number, date: number) => boolean;
72
+ disableFn?: (year: number, month: number) => boolean;
48
73
  },
49
74
  ) => {
50
75
  let domTitle: HTMLElement;
51
76
  let domBody: HTMLElement;
52
77
 
53
- const [selectedValue, setSelectedDate] = createSignal(props.value);
78
+ const [selectedValue, setSelectedValue] = createSignal(props.value);
54
79
  const [currentValue, setCurrentValue] = createSignal(selectedValue() || getCurrentMonth());
55
80
 
81
+ const onclick = (event: Event) => {
82
+ let target = event.currentTarget as HTMLElement;
83
+ let month = target.dataset.month as any;
84
+
85
+ // 没有选中
86
+ if (month && !target.classList.contains('selected')) {
87
+ month = month.split('|');
88
+ month = [currentValue()[0] + (month[0] | 0), month[1] | 0];
89
+
90
+ setSelectedValue(month);
91
+ props.onValueChange && props.onValueChange(month);
92
+ }
93
+ };
94
+
56
95
  return (
57
96
  <div class={combineClass('monthwidget datewidget', props.class)}>
58
97
  <div class="datewidget-header">
59
98
  <div ref={domTitle as any} class="datewidget-title">
60
- {replaceTemplate(i18n.Month, currentValue()[0], formatMonth(currentValue()[1]))}
99
+ {replaceTemplate(i18n.Title, currentValue()[0])}
61
100
  </div>
62
- <svg class="icon icon-s" aria-hidden={true} onclick={() => setCurrentValue(switchMonth(selectedValue(), -1))}>
101
+ <svg
102
+ class="icon icon-s"
103
+ aria-hidden={true}
104
+ onclick={() => setCurrentValue([currentValue()[0] - 1, currentValue()[1]])}
105
+ >
63
106
  <use href="#icon-backward"></use>
64
107
  </svg>
65
- <svg class="icon icon-s" aria-hidden={true} onclick={() => setCurrentValue(switchMonth(selectedValue(), 1))}>
108
+ <svg
109
+ class="icon icon-s"
110
+ aria-hidden={true}
111
+ onclick={() => setCurrentValue([currentValue()[0] + 1, currentValue()[1]])}
112
+ >
66
113
  <use href="#icon-forward"></use>
67
114
  </svg>
68
115
  </div>
69
- <div
70
- ref={domBody as any}
71
- class="datewidget-body"
72
- onclick={(event) => {
73
- let target = event.target as HTMLElement;
74
- let value, onValueChange;
75
-
76
- if (target && (onValueChange = props.onValueChange)) {
77
- let dom = domBody.querySelector('.selected') as HTMLElement;
78
-
79
- if (dom !== target) {
80
- value = [currentValue()[0], +target.textContent];
81
-
82
- setSelectedDate(value);
83
- onValueChange(value);
84
- }
85
- }
86
- }}
87
- >
88
- <For each={MONTH_LIST}>{(item) => <span>{item}</span>}</For>
116
+ <div ref={domBody as any} class="datewidget-body">
117
+ <For each={MONTH_LIST}>
118
+ {(item) => (
119
+ <MonthItem
120
+ value={item}
121
+ selectedValue={selectedValue()}
122
+ currentValue={currentValue()}
123
+ onclick={onclick}
124
+ ></MonthItem>
125
+ )}
126
+ </For>
89
127
  </div>
90
128
  </div>
91
129
  );
@@ -1,13 +1,121 @@
1
+ import { JSX } from '../jsx';
2
+ import { YearWidget as i18n } from '../i18n';
3
+ import { replaceTemplate } from '../template';
1
4
  import { createSignal, combineClass } from '../reactive';
5
+ import { For } from './For';
2
6
 
3
- import { JSX } from '../jsx';
7
+ // 渲染日期项
8
+ const renderDates = (
9
+ items: string[],
10
+ year: number,
11
+ month: number,
12
+ from: number,
13
+ to: number,
14
+ className: string,
15
+ todayValue: Date,
16
+ selectedValue?: Date,
17
+ disableFn?: (year: number, month: number, date: number) => boolean,
18
+ ) => {
19
+ let today = todayValue.getFullYear() === year && todayValue.getMonth() === month ? todayValue.getDate() : -1;
20
+ let selected =
21
+ selectedValue && selectedValue.getFullYear() === year && selectedValue.getMonth() === month
22
+ ? selectedValue.getDate()
23
+ : -1;
24
+
25
+ for (let i = from; i <= to; i++) {
26
+ items.push(
27
+ `<span class="datewidget-item${className}${today === i ? ' today' : ''}${selected === i ? ' selected' : ''}${
28
+ disableFn && disableFn(year, month, i) ? ' disabled' : ''
29
+ }" data-date="${year + '|' + month + '|' + i}">${i}</span>`,
30
+ );
31
+ }
32
+ };
33
+
34
+ // 渲染上月日期项
35
+ const renderPrevMonthItems = (
36
+ items: string[],
37
+ year: number,
38
+ month: number,
39
+ index: number,
40
+ todayValue: Date,
41
+ selectedValue?: Date,
42
+ disableFn?: (year: number, month: number, date: number) => boolean,
43
+ ) => {
44
+ // 获取上月天数
45
+ let days = new Date(year, month, 0).getDate();
46
+
47
+ if (month > 0) {
48
+ month--;
49
+ } else {
50
+ year--;
51
+ month = 11;
52
+ }
53
+
54
+ renderDates(items, year, month, days - index + 1, days, ' prev-block', todayValue, selectedValue, disableFn);
55
+ };
56
+
57
+ const renderNextMonthItems = (
58
+ items: string[],
59
+ year: number,
60
+ month: number,
61
+ days: number,
62
+ todayValue: Date,
63
+ selectedValue?: Date,
64
+ disableFn?: (year: number, month: number, date: number) => boolean,
65
+ ) => {
66
+ if (month < 11) {
67
+ month++;
68
+ } else {
69
+ year++;
70
+ month = 0;
71
+ }
72
+
73
+ renderDates(items, year, month, 1, days, ' next-block', todayValue, selectedValue, disableFn);
74
+ };
75
+
76
+ const renderItems = (
77
+ currentValue: Date,
78
+ selectedValue?: Date,
79
+ disableFn?: (year: number, month: number, date: number) => boolean,
80
+ ) => {
81
+ let today = new Date();
82
+ let year = currentValue.getFullYear();
83
+ let month = currentValue.getMonth();
84
+ let firstDate = new Date(year, month, 1); // 获取当前月的第一天
85
+
86
+ let firstWeek = firstDate.getDay();
87
+ let items = [];
88
+ let index = 0;
89
+ let days;
90
+
91
+ // 当前月第一天不是周一,渲染上月数据
92
+ if (firstWeek !== 1) {
93
+ index = firstWeek > 0 ? firstWeek - 1 : 6;
94
+ renderPrevMonthItems(items, year, month, index, today, selectedValue, disableFn);
95
+ }
96
+
97
+ // 获取当前月的天数
98
+ days = new Date(year, month + 1, 0).getDate();
99
+ // 渲染本月日期
100
+ renderDates(items, year, month, 1, days, '', today, selectedValue, disableFn);
4
101
 
102
+ // 当前月最后一天没有占满,渲染下月数据
103
+ if ((index += days) < 42) {
104
+ renderNextMonthItems(items, year, month, 42 - index, today, selectedValue, disableFn);
105
+ }
106
+
107
+ return items.join('');
108
+ };
109
+
110
+ /**
111
+ * 年份组件
112
+ */
5
113
  export const YearWidget = (
6
114
  props: Omit<JSX.HTMLAttributes<never>, 'children'> & {
7
115
  /**
8
- * 日期值
116
+ * 年月值
9
117
  */
10
- value?: Date | string | number;
118
+ value?: [year: number, month: number];
11
119
  /**
12
120
  * 值变更事件
13
121
  */
@@ -15,8 +123,76 @@ export const YearWidget = (
15
123
  /**
16
124
  * 禁用函数
17
125
  */
18
- disableFn?: (year: number, month: number, date: number) => boolean;
126
+ disableFn?: (year: number, month: number) => boolean;
19
127
  },
20
128
  ) => {
21
- return <div></div>;
129
+ let domTitle: HTMLElement;
130
+ let domBody: HTMLElement;
131
+
132
+ // const [selectedValue, setSelectedValue] = createSignal(props.value);
133
+ // const [currentValue, setCurrentValue] = createSignal(selectedValue() || getCurrentMonth());
134
+
135
+ // const onclick = (event: Event) => {
136
+ // let target = event.currentTarget as HTMLElement;
137
+ // let month = target.dataset.month as any;
138
+
139
+ // // 没有选中
140
+ // if (month && !target.classList.contains('selected')) {
141
+ // month = month.split('|');
142
+ // month = [currentValue()[0] + (month[0] | 0), month[1] | 0];
143
+
144
+ // setSelectedValue(month);
145
+ // props.onValueChange && props.onValueChange(month);
146
+ // }
147
+ // };
148
+
149
+ return (
150
+ <div class={combineClass('monthwidget datewidget', props.class)}>
151
+ {/* <div class="datewidget-header">
152
+ <div ref={domTitle as any} class="datewidget-title">
153
+ {replaceTemplate(i18n.Title, currentValue()[0], formatMonth(currentValue()[1]))}
154
+ </div>
155
+ <svg
156
+ class="icon icon-s"
157
+ aria-hidden={true}
158
+ onclick={() => setCurrentValue([currentValue()[0] - 1, currentValue()[1]])}
159
+ >
160
+ <use href="#icon-backward"></use>
161
+ </svg>
162
+ <svg
163
+ class="icon icon-s"
164
+ aria-hidden={true}
165
+ onclick={() => setCurrentValue([currentValue()[0] + 1, currentValue()[1]])}
166
+ >
167
+ <use href="#icon-forward"></use>
168
+ </svg>
169
+ </div>
170
+ <div
171
+ ref={domBody as any}
172
+ class="datewidget-body canlendar-body"
173
+ onclick={(event) => {
174
+ let target = event.target as HTMLElement;
175
+ let date;
176
+
177
+ while (target && target !== domBody) {
178
+ if ((date = target.dataset.date)) {
179
+ // 没有选中
180
+ if (!target.classList.contains('selected')) {
181
+ date = date.split('|');
182
+ date = new Date(date[0] | 0, date[1] | 0, date[2] | 0);
183
+
184
+ setSelectedValue(date);
185
+ props.onValueChange && props.onValueChange(date);
186
+ }
187
+
188
+ break;
189
+ } else {
190
+ target = target.parentNode as HTMLElement;
191
+ }
192
+ }
193
+ }}
194
+ innerHTML={renderItems(currentValue(), selectedValue(), props.disableFn)}
195
+ ></div> */}
196
+ </div>
197
+ );
22
198
  };
package/src/i18n/index.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import i18n from './languages/en.json';
2
2
 
3
+ /**
4
+ * 年份面板
5
+ */
6
+ export let YearWidget = i18n.YearWidget;
7
+
8
+ /**
9
+ * 月份面板
10
+ */
11
+ export let MonthWidget = i18n.MonthWidget;
12
+
3
13
  /**
4
14
  * 日历
5
15
  */
@@ -16,6 +26,8 @@ export let Form = i18n.Form;
16
26
  * @param data 当前语言数据
17
27
  */
18
28
  export const switchLanguage = (data: typeof i18n) => {
29
+ YearWidget = i18n.YearWidget;
30
+ MonthWidget = i18n.MonthWidget;
19
31
  Canleandar = i18n.Canlendar;
20
32
  Form = i18n.Form;
21
33
  };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "Canlendar": {
3
- "Month": "${0}年${1}月",
3
+ "Title": "${0}年${1}月",
4
4
  "Weeks": [
5
5
  "一",
6
6
  "二",
@@ -11,6 +11,13 @@
11
11
  "日"
12
12
  ]
13
13
  },
14
+ "MonthWidget": {
15
+ "Title": "${0}年",
16
+ "Format": "${0}月"
17
+ },
18
+ "YearWidget": {
19
+ "Title": "${0} - ${1}"
20
+ },
14
21
  "Form": {
15
22
  "Required": "不能为空",
16
23
  "NotLessThan": "不能小于 ${value}",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "Canlendar": {
3
- "Month": "${0}年${1}月",
3
+ "Title": "${0}年${1}月",
4
4
  "Weeks": [
5
5
  "一",
6
6
  "二",
@@ -10,5 +10,19 @@
10
10
  "六",
11
11
  "日"
12
12
  ]
13
+ },
14
+ "MonthWidget": {
15
+ "Title": "${0}年",
16
+ "Format": "${0}月"
17
+ },
18
+ "YearWidget": {
19
+ "Title": "${0} - ${1}"
20
+ },
21
+ "Form": {
22
+ "Required": "不能为空",
23
+ "NotLessThan": "不能小于 ${value}",
24
+ "NotGreaterThan": "不能大于 ${value}",
25
+ "Between": "必须在 ${min} -> ${max} 之间",
26
+ "NotDate": "\"${value}\" 不是一个有效的日期值"
13
27
  }
14
28
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "Canlendar": {
3
- "Month": "${0}年${1}月",
3
+ "Title": "${0}年${1}月",
4
4
  "Weeks": [
5
5
  "一",
6
6
  "二",
@@ -10,5 +10,19 @@
10
10
  "六",
11
11
  "日"
12
12
  ]
13
+ },
14
+ "MonthWidget": {
15
+ "Title": "${0}年",
16
+ "Format": "${0}月"
17
+ },
18
+ "YearWidget": {
19
+ "Title": "${0} - ${1}"
20
+ },
21
+ "Form": {
22
+ "Required": "不能为空",
23
+ "NotLessThan": "不能小于 ${value}",
24
+ "NotGreaterThan": "不能大于 ${value}",
25
+ "Between": "必须在 ${min} -> ${max} 之间",
26
+ "NotDate": "\"${value}\" 不是一个有效的日期值"
13
27
  }
14
28
  }
package/src/index.ts CHANGED
@@ -26,6 +26,7 @@ export * from './components/Form';
26
26
  export * from './components/CollapsiblePanel';
27
27
  export * from './components/Carousel';
28
28
  export * from './components/KeepAlive';
29
+ export * from './components/Popup';
29
30
  export * from './components/Dialog';
30
31
 
31
32
  export * from './ssr/render';
package/src/location.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isBrowser } from './dom';
2
- import { reactive } from './reactive';
2
+ import { batch, reactive } from './reactive';
3
3
 
4
4
  export interface Location {
5
5
  /**
@@ -98,10 +98,12 @@ export const updateURL = (path: string, search?: string, hash?: string) => {
98
98
  location.hash = hash || '';
99
99
 
100
100
  if (location.path !== path || location.search !== search) {
101
- location.path = path;
102
- location.paths = path.match(/\/[^/]*/g) || [];
103
- location.search = search || '';
104
- location.query = search ? parseQuery(search) : {};
101
+ batch(() => {
102
+ location.path = path;
103
+ location.paths = path.match(/\/[^/]*/g) || [];
104
+ location.search = search || '';
105
+ location.query = search ? parseQuery(search) : {};
106
+ });
105
107
  }
106
108
  };
107
109