Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Table] Allow to collapse a row cells vertically on a breakpoint #527

Open
DarkGhostHunter opened this issue Aug 11, 2023 · 1 comment
Open
Labels
enhancement New feature or request

Comments

@DarkGhostHunter
Copy link
Contributor

Is your feature request related to a problem? Please describe.

Currently, tables work like normal HTML tables. This means that on small screens the width will mostly/always exceed the device width, leaving the user to scroll down through the results.

Describe the solution you'd like

Instead of letting the user scrolling and hide the information from other columns due to the device width, I think a good solution would be to collapse the cells vertically:

  • Headers would be kept as-is, allowing the user to scroll through the header columns.
  • The rest of the Table functionality would be kept intact.

Describe alternatives you've considered

Creating my own table with using table CSS properties is cumbersome and using HTML's <table> doesn't leave space for creativity.

Also, since it's not a Nuxt UI Table, all functionality is lost and must be made from scratch (or forked).

Additional context

The other approach is to create a new Data element called List that would work as table-like, but use <div> internally, use CSS to be presented as table-like, offer the same features (sorting, pagination, etc.) , and configure a breakpoint to transform the list into a grid.

@DarkGhostHunter DarkGhostHunter added the enhancement New feature or request label Aug 11, 2023
@galexrt
Copy link
Contributor

galexrt commented Apr 7, 2024

From my perspective, as a short-term "workaround," it would be good if there was a way to apply classes to the data columns directly, e.g., rowClass property, from the columns list. This would allow us to be easily be able to use media queries to hide/show/"combine" data where appropriate.

columns
{ [key: string]: any; key: string; sortable?: boolean; sort?: (a: any, b: any, direction: "asc" | "desc") => number; direction?: "asc" | "desc";
class?: string; rowClass?: string }[]

These classes would then be applied to the columns to hide/display them to improve visibility for smaller screens, as it heavily depends on the data if it can be hidden on smaller screens or combined with other columns.

const columns = [
   {
        key: 'test1',
        label: 'Big Screen',
        class: 'hidden lg:block',
        rowClass: 'hidden lg:block',
    },
   {
        key: 'test2',
        label: 'Mobile only',
        class: 'block lg:hidden',
        rowClass: 'block lg:hidden',
    },
];
<table>
  <thead>
    <tr class="hidden lg:block">
      Big Screen
    </tr>
    <tr class="block lg:hidden">
      Mobile only
    </tr>
  </thead>

  <tbody>
    <tr>
      <td class="hidden lg:block">Big Screen</td>
      <td class="block lg:hidden">Mobile only</td>
    </tr>
  </tbody>
</table>

I have used hidden lg:block, and so on to hide specific data or display it in another column as a "block of data" in tables. In the code below, I would hide/combine the dateofbirth and occupation columns into the name column in a nice-looking block like this:

            <template #name-data="{ row }">
                <div class="inline-flex items-center">
                    <UAvatar
                        :url="row.avatar"
                        alt="Avatar"
                        size="sm"
                    />

                    <span>{{ row.name }}</span>
                    <span class="lg:hidden"> ({{ row.dateofbirth }}) </span>
                </div>

                <dl class="lg:hidden">
                    <dt class="sr-only">Occupation</dt>
                    <dd class="truncate">{{ row.occupation }}</dd>
                </dl>
            </template>

Results more or less in something looking like this on smaller screens:

<td
  class="whitespace-nowrap px-1.5 py-1.5 text-gray-500 dark:text-gray-400 text-sm"
>
  <div class="inline-flex items-center gap-1">
    <span
      class="relative inline-flex items-center justify-center flex-shrink-0 bg-gray-100 dark:bg-gray-800 rounded-full h-8 w-8 text-sm"
      ><span
        class="font-medium leading-none text-gray-900 dark:text-white truncate"
        >AT</span
      ><!--v-if--></span
    ><span>Alexander T.</span><span class="lg:hidden"> (01.01.1970) </span>
  </div>
  <!--v-if-->
  <dl class="font-normal lg:hidden">
    <dt class="sr-only">Occupation</dt>
    <dd class="mt-1 truncate">IT Engineer</dd>
  </dl>
</td>

image

I can modify the rows list to add a class property, as is written in the docs, but I would prefer not to have to modify the list from the API call that I pass to the table :D
I haven't figured out if something like rowClass is already available that would hide the column; that's why the occupation is seen after the name block in the screenshot (the table header disappears as expected though).

Any thoughts on this approach for table data?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants