From ed86f7ef012fb558fe8a8974e1e162ce75cbfd15 Mon Sep 17 00:00:00 2001
From: Mohamed Bassem <me@mbassem.com>
Date: Tue, 26 Aug 2025 15:47:05 +0300
Subject: feat(mobile): Retheme the mobile app (#1872)

* Add nativewindui

* migrate to nativewindui text

* Replace buttons with nativewindui buttons

* Use nativewindui search input

* fix the divider color

* More changes

* fix manage tag icon

* fix styling of bookmark card

* fix ios compilation

* fix search clear

* fix tag pill border color

* Store theme setting in app settings

* fix setting color appearance

* fix coloring of search input

* fix following system theme

* add a save button to info

* fix the grey colors on android

* fix icon active tint color

* drop the use of TextField
---
 .../components/ui/SearchInput/SearchInput.tsx      | 114 +++++++++++++++++++++
 1 file changed, 114 insertions(+)
 create mode 100644 apps/mobile/components/ui/SearchInput/SearchInput.tsx

(limited to 'apps/mobile/components/ui/SearchInput/SearchInput.tsx')

diff --git a/apps/mobile/components/ui/SearchInput/SearchInput.tsx b/apps/mobile/components/ui/SearchInput/SearchInput.tsx
new file mode 100644
index 00000000..7e816ab6
--- /dev/null
+++ b/apps/mobile/components/ui/SearchInput/SearchInput.tsx
@@ -0,0 +1,114 @@
+import * as React from "react";
+import { Pressable, TextInput, View } from "react-native";
+import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
+import { TailwindResolver } from "@/components/TailwindResolver";
+import { Button } from "@/components/ui/Button";
+import { useColorScheme } from "@/lib/useColorScheme";
+import { cn } from "@/lib/utils";
+import { useAugmentedRef, useControllableState } from "@rn-primitives/hooks";
+import { Icon } from "@roninoss/icons";
+
+import type { SearchInputProps } from "./types";
+
+const SearchInput = React.forwardRef<
+  React.ElementRef<typeof TextInput>,
+  SearchInputProps
+>(
+  (
+    {
+      value: valueProp,
+      onChangeText: onChangeTextProp,
+      placeholder = "Search...",
+      containerClassName,
+      iconContainerClassName,
+      className,
+      onCancel,
+      ...props
+    },
+    ref,
+  ) => {
+    const { colors } = useColorScheme();
+    const inputRef = useAugmentedRef({ ref, methods: { focus, blur, clear } });
+    const [value = "", onChangeText] = useControllableState({
+      prop: valueProp,
+      defaultProp: valueProp ?? "",
+      onChange: onChangeTextProp,
+    });
+
+    function focus() {
+      inputRef.current?.focus();
+    }
+
+    function blur() {
+      inputRef.current?.blur();
+    }
+
+    function clear() {
+      onCancel?.();
+      onChangeText("");
+    }
+
+    return (
+      <Button
+        variant="plain"
+        className={cn(
+          "android:gap-0 android:h-14 flex-row items-center rounded-full bg-card px-2",
+          containerClassName,
+        )}
+        onPress={focus}
+      >
+        <View
+          className={cn("p-2", iconContainerClassName)}
+          pointerEvents="none"
+        >
+          <TailwindResolver
+            className="text-muted"
+            comp={(styles) => (
+              <Icon
+                color={styles?.color?.toString()}
+                name="magnify"
+                size={24}
+              />
+            )}
+          />
+        </View>
+
+        <View className="flex-1" pointerEvents="none">
+          <TextInput
+            ref={inputRef}
+            placeholder={placeholder}
+            className={cn(
+              "flex-1 rounded-r-full p-2 text-[17px] text-foreground placeholder:text-muted",
+              className,
+            )}
+            placeholderTextColor={colors.foreground}
+            value={value}
+            onChangeText={onChangeText}
+            role="searchbox"
+            {...props}
+          />
+        </View>
+        {!!value && (
+          <Animated.View entering={FadeIn} exiting={FadeOut.duration(150)}>
+            <Pressable className="p-2" onPress={clear}>
+              <TailwindResolver
+                className="text-muted"
+                comp={(styles) => (
+                  <Icon
+                    name="close"
+                    size={24}
+                    color={styles?.color?.toString()}
+                  />
+                )}
+              />
+            </Pressable>
+          </Animated.View>
+        )}
+      </Button>
+    );
+  },
+);
+
+SearchInput.displayName = "SearchInput";
+
+export { SearchInput };
-- 
cgit v1.2.3-70-g09d2

