sprintify-ui 0.4.4 → 0.4.6
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/dist/sprintify-ui.es.js +27776 -18060
- package/dist/style.css +1 -1
- package/dist/types/src/components/BaseCalendar.vue.d.ts +124 -0
- package/dist/types/src/components/BaseDisplayRelativeTime.vue.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +2 -1
- package/dist/types/src/index.d.ts +12 -0
- package/dist/types/src/types/CalendarEvent.d.ts +9 -0
- package/dist/types/src/types/index.d.ts +1 -0
- package/package.json +8 -1
- package/src/components/BaseButton.vue +1 -1
- package/src/components/BaseCalendar.stories.js +202 -0
- package/src/components/BaseCalendar.vue +216 -0
- package/src/components/index.ts +2 -0
- package/src/lang/en.json +7 -1
- package/src/lang/fr.json +7 -1
- package/src/types/CalendarEvent.ts +9 -0
- package/src/types/index.ts +1 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import BaseCalendar from './BaseCalendar.vue';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Components/BaseCalendar',
|
|
5
|
+
component: BaseCalendar,
|
|
6
|
+
args: {},
|
|
7
|
+
argTypes: {
|
|
8
|
+
locale: {
|
|
9
|
+
control: { type: 'select' },
|
|
10
|
+
options: ['en', 'fr']
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function getDateByDay(day) {
|
|
16
|
+
const today = new Date();
|
|
17
|
+
const year = today.getFullYear();
|
|
18
|
+
const month = today.getMonth() + 1;
|
|
19
|
+
|
|
20
|
+
const formattedMonth = month < 10 ? `0${month}` : month;
|
|
21
|
+
const formattedDay = day < 10 ? `0${day}` : day;
|
|
22
|
+
|
|
23
|
+
const dateString = `${year}-${formattedMonth}-${formattedDay}`;
|
|
24
|
+
return dateString;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const events = [
|
|
28
|
+
{ id: 1, title: 'Reserved', start: getDateByDay(15) + ' 10:30:00', end: getDateByDay(20) + ' 13:25:00' },
|
|
29
|
+
{ id: 2, title: 'Accepted', start: getDateByDay(11), end: getDateByDay(17), backgroundColor: 'green', borderColor: 'green' },
|
|
30
|
+
{ id: 3, title: 'Blocked', start: getDateByDay(5), end: getDateByDay(5), backgroundColor: '#000', borderColor: '#000' },
|
|
31
|
+
{ id: 4, title: 'Removed', start: getDateByDay(25), end: getDateByDay(26), backgroundColor: 'orange', borderColor: 'red', textColor: 'blue' },
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
const Template = (args) => ({
|
|
35
|
+
components: { BaseCalendar },
|
|
36
|
+
setup() {
|
|
37
|
+
return { args };
|
|
38
|
+
},
|
|
39
|
+
template: `
|
|
40
|
+
<BaseCalendar v-bind="args" class="mb-3">
|
|
41
|
+
</BaseCalendar>
|
|
42
|
+
`,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
const TemplateWithAllEvents = (args) => ({
|
|
47
|
+
components: { BaseCalendar },
|
|
48
|
+
setup() {
|
|
49
|
+
function onSelect(payload) {
|
|
50
|
+
alert('selected: start = ' + payload.start + ', end = ' + payload.end);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function onClick(payload) {
|
|
54
|
+
alert('clicked: title = ' + payload.event.title + ', start = ' + payload.event.start + ', end = ' + payload.event.end)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function onAdd() {
|
|
58
|
+
alert('added')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function onChange(payload) {
|
|
62
|
+
alert('changed: start = ' + payload.event.start + ', end = ' + payload.event.end)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function onResize(payload) {
|
|
66
|
+
alert('resized: start = ' + payload.event.start + ', end = ' + payload.event.end)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function onDrop(payload) {
|
|
70
|
+
alert('dropped: start = ' + payload.event.start + ', end = ' + payload.event.end)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function onDateClick(payload) {
|
|
74
|
+
alert('date clicked = ' + payload.date);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return { args, onSelect, onClick, onAdd, onChange, onResize, onDrop, onDateClick };
|
|
78
|
+
},
|
|
79
|
+
template: `
|
|
80
|
+
<BaseCalendar
|
|
81
|
+
v-bind="args"
|
|
82
|
+
class="mb-3"
|
|
83
|
+
@select="onSelect"
|
|
84
|
+
@click="onClick"
|
|
85
|
+
@add="onAdd"
|
|
86
|
+
@change="onChange"
|
|
87
|
+
@resize="onResize"
|
|
88
|
+
@drop="onDrop"
|
|
89
|
+
@dateClick="onDateClick"
|
|
90
|
+
>
|
|
91
|
+
</BaseCalendar>
|
|
92
|
+
`,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const TemplateWithHoverEvents = (args) => ({
|
|
96
|
+
components: { BaseCalendar },
|
|
97
|
+
setup() {
|
|
98
|
+
function onMouseenter(payload) {
|
|
99
|
+
alert('mouseenter: title = ' + payload.event.title + ', start = ' + payload.event.start + ', end = ' + payload.event.end)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function onMouseleave(payload) {
|
|
103
|
+
alert('mouseleave: title = ' + payload.event.title + ', start = ' + payload.event.start + ', end = ' + payload.event.end)
|
|
104
|
+
}
|
|
105
|
+
return { args, onMouseenter, onMouseleave };
|
|
106
|
+
},
|
|
107
|
+
template: `
|
|
108
|
+
<BaseCalendar
|
|
109
|
+
v-bind="args"
|
|
110
|
+
class="mb-3"
|
|
111
|
+
@mouseenter="onMouseenter"
|
|
112
|
+
@mouseleave="onMouseleave"
|
|
113
|
+
>
|
|
114
|
+
</BaseCalendar>
|
|
115
|
+
`,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const TemplateWithSlot = (args) => ({
|
|
119
|
+
components: { BaseCalendar },
|
|
120
|
+
setup() {
|
|
121
|
+
return { args };
|
|
122
|
+
},
|
|
123
|
+
template: `
|
|
124
|
+
<BaseCalendar v-bind="args" class="mb-3">
|
|
125
|
+
<template #eventContent="{ event }">
|
|
126
|
+
<div class="px-3 py-2">
|
|
127
|
+
<div class="text-center">
|
|
128
|
+
{{ event.title }} 🤓🤓🤓
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</template>
|
|
132
|
+
</BaseCalendar>
|
|
133
|
+
`,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export const Demo = Template.bind({});
|
|
137
|
+
Demo.args = {
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const Event = TemplateWithAllEvents.bind({});
|
|
141
|
+
Event.args = {
|
|
142
|
+
events: events,
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export const HoverEvent = TemplateWithHoverEvents.bind({});
|
|
146
|
+
HoverEvent.args = {
|
|
147
|
+
events: events
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const CustomSlot = TemplateWithSlot.bind({});
|
|
151
|
+
CustomSlot.args = {
|
|
152
|
+
events: events
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export const ToolbarHeaderAll1 = Template.bind({});
|
|
156
|
+
ToolbarHeaderAll1.args = {
|
|
157
|
+
headerToolbarLeft: 'multiMonthYear dayGridMonth timeGridWeek timeGridDay listWeek',
|
|
158
|
+
headerToolbarCenter: 'title',
|
|
159
|
+
headerToolbarRight: 'prev,next today',
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const ToolbarHeaderAll2 = Template.bind({});
|
|
163
|
+
ToolbarHeaderAll2.args = {
|
|
164
|
+
headerToolbarLeft: 'title',
|
|
165
|
+
headerToolbarCenter: 'multiMonthYear dayGridMonth timeGridWeek timeGridDay listWeek',
|
|
166
|
+
headerToolbarRight: 'prev,next today',
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const ToolbarHeaderAll3 = Template.bind({});
|
|
170
|
+
ToolbarHeaderAll3.args = {
|
|
171
|
+
headerToolbarLeft: 'multiMonthYear dayGridMonth timeGridWeek timeGridDay listWeek',
|
|
172
|
+
headerToolbarCenter: 'prev,next today',
|
|
173
|
+
headerToolbarRight: 'title',
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const ToolbarHeaderAll4 = Template.bind({});
|
|
177
|
+
ToolbarHeaderAll4.args = {
|
|
178
|
+
headerToolbarLeft: 'prev,next today',
|
|
179
|
+
headerToolbarCenter: 'multiMonthYear dayGridMonth timeGridWeek timeGridDay listWeek',
|
|
180
|
+
headerToolbarRight: 'title',
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export const ToolbarHeaderAll5 = Template.bind({});
|
|
184
|
+
ToolbarHeaderAll5.args = {
|
|
185
|
+
headerToolbarLeft: 'title',
|
|
186
|
+
headerToolbarCenter: 'prev,next today',
|
|
187
|
+
headerToolbarRight: 'multiMonthYear dayGridMonth timeGridWeek timeGridDay listWeek',
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export const ToolbarHeaderAll6 = Template.bind({});
|
|
191
|
+
ToolbarHeaderAll6.args = {
|
|
192
|
+
headerToolbarLeft: 'prev,next today',
|
|
193
|
+
headerToolbarCenter: 'title',
|
|
194
|
+
headerToolbarRight: 'multiMonthYear dayGridMonth timeGridWeek timeGridDay listWeek',
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const ToolbarHeaderSome = Template.bind({});
|
|
198
|
+
ToolbarHeaderSome.args = {
|
|
199
|
+
headerToolbarRight: 'dayGridMonth timeGridWeek',
|
|
200
|
+
headerToolbarCenter: 'title',
|
|
201
|
+
headerToolbarLeft: 'prev,next'
|
|
202
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<FullCalendar
|
|
3
|
+
ref="fullCalendar"
|
|
4
|
+
class="base-full-calendar"
|
|
5
|
+
:options="calendarOptions"
|
|
6
|
+
>
|
|
7
|
+
<template
|
|
8
|
+
v-if="$slots.eventContent"
|
|
9
|
+
#eventContent="slotProps"
|
|
10
|
+
>
|
|
11
|
+
<slot
|
|
12
|
+
name="eventContent"
|
|
13
|
+
v-bind="{ ...slotProps }"
|
|
14
|
+
/>
|
|
15
|
+
</template>
|
|
16
|
+
</FullCalendar>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script lang="ts" setup>
|
|
20
|
+
import { t } from '@/i18n';
|
|
21
|
+
import FullCalendar from '@fullcalendar/vue3'
|
|
22
|
+
import dayGridPlugin from '@fullcalendar/daygrid'
|
|
23
|
+
import interactionPlugin from '@fullcalendar/interaction'
|
|
24
|
+
import timeGridPlugin from '@fullcalendar/timegrid'
|
|
25
|
+
import listPlugin from '@fullcalendar/list';
|
|
26
|
+
import multiMonthPlugin from '@fullcalendar/multimonth'
|
|
27
|
+
import { useI18nStore } from '@/stores/i18n';
|
|
28
|
+
import { PropType } from 'vue';
|
|
29
|
+
import { CalendarEvent } from '../types/CalendarEvent';
|
|
30
|
+
import { CalendarOptions } from '@fullcalendar/core';
|
|
31
|
+
|
|
32
|
+
const emit = defineEmits([
|
|
33
|
+
'click',
|
|
34
|
+
'mouseenter',
|
|
35
|
+
'mouseleave',
|
|
36
|
+
'select',
|
|
37
|
+
'add',
|
|
38
|
+
'change',
|
|
39
|
+
'resize',
|
|
40
|
+
'drop',
|
|
41
|
+
'dateClick',
|
|
42
|
+
'remove',
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const fullCalendar = ref<typeof FullCalendar | null>(null);
|
|
46
|
+
|
|
47
|
+
const props = defineProps({
|
|
48
|
+
headerToolbarLeft: {
|
|
49
|
+
default: 'prev,next',
|
|
50
|
+
type: String,
|
|
51
|
+
},
|
|
52
|
+
headerToolbarCenter: {
|
|
53
|
+
default: 'title',
|
|
54
|
+
type: String,
|
|
55
|
+
},
|
|
56
|
+
headerToolbarRight: {
|
|
57
|
+
default: '',
|
|
58
|
+
type: String,
|
|
59
|
+
},
|
|
60
|
+
initialView: {
|
|
61
|
+
default: 'dayGridMonth',
|
|
62
|
+
type: String as PropType<'dayGridMonth' | 'timeGridWeek' | 'timeGridDay' | 'listWeek' | 'multiMonthPlugin'>,
|
|
63
|
+
},
|
|
64
|
+
eventDisplay: {
|
|
65
|
+
default: 'auto',
|
|
66
|
+
type: String as PropType<'auto' | 'block' | 'list-item' | 'background' | 'inverse-background' | 'none'>,
|
|
67
|
+
},
|
|
68
|
+
editable: {
|
|
69
|
+
default: true,
|
|
70
|
+
type: Boolean,
|
|
71
|
+
},
|
|
72
|
+
selectable: {
|
|
73
|
+
default: true,
|
|
74
|
+
type: Boolean,
|
|
75
|
+
},
|
|
76
|
+
dayMaxEvents: {
|
|
77
|
+
default: true,
|
|
78
|
+
type: Boolean,
|
|
79
|
+
},
|
|
80
|
+
weekends: {
|
|
81
|
+
default: true,
|
|
82
|
+
type: Boolean,
|
|
83
|
+
},
|
|
84
|
+
events: {
|
|
85
|
+
default: () => [],
|
|
86
|
+
type: Array as PropType<CalendarEvent[]>,
|
|
87
|
+
},
|
|
88
|
+
locale: {
|
|
89
|
+
default: '',
|
|
90
|
+
type: String
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const internalLocale = computed(() => {
|
|
95
|
+
if (!props.locale) {
|
|
96
|
+
return useI18nStore().locale
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return props.locale;
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
const calendarOptions = computed(() => {
|
|
103
|
+
return {
|
|
104
|
+
plugins: [
|
|
105
|
+
dayGridPlugin,
|
|
106
|
+
timeGridPlugin,
|
|
107
|
+
interactionPlugin,
|
|
108
|
+
listPlugin,
|
|
109
|
+
multiMonthPlugin
|
|
110
|
+
],
|
|
111
|
+
headerToolbar: {
|
|
112
|
+
left: props.headerToolbarLeft,
|
|
113
|
+
center: props.headerToolbarCenter,
|
|
114
|
+
right: props.headerToolbarRight
|
|
115
|
+
},
|
|
116
|
+
initialView: props.initialView,
|
|
117
|
+
initialEvents: [],
|
|
118
|
+
buttonText: {
|
|
119
|
+
year: t('year'),
|
|
120
|
+
month: t('month'),
|
|
121
|
+
week: t('week'),
|
|
122
|
+
list: t('list'),
|
|
123
|
+
day: t('day'),
|
|
124
|
+
today: t('today'),
|
|
125
|
+
class: 'btn btn-primary'
|
|
126
|
+
},
|
|
127
|
+
locale: internalLocale.value,
|
|
128
|
+
editable: props.editable,
|
|
129
|
+
selectable: props.selectable,
|
|
130
|
+
dayMaxEvents: props.dayMaxEvents,
|
|
131
|
+
weekends: props.weekends,
|
|
132
|
+
eventDisplay: props.eventDisplay,
|
|
133
|
+
select: select,
|
|
134
|
+
eventClick: click,
|
|
135
|
+
eventMouseEnter: mouseenter,
|
|
136
|
+
eventMouseLeave: mouseleave,
|
|
137
|
+
eventAdd: add,
|
|
138
|
+
eventChange: change,
|
|
139
|
+
eventResize: resize,
|
|
140
|
+
eventDrop: drop,
|
|
141
|
+
eventRemove: remove,
|
|
142
|
+
dateClick: dateClick,
|
|
143
|
+
events: props.events,
|
|
144
|
+
} as CalendarOptions;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
function select(payload: any) {
|
|
148
|
+
emit('select', payload);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function click(payload: any) {
|
|
152
|
+
emit('click', payload);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function mouseenter(payload: any) {
|
|
156
|
+
emit('mouseenter', payload);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function mouseleave(payload: any) {
|
|
160
|
+
emit('mouseleave', payload);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function add(payload: any) {
|
|
164
|
+
emit('add', payload);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function change(payload: any) {
|
|
168
|
+
emit('change', payload);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function resize(payload: any) {
|
|
172
|
+
emit('resize', payload);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function drop(payload: any) {
|
|
176
|
+
emit('drop', payload);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function dateClick(payload: any) {
|
|
180
|
+
emit('dateClick', payload);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function remove(payload: any) {
|
|
184
|
+
emit('remove', payload);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
</script>
|
|
188
|
+
<style lang="postcss">
|
|
189
|
+
.base-full-calendar {
|
|
190
|
+
&.fc {
|
|
191
|
+
.fc-button-primary:disabled {
|
|
192
|
+
@apply btn btn-primary cursor-not-allowed;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.fc-button-primary {
|
|
196
|
+
@apply btn btn-primary;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.fc-button-primary:not(:disabled).fc-button-active {
|
|
200
|
+
@apply bg-primary-600 text-white border-primary-700
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.fc-button-primary:not(:disabled):active {
|
|
204
|
+
@apply bg-primary-600 text-white border-primary-700
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.fc-button-primary:hover {
|
|
208
|
+
@apply border-primary-700;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.fc-button-primary:focus {
|
|
212
|
+
@apply ring-4 ring-primary-200 !important;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
</style>
|
package/src/components/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import BaseCardRow from './BaseCardRow.vue';
|
|
|
19
19
|
import BaseCharacterCounter from './BaseCharacterCounter.vue';
|
|
20
20
|
import BaseClickOutside from './BaseClickOutside.vue';
|
|
21
21
|
import BaseClipboard from './BaseClipboard.vue';
|
|
22
|
+
import BaseCalendar from './BaseCalendar.vue';
|
|
22
23
|
import BaseColor from './BaseColor.vue';
|
|
23
24
|
import BaseContainer from './BaseContainer.vue';
|
|
24
25
|
import BaseCounter from './BaseCounter.vue';
|
|
@@ -117,6 +118,7 @@ export {
|
|
|
117
118
|
BaseCharacterCounter,
|
|
118
119
|
BaseClickOutside,
|
|
119
120
|
BaseClipboard,
|
|
121
|
+
BaseCalendar,
|
|
120
122
|
BaseColor,
|
|
121
123
|
BaseContainer,
|
|
122
124
|
BaseCounter,
|
package/src/lang/en.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"cancel": "Cancel",
|
|
3
3
|
"cropper": "Crop",
|
|
4
|
+
"day": "Day",
|
|
4
5
|
"drag_to_reposition": "Drag to reposition",
|
|
6
|
+
"list": "List",
|
|
7
|
+
"month": "Month",
|
|
5
8
|
"save": "Save",
|
|
6
9
|
"sui": {
|
|
7
10
|
"address": "Address",
|
|
@@ -85,5 +88,8 @@
|
|
|
85
88
|
"yes_delete": "Yes, delete",
|
|
86
89
|
"you_can_upload_up_to_n_files": "You can upload one file at most|You can upload up to {count} files",
|
|
87
90
|
"you_cannot_select_more_than_x_items": "You can't select more than one item|You can't select more than {count} items"
|
|
88
|
-
}
|
|
91
|
+
},
|
|
92
|
+
"today": "Today",
|
|
93
|
+
"week": "Week",
|
|
94
|
+
"year": "Year"
|
|
89
95
|
}
|
package/src/lang/fr.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"cancel": "Fermer",
|
|
3
3
|
"cropper": "Recadrer",
|
|
4
|
+
"day": "Jour",
|
|
4
5
|
"drag_to_reposition": "Faites glisser pour repositionner",
|
|
6
|
+
"list": "Liste",
|
|
7
|
+
"month": "Mois",
|
|
5
8
|
"save": "Sauvegarder",
|
|
6
9
|
"sui": {
|
|
7
10
|
"address": "Adresse",
|
|
@@ -85,5 +88,8 @@
|
|
|
85
88
|
"yes_delete": "Oui, supprimer",
|
|
86
89
|
"you_can_upload_up_to_n_files": "Vous pouvez télécharger un fichier au maximum|Vous pouvez télécharger jusqu'à {count} fichiers",
|
|
87
90
|
"you_cannot_select_more_than_x_items": "Vous ne pouvez pas sélectionner plus de un élément|Vous ne pouvez pas sélectionner plus de {count} éléments"
|
|
88
|
-
}
|
|
91
|
+
},
|
|
92
|
+
"today": "Aujourd\\'hui",
|
|
93
|
+
"week": "Semaine",
|
|
94
|
+
"year": "Année"
|
|
89
95
|
}
|