Skip to content

Conversation

@ickas
Copy link
Member

@ickas ickas commented Jan 19, 2026

Summary

  • CSS Modules Migration: Migrated all components from styled-components to CSS modules for better performance and maintainability
  • Package Manager: Migrated from yarn to bun
  • Storybook 10: Upgraded from Storybook 7 to Storybook 10.1.11 with Vite builder
  • React 18: Upgraded React peer dependency to v18 for Storybook compatibility
  • Testing: Added Vitest addon with play functions, improving coverage from 76% to 84%
  • Accessibility: Enabled a11y testing for all stories via @storybook/addon-a11y
  • Cleanup: Removed redundant Jest tests now covered by Storybook play functions

Changes

CSS Modules Migration (Phase 1-4)

  • Migrated all atoms, molecules, and organisms to CSS modules
  • Removed styled-components and polished dependencies
  • Added CSS utility functions for color manipulation

Dependency Updates

  • yarnbun package manager
  • Storybook 7Storybook 10.1.11
  • WebpackVite builder for Storybook
  • React 16+React 18 (dev dependency for Storybook)

Testing Improvements

  • Added @storybook/addon-vitest for browser-based component testing
  • Added play functions to 15 story files
  • Enabled accessibility testing with a11y-test tag
  • Removed 14 redundant Jest test files (~1,381 lines)

Bug Fixes

  • Fixed CSS variable circular reference in button component
  • Fixed controlled/uncontrolled component warnings in text-area and text-field
  • Fixed drag and drop visual update in table-dnd
  • Fixed toggle CSS module class matching
  • Fixed various Storybook deprecation warnings

Test plan

  • Run bun install to install dependencies
  • Run bun run storybook to verify all stories render correctly
  • Run bun run test:storybook to verify all play functions pass
  • Run bun run test to verify remaining Jest tests pass
  • Run bun run build to verify production build succeeds

🤖 Generated with Claude Code

ickas and others added 30 commits January 19, 2026 19:09
- Add clsx dependency for conditional class names
- Create CSS utilities (rem, transparentize) to replace polished functions
- Add button and field design tokens as CSS variables in global.css
- Update useColor hook to return CSS variable references (colorVar, hoverVar)
- Update snapshots for actions-menu tests

Part of TKAI-4185

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrate 12 simple components from styled-components to CSS modules:

Atoms (6):
- truncate-line
- video-player
- label
- progress-bar
- tag
- avatar-image

Molecules (6):
- card-value
- empty-table
- field-with-button
- modal-footer
- grid-container
- data-warning

Also added breakpoint CSS variables to global.css.

Part of TKAI-4185

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrate 8 components from styled-components to CSS modules:

Atoms (5):
- spinner (with @Keyframes animation)
- tag-number
- select
- button-dropdown
- text-field-appendix

Molecules (3):
- form-group

Part of TKAI-4185

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrated remaining Tier 2 molecules to CSS modules:
- error
- checkbox-group
- radio-group
- pagination-control

Also fixed TypeScript error with custom CSS properties by using
CSSProperties & Record<string, string> type assertion in:
- spinner
- tag
- tag-number
- avatar-image
- button-dropdown

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrated moderate complexity atoms to CSS modules:
- checkbox-button
- toggle
- text-area
- file-picker
- select-interactive
- error-field (migrated early due to dependency on text-area)

All components use clsx for conditional classes and CSS custom
properties for dynamic values where needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed obsolete styles.tsx files from previously migrated components
and fixed grid-container's grid-row and grid-col components that were
still importing from the old styles module.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… checkbox, text-field

Migrated complex atoms to CSS modules:
- button: useColor hook integration, CSS custom properties for dynamic colors
- button-link: similar pattern to button with anchor element
- checkbox: checkmark styling with state classes
- text-field: dynamic SVG icons via CSS custom properties

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrated molecules to CSS modules:
- actions-menu: dynamic positioning via CSS custom properties
- note-card: color variants with CSS variables
- number-input-spinner: dynamic input width
- wizard-steps: active state with CSS variables

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ideshow

