Skip to content

Conversation

@rushi
Copy link
Member

@rushi rushi commented Jan 13, 2026

Summary

This PR performs a major upgrade of the Xola UI Kit to React v18, with extensive TypeScript migration and dependency updates.

Key Changes:

  • React Upgrade: Migrated from React v17 to v18
  • TypeScript Migration: Converted numerous components and utilities from JavaScript to TypeScript
  • Icon Separation: Moved all icons to a new package for better modularity
  • Dependency Updates:
    • Replaced with
    • Updated build tools (Vite, TypeScript configs)
    • Added new peer dependencies and externalized packages
  • New Components: Added MonthPicker, MonthSelector, and UpcomingDatePicker
  • Build System: Updated Vite configuration with React plugin and improved tree-shaking
  • Documentation: Enhanced Storybook stories and added installation guides

rushi added 24 commits December 7, 2025 13:35
- Disable TypeScript declaration maps to reduce file count by 50%
- Move build-time dependencies to devDependencies:
  * autoprefixer, postcss, tailwindcss
  * prettier, prettier-plugin-tailwindcss
  * react-dom (not needed at runtime)
- Move react to peerDependencies (consumed from host project)
- Keep only runtime dependencies: clsx, tailwind-merge
- Update vite.config.js to properly externalize all dependencies

Package size improvements:
- Reduced from 471 to 237 files (-50%)
- Package size: 89.4 kB → 80.4 kB (-10%)
- Unpacked size: 327.0 kB → 280.3 kB (-14%)
- Bundle size unchanged: 245.02 kB (70.24 kB gzipped)

Consumers will now install fewer dependencies, as most are dev-only.
- Disable TypeScript declaration maps to reduce file count
- Move react and react-dom from dependencies to peerDependencies
- Move storybook-addon-designs from dependencies to devDependencies
- Update vite.config.ts to externalize peerDependencies

Package size improvements:
- Package size: 199.9 kB → 188.3 kB (-5.8%, -11.6 kB)
- Unpacked size: 772.7 kB → 719.6 kB (-6.9%, -53.1 kB)
- Total files: 200 → 104 (-48%, removed 96 .d.ts.map files)

