Skip to content

Commit 775e958

Browse files
authored
feat(QDate): add day slot for content quasarframework#7076, quasarframework#7290 (quasarframework#7315)
* feat(QDate): add day slot for content quasarframework#7076, quasarframework#7290 * chore(QDate): add addedIn for day scoped slot
1 parent fd8d41b commit 775e958

File tree

5 files changed

+267
-6
lines changed

5 files changed

+267
-6
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<template>
2+
<div class="q-pa-md">
3+
<div class="q-gutter-md">
4+
<q-date
5+
class="day-slot--example"
6+
v-model="date"
7+
:events="eventsFn"
8+
:event-color="eventDetailsFn"
9+
>
10+
<template v-slot:day="day">
11+
<small v-if="day.fill === true" class="text-grey-4">
12+
{{ day.i }}
13+
</small>
14+
<div v-else-if="day.event" class="day-slot__events--example absolute-full">
15+
<div
16+
v-for="({ color, label, details }, index) in day.event"
17+
:key="index"
18+
:class="'bg-' + color"
19+
>
20+
<q-tooltip
21+
:content-class="'day-slot__tooltip--example q-px-md q-py-sm rounded-borders bg-white text-subtitle2 text-' + color"
22+
anchor="bottom right"
23+
self="top left"
24+
:offset="[ 4, 4 ]"
25+
>
26+
{{ label }}
27+
</q-tooltip>
28+
</div>
29+
</div>
30+
</template>
31+
</q-date>
32+
</div>
33+
</div>
34+
</template>
35+
36+
<style lang="sass">
37+
.day-slot__events--example
38+
border-radius: 50%
39+
mix-blend-mode: overlay
40+
41+
> div
42+
position: absolute
43+
left: 0
44+
right: 0
45+
height: 50%
46+
47+
> div:first-child
48+
top: 0
49+
border-top-left-radius: 15px
50+
border-top-right-radius: 15px
51+
52+
> div:last-child
53+
bottom: 0
54+
border-bottom-left-radius: 15px
55+
border-bottom-right-radius: 15px
56+
57+
> div:first-child:last-child
58+
height: 100%
59+
60+
.day-slot--example
61+
.q-btn--unelevated
62+
.day-slot__events--example
63+
border: 2px solid transparent
64+
65+
.q-date__calendar-item--fill
66+
visibility: visible
67+
68+
.day-slot__tooltip--example
69+
border: 2px solid currentColor
70+
</style>
71+
72+
<script>
73+
export default {
74+
data () {
75+
return {
76+
date: '2019/02/01'
77+
}
78+
},
79+
80+
methods: {
81+
eventsFn (date) {
82+
const parts = date.split('/')
83+
return [ 1, 3 ].indexOf(parts[2] % 6) > -1
84+
},
85+
86+
eventDetailsFn (date) {
87+
const parts = date.split('/')
88+
return parts[2] % 6 === 1
89+
? [
90+
{
91+
color: 'red',
92+
label: `Event on ${date}`
93+
}
94+
]
95+
: [
96+
{
97+
color: 'orange',
98+
label: `Task on ${date}`
99+
},
100+
{
101+
color: 'green',
102+
label: `Recurring event on ${date}`
103+
}
104+
]
105+
}
106+
}
107+
}
108+
</script>

docs/src/pages/vue-components/date.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ The first example is using an array and the second example is using a function.
108108

109109
<doc-example title="Event color" file="QDate/EventColor" overflow />
110110

111+
### Day scoped slot
112+
113+
You can use the `day` scoped slot to render custom event markers or tooltips specific to each day.
114+
115+
<doc-example title="Day slot" file="QDate/DaySlot" overflow />
116+
111117
### Limiting options
112118

113119
* You can use the `options` prop to limit user selection to certain times.

ui/dev/src/pages/form/date.vue

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,35 @@
133133
/>
134134
</div>
135135

136+
<div class="text-h6">
137+
Day slot
138+
</div>
139+
<div class="q-gutter-md">
140+
<q-date
141+
class="day-slot--test"
142+
v-model="date"
143+
v-bind="props"
144+
:events="eventMultiFn"
145+
:event-color="eventMultiDetails"
146+
:style="style"
147+
>
148+
<template v-slot:day="day">
149+
<small v-if="day.fill === true" class="text-grey-5">
150+
{{ day.i }}
151+
</small>
152+
<div v-else-if="day.event" class="day-slot__events--test absolute-full">
153+
<div
154+
v-for="({ color, label, details }, index) in day.event"
155+
:key="index"
156+
:class="'bg-' + color"
157+
>
158+
<q-tooltip>{{ label }}</q-tooltip>
159+
</div>
160+
</div>
161+
</template>
162+
</q-date>
163+
</div>
164+
136165
<div class="text-h6">
137166
Limited options
138167
</div>
@@ -327,6 +356,39 @@
327356
</div>
328357
</template>
329358

