Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c30dabd
chore: create component development skill
gluecksmelodie Jul 28, 2026
8c56359
chore: create onboarding skill
gluecksmelodie Jul 28, 2026
efde466
chore: create agents.md
gluecksmelodie Jul 28, 2026
bbd37c4
chore: create pr review skill
gluecksmelodie Jul 28, 2026
71adb1a
chore: create release skill
gluecksmelodie Jul 28, 2026
2eb9f2d
chore: remove release skill
gluecksmelodie Aug 5, 2026
d007e57
chore: condense AGENTS.md
gluecksmelodie Aug 5, 2026
bbf8a89
feat(core): add segmented control component
gluecksmelodie Aug 10, 2026
20ace6c
chore: fix prettier
gluecksmelodie Aug 10, 2026
db2b9e5
feat(core): add segmented control screenshot tests
gluecksmelodie Aug 11, 2026
97737e0
chore: fix prettier
gluecksmelodie Aug 11, 2026
c23820e
chore: update reference screenshots
actions-user Aug 11, 2026
6288a9e
Merge branch 'refs/heads/main' into feature/COYOFOUR-26962-create-new…
gluecksmelodie Aug 11, 2026
0f792d5
feat(core): add segmented control tests, a11y labels and events
gluecksmelodie Aug 11, 2026
0ea36a9
feat(core): add segmented control tests, a11y labels and events
gluecksmelodie Aug 11, 2026
12876de
chore: update readme
gluecksmelodie Aug 12, 2026
9b01c9e
feat(core): add new components to catalyst.module.ts
gluecksmelodie Aug 12, 2026
e503c49
chore: improve skill
gluecksmelodie Aug 12, 2026
8086a44
Merge remote-tracking branch 'origin/feature/COYOFOUR-26962-create-ne…
gluecksmelodie Aug 12, 2026
bfc7a9b
feat(core): generate proxies.ts with new components
gluecksmelodie Aug 12, 2026
2170916
chore: remove agents instructions (to be introduced separately)
gluecksmelodie Aug 12, 2026
3a9930d
chore: remove agents instructions (to be introduced separately)
gluecksmelodie Aug 13, 2026
0bd61d4
chore: copy pr review skills for copilot
gluecksmelodie Aug 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/skills/code-review/CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Catalyst Code Review Checklist

Apply only sections relevant to changed paths. Mark every applicable rule ✅, ❌, or N/A with a reason.

## Repository-wide

- [ ] PR description explains user-facing or maintenance intent and scope.
- [ ] Commit messages follow Conventional Commits. If a scope is present, it is one of `core`, `angular`, `angular-formly`, `react`, `tokens`, or `release`; scope is review policy, not enforced as required by current commitlint config.
- [ ] Commit-message validation is absent from CI. Local commitlint runs from Husky's `commit-msg` hook and can be bypassed; inspect commits when relevant.
- [ ] No secrets, credentials, `.env` files, or sensitive infrastructure information are added.
- [ ] Dependency, lockfile, CI, release, deployment, or infrastructure changes are intentional, minimal, and documented. Escalate shared-infrastructure changes for platform review.
- [ ] No generated output is hand-edited: `dist/`, `core/loader/`, `core/www/`, `.stencil/`, generated Angular proxies, or generated React bindings.

## Tokens (`tokens/**`)

- [ ] Token source follows existing design-token structure.
- [ ] Token build output is regenerated and reviewed; affected Core consumers are rebuilt when token names or values change.
- [ ] Token changes preserve consumer compatibility or include a deprecation/migration path.

## Core public contract (`core/src/components/**`)

- [ ] Public props, events, methods, slots, CSS parts, and form behavior remain backward compatible; removals or semantic changes include deprecation and migration guidance.
- [ ] Public API changes regenerate and review `angular/projects/catalyst/src/lib/directives/proxies.ts` and `react/src/components/stencil-generated/index.ts`; Angular and React builds pass.
- [ ] Changes to `cat-input`, `cat-textarea`, `cat-datepicker`, `cat-datepicker-inline`, `cat-checkbox`, `cat-toggle`, `cat-radio`, `cat-radio-group`, `cat-select`, or `cat-tag` preserve or deliberately update value-accessor bindings in `core/stencil.config.ts`.

### Props, events, and methods

