skip to Main Content

I have an unordered list. I want to append the word "and" at the end of each item, except the last.

<ul className="ml-4">
  {
    categories.map((category, Idx) => (
        <li key={category.id} className="last:text-red-400">
         {category.description} <span className="last:hidden">; AND</span>
        </li>
    )
  }
</ul>

Actual output:

Red
Blue
Green

Desired output:

Red; AND
Blue; AND
Green

The "last" decorator on the "text-red-400" works. It was just for testing.
The one for "hidden" doesn’t do what I want. All the "AND" s are hidden, presumably because they are all actually the last child of each of the li items, so the decorator is always active(?).

My current solution is

<ul className="ml-4">
  {
    categories.map((category, Idx, arr) => (
        <li key={category.id}>
         {category.description} <span className={`${Idx == arr.length - 1 && "hidden"}`}>; AND</span>
        </li>
    )
  }
</ul>

But i wondered if there was a better way apply the class so that only the word "and" on the last child of ul is hidden?

2

Answers


  1. Not a solution by tailwind but the same result

    Adding a condition on the ; AND span

    {Idx < categories.length - 1 && (
      <span>; AND</span>
    )}
    
    import React from 'react';
    
    const categories = [
      {
        id: 1,
        description: 'Red',
      },
      {
        id: 2,
        description: 'Blue',
      },
      {
        id: 3,
        description: 'Green',
      },
    ];
    
    export function App(props) {
      return (
        <div className='App'>
          <ul className='ml-4'>
            {categories.map((category, Idx) => (
              <li key={category.id} className='last:text-red-400'>
                {category.description}{' '}
                {Idx < categories.length - 1 && (
                  <span>; AND</span>
                )}
              </li>
            ))}
          </ul>
        </div>
      );
    }
    
    Login or Signup to reply.
  2. Something like this maybe?

    <ul class="ml-4">
      <li class="last:text-red-400 [&:last-child>span]:hidden">Blue <span>; AND</span></li>
      <li class="last:text-red-400 [&:last-child>span]:hidden">Green <span>; AND</span></li>
      <li class="last:text-red-400 [&:last-child>span]:hidden">Red <span>; AND</span></li>
    </ul>
    

    If there are multiple spans inside an li, you can specify something like this:

    <ul class="ml-4">
      <li class="last:text-red-400 [&:last-child>.foo]:hidden">Blue <span class="foo">; AND</span></li>
      <li class="last:text-red-400 [&:last-child>.foo]:hidden">Green <span class="foo">; AND</span></li>
      <li class="last:text-red-400 [&:last-child>.foo]:hidden">Red <span class="foo">; AND</span></li>
    </ul>
    

    Another solution might be to use groups:

    <ul class="ml-4">
      <li class="last:text-red-400 group">Blue <span class="group-last:hidden">; AND</span></li>
      <li class="last:text-red-400 group">Green <span class="group-last:hidden">; AND</span></li>
      <li class="last:text-red-400 group">Red <span class="group-last:hidden">; AND</span></li>
    </ul>
    

    If there are nested groups (i.e. one of the parents already has group), you can name them:

    <ul class="ml-4">
      <li class="last:text-red-400 group/foo">Blue <span class="group-last/foo:hidden">; AND</span></li>
      <li class="last:text-red-400 group/foo">Green <span class="group-last/foo:hidden">; AND</span></li>
      <li class="last:text-red-400 group/foo">Red <span class="group-last/foo:hidden">; AND</span></li>
    </ul>
    

    Feel free to change it to JSX. Playground: https://play.tailwindcss.com/XqG11h8pWD

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search