frappe / frappe-ui

A set of components and utilities for rapid UI development
https://frappeui.com
MIT License
256 stars 109 forks source link

feat: ListView component #105

Closed shariquerik closed 11 months ago

shariquerik commented 11 months ago

Simple List:

image

<ListView :columns="columns" :rows="rows" row-key="id" />

const columns = [
  {
    label: 'Name',
    key: 'name',
    width: 5,
  },
  {
    label: 'Email',
    key: 'email',
    width: '200px',
  },
  {
    label: 'Role',
    key: 'role',
  },
  {
    label: 'Status',
    key: 'status',
  },
]

const rows = [
  {
    id: 1,
    row: {
      name: 'John Doe',
      email: 'john@doe.com',
      status: 'Active',
      role: 'Developer',
    },
    onClick: () => console.log('John Doe was clicked'),
  },
  {
    id: 2,
    row: {
      name: 'Jane Doe',
      email: 'jane@doe.com',
      status: 'Inactive',
      role: 'HR',
    },
    route: { name: 'User', params: { userId: 2 } },
  },
]

Dynamic List: You can add prefix/suffix icon to header & row items or add your own custom item

image

<ListView :columns="columns" :rows="rows" row-key="id">
  <ListHeader>
    <ListHeaderItem v-for="column in columns" :key="column.key" :column="column">
        <template #prefix="{ column }">
          <FeatherIcon v-if="column.key == 'name'" name="user" class="h-4 w-4" />
          <FeatherIcon
            v-else-if="column.key == 'email'"
            name="at-sign"
            class="h-3.5 w-3.5"
          />
        </template>
    </ListHeaderItem>
  </ListHeader>
  <ListRows>
    <ListRow v-for="(row, i) in rows" :key="row['name']" v-slot="{ column, item }" :row="row" :idx="i">
      <ListRowItem :item="item" :type="column.type" :align="column.align">
        <template #prefix>
          <IndicatorIcon
            v-if="column.key == 'status'"
            :class="item.color"
          />
        </template>
        <Badge
          v-if="column.key == 'role'"
          variant="subtle"
          :theme="item.color"
          size="md"
          :label="item.label"
        />
      </ListRowItem>
    </ListRow>
  </ListRows>
  <ListSelectBanner />
</ListView>

const columns = [
  {
    label: 'Name',
    key: 'name',
    width: 5,
  },
  {
    label: 'Email',
    key: 'email',
    width: '200px',
  },
  {
    label: 'Role',
    key: 'role',
  },
  {
    label: 'Status',
    key: 'status',
  },
]

const rows = [
  {
    id: 1,
    row: {
      name: 'John Doe',
      email: 'john@doe.com',
      status: {
        label: 'Active',
        color: 'text-green-600',
      },
      role: {
        label: 'Developer',
        color: 'green',
      },
    },
    onClick: () => console.log('John Doe was clicked'),
  },
  {
    id: 2,
    row: {
      name: 'Jane Doe',
      email: 'jane@doe.com',
      status: {
        label: 'Inactive',
        color: 'text-red-600',
      },
      role: {
        label: 'HR',
        color: 'red',
      },
    },
    route: { name: 'User', params: { userId: 2 } },
  },
]

Selection Banner:

Without custom action buttons:

image

With custom action buttons:

image
<ListSelectBanner>
    <template #actions>
      <div class="flex gap-2">
        <Button variant="ghost" label="Delete" />
        <Button variant="ghost" label="Edit" />
      </div>
    </template>
</ListSelectBanner>

You can also make your own custom selection banner

image
<ListSelectBanner>
    <div>Custom Banner</div>
</ListSelectBanner>
image

Column:

  1. label & key is required in column object.

  2. width is optional and it is used to set column width in list

    1. If you need a column to be 3 times a default column then add 3. if width is not mentioned default will be 1
    2. You can also add custom width in px and rem e.g 300px or 12rem
    3. Combination of both can also be used.
  3. align is also optional. You can change the alignment of the content in the column by setting it as.

    1. start or left (default)
    2. center or middle
    3. end or right
  4. You can add more attributes which can be used to render custom column header items.

Row

  1. The row object must contain a unique_key which was mentioned in ListView row-key

  2. You can either add all row fields in a separate row object or just add them in directly if the fieldnames doesn't conflict with route or onClick E.g. 1

    {
        // unique_key 'id'
        id: 1,
        // row fields
        name: 'John Doe',
        age: 25,
        email: 'john@doe.com',
        // if you need to route
        route: { label: 'User', { params: { userId: 1 } }
        // if you need to perform action
        onClick: () => console.log('John Doe was clicked')
        // you can add more options after this which you can use to render custom row items
    }

    E.g. 2

    {
        // unique_key 'id'
        id: 1,
        // row fields in separate row object
        row: {
            name: 'John Doe',
            age: 25,
            email: 'john@doe.com',
            route: '', // used separate row to avoid this conflict
        }
        // if you need to route
        route: { label: 'User', { params: { userId: 1 } }
        // if you need to perform action
        onClick: () => console.log('John Doe was clicked')
        // you can add more options after this which you can use to render custom row items
    }
  3. You can also add an object for the field value but make sure it has a label attribute which holds the actual value to be shown

    row: {
        name: {
            label: 'John Doe',
            image: '/johndoe.jpg',
        },
        age: 25,
        status: {
            label: 'Active',
            color: 'green'
        }
    }
  4. Click action: Add route or onClick event in row object

    1. If you want to route using router-link just add a route: { name: 'User', params: { userId: 2 } }
    2. if you need to do some action or open a dialog add a click event instead of a route onClick: () => console.log('John Doe was clicked')
netlify[bot] commented 11 months ago

Deploy Preview for frappeui ready!

Name Link
Latest commit a10874eef82fc062cf1a32e894240d30d900d3d3
Latest deploy log https://app.netlify.com/sites/frappeui/deploys/652bb1996cee230008209c5b
Deploy Preview https://deploy-preview-105--frappeui.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

shariquerik commented 11 months ago

Refactor PR: https://github.com/frappe/frappe-ui/pull/106