diff options
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/forms/HostingProvider.tsx | 69 | ||||
-rw-r--r-- | src/components/forms/TextField.tsx | 8 | ||||
-rw-r--r-- | src/components/icons/Lock.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/Pencil.tsx | 5 | ||||
-rw-r--r-- | src/components/icons/Ticket.tsx | 5 |
5 files changed, 91 insertions, 1 deletions
diff --git a/src/components/forms/HostingProvider.tsx b/src/components/forms/HostingProvider.tsx new file mode 100644 index 000000000..df506b77c --- /dev/null +++ b/src/components/forms/HostingProvider.tsx @@ -0,0 +1,69 @@ +import React from 'react' +import {TouchableOpacity, View} from 'react-native' + +import {isAndroid} from '#/platform/detection' +import {atoms as a, useTheme} from '#/alf' +import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' +import {Pencil_Stroke2_Corner0_Rounded as Pencil} from '#/components/icons/Pencil' +import * as TextField from './TextField' +import {useDialogControl} from '../Dialog' +import {Text} from '../Typography' +import {ServerInputDialog} from '#/view/com/auth/server-input' +import {toNiceDomain} from '#/lib/strings/url-helpers' + +export function HostingProvider({ + serviceUrl, + onSelectServiceUrl, + onOpenDialog, +}: { + serviceUrl: string + onSelectServiceUrl: (provider: string) => void + onOpenDialog?: () => void +}) { + const serverInputControl = useDialogControl() + const t = useTheme() + + const onPressSelectService = React.useCallback(() => { + serverInputControl.open() + if (onOpenDialog) { + onOpenDialog() + } + }, [onOpenDialog, serverInputControl]) + + return ( + <> + <ServerInputDialog + control={serverInputControl} + onSelect={onSelectServiceUrl} + /> + <TouchableOpacity + accessibilityRole="button" + style={[ + a.w_full, + a.flex_row, + a.align_center, + a.rounded_sm, + a.px_md, + a.gap_xs, + {paddingVertical: isAndroid ? 14 : 9}, + t.atoms.bg_contrast_25, + ]} + onPress={onPressSelectService}> + <TextField.Icon icon={Globe} /> + <Text style={[a.text_md]}>{toNiceDomain(serviceUrl)}</Text> + <View + style={[ + a.rounded_sm, + t.atoms.bg_contrast_100, + {marginLeft: 'auto', left: 6, padding: 6}, + ]}> + <Pencil + style={{color: t.palette.contrast_500}} + height={18} + width={18} + /> + </View> + </TouchableOpacity> + </> + ) +} diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index b37f4bfae..3cffe5b2b 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -14,6 +14,7 @@ import {useTheme, atoms as a, web, android} from '#/alf' import {Text} from '#/components/Typography' import {useInteractionState} from '#/components/hooks/useInteractionState' import {Props as SVGIconProps} from '#/components/icons/common' +import {mergeRefs} from '#/lib/merge-refs' const Context = React.createContext<{ inputRef: React.RefObject<TextInput> | null @@ -128,6 +129,7 @@ export type InputProps = Omit<TextInputProps, 'value' | 'onChangeText'> & { value: string onChangeText: (value: string) => void isInvalid?: boolean + inputRef?: React.RefObject<TextInput> } export function createInput(Component: typeof TextInput) { @@ -137,6 +139,7 @@ export function createInput(Component: typeof TextInput) { value, onChangeText, isInvalid, + inputRef, ...rest }: InputProps) { const t = useTheme() @@ -161,19 +164,22 @@ export function createInput(Component: typeof TextInput) { ) } + const refs = mergeRefs([ctx.inputRef, inputRef!].filter(Boolean)) + return ( <> <Component accessibilityHint={undefined} {...rest} accessibilityLabel={label} - ref={ctx.inputRef} + ref={refs} value={value} onChangeText={onChangeText} onFocus={ctx.onFocus} onBlur={ctx.onBlur} placeholder={placeholder || label} placeholderTextColor={t.palette.contrast_500} + keyboardAppearance={t.name === 'light' ? 'light' : 'dark'} hitSlop={HITSLOP_20} style={[ a.relative, diff --git a/src/components/icons/Lock.tsx b/src/components/icons/Lock.tsx new file mode 100644 index 000000000..87830b379 --- /dev/null +++ b/src/components/icons/Lock.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Lock_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M7 7a5 5 0 0 1 10 0v2h1a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2h1V7Zm-1 4v9h12v-9H6Zm9-2H9V7a3 3 0 1 1 6 0v2Zm-3 4a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Z', +}) diff --git a/src/components/icons/Pencil.tsx b/src/components/icons/Pencil.tsx new file mode 100644 index 000000000..1b7fc17cf --- /dev/null +++ b/src/components/icons/Pencil.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Pencil_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M13.586 1.5a2 2 0 0 1 2.828 0L19.5 4.586a2 2 0 0 1 0 2.828l-13 13A2 2 0 0 1 5.086 21H1a1 1 0 0 1-1-1v-4.086A2 2 0 0 1 .586 14.5l13-13ZM15 2.914l-13 13V19h3.086l13-13L15 2.914ZM11 20a1 1 0 0 1 1-1h7a1 1 0 1 1 0 2h-7a1 1 0 0 1-1-1Z', +}) diff --git a/src/components/icons/Ticket.tsx b/src/components/icons/Ticket.tsx new file mode 100644 index 000000000..1a8059c2a --- /dev/null +++ b/src/components/icons/Ticket.tsx @@ -0,0 +1,5 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Ticket_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M4 5.5a.5.5 0 0 0-.5.5v2.535a.5.5 0 0 0 .25.433A3.498 3.498 0 0 1 5.5 12a3.498 3.498 0 0 1-1.75 3.032.5.5 0 0 0-.25.433V18a.5.5 0 0 0 .5.5h16a.5.5 0 0 0 .5-.5v-2.535a.5.5 0 0 0-.25-.433A3.498 3.498 0 0 1 18.5 12a3.5 3.5 0 0 1 1.75-3.032.5.5 0 0 0 .25-.433V6a.5.5 0 0 0-.5-.5H4ZM2.5 6A1.5 1.5 0 0 1 4 4.5h16A1.5 1.5 0 0 1 21.5 6v3.17a.5.5 0 0 1-.333.472 2.501 2.501 0 0 0 0 4.716.5.5 0 0 1 .333.471V18a1.5 1.5 0 0 1-1.5 1.5H4A1.5 1.5 0 0 1 2.5 18v-3.17a.5.5 0 0 1 .333-.472 2.501 2.501 0 0 0 0-4.716.5.5 0 0 1-.333-.471V6Zm12 2a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Zm0 4a.5.5 0 1 1 1 0 .5.5 0 0 1-1 0Z', +}) |