expo-starter / expo-local-first-template

📱 A template for your local-first Expo project: Bun, Expo 51, TypeScript, TailwindCSS, DrizzleORM, Sqlite, EAS, GitHub Actions, Env Vars, expo-router, react-hook-form.
https://expostarter.com
Apache License 2.0
174 stars 10 forks source link

Add List & List item component #8

Closed fluid-design-io closed 3 months ago

fluid-design-io commented 4 months ago

was thinking about creating a list component which is widely used in mobile applications, and I also loved using ionic's IonItem component back in the old days. So I've created a simple List and ListItem component combined with cva() to create different variants.

In addition, users can also pass href directly to convert it into an Expo Link Component, here's the example screenshot: CleanShot 2024-05-30 at 10 03 49@2x

The rounded corners are automatically added to the first & last ListItem

Note: I've generalized and added some a11y props to make it more accessible. Here's an example setup:

Example


import { ExternalLink } from "lucide-react-native";
import { useState } from "react";
import { View } from "react-native";

import { PlusCircle } from "~/components/Icons";
import List, { ListHeader } from "~/components/ui/list";
import ListItem from "~/components/ui/list-item";
import { Switch } from "~/components/ui/switch";
import { Muted } from "~/components/ui/typography";

function Test() {
  const [value, setValue] = useState(false)
  const onChange = (value: boolean) => {
    setValue(value)
  }
  return (
    <View className="flex-1 w-full px-6 pt-12 bg-muted gap-y-6">
      <List>
        <ListHeader>
          <Muted>Settings</Muted>
        </ListHeader>
        <ListItem
          itemLeft={(props) => <PlusCircle {...props} />} // props adds size and color attributes
          label="General"
          href="/general" // automatically adds a ">" icon
        />
        <ListItem
          itemRight={(props) => <ExternalLink {...props} />} // overwrite default ">" icon
          label="Help"
          href="/help"
          variant='link' // change the variant
        />
        <ListItem
          label="Dark Mode"
          itemRight={() => <Switch
            onCheckedChange={onChange}
            checked={value}
          />} // can pass any component
        />
      </List>
      <List>
        <ListItem
          label="Logout"
          variant='destructive'
          onPress={() => {
            console.log('logout')
          }}
          detail={false} // no ">" icon despite pressable
        />
      </List>
    </View>
  )
}

export default Test
younes200 commented 3 months ago

Thank you @fluid-design-io for your contribution. It would be wonderful to include an example of a settings screen. What do you think?