✨(react) add generic Field component
This component will wrap most of form components in order to provide them a generic state attribute along with texts below them.
This commit is contained in:
5
.changeset/clean-ladybugs-visit.md
Normal file
5
.changeset/clean-ladybugs-visit.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@openfun/cunningham-react": minor
|
||||
---
|
||||
|
||||
Add Field component
|
||||
30
packages/react/src/components/Forms/Field/index.scss
Normal file
30
packages/react/src/components/Forms/Field/index.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
.c__field {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
width: var(--c--components--forms-field--width);
|
||||
color: var(--c--components--forms-field--color);
|
||||
box-sizing: border-box;
|
||||
|
||||
&__footer {
|
||||
font-size: var(--c--components--forms-field--font-size);
|
||||
padding: 0.25rem calc(1rem + 2px) 0 calc(1rem + 2px);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__text, &__text-right {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
&--error {
|
||||
color: var(--c--theme--colors--danger-500);
|
||||
}
|
||||
|
||||
&--success {
|
||||
color: var(--c--theme--colors--success-600)
|
||||
}
|
||||
|
||||
&--full-width {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
27
packages/react/src/components/Forms/Field/index.stories.mdx
Normal file
27
packages/react/src/components/Forms/Field/index.stories.mdx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Canvas, Meta, Story, Source, ArgsTable } from '@storybook/addon-docs';
|
||||
import { Field } from "./index";
|
||||
|
||||
<Meta title="Components/Forms/Field/Doc" component={Field}/>
|
||||
|
||||
export const Template = (args) => <Field {...args} />;
|
||||
|
||||
# Field
|
||||
|
||||
The Field component is used to wrap a form input. As a design system consumer you are
|
||||
not supposed to directly use it, unless you need to create custom inputs.
|
||||
|
||||
**But, as most of Cunningham's components are wrapped inside this component, you may need to customize**
|
||||
the default width, the generics texts below inputs for example. This documentation is here to show you the
|
||||
available design token to do so.
|
||||
|
||||
## Design tokens
|
||||
|
||||
| Token | Description |
|
||||
|--------------- |----------------------------- |
|
||||
| width | Default width of inputs ( default is 292px ) |
|
||||
| font-size | Font size of texts below inputs |
|
||||
| color | Font color of texts below inputs |
|
||||
|
||||
## Props
|
||||
|
||||
<ArgsTable of={Field} />
|
||||
34
packages/react/src/components/Forms/Field/index.stories.tsx
Normal file
34
packages/react/src/components/Forms/Field/index.stories.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { ComponentMeta, ComponentStory } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { Field } from "components/Forms/Field/index";
|
||||
|
||||
export default {
|
||||
title: "Components/Forms/Field",
|
||||
component: Field,
|
||||
} as ComponentMeta<typeof Field>;
|
||||
|
||||
const Template: ComponentStory<typeof Field> = (args) => (
|
||||
<Field {...args}>
|
||||
<strong>Any children</strong>
|
||||
</Field>
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
text: "This is an optional text",
|
||||
rightText: "Right text",
|
||||
};
|
||||
|
||||
export const Success = Template.bind({});
|
||||
Success.args = {
|
||||
state: "success",
|
||||
text: "This is an optional success message",
|
||||
rightText: "Right text",
|
||||
};
|
||||
|
||||
export const Error = Template.bind({});
|
||||
Error.args = {
|
||||
state: "error",
|
||||
text: "This is an optional error message",
|
||||
rightText: "Right text",
|
||||
};
|
||||
37
packages/react/src/components/Forms/Field/index.tsx
Normal file
37
packages/react/src/components/Forms/Field/index.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import React, { PropsWithChildren } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
export type FieldState = "success" | "error" | "default";
|
||||
|
||||
export type FieldProps = {
|
||||
state?: FieldState | undefined;
|
||||
text?: string | undefined;
|
||||
rightText?: string | undefined;
|
||||
fullWidth?: boolean | undefined;
|
||||
};
|
||||
|
||||
type Props = FieldProps & PropsWithChildren;
|
||||
|
||||
export const Field = ({
|
||||
children,
|
||||
state = "default",
|
||||
text,
|
||||
rightText,
|
||||
fullWidth,
|
||||
}: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames("c__field", "c__field--" + state, {
|
||||
"c__field--full-width": fullWidth,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
{(text || rightText) && (
|
||||
<div className="c__field__footer">
|
||||
<span className="c__field__text">{text}</span>
|
||||
<span className="c__field__text__right">{rightText}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
7
packages/react/src/components/Forms/Field/tokens.ts
Normal file
7
packages/react/src/components/Forms/Field/tokens.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { DefaultTokens } from "@openfun/cunningham-tokens";
|
||||
|
||||
export const tokens = (defaults: DefaultTokens) => ({
|
||||
width: "292px",
|
||||
"font-size": defaults.theme.font.sizes.s,
|
||||
color: defaults.theme.colors["greyscale-600"],
|
||||
});
|
||||
@@ -3,6 +3,7 @@
|
||||
@import './components/Accessibility';
|
||||
@import './components/Button';
|
||||
@import './components/DataGrid';
|
||||
@import './components/Forms/Field';
|
||||
@import './components/Forms/Input';
|
||||
@import './components/Loader';
|
||||
@import './components/Pagination';
|
||||
|
||||
@@ -3,6 +3,7 @@ import "./index.scss";
|
||||
export * from "./components/Button";
|
||||
export * from "./components/DataGrid";
|
||||
export * from "./components/DataGrid/SimpleDataGrid";
|
||||
export * from "./components/Forms/Field";
|
||||
export * from "./components/Loader";
|
||||
export * from "./components/Pagination";
|
||||
export * from "./components/Provider";
|
||||
|
||||
Reference in New Issue
Block a user