Refactor input
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
|||||||
LayoutChangeEvent,
|
LayoutChangeEvent,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
|
||||||
import {useTheme, atoms, web, tokens} from '#/alf'
|
import {useTheme, atoms as a, web, tokens} from '#/alf'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import {BaseProps} from '#/components/forms/types'
|
|||||||
|
|
||||||
type Props = BaseProps &
|
type Props = BaseProps &
|
||||||
Omit<TextInputProps, 'placeholder'> & {
|
Omit<TextInputProps, 'placeholder'> & {
|
||||||
placeholder: Required<TextInputProps>['placeholder']
|
placeholder?: Required<TextInputProps>['placeholder']
|
||||||
icon?: React.FunctionComponent<any>
|
icon?: React.FunctionComponent<any>
|
||||||
suffix?: React.FunctionComponent<any>
|
suffix?: React.FunctionComponent<any>
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,6 @@ export function createTextInput(Input: typeof TextInput) {
|
|||||||
value: initialValue,
|
value: initialValue,
|
||||||
onChange,
|
onChange,
|
||||||
testID,
|
testID,
|
||||||
accessibilityLabel,
|
|
||||||
accessibilityHint,
|
|
||||||
label,
|
label,
|
||||||
hasError,
|
hasError,
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
@@ -146,21 +144,22 @@ export function createTextInput(Input: typeof TextInput) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[atoms.relative, atoms.w_full]}>
|
<View style={[a.relative, a.w_full]}>
|
||||||
{label && (
|
{label && (
|
||||||
<Text
|
<Text
|
||||||
nativeID={labelId}
|
nativeID={labelId}
|
||||||
style={[
|
style={[
|
||||||
atoms.text_sm,
|
a.text_sm,
|
||||||
atoms.font_bold,
|
a.font_bold,
|
||||||
t.atoms.text_contrast_600,
|
t.atoms.text_contrast_600,
|
||||||
atoms.mb_sm,
|
a.mb_sm,
|
||||||
]}>
|
]}>
|
||||||
{label}
|
{label}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
|
accessibilityHint={undefined}
|
||||||
{...props}
|
{...props}
|
||||||
value={value}
|
value={value}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
@@ -168,8 +167,7 @@ export function createTextInput(Input: typeof TextInput) {
|
|||||||
aria-label={label}
|
aria-label={label}
|
||||||
aria-invalid={hasError}
|
aria-invalid={hasError}
|
||||||
aria-placeholder={props.placeholder}
|
aria-placeholder={props.placeholder}
|
||||||
accessibilityLabel={accessibilityLabel}
|
accessibilityLabel={label}
|
||||||
accessibilityHint={accessibilityHint}
|
|
||||||
placeholderTextColor={t.atoms.text_contrast_400.color}
|
placeholderTextColor={t.atoms.text_contrast_400.color}
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
@@ -180,17 +178,17 @@ export function createTextInput(Input: typeof TextInput) {
|
|||||||
})}
|
})}
|
||||||
style={[
|
style={[
|
||||||
t.atoms.bg_contrast_50,
|
t.atoms.bg_contrast_50,
|
||||||
atoms.w_full,
|
a.w_full,
|
||||||
atoms.px_lg,
|
a.px_lg,
|
||||||
atoms.py_md,
|
a.py_md,
|
||||||
atoms.rounded_sm,
|
a.rounded_sm,
|
||||||
atoms.text_md,
|
a.text_md,
|
||||||
t.atoms.text,
|
t.atoms.text,
|
||||||
web({
|
web({
|
||||||
paddingTop: atoms.pt_md.paddingTop - 1,
|
paddingTop: a.pt_md.paddingTop - 1,
|
||||||
}),
|
}),
|
||||||
{borderColor: 'transparent', paddingRight: suffixPadding},
|
{borderColor: 'transparent', paddingRight: suffixPadding},
|
||||||
{borderWidth: 2, lineHeight: atoms.text_md.lineHeight * 1.1875},
|
{borderWidth: 2, lineHeight: a.text_md.lineHeight * 1.1875},
|
||||||
...inputBaseStyles,
|
...inputBaseStyles,
|
||||||
...(hovered ? inputHoverStyles : []),
|
...(hovered ? inputHoverStyles : []),
|
||||||
...(focused ? inputFocusStyles : []),
|
...(focused ? inputFocusStyles : []),
|
||||||
@@ -201,11 +199,11 @@ export function createTextInput(Input: typeof TextInput) {
|
|||||||
{Icon && (
|
{Icon && (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
atoms.absolute,
|
a.absolute,
|
||||||
atoms.inset_0,
|
a.inset_0,
|
||||||
atoms.align_center,
|
a.align_center,
|
||||||
atoms.justify_center,
|
a.justify_center,
|
||||||
atoms.pl_md,
|
a.pl_md,
|
||||||
{right: 'auto'},
|
{right: 'auto'},
|
||||||
]}>
|
]}>
|
||||||
<Icon
|
<Icon
|
||||||
@@ -232,11 +230,11 @@ export function createTextInput(Input: typeof TextInput) {
|
|||||||
<View
|
<View
|
||||||
onLayout={handleSuffixLayout}
|
onLayout={handleSuffixLayout}
|
||||||
style={[
|
style={[
|
||||||
atoms.absolute,
|
a.absolute,
|
||||||
atoms.inset_0,
|
a.inset_0,
|
||||||
atoms.align_center,
|
a.align_center,
|
||||||
atoms.justify_center,
|
a.justify_center,
|
||||||
atoms.pr_lg,
|
a.pr_lg,
|
||||||
{left: 'auto'},
|
{left: 'auto'},
|
||||||
]}>
|
]}>
|
||||||
<Suffix />
|
<Suffix />
|
||||||
|
|||||||
@@ -0,0 +1,316 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
View,
|
||||||
|
TextInput,
|
||||||
|
TextInputProps,
|
||||||
|
TextStyle,
|
||||||
|
ViewStyle,
|
||||||
|
Pressable,
|
||||||
|
StyleSheet,
|
||||||
|
AccessibilityProps,
|
||||||
|
} from 'react-native'
|
||||||
|
|
||||||
|
import {isWeb} from '#/platform/detection'
|
||||||
|
import {useTheme, atoms as a, web, tokens} from '#/alf'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
|
||||||
|
const Context = React.createContext<{
|
||||||
|
inputRef: React.RefObject<TextInput> | null
|
||||||
|
isInvalid: boolean
|
||||||
|
hovered: boolean
|
||||||
|
onHoverIn: () => void
|
||||||
|
onHoverOut: () => void
|
||||||
|
focused: boolean
|
||||||
|
onFocus: () => void
|
||||||
|
onBlur: () => void
|
||||||
|
}>({
|
||||||
|
inputRef: null,
|
||||||
|
isInvalid: false,
|
||||||
|
hovered: false,
|
||||||
|
onHoverIn: () => {},
|
||||||
|
onHoverOut: () => {},
|
||||||
|
focused: false,
|
||||||
|
onFocus: () => {},
|
||||||
|
onBlur: () => {},
|
||||||
|
})
|
||||||
|
|
||||||
|
export type RootProps = React.PropsWithChildren<{isInvalid?: boolean}>
|
||||||
|
|
||||||
|
function Root({children, isInvalid = false}: RootProps) {
|
||||||
|
const inputRef = React.useRef<TextInput>(null)
|
||||||
|
const rootRef = React.useRef<View>(null)
|
||||||
|
const {
|
||||||
|
state: hovered,
|
||||||
|
onIn: onHoverIn,
|
||||||
|
onOut: onHoverOut,
|
||||||
|
} = useInteractionState()
|
||||||
|
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
||||||
|
|
||||||
|
const context = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
inputRef,
|
||||||
|
hovered,
|
||||||
|
onHoverIn,
|
||||||
|
onHoverOut,
|
||||||
|
focused,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
|
isInvalid,
|
||||||
|
}),
|
||||||
|
[
|
||||||
|
inputRef,
|
||||||
|
hovered,
|
||||||
|
onHoverIn,
|
||||||
|
onHoverOut,
|
||||||
|
focused,
|
||||||
|
onFocus,
|
||||||
|
onBlur,
|
||||||
|
isInvalid,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
React.useLayoutEffect(() => {
|
||||||
|
const root = rootRef.current
|
||||||
|
if (!root || !isWeb) return
|
||||||
|
// @ts-ignore web only
|
||||||
|
root.tabIndex = -1
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Context.Provider value={context}>
|
||||||
|
<Pressable
|
||||||
|
accessibilityRole="button"
|
||||||
|
ref={rootRef}
|
||||||
|
role="none"
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.align_center,
|
||||||
|
a.relative,
|
||||||
|
a.w_full,
|
||||||
|
a.px_md,
|
||||||
|
{
|
||||||
|
paddingVertical: 14,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
onPressIn={() => inputRef.current?.focus()}
|
||||||
|
onHoverIn={onHoverIn}
|
||||||
|
onHoverOut={onHoverOut}>
|
||||||
|
{children}
|
||||||
|
</Pressable>
|
||||||
|
</Context.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function useSharedInputStyles() {
|
||||||
|
const t = useTheme()
|
||||||
|
return React.useMemo(() => {
|
||||||
|
const hover: ViewStyle[] = [
|
||||||
|
{
|
||||||
|
borderColor: t.palette.contrast_100,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const focus: ViewStyle[] = [
|
||||||
|
{
|
||||||
|
backgroundColor: t.palette.contrast_50,
|
||||||
|
borderColor: t.palette.primary_500,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const error: ViewStyle[] = [
|
||||||
|
{
|
||||||
|
backgroundColor:
|
||||||
|
t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900,
|
||||||
|
borderColor:
|
||||||
|
t.name === 'light' ? t.palette.negative_300 : t.palette.negative_800,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const errorHover: ViewStyle[] = [
|
||||||
|
{
|
||||||
|
backgroundColor:
|
||||||
|
t.name === 'light' ? t.palette.negative_25 : t.palette.negative_900,
|
||||||
|
borderColor: tokens.color.red_500,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return {
|
||||||
|
chromeHover: StyleSheet.flatten(hover),
|
||||||
|
chromeFocus: StyleSheet.flatten(focus),
|
||||||
|
chromeError: StyleSheet.flatten(error),
|
||||||
|
chromeErrorHover: StyleSheet.flatten(errorHover),
|
||||||
|
}
|
||||||
|
}, [t])
|
||||||
|
}
|
||||||
|
|
||||||
|
export type InputProps = Omit<TextInputProps, 'value' | 'onChangeText'> & {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
onChangeText: (value: string) => void
|
||||||
|
isInvalid?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
if (!withinRoot) {
|
||||||
|
return (
|
||||||
|
<Root isInvalid={isInvalid}>
|
||||||
|
<Input
|
||||||
|
label={label}
|
||||||
|
placeholder={placeholder}
|
||||||
|
value={value}
|
||||||
|
onChangeText={onChangeText}
|
||||||
|
isInvalid={isInvalid}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
</Root>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 : {},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Icon({icon: Comp}: {icon: React.ComponentType<SVGIconProps>}) {
|
||||||
|
const t = useTheme()
|
||||||
|
const ctx = React.useContext(Context)
|
||||||
|
const {hover, focus, errorHover, errorFocus} = React.useMemo(() => {
|
||||||
|
const hover: TextStyle[] = [
|
||||||
|
{
|
||||||
|
color: t.palette.contrast_800,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const focus: TextStyle[] = [
|
||||||
|
{
|
||||||
|
color: t.palette.primary_500,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const errorHover: TextStyle[] = [
|
||||||
|
{
|
||||||
|
color: t.palette.negative_500,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const errorFocus: TextStyle[] = [
|
||||||
|
{
|
||||||
|
color: t.palette.negative_500,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return {
|
||||||
|
hover,
|
||||||
|
focus,
|
||||||
|
errorHover,
|
||||||
|
errorFocus,
|
||||||
|
}
|
||||||
|
}, [t])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.z_20, a.pr_xs]}>
|
||||||
|
<Comp
|
||||||
|
size="md"
|
||||||
|
style={[
|
||||||
|
{color: t.palette.contrast_500},
|
||||||
|
ctx.hovered ? hover : {},
|
||||||
|
ctx.focused ? focus : {},
|
||||||
|
ctx.isInvalid && ctx.hovered ? errorHover : {},
|
||||||
|
ctx.isInvalid && ctx.focused ? errorFocus : {},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Suffix({
|
||||||
|
children,
|
||||||
|
label,
|
||||||
|
accessibilityHint,
|
||||||
|
}: React.PropsWithChildren<{
|
||||||
|
label: string
|
||||||
|
accessibilityHint?: AccessibilityProps['accessibilityHint']
|
||||||
|
}>) {
|
||||||
|
const t = useTheme()
|
||||||
|
const ctx = React.useContext(Context)
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
aria-label={label}
|
||||||
|
accessibilityLabel={label}
|
||||||
|
accessibilityHint={accessibilityHint}
|
||||||
|
style={[
|
||||||
|
a.z_20,
|
||||||
|
a.pr_sm,
|
||||||
|
a.text_md,
|
||||||
|
t.atoms.text_contrast_400,
|
||||||
|
{
|
||||||
|
pointerEvents: 'none',
|
||||||
|
},
|
||||||
|
web({
|
||||||
|
marginTop: -2,
|
||||||
|
}),
|
||||||
|
ctx.hovered || ctx.focused
|
||||||
|
? {
|
||||||
|
color: t.palette.contrast_800,
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
]}>
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Root,
|
||||||
|
Input,
|
||||||
|
Icon,
|
||||||
|
Suffix,
|
||||||
|
}
|
||||||
@@ -2,17 +2,10 @@ import {AccessibilityProps} from 'react-native'
|
|||||||
|
|
||||||
export type RequiredAccessibilityProps = Required<AccessibilityProps>
|
export type RequiredAccessibilityProps = Required<AccessibilityProps>
|
||||||
|
|
||||||
export type BaseProps<T = string> = Omit<
|
export type BaseProps<T = string> = AccessibilityProps & {
|
||||||
AccessibilityProps,
|
|
||||||
'accessibilityLabel' | 'accessibilityHint'
|
|
||||||
> &
|
|
||||||
Pick<
|
|
||||||
RequiredAccessibilityProps,
|
|
||||||
'accessibilityLabel' | 'accessibilityHint'
|
|
||||||
> & {
|
|
||||||
value: T
|
value: T
|
||||||
onChange: (value: T) => void
|
onChange: (value: T) => void
|
||||||
testID: string
|
testID?: string
|
||||||
label?: string
|
label: string
|
||||||
hasError?: boolean
|
hasError?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ export const ArrowTopRight_Stroke2_Corner0_Rounded = React.forwardRef(
|
|||||||
// @ts-ignore it's fiiiiine
|
// @ts-ignore it's fiiiiine
|
||||||
ref={ref}
|
ref={ref}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
style={[{width: size}, style]}>
|
width={size}
|
||||||
|
height={size}
|
||||||
|
style={[style]}>
|
||||||
<Path
|
<Path
|
||||||
fill={fill}
|
fill={fill}
|
||||||
fill-rule="evenodd"
|
fillRule="evenodd"
|
||||||
clip-rule="evenodd"
|
clipRule="evenodd"
|
||||||
d="M8 6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v9a1 1 0 1 1-2 0V8.414l-9.793 9.793a1 1 0 0 1-1.414-1.414L15.586 7H9a1 1 0 0 1-1-1Z"
|
d="M8 6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v9a1 1 0 1 1-2 0V8.414l-9.793 9.793a1 1 0 0 1-1.414-1.414L15.586 7H9a1 1 0 0 1-1-1Z"
|
||||||
/>
|
/>
|
||||||
</Svg>
|
</Svg>
|
||||||
|
|||||||
@@ -16,10 +16,13 @@ export const Globe_Stroke2_Corner0_Rounded = React.forwardRef(function LogoImpl(
|
|||||||
// @ts-ignore it's fiiiiine
|
// @ts-ignore it's fiiiiine
|
||||||
ref={ref}
|
ref={ref}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
style={[{width: size}, style]}>
|
width={size}
|
||||||
|
height={size}
|
||||||
|
style={[style]}>
|
||||||
<Path
|
<Path
|
||||||
fill={fill}
|
fill={fill}
|
||||||
fill-rule="evenodd"
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
d="M4.062 11h2.961c.103-2.204.545-4.218 1.235-5.77.06-.136.123-.269.188-.399A8.007 8.007 0 0 0 4.062 11ZM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm0 2c-.227 0-.518.1-.868.432-.354.337-.719.872-1.047 1.61-.561 1.263-.958 2.991-1.06 4.958h5.95c-.102-1.967-.499-3.695-1.06-4.958-.328-.738-.693-1.273-1.047-1.61C12.518 4.099 12.227 4 12 4Zm4.977 7c-.103-2.204-.545-4.218-1.235-5.77a9.78 9.78 0 0 0-.188-.399A8.006 8.006 0 0 1 19.938 11h-2.961Zm-2.003 2H9.026c.101 1.966.498 3.695 1.06 4.958.327.738.692 1.273 1.046 1.61.35.333.641.432.868.432.227 0 .518-.1.868-.432.354-.337.719-.872 1.047-1.61.561-1.263.958-2.991 1.06-4.958Zm.58 6.169c.065-.13.128-.263.188-.399.69-1.552 1.132-3.566 1.235-5.77h2.961a8.006 8.006 0 0 1-4.384 6.169Zm-7.108 0a9.877 9.877 0 0 1-.188-.399c-.69-1.552-1.132-3.566-1.235-5.77H4.062a8.006 8.006 0 0 0 4.384 6.169Z"
|
d="M4.062 11h2.961c.103-2.204.545-4.218 1.235-5.77.06-.136.123-.269.188-.399A8.007 8.007 0 0 0 4.062 11ZM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm0 2c-.227 0-.518.1-.868.432-.354.337-.719.872-1.047 1.61-.561 1.263-.958 2.991-1.06 4.958h5.95c-.102-1.967-.499-3.695-1.06-4.958-.328-.738-.693-1.273-1.047-1.61C12.518 4.099 12.227 4 12 4Zm4.977 7c-.103-2.204-.545-4.218-1.235-5.77a9.78 9.78 0 0 0-.188-.399A8.006 8.006 0 0 1 19.938 11h-2.961Zm-2.003 2H9.026c.101 1.966.498 3.695 1.06 4.958.327.738.692 1.273 1.046 1.61.35.333.641.432.868.432.227 0 .518-.1.868-.432.354-.337.719-.872 1.047-1.61.561-1.263.958-2.991 1.06-4.958Zm.58 6.169c.065-.13.128-.263.188-.399.69-1.552 1.132-3.566 1.235-5.77h2.961a8.006 8.006 0 0 1-4.384 6.169Zm-7.108 0a9.877 9.877 0 0 1-.188-.399c-.69-1.552-1.132-3.566-1.235-5.77H4.062a8.006 8.006 0 0 0 4.384 6.169Z"
|
||||||
/>
|
/>
|
||||||
</Svg>
|
</Svg>
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ export const IconTemplate_Stroke2_Corner0_Rounded = React.forwardRef(
|
|||||||
// @ts-ignore it's fiiiiine
|
// @ts-ignore it's fiiiiine
|
||||||
ref={ref}
|
ref={ref}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
style={[{width: size}, style]}>
|
width={size}
|
||||||
|
height={size}
|
||||||
|
style={[style]}>
|
||||||
<Path
|
<Path
|
||||||
fill={fill}
|
fill={fill}
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ import React from 'react'
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
|
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import {Text, H1, H3} from '#/components/Typography'
|
import {H1, H3} from '#/components/Typography'
|
||||||
import {InputText} from '#/components/forms/InputText'
|
import {InputText} from '#/components/forms/InputText'
|
||||||
|
import TextField from '#/components/forms/TextField'
|
||||||
import {InputDate, utils} from '#/components/forms/InputDate'
|
import {InputDate, utils} from '#/components/forms/InputDate'
|
||||||
import {InputGroup} from '#/components/forms/InputGroup'
|
import {InputGroup} from '#/components/forms/InputGroup'
|
||||||
import {Logo} from '#/view/icons/Logo'
|
|
||||||
import Toggle from '#/components/forms/Toggle'
|
import Toggle from '#/components/forms/Toggle'
|
||||||
import ToggleButton from '#/components/forms/ToggleButton'
|
import ToggleButton from '#/components/forms/ToggleButton'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
|
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
|
||||||
|
|
||||||
export function Forms() {
|
export function Forms() {
|
||||||
const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a'])
|
const [toggleGroupAValues, setToggleGroupAValues] = React.useState(['a'])
|
||||||
@@ -17,6 +18,8 @@ export function Forms() {
|
|||||||
const [toggleGroupCValues, setToggleGroupCValues] = React.useState(['a', 'b'])
|
const [toggleGroupCValues, setToggleGroupCValues] = React.useState(['a', 'b'])
|
||||||
const [toggleGroupDValues, setToggleGroupDValues] = React.useState(['warn'])
|
const [toggleGroupDValues, setToggleGroupDValues] = React.useState(['warn'])
|
||||||
|
|
||||||
|
const [value, setValue] = React.useState('')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[a.gap_4xl, a.align_start]}>
|
<View style={[a.gap_4xl, a.align_start]}>
|
||||||
<H1>Forms</H1>
|
<H1>Forms</H1>
|
||||||
@@ -24,77 +27,43 @@ export function Forms() {
|
|||||||
<View style={[a.gap_md, a.align_start, a.w_full]}>
|
<View style={[a.gap_md, a.align_start, a.w_full]}>
|
||||||
<H3>InputText</H3>
|
<H3>InputText</H3>
|
||||||
|
|
||||||
<InputText
|
<TextField.Input
|
||||||
testID="input"
|
value={value}
|
||||||
accessibilityLabel="Input"
|
onChangeText={setValue}
|
||||||
accessibilityHint="Enter some text"
|
label="Text field"
|
||||||
placeholder="Type here"
|
|
||||||
value=""
|
|
||||||
onChange={text => console.log(text)}
|
|
||||||
/>
|
/>
|
||||||
<InputText
|
|
||||||
hasError
|
<TextField.Root>
|
||||||
testID="input"
|
<TextField.Icon icon={Globe} />
|
||||||
accessibilityLabel="Input"
|
<TextField.Input
|
||||||
accessibilityHint="Enter some text"
|
value={value}
|
||||||
placeholder="Type here"
|
onChangeText={setValue}
|
||||||
value="Test initial value"
|
label="Text field"
|
||||||
onChange={text => console.log(text)}
|
|
||||||
/>
|
/>
|
||||||
<InputText
|
</TextField.Root>
|
||||||
hasError
|
|
||||||
testID="input"
|
<TextField.Root>
|
||||||
accessibilityLabel="Input"
|
<TextField.Icon icon={Globe} />
|
||||||
accessibilityHint="Enter some text"
|
<TextField.Input
|
||||||
placeholder="Type here"
|
value={value}
|
||||||
value="Test initial value"
|
onChangeText={setValue}
|
||||||
onChange={text => console.log(text)}
|
label="Text field"
|
||||||
icon={Logo}
|
|
||||||
/>
|
|
||||||
<InputText
|
|
||||||
testID="input"
|
|
||||||
accessibilityLabel="Input"
|
|
||||||
accessibilityHint="Enter some text"
|
|
||||||
placeholder="Type here"
|
|
||||||
value=""
|
|
||||||
onChange={text => console.log(text)}
|
|
||||||
icon={Logo}
|
|
||||||
/>
|
|
||||||
<InputText
|
|
||||||
testID="input"
|
|
||||||
accessibilityLabel="Input"
|
|
||||||
accessibilityHint="Enter some text"
|
|
||||||
placeholder="Type here"
|
|
||||||
value=""
|
|
||||||
onChange={text => console.log(text)}
|
|
||||||
icon={Logo}
|
|
||||||
suffix={() => <Text>.bksy.social</Text>}
|
|
||||||
/>
|
|
||||||
<InputText
|
|
||||||
multiline
|
|
||||||
numberOfLines={3}
|
|
||||||
testID="input"
|
|
||||||
accessibilityLabel="Input"
|
|
||||||
accessibilityHint="Enter some text"
|
|
||||||
placeholder="Type here"
|
|
||||||
value=""
|
|
||||||
onChange={text => console.log(text)}
|
|
||||||
/>
|
/>
|
||||||
|
<TextField.Suffix label="@gmail.com">@gmail.com</TextField.Suffix>
|
||||||
|
</TextField.Root>
|
||||||
|
|
||||||
<H3>InputDate</H3>
|
<H3>InputDate</H3>
|
||||||
<InputDate
|
<InputDate
|
||||||
testID="date"
|
testID="date"
|
||||||
value={'2001-01-01'}
|
value={'2001-01-01'}
|
||||||
onChange={date => console.log(date)}
|
onChange={date => console.log(date)}
|
||||||
accessibilityLabel="Date"
|
label="Input"
|
||||||
accessibilityHint="Enter a date"
|
|
||||||
/>
|
/>
|
||||||
<InputDate
|
<InputDate
|
||||||
testID="date"
|
testID="date"
|
||||||
value={utils.toSimpleDateString(new Date())}
|
value={utils.toSimpleDateString(new Date())}
|
||||||
onChange={date => console.log(date)}
|
onChange={date => console.log(date)}
|
||||||
accessibilityLabel="Date"
|
label="Input"
|
||||||
accessibilityHint="Enter a date"
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -103,24 +72,21 @@ export function Forms() {
|
|||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputText
|
<InputText
|
||||||
testID="input"
|
testID="input"
|
||||||
accessibilityLabel="Input"
|
label="Input"
|
||||||
accessibilityHint="Enter some text"
|
|
||||||
placeholder="Type here"
|
placeholder="Type here"
|
||||||
value=""
|
value=""
|
||||||
onChange={text => console.log(text)}
|
onChange={text => console.log(text)}
|
||||||
/>
|
/>
|
||||||
<InputText
|
<InputText
|
||||||
testID="input"
|
testID="input"
|
||||||
accessibilityLabel="Input"
|
label="Input"
|
||||||
accessibilityHint="Enter some text"
|
|
||||||
placeholder="Type here"
|
placeholder="Type here"
|
||||||
value=""
|
value=""
|
||||||
onChange={text => console.log(text)}
|
onChange={text => console.log(text)}
|
||||||
/>
|
/>
|
||||||
<InputText
|
<InputText
|
||||||
testID="input"
|
testID="input"
|
||||||
accessibilityLabel="Input"
|
label="Input"
|
||||||
accessibilityHint="Enter some text"
|
|
||||||
placeholder="Type here"
|
placeholder="Type here"
|
||||||
value=""
|
value=""
|
||||||
onChange={text => console.log(text)}
|
onChange={text => console.log(text)}
|
||||||
|
|||||||
Reference in New Issue
Block a user