-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1453 from weslleyrsr/vNext
feat: implement CvDatePicker
- Loading branch information
Showing
12 changed files
with
1,255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# cv-date-picker | ||
|
||
A Vue implementation of a Carbon Components date-picker. | ||
|
||
http://www.carbondesignsystem.com/components/date-picker/code | ||
|
||
## Usage | ||
|
||
### Short | ||
|
||
```html | ||
<cv-date-picker | ||
kind="short" | ||
pattern="\d{1,2}/\d{2}" | ||
placeholder="mm/yy" | ||
@onChange="actionChange" | ||
> | ||
</cv-date-picker> | ||
``` | ||
|
||
### Simple | ||
|
||
```html | ||
<cv-date-picker | ||
kind="simple" | ||
pattern="\d{1,2}/\d{1,2}/\d{4}" | ||
placeholder="mm/dd/yyyy" | ||
@onChange="actionChange" | ||
> | ||
</cv-date-picker> | ||
``` | ||
|
||
### Single | ||
|
||
```html | ||
<cv-date-picker | ||
kind="single" | ||
pattern="\d{1,2}/\d{1,2}/\d{4}" | ||
placeholder="mm/dd/yyyy" | ||
:cal-options="calOptions" | ||
@onChange="actionChange" | ||
> | ||
</cv-date-picker> | ||
``` | ||
|
||
### Range | ||
|
||
```html | ||
<cv-date-picker | ||
kind="range" | ||
pattern="\d{1,2}/\d{1,2}/\d{4}" | ||
placeholder="mm/dd/yyyy" | ||
:cal-options="calOptions" | ||
@onChange="actionChange" | ||
> | ||
</cv-date-picker> | ||
``` | ||
|
||
## Attributes | ||
|
||
- dateLabel: optional label for the date input (first in range) | ||
- dateEndLabel: optional for the end range date input (first in range) | ||
- kind: 'short', 'simple', 'single', 'range' as per carbon components core only single and range have a date picker | ||
- calOptions: Options to confiure flatpickr, see flatpickr for full details. | ||
|
||
- e.g. { dateFormat: 'd/m/Y', defaultDate: '01/01/2019' } | ||
- NOTE: passing event handlers onChange and onValueUpdate are swallowed internally. Both produce an onChange. | ||
|
||
- pattern: Regex pattern used for form validation '\\d{1,2}/\\d{1,2}/\\d{4}', | ||
- placeholder: Shown when date picker is empty, | ||
- invalidMessage: Message displayed if invalid is true | ||
|
||
- value: can be | ||
- Javascript Date | ||
- String with a date matching the format based on the calendar options | ||
- Object (kind === 'range' only): { startDate: val, endDate: val2 } where val and val2 are a javascript date or date string as per format option | ||
|
||
## Slots | ||
|
||
invalid-message: Overrides the invalid message property | ||
|
||
### | ||
|
||
## Events | ||
|
||
- change raised when single or ranged date picker value changes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
import { | ||
sbCompPrefix, | ||
storyParametersObject, | ||
} from '../../global/storybook-utils'; | ||
|
||
import { CvDatePicker } from '.'; | ||
import { CvDatePickerSkeleton } from '.'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { ref } from 'vue'; | ||
|
||
const initArgs = { | ||
dateLabel: 'Date label', | ||
invalidMessage: '', | ||
}; | ||
|
||
const now = new Date(); | ||
const tomorrow = new Date(); | ||
tomorrow.setDate(now.getDate() + 1); | ||
|
||
export default { | ||
title: `${sbCompPrefix}/CvDatePicker`, | ||
component: CvDatePicker, | ||
parameters: { | ||
a11y: { | ||
config: { | ||
rules: [], | ||
}, | ||
manual: true, | ||
}, | ||
}, | ||
argTypes: { | ||
dateLabel: { type: String, description: 'Date picker label' }, | ||
invalidMessage: { | ||
type: String, | ||
description: 'Date picker text on invalid value', | ||
}, | ||
}, | ||
}; | ||
|
||
/* DEFAULT STORY */ | ||
|
||
const template = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange'> | ||
</cv-date-picker> | ||
</div> | ||
`; | ||
const Template = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
onChange: action('change'), | ||
}), | ||
template, | ||
}; | ||
}; | ||
|
||
export const Default = Template.bind({}); | ||
Default.args = initArgs; | ||
Default.parameters = storyParametersObject( | ||
Default.parameters, | ||
template, | ||
Default.args | ||
); | ||
|
||
/* V-MODEL STORY */ | ||
|
||
const modelValue = ref(''); | ||
const templateVModel = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange' v-model="modelValue"> | ||
</cv-date-picker> | ||
</div> | ||
<div style="margin: 32px 0;"> | ||
<div style="font-size: 150%;">Sample interaction</div> | ||
<label for="date-model" style='margin-right: 0.5rem'>V-model:</label> | ||
<input id="date-model" type="text" :value="modelValue.startDate || modelValue" @change="ev => { if (args.kind === 'range') { modelValue.startDate = ev.currentTarget.value } else { modelValue = ev.currentTarget.value } }"/> | ||
<input v-if="args.kind === 'range'" id="date-model" type="text" :value="modelValue.endDate" @change="ev => modelValue.endDate = ev.currentTarget.value"/> | ||
</div> | ||
`; | ||
|
||
const TemplateVModel = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
modelValue, | ||
now, | ||
onChange: action('change'), | ||
}), | ||
template: templateVModel, | ||
}; | ||
}; | ||
|
||
export const vModel = TemplateVModel.bind({}); | ||
vModel.args = initArgs; | ||
vModel.parameters = storyParametersObject( | ||
vModel.parameters, | ||
templateVModel, | ||
vModel.args | ||
); | ||
|
||
/* INVALID MESSAGE STORY */ | ||
|
||
const templateInvalidMessage = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange'> | ||
</cv-date-picker> | ||
</div> | ||
`; | ||
|
||
const TemplateInvalidMessage = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
onChange: action('change'), | ||
}), | ||
template: templateInvalidMessage, | ||
}; | ||
}; | ||
|
||
export const InvalidMessage = TemplateInvalidMessage.bind({}); | ||
InvalidMessage.args = { ...initArgs, invalidMessage: 'Invalid date' }; | ||
|
||
/* INVALID MESSAGE SLOT STORY */ | ||
|
||
const templateInvalidMessageSlot = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange'> | ||
<template #invalid-message>Invalid date slot</template> | ||
</cv-date-picker> | ||
</div> | ||
`; | ||
|
||
const TemplateInvalidMessageSlot = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
onChange: action('change'), | ||
}), | ||
template: templateInvalidMessageSlot, | ||
}; | ||
}; | ||
|
||
export const InvalidMessageSlot = TemplateInvalidMessageSlot.bind({}); | ||
InvalidMessageSlot.args = initArgs; | ||
|
||
/* SINGLE USING DATE STORY */ | ||
|
||
const templateSingleUsingDate = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange' kind="single" :value="now"> | ||
</cv-date-picker> | ||
</div> | ||
`; | ||
|
||
const TemplateSingleUsingDate = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
now, | ||
onChange: action('change'), | ||
}), | ||
template: templateSingleUsingDate, | ||
}; | ||
}; | ||
|
||
export const SingleUsingDate = TemplateSingleUsingDate.bind({}); | ||
SingleUsingDate.args = initArgs; | ||
|
||
/* RANGE USING DATE STORY */ | ||
|
||
const templateRangeUsingDate = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange' kind="range" :value="{startDate: now.toLocaleDateString(), endDate: tomorrow.toLocaleDateString()}"> | ||
</cv-date-picker> | ||
</div> | ||
`; | ||
|
||
const TemplateRangeUsingDate = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
now, | ||
tomorrow, | ||
onChange: action('change'), | ||
}), | ||
template: templateRangeUsingDate, | ||
}; | ||
}; | ||
|
||
export const RangeUsingDate = TemplateRangeUsingDate.bind({}); | ||
RangeUsingDate.args = initArgs; | ||
|
||
/* MINIMAL STORY */ | ||
|
||
const templateMinimal = ` | ||
<div> | ||
<cv-date-picker v-bind='args' @change='onChange'> | ||
</cv-date-picker> | ||
</div> | ||
`; | ||
|
||
const TemplateMinimal = args => { | ||
return { | ||
components: { CvDatePicker }, | ||
setup: () => ({ | ||
args, | ||
onChange: action('change'), | ||
}), | ||
template: templateMinimal, | ||
}; | ||
}; | ||
|
||
export const Minimal = TemplateMinimal.bind({}); | ||
|
||
/* SKELETON STORY */ | ||
|
||
const templateSkeleton = ` | ||
<div> | ||
<cv-date-picker-skeleton v-bind='args'></cv-date-picker-skeleton> | ||
</div> | ||
`; | ||
|
||
const TemplateSkeleton = args => { | ||
return { | ||
components: { CvDatePicker, CvDatePickerSkeleton }, | ||
setup: () => ({ | ||
args, | ||
onChange: action('change'), | ||
}), | ||
template: templateSkeleton, | ||
}; | ||
}; | ||
|
||
export const Skeleton = TemplateSkeleton.bind({}); |
Oops, something went wrong.