Jim Vercoelen
Jim Vercoelen

Reputation: 1077

PrimeReact checkbox not focussing using Tailwind

Context
We're using ReactPrime as UI lib for our NextJS, on top of which we apply our custom styles using Tailwind.

import { CustomDesignSystem } from "@/app/ui/design-system"
...

interface CustomPrimeReactProviderProps {
  children: ReactNode
  value?: Partial<APIOptions>
}
export function CustomPrimeReactProvider({
  children,
}: CustomPrimeReactProviderProps) {
  return (
    <PrimeReactProvider
      value={{
        ripple: true,
        unstyled: true,
        pt: CustomDesignSystem,
        ptOptions: {
          mergeSections: true,
          mergeProps: true,
          classNameMergeFunction: twMerge,
        },
      }}
    >
      {children}
    </PrimeReactProvider>
  )
}

Issue
For some reason, the combination of the two is causing issues with the checkbox focus state. It's either impossible to navigate to the checkbox component using the tab key, or there’s no styling applied when it is focused.

Possible Solution
Perhaps it is because we basically hide the input field entirely and style the box instead.

// "/app/ui/design-system.ts"
...
  checkbox: {
    ...Tailwind.checkbox,
    root: {
      className: classNames(
        "cursor-pointer inline-flex relative select-none align-bottom",
        "w-6 h-6",
      ),
    },
    input: {
      className: classNames(
        "absolute appearance-none top-0 left-0 size-full p-0 m-0 opacity-0 z-10 outline-none cursor-pointer",
      ),
    },
    box: ({
      props,
      context,
    }: {
      props: CheckboxProps
      context: CheckboxContext
    }) => ({
      className: classNames(
        "flex items-center justify-center",
        "border-2 w-6 h-6 text-fg-primary-950 rounded-md transition-colors duration-200",
        {
          "border-dark-bg-primary-600 bg-transparent dark:border-blue-900/40 dark:bg-gray-900":
            !context.checked,
          "border-bg-primary-500 bg-bg-primary-500 dark:border-dark-bg-primary-950 dark:bg-dark-bg-primary-950":
            context.checked,
        },
        {
          "hover:border-blue-500 dark:hover:border-blue-400 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[inset_0_0_0_0.2rem_rgba(147,197,253,0.5)]":
            !props.disabled,
          "cursor-default opacity-60": props.disabled,
        },
      ),
    }),
    icon: {
      className:
        "w-4 h-4 transition-all duration-200 text-fg-primary-950 text-base dark:text-gray-900",
    },
  },

At this point, I've tried multiple things and have even lost track of what I've tried. I am reaching out to see if anyone has any insights—or possibly even a simple example I can work from. That would be great.

Thanks

Upvotes: 1

Views: 20

Answers (0)

Related Questions