From fc607775860cf3131ea19f2faf68bfdeb9d87493 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Fri, 25 Sep 2026 12:22:41 -0700 Subject: [PATCH] mobile: draw the cloud scope with the desktop sidebar's cloud glyph Mobile used Lucide's cloud while the desktop sidebar draws Tabler's, so the same workspace read differently on each surface. react-icons is DOM-only, and pulling in @tabler/icons-react-native would ship its whole barrel through Metro for one glyph, so the Tabler path is built with createLucideIcon and keeps working with the Icon wrapper. Co-Authored-By: Claude --- .../(authenticated)/(home)/filter/FilterScreen.tsx | 4 ++-- .../(home)/filter/scope/ScopeFilterScreen.tsx | 4 ++-- .../(home)/home/components/ScopeBar/ScopeBar.tsx | 4 ++-- .../components/CloudIcon/CloudIcon.tsx | 12 ++++++++++++ .../(authenticated)/components/CloudIcon/index.ts | 1 + .../CloudWorkspaceProvisioningState.tsx | 4 ++-- 6 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 apps/mobile/screens/(authenticated)/components/CloudIcon/CloudIcon.tsx create mode 100644 apps/mobile/screens/(authenticated)/components/CloudIcon/index.ts diff --git a/apps/mobile/screens/(authenticated)/(home)/filter/FilterScreen.tsx b/apps/mobile/screens/(authenticated)/(home)/filter/FilterScreen.tsx index 0da03c07090..e589741d586 100644 --- a/apps/mobile/screens/(authenticated)/(home)/filter/FilterScreen.tsx +++ b/apps/mobile/screens/(authenticated)/(home)/filter/FilterScreen.tsx @@ -2,7 +2,6 @@ import Ionicons from "@expo/vector-icons/Ionicons"; import { useLingui } from "@lingui/react/macro"; import { i18n } from "@superset/i18n"; import { Stack, useRouter } from "expo-router"; -import { Cloud } from "lucide-react-native"; import { View } from "react-native"; import { Icon } from "@/components/ui/icon"; import { useTheme } from "@/hooks/useTheme"; @@ -12,6 +11,7 @@ import { } from "@/screens/(authenticated)/(home)/home/stores/workspacesFilterStore"; import { useSelectedHost } from "@/screens/(authenticated)/(home)/hooks/useSelectedHost"; import { useWorkspaceScope } from "@/screens/(authenticated)/(home)/hooks/useWorkspaceScope"; +import { CloudIcon } from "@/screens/(authenticated)/components/CloudIcon"; import { HostStatusDot } from "@/screens/(authenticated)/components/HostStatusDot"; import { ListRow } from "@/screens/(authenticated)/components/ListRow"; import { ListRowValue } from "@/screens/(authenticated)/components/ListRowValue"; @@ -47,7 +47,7 @@ export function FilterScreen() { accessory={ cloud ? ( diff --git a/apps/mobile/screens/(authenticated)/(home)/filter/scope/ScopeFilterScreen.tsx b/apps/mobile/screens/(authenticated)/(home)/filter/scope/ScopeFilterScreen.tsx index f5cfe8e3a2b..f780e77239c 100644 --- a/apps/mobile/screens/(authenticated)/(home)/filter/scope/ScopeFilterScreen.tsx +++ b/apps/mobile/screens/(authenticated)/(home)/filter/scope/ScopeFilterScreen.tsx @@ -1,6 +1,5 @@ import { useLingui } from "@lingui/react/macro"; import { useRouter } from "expo-router"; -import { Cloud } from "lucide-react-native"; import { useMemo } from "react"; import { ScrollView } from "react-native"; import { Icon } from "@/components/ui/icon"; @@ -13,6 +12,7 @@ import { useCloudScopeEnabled, useWorkspaceScope, } from "@/screens/(authenticated)/(home)/hooks/useWorkspaceScope"; +import { CloudIcon } from "@/screens/(authenticated)/components/CloudIcon"; import { HostStatusDot } from "@/screens/(authenticated)/components/HostStatusDot"; import { ListRow } from "@/screens/(authenticated)/components/ListRow"; import { ListRowCheck } from "@/screens/(authenticated)/components/ListRowCheck"; @@ -70,7 +70,7 @@ export function ScopeFilterScreen() { diff --git a/apps/mobile/screens/(authenticated)/(home)/home/components/ScopeBar/ScopeBar.tsx b/apps/mobile/screens/(authenticated)/(home)/home/components/ScopeBar/ScopeBar.tsx index a128dd80aa8..6f03169855a 100644 --- a/apps/mobile/screens/(authenticated)/(home)/home/components/ScopeBar/ScopeBar.tsx +++ b/apps/mobile/screens/(authenticated)/(home)/home/components/ScopeBar/ScopeBar.tsx @@ -1,7 +1,7 @@ -import { Cloud } from "lucide-react-native"; import { View } from "react-native"; import { Icon } from "@/components/ui/icon"; import type { WorkspaceScope } from "@/screens/(authenticated)/(home)/home/stores/workspacesFilterStore"; +import { CloudIcon } from "@/screens/(authenticated)/components/CloudIcon"; import { HostStatusDot } from "@/screens/(authenticated)/components/HostStatusDot"; import { Chip } from "./components/Chip"; @@ -42,7 +42,7 @@ export function ScopeBar({ leading={ cloud ? ( diff --git a/apps/mobile/screens/(authenticated)/components/CloudIcon/CloudIcon.tsx b/apps/mobile/screens/(authenticated)/components/CloudIcon/CloudIcon.tsx new file mode 100644 index 00000000000..557a46ce31c --- /dev/null +++ b/apps/mobile/screens/(authenticated)/components/CloudIcon/CloudIcon.tsx @@ -0,0 +1,12 @@ +import { createLucideIcon } from "lucide-react-native"; + +/** Tabler's cloud, the glyph the desktop sidebar draws for cloud workspaces. */ +export const CloudIcon = createLucideIcon("Cloud", [ + [ + "path", + { + d: "M6.657 18c-2.572 0 -4.657 -2.007 -4.657 -4.483c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.913 0 3.464 1.56 3.464 3.486c0 1.927 -1.551 3.487 -3.465 3.487h-11.878", + key: "cloud", + }, + ], +]); diff --git a/apps/mobile/screens/(authenticated)/components/CloudIcon/index.ts b/apps/mobile/screens/(authenticated)/components/CloudIcon/index.ts new file mode 100644 index 00000000000..a8f67e382e7 --- /dev/null +++ b/apps/mobile/screens/(authenticated)/components/CloudIcon/index.ts @@ -0,0 +1 @@ +export { CloudIcon } from "./CloudIcon"; diff --git a/apps/mobile/screens/(authenticated)/workspace/[id]/components/CloudWorkspaceProvisioningState/CloudWorkspaceProvisioningState.tsx b/apps/mobile/screens/(authenticated)/workspace/[id]/components/CloudWorkspaceProvisioningState/CloudWorkspaceProvisioningState.tsx index 58ee48b8a9f..f33deb73d80 100644 --- a/apps/mobile/screens/(authenticated)/workspace/[id]/components/CloudWorkspaceProvisioningState/CloudWorkspaceProvisioningState.tsx +++ b/apps/mobile/screens/(authenticated)/workspace/[id]/components/CloudWorkspaceProvisioningState/CloudWorkspaceProvisioningState.tsx @@ -3,7 +3,6 @@ import { useRouter } from "expo-router"; import { AlertCircle, Check, - Cloud, GitBranch, type LucideIcon, } from "lucide-react-native"; @@ -15,6 +14,7 @@ import { Text } from "@/components/ui/text"; import { useCloudWorkspaceActions } from "@/hooks/useCloudWorkspaceActions"; import type { CloudWorkspaceRow } from "@/hooks/useCloudWorkspaces"; import { cn } from "@/lib/utils"; +import { CloudIcon } from "@/screens/(authenticated)/components/CloudIcon"; /** * A warm sandbox is up in a second or two; the first ones after an image @@ -64,7 +64,7 @@ export function CloudWorkspaceProvisioningState({ const sandboxReady = cloud.status !== "provisioning"; return ( - +