- [ ] Boolean props use explicit `false` defaults when false is their default behavior.
- [ ] Multi-word props are camelCase; string unions reuse established scales unless an intentional contract addition is documented.
- [ ] Public `@Prop()`, `@Event()`, and `@Method()` members have accurate JSDoc.
- [ ] Deprecated APIs remain available and their JSDoc gives actionable replacement or migration guidance.
- [ ] Events use `cat` prefix and precise `EventEmitter<T>` payloads; value-change events emit their value type.
- [ ] Native-element wrappers expose `doFocus`, `doBlur`, or `doClick` as appropriate; documentation directs consumers away from inner-element access.
- [ ] Public `@Method()` members are asynchronous and return `Promise<void>` unless an established contract requires another return type.

### Native controls and parts

- [ ] Components wrapping a native control expose `@Element()`, `testId`, and `nativeAttributes` when an inner native element can receive them; `testId` maps to `data-test` and `nativeAttributes` is forwarded.
- [ ] Component JSDoc declares every exposed CSS part; every declared part appears in render output.
- [ ] Parts expose consumer-meaningful surfaces, not internal layout or state-only wrappers.

### SCSS and Shadow DOM

- [ ] Component SCSS uses established imports, token helpers, mixins, `:host` layout, and `:host([hidden]) { display: none; }` where applicable.
- [ ] Colors, typography, radii, and transitions use existing token or mixin patterns. Hardcoded color values are rejected; token-backed CSS custom-property and RGB consumption is allowed.
- [ ] Vendor-prefix exceptions use narrow paired Stylelint disable/enable comments.
- [ ] Shadow-boundary ancestor traversal uses `findClosest`; outside-click detection uses `event.composedPath()`.
- [ ] Focusable wrappers use `shadow: { delegatesFocus: true }` when this matches established component behavior.

### Accessibility and tests

- [ ] Keyboard behavior, focus movement/restoration, disabled behavior, labels, semantic roles, and ARIA state remain correct.
- [ ] Render-affecting prop changes have spec coverage.
- [ ] Interaction, focus, value, or event changes have e2e coverage.
- [ ] Visual variants or state changes have screenshot coverage; baseline changes are intentional and reviewed.

## Angular and Formly (`angular/**`)

- [ ] Public Angular or Formly API changes preserve compatibility or include deprecation and migration guidance.
- [ ] Changes are covered by relevant Angular or Formly tests and `build:angular` / `build:angular-formly` validation.
- [ ] Generated Core proxies are not hand-edited.

## React (`react/**`)

- [ ] Public wrapper API changes preserve compatibility or include deprecation and migration guidance.
- [ ] Generated Stencil bindings are not hand-edited.
- [ ] React build passes; add targeted tests when test infrastructure exists or behavior changes warrant coverage.

## Tooling and release

- [ ] CI changes map correctly to affected paths and preserve required build order: tokens → core → Angular/Formly and tokens → core → React.
- [ ] Public breaking changes are explicitly flagged with consumer migration path; linked release versions do not eliminate compatibility review.
- [ ] Formatter, linter, builds, and relevant tests were run or CI status proves their applicable execution.
46 changes: 46 additions & 0 deletions .github/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: code-review
description: Review Catalyst pull requests. Use for pull request and code review, especially changes to Catalyst components, tokens, Angular, Angular Formly, React bindings, generated bindings, CI checks, or public API contracts.
---

# Catalyst Code Review

The **gate**: approve only when every applicable check passes or is explicitly N/A. Report all blocking findings in one review.

## Step 1 — Establish review context

Use current pull request context. If unavailable, ask for its URL or number. Inspect the description, base and head commits, changed files, commits, existing review threads, and check runs.

Map changed paths to applicable workflows:

| Changed path | Workflow | Checks |
|--------------|----------|-------------------|
| `tokens/**` | Tokens | build |
| `core/**` | Core | build, lint, test |
| `angular/**` | Angular | build, test |
| `react/**` | React | build |

Workflow paths are authoritative; check `.github/workflows/` when they change. React and Tokens have no dedicated lint or test workflow. If a public Core contract changes, also require generated binding review and Angular and React consumer builds: their workflows do not run for `core/**` alone.

Record failed applicable checks. Continue static review, but do not approve while required applicable checks fail.

Completion criterion: changed areas and applicable checks identified; every failed check recorded.

## Step 2 — Apply applicable checks

Load [CHECKLIST.md](CHECKLIST.md). Select sections by changed area. Mark every applicable item ✅, ❌, or N/A with a short reason. For every ❌, record exact file, line, evidence, and required correction.

Inspect changed source, tests, generated bindings, public contracts, and dependency or tooling changes; do not infer correctness from green CI.

Completion criterion: every applicable checklist item accounted for; every blocking finding has actionable evidence.

## Step 3 — Publish one review

