Reworked
This commit is contained in:
parent
6677695b78
commit
faeb9330a4
58
src/components/Checkbox.stories.tsx
Normal file
58
src/components/Checkbox.stories.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
||||||
|
|
||||||
|
import Checkbox from './Checkbox';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// Title inside navigation bar
|
||||||
|
title: 'Checkbox',
|
||||||
|
// Component to test
|
||||||
|
component: Checkbox,
|
||||||
|
// Clarifying the way how to process specific
|
||||||
|
// properties of your component and which values
|
||||||
|
// it can accept.
|
||||||
|
argTypes: {
|
||||||
|
checked: {
|
||||||
|
options: [true, false],
|
||||||
|
control: { type: 'radio' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as ComponentMeta<typeof Checkbox>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a way to define a tempalte for your component.
|
||||||
|
*
|
||||||
|
* This template should cover all the states.
|
||||||
|
*
|
||||||
|
* In most cases you should just distruct args attribute
|
||||||
|
* on a returning component.
|
||||||
|
*/
|
||||||
|
const Template: ComponentStory<typeof Checkbox> = (args) => (
|
||||||
|
<Checkbox {...args} />
|
||||||
|
);
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* States of your component */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
export const Unchecked = Template.bind({});
|
||||||
|
Unchecked.args = {
|
||||||
|
label: "On/off lights",
|
||||||
|
checked: false,
|
||||||
|
children: undefined,
|
||||||
|
}
|
||||||
|
export const Checked = Template.bind({});
|
||||||
|
Checked.args = {
|
||||||
|
children: "On/off lights",
|
||||||
|
checked: true,
|
||||||
|
label: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EitherLabelChildren = Template.bind({});
|
||||||
|
EitherLabelChildren.args = {
|
||||||
|
children: "On/off lights",
|
||||||
|
checked: true,
|
||||||
|
label: "Label!",
|
||||||
|
}
|
||||||
|
// GO Further
|
@ -1,71 +1,39 @@
|
|||||||
|
import classNames from "classnames";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
/**
|
||||||
|
* The way to provide `children` inside a component
|
||||||
|
* via attribute instead of enclosed tag
|
||||||
|
*/
|
||||||
|
label?: React.ReactNode;
|
||||||
|
/**
|
||||||
|
* When you will have both `children` and `label`
|
||||||
|
* defined on a component it will choose `children`
|
||||||
|
* to display
|
||||||
|
*/
|
||||||
|
children?: React.ReactNode;
|
||||||
|
} & Omit<React.ComponentPropsWithoutRef<"input">, "type">;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [*] A Checkbox Component
|
* Customized `input[type="checkbox"]` component with label
|
||||||
*
|
*
|
||||||
* [*] when the label is clicked => The checkbox will be checked
|
* All common input properties are inherited.
|
||||||
*
|
*
|
||||||
* [*] for each item(row) you have to put the following in App.tsx:
|
* To define a label content either provide `label` attribute
|
||||||
* const [isCheckedA, setIsCheckedA] = useState(true);
|
* or use common `children` property
|
||||||
const handleChangeA = (e: React.ChangeEvent<HTMLInputElement>) => {
|
*/
|
||||||
setIsCheckedA(e.target.checked);
|
const Checkbox = ({label, children, className, ...props}: Props) => {
|
||||||
};
|
|
||||||
*
|
|
||||||
* [*] to create this component, you have to provide the following:
|
|
||||||
* [1] label
|
|
||||||
* [2] if the item is checked or not.
|
|
||||||
*
|
|
||||||
* [*] A good example will be:
|
|
||||||
const App: React.FC = () =>
|
|
||||||
{
|
|
||||||
const [isCheckedA, setIsCheckedA] = useState(true);
|
|
||||||
const handleChangeA = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setIsCheckedA(e.target.checked);
|
|
||||||
};
|
|
||||||
|
|
||||||
const [isCheckedB, setIsCheckedB] = useState(true);
|
if(label && !children) {
|
||||||
const handleChangeB = (e: React.ChangeEvent<HTMLInputElement>) => {
|
children = label;
|
||||||
setIsCheckedB(e.target.checked);
|
}
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<label className={classNames(className, "flex items-center")}>
|
||||||
|
<input type="checkbox" {...props} />
|
||||||
<Checkbox
|
{children !== undefined && <span>{children}</span>}
|
||||||
handleChange={handleChangeA}
|
</label>
|
||||||
isChecked={isCheckedA}
|
|
||||||
label=" Leo Tolstoy "
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Checkbox
|
|
||||||
handleChange={handleChangeB}
|
|
||||||
isChecked={isCheckedB}
|
|
||||||
label=" Fyodor Dostoevsky "
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
isChecked: boolean;
|
|
||||||
handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
||||||
label: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Checkbox = (props: Props) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
id={props.label}
|
|
||||||
checked={props.isChecked}
|
|
||||||
onChange={props.handleChange}
|
|
||||||
/>
|
|
||||||
<label htmlFor={props.label}>{props.label}</label>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default Checkbox;
|
export default Checkbox;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user