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

refactor(radio-group): hlm-radio component and fix card styles #556

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,113 +2,108 @@ import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideApple, lucideCreditCard } from '@ng-icons/lucide';
import { BrnRadioComponent } from '@spartan-ng/brain/radio-group';
import { hlm } from '@spartan-ng/brain/core';
import { HlmIconDirective } from '@spartan-ng/ui-icon-helm';
import { HlmRadioDirective, HlmRadioGroupComponent } from '@spartan-ng/ui-radiogroup-helm';
import { HlmRadioComponent, HlmRadioGroupComponent } from '@spartan-ng/ui-radiogroup-helm';

@Component({
selector: 'spartan-radio-card-preview',
standalone: true,
providers: [provideIcons({ lucideCreditCard, lucideApple })],
imports: [FormsModule, BrnRadioComponent, HlmRadioDirective, HlmRadioGroupComponent, NgIcon, HlmIconDirective],
imports: [FormsModule, HlmRadioComponent, HlmRadioGroupComponent, NgIcon, HlmIconDirective],
template: `
<hlm-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="payment">
<brn-radio hlm value="card" class="group space-x-0">
<div
class="border-muted bg-popover hover:bg-accent hover:text-accent-foreground group-data-[checked=true]:border-primary flex flex-col items-center justify-between rounded-md border-2 p-4"
>
<ng-icon hlm name="lucideCreditCard" class="mb-3" />
<!-- FIXME style issue with short text -->
Card
</div>
</brn-radio>
<brn-radio hlm value="paypal" class="group space-x-0">
<div
class="border-muted bg-popover hover:bg-accent hover:text-accent-foreground group-data-[checked=true]:border-primary flex flex-col items-center justify-between rounded-md border-2 p-4"
>
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>PayPal</title>
<path
d="M7.016 19.198h-4.2a.562.562 0 0 1-.555-.65L5.093.584A.692.692 0 0 1 5.776 0h7.222c3.417 0 5.904 2.488 5.846 5.5-.006.25-.027.5-.066.747A6.794 6.794 0 0 1 12.071 12H8.743a.69.69 0 0 0-.682.583l-.325 2.056-.013.083-.692 4.39-.015.087zM19.79 6.142c-.01.087-.01.175-.023.261a7.76 7.76 0 0 1-7.695 6.598H9.007l-.283 1.795-.013.083-.692 4.39-.134.843-.014.088H6.86l-.497 3.15a.562.562 0 0 0 .555.65h3.612c.34 0 .63-.249.683-.585l.952-6.031a.692.692 0 0 1 .683-.584h2.126a6.793 6.793 0 0 0 6.707-5.752c.306-1.95-.466-3.744-1.89-4.906z"
/>
</svg>
PayPal
</div>
</brn-radio>
<brn-radio hlm value="apple" class="group space-x-0">
<div
class="border-muted bg-popover hover:bg-accent hover:text-accent-foreground group-data-[checked=true]:border-primary flex flex-col items-center justify-between rounded-md border-2 p-4"
>
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>Apple</title>
<path
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
/>
</svg>
Apple
</div>
</brn-radio>
<hlm-radio value="card" [class]="cardClass">
<ng-icon hlm name="lucideCreditCard" class="mb-3" />
Card
</hlm-radio>
<hlm-radio value="paypal" [class]="cardClass">
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>PayPal</title>
<path
d="M7.016 19.198h-4.2a.562.562 0 0 1-.555-.65L5.093.584A.692.692 0 0 1 5.776 0h7.222c3.417 0 5.904 2.488 5.846 5.5-.006.25-.027.5-.066.747A6.794 6.794 0 0 1 12.071 12H8.743a.69.69 0 0 0-.682.583l-.325 2.056-.013.083-.692 4.39-.015.087zM19.79 6.142c-.01.087-.01.175-.023.261a7.76 7.76 0 0 1-7.695 6.598H9.007l-.283 1.795-.013.083-.692 4.39-.134.843-.014.088H6.86l-.497 3.15a.562.562 0 0 0 .555.65h3.612c.34 0 .63-.249.683-.585l.952-6.031a.692.692 0 0 1 .683-.584h2.126a6.793 6.793 0 0 0 6.707-5.752c.306-1.95-.466-3.744-1.89-4.906z"
/>
</svg>
PayPal
</hlm-radio>
<hlm-radio value="apple" [class]="cardClass">
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>Apple</title>
<path
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
/>
</svg>
Apple
</hlm-radio>
</hlm-radio-group>
`,
})
export class RadioGroupCardComponent {
public payment = 'card';

public readonly cardClass = hlm(
'block space-x-0',
// base card styles for the label
'[&>[data-slot=label]]:flex [&>[data-slot=label]]:flex-col [&>[data-slot=label]]:items-center [&>[data-slot=label]]:justify-between [&>[data-slot=label]]:bg-popover [&>[data-slot=label]]:rounded-md [&>[data-slot=label]]:border-2 [&>[data-slot=label]]:border-muted [&>[data-slot=label]]:p-4',
// hover styles
'[&>[data-slot=label]]:hover:bg-accent [&>[data-slot=label]]:hover:text-accent-foreground',
// highlight checked radio
'[&>[data-slot=label]]:data-[checked=true]:border-primary',
);
}

export const cardCode = `
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { provideIcons } from '@ng-icons/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideApple, lucideCreditCard } from '@ng-icons/lucide';
import { BrnRadioComponent } from '@spartan-ng/brain/radio-group';
import { hlm } from '@spartan-ng/brain/core';
import { HlmIconDirective } from '@spartan-ng/ui-icon-helm';
import { HlmRadioDirective, HlmRadioGroupComponent } from '@spartan-ng/ui-radiogroup-helm';
import { HlmRadioComponent, HlmRadioGroupComponent } from '@spartan-ng/ui-radiogroup-helm';

@Component({
selector: 'spartan-radio-card-preview',
standalone: true,
providers: [provideIcons({ lucideCreditCard, lucideApple })],
imports: [FormsModule, BrnRadioComponent, HlmRadioDirective, HlmRadioGroupComponent, HlmIconDirective],
imports: [FormsModule, HlmRadioComponent, HlmRadioGroupComponent, NgIcon, HlmIconDirective],
template: \`
<hlm-radio-group class="grid grid-cols-3 gap-4" [(ngModel)]="payment">
<brn-radio hlm value="card" class="group space-x-0">
<div
class="border-muted bg-popover hover:bg-accent hover:text-accent-foreground group-data-[checked=true]:border-primary flex flex-col items-center justify-between rounded-md border-2 p-4"
>
<ng-icon hlm name="lucideCreditCard" class="mb-3" />
Card
</div>
</brn-radio>
<brn-radio hlm value="paypal" class="group space-x-0">
<div
class="border-muted bg-popover hover:bg-accent hover:text-accent-foreground group-data-[checked=true]:border-primary flex flex-col items-center justify-between rounded-md border-2 p-4"
>
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>PayPal</title>
<path
d="M7.016 19.198h-4.2a.562.562 0 0 1-.555-.65L5.093.584A.692.692 0 0 1 5.776 0h7.222c3.417 0 5.904 2.488 5.846 5.5-.006.25-.027.5-.066.747A6.794 6.794 0 0 1 12.071 12H8.743a.69.69 0 0 0-.682.583l-.325 2.056-.013.083-.692 4.39-.015.087zM19.79 6.142c-.01.087-.01.175-.023.261a7.76 7.76 0 0 1-7.695 6.598H9.007l-.283 1.795-.013.083-.692 4.39-.134.843-.014.088H6.86l-.497 3.15a.562.562 0 0 0 .555.65h3.612c.34 0 .63-.249.683-.585l.952-6.031a.692.692 0 0 1 .683-.584h2.126a6.793 6.793 0 0 0 6.707-5.752c.306-1.95-.466-3.744-1.89-4.906z"
/>
</svg>
PayPal
</div>
</brn-radio>
<brn-radio hlm value="apple" class="group space-x-0">
<div
class="border-muted bg-popover hover:bg-accent hover:text-accent-foreground group-data-[checked=true]:border-primary flex flex-col items-center justify-between rounded-md border-2 p-4"
>
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>Apple</title>
<path
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
/>
</svg>
Apple
</div>
</brn-radio>
<hlm-radio value="card" [class]="cardClass">
<ng-icon hlm name="lucideCreditCard" class="mb-3" />
Card
</hlm-radio>
<hlm-radio value="paypal" [class]="cardClass">
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>PayPal</title>
<path
d="M7.016 19.198h-4.2a.562.562 0 0 1-.555-.65L5.093.584A.692.692 0 0 1 5.776 0h7.222c3.417 0 5.904 2.488 5.846 5.5-.006.25-.027.5-.066.747A6.794 6.794 0 0 1 12.071 12H8.743a.69.69 0 0 0-.682.583l-.325 2.056-.013.083-.692 4.39-.015.087zM19.79 6.142c-.01.087-.01.175-.023.261a7.76 7.76 0 0 1-7.695 6.598H9.007l-.283 1.795-.013.083-.692 4.39-.134.843-.014.088H6.86l-.497 3.15a.562.562 0 0 0 .555.65h3.612c.34 0 .63-.249.683-.585l.952-6.031a.692.692 0 0 1 .683-.584h2.126a6.793 6.793 0 0 0 6.707-5.752c.306-1.95-.466-3.744-1.89-4.906z"
/>
</svg>
PayPal
</hlm-radio>
<hlm-radio value="apple" [class]="cardClass">
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="mb-3 size-6">
<title>Apple</title>
<path
d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"
/>
</svg>
Apple
</hlm-radio>
</hlm-radio-group>
\`,
})
export class RadioGroupCardComponent {
public payment = 'card';

public readonly cardClass = hlm(
'block space-x-0',
// base card styles for the label
'[&>[data-slot=label]]:flex [&>[data-slot=label]]:flex-col [&>[data-slot=label]]:items-center [&>[data-slot=label]]:justify-between [&>[data-slot=label]]:bg-popover [&>[data-slot=label]]:rounded-md [&>[data-slot=label]]:border-2 [&>[data-slot=label]]:border-muted [&>[data-slot=label]]:p-4',
// hover styles
'[&>[data-slot=label]]:hover:bg-accent [&>[data-slot=label]]:hover:text-accent-foreground',
// highlight checked radio
'[&>[data-slot=label]]:data-[checked=true]:border-primary',
);
}
`;
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrnRadioComponent } from '@spartan-ng/brain/radio-group';
import { HlmRadioDirective, HlmRadioGroupComponent, HlmRadioIndicatorComponent } from '@spartan-ng/ui-radiogroup-helm';
import { HlmRadioComponent, HlmRadioGroupComponent, HlmRadioIndicatorComponent } from '@spartan-ng/ui-radiogroup-helm';
import { HlmSmallDirective } from '@spartan-ng/ui-typography-helm';

@Component({
selector: 'spartan-radio-group-preview',
standalone: true,
imports: [
FormsModule,
BrnRadioComponent,
HlmRadioIndicatorComponent,
HlmRadioDirective,
HlmRadioGroupComponent,
HlmSmallDirective,
],
imports: [FormsModule, HlmRadioComponent, HlmRadioIndicatorComponent, HlmRadioGroupComponent, HlmSmallDirective],
template: `
<small hlmSmall class="font-semibold">Choose a version</small>
<hlm-radio-group class="font-mono text-sm font-medium" [(ngModel)]="version">
<brn-radio hlm value="16.1.4">
<hlm-radio value="16.1.4">
<hlm-radio-indicator indicator />
v16.1.4
</brn-radio>
<brn-radio hlm value="16.0.0">
</hlm-radio>
<hlm-radio value="16.0.0">
<hlm-radio-indicator indicator />
v16.0.0
</brn-radio>
<brn-radio hlm value="15.8.0">
</hlm-radio>
<hlm-radio value="15.8.0">
<hlm-radio-indicator indicator />
v15.8.0
</brn-radio>
<brn-radio disabled hlm value="15.2.0">
</hlm-radio>
<hlm-radio disabled value="15.2.0">
<hlm-radio-indicator indicator />
v15.2.0
</brn-radio>
</hlm-radio>
</hlm-radio-group>
`,
})
Expand All @@ -44,40 +36,32 @@ export class RadioGroupPreviewComponent {
export const defaultCode = `
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrnRadioComponent } from '@spartan-ng/brain/radio-group';
import { HlmRadioDirective, HlmRadioGroupComponent, HlmRadioIndicatorComponent } from '@spartan-ng/ui-radiogroup-helm';
import { HlmRadioComponent, HlmRadioGroupComponent, HlmRadioIndicatorComponent } from '@spartan-ng/ui-radiogroup-helm';
import { HlmSmallDirective } from '@spartan-ng/ui-typography-helm';

@Component({
selector: 'spartan-radio-group-preview',
standalone: true,
imports: [
FormsModule,
BrnRadioComponent,
HlmRadioIndicatorComponent,
HlmRadioDirective,
HlmRadioGroupComponent,
HlmSmallDirective,
],
imports: [FormsModule, HlmRadioComponent, HlmRadioIndicatorComponent, HlmRadioGroupComponent, HlmSmallDirective],
template: \`
<small hlmSmall class="font-semibold">Choose a version</small>
<small hlmSmall class="font-semibold">Choose a version</small>
<hlm-radio-group class="font-mono text-sm font-medium" [(ngModel)]="version">
<brn-radio hlm value="16.1.4">
<hlm-radio value="16.1.4">
<hlm-radio-indicator indicator />
v16.1.4
</brn-radio>
<brn-radio hlm value="16.0.0">
</hlm-radio>
<hlm-radio value="16.0.0">
<hlm-radio-indicator indicator />
v16.0.0
</brn-radio>
<brn-radio hlm value="15.8.0">
</hlm-radio>
<hlm-radio value="15.8.0">
<hlm-radio-indicator indicator />
v15.8.0
</brn-radio>
<brn-radio disabled hlm value="15.2.0">
</hlm-radio>
<hlm-radio disabled value="15.2.0">
<hlm-radio-indicator indicator />
v15.2.0
</brn-radio>
</hlm-radio>
</hlm-radio-group>
\`,
})
Expand All @@ -87,18 +71,17 @@ export class RadioGroupPreviewComponent {
`;

export const defaultImports = `
import { BrnRadioComponent } from '@spartan-ng/brain/radio-group';
import {
HlmRadioDirective,
HlmRadioComponent,
HlmRadioGroupComponent,
HlmRadioIndicatorComponent,
} from '@spartan-ng/ui-radiogroup-helm';
`;
export const defaultSkeleton = `
<hlm-radio-group>
<brn-radio hlm value="16.1.4">
<hlm-radio value="16.1.4">
<hlm-radio-indicator indicator />
v16.1.4
</brn-radio>
</hlm-radio>
</hlm-radio-group>
`;
23 changes: 14 additions & 9 deletions libs/brain/radio-group/src/lib/brn-radio.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class BrnRadioChange<T> {
standalone: true,
host: {
class: 'brn-radio',
'[attr.id]': 'id()',
'[attr.id]': 'hostId()',
'[class.brn-radio-checked]': 'checked()',
'[class.brn-radio-disabled]': 'disabledState()',
'[attr.data-checked]': 'checked()',
Expand All @@ -47,7 +47,11 @@ export class BrnRadioChange<T> {
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div style="display: flex; height: fit-content; width: fit-content" (click)="onTouchTargetClick($event)">
<div
data-slot="indicator"
style="display: flex; height: fit-content; width: fit-content"
(click)="onTouchTargetClick($event)"
>
<ng-content select="[target],[indicator]" />
</div>
<input
Expand All @@ -67,7 +71,7 @@ export class BrnRadioChange<T> {
(change)="onInputInteraction($event)"
(click)="onInputClick($event)"
/>
<label style="display: flex; height: fit-content; width: fit-content" [for]="inputId()">
<label [for]="inputId()" data-slot="label">
<ng-content />
</label>
`,
Expand All @@ -81,10 +85,7 @@ export class BrnRadioComponent<T = unknown> implements OnDestroy {
/**
* Whether the radio button is disabled.
*/
public readonly disabled = input<boolean, BooleanInput>(false, {
transform: booleanAttribute,
alias: 'disabled',
});
public readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });

/**
* Whether the radio button is disabled or the radio group is disabled.
Expand All @@ -111,7 +112,7 @@ export class BrnRadioComponent<T = unknown> implements OnDestroy {
/**
* The unique ID for the radio button input. If none is supplied, it will be auto-generated.
*/
public readonly id = input(`brn-radio-${++BrnRadioComponent._nextUniqueId}`);
public readonly id = input<string | undefined>(undefined);

public readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });

Expand All @@ -136,7 +137,11 @@ export class BrnRadioComponent<T = unknown> implements OnDestroy {
*/
public readonly change = output<BrnRadioChange<T>>();

protected readonly inputId = computed(() => `${this.id()}-input`);
protected readonly hostId = computed(() =>
this.id() ? this.id() : `brn-radio-${++BrnRadioComponent._nextUniqueId}`,
);

protected readonly inputId = computed(() => `${this.hostId()}-input`);

protected readonly inputElement = viewChild.required<ElementRef<HTMLInputElement>>('input');

Expand Down
6 changes: 3 additions & 3 deletions libs/ui/radio-group/helm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { NgModule } from '@angular/core';

import { HlmRadioGroupComponent } from './lib/hlm-radio-group.component';
import { HlmRadioIndicatorComponent } from './lib/hlm-radio-indicator.component';
import { HlmRadioDirective } from './lib/hlm-radio.directive';
import { HlmRadioComponent } from './lib/hlm-radio.component';

export * from './lib/hlm-radio-group.component';
export * from './lib/hlm-radio-indicator.component';
export * from './lib/hlm-radio.directive';
export * from './lib/hlm-radio.component';

export const HlmRadioGroupImports = [HlmRadioGroupComponent, HlmRadioDirective, HlmRadioIndicatorComponent];
export const HlmRadioGroupImports = [HlmRadioGroupComponent, HlmRadioComponent, HlmRadioIndicatorComponent];

@NgModule({
imports: [...HlmRadioGroupImports],
Expand Down
Loading
Loading