- Lead with one sentence describing PR effect.
- List ❌ items as required changes with file, line, evidence, and rule.
- Label non-blocking observations as suggestions.
- Request changes for any blocking finding.
- Approve only when no blocking findings exist and all required applicable checks pass.
- Otherwise leave a comment review describing pending failed or missing checks.

Completion criterion: one complete review published or drafted, with no unreported blocking finding.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,17 @@ Steps:
1. Make changes;
2. Run `pnpm build`;

Extra steps for testing the changes in angular package:
`pnpm run build:core` regenerates Angular and React binding files through
Stencil output targets. Review and commit generated changes with component:

- `angular/projects/catalyst/src/lib/directives/proxies.ts`
- `react/src/components/stencil-generated/index.ts`

`pnpm run build:angular` and `pnpm run build:react` validate and compile those
bindings. CI does not commit generated binding changes. Do not edit generated
files manually.

Extra steps for testing the changes in Angular package:
1. Run `pnpm install` again;
2. For
- [angular](angular/projects/catalyst) Go to `/angular/dist/catalyst`;
Expand Down Expand Up @@ -117,13 +127,13 @@ Both local and CI reference screenshots are committed to the repository so that
Screenshot tests are intentionally excluded from `pnpm run test`. To run them locally:

```
pnpm run test:screenshot # from core/
pnpm run test:screenshot # from repo root
```

To update the local (macOS) reference screenshots after an intentional visual change:

```
pnpm run test:screenshot:update # from core/
pnpm run test:screenshot:update # from repo root
```

This regenerates the `-darwin` screenshots and commits them alongside your changes.
Expand Down
2 changes: 2 additions & 0 deletions angular/projects/catalyst/src/lib/catalyst.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const CatComponents = [
Components.CatRadio,
Components.CatRadioGroup,
Components.CatScrollable,
Components.CatSegment,
Components.CatSegmentedControl,
Components.CatSelect,
Components.CatSkeleton,
Components.CatSpinner,
Expand Down
77 changes: 77 additions & 0 deletions angular/projects/catalyst/src/lib/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,83 @@ export declare interface CatScrollable extends Components.CatScrollable {
scrolledBottom: EventEmitter<CustomEvent<void>>;
}

@ProxyCmp({
inputs: ['a11yControls', 'a11yLabel', 'disabled', 'icon', 'iconOnly', 'nativeAttributes', 'testId', 'value'],
methods: ['doFocus', 'doBlur']
})
@Component({
selector: 'cat-segment',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: [
'a11yControls',
'a11yLabel',
'disabled',
'icon',
'iconOnly',
'nativeAttributes',
'testId',
{ name: 'value', required: true }
],
standalone: false
})
export class CatSegment {
protected el: HTMLCatSegmentElement;
constructor(
c: ChangeDetectorRef,
r: ElementRef,
protected z: NgZone
) {
c.detach();
this.el = r.nativeElement;
}
}

export declare interface CatSegment extends Components.CatSegment {}

@ProxyCmp({
inputs: ['a11yLabel', 'disabled', 'nativeAttributes', 'size', 'testId', 'value']
})
@Component({
selector: 'cat-segmented-control',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['a11yLabel', 'disabled', 'nativeAttributes', 'size', 'testId', 'value'],
outputs: ['catChange', 'catFocus', 'catBlur'],
standalone: false
})
export class CatSegmentedControl {
protected el: HTMLCatSegmentedControlElement;
@Output() catChange = new EventEmitter<CustomEvent<string>>();
@Output() catFocus = new EventEmitter<CustomEvent<string>>();
@Output() catBlur = new EventEmitter<CustomEvent<string>>();
constructor(
c: ChangeDetectorRef,
r: ElementRef,
protected z: NgZone
) {
c.detach();
this.el = r.nativeElement;
}
}

export declare interface CatSegmentedControl extends Components.CatSegmentedControl {
/**
* Emitted when the selected segment changes. Payload is the new segment value.
*/
catChange: EventEmitter<CustomEvent<string>>;
/**
* Emitted when a segment gains focus. Payload is the segment value.
*/
catFocus: EventEmitter<CustomEvent<string>>;
/**
* Emitted when a segment loses focus. Payload is the segment value.
*/
catBlur: EventEmitter<CustomEvent<string>>;
}

@ProxyCmp({
inputs: [
'autoComplete',
Expand Down
1 change: 1 addition & 0 deletions core/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ dist/
www/
loader/
coverage/
.vitest-attachments/

*~
*.sw[mnpcod]
Expand Down
Loading
Loading