cdui-js 1.0.19 → 1.0.21
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/css/all.css +1 -1
- package/css/{canlendar.css → datewidget.css} +39 -34
- package/demo/css/css.md +9 -8
- package/demo/src/App.tsx +2 -26
- package/demo/src/css/atomic.css +7 -7
- package/demo/src/pages/Canlendar.tsx +12 -6
- package/demo/src/pages/Carousel.tsx +40 -0
- package/demo/src/pages/Form.tsx +1 -4
- package/package.json +1 -1
- package/src/components/Canlendar.tsx +29 -21
- package/src/components/Carousel.tsx +26 -30
- package/src/components/MonthWidget.tsx +86 -48
- package/src/components/YearWidget.tsx +181 -5
- package/src/i18n/index.ts +12 -0
- package/src/i18n/languages/en.json +8 -1
- package/src/i18n/languages/zh-CN.json +15 -1
- package/src/i18n/languages/zh-TW.json +15 -1
- package/src/index.ts +1 -0
package/css/all.css
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
.
|
|
2
|
-
.monthwidget {
|
|
1
|
+
.datewidget {
|
|
3
2
|
max-width: 380px;
|
|
4
3
|
height: 320px;
|
|
5
4
|
border-radius: 12px;
|
|
6
5
|
padding: 16px;
|
|
7
|
-
font-size: 12px;
|
|
8
6
|
user-select: none;
|
|
7
|
+
font-size: 16px;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
.
|
|
12
|
-
.canlendar-weeks,
|
|
13
|
-
.monthwidget-header {
|
|
10
|
+
.datewidget-header {
|
|
14
11
|
display: flex;
|
|
15
12
|
align-items: center;
|
|
16
13
|
height: 36px;
|
|
17
14
|
line-height: 36px;
|
|
18
15
|
}
|
|
19
16
|
|
|
20
|
-
.
|
|
21
|
-
.monthwidget-title {
|
|
17
|
+
.datewidget-title {
|
|
22
18
|
flex: auto;
|
|
23
19
|
padding-left: 12px;
|
|
24
20
|
font-weight: bold;
|
|
@@ -26,8 +22,7 @@
|
|
|
26
22
|
cursor: pointer;
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
.
|
|
30
|
-
.monthwidget-header > .icon {
|
|
25
|
+
.datewidget-header > .icon {
|
|
31
26
|
box-sizing: border-box;
|
|
32
27
|
width: 40px;
|
|
33
28
|
height: 100%;
|
|
@@ -35,46 +30,56 @@
|
|
|
35
30
|
cursor: pointer;
|
|
36
31
|
}
|
|
37
32
|
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
text-align: center;
|
|
41
|
-
vertical-align: middle;
|
|
33
|
+
.datewidget-body {
|
|
34
|
+
height: calc(100% - 36px);
|
|
42
35
|
}
|
|
43
36
|
|
|
44
|
-
.
|
|
45
|
-
height: calc(100% - 72px);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.canlendar-date,
|
|
49
|
-
.monthwidget-month {
|
|
37
|
+
.datewidget-item {
|
|
50
38
|
display: inline-flex;
|
|
51
39
|
justify-content: center;
|
|
52
40
|
align-items: center;
|
|
53
|
-
width:
|
|
54
|
-
height:
|
|
41
|
+
width: 25%;
|
|
42
|
+
height: 25%;
|
|
55
43
|
cursor: pointer;
|
|
56
44
|
}
|
|
57
45
|
|
|
58
|
-
.
|
|
59
|
-
.monthwidget-month.disabled {
|
|
46
|
+
.datewidget-item.disabled {
|
|
60
47
|
cursor: not-allowed;
|
|
61
48
|
}
|
|
62
49
|
|
|
63
|
-
.
|
|
64
|
-
.
|
|
65
|
-
.monthwidget-month.today,
|
|
66
|
-
.monthwidget-month.selected {
|
|
50
|
+
.datewidget-item.today,
|
|
51
|
+
.datewidget-item.selected {
|
|
67
52
|
position: relative;
|
|
68
53
|
}
|
|
69
54
|
|
|
70
|
-
.
|
|
71
|
-
.
|
|
72
|
-
.monthwidget-month.today::before,
|
|
73
|
-
.monthwidget-month.selected::before {
|
|
55
|
+
.datewidget-item.today::before,
|
|
56
|
+
.datewidget-item.selected::before {
|
|
74
57
|
position: absolute;
|
|
75
58
|
content: '';
|
|
59
|
+
width: 60px;
|
|
60
|
+
height: 60px;
|
|
61
|
+
border-radius: 60px;
|
|
62
|
+
z-index: -1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.canlendar-weeks > span {
|
|
66
|
+
flex: auto;
|
|
67
|
+
text-align: center;
|
|
68
|
+
vertical-align: middle;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.canlendar-body {
|
|
72
|
+
height: calc(100% - 72px);
|
|
73
|
+
font-size: 12px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.canlendar-body .datewidget-item {
|
|
77
|
+
width: 14.28%;
|
|
78
|
+
height: 16.66%;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.canlendar-body .datewidget-item.today::before,
|
|
82
|
+
.canlendar-body .datewidget-item.selected::before {
|
|
76
83
|
width: 40px;
|
|
77
84
|
height: 40px;
|
|
78
|
-
border-radius: 40px;
|
|
79
|
-
z-index: -1;
|
|
80
85
|
}
|
package/demo/css/css.md
CHANGED
|
@@ -287,16 +287,17 @@
|
|
|
287
287
|
.combobox:has(.combobox-input:focus) { border: 1px solid #1b212d; }
|
|
288
288
|
|
|
289
289
|
|
|
290
|
-
# canlendar 日历
|
|
290
|
+
# canlendar monthwidget yearwidget 日历 年月 年
|
|
291
|
+
|
|
292
|
+
.datewidget { border: 1px solid #e4e4e4; }
|
|
293
|
+
.datewidget-header > .icon { stroke: #1b212d; }
|
|
294
|
+
.datewidget-item.disabled { color: #e4e4e4; }
|
|
295
|
+
.datewidget-item.prev-block, .datewidget-item.next-block { color: #888f97; }
|
|
296
|
+
.datewidget-item.today::before { background: #f5f5f5; }
|
|
297
|
+
.datewidget-item.selected { color: white; }
|
|
298
|
+
.datewidget-item.selected::before { background: #ff4000; }
|
|
291
299
|
|
|
292
|
-
.canlendar { border: 1px solid #e4e4e4; }
|
|
293
|
-
.canlendar-header > .icon { stroke: #1b212d; }
|
|
294
300
|
.canlendar-weeks > span { color: #888f97; }
|
|
295
|
-
.canlendar-date.disabled { color: #e4e4e4; }
|
|
296
|
-
.canlendar-date.prev-month, .canlendar-date.next-month { color: #888f97; }
|
|
297
|
-
.canlendar-date.today::before { background: #f5f5f5; }
|
|
298
|
-
.canlendar-date.selected { color: white; }
|
|
299
|
-
.canlendar-date.selected::before { background: #ff4000; }
|
|
300
301
|
|
|
301
302
|
|
|
302
303
|
# datepicker 日期选择
|
package/demo/src/App.tsx
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
|
-
import { batch, createEffect, omitProps, pickProps, reactive } from '../../src/reactive';
|
|
2
|
-
import { Icon } from '../../src/components/Icon';
|
|
3
1
|
import { CanlendarPage } from './pages/Canlendar';
|
|
2
|
+
import { CarouselPage } from './pages/Carousel';
|
|
4
3
|
import { ComboBoxPage } from './pages/ComboBox';
|
|
5
4
|
import { DatePickerPage } from './pages/DatePicker';
|
|
6
5
|
import { FormPage } from './pages/Form';
|
|
7
6
|
import { MobileDatePickerPage } from './pages/MobileDatePicker';
|
|
8
|
-
import { TextBox } from '../../src/components/TextBox';
|
|
9
|
-
|
|
10
|
-
const Test = (props: { text1: string; text2: string }) => {
|
|
11
|
-
let dom: HTMLElement;
|
|
12
|
-
return (
|
|
13
|
-
<div>
|
|
14
|
-
<div>{pickProps(props, ['text1']).text1}</div>
|
|
15
|
-
<div>{omitProps(props, ['text1']).text2}</div>
|
|
16
|
-
<TextBox ref={dom as any}></TextBox>
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
7
|
|
|
21
8
|
export const App = () => {
|
|
22
|
-
let state = reactive({
|
|
23
|
-
text1: '111',
|
|
24
|
-
text2: '222',
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
createEffect(() => {
|
|
28
|
-
console.log(state.text1, state.text2);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
9
|
return (
|
|
32
10
|
<div style={{ 'min-height': '100%' }}>
|
|
33
|
-
<
|
|
34
|
-
<Test text1={state.text1} text2={state.text2}></Test>
|
|
35
|
-
<button onclick={() => batch(() => (state.text1 = state.text2 = '' + Math.random()))}>click</button>
|
|
11
|
+
<CarouselPage></CarouselPage>
|
|
36
12
|
<CanlendarPage></CanlendarPage>
|
|
37
13
|
<DatePickerPage></DatePickerPage>
|
|
38
14
|
<MobileDatePickerPage></MobileDatePickerPage>
|
package/demo/src/css/atomic.css
CHANGED
|
@@ -913,14 +913,14 @@ body { stroke: #A2A7AD; fill: #A2A7AD; }
|
|
|
913
913
|
.combobox:has(.combobox-input:focus) { border: 1px solid #1b212d; }
|
|
914
914
|
|
|
915
915
|
|
|
916
|
-
.
|
|
917
|
-
.
|
|
916
|
+
.datewidget { border: 1px solid #e4e4e4; }
|
|
917
|
+
.datewidget-header > .icon { stroke: #1b212d; }
|
|
918
|
+
.datewidget-item.disabled { color: #e4e4e4; }
|
|
919
|
+
.datewidget-item.prev-block, .datewidget-item.next-block { color: #888f97; }
|
|
920
|
+
.datewidget-item.today::before { background: #f5f5f5; }
|
|
921
|
+
.datewidget-item.selected { color: white; }
|
|
922
|
+
.datewidget-item.selected::before { background: #ff4000; }
|
|
918
923
|
.canlendar-weeks > span { color: #888f97; }
|
|
919
|
-
.canlendar-date.disabled { color: #e4e4e4; }
|
|
920
|
-
.canlendar-date.prev-month, .canlendar-date.next-month { color: #888f97; }
|
|
921
|
-
.canlendar-date.today::before { background: #f5f5f5; }
|
|
922
|
-
.canlendar-date.selected { color: white; }
|
|
923
|
-
.canlendar-date.selected::before { background: #ff4000; }
|
|
924
924
|
|
|
925
925
|
|
|
926
926
|
.datepicker { border: 1px solid #e4e4e4; background: white; }
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { Canlendar } from '../../../src/components/Canlendar';
|
|
2
|
+
import { MonthWidget } from '../../../src/components/MonthWidget';
|
|
3
|
+
import { YearWidget } from '../../../src/components/YearWidget';
|
|
2
4
|
|
|
3
5
|
export const CanlendarPage = () => {
|
|
4
6
|
return (
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
<div>
|
|
8
|
+
<Canlendar
|
|
9
|
+
value={new Date()}
|
|
10
|
+
onValueChange={(date) => {
|
|
11
|
+
console.log(date);
|
|
12
|
+
}}
|
|
13
|
+
></Canlendar>
|
|
14
|
+
<MonthWidget></MonthWidget>
|
|
15
|
+
<YearWidget></YearWidget>
|
|
16
|
+
</div>
|
|
11
17
|
);
|
|
12
18
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Carousel, CarouselApi, CarouselButtons } from '../../../src/components/Carousel';
|
|
2
|
+
|
|
3
|
+
const carousels = [
|
|
4
|
+
{
|
|
5
|
+
text: '页面1',
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
text: '页面2',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
text: '页面3',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
text: '页面4',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export const CarouselPage = () => {
|
|
19
|
+
let carousel: CarouselApi;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div class="relative">
|
|
23
|
+
<Carousel
|
|
24
|
+
class="row-gap"
|
|
25
|
+
api={(api) => (carousel = api)}
|
|
26
|
+
each={carousels}
|
|
27
|
+
disabledScroll={true}
|
|
28
|
+
autoplay={false}
|
|
29
|
+
style={{ width: '100%', height: '200px' }}
|
|
30
|
+
>
|
|
31
|
+
{(item) => (
|
|
32
|
+
<div class="border round" style={{ flex: 'none', width: '100%', height: '100%', 'margin-right': '4px' }}>
|
|
33
|
+
{item.text}
|
|
34
|
+
</div>
|
|
35
|
+
)}
|
|
36
|
+
</Carousel>
|
|
37
|
+
<CarouselButtons carousel={carousel}></CarouselButtons>
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
};
|
package/demo/src/pages/Form.tsx
CHANGED
|
@@ -59,10 +59,7 @@ export const FormPage = () => {
|
|
|
59
59
|
{(item) => (
|
|
60
60
|
<FormItem field={item.field} label={item.label} required={item.required}>
|
|
61
61
|
<div>
|
|
62
|
-
<
|
|
63
|
-
{/* <item.Input></item.Input> */}
|
|
64
|
-
<TextBox></TextBox>
|
|
65
|
-
<TextBox></TextBox>
|
|
62
|
+
<item.Input></item.Input>
|
|
66
63
|
</div>
|
|
67
64
|
</FormItem>
|
|
68
65
|
)}
|
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@ const renderDates = (
|
|
|
24
24
|
|
|
25
25
|
for (let i = from; i <= to; i++) {
|
|
26
26
|
items.push(
|
|
27
|
-
`<span class="
|
|
27
|
+
`<span class="datewidget-item${className}${today === i ? ' today' : ''}${selected === i ? ' selected' : ''}${
|
|
28
28
|
disableFn && disableFn(year, month, i) ? ' disabled' : ''
|
|
29
29
|
}" data-date="${year + '|' + month + '|' + i}">${i}</span>`,
|
|
30
30
|
);
|
|
@@ -51,7 +51,7 @@ const renderPrevMonthItems = (
|
|
|
51
51
|
month = 11;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
renderDates(items, year, month, days - index + 1, days, ' prev-
|
|
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-
|
|
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,
|
|
164
|
+
const [selectedValue, setSelectedValue] = createSignal(parseDate(props.value));
|
|
162
165
|
const [currentValue, setCurrentValue] = createSignal(selectedValue() || new Date());
|
|
163
166
|
|
|
164
167
|
return (
|
|
165
|
-
<div class={combineClass('canlendar', props.class)} {...omitProps(props, OMIT_PROPS)}>
|
|
166
|
-
<div class="canlendar-header">
|
|
167
|
-
<div ref={domTitle as any} class="
|
|
168
|
-
{replaceTemplate(i18n.
|
|
168
|
+
<div class={combineClass('canlendar datewidget', props.class)} {...omitProps(props, OMIT_PROPS)}>
|
|
169
|
+
<div class="datewidget-header canlendar-header">
|
|
170
|
+
<div ref={domTitle as any} class="datewidget-title">
|
|
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>
|
|
@@ -174,25 +177,30 @@ export const Canlendar = (
|
|
|
174
177
|
<use href="#icon-forward"></use>
|
|
175
178
|
</svg>
|
|
176
179
|
</div>
|
|
177
|
-
<div class="canlendar-weeks">
|
|
180
|
+
<div class="datewidget-header canlendar-weeks">
|
|
178
181
|
<For each={i18n.Weeks}>{(item) => <span>{item}</span>}</For>
|
|
179
182
|
</div>
|
|
180
183
|
<div
|
|
181
184
|
ref={domBody as any}
|
|
182
|
-
class="canlendar-body"
|
|
185
|
+
class="datewidget-body canlendar-body"
|
|
183
186
|
onclick={(event) => {
|
|
184
187
|
let target = event.target as HTMLElement;
|
|
185
|
-
let date
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
}}
|
|
@@ -15,9 +15,7 @@ import {
|
|
|
15
15
|
import { For } from './For';
|
|
16
16
|
import { Icon } from './Icon';
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const EVENT_OPTIONS = { passive: true, capture: true };
|
|
18
|
+
const EVENT_OPTIONS = { passive: false, capture: true };
|
|
21
19
|
|
|
22
20
|
const DOTS = new Array(100).join('0').split('');
|
|
23
21
|
|
|
@@ -48,7 +46,7 @@ if (isBrowser) {
|
|
|
48
46
|
);
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
const OMIT_PROPS = ['class', 'each', 'children', 'autoplay', 'interval', '
|
|
49
|
+
const OMIT_PROPS = ['class', 'each', 'children', 'autoplay', 'interval', 'disabledScroll', 'api'] as const;
|
|
52
50
|
|
|
53
51
|
/**
|
|
54
52
|
* 轮播组件外部调用接口
|
|
@@ -94,9 +92,9 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
94
92
|
*/
|
|
95
93
|
interval?: number;
|
|
96
94
|
/**
|
|
97
|
-
*
|
|
95
|
+
* 是否禁止滚动(触控时不允许上下滚动)
|
|
98
96
|
*/
|
|
99
|
-
|
|
97
|
+
disabledScroll?: boolean;
|
|
100
98
|
/**
|
|
101
99
|
* 外部调用接口
|
|
102
100
|
*/
|
|
@@ -113,11 +111,6 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
113
111
|
// 自动滚动计时器
|
|
114
112
|
let autoplayTimer: any;
|
|
115
113
|
|
|
116
|
-
// 获取滚动方向
|
|
117
|
-
const scrollType = createMemo(() => (props.vertical ? 'scrollTop' : 'scrollLeft'));
|
|
118
|
-
const offsetType = createMemo(() => (props.vertical ? 'offsetTop' : 'offsetLeft'));
|
|
119
|
-
const screenType = createMemo(() => (props.vertical ? 'screenY' : 'screenX'));
|
|
120
|
-
|
|
121
114
|
// 滚动到指定索引
|
|
122
115
|
const scrollTo = (index: number) => {
|
|
123
116
|
let children = ref.children;
|
|
@@ -135,7 +128,7 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
135
128
|
animateScrollIntoView(ref, children[index % length] as HTMLElement).then(() => {
|
|
136
129
|
if (index >= count) {
|
|
137
130
|
// 滚动到对应节点
|
|
138
|
-
ref
|
|
131
|
+
ref.scrollLeft = (children[index - count] as HTMLElement).offsetLeft;
|
|
139
132
|
// 调整到指定节点
|
|
140
133
|
index -= count;
|
|
141
134
|
}
|
|
@@ -152,7 +145,7 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
152
145
|
let count = props.each.length;
|
|
153
146
|
|
|
154
147
|
// 先滚动到对应节点的填充节点
|
|
155
|
-
ref
|
|
148
|
+
ref.scrollLeft = (ref.children[index + count] as HTMLElement).offsetLeft;
|
|
156
149
|
// 调整到指定节点
|
|
157
150
|
index += count;
|
|
158
151
|
}
|
|
@@ -174,21 +167,31 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
174
167
|
checkFirstIndex();
|
|
175
168
|
|
|
176
169
|
// 记录按下时状态
|
|
177
|
-
pressdown = (event.changedTouches[0] || event.touches[0])
|
|
178
|
-
pressdownScroll = ref
|
|
170
|
+
pressdown = (event.changedTouches[0] || event.touches[0]).screenX;
|
|
171
|
+
pressdownScroll = ref.scrollLeft;
|
|
179
172
|
|
|
180
173
|
// 取消自动播放
|
|
181
174
|
clearTimeout(autoplayTimer);
|
|
175
|
+
|
|
176
|
+
if (props.disabledScroll) {
|
|
177
|
+
event.preventDefault();
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
182
180
|
};
|
|
183
181
|
|
|
184
182
|
const ontouchmove = (event: TouchEvent) => {
|
|
185
183
|
if (pressdown >= 0) {
|
|
186
|
-
ref
|
|
184
|
+
ref.scrollLeft = pressdownScroll - ((event.changedTouches[0] || event.touches[0]).screenX - pressdown);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (props.disabledScroll) {
|
|
188
|
+
event.preventDefault();
|
|
189
|
+
return false;
|
|
187
190
|
}
|
|
188
191
|
};
|
|
189
192
|
|
|
190
193
|
const ontouchend = (event: TouchEvent) => {
|
|
191
|
-
let distance = (event.changedTouches[0] || event.touches[0])
|
|
194
|
+
let distance = (event.changedTouches[0] || event.touches[0]).screenX - pressdown;
|
|
192
195
|
let index = currentIndex();
|
|
193
196
|
|
|
194
197
|
// 清除按下状态
|
|
@@ -200,13 +203,18 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
200
203
|
} else if (distance < -20) {
|
|
201
204
|
// 如果是第一个位置,则恢复滚动位置
|
|
202
205
|
if (index === 0) {
|
|
203
|
-
ref
|
|
206
|
+
ref.scrollLeft = (ref.children[0] as HTMLElement).offsetLeft;
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
scrollTo(index + 1);
|
|
207
210
|
} else {
|
|
208
211
|
animateScrollIntoView(ref, ref.children[index % ref.children.length] as HTMLElement);
|
|
209
212
|
}
|
|
213
|
+
|
|
214
|
+
if (props.disabledScroll) {
|
|
215
|
+
event.preventDefault();
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
210
218
|
};
|
|
211
219
|
|
|
212
220
|
const autoplay = () => {
|
|
@@ -244,18 +252,6 @@ export const Carousel = <T, U extends JSX.Element>(
|
|
|
244
252
|
) as CarouselApi,
|
|
245
253
|
);
|
|
246
254
|
|
|
247
|
-
createEffect(() => {
|
|
248
|
-
let classList = ref.classList;
|
|
249
|
-
|
|
250
|
-
if (props.vertical) {
|
|
251
|
-
if (!classList.contains(CLASS_NAME)) {
|
|
252
|
-
classList.add();
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
classList.remove(CLASS_NAME);
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
|
|
259
255
|
createEffect(autoplay);
|
|
260
256
|
|
|
261
257
|
onMount(() => {
|
|
@@ -1,36 +1,61 @@
|
|
|
1
|
-
import { createSignal, combineClass } from '../reactive';
|
|
2
|
-
|
|
3
1
|
import { JSX } from '../jsx';
|
|
4
|
-
import {
|
|
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
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
<div>
|
|
58
|
-
<div class="
|
|
59
|
-
<div ref={domTitle as any} class="
|
|
60
|
-
{replaceTemplate(i18n.
|
|
96
|
+
<div class={combineClass('monthwidget datewidget', props.class)}>
|
|
97
|
+
<div class="datewidget-header">
|
|
98
|
+
<div ref={domTitle as any} class="datewidget-title">
|
|
99
|
+
{replaceTemplate(i18n.Title, currentValue()[0])}
|
|
61
100
|
</div>
|
|
62
|
-
<svg
|
|
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
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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?:
|
|
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
|
|
126
|
+
disableFn?: (year: number, month: number) => boolean;
|
|
19
127
|
},
|
|
20
128
|
) => {
|
|
21
|
-
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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';
|