Skip to content

Commit

Permalink
feat(checkbox): ✨ implement best simple comp & more changes
Browse files Browse the repository at this point in the history
  • Loading branch information
navin-moorthy committed Aug 27, 2021
1 parent 3b61b2d commit d3a1d4c
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 67 deletions.
74 changes: 63 additions & 11 deletions src/checkboxNew/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import {
CheckboxStateReturn,
CheckboxInitialState,
} from "./CheckboxState";
import { runIfFn } from "../utils";
import { CheckboxText } from "./CheckboxText";
import { CheckboxLabel } from "./CheckboxLabel";
import { USE_CHECKBOX_STATE_KEYS } from "./__keys";
import { getValidChildren, runIfFn } from "../utils";
import { CheckboxDescription } from "./CheckboxDescription";
import { CheckboxIcon, CheckboxDefaultIcon } from "./CheckboxIcon";
import { CheckboxInput, CheckboxInputHTMLProps } from "./CheckboxInput";
import { Dict } from "../utils/types";

export type CheckboxOwnProps = CheckboxInputHTMLProps & {
/**
Expand All @@ -23,7 +24,12 @@ export type CheckboxOwnProps = CheckboxInputHTMLProps & {
/**
* Description for the Checkbox.
*/
description?: string;
label?: React.ReactNode | ((args: CheckboxStateReturn) => JSX.Element);

/**
* Description for the Checkbox.
*/
description?: React.ReactNode | ((args: CheckboxStateReturn) => JSX.Element);
};

export type CheckboxProps = CheckboxInitialState & CheckboxOwnProps;
Expand All @@ -33,24 +39,48 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
const [state, checkboxProps] = useCheckboxProps(props);
const {
icon = CheckboxDefaultIcon,
children,
label,
description,
className,
style,
children,
...inputProps
} = checkboxProps;

const componentProps = getCheckboxComponentProps(children);

return (
<CheckboxLabel {...state} className={className} style={style}>
<CheckboxInput ref={ref} {...state} {...inputProps} />
<CheckboxIcon {...state}>{runIfFn(icon, state)}</CheckboxIcon>
{children && !description ? (
<CheckboxText {...state}>{children}</CheckboxText>
<CheckboxLabel
{...state}
className={className}
style={style}
{...componentProps?.labelProps}
>
<CheckboxInput
ref={ref}
{...state}
{...inputProps}
{...componentProps?.inputProps}
/>
<CheckboxIcon {...state} label={label} {...componentProps?.iconProps}>
{runIfFn(icon, state)}
</CheckboxIcon>
{label && !description ? (
<CheckboxText {...state} {...componentProps?.textProps}>
{runIfFn(label, state)}
</CheckboxText>
) : null}
{children && description ? (
{label && description ? (
<div className="flex flex-col">
<CheckboxText {...state}>{children}</CheckboxText>
<CheckboxDescription {...state}>{description}</CheckboxDescription>
<CheckboxText {...state} {...componentProps?.textProps}>
{runIfFn(label, state)}
</CheckboxText>
<CheckboxDescription
{...state}
{...componentProps?.descriptionProps}
>
{runIfFn(description, state)}
</CheckboxDescription>
</div>
) : null}
</CheckboxLabel>
Expand All @@ -73,3 +103,25 @@ export const useCheckboxProps = (props: CheckboxProps) => {
CheckboxInitialState,
];
};

const ComponentPropsMap = {
CheckboxLabel: "labelProps",
CheckboxInput: "inputProps",
CheckboxIcon: "iconProps",
CheckboxText: "textProps",
CheckboxDescription: "descriptionProps",
};

export const getCheckboxComponentProps = (children: React.ReactNode) => {
const validChildren = getValidChildren(children);
const props: Dict = {};

validChildren.forEach(child => {
props[
// @ts-ignore
ComponentPropsMap[child.type.displayName]
] = child.props;
});

return props;
};
12 changes: 7 additions & 5 deletions src/checkboxNew/CheckboxIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { createComponent, createHook } from "reakit-system";

import { useTheme } from "../theme";
import { withIconA11y } from "../utils";
import { CHECKBOX_LABEL_KEYS } from "./__keys";
import { CheckboxProps } from "./Checkbox";
import { CHECKBOX_ICON_KEYS } from "./__keys";
import { CheckboxStateReturn } from "./CheckboxState";
import { IndeterminateIcon, CheckIcon } from "../icons";
import { BoxHTMLProps, BoxOptions, useBox } from "../box";
Expand All @@ -12,7 +13,7 @@ export type CheckboxIconOptions = BoxOptions &
Pick<
CheckboxStateReturn,
"isChecked" | "isIndeterminate" | "isUnchecked" | "size"
>;
> & { label: CheckboxProps["label"] };

export type CheckboxIconHTMLProps = BoxHTMLProps;

Expand All @@ -24,16 +25,17 @@ export const useCheckboxIcon = createHook<
>({
name: "CheckboxIcon",
compose: useBox,
keys: CHECKBOX_LABEL_KEYS,
keys: CHECKBOX_ICON_KEYS,

useProps(options, htmlProps) {
const { isChecked, isIndeterminate, isUnchecked, size } = options;
const { isChecked, isIndeterminate, isUnchecked, size, label } = options;
const { className: htmlClassName, ...restHtmlProps } = htmlProps;

const checkbox = useTheme("checkboxNew");
const className = cx(
checkbox.icon.base,
checkbox.icon.size[size],
checkbox.icon.size.base[size],
label ? checkbox.icon.size.space[size] : "",
isUnchecked
? cx(
checkbox.icon.unChecked.default,
Expand Down
7 changes: 6 additions & 1 deletion src/checkboxNew/CheckboxState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export type CheckboxState = RenderlesskitCheckboxState & {
*
* @default md
*/
size: keyof Renderlesskit.GetThemeValue<"checkboxNew", "icon", "size">;
size: keyof Renderlesskit.GetThemeValue<
"checkboxNew",
"icon",
"size",
"base"
>;

/**
* If true, Checkbox is checked.
Expand Down
8 changes: 6 additions & 2 deletions src/checkboxNew/__keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const CHECKBOX_STATE_KEYS = [
"isChecked",
"isIndeterminate",
"isUnchecked",
"value",
"setState",
] as const;
export const USE_CHECKBOX_STATE_KEYS = [
Expand All @@ -15,7 +16,10 @@ export const USE_CHECKBOX_STATE_KEYS = [
"value",
] as const;
export const CHECKBOX_DESCRIPTION_KEYS = CHECKBOX_STATE_KEYS;
export const CHECKBOX_ICON_KEYS = CHECKBOX_DESCRIPTION_KEYS;
export const CHECKBOX_INPUT_KEYS = CHECKBOX_ICON_KEYS;
export const CHECKBOX_ICON_KEYS = [
...CHECKBOX_DESCRIPTION_KEYS,
"label",
] as const;
export const CHECKBOX_INPUT_KEYS = CHECKBOX_DESCRIPTION_KEYS;
export const CHECKBOX_LABEL_KEYS = CHECKBOX_INPUT_KEYS;
export const CHECKBOX_TEXT_KEYS = CHECKBOX_LABEL_KEYS;
Loading

0 comments on commit d3a1d4c

Please sign in to comment.