Skip to content

Commit 1092f15

Browse files
Merge remote-tracking branch 'origin/main' into fix/5939
2 parents 087a513 + 877403c commit 1092f15

File tree

138 files changed

+7023
-1726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+7023
-1726
lines changed

CLAUDE.md

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,164 @@
1-
Use yarn instead of npm for running commands
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Package Manager
6+
7+
**Always use `yarn` instead of `npm`** for all commands in this repository (yarn@4.9.2).
8+
9+
## Common Commands
10+
11+
### Development
12+
13+
- `yarn install` - Install dependencies (run from project root)
14+
- `yarn start` - Start the docs-site development server at http://localhost:5173
15+
- `yarn build` - Full production build (JS + CSS in all formats)
16+
- `yarn build-dev` - Development build with file watching
17+
18+
### Testing and Quality
19+
20+
- `yarn test` - Run the full test suite (Jest with ts-jest)
21+
- `yarn test src/test/calendar_test.test.tsx` - Run a single test file
22+
- `yarn test:watch` - Run tests in watch mode
23+
- `yarn test:ci` - Run tests with coverage for CI
24+
- `yarn lint` - Run both ESLint and Stylelint
25+
- `yarn eslint` - Run ESLint on src directory
26+
- `yarn sass-lint` - Run Stylelint on SCSS files
27+
- `yarn type-check` - Run TypeScript type checking without emitting files
28+
- `yarn prettier` - Format all JS/JSX/TS/TSX files
29+
- `yarn prettier:check` - Check formatting without making changes
30+
31+
### Building Individual Pieces
32+
33+
- `yarn build:src` - Build JS using Rollup
34+
- `yarn js:dev` - Build JS in watch mode
35+
- `yarn css:prod` - Build minified production CSS
36+
- `yarn css:dev` - Build expanded development CSS
37+
- `yarn css:modules:prod` - Build CSS modules (minified)
38+
- `yarn css:modules:dev` - Build CSS modules (expanded)
39+
40+
## Architecture Overview
41+
42+
### Component Hierarchy
43+
44+
The main entry point is `src/index.tsx` which exports the `DatePicker` component. The component hierarchy flows as follows:
45+
46+
```
47+
DatePicker (index.tsx) - Main component, class-based
48+
├── PopperComponent (popper_component.tsx) - Positioned calendar container
49+
│ ├── withFloating HOC (with_floating.tsx) - Floating UI integration
50+
│ ├── Portal (portal.tsx) - Optional portal rendering
51+
│ └── TabLoop (tab_loop.tsx) - Keyboard navigation wrapper
52+
│ └── Calendar (calendar.tsx) - Core calendar logic
53+
│ ├── ClickOutsideWrapper - Handles outside clicks
54+
│ ├── Month/Year/Time components - Date selection UI
55+
│ └── Various dropdowns for date navigation
56+
```
57+
58+
### Key Architectural Patterns
59+
60+
**Positioning System**: The datepicker uses `@floating-ui/react` (v0.27.15) for positioning the calendar relative to the input. The `withFloating` HOC wraps `PopperComponent` to provide positioning logic.
61+
62+
**Date Utilities**: All date manipulation goes through `date_utils.ts`, which wraps `date-fns` (v4.1.0). This provides a consistent API across the codebase and makes it easier to maintain date-related logic.
63+
64+
**State Management**: The main `DatePicker` component is class-based and manages state internally. Most child components are controlled components that receive props and callbacks.
65+
66+
**Styling**: SCSS source files live in `src/stylesheets/`. The build process generates multiple CSS outputs:
67+
68+
- Regular CSS: `react-datepicker.css` (dev) and `react-datepicker.min.css` (prod)
69+
- CSS Modules: `react-datepicker-cssmodules.css` and `react-datepicker.module.css`
70+
71+
### Build Output
72+
73+
Rollup (configured in `rollup.config.mjs`) generates multiple bundle formats in the `dist/` directory:
74+
75+
- **UMD**: `react-datepicker.js` and `react-datepicker.min.js` (browser)
76+
- **CommonJS**: `index.js` (Node/bundlers)
77+
- **ES Modules**: `index.es.js` (modern bundlers)
78+
- **Types**: `index.d.ts` (TypeScript definitions)
79+
80+
### Testing Architecture
81+
82+
Tests use Jest with `@testing-library/react` and are located in `src/test/`. The test setup:
83+
84+
- Configuration: `jest.config.js`
85+
- Setup file: `src/test/index.ts`
86+
- Helper components: `src/test/helper_components/`
87+
- Coverage is collected and reported to Codecov
88+
89+
**Important for tests**: Some components use ShadowDOM for testing. The `shadow_root.tsx` helper uses `flushSync` to ensure synchronous updates required by tests.
90+
91+
### Floating UI Integration Notes
92+
93+
The codebase uses `@floating-ui/react` for positioning. **Important**: The Floating UI library requires refs and context to be accessed during render, which is by design. When fixing linting errors:
94+
95+
- Use `eslint-disable` comments for Floating UI ref accesses (e.g., `popperProps.refs.setFloating`, `popperProps.context`, `arrowRef`)
96+
- These are **not** violations of React best practices—they're intentional library usage
97+
- See `popper_component.tsx` and `with_floating.tsx` for examples
98+
99+
### React Hooks Rules
100+
101+
This codebase uses `eslint-plugin-react-hooks` v7.0.1+ which has strict rules about:
102+
103+
- **Ref access during render**: Generally not allowed, but see Floating UI exception above
104+
- **setState in effects**: Avoid calling setState directly in effects; use `flushSync` when synchronous updates are needed
105+
- When refs must be updated based on props, do it in `useEffect`, not during render
106+
107+
## Development Workflow
108+
109+
### Local Development Setup (Full)
110+
111+
1. Install node >=16.0.0 and yarn >=4.6.x
112+
2. `yarn install` from project root
113+
3. `yarn build` from project root (generates dist/ directory)
114+
4. `yarn start` to launch docs at http://localhost:5173
115+
5. In a new terminal, run `yarn build-dev` to auto-rebuild on changes
116+
117+
**Note**: The docs-site uses a portal: dependency (`"react-datepicker": "portal:../"`) which links to the parent project. Changes to the main package are reflected in the docs when you rebuild.
118+
119+
### Alternative Setup with yarn link (from CONTRIBUTING.md)
120+
121+
If you need tighter integration during development:
122+
123+
1. Run `yarn link` from project root
124+
2. Run `cd docs-site && yarn link react-datepicker`
125+
3. Then follow steps above
126+
127+
### Quick Development Workflow
128+
129+
After initial setup, when making changes:
130+
131+
- **JS/TS changes**: Changes auto-rebuild if `yarn build-dev` is running
132+
- **SCSS changes**: Run `yarn run css:dev && yarn run css:modules:dev`
133+
134+
### Pre-commit Hooks
135+
136+
The repo uses Husky with lint-staged. On commit:
137+
138+
- Prettier formats staged files automatically
139+
- Files are automatically added to the commit (via `git add` in lint-staged config)
140+
141+
## Dependencies
142+
143+
### Core Runtime Dependencies
144+
145+
- `react` and `react-dom` (^16.9.0 || ^17 || ^18 || ^19) - peer dependencies
146+
- `date-fns` (^4.1.0) - Date manipulation library
147+
- `@floating-ui/react` (^0.27.15) - Positioning engine
148+
- `clsx` (^2.1.1) - Conditional className utility
149+
150+
### Important Dev Tools
151+
152+
- **Build**: Rollup with Babel and TypeScript plugins
153+
- **Testing**: Jest, ts-jest, @testing-library/react, jest-axe
154+
- **Linting**: ESLint 9, TypeScript ESLint, Stylelint
155+
- **Formatting**: Prettier 3.4.2
156+
- **CSS**: Sass 1.93.2
157+
158+
## Code Conventions
159+
160+
- **Prettier handles all code formatting** - don't worry about tabs vs spaces
161+
- **ESLint enforces coding standards** - run `yarn lint` before committing
162+
- **TypeScript strict mode** - the codebase is fully typed
163+
- **Tests are required** - add Jest tests for new functionality
164+
- **Accessibility matters** - maintain ARIA attributes and keyboard navigation

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,31 @@ You can use `onSelect` event handler which fires each time some calendar date ha
6262

