I convert your package on typescript, copy paste if you want or any want it, if you really make great package then use https://github.com/formium/tsdx thanks for awesome component !
const now = new Date()
const getTodayAtSpecificHour = (hour = 12) =>
set(now, { hours: hour, minutes: 0, seconds: 0, milliseconds: 0 })
const selectedStart = getTodayAtSpecificHour()
const selectedEnd = getTodayAtSpecificHour(14)
const startTime = getTodayAtSpecificHour(7)
const endTime = endOfToday()
const disabledIntervals = [
{ start: getTodayAtSpecificHour(16), end: getTodayAtSpecificHour(17) },
{ start: getTodayAtSpecificHour(7), end: getTodayAtSpecificHour(12) },
{ start: getTodayAtSpecificHour(20), end: getTodayAtSpecificHour(24) }
]
export class TimeRangePeriod extends React.Component<any,any> {
constructor(props:any){
super(props);
this.state = {
error: false,
selectedInterval: [selectedStart, selectedEnd],
}
}
errorHandler = ({ error }) => this.setState({ error })
onChangeCallback = selectedInterval => this.setState({ selectedInterval })
render() {
const { selectedInterval, error } = this.state
return (
<TimeRangePeriodTRS
sliderRailClassName="react_time_range__rail"
formatTick={ms => format(new Date(ms), 'HH:mm')}
step={1}
containerClassName="TimeRangePeriodTRS"
error={error}
ticksNumber={36}
selectedInterval={selectedInterval}
timelineInterval={[startTime, endTime]}
onUpdateCallback={this.errorHandler}
onChangeCallback={this.onChangeCallback}
disabledIntervals={disabledIntervals}
/>
)
}
}
class SliderRail extends Component<{ getRailProps: any, className_: string }, any> {
render() {
const { getRailProps, className_ } = this.props;
return <div className={className_}>
<div className='react_time_range__rail__outer' {...getRailProps()} />
<div className='react_time_range__rail__inner' />
</div>
}
}
interface HandlePeriodTRSProps {
error: any,
domain: { min: number, max: number },
handle: {
id: string,
value: number,
percent: number
}
getHandleProps: Function,
disabled: boolean,
}
// {
// error,
// domain: [min, max],
// handle: { id, value, percent = 0 },
// disabled,
// getHandleProps,
// }
// { disabled: false }
class HandlePeriodTRS extends Component<HandlePeriodTRSProps, any>{
render() {
const { domain, handle, getHandleProps, disabled, error } = this.props;
const { min, max } = domain;
const { id, value, percent } = handle;
const leftPosition = `${percent}%`
return (
<>
<div className='react_time_range__handle_wrapper' style={{ left: leftPosition }} {...getHandleProps(id)} />
<div
role='slider'
aria-valuemin={min}
aria-valuemax={max}
aria-valuenow={value}
className={`react_time_range__handle_container${disabled ? '__disabled' : ''}`}
style={{ left: leftPosition }}
>
<div className={`react_time_range__handle_marker${error ? '__error' : ''}`} />
</div>
</>
)
}
}
interface KeyboardHandlePeriodTRSProps {
error: any,
domain: { min: number, max: number },
handle: {
id: string,
value: number,
percent: number
}
getHandleProps: Function,
disabled: boolean,
}
// {
// error,
// domain: [min, max],
// handle: { id, value, percent = 0 },
// disabled,
// getHandleProps,
// }
// { disabled: false }
class KeyboardHandlePeriodTRS extends Component<KeyboardHandlePeriodTRSProps, any>{
render() {
const { domain, handle, getHandleProps, disabled, error } = this.props;
const { min, max } = domain;
const { id, value, percent } = handle;
return <button
role='slider'
aria-valuemin={min}
aria-valuemax={max}
aria-valuenow={value}
className='react_time_range__keyboard_handle'
style={{
left: `${percent}%`,
backgroundColor: disabled ? '#666' : '#ffc400'
}}
{...getHandleProps(id)}
/>
}
}
// Track.defaultProps = { disabled: false }
interface TrackPeriodTRSProps {
source: {
id: string,
value: number,
percent: number
},
target: {
id: string,
value: number,
percent: number
},
getTrackProps?: Function,
disabled: boolean,
error?: any
}
class TrackPeriodTRS extends Component<TrackPeriodTRSProps, any>{
getTrackConfig = ({ error, source, target, disabled }) => {
const basicStyle = {
left: `${source.percent}%`,
width: `calc(${target.percent - source.percent}% - 1px)`,
}
if (disabled) return basicStyle
const coloredTrackStyle = error
? {
backgroundColor: 'rgba(214,0,11,0.5)',
borderLeft: '1px solid rgba(214,0,11,0.5)',
borderRight: '1px solid rgba(214,0,11,0.5)',
}
: {
backgroundColor: 'rgba(98, 203, 102, 0.5)',
borderLeft: '1px solid #62CB66',
borderRight: '1px solid #62CB66',
}
return { ...basicStyle, ...coloredTrackStyle }
}
render() {
const { source, target, getTrackProps, disabled, error } = this.props;
return <div
className={`react_time_range__track${disabled ? '__disabled' : ''}`}
style={this.getTrackConfig({ error, source, target, disabled })}
{...getTrackProps!()}
/>
}
}
interface TickPeriodTRSProps {
tick: {
id: string,
value: number,
percent: number
}
count: number,
format: Function
}
class TickPeriodTRS extends Component<TickPeriodTRSProps, any>{
render() {
const { tick, count, format } = this.props;
const isFullHour = !getMinutes(tick.value)
const tickLabelStyle = {
marginLeft: `${-(100 / count) / 2}%`,
width: `${100 / count}%`,
left: `${tick.percent}%`,
}
return (
<>
<div
className={`react_time_range__tick_marker${isFullHour ? '__large' : ''}`}
style={{ left: `${tick.percent}%` }}
/>
{isFullHour && (
<div className='react_time_range__tick_label' style={tickLabelStyle}>
{format(tick.value)}
</div>
)}
</>
)
}
}
const getTimelineConfig = (timelineStart, timelineLength) => (date) => {
const percent = differenceInMilliseconds(date, timelineStart) / timelineLength * 100
const value = Number(format(date, 'T'))
return { percent, value }
}
const getFormattedBlockedIntervals = (blockedDates: any[] = [], [startTime, endTime]: any[]) => {
if (!blockedDates.length) return null
const timelineLength = differenceInMilliseconds(endTime, startTime)
const getConfig = getTimelineConfig(startTime, timelineLength)
const formattedBlockedDates = blockedDates.map((interval, index) => {
let { start, end } = interval
if (isBefore(start, startTime)) start = startTime
if (isAfter(end, endTime)) end = endTime
const source = getConfig(start)
const target = getConfig(end)
return { id: `blocked-track-${index}`, source, target }
})
return formattedBlockedDates
}
const getNowConfig = ([startTime, endTime]: any[]) => {
const timelineLength = differenceInMilliseconds(endTime, startTime)
const getConfig = getTimelineConfig(startTime, timelineLength)
const source = getConfig(new Date())
const target = getConfig(addMinutes(new Date(), 1))
return { id: 'now-track', source, target }
}
// selectedInterval: [
// set(new Date(), { minutes: 0, seconds: 0, milliseconds: 0 }),
// set(addHours(new Date(), 1), { minutes: 0, seconds: 0, milliseconds: 0 })
// ],
// timelineInterval: [startOfToday(), endOfToday()],
// formatTick: ms => format(new Date(ms), 'HH:mm'),
// disabledIntervals: [],
// step: 1000*60*30,
// ticksNumber: 48,
// error: false,
// mode: 3,
interface TimeRangePeriodTRSProps {
ticksNumber: number,
selectedInterval: any[],
timelineInterval: any[],
disabledIntervals: any[],
containerClassName: string,
sliderRailClassName: string,
step: number,
formatTick: Function,
onChangeCallback: any
onUpdateCallback: any
error: any
}
class TimeRangePeriodTRS extends React.Component<TimeRangePeriodTRSProps, any> {
get disabledIntervals() {
return getFormattedBlockedIntervals(this.props.disabledIntervals, this.props.timelineInterval)
}
get now() {
return getNowConfig(this.props.timelineInterval)
}
onChange = newTime => {
const formattedNewTime = newTime.map(t => new Date(t))
this.props.onChangeCallback(formattedNewTime)
}
checkIsSelectedIntervalNotValid = ([start, end], source, target) => {
const { value: startInterval } = source
const { value: endInterval } = target
if (startInterval > start && endInterval <= end || startInterval >= start && endInterval < end)
return true
if (start >= startInterval && end <= endInterval) return true
const isStartInBlockedInterval = start > startInterval && start < endInterval && end >= endInterval
const isEndInBlockedInterval = end < endInterval && end > startInterval && start <= startInterval
return isStartInBlockedInterval || isEndInBlockedInterval
}
onUpdate = newTime => {
const { onUpdateCallback } = this.props
const disabledIntervals = this.disabledIntervals
if (disabledIntervals?.length) {
const isValuesNotValid = disabledIntervals.some(({ source, target }) =>
this.checkIsSelectedIntervalNotValid(newTime, source, target))
onUpdateCallback({ error: isValuesNotValid })
return
}
onUpdateCallback({ error: false })
}
getDateTicks = () => {
const { timelineInterval, ticksNumber } = this.props
return scaleTime().domain(timelineInterval).ticks(ticksNumber).map(t => +t)
}
render() {
const {
sliderRailClassName,
timelineInterval,
selectedInterval,
containerClassName,
error,
step,
// showNow,
formatTick,
// mode,
} = this.props
const domain = timelineInterval.map(t => Number(t))
const disabledIntervals = this.disabledIntervals
return (
<div className={containerClassName || 'react_time_range__time_range_container'}>
<Slider
mode={1}
step={step}
domain={domain}
onUpdate={this.onUpdate}
onChange={this.onChange}
values={selectedInterval.map(t => +t)}
rootStyle={{ position: 'relative', width: '100%' }}
>
<Rail>
{({ getRailProps }) =>
<SliderRail className_={sliderRailClassName} getRailProps={getRailProps} />}
</Rail>
<Handles>
{({ handles, getHandleProps }) => (
<>
{handles.map(handle => (
<HandlePeriodTRS
disabled={false}
error={error}
key={handle.id}
handle={handle}
domain={{ min: domain[0], max: domain[1] }}
getHandleProps={getHandleProps}
/>
))}
</>
)}
</Handles>
<Tracks left={false} right={false}>
{({ tracks, getTrackProps }) => (
<>
{tracks?.map(({ id, source, target }) =>{
return <TrackPeriodTRS
error={error}
key={id}
source={source}
target={target}
getTrackProps={getTrackProps}
disabled={false}
/>
})}
</>
)}
</Tracks>
{disabledIntervals?.length && (
<Tracks left={false} right={false}>
{({ getTrackProps }) => (
<>
{disabledIntervals.map(({ id, source, target }) => {
return <TrackPeriodTRS
key={id}
source={{ ...source, id: id }}
target={{ ...target, id: id }}
getTrackProps={getTrackProps}
disabled={true}
/>}
)}
</>
)}
</Tracks>
)}
{//showNow &&
(
<Tracks left={false} right={false}>
{({ getTrackProps }) => (
<TrackPeriodTRS
key={this.now?.id}
source={{ ...this.now?.source, id: this.now?.id }}
target={{ ...this.now?.target, id: this.now?.id }}
getTrackProps={getTrackProps}
disabled={false}
/>
)}
</Tracks>
)}
<Ticks values={this.getDateTicks()}>
{({ ticks }) => (
<>
{ticks.map(tick => (
<TickPeriodTRS
key={tick.id}
tick={tick}
count={ticks.length}
format={formatTick}
/>
))}
</>
)}
</Ticks>
</Slider>
</div>
)
}
}