generated from timelessco/react-components-template
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(radio): radio with tailwind forms (#46)
* chore(radio): radio with tailwind forms * chore(radio): added disabled state styles * chore: purge fix * chore: added controllable state * chore: addComponent for radio styles * chore(radio): added RadioLabel * chore(radio): radio label improvements * chore: remove css file * chore: changed spinner types to getThemeValue * chore: added Box in radio label * feat(radio): added size prop * fix(radio): fix radio state context * chore: radio types cleanup * feat(radio): added radio v2 (#49) * feat(radio): migrate radio to use conditional rendering * refactor(radio): added size support and refactored all types * chore: radio controlled state * chore: review updates * fix(radio): fixed radio controlled state * fix(radio): fixed radio controlled state * refactor: rearrange imports * refactor(radio): added radio icons with css * Revert "refactor(radio): added radio icons with css" This reverts commit 5572582. * refactor(radio): minor updates * feat(radio): added icon props in radio * chore: refactor & remove old code
- Loading branch information
1 parent
54d2d80
commit e95ed2c
Showing
15 changed files
with
858 additions
and
501 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import * as React from "react"; | ||
import { createIcon } from "../icon"; | ||
|
||
export const RadioCheckedIcon = createIcon({ | ||
displayName: "RadioChecked", | ||
viewBox: "0 0 16 16", | ||
path: ( | ||
<> | ||
<circle cx="8" cy="8" r="8" fill="currentColor" /> | ||
<circle cx="8" cy="8" r="3" fill="white" /> | ||
</> | ||
), | ||
}); | ||
|
||
export const RadioUncheckedIcon = createIcon({ | ||
displayName: "RadioUnchecked", | ||
viewBox: "0 0 16 16", | ||
path: ( | ||
<> | ||
<circle | ||
cx="8" | ||
cy="8" | ||
r="7" | ||
fill="white" | ||
stroke="currentColor" | ||
strokeWidth="1.5" | ||
/> | ||
</> | ||
), | ||
}); | ||
|
||
export const RadioDisabledIcon = createIcon({ | ||
displayName: "RadioDisabled", | ||
viewBox: "0 0 16 16", | ||
path: ( | ||
<> | ||
<circle cx="8" cy="8" r="8" fill="#E4E4E7" /> | ||
<circle cx="8" cy="8" r="3" fill="currentColor" /> | ||
</> | ||
), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,55 @@ | ||
import { cx } from "@renderlesskit/react"; | ||
import React from "react"; | ||
import { | ||
RadioHTMLProps, | ||
Radio as ReakitRadio, | ||
RadioGroup as ReakitRadioGroup, | ||
RadioGroupProps, | ||
RadioInitialState, | ||
RadioProps, | ||
useRadioState, | ||
RadioProps as ReakitRadioProps, | ||
} from "reakit"; | ||
import { createContext } from "../utils"; | ||
import { cx } from "@renderlesskit/react"; | ||
|
||
import { useTheme } from "../theme"; | ||
import { RadioIcon } from "./RadioIcon"; | ||
import { useRadioContext } from "./RadioGroup"; | ||
import { forwardRefWithAs } from "../utils/types"; | ||
|
||
const [RadioProvider, useRadioContext] = createContext({ | ||
name: "RadioContext", | ||
strict: true, | ||
errorMessage: "Radio must be used within RadioContextProvider", | ||
}); | ||
export type RadioCommonProps = Partial< | ||
Pick<ReakitRadioProps, "value" | "disabled"> | ||
> & { | ||
size?: keyof Renderlesskit.GetThemeValue<"radio", "icon">["size"]; | ||
}; | ||
|
||
export const RadioInput: React.FC<RadioHTMLProps & RadioCommonProps> = ({ | ||
className, | ||
...rest | ||
}) => { | ||
const theme = useTheme(); | ||
const { radioState } = useRadioContext(); | ||
|
||
const radioStyles = cx(theme.radio.input, className); | ||
|
||
return <ReakitRadio className={radioStyles} {...radioState} {...rest} />; | ||
}; | ||
|
||
export const Radio = forwardRefWithAs< | ||
Partial<RadioProps>, | ||
RadioHTMLProps & | ||
RadioCommonProps & { | ||
checkedIcon?: React.ReactNode; | ||
uncheckedIcon?: React.ReactNode; | ||
disabledIcon?: React.ReactNode; | ||
}, | ||
HTMLInputElement, | ||
"input" | ||
>(({ children, className, ...props }, ref) => { | ||
const state = useRadioContext(); | ||
return ( | ||
<label className={cx("radio", className)}> | ||
<span className="radio__input"> | ||
<ReakitRadio className="sr-only" {...state} {...props} ref={ref} /> | ||
<span className="radio__control" /> | ||
</span> | ||
<span className="radio__label">{children}</span> | ||
</label> | ||
); | ||
}); | ||
|
||
export const RadioGroup = forwardRefWithAs< | ||
Partial<RadioGroupProps & RadioInitialState>, | ||
HTMLDivElement, | ||
"div" | ||
>(({ children, ...props }, ref) => { | ||
const radio = useRadioState(props); | ||
|
||
>((props, ref) => { | ||
const { checkedIcon, uncheckedIcon, disabledIcon } = props; | ||
return ( | ||
<RadioProvider value={radio}> | ||
<ReakitRadioGroup {...radio} ref={ref}> | ||
{children} | ||
</ReakitRadioGroup> | ||
</RadioProvider> | ||
<> | ||
<RadioInput ref={ref} {...props} /> | ||
<RadioIcon | ||
value={props.value} | ||
disabled={props.disabled} | ||
checkedIcon={checkedIcon} | ||
uncheckedIcon={uncheckedIcon} | ||
disabledIcon={disabledIcon} | ||
/> | ||
</> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React from "react"; | ||
import { RadioInitialState, RadioStateReturn } from "reakit"; | ||
|
||
import { createContext } from "../utils"; | ||
import { RadioCommonProps } from "./Radio"; | ||
import { useRadioState } from "./useRadioState"; | ||
|
||
type RadioContextType = { | ||
radioState?: RadioStateReturn; | ||
radioSize?: RadioCommonProps["size"]; | ||
}; | ||
|
||
const [RadioProvider, useRadioContext] = createContext<RadioContextType>({ | ||
errorMessage: "Radio must be used within RadioProvider", | ||
name: "RadioContext", | ||
strict: true, | ||
}); | ||
|
||
export { RadioProvider, useRadioContext }; | ||
|
||
export type RadioGroupProps = RadioInitialState & | ||
Pick<RadioCommonProps, "size"> & { | ||
onStateChange?: (state: RadioCommonProps["value"]) => void; | ||
state?: RadioCommonProps["value"]; | ||
defaultState?: RadioCommonProps["value"]; | ||
}; | ||
|
||
export const RadioGroup: React.FC<RadioGroupProps> = ({ | ||
children, | ||
size = "sm", | ||
...props | ||
}) => { | ||
const radioState = useRadioState(props); | ||
|
||
return ( | ||
<RadioProvider value={{ radioState: radioState, radioSize: size }}> | ||
{children} | ||
</RadioProvider> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import React from "react"; | ||
import { cx } from "@renderlesskit/react"; | ||
import { Box, BoxProps, RadioState } from "reakit"; | ||
|
||
import { | ||
RadioCheckedIcon, | ||
RadioDisabledIcon, | ||
RadioUncheckedIcon, | ||
} from "../icons/RadioIcons"; | ||
import { useTheme } from ".."; | ||
import { RadioCommonProps } from "./Radio"; | ||
import { useRadioContext } from "./RadioGroup"; | ||
import { forwardRefWithAs } from "../utils/types"; | ||
|
||
export type RadioIconProps = BoxProps & | ||
RadioState & | ||
RadioCommonProps & { | ||
checkedIcon?: React.ReactNode; | ||
uncheckedIcon?: React.ReactNode; | ||
disabledIcon?: React.ReactNode; | ||
}; | ||
|
||
export const RadioIcon = forwardRefWithAs< | ||
Partial<RadioIconProps>, | ||
HTMLDivElement, | ||
"div" | ||
>((props, ref) => { | ||
const { radioState, radioSize } = useRadioContext(); | ||
const { value, size, disabled, ...mainProps } = props; | ||
const { className, children, ...rest } = mainProps; | ||
|
||
const _size = size || radioSize || "sm"; | ||
const stateProp = radioState?.state === value; | ||
|
||
const theme = useTheme(); | ||
const radioIconStyles = cx( | ||
theme.radio.icon.base, | ||
theme.radio.icon.size[_size], | ||
disabled | ||
? theme.radio.icon.disabled | ||
: stateProp | ||
? theme.radio.icon.checked | ||
: theme.radio.icon.unchecked, | ||
className, | ||
); | ||
|
||
const iconMap = { | ||
checked: props.checkedIcon || <RadioCheckedIcon />, | ||
unchecked: props.uncheckedIcon || <RadioUncheckedIcon />, | ||
disabled: props.disabledIcon || <RadioDisabledIcon />, | ||
}; | ||
|
||
return ( | ||
<Box | ||
ref={ref} | ||
role="img" | ||
aria-hidden="true" | ||
className={radioIconStyles} | ||
{...rest} | ||
> | ||
{children | ||
? children | ||
: disabled | ||
? iconMap.disabled | ||
: stateProp | ||
? iconMap.checked | ||
: iconMap.unchecked} | ||
</Box> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import React from "react"; | ||
import { BoxProps } from "reakit"; | ||
import { cx } from "@renderlesskit/react"; | ||
|
||
import { Box } from "../box"; | ||
import { useTheme } from ".."; | ||
import { RadioCommonProps } from "./Radio"; | ||
import { useRadioContext } from "./RadioGroup"; | ||
import { forwardRefWithAs } from "../utils/types"; | ||
|
||
export type RadioLabelProps = BoxProps & Omit<RadioCommonProps, "value">; | ||
|
||
export const RadioLabel = forwardRefWithAs< | ||
RadioLabelProps, | ||
HTMLLabelElement, | ||
"label" | ||
>((props, ref) => { | ||
const { size, disabled = false, ...mainProps } = props; | ||
const { className, ...rest } = mainProps; | ||
const theme = useTheme(); | ||
const { radioSize } = useRadioContext(); | ||
const _size = size || radioSize || "sm"; | ||
|
||
const radioStyles = cx( | ||
theme.radio.base, | ||
theme.radio.label.base, | ||
theme.radio.label.size[_size], | ||
disabled ? theme.radio.disabled : "", | ||
className, | ||
); | ||
|
||
return <Box as="label" ref={ref} className={radioStyles} {...rest} />; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from "./Radio"; | ||
export * from "./RadioIcon"; | ||
export * from "./RadioLabel"; | ||
export * from "./RadioGroup"; | ||
export * from "./useRadioState"; |
Oops, something went wrong.