6363
See [here](https://github.com/Hacker0x01/react-datepicker/blob/main/docs/datepicker.md) for a full list of props that may be passed to the component. Examples are given on the [main website](https://hacker0x01.github.io/react-datepicker).
6464

65+
### Working with Examples
66+
67+
When using examples from the documentation site, note that they may reference utilities from external libraries. Common imports you might need:
68+
69+
**Date manipulation** (from `date-fns`):
70+
71+
```js
72+
import { getYear, getMonth, addDays, subDays, setHours, setMinutes } from "date-fns";
73+
```
74+
75+
**Utility functions**:
76+
77+
- For `range()` function used in custom headers: `import range from "lodash/range";`
78+
- Or implement your own: `const range = (start, end, step) => Array.from({ length: (end - start) / step }, (_, i) => start + i * step);`
79+
80+
**TypeScript types**:
81+
82+
```ts
83+
import type { ReactDatePickerCustomHeaderProps } from "react-datepicker";
84+
```
85+
86+
All examples on the documentation site include commented import statements at the top showing exactly what you need to import for your own project.
87+
88+
For a comprehensive guide on imports, see the [Common Imports Guide](https://github.com/Hacker0x01/react-datepicker/blob/main/docs/imports-guide.md).
89+
6590
### Time picker
6691

6792
You can also include a time picker by adding the showTimeSelect prop

docs-site/package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"dependencies": {
77
"copy-to-clipboard": "^3.3.3",
88
"date-fns": "^4.1.0",
9-
"esbuild-wasm": "^0.25.11",
9+
"esbuild-wasm": "^0.27.0",
1010
"highlight.js": "^11.11.1",
1111
"lodash": "^4.17.21",
1212
"prism-react-renderer": "^2.4.1",
@@ -24,21 +24,21 @@
2424
"type-check": "tsc --noEmit"
2525
},
2626
"devDependencies": {
27-
"@eslint/js": "^9.37.0",
28-
"@types/lodash": "^4.17.0",
29-
"@types/react": "^19.2.2",
30-
"@types/react-dom": "^19.2.2",
31-
"@typescript-eslint/eslint-plugin": "^8.46.1",
32-
"@typescript-eslint/parser": "^8.46.1",
33-
"@vitejs/plugin-react": "^5.0.3",
34-
"eslint": "^9.37.0",
27+
"@eslint/js": "^9.39.1",
28+
"@types/lodash": "^4.17.21",
29+
"@types/react": "^19.2.7",
30+
"@types/react-dom": "^19.2.3",
31+
"@typescript-eslint/eslint-plugin": "^8.48.0",
32+
"@typescript-eslint/parser": "^8.48.0",
33+
"@vitejs/plugin-react": "^5.1.1",
34+
"eslint": "^9.39.1",
3535
"eslint-plugin-react": "^7.37.5",
36-
"eslint-plugin-react-hooks": "^7.0.0",
36+
"eslint-plugin-react-hooks": "^7.0.1",
3737
"eslint-plugin-react-refresh": "^0.4.24",
38-
"globals": "^16.4.0",
39-
"sass": "^1.93.2",
38+
"globals": "^16.5.0",
39+
"sass": "^1.94.2",
4040
"typescript": "^5.9.3",
41-
"vite": "^7.1.10"
41+
"vite": "^7.2.4"
4242
},
4343
"packageManager": "yarn@4.9.2"
4444
}

docs-site/src/examples/ts/calendarContainer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const CustomCalendarContainer = () => {
2323
return (
2424
<DatePicker
2525
selected={selectedDate}
26-
onChange={(date: Date | null) => setSelectedDate(date)}
26+
onChange={setSelectedDate}
2727
calendarContainer={MyContainer}
2828
/>
2929
);

docs-site/src/examples/ts/calendarIcon.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ const CalendarIcon = () => {
22
const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());
33

44
return (
5-
<DatePicker
6-
showIcon
7-
selected={selectedDate}
8-
onChange={(date: Date | null) => setSelectedDate(date)}
9-
/>
5+
<DatePicker showIcon selected={selectedDate} onChange={setSelectedDate} />
106
);
117
};
128

docs-site/src/examples/ts/calendarIconExternal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const CalendarIconExternal = () => {
55
<DatePicker
66
showIcon
77
selected={selectedDate}
8-
onChange={(date: Date | null) => setSelectedDate(date)}
8+
onChange={setSelectedDate}
99
icon="fa fa-calendar"
1010
/>
1111
);

docs-site/src/examples/ts/calendarIconSvgIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const CalendarIconSvgIcon = () => {
55
<DatePicker
66
showIcon
77
selected={selectedDate}
8-
onChange={(date: Date | null) => setSelectedDate(date)}
8+
onChange={setSelectedDate}
99
icon={
1010
<svg
1111
xmlns="http://www.w3.org/2000/svg"

docs-site/src/examples/ts/calendarStartDay.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const CalendarStartDay = () => {
44
return (
55
<DatePicker
66
selected={selectedDate}
7-
onChange={(date: Date | null) => setSelectedDate(date)}
7+
onChange={setSelectedDate}
88
calendarStartDay={3}
99
/>
1010
);

docs-site/src/examples/ts/children.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ const Children = () => {
22
const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());
33

44
return (
5-
<DatePicker
6-
selected={selectedDate}
7-
onChange={(date: Date | null) => setSelectedDate(date)}
8-
>
5+
<DatePicker selected={selectedDate} onChange={setSelectedDate}>
96
<div style={{ color: "red" }}>Don't forget to check the weather!</div>
107
</DatePicker>
118
);

docs-site/src/examples/ts/clearInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const ClearInput = () => {
44
return (
55
<DatePicker
66
selected={selectedDate}
7-
onChange={(date: Date | null) => setSelectedDate(date)}
7+
onChange={setSelectedDate}
88
isClearable
99
placeholderText="I have been cleared!"
1010
/>

0 commit comments

Comments
 (0)