Add generated docs to source

This commit is contained in:
Yury Bondarenko
2024-03-29 10:47:04 +01:00
parent 515e5f00cf
commit 08a5443cc2
6 changed files with 861 additions and 0 deletions

4
docs/lint/html/index.md Normal file
View File

@@ -0,0 +1,4 @@
[DSpace ESLint plugins](../../../lint/README.md) > HTML rules
_______
- [`dspace-angular-html/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via the selector of their `ThemedComponent` wrapper class

View File

@@ -0,0 +1,110 @@
[DSpace ESLint plugins](../../../../lint/README.md) > [HTML rules](../index.md) > `dspace-angular-html/themed-component-usages`
_______
Themeable components should be used via the selector of their `ThemedComponent` wrapper class
This ensures that custom themes can correctly override _all_ instances of this component.
The only exception to this rule are unit tests, where we may want to use the base component in order to keep the test setup simple.
_______
[Source code](../../../../lint/src/rules/html/themed-component-usages.ts)
### Examples
#### Valid code
##### use no-prefix selectors in HTML templates
```html
<ds-test-themeable/>
<ds-test-themeable></ds-test-themeable>
<ds-test-themeable [test]="something"></ds-test-themeable>
```
##### use no-prefix selectors in TypeScript templates
```html
@Component({
template: '<ds-test-themeable></ds-test-themeable>'
})
class Test {
}
```
##### use no-prefix selectors in TypeScript test templates
Filename: `lint/test/fixture/src/test.spec.ts`
```html
@Component({
template: '<ds-test-themeable></ds-test-themeable>'
})
class Test {
}
```
##### base selectors are also allowed in TypeScript test templates
Filename: `lint/test/fixture/src/test.spec.ts`
```html
@Component({
template: '<ds-base-test-themeable></ds-base-test-themeable>'
})
class Test {
}
```
#### Invalid code &amp; automatic fixes
##### themed override selectors are not allowed in HTML templates
```html
<ds-themed-test-themeable/>
<ds-themed-test-themeable></ds-themed-test-themeable>
<ds-themed-test-themeable [test]="something"></ds-themed-test-themeable>
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper's selector
Themeable components should be used via their ThemedComponent wrapper's selector
Themeable components should be used via their ThemedComponent wrapper's selector
```
Result of `yarn lint --fix`:
```html
<ds-test-themeable/>
<ds-test-themeable></ds-test-themeable>
<ds-test-themeable [test]="something"></ds-test-themeable>
```
##### base selectors are not allowed in HTML templates
```html
<ds-base-test-themeable/>
<ds-base-test-themeable></ds-base-test-themeable>
<ds-base-test-themeable [test]="something"></ds-base-test-themeable>
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper's selector
Themeable components should be used via their ThemedComponent wrapper's selector
Themeable components should be used via their ThemedComponent wrapper's selector
```
Result of `yarn lint --fix`:
```html
<ds-test-themeable/>
<ds-test-themeable></ds-test-themeable>
<ds-test-themeable [test]="something"></ds-test-themeable>
```

6
docs/lint/ts/index.md Normal file
View File

@@ -0,0 +1,6 @@
[DSpace ESLint plugins](../../../lint/README.md) > TypeScript rules
_______
- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes
- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention
- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class

View File

@@ -0,0 +1,253 @@
[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-classes`
_______
Formatting rules for themeable component classes
_______
[Source code](../../../../lint/src/rules/ts/themed-component-classes.ts)
### Examples
#### Valid code
##### Regular non-themeable component
```typescript
@Component({
selector: 'ds-something',
standalone: true,
})
class Something {
}
```
##### Base component
```typescript
@Component({
selector: 'ds-base-test-themable',
standalone: true,
})
class TestThemeableTomponent {
}
```
##### Wrapper component
Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [
TestThemeableComponent,
],
})
class ThemedTestThemeableTomponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### Override component
Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-themed-test-themable',
standalone: true,
})
class Override extends BaseComponent {
}
```
#### Invalid code &amp; automatic fixes
##### Base component must be standalone
```typescript
@Component({
selector: 'ds-base-test-themable',
})
class TestThemeableComponent {
}
```
Will produce the following error(s):
```
Themeable components must be standalone
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-base-test-themable',
standalone: true,
})
class TestThemeableComponent {
}
```
##### Wrapper component must be standalone and import base component
Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-test-themable',
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
Will produce the following error(s):
```
Themeable component wrapper classes must be standalone and import the base class
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [TestThemeableComponent],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### Wrapper component must import base component (array present but empty)
Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
Will produce the following error(s):
```
Themed component wrapper classes must only import the base class
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [TestThemeableComponent],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### Wrapper component must import base component (array is wrong)
Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
```typescript
import { SomethingElse } from './somewhere-else';
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [
SomethingElse,
],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
Will produce the following error(s):
```
Themed component wrapper classes must only import the base class
```
Result of `yarn lint --fix`:
```typescript
import { SomethingElse } from './somewhere-else';
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [TestThemeableComponent],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### Wrapper component must import base component (array is wrong)
Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
```typescript
import { Something, SomethingElse } from './somewhere-else';
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [
SomethingElse,
],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
Will produce the following error(s):
```
Themed component wrapper classes must only import the base class
```
Result of `yarn lint --fix`:
```typescript
import { Something, SomethingElse } from './somewhere-else';
@Component({
selector: 'ds-test-themable',
standalone: true,
imports: [TestThemeableComponent],
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### Override component must be standalone
Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-themed-test-themable',
})
class Override extends BaseComponent {
}
```
Will produce the following error(s):
```
Themeable components must be standalone
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-themed-test-themable',
standalone: true,
})
class Override extends BaseComponent {
}
```

