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

Mantine FileInput (#34117)

parent 927c4894
Branches
Tags
No related merge requests found
Showing
with 351 additions and 175 deletions
......@@ -198,9 +198,7 @@ DefaultDisabledGrid.args = {
};
<Canvas>
<Story name="Default size, disabled" args={DefaultDisabledGrid.args}>
{DefaultDisabledGrid}
</Story>
<Story name="Default size, disabled">{DefaultDisabledGrid}</Story>
</Canvas>
#### Loading state
......@@ -211,9 +209,7 @@ DefaultLoadingGrid.args = {
};
<Canvas>
<Story name="Default size, loading" args={DefaultLoadingGrid.args}>
{DefaultLoadingGrid}
</Story>
<Story name="Default size, loading">{DefaultLoadingGrid}</Story>
</Canvas>
### Default size & full width
......@@ -224,9 +220,7 @@ DefaultFullWidthGrid.args = {
};
<Canvas>
<Story name="Default size, full width" args={DefaultFullWidthGrid.args}>
{DefaultFullWidthGrid}
</Story>
<Story name="Default size, full width">{DefaultFullWidthGrid}</Story>
</Canvas>
#### Disabled state
......@@ -238,10 +232,7 @@ DefaultDisabledFullWidthGrid.args = {
};
<Canvas>
<Story
name="Default size, full width, disabled"
args={DefaultDisabledFullWidthGrid.args}
>
<Story name="Default size, full width, disabled">
{DefaultDisabledFullWidthGrid}
</Story>
</Canvas>
......@@ -255,10 +246,7 @@ DefaultLoadingFullWidthGrid.args = {
};
<Canvas>
<Story
name="Default size, full width, loading"
args={DefaultLoadingFullWidthGrid.args}
>
<Story name="Default size, full width, loading">
{DefaultLoadingFullWidthGrid}
</Story>
</Canvas>
......@@ -271,9 +259,7 @@ CompactGrid.args = {
};
<Canvas>
<Story name="Compact size" args={CompactGrid.args}>
{CompactGrid}
</Story>
<Story name="Compact size">{CompactGrid}</Story>
</Canvas>
#### Custom color
......@@ -297,9 +283,7 @@ CompactDisabledGrid.args = {
};
<Canvas>
<Story name="Compact size, disabled" args={CompactDisabledGrid.args}>
{CompactDisabledGrid}
</Story>
<Story name="Compact size, disabled">{CompactDisabledGrid}</Story>
</Canvas>
#### Loading state
......@@ -311,9 +295,7 @@ CompactLoadingGrid.args = {
};
<Canvas>
<Story name="Compact size, loading" args={CompactLoadingGrid.args}>
{CompactLoadingGrid}
</Story>
<Story name="Compact size, loading">{CompactLoadingGrid}</Story>
</Canvas>
### Compact size & full width
......@@ -325,9 +307,7 @@ CompactFullWidthGrid.args = {
};
<Canvas>
<Story name="Compact size, full width" args={CompactFullWidthGrid.args}>
{CompactFullWidthGrid}
</Story>
<Story name="Compact size, full width">{CompactFullWidthGrid}</Story>
</Canvas>
#### Disabled state
......@@ -340,10 +320,7 @@ CompactDisabledFullWidthGrid.args = {
};
<Canvas>
<Story
name="Compact size, full width, disabled"
args={CompactDisabledFullWidthGrid.args}
>
<Story name="Compact size, full width, disabled">
{CompactDisabledFullWidthGrid}
</Story>
</Canvas>
......@@ -358,10 +335,7 @@ CompactLoadingFullWidthGrid.args = {
};
<Canvas>
<Story
name="Compact size, full width, loading"
args={CompactLoadingFullWidthGrid.args}
>
<Story name="Compact size, full width, loading">
{CompactLoadingFullWidthGrid}
</Story>
</Canvas>
......@@ -127,9 +127,7 @@ LabelLeft.args = {
};
<Canvas>
<Story name="Label, left position" args={LabelLeft.args}>
{LabelLeft}
</Story>
<Story name="Label, left position">{LabelLeft}</Story>
</Canvas>
### Description
......@@ -148,9 +146,7 @@ DescriptionLeft.args = {
};
<Canvas>
<Story name="Description, left position" args={DescriptionLeft.args}>
{DescriptionLeft}
</Story>
<Story name="Description, left position">{DescriptionLeft}</Story>
</Canvas>
## Related components
......
import { Canvas, Story, Meta } from "@storybook/addon-docs";
import { Icon } from "metabase/core/components/Icon";
import { Stack, FileInput } 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 = {
label: "SSL Client Certificate (PEM)",
description: "A certificate to authenticate the instance to the server",
placeholder: "Select a file",
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" },
},
withAsterisk: {
control: { type: "boolean" },
},
};
<Meta
title="Inputs/FileInput"
component={FileInput}
args={args}
argTypes={argTypes}
/>
# FileInput
Our themed wrapper around [Mantine FileInput](https://mantine.dev/core/file-input/).
## Docs
- [Mantine FileInput Docs](https://mantine.dev/core/file-input/)
## Examples
export const DefaultTemplate = args => <FileInput {...args} />;
export const VariantTemplate = args => (
<Stack>
<FileInput {...args} variant="default" />
<FileInput {...args} variant="unstyled" />
</Stack>
);
export const IconTemplate = args => (
<VariantTemplate {...args} icon={<Icon name="attachment" />} />
);
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>
#### 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>
### Size - xs
export const EmptyXs = VariantTemplate.bind({});
EmptyXs.args = {
...EmptyMd.args,
size: "xs",
};
<Canvas>
<Story name="Empty, xs">{EmptyXs}</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>
import type { MantineThemeOverride } from "@mantine/core";
import { FileInputValue } from "./FileInputValue";
export const getFileInputOverrides =
(): MantineThemeOverride["components"] => ({
FileInput: {
defaultProps: {
size: "md",
valueComponent: FileInputValue,
},
styles: theme => ({
wrapper: {
marginTop: theme.spacing.xs,
},
}),
},
});
import styled from "@emotion/styled";
import { Text } from "@mantine/core";
import type { TextProps } from "@mantine/core";
export const FileInputText = styled(Text)<TextProps>`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
import { FileInputText } from "./FileInputValue.styled";
interface FileInputValueProps {
value: File | File[] | null;
}
export const FileInputValue = ({ value }: FileInputValueProps) => {
const text = Array.isArray(value)
? value.map(file => file.name).join(", ")
: value?.name;
return <FileInputText color="inherit">{text}</FileInputText>;
};
export { FileInput } from "@mantine/core";
export type { FileInputProps } from "@mantine/core";
export { getFileInputOverrides } from "./FileInput.styled";
......@@ -127,9 +127,7 @@ EmptyMd.args = {
};
<Canvas>
<Story name="Empty, md" args={EmptyMd.args}>
{EmptyMd}
</Story>
<Story name="Empty, md">{EmptyMd}</Story>
</Canvas>
#### Filled
......@@ -142,9 +140,7 @@ FilledMd.args = {
};
<Canvas>
<Story name="Filled, md" args={FilledMd.args}>
{FilledMd}
</Story>
<Story name="Filled, md">{FilledMd}</Story>
</Canvas>
#### Asterisk
......@@ -157,9 +153,7 @@ AsteriskMd.args = {
};
<Canvas>
<Story name="Asterisk, md" args={AsteriskMd.args}>
{AsteriskMd}
</Story>
<Story name="Asterisk, md">{AsteriskMd}</Story>
</Canvas>
#### Description
......@@ -172,9 +166,7 @@ DescriptionMd.args = {
};
<Canvas>
<Story name="Description, md" args={DescriptionMd.args}>
{DescriptionMd}
</Story>
<Story name="Description, md">{DescriptionMd}</Story>
</Canvas>
#### Disabled
......@@ -189,9 +181,7 @@ DisabledMd.args = {
};
<Canvas>
<Story name="Disabled, md" args={DisabledMd.args}>
{DisabledMd}
</Story>
<Story name="Disabled, md">{DisabledMd}</Story>
</Canvas>
#### Error
......@@ -206,9 +196,7 @@ ErrorMd.args = {
};
<Canvas>
<Story name="Error, md" args={ErrorMd.args}>
{ErrorMd}
</Story>
<Story name="Error, md">{ErrorMd}</Story>
</Canvas>
#### Icon
......@@ -222,9 +210,7 @@ IconMd.args = {
};
<Canvas>
<Story name="Icon, md" args={IconMd.args}>
{IconMd}
</Story>
<Story name="Icon, md">{IconMd}</Story>
</Canvas>
#### Read only
......@@ -239,9 +225,7 @@ ReadOnlyMd.args = {
};
<Canvas>
<Story name="Read only, md" args={ReadOnlyMd.args}>
{ReadOnlyMd}
</Story>
<Story name="Read only, md">{ReadOnlyMd}</Story>
</Canvas>
#### Min / max
......@@ -256,9 +240,7 @@ MinMaxMd.args = {
};
<Canvas>
<Story name="Min / max, md" args={MinMaxMd.args}>
{MinMaxMd}
</Story>
<Story name="Min / max, md">{MinMaxMd}</Story>
</Canvas>
#### Controls
......@@ -274,9 +256,7 @@ ControlsMd.args = {
};
<Canvas>
<Story name="Controls, md" args={ControlsMd.args}>
{ControlsMd}
</Story>
<Story name="Controls, md">{ControlsMd}</Story>
</Canvas>
#### Precision and decimal separator
......@@ -291,9 +271,7 @@ PrecisionMd.args = {
};
<Canvas>
<Story name="Precision and decimal separator, md" args={PrecisionMd.md}>
{PrecisionMd}
</Story>
<Story name="Precision and decimal separator, md">{PrecisionMd}</Story>
</Canvas>
#### Parser and formatter
......@@ -309,9 +287,7 @@ VariantTemplate.args = {
};
<Canvas>
<Story name="Parser and formatter, md" args={ParserFormatterMd.args}>
{ParserFormatterMd}
</Story>
<Story name="Parser and formatter, md">{ParserFormatterMd}</Story>
</Canvas>
### Size - xs
......@@ -323,9 +299,7 @@ EmptyXs.args = {
};
<Canvas>
<Story name="Empty, xs" args={EmptyXs.args}>
{EmptyXs}
</Story>
<Story name="Empty, xs">{EmptyXs}</Story>
</Canvas>
#### Filled
......@@ -337,9 +311,7 @@ FilledXs.args = {
};
<Canvas>
<Story name="Filled, xs" args={FilledXs.args}>
{FilledXs}
</Story>
<Story name="Filled, xs">{FilledXs}</Story>
</Canvas>
#### Asterisk
......@@ -351,9 +323,7 @@ AsteriskXs.args = {
};
<Canvas>
<Story name="Asterisk, xs" args={AsteriskXs.args}>
{AsteriskXs}
</Story>
<Story name="Asterisk, xs">{AsteriskXs}</Story>
</Canvas>
#### Description
......@@ -365,9 +335,7 @@ DescriptionXs.args = {
};
<Canvas>
<Story name="Description, xs" args={DescriptionXs.args}>
{DescriptionXs}
</Story>
<Story name="Description, xs">{DescriptionXs}</Story>
</Canvas>
#### Disabled
......@@ -379,9 +347,7 @@ DisabledXs.args = {
};
<Canvas>
<Story name="Disabled, xs" args={DisabledXs.args}>
{DisabledXs}
</Story>
<Story name="Disabled, xs">{DisabledXs}</Story>
</Canvas>
#### Error
......@@ -393,9 +359,7 @@ ErrorXs.args = {
};
<Canvas>
<Story name="Error, xs" args={ErrorXs.args}>
{ErrorXs}
</Story>
<Story name="Error, xs">{ErrorXs}</Story>
</Canvas>
#### Icon
......@@ -407,9 +371,7 @@ IconXs.args = {
};
<Canvas>
<Story name="Icon, xs" args={IconXs.args}>
{IconXs}
</Story>
<Story name="Icon, xs">{IconXs}</Story>
</Canvas>
#### Read only
......@@ -421,9 +383,7 @@ ReadOnlyXs.args = {
};
<Canvas>
<Story name="Read only, xs" args={ReadOnlyXs.args}>
{ReadOnlyXs}
</Story>
<Story name="Read only, xs">{ReadOnlyXs}</Story>
</Canvas>
#### Min / max
......@@ -435,9 +395,7 @@ MinMaxXs.args = {
};
<Canvas>
<Story name="Min / max, xs" args={MinMaxXs.args}>
{MinMaxXs}
</Story>
<Story name="Min / max, xs">{MinMaxXs}</Story>
</Canvas>
#### Controls
......@@ -449,9 +407,7 @@ ControlsXs.args = {
};
<Canvas>
<Story name="Controls, xs" args={ControlsXs.args}>
{ControlsXs}
</Story>
<Story name="Controls, xs">{ControlsXs}</Story>
</Canvas>
#### Precision and decimal separator
......@@ -463,9 +419,7 @@ PrecisionXs.args = {
};
<Canvas>
<Story name="Precision and decimal separator, xs" args={PrecisionXs.xs}>
{PrecisionXs}
</Story>
<Story name="Precision and decimal separator, xs">{PrecisionXs}</Story>
</Canvas>
#### Parser and formatter
......@@ -477,7 +431,5 @@ ParserFormatterXs.args = {
};
<Canvas>
<Story name="Parser and formatter, xs" args={ParserFormatterXs.args}>
{ParserFormatterXs}
</Story>
<Story name="Parser and formatter, xs">{ParserFormatterXs}</Story>
</Canvas>
......@@ -103,9 +103,7 @@ LabelLeft.args = {
};
<Canvas>
<Story name="Label, left position" args={LabelLeft.args}>
{LabelLeft}
</Story>
<Story name="Label, left position">{LabelLeft}</Story>
</Canvas>
### Description
......@@ -116,9 +114,7 @@ Description.args = {
};
<Canvas>
<Story name="Description" args={Description.args}>
{Description}
</Story>
<Story name="Description">{Description}</Story>
</Canvas>
export const DescriptionLeft = StateTemplate.bind({});
......@@ -130,9 +126,7 @@ DescriptionLeft.args = {
#### Left label position
<Canvas>
<Story name="Description, left position" args={DescriptionLeft.args}>
{DescriptionLeft}
</Story>
<Story name="Description, left position">{DescriptionLeft}</Story>
</Canvas>
## Related components
......
......@@ -113,9 +113,7 @@ FilledMd.args = {
};
<Canvas>
<Story name="Filled, md" args={FilledMd.args}>
{FilledMd}
</Story>
<Story name="Filled, md">{FilledMd}</Story>
</Canvas>
#### Asterisk
......@@ -128,9 +126,7 @@ AsteriskMd.args = {
};
<Canvas>
<Story name="Asterisk, md" args={AsteriskMd.args}>
{AsteriskMd}
</Story>
<Story name="Asterisk, md">{AsteriskMd}</Story>
</Canvas>
#### Description
......@@ -143,9 +139,7 @@ DescriptionMd.args = {
};
<Canvas>
<Story name="Description, md" args={DescriptionMd.args}>
{DescriptionMd}
</Story>
<Story name="Description, md">{DescriptionMd}</Story>
</Canvas>
#### Disabled
......@@ -160,9 +154,7 @@ DisabledMd.args = {
};
<Canvas>
<Story name="Disabled, md" args={DisabledMd.args}>
{DisabledMd}
</Story>
<Story name="Disabled, md">{DisabledMd}</Story>
</Canvas>
#### Error
......@@ -177,9 +169,7 @@ ErrorMd.args = {
};
<Canvas>
<Story name="Error, md" args={ErrorMd.args}>
{ErrorMd}
</Story>
<Story name="Error, md">{ErrorMd}</Story>
</Canvas>
#### Icon
......@@ -193,9 +183,7 @@ IconMd.args = {
};
<Canvas>
<Story name="Icon, md" args={IconMd.args}>
{IconMd}
</Story>
<Story name="Icon, md">{IconMd}</Story>
</Canvas>
#### Right section
......@@ -209,9 +197,7 @@ RightSectionMd.args = {
};
<Canvas>
<Story name="Right section, md" args={RightSectionMd.args}>
{RightSectionMd}
</Story>
<Story name="Right section, md">{RightSectionMd}</Story>
</Canvas>
#### Read only
......@@ -226,14 +212,16 @@ RightSectionMd.args = {
};
<Canvas>
<Story name="Read only, md" args={ReadOnlyMd.args}>
{ReadOnlyMd}
</Story>
<Story name="Read only, md">{ReadOnlyMd}</Story>
</Canvas>
### Size - xs
export const EmptyXs = VariantTemplate.bind({});
EmptyXs.args = {
...EmptyMd.args,
size: "xs",
};
<Canvas>
<Story name="Empty, xs">{EmptyXs}</Story>
......@@ -244,12 +232,11 @@ export const EmptyXs = VariantTemplate.bind({});
export const FilledXs = VariantTemplate.bind({});
FilledXs.args = {
...FilledMd.args,
size: "xs",
};
<Canvas>
<Story name="Filled, xs" args={FilledXs.args}>
{FilledXs}
</Story>
<Story name="Filled, xs">{FilledXs}</Story>
</Canvas>
#### Asterisk
......@@ -257,12 +244,11 @@ FilledXs.args = {
export const AsteriskXs = VariantTemplate.bind({});
AsteriskXs.args = {
...AsteriskMd.args,
size: "xs",
};
<Canvas>
<Story name="Asterisk, xs" args={AsteriskXs.args}>
{AsteriskXs}
</Story>
<Story name="Asterisk, xs">{AsteriskXs}</Story>
</Canvas>
#### Description
......@@ -270,12 +256,11 @@ AsteriskXs.args = {
export const DescriptionXs = VariantTemplate.bind({});
DescriptionXs.args = {
...DescriptionMd.args,
size: "xs",
};
<Canvas>
<Story name="Description, xs" args={DescriptionXs.args}>
{DescriptionXs}
</Story>
<Story name="Description, xs">{DescriptionXs}</Story>
</Canvas>
#### Disabled
......@@ -283,12 +268,11 @@ DescriptionXs.args = {
export const DisabledXs = VariantTemplate.bind({});
DisabledXs.args = {
...DisabledMd.args,
size: "xs",
};
<Canvas>
<Story name="Disabled, xs" args={DisabledXs.args}>
{DisabledXs}
</Story>
<Story name="Disabled, xs">{DisabledXs}</Story>
</Canvas>
#### Error
......@@ -296,12 +280,11 @@ DisabledXs.args = {
export const ErrorXs = VariantTemplate.bind({});
ErrorXs.args = {
...ErrorMd.args,
size: "xs",
};
<Canvas>
<Story name="Error, xs" args={ErrorXs.args}>
{ErrorXs}
</Story>
<Story name="Error, xs">{ErrorXs}</Story>
</Canvas>
#### Icon
......@@ -309,12 +292,11 @@ ErrorXs.args = {
export const IconXs = IconTemplate.bind({});
IconXs.args = {
...IconMd.args,
size: "xs",
};
<Canvas>
<Story name="Icon, xs" args={IconXs.args}>
{IconXs}
</Story>
<Story name="Icon, xs">{IconXs}</Story>
</Canvas>
#### Right section
......@@ -322,12 +304,11 @@ IconXs.args = {
export const RightSectionXs = RightSectionTemplate.bind({});
RightSectionXs.args = {
...RightSectionMd.args,
size: "xs",
};
<Canvas>
<Story name="Right section, xs" args={RightSectionXs.args}>
{RightSectionXs}
</Story>
<Story name="Right section, xs">{RightSectionXs}</Story>
</Canvas>
#### Read only
......@@ -335,10 +316,9 @@ RightSectionXs.args = {
export const ReadOnlyXs = RightSectionTemplate.bind({});
RightSectionXs.args = {
...ReadOnlyMd.args,
size: "xs",
};
<Canvas>
<Story name="Read only, xs" args={ReadOnlyXs.args}>
{ReadOnlyXs}
</Story>
<Story name="Read only, xs">{ReadOnlyXs}</Story>
</Canvas>
export * from "./Checkbox";
export * from "./FileInput";
export * from "./Input";
export * from "./NumberInput";
export * from "./Radio";
......
......@@ -92,7 +92,5 @@ Border.args = {
};
<Canvas>
<Story name="Border" args={Border.args}>
{Border}
</Story>
<Story name="Border">{Border}</Story>
</Canvas>
......@@ -7,6 +7,7 @@ import {
getButtonOverrides,
getCardOverrides,
getCheckboxOverrides,
getFileInputOverrides,
getInputOverrides,
getMenuOverrides,
getNumberInputOverrides,
......@@ -105,6 +106,7 @@ export const getThemeOverrides = (): MantineThemeOverride => ({
...getButtonOverrides(),
...getCardOverrides(),
...getCheckboxOverrides(),
...getFileInputOverrides(),
...getInputOverrides(),
...getMenuOverrides(),
...getNumberInputOverrides(),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment