"Enhance your forms with RadixUI's beautiful designs for

New to Radix UI and styling components, I encountered difficulties while trying to adapt a JSX component to Radix UI:

Utilizing Radix UI Radio Groups, I aim to style my component similar to this example from Hyper UI with grid layout showing stacked content and checked state:

Key Points

  • Incorporating NextJS 13, TypeScript, and React in my project.
  • Adjusted the code to display radio icon on selection but experienced issues activating borders.
  • The goal is to have block borders with specific styles for selected items.
  • Current implementation includes adding {children} to RadioGroupPrimitive.Indicator which is incorrect as it only handles the button, leading to text appearing only upon selection.

Considering exploring options involving labels, given that selection encompasses entire block along with icon, challenges arise in correctly positioning title and subtitle.

Experimenting further, I arrived at:

//Code snippet here

Followed by frontend call like:

<RadioGroupItemModern key={choice.value} value={choice.value} id={choice.value} defaultValue={field.value || ''}>
    <div>
    <RadioGroupItemTitle>{choice.text}</RadioGroupItemTitle>
    <RadioGroupItemSubtitle>{choice.description}</RadioGroupItemSubtitle>
    </div>
</RadioGroupItemModern>

Currently, desired result displays only when selection is made (albeit invisible).

Exploring Radix Primitives, experimented with various ways of incorporating children, yet struggling to grasp correct logic due to Radix treating group radio and labels as separate components.

Answer №1

If you're looking for the best solution, check out the examples in the shadcn/ui repository here.

In those examples, there are two crucial sets of classes that need to be applied:

  1. The first set should be added to each RadioGroupItem within your RadioGroup. These items should have the classes peer sr-only. The key class here is peer, as mentioned in a different response, which comes from Tailwind.

  2. The second set of classes applies to the element whose visual appearance you want to change when a specific RadioGroupItem is selected. In the example provided, a border is introduced to the Label inside the RadioGroupItem using an attribute selector:

    peer-data-[state=checked]:border-primary
    . This selector looks at the value of the data-state attribute on the button element generated by the RadioGroupItem to determine when to apply the Tailwind class; in this case, it's adding a border-primary, but it could be anything like displaying or hiding an SVG.

These instructions are applicable to RadixUI and shadcn/ui components, utilizing standard attribute selectors for implementation.

If you're curious about the role of peer, you can refer to the relevant documentation on Tailwind's website here!

Answer №2

To make styling adjustments based on sibling state in Radix component, utilize peer from TailwindCSS & aria-checked: instead of checked:. This is necessary because the input is enclosed within a button. Refer to this simple implementation using RadixUI & shadcn/ui:

<FormItem className="block w-full space-x-3 space-y-0">
  <FormControl>
    <RadioGroupItem value="myValue" className="peer hidden" />
  </FormControl>
  <FormLabel className="block cursor-pointer rounded-md border border-border p-4 font-normal shadow-sm hover:border-primary peer-aria-checked:border-primary peer-aria-checked:ring-1 peer-aria-checked:ring-ring">
    My Label
  </FormLabel>
</FormItem>

Answer №3

Recently, I came across a solution that I forgot to share earlier. In the library creator shadcn's Examples, there is an interesting use of the &:has([data-state=checked] attribute from Radix UI. This attribute is utilized to handle the checked item.

The creator uses this attribute as a boolean to apply the border-primary class:

<FormLabel className="[&:has([data-state=checked])>div]:border-primary">

To explore further details, check out the GitHub Repo here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The import component functions correctly when it is located in the app folder, but does not work when it is installed as

I have a situation with an angular 2 component. When I place it in app-name/src/app/component-folder/component.ts and import it as import {Component} from './component-folder/component', everything works perfectly fine. However, if I install the ...

Angular2 Eclipse: Eclipse Oxygen's HTML editor detects TypeScript errors in real-time

After installing the Eclipse Oxygen plugin for Angular2, I created a project using the Angular CLI and opened it in Eclipse. However, when trying to convert the project to an Angular project, I couldn't find the option under configuration. Instead, th ...

When using Typescript, I am encountering an issue where declared modules in my declaration file, specifically those with the file

One of the declarations in my ./src/types.d.ts file includes various modules: /// <reference types="@emotion/react/types/css-prop" /> import '@emotion/react'; import { PureComponent, SVGProps } from 'react'; declare mod ...

Unable to assign to 'disabled' as it is not recognized as a valid attribute for 'app-button'