Benefits:
- Smaller npm install footprint
- No duplicate React installations (uses host project's React)
- Storybook addon only installed in dev environments
- Faster installs and smaller node_modules
Missing icon exports added (11 icons):
- CalendarListIcon - calendar list view icon
- CollectionIcon - collection/group icon
- CustomizeColumnsIcon - column customization icon
- EditNotesIcon - edit notes icon
- EmailSendIcon - send email icon
- EyeClosedIcon - closed eye/hidden visibility icon
- LabelIcon - label/tag icon
- PauseIcon - pause control icon
- RefundIcon - refund/money back icon
- TableIcon - table/grid icon
- TranslationIcon - translation/language icon

Linting improvements:
- Switch from xola-lint to eslint with @xola/jslint (matching ui-kit)
- Add eslint.config.js using same config as ui-kit
- Update lint scripts to use eslint --cache --fix
- Add lint:ci script for CI environments
- Add @xola/jslint ^3.2.0 and eslint ^9.39.1 to devDependencies

All 233 icons now properly exported and ready for use.
- Change React peerDependency from ^18.3.1 to >=17
- Allows icons package to work with React 17, 18, 19, and future versions
- Provides better compatibility for projects on different React versions
- Update React version references from v17 to v18 in Introduction stories
- Add missing FilterIconOld export to icons/index.js
- Add CLAUDE.md with project overview, TypeScript migration patterns, and coding guidelines
- Includes setup commands, build instructions, and PR guidelines
- Documents TypeScript patterns for components, props, and common fixes
- Provides agent coding and review guidelines for maintaining code quality
- Add complete globals mapping in vite.config.ts for all external dependencies
- Fix vite-plugin-dts configuration: tsConfigFilePath → tsconfigPath
- Add lodash-es, use-debounce, axios, ahooks, react18-json-view, tailwind-merge globals
- Fix Tailwind content pattern to exclude node_modules and prevent performance issues
- Re-add ajv package (required for vite-plugin-dts compatibility)
- Export 26 frequently used icons from src/index.js for Storybook stories
- Includes MenuIcon, UserIcon, CheckIcon, CalendarIcons, and other common icons
- Fixes "No matching export" errors in PopoverList and Tooltip stories
- Note: Icons are still published separately as @xola/icons package
- Remove icon exports from src/index.js that were added for Storybook
- Install @xola/icons@1.2.4 as devDependency from npm registry
- Update 8 story files to import icons from @xola/icons instead of "../.."
- Add @xola/icons to vite external configuration to prevent bundling
- Story files updated:
  - Forms: Button, ButtonGroup, ToggleButton
  - DataDisplay: Badge
  - Navigation: Sidebar
  - Overlay: PopoverList, Tooltip
  - Other: Breakdown

Note: Components still import icons from local ./icons folder (bundled)
- Updated react-day-picker from 7.4.10 to 9.12.0
- Migrated from dayjs locales to date-fns locales
- Updated DatePicker.helpers.ts to use date-fns locale objects
- Converted LocalizedDayPicker to use v9 DayPicker API
- Updated DatePicker.tsx to use new v9 props (mode, selected, onSelect, components)
- Replaced DateUtils with date-fns functions (isBefore, isAfter, isSameDay)
- Updated RangeDatePicker to use v9 API with custom components
- Migrated NavbarElement to use useDayPicker hook
- Fixed TypeScript type compatibility issues
- Copied over to the style used in checkout app
Externalize react/jsx-runtime and react/jsx-dev-runtime to prevent bundling
React's internal APIs in the build output. This ensures the UI Kit works
correctly with both React 18 and React 19 consumers by using the consumer's
JSX runtime instead of bundling a version-specific implementation.

Fixes compatibility issues with React 19 where bundled React 18 internals
cause "Cannot read properties of undefined (reading 'ReactCurrentDispatcher')"
errors.
Replace the heavyweight google-libphonenumber library with the lighter
libphonenumber-js alternative to reduce bundle size and improve performance.

Changes:
- Replace google-libphonenumber dependency with libphonenumber-js (^1.12.31)
- Remove @types/google-libphonenumber devDependency (no longer needed)
- Update phone utility functions to use libphonenumber-js API:
  - Use parsePhoneNumber instead of PhoneNumberUtil.getInstance()
  - Use phoneNumber.country instead of getRegionCodeForNumber()
  - Use phoneNumber.formatNational()/formatInternational() instead of format()
- Update Phone component to use CountryCode type from libphonenumber-js
- Update vite.config.ts globals mapping
- Remove google-libphonenumber from tsconfig.json types array

Benefits:
- Smaller bundle size (libphonenumber-js is ~75% smaller)
- Built-in TypeScript support (no @types package needed)
- Simpler, more modern API
- Maintains backward compatibility with existing functionality
Update the icons build configuration to preserve module structure, enabling
modern bundlers to tree-shake unused icons and significantly reduce bundle size.

Changes:
- Add `sideEffects: false` to package.json to signal safe tree-shaking
- Configure Rollup with `preserveModules: true` to maintain file structure
- Add `entryFileNames` function to preserve meaningful icon names
- Update package exports to point to index.js instead of bundled file

Build output structure:
- Individual icon files: CheckIcon.js, AccountIcon.js, etc. (~450 bytes each)
- Barrel file (index.js) re-exports all icons for convenience (~18KB)
- Subdirectories preserved: CreditCards/, Logos/, MobileStore/, etc.

Benefits:
- Developers can still import from barrel: `import { CheckIcon } from '@xola/icons'`
- Modern bundlers (Webpack 5, Rollup, Vite) automatically tree-shake unused icons
- Typical savings: ~90% reduction when using only a few icons
- Example: Using 5 icons = ~2.5KB instead of entire 18KB+ barrel

No breaking changes - existing imports continue to work identically.
Update the UI Kit build configuration to preserve module structure, enabling
modern bundlers to tree-shake unused components and significantly reduce bundle size.

Changes:
- Add `sideEffects: ["*.css"]` to package.json to mark CSS as having side effects
- Configure Rollup with `preserveModules: true` to maintain file structure
- Add `entryFileNames` function to preserve component file structure
- Update package exports to point to index.js instead of bundled ui-kit.es.js
- Improve external configuration to use function-based matching for subpaths
- Externalize common transitive dependencies (@emotion, date-fns, etc.)

Build output structure:
- Individual component files: components/Buttons/Button.js (~3.3KB each)
- Individual helper files: helpers/date.js (~1.4KB each)
- Barrel file (index.js) re-exports all components for convenience (~5.8KB)
- Subdirectories preserved: components/, helpers/, hooks/, utils/, types/
- Build size: 952KB total (113 JS files)

Benefits:
- Developers can still import from barrel: `import { Button } from '@xola/ui-kit'`
- Modern bundlers (Webpack 5, Rollup, Vite) automatically tree-shake unused components
- Typical savings: ~80-95% reduction when using only a few components
- Example: Using 5 components = ~20KB instead of entire ~550KB+ bundle
- Transitive dependencies properly externalized (no bundled node_modules)

No breaking changes - existing imports continue to work identically.
@rushi rushi changed the base branch from master to react-upgrade January 13, 2026 09:10
rushi added 3 commits January 13, 2026 14:43
Remove deprecated v7 props destructuring, unused useDateSelectedRangeStyle,
and unused children props in DayButton components. Includes auto-formatting.
@rushi rushi marked this pull request as ready for review January 13, 2026 09:19
@rushi rushi merged commit 56fd5bd into xola:react-upgrade Jan 13, 2026
1 check failed
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.

1 participant