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

Design system button toggle #671

Merged
merged 10 commits into from
Aug 28, 2024
3 changes: 3 additions & 0 deletions libs/design-system/button-toggle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# @hra-ui/design-system/button-toggle

Secondary entry point of `@hra-ui/design-system`. It can be used by importing from `@hra-ui/design-system/button-toggle`.
5 changes: 5 additions & 0 deletions libs/design-system/button-toggle/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"lib": {
"entryFile": "src/index.ts"
}
}
1 change: 1 addition & 0 deletions libs/design-system/button-toggle/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/providers';
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { computed, Directive, input } from '@angular/core';

/** Input options for icon button size */
export type IconButtonSize = 'medium' | 'large';

/** Interface for ButtonToggle Config */
interface ButtonToggleConfig {
/** Line height of the button */
lineHeight: number;
/** Font variable of the button toggle */
font: string;
}

/** Record of button sizes (number in rem) */
const BUTTON_CONFIG: Record<IconButtonSize, ButtonToggleConfig> = {
medium: {
lineHeight: 21,
font: '--sys-label-medium',
},
large: {
lineHeight: 24,
font: '--sys-label-large',
},
};

/**
* Directive for icon buttons
*/
@Directive({
selector: '[hraButtonToggleSize]',
standalone: true,
host: {
'[style.--mat-standard-button-toggle-height]': 'lineHeight()',
'[style.--mat-standard-button-toggle-label-text-line-height]': 'lineHeight()',
'[style.font]': 'fontVar()',
},
})
export class ToggleButtonSizeDirective {
/** Size of icon button to use */
readonly size = input.required<IconButtonSize>({ alias: 'hraButtonToggleSize' });

/** Gets size of button in rem */
protected readonly buttonSize = computed(() => BUTTON_CONFIG[this.size()]);

/** Gets the font variable for the current button size */
protected readonly fontVar = computed(() => `var(${BUTTON_CONFIG[this.size()].font})`);

/** Gets the line height for the current button size */
protected readonly lineHeight = computed(() => `${BUTTON_CONFIG[this.size()].lineHeight}px`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
mat-button-toggle-group {
--mat-standard-button-toggle-shape: 0.25rem;
--mat-standard-button-toggle-divider-color: var(--sys-primary);
--mat-standard-button-toggle-selected-state-background-color: var(--sys-tertiary);
--mat-standard-button-toggle-selected-state-text-color: var(--sys-on-primary);
--mat-standard-button-toggle-hover-state-layer-opacity: 0.04;
width: 100%;

&.mat-button-toggle-group-appearance-standard {
border: unset;
outline: solid 1px var(--mat-standard-button-toggle-divider-color);
}

.mat-button-toggle {
width: 100%;

&:active {
--mat-standard-button-toggle-hover-state-layer-opacity: 0.08;
}
}

.mat-button-toggle:not(.mat-button-toggle-checked) .mat-button-toggle-button {
padding: 0.5rem 1.15rem;
}

.mat-button-toggle.mat-button-toggle-checked .mat-button-toggle-button {
padding: 0.5rem 0.2rem;
}

&[hraButtonToggleSize='medium'] {
.mat-button-toggle:not(.mat-button-toggle-checked) .mat-button-toggle-button {
padding: 0.3438rem 1.15rem;
}

.mat-button-toggle.mat-button-toggle-checked .mat-button-toggle-button {
padding: 0.3438rem 0.2rem;
}

.mat-button-toggle .mat-button-toggle-label-content {
vertical-align: middle;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';

/**
* Applies button toggle styles globally
*/
@Component({
selector: 'hra-button-toggle-styles',
standalone: true,
template: '',
styleUrls: ['./button-toggle-styles.component.scss'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ButtonToggleStylesComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { applicationConfig, Meta, moduleMetadata, StoryObj } from '@storybook/angular';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { provideButtonToggle } from './providers';
import { ToggleButtonSizeDirective } from './button-toggle-size/button-toggle-size.directive';
const meta: Meta = {
title: 'ButtonToggleComponent',
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/design/BCEJn9KCIbBJ5MzqnojKQp/Design-System-Components?node-id=853-284',
},
},
decorators: [
applicationConfig({
providers: [provideButtonToggle()],
}),
moduleMetadata({
imports: [MatButtonToggleModule, ToggleButtonSizeDirective],
}),
],
};
export default meta;
type Story = StoryObj;

export const SingleSelect: Story = {
bhushankhope marked this conversation as resolved.
Show resolved Hide resolved
args: {
size: 'large',
},
argTypes: {
size: {
control: 'select',
options: ['medium', 'large'],
},
},
render: (args) => ({
props: args,
template: `
<h2>Single Select</h2>
<mat-button-toggle-group name="singleSelect" aria-label="Single Select"
hraButtonToggleSize="${args['size']}">
<mat-button-toggle disableRipple value="button1" checked>Button</mat-button-toggle>
<mat-button-toggle disableRipple value="button2">Button</mat-button-toggle>
<mat-button-toggle disableRipple disabled value="button3">Button</mat-button-toggle>
</mat-button-toggle-group>

<h2>Multi Select</h2>
<mat-button-toggle-group multiple name="multiSelect" aria-label="Multi Select"
hraButtonToggleSize="${args['size']}">
<mat-button-toggle disableRipple value="button1" checked>Button</mat-button-toggle>
<mat-button-toggle disableRipple value="button2">Button</mat-button-toggle>
<mat-button-toggle disableRipple value="button3">Button</mat-button-toggle>
</mat-button-toggle-group>
`,
}),
};
10 changes: 10 additions & 0 deletions libs/design-system/button-toggle/src/lib/providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';
import { provideStyleComponents } from '@hra-ui/cdk/styling';
import { ButtonToggleStylesComponent } from './button-toggle-styles/button-toggle-styles.component';

/**
* Returns providers for button toggle
*/
export function provideButtonToggle(): EnvironmentProviders {
return makeEnvironmentProviders([provideStyleComponents(ButtonToggleStylesComponent)]);
}
3 changes: 3 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
"@hra-ui/design-system/button": [
"libs/design-system/button/src/index.ts"
],
"@hra-ui/design-system/button-toggle": [
"libs/design-system/button-toggle/src/index.ts"
],
"@hra-ui/design-system/footer": [
"libs/design-system/footer/src/index.ts"
],
Expand Down
Loading