359+
<style lang="sass">
360+
.day-slot__events--test
361+
border-radius: 50%
362+
mix-blend-mode: overlay
363+
364+
> div
365+
position: absolute
366+
left: 0
367+
right: 0
368+
height: 50%
369+
370+
> div:first-child
371+
top: 0
372+
border-top-left-radius: 15px
373+
border-top-right-radius: 15px
374+
375+
> div:last-child
376+
bottom: 0
377+
border-bottom-left-radius: 15px
378+
border-bottom-right-radius: 15px
379+
380+
> div:first-child:last-child
381+
height: 100%
382+
383+
.day-slot--test
384+
.q-btn--unelevated
385+
.day-slot__events--test
386+
border: 2px solid transparent
387+
388+
.q-date__calendar-item--fill
389+
visibility: visible
390+
</style>
391+
330392
<script>
331393
import languages from 'quasar/lang/index.json'
332394
@@ -430,6 +492,30 @@ export default {
430492
return date[9] % 2 === 0 ? 'teal' : 'orange'
431493
},
432494
495+
eventMultiFn (date) {
496+
return [ 1, 3 ].indexOf(date[9] % 6) > -1
497+
},
498+
499+
eventMultiDetails (date) {
500+
return date[9] % 6 === 1
501+
? [
502+
{
503+
color: 'red',
504+
label: `Event on ${date}`
505+
}
506+
]
507+
: [
508+
{
509+
color: 'orange',
510+
label: `Task on ${date}`
511+
},
512+
{
513+
color: 'green',
514+
label: `Recurring event on ${date}`
515+
}
516+
]
517+
},
518+
433519
optionsFn (date) {
434520
return date[9] % 3 === 0
435521
},

ui/src/components/date/QDate.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,14 @@ export default Vue.extend({
230230
const day = prefix + pad(i)
231231

232232
if (this.options !== void 0 && this.isInSelection(day) !== true) {
233-
res.push({ i })
233+
res.push({ i, day })
234234
}
235235
else {
236236
const event = this.events !== void 0 && this.evtFn(day) === true
237237
? this.evtColor(day)
238238
: false
239239

240-
res.push({ i, in: true, flat: true, event })
240+
res.push({ i, day, in: true, flat: true, event })
241241
}
242242
}
243243

@@ -470,6 +470,15 @@ export default Vue.extend({
470470
},
471471

472472
__getCalendarView (h) {
473+
const dayContentFn = this.$scopedSlots.day !== void 0
474+
? this.$scopedSlots.day
475+
: day => (day.event !== false ? [
476+
h('div', { staticClass: 'q-date__event bg-' + day.event })
477+
] : null)
478+
const dayFillContentFn = this.$scopedSlots.day !== void 0
479+
? this.$scopedSlots.day
480+
: day => h('div', [ day.i ])
481+
473482
return [
474483
h('div', {
475484
key: 'calendar-view',
@@ -524,10 +533,8 @@ export default Vue.extend({
524533
tabindex: this.computedTabindex
525534
},
526535
on: cache(this, 'day#' + day.i, { click: () => { this.__setDay(day.i) } })
527-
}, day.event !== false ? [
528-
h('div', { staticClass: 'q-date__event bg-' + day.event })
529-
] : null)
530-
: h('div', [ day.i ])
536+
}, dayContentFn(day))
537+
: dayFillContentFn(day)
531538
])))
532539
])
533540
])

ui/src/components/date/QDate.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,60 @@
131131
}
132132
},
133133

134+
"scopedSlots": {
135+
"day": {
136+
"desc": "Override default day content slot; Suggestion: tooltips and / or multiple event markers",
137+
"scope": {
138+
"i": {
139+
"type": "Number",
140+
"desc": "The day number in month",
141+
"examples": [ 23 ]
142+
},
143+
"day": {
144+
"type": "String",
145+
"desc": "Full date in YYYY/MM/DD form",
146+
"examples": [ "20/05/2020" ]
147+
},
148+
"fill": {
149+
"type": "Boolean",
150+
"desc": "The day does not belong to the currently displayed month / year (no QBtn and hidden by default)"
151+
},
152+
"in": {
153+
"type": "Boolean",
154+
"desc": "The day is selectable (QBtn is not disabled)"
155+
},
156+
"today": {
157+
"type": "Boolean",
158+
"desc": "The day is today"
159+
},
160+
"unelevated": {
161+
"type": "Boolean",
162+
"desc": "The day is selected"
163+
},
164+
"flat": {
165+
"type": "Boolean",
166+
"desc": "The day is not selected"
167+
},
168+
"color": {
169+
"type": "String",
170+
"desc": "The color of the QBtn used for the day",
171+
"examples": [ "primary" ]
172+
},
173+
"textColor": {
174+
"type": "String",
175+
"desc": "The text color of the QBtn used for the day",
176+
"examples": [ "orange-2" ]
177+
},
178+
"event": {
179+
"type": [ "Boolean", "String", "Any" ],
180+
"desc": "Boolean false if there is no event for the day; The event-color or the value returned by the event-color function",
181+
"examples": [ "red" ]
182+
}
183+
},
184+
"addedIn": "v1.12.9"
185+
}
186+
},
187+
134188
"events": {
135189
"input": {
136190
"extends": "input",

0 commit comments

Comments
 (0)