Skip to content

feat(checkbox): add atom component#243

Merged
egdev6 merged 2 commits into
mainfrom
feat/18-checkbox
May 30, 2026
Merged

feat(checkbox): add atom component#243
egdev6 merged 2 commits into
mainfrom
feat/18-checkbox

Conversation

@egdev6
Copy link
Copy Markdown
Member

@egdev6 egdev6 commented May 30, 2026

Summary

  • Adds the Checkbox atom following the approved issue [ATOMS] Checkbox #18 component spec and 6-file pattern.
  • Supports native checkbox semantics, controlled/uncontrolled state, indeterminate, readOnly, disabled, invalid/error, description, and strict accessible-name requirements.
  • Adds strict inline-only labelHtml sanitization plus Storybook/test coverage for visual states and non-clickable descriptive text.

Closes #18

Review scope

  • Primary files/areas:
    • src/components/atoms/checkbox/*
    • src/utils/sanitizeHtml.ts
    • src/utils/sanitizeHtml.test.ts
    • src/index.ts
  • Out of scope:
    • CheckboxGroup behavior
    • Table migration to the new Checkbox atom
    • Wider Text sanitizer behavior beyond the strict inline profile used here
  • Review workload: large; new atom plus stories/tests and sanitizer profile. Spec and review gates were completed in issue [ATOMS] Checkbox #18.

Type of change

  • New component
  • Existing component update/refactor
  • Bug fix
  • Accessibility
  • Design tokens
  • Storybook/docs
  • Infrastructure/tooling
  • NPM/dependencies

Workflow gates

  • Linked issue is present with Closes #NNN or maintainer approved an exception.
  • Linked issue has label status:approved before implementation starts.
  • Work was started through the Project flow: assignee set, Project status In progress, branch/worktree recorded.
  • PR title follows Conventional Commit format: <type>(<optional scope>): <description>.
  • Commits follow the same commitlint-enforced format.
  • Diff is focused; unrelated work is called out in Review scope.
  • MCP/runtime artifacts are absent: .playwright-mcp, page-*.png, page-*.jpeg, *.md.playwright-output.

Component evidence (required for component changes)

  • Validated component spec is linked or quoted in the issue.
  • Accessibility contract from the spec was implemented or deviations are explained below.
  • Follows the 6-file pattern: types.ts, use*.ts, Component.tsx, Component.test.tsx, Component.stories.tsx, index.ts.
  • CVA variants live in types.ts; JSX component has no state, CVA calls, or business logic.
  • Uses design tokens from theme.css; no hardcoded colors or arbitrary color utilities.
  • Storybook covers default, variants, documented states, edge cases, and dark mode when visually different.
  • Component audit result is PASS or accepted PASS WITH WARNINGS.
  • Visual review result is included when visuals changed.

Accessibility evidence

  • Role/name semantics verified with Testing Library queries or equivalent.
  • Keyboard-only behavior verified: Space toggles native checkbox; readOnly blocks Space; Enter is not a checkbox toggle requirement.
  • Focus lifecycle verified: native input receives focus; focus-visible ring applies to the visual control.
  • Disabled, required, invalid/error, and indeterminate states expose expected semantics.
  • Reduced motion behavior is respected where motion changed.
  • Screen reader or axe/manual evidence is included below when applicable.

Validation evidence

  • TypeScript: pnpm exec tsc --noEmit
  • Unit tests:
    • pnpm exec vitest run src/components/atoms/checkbox/Checkbox.test.tsx src/utils/sanitizeHtml.test.ts
    • pre-push pnpm test26 passed / 403 tests
  • Build/package: pnpm run build
  • Storybook or visual check: live Storybook visual review via Playwright ✅; final visual/audit reviewer PASS
  • Accessibility check: Testing Library role/name/ARIA/keyboard/readOnly/indeterminate/form tests ✅
  • Security/dependency check: strict inline labelHtml sanitizer tests remove/neutralize interactive and unsafe HTML ✅

Screenshots or recordings

Not attached. Live Storybook visual review was performed locally; Playwright runtime artifacts were cleaned before PR.

Notes for reviewer

  • Source of truth for final spec conflicts: [ATOMS] Checkbox #18 (comment)
  • label, description, and errorMessage intentionally do not toggle the checkbox; only the visual control hit area toggles.
  • labelHtml uses a strict inline-only sanitizer profile; the general Text sanitizer remains broader by design.
  • Latest visual polish: tighter text alignment, Input-style error icon row, less-rounded control corners, and a 2px right shift for the error row.

@egdev6 egdev6 added the type:feature Feature changes label May 30, 2026
@egdev6 egdev6 self-assigned this May 30, 2026
@egdev6 egdev6 requested a review from Copilot May 30, 2026 01:29
@ludevdot
Copy link
Copy Markdown
Collaborator

  • useCheckbox.ts: el estado DOM input.indeterminate puede desincronizarse después de una activación nativa, porque el browser limpia indeterminate al click y el effect solo depende de
    indeterminate. Si el padre mantiene indeterminate={true}, puede quedar DOM false pero aria-checked="mixed". Sumaría re-sync después de cambios de checked y un test de ese caso.
    • types.ts: el label disabled cambia a color secundario además de usar opacity-40 en root. El contract pide disabled por opacity/cursor/pointer, no sustitución de color.
    • Si aplica en este repo, faltaría mockear lucide-react/dynamic.js antes de importar Checkbox en tests, porque Checkbox importa Icon.

Mira el storybook la tab accesibilidad da warnings de contraste

El resto... fetén.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Checkbox atom with native checkbox semantics, accessibility-focused naming/description handling, sanitised labelHtml, Storybook coverage, and unit tests.

Changes:

  • Added Checkbox component, hook, CVA types, stories, tests, and atom exports.
  • Added strict inline HTML sanitization utilities for checkbox label HTML.
  • Exported Checkbox from the package entrypoint.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/components/atoms/checkbox/Checkbox.tsx Renders the Checkbox atom UI and error/description rows.
src/components/atoms/checkbox/useCheckbox.ts Implements checkbox state, ARIA wiring, sanitised labels, and event handling.
src/components/atoms/checkbox/types.ts Defines props, variants, and CVA styling.
src/components/atoms/checkbox/Checkbox.test.tsx Adds component and hook behavior tests.
src/components/atoms/checkbox/Checkbox.stories.tsx Adds Storybook examples for supported states.
src/components/atoms/checkbox/index.ts Exports Checkbox and its types.
src/utils/sanitizeHtml.ts Adds inline sanitization profile and text extraction helper.
src/utils/sanitizeHtml.test.ts Covers default and inline sanitization behavior.
src/index.ts Exports Checkbox from the package entrypoint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/atoms/checkbox/useCheckbox.ts Outdated
Comment thread src/utils/sanitizeHtml.ts Outdated
@egdev6
Copy link
Copy Markdown
Member Author

egdev6 commented May 30, 2026

Review feedback addressed

Gracias por la revisión. Apliqué los puntos que correspondían:

  • useCheckbox.ts: re-sync de input.indeterminate también cuando cambia checked, para cubrir la activación nativa que limpia el flag DOM aunque indeterminate={true} siga activo. Añadí test de regresión.
  • types.ts: el label disabled ya no cambia a color secundario; queda bajo el tratamiento de opacity-40 del root según el contract.
  • Checkbox.test.tsx: añadí mock de lucide-react/dynamic.js antes de importar Checkbox.
  • sanitizeHtml.ts: getSanitizedTextContent ahora parsea HTML y usa textContent, así entidades como &nbsp; no pasan como nombre accesible válido. Añadí cobertura.

Validación local/pre-push:

  • pnpm exec vitest run src/components/atoms/checkbox/Checkbox.test.tsx src/utils/sanitizeHtml.test.ts
  • pre-commit Biome + typecheck ✅
  • pre-push pnpm test26 files / 405 tests passed

Sobre los warnings de contraste en Storybook: además de quitar la sustitución de color en disabled label, los checks de Accessibility del PR estaban en verde. Queda listo para re-check de CI con el nuevo commit.

@egdev6 egdev6 merged commit fd183f8 into main May 30, 2026
9 checks passed
@egdev6 egdev6 deleted the feat/18-checkbox branch May 30, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:feature Feature changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ATOMS] Checkbox

3 participants