Skip to content

Commit

Permalink
Merge pull request #18 from jason89521/react-date-time-picker-component
Browse files Browse the repository at this point in the history
  • Loading branch information
jason89521 authored Oct 10, 2022
2 parents 9dd23c2 + 35331ea commit e787bee
Show file tree
Hide file tree
Showing 48 changed files with 1,053 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# React Components Monorepo

- [react-typist-component](./packages/react-typist-component/README.md)
- [react-use-calendar-component](./packages//react-use-calendar-component/README.md)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"test": "pnpm -r --filter ./packages/* run test",
"dev:website": "pnpm build:packages && pnpm --filter ./website dev",
"build:website": "pnpm build:packages && pnpm --filter ./website run build",
"build:packages": "pnpm -r --filter ./packages/* run build:package",
"build:packages": "pnpm -r --filter './packages/*' run build:package",
"prepublishOnly": "pnpm build:lib"
},
"devDependencies": {
Expand Down
24 changes: 24 additions & 0 deletions packages/react-use-calendar-component/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
22 changes: 22 additions & 0 deletions packages/react-use-calendar-component/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# React Use Calendar Component

This project is aimed to provide an easy-to-use API interface for those people who want to build their own calendar component with custom style.

## Caveat

This package is still under development, the API interface may change frequently.

## Todo

- [x] Generate 42 date cell information
- [x] Change displayed year/month when selected date is change
- [x] Select multiple dates
- [ ] Select with range
- [ ] Support disabled date
- [ ] Support displaying two calendar
- [ ] Support week, month, year selection

## Examples

- [Single Mode](./src/app/components/Examples/Single.tsx)
- [Multiple Mode](./src/app/components/Examples/Multiple.tsx)
15 changes: 15 additions & 0 deletions packages/react-use-calendar-component/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="./src/app/main.tsx"></script>
</body>

</html>
1 change: 1 addition & 0 deletions packages/react-use-calendar-component/jest-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom/extend-expect';
6 changes: 6 additions & 0 deletions packages/react-use-calendar-component/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
export default {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],
};
48 changes: 48 additions & 0 deletions packages/react-use-calendar-component/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "react-use-calendar-component",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"test": "jest",
"test:watch": "jest --watch",
"build:website": "tsc && vite build",
"build:types": "tsc --project tsconfig.lib.json",
"build:package": "vite build --mode lib && pnpm build:types",
"prepublishOnly": "pnpm build:package",
"preview": "vite preview"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/jason89521/react-components-monorepo"
},
"files": [
"dist"
],
"types": "./dist/types/index.d.ts",
"main": "./dist/react-use-calendar-component.umd.cjs",
"module": "./dist/react-use-calendar-component.js",
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "14.4.3",
"@types/jest": "^29.0.3",
"@types/react": "^18.0.20",
"@types/react-dom": "^18.0.6",
"@types/testing-library__jest-dom": "5.14.5",
"@vitejs/plugin-react": "^2.1.0",
"autoprefixer": "^10.4.11",
"jest": "^29.0.3",
"postcss": "^8.4.16",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.1.8",
"ts-jest": "^29.0.1",
"typescript": "^4.8.3",
"vite": "^3.1.3"
},
"peerDependencies": {
"react": ">=18.0.0"
}
}
6 changes: 6 additions & 0 deletions packages/react-use-calendar-component/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
41 changes: 41 additions & 0 deletions packages/react-use-calendar-component/src/app/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
26 changes: 26 additions & 0 deletions packages/react-use-calendar-component/src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useState } from 'react';

import { Single, Multiple } from './components/Examples';

type ExampleType = 'single' | 'multiple';

const exampleMap = {
single: <Single />,
multiple: <Multiple />,
};

export default function App() {
const [value, setValue] = useState<ExampleType>('single');

return (
<div className='flex flex-col items-center gap-10 pt-10 min-h-screen bg-slate-500'>
<select
value={value}
onChange={e => setValue(e.currentTarget.value as ExampleType)}>
<option value='single'>single</option>
<option value='multiple'>multiple</option>
</select>
{exampleMap[value]}
</div>
);
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import useCalendarComponent from '../../lib';
import CalendarBody from './CalendarBody';
import CalendarHeader from './CalendarHeader';

interface Props {
calendarControl: ReturnType<typeof useCalendarComponent>;
}

export default function Calendar({ calendarControl }: Props) {
const {
displayedYear,
displayedMonth,
changeDisplayedMonth,
changeDisplayedYear,
getDateCellInfos,
} = calendarControl;

return (
<div className='bg-white shadow-2xl rounded-3xl p-8 w-[500px]'>
<CalendarHeader
onYearClick={changeDisplayedYear}
onMonthClick={changeDisplayedMonth}
year={displayedYear}
month={displayedMonth}
/>
<CalendarBody dateCellInfos={getDateCellInfos()} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { DateCellInfo } from '../../lib/types';
import { getWeekDayList } from '../../lib/utils/locale';
import CalendarCell from './CalendarCell';

const weekDayList = getWeekDayList();

interface Props {
dateCellInfos: DateCellInfo[];
}

export default function CalendarBody({ dateCellInfos }: Props) {
return (
<div className='mt-5'>
<div className='grid grid-cols-7 mb-4'>
{weekDayList.map((d, i) => (
<div key={i} className='flex items-center justify-center'>
{d}
</div>
))}
</div>
<div className='grid grid-cols-7 gap-y-4'>
{dateCellInfos.map(({ key, ...info }) => (
<CalendarCell key={key} {...info} />
))}
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { DateCellInfo } from '../../lib/types';

export default function CalendarCell({
monthStatus,
isSelected,
isToday,
dayOfMonth,
selectThisDate,
}: DateCellInfo) {
const title = isToday ? 'today' : undefined;
let className = 'rounded-full';
if (monthStatus !== 'current') className = `${className} text-slate-300`;
if (isSelected) className = `${className} bg-green-200 selected`;
if (isToday && !isSelected) className = `${className} bg-amber-200`;
if (!isToday && !isSelected) className = `${className} hover:bg-stone-100`;

return (
<button
className={`${className} ${monthStatus}`}
onClick={() => selectThisDate()}
type='button'
title={title}>
<div className='flex items-center justify-center'>
<span>{dayOfMonth}</span>
</div>
</button>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { getMonthList } from '../../lib/utils/locale';
import LeftArrow from './LeftArrow';
import RightArrow from './RightArrow';

const monthList = getMonthList();

interface Props {
year: number;
month: number;
onYearClick: (value: number) => void;
onMonthClick: (value: number) => void;
}

export default function CalendarHeader({
year,
month,
onYearClick,
onMonthClick,
}: Props) {
return (
<div className='flex justify-between items-center'>
<LeftArrow
arrowAmount={2}
onClick={() => onYearClick(-1)}
ariaLabel='sub-year'
/>
<LeftArrow onClick={() => onMonthClick(-1)} ariaLabel='sub-month' />
<div className='flex flex-col justify-center items-center'>
<span className='text-lg'>{year}</span>
<span className='text-sm'>{monthList[month]}</span>
</div>
<RightArrow onClick={() => onMonthClick(1)} ariaLabel='add-month' />
<RightArrow
arrowAmount={2}
onClick={() => onYearClick(1)}
ariaLabel='add-year'
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useState } from 'react';

import useCalendarComponent from '../../../lib';
import Calendar from '../Calendar';
import SelectedDates from '../SelectedDates';

export function Multiple() {
const [value, setValue] = useState([new Date()]);
console.log(value);
const calendarControl = useCalendarComponent({
selectType: 'multiple',
value,
onChange: setValue,
});
const { selectedDates } = calendarControl;

return (
<div>
<Calendar calendarControl={calendarControl} />
<SelectedDates selectedDates={selectedDates} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useState } from 'react';

import useCalendarComponent from '../../../lib';
import Calendar from '../Calendar';
import SelectedDates from '../SelectedDates';

export function Single() {
const [value, setValue] = useState(new Date());
const calendarControl = useCalendarComponent({ value, onChange: setValue });
const { selectedDates } = calendarControl;

return (
<div>
<Calendar calendarControl={calendarControl} />
<SelectedDates selectedDates={selectedDates} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './Single';
export * from './Multiple';
Loading

1 comment on commit e787bee

@vercel
Copy link

@vercel vercel bot commented on e787bee Oct 10, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.