View File

@@ -0,0 +1,156 @@
[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-selectors`
_______
Themeable component selectors should follow the DSpace convention
Each themeable component is comprised of a base component, a wrapper component and any number of themed components
- Base components should have a selector starting with `ds-base-`
- Themed components should have a selector starting with `ds-themed-`
- Wrapper components should have a selector starting with `ds-`, but not `ds-base-` or `ds-themed-`
- This is the regular DSpace selector prefix
- **When making a regular component themeable, its selector prefix should be changed to `ds-base-`, and the new wrapper's component should reuse the previous selector**
Unit tests are exempt from this rule, because they may redefine components using the same class name as other themeable components elsewhere in the source.
_______
[Source code](../../../../lint/src/rules/ts/themed-component-selectors.ts)
### Examples
#### Valid code
##### Regular non-themeable component selector
```typescript
@Component({
selector: 'ds-something',
})
class Something {
}
```
##### Themeable component selector should replace the original version, unthemed version should be changed to ds-base-
```typescript
@Component({
selector: 'ds-base-something',
})
class Something {
}
@Component({
selector: 'ds-something',
})
class ThemedSomething extends ThemedComponent<Something> {
}
@Component({
selector: 'ds-themed-something',
})
class OverrideSomething extends Something {
}
```
##### Other themed component wrappers should not interfere
```typescript
@Component({
selector: 'ds-something',
})
class Something {
}
@Component({
selector: 'ds-something-else',
})
class ThemedSomethingElse extends ThemedComponent<SomethingElse> {
}
```
#### Invalid code &amp; automatic fixes
##### Wrong selector for base component
Filename: `lint/test/fixture/src/app/test/test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-something',
})
class TestThemeableComponent {
}
```
Will produce the following error(s):
```
Unthemed version of themeable component should have a selector starting with 'ds-base-'
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-base-something',
})
class TestThemeableComponent {
}
```
##### Wrong selector for wrapper component
Filename: `lint/test/fixture/src/app/test/themed-test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-themed-something',
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
Will produce the following error(s):
```
Themed component wrapper of themeable component shouldn't have a selector starting with 'ds-themed-'
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-something',
})
class ThemedTestThemeableComponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### Wrong selector for theme override
Filename: `lint/test/fixture/src/themes/test/app/test/test-themeable.component.ts`
```typescript
@Component({
selector: 'ds-something',
})
class TestThememeableComponent extends BaseComponent {
}
```
Will produce the following error(s):
```
Theme override of themeable component should have a selector starting with 'ds-themed-'
```
Result of `yarn lint --fix`:
```typescript
@Component({
selector: 'ds-themed-something',
})
class TestThememeableComponent extends BaseComponent {
}
```

View File

@@ -0,0 +1,332 @@
[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-component-usages`
_______
Themeable components should be used via their `ThemedComponent` wrapper class
This ensures that custom themes can correctly override _all_ instances of this component.
There are a few exceptions where the base class can still be used:
- Class declaration expressions (otherwise we can't declare, extend or override the class in the first place)
- Angular modules (except for routing modules)
- Angular `@ViewChild` decorators
- Type annotations
_______
[Source code](../../../../lint/src/rules/ts/themed-component-usages.ts)
### Examples
#### Valid code
##### allow wrapper class usages
```typescript
import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component';
const config = {
a: ThemedTestThemeableComponent,
b: ChipsComponent,
}
```
##### allow base class in class declaration
```typescript
export class TestThemeableComponent {
}
```
##### allow inheriting from base class
```typescript
import { TestThemeableComponent } from './app/test/test-themeable.component';
export class ThemedAdminSidebarComponent extends ThemedComponent<TestThemeableComponent> {
}
```
##### allow base class in ViewChild
```typescript
import { TestThemeableComponent } from './app/test/test-themeable.component';
export class Something {
@ViewChild(TestThemeableComponent) test: TestThemeableComponent;
}
```
##### allow wrapper selectors in test queries
Filename: `lint/test/fixture/src/app/test/test.component.spec.ts`
```typescript
By.css('ds-themeable');
By.css('#test > ds-themeable > #nest');
```
##### allow wrapper selectors in cypress queries
Filename: `lint/test/fixture/src/app/test/test.component.cy.ts`
```typescript
By.css('ds-themeable');
By.css('#test > ds-themeable > #nest');
```
#### Invalid code &amp; automatic fixes
##### disallow direct usages of base class
```typescript
import { TestThemeableComponent } from './app/test/test-themeable.component';
import { TestComponent } from './app/test/test.component';
const config = {
a: TestThemeableComponent,
b: TestComponent,
}
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component';
import { TestComponent } from './app/test/test.component';
const config = {
a: ThemedTestThemeableComponent,
b: TestComponent,
}
```
##### disallow direct usages of base class, keep other imports
```typescript
import { Something, TestThemeableComponent } from './app/test/test-themeable.component';
import { TestComponent } from './app/test/test.component';
const config = {
a: TestThemeableComponent,
b: TestComponent,
c: Something,
}
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
import { Something } from './app/test/test-themeable.component';
import { ThemedTestThemeableComponent } from './app/test/themed-test-themeable.component';
import { TestComponent } from './app/test/test.component';
const config = {
a: ThemedTestThemeableComponent,
b: TestComponent,
c: Something,
}
```
##### handle array replacements correctly
```typescript
const DECLARATIONS = [
Something,
TestThemeableComponent,
Something,
ThemedTestThemeableComponent,
];
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
const DECLARATIONS = [
Something,
Something,
ThemedTestThemeableComponent,
];
```
##### disallow override selector in test queries
Filename: `lint/test/fixture/src/app/test/test.component.spec.ts`
```typescript
By.css('ds-themed-themeable');
By.css('#test > ds-themed-themeable > #nest');
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
By.css('ds-themeable');
By.css('#test > ds-themeable > #nest');
```
##### disallow base selector in test queries
Filename: `lint/test/fixture/src/app/test/test.component.spec.ts`
```typescript
By.css('ds-base-themeable');
By.css('#test > ds-base-themeable > #nest');
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
By.css('ds-themeable');
By.css('#test > ds-themeable > #nest');
```
##### disallow override selector in cypress queries
Filename: `lint/test/fixture/src/app/test/test.component.cy.ts`
```typescript
cy.get('ds-themed-themeable');
cy.get('#test > ds-themed-themeable > #nest');
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
cy.get('ds-themeable');
cy.get('#test > ds-themeable > #nest');
```
##### disallow base selector in cypress queries
Filename: `lint/test/fixture/src/app/test/test.component.cy.ts`
```typescript
cy.get('ds-base-themeable');
cy.get('#test > ds-base-themeable > #nest');
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
cy.get('ds-themeable');
cy.get('#test > ds-themeable > #nest');
```
##### edge case: unable to find usage node through usage token, but import is still flagged and fixed
Filename: `lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts`
```typescript
import { Component } from '@angular/core';
import { Context } from './app/core/shared/context.model';
import { TestThemeableComponent } from '../../../../app/test/test-themeable.component';
@Component({
standalone: true,
imports: [TestThemeableComponent],
})
export class UsageComponent {
}
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
import { Component } from '@angular/core';
import { Context } from './app/core/shared/context.model';
import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component';
@Component({
standalone: true,
imports: [ThemedTestThemeableComponent],
})
export class UsageComponent {
}
```
##### edge case edge case: both are imported, only wrapper is retained
Filename: `lint/test/fixture/src/themes/test/app/test/other-themeable.component.ts`
```typescript
import { Component } from '@angular/core';
import { Context } from './app/core/shared/context.model';
import { TestThemeableComponent } from '../../../../app/test/test-themeable.component';
import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component';
@Component({
standalone: true,
imports: [TestThemeableComponent, ThemedTestThemeableComponent],
})
export class UsageComponent {
}
```
Will produce the following error(s):
```
Themeable components should be used via their ThemedComponent wrapper
Themeable components should be used via their ThemedComponent wrapper
```
Result of `yarn lint --fix`:
```typescript
import { Component } from '@angular/core';
import { Context } from './app/core/shared/context.model';
import { ThemedTestThemeableComponent } from '../../../../app/test/themed-test-themeable.component';
@Component({
standalone: true,
imports: [ThemedTestThemeableComponent],
})
export class UsageComponent {
}
```