about summary refs log tree commit diff
path: root/src/components/forms
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/forms')
-rw-r--r--src/components/forms/HostingProvider.tsx69
-rw-r--r--src/components/forms/TextField.tsx8
2 files changed, 76 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,