Skip to content

Commit b24a9da

Browse files
authored
docs: update README and add Skills and Rules to Cursor 📝 (#1368)
* docs: improve README 📝 * docs: add rules and skills 📝 * refactor: recovery app components to show 🔨
1 parent 7460614 commit b24a9da

File tree

10 files changed

+839
-26
lines changed

10 files changed

+839
-26
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
description: Angular component authoring rules for Ion Design System.
3+
globs: projects/ion/src/lib/**/*.component.ts, projects/ion/src/lib/**/*.directive.ts
4+
alwaysApply: false
5+
---
6+
7+
# Angular Component & Directive Rules
8+
9+
## Component Decorator
10+
11+
- Set `changeDetection: ChangeDetectionStrategy.OnPush` in every `@Component`
12+
- Do NOT set `standalone: true` — it's default in Angular v21+
13+
- Use `templateUrl` and `styleUrls` for components with more than a few lines of template
14+
- Use inline `template` only for very small components (< ~10 lines of HTML)
15+
- Use relative paths for templateUrl/styleUrls: `'./button.component.html'`
16+
17+
## Inputs & Outputs
18+
19+
- Use `input()` signal function instead of `@Input()` decorator
20+
- Use `output()` signal function instead of `@Output()` decorator
21+
- Type inputs explicitly: `label = input<string>()`
22+
- Provide defaults where sensible: `type = input<Type>('primary')`
23+
- Use `input.required<T>()` when the value must be provided
24+
25+
## State Management
26+
27+
- Use `signal()` for mutable component state
28+
- Use `computed()` for derived state
29+
- Use `effect()` for reactions to signal changes
30+
- Update signals with `.set()` or `.update()` — NEVER use `.mutate()`
31+
32+
## Host Bindings
33+
34+
- Do NOT use `@HostBinding` or `@HostListener` decorators
35+
- Use the `host` property in the decorator instead:
36+
37+
```typescript
38+
@Component({
39+
host: {
40+
'[attr.disabled]': 'disabled() ? true : null',
41+
'(click)': 'onClick()',
42+
},
43+
})
44+
```
45+
46+
## Templates
47+
48+
- Use native control flow: `@if`, `@for`, `@switch` — NEVER `*ngIf`, `*ngFor`, `*ngSwitch`
49+
- Use `[class.name]` bindings instead of `ngClass`
50+
- Use `[style.prop]` bindings instead of `ngStyle`
51+
- Use `[attr.data-testid]` for test selectors following pattern: `'btn-' + (label() || id())`
52+
- Do NOT write arrow functions in templates
53+
- Do NOT call `new Date()` or other globals directly in templates
54+
55+
## Forms
56+
57+
- Prefer Reactive Forms over Template-driven forms
58+
- Import `ReactiveFormsModule` or individual form directives as needed
59+
60+
## Accessibility
61+
62+
- Must pass all AXE checks and WCAG AA requirements
63+
- Include proper ARIA attributes where semantics are insufficient
64+
- Manage focus for overlays, modals, dropdowns, and tooltips
65+
66+
## Services
67+
68+
- Use `providedIn: 'root'` for singleton services
69+
- Use `inject()` function instead of constructor injection
70+
- Design services around a single responsibility

.cursor/rules/ion-project.mdc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
description: Ion Design System - project context and conventions. Always active for all files in this repository.
3+
globs:
4+
alwaysApply: true
5+
---
6+
7+
# Ion Design System — Project Context
8+
9+
You are working on **Ion**, the official Angular-based Design System for **Brisanet**.
10+
This is a **library workspace** (`projectType: "library"`) published as `@brisanet/ion` on npm.
11+
12+
## Tech Stack
13+
14+
- **Angular** v21 (standalone components are the default — do NOT set `standalone: true`)
15+
- **TypeScript** 5.9 with strict mode
16+
- **SCSS** for component styles with a theme system under `projects/ion/src/styles/`
17+
- **Angular CDK** (`@angular/cdk`) for overlays, portals, and scroll strategies
18+
- **ng-packagr** for library builds
19+
- **Jest** 30 + `jest-preset-angular` for unit testing
20+
- **Angular Testing Library** (`@testing-library/angular`) for integration-style tests
21+
- **Storybook** 10 with `@storybook/angular` for component documentation
22+
- **Prettier** (single quotes, auto end-of-line)
23+
- **EditorConfig** (2-space indent, UTF-8)
24+
25+
## Project Structure
26+
27+
```
28+
projects/
29+
ion/ # The core library
30+
src/
31+
lib/ # All component directories
32+
<component-name>/ # One folder per component
33+
<name>.component.ts
34+
<name>.component.html
35+
<name>.component.scss
36+
<name>.component.spec.ts
37+
_<name>.theme.scss # Optional theme file
38+
core/
39+
types/ # Shared TypeScript interfaces/types
40+
bn-filter/ # Business components prefixed `bn-`
41+
utils/ # Shared utility functions
42+
styles/ # Global design tokens (colors, fonts, shadows, z-indexes, themes)
43+
stories/ # Storybook stories
44+
public-api.ts # Library barrel file — all public exports
45+
ng-package.json
46+
ion-test-app/ # Showcase / integration test app
47+
```
48+
49+
## Key Conventions
50+
51+
- All components are **standalone** (do NOT add `standalone: true` — it's default in Angular v21+)
52+
- Component selector prefix: `ion-` (e.g. `ion-button`, `ion-card`)
53+
- Component class naming: `Ion<Name>Component` (e.g. `IonButtonComponent`)
54+
- Service class naming: `Ion<Name>Service` or descriptive name (e.g. `IonModalService`, `TooltipService`)
55+
- Directive class naming: `Ion<Name>Directive` (e.g. `IonTooltipDirective`)
56+
- Type definitions live in `projects/ion/src/lib/core/types/<component>.ts`
57+
- Every new public component/directive/service MUST be exported from `projects/ion/src/public-api.ts`
58+
59+
## CI/CD
60+
61+
- **PR tests**: GitHub Actions runs `npm test` + `npm run build ion` on every PR to `main`
62+
- **Release**: Triggered on GitHub Release publish; builds and publishes to npm with provenance
63+
- **Node version**: 22.22.0 for builds

.cursor/rules/storybook.mdc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
description: Storybook story authoring conventions for Ion components.
3+
globs: projects/ion/src/stories/**/*.stories.ts, projects/ion/**/*.stories.ts
4+
alwaysApply: false
5+
---
6+
7+
# Storybook Rules
8+
9+
## Framework
10+
11+
- **Storybook 10** with `@storybook/angular`
12+
- Stories live in `projects/ion/src/stories/` or alongside components
13+
14+
## Story Format
15+
16+
Use CSF3 (Component Story Format 3) with `Meta` and `StoryObj`:
17+
18+
```typescript
19+
import type { Meta, StoryObj } from '@storybook/angular';
20+
import { IonMyComponent } from '../lib/my/my.component';
21+
22+
const meta: Meta<IonMyComponent> = {
23+
title: 'Components/MyComponent',
24+
component: IonMyComponent,
25+
tags: ['autodocs'],
26+
argTypes: {
27+
ionOnClick: { action: 'clicked' },
28+
},
29+
};
30+
31+
export default meta;
32+
33+
export const Default: StoryObj<IonMyComponent> = {
34+
args: {
35+
label: 'Click me',
36+
type: 'primary',
37+
},
38+
};
39+
40+
export const Disabled: StoryObj<IonMyComponent> = {
41+
args: {
42+
label: 'Disabled',
43+
disabled: true,
44+
},
45+
};
46+
```
47+
48+
## Providing Services
49+
50+
If the component depends on services, use `applicationConfig`:
51+
52+
```typescript
53+
render: (args) => ({
54+
props: args,
55+
applicationConfig: {
56+
providers: [MyService],
57+
},
58+
}),
59+
```
60+
61+
## Running Storybook
62+
63+
```bash
64+
npm run storybook # Start dev server on port 6006
65+
npm run build-storybook # Build static site to dist/storybook/ion
66+
```

.cursor/rules/styling.mdc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
description: SCSS styling conventions and design tokens for Ion.
3+
globs: projects/ion/**/*.scss
4+
alwaysApply: false
5+
---
6+
7+
# Styling Rules
8+
9+
## Language
10+
11+
- Use **SCSS** for all component styles
12+
- Component styles: `<name>.component.scss` (external file, referenced via `styleUrls`)
13+
- Theme files: `_<name>.theme.scss` (partial, imported by the theme system)
14+
15+
## Design Tokens
16+
17+
Design tokens are defined under `projects/ion/src/styles/`:
18+
19+
| Token Category | Location |
20+
| -------------- | ----------------------------- |
21+
| Colors | `styles/colors/colors.scss` |
22+
| Fonts | `styles/fonts/index.scss` |
23+
| Shadows | `styles/shadows/index.scss` |
24+
| Z-indexes | `styles/z-indexes/index.scss` |
25+
| Themes | `styles/themes/index.scss` |
26+
| Overlays | `styles/_overlays.scss` |
27+
28+
Always use existing design tokens instead of hardcoding values.
29+
30+
## CSS Class Naming
31+
32+
- Component variant classes: `ion-btn-primary`, `ion-btn-secondary`
33+
- Size classes: `ion-btn-sm`, `ion-btn-md`, `ion-btn-lg`, `ion-btn-xl`
34+
- State classes: `danger`, `loading`, `right-side-icon`
35+
36+
## Theming
37+
38+
- Theme variables are defined in `styles/themes/`
39+
- Components should use CSS custom properties (variables) from the theme
40+
- Support light/dark themes through the existing theme infrastructure

.cursor/rules/testing.mdc

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
description: Testing conventions for Ion Design System using Jest and Angular Testing Library.
3+
globs: projects/ion/**/*.spec.ts
4+
alwaysApply: false
5+
---
6+
7+
# Testing Rules
8+
9+
## Framework
10+
11+
- **Jest 30** with `jest-preset-angular`
12+
- **Angular Testing Library** (`@testing-library/angular`) available for integration-style tests
13+
- **`@testing-library/jest-dom`** matchers are globally available (e.g. `toHaveAttribute`)
14+
15+
## Test File Location
16+
17+
- Test files live alongside their component: `<name>.component.spec.ts`
18+
- Test match pattern: `projects/ion/**/*.spec.ts`
19+
20+
## Test Setup Pattern
21+
22+
```typescript
23+
import { ComponentFixture, TestBed } from '@angular/core/testing';
24+
import { IonMyComponent } from './my.component';
25+
26+
describe('MyComponent', () => {
27+
let component: IonMyComponent;
28+
let fixture: ComponentFixture<IonMyComponent>;
29+
30+
beforeEach(async () => {
31+
await TestBed.configureTestingModule({
32+
imports: [IonMyComponent], // standalone component goes in imports
33+
}).compileComponents();
34+
35+
fixture = TestBed.createComponent(IonMyComponent);
36+
component = fixture.componentInstance;
37+
});
38+
39+
it('should create', () => {
40+
expect(component).toBeTruthy();
41+
});
42+
});
43+
```
44+
45+
## Setting Inputs
46+
47+
- Use `fixture.componentRef.setInput('inputName', value)` — NOT direct property assignment
48+
- Always call `fixture.detectChanges()` after setting inputs
49+
50+
```typescript
51+
fixture.componentRef.setInput('label', 'Click me');
52+
fixture.componentRef.setInput('disabled', true);
53+
fixture.detectChanges();
54+
```
55+
56+
## Querying DOM
57+
58+
- Use `fixture.nativeElement.querySelector()` for DOM queries
59+
- Use `data-testid` attributes for reliable selectors: `[data-testid="btn-myId"]`
60+
- For overlay/portal components (dropdown, modal, tooltip), query from `document.body`
61+
62+
## Event Testing
63+
64+
- Use `jest.fn()` for spy functions
65+
- Subscribe to component outputs for event testing
66+
- Call `.click()` on native elements to trigger events
67+
68+
```typescript
69+
const clickSpy = jest.fn();
70+
component.ionOnClick.subscribe(clickSpy);
71+
fixture.detectChanges();
72+
73+
const button = fixture.nativeElement.querySelector('button');
74+
button.click();
75+
76+
expect(clickSpy).toHaveBeenCalled();
77+
```
78+
79+
## Iteration Tests
80+
81+
- Use `.forEach()` to test multiple variants (types, sizes, states):
82+
83+
```typescript
84+
const types = ['primary', 'secondary', 'ghost', 'dashed'];
85+
types.forEach((type) => {
86+
it(`should render type: ${type}`, () => {
87+
fixture.componentRef.setInput('type', type);
88+
fixture.detectChanges();
89+
const el = fixture.nativeElement.querySelector('button');
90+
expect(el.classList.contains(`ion-btn-${type}`)).toBe(true);
91+
});
92+
});
93+
```
94+
95+
## Running Tests
96+
97+
```bash
98+
npm test # Run all tests
99+
npx jest --testPathPattern=button # Run specific tests
100+
npx jest --coverage # With coverage report
101+
```

0 commit comments

Comments
 (0)