Skip to content

Commit fcde90c

Browse files
committed
Add ok button for multiple
1 parent 3430b9b commit fcde90c

File tree

10 files changed

+133
-21
lines changed

10 files changed

+133
-21
lines changed

src/components/TDatepicker.vue

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ import {
9292
provide,
9393
watch,
9494
InputHTMLAttributes,
95+
computed,
9596
} from 'vue';
9697
9798
import {
@@ -111,7 +112,7 @@ import {
111112
} from '@variantjs/core';
112113
import { Options, Placement } from '@popperjs/core';
113114
import useConfigurationWithClassesList from '../use/useConfigurationWithClassesList';
114-
import { useSelectedDate, useActiveDate, useCalendarView, useDateFormatting, useDateParsing, useCalendarState, useVisibleDate } from '../use/datepicker';
115+
import { useSelectedDate, useActiveDate, useCalendarView, useDateFormatting, useDateParsing, useCalendarState, useVisibleDate, useDateLocale } from '../use/datepicker';
115116
import { getVariantPropsWithClassesList } from '../utils/getVariantProps';
116117
import { TDatepickerOptions, TDatepickerValue } from '../types';
117118
import DatepickerDropdown from './TDatepicker/DatepickerDropdown.vue';
@@ -275,7 +276,7 @@ export default defineComponent({
275276
},
276277
closeOnSelect: {
277278
type: Boolean,
278-
default: true,
279+
default: undefined,
279280
},
280281
show: {
281282
type: Boolean,
@@ -289,6 +290,10 @@ export default defineComponent({
289290
type: [String, Object] as PropType<string | HTMLElement>,
290291
default: 'body',
291292
},
293+
showOkButton: {
294+
type: Boolean,
295+
default: undefined,
296+
},
292297
},
293298
emits: {
294299
change: (e: CustomEvent) => e instanceof CustomEvent,
@@ -308,17 +313,28 @@ export default defineComponent({
308313
// - In multiple add an ok button
309314
// - Add a clear button
310315
const { configuration, attributes } = useConfigurationWithClassesList<TDatepickerOptions>(TDatepickerConfig, TDatepickerClassesKeys);
311-
const { parseDate } = useDateParsing(configuration);
316+
const locale = useDateLocale({ configuration });
317+
const { parseDate } = useDateParsing({ configuration, locale });
312318
const { selectedDate, selectedDateHolder, setSelectedDate, addSelectedDate, getInitialSelectedDate, resetRangeSelection } = useSelectedDate(props, configuration, parseDate);
313319
const { activeDate, activeDateIsVisible, initActiveDate, setActiveDate, hideActiveDate, showActiveDate } = useActiveDate({
314320
configuration, selectedDate, parseDate,
315321
});
316-
const { formatDate, formattedDate, userFormattedDate } = useDateFormatting(configuration, selectedDate);
322+
const { formatDate, formattedDate, userFormattedDate } = useDateFormatting({ configuration, selectedDate, locale });
317323
const { currentView, initView, setCurrentView } = useCalendarView(configuration);
318-
const { shown, doShow, doHide, isMultiple, isDropdownClosed, isDropdownOpened } = useCalendarState(configuration);
319-
324+
const { shown, doShow, doHide, isMultiple, isRange, isDropdownClosed, isDropdownOpened } = useCalendarState(configuration);
320325
const { visibleDate, resetVisibleDate } = useVisibleDate({ activeDate, configuration });
326+
const shouldCloseOnSelect = computed<boolean>(() => {
327+
if (configuration.closeOnSelect === undefined) {
328+
return isRange.value || !isMultiple.value;
329+
}
321330
331+
return configuration.closeOnSelect;
332+
});
333+
334+
const okButtonHandler = () => {
335+
doHide();
336+
};
337+
322338
const initAllViewData = () => {
323339
initView();
324340
initActiveDate();
@@ -350,7 +366,7 @@ export default defineComponent({
350366
emit('input', event);
351367
emit('update:modelValue', formattedDate.value);
352368
353-
if (configuration.closeOnSelect && isDropdownOpened.value) {
369+
if (shouldCloseOnSelect.value && isDropdownOpened.value) {
354370
doHide();
355371
}
356372
});
@@ -537,6 +553,10 @@ export default defineComponent({
537553
provide('currentView', currentView);
538554
539555
provide('userFormattedDate', userFormattedDate);
556+
557+
provide('locale', locale);
558+
559+
provide('okButtonHandler', okButtonHandler);
540560
541561
return {
542562
configuration,

src/components/TDatepicker/DatepickerDropdown.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="inline-flex flex-col mt-1 bg-white border rounded">
3-
<div class="inline-flex flex-wrap ">
3+
<div class="inline-flex flex-wrap">
44
<datepicker-view
55
v-for="(month, index) in visibleMonths"
66
:key="month.toISOString"

src/components/TDatepicker/DatepickerView.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
<datepicker-view-year v-else-if="isYearView" />
2323

2424
<datepicker-view-multiple-years v-else />
25+
26+
<datepicker-view-footer v-if="first" />
2527
</div>
2628
</template>
2729

@@ -33,6 +35,7 @@ import DatepickerViewYear from './DatepickerViewYear.vue';
3335
import DatepickerViewMultipleYears from './DatepickerViewMultipleYears.vue';
3436
import DatepickerViewControls from './DatepickerViewControls.vue';
3537
import DatepickerViewControlsLabel from './DatepickerViewControlsLabel.vue';
38+
import DatepickerViewFooter from './DatepickerViewFooter.vue';
3639
3740
export default defineComponent({
3841
name: 'DatepickerView',
@@ -42,6 +45,7 @@ export default defineComponent({
4245
DatepickerViewMultipleYears,
4346
DatepickerViewControls,
4447
DatepickerViewControlsLabel,
48+
DatepickerViewFooter,
4549
},
4650
props: {
4751
month: {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<template>
2+
<div
3+
v-if="show"
4+
class="flex items-center px-3 pb-2 space-x-2"
5+
>
6+
<!-- <label class="flex-grow text-sm text-gray-500">Time</label>
7+
<div class="flex items-center space-x-2">
8+
<div
9+
tabindex="0"
10+
inputmode="numeric"
11+
contenteditable="true"
12+
class="bg-gray-100 rounded-md w-full text-right flex items-center border border-gray-100 focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50"
13+
style="caret-color: transparent;"
14+
>
15+
<input
16+
inputmode="numeric"
17+
type="text"
18+
contenteditable="false"
19+
class="text-center w-8 border-transparent bg-transparent p-0 h-6 text-sm transition duration-100 ease-in-out border border-transparent focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 rounded"
20+
><span
21+
contenteditable="false"
22+
class=""
23+
>:</span><input
24+
inputmode="numeric"
25+
type="text"
26+
contenteditable="false"
27+
class="text-center w-8 border-transparent bg-transparent p-0 h-6 text-sm transition duration-100 ease-in-out border border-transparent focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 rounded"
28+
>
29+
</div> -->
30+
<button
31+
type="button"
32+
class="text-blue-600 text-sm uppercase font-semibold transition duration-100 ease-in-out border border-transparent focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 rounded cursor-pointer ml-auto"
33+
@click="okButtonHandler"
34+
v-text="locale.okLabel"
35+
/>
36+
</div>
37+
</template>
38+
39+
<script lang="ts">
40+
import { DateLocale } from '@variantjs/core';
41+
import { computed, ComputedRef, defineComponent, inject } from 'vue';
42+
import { TDatepickerOptions } from '../../types/components/t-datepicker';
43+
import { useCalendarState } from '../../use/datepicker';
44+
45+
export default defineComponent({
46+
name: 'DatepickerViewFooter',
47+
setup() {
48+
const configuration = inject<TDatepickerOptions>('configuration')!;
49+
const locale = inject<ComputedRef<DateLocale>>('locale')!;
50+
const okButtonHandler = inject<() => void>('okButtonHandler')!;
51+
52+
const { isMultiple, isRange } = useCalendarState(configuration);
53+
54+
const show = computed(() => {
55+
if (configuration.showOkButton === undefined) {
56+
return isMultiple.value && !isRange.value;
57+
}
58+
59+
return configuration.showOkButton;
60+
});
61+
62+
return { show, locale, okButtonHandler };
63+
},
64+
});
65+
</script>

src/types/components/t-datepicker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ export type TDatepickerOptions = WithVariantPropsAndClassesList<{
5252
addFormInput?: boolean,
5353
teleport?: boolean,
5454
teleportTo?: string | HTMLElement,
55+
showOkButton?: boolean,
5556
} & HTMLAttributes & Data, TDatepickerClassesValidKeys>;

src/use/datepicker/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ import useDateFormatting from './useDateFormatting';
55
import useDateParsing from './useDateParsing';
66
import useCalendarState from './useCalendarState';
77
import useVisibleDate from './useVisibleDate';
8+
import useDateLocale from './useDateLocale';
89

9-
export { useActiveDate, useCalendarView, useSelectedDate, useDateFormatting, useDateParsing, useCalendarState, useVisibleDate };
10+
export { useActiveDate, useCalendarView, useSelectedDate, useDateFormatting, useDateParsing, useCalendarState, useVisibleDate, useDateLocale };

src/use/datepicker/useDateFormatting.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
import { buildDateFormatter, DateFormatter, dateEnglishLocale } from '@variantjs/core';
1+
import { buildDateFormatter, DateFormatter, dateEnglishLocale, DateLocale } from '@variantjs/core';
22
import { computed, ComputedRef, Ref } from 'vue';
33
import { TDatepickerOptions } from '../../types/components/t-datepicker';
44

5-
export default function useDateFormatting<C extends Pick<TDatepickerOptions, 'locale' | 'dateFormatter' | 'dateFormat' | 'userFormat' | 'range' | 'dateParser'>>(
5+
export default function useDateFormatting<C extends Pick<TDatepickerOptions, 'locale' | 'dateFormatter' | 'dateFormat' | 'userFormat' | 'range' | 'dateParser'>>({
6+
configuration,
7+
locale,
8+
selectedDate,
9+
}: {
610
configuration: C,
7-
selectedDate: Ref<Date | Date[] | undefined>,
8-
): {
11+
locale: ComputedRef<DateLocale>,
12+
selectedDate: Ref<Date | Date[] | undefined>
13+
}): {
914
formatDate: ComputedRef<DateFormatter>,
1015
formattedDate: ComputedRef<string | string[]>,
1116
userFormattedDate: ComputedRef<string>,
1217
} {
1318

14-
const formatDate = computed<DateFormatter>(() => buildDateFormatter(configuration.locale || dateEnglishLocale, configuration.dateFormatter));
19+
const formatDate = computed<DateFormatter>(() => buildDateFormatter(locale.value, configuration.dateFormatter));
1520

1621
const dateRangeSeparator = computed<string>(() => {
17-
return (configuration.locale || dateEnglishLocale).rangeSeparator || dateEnglishLocale.rangeSeparator;
22+
return locale.value.rangeSeparator || dateEnglishLocale.rangeSeparator;
1823
});
1924

2025
const formattedDate = computed<string | string[]>(() => {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { dateEnglishLocale, DateLocale } from '@variantjs/core';
2+
import { computed, ComputedRef } from 'vue';
3+
import { TDatepickerOptions } from '../../types/components/t-datepicker';
4+
5+
export default function useDateLocale<C extends Pick<TDatepickerOptions, 'locale'>>({
6+
configuration,
7+
}: {
8+
configuration: C,
9+
}): ComputedRef<DateLocale> {
10+
return computed(() => configuration.locale || dateEnglishLocale);
11+
}
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
import { dateEnglishLocale, DateParser, buildDateParser } from '@variantjs/core';
1+
import { DateParser, buildDateParser, DateLocale } from '@variantjs/core';
22
import { computed, ComputedRef } from 'vue';
33
import { TDatepickerOptions } from '../../types/components/t-datepicker';
44

5-
export default function useDateParsing<C extends Pick<TDatepickerOptions, 'locale' | 'dateParser'>>(configuration: C): {
6-
parseDate: ComputedRef<DateParser>,
7-
} {
8-
const parseDate = computed<DateParser>(() => buildDateParser(configuration.locale || dateEnglishLocale, configuration.dateParser));
5+
export default function useDateParsing<C extends Pick<TDatepickerOptions, 'locale' | 'dateParser'>>({
6+
configuration,
7+
locale,
8+
}: {
9+
configuration: C,
10+
locale: ComputedRef<DateLocale>
11+
}): {
12+
parseDate: ComputedRef<DateParser>,
13+
} {
14+
const parseDate = computed<DateParser>(() => buildDateParser(locale.value, configuration.dateParser));
915

1016
return { parseDate };
1117
}

src/use/datepicker/useSelectedDate.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ export default function useSelectedDate<P extends {
9999
}
100100

101101
if (isMultiple.value) {
102-
// @TODO: consider user option like an "Ok" button to confirm the selection
103102
return true;
104103
}
105104

0 commit comments

Comments
 (0)