@mptw/skylens-ui 1.0.0
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/.editorconfig +12 -0
- package/.eslintrc.cjs +4 -0
- package/.nuxtrc +1 -0
- package/.playground/app.config.ts +5 -0
- package/.playground/nuxt.config.ts +3 -0
- package/README.md +73 -0
- package/app.config.ts +5 -0
- package/app.vue +3 -0
- package/assets/css/fonts/MEShPlus-font-icon.eot +0 -0
- package/assets/css/fonts/MEShPlus-font-icon.svg +186 -0
- package/assets/css/fonts/MEShPlus-font-icon.ttf +0 -0
- package/assets/css/fonts/MEShPlus-font-icon.woff +0 -0
- package/assets/css/icons.css +555 -0
- package/assets/css/layout.styl +98 -0
- package/assets/css/tailwind.css +3 -0
- package/assets/images/commons/app-logo-white.png +0 -0
- package/assets/images/commons/app-logo.png +0 -0
- package/assets/images/commons/empty-box.png +0 -0
- package/assets/images/commons/watermark.svg +15 -0
- package/components/SLAlertModal.vue +99 -0
- package/components/SLBreadcrumbs.vue +42 -0
- package/components/SLButton.vue +301 -0
- package/components/SLCalendarButton.vue +259 -0
- package/components/SLCalendarPopup.vue +832 -0
- package/components/SLCard.vue +118 -0
- package/components/SLChart.vue +181 -0
- package/components/SLCheckbox.vue +179 -0
- package/components/SLCircleButton.vue +95 -0
- package/components/SLCollapsableBlock.vue +116 -0
- package/components/SLCollapsableMulitPillSelect.vue +92 -0
- package/components/SLConfirmModal.vue +122 -0
- package/components/SLDateInput.vue +460 -0
- package/components/SLDatePicker.vue +143 -0
- package/components/SLDistributor.vue +30 -0
- package/components/SLDownloadButton.vue +410 -0
- package/components/SLDraggable.vue +151 -0
- package/components/SLDropdown.vue +277 -0
- package/components/SLDropdownItem.vue +31 -0
- package/components/SLElementWithTitle.vue +181 -0
- package/components/SLEyeCheckbox.vue +162 -0
- package/components/SLFileInput.vue +101 -0
- package/components/SLGenderAgeSelect.vue +279 -0
- package/components/SLHeatMap.vue +151 -0
- package/components/SLHourRangeInput.vue +211 -0
- package/components/SLIOSSwitch.vue +235 -0
- package/components/SLIcon.vue +35 -0
- package/components/SLIconButton.vue +130 -0
- package/components/SLInfoTip.vue +221 -0
- package/components/SLInsightSitePage.vue +27 -0
- package/components/SLLegend.vue +76 -0
- package/components/SLLinearProgressBar.vue +35 -0
- package/components/SLLink.vue +162 -0
- package/components/SLLoading.vue +127 -0
- package/components/SLMapChart.vue +151 -0
- package/components/SLModal.vue +377 -0
- package/components/SLMonthCalendarButton.vue +378 -0
- package/components/SLMonthPicker.vue +151 -0
- package/components/SLMultiSelect.vue +121 -0
- package/components/SLNoData.vue +43 -0
- package/components/SLPageModal.vue +64 -0
- package/components/SLPagination.vue +192 -0
- package/components/SLPillCheckbox.vue +207 -0
- package/components/SLPillLabel.vue +101 -0
- package/components/SLPopupMenuButton.vue +158 -0
- package/components/SLProfileButton.vue +186 -0
- package/components/SLRadioButton.vue +97 -0
- package/components/SLRadioButtonGroup.vue +113 -0
- package/components/SLRadioGroup.vue +201 -0
- package/components/SLRangeInput.vue +209 -0
- package/components/SLRegionsMapChart.vue +151 -0
- package/components/SLRightSider.vue +242 -0
- package/components/SLSearchInput.vue +87 -0
- package/components/SLSelect.vue +545 -0
- package/components/SLSelectAllToggle.vue +118 -0
- package/components/SLSiderbarNav.vue +394 -0
- package/components/SLSiderbarNavItem.vue +204 -0
- package/components/SLSitePage.vue +96 -0
- package/components/SLSkyInsightSitePage.vue +27 -0
- package/components/SLSortByDropdown.vue +189 -0
- package/components/SLSpinIcon.vue +24 -0
- package/components/SLStayRangeInput.vue +306 -0
- package/components/SLTab.vue +159 -0
- package/components/SLTable.vue +409 -0
- package/components/SLTableTooltip.vue +111 -0
- package/components/SLTabs.vue +388 -0
- package/components/SLTextInput.vue +362 -0
- package/components/SLTextarea.vue +134 -0
- package/components/SLToast.vue +71 -0
- package/components/SLToggleButton.vue +78 -0
- package/components/SLTwoLayerMultiSelect.vue +428 -0
- package/components/SLTwoLayerSelect.vue +265 -0
- package/components/SLWarnModal.vue +75 -0
- package/interface/IDateRange.ts +5 -0
- package/interface/IHourRange.ts +4 -0
- package/interface/IInputOption.ts +6 -0
- package/interface/ILegendItem.ts +7 -0
- package/interface/IPopupMenuButton.ts +5 -0
- package/interface/IStayRange.ts +15 -0
- package/interface/ITableField.ts +19 -0
- package/interface/IWeb.ts +5 -0
- package/interface/NavConfigType.ts +14 -0
- package/interface/commons.ts +7 -0
- package/models/DateRange.ts +21 -0
- package/nuxt.config.ts +22 -0
- package/package.json +52 -0
- package/plugins/googlemaps.ts +17 -0
- package/plugins/v-calendar.ts +5 -0
- package/public/assets/files/taiwan-regions.json +7 -0
- package/public/assets/files/taiwan.json +24 -0
- package/public/assets/images/commons/default-favico.png +0 -0
- package/public/assets/images/dashboard/closure-button-icon.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-bar-chart-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-bar-chart-icon-poi.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-bar-chart-icon-web.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-country-heatmap-chart-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-country-heatmap-chart-icon.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-geo-list-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-geo-list-icon-poi.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-geo-list-icon-web.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-heatmap-chart-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-heatmap-chart-icon-web.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-line-chart-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-line-chart-icon-poi.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-list-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-list-icon-poi.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-list-icon-web.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-pie-chart-icon-disabled.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-pie-chart-icon-poi.png +0 -0
- package/public/assets/images/dashboard/dashboard-widget-pie-chart-icon-web.png +0 -0
- package/public/assets/images/dashboard/drag-hint-icon.svg +3 -0
- package/public/assets/images/dashboard/extend-button-icon.png +0 -0
- package/public/assets/images/dashboard/map-list-chart-icon.svg +17 -0
- package/public/assets/images/dashboard/map-marker-chart-icon.svg +32 -0
- package/public/assets/images/dashboard/pie-chart-icon.svg +4 -0
- package/public/assets/images/dashboard/poi-gender-age-chart-icon.svg +20 -0
- package/public/assets/images/dashboard/poi-nav-icon.png +0 -0
- package/public/assets/images/dashboard/web-gender-age-chart-icon.svg +20 -0
- package/public/assets/images/dashboard/web-nav-icon.png +0 -0
- package/tailwind.config.js +300 -0
- package/tsconfig.json +8 -0
- package/utils/constants.ts +160 -0
- package/utils/generateSheet.ts +36 -0
- package/utils/index.ts +539 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
SLModal(
|
|
3
|
+
:show="show"
|
|
4
|
+
:title="title"
|
|
5
|
+
size="xs"
|
|
6
|
+
:backdrop="true"
|
|
7
|
+
:closeOnBackdrop="false"
|
|
8
|
+
modalClass='alert-modal'
|
|
9
|
+
@update:show="onUpdatedShow"
|
|
10
|
+
)
|
|
11
|
+
slot
|
|
12
|
+
SLIcon(
|
|
13
|
+
v-if="color === 'primary'"
|
|
14
|
+
icon="check-circle"
|
|
15
|
+
).text-secondary
|
|
16
|
+
SLIcon(
|
|
17
|
+
v-else
|
|
18
|
+
icon="exclamation-triangle"
|
|
19
|
+
:class="color === '' ? '' : `text-${color}-hover`"
|
|
20
|
+
)
|
|
21
|
+
p(v-html='message')
|
|
22
|
+
template(#footer)
|
|
23
|
+
SLButton(
|
|
24
|
+
color="primary"
|
|
25
|
+
size="lg"
|
|
26
|
+
:title="buttonTitle"
|
|
27
|
+
@click="onClickedConfirm"
|
|
28
|
+
)
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script lang="ts">
|
|
32
|
+
export default defineComponent({
|
|
33
|
+
name: "SLAlertModal",
|
|
34
|
+
components: {},
|
|
35
|
+
props: {
|
|
36
|
+
show: {
|
|
37
|
+
type: Boolean,
|
|
38
|
+
default: false,
|
|
39
|
+
},
|
|
40
|
+
title: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: "",
|
|
43
|
+
},
|
|
44
|
+
buttonTitle: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: "確定",
|
|
47
|
+
},
|
|
48
|
+
color: {
|
|
49
|
+
type: String,
|
|
50
|
+
default: "secondary",
|
|
51
|
+
validator: (value: string) =>
|
|
52
|
+
["", "primary", "secondary", "danger"].includes(value),
|
|
53
|
+
},
|
|
54
|
+
message: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: "",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
emits: ["update:show"],
|
|
60
|
+
setup(_, { emit }) {
|
|
61
|
+
function onClickedConfirm() {
|
|
62
|
+
emit("update:show", false);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function onUpdatedShow(value: boolean) {
|
|
66
|
+
emit("update:show", value);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
onClickedConfirm,
|
|
71
|
+
onUpdatedShow,
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<style lang="stylus">
|
|
78
|
+
.alert-modal
|
|
79
|
+
@apply z-60
|
|
80
|
+
|
|
81
|
+
.modal-backdrop
|
|
82
|
+
@apply s('bg-white/40') backdrop-blur-5
|
|
83
|
+
|
|
84
|
+
&.show
|
|
85
|
+
@apply s('bg-white/40')
|
|
86
|
+
|
|
87
|
+
.modal-body
|
|
88
|
+
&-content
|
|
89
|
+
@apply text-base leading-6 text-gray-2 text-center space-y-4
|
|
90
|
+
|
|
91
|
+
.icon
|
|
92
|
+
@apply s('text-7.17xl')
|
|
93
|
+
|
|
94
|
+
p
|
|
95
|
+
@apply whitespace-pre-wrap
|
|
96
|
+
|
|
97
|
+
.modal-footer
|
|
98
|
+
@apply flex justify-center
|
|
99
|
+
</style>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
.breadcrumbs
|
|
3
|
+
.breadcrumbs-container
|
|
4
|
+
template(v-for="item, i in items")
|
|
5
|
+
span.breadcrumb-divider(v-if="i > 0") |
|
|
6
|
+
span.breadcrumb-item {{ item }}
|
|
7
|
+
SLInfoTip(v-if="info !== ''" :info="info")
|
|
8
|
+
.breadcrumbs-notice(v-if="$slots.notice")
|
|
9
|
+
slot(name="notice")
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import type { PropType } from "vue";
|
|
14
|
+
|
|
15
|
+
export default defineComponent({
|
|
16
|
+
name: "SLBreadcrumbs",
|
|
17
|
+
components: {},
|
|
18
|
+
props: {
|
|
19
|
+
items: {
|
|
20
|
+
type: Array as PropType<Array<string>>,
|
|
21
|
+
default: () => [],
|
|
22
|
+
},
|
|
23
|
+
info: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: "",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
setup() {},
|
|
29
|
+
});
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style lang="stylus">
|
|
33
|
+
.breadcrumbs
|
|
34
|
+
@apply flex flex-wrap items-center justify-start text-lg text-primary font-bold
|
|
35
|
+
|
|
36
|
+
&-container
|
|
37
|
+
.breadcrumb-item:not(:last-child)
|
|
38
|
+
@apply text-base font-normal
|
|
39
|
+
|
|
40
|
+
&-notice
|
|
41
|
+
@apply inline-flex items-center
|
|
42
|
+
</style>
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
button(:type='type', :class='btnClass' :disabled="disabled")
|
|
3
|
+
.btn-content
|
|
4
|
+
slot
|
|
5
|
+
SLIcon(v-if='icon !== ""', :icon='icon')
|
|
6
|
+
span(v-if='title !== ""') {{ title }}
|
|
7
|
+
SLIcon(v-if='postIcon !== ""', :icon='postIcon')
|
|
8
|
+
.btn-loading
|
|
9
|
+
.loading
|
|
10
|
+
div
|
|
11
|
+
div
|
|
12
|
+
div
|
|
13
|
+
div
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import type { PropType } from "vue";
|
|
18
|
+
|
|
19
|
+
export default defineComponent({
|
|
20
|
+
name: "SLButton",
|
|
21
|
+
components: {},
|
|
22
|
+
props: {
|
|
23
|
+
size: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: "",
|
|
26
|
+
validator: (val: string) => ["", "lg", "md", "sm", "xs"].includes(val),
|
|
27
|
+
},
|
|
28
|
+
color: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: "",
|
|
31
|
+
validator: (val: string) =>
|
|
32
|
+
[
|
|
33
|
+
"",
|
|
34
|
+
"white",
|
|
35
|
+
"primary",
|
|
36
|
+
"primary-hover",
|
|
37
|
+
"secondary",
|
|
38
|
+
"third",
|
|
39
|
+
"danger",
|
|
40
|
+
"cancel",
|
|
41
|
+
"gray-2",
|
|
42
|
+
"secondary-new",
|
|
43
|
+
"blue-1",
|
|
44
|
+
"insight-title-line",
|
|
45
|
+
].includes(val),
|
|
46
|
+
},
|
|
47
|
+
variant: {
|
|
48
|
+
type: String,
|
|
49
|
+
default: "",
|
|
50
|
+
validator: (val: string) => ["", "outline", "icon"].includes(val),
|
|
51
|
+
},
|
|
52
|
+
disabled: {
|
|
53
|
+
type: Boolean,
|
|
54
|
+
default: false,
|
|
55
|
+
},
|
|
56
|
+
icon: {
|
|
57
|
+
type: String,
|
|
58
|
+
default: "",
|
|
59
|
+
},
|
|
60
|
+
postIcon: {
|
|
61
|
+
type: String,
|
|
62
|
+
default: "",
|
|
63
|
+
},
|
|
64
|
+
title: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: "",
|
|
67
|
+
},
|
|
68
|
+
type: {
|
|
69
|
+
type: String as PropType<"submit" | "reset" | "button">,
|
|
70
|
+
default: "button",
|
|
71
|
+
validator: (val: string) => ["submit", "reset", "button"].includes(val),
|
|
72
|
+
},
|
|
73
|
+
loading: {
|
|
74
|
+
type: Boolean,
|
|
75
|
+
default: false,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
setup(props, { emit }) {
|
|
79
|
+
const { size, color, variant, disabled, loading } = toRefs(props);
|
|
80
|
+
|
|
81
|
+
const btnClass = computed(() => {
|
|
82
|
+
const btnClass = ["btn"];
|
|
83
|
+
if (size.value !== "") {
|
|
84
|
+
btnClass.push(`btn-${size.value}`);
|
|
85
|
+
}
|
|
86
|
+
if (color.value !== "") {
|
|
87
|
+
btnClass.push(`btn-${color.value}`);
|
|
88
|
+
}
|
|
89
|
+
if (variant.value !== "") {
|
|
90
|
+
btnClass.push(`btn-${variant.value}`);
|
|
91
|
+
}
|
|
92
|
+
if (disabled.value) {
|
|
93
|
+
btnClass.push("btn-disabled");
|
|
94
|
+
}
|
|
95
|
+
if (loading.value) {
|
|
96
|
+
btnClass.push("loading");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return btnClass.join(" ");
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
btnClass,
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<style lang="stylus">
|
|
110
|
+
.btn
|
|
111
|
+
@apply relative inline-flex items-center justify-center s("p-1.75") border border-transparent rounded bg-transparent text-base leading-normal s("focus:outline-none")
|
|
112
|
+
|
|
113
|
+
&-lg
|
|
114
|
+
@apply s("px-7.75")
|
|
115
|
+
|
|
116
|
+
&-md
|
|
117
|
+
@apply s("px-3.75")
|
|
118
|
+
|
|
119
|
+
&-sm
|
|
120
|
+
@apply s("py-0.75") s("px-1.75")
|
|
121
|
+
|
|
122
|
+
.btn-content
|
|
123
|
+
@apply space-x-1
|
|
124
|
+
|
|
125
|
+
&-xs
|
|
126
|
+
@apply s("py-0.75") s("px-1.75") text-xs
|
|
127
|
+
|
|
128
|
+
.btn-content
|
|
129
|
+
@apply space-x-1
|
|
130
|
+
|
|
131
|
+
&-white
|
|
132
|
+
@apply bg-white border-white text-gray-2 s("hover:bg-white") s("hover:border-white")
|
|
133
|
+
|
|
134
|
+
&.btn-outline
|
|
135
|
+
@apply text-gray-2 s("hover:text-gray-2")
|
|
136
|
+
|
|
137
|
+
.btn-loading
|
|
138
|
+
.loading
|
|
139
|
+
div
|
|
140
|
+
border-color white transparent transparent transparent
|
|
141
|
+
|
|
142
|
+
&-primary
|
|
143
|
+
@apply bg-primary border-primary text-gray s("hover:bg-primary-hover") s("hover:border-primary-hover")
|
|
144
|
+
|
|
145
|
+
&.btn-outline
|
|
146
|
+
@apply text-primary s("hover:text-primary-hover")
|
|
147
|
+
|
|
148
|
+
.btn-loading
|
|
149
|
+
.loading
|
|
150
|
+
div
|
|
151
|
+
border-color theme('colors.primary.DEFAULT') transparent transparent transparent
|
|
152
|
+
|
|
153
|
+
&-primary-hover
|
|
154
|
+
@apply bg-primary-hover border-primary-hover text-gray s("hover:bg-primary-lighter") s("hover:border-primary-lighter")
|
|
155
|
+
|
|
156
|
+
&.btn-outline
|
|
157
|
+
@apply text-primary-hover s("hover:text-primary-lighter")
|
|
158
|
+
|
|
159
|
+
.btn-loading
|
|
160
|
+
.loading
|
|
161
|
+
div
|
|
162
|
+
border-color theme('colors.primary.hover') transparent transparent transparent
|
|
163
|
+
|
|
164
|
+
&-secondary
|
|
165
|
+
@apply bg-secondary border-secondary text-gray s("hover:bg-secondary-hover") s("hover:text-white") s("hover:border-secondary-hover")
|
|
166
|
+
|
|
167
|
+
&.btn-outline
|
|
168
|
+
@apply text-secondary s("hover:text-secondary-hover")
|
|
169
|
+
|
|
170
|
+
.btn-loading
|
|
171
|
+
.loading
|
|
172
|
+
div
|
|
173
|
+
border-color theme('colors.secondary.hover') transparent transparent transparent
|
|
174
|
+
|
|
175
|
+
&-third
|
|
176
|
+
@apply bg-third-7 border-third-7 text-white s("hover:bg-third-hover") s("hover:text-white") s("hover:border-third-hover")
|
|
177
|
+
|
|
178
|
+
&.btn-outline
|
|
179
|
+
@apply text-secondary s("hover:text-secondary-hover")
|
|
180
|
+
|
|
181
|
+
.btn-loading
|
|
182
|
+
.loading
|
|
183
|
+
div
|
|
184
|
+
border-color theme('colors.third.hover') transparent transparent transparent
|
|
185
|
+
|
|
186
|
+
&-danger
|
|
187
|
+
@apply bg-danger border-danger text-white s("hover:bg-danger-hover") s("hover:border-danger-hover")
|
|
188
|
+
|
|
189
|
+
&.btn-outline
|
|
190
|
+
@apply text-danger s("hover:text-danger-hover")
|
|
191
|
+
|
|
192
|
+
.btn-loading
|
|
193
|
+
.loading
|
|
194
|
+
div
|
|
195
|
+
border-color theme('colors.danger.hover') transparent transparent transparent
|
|
196
|
+
|
|
197
|
+
&-cancel
|
|
198
|
+
@apply bg-cancel border-cancel text-gray-2 s("hover:bg-cancel-hover") s("hover:border-cancel-hover")
|
|
199
|
+
|
|
200
|
+
&.btn-outline
|
|
201
|
+
@apply text-cancel s("hover:text-cancel-hover")
|
|
202
|
+
|
|
203
|
+
.btn-loading
|
|
204
|
+
.loading
|
|
205
|
+
div
|
|
206
|
+
border-color theme('colors.cancel.hover') transparent transparent transparent
|
|
207
|
+
|
|
208
|
+
&-gray-2
|
|
209
|
+
@apply bg-gray-2 border-gray-2 text-white s("hover:bg-gray-3") s("hover:border-gray-3")
|
|
210
|
+
|
|
211
|
+
&.btn-outline
|
|
212
|
+
@apply text-gray-2 s("hover:text-gray-3")
|
|
213
|
+
|
|
214
|
+
.btn-loading
|
|
215
|
+
.loading
|
|
216
|
+
div
|
|
217
|
+
border-color theme('colors.gray.3') transparent transparent transparent
|
|
218
|
+
|
|
219
|
+
&-secondary-new
|
|
220
|
+
@apply bg-secondary-new border-secondary-new text-white s("hover:bg-secondary-new") s("hover:border-secondary-new")
|
|
221
|
+
|
|
222
|
+
&.btn-outline
|
|
223
|
+
@apply text-secondary-new s("hover:text-secondary-new")
|
|
224
|
+
|
|
225
|
+
.btn-loading
|
|
226
|
+
.loading
|
|
227
|
+
div
|
|
228
|
+
border-color theme('colors.secondary.new') transparent transparent transparent
|
|
229
|
+
|
|
230
|
+
&-blue-1
|
|
231
|
+
@apply bg-secondary-new border-secondary-new text-white s("hover:bg-blue-1") s("hover:border-blue-1")
|
|
232
|
+
|
|
233
|
+
&.btn-outline
|
|
234
|
+
@apply text-blue-1 s("hover:text-blue-1")
|
|
235
|
+
|
|
236
|
+
.btn-loading
|
|
237
|
+
.loading
|
|
238
|
+
div
|
|
239
|
+
border-color theme('colors.blue.1') transparent transparent transparent
|
|
240
|
+
|
|
241
|
+
&-insight-title-line
|
|
242
|
+
@apply bg-insight-title-line border-insight-title-line text-white s("hover:bg-insight-title-line") s("hover:border-insight-title-line")
|
|
243
|
+
|
|
244
|
+
&.btn-outline
|
|
245
|
+
@apply text-insight-title s("hover:text-insight-title")
|
|
246
|
+
|
|
247
|
+
.btn-loading
|
|
248
|
+
.loading
|
|
249
|
+
div
|
|
250
|
+
border-color theme('colors.blue.1') transparent transparent transparent
|
|
251
|
+
|
|
252
|
+
&-outline
|
|
253
|
+
@apply bg-transparent border s("hover:bg-white")
|
|
254
|
+
|
|
255
|
+
&-disabled
|
|
256
|
+
@apply bg-cancel border-cancel text-white cursor-default s("hover:bg-cancel") s("hover:border-cancel") s("hover:text-white")
|
|
257
|
+
|
|
258
|
+
&.btn-outline
|
|
259
|
+
@apply bg-cancel border-cancel text-white s("hover:bg-cancel") s("hover:border-cancel") s("hover:text-white")
|
|
260
|
+
|
|
261
|
+
&.btn-icon
|
|
262
|
+
@apply bg-transparent border-transparent text-cancel s("hover:bg-transparent") s("hover:border-transparent") s("hover:text-cancel")
|
|
263
|
+
|
|
264
|
+
&.loading
|
|
265
|
+
@apply bg-line border-line cursor-default
|
|
266
|
+
|
|
267
|
+
.btn-content
|
|
268
|
+
@apply opacity-0
|
|
269
|
+
|
|
270
|
+
.btn-loading
|
|
271
|
+
@apply block
|
|
272
|
+
|
|
273
|
+
.btn-content
|
|
274
|
+
@apply inline-flex items-center space-x-2
|
|
275
|
+
|
|
276
|
+
.btn-loading
|
|
277
|
+
@apply absolute s('top-1/2') s('left-1/2') w-4 h-4 s('-translate-x-1/2') s('-translate-y-1/2') pointer-events-none hidden
|
|
278
|
+
|
|
279
|
+
.loading
|
|
280
|
+
@apply relative inline-block w-4 h-4
|
|
281
|
+
|
|
282
|
+
div
|
|
283
|
+
@apply absolute block w-4 h-4 border-2 rounded-full
|
|
284
|
+
animation loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite
|
|
285
|
+
|
|
286
|
+
&:nth-child(1)
|
|
287
|
+
animation-delay -0.45s
|
|
288
|
+
|
|
289
|
+
&:nth-child(2)
|
|
290
|
+
animation-delay -0.3s
|
|
291
|
+
|
|
292
|
+
&:nth-child(3)
|
|
293
|
+
animation-delay -0.15s
|
|
294
|
+
|
|
295
|
+
@keyframes loading
|
|
296
|
+
0%
|
|
297
|
+
transform rotate(0deg)
|
|
298
|
+
|
|
299
|
+
100%
|
|
300
|
+
transform rotate(360deg)
|
|
301
|
+
</style>
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<template lang="pug">
|
|
2
|
+
.calendar-button(ref="button")
|
|
3
|
+
a(
|
|
4
|
+
href="javascript:;"
|
|
5
|
+
@click="onClickedToggle"
|
|
6
|
+
ref="toggle"
|
|
7
|
+
).toggle-button
|
|
8
|
+
.date-range
|
|
9
|
+
SLIcon(icon="calendar")
|
|
10
|
+
span.divider
|
|
11
|
+
span.date-range {{ dateRange1 }}
|
|
12
|
+
span.range-days(v-if='dateRange1Days') {{ dateRange1Days }} 天
|
|
13
|
+
.compare-date-range(v-if="dateRange2 && showCompareSwitch")
|
|
14
|
+
span v.s.
|
|
15
|
+
span {{ dateRange2 }}
|
|
16
|
+
ClientOnly
|
|
17
|
+
Teleport(to="body")
|
|
18
|
+
SLCalendarPopup(
|
|
19
|
+
:data-source-type='dataSourceType'
|
|
20
|
+
:show-quicks="showQuicks"
|
|
21
|
+
:showCompareSwitch="showCompareSwitch"
|
|
22
|
+
:min-date="minDate"
|
|
23
|
+
:maxDate="maxDate"
|
|
24
|
+
:maxDays="maxDays"
|
|
25
|
+
:modelValue="modelValue"
|
|
26
|
+
@compare:change="onCompareChanged"
|
|
27
|
+
@update:modelValue="onInputed"
|
|
28
|
+
ref="popup"
|
|
29
|
+
)
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script lang="ts">
|
|
33
|
+
import { SLCalendarPopup } from "#components";
|
|
34
|
+
import type { PropType } from "vue";
|
|
35
|
+
import { fromEvent } from "rxjs";
|
|
36
|
+
import { differenceInCalendarDays, subDays } from "date-fns";
|
|
37
|
+
import { createPopper } from "@popperjs/core";
|
|
38
|
+
import type { Placement } from "@popperjs/core";
|
|
39
|
+
import DateRange from "~ui/models/DateRange";
|
|
40
|
+
import type IDateRange from "~ui/interface/IDateRange";
|
|
41
|
+
import { OnlineSourceType } from "~ui/interface/IWeb";
|
|
42
|
+
|
|
43
|
+
type SLCalendarPopupType = InstanceType<typeof SLCalendarPopup>;
|
|
44
|
+
|
|
45
|
+
export default defineComponent({
|
|
46
|
+
name: "SLCalendarButton",
|
|
47
|
+
components: {},
|
|
48
|
+
props: {
|
|
49
|
+
dataSourceType: {
|
|
50
|
+
type: Number as PropType<OnlineSourceType>,
|
|
51
|
+
default: OnlineSourceType.Mobile,
|
|
52
|
+
},
|
|
53
|
+
showQuicks: {
|
|
54
|
+
type: Boolean,
|
|
55
|
+
default: true,
|
|
56
|
+
},
|
|
57
|
+
showCompareSwitch: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: true,
|
|
60
|
+
},
|
|
61
|
+
minDate: {
|
|
62
|
+
type: Date,
|
|
63
|
+
default: () => null,
|
|
64
|
+
},
|
|
65
|
+
maxDate: {
|
|
66
|
+
type: Date,
|
|
67
|
+
default: () => subDays(Date.now(), 1),
|
|
68
|
+
},
|
|
69
|
+
maxDays: {
|
|
70
|
+
type: Number,
|
|
71
|
+
default: 365,
|
|
72
|
+
},
|
|
73
|
+
modelValue: {
|
|
74
|
+
type: Array as PropType<Array<IDateRange | null>>,
|
|
75
|
+
default: () => [
|
|
76
|
+
{ start: new Date(2020, 8, 11), end: new Date(2020, 8, 17) },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
placement: {
|
|
80
|
+
type: String,
|
|
81
|
+
default: "bottom-start",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
emits: ["update:modelValue"],
|
|
85
|
+
setup(props, { emit }) {
|
|
86
|
+
const { modelValue, placement } = toRefs(props);
|
|
87
|
+
|
|
88
|
+
const button = shallowRef<HTMLElement | null>(null);
|
|
89
|
+
const toggle = shallowRef<HTMLElement | null>(null);
|
|
90
|
+
const popup = shallowRef<SLCalendarPopupType | null>(null);
|
|
91
|
+
|
|
92
|
+
let popperInstance: any = null;
|
|
93
|
+
let clickSubscriber: any = null;
|
|
94
|
+
|
|
95
|
+
const dateRange1 = computed(() => {
|
|
96
|
+
const [dateRange1] = modelValue.value;
|
|
97
|
+
if (!dateRange1) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return new DateRange(dateRange1.start, dateRange1.end);
|
|
101
|
+
});
|
|
102
|
+
const dateRange2 = computed(() => {
|
|
103
|
+
const [, dateRange2] = modelValue.value;
|
|
104
|
+
if (!dateRange2) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return new DateRange(dateRange2.start, dateRange2.end);
|
|
108
|
+
});
|
|
109
|
+
const dateRange1Days = computed(() => {
|
|
110
|
+
if (!dateRange1.value || !dateRange1.value.start || !dateRange1.value.end)
|
|
111
|
+
return 0;
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
differenceInCalendarDays(dateRange1.value.end, dateRange1.value.start) +
|
|
115
|
+
1
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
function subscribeClick() {
|
|
120
|
+
clickSubscriber = fromEvent(window, "click").subscribe((e) => {
|
|
121
|
+
const { target } = e;
|
|
122
|
+
if (
|
|
123
|
+
button.value &&
|
|
124
|
+
!button.value.contains(target as Node) &&
|
|
125
|
+
popup.value &&
|
|
126
|
+
!popup.value.$el.contains(target as Node)
|
|
127
|
+
) {
|
|
128
|
+
hide();
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function unsubscribeClick() {
|
|
134
|
+
if (clickSubscriber) {
|
|
135
|
+
clickSubscriber.unsubscribe();
|
|
136
|
+
}
|
|
137
|
+
clickSubscriber = null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function show() {
|
|
141
|
+
if (!popup.value) return;
|
|
142
|
+
|
|
143
|
+
subscribeClick();
|
|
144
|
+
popup.value.$el.setAttribute("data-show", "");
|
|
145
|
+
|
|
146
|
+
popperInstance.setOptions({
|
|
147
|
+
modifiers: [
|
|
148
|
+
{
|
|
149
|
+
name: "offset",
|
|
150
|
+
options: {
|
|
151
|
+
offset: [0, 8],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{ name: "eventListeners", enabled: true },
|
|
155
|
+
],
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
popperInstance.update();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function hide() {
|
|
162
|
+
if (!popup.value || popup.value.$el.getAttribute("data-show") === null)
|
|
163
|
+
return;
|
|
164
|
+
unsubscribeClick();
|
|
165
|
+
popup.value.$el.removeAttribute("data-show");
|
|
166
|
+
popperInstance.setOptions({
|
|
167
|
+
modifiers: [{ name: "eventListeners", enabled: false }],
|
|
168
|
+
});
|
|
169
|
+
nextTick(() => {
|
|
170
|
+
if (popup.value) {
|
|
171
|
+
popup.value.reset();
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function onClickedToggle() {
|
|
177
|
+
if (!popup.value || popup.value.$el.getAttribute("data-show") !== null) {
|
|
178
|
+
hide();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
show();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function onInputed(value: Array<IDateRange>) {
|
|
185
|
+
emit("update:modelValue", value);
|
|
186
|
+
hide();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function onCompareChanged() {
|
|
190
|
+
popperInstance.update();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
onMounted(() => {
|
|
194
|
+
nextTick(() => {
|
|
195
|
+
if (button.value && popup.value && popup.value.$el) {
|
|
196
|
+
popperInstance = createPopper(
|
|
197
|
+
button.value,
|
|
198
|
+
popup.value.$el as HTMLElement,
|
|
199
|
+
{
|
|
200
|
+
placement: placement.value as Placement,
|
|
201
|
+
modifiers: [{ name: "eventListeners", enabled: false }],
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
onBeforeUnmount(() => {
|
|
209
|
+
if (popperInstance) {
|
|
210
|
+
popperInstance.destroy();
|
|
211
|
+
}
|
|
212
|
+
popperInstance = null;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
button,
|
|
217
|
+
toggle,
|
|
218
|
+
popup,
|
|
219
|
+
dateRange1,
|
|
220
|
+
dateRange2,
|
|
221
|
+
dateRange1Days,
|
|
222
|
+
onClickedToggle,
|
|
223
|
+
onInputed,
|
|
224
|
+
onCompareChanged,
|
|
225
|
+
hide,
|
|
226
|
+
};
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
</script>
|
|
230
|
+
|
|
231
|
+
<style lang="stylus" scoped>
|
|
232
|
+
.calendar-button
|
|
233
|
+
@apply inline-block
|
|
234
|
+
|
|
235
|
+
.toggle-button
|
|
236
|
+
@apply inline-flex flex-col justify-center s('px-2.75') space-y-1 border s('border-white/20') rounded bg-white text-sm leading-normal text-gray-2
|
|
237
|
+
height 58px
|
|
238
|
+
|
|
239
|
+
.date-range
|
|
240
|
+
@apply flex items-center
|
|
241
|
+
|
|
242
|
+
.icon
|
|
243
|
+
@apply flex-grow-0 flex-shrink-0 text-base text-primary leading-none
|
|
244
|
+
|
|
245
|
+
.divider
|
|
246
|
+
@apply flex-grow-0 flex-shrink-0 block w-px s('h-4.75') ml-2 s('mr-1.75') bg-primary
|
|
247
|
+
|
|
248
|
+
.range-days
|
|
249
|
+
@apply block s('ml-0.5') px-1 s('py-0.5') bg-bg-middle rounded text-xs text-primary
|
|
250
|
+
|
|
251
|
+
.compare-date-range
|
|
252
|
+
@apply pl-1 space-x-2 text-sm text-gray-3
|
|
253
|
+
|
|
254
|
+
.calendar-popup
|
|
255
|
+
@apply z-60 absolute invisible pointer-events-none
|
|
256
|
+
|
|
257
|
+
&[data-show]
|
|
258
|
+
@apply visible pointer-events-auto
|
|
259
|
+
</style>
|