Skip to content

Commit

Permalink
feat: brn-label (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
thatsamsonkid authored Jan 3, 2024
1 parent 73115c5 commit c46aafc
Show file tree
Hide file tree
Showing 17 changed files with 306 additions and 37 deletions.
20 changes: 20 additions & 0 deletions apps/ui-storybook-e2e/src/integration/label/label.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
describe('label', () => {
describe('default', () => {
beforeEach(() => {
cy.visit('/iframe.html?id=label--default');
cy.injectAxe();
});

it('should have an id autogenerated if none provided', () => {
cy.get('[hlmLabel]').as('label');
cy.get('@label').should('have.attr', 'id', 'brn-label-0');
});

it('should override default id if one is defined', () => {
cy.visit('/iframe.html?id=label--default&args=id:my-id');

cy.get('[hlmLabel]').as('label');
cy.get('@label').should('have.attr', 'id', 'my-id');
});
});
});
41 changes: 41 additions & 0 deletions libs/ui/label/brain/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"extends": ["../../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts"],
"extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
"rules": {
"@angular-eslint/no-host-metadata-property": 0,
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "brn",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "brn",
"style": "kebab-case"
}
]
}
},
{
"files": ["*.html"],
"extends": ["plugin:@nx/angular-template"],
"rules": {}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": "error"
}
}
]
}
7 changes: 7 additions & 0 deletions libs/ui/label/brain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ui-label-brain

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test ui-label-brain` to execute the unit tests.
22 changes: 22 additions & 0 deletions libs/ui/label/brain/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable */
export default {
displayName: 'ui-label-brain',
preset: '../../../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../../../coverage/libs/ui/label/brain',
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',
],
};
7 changes: 7 additions & 0 deletions libs/ui/label/brain/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../../dist/libs/ui/label/brain",
"lib": {
"entryFile": "src/index.ts"
}
}
12 changes: 12 additions & 0 deletions libs/ui/label/brain/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@spartan-ng/ui-label-brain",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^17.0.0",
"@angular/core": "^17.0.0"
},
"dependencies": {
"tslib": "^2.3.0"
},
"sideEffects": false
}
44 changes: 44 additions & 0 deletions libs/ui/label/brain/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "ui-label-brain",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/ui/label/brain/src",
"prefix": "brn",
"tags": [],
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/angular:package",
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
"options": {
"project": "libs/ui/label/brain/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "libs/ui/label/brain/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "libs/ui/label/brain/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/ui/label/brain/jest.config.ts"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": [
"libs/ui/label/brain/**/*.ts",
"libs/ui/label/brain/**/*.html",
"libs/ui/label/brain/package.json"
]
}
}
}
}
10 changes: 10 additions & 0 deletions libs/ui/label/brain/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { NgModule } from '@angular/core';
import { BrnLabelDirective } from './lib/brn-label.directive';

export * from './lib/brn-label.directive';

@NgModule({
imports: [BrnLabelDirective],
exports: [BrnLabelDirective],
})
export class BrnLabelModule {}
43 changes: 43 additions & 0 deletions libs/ui/label/brain/src/lib/brn-label.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { isPlatformBrowser } from '@angular/common';
import { Directive, ElementRef, inject, Input, OnInit, PLATFORM_ID, signal } from '@angular/core';

let nextId = 0;

@Directive({
selector: '[brnLabel]',
standalone: true,
host: {
'[id]': '_id()',
},
})
export class BrnLabelDirective implements OnInit {
protected readonly _id = signal(`brn-label-${nextId++}`);

@Input()
set id(id: string) {
this._id.set(id || this._id());
}

private readonly _isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
private readonly _element = inject(ElementRef).nativeElement;
private _changes?: MutationObserver;
private readonly _dataDisabled = signal<boolean | 'auto'>('auto');
public readonly dataDisabled = this._dataDisabled.asReadonly();

ngOnInit(): void {
if (!this._isBrowser) return;
this._changes = new MutationObserver((mutations: MutationRecord[]) => {
mutations.forEach((mutation: MutationRecord) => {
if (mutation.attributeName !== 'data-disabled') return;
// eslint-disable-next-line
const state = (mutation.target as any).attributes.getNamedItem(mutation.attributeName)?.value === 'true';
this._dataDisabled.set(state ?? 'auto');
});
});
this._changes?.observe(this._element, {
attributes: true,
childList: true,
characterData: true,
});
}
}
8 changes: 8 additions & 0 deletions libs/ui/label/brain/src/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment
globalThis.ngJest = {
testEnvironmentOptions: {
errorOnUnknownElements: true,
errorOnUnknownProperties: true,
},
};
import 'jest-preset-angular/setup-jest';
29 changes: 29 additions & 0 deletions libs/ui/label/brain/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"compilerOptions": {
"target": "es2022",
"useDefineForClassFields": false,
"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
}
}
12 changes: 12 additions & 0 deletions libs/ui/label/brain/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"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"]
}
9 changes: 9 additions & 0 deletions libs/ui/label/brain/tsconfig.lib.prod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"compilationMode": "partial"
}
}
11 changes: 11 additions & 0 deletions libs/ui/label/brain/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"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"]
}
52 changes: 22 additions & 30 deletions libs/ui/label/helm/src/lib/hlm-label.directive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isPlatformBrowser } from '@angular/common';
import { computed, Directive, ElementRef, inject, Input, OnInit, PLATFORM_ID, signal } from '@angular/core';
import { computed, Directive, inject, Input, signal } from '@angular/core';
import { hlm } from '@spartan-ng/ui-core';
import { BrnLabelDirective } from '@spartan-ng/ui-label-brain';
import { cva, VariantProps } from 'class-variance-authority';
import { ClassValue } from 'clsx';

Expand Down Expand Up @@ -32,32 +32,30 @@ export type LabelVariants = VariantProps<typeof labelVariants>;
@Directive({
selector: '[hlmLabel]',
standalone: true,
hostDirectives: [
{
directive: BrnLabelDirective,
inputs: ['id'],
},
],
host: {
'[class]': '_computedClass()',
},
})
export class HlmLabelDirective implements OnInit {
private readonly _isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
private readonly _element = inject(ElementRef).nativeElement;
private _changes?: MutationObserver;
private readonly _dataDisabled = signal<boolean | 'auto'>('auto');
export class HlmLabelDirective {
private readonly _brn = inject(BrnLabelDirective, { host: true });

protected readonly _computedClass = computed(() =>
hlm(
labelVariants({
variant: this._variant(),
error: this._error(),
disabled: this._brn?.dataDisabled() ?? 'auto',
}),
this._userCls(),
),
);

ngOnInit(): void {
if (!this._isBrowser) return;
this._changes = new MutationObserver((mutations: MutationRecord[]) => {
mutations.forEach((mutation: MutationRecord) => {
if (mutation.attributeName !== 'data-disabled') return;
// eslint-disable-next-line
const state = (mutation.target as any).attributes.getNamedItem(mutation.attributeName)?.value === 'true';
this._dataDisabled.set(state ?? 'auto');
});
});
this._changes?.observe(this._element, {
attributes: true,
childList: true,
characterData: true,
});
}
private readonly _variant = signal<LabelVariants['variant']>('default');
@Input()
set variant(value: LabelVariants['variant']) {
Expand All @@ -71,15 +69,9 @@ export class HlmLabelDirective implements OnInit {
}

private readonly _userCls = signal<ClassValue>('');

@Input()
set class(userCls: ClassValue) {
this._userCls.set(userCls);
}

protected readonly _computedClass = computed(() =>
hlm(
labelVariants({ variant: this._variant(), error: this._error(), disabled: this._dataDisabled() }),
this._userCls(),
),
);
}
Loading

0 comments on commit c46aafc

Please sign in to comment.