Skip to content
Snippets Groups Projects
Unverified Commit d3865eef authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Mantine DatePicker and DateInput (#34651)

parent 74639534
No related branches found
No related tags found
No related merge requests found
Showing
with 696 additions and 1 deletion
import { getStylesRef, rem } from "@mantine/core";
import type { MantineThemeOverride } from "@mantine/core";
export const getCalendarOverrides = (): MantineThemeOverride["components"] => ({
Day: {
styles: theme => ({
day: {
width: rem(40),
height: rem(40),
color: theme.colors.text[2],
fontSize: theme.fontSizes.md,
lineHeight: rem(24),
borderRadius: theme.radius.xs,
"&:hover": {
backgroundColor: theme.colors.bg[0],
},
"&[data-disabled]": {
color: theme.colors.bg[2],
},
"&[data-weekend]": {
color: theme.colors.text[2],
},
"&[data-outside]": {
color: theme.colors.bg[2],
},
"&[data-in-range]": {
color: theme.colors.text[1],
borderRadius: 0,
backgroundColor: theme.colors.brand[0],
"&:hover": {
backgroundColor: theme.colors.brand[0],
},
},
"&[data-first-in-range]": {
borderTopLeftRadius: theme.radius.xs,
borderBottomLeftRadius: theme.radius.xs,
},
"&[data-last-in-range]": {
borderTopRightRadius: theme.radius.xs,
borderBottomRightRadius: theme.radius.xs,
},
"&[data-selected]": {
color: theme.white,
backgroundColor: theme.colors.brand[1],
"&:hover": {
backgroundColor: theme.colors.brand[1],
},
},
},
}),
},
WeekdaysRow: {
styles: theme => ({
weekday: {
width: rem(40),
height: rem(32),
color: theme.colors.text[0],
fontSize: theme.fontSizes.sm,
lineHeight: rem(24),
textAlign: "center",
paddingBottom: 0,
},
}),
},
PickerControl: {
styles: theme => ({
pickerControl: {
color: theme.colors.text[2],
fontSize: theme.fontSizes.md,
lineHeight: rem(24),
width: rem(80),
height: rem(32),
borderRadius: theme.radius.sm,
"&:hover": {
backgroundColor: theme.colors.bg[0],
},
"&[data-disabled]": {
color: theme.colors.bg[2],
},
"&[data-weekend]": {
color: theme.colors.text[2],
},
"&[data-outside]": {
color: theme.colors.bg[2],
},
"&[data-in-range]": {
color: theme.colors.text[1],
borderRadius: 0,
backgroundColor: theme.colors.brand[0],
"&:hover": {
backgroundColor: theme.colors.brand[0],
},
},
},
}),
},
Month: {
styles: () =>
getListStyles({
rowClass: "monthRow",
cellClass: "monthCell",
horizontalPadding: rem(1),
verticalPadding: rem(1),
}),
},
MonthsList: {
styles: theme =>
getListStyles({
rowClass: "monthsListRow",
cellClass: "monthsListCell",
horizontalPadding: theme.spacing.sm,
verticalPadding: theme.spacing.xs,
}),
},
YearsList: {
styles: theme =>
getListStyles({
rowClass: "yearsListRow",
cellClass: "yearsListCell",
horizontalPadding: theme.spacing.sm,
verticalPadding: theme.spacing.xs,
}),
},
CalendarHeader: {
styles: theme => ({
calendarHeader: {
marginBottom: 0,
},
calendarHeaderLevel: {
height: rem(32),
color: theme.colors.text[2],
fontSize: theme.fontSizes.md,
fontWeight: "bold",
lineHeight: rem(24),
"&:hover": {
backgroundColor: theme.colors.bg[0],
},
},
calendarHeaderControl: {
width: rem(32),
height: rem(32),
borderRadius: theme.radius.xs,
color: theme.colors.bg[2],
"&:hover": {
backgroundColor: theme.colors.bg[0],
},
},
}),
},
MonthLevel: {
styles: () => ({
calendarHeader: {
marginBottom: 0,
},
}),
},
});
interface ListStylesParams {
rowClass: string;
cellClass: string;
horizontalPadding: string;
verticalPadding: string;
}
const getListStyles = ({
rowClass,
cellClass,
horizontalPadding,
verticalPadding,
}: ListStylesParams) => ({
[cellClass]: {
ref: getStylesRef(cellClass),
"&[data-with-spacing]": {
padding: 0,
"&:not(:first-of-type)": {
paddingLeft: horizontalPadding,
},
"&:not(:last-of-type)": {
paddingRight: horizontalPadding,
},
},
},
[rowClass]: {
[`&:not(:first-of-type) .${getStylesRef(cellClass)}`]: {
paddingTop: verticalPadding,
},
[`&:not(:last-of-type) .${getStylesRef("monthCell")}`]: {
paddingBottom: verticalPadding,
},
},
});
export { getCalendarOverrides } from "./Calendar.styled";
import { Canvas, Story, Meta } from "@storybook/addon-docs";
import { Icon } from "metabase/core/components/Icon";
import { DateInput, Stack } from "metabase/ui";
export const args = {
variant: "default",
size: "md",
label: "Label",
description: undefined,
error: undefined,
placeholder: "Placeholder",
disabled: false,
readOnly: false,
withAsterisk: false,
};
export const sampleArgs = {
value: new Date(2023, 9, 8),
label: "Event date",
description:
"The event is visible if the date falls within the chart’s time range",
placeholder: "Enter date",
error: "required",
};
export const argTypes = {
variant: {
options: ["default", "unstyled"],
control: { type: "inline-radio" },
},
size: {
options: ["xs", "md"],
control: { type: "inline-radio" },
},
label: {
control: { type: "text" },
},
description: {
control: { type: "text" },
},
placeholder: {
control: { type: "text" },
},
error: {
control: { type: "text" },
},
disabled: {
control: { type: "boolean" },
},
readOnly: {
control: { type: "boolean" },
},
withAsterisk: {
control: { type: "boolean" },
},
};
<Meta
title="Inputs/DateInput"
component={DateInput}
args={args}
argTypes={argTypes}
/>
# DateInput
Our themed wrapper around [Mantine DateInput](https://v6.mantine.dev/dates/date-input/).
## Docs
- [Figma File](https://www.figma.com/file/oIZhYS5OoRA7twd4KqN4Eu/Input-%2F-Text?type=design&node-id=1-96&mode=design&t=yaNljw178EFJeU7k-0)
- [Mantine DateInput Docs](https://v6.mantine.dev/dates/date-input/)
## Examples
export const DefaultTemplate = args => <DateInput {...args} />;
export const VariantTemplate = args => (
<Stack>
<DateInput {...args} variant="default" />
<DateInput {...args} variant="unstyled" />
</Stack>
);
export const IconTemplate = args => (
<VariantTemplate {...args} icon={<Icon name="calendar" />} />
);
export const Default = DefaultTemplate.bind({});
<Canvas>
<Story name="Default">{Default}</Story>
</Canvas>
### Size - md
export const EmptyMd = VariantTemplate.bind({});
<Canvas>
<Story name="Empty, md">{EmptyMd}</Story>
</Canvas>
#### Filled
export const FilledMd = VariantTemplate.bind({});
FilledMd.args = {
defaultValue: sampleArgs.value,
label: sampleArgs.label,
placeholder: sampleArgs.placeholder,
};
<Canvas>
<Story name="Filled, md">{FilledMd}</Story>
</Canvas>
#### Asterisk
export const AsteriskMd = VariantTemplate.bind({});
AsteriskMd.args = {
label: sampleArgs.label,
placeholder: sampleArgs.placeholder,
withAsterisk: true,
};
<Canvas>
<Story name="Asterisk, md">{AsteriskMd}</Story>
</Canvas>
#### Description
export const DescriptionMd = VariantTemplate.bind({});
DescriptionMd.args = {
label: sampleArgs.label,
description: sampleArgs.description,
placeholder: sampleArgs.placeholder,
};
<Canvas>
<Story name="Description, md">{DescriptionMd}</Story>
</Canvas>
#### Disabled
export const DisabledMd = VariantTemplate.bind({});
DisabledMd.args = {
label: sampleArgs.label,
description: sampleArgs.description,
placeholder: sampleArgs.placeholder,
disabled: true,
withAsterisk: true,
};
<Canvas>
<Story name="Disabled, md">{DisabledMd}</Story>
</Canvas>
#### Error
export const ErrorMd = VariantTemplate.bind({});
ErrorMd.args = {
label: sampleArgs.label,
description: sampleArgs.description,
placeholder: sampleArgs.placeholder,
error: sampleArgs.error,
withAsterisk: true,
};
<Canvas>
<Story name="Error, md">{ErrorMd}</Story>
</Canvas>
#### Icon
export const IconMd = IconTemplate.bind({});
IconMd.args = {
label: sampleArgs.label,
description: sampleArgs.description,
placeholder: sampleArgs.placeholder,
withAsterisk: true,
};
<Canvas>
<Story name="Icon, md">{IconMd}</Story>
</Canvas>
#### Read only
export const ReadOnlyMd = VariantTemplate.bind({});
ReadOnlyMd.args = {
defaultValue: sampleArgs.value,
label: sampleArgs.label,
description: sampleArgs.description,
placeholder: sampleArgs.placeholder,
readOnly: true,
};
<Canvas>
<Story name="Read only, md">{ReadOnlyMd}</Story>
</Canvas>
#### No popover
export const NoPopoverMd = VariantTemplate.bind({});
NoPopoverMd.args = {
defaultValue: sampleArgs.value,
label: sampleArgs.label,
description: sampleArgs.description,
placeholder: sampleArgs.placeholder,
popoverProps: { opened: false },
};
<Canvas>
<Story name="No popover, md">{NoPopoverMd}</Story>
</Canvas>
### Size - xs
export const EmptyXs = VariantTemplate.bind({});
EmptyXs.args = {
...EmptyMd.args,
size: "xs",
};
<Canvas>
<Story name="Empty, xs">{EmptyXs}</Story>
</Canvas>
#### Filled
export const FilledXs = VariantTemplate.bind({});
FilledXs.args = {
...FilledMd.args,
size: "xs",
};
<Canvas>
<Story name="Filled, xs">{FilledXs}</Story>
</Canvas>
#### Asterisk
export const AsteriskXs = VariantTemplate.bind({});
AsteriskXs.args = {
...AsteriskMd.args,
size: "xs",
};
<Canvas>
<Story name="Asterisk, xs">{AsteriskXs}</Story>
</Canvas>
#### Description
export const DescriptionXs = VariantTemplate.bind({});
DescriptionXs.args = {
...DescriptionMd.args,
size: "xs",
};
<Canvas>
<Story name="Description, xs">{DescriptionXs}</Story>
</Canvas>
#### Disabled
export const DisabledXs = VariantTemplate.bind({});
DisabledXs.args = {
...DisabledMd.args,
size: "xs",
};
<Canvas>
<Story name="Disabled, xs">{DisabledXs}</Story>
</Canvas>
#### Error
export const ErrorXs = VariantTemplate.bind({});
ErrorXs.args = {
...ErrorMd.args,
size: "xs",
};
<Canvas>
<Story name="Error, xs">{ErrorXs}</Story>
</Canvas>
#### Icon
export const IconXs = IconTemplate.bind({});
IconXs.args = {
...IconMd.args,
size: "xs",
};
<Canvas>
<Story name="Icon, xs">{IconXs}</Story>
</Canvas>
#### Read only
export const ReadOnlyXs = VariantTemplate.bind({});
ReadOnlyXs.args = {
...ReadOnlyMd.args,
size: "xs",
};
<Canvas>
<Story name="Read only, xs">{ReadOnlyXs}</Story>
</Canvas>
#### No popover
export const NoPopoverXs = VariantTemplate.bind({});
NoPopoverXs.args = {
...NoPopoverMd.args,
size: "xs",
};
<Canvas>
<Story name="No popover, xs">{NoPopoverXs}</Story>
</Canvas>
import type { MantineThemeOverride } from "@mantine/core";
export const getDateInputOverrides =
(): MantineThemeOverride["components"] => ({
DateInput: {
defaultProps: {
size: "md",
},
styles: theme => ({
wrapper: {
"&:not(:only-child)": {
marginTop: theme.spacing.xs,
},
},
calendar: {
padding: `${theme.spacing.sm} ${theme.spacing.md}`,
},
}),
},
});
export { DateInput } from "@mantine/dates";
export type { DateInputProps } from "@mantine/dates";
export { getDateInputOverrides } from "./DateInput.styled";
import { Fragment } from "react";
import { Canvas, Story, Meta } from "@storybook/addon-docs";
import { DatePicker } from "metabase/ui";
export const args = {
type: "default",
allowDeselect: undefined,
allowSingleDateInRange: undefined,
numberOfColumns: undefined,
};
export const sampleArgs = {
date1: new Date(2023, 9, 8),
date2: new Date(2023, 9, 24),
date3: new Date(2023, 9, 16),
};
export const argTypes = {
type: {
options: ["default", "multiple", "range"],
control: { type: "inline-radio" },
},
allowDeselect: {
control: { type: "boolean" },
},
allowSingleDateInRange: {
control: { type: "boolean" },
},
numberOfColumns: {
control: { type: "number" },
},
};
<Meta
title="Inputs/DatePicker"
component={DatePicker}
args={args}
argTypes={argTypes}
/>
# DatePicker
Our themed wrapper around [Mantine DatePicker](https://v6.mantine.dev/dates/date-picker/).
## Docs
- [Figma File](https://www.figma.com/file/cncRbkG7XJQs144EG9r9hM/Date-Picker?type=design&node-id=0-1&mode=design&t=v00tLhbD9OFEgy25-0)
- [Mantine DatePicker Docs](https://v6.mantine.dev/dates/date-picker/)
## Examples
export const DefaultTemplate = args => {
return <DatePicker {...args} />;
};
export const Default = DefaultTemplate.bind({});
Default.args = {
defaultDate: sampleArgs.date1,
};
<Canvas>
<Story name="Default">{Default}</Story>
</Canvas>
### Allow deselect
export const AllowDeselect = DefaultTemplate.bind({});
AllowDeselect.args = {
allowDeselect: true,
defaultDate: sampleArgs.date1,
defaultValue: sampleArgs.date1,
};
<Canvas>
<Story name="Allow deselect">{AllowDeselect}</Story>
</Canvas>
### Multiple dates
export const MultipleDates = DefaultTemplate.bind({});
MultipleDates.args = {
type: "multiple",
defaultValue: [sampleArgs.date1, sampleArgs.date2],
defaultDate: sampleArgs.date1,
};
<Canvas>
<Story name="Multiple dates">{MultipleDates}</Story>
</Canvas>
### Dates range
export const DatesRange = DefaultTemplate.bind({});
DatesRange.args = {
type: "range",
defaultValue: [sampleArgs.date1, sampleArgs.date2],
defaultDate: sampleArgs.date1,
};
<Canvas>
<Story name="Dates range">{DatesRange}</Story>
</Canvas>
### Single date in range
export const SingleDateInRange = DefaultTemplate.bind({});
SingleDateInRange.args = {
type: "range",
defaultValue: [sampleArgs.date1, sampleArgs.date1],
defaultDate: sampleArgs.date1,
allowSingleDateInRange: true,
};
<Canvas>
<Story name="Single date in range">{SingleDateInRange}</Story>
</Canvas>
### Number of columns
export const NumberOfColumns = DefaultTemplate.bind({});
NumberOfColumns.args = {
type: "range",
defaultValue: [sampleArgs.date1, sampleArgs.date3],
defaultDate: sampleArgs.date1,
numberOfColumns: 2,
};
<Canvas>
<Story name="Number of columns">{NumberOfColumns}</Story>
</Canvas>
import type { MantineThemeOverride } from "@mantine/core";
export const getDatePickerOverrides =
(): MantineThemeOverride["components"] => ({
DatePicker: {
defaultProps: {
size: "md",
},
},
});
export { DatePicker } from "@mantine/dates";
export type { DatePickerProps } from "@mantine/dates";
export { getDatePickerOverrides } from "./DatePicker.styled";
......@@ -203,7 +203,7 @@ RightSectionMd.args = {
#### Read only
export const ReadOnlyMd = RightSectionTemplate.bind({});
RightSectionMd.args = {
ReadOnlyMd.args = {
defaultValue: sampleArgs.value,
label: sampleArgs.label,
description: sampleArgs.description,
......
export * from "./Calendar";
export * from "./Checkbox";
export * from "./DateInput";
export * from "./DatePicker";
export * from "./FileInput";
export * from "./Input";
export * from "./NumberInput";
......
......@@ -5,8 +5,11 @@ import {
getAccordionOverrides,
getAnchorOverrides,
getButtonOverrides,
getCalendarOverrides,
getCardOverrides,
getCheckboxOverrides,
getDateInputOverrides,
getDatePickerOverrides,
getDividerOverrides,
getFileInputOverrides,
getInputOverrides,
......@@ -111,8 +114,11 @@ export const getThemeOverrides = (): MantineThemeOverride => ({
...getAccordionOverrides(),
...getAnchorOverrides(),
...getButtonOverrides(),
...getCalendarOverrides(),
...getCardOverrides(),
...getCheckboxOverrides(),
...getDateInputOverrides(),
...getDatePickerOverrides(),
...getDividerOverrides(),
...getFileInputOverrides(),
...getInputOverrides(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment