UNPKG

@postnord/web-components

Version:

PostNord Web Components

301 lines (300 loc) 10.1 kB
/*! * 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