From 797aa3df9696c03f82744597c94c0f54afe36a45 Mon Sep 17 00:00:00 2001 From: Tim Fabian Date: Tue, 26 Aug 2025 00:46:39 +0200 Subject: [PATCH] fixed angular library --- cspell.words.txt | 3 +- package-lock.json | 4 +- package.json | 2 +- .../add-angular-library.command.ts | 65 +++++++++++++--- .../button-component-html.content.ts | 16 ++++ .../button-component-ts.content.ts | 33 ++++++++ .../button-stories-ts.content.ts | 45 +++++++++++ .../storybook-main-ts.content.ts | 27 +++++++ src/commands/init/init.command.ts | 20 +---- .../init/tailwind-config-js.content.ts | 78 +++++++++++++++++++ src/npm/npm-package.enum.ts | 2 +- src/npm/package-json.model.ts | 6 +- 12 files changed, 269 insertions(+), 32 deletions(-) create mode 100644 src/commands/add/add-angular-library/button-component-html.content.ts create mode 100644 src/commands/add/add-angular-library/button-component-ts.content.ts create mode 100644 src/commands/add/add-angular-library/button-stories-ts.content.ts create mode 100644 src/commands/add/add-angular-library/storybook-main-ts.content.ts create mode 100644 src/commands/init/tailwind-config-js.content.ts diff --git a/cspell.words.txt b/cspell.words.txt index ddcd138..f2a7fd3 100644 --- a/cspell.words.txt +++ b/cspell.words.txt @@ -41,4 +41,5 @@ cldrjs htpasswd basicauth usersfile -zibri \ No newline at end of file +zibri +autodocs \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 58a6f16..10bdc9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "monux-cli", - "version": "2.5.0", + "version": "2.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "monux-cli", - "version": "2.5.0", + "version": "2.5.1", "license": "MIT", "dependencies": { "chalk": "^4.1.2", diff --git a/package.json b/package.json index 43c3608..c0f3ff9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "monux-cli", - "version": "2.5.0", + "version": "2.5.1", "license": "MIT", "main": "index.js", "engines": { diff --git a/src/commands/add/add-angular-library/add-angular-library.command.ts b/src/commands/add/add-angular-library/add-angular-library.command.ts index 9bb8869..82da42a 100644 --- a/src/commands/add/add-angular-library/add-angular-library.command.ts +++ b/src/commands/add/add-angular-library/add-angular-library.command.ts @@ -1,3 +1,7 @@ +import { buttonComponentHtmlContent } from './button-component-html.content'; +import { buttonComponentTsContent } from './button-component-ts.content'; +import { buttonStoriesTsContent } from './button-stories-ts.content'; +import { storybookMainTsContent } from './storybook-main-ts.content'; import { AngularUtilities } from '../../../angular'; import { ANGULAR_JSON_FILE_NAME, BASE_TS_CONFIG_FILE_NAME, ESLINT_CONFIG_FILE_NAME, GIT_IGNORE_FILE_NAME, LIBS_DIRECTORY_NAME, PACKAGE_JSON_FILE_NAME } from '../../../constants'; import { FsUtilities, JsonUtilities, QuestionsFor } from '../../../encapsulation'; @@ -56,7 +60,6 @@ export class AddAngularLibraryCommand extends BaseAddCommand { - await FsUtilities.updateFile(getPath(root, 'src', 'public-api.ts'), '', 'replace'); - } - private async setupTailwind(root: string): Promise { await TailwindUtilities.setupProjectTailwind(root); await FsUtilities.createFile(getPath(root, 'src', 'styles.css'), [ @@ -96,7 +95,8 @@ export class AddAngularLibraryCommand extends BaseAddCommand { + await FsUtilities.updateFile(getPath(newProject.path, 'src', 'public-api.ts'), 'export * from \'./stories\';', 'replace'); + await FsUtilities.createFile( + getPath(newProject.path, 'src', 'stories', 'index.ts'), + 'export * from \'./button/button.component\';' + ); + await FsUtilities.createFile( + getPath(newProject.path, 'src', 'stories', 'button', 'button.component.ts'), + buttonComponentTsContent + ); + await FsUtilities.createFile( + getPath(newProject.path, 'src', 'stories', 'button', 'button.component.html'), + buttonComponentHtmlContent + ); + await FsUtilities.createFile( + getPath(newProject.path, 'src', 'stories', 'button', 'button.stories.ts'), + buttonStoriesTsContent + ); + } + + private async cleanup(newProject: WorkspaceProject): Promise { + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', '.eslintrc.json')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'button.component.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'button.css')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'button.stories.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'header.component.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'header.css')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'header.stories.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'page.component.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'page.css')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'page.stories.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'user.ts')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'Configure.mdx')); + await FsUtilities.rm(getPath(newProject.path, 'src', 'stories', 'assets')); + } + private async setupTsConfig(root: Path, config: AddAngularLibraryConfiguration): Promise { // eslint-disable-next-line no-console console.log('sets up tsconfig'); @@ -238,7 +284,8 @@ export class AddAngularLibraryCommand extends BaseAddCommand + +`; \ No newline at end of file diff --git a/src/commands/add/add-angular-library/button-component-ts.content.ts b/src/commands/add/add-angular-library/button-component-ts.content.ts new file mode 100644 index 0000000..b15de7e --- /dev/null +++ b/src/commands/add/add-angular-library/button-component-ts.content.ts @@ -0,0 +1,33 @@ +// eslint-disable-next-line jsdoc/require-jsdoc +export const buttonComponentTsContent: string += `import { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; + +/** + * A button. + */ +@Component({ + selector: 'ui-button', + standalone: true, + imports: [CommonModule], + templateUrl: './button.component.html' +}) +export class ButtonComponent { + /** + * The type of the button. + */ + @Input() + buttonType: 'button' | 'menu' | 'reset' | 'submit' = 'button'; + + /** + * The color theme of the button. + */ + @Input() + color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' = 'primary'; + + /** + * Whether or not the button should look raised. + */ + @Input() + raised: boolean = true; +}`; \ No newline at end of file diff --git a/src/commands/add/add-angular-library/button-stories-ts.content.ts b/src/commands/add/add-angular-library/button-stories-ts.content.ts new file mode 100644 index 0000000..bf76c3f --- /dev/null +++ b/src/commands/add/add-angular-library/button-stories-ts.content.ts @@ -0,0 +1,45 @@ +// eslint-disable-next-line jsdoc/require-jsdoc +export const buttonStoriesTsContent: string += `import { componentWrapperDecorator, StoryFn, type Meta } from '@storybook/angular'; + +import { ButtonComponent } from './button.component'; + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories +const meta: Meta = { + title: 'Components/Button', + component: ButtonComponent, + decorators: [componentWrapperDecorator(ButtonComponent, ({ args }) => ({ ...args }))], + tags: ['autodocs'], + argTypes: { + color: { + control: 'select', + options: ['primary', 'secondary', 'success', 'warning', 'error'], + description: 'The color theme of the button.', + table: { + defaultValue: { + summary: 'primary' + } + } + }, + buttonType: { + control: 'select', + options: ['button', 'menu', 'reset', 'submit'], + description: 'The html button type, what it should be used for.', + table: { + defaultValue: { + summary: 'button' + } + } + }, + raised: { + control: 'boolean' + } + }, + args: {} +}; + +export default meta; + +type Story = StoryFn; + +export const Default: Story = (args) => ({ ...args, template: 'Primary' });`; \ No newline at end of file diff --git a/src/commands/add/add-angular-library/storybook-main-ts.content.ts b/src/commands/add/add-angular-library/storybook-main-ts.content.ts new file mode 100644 index 0000000..27a9a4b --- /dev/null +++ b/src/commands/add/add-angular-library/storybook-main-ts.content.ts @@ -0,0 +1,27 @@ +// eslint-disable-next-line jsdoc/require-jsdoc +export const storybookMainTsContent: string += `import { join, dirname } from 'path'; + +import type { StorybookConfig } from '@storybook/angular'; + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + * @param value - The original value to get the absolute path for. + * @returns The absolute path. + */ +function getAbsolutePath(value: string): string { + // eslint-disable-next-line typescript/no-unsafe-return, typescript/no-unsafe-call, typescript/no-unsafe-member-access + return dirname(require.resolve(join(value, 'package.json'))); +} + +const config: StorybookConfig = { + stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [getAbsolutePath('@storybook/addon-docs')], + framework: { + name: getAbsolutePath('@storybook/angular'), + options: {} + } +}; + +export default config;`; \ No newline at end of file diff --git a/src/commands/init/init.command.ts b/src/commands/init/init.command.ts index ed29645..7c22039 100644 --- a/src/commands/init/init.command.ts +++ b/src/commands/init/init.command.ts @@ -1,7 +1,7 @@ import { initConfigQuestions, InitConfiguration } from './init-configuration.model'; import { APPS_DIRECTORY_NAME, ENV_FILE_NAME, ENVIRONMENT_TS_FILE_NAME, ESLINT_CONFIG_FILE_NAME, GIT_IGNORE_FILE_NAME, LIBS_DIRECTORY_NAME, ROBOTS_FILE_NAME, TAILWIND_CONFIG_FILE_NAME } from '../../constants'; import { DockerUtilities } from '../../docker'; -import { COLOR_PRIMARY, CPUtilities, FsUtilities, InquirerUtilities } from '../../encapsulation'; +import { CPUtilities, FsUtilities, InquirerUtilities } from '../../encapsulation'; import { EnvUtilities } from '../../env'; import { GithubUtilities } from '../../github'; import { NpmPackage, NpmUtilities } from '../../npm'; @@ -9,6 +9,7 @@ import { TsConfigUtilities } from '../../tsconfig'; import { exitWithError, getPath } from '../../utilities'; import { WorkspaceConfig, WorkspaceUtilities } from '../../workspace'; import { BaseCommand } from '../base-command.model'; +import { tailwindConfigJsContent } from './tailwind-config-js.content'; /** * Initializes a new Monux monorepo. @@ -113,22 +114,7 @@ export class InitCommand extends BaseCommand { private async createTailwindConfig(): Promise { await FsUtilities.createFile( getPath(TAILWIND_CONFIG_FILE_NAME), - [ - `const PRIMARY = '${COLOR_PRIMARY}'`, - '', - '// eslint-disable-next-line jsdoc/require-description', - '/** @type {import(\'tailwindcss\').Config} */', - 'module.exports = {', - ' theme: {', - ' colors: {', - ' primary: {', - ' DEFAULT: PRIMARY,', - ' darker: `color-mix(in srgb, ${PRIMARY} 90%, black)`', - ' }', - ' }', - ' }', - '};' - ] + tailwindConfigJsContent ); } } \ No newline at end of file diff --git a/src/commands/init/tailwind-config-js.content.ts b/src/commands/init/tailwind-config-js.content.ts new file mode 100644 index 0000000..0fe826e --- /dev/null +++ b/src/commands/init/tailwind-config-js.content.ts @@ -0,0 +1,78 @@ +// eslint-disable-next-line jsdoc/require-jsdoc +export const tailwindConfigJsContent: string += `const PRIMARY = '#37517e'; +const PRIMARY_CONTRAST = 'white'; + +const SECONDARY = '#00B4D8'; +const SECONDARY_CONTRAST = 'white'; + +const SUCCESS = 'green'; +const SUCCESS_CONTRAST = 'white'; + +const WARNING = 'orange'; +const WARNING_CONTRAST = 'black'; +const ERROR = 'red'; +const ERROR_CONTRAST = 'white'; + +// eslint-disable-next-line jsdoc/require-description +/** @type {import('tailwindcss').Config} */ +module.exports = { + theme: { + colors: { + inherit: 'inherit', + transparent: 'transparent', + primary: { + DEFAULT: PRIMARY, + darker: \`color-mix(in srgb, \${PRIMARY} 80%, black)\`, + contrast: PRIMARY_CONTRAST + }, + secondary: { + DEFAULT: SECONDARY, + darker: \`color-mix(in srgb, \${SECONDARY} 80%, black)\`, + contrast: SECONDARY_CONTRAST + }, + success: { + DEFAULT: SUCCESS, + darker: \`color-mix(in srgb, \${SUCCESS} 80%, black)\`, + contrast: SUCCESS_CONTRAST + }, + warning: { + DEFAULT: WARNING, + darker: \`color-mix(in srgb, \${WARNING} 80%, black)\`, + contrast: WARNING_CONTRAST + }, + error: { + DEFAULT: ERROR, + darker: \`color-mix(in srgb, \${ERROR} 80%, black)\`, + contrast: ERROR_CONTRAST + } + }, + boxShadow: { + 'elevation-none': 'none', + 'elevation-1': '0px 2px 1px -1px rgba(0,0,0,0.2), 0px 1px 1px 0px rgba(0,0,0,0.14), 0px 1px 3px 0px rgba(0,0,0,0.12)', + 'elevation-2': '0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12)', + 'elevation-3': '0px 3px 3px -2px rgba(0,0,0,0.2), 0px 3px 4px 0px rgba(0,0,0,0.14), 0px 1px 8px 0px rgba(0,0,0,0.12)', + 'elevation-4': '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)', + 'elevation-5': '0px 3px 5px -1px rgba(0,0,0,0.2), 0px 5px 8px 0px rgba(0,0,0,0.14), 0px 1px 14px 0px rgba(0,0,0,0.12)', + 'elevation-6': '0px 3px 5px -1px rgba(0,0,0,0.2), 0px 6px 10px 0px rgba(0,0,0,0.14), 0px 1px 18px 0px rgba(0,0,0,0.12)', + 'elevation-7': '0px 4px 5px -2px rgba(0,0,0,0.2), 0px 7px 10px 1px rgba(0,0,0,0.14), 0px 2px 16px 1px rgba(0,0,0,0.12)', + 'elevation-8': '0px 5px 5px -3px rgba(0,0,0,0.2), 0px 8px 10px 1px rgba(0,0,0,0.14), 0px 3px 14px 2px rgba(0,0,0,0.12)', + 'elevation-9': '0px 5px 6px -3px rgba(0,0,0,0.2), 0px 9px 12px 1px rgba(0,0,0,0.14), 0px 3px 16px 2px rgba(0,0,0,0.12)', + 'elevation-10': '0px 6px 6px -3px rgba(0,0,0,0.2), 0px 10px 14px 1px rgba(0,0,0,0.14), 0px 4px 18px 3px rgba(0,0,0,0.12)', + 'elevation-11': '0px 6px 7px -4px rgba(0,0,0,0.2), 0px 11px 15px 1px rgba(0,0,0,0.14), 0px 4px 20px 3px rgba(0,0,0,0.12)', + 'elevation-12': '0px 7px 8px -4px rgba(0,0,0,0.2), 0px 12px 17px 2px rgba(0,0,0,0.14), 0px 5px 22px 4px rgba(0,0,0,0.12)', + 'elevation-13': '0px 7px 8px -4px rgba(0,0,0,0.2), 0px 13px 19px 2px rgba(0,0,0,0.14), 0px 5px 24px 4px rgba(0,0,0,0.12)', + 'elevation-14': '0px 7px 9px -4px rgba(0,0,0,0.2), 0px 14px 21px 2px rgba(0,0,0,0.14), 0px 5px 26px 4px rgba(0,0,0,0.12)', + 'elevation-15': '0px 8px 9px -5px rgba(0,0,0,0.2), 0px 15px 22px 2px rgba(0,0,0,0.14), 0px 6px 28px 5px rgba(0,0,0,0.12)', + 'elevation-16': '0px 8px 10px -5px rgba(0,0,0,0.2), 0px 16px 24px 2px rgba(0,0,0,0.14), 0px 6px 30px 5px rgba(0,0,0,0.12)', + 'elevation-17': '0px 8px 11px -5px rgba(0,0,0,0.2), 0px 17px 26px 2px rgba(0,0,0,0.14), 0px 6px 32px 5px rgba(0,0,0,0.12)', + 'elevation-18': '0px 9px 11px -5px rgba(0,0,0,0.2), 0px 18px 28px 2px rgba(0,0,0,0.14), 0px 7px 34px 6px rgba(0,0,0,0.12)', + 'elevation-19': '0px 9px 12px -6px rgba(0,0,0,0.2), 0px 19px 29px 2px rgba(0,0,0,0.14), 0px 7px 36px 6px rgba(0,0,0,0.12)', + 'elevation-20': '0px 10px 13px -6px rgba(0,0,0,0.2), 0px 20px 31px 3px rgba(0,0,0,0.14), 0px 8px 38px 7px rgba(0,0,0,0.12)', + 'elevation-21': '0px 10px 13px -6px rgba(0,0,0,0.2), 0px 21px 33px 3px rgba(0,0,0,0.14), 0px 8px 40px 7px rgba(0,0,0,0.12)', + 'elevation-22': '0px 10px 14px -6px rgba(0,0,0,0.2), 0px 22px 35px 3px rgba(0,0,0,0.14), 0px 8px 42px 7px rgba(0,0,0,0.12)', + 'elevation-23': '0px 11px 14px -7px rgba(0,0,0,0.2), 0px 23px 36px 3px rgba(0,0,0,0.14), 0px 9px 44px 8px rgba(0,0,0,0.12)', + 'elevation-24': '0px 11px 15px -7px rgba(0,0,0,0.2), 0px 24px 38px 3px rgba(0,0,0,0.14), 0px 9px 46px 8px rgba(0,0,0,0.12)' + } + } +};`; \ No newline at end of file diff --git a/src/npm/npm-package.enum.ts b/src/npm/npm-package.enum.ts index 0ec5eba..4eafa37 100644 --- a/src/npm/npm-package.enum.ts +++ b/src/npm/npm-package.enum.ts @@ -2,7 +2,7 @@ * All known npm packages. */ export enum NpmPackage { - TAILWIND = 'tailwindcss', + TAILWIND = 'tailwindcss@3', NGX_PERSISTENCE_LOGGER = 'ngx-persistence-logger', NGX_MATERIAL_AUTH = 'ngx-material-auth', NGX_MATERIAL_CHANGE_SETS = 'ngx-material-change-sets', diff --git a/src/npm/package-json.model.ts b/src/npm/package-json.model.ts index 951b0c7..622b487 100644 --- a/src/npm/package-json.model.ts +++ b/src/npm/package-json.model.ts @@ -72,5 +72,9 @@ export type PackageJson = { /** * PeerDependencies of the package. */ - peerDependencies?: Record + peerDependencies?: Record, + /** + * Prettier configuration. Is used by default by storybook. + */ + prettier?: unknown }; \ No newline at end of file