@postnord/web-components
Version:
PostNord Web Components
301 lines (300 loc) • 10.1 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { getToday, modifyDate } from "../../../globals/date/index";
import { createDocumentation, createComponent } from "../../../globals/documentation/story";
import docs from "./pn-date-picker-docs.json";
import { getFigmaUrl } from "../../../globals/figmaLinks";
const { argTypes, textContent } = createDocumentation(docs);
const format = 'YYYY-MM-DD';
const dateToday = getToday().format(format);
const datePast = modifyDate({ data: getToday(), unit: 'day', amount: 1, minus: true });
const dateFuture = modifyDate({ data: getToday(), unit: 'day', amount: 60, plus: true });
/**
* Select a date by either writing it manually in the field or open the calendar to select one.
*
* The component is very flexible with its date formats. You can view the available formats in
* <pn-text-link href="https://day.js.org/docs/en/display/format">DayJS format documentation</pn-text-link>.
*
* Similar to other inputs, it has built in `label-from`, `helpertext`, `error` and more props to help you get started.
* We recommend that you always have a `label-from` and `label-to` to properly describe the date picker.
* If you deviate from the standard `YYYY-MM-DD` format, its a good idea the explain this in the `helpertext`.
**/
const meta = {
title: 'Components/Input/Date Picker',
parameters: {
layout: 'padded',
actions: {
handles: ['dateSelection', 'dateInvalid', 'toggleCalendar', 'currentView'],
},
design: {
type: 'figma',
url: getFigmaUrl(import.meta.url),
},
},
args: {
labelFrom: 'Select date',
labelTo: 'Select end date',
helpertext: '',
start: '',
end: '',
format: '',
language: '',
dateId: '',
name: '',
placeholder: '',
endPlaceholder: '',
autocomplete: '',
list: '',
listEnd: '',
pattern: '',
range: false,
// rangeLimit: null,
view: null,
calendarUp: false,
weekNumbers: false,
disableTypeAhead: false,
disableWeekends: false,
disabledDates: '',
required: false,
readonly: false,
disabled: false,
error: '',
invalid: false,
minDate: '',
maxDate: '',
},
argTypes,
};
meta.argTypes.minDate.control = 'text';
meta.argTypes.maxDate.control = 'text';
meta.argTypes.labelTo.if = { arg: 'range', eq: true };
meta.argTypes.end.if = { arg: 'range', eq: true };
meta.argTypes.endPlaceholder.if = { arg: 'range', eq: true };
meta.argTypes.listEnd.if = { arg: 'range', eq: true };
export default meta;
export const PnDatePicker = {
name: 'pn-date-picker',
parameters: {
docs: {
description: {
story: textContent,
},
},
},
render: args => {
const form = document.createElement('div');
form.style.width = '100%';
form.style.margin = '0 auto';
if (args.range)
form.style.maxWidth = '25em';
else
form.style.maxWidth = '11em';
if (args.calendarUp)
form.style.marginTop = '25em';
else
form.style.marginBottom = '25em';
const datePicker = createComponent('pn-date-picker', args);
form.appendChild(datePicker);
return form;
},
args: {
start: '',
},
};
/** You can set the `helpertext` with either a prop or slot. */
export const PnDatePickerHelpertext = {
name: 'pn-date-picker (helpertext)',
render: PnDatePicker.render,
args: {
labelFrom: 'Delivery date',
helpertext: 'Select prefered delivery date.',
},
};
/** You can set the `helpertext` with either a prop or slot. */
export const PnDatePickerError = {
name: 'pn-date-picker (error)',
render: PnDatePicker.render,
args: {
...PnDatePickerHelpertext.args,
start: '2025-03-08',
minDate: '2025-03-12',
error: 'Please select a valid date',
},
};
/**
* Select a different default view when opening the date picker.
* The default is `calendar` and can be changed to either `months` or `years`.
*
* This is only the view change. If you wish to initiate the calendar with a default value, use the `start` prop.
**/
export const PnDatePickerView = {
name: 'pn-date-picker (view)',
render: PnDatePicker.render,
args: {
view: 'months',
},
};
/** Set the date picker as readonly. */
export const PnDatePickerReadonly = {
name: 'pn-date-picker (readonly)',
render: args => createComponent('pn-date-picker', args),
args: {
start: dateToday,
readonly: true,
},
};
/** You can disable the date picker entirely. */
export const PnDatePickerDisabled = {
name: 'pn-date-picker (disabled)',
render: PnDatePickerReadonly.render,
args: {
start: dateToday,
disabled: true,
},
};
/** You can set a minimun and maximum date that can be selected with the `minDate` and `maxDate`. */
export const PnDatePickerDisabledDates = {
name: 'pn-date-picker (min/max dates)',
render: PnDatePicker.render,
args: {
start: dateToday,
minDate: datePast.format(format),
maxDate: dateFuture.format(format),
},
};
/** You can disable all weekends with the `disable-weekends` prop. */
export const PnDatePickerDisableWeekends = {
name: 'pn-date-picker (disable weekends)',
render: PnDatePicker.render,
args: {
disableWeekends: true,
},
};
/**
* The `pn-date-picker` allows for a very flexible date format.
*
* Look at the <pn-text-link href="https://day.js.org/docs/en/display/format">DayJS format documentation</pn-text-link> for all possible formats.
* */
export const PnDatePickerFormat = {
name: 'pn-date-picker (format)',
render: PnDatePicker.render,
args: {
start: '03/13/2025',
format: 'MM/DD/YYYY',
disabledDates: '03/18/2025,03/20/2025',
},
};
/**
* You can turn the date picker into a range select by enabling the `range` prop.
*
* Remember to use both label props `label-from` and `label-to` when using `range`.
*/
export const PnDatePickerRange = {
name: 'pn-date-picker (range)',
render: PnDatePicker.render,
args: {
labelFrom: 'Start date',
labelTo: 'End date',
range: true,
},
};
/** Make the calendar to open upwards by default. */
export const PnDatePickerUp = {
name: 'pn-date-picker (calendar up)',
render: PnDatePicker.render,
args: {
calendarUp: true,
},
};
/** Show the week number to the right of the calendar grid. */
export const PnDatePickerWeekNumbers = {
name: 'pn-date-picker (week numbers)',
render: PnDatePicker.render,
args: {
weekNumbers: true,
},
};
/**
* There are three slots available for the calendar picker.
*
* The following slots behave just as the props with the same names:
* - helpertext
* - error
*
* The slot `chips` will be positioned underneath the calendar grid.
* The idea is that you can add your own quick selection chips. Such as a "Select today" or "Select the next 2 weeks", etc...
**/
export const PnDatePickerSlot = {
name: 'pn-date-picker (slot)',
render: (args, context) => {
const div = document.createElement('div');
const datePickerContainer = PnDatePicker.render(args, context);
const datePicker = datePickerContainer.querySelector('pn-date-picker');
const chips = document.createElement('div');
chips.setAttribute('slot', 'chips');
chips.addEventListener('change', ({ target }) => {
const { value, checked } = target;
datePicker.setAttribute('start', checked && value !== 'on' ? value : '');
});
const chipSelectDate = createComponent('pn-choice-chip', {
label: 'Today',
value: getToday().format(args.format || 'YYYY-MM-DD'),
name: 'pn-date-box',
small: true,
});
chips.appendChild(chipSelectDate);
datePicker.appendChild(chips);
datePicker.addEventListener('dateSelection', ({ detail }) => chipSelectDate.setAttribute('checked', (detail.start === chipSelectDate.value).toString()));
div.appendChild(datePickerContainer);
return div;
},
args: {
start: '',
},
};
/**
* Use the `list` feature to suggest date values. Just click or tab to the input elements to view the suggestions.
*
* This is an excellent way to suggest common date values in an accessible way.
*/
export const PnDatePickerList = {
name: 'pn-date-picker (list)',
render: (args, context) => {
const picker = PnDatePicker.render(args, context);
const suggestions = [
{ name: '2025 March 1', value: '2025-03-01' },
{ name: '2025 April 1', value: '2025-04-01' },
{ name: '2025 May 1', value: '2025-05-01' },
];
const suggestionsEnd = [
{ name: '2025 June 1', value: '2025-06-01' },
{ name: '2025 July 1', value: '2025-07-01' },
{ name: '2025 August 1', value: '2025-08-01' },
];
const createList = (id, options) => {
const list = document.createElement('datalist');
list.id = id;
options.forEach(({ name, value }) => {
const option = document.createElement('option');
option.value = value;
option.textContent = name;
list.appendChild(option);
});
picker.appendChild(list);
};
if (args.list)
createList(args.list, suggestions);
if (args.listEnd)
createList(args.listEnd, suggestionsEnd);
return picker;
},
args: {
start: '',
range: true,
list: 'pn-date-start-suggestions',
listEnd: 'pn-date-end-suggestions',
},
};
//# sourceMappingURL=pn-date-picker.stories.js.map