✨(react) add Switch component
Implement a shiny new component that can be used as an alternative to the regular checkbox.
This commit is contained in:
5
.changeset/three-days-fold.md
Normal file
5
.changeset/three-days-fold.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@openfun/cunningham-react": minor
|
||||
---
|
||||
|
||||
add Switch component
|
||||
137
packages/react/src/components/Forms/Switch/index.mdx
Normal file
137
packages/react/src/components/Forms/Switch/index.mdx
Normal file
@@ -0,0 +1,137 @@
|
||||
import { Canvas, Story, Meta, ArgsTable, Source } from '@storybook/addon-docs';
|
||||
import { Switch } from './index';
|
||||
import * as Stories from './index.stories';
|
||||
|
||||
<Meta of={Stories}/>
|
||||
|
||||
# Switch
|
||||
|
||||
Cunningham provides a Switch component that can be used in a variety of ways.
|
||||
|
||||
> To better understand the Switch component, keep in mind that it is kind of a wrapper around the native HTML checkbox element.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-forms-switch--form-example"/>
|
||||
</Canvas>
|
||||
|
||||
|
||||
## Label
|
||||
|
||||
The `label` props is optional, but you can use it to provide a description of the switch.
|
||||
|
||||
**Without label**
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--default"/>
|
||||
</Canvas>
|
||||
|
||||
**With label**
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--with-label"/>
|
||||
</Canvas>
|
||||
|
||||
## Label Side
|
||||
|
||||
You can decide where to place the label by using the `labelSide` prop.
|
||||
|
||||
> By default the label is placed on the left.
|
||||
|
||||
**Label on the left (default)**
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--with-label"/>
|
||||
</Canvas>
|
||||
|
||||
**Label on the right**
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--with-label-right"/>
|
||||
</Canvas>
|
||||
|
||||
## Disabled
|
||||
|
||||
You can disable the switch by using the `disabled` prop.
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--disabled"/>
|
||||
<Story id="components-forms-switch--disabled-checked"/>
|
||||
</Canvas>
|
||||
|
||||
## States
|
||||
|
||||
You can use the following props to change the state of the component by using the `state` props.
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--with-text"/>
|
||||
</Canvas>
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--success"/>
|
||||
</Canvas>
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--error"/>
|
||||
</Canvas>
|
||||
|
||||
## Width
|
||||
|
||||
By default, the Switch will automatically take the minimum needed width. But you can force it to take the full width of
|
||||
its container by using the `fullWidth` prop.
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--full-width"/>
|
||||
</Canvas>
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--with-label-right-and-full-width"/>
|
||||
</Canvas>
|
||||
|
||||
## Controlled / Non Controlled
|
||||
|
||||
In order to control the value of the switch, you can use the `checked` or `defaultChecked` props, as the native HTML checkbox element. You can't use both at the same time.
|
||||
|
||||
> If you use the `checked` prop, you will need to handle the `onChange` event to update the value of the switch.
|
||||
|
||||
> If you use the `defaultChecked` prop, the switch will be uncontrolled.
|
||||
|
||||
<Canvas sourceState="shown">
|
||||
<Story id="components-forms-switch--controlled"/>
|
||||
</Canvas>
|
||||
|
||||
## Props
|
||||
|
||||
The props of this component are as close as possible to the native checkbox component. You can see the list of props below.
|
||||
|
||||
<ArgsTable of={Switch} />
|
||||
|
||||
## Design tokens
|
||||
|
||||
Here are available custom design tokens.
|
||||
|
||||
| Token | Description |
|
||||
|--------------- |----------------------------- |
|
||||
| accent-color | Color of the background |
|
||||
| rail-background-color | Color of the switch rail background |
|
||||
| rail-background-color--disabled | Color of the switch rail background when disabled |
|
||||
| rail-border-radius | Border radius of the switch rail |
|
||||
| handle-background-color | Background color of the switch handle |
|
||||
| handle-background-color--disabled | Background color of the switch handle when disabled |
|
||||
| handle-border-radius | Border radius of the switch handle when disabled |
|
||||
|
||||
The design tokens `font-size`, `font-weight`, `color`, `width`, `height` are shared with [Checkbox](?path=/story/components-forms-checkbox-doc--page)
|
||||
|
||||
See also [Field](?path=/story/components-forms-field-doc--page)
|
||||
|
||||
|
||||
##
|
||||
|
||||
<img src="components/Forms/Switch/resources/dd_1.svg"/>
|
||||
|
||||
##
|
||||
|
||||
<img src="components/Forms/Switch/resources/dd_2.svg"/>
|
||||
|
||||
##
|
||||
|
||||
<img src="components/Forms/Switch/resources/dd_3.svg"/>
|
||||
89
packages/react/src/components/Forms/Switch/index.scss
Normal file
89
packages/react/src/components/Forms/Switch/index.scss
Normal file
@@ -0,0 +1,89 @@
|
||||
.c__switch {
|
||||
|
||||
input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0;
|
||||
// This is made to prevent a bug on Chromium were was the labelSide is set to right then it
|
||||
// creates an artificial margin between successive switches.
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.c__checkbox__container {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
input:checked + &__rail {
|
||||
background-color: var(--c--components--forms-switch--accent-color);
|
||||
}
|
||||
|
||||
input:checked + &__rail:before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
&__rail__wrapper {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
&__rail {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
width: 2.8125rem;
|
||||
height: 1.5rem;
|
||||
background-color: var(--c--components--forms-switch--rail-background-color);
|
||||
transition: var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
|
||||
border-radius: var(--c--components--forms-switch--rail-border-radius);
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 1.125rem;
|
||||
width: 1.125rem;
|
||||
left: 4px;
|
||||
top: 3px;
|
||||
background-color: var(--c--components--forms-switch--handle-background-color);
|
||||
transition: var(--c--theme--transitions--duration) var(--c--theme--transitions--ease-out);
|
||||
border-radius: var(--c--components--forms-switch--handle-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.c__field__footer {
|
||||
padding: 0.25rem 0 0 0;
|
||||
}
|
||||
|
||||
&.c__checkbox--disabled {
|
||||
|
||||
input:not(:checked) + .c__switch__rail {
|
||||
background-color: var(--c--components--forms-switch--rail-background-color--disabled);
|
||||
}
|
||||
|
||||
.c__switch__rail {
|
||||
cursor: default;
|
||||
|
||||
&:before {
|
||||
background-color: var(--c--components--forms-switch--handle-background-color--disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--right {
|
||||
.c__checkbox__container {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.c__field__footer {
|
||||
padding: 0.25rem 0 0 3.3rem;
|
||||
}
|
||||
|
||||
&.c__switch--full-width {
|
||||
.c__field__footer {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--full-width {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
135
packages/react/src/components/Forms/Switch/index.spec.tsx
Normal file
135
packages/react/src/components/Forms/Switch/index.spec.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { Switch } from ":/components/Forms/Switch/index";
|
||||
|
||||
describe("<Switch/>", () => {
|
||||
it("renders and can be checked", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<Switch label="Newsletter" />);
|
||||
const input: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Newsletter",
|
||||
});
|
||||
expect(input.checked).toEqual(false);
|
||||
await user.click(input);
|
||||
expect(input.checked).toEqual(true);
|
||||
});
|
||||
|
||||
it("renders with default value and can be unchecked", async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<Switch label="Newsletter" defaultChecked={true} />);
|
||||
const input: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Newsletter",
|
||||
});
|
||||
expect(input.checked).toEqual(true);
|
||||
await user.click(input);
|
||||
expect(input.checked).toEqual(false);
|
||||
});
|
||||
|
||||
it("renders disabled", async () => {
|
||||
render(<Switch label="Newsletter" disabled={true} />);
|
||||
expect(screen.getByRole("checkbox", { name: "Newsletter" })).toBeDisabled();
|
||||
// Click and expect the checkbox does not get checked
|
||||
const user = userEvent.setup();
|
||||
const input: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Newsletter",
|
||||
});
|
||||
expect(input.checked).toEqual(false);
|
||||
await user.click(input);
|
||||
expect(input.checked).toEqual(false);
|
||||
});
|
||||
|
||||
it("renders with text", async () => {
|
||||
render(<Switch label="Newsletter" text="Text" />);
|
||||
screen.getByText("Text");
|
||||
});
|
||||
|
||||
it("renders with state=success", async () => {
|
||||
render(<Switch label="Newsletter" state="success" text="Success text" />);
|
||||
screen.getByText("Success text");
|
||||
expect(
|
||||
document.querySelector(".c__field.c__field--success")
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders with state=error", async () => {
|
||||
render(<Switch label="Newsletter" state="error" text="Error text" />);
|
||||
screen.getByText("Error text");
|
||||
expect(
|
||||
document.querySelector(".c__field.c__field--error")
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders multiple", async () => {
|
||||
// make sure switching one does not switch the others.
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<div>
|
||||
<Switch label="Newsletter" />
|
||||
<Switch label="Notifications" />
|
||||
<Switch label="Phone" />
|
||||
</div>
|
||||
);
|
||||
// expect all checkboxes to be unchecked
|
||||
const newsletter: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Newsletter",
|
||||
});
|
||||
const notifications: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Notifications",
|
||||
});
|
||||
const phone: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Phone",
|
||||
});
|
||||
expect(newsletter.checked).toEqual(false);
|
||||
expect(notifications.checked).toEqual(false);
|
||||
expect(phone.checked).toEqual(false);
|
||||
|
||||
// Turn on only one checkbox.
|
||||
await user.click(newsletter);
|
||||
expect(newsletter.checked).toEqual(true);
|
||||
expect(notifications.checked).toEqual(false);
|
||||
expect(phone.checked).toEqual(false);
|
||||
|
||||
// Turn off only one checkbox.
|
||||
await user.click(newsletter);
|
||||
expect(newsletter.checked).toEqual(false);
|
||||
expect(notifications.checked).toEqual(false);
|
||||
expect(phone.checked).toEqual(false);
|
||||
});
|
||||
|
||||
it("renders with label right", async () => {
|
||||
render(<Switch label="Newsletter" labelSide="right" />);
|
||||
const input: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Newsletter",
|
||||
});
|
||||
expect(input.closest(".c__switch")).toHaveClass("c__switch--right");
|
||||
});
|
||||
|
||||
it("renders controlled", async () => {
|
||||
const Wrapper = () => {
|
||||
const [checked, setChecked] = React.useState(false);
|
||||
return (
|
||||
<div>
|
||||
<div>Value: {JSON.stringify(checked)}.</div>
|
||||
<Switch
|
||||
label="Newsletter"
|
||||
checked={checked}
|
||||
onChange={(e) => setChecked(e.target.checked)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
render(<Wrapper />);
|
||||
const input: HTMLInputElement = screen.getByRole("checkbox", {
|
||||
name: "Newsletter",
|
||||
});
|
||||
expect(input.checked).toEqual(false);
|
||||
screen.queryByText("Value: false.");
|
||||
await userEvent.click(input);
|
||||
expect(input.checked).toEqual(true);
|
||||
screen.queryByText("Value: true.");
|
||||
await userEvent.click(input);
|
||||
expect(input.checked).toEqual(false);
|
||||
screen.queryByText("Value: false.");
|
||||
});
|
||||
});
|
||||
191
packages/react/src/components/Forms/Switch/index.stories.tsx
Normal file
191
packages/react/src/components/Forms/Switch/index.stories.tsx
Normal file
@@ -0,0 +1,191 @@
|
||||
import { Meta } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { Switch } from ":/components/Forms/Switch/index";
|
||||
import { Button } from ":/components/Button";
|
||||
|
||||
export default {
|
||||
title: "Components/Forms/Switch",
|
||||
component: Switch,
|
||||
} as Meta<typeof Switch>;
|
||||
|
||||
export const Default = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const Checked = {
|
||||
args: {
|
||||
checked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLabel = {
|
||||
args: {
|
||||
label: "Label",
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLabelChecked = {
|
||||
args: {
|
||||
label: "Label",
|
||||
checked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithText = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
checked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const FullWidth = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
fullWidth: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLabelRight = {
|
||||
args: {
|
||||
label: "Label",
|
||||
labelSide: "right",
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLabelRightAndText = {
|
||||
args: {
|
||||
label: "Label",
|
||||
labelSide: "right",
|
||||
text: "This is an optional text",
|
||||
},
|
||||
};
|
||||
|
||||
export const WithLabelRightAndFullWidth = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
fullWidth: true,
|
||||
labelSide: "right",
|
||||
},
|
||||
};
|
||||
|
||||
export const Disabled = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
disabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const DisabledChecked = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
disabled: true,
|
||||
defaultChecked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Error = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
state: "error",
|
||||
defaultChecked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Success = {
|
||||
args: {
|
||||
label: "Label",
|
||||
text: "This is an optional text",
|
||||
state: "success",
|
||||
defaultChecked: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const Controlled = {
|
||||
render: () => {
|
||||
const [checked, setChecked] = React.useState(false);
|
||||
return (
|
||||
<div>
|
||||
<div>Value: {JSON.stringify(checked)}</div>
|
||||
<Switch
|
||||
checked={checked}
|
||||
onChange={(e) => setChecked(e.target.checked)}
|
||||
/>
|
||||
<Button onClick={() => setChecked(!checked)}>Toggle</Button>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const FormExample = {
|
||||
render: () => {
|
||||
return (
|
||||
<form>
|
||||
<div style={{ width: "300px" }}>
|
||||
<Switch
|
||||
label="Energy efficiency"
|
||||
fullWidth={true}
|
||||
text="Increases power by 15%"
|
||||
/>
|
||||
<Switch
|
||||
label="Battery percentage"
|
||||
fullWidth={true}
|
||||
defaultChecked={true}
|
||||
/>
|
||||
<Switch label="Wi-Fi" fullWidth={true} defaultChecked={true} />
|
||||
<Switch label="Bluetooth" fullWidth={true} />
|
||||
<Switch
|
||||
label="VPN"
|
||||
fullWidth={true}
|
||||
text="You must pay for this feature"
|
||||
state="error"
|
||||
disabled={true}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const FormExampleRight = {
|
||||
render: () => {
|
||||
return (
|
||||
<form>
|
||||
<div style={{ width: "300px" }}>
|
||||
<Switch
|
||||
label="Energy efficiency"
|
||||
fullWidth={true}
|
||||
labelSide="right"
|
||||
text="Increases power by 15%"
|
||||
/>
|
||||
<Switch
|
||||
label="Battery percentage"
|
||||
fullWidth={true}
|
||||
defaultChecked={true}
|
||||
labelSide="right"
|
||||
/>
|
||||
<Switch
|
||||
label="Wi-Fi"
|
||||
fullWidth={true}
|
||||
defaultChecked={true}
|
||||
labelSide="right"
|
||||
/>
|
||||
<Switch label="Bluetooth" fullWidth={true} labelSide="right" />
|
||||
<Switch
|
||||
label="VPN"
|
||||
fullWidth={true}
|
||||
labelSide="right"
|
||||
text="You must pay for this feature"
|
||||
state="error"
|
||||
disabled={true}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
},
|
||||
};
|
||||
43
packages/react/src/components/Forms/Switch/index.tsx
Normal file
43
packages/react/src/components/Forms/Switch/index.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React, { InputHTMLAttributes } from "react";
|
||||
import classNames from "classnames";
|
||||
import { Field, FieldProps } from ":/components/Forms/Field";
|
||||
|
||||
type Props = InputHTMLAttributes<HTMLInputElement> &
|
||||
FieldProps & {
|
||||
label?: string;
|
||||
labelSide?: "left" | "right";
|
||||
};
|
||||
|
||||
export const Switch = ({
|
||||
label,
|
||||
text,
|
||||
state,
|
||||
fullWidth,
|
||||
labelSide = "left",
|
||||
|
||||
...props
|
||||
}: Props) => {
|
||||
return (
|
||||
<label
|
||||
className={classNames(
|
||||
"c__checkbox",
|
||||
"c__switch",
|
||||
"c__switch--" + labelSide,
|
||||
{
|
||||
"c__checkbox--disabled": props.disabled,
|
||||
"c__switch--full-width": fullWidth,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Field text={text} compact={true} state={state} fullWidth={fullWidth}>
|
||||
<div className="c__checkbox__container">
|
||||
{label && <div className="c__checkbox__label">{label}</div>}
|
||||
<div className="c__switch__rail__wrapper">
|
||||
<input type="checkbox" {...props} />
|
||||
<div className="c__switch__rail" />
|
||||
</div>
|
||||
</div>
|
||||
</Field>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 185 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 191 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 268 KiB |
11
packages/react/src/components/Forms/Switch/tokens.ts
Normal file
11
packages/react/src/components/Forms/Switch/tokens.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DefaultTokens } from "@openfun/cunningham-tokens";
|
||||
|
||||
export const tokens = (defaults: DefaultTokens) => ({
|
||||
"accent-color": defaults.theme.colors["success-700"],
|
||||
"rail-background-color": defaults.theme.colors["greyscale-500"],
|
||||
"rail-background-color--disabled": defaults.theme.colors["greyscale-400"],
|
||||
"rail-border-radius": "50vw",
|
||||
"handle-background-color": "white",
|
||||
"handle-background-color--disabled": defaults.theme.colors["greyscale-200"],
|
||||
"handle-border-radius": "50%",
|
||||
});
|
||||
@@ -96,6 +96,13 @@
|
||||
--c--theme--transitions--ease-out: cubic-bezier(0.33, 1, 0.68, 1);
|
||||
--c--theme--transitions--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
||||
--c--theme--transitions--duration: 250ms;
|
||||
--c--components--forms-switch--accent-color: #419A14;
|
||||
--c--components--forms-switch--rail-background-color: #9EA3AA;
|
||||
--c--components--forms-switch--rail-background-color--disabled: #C2C6CA;
|
||||
--c--components--forms-switch--rail-border-radius: 50vw;
|
||||
--c--components--forms-switch--handle-background-color: white;
|
||||
--c--components--forms-switch--handle-background-color--disabled: #F3F4F4;
|
||||
--c--components--forms-switch--handle-border-radius: 50%;
|
||||
--c--components--forms-select--border-color: #E7E8EA;
|
||||
--c--components--forms-select--border-color--focus: #0556BF;
|
||||
--c--components--forms-select--border-color--hover: #9EA3AA;
|
||||
@@ -131,7 +138,7 @@
|
||||
--c--components--forms-field--color: #79818A;
|
||||
--c--components--forms-checkbox--background-color--hover: #F3F4F4;
|
||||
--c--components--forms-checkbox--font-size: 0.8125rem;
|
||||
--c--components--forms-checkbox--font-weight: 400;
|
||||
--c--components--forms-checkbox--font-weight: 500;
|
||||
--c--components--forms-checkbox--color: #0C1A2B;
|
||||
--c--components--forms-checkbox--border-color: #E7E8EA;
|
||||
--c--components--forms-checkbox--border-radius: 2px;
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const tokens = {"theme":{"colors":{"primary-text":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","greyscale-000":"#FFFFFF","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","success-text":"#FFFFFF","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","warning-text":"#FFFFFF","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-text":"#FFFFFF","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":100,"regular":300,"medium":400,"bold":500,"extrabold":700,"black":900},"families":{"base":"Roboto","accent":"Roboto"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"}},"components":{"forms-select":{"border-color":"#E7E8EA","border-color--focus":"#0556BF","border-color--hover":"#9EA3AA","border-radius":"8px","border-radius--focus":"2px","border-radius--hover":"2px","border-style":"solid","border-width":"2px","color":"#303C4B","font-size":"1rem","height":"3.5rem","item-background-color--hover":"#F3F4F4","item-background-color--selected":"#EBF2FC","item-color":"#303C4B","item-font-size":"1rem","background-color":"white","menu-background-color":"white"},"forms-radio":{"border-color":"#E7E8EA","accent-color":"#419A14"},"forms-input":{"font-weight":400,"font-size":"1rem","border-radius":"8px","border-radius--hover":"2px","border-radius--focus":"2px","border-width":"2px","border-color":"#E7E8EA","border-color--hover":"#9EA3AA","border-color--focus":"#0556BF","border-style":"solid","color":"#303C4B"},"forms-field":{"width":"292px","font-size":"0.6875rem","color":"#79818A"},"forms-checkbox":{"background-color--hover":"#F3F4F4","font-size":"0.8125rem","font-weight":400,"color":"#0C1A2B","border-color":"#E7E8EA","border-radius":"2px","accent-color":"#419A14","size":"1.5rem"},"button":{"border-radius":"8px","border-radius--active":"2px","medium-height":"48px","small-height":"32px","medium-font-size":"1rem","small-font-size":"0.8125rem","font-weight":400}}};
|
||||
export const tokens = {"theme":{"colors":{"primary-text":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","greyscale-000":"#FFFFFF","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","success-text":"#FFFFFF","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","warning-text":"#FFFFFF","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-text":"#FFFFFF","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":100,"regular":300,"medium":400,"bold":500,"extrabold":700,"black":900},"families":{"base":"Roboto","accent":"Roboto"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"}},"components":{"forms-switch":{"accent-color":"#419A14","rail-background-color":"#9EA3AA","rail-background-color--disabled":"#C2C6CA","rail-border-radius":"50vw","handle-background-color":"white","handle-background-color--disabled":"#F3F4F4","handle-border-radius":"50%"},"forms-select":{"border-color":"#E7E8EA","border-color--focus":"#0556BF","border-color--hover":"#9EA3AA","border-radius":"8px","border-radius--focus":"2px","border-radius--hover":"2px","border-style":"solid","border-width":"2px","color":"#303C4B","font-size":"1rem","height":"3.5rem","item-background-color--hover":"#F3F4F4","item-background-color--selected":"#EBF2FC","item-color":"#303C4B","item-font-size":"1rem","background-color":"white","menu-background-color":"white"},"forms-radio":{"border-color":"#E7E8EA","accent-color":"#419A14"},"forms-input":{"font-weight":400,"font-size":"1rem","border-radius":"8px","border-radius--hover":"2px","border-radius--focus":"2px","border-width":"2px","border-color":"#E7E8EA","border-color--hover":"#9EA3AA","border-color--focus":"#0556BF","border-style":"solid","color":"#303C4B"},"forms-field":{"width":"292px","font-size":"0.6875rem","color":"#79818A"},"forms-checkbox":{"background-color--hover":"#F3F4F4","font-size":"0.8125rem","font-weight":500,"color":"#0C1A2B","border-color":"#E7E8EA","border-radius":"2px","accent-color":"#419A14","size":"1.5rem"},"button":{"border-radius":"8px","border-radius--active":"2px","medium-height":"48px","small-height":"32px","medium-font-size":"1rem","small-font-size":"0.8125rem","font-weight":400}}};
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const tokens = {"theme":{"colors":{"primary-text":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","greyscale-000":"#FFFFFF","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","success-text":"#FFFFFF","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","warning-text":"#FFFFFF","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-text":"#FFFFFF","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":100,"regular":300,"medium":400,"bold":500,"extrabold":700,"black":900},"families":{"base":"Roboto","accent":"Roboto"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"}},"components":{"forms-select":{"border-color":"#E7E8EA","border-color--focus":"#0556BF","border-color--hover":"#9EA3AA","border-radius":"8px","border-radius--focus":"2px","border-radius--hover":"2px","border-style":"solid","border-width":"2px","color":"#303C4B","font-size":"1rem","height":"3.5rem","item-background-color--hover":"#F3F4F4","item-background-color--selected":"#EBF2FC","item-color":"#303C4B","item-font-size":"1rem","background-color":"white","menu-background-color":"white"},"forms-radio":{"border-color":"#E7E8EA","accent-color":"#419A14"},"forms-input":{"font-weight":400,"font-size":"1rem","border-radius":"8px","border-radius--hover":"2px","border-radius--focus":"2px","border-width":"2px","border-color":"#E7E8EA","border-color--hover":"#9EA3AA","border-color--focus":"#0556BF","border-style":"solid","color":"#303C4B"},"forms-field":{"width":"292px","font-size":"0.6875rem","color":"#79818A"},"forms-checkbox":{"background-color--hover":"#F3F4F4","font-size":"0.8125rem","font-weight":400,"color":"#0C1A2B","border-color":"#E7E8EA","border-radius":"2px","accent-color":"#419A14","size":"1.5rem"},"button":{"border-radius":"8px","border-radius--active":"2px","medium-height":"48px","small-height":"32px","medium-font-size":"1rem","small-font-size":"0.8125rem","font-weight":400}}};
|
||||
export const tokens = {"theme":{"colors":{"primary-text":"#FFFFFF","primary-100":"#EBF2FC","primary-200":"#8CB5EA","primary-300":"#5894E1","primary-400":"#377FDB","primary-500":"#055FD2","primary-600":"#0556BF","primary-700":"#044395","primary-800":"#033474","primary-900":"#022858","secondary-text":"#555F6B","secondary-100":"#F2F7FC","secondary-200":"#EBF3FA","secondary-300":"#E2EEF8","secondary-400":"#DDEAF7","secondary-500":"#D4E5F5","secondary-600":"#C1D0DF","secondary-700":"#97A3AE","secondary-800":"#757E87","secondary-900":"#596067","greyscale-000":"#FFFFFF","greyscale-100":"#FAFAFB","greyscale-200":"#F3F4F4","greyscale-300":"#E7E8EA","greyscale-400":"#C2C6CA","greyscale-500":"#9EA3AA","greyscale-600":"#79818A","greyscale-700":"#555F6B","greyscale-800":"#303C4B","greyscale-900":"#0C1A2B","success-text":"#FFFFFF","success-100":"#EFFCD3","success-200":"#DBFAA9","success-300":"#BEF27C","success-400":"#A0E659","success-500":"#76D628","success-600":"#5AB81D","success-700":"#419A14","success-800":"#2C7C0C","success-900":"#1D6607","info-text":"#FFFFFF","info-100":"#EBF2FC","info-200":"#8CB5EA","info-300":"#5894E1","info-400":"#377FDB","info-500":"#055FD2","info-600":"#0556BF","info-700":"#044395","info-800":"#033474","info-900":"#022858","warning-text":"#FFFFFF","warning-100":"#FFF8CD","warning-200":"#FFEF9B","warning-300":"#FFE469","warning-400":"#FFDA43","warning-500":"#FFC805","warning-600":"#DBA603","warning-700":"#B78702","warning-800":"#936901","warning-900":"#7A5400","danger-text":"#FFFFFF","danger-100":"#F4B0B0","danger-200":"#EE8A8A","danger-300":"#E65454","danger-400":"#E13333","danger-500":"#DA0000","danger-600":"#C60000","danger-700":"#9B0000","danger-800":"#780000","danger-900":"#5C0000"},"font":{"sizes":{"h1":"1.75rem","h2":"1.375rem","h3":"1.125rem","h4":"0.8125rem","h5":"0.625rem","h6":"0.5rem","l":"1rem","m":"0.8125rem","s":"0.6875rem"},"weights":{"thin":100,"regular":300,"medium":400,"bold":500,"extrabold":700,"black":900},"families":{"base":"Roboto","accent":"Roboto"}},"spacings":{"xl":"4rem","l":"3rem","b":"1.625rem","s":"1rem","t":"0.5rem","st":"0.25rem"},"transitions":{"ease-in":"cubic-bezier(0.32, 0, 0.67, 0)","ease-out":"cubic-bezier(0.33, 1, 0.68, 1)","ease-in-out":"cubic-bezier(0.65, 0, 0.35, 1)","duration":"250ms"}},"components":{"forms-switch":{"accent-color":"#419A14","rail-background-color":"#9EA3AA","rail-background-color--disabled":"#C2C6CA","rail-border-radius":"50vw","handle-background-color":"white","handle-background-color--disabled":"#F3F4F4","handle-border-radius":"50%"},"forms-select":{"border-color":"#E7E8EA","border-color--focus":"#0556BF","border-color--hover":"#9EA3AA","border-radius":"8px","border-radius--focus":"2px","border-radius--hover":"2px","border-style":"solid","border-width":"2px","color":"#303C4B","font-size":"1rem","height":"3.5rem","item-background-color--hover":"#F3F4F4","item-background-color--selected":"#EBF2FC","item-color":"#303C4B","item-font-size":"1rem","background-color":"white","menu-background-color":"white"},"forms-radio":{"border-color":"#E7E8EA","accent-color":"#419A14"},"forms-input":{"font-weight":400,"font-size":"1rem","border-radius":"8px","border-radius--hover":"2px","border-radius--focus":"2px","border-width":"2px","border-color":"#E7E8EA","border-color--hover":"#9EA3AA","border-color--focus":"#0556BF","border-style":"solid","color":"#303C4B"},"forms-field":{"width":"292px","font-size":"0.6875rem","color":"#79818A"},"forms-checkbox":{"background-color--hover":"#F3F4F4","font-size":"0.8125rem","font-weight":500,"color":"#0C1A2B","border-color":"#E7E8EA","border-radius":"2px","accent-color":"#419A14","size":"1.5rem"},"button":{"border-radius":"8px","border-radius--active":"2px","medium-height":"48px","small-height":"32px","medium-font-size":"1rem","small-font-size":"0.8125rem","font-weight":400}}};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
@import './components/Forms/Input';
|
||||
@import './components/Forms/LabelledBox';
|
||||
@import './components/Forms/Select';
|
||||
@import './components/Forms/Switch';
|
||||
@import './components/Loader';
|
||||
@import './components/Pagination';
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ export * from "./components/Forms/Field";
|
||||
export * from "./components/Forms/Input";
|
||||
export * from "./components/Forms/Radio";
|
||||
export * from "./components/Forms/Select";
|
||||
export * from "./components/Forms/Switch";
|
||||
export * from "./components/Loader";
|
||||
export * from "./components/Pagination";
|
||||
export * from "./components/Provider";
|
||||
|
||||
Reference in New Issue
Block a user