Allow extension of input

This commit is contained in:
Eric Bailey
2024-01-18 11:17:27 -06:00
parent 1e5f213f12
commit 43dc77491e
3 changed files with 75 additions and 79 deletions
+2 -2
View File
@@ -10,7 +10,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {useTheme, atoms as a} from '#/alf'
import {Portal} from '#/components/Portal'
import {createTextInput} from '#/components/forms/InputText'
import {createInput} from '#/components/forms/TextField'
import {
DialogOuterProps,
@@ -22,7 +22,7 @@ import {Context} from '#/components/Dialog/context'
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
export * from '#/components/Dialog/types'
// @ts-ignore
export const InputText = createTextInput(BottomSheetTextInput)
export const Input = createInput(BottomSheetTextInput)
export function Outer({
children,
+69 -63
View File
@@ -149,79 +149,85 @@ export type InputProps = Omit<TextInputProps, 'value' | 'onChangeText'> & {
isInvalid?: boolean
}
function Input({
label,
placeholder,
value,
onChangeText,
isInvalid,
...rest
}: InputProps) {
const t = useTheme()
const ctx = React.useContext(Context)
const withinRoot = Boolean(ctx.inputRef)
export function createInput(Component: typeof TextInput) {
return function Input({
label,
placeholder,
value,
onChangeText,
isInvalid,
...rest
}: InputProps) {
const t = useTheme()
const ctx = React.useContext(Context)
const withinRoot = Boolean(ctx.inputRef)
const {chromeHover, chromeFocus, chromeError, chromeErrorHover} =
useSharedInputStyles()
const {chromeHover, chromeFocus, chromeError, chromeErrorHover} =
useSharedInputStyles()
if (!withinRoot) {
return (
<Root isInvalid={isInvalid}>
<Input
label={label}
placeholder={placeholder}
value={value}
onChangeText={onChangeText}
isInvalid={isInvalid}
{...rest}
/>
</Root>
)
}
if (!withinRoot) {
return (
<Root isInvalid={isInvalid}>
<Input
label={label}
placeholder={placeholder}
<>
<Component
accessibilityHint={undefined}
{...rest}
aria-label={label}
accessibilityLabel={label}
ref={ctx.inputRef}
value={value}
onChangeText={onChangeText}
isInvalid={isInvalid}
{...rest}
onFocus={ctx.onFocus}
onBlur={ctx.onBlur}
placeholder={placeholder || label}
placeholderTextColor={t.palette.contrast_500}
style={[
a.relative,
a.z_20,
a.flex_1,
a.text_md,
t.atoms.text,
a.px_xs,
{lineHeight: a.text_md.lineHeight * 1.1875},
]}
/>
</Root>
<View
style={[
a.z_10,
a.absolute,
a.inset_0,
a.rounded_sm,
t.atoms.bg_contrast_50,
{borderColor: 'transparent', borderWidth: 2},
ctx.hovered ? chromeHover : {},
ctx.focused ? chromeFocus : {},
ctx.isInvalid ? chromeError : {},
ctx.isInvalid && (ctx.hovered || ctx.focused)
? chromeErrorHover
: {},
]}
/>
</>
)
}
return (
<>
<TextInput
accessibilityHint={undefined}
{...rest}
aria-label={label}
accessibilityLabel={label}
ref={ctx.inputRef}
value={value}
onChangeText={onChangeText}
onFocus={ctx.onFocus}
onBlur={ctx.onBlur}
placeholder={placeholder || label}
placeholderTextColor={t.palette.contrast_500}
style={[
a.relative,
a.z_20,
a.flex_1,
a.text_md,
t.atoms.text,
a.px_xs,
{lineHeight: a.text_md.lineHeight * 1.1875},
]}
/>
<View
style={[
a.z_10,
a.absolute,
a.inset_0,
a.rounded_sm,
t.atoms.bg_contrast_50,
{borderColor: 'transparent', borderWidth: 2},
ctx.hovered ? chromeHover : {},
ctx.focused ? chromeFocus : {},
ctx.isInvalid ? chromeError : {},
ctx.isInvalid && (ctx.hovered || ctx.focused) ? chromeErrorHover : {},
]}
/>
</>
)
}
const Input = createInput(TextInput)
function Icon({icon: Comp}: {icon: React.ComponentType<SVGIconProps>}) {
const t = useTheme()
const ctx = React.useContext(Context)
+4 -14
View File
@@ -18,8 +18,7 @@ export function Dialogs() {
color="secondary"
size="small"
onPress={() => control.open()}
accessibilityLabel="Open basic dialog"
accessibilityHint="Open basic dialog">
label="Open basic dialog">
Open basic dialog
</Button>
@@ -28,8 +27,7 @@ export function Dialogs() {
color="primary"
size="small"
onPress={() => prompt.open()}
accessibilityLabel="Open prompt"
accessibilityHint="Open prompt">
label="Open prompt">
Open prompt
</Button>
@@ -58,14 +56,7 @@ export function Dialogs() {
<P nativeID="dialog-description">
A scrollable dialog with an input within it.
</P>
<Dialog.InputText
testID=""
value=""
onChange={() => {}}
placeholder="Type here"
accessibilityLabel="Type"
accessibilityHint="Type"
/>
<Dialog.Input value="" onChangeText={() => {}} label="Type here" />
<View style={{height: 1000}} />
<View style={[a.flex_row, a.justify_end]}>
<Button
@@ -73,8 +64,7 @@ export function Dialogs() {
color="primary"
size="small"
onPress={() => control.close()}
accessibilityLabel="Open basic dialog"
accessibilityHint="Open basic dialog">
label="Open basic dialog">
Close basic dialog
</Button>
</View>