feat: add ui-toolbar component and update button components

This commit is contained in:
Lorenz Hilpert
2025-03-07 15:51:17 +01:00
parent 592027f648
commit 73fd487a13
25 changed files with 281 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
import { ButtonColor, ButtonSize, UiButtonComponent } from '@isa/ui/buttons';
import { ButtonColor, ButtonSize, ButtonComponent } from '@isa/ui/buttons';
// import { within } from '@storybook/testing-library';
// import { expect } from '@storybook/jest';
@@ -11,7 +11,7 @@ type UiButtonComponentInputs = {
};
const meta: Meta<UiButtonComponentInputs> = {
component: UiButtonComponent,
component: ButtonComponent,
title: 'ui/buttons/Button',
argTypes: {
color: {
@@ -36,7 +36,7 @@ const meta: Meta<UiButtonComponentInputs> = {
};
export default meta;
type Story = StoryObj<UiButtonComponent>;
type Story = StoryObj<ButtonComponent>;
export const Default: Story = {
args: {},

View File

@@ -1,5 +1,5 @@
import { argsToTemplate, type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
import { IconButtonColor, IconButtonSize, UiIconButtonComponent } from '@isa/ui/buttons';
import { IconButtonColor, IconButtonSize, IconButtonComponent } from '@isa/ui/buttons';
// import { within } from '@storybook/testing-library';
// import { expect } from '@storybook/jest';
import * as IsaIcons from '@isa/icons';
@@ -14,7 +14,7 @@ type UiIconButtonComponentInputs = {
};
const meta: Meta<UiIconButtonComponentInputs> = {
component: UiIconButtonComponent,
component: IconButtonComponent,
decorators: [
moduleMetadata({
imports: [NgIconComponent],
@@ -51,7 +51,7 @@ const meta: Meta<UiIconButtonComponentInputs> = {
};
export default meta;
type Story = StoryObj<UiIconButtonComponent>;
type Story = StoryObj<IconButtonComponent>;
export const Default: Story = {
args: {},

View File

@@ -1,5 +1,5 @@
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
import { UiTextButtonComponent, TextButtonColor, TextButtonSize } from '@isa/ui/buttons';
import { TextButtonComponent, TextButtonColor, TextButtonSize } from '@isa/ui/buttons';
// import { within } from '@storybook/testing-library';
// import { expect } from '@storybook/jest';
@@ -10,7 +10,7 @@ type UiTextButtonComponentInputs = {
};
const meta: Meta<UiTextButtonComponentInputs> = {
component: UiTextButtonComponent,
component: TextButtonComponent,
title: 'ui/buttons/TextButton',
argTypes: {
color: {
@@ -32,7 +32,7 @@ const meta: Meta<UiTextButtonComponentInputs> = {
};
export default meta;
type Story = StoryObj<UiTextButtonComponent>;
type Story = StoryObj<TextButtonComponent>;
export const Default: Story = {
args: {},

View File

@@ -1,6 +1,6 @@
import { argsToTemplate, type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
import { EmptyStateComponent } from '@isa/ui/empty-state';
import { UiButtonComponent } from '@isa/ui/buttons';
import { ButtonComponent } from '@isa/ui/buttons';
type EmptyStateComponentInputs = {
title: string;
@@ -12,7 +12,7 @@ const meta: Meta<EmptyStateComponentInputs> = {
title: 'ui/empty-state/EmptyState',
decorators: [
moduleMetadata({
imports: [UiButtonComponent],
imports: [ButtonComponent],
}),
],
argTypes: {

View File

@@ -3,7 +3,7 @@ import { UiSearchBarClearComponent, UiSearchBarComponent } from '@isa/ui/search-
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { isaActionSearch } from '@isa/icons';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { UiIconButtonComponent } from '@isa/ui/buttons';
import { IconButtonComponent } from '@isa/ui/buttons';
export interface UiSearchBarComponentInputs {
placeholder: string;
@@ -16,7 +16,7 @@ const meta: Meta<UiSearchBarComponentInputs> = {
decorators: [
moduleMetadata({
imports: [
UiIconButtonComponent,
IconButtonComponent,
UiSearchBarClearComponent,
NgIconComponent,
FormsModule,

View File

@@ -0,0 +1,55 @@
import { type Meta, type StoryObj, argsToTemplate, moduleMetadata } from '@storybook/angular';
import { ToolbarComponent, ToolbarSize } from '@isa/ui/toolbar';
import { TextButtonComponent } from '@isa/ui/buttons';
const meta: Meta<ToolbarComponent> = {
component: ToolbarComponent,
decorators: [
moduleMetadata({
imports: [TextButtonComponent],
}),
],
title: 'ui/toolbar/Toolbar',
argTypes: {
size: {
control: 'select',
options: Object.values(ToolbarSize),
},
},
args: {},
};
export default meta;
type Story = StoryObj<ToolbarComponent>;
export const Sortbar: Story = {
args: {},
render: (args) => ({
props: args,
template: `<ui-toolbar ${argsToTemplate(args)}>
<span class="text-isa-neutral-600 isa-text-body-1-regular">Sortieren</span>
<div class="flex-grow"></div>
<button uiTextButton>Belegdatum</button>
<button uiTextButton>Email</button>
<button uiTextButton>Name</button>
<button uiTextButton>PLZ</button>
</ui-toolbar>`,
}),
};
export const SmallToolbar: Story = {
args: {
size: 'small',
},
render: (args) => ({
props: args,
template: `<ui-toolbar ${argsToTemplate(args)}>
<span class="isa-text-body-2-bold">2 Artikel</span>
<span class="isa-text-body-2-bold">18.10.2024</span>
<span class="isa-text-body-2-regular">562831968883788</span>
<div class="flex-grow"></div>
<button uiTextButton color="strong">Alle auswählen</button>
</ui-toolbar>`,
}),
};

View File

@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';
import { UiSearchBarComponent } from '@isa/ui/search-bar';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { UiIconButtonComponent } from '@isa/ui/buttons';
import { IconButtonComponent } from '@isa/ui/buttons';
import { NgIconComponent, provideIcons } from '@ng-icons/core';
import { isaActionSearch } from '@isa/icons';
import { FilterService, TextFilterInput } from '../../core';
@@ -13,7 +13,7 @@ import { InputType } from '../../types';
styleUrls: ['./search-bar-input.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [UiSearchBarComponent, UiIconButtonComponent, NgIconComponent, ReactiveFormsModule],
imports: [UiSearchBarComponent, IconButtonComponent, NgIconComponent, ReactiveFormsModule],
providers: [provideIcons({ isaActionSearch })],
})
export class SearchBarInputComponent {

View File

@@ -24,7 +24,7 @@ import { isaLoading } from '@isa/icons';
'[tabindex]': 'tabIndex()',
},
})
export class UiButtonComponent {
export class ButtonComponent {
size = input<ButtonSize>('medium');
sizeClass = computed(() => `ui-button__${this.size()}`);

View File

@@ -23,7 +23,7 @@ import { isaLoading } from '@isa/icons';
'[tabindex]': 'tabIndex()',
},
})
export class UiIconButtonComponent {
export class IconButtonComponent {
size = input<IconButtonSize>('medium');
sizeClass = computed(() => `ui-icon-button__${this.size()}`);

View File

@@ -11,6 +11,14 @@
cursor: pointer;
}
.ui-text-button__normal {
@apply text-isa-neutral-900;
&:hover {
@apply text-isa-neutral-700;
}
}
.ui-text-button__strong {
@apply text-isa-accent-blue;

View File

@@ -20,12 +20,12 @@ import { TextButtonColor, TextButtonSize } from './types';
'[tabindex]': 'tabIndex()',
},
})
export class UiTextButtonComponent {
export class TextButtonComponent {
size = input<TextButtonSize>('medium');
sizeClass = computed(() => `ui-text-button__${this.size()}`);
color = input<TextButtonColor>('strong');
color = input<TextButtonColor>('normal');
colorClass = computed(() => `ui-text-button__${this.color()}`);

View File

@@ -20,6 +20,7 @@ export const TextButtonSize = ButtonSize;
export type TextButtonSize = (typeof TextButtonSize)[keyof typeof TextButtonSize];
export const TextButtonColor = {
Normal: 'normal',
Strong: 'strong',
Subtle: 'subtle',
} as const;

View File

@@ -0,0 +1,7 @@
# ui-toolbar
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test ui-toolbar` to execute the unit tests.

View File

@@ -0,0 +1,34 @@
import nx from '@nx/eslint-plugin';
import baseConfig from '../../../eslint.config.mjs';
export default [
...baseConfig,
...nx.configs['flat/angular'],
...nx.configs['flat/angular-template'],
{
files: ['**/*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{
type: 'attribute',
prefix: 'ui',
style: 'camelCase',
},
],
'@angular-eslint/component-selector': [
'error',
{
type: 'element',
prefix: 'ui',
style: 'kebab-case',
},
],
},
},
{
files: ['**/*.html'],
// Override or add rules here
rules: {},
},
];

View File

@@ -0,0 +1,21 @@
export default {
displayName: 'ui-toolbar',
preset: '../../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../../coverage/libs/ui/toolbar',
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
};

View File

@@ -0,0 +1,20 @@
{
"name": "ui-toolbar",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/ui/toolbar/src",
"prefix": "ui",
"projectType": "library",
"tags": [],
"targets": {
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/ui/toolbar/jest.config.ts"
}
},
"lint": {
"executor": "@nx/eslint:lint"
}
}
}

View File

@@ -0,0 +1 @@
export * from './lib/toolbar.component';

View File

@@ -0,0 +1 @@
<ng-content></ng-content>

View File

@@ -0,0 +1,16 @@
.ui-toolbar {
display: flex;
height: 3.25rem;
padding: 1rem 1.5rem;
justify-content: flex-start;
align-items: flex-start;
gap: 2.5rem;
@apply rounded-full bg-isa-neutral-400;
}
.ui-toolbar__small {
height: 3rem;
gap: 1.5rem;
font-size: 0.875rem;
}

View File

@@ -0,0 +1,30 @@
import {
ChangeDetectionStrategy,
Component,
computed,
input,
ViewEncapsulation,
} from '@angular/core';
export const ToolbarSize = {
Small: 'small',
Medium: 'medium',
} as const;
export type ToolbarSize = (typeof ToolbarSize)[keyof typeof ToolbarSize];
@Component({
selector: 'ui-toolbar',
templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
'[class]': '["ui-toolbar", sizeClass()]',
},
})
export class ToolbarComponent {
size = input<ToolbarSize>('medium');
sizeClass = computed(() => `ui-toolbar__${this.size()}`);
}

View File

@@ -0,0 +1,6 @@
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
setupZoneTestEnv({
errorOnUnknownElements: true,
errorOnUnknownProperties: true,
});

View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es2022",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"extends": "../../../tsconfig.base.json",
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}

View File

@@ -0,0 +1,17 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": []
},
"exclude": [
"src/**/*.spec.ts",
"src/test-setup.ts",
"jest.config.ts",
"src/**/*.test.ts"
],
"include": ["src/**/*.ts"]
}

View File

@@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"target": "es2016",
"types": ["jest", "node"]
},
"files": ["src/test-setup.ts"],
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

View File

@@ -54,6 +54,7 @@
"@isa/ui/input-controls": ["libs/ui/input-controls/src/index.ts"],
"@isa/ui/item-rows": ["libs/ui/item-rows/src/index.ts"],
"@isa/ui/search-bar": ["libs/ui/search-bar/src/index.ts"],
"@isa/ui/toolbar": ["libs/ui/toolbar/src/index.ts"],
"@modal/*": ["apps/isa-app/src/modal/*/index.ts"],
"@page/*": ["apps/isa-app/src/page/*/index.ts"],
"@shared/*": ["apps/isa-app/src/shared/*/index.ts"],