Migrated complex components to CSS modules:
- table: responsive layout, skeleton loading animation, shared styles
- table-dnd: drag and drop styling, uses table shared styles
- slideshow: carousel overrides using :global() selectors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrated remaining organisms to CSS modules:
- loading-state: skeleton animations
- tabs-panel: react-responsive-tabs overrides via :global()
- modal-drawer: slide-in animation, z-index via CSS variable
- modal: overflow handling, z-index via CSS variable
- icon stories: storybook demo styles

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove styled-components, @types/styled-components, polished
- Remove jest-styled-components from all test files
- Add rgba utility to css-utils.ts
- Update variables.ts to use local css-utils instead of polished

All tests pass (117 tests). Build compiles successfully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
No Flow files exist in the project. This preset was configured
but never actually used.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… config

- Move @babel/preset-react, @types/uuid, eslint-config-prettier from
  dependencies to devDependencies
- Remove eslint-config-react-app (caused ESM compatibility issues)
- Add eslint-plugin-react-hooks for React hooks linting
- Update eslint-plugin-testing-library to v6
- Configure ESLint directly with @typescript-eslint/parser
- Run ESLint directly instead of through TSDX to avoid config conflicts
- Add @eslint/eslintrc resolution to fix ESM compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update the following packages to their latest patch/minor versions:
- @babel/preset-react: 7.28.5
- @babel/preset-typescript: 7.28.5
- @types/react: 17.0.90
- @types/react-dom: 17.0.26
- @types/react-beautiful-dnd: 13.1.8
- prettier: 3.8.0
- eslint-plugin-prettier: 5.5.5
- react-select: 5.10.2
- react-intersection-observer: 9.16.0
- react-player: 2.16.1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all Storybook packages to latest 8.x release:
- @storybook/addon-a11y: 8.6.15
- @storybook/addon-controls: 8.6.15
- @storybook/addon-essentials: 8.6.14
- @storybook/addon-links: 8.6.15
- @storybook/addon-webpack5-compiler-swc: 1.0.6
- @storybook/react: 8.6.15
- @storybook/react-webpack5: 8.6.15
- @storybook/theming: 8.6.14
- storybook: 8.6.15

Also add storybook-static to .gitignore.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace yarn with bun for faster dependency installation while
maintaining compatibility with existing build tooling (TSDX, Jest,
Storybook webpack5).

Benefits:
- Faster dependency installation (~25s vs ~45s)
- Faster script execution
- Native TypeScript support

Note: Build tooling (TSDX, Storybook) still runs through their
respective commands. Full Bun ecosystem migration (replacing
TSDX with tsup, Storybook with Vite) would be a separate effort.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace @storybook/addons with @storybook/manager-api
- Remove @storybook/addon-styling (unused theme decorator)
- Update preview.tsx to use Storybook 8 config format

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update all @storybook packages to v10
- Remove @storybook/addon-essentials (now part of core)
- Remove @storybook/manager-api and @storybook/theming (consolidated into storybook package)
- Update imports to use consolidated paths (storybook/manager-api, storybook/theming/create)
- Migrate backgrounds config from values array to options object
- Replace deprecated docs.autodocs with tags: ['autodocs']
- Update eslint-plugin-storybook to v10
- Requires Node.js 20.19+ or 22.12+

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update react, react-dom, react-is to ^18
- Update @types/react, @types/react-dom to ^18
- Fix TypeScript errors with React 18 stricter children types
  in Table and TableDnD components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Switch Storybook from react-webpack5 to react-vite for better CSS modules
support and faster development experience. This simplifies the configuration
by removing custom webpack rules since Vite handles CSS modules natively.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Preview type annotation to .storybook/preview.tsx
- Simplify nested ternaries in table/index.tsx using array lookup
- Replace @ts-ignore with @ts-expect-error in table-dnd/index.tsx
- Add missing handleOptionClick prop to ActionMenuList in table-dnd
- Update CLAUDE.md with bun commands and Storybook 10/React 18 versions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The inline style was setting --buttonPadding using var(--buttonPadding),
creating a circular reference. Fixed by:
- Moving padding construction to CSS: padding: 0 var(--buttonPadding)
- Removing the buggy inline --buttonPadding from JS
- The .iconOnly class already handles icon-only buttons with padding: 0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- checkbox: use Fragment instead of array to avoid key prop warning
- file-picker, icon, slideshow: migrate from deprecated .story annotation
  to modern .storyName, .args, .argTypes, .decorators format
