Bird
Raised Fist0
Tailwindmarkup~10 mins

Component library patterns (Headless UI) in Tailwind - Interactive Code Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to create a basic Headless UI <Menu> component with Tailwind CSS.

Tailwind
<Menu>
  <Menu.Button className="px-4 py-2 bg-blue-600 text-white rounded">Options</Menu.Button>
  <Menu.Items className="mt-2 w-48 bg-white shadow-lg rounded">
    <Menu.Item>
      {({ active }) => (
        <button className={`${active ? '[1]' : ''} block w-full text-left px-4 py-2`}>Account</button>
      )}
    </Menu.Item>
  </Menu.Items>
</Menu>
Drag options to blanks, or click blank then click option'
Abg-blue-500
Bitalic
Cborder
Dtext-red-500
Attempts:
3 left
💡 Hint
Common Mistakes
Using text color instead of background color for active state.
Forgetting to use template literals for conditional class names.
2fill in blank
medium

Complete the code to add keyboard accessibility to the Headless UI <Disclosure> component.

Tailwind
<Disclosure>
  <Disclosure.Button className="px-4 py-2 bg-gray-700 text-white rounded">
    [1]
  </Disclosure.Button>
  <Disclosure.Panel className="p-4 bg-gray-100">
    This is the hidden content revealed by the button.
  </Disclosure.Panel>
</Disclosure>
Drag options to blanks, or click blank then click option'
AToggle Content <button>
B<span>Toggle Content</span>
CToggle Content
DToggle Content <ChevronDownIcon />
Attempts:
3 left
💡 Hint
Common Mistakes
Using plain text only without any visual toggle indicator.
Wrapping the button text inside another button element.
3fill in blank
hard

Fix the error in the Headless UI component by completing the missing prop.

Tailwind
<Tab.Group [1]>
  <Tab.List className="flex space-x-1 bg-blue-900/20 p-1 rounded">
    <Tab className={({ selected }) => selected ? 'bg-white text-blue-700' : 'text-blue-100'}>Tab 1</Tab>
    <Tab className={({ selected }) => selected ? 'bg-white text-blue-700' : 'text-blue-100'}>Tab 2</Tab>
  </Tab.List>
  <Tab.Panels>
    <Tab.Panel className="p-4 bg-white">Content 1</Tab.Panel>
    <Tab.Panel className="p-4 bg-white">Content 2</Tab.Panel>
  </Tab.Panels>
</Tab.Group>
Drag options to blanks, or click blank then click option'
Aindex={0}
BdefaultIndex={0}
CinitialIndex={0}
DselectedIndex={0}
Attempts:
3 left
💡 Hint
Common Mistakes
Using selectedIndex which requires controlled state.
Using non-existent props like initialIndex or index.
4fill in blank
hard

Fill both blanks to create a Headless UI <Listbox> with Tailwind styling and accessibility.

Tailwind
<Listbox value={selected} onChange={setSelected}>
  <Listbox.Button className="relative w-48 cursor-default rounded bg-white py-2 pl-3 pr-10 text-left shadow-md">
    [1]
  </Listbox.Button>
  <Listbox.Options className="absolute mt-1 max-h-60 w-48 overflow-auto rounded bg-white py-1 text-base shadow-lg">
    [2]
  </Listbox.Options>
</Listbox>
Drag options to blanks, or click blank then click option'
A{selected.name}
B{options.map((option) => ( <Listbox.Option key={option.id} value={option}> {option.name} </Listbox.Option> ))}
C{selected.value}
D{items.map(item => <Listbox.Option key={item.id} value={item}>{item.label}</Listbox.Option>)}
Attempts:
3 left
💡 Hint
Common Mistakes
Using wrong property names like value or label inconsistently.
Not mapping over the correct array of options.
5fill in blank
hard

Fill all three blanks to build a Headless UI <Popover> with accessible button, panel, and transition.

Tailwind
<Popover className="relative">
  <Popover.Button className="inline-flex justify-center rounded-md bg-indigo-600 px-4 py-2 text-white">
    [1]
  </Popover.Button>
  <Transition
    enter="transition duration-200 ease-out"
    enterFrom="opacity-0 scale-95"
    enterTo="opacity-100 scale-100"
    leave="transition duration-150 ease-in"
    leaveFrom="opacity-100 scale-100"
    leaveTo="opacity-0 scale-95"
  >
    <Popover.Panel className="absolute z-10 mt-3 w-screen max-w-sm rounded bg-white p-4 shadow-lg">
      [2]
      [3]
    </Popover.Panel>
  </Transition>
</Popover>
Drag options to blanks, or click blank then click option'
A"Open Menu"
B<p>This is the popover content.</p>
C<button className="mt-2 px-3 py-1 bg-blue-500 text-white rounded">Close</button>
D"Close Menu"
Attempts:
3 left
💡 Hint
Common Mistakes
Leaving the button label empty or unclear.
Not including a close button inside the popover panel for keyboard users.

Practice

(1/5)
1. What is the main purpose of Headless UI in web development?
easy
A. To create animations for UI elements automatically
B. To offer pre-styled UI components ready to use
C. To replace Tailwind CSS for styling
D. To provide accessible component behavior without styling

Solution

  1. Step 1: Understand Headless UI's role

    Headless UI provides the logic and accessibility for components but no styles.
  2. Step 2: Compare with styling tools

    Styling is added separately, often with Tailwind CSS, so Headless UI focuses on behavior only.
  3. Final Answer:

    To provide accessible component behavior without styling -> Option D
  4. Quick Check:

    Headless UI = behavior only [OK]
