Skip to content

Commit

Permalink
refactor: wrap text input componets around a text field (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
PHILLIPS71 authored Nov 10, 2024
1 parent f80969c commit f6da629
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 38 deletions.
37 changes: 21 additions & 16 deletions packages/react/src/components/input/InputPhone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import type { InputVariantProps } from '@giantnodes/theme'
import type { CountryCode } from 'libphonenumber-js'
import type { InputProps } from 'react-aria-components'
import type { InputProps, TextFieldProps } from 'react-aria-components'
import React from 'react'
import { getExampleNumber, parsePhoneNumber } from 'libphonenumber-js/min'
import examples from 'libphonenumber-js/mobile/examples'
import { Input } from 'react-aria-components'
import { Input, TextField } from 'react-aria-components'

import type * as Polymophic from '~/utilities/polymorphic'
import { useFormGroup } from '~/components/form/use-form-group.hook'
Expand All @@ -16,10 +16,11 @@ import { cn } from '~/utilities'

const __ELEMENT_TYPE__ = 'input'

type ComponentOwnProps = InputVariantProps & {
country: CountryCode
onTemplateChange?: (template: string) => void
}
type ComponentOwnProps = InputVariantProps &
Omit<TextFieldProps, 'children'> & {
country: CountryCode
onTemplateChange?: (template: string) => void
}

type ComponentProps<TElement extends React.ElementType = typeof __ELEMENT_TYPE__> = Polymophic.ComponentPropsWithRef<
TElement,
Expand All @@ -35,9 +36,9 @@ const Component: ComponentType = React.forwardRef(
props: ComponentProps<TElement>,
ref: Polymophic.Ref<TElement>
) => {
const { as, children, className, country, color, size, shape, variant, onTemplateChange, ...rest } = props
const { as, className, country, color, size, shape, variant, onTemplateChange, ...rest } = props

const Element = as ?? Input
const Element = as ?? TextField
const group = useFormGroup()
const context = useInput()

Expand Down Expand Up @@ -68,9 +69,7 @@ const Component: ComponentType = React.forwardRef(

const parsed = parsePhoneNumber(example.number, country)
const formatted = parsed.format('NATIONAL')
const template = formatted.replace(/\d/g, '#')

return template
return formatted.replace(/\d/g, '#')
}, [country])

/**
Expand Down Expand Up @@ -113,16 +112,22 @@ const Component: ComponentType = React.forwardRef(
[format, group]
)

const component = React.useMemo<InputProps>(
const component = React.useMemo<TextFieldProps>(
() => ({
name: group?.name,
onChange: onChange,
onBlur: group?.onBlur,
className: slots.input({ className: cn(className) }),
...group?.fieldProps,
...rest,
}),
[className, group?.fieldProps, group?.name, group?.onBlur, onChange, rest, slots]
[group?.fieldProps, group?.name, group?.onBlur, onChange, rest]
)

const input = React.useMemo<InputProps>(
() => ({
className: slots.input({ className: cn(className) }),
}),
[className, slots]
)

React.useEffect(() => {
Expand All @@ -135,8 +140,8 @@ const Component: ComponentType = React.forwardRef(
<CountryFlag country={country} />
</Addon>

<Element {...component} ref={(group?.ref as React.RefObject<HTMLInputElement> | undefined) ?? ref}>
{children}
<Element {...component}>
<Input {...input} ref={(group?.ref as React.RefObject<HTMLInputElement> | undefined) ?? ref} />
</Element>
</>
)
Expand Down
32 changes: 21 additions & 11 deletions packages/react/src/components/input/InputText.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client'

import type { InputVariantProps } from '@giantnodes/theme'
import type { InputProps } from 'react-aria-components'
import type { InputProps, TextFieldProps } from 'react-aria-components'
import React from 'react'
import { Input } from 'react-aria-components'
import { Input, TextField } from 'react-aria-components'

import type * as Polymophic from '~/utilities/polymorphic'
import { useFormGroup } from '~/components/form/use-form-group.hook'
Expand All @@ -12,7 +12,7 @@ import { cn } from '~/utilities'

const __ELEMENT_TYPE__ = 'input'

type ComponentOwnProps = InputVariantProps
type ComponentOwnProps = InputVariantProps & Omit<TextFieldProps, 'children'>

type ComponentProps<TElement extends React.ElementType = typeof __ELEMENT_TYPE__> = Polymophic.ComponentPropsWithRef<
TElement,
Expand All @@ -28,9 +28,9 @@ const Component: ComponentType = React.forwardRef(
props: ComponentProps<TElement>,
ref: Polymophic.Ref<TElement>
) => {
const { as, children, className, color, size, shape, variant, ...rest } = props
const { as, className, color, size, shape, variant, ...rest } = props

const Element = as ?? Input
const Element = as ?? TextField

const group = useFormGroup()
const context = useInput()
Expand All @@ -42,21 +42,31 @@ const Component: ComponentType = React.forwardRef(
variant: variant ?? context?.variant,
})

const component = React.useMemo<InputProps>(
const component = React.useMemo<TextFieldProps>(
() => ({
name: group?.name,
onChange: group?.onChange,
onChange: (value: string) =>
group?.onChange?.({
target: { value },
type: 'change',
}),
onBlur: group?.onBlur,
className: slots.input({ className: cn(className) }),
...group?.fieldProps,
...rest,
}),
[className, group?.fieldProps, group?.name, group?.onBlur, group?.onChange, rest, slots]
[group, rest]
)

const input = React.useMemo<InputProps>(
() => ({
className: slots.input({ className: cn(className) }),
}),
[className, slots]
)

return (
<Element {...component} ref={(group?.ref as React.RefObject<HTMLInputElement> | undefined) ?? ref}>
{children}
<Element {...component}>
<Input {...input} ref={(group?.ref as React.RefObject<HTMLInputElement> | undefined) ?? ref} />
</Element>
)
}
Expand Down
30 changes: 20 additions & 10 deletions packages/react/src/components/input/InputTextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client'

import type { InputVariantProps } from '@giantnodes/theme'
import type { TextAreaProps } from 'react-aria-components'
import type { TextAreaProps, TextFieldProps } from 'react-aria-components'
import React from 'react'
import { TextArea } from 'react-aria-components'
import { TextArea, TextField } from 'react-aria-components'

import type * as Polymophic from '~/utilities/polymorphic'
import { useFormGroup } from '~/components/form/use-form-group.hook'
Expand All @@ -28,9 +28,9 @@ const Component: ComponentType = React.forwardRef(
props: ComponentProps<TElement>,
ref: Polymophic.Ref<TElement>
) => {
const { as, children, className, color, size, shape, variant, ...rest } = props
const { as, className, color, size, shape, variant, ...rest } = props

const Element = as ?? TextArea
const Element = as ?? TextField

const context = useInput()
const { slots } = useInputValue({
Expand All @@ -42,21 +42,31 @@ const Component: ComponentType = React.forwardRef(

const group = useFormGroup()

const component = React.useMemo<TextAreaProps>(
const component = React.useMemo<TextFieldProps>(
() => ({
name: group?.name,
onChange: group?.onChange,
onChange: (value: string) =>
group?.onChange?.({
target: { value },
type: 'change',
}),
onBlur: group?.onBlur,
className: slots.input({ className: cn(className) }),
...group?.fieldProps,
...rest,
}),
[className, group?.fieldProps, group?.name, group?.onBlur, group?.onChange, rest, slots]
[group, rest]
)

const input = React.useMemo<TextAreaProps>(
() => ({
className: slots.input({ className: cn(className) }),
}),
[className, slots]
)

return (
<Element {...component} ref={(group?.ref as React.RefObject<HTMLTextAreaElement> | undefined) ?? ref}>
{children}
<Element {...component}>
<TextArea {...input} ref={(group?.ref as React.RefObject<HTMLTextAreaElement> | undefined) ?? ref} />
</Element>
)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ const Component: ComponentType = React.forwardRef(
}

return React.cloneElement(icon as React.ReactElement, { className: context.slots.icon() })
}, [icon])
}, [context.slots, icon])

return (
<SelectContext.Provider value={context}>
Expand Down

0 comments on commit f6da629

Please sign in to comment.