@@ -14,12 +14,19 @@ const props = defineProps({
1414 to: {
1515 type: String ,
1616 default: ' ' ,
17+ },
18+ minDate: {
19+ type: String ,
20+ default: ' ' ,
1721 }
1822})
1923
2024const emit = defineEmits ([" onUpdate" ])
21- const month = ref (DateTime .now ().month )
22- const year = ref (DateTime .now ().year )
25+
26+ const currentDate = ref (DateTime .now ())
27+ const limitMinDate = ref (props .minDate ? DateTime .fromISO (props .minDate ) : ' ' )
28+ const month = ref (currentDate .value .month )
29+ const year = ref (currentDate .value .year )
2330const startDate = ref (props .from ? DateTime .fromSeconds (parseInt (props .from )) : {})
2431const endDate = ref (props .to ? DateTime .fromSeconds (parseInt (props .to )) : {})
2532const weekdays = ref (Info .weekdays (' narrow' , { locale: ' en-US' }))
@@ -56,6 +63,36 @@ const days = computed(() => {
5663 return resDays
5764})
5865
66+ const selectedRange = ref (' ' )
67+ const updateSelectedRange = (from , to ) => {
68+ if (from? .ts ) {
69+ if (to? .ts ) {
70+ if (from .year === to .year ) {
71+ selectedRange .value = from .toFormat (' dd LLL' ) !== to .toFormat (' dd LLL' ) ? ` ${ from .toFormat (' dd LLL' )} - ${ to .toFormat (' dd LLL' )} ` : from .toFormat (' dd LLL' )
72+ } else {
73+ selectedRange .value = ` ${ from .toFormat (' dd LLL yyyy' )} - ${ to .toFormat (' dd LLL yyyy' )} `
74+ }
75+ } else {
76+ selectedRange .value = from .toFormat (' dd LLL' )
77+ }
78+ } else {
79+ selectedRange .value = ' '
80+ }
81+ }
82+ updateSelectedRange (startDate .value , endDate .value )
83+
84+ const isNextMonthAvailable = computed (() => ! (month .value === currentDate .value .month && year .value === currentDate .value .year ))
85+ const isPrevMonthAvailable = computed (() => limitMinDate .value ? limitMinDate .value .ts < days .value [0 ][0 ].ts : true )
86+ const isDayAvailable = (d ) => {
87+ if (d .startOf (' day' ).ts > currentDate .value .startOf (' day' ).ts ) {
88+ return false
89+ } else if (limitMinDate .value ) {
90+ return d .startOf (' day' ).ts >= limitMinDate .value .startOf (' day' ).ts
91+ } else {
92+ return true
93+ }
94+ }
95+
5996const handleSelectDate = (d ) => {
6097 if (! startDate .value .ts ) {
6198 startDate .value = d
@@ -91,21 +128,30 @@ const handleOpen = () => {
91128}
92129const handleClose = () => {
93130 isOpen .value = false
131+
132+ if (! startDate .value .ts ) {
133+ month .value = currentDate .value .month
134+ year .value = currentDate .value .year
135+ }
94136}
95137
96138const handleApply = () => {
97- emit (' onUpdate' , { from: parseInt (startDate .value .ts / 1_000 ), to: parseInt ((endDate .value .ts ? endDate .value .ts : startDate .value .endOf (' day' ).ts ) / 1_000 ) })
98-
99139 isOpen .value = false
140+
141+ if (! endDate .value .ts ) {
142+ endDate .value = startDate .value .endOf (' day' )
143+ }
144+
145+ emit (' onUpdate' , { from: parseInt (startDate .value .ts / 1_000 ), to: parseInt (endDate .value .ts / 1_000 ) })
100146}
101147
102148const handleClear = () => {
149+ isOpen .value = false
150+
103151 startDate .value = {}
104152 endDate .value = {}
105153
106154 emit (' onUpdate' , { clear: true })
107-
108- isOpen .value = false
109155}
110156
111157const handleMonthChange = (v ) => {
@@ -122,6 +168,13 @@ const handleMonthChange = (v) => {
122168 month .value += v
123169 }
124170}
171+
172+ watch (
173+ () => props .from ,
174+ () => {
175+ updateSelectedRange (DateTime .fromSeconds (parseInt (props .from )), DateTime .fromSeconds (parseInt (props .to )))
176+ },
177+ )
125178< / script>
126179
127180< template>
@@ -131,11 +184,11 @@ const handleMonthChange = (v) => {
131184
132185 < Text color= " secondary" > Date Range < / Text >
133186
134- <template v-if =" from " >
187+ < template v- if = " selectedRange " >
135188 < div : class = " $style.vertical_divider" / >
136189
137190 < Text size= " 12" weight= " 600" color= " primary" >
138- {{ (endDate.ts && startDate.toFormat('LLL dd') !== endDate?.toFormat('LLL dd')) ? `${startDate.toFormat('LLL dd')} - ${endDate.toFormat('LLL dd')}` : startDate.toFormat('LLL dd') }}
191+ {{ selectedRange }}
139192 < / Text >
140193
141194 < Icon @click .stop = " handleClear" name= " close-circle" size= " 12" color= " secondary" / >
@@ -150,6 +203,7 @@ const handleMonthChange = (v) => {
150203 name= " chevron"
151204 size= " 14"
152205 color= " tertiary"
206+ : class = " !isPrevMonthAvailable && $style.disabled"
153207 : style= " { transform: 'rotate(90deg)' }"
154208 / >
155209
@@ -160,6 +214,7 @@ const handleMonthChange = (v) => {
160214 name= " chevron"
161215 size= " 14"
162216 color= " tertiary"
217+ : class = " !isNextMonthAvailable && $style.disabled"
163218 : style= " { transform: 'rotate(-90deg)' }"
164219 / >
165220 < / Flex>
@@ -176,13 +231,13 @@ const handleMonthChange = (v) => {
176231
177232 < tbody>
178233 < tr v- for = " w in days" >
179- <td v-for =" d in w" >
234+ < td v- for = " d in w" : class = " !isDayAvailable(d) && $style.disabled " >
180235 < Flex align= " center" justify= " center"
181236 @click= " handleSelectDate(d)"
182237 : class = " [
183238 $style.day,
184239 (d.ts === startDate.ts || d.ts === endDate.ts) && $style.edgeDate,
185- isInSelectedPeriod(d) && $style.inSelectedPeriod
240+ isInSelectedPeriod(d) && $style.inSelectedPeriod
186241 ]"
187242 >
188243 < Text size= " 12" color= " primary"
@@ -264,7 +319,6 @@ const handleMonthChange = (v) => {
264319
265320.edgeDate {
266321 background- color: rgba (51 , 168 , 83 , 70 % );
267- /* background-color: var(--neutral-green); */
268322}
269323
270324.inSelectedPeriod {
@@ -275,7 +329,9 @@ const handleMonthChange = (v) => {
275329 color: var (-- txt- primary);
276330}
277331
278- .endDate {
279- background-color : rgba (51 , 168 , 83 , 70% );
332+ .disabled {
333+ opacity: 0.3 ;
334+ pointer- events: none;
335+ cursor: default;
280336}
281337< / style>
0 commit comments