Hint: Headless UI = logic + accessibility, no styles [OK]
Common Mistakes:
  • Thinking Headless UI provides styles
  • Confusing Headless UI with Tailwind CSS
  • Assuming it creates animations automatically
2. Which of the following is the correct way to import a Headless UI component in a React project?
easy
A. import { Menu } from '@headlessui/react';
B. import Menu from 'headless-ui';
C. import { Menu } from 'tailwindcss';
D. import Menu from '@headlessui/css';

Solution

  1. Step 1: Identify the correct package name

    The official Headless UI React package is '@headlessui/react'.
  2. Step 2: Use named import for components

    Components like Menu are imported as named imports from '@headlessui/react'.
  3. Final Answer:

    import { Menu } from '@headlessui/react'; -> Option A
  4. Quick Check:

    Correct import syntax = import { Menu } from '@headlessui/react'; [OK]
Hint: Headless UI React imports use named imports from '@headlessui/react' [OK]
Common Mistakes:
  • Using default import instead of named import
  • Importing from 'tailwindcss' instead of '@headlessui/react'
  • Using wrong package names like 'headless-ui' or '@headlessui/css'
3. Given this React code using Headless UI's Menu component, what will be the visible output when the button is clicked?
import { Menu } from '@headlessui/react';

export default function Example() {
  return (
    
      Options
      
        
          {({ active }) => (
            <a href='#' className={`${active ? 'bg-blue-500 text-white' : 'text-black'}`}>Account</a>
          )}
        
        
          {({ active }) => (
            <a href='#' className={`${active ? 'bg-blue-500 text-white' : 'text-black'}`}>Settings</a>
          )}
        
      
    
  );
}
medium
A. An error because Menu.Items is missing a wrapper element
B. A button labeled 'Options' that toggles a dropdown with 'Account' and 'Settings' links
C. A button labeled 'Options' with no dropdown appearing on click
D. Only a static list of 'Account' and 'Settings' links visible without a button

Solution

  1. Step 1: Understand Menu component behavior

    The Menu.Button toggles visibility of Menu.Items as a dropdown.
  2. Step 2: Check rendering of Menu.Items and Menu.Item

    Menu.Items contains two Menu.Item links that show with styling on hover (active).
  3. Final Answer:

    A button labeled 'Options' that toggles a dropdown with 'Account' and 'Settings' links -> Option B
  4. Quick Check:

    Menu.Button toggles dropdown = A button labeled 'Options' that toggles a dropdown with 'Account' and 'Settings' links [OK]
Hint: Menu.Button toggles Menu.Items dropdown visibility [OK]
Common Mistakes:
  • Thinking dropdown is always visible
  • Assuming Menu.Items needs extra wrapper
  • Expecting error due to JSX structure
4. What is the main issue with this Headless UI Disclosure usage in React?
import { Disclosure } from '@headlessui/react';

export default function Example() {
  return (
    <Disclosure>
      <Disclosure.Button>Toggle</Disclosure.Button>
      <div>Hidden content</div>
    </Disclosure>
  );
}
medium
A. The hidden content should be wrapped in Disclosure.Panel for proper behavior
B. Disclosure.Button must be outside Disclosure component
C. The import statement is incorrect
D. Disclosure requires a state hook to work

Solution

  1. Step 1: Check Disclosure structure

    Disclosure requires hidden content inside Disclosure.Panel for toggle functionality.
  2. Step 2: Identify missing wrapper

    The <div>Hidden content</div> should be replaced with <Disclosure.Panel>Hidden content</Disclosure.Panel>.
  3. Final Answer:

    The hidden content should be wrapped in Disclosure.Panel for proper behavior -> Option A
  4. Quick Check:

    Disclosure.Panel wraps hidden content [OK]
Hint: Hidden content must be inside Disclosure.Panel [OK]
Common Mistakes:
  • Placing hidden content directly without Disclosure.Panel
  • Moving Disclosure.Button outside Disclosure
  • Incorrect import or missing hooks
5. You want to create a custom dropdown menu using Headless UI's Menu component styled with Tailwind CSS. You want the menu items to close the menu when clicked and highlight on keyboard navigation. Which approach correctly combines Headless UI behavior with Tailwind styling?
hard
A. Use Menu.Button and style it only; menu items are plain HTML links without Headless UI components
B. Use Menu.Items without Menu.Button and add Tailwind hover classes manually
C. Use Menu.Button to toggle, wrap items in Menu.Items, and style Menu.Item using the active state with Tailwind classes
D. Use only Tailwind CSS dropdown utilities without Headless UI components

Solution

  1. Step 1: Use Headless UI components for behavior

    Menu.Button toggles menu visibility; Menu.Items contains menu options; Menu.Item handles keyboard navigation and active state.
  2. Step 2: Apply Tailwind CSS for styling active states

    Use the active render prop in Menu.Item to conditionally apply Tailwind classes for highlight on keyboard focus or hover.
  3. Step 3: Ensure menu closes on item click

    Headless UI automatically closes the menu when a Menu.Item is clicked, preserving accessibility.
  4. Final Answer:

    Use Menu.Button to toggle, wrap items in Menu.Items, and style Menu.Item using the active state with Tailwind classes -> Option C
  5. Quick Check:

    Headless UI + Tailwind styling = Use Menu.Button to toggle, wrap items in Menu.Items, and style Menu.Item using the active state with Tailwind classes [OK]
Hint: Style Menu.Item active state with Tailwind inside Headless UI Menu [OK]
Common Mistakes:
  • Styling only Menu.Button and ignoring Menu.Item active states
  • Not using Menu.Item components for menu options
  • Trying to build dropdown without Menu.Button
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard