Skip to content

Commit

Permalink
feat: integrate react-native-uikit-colors for improved theming and UI…
Browse files Browse the repository at this point in the history
… consistency

- Added `react-native-uikit-colors` package to enhance color management.
- Updated `tailwind.config.ts` to utilize `withUIKit` for better color integration.
- Refactored color handling in `colors.ts` and `utils.ts` to leverage the new package.
- Adjusted components to use safe area insets and improved layout in `rsshub-form.tsx`.
- Enhanced `MarkdownWeb` component with custom styles for better rendering.

This update streamlines color management and improves the overall UI experience.

Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Jan 18, 2025
1 parent bbb4e7d commit f947bd1
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 274 deletions.
1 change: 1 addition & 0 deletions apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.1.0",
"react-native-svg": "15.8.0",
"react-native-uikit-colors": "0.1.1",
"react-native-web": "~0.19.13",
"react-native-webview": "13.12.5",
"swiftui-react-native": "6.3.3",
Expand Down
10 changes: 10 additions & 0 deletions apps/mobile/src/components/ui/typography/MarkdownWeb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ const MarkdownWeb: WebComponent<{ value: string; style?: React.CSSProperties }>
className={cn("text-text prose min-w-0", isDarkMode ? "prose-invert" : "prose")}
style={style}
>
<style
dangerouslySetInnerHTML={{
__html: `
body, html {
height: 100%;
overflow: hidden;
}
`,
}}
/>
{useMemo(() => parseMarkdown(value).content, [value])}
</div>
)
Expand Down
11 changes: 8 additions & 3 deletions apps/mobile/src/screens/(modal)/rsshub-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { memo, useEffect, useMemo, useState } from "react"
import { Controller, useForm } from "react-hook-form"
import { Linking, Text, TouchableOpacity, View } from "react-native"
import { KeyboardAwareScrollView } from "react-native-keyboard-controller"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { z } from "zod"

import { HeaderTitleExtra } from "@/src/components/common/HeaderTitleExtra"
Expand Down Expand Up @@ -110,6 +111,7 @@ function FormImpl({ route, routePrefix, name }: RsshubFormParams) {
mode: "all",
})

const insets = useSafeAreaInsets()
return (
<FormProvider form={form}>
<ScreenOptions
Expand All @@ -120,8 +122,11 @@ function FormImpl({ route, routePrefix, name }: RsshubFormParams) {
/>

<PortalProvider>
<KeyboardAwareScrollView className="bg-system-grouped-background">
<View className="bg-secondary-system-grouped-background mx-2 mt-4 gap-4 rounded-lg px-3 py-6">
<KeyboardAwareScrollView
className="bg-system-grouped-background"
contentContainerStyle={{ paddingBottom: insets.bottom, flexGrow: 1 }}
>
<View className="bg-secondary-system-grouped-background mx-2 mt-2 gap-4 rounded-lg px-3 py-6">
{keys.map((keyItem) => {
const parameters = normalizeRSSHubParameters(route.parameters[keyItem.name])

Expand Down Expand Up @@ -183,7 +188,7 @@ function FormImpl({ route, routePrefix, name }: RsshubFormParams) {
<Maintainers maintainers={route.maintainers} />

{!!route.description && (
<View className="mx-4 mt-4">
<View className="bg-system-background mt-4 flex-1 px-4">
<MarkdownWeb
value={route.description.replaceAll("::: ", ":::")}
dom={{ matchContents: true, scrollEnabled: false }}
Expand Down
165 changes: 1 addition & 164 deletions apps/mobile/src/theme/colors.ts
Original file line number Diff line number Diff line change
@@ -1,166 +1,3 @@
import { rgbStringToRgb } from "@follow/utils"
import { useColorScheme, vars } from "nativewind"
import { useMemo } from "react"

// @ts-expect-error
const IS_DOM = typeof ReactNativeWebView !== "undefined"

const varPrefix = "--color"
export const accentColor = "#FF5C00"
export const buildVars = (_vars: Record<string, string>) => {
const cssVars = {} as Record<`${typeof varPrefix}-${string}`, string>
for (const [key, value] of Object.entries(_vars)) {
cssVars[`${varPrefix}-${key}`] = value
}

return IS_DOM ? cssVars : vars(cssVars)
}

const lightPalette = {
red: "255 59 48",
orange: "255 149 0",
yellow: "255 204 0",
green: "52 199 89",
mint: "0 199 190",
teal: "48 176 190",
cyan: "50 173 200",
blue: "0 122 255",
indigo: "88 86 214",
purple: "175 82 222",
pink: "255 45 85",
brown: "162 132 94",
gray: "142 142 147",
gray2: "172 172 178",
gray3: "199 199 204",
gray4: "209 209 214",
gray5: "229 229 234",
gray6: "242 242 247",
}
const darkPalette = {
red: "255 69 58",
orange: "255 175 113",
yellow: "255 214 10",
green: "48 209 88",
mint: "99 230 226",
teal: "64 200 244",
cyan: "100 210 255",
blue: "10 132 255",
indigo: "94 92 230",
purple: "191 90 242",
pink: "255 55 95",
brown: "172 142 104",
gray: "142 142 147",
gray2: "99 99 102",
gray3: "72 72 74",
gray4: "58 58 60",
gray5: "44 44 46",
gray6: "28 28 30",
}
export const palette = {
// iOS color palette https://developer.apple.com/design/human-interface-guidelines/color
light: buildVars(lightPalette),
dark: buildVars(darkPalette),
}

export const lightVariants = {
// UIKit Colors

placeholderText: "199 199 204",
separator: "84 84 86 0.34",
opaqueSeparator: "84 84 86 0.34",
nonOpaqueSeparator: "198 198 200",
link: "0 122 255",

systemBackground: "255 255 255",
secondarySystemBackground: "242 242 247",
tertiarySystemBackground: "255 255 255",

// Grouped
systemGroupedBackground: "242 242 247",
secondarySystemGroupedBackground: "255 255 255",
tertiarySystemGroupedBackground: "242 242 247",

// System Colors
systemFill: "120 120 128 0.2",
secondarySystemFill: "120 120 128 0.16",
tertiarySystemFill: "120 120 128 0.12",
quaternarySystemFill: "120 120 128 0.08",

// Text Colors
label: "0 0 0",
text: "0 0 0",
secondaryLabel: "60 60 67 0.6",
tertiaryLabel: "60 60 67 0.3",
quaternaryLabel: "60 60 67 0.18",

// Extended colors
disabled: "235 235 228",
itemPressed: "229 229 234",
}
export const darkVariants = {
// UIKit Colors

placeholderText: "122 122 122",
separator: "56 56 58 0.6",
opaqueSeparator: "56 56 58 0.6",
nonOpaqueSeparator: "84 84 86",
link: "10 132 255",
systemBackground: "0 0 0",
secondarySystemBackground: "28 28 30",
tertiarySystemBackground: "44 44 46",

// Grouped
systemGroupedBackground: "0 0 0",
secondarySystemGroupedBackground: "28 28 30",
tertiarySystemGroupedBackground: "44 44 46",

// System Colors
systemFill: "120 120 128 36",
secondarySystemFill: "120 120 128 0.32",
tertiarySystemFill: "120 120 128 0.24",
quaternarySystemFill: "120 120 128 0.19",

// Text Colors
label: "255 255 255",
text: "255 255 255",
secondaryLabel: "235 235 245 0.6",
tertiaryLabel: "235 235 245 0.3",
quaternaryLabel: "235 235 245 0.18",

// Extended colors
disabled: "85 85 85",
itemPressed: "44 44 46",
}

/// Utils

const mergedLightColors = {
...lightVariants,
...lightPalette,
}
const mergedDarkColors = {
...darkVariants,
...darkPalette,
}
const mergedColors = {
light: mergedLightColors,
dark: mergedDarkColors,
}

export const colorVariants = {
light: buildVars(lightVariants),
dark: buildVars(darkVariants),
}

export const useColor = (color: keyof typeof mergedLightColors) => {
const { colorScheme } = useColorScheme()
const colors = mergedColors[colorScheme || "light"]
return useMemo(() => rgbStringToRgb(colors[color]), [color, colors])
}

export const useColors = () => {
const { colorScheme } = useColorScheme()
return mergedColors[colorScheme || "light"]
}

export type Colors = typeof mergedLightColors
export * from "react-native-uikit-colors"
22 changes: 1 addition & 21 deletions apps/mobile/src/theme/utils.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1 @@
import { rgbStringToRgb } from "@follow/utils"
import type { StyleProp, ViewStyle } from "react-native"
import { Appearance, StyleSheet } from "react-native"

import { colorVariants, darkVariants, lightVariants, palette } from "./colors"

export const getCurrentColors = () => {
const colorScheme = Appearance.getColorScheme() || "light"

return StyleSheet.compose(
colorVariants[colorScheme],
palette[colorScheme],
) as StyleProp<ViewStyle>
}

export const getSystemBackgroundColor = () => {
const colorScheme = Appearance.getColorScheme() || "light"

const colors = colorScheme === "light" ? lightVariants : darkVariants
return rgbStringToRgb(colors.systemBackground)
}
export { getCurrentColors, getSystemBackgroundColor } from "react-native-uikit-colors"
25 changes: 1 addition & 24 deletions apps/mobile/src/theme/web.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1 @@
import { useInsertionEffect } from "react"
import { useDarkMode } from "usehooks-ts"

import { colorVariants, palette } from "./colors"

export const useCSSInjection = () => {
const isDark = useDarkMode().isDarkMode

useInsertionEffect(() => {
const style = document.createElement("style")

const vars1 = colorVariants[isDark ? "dark" : "light"]
const vars2 = palette[isDark ? "dark" : "light"]

style.innerHTML = `:root {${[...Object.entries(vars1), ...Object.entries(vars2)]
.map(([key, value]) => `${key}: ${value};`)
.join("\n")}}`

document.head.append(style)
return () => {
style.remove()
}
}, [isDark])
}
export { useCSSInjection } from "react-native-uikit-colors/dist/web"
60 changes: 2 additions & 58 deletions apps/mobile/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('tailwindcss').Config} */
import resolveConfig from "tailwindcss/resolveConfig"
import { withUIKit } from "react-native-uikit-colors/tailwind"

export default resolveConfig({
export default withUIKit({
darkMode: "class",
content: ["./src/**/*.{js,jsx,ts,tsx}"],
presets: [require("nativewind/preset")],
Expand All @@ -15,62 +15,6 @@ export default resolveConfig({
},
colors: {
accent: "#FF5C00",
// Palette colors
red: "rgb(var(--color-red) / <alpha-value>)",
orange: "rgb(var(--color-orange) / <alpha-value>)",
yellow: "rgb(var(--color-yellow) / <alpha-value>)",
green: "rgb(var(--color-green) / <alpha-value>)",
mint: "rgb(var(--color-mint) / <alpha-value>)",
teal: "rgb(var(--color-teal) / <alpha-value>)",
cyan: "rgb(var(--color-cyan) / <alpha-value>)",
blue: "rgb(var(--color-blue) / <alpha-value>)",
indigo: "rgb(var(--color-indigo) / <alpha-value>)",
purple: "rgb(var(--color-purple) / <alpha-value>)",
pink: "rgb(var(--color-pink) / <alpha-value>)",
brown: "rgb(var(--color-brown) / <alpha-value>)",
gray: {
DEFAULT: "rgb(var(--color-gray) / <alpha-value>)",
2: "rgb(var(--color-gray2) / <alpha-value>)",
3: "rgb(var(--color-gray3) / <alpha-value>)",
4: "rgb(var(--color-gray4) / <alpha-value>)",
5: "rgb(var(--color-gray5) / <alpha-value>)",
6: "rgb(var(--color-gray6) / <alpha-value>)",
},

// System colors

"placeholder-text": "rgb(var(--color-placeholderText) / <alpha-value>)",
separator: "rgb(var(--color-separator) / <alpha-value>)",
"opaque-separator": "rgba(var(--color-opaqueSeparator))",
"non-opaque-separator": "rgba(var(--color-nonOpaqueSeparator))",
link: "rgb(var(--color-link) / <alpha-value>)",

// Backgrounds
"system-background": "rgb(var(--color-systemBackground) / <alpha-value>)",
"secondary-system-background":
"rgb(var(--color-secondarySystemBackground) / <alpha-value>)",
"tertiary-system-background": "rgb(var(--color-tertiarySystemBackground) / <alpha-value>)",
"system-grouped-background": "rgb(var(--color-systemGroupedBackground) / <alpha-value>)",
"secondary-system-grouped-background":
"rgb(var(--color-secondarySystemGroupedBackground) / <alpha-value>)",
"tertiary-system-grouped-background":
"rgb(var(--color-tertiarySystemGroupedBackground) / <alpha-value>)",
// System fills
"system-fill": "rgba(var(--color-systemFill))",
"secondary-system-fill": "rgba(var(--color-secondarySystemFill))",
"tertiary-system-fill": "rgba(var(--color-tertiarySystemFill))",
"quaternary-system-fill": "rgba(var(--color-quaternarySystemFill))",

// Text colors
label: "rgb(var(--color-text) / <alpha-value>)",
text: "rgb(var(--color-text) / <alpha-value>)",
"secondary-label": "rgba(var(--color-secondaryLabel))",
"tertiary-label": "rgba(var(--color-tertiaryLabel))",
"quaternary-label": "rgba(var(--color-quaternaryLabel))",

// Extended colors
disabled: "rgb(var(--color-disabled) / <alpha-value>)",
"item-pressed": "rgb(var(--color-itemPressed) / <alpha-value>)",
},
},
},
Expand Down
Loading

0 comments on commit f947bd1

Please sign in to comment.