UNPKG

@wix/design-system

Version:

@wix/design-system

339 lines (303 loc) 8.66 kB
## Feature Examples ### Presets - description: Empower the user to quickly select a predefined range or date using `presets` prop. - example: ```jsx () => { const [selectedValue, setSelectedValue] = React.useState(); const today = new Date(); const getDateDaysAgo = days => new Date(Date.now() - days * 1000 * 60 * 60 * 24); const presets = [ { id: 0, selectedDays: getDateDaysAgo(1), value: 'Yesterday', }, { id: 1, selectedDays: today, value: 'Today', }, { id: 2, selectedDays: { from: getDateDaysAgo(7), to: today, }, value: 'Last 7 Days', }, { id: 3, selectedDays: { from: getDateDaysAgo(30), to: today, }, value: 'Last 30 Days', }, { id: 4, selectedDays: { from: getDateDaysAgo(90), to: today, }, value: 'Last 90 Days', }, ]; return ( <CalendarPanel presets={presets} onChange={value => setSelectedValue(value)} value={selectedValue} autoFocus={false} /> ); }; ``` ### Footer - description: Make the date selection secure by using `footer` prop which adds summarized date selection and confirmation actions. - example: ```jsx <CalendarPanel value={new Date()} footer={({ selectedDays }) => ( <CalendarPanelFooter primaryActionLabel="Submit" secondaryActionLabel="Cancel" selectedDays={selectedDays} dateToString={date => date.toLocaleDateString('en-US')} /> )} autoFocus={false} />; ``` ### Number of Months - description: Specify a number of months visible inside of a panel with `numOfMonths` prop.<br/> <br/> By default panel displays 2 months at once. Display a single month only when presets are available. - example: ```jsx () => { const presets = [ { id: 0, value: 'Last 7 Days', }, { id: 1, value: 'Last Month', }, { id: 2, value: 'Next 2 days', }, { id: 3, value: 'Next 3 days', }, { id: 4, value: 'Next 5 days', }, ]; return ( <StorybookComponents.Stack flexDirection="column"> <StorybookComponents.Stack> <CalendarPanel numOfMonths={1} presets={presets} autoFocus={false} /> </StorybookComponents.Stack> <StorybookComponents.Stack> <CalendarPanel numOfMonths={2} presets={presets} autoFocus={false} /> </StorybookComponents.Stack> </StorybookComponents.Stack> ); }; ``` ### Selection Mode - description: Enable users to select the range of dates with `selectionMode` prop. It supports 2 values:<br/> &emsp;- `day` (default) - lets to select 1 day.<br/> &emsp;- `range` - lets to select any range of dates. - example: ```jsx _selectionMode ``` ### Month and Year Selection - description: Let the user quickly change the month and year values with:<br/> &emsp;- `showMonthDropdown` (default) - enables month selection dropdown.<br/> &emsp;- `showYearDropdown` - enables year selection dropdown. - example: ```jsx <CalendarPanel showMonthDropdown showYearDropdown autoFocus={false} />; ``` ### Excluding Dates - description: Control what dates the user can select with 2 props:<br/> &emsp;- `filterDate` (default) - define what dates will be selectable.<br/> &emsp;- `excludePastDates` - allow selecting only today and future dates. - example: ```jsx <StorybookComponents.Stack flexDirection="column"> <CalendarPanel filterDate={date => date < new Date()} autoFocus={false} /> <CalendarPanel excludePastDates autoFocus={false} /> </StorybookComponents.Stack>; ``` ### Localization - description: Change the language using `locale` prop. Some languages will change the start of the week day and order of month and year. First Day of the week can be controlled manually with `firstDayOfWeek` prop.<br/> <br/> Presets and footer actions aren’t controlled by this and have to be translated manually.<br/> <br/> When using `Yoshi 5` with `BM Flow` there's no need to use `locale` prop anymore. It is handled automatically. - example: ```jsx <CalendarPanel locale="ko" presets={[{ value: "I'm still English" }]} footer={() => ( <CalendarPanelFooter secondaryActionLabel="Me too" primaryActionLabel="Me as well" selectedDays={new Date()} dateToString={date => date.toLocaleDateString('en-US')} /> )} autoFocus={false} />; ``` ## Common Use Case Examples ### Trigger - description: Call it out from any action component such as `<IconButton/>`, `<TextButton/>`, `<Button/>`, etc. Use it to filter data and content. - example: ```jsx () => { const today = new Date(); const dayInMilliseconds = 1000 * 60 * 60 * 24; const getDateDaysAgo = days => new Date(Date.now() - days * dayInMilliseconds); const getShortDate = date => date.toLocaleDateString(); const oneDayChartData = [ { value: Math.floor(Math.random() * 1000), label: '00:00', }, { value: Math.floor(Math.random() * 1000), label: '23:59', }, ]; const [currentRange, setCurrentRange] = React.useState(today); const [analyticsData, setAnalyticsData] = React.useState({ chartData: oneDayChartData, range: today, rangeText: getShortDate(today), }); const [panelShown, setPanelShown] = React.useState(false); const presets = [ { id: 0, selectedDays: { from: getDateDaysAgo(7), to: today, }, value: 'Last 7 Days', }, { id: 1, selectedDays: { from: getDateDaysAgo(30), to: today, }, value: 'Last 30 Days', }, { id: 2, selectedDays: { from: getDateDaysAgo(90), to: today, }, value: 'Last 90 Days', }, ]; const getRangeOfDates = (startDate, endDate) => { const diffInDays = Math.ceil( (endDate.getTime() - startDate.getTime()) / dayInMilliseconds + 1, ); return new Array(diffInDays) .fill(0) .map( (_, index) => new Date(startDate.getTime() + index * dayInMilliseconds), ); }; const getChartAreaData = (startDate, endDate) => { if (startDate.getTime() === endDate.getTime()) { return oneDayChartData; } return getRangeOfDates(startDate, endDate).map((date, index) => ({ label: \`\${date.getMonth() + 1}/\${date.getDate()}\`, value: Math.floor(Math.random() * 1000), })); }; const getRangeText = (startDate, endDate) => startDate.getTime() === endDate.getTime() ? getShortDate(startDate) : \`\${getShortDate(startDate)}-\${getShortDate(endDate)}\`; const onSubmitClick = () => { setPanelShown(false); setAnalyticsData({ range: currentRange, chartData: getChartAreaData(currentRange.from, currentRange.to), rangeText: getRangeText(currentRange.from, currentRange.to), }); }; const onCancelClick = () => { setPanelShown(false); setCurrentRange(analyticsData.range); }; return ( <Card> <Card.Header title="Analytics" suffix={ <Popover shown={panelShown} onClickOutside={onCancelClick} appendTo="window" placement="bottom" > <Popover.Element> <TextButton onClick={() => setPanelShown(!panelShown)}> <Box verticalAlign="middle"> {analyticsData.rangeText} <Icons.ChevronDownSmall /> </Box> </TextButton> </Popover.Element> <Popover.Content> <CalendarPanel presets={presets} value={currentRange} onChange={setCurrentRange} selectionMode="range" footer={({ selectedDays }) => ( <CalendarPanelFooter primaryActionLabel="Submit" secondaryActionLabel="Cancel" primaryActionOnClick={onSubmitClick} secondaryActionOnClick={onCancelClick} selectedDays={selectedDays} dateToString={date => date.toLocaleDateString('en-US')} /> )} autoFocus={false} /> </Popover.Content> </Popover> } /> <Card.Divider /> <Card.Content> <AreaChart data={analyticsData.chartData} /> </Card.Content> </Card> ); }; ```