Skip to content

Commit

Permalink
feat: redesign radio (#69)
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei authored Jun 17, 2024
1 parent ba6184d commit 6d3f6c2
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 126 deletions.
37 changes: 0 additions & 37 deletions src/renderer/src/components/ui/radio-group.tsx

This file was deleted.

52 changes: 52 additions & 0 deletions src/renderer/src/components/ui/radio-group/Radio.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { cn } from "@renderer/lib/utils"
import type { FC, ReactNode } from "react"
import { useEventCallback } from "usehooks-ts"

import { useRadioContext, useRadioGroupValue } from "./context"

export const Radio: FC<
React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
> & {
label: ReactNode
wrapperClassName?: string
}
> = (props) => {
const { id, label, className, wrapperClassName, value, onChange, ...rest } =
props
const { groupId, onChange: ctxOnChange } = useRadioContext() || {}

const ctxValue = useRadioGroupValue()

const handleChange: React.ChangeEventHandler<HTMLInputElement> =
useEventCallback((e) => {
ctxOnChange?.(e.target.value)
onChange?.(e)
})
return (
<div className={cn("flex items-center gap-2", wrapperClassName)}>
<input
{...rest}
type="radio"
id={groupId || id}
className={cn(
"radio radio-primary radio-sm disabled:radio-current disabled:cursor-not-allowed disabled:text-theme-disabled",
className,
)}
value={value}
checked={ctxValue === value}
onChange={handleChange}
/>

<label
className={cn(
rest.disabled ? "text-theme-disabled" : "",
)}
htmlFor={groupId || id}
>
{label}
</label>
</div>
)
}
33 changes: 33 additions & 0 deletions src/renderer/src/components/ui/radio-group/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useId, useMemo, useRef, useState } from "react"

import { RadioGroupContextProvider, RadioGroupValueProvider } from "./context"

export const RadioGroup: Component<{
value?: string
onValueChange?: (value: string) => void
}> = (props) => {
const id = useId()
const { onValueChange, value } = props

const stableOnValueChange = useRef(onValueChange).current

const [currentValue, setCurrentValue] = useState(value)
return (
<RadioGroupContextProvider
value={useMemo(
() => ({
groupId: id,
onChange(value) {
setCurrentValue(value)
stableOnValueChange?.(value)
},
}),
[id, stableOnValueChange],
)}
>
<RadioGroupValueProvider value={currentValue}>
{props.children}
</RadioGroupValueProvider>
</RadioGroupContextProvider>
)
}
17 changes: 17 additions & 0 deletions src/renderer/src/components/ui/radio-group/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createContext, useContext } from "react"

interface RadioContext {
groupId: string
onChange: (value: string) => void

}
const RadioContext = createContext<RadioContext>(null!)

export const useRadioContext = () => useContext(RadioContext)

export const RadioGroupContextProvider = RadioContext.Provider
type RadioGroupValue = string | undefined

const RadioGroupValueContext = createContext<RadioGroupValue>("")
export const RadioGroupValueProvider = RadioGroupValueContext.Provider
export const useRadioGroupValue = () => useContext(RadioGroupValueContext)
3 changes: 3 additions & 0 deletions src/renderer/src/components/ui/radio-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./context"
export * from "./Radio"
export * from "./RadioGroup"
Loading

0 comments on commit 6d3f6c2

Please sign in to comment.