UNPKG

time-period-selector-react

Version:

TimePeriodSelector - Drag to Select Time Period of the Day

210 lines (209 loc) 9.33 kB
import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__ from "react/jsx-runtime"; import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"; import "./index.css"; const weekDays = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]; const weekDayDisplayZh = { Mon: '周一', Tue: '周二', Wed: '周三', Thu: '周四', Fri: '周五', Sat: '周六', Sun: '周日' }; const weekDayDisplayEn = { Mon: 'Monday', Tue: 'Tuesday', Wed: 'Wednesday', Thu: 'Thursday', Fri: 'Friday', Sat: 'Saturday', Sun: 'Sunday' }; function TimePeriodSelector(props) { const { style, title, language = 'en', showTime, value, onChange } = props; const weekDayDisplay = 'en' === language ? weekDayDisplayEn : weekDayDisplayZh; const [selectedSlots, setSelectedSlots] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(value || { Mon: [], Tue: [], Wed: [], Thu: [], Fri: [], Sat: [], Sun: [] }); const [isSelecting, setIsSelecting] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(false); const [selectionStart, setSelectionStart] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(null); const handleClick = (day, hour)=>{ if (isSelecting) return; const newSelectedSlots = { ...selectedSlots }; const currentHours = selectedSlots[day]; if (currentHours.includes(hour)) newSelectedSlots[day] = currentHours.filter((h)=>h !== hour); else newSelectedSlots[day] = [ ...currentHours, hour ].sort((a, b)=>a - b); setSelectedSlots(newSelectedSlots); onChange?.(newSelectedSlots); }; const handleMouseDown = (day, hour)=>{ setIsSelecting(true); setSelectionStart({ day, hour }); }; const handleMouseEnter = (day, hour)=>{ if (!isSelecting || !selectionStart || selectionStart.day !== day) return; const minHour = Math.min(selectionStart.hour, hour); const maxHour = Math.max(selectionStart.hour, hour); const hours = Array.from({ length: maxHour - minHour + 1 }, (_, i)=>minHour + i); const newSelectedSlots = { ...selectedSlots, [day]: Array.from(new Set([ ...selectedSlots[day], ...hours ])).sort((a, b)=>a - b) }; setSelectedSlots(newSelectedSlots); onChange?.(newSelectedSlots); }; const handleMouseUp = ()=>{ setIsSelecting(false); setSelectionStart(null); }; const formatSelectedTimes = ()=>Object.entries(selectedSlots).filter(([, hours])=>hours.length > 0).map(([day, hours])=>{ const timeRanges = []; let start = hours[0]; let prev = hours[0]; for(let i = 1; i <= hours.length; i++)if (i === hours.length || hours[i] !== prev + 1) { timeRanges.push([ start, prev + 1 ]); if (i < hours.length) { start = hours[i]; prev = hours[i]; } } else prev = hours[i]; const formattedHours = timeRanges.map(([start, end])=>`${String(start).padStart(2, '0')}:00~${String(end).padStart(2, '0')}:00`).join('、'); return `${weekDayDisplay[day]} ${formattedHours}`; }).join('\n'); const handleClear = ()=>{ const emptySlots = { Mon: [], Tue: [], Wed: [], Thu: [], Fri: [], Sat: [], Sun: [] }; setSelectedSlots(emptySlots); onChange?.(emptySlots); }; return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)("div", { className: "time-period-selector", style: style, children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)("div", { className: "time-period-header", children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("h3", { className: "time-period-title", children: title }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("a", { onClick: handleClear, className: "clear-button", children: 'zh' === language ? '清空' : 'Clear' }) ] }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)("table", { className: "time-period-table", children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)("thead", { className: "time-period-thead", children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)("tr", { children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("th", { rowSpan: 2, className: "time-period-th", children: 'zh' === language ? '日期/时间' : 'Date/Time' }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("th", { colSpan: 12, className: "time-period-th", children: "00:00~12:00" }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("th", { colSpan: 12, className: "time-period-th", children: "12:00~24:00" }) ] }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("tr", { children: Array.from({ length: 24 }).map((_, i)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("th", { className: "time-period-hour-th", children: i }, i)) }) ] }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("tbody", { children: weekDays.map((day)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)("tr", { children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("td", { className: "time-period-day", children: weekDayDisplay[day] }), Array.from({ length: 24 }).map((_, hourIndex)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("td", { className: `time-period-hour ${selectedSlots[day].includes(hourIndex) ? 'selected' : ''}`, onMouseDown: ()=>handleMouseDown(day, hourIndex), onMouseEnter: ()=>handleMouseEnter(day, hourIndex), onMouseUp: handleMouseUp, onClick: ()=>handleClick(day, hourIndex) }, hourIndex)) ] }, day)) }) ] }), showTime && /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsxs)(__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.Fragment, { children: [ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("div", { className: "time-period-divider" }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("div", { className: "time-period-selected-times", children: 'zh' === language ? '已选择时间:' : 'Selected Times:' }), /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)("pre", { className: "time-period-selected-times-text", children: formatSelectedTimes() }) ] }) ] }); } export { TimePeriodSelector };