From 61424714c79bf46a67d7a25f1bc003b84869436c Mon Sep 17 00:00:00 2001 From: Anthony Rey Date: Fri, 12 Jun 2026 09:52:52 +0200 Subject: [PATCH] docs: add contributing guides and refine review handling in skill Add a root CONTRIBUTING.md (ownership, opening an issue, workflow, commits, pull requests) plus per-package guides for styles, react and icons, a Contributing link in the README, and the supporting per-package mise tasks. Also extend the pick-issue-to-pr skill (step 9) to reply to review threads and resolve them only when the feedback is fully addressed, leaving them open on questions, pushback, partial fixes or deferrals. Closes #4 --- .agents/skills/pick-issue-to-pr/SKILL.md | 12 ++- CONTRIBUTING.md | 83 +++++++++++++++++ README.md | 5 + icons/CONTRIBUTING.md | 43 +++++++++ mise.toml | 15 +++ react/CONTRIBUTING.md | 86 +++++++++++++++++ styles/CONTRIBUTING.md | 112 +++++++++++++++++++++++ 7 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md create mode 100644 icons/CONTRIBUTING.md create mode 100644 react/CONTRIBUTING.md create mode 100644 styles/CONTRIBUTING.md diff --git a/.agents/skills/pick-issue-to-pr/SKILL.md b/.agents/skills/pick-issue-to-pr/SKILL.md index 906828a..200a125 100644 --- a/.agents/skills/pick-issue-to-pr/SKILL.md +++ b/.agents/skills/pick-issue-to-pr/SKILL.md @@ -108,7 +108,17 @@ git commit --amend --no-edit # or adjust the message if the scope changed git push --force-with-lease ``` -- Reply to the review threads where useful. +- Reply to each review thread (`mcp__github__add_reply_to_pull_request_comment`, or `gh api`) saying what you did. + +#### Resolve only what is actually resolved + +After replying, **resolve a thread only when its feedback is fully addressed in the pushed commit** and you are confident the change satisfies it. Resolving has no direct MCP or `gh pr` command; use the GraphQL `resolveReviewThread` mutation, keyed on the **thread node id** (the `id` field like `PRRT_…` from `get_review_comments`, _not_ a comment id): + +```bash +gh api graphql -f query='mutation($t:ID!){ resolveReviewThread(input:{threadId:$t}){ thread { isResolved } } }' -f t="PRRT_…" +``` + +**Leave the thread open for the reviewer whenever you are not closing the loop yourself**: replying with a question, pushing back or proposing an alternative not yet agreed, only partially addressing it, or deferring it to a follow-up. When in doubt, leave it open. Never resolve a thread you have not replied to. Repeat until the PR is approved. **The branch ends with a single commit, always.** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f635ef3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,83 @@ +# Contributing to Ippon UI + +Thanks for taking the time to contribute. Ippon UI is a monorepo of independently +published packages (`@ippon-ui/styles`, `@ippon-ui/react`, `@ippon-ui/icons`). +This guide covers the shared workflow; each package has its own guide for the +conventions specific to it. + +## Ownership + +Every contributor is responsible for the code they submit: its quality, its tests, +and following it through review until it is merged. A pull request is not "thrown +over the wall" — you own it from the first commit to the merge, including +addressing review feedback and keeping it green in CI. + +## Opening an issue + +Issues are the source of truth for the work to be done. Before opening one: + +- Search the [existing issues](https://github.com/ippontech/ui/issues) to avoid + duplicates. +- For a bug, describe the context, the expected behaviour, the actual behaviour, + and how to reproduce it. +- For a change or a new component, describe the need and the intended scope. + +Keep an issue focused on a single concern: one issue, one change. + +## Getting set up + +This repository uses [mise](https://mise.jdx.dev) to manage tooling and tasks. +From the monorepo root: + +```sh +mise trust # trust the local mise configuration +mise install # install the pinned tools (Node, pnpm, Tikui CLI) +mise setup # install dependencies +``` + +See the [README](./README.md) for the full list of tasks. + +## Workflow + +1. Pick or open an issue and assign it to yourself. +2. Create a branch from `main`. +3. Write the code in English (comments, identifiers, documentation). +4. Before committing, run: + + ```sh + mise format # format the code + mise lint # lint and auto-fix + mise test-unit-ci # run the unit tests + ``` + + A pre-commit hook (lefthook) also checks formatting (Prettier) and SCSS + (Stylelint) on staged files. + +## Commits + +Commits follow [Conventional Commits](https://www.conventionalcommits.org): +`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `test:`… Reference the issue in +the body or footer when relevant. + +## Pull requests + +- Target the `main` branch — never push to it directly. +- Open the pull request as a draft until it is ready for review. +- Keep it scoped to a single issue and link the issue with `Closes #`. +- Make sure CI is green before requesting a review. + +## Package guides + +Each package documents its own conventions: + +- [`styles/CONTRIBUTING.md`](./styles/CONTRIBUTING.md) — Pattern Library: Atomic + Design, CAP, tokens and quarks. +- [`react/CONTRIBUTING.md`](./react/CONTRIBUTING.md) — Component Library: React + components wrapping the Pattern Library. +- [`icons/CONTRIBUTING.md`](./icons/CONTRIBUTING.md) — icon font generated from + Ionicons. + +## License + +By contributing, you agree that your contributions are licensed under the +[Apache-2.0](./LICENSE) license. diff --git a/README.md b/README.md index 4535b98..2a17d74 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,11 @@ Common tasks: See [`AGENTS.md`](./AGENTS.md) for the monorepo structure and conventions. +## Contributing + +See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for how to open an issue, the +development workflow, and the per-package guides. + ## License [Apache-2.0](./LICENSE) © Ippon Technologies diff --git a/icons/CONTRIBUTING.md b/icons/CONTRIBUTING.md new file mode 100644 index 0000000..6bef01a --- /dev/null +++ b/icons/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing to `@ippon-ui/icons` + +This package generates an icon font from [Ionicons](https://ionic.io/ionicons). +It is a build step, not a hand-written collection: it ships the compiled font, +its stylesheet and the TypeScript types of every available icon name. + +Read the repository's root `CONTRIBUTING.md` first for the shared workflow +(issues, branches, commits, pull requests). + +## How it works + +`index.ts` is the whole package. It: + +1. Reads the SVG icons shipped by the `ionicons` dependency. +2. Categorises each icon (`logo-*`, `*-outline`, `*-sharp`, or filled) and + writes the `IconClassic`, `IconLogo` and `IconVariant` types to `types/`. +3. Fixes the SVGs and converts them to the `ionicons` font under `dist/`, with + the `ippon-ion` class-name prefix. + +## Building + +From the monorepo root: + +```sh +mise icons-build # runs `node index.ts` +``` + +The generated `dist/` and `types/` are not committed. Most changes here mean +bumping the `ionicons` dependency (Renovate handles this) or adjusting the +generation in `index.ts`; rerun the build and check the produced types. + +## What it produces + +- A `dist/` folder with the `ionicons` web font and its stylesheet. Icons are + exposed as CSS classes prefixed with `ippon-ion` and support ligatures, so a + consuming application can render an icon from its name. +- A `types/index.d.ts` with the available icon names as types — `IconClassic`, + `IconLogo` and `IconVariant` (`'sharp' | 'outline'`) — to type props against + the existing icons. + +## License + +Contributions are licensed under [Apache-2.0](./LICENCE). diff --git a/mise.toml b/mise.toml index dda45ef..0e9bc33 100644 --- a/mise.toml +++ b/mise.toml @@ -43,6 +43,21 @@ run = "pnpm test:unit:ci" [tasks.styles-dev] run = "pnpm --filter styles dev" +[tasks.styles-lint] +run = "pnpm --filter styles lint" + +[tasks.styles-test-unit-ci] +run = "pnpm --filter styles test:unit:ci" + +[tasks.react-lint] +run = "pnpm --filter react lint" + +[tasks.react-test-unit-ci] +run = "pnpm --filter react test:unit:ci" + +[tasks.icons-build] +run = "pnpm --filter icons build" + [tasks.styles-create-component] dir="styles" description="Create a style components using Tikui CLI" diff --git a/react/CONTRIBUTING.md b/react/CONTRIBUTING.md new file mode 100644 index 0000000..ab6c797 --- /dev/null +++ b/react/CONTRIBUTING.md @@ -0,0 +1,86 @@ +# Contributing to `@ippon-ui/react` + +The React Component Library provides the **mechanical** part of each component: +React components that render the Pattern Library markup and expose typed props. +The Pattern Library owns the markup, the CSS classes and the visual states; refer +to its documentation for the classes and structure to use, and follow its CAP +convention (Component Alternative Part), tokens and Atomic Design hierarchy. + +Read the repository's root `CONTRIBUTING.md` first for the shared workflow +(issues, branches, commits, pull requests). + +## File organisation + +Each component is made of: + +- **Component**: `react/src/Ippon.tsx` (PascalCase). +- **Test**: `react/test/Ippon.spec.tsx`. +- **Export**: added to `react/src/index.ts`. + +## Component conventions + +```tsx +import type { DataSelectableWithChildren } from './DataSelectable.ts'; +import { clsx } from 'clsx'; +import { optionalToAlternativeClass } from './CAP.ts'; + +type IpponComponentProps = DataSelectableWithChildren<{ + alternative?: 'primary' | 'secondary'; +}>; + +export const IpponComponent = (props: IpponComponentProps) => ( +
+ {props.children} +
+); +``` + +- Extend `DataSelectable` (no children) or `DataSelectableWithChildren` + (with children); both provide `dataSelector?: string`. +- `data-selector` exposes the element so it can be targeted in tests + (Testing Library is configured with `testIdAttribute: 'data-selector'`); always + forward it. +- Use the types from `Tokens.ts` for colours and sizes (e.g. + `IpponTokenTextColor`, `IpponTokenSize`). +- Model CAP **alternatives** as union types and booleans like `border` as + optional props. +- Build class names with `clsx()` and the helpers from `CAP.ts`: + `optionalToAlternativeClass('primary')` → `'-primary'`, + `optionalToPrefixedAlternativeClass('shadow')('l1')` → `'-shadow-l1'`, + `toAlternativeClass(value)` (non-optional). + +For a CAP **part** (`ippon-component--part`) with significant props, create a +dedicated sub-component and export both from the same file: + +```tsx +type IpponComponentLabelProps = DataSelectableWithChildren<{ + alternative?: 'strong'; +}>; + +export const IpponComponentLabel = (props: IpponComponentLabelProps) => ( + + {props.children} + +); +``` + +## Tests + +Tests use Vitest and Testing Library and live in `react/test/`. Each test should +verify the base class name, every alternative, children rendering, the +`data-selector` binding, and any custom tag support. From the monorepo root: + +```sh +mise react-lint # ESLint +mise react-test-unit-ci # Vitest +``` + +## License + +Contributions are licensed under [Apache-2.0](./LICENCE). diff --git a/styles/CONTRIBUTING.md b/styles/CONTRIBUTING.md new file mode 100644 index 0000000..0a872e2 --- /dev/null +++ b/styles/CONTRIBUTING.md @@ -0,0 +1,112 @@ +# Contributing to `@ippon-ui/styles` + +The Pattern Library represents the **visual** part of each component as SCSS/CSS: +the rendering and the states, not the mechanical behaviour. It is built with +[Tikui](https://tikui.org) and documents every component so any web application +can consume it, regardless of its technology. + +Read the repository's root `CONTRIBUTING.md` first for the shared workflow +(issues, branches, commits, pull requests). + +## Atomic Design + +Components are organised following +[Atomic Design](https://atomicdesign.bradfrost.com), hierarchically composed: + +- `atom/` — indivisible elements (button, badge, icon, text, title…). +- `molecule/` — groups of atoms (tabs, toggle, import-file…). +- `organism/` — groups of molecules (card, container, grid, header, modal…). +- `template/` — page layouts assembled from organisms, molecules and atoms. + +`quark/` and `token/` hold the shared building blocks described below. + +## CAP — Component Alternative Part + +CSS classes follow the CAP convention: + +- **Component**: the component name in `kebab-case` (`.ippon-button`). +- **Alternative**: an alternative or state, prefixed with `-` (`&.-primary`). +- **Part**: a part of the component, prefixed with `--` (`&--icon`). + +```scss +.ippon-button { + &.-primary { + /* primary alternative */ + } + + &--icon { + /* icon part */ + } +} +``` + +```html + +``` + +## Tokens + +A token is a style property (a colour, a font, a spacing…). It is a concept: +even when implemented with a CSS variable, do not confuse a token with a +variable. Tokens live in `token/`. + +- **Base colours** carry a quantity from `100` to `900` + (`--ippon-color-green-500`). A base colour is never used directly by a + component. +- **Semantic colours** give a base colour a meaning (`positive` uses `green`) + and are grouped by usage: `surface`, `text-icon`, `border`, with alternatives + such as `primary`/`secondary` and `on-*` variants for content placed on a + surface (`--ippon-color-success-text-icon-on-primary`). + +Components must use semantic colours, never base colours directly. + +## Quarks + +A quark is a portion of a component that cannot be used on its own (typically a +SCSS `@mixin`). Use a quark to share styling across components — for example a +`weights` mixin reused by both `Text` and `Title`. Quarks live in `quark/` and +produce no rendered output by themselves. + +## Creating a component + +Generate the scaffold with the Tikui CLI (from the monorepo root): + +```sh +mise styles-create-component --path +``` + +- `` — name in `kebab-case` (e.g. `button-card`). +- `--path` — folder under `src/`, defaults to `atom`. +- The `ippon` prefix is applied automatically. + +Each component is made of four files: + +``` +/ + .mixin.pug + .code.pug + .render.pug + _.scss +``` + +Document it by including its Markdown file where it should appear: + +- `include:componentDoc(height=300) button/button.md` for atoms, molecules and + organisms (the optional `height` sizes the rendering). +- `include:templateDoc layout/layout.md` for templates. + +## Checks + +From the monorepo root: + +```sh +mise styles-lint # Stylelint (auto-fix) +mise styles-test-unit-ci # Vitest + sass-true +``` + +## License + +Contributions are licensed under [Apache-2.0](./LICENCE).