@carbon/vue 3.0.4-alpha.0 → 3.0.6-alpha.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/README.md +16 -0
- package/dist/carbon-vue-3.common.js +11782 -2709
- package/dist/carbon-vue-3.common.js.map +1 -1
- package/dist/carbon-vue-3.css +1 -0
- package/dist/carbon-vue-3.umd.js +11782 -2709
- package/dist/carbon-vue-3.umd.js.map +1 -1
- package/dist/carbon-vue-3.umd.min.js +30 -2
- package/dist/carbon-vue-3.umd.min.js.map +1 -1
- package/package.json +3 -2
- package/src/components/CvCheckbox/CvCheckbox.vue +0 -2
- package/src/components/CvDatePicker/CvDatePicker-notes.md +86 -0
- package/src/components/CvDatePicker/CvDatePicker.stories.js +241 -0
- package/src/components/CvDatePicker/CvDatePicker.vue +402 -0
- package/src/components/CvDatePicker/CvDatePickerSkeleton.vue +106 -0
- package/src/components/CvDatePicker/index.js +4 -0
- package/src/components/CvDatePicker/plugins/appendToPlugin.js +64 -0
- package/src/components/CvDatePicker/plugins/fixEventsPlugin.js +79 -0
- package/src/components/CvDatePicker/plugins/monthSelectPlugin.js +86 -0
- package/src/components/CvDatePicker/plugins/rangePlugin.js +47 -0
- package/src/components/CvForm/CvForm.stories.mdx +193 -0
- package/src/components/CvForm/CvForm.vue +9 -0
- package/src/components/CvForm/CvFormGroup.vue +27 -0
- package/src/components/CvForm/CvFormItem.vue +9 -0
- package/src/components/CvForm/index.js +5 -0
- package/src/components/CvModal/CvModal.stories.mdx +234 -0
- package/src/components/CvModal/CvModal.vue +403 -0
- package/src/components/CvModal/index.js +3 -0
- package/src/components/CvTextArea/CvTextArea.stories.js +174 -0
- package/src/components/CvTextArea/CvTextArea.vue +107 -0
- package/src/components/CvTextArea/index.js +4 -0
- package/src/components/CvTextInput/CvTextInput.stories.js +245 -0
- package/src/components/CvTextInput/CvTextInput.vue +217 -0
- package/src/components/CvTextInput/const.js +2 -0
- package/src/components/CvTextInput/index.js +4 -0
- package/src/components/CvTile/CvTile.stories.mdx +156 -0
- package/src/components/CvTile/CvTile.vue +67 -0
- package/src/components/CvTile/CvTileClickable.vue +23 -0
- package/src/components/CvTile/CvTileExpandable.vue +103 -0
- package/src/components/CvTile/CvTileSelectable.vue +52 -0
- package/src/components/CvTile/CvTileStandard.vue +7 -0
- package/src/components/CvTile/index.js +4 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<cv-wrapper
|
|
3
|
+
:tag-type="formItem ? 'div' : ''"
|
|
4
|
+
:class="`cv-date-picker ${carbonPrefix}--form-item`"
|
|
5
|
+
:id="cvId"
|
|
6
|
+
>
|
|
7
|
+
<div
|
|
8
|
+
:data-date-picker="['single', 'range'].includes(getKind)"
|
|
9
|
+
:data-date-picker-type="getKind"
|
|
10
|
+
:class="[
|
|
11
|
+
`${carbonPrefix}--date-picker ${carbonPrefix}--date-picker--${getKind}`,
|
|
12
|
+
{
|
|
13
|
+
[`${carbonPrefix}--date-picker--simple`]: getKind === 'short',
|
|
14
|
+
[`${carbonPrefix}--date-picker--light`]: isLight,
|
|
15
|
+
'cv-date-picker': !formItem,
|
|
16
|
+
},
|
|
17
|
+
]"
|
|
18
|
+
ref="dateWrapper"
|
|
19
|
+
:id="formItem ? undefined : cvId"
|
|
20
|
+
>
|
|
21
|
+
<div
|
|
22
|
+
:class="{
|
|
23
|
+
[`${carbonPrefix}--date-picker-container`]: [
|
|
24
|
+
'single',
|
|
25
|
+
'range',
|
|
26
|
+
].includes(getKind),
|
|
27
|
+
[`${carbonPrefix}--date-picker--nolabel`]: getDateLabel !== undefined,
|
|
28
|
+
}"
|
|
29
|
+
>
|
|
30
|
+
<label
|
|
31
|
+
v-if="getDateLabel.length > 0"
|
|
32
|
+
:for="`${cvId}-input-1`"
|
|
33
|
+
:class="`${carbonPrefix}--label`"
|
|
34
|
+
>
|
|
35
|
+
{{ getDateLabel }}
|
|
36
|
+
</label>
|
|
37
|
+
<div :class="`${carbonPrefix}--date-picker-input__wrapper`">
|
|
38
|
+
<input
|
|
39
|
+
ref="date"
|
|
40
|
+
type="text"
|
|
41
|
+
data-date-picker-input
|
|
42
|
+
role="datepicker"
|
|
43
|
+
:data-invalid="isInvalid || null"
|
|
44
|
+
:disabled="disabled"
|
|
45
|
+
:data-date-picker-input-from="getKind === 'range'"
|
|
46
|
+
:id="`${cvId}-input-1`"
|
|
47
|
+
:class="`${carbonPrefix}--date-picker__input`"
|
|
48
|
+
:pattern="pattern"
|
|
49
|
+
:placeholder="placeholder"
|
|
50
|
+
@change="handleUpdateEvent"
|
|
51
|
+
@click="handleClick"
|
|
52
|
+
/>
|
|
53
|
+
<Calendar16
|
|
54
|
+
v-if="['single', 'range'].includes(getKind)"
|
|
55
|
+
:class="`${carbonPrefix}--date-picker__icon`"
|
|
56
|
+
data-date-picker-icon
|
|
57
|
+
/>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div :class="`${carbonPrefix}--form-requirement`" v-if="isInvalid">
|
|
61
|
+
<slot name="invalid-message">{{ invalidMessage }}</slot>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<!-- maybe use input as another component? -->
|
|
66
|
+
<div
|
|
67
|
+
v-if="isRange"
|
|
68
|
+
:class="{
|
|
69
|
+
[`${carbonPrefix}--date-picker-container`]: getKind === 'range',
|
|
70
|
+
[`${carbonPrefix}--date-picker--nolabel`]: dateEndLabel !== undefined,
|
|
71
|
+
}"
|
|
72
|
+
>
|
|
73
|
+
<label
|
|
74
|
+
v-if="dateEndLabel.length > 0"
|
|
75
|
+
:for="`${cvId}-input-2`"
|
|
76
|
+
:class="`${carbonPrefix}--label`"
|
|
77
|
+
>
|
|
78
|
+
{{ dateEndLabel }}
|
|
79
|
+
</label>
|
|
80
|
+
<div
|
|
81
|
+
:class="`${carbonPrefix}--date-picker-input__wrapper`"
|
|
82
|
+
@click="calendar.open()"
|
|
83
|
+
>
|
|
84
|
+
<input
|
|
85
|
+
ref="todate"
|
|
86
|
+
type="text"
|
|
87
|
+
data-date-picker-input
|
|
88
|
+
role="todatepicker"
|
|
89
|
+
:data-date-picker-input-to="kind === 'range'"
|
|
90
|
+
:data-invalid="isInvalid || null"
|
|
91
|
+
:disabled="disabled"
|
|
92
|
+
:id="`${cvId}-input-2`"
|
|
93
|
+
:class="`${carbonPrefix}--date-picker__input`"
|
|
94
|
+
:pattern="pattern"
|
|
95
|
+
:placeholder="placeholder"
|
|
96
|
+
@change="handleUpdateEvent"
|
|
97
|
+
/>
|
|
98
|
+
<Calendar16
|
|
99
|
+
:class="`${carbonPrefix}--date-picker__icon`"
|
|
100
|
+
data-date-picker-icon
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
<div :class="`${carbonPrefix}--form-requirement`" v-if="isInvalid">
|
|
104
|
+
<span id="invalid-message-placeholder"></span>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</cv-wrapper>
|
|
109
|
+
</template>
|
|
110
|
+
|
|
111
|
+
<script setup>
|
|
112
|
+
import {
|
|
113
|
+
ref,
|
|
114
|
+
computed,
|
|
115
|
+
onMounted,
|
|
116
|
+
onUpdated,
|
|
117
|
+
onBeforeMount,
|
|
118
|
+
onUnmounted,
|
|
119
|
+
watch,
|
|
120
|
+
nextTick,
|
|
121
|
+
useSlots,
|
|
122
|
+
} from 'vue';
|
|
123
|
+
import { carbonPrefix } from '../../global/settings';
|
|
124
|
+
import { props as propsCvId, useCvId } from '../../use/cvId';
|
|
125
|
+
import { Calendar16 } from '@carbon/icons-vue';
|
|
126
|
+
import CvWrapper from '../CvWrapper/CvWrapper';
|
|
127
|
+
import { props as propsCvTheme, useIsLight } from '../../use/cvTheme';
|
|
128
|
+
import flatpickr from 'flatpickr';
|
|
129
|
+
import l10n from 'flatpickr/dist/l10n/index';
|
|
130
|
+
import carbonFlatpickrFixEventsPlugin from './plugins/fixEventsPlugin';
|
|
131
|
+
import carbonFlatpickrRangePlugin from './plugins/rangePlugin';
|
|
132
|
+
import carbonFlatpickrMonthSelectPlugin from './plugins/monthSelectPlugin';
|
|
133
|
+
|
|
134
|
+
const slots = useSlots();
|
|
135
|
+
|
|
136
|
+
const dateWrapper = ref(null);
|
|
137
|
+
const date = ref(null);
|
|
138
|
+
const todate = ref(null);
|
|
139
|
+
|
|
140
|
+
const cvId = useCvId(props, true, 'date-picker-');
|
|
141
|
+
const isLight = useIsLight(props);
|
|
142
|
+
|
|
143
|
+
let calendar;
|
|
144
|
+
|
|
145
|
+
const props = defineProps({
|
|
146
|
+
modelValue: [String, Object, Array, Date],
|
|
147
|
+
dateLabel: { type: String, default: undefined },
|
|
148
|
+
dateEndLabel: { type: String, default: 'End date' },
|
|
149
|
+
invalid: { type: Boolean, default: false },
|
|
150
|
+
disabled: { type: Boolean, default: false },
|
|
151
|
+
invalidMessage: { type: String },
|
|
152
|
+
pattern: { type: String, default: '\\d{1,2}/\\d{1,2}/\\d{4}' },
|
|
153
|
+
placeholder: { type: String, default: 'mm/dd/yyyy' },
|
|
154
|
+
calOptions: {
|
|
155
|
+
type: Object,
|
|
156
|
+
default() {
|
|
157
|
+
return {
|
|
158
|
+
dateFormat: 'm/d/Y',
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
formItem: { type: Boolean, default: true },
|
|
163
|
+
kind: {
|
|
164
|
+
type: String,
|
|
165
|
+
default: 'simple',
|
|
166
|
+
validator: val => ['short', 'simple', 'single', 'range'].includes(val),
|
|
167
|
+
},
|
|
168
|
+
value: [String, Object, Array, Date],
|
|
169
|
+
...propsCvId,
|
|
170
|
+
...propsCvTheme,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const emit = defineEmits(['update:modelValue']);
|
|
174
|
+
|
|
175
|
+
const getKind = computed({
|
|
176
|
+
get() {
|
|
177
|
+
if (['short', 'simple', 'single', 'range'].includes(props.kind)) {
|
|
178
|
+
return props.kind;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return 'simple';
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const getDateLabel = computed({
|
|
186
|
+
get() {
|
|
187
|
+
if (props.kind === 'range' && !props.dateLabel) {
|
|
188
|
+
return 'Start date';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!props.dateLabel) {
|
|
192
|
+
return 'Date label';
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return props.dateLabel;
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const isRange = computed(() => {
|
|
200
|
+
return props.kind === 'range';
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const isSingle = computed(() => {
|
|
204
|
+
return props.kind === 'single';
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const isInvalid = computed(() => {
|
|
208
|
+
return !!props.invalidMessage || !!slots['invalid-message'];
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const getFlatpickrOptions = () => {
|
|
212
|
+
const options = { ...props.calOptions };
|
|
213
|
+
|
|
214
|
+
options.plugins = [
|
|
215
|
+
props.kind === 'range'
|
|
216
|
+
? carbonFlatpickrRangePlugin({
|
|
217
|
+
input: todate.value,
|
|
218
|
+
})
|
|
219
|
+
: () => {},
|
|
220
|
+
carbonFlatpickrMonthSelectPlugin({
|
|
221
|
+
selectorFlatpickrMonthYearContainer: '.flatpickr-current-month',
|
|
222
|
+
selectorFlatpickrYearContainer: '.numInputWrapper',
|
|
223
|
+
selectorFlatpickrCurrentMonth: '.cur-month',
|
|
224
|
+
classFlatpickrCurrentMonth: 'cur-month',
|
|
225
|
+
}),
|
|
226
|
+
carbonFlatpickrFixEventsPlugin({
|
|
227
|
+
inputFrom: date.value,
|
|
228
|
+
inputTo: todate.value,
|
|
229
|
+
}),
|
|
230
|
+
];
|
|
231
|
+
|
|
232
|
+
options.nextArrow = `
|
|
233
|
+
<svg width="16px" height="16px" viewBox="0 0 16 16">
|
|
234
|
+
<polygon points="11,8 6,13 5.3,12.3 9.6,8 5.3,3.7 6,3 "/>
|
|
235
|
+
<rect width="16" height="16" style="fill:none" />
|
|
236
|
+
</svg>
|
|
237
|
+
`;
|
|
238
|
+
|
|
239
|
+
options.prevArrow = `
|
|
240
|
+
<svg width="16px" height="16px" viewBox="0 0 16 16">
|
|
241
|
+
<polygon points="5,8 10,3 10.7,3.7 6.4,8 10.7,12.3 10,13 "/>
|
|
242
|
+
<rect width="16" height="16" style="fill:none" />
|
|
243
|
+
</svg>
|
|
244
|
+
`;
|
|
245
|
+
|
|
246
|
+
options.mode = props.kind;
|
|
247
|
+
// add events update based on parameters
|
|
248
|
+
options.onChange = handleDatePick;
|
|
249
|
+
// options.onOpen = onOpen;
|
|
250
|
+
options.onReady = onCalReady;
|
|
251
|
+
|
|
252
|
+
return options;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const onCalReady = (selectedDates, dateStr, instance) => {
|
|
256
|
+
const calendarContainer = instance.calendarContainer;
|
|
257
|
+
const options = {
|
|
258
|
+
classCalendarContainer: `${carbonPrefix}--date-picker__calendar`,
|
|
259
|
+
classMonth: `${carbonPrefix}--date-picker__month`,
|
|
260
|
+
classWeekdays: `${carbonPrefix}--date-picker__weekdays`,
|
|
261
|
+
classDays: `${carbonPrefix}--date-picker__days`,
|
|
262
|
+
classWeekday: `${carbonPrefix}--date-picker__weekday`,
|
|
263
|
+
classDay: `${carbonPrefix}--date-picker__day`,
|
|
264
|
+
classFocused: `${carbonPrefix}--focused`,
|
|
265
|
+
classVisuallyHidden: `${carbonPrefix}--visually-hidden`,
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
if (calendarContainer) {
|
|
269
|
+
calendarContainer.classList.add(options.classCalendarContainer);
|
|
270
|
+
calendarContainer
|
|
271
|
+
.querySelector('.flatpickr-month')
|
|
272
|
+
.classList.add(options.classMonth);
|
|
273
|
+
calendarContainer
|
|
274
|
+
.querySelector('.flatpickr-weekdays')
|
|
275
|
+
.classList.add(options.classWeekdays);
|
|
276
|
+
calendarContainer
|
|
277
|
+
.querySelector('.flatpickr-days')
|
|
278
|
+
.classList.add(options.classDays);
|
|
279
|
+
for (const item of calendarContainer.querySelectorAll(
|
|
280
|
+
'.flatpickr-weekday'
|
|
281
|
+
)) {
|
|
282
|
+
const currentItem = item;
|
|
283
|
+
currentItem.innerHTML = currentItem.innerHTML.replace(/\s+/g, '');
|
|
284
|
+
currentItem.classList.add(options.classWeekday);
|
|
285
|
+
}
|
|
286
|
+
for (const item of calendarContainer.querySelectorAll('.flatpickr-day')) {
|
|
287
|
+
item.classList.add(options.classDay);
|
|
288
|
+
if (item.classList.contains('today') && selectedDates.length > 0) {
|
|
289
|
+
item.classList.add('no-border');
|
|
290
|
+
} else if (
|
|
291
|
+
item.classList.contains('today') &&
|
|
292
|
+
selectedDates.length === 0
|
|
293
|
+
) {
|
|
294
|
+
item.classList.remove('no-border');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const initFlatpickr = () => {
|
|
301
|
+
return flatpickr(date.value, getFlatpickrOptions());
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
let dateToString = val => {
|
|
305
|
+
return calendar.formatDate(val, props.calOptions.dateFormat);
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const handleDatePick = (selectedDates, dateStr, instance) => {
|
|
309
|
+
if (isSingle.value) {
|
|
310
|
+
const temp = dateToString(selectedDates[0]);
|
|
311
|
+
|
|
312
|
+
nextTick(() => {
|
|
313
|
+
date.value.value = temp;
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
emit('update:modelValue', temp);
|
|
317
|
+
} else if (isRange.value && selectedDates[0] && selectedDates[1]) {
|
|
318
|
+
const startDate = dateToString(selectedDates[0]);
|
|
319
|
+
const endDate = dateToString(selectedDates[1]);
|
|
320
|
+
|
|
321
|
+
nextTick(() => {
|
|
322
|
+
date.value.value = startDate;
|
|
323
|
+
todate.value.value = endDate;
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
emit('update:modelValue', {
|
|
327
|
+
startDate: startDate,
|
|
328
|
+
endDate: endDate,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const handleUpdateEvent = event => {
|
|
334
|
+
if (['short', 'simple'].includes(props.kind)) {
|
|
335
|
+
emit('update:modelValue', event.target.value);
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
const setDate = value => {
|
|
340
|
+
if (!value) return;
|
|
341
|
+
|
|
342
|
+
if (isSingle.value) {
|
|
343
|
+
calendar.setDate(value, true);
|
|
344
|
+
} else if (isRange.value) {
|
|
345
|
+
calendar.setDate([value.startDate, value.endDate], true);
|
|
346
|
+
} else {
|
|
347
|
+
date.value.value = value;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
watch(
|
|
352
|
+
() => props.modelValue,
|
|
353
|
+
newValue => {
|
|
354
|
+
if (isRange.value) {
|
|
355
|
+
if (
|
|
356
|
+
date.value.value !== newValue.startDate ||
|
|
357
|
+
todate.value.value !== newValue.endDate
|
|
358
|
+
) {
|
|
359
|
+
setDate(newValue);
|
|
360
|
+
}
|
|
361
|
+
} else {
|
|
362
|
+
if (date.value.value !== newValue) {
|
|
363
|
+
setDate(newValue);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
{ deep: true }
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
onBeforeMount(() => {
|
|
371
|
+
// Weekdays shorthand for english locale
|
|
372
|
+
l10n.en.weekdays.shorthand.forEach((day, index) => {
|
|
373
|
+
const currentDay = l10n.en.weekdays.shorthand;
|
|
374
|
+
if (currentDay[index] === 'Thu' || currentDay[index] === 'Th') {
|
|
375
|
+
currentDay[index] = 'Th';
|
|
376
|
+
} else {
|
|
377
|
+
currentDay[index] = currentDay[index].charAt(0);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
onMounted(() => {
|
|
383
|
+
if (['range', 'single'].includes(props.kind)) {
|
|
384
|
+
calendar = initFlatpickr();
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
setDate(props.modelValue || props.value);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
onUnmounted(() => {
|
|
391
|
+
if (calendar) {
|
|
392
|
+
calendar.destroy();
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
</script>
|
|
396
|
+
|
|
397
|
+
<style lang="scss">
|
|
398
|
+
#invalid-message-placeholder {
|
|
399
|
+
display: block;
|
|
400
|
+
height: 16px;
|
|
401
|
+
}
|
|
402
|
+
</style>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<cv-wrapper
|
|
3
|
+
:tag-type="formItem ? 'div' : ''"
|
|
4
|
+
:class="`cv-date-picker ${carbonPrefix}--form-item`"
|
|
5
|
+
:id="cvId"
|
|
6
|
+
>
|
|
7
|
+
<div
|
|
8
|
+
:data-date-picker="['single', 'range'].includes(getKind)"
|
|
9
|
+
:data-date-picker-type="getKind"
|
|
10
|
+
:class="[
|
|
11
|
+
`${carbonPrefix}--date-picker ${carbonPrefix}--date-picker--${getKind}`,
|
|
12
|
+
{
|
|
13
|
+
[`${carbonPrefix}--date-picker--simple`]: getKind === 'short',
|
|
14
|
+
'cv-date-picker': !formItem,
|
|
15
|
+
},
|
|
16
|
+
]"
|
|
17
|
+
ref="dateWrapper"
|
|
18
|
+
:id="formItem ? undefined : cvId"
|
|
19
|
+
>
|
|
20
|
+
<div
|
|
21
|
+
class="inputWrapper"
|
|
22
|
+
:class="{
|
|
23
|
+
[`${carbonPrefix}--date-picker-container`]: [
|
|
24
|
+
'single',
|
|
25
|
+
'range',
|
|
26
|
+
].includes(getKind),
|
|
27
|
+
[`${carbonPrefix}--date-picker--nolabel`]: label === false,
|
|
28
|
+
}"
|
|
29
|
+
>
|
|
30
|
+
<CvSkeletonText width="50%" class="label"></CvSkeletonText>
|
|
31
|
+
<CvSkeletonText :heading="true" class="input"></CvSkeletonText>
|
|
32
|
+
<div
|
|
33
|
+
:style="`display: block; width: ${
|
|
34
|
+
getKind === 'single' ? '240px' : '120px'
|
|
35
|
+
};`"
|
|
36
|
+
:class="`${carbonPrefix}--date-picker-input__wrapper`"
|
|
37
|
+
></div>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div
|
|
41
|
+
v-if="getKind === 'range'"
|
|
42
|
+
:class="{
|
|
43
|
+
[`${carbonPrefix}--date-picker-container`]: [
|
|
44
|
+
'single',
|
|
45
|
+
'range',
|
|
46
|
+
].includes(getKind),
|
|
47
|
+
[`${carbonPrefix}--date-picker--nolabel`]: label === false,
|
|
48
|
+
}"
|
|
49
|
+
>
|
|
50
|
+
<CvSkeletonText width="50%" class="label"></CvSkeletonText>
|
|
51
|
+
<CvSkeletonText :heading="true" class="input"></CvSkeletonText>
|
|
52
|
+
<div
|
|
53
|
+
style="display: block; width: 120px"
|
|
54
|
+
:class="`${carbonPrefix}--date-picker-input__wrapper`"
|
|
55
|
+
></div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</cv-wrapper>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<script setup>
|
|
62
|
+
import { computed } from 'vue';
|
|
63
|
+
import { carbonPrefix } from '../../global/settings';
|
|
64
|
+
import { props as propsCvId, useCvId } from '../../use/cvId';
|
|
65
|
+
import CvWrapper from '../CvWrapper/CvWrapper';
|
|
66
|
+
import CvSkeletonText from '../CvSkeletonText';
|
|
67
|
+
|
|
68
|
+
const cvId = useCvId(props, true, 'date-picker-skeleton-');
|
|
69
|
+
|
|
70
|
+
const props = defineProps({
|
|
71
|
+
formItem: { type: Boolean, default: true },
|
|
72
|
+
label: { type: Boolean, default: true },
|
|
73
|
+
kind: {
|
|
74
|
+
type: String,
|
|
75
|
+
default: 'simple',
|
|
76
|
+
validator: val => ['short', 'simple', 'single', 'range'].includes(val),
|
|
77
|
+
},
|
|
78
|
+
...propsCvId,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const getKind = computed({
|
|
82
|
+
get() {
|
|
83
|
+
if (['short', 'simple', 'single', 'range'].includes(props.kind)) {
|
|
84
|
+
return props.kind;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return 'simple';
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<style scoped>
|
|
93
|
+
.inputWrapper {
|
|
94
|
+
width: 8.96875rem;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.label {
|
|
98
|
+
width: 4.6875rem;
|
|
99
|
+
height: 0.875rem;
|
|
100
|
+
margin-bottom: 0.5rem;
|
|
101
|
+
}
|
|
102
|
+
.input {
|
|
103
|
+
height: 2.5rem;
|
|
104
|
+
margin-bottom: 0;
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright IBM Corp. 2019
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* COPIED FROM carbon-components-react
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {object} config Plugin configuration.
|
|
16
|
+
* @returns {Plugin} A Flatpickr plugin to put adjust the position of calendar dropdown.
|
|
17
|
+
*/
|
|
18
|
+
export default config => fp => {
|
|
19
|
+
/**
|
|
20
|
+
* Adjusts the floating meun position after Flatpicker sets it.
|
|
21
|
+
*/
|
|
22
|
+
const handlePreCalendarPosition = () => {
|
|
23
|
+
Promise.resolve().then(() => {
|
|
24
|
+
const {
|
|
25
|
+
calendarContainer,
|
|
26
|
+
config: fpConfig,
|
|
27
|
+
_positionElement: positionElement,
|
|
28
|
+
} = fp;
|
|
29
|
+
const { appendTo } = fpConfig;
|
|
30
|
+
const { left: containerLeft, top: containerTop } =
|
|
31
|
+
appendTo.getBoundingClientRect();
|
|
32
|
+
const { left: refLeft, bottom: refBottom } =
|
|
33
|
+
positionElement.getBoundingClientRect();
|
|
34
|
+
if (
|
|
35
|
+
(appendTo !== appendTo.ownerDocument.body ||
|
|
36
|
+
containerLeft !== 0 ||
|
|
37
|
+
containerTop !== 0) &&
|
|
38
|
+
appendTo.ownerDocument.defaultView
|
|
39
|
+
.getComputedStyle(appendTo)
|
|
40
|
+
.getPropertyValue('position') === 'static'
|
|
41
|
+
) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
'Floating menu container must not have `position:static`.'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
// `2` for negative mergin on calendar dropdown
|
|
47
|
+
calendarContainer.style.top = `${refBottom - containerTop + 2}px`;
|
|
48
|
+
calendarContainer.style.left = `${refLeft - containerLeft}px`;
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Registers this Flatpickr plugin.
|
|
54
|
+
*/
|
|
55
|
+
const register = () => {
|
|
56
|
+
fp.loadedPlugins.push('carbonFlatpickrAppendToPlugin');
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
appendTo: config.appendTo,
|
|
61
|
+
onReady: register,
|
|
62
|
+
onPreCalendarPosition: handlePreCalendarPosition,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2018
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* COPIED FROM carbon-components-react - amended to remove keyboard code dependency
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {object} config Plugin configuration.
|
|
14
|
+
* @returns {Plugin} A Flatpickr plugin to fix Flatpickr's behavior of certain events.
|
|
15
|
+
*/
|
|
16
|
+
export default config => fp => {
|
|
17
|
+
/**
|
|
18
|
+
* Handles `keydown` event.
|
|
19
|
+
*/
|
|
20
|
+
const handleKeydown = event => {
|
|
21
|
+
const { inputFrom, inputTo } = config;
|
|
22
|
+
const { target } = event;
|
|
23
|
+
if (inputFrom === target || inputTo === target) {
|
|
24
|
+
if (event.key === 'Enter') {
|
|
25
|
+
// Makes sure the hitting enter key picks up pending values of both `<input>`
|
|
26
|
+
// Workaround for: https://github.com/flatpickr/flatpickr/issues/1942
|
|
27
|
+
fp.setDate(
|
|
28
|
+
[inputFrom.value, inputTo && inputTo.value],
|
|
29
|
+
true,
|
|
30
|
+
fp.config.dateFormat
|
|
31
|
+
);
|
|
32
|
+
event.stopPropagation();
|
|
33
|
+
} else if (event.key === 'Left' || event.key === 'Right') {
|
|
34
|
+
// Prevents Flatpickr code from canceling the event if left/right arrow keys are hit on `<input>`,
|
|
35
|
+
// so user can move the keyboard cursor for editing dates
|
|
36
|
+
// Workaround for: https://github.com/flatpickr/flatpickr/issues/1943
|
|
37
|
+
event.stopPropagation();
|
|
38
|
+
} else if (event.key === 'Down') {
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
fp.open();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Releases event listeners used in this Flatpickr plugin.
|
|
47
|
+
*/
|
|
48
|
+
const release = () => {
|
|
49
|
+
const { inputFrom, inputTo } = config;
|
|
50
|
+
if (inputTo) {
|
|
51
|
+
inputTo.removeEventListener('keydown', handleKeydown, true);
|
|
52
|
+
}
|
|
53
|
+
inputFrom.removeEventListener('keydown', handleKeydown, true);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Sets up event listeners used for this Flatpickr plugin.
|
|
58
|
+
*/
|
|
59
|
+
const init = () => {
|
|
60
|
+
release();
|
|
61
|
+
const { inputFrom, inputTo } = config;
|
|
62
|
+
inputFrom.addEventListener('keydown', handleKeydown, true);
|
|
63
|
+
if (inputTo) {
|
|
64
|
+
inputTo.addEventListener('keydown', handleKeydown, true);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Registers this Flatpickr plugin.
|
|
70
|
+
*/
|
|
71
|
+
const register = () => {
|
|
72
|
+
fp.loadedPlugins.push('carbonFlatpickrFixEventsPlugin');
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
onReady: [register, init],
|
|
77
|
+
onDestroy: [release],
|
|
78
|
+
};
|
|
79
|
+
};
|