[Stack 3/3] Composed components and contract baseline#39
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR implements Story 1.1 (Core Contract and Export Baseline) by introducing UiCardItem/UiCardList (with grid and swiper layouts), UiFooter (default and mobile), Layout (document sync), comprehensive type updates for asset resolution, and full test coverage across all new components. ChangesStory and Specification
Type System and Contracts
Card Item and Services
Card List and Responsive Layout
Footer System
Layout and Document Sync
Exports and Configuration
Test Coverage
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Suggested reviewers
|
(cherry picked from commit f8c3ff5)
- Add type annotations in storybookConfig.test.ts to satisfy @typescript-eslint/typedef (fixes failing static CI check). - Move semver to devDependencies; it is only used by the dev-time checkNodeVersion.js script. - Use the top-level semver import path so the eslint import/no-unresolved rule is satisfied. - Replace console.error usage in build.config.mjs with process.stderr.write for consistency with the rest of the codebase. - Stop swallowing localization parse failures in scripts/localizationGenerator.js — re-throw with file context so a bad locale file fails the build instead of producing partial output. - Normalize feature_request.md headings to ## to match bug_report.md. - Align docker-compose.yml with the VilnaCRM CRM template: add source bind-mount and a named node_modules volume (omit host port mappings to avoid collisions across local projects).
The frozen-lockfile install in Docker failed because bun.lock still recorded semver under dependencies; refresh it so the prod/dev split in package.json matches the lockfile.
The bind mount caused `make copy-coverage` to fail in CI with "mkdir: permission denied" because the container writes /app/coverage as root through the bind mount, leaving the host coverage dir root-owned. Restore the minimal compose layout (source baked into the image, extracted via `docker compose cp`) that the existing Makefile/CI flow relies on.
- Wrap the SECURITY.md known-vulnerabilities paragraph so it satisfies the markdownlint MD013 100-char line limit. - Switch stryker.config.mjs packageManager from "bun" to "npm" — Stryker only accepts npm/yarn/pnpm, and "bun" makes it abort at validation. - Apply Prettier to scripts/localizationGenerator.js so qlty fmt passes.
…o review-2-ui-primitives
…iew-2-ui-primitives
- Fix boxShadow typo in UiButton disabled style - Add rel="noopener noreferrer" default for UiLink target="_blank" - Restore variant-to-element mapping in UiTypography - Improve UiTooltip keyboard accessibility (role, tabIndex, key handlers) - Fix UiToolbar 425px breakpoint overlap - Fix UiTextFieldForm orphaned absolute positioning - Replace unstable CSSProperties import with React's type - Use SxProps<Theme> on UiImage/UiTooltip and stronger onClick type on UiButton - Re-export public API from src/index.ts - Use Playwright baseURL instead of hardcoded localhost in e2e tests - Replace faker calls in test constants with deterministic literals - Remove dead test fixtures referencing non-existent UiCardList/UiFooter - Strengthen tooltip/typography test assertions; drop duplicate/no-op tests
Kills mutants in the new effect cleanup (restore-on-unmount branches and the [metaDescription, pageTitle] dependency array). Layout mutation score 56.76 -> 91.89, restoring the global score above the 80% break threshold.
|
@cubic-dev-ai review |
@RudoiDmytro I have started the AI code review. It will take a few minutes to complete. |
Accessibility:
- CardContent: remove the nested <a> inside the tooltip role="button" trigger
and the invalid <p>-in-<p>; "services" is now a plain inline span disclosure
(WCAG 4.1.2), which also drops the placeholder href="/"
- UiCardItem/UiCardList: add optional headingComponent to decouple the card
title's semantic level from its visual size (WCAG 1.3.1)
- SocialMediaItem: decorative icon now uses alt="" since the link's aria-label
is the accessible name (WCAG 1.1.1)
Correctness / types:
- Type asset imports as `string | { src: string }` behind a shared
resolveImageSrc helper instead of an implicit any; apply across footer,
checkbox and card image usage
- UiCardList: gate CardGrid on !isSmallScreen so the card tree no longer
renders twice on mobile
- CardGrid/CardSwiper: render Box instead of Grid, removing the unsafe ref cast
Config / hygiene:
- Read REACT_APP_ env vars (matching .env) instead of NEXT_PUBLIC_; document
the policy-URL vars in .env(.example)
- Remove empty pages/_app.tsx (accidental .codex rename), drop the dead qlty
memory-leak triage block, and clear the executable bit on source + LICENSE
- Rename VilnaCRMGmail.tsx -> VilnaCRMEmail.tsx; refresh the stale story doc
to the actual React 19 / MUI 9 / TS 6 / Storybook 10 stack
Tests:
- Replace the tautological CardGrid style assertions with real branch checks
- Add a UiCardSwiper suite covering the MutationObserver pointer-events logic
and observer disconnect (previously 0% function coverage)
- Guard against nested-interactive/<p> regressions and cover the heading
override; assert CardGrid presence/absence per breakpoint in UiCardList
7390283
Resolves the unresolved qlty review comments and the failing static / qlty fmt CI checks: - prettier-wrap JSX ternary in UiCardList and the spyOn chain in UiCardItem test - shorten two it() titles under the 100-col editorconfig limit
|
@cubic-dev-ai review |
@RudoiDmytro I have started the AI code review. It will take a few minutes to complete. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/Layout/index.tsx`:
- Around line 37-43: The conditional guards in the Layout component use truthy
checks for pageTitle and metaDescription which wrongly treat empty strings as
absent; change the checks to explicit undefined/null comparisons (e.g.,
pageTitle !== undefined and metaDescription !== undefined or use != null) before
assigning document.title or calling upsertMetaDescription, and apply the same
fix to the other head-related checks in this file (the block that sets/clears
meta tags and title).
In `@src/components/UiFooter/VilnaCRMEmail/VilnaCRMEmail.tsx`:
- Line 11: The component now reads the email from
process.env.REACT_APP_VILNACRM_GMAIL (assigned to the email constant), so update
your deployment/CI environment to provide REACT_APP_VILNACRM_GMAIL with the
desired address (so the fallback defaultEmailAddress isn't used), and also
replace or document the remaining NEXT_PUBLIC_VILNACRM_GMAIL reference in
docs/specs to avoid confusion; no code change required in VilnaCRMEmail.tsx
other than ensuring the env var is present at build time.
In `@tests/unit/PrivacyPolicy.test.tsx`:
- Around line 13-15: Tests are still referencing the old NEXT_PUBLIC env names;
update the test to set/restore the new REACT_APP_VILNACRM_PRIVACY_POLICY_URL and
REACT_APP_VILNACRM_USAGE_POLICY_URL env vars used by PrivacyPolicy component: in
tests/unit/PrivacyPolicy.test.tsx ensure you read/process and restore
process.env.REACT_APP_VILNACRM_PRIVACY_POLICY_URL and
process.env.REACT_APP_VILNACRM_USAGE_POLICY_URL (matching the variables used in
src/components/UiFooter/PrivacyPolicy/PrivacyPolicy.tsx) so the test lifecycle
saves originals, assigns test values, and restores them after each test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8b2abb29-fde4-4df1-bbb2-6e625462d700
📒 Files selected for processing (55)
.env.env.example.qlty/qlty.tomlspecs/implementation-artifacts/1-1-core-contract-and-export-baseline.mdsrc/components/Layout/index.tsxsrc/components/UiCardItem/CardContent.tsxsrc/components/UiCardItem/CardItem.stories.tsxsrc/components/UiCardItem/ServicesHoverCard/ImageItem/ImageItem.tsxsrc/components/UiCardItem/ServicesHoverCard/ImageItem/index.tssrc/components/UiCardItem/ServicesHoverCard/ServicesHoverCard.tsxsrc/components/UiCardItem/ServicesHoverCard/index.tssrc/components/UiCardItem/ServicesHoverCard/styles.tssrc/components/UiCardItem/constants.tssrc/components/UiCardItem/index.tsxsrc/components/UiCardItem/styles.tssrc/components/UiCardItem/types.tssrc/components/UiCardList/CardGrid.tsxsrc/components/UiCardList/CardList.stories.tsxsrc/components/UiCardList/CardSwiper.tsxsrc/components/UiCardList/constants.tssrc/components/UiCardList/index.tsxsrc/components/UiCardList/styles.tssrc/components/UiCardList/types.tssrc/components/UiCheckbox/styles.tssrc/components/UiFooter/DefaultFooter/DefaultFooter.tsxsrc/components/UiFooter/DefaultFooter/index.tssrc/components/UiFooter/DefaultFooter/styles.tssrc/components/UiFooter/Footer.stories.tsxsrc/components/UiFooter/Mobile/Mobile.tsxsrc/components/UiFooter/Mobile/index.tssrc/components/UiFooter/Mobile/styles.tssrc/components/UiFooter/PrivacyPolicy/PrivacyPolicy.tsxsrc/components/UiFooter/PrivacyPolicy/index.tssrc/components/UiFooter/PrivacyPolicy/styles.tssrc/components/UiFooter/SocialMediaItem/SocialMediaItem.tsxsrc/components/UiFooter/SocialMediaItem/styles.tssrc/components/UiFooter/UiFooter.tsxsrc/components/UiFooter/VilnaCRMEmail/VilnaCRMEmail.tsxsrc/components/UiFooter/VilnaCRMEmail/index.tssrc/components/UiFooter/VilnaCRMEmail/styles.tssrc/components/UiFooter/constants.tssrc/components/UiFooter/index.tssrc/components/UiFooter/styles.tssrc/components/UiFooter/types.tssrc/components/index.tssrc/react-app-env.d.tssrc/types/assets.tstests/unit/Layout.test.tsxtests/unit/PrivacyPolicy.test.tsxtests/unit/UiCardGrid.test.tsxtests/unit/UiCardItem.test.tsxtests/unit/UiCardList.test.tsxtests/unit/UiCardSwiper.test.tsxtests/unit/UiFooterEmail.test.tsxtests/unit/UiMobile.test.tsx
💤 Files with no reviewable changes (23)
- src/components/UiFooter/Footer.stories.tsx
- src/components/UiCardItem/ServicesHoverCard/ImageItem/index.ts
- src/components/UiCardItem/ServicesHoverCard/ServicesHoverCard.tsx
- src/components/UiCardItem/ServicesHoverCard/index.ts
- src/components/UiFooter/PrivacyPolicy/styles.ts
- src/components/UiFooter/styles.ts
- src/components/UiFooter/PrivacyPolicy/index.ts
- src/components/UiFooter/SocialMediaItem/styles.ts
- src/components/UiFooter/Mobile/index.ts
- src/components/UiCardItem/ServicesHoverCard/styles.ts
- src/components/UiCardList/constants.ts
- src/components/UiFooter/index.ts
- src/components/index.ts
- src/components/UiFooter/constants.ts
- src/components/UiFooter/DefaultFooter/index.ts
- src/components/UiFooter/UiFooter.tsx
- .qlty/qlty.toml
- src/components/UiCardList/CardList.stories.tsx
- src/components/UiFooter/VilnaCRMEmail/styles.ts
- src/components/UiCardItem/CardItem.stories.tsx
- src/components/UiFooter/Mobile/styles.ts
- src/components/UiCardList/styles.ts
- src/components/UiFooter/DefaultFooter/styles.ts
✅ Files skipped from review due to trivial changes (1)
- src/types/assets.ts
🚧 Files skipped from review as they are similar to previous changes (14)
- tests/unit/UiMobile.test.tsx
- src/components/UiCardList/CardGrid.tsx
- src/components/UiCardList/index.tsx
- tests/unit/UiCardGrid.test.tsx
- src/components/UiFooter/VilnaCRMEmail/index.ts
- src/components/UiCardItem/ServicesHoverCard/ImageItem/ImageItem.tsx
- src/components/UiFooter/DefaultFooter/DefaultFooter.tsx
- src/components/UiFooter/PrivacyPolicy/PrivacyPolicy.tsx
- src/components/UiCardItem/index.tsx
- src/components/UiFooter/Mobile/Mobile.tsx
- src/components/UiFooter/types.ts
- src/components/UiCardList/CardSwiper.tsx
- src/components/UiCardItem/constants.ts
- tests/unit/UiCardList.test.tsx
…ar in spec Clarify that empty/blank pageTitle and metaDescription are intentionally treated as absent (avoids blanking document.title — WCAG 2.4.2) rather than a truthy-check oversight. Correct the lingering NEXT_PUBLIC_VILNACRM_GMAIL reference in the story spec to the shipped REACT_APP_VILNACRM_GMAIL name.
|
|
@cubic-dev-ai review |
@RudoiDmytro I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |



Summary
This is stack PR 3 of 3 replacing the oversized draft PR #9 for CodeRabbit review.
This PR contains the remaining feature layer:
Stack
review-2-ui-primitivesNotes