- icon: fix argTypes format (options at same level as control, not nested)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move options from nested control object to argType level:
- control: { type: 'select', options: [...] }
+ control: 'select', options: [...]

This fixes "Select with no options" warnings in Storybook 10.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
React warns against using selected on <option> elements.
Use defaultValue on <select> to set the initial selection instead.

Also fixed story argTypes to use modern Storybook format.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… warnings

Prevent React warnings about having both value and defaultValue props:
- Only pass defaultValue when value is undefined
- Remove value: null from story args

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move {...args} before custom onChange handler to prevent args from
overriding the stateful onChange that updates the character count.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CSS fix:
- Wrap .switch-on and .switch-off selectors in :global() to prevent
  CSS modules from transforming them, matching the plain class names
  used in the component JSX

Story fix:
- Add useState and useEffect for proper state management
- Sync state with args.checked changes from Storybook controls

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The component uses className="check" as a plain string, but CSS modules
was transforming .check selectors. Wrapping in :global() ensures the
CSS matches the actual class names in the DOM.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ickas and others added 9 commits January 20, 2026 16:29
- Use row.id instead of index for Draggable key and draggableId
- Move {...args} spread before custom props to prevent Storybook action
  from overriding onChange handler

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CSS modules migration incorrectly used --colorWhite and --colorBlack
but the global CSS defines --white and --black. This caused colors to
fall back to black when the undefined variables were used.

Affected components:
- tabs-panel, modal, modal-drawer (organisms)
- table, table-dnd, note-card, wizard-steps (molecules)
- slideshow (atoms)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ey/purple/etc

The CSS modules migration incorrectly prefixed color variables with "color"
(e.g., --colorGrey200) but the global CSS defines them without the prefix
(e.g., --grey200). This caused borders and colors to fall back to black.

Affected components:
- table, table-dnd, note-card, number-input-spinner, wizard-steps (molecules)
- modal, loading-state (organisms)
- icon stories (atoms)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Install @storybook/addon-vitest to enable running component tests
directly inside Storybook's UI.

Added dependencies:
- @storybook/addon-vitest
- vitest
- playwright
- @vitest/browser-playwright
- @vitest/coverage-v8

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Storybook Vitest addon to enable component testing with play functions.
This allows running interaction tests against Storybook stories directly.

- Add @storybook/addon-vitest and Vitest dependencies
- Add @vitest/browser-playwright for browser testing
- Create vitest.config.mts for Storybook test configuration
- Add vitest.setup.ts for Storybook annotations
- Add sample play function to Button component story
- Add test:storybook script to run component tests

Requires Node.js 20.12+ for Vite 7 compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive interaction tests via Storybook play functions to atoms,
molecules, and organisms components. This improves test coverage metrics:
- Statements: 78% → 84%
- Branches: 72% → 80%
- Functions: 63% → 76%
- Lines: 78% → 85%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tions

Remove 14 redundant Jest test suites that are now fully covered by
Storybook play functions with better browser-based testing:
- checkbox-button, checkbox, file-picker, select-interactive, select
- text-area, text-field, toggle
- actions-menu, checkbox-group, number-input-spinner, radio-group
- modal, modal-drawer

Also update snapshots for remaining Jest tests (CSS modules class changes).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add a11y addon annotations to vitest setup
- Enable 'a11y-test' tag globally for all stories
- Accessibility checks now run as part of automated test suite

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@ickas ickas changed the title [TKAI-4185] refactor to css modules refactor: migrate to CSS modules, upgrade Storybook 10, and improve testing Jan 20, 2026
@ickas ickas marked this pull request as ready for review January 20, 2026 18:48
@ickas ickas requested a review from vhcsilva January 20, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants