mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
feat: implement new text field and button components; remove deprecated search bar and input controls
This commit is contained in:
21
apps/isa-app/.storybook/main.ts
Normal file
21
apps/isa-app/.storybook/main.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { StorybookConfig } from '@storybook/angular';
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ['../stories/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'],
|
||||
addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
|
||||
staticDirs: ['../src/assets'],
|
||||
previewHead: (head) => `
|
||||
${head}
|
||||
<link href="/assets/fonts/fonts.css" rel="stylesheet" />
|
||||
`,
|
||||
framework: {
|
||||
name: '@storybook/angular',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
// To customize your webpack configuration you can use the webpackFinal field.
|
||||
// Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config
|
||||
// and https://nx.dev/recipes/storybook/custom-builder-configs
|
||||
21
apps/isa-app/.storybook/tsconfig.json
Normal file
21
apps/isa-app/.storybook/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true
|
||||
},
|
||||
"exclude": ["../**/*.spec.ts"],
|
||||
"include": [
|
||||
// "../src/**/*.stories.ts",
|
||||
// "../src/**/*.stories.js",
|
||||
// "../src/**/*.stories.jsx",
|
||||
// "../src/**/*.stories.tsx",
|
||||
// "../src/**/*.stories.mdx",
|
||||
"../stories/**/*.stories.ts",
|
||||
"../stories/**/*.stories.js",
|
||||
"../stories/**/*.stories.jsx",
|
||||
"../stories/**/*.stories.tsx",
|
||||
"../stories/**/*.stories.mdx",
|
||||
"*.js",
|
||||
"*.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "isa-app",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"sourceRoot": "apps/isa-app/src",
|
||||
@@ -105,6 +105,56 @@
|
||||
"staticFilePath": "dist/apps/isa-app/browser",
|
||||
"spa": true
|
||||
}
|
||||
},
|
||||
"storybook": {
|
||||
"executor": "@storybook/angular:start-storybook",
|
||||
"options": {
|
||||
"port": 4400,
|
||||
"configDir": "apps/isa-app/.storybook",
|
||||
"browserTarget": "isa-app:build",
|
||||
"compodoc": false,
|
||||
"styles": ["apps/isa-app/src/styles.scss"]
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"quiet": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"build-storybook": {
|
||||
"executor": "@storybook/angular:build-storybook",
|
||||
"outputs": ["{options.outputDir}"],
|
||||
"options": {
|
||||
"outputDir": "dist/storybook/isa-app",
|
||||
"configDir": "apps/isa-app/.storybook",
|
||||
"browserTarget": "isa-app:build",
|
||||
"compodoc": false
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"quiet": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"test-storybook": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "test-storybook -c apps/isa-app/.storybook --url=http://localhost:4400"
|
||||
}
|
||||
},
|
||||
"static-storybook": {
|
||||
"executor": "@nx/web:file-server",
|
||||
"dependsOn": ["build-storybook"],
|
||||
"options": {
|
||||
"buildTarget": "isa-app:build-storybook",
|
||||
"staticFilePath": "dist/storybook/isa-app",
|
||||
"spa": true
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"buildTarget": "isa-app:build-storybook:ci"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
65
apps/isa-app/stories/ui/buttons/ui-button.stories.ts
Normal file
65
apps/isa-app/stories/ui/buttons/ui-button.stories.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
|
||||
import { ButtonColor, ButtonSize, UiButtonComponent } from '@isa/ui/buttons';
|
||||
// import { within } from '@storybook/testing-library';
|
||||
// import { expect } from '@storybook/jest';
|
||||
|
||||
type UiButtonComponentInputs = {
|
||||
color: ButtonColor;
|
||||
size: ButtonSize;
|
||||
pending: boolean;
|
||||
disabled: boolean;
|
||||
};
|
||||
|
||||
const meta: Meta<UiButtonComponentInputs> = {
|
||||
component: UiButtonComponent,
|
||||
title: 'ui/buttons/Button',
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['primary', 'secondary', 'brand', 'tertiary'] as ButtonColor[],
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['small', 'medium', 'large'] as ButtonSize[],
|
||||
},
|
||||
pending: {
|
||||
control: 'boolean',
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
},
|
||||
},
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `<ui-button ${argsToTemplate(args, { exclude: ['disabled'] })} ${args.disabled ? 'disabled' : ''}>Button</ui-button>`,
|
||||
}),
|
||||
};
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<UiButtonComponent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
// export const Heading: Story = {
|
||||
// args: {},
|
||||
// play: async ({ canvasElement }) => {
|
||||
// const canvas = within(canvasElement);
|
||||
// expect(canvas.getByText(/ui-button works!/gi)).toBeTruthy();
|
||||
// },
|
||||
// };
|
||||
|
||||
export const PrimarySmall: Story = {
|
||||
args: {
|
||||
color: 'primary',
|
||||
size: 'small',
|
||||
},
|
||||
};
|
||||
|
||||
export const PrimaryLarge: Story = {
|
||||
args: {
|
||||
color: 'primary',
|
||||
size: 'large',
|
||||
},
|
||||
};
|
||||
58
apps/isa-app/stories/ui/buttons/ui-icon-button.stories.ts
Normal file
58
apps/isa-app/stories/ui/buttons/ui-icon-button.stories.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { argsToTemplate, type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
|
||||
import { IconButtonColor, IconButtonSize, UiIconButtonComponent } from '@isa/ui/buttons';
|
||||
// import { within } from '@storybook/testing-library';
|
||||
// import { expect } from '@storybook/jest';
|
||||
import * as IsaIcons from '@isa/icons';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
|
||||
type UiIconButtonComponentInputs = {
|
||||
color: IconButtonColor;
|
||||
size: IconButtonSize;
|
||||
pending: boolean;
|
||||
disabled: boolean;
|
||||
icon: string;
|
||||
};
|
||||
|
||||
const meta: Meta<UiIconButtonComponentInputs> = {
|
||||
component: UiIconButtonComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [NgIconComponent],
|
||||
providers: [provideIcons(IsaIcons)],
|
||||
}),
|
||||
],
|
||||
title: 'ui/buttons/IconButton',
|
||||
argTypes: {
|
||||
icon: { control: 'select', options: Object.keys(IsaIcons) },
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['brand', 'primary', 'secondary', 'tertiary'] as IconButtonColor[],
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['small', 'medium'] as IconButtonSize[],
|
||||
},
|
||||
pending: {
|
||||
control: 'boolean',
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
icon: 'isaActionCheck',
|
||||
},
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `<ui-icon-button ${argsToTemplate(args, { exclude: ['disabled', 'icon'] })} ${args.disabled ? 'disabled' : ''}>
|
||||
<ng-icon name="${args.icon}"></ng-icon>
|
||||
</ui-icon-button>`,
|
||||
}),
|
||||
};
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<UiIconButtonComponent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
};
|
||||
61
apps/isa-app/stories/ui/buttons/ui-text-button.stories.ts
Normal file
61
apps/isa-app/stories/ui/buttons/ui-text-button.stories.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
|
||||
import { UiTextButtonComponent, TextButtonColor, TextButtonSize } from '@isa/ui/buttons';
|
||||
// import { within } from '@storybook/testing-library';
|
||||
// import { expect } from '@storybook/jest';
|
||||
|
||||
type UiTextButtonComponentInputs = {
|
||||
color: TextButtonColor;
|
||||
size: TextButtonSize;
|
||||
disabled: boolean;
|
||||
};
|
||||
|
||||
const meta: Meta<UiTextButtonComponentInputs> = {
|
||||
component: UiTextButtonComponent,
|
||||
title: 'ui/buttons/TextButton',
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['strong', 'subtle'] as TextButtonColor[],
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['small', 'medium', 'large'] as TextButtonSize[],
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
},
|
||||
},
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `<ui-text-button ${argsToTemplate(args, { exclude: ['disabled'] })} ${args.disabled ? 'disabled' : ''}>Button</ui-text-button>`,
|
||||
}),
|
||||
};
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<UiTextButtonComponent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
// export const Heading: Story = {
|
||||
// args: {},
|
||||
// play: async ({ canvasElement }) => {
|
||||
// const canvas = within(canvasElement);
|
||||
// expect(canvas.getByText(/ui-button works!/gi)).toBeTruthy();
|
||||
// },
|
||||
// };
|
||||
|
||||
export const StrongSmall: Story = {
|
||||
args: {
|
||||
color: 'strong',
|
||||
size: 'small',
|
||||
},
|
||||
};
|
||||
|
||||
export const StrongLarge: Story = {
|
||||
args: {
|
||||
color: 'strong',
|
||||
size: 'large',
|
||||
},
|
||||
};
|
||||
24
apps/isa-app/stories/ui/input-controls/text-field.stories.ts
Normal file
24
apps/isa-app/stories/ui/input-controls/text-field.stories.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { argsToTemplate, type Meta, type StoryObj } from '@storybook/angular';
|
||||
import { TextFieldComponent } from '@isa/ui/input-controls';
|
||||
|
||||
const meta: Meta<TextFieldComponent> = {
|
||||
component: TextFieldComponent,
|
||||
title: 'ui/input-controls/TextField',
|
||||
argTypes: {},
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<ui-text-field>
|
||||
<input type="text" placeholder="Enter your name" />
|
||||
</ui-text-field>
|
||||
`,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<TextFieldComponent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
};
|
||||
61
apps/isa-app/stories/ui/search-bar/search-bar.stories.ts
Normal file
61
apps/isa-app/stories/ui/search-bar/search-bar.stories.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { argsToTemplate, type Meta, type StoryObj, moduleMetadata } from '@storybook/angular';
|
||||
import { UiSearchBarClearComponent, UiSearchBarComponent } from '@isa/ui/search-bar';
|
||||
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';
|
||||
|
||||
export interface UiSearchBarComponentInputs {
|
||||
placeholder: string;
|
||||
value: string;
|
||||
resetValue: string;
|
||||
}
|
||||
|
||||
const meta: Meta<UiSearchBarComponentInputs> = {
|
||||
component: UiSearchBarComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [
|
||||
UiIconButtonComponent,
|
||||
UiSearchBarClearComponent,
|
||||
NgIconComponent,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
],
|
||||
providers: [provideIcons({ isaActionSearch })],
|
||||
}),
|
||||
],
|
||||
title: 'ui/search-bar/SearchBar',
|
||||
argTypes: {
|
||||
placeholder: {
|
||||
control: 'text',
|
||||
},
|
||||
value: {
|
||||
control: 'text',
|
||||
},
|
||||
resetValue: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
placeholder: 'Rechnungsnummer, E-Mail, Kundenkarte, Name...',
|
||||
},
|
||||
render: (args) => ({
|
||||
props: { ...args, control: new FormControl(args.value) },
|
||||
template: `<ui-search-bar ${argsToTemplate(args, { exclude: ['placeholder', 'value', 'resetValue'] })}>
|
||||
<input [formControl]="control" type="text" uiSearchBarInput placeholder="${args.placeholder}" />
|
||||
<ui-search-bar-clear value="${args.resetValue}"></ui-search-bar-clear>
|
||||
<button type="submit" uiIconButton color="brand">
|
||||
<ng-icon name="isaActionSearch"></ng-icon>
|
||||
</button>
|
||||
</ui-search-bar>`,
|
||||
}),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<UiSearchBarComponent>;
|
||||
|
||||
export const Primary: Story = {
|
||||
args: {},
|
||||
};
|
||||
@@ -6,5 +6,11 @@
|
||||
},
|
||||
"files": ["src/main.ts"],
|
||||
"include": ["src/**/*.d.ts"],
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
"exclude": [
|
||||
"jest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"**/*.stories.ts",
|
||||
"**/*.stories.js"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,5 +2,11 @@
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src/**/*.ts"],
|
||||
"compilerOptions": {},
|
||||
"exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
|
||||
"exclude": [
|
||||
"jest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"**/*.stories.ts",
|
||||
"**/*.stories.js"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
},
|
||||
{
|
||||
"path": "./.storybook/tsconfig.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../tsconfig.base.json",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import nx from '@nx/eslint-plugin'
|
||||
import prettierConfig from 'eslint-config-prettier'
|
||||
import prettierPlugin from 'eslint-plugin-prettier'
|
||||
import nx from '@nx/eslint-plugin';
|
||||
import prettierConfig from 'eslint-config-prettier';
|
||||
import prettierPlugin from 'eslint-plugin-prettier';
|
||||
|
||||
export default [
|
||||
...nx.configs['flat/base'],
|
||||
@@ -39,4 +39,4 @@ export default [
|
||||
},
|
||||
...prettierConfig,
|
||||
},
|
||||
]
|
||||
];
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +1,4 @@
|
||||
export * from './lib/button.component';
|
||||
export * from './lib/icon-button.component';
|
||||
export * from './lib/text-button.component';
|
||||
export * from './lib/types';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@if (!pending()) {
|
||||
<ng-content></ng-content>
|
||||
} @else {
|
||||
<ng-icon class="animate-spin" name="isaActionChevron"></ng-icon>
|
||||
<ng-icon size="1.5rem" class="animate-spin text-isa-white" name="isaLoading"></ng-icon>
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
.ui-button {
|
||||
@apply font-sans cursor-pointer;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
border-radius: 6.25rem;
|
||||
}
|
||||
|
||||
.ui-button__small {
|
||||
@@ -36,21 +37,79 @@
|
||||
|
||||
.ui-button__primary {
|
||||
@apply bg-isa-secondary-600 text-isa-white;
|
||||
}
|
||||
|
||||
.ui-button__primary:hover {
|
||||
@apply bg-isa-secondary-700;
|
||||
}
|
||||
&:hover {
|
||||
@apply bg-isa-secondary-700;
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
@apply bg-isa-secondary-800;
|
||||
}
|
||||
|
||||
.ui-button__primary:active,
|
||||
.ui-button.active {
|
||||
@apply bg-isa-secondary-800;
|
||||
}
|
||||
|
||||
.ui-button__primary:disabled {
|
||||
@apply bg-isa-neutral-400;
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button__secondary {
|
||||
@apply border border-solid border-isa-secondary-600 text-isa-secondary-600;
|
||||
|
||||
&:hover {
|
||||
@apply border-isa-secondary-700 bg-isa-neutral-100 text-isa-secondary-700;
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
@apply border-isa-secondary-800 bg-isa-neutral-200 text-isa-secondary-800;
|
||||
}
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply border-isa-neutral-400 text-isa-neutral-400 bg-isa-white;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button__brand {
|
||||
@apply bg-isa-accent-red text-isa-white;
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-shades-red-600;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
@apply bg-isa-shades-red-700;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button__tertiary {
|
||||
@apply bg-isa-neutral-300 text-isa-neutral-900;
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
@apply bg-isa-neutral-500 text-isa-white;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply bg-isa-neutral-200 text-isa-neutral-500;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button:disabled,
|
||||
.ui-button[disabled],
|
||||
.ui-button.disabled {
|
||||
@apply cursor-default;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { ButtonColor, ButtonSize } from './types';
|
||||
import { isaActionChevron } from '@isa/icons';
|
||||
import { isaLoading } from '@isa/icons';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-button, [uiButton]',
|
||||
templateUrl: './button.component.html',
|
||||
styleUrls: ['./button.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
standalone: true,
|
||||
imports: [NgIconComponent],
|
||||
// TODO: Gegen loader icon ersetzen
|
||||
providers: [provideIcons({ isaActionChevron })],
|
||||
providers: [provideIcons({ isaLoading })],
|
||||
host: {
|
||||
'[class]': '["ui-button", sizeClass(), colorClass()]',
|
||||
'[tabindex]': 'tabIndex()',
|
||||
},
|
||||
})
|
||||
export class NameComponent {
|
||||
export class UiButtonComponent {
|
||||
size = input<ButtonSize>('medium');
|
||||
|
||||
sizeClass = computed(() => `ui-button__${this.size()}`);
|
||||
@@ -26,4 +34,6 @@ export class NameComponent {
|
||||
colorClass = computed(() => `ui-button__${this.color()}`);
|
||||
|
||||
pending = input<boolean>(false);
|
||||
|
||||
tabIndex = input<number>(0);
|
||||
}
|
||||
|
||||
5
libs/ui/buttons/src/lib/icon-button.component.html
Normal file
5
libs/ui/buttons/src/lib/icon-button.component.html
Normal file
@@ -0,0 +1,5 @@
|
||||
@if (!pending()) {
|
||||
<ng-content select="ng-icon"></ng-content>
|
||||
} @else {
|
||||
<ng-icon class="animate-spin" name="isaLoading"></ng-icon>
|
||||
}
|
||||
98
libs/ui/buttons/src/lib/icon-button.component.scss
Normal file
98
libs/ui/buttons/src/lib/icon-button.component.scss
Normal file
@@ -0,0 +1,98 @@
|
||||
.ui-icon-button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
@apply rounded-full cursor-pointer bg-isa-white;
|
||||
}
|
||||
|
||||
.ui-icon-button__small {
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
padding: 0.5rem;
|
||||
@apply text-xl;
|
||||
}
|
||||
|
||||
.ui-icon-button__medium {
|
||||
padding: 0.75rem;
|
||||
@apply text-2xl;
|
||||
}
|
||||
|
||||
.ui-icon-button__primary {
|
||||
@apply bg-isa-secondary-600 text-isa-white;
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-secondary-700;
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
@apply bg-isa-secondary-800;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-icon-button__secondary {
|
||||
@apply border border-solid border-isa-secondary-600 text-isa-secondary-600;
|
||||
|
||||
&:hover {
|
||||
@apply border-isa-secondary-700 bg-isa-neutral-100 text-isa-secondary-700;
|
||||
}
|
||||
&:active,
|
||||
&.active {
|
||||
@apply border-isa-secondary-800 bg-isa-neutral-200 text-isa-secondary-800;
|
||||
}
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply border-isa-neutral-400 text-isa-neutral-400 bg-isa-white;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-icon-button__brand {
|
||||
@apply bg-isa-accent-red text-isa-white;
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-shades-red-600;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
@apply bg-isa-shades-red-700;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-icon-button__tertiary {
|
||||
@apply bg-isa-neutral-300 text-isa-neutral-900;
|
||||
|
||||
&:hover {
|
||||
@apply bg-isa-neutral-400;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
@apply bg-isa-neutral-500 text-isa-white;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&[disabled],
|
||||
&.disabled {
|
||||
@apply bg-isa-neutral-200 text-isa-neutral-500;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-icon-button:disabled,
|
||||
.ui-icon-button[disabled],
|
||||
.ui-icon-button.disabled {
|
||||
@apply cursor-default;
|
||||
}
|
||||
38
libs/ui/buttons/src/lib/icon-button.component.ts
Normal file
38
libs/ui/buttons/src/lib/icon-button.component.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { IconButtonColor, IconButtonSize } from './types';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { isaLoading } from '@isa/icons';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-icon-button, [uiIconButton]',
|
||||
templateUrl: './icon-button.component.html',
|
||||
styleUrls: ['./icon-button.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
standalone: true,
|
||||
imports: [NgIconComponent],
|
||||
providers: [provideIcons({ isaLoading })],
|
||||
host: {
|
||||
'[class]': "['ui-icon-button', sizeClass(), colorClass()]",
|
||||
'[tabindex]': 'tabIndex()',
|
||||
},
|
||||
})
|
||||
export class UiIconButtonComponent {
|
||||
size = input<IconButtonSize>('medium');
|
||||
|
||||
sizeClass = computed(() => `ui-icon-button__${this.size()}`);
|
||||
|
||||
color = input<IconButtonColor>('primary');
|
||||
|
||||
colorClass = computed(() => `ui-icon-button__${this.color()}`);
|
||||
|
||||
pending = input<boolean>(false);
|
||||
|
||||
tabIndex = input<number>(0);
|
||||
}
|
||||
1
libs/ui/buttons/src/lib/text-button.component.html
Normal file
1
libs/ui/buttons/src/lib/text-button.component.html
Normal file
@@ -0,0 +1 @@
|
||||
<ng-content></ng-content>
|
||||
55
libs/ui/buttons/src/lib/text-button.component.scss
Normal file
55
libs/ui/buttons/src/lib/text-button.component.scss
Normal file
@@ -0,0 +1,55 @@
|
||||
.ui-text-button {
|
||||
@apply font-sans;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui-text-button__strong {
|
||||
@apply text-isa-accent-blue;
|
||||
|
||||
&:hover {
|
||||
@apply text-isa-secondary-500;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-text-button__subtle {
|
||||
@apply text-isa-neutral-900;
|
||||
text-decoration-line: underline;
|
||||
text-decoration-style: solid;
|
||||
text-decoration-skip-ink: none;
|
||||
text-decoration-thickness: auto;
|
||||
text-underline-offset: auto;
|
||||
text-underline-position: from-font;
|
||||
|
||||
&:hover {
|
||||
@apply text-isa-neutral-700;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-text-button:disabled,
|
||||
.ui-text-button[disabled],
|
||||
.ui-text-button.disabled {
|
||||
@apply text-isa-neutral-400 cursor-default;
|
||||
}
|
||||
|
||||
.ui-text-button__small {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem; /* 133.333% */
|
||||
}
|
||||
|
||||
.ui-text-button__medium {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem; /* 142.857% */
|
||||
}
|
||||
|
||||
.ui-text-button__large {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5rem; /* 150% */
|
||||
}
|
||||
33
libs/ui/buttons/src/lib/text-button.component.ts
Normal file
33
libs/ui/buttons/src/lib/text-button.component.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { TextButtonColor, TextButtonSize } from './types';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-text-button, [uiTextButton]',
|
||||
templateUrl: './text-button.component.html',
|
||||
styleUrls: ['./text-button.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
standalone: true,
|
||||
imports: [],
|
||||
host: {
|
||||
'[class]': '["ui-text-button", sizeClass(), colorClass()]',
|
||||
'[tabindex]': 'tabIndex()',
|
||||
},
|
||||
})
|
||||
export class UiTextButtonComponent {
|
||||
size = input<TextButtonSize>('medium');
|
||||
|
||||
sizeClass = computed(() => `ui-text-button__${this.size()}`);
|
||||
|
||||
color = input<TextButtonColor>('strong');
|
||||
|
||||
colorClass = computed(() => `ui-text-button__${this.color()}`);
|
||||
|
||||
tabIndex = input<number>(0);
|
||||
}
|
||||
@@ -14,3 +14,25 @@ export const ButtonColor = {
|
||||
} as const;
|
||||
|
||||
export type ButtonColor = (typeof ButtonColor)[keyof typeof ButtonColor];
|
||||
|
||||
export const TextButtonSize = ButtonSize;
|
||||
|
||||
export type TextButtonSize = (typeof TextButtonSize)[keyof typeof TextButtonSize];
|
||||
|
||||
export const TextButtonColor = {
|
||||
Strong: 'strong',
|
||||
Subtle: 'subtle',
|
||||
} as const;
|
||||
|
||||
export type TextButtonColor = (typeof TextButtonColor)[keyof typeof TextButtonColor];
|
||||
|
||||
export const IconButtonSize = {
|
||||
Small: 'small',
|
||||
Medium: 'medium',
|
||||
} as const;
|
||||
|
||||
export type IconButtonSize = (typeof IconButtonSize)[keyof typeof IconButtonSize];
|
||||
|
||||
export const IconButtonColor = ButtonColor;
|
||||
|
||||
export type IconButtonColor = (typeof IconButtonColor)[keyof typeof IconButtonColor];
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from './lib/ui-input-controls/ui-input-controls.component';
|
||||
export * from './lib/text-field/text-field.component';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="ui-text-field__wrapper">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
@@ -0,0 +1,44 @@
|
||||
.ui-text-field {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
border-radius: 6.25rem;
|
||||
height: 3.5rem;
|
||||
@apply bg-isa-white;
|
||||
@apply border border-solid border-isa-neutral-600;
|
||||
|
||||
@apply focus-within:border-isa-neutral-900;
|
||||
|
||||
&:has(input.ng-invalid) {
|
||||
@apply border-isa-accent-red;
|
||||
}
|
||||
|
||||
.ui-text-field__wrapper {
|
||||
display: flex;
|
||||
width: 22.875rem;
|
||||
height: 2.5rem;
|
||||
min-width: 10rem;
|
||||
padding: 0.5rem 1.25rem;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
@apply focus:outline-none;
|
||||
@apply text-isa-neutral-900 appearance-none;
|
||||
|
||||
font-size: 0.875rem;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1.25rem; /* 142.857% */
|
||||
|
||||
&::placeholder {
|
||||
@apply text-isa-neutral-400;
|
||||
}
|
||||
|
||||
&:hover::placeholder,
|
||||
&:focus::placeholder {
|
||||
@apply text-isa-neutral-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-text-field',
|
||||
templateUrl: './text-field.component.html',
|
||||
styleUrls: ['./text-field.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [],
|
||||
host: {
|
||||
'[class]': '["ui-text-field"]',
|
||||
},
|
||||
})
|
||||
export class TextFieldComponent {}
|
||||
@@ -1 +0,0 @@
|
||||
<p>UiInputControls works!</p>
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { UiInputControlsComponent } from './ui-input-controls.component';
|
||||
|
||||
describe('UiInputControlsComponent', () => {
|
||||
let component: UiInputControlsComponent;
|
||||
let fixture: ComponentFixture<UiInputControlsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [UiInputControlsComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UiInputControlsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-ui-input-controls',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './ui-input-controls.component.html',
|
||||
styleUrl: './ui-input-controls.component.css',
|
||||
})
|
||||
export class UiInputControlsComponent {}
|
||||
@@ -26,9 +26,4 @@ export default [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.html'],
|
||||
// Override or add rules here
|
||||
rules: {},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './lib/ui-search-bar/ui-search-bar.component';
|
||||
export * from './lib/search-bar-clear.component';
|
||||
export * from './lib/search-bar.component';
|
||||
|
||||
38
libs/ui/search-bar/src/lib/search-bar-clear.component.ts
Normal file
38
libs/ui/search-bar/src/lib/search-bar-clear.component.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
inject,
|
||||
input,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { isaActionClose } from '@isa/icons';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { UiSearchBarComponent } from './search-bar.component';
|
||||
import { asapScheduler } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-search-bar-clear',
|
||||
template: '<ng-icon name="isaActionClose"></ng-icon>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
standalone: true,
|
||||
imports: [NgIconComponent],
|
||||
providers: [provideIcons({ isaActionClose })],
|
||||
host: {
|
||||
'[class]': "['ui-search-bar__action__close']",
|
||||
'(click)': 'reset(null)',
|
||||
},
|
||||
})
|
||||
export class UiSearchBarClearComponent {
|
||||
private searchBar = inject(UiSearchBarComponent);
|
||||
|
||||
value = input<unknown>();
|
||||
|
||||
reset(value?: unknown): void {
|
||||
const resetValue = value ?? this.value();
|
||||
this.searchBar.inputControl().reset(resetValue);
|
||||
asapScheduler.schedule(() => {
|
||||
this.searchBar.inputControlElementRef().nativeElement.focus();
|
||||
});
|
||||
}
|
||||
}
|
||||
8
libs/ui/search-bar/src/lib/search-bar.component.html
Normal file
8
libs/ui/search-bar/src/lib/search-bar.component.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<ng-content select="[uiSearchBarInput]"></ng-content>
|
||||
|
||||
@let control = inputControl();
|
||||
|
||||
<div class="ui-search-bar__actions">
|
||||
<ng-content select="ui-search-bar-clear"></ng-content>
|
||||
<ng-content select="[uiIconButton]"></ng-content>
|
||||
</div>
|
||||
58
libs/ui/search-bar/src/lib/search-bar.component.scss
Normal file
58
libs/ui/search-bar/src/lib/search-bar.component.scss
Normal file
@@ -0,0 +1,58 @@
|
||||
.ui-search-bar {
|
||||
display: flex;
|
||||
width: 32.5rem;
|
||||
height: 3.75rem;
|
||||
padding: 0rem 0.5rem 0rem 1.5rem;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
@apply bg-isa-white rounded-full;
|
||||
|
||||
.ui-search-bar__action__close {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
&:has(input[type="text"]:placeholder-shown) {
|
||||
.ui-search-bar__action__close {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
appearance: none;
|
||||
flex-grow: 1;
|
||||
|
||||
font-size: 0.875rem;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 1.25rem; /* 142.857% */
|
||||
@apply text-isa-neutral-900;
|
||||
|
||||
&::placeholder {
|
||||
@apply text-isa-neutral-500;
|
||||
font-size: 0.875rem;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: 1.25rem; /* 142.857% */
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
@apply text-isa-neutral-900;
|
||||
}
|
||||
}
|
||||
|
||||
@apply focus:outline-none;
|
||||
}
|
||||
|
||||
.ui-search-bar__actions {
|
||||
@apply flex items-center gap-4 shrink-0;
|
||||
}
|
||||
|
||||
.ui-search-bar__action__close {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
@apply text-2xl cursor-pointer;
|
||||
}
|
||||
28
libs/ui/search-bar/src/lib/search-bar.component.ts
Normal file
28
libs/ui/search-bar/src/lib/search-bar.component.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
contentChild,
|
||||
ElementRef,
|
||||
ViewEncapsulation,
|
||||
} from '@angular/core';
|
||||
import { isaActionClose } from '@isa/icons';
|
||||
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||
import { NgControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-search-bar',
|
||||
imports: [NgIconComponent],
|
||||
templateUrl: './search-bar.component.html',
|
||||
styleUrl: './search-bar.component.scss',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [provideIcons({ isaActionClose })],
|
||||
host: {
|
||||
'[class]': '["ui-search-bar"]',
|
||||
},
|
||||
})
|
||||
export class UiSearchBarComponent {
|
||||
inputControl = contentChild.required(NgControl, { read: NgControl });
|
||||
|
||||
inputControlElementRef = contentChild.required(NgControl, { read: ElementRef });
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<p>UiSearchBar works!</p>
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { UiSearchBarComponent } from './ui-search-bar.component';
|
||||
|
||||
describe('UiSearchBarComponent', () => {
|
||||
let component: UiSearchBarComponent;
|
||||
let fixture: ComponentFixture<UiSearchBarComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [UiSearchBarComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UiSearchBarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-ui-search-bar',
|
||||
imports: [CommonModule],
|
||||
templateUrl: './ui-search-bar.component.html',
|
||||
styleUrl: './ui-search-bar.component.css',
|
||||
})
|
||||
export class UiSearchBarComponent {}
|
||||
8
nx.json
8
nx.json
@@ -44,6 +44,9 @@
|
||||
"cache": true,
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"]
|
||||
},
|
||||
"build-storybook": {
|
||||
"cache": true
|
||||
}
|
||||
},
|
||||
"defaultBase": "develop",
|
||||
@@ -59,7 +62,10 @@
|
||||
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
|
||||
"!{projectRoot}/jest.config.[jt]s",
|
||||
"!{projectRoot}/src/test-setup.[jt]s",
|
||||
"!{projectRoot}/test-setup.[jt]s"
|
||||
"!{projectRoot}/test-setup.[jt]s",
|
||||
"!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)",
|
||||
"!{projectRoot}/.storybook/**/*",
|
||||
"!{projectRoot}/tsconfig.storybook.json"
|
||||
]
|
||||
},
|
||||
"generators": {
|
||||
|
||||
3639
package-lock.json
generated
3639
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -75,6 +75,13 @@
|
||||
"@schematics/angular": "^19.1.8",
|
||||
"@softarc/eslint-plugin-sheriff": "^0.18.0",
|
||||
"@softarc/sheriff-core": "^0.18.0",
|
||||
"@storybook/addon-essentials": "^8.4.6",
|
||||
"@storybook/addon-interactions": "^8.4.6",
|
||||
"@storybook/angular": "^8.4.6",
|
||||
"@storybook/core-server": "^8.4.6",
|
||||
"@storybook/jest": "^0.2.3",
|
||||
"@storybook/test-runner": "^0.19.0",
|
||||
"@storybook/testing-library": "^0.2.2",
|
||||
"@swc-node/register": "~1.9.1",
|
||||
"@swc/core": "~1.5.7",
|
||||
"@swc/helpers": "~0.5.11",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const plugin = require('tailwindcss/plugin')
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
@@ -83,6 +83,7 @@ module.exports = {
|
||||
white: '#FFFFFF',
|
||||
accent: {
|
||||
red: '#DF001B',
|
||||
blue: '#354ACB',
|
||||
},
|
||||
shades: {
|
||||
red: {
|
||||
@@ -245,7 +246,7 @@ module.exports = {
|
||||
require('./tailwind-plugins/section.plugin.js'),
|
||||
require('./tailwind-plugins/typography.plugin.js'),
|
||||
plugin(({ addVariant }) => {
|
||||
addVariant('open', '&.open')
|
||||
addVariant('open', '&.open');
|
||||
}),
|
||||
],
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"@ui/*": ["apps/isa-app/src/ui/*/index.ts"],
|
||||
"@utils/*": ["apps/isa-app/src/utils/*/index.ts"],
|
||||
"packageJson": ["package.json"]
|
||||
}
|
||||
},
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,10 @@
|
||||
"angularCompilerOptions": {
|
||||
"strictTemplates": true
|
||||
},
|
||||
"extends": "./tsconfig.base.json"
|
||||
"extends": "./tsconfig.base.json",
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user