Allow extension of input
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user