nuxt / ui

A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.
https://ui.nuxt.com
MIT License
3.88k stars 480 forks source link

[Table] New generic slots. #1931

Closed caiotarifa closed 3 weeks ago

caiotarifa commented 3 months ago

Description

Currently, we have slots named <column>-header and <column>-data. However, in some scenarios, it may be necessary to intercept all cells, regardless of the column name.

It would be beneficial to introduce generic header and data slots.

<UTable>
  <template #data="{ row }">
    Now, all data cells are equal.
  </template>
</UTable>

Additional context

No response

migro1982 commented 3 months ago

I'm also looking for a way to manipulate the header because I would like to display icons there

caiotarifa commented 3 months ago

I'm also looking for a way to manipulate the header because I would like to display icons there

@migro1982 you can do something like this.

It's not as obvious as proposed in the issue, but it solves the problem.

<template
  v-for="header in headers"
  :key="header.key"
  #[`${header.key}-header`]="{ column }"
>
  Slot of "{{ column }}"
</template>
Nyantekyi commented 2 months ago

This would be so helpful... this is my current set up


<script setup lang="ts">
import { z } from "zod";
import type { FormError, FormSubmitEvent } from "#ui/types";
const formtype = z.object({
  name: z.string(),
  title: z.string(),
  email: z.string().email(),
  role: z.string(),
});

const datatype = z.object({
  id: z.number(),
  name: z.string(),
  title: z.string(),
  email: z.string().email(),
  role: z.string(),
});
type dataschema = z.output<typeof datatype>;

const people = reactive<dataschema[]>([
  {
    id: 1,
    name: "Lindsay Walton",
    title: "Front-end Developer",
    email: "lindsay.walton@example.com",
    role: "Member",
  },
  {
    id: 2,
    name: "Courtney Henry",
    title: "Designer",
    email: "courtney.henry@example.com",
    role: "Admin",
  },
  {
    id: 3,
    name: "Tom Cook",
    title: "Director of Product",
    email: "tom.cook@example.com",
    role: "Member",
  },
  {
    id: 4,
    name: "Whitney Francis",
    title: "Copywriter",
    email: "whitney.francis@example.com",
    role: "Admin",
  },
  {
    id: 5,
    name: "Leonard Krasner",
    title: "Senior Designer",
    email: "leonard.krasner@example.com",
    role: "Owner",
  },
]);
const edit = ref<boolean>(false);
const editIndex = ref<number>();
function select(row: dataschema) {
  edit.value = true;
  editIndex.value = row.id;
}

// const selected = ref([people[1]]);
</script>

<template>
  <UTable :rows="people" @select="select">
    <template #name-data="{ row }">
      <div class="flex items-center">
        <!-- Create a uinput that only shows when editindex is row.id else show row content -->

        <UInput v-if="editIndex === row.id" v-model="row.name" :state="row.name" />
        <span v-else>{{ row.name }}</span>
      </div>
    </template>
    <template #title-data="{ row }">
      <div class="flex items-center">
        <UInput v-if="editIndex === row.id" v-model="row.title" :state="row.title" />
        <span v-else>{{ row.title }}</span>
      </div>
    </template>
    <template #email-data="{ row }">
      <div class="flex items-center">
        <UForm :schema="datatype" :state="row">
          <UFormGroup name="email">
            <UInput v-if="editIndex === row.id" v-model="row.email" />
            <span v-else>{{ row.email }}</span>
          </UFormGroup>
        </UForm>
        <!-- <UInput v-if="editIndex === row.id" v-model="row.email" :state="row.email" /> -->
      </div>
    </template>

    <template #role-data="{ row }">
      <div class="flex items-center">
        <USelect
          v-if="editIndex === row.id"
          v-model="row.role"
          :state="row.role"
          :options="[
            { value: 'Admin', label: 'Admin' },
            { value: 'Member', label: 'Member' },
            { value: 'Owner', label: 'Owner' },
          ]"
        />
        <span v-else>{{ row.role }}</span>
      </div>
    </template>
  </UTable>
</template>

I would really prefer it if I could indicate a condition for when the row is selected and present the complete form with validation else default to the table data... This is my implementation of utable with form input

Nyantekyi commented 2 months ago

@benjamincanac An I deal situation for me is something similar to what primevue did here https://tailwind.primevue.org/datatable/#cell_edit

benjamincanac commented 2 months ago

@Nyantekyi I'll keep this in mind when building the Table component for v3 😊

benjamincanac commented 3 weeks ago

Duplicate #818.