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

RFC: Radio Groups as card layouts #246

Open
1 of 2 tasks
marcjulian opened this issue Apr 2, 2024 · 7 comments
Open
1 of 2 tasks

RFC: Radio Groups as card layouts #246

marcjulian opened this issue Apr 2, 2024 · 7 comments
Labels
enhancement New feature or request

Comments

@marcjulian
Copy link
Contributor

Which scope/s are relevant/related to the feature request?

radio-group

Information

Allow Radio Groups to be styled in any layout such as these cards.

CleanShot 2024-04-02 at 19 35 25
CleanShot 2024-04-02 at 19 36 11

label is part of BrnRadioComponent how to style the label for custom layouts? Should the label be extracted from BrnRadioComponent to be styled by the user and follow a similar API as shadcn?

Shadcn API

<RadioGroup defaultValue="option-one">
 <div>
            <RadioGroupItem
              value="card"
              id="card"
              className="peer sr-only"
              aria-label="Card"
            />
            <Label
              htmlFor="card"
              className="flex flex-col items-center justify-between rounded-md border-2 border-muted bg-transparent p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary"
            >
              <svg
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="2"
                className="mb-3 h-6 w-6"
              >
                <rect width="20" height="14" x="2" y="5" rx="2" />
                <path d="M2 10h20" />
              </svg>
              Card
            </Label>
          </div>
   ...
</RadioGroup>

Describe any alternatives/workarounds you're currently using

No response

I would be willing to submit a PR to fix this issue

  • Yes
  • No
@marcjulian marcjulian added the enhancement New feature or request label Apr 2, 2024
@goetzrobin
Copy link
Owner

How about we make styles and classes for the label, indicator, input inside the brn-radio inputs that can be overwritten?
That way we have more flexibility on how to style the actual button. The anatomy of the brn-radio is inspired by Material, and I think in the case you are describing the label would be marked with sr-only and the indicator/touchTarget is where you would style the Card

@marcjulian
Copy link
Contributor Author

marcjulian commented Apr 23, 2024

Input component design

API design when we would add class inputs for label, indicator and input for brn-radio could look like

<brn-radio-group hlm class="grid grid-cols-3 gap-4" [(ngModel)]="card">
  <brn-radio hlm value="card" labelClass="...">
    <svg>...</svg>
    Card
  </brn-radio>
   ...
</brn-radio-group>

What about refactoring the hlm directives to components to use them instead

<hlm-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="card">
  <hlm-radio value="card" labelClass="...">
    <svg>...</svg>
    Card
  </hlm-radio>
   ...
</hlm-radio-group>

Extract label component design

What if we extract the label from brn-radio:

// brn-radio.component.ts
<div style="display: flex; height: fit-content; width: fit-content" (click)="_onTouchTargetClick($event)">
  <ng-content select="[target],[indicator]" />
</div>
<input 
  #input 
  style="position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0;"
  type="radio" 
  [id]="inputId" 
  [checked]="checked" 
  [disabled]="disabled" 
  [attr.name]="name" 
  [attr.value]="value" 
  [required]="required" 
  [attr.aria-label]="ariaLabel" 
  [attr.aria-labelledby]="ariaLabelledby" 
  [attr.aria-describedby]="ariaDescribedby" 
  (change)="_onInputInteraction($event)" 
  (click)="_onInputClick($event)" 
/>
- <label style="display: flex; height: fit-content; width: fit-content" [for]="inputId">
  <ng-content></ng-content>
- </label>

The API could look like as follow when we pull out the label from brn-radio, but we also need to handle <label [for]="inputId > each time.

<brn-radio-group hlm class="grid grid-cols-3 gap-4" [(ngModel)]="version">
  <brn-radio hlm value="card">
    <label class="...">
      <svg>...</svg>
      Card
    </label>
  </brn-radio>
  ...
</brn-radio-group>

Or with hlm components

<hlm-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="version">
  <hlm-radio value="card">
    <label class="...">
      <svg>...</svg>
      Card
    </label>
  </hlm-radio>
  ...
</hlm-radio-group>

@marcjulian
Copy link
Contributor Author

marcjulian commented Apr 23, 2024

You think it would be better to move the card layout into the indicator selector, something like this:

<brn-radio-group hlm class="grid grid-cols-3 gap-4" [(ngModel)]="card">
  <brn-radio hlm value="card" labelClass="sr-only">
    <!-- projected into indicator: touch area -->
    <div indicator class="...">
      <svg>...</svg>
      Card
    </div>
    <!-- projected into label: apply sr-only class-->
    Card
  </brn-radio>
</brn-radio-group>

@goetzrobin
Copy link
Owner

Interesting. What are you thinking?

@goetzrobin
Copy link
Owner

After reviewing this I think my absolute favorite would be this. And inside hlm-radio we allow you access to the label classes and styles.

<hlm-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="version">
  <hlm-radio value="card">
      Card
  </hlm-radio>
  ...
</hlm-radio-group>

And then for a custom radio we could do something like this:

<brn-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="card">
  <brn-radio value="card" labelClass="sr-only">
    <!-- projected into indicator: touch area -->
    <div indicator class="...">
      <svg>...</svg>
      Card
    </div>
    <!-- projected into label: apply sr-only class-->
    Card
  </brn-radio>
</brn-radio-group>

@marcjulian
Copy link
Contributor Author

This sounds good to me.

<hlm-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="version">
  <hlm-radio value="card">
      Card
  </hlm-radio>
  ...
</hlm-radio-group>

But the for the custom radio, I don't like that we need to repeat the label. What is there reason not to project the custom radio into the label and apply the needed styles?

@goetzrobin
Copy link
Owner

@marcjulian just getting back to this. Were you able to get this to work? Anything I can do to help

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
Status: No status
Development

No branches or pull requests

2 participants