How to link the disabled property with my button component? I attempted to add 'disabled' to the HTML file where it should be recognized as an input in the button component (similar to how color and font color are recognized as inputs) ... but ...

How can I resolve the problem of transferring retrieved data to a POST form?

When it comes to the form, its purpose is to send data fetched from another API along with an additional note. The fetched data was successfully received, as I confirmed by logging it to the console. It seems that the form is able to send both the fetche ...

Is it possible to use square brackets in conjunction with the "this" keyword to access a class property using an expression?

export class AppComponent implements OnInit { userSubmitted = false; accountSubmitted = false; userForm!: FormGroup; ngOnInit(): void {} onSubmit(type: string): void { this[type + 'Submitted'] = true; if(this[type + 'For ...

The upcoming thirteenth client-side data retrieval experience

I am currently working with Next.js version 13.3.1 and trying to make an API call in a client component. Below is the code snippet I am using: const [people, setPeople] = useState<null | Person[]>(null); useEffect(() => { const fetchData = as ...

Error type inferred by TypeScript

I am currently in the process of learning TypeScript, and I encountered some errors in the code below: Error: Unexpected token. A constructor, method, accessor, or property was expected. [ts] Declaration or statement expected. class duckType{ public ...

Include a class in ul > li elements upon page load in Angular4

I attempted to add a class to each "li" element in an Angular4 page, but the class was not applied. Here is the relevant HTML code: <ul class="pagination"> <button class="previous" (click)="previous()">Previous</button> <button ...

What is the process for adjusting the expiration time of a GitLab accessToken?

I am currently using NextAuth for logging in with GitLab, but I am encountering an issue where my accessToken changes every 2 hours. How can I ensure that it remains valid for a longer period so that I can successfully store it in my database? It's wo ...

Ways to transfer data from TypeScript to CSS within Angular 6

Trying to work with ngClass or ngStyle, but I'm struggling with passing the value. Here's my current code: strip.component.ts import { ... } from '@angular/core'; @Component({ selector: 'app-strip', templateUrl: &apo ...

Setting up Environment-Specific Redirect URLs for Next.js with Supabase Authentication

I am currently working on a Next.js project that includes Supabase authentication. I have set the 'Site URL' in my Supabase settings to https://some-production-url.com for the production environment. However, during local development, I need the ...

What scenarios call for implementing loadable components within a NextJS application?

I'm determined to boost my website's performance, and the Google Chrome Lighthouse tool is advising me to utilize loadable-components for server-side rendering to "eliminate unused JavaScript". After reading through the documentation, it appears ...

Maintaining awareness of which accordion drawer is currently open within a React application

Just getting started with coding, I recently created a collapsible accordion in a NextJs app using the react-collapse package. Everything seems to be working fine, but I'm running into an issue with keeping track of which 'drawer' is current ...

Why hasn't the variable been defined?

Why am I receiving an error message saying "test is not defined" in this code? Even though I have properly defined the variable in another service file, it seems to be causing issues here. Any insights on what could be going wrong? import { Injectable } f ...

Comparison between Destructuring in TypeScript and JavaScript

Starting my journey with TypeScript after a background in JavaScript. In the realm of modern JavaScript, one can easily destructure objects like this: let {n,s} = {n:42, s:'test'}; console.log(n, s); // 42 test Assuming TypeScript follows su ...

Managing different data types in a single event emitter using Typescript: how do you approach it?

I'm currently working on a TypeScript function that detects the "Enter" key press and, if the event.target.value's length is greater than 0, redirects to a page with that value. This code snippet is being used in a Next.js application, hence the ...

Steps for assigning a parameter to a general purpose function

Having a generic function named retrieve: function retrieve<T>(endpoint: string, id: string, /* etc */): T {} The goal is to define a function like retrieveUser, which binds the first parameter and specifies T. An attempt was made using Function.pr ...

What steps can be taken to resolve the issue of receiving the error message "Invalid 'code' in request" from Discord OAuth2?

I'm in the process of developing an authentication application, but I keep encountering the error message Invalid "code" in request when attempting to obtain a refresh token from the code provided by Discord. Below is a snippet of my reques ...

Is it secure to use ES6 in Typescript with nodejs/koa?

As I transition to using TypeScript in a Node.js/koa project, I came across the need to modify the .tsconfig file to target ES6. Otherwise, an error message will appear stating: Generators are only available when targeting ECMAScript 6 or higher. // index ...