Giter VIP home page Giter VIP logo

react-schedule-selector's Introduction

React Schedule Selector

npm version Build Status Coverage Status

A mobile-friendly when2meet-style grid-based schedule selector built with styled components and date-fns.

Live example

image

Getting Started

yarn add react-schedule-selector styled-components
import ScheduleSelector from 'react-schedule-selector'

class App extends React.Component {
  state = { schedule = [] }

  handleChange = newSchedule => {
    this.setState({ schedule: newSchedule })
  }

  render() {
    return (
      <ScheduleSelector
        selection={this.state.schedule}
        numDays={5}
        minTime={8}
        maxTime={22}
        hourlyChunks={2}
        onChange={this.handleChange}
      />
    )
  }
}

<ScheduleSelector />

ScheduleSelector is a controlled component that can be used easily with the default settings. Just provide a controlled value for selection and include an onChange handler and you're good to go. Further customization can be done using the props outlined below.

To customize the UI, you can either:

  1. Specify values for the color, margin, format, etc. props
  2. Use the renderDateCell render prop to handle rendering yourself.

Props

selection

type: Array<Date>

description: List of dates that should be filled in on the grid (reflect the start time of each cell).

required: yes

selectionScheme

type: 'square' | 'linear'

description: The behavior for selection when dragging. square selects a square with the start and end cells at opposite corners. linear selects all the cells that are chronologically between the start and end cells.

required: no

default value: 'square'

onChange

type: (Array<Date>) => void

description: Called when selected availability is changed. The new list of selected dates is passed in as the first parameter.

required: yes

startDate

type: Date

description: The date on which the grid should start (time portion is ignored, specify start time via minTime)

required: no

default value: today

numDays

type: number

description: The number of days to show, starting from today

required: no

default value: 7

hourlyChunks

type: number

description: How many chunks to divide each hour into (e.g. 2 divides the hour into half-hour steps, 4 into 15-minute steps)

required: no

default value: 1

minTime

type: number

description: The minimum hour to show (0-23)

required: no

default value: 9

maxTime

type: number

description: The maximum hour to show (0-23)

required: no

default value: 23

dateFormat

type: string

description: The date format to be used for the column headers

required: no

default value: 'M/D'

timeFormat

type: string

description: The time format to be used for the row labels

required: no

default value: 'ha'

margin (removed in v3.0, use columnGap and rowGap instead)

type: number

description: The margin between grid cells (in pixels)

required: no

default value: 3

columnGap

type: string

description: The gap between grid columns, specified using any valid CSS units

required: no

default value: '4 px'

rowGap

type: string

description: The gap between grid rows, specified using any valid CSS units

required: no

default value: '4 px'

unselectedColor

type: string

description: The color of an unselected cell

required: no

default value: 'rgba(89, 154, 242, 1)'

selectedColor

type: string

description: The color of an unselected cell

required: no

default value: 'rgba(162, 198, 248, 1)'

hoveredColor

type: string

description: The color of a hovered cell

required: no

default value: '#dbedff'

renderDateCell

type: (datetime: Date, selected: boolean, refSetter: (dateCell: HTMLElement | null) => void) => React.Node

description: A render prop function that accepts the time this cell is representing and whether the cell is selected or not and should return a React element. It is your responsibility to apply the refSetter as a ref to the component you render -- neglecting to do so will cause the component to not work properly for touch devices. If you choose to use this custom render function, the color props above have no effect.

required: no

renderTimeLabel

type: (time: Date) => React.Node

description: A render prop function that accepts the time a given row is representing and should return a React element.

required: no

renderDateLabel

type: (date: Date) => React.Node

description: A render prop function that accepts the time a given row is representing and should return a React element.

required: no

react-schedule-selector's People

Contributors

bibekg avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-schedule-selector's Issues

Small mode

can we have a small mode? small mode is very important to me because the scheduler is way too long on my chrome extension, and I can't change the height of the cells. its not nice for the user to have to scroll to fill out all the times

unfortunately even if i use renderDateCell to make each cell 15px height, it won't change the height of the cells. the cells seem to have a fix height of 25px.

image

Square Selection Scheme Issue

Hi,

I found a bug when you using square selection scheme over the 3rd of Oct, the time selected is not a square any more.
image
Do you kno whow to fix it?

Possible to add multiple "selection" levels?

Hi there! If we want to allow users to make multiple types of selections (e.g. "preferred" times and "available" times, designated by different colors) on the calendar, how would you suggest doing that? Thanks!

Disable dragging selection

Is it possible to disable dragging selection? Neiter 'square' nor 'linear' selectionScheme fits my needs, I would like to only have click/touch to select.

Possible to display a given set of dates/times on the schedule without user selection?

Hello! I currently save users' availabilities in Firebase and want to allow them to update them later. Is there a way i can load the existing schedule onto the rendered schedule selector, so that times/dates they selected previously will appear as dark blue and they can add/remove times as they wish? I have successfully read the data from firebase and saved it to this.state.schedule, but am struggling to get it to display on the selector. Thanks!

can't resolve web.dom-collections.iterator on installation

Compiling doesn't succeed, error thrown

Failed to compile.

./node_modules/react-schedule-selector/dist/lib/ScheduleSelector.js
Module not found: Can't resolve 'core-js/modules/web.dom-collections.iterator' in '/frontend/node_modules/react-schedule-selector/dist/lib'

Updating the component when startDate changes

Hi I am having an issue about changing startDate in order to essentially cycle through weeks at a time. I have a button set up to change the startDate state and tried to forceUpdate in order to refresh the scheduling table but the dates do not change. When I console.log(this.state) the startDate was increased by a week.

Possible feature

Is it possible to make an horizontal drag and drop.

In general, let's say that being able to drag the event you dropped on the calendar horizontally on a specific time range, you can create a repeated event.

Here is a use case where you can understand the usage. This week, every day at the same time range 10:00 - 11:00, I have to go to the gym. So, you drop an event on Monday at 10 - 11, then you drag it horizontally till Friday only to the specific time range and as a callback you'll have all the dates you dragged the event.

Programmatically disable cells.

As discussed in this thread: #23

Please can I request an enhancement to prevent the user from selecting certain cells. For any given day I know which cells are available to book and which have already been booked. I therefore need to be able to prevent the user from selecting the slots which have already been chosen by someone else.

The cells which has a "disabled" state should be styled differently to make it clear that they are not selectable and obviously would not respond to click events.

Multi-language

Is there any way to change the language that is displayed from dateFormat? I've tried using moment.js, but that doesn't seem to work.

Thanks in advance!

Possible Bug with Duplicated Dates on Drag Selection

Hi,

I believe there's an issue with the dates being duplicated in the date array passed into "onChange".
This can be reproduced by:

  1. Select a cell (e.g. Cell A).
  2. Click an unselected cell (e.g. Cell B) and simultaneously drag it onto the selected Cell A.

Array will contain ["Cell A", "Cell B", "Cell A"].

Problem reproducible in sandbox:
https://codesandbox.io/s/objective-pateu-y8lr0?file=/src/App.js

Currently using the following as a temporary workaround:

  const [schedule, setSchedule] = React.useState([])

  // ...

  const handleChange = (newSchedule) => {
    // setSchedule(schedule) // has duplicates - below will filter date to be unique.
    setSchedule([...new Set(schedule.map(date => +date))].map(timestamp => new Date(timestamp)));
  }

Thanks :) - Really appreciate your work!

Trouble getting schedule to work on mobile?

I'm having trouble getting the component to work on mobile, namely the ability to touch and drag over the tiles. I believe it has something to do with the touchstart Event Listener. I'm wondering if anyone else has struggled with this before and if there is a quick fix for it.

No Typing

Looks like the project is written in TypeScript. However, I am not able to get the typing from my editor.

Could not find a declaration file for module 'react-schedule-selector'. './node_modules/react-schedule-selector/dist/lib/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/react-schedule-selector` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-schedule-selector';`ts(7016)

Select Time in minutes

Hai @bibekg , thank you for the best schedule selector i know..
i have request about time hours selector, can the hour format be added minutes?

for example:
Screen Shot 2020-01-10 at 10 38 32 AM

Blocked dates

Add the option to block dates and times (like, if you aren't available at the selected time)

[Docs] I found typo in its documentation in npm

It says :

numDays
type: number

description: The number of days to show, startin from today

required: no

default value: 7

I believe 'startin' should be starting in description.
If you allow me, I am happy to correct that and do PR to here.
However, let me know where is the source code of your docs in npm so that I can fix the typo.
thanks !!

TypeError: this.props.renderDateCell is not a function

Hi!
Is there anyway to add selected days ? (i want to pull dates from the db and mark them as selected)
here is what i am trying :

        <ScheduleSelector
        selectionScheme="linear"
          startDate={startDate}
          selection={schedule}
          className={"overflow-y-auto h-96"}
          numDays={7}
          unselectedColor={'#EDF2F3'}
          selectedColor={'#5289B5'}
          dateFormat="dddd"
          hoveredColor={'#AFD8F2'}
          minTime={0}
          maxTime={24}
          onChange={handleClick}
          renderDateCell={scheduledates}
        />
      </div>

(scheduledates are the dates pulled from the db)

Need a small version of the schedule selector to be able to choose full 24 hours

So I like this library but I'm having trouble using it. As you can see below, the column headers are specific dates: 6/10,6/11, 6/12, ... etc.

image

However for my use case I want the user to specify hours within a generic week. So instead of specific dates, I want the column headers to be Monday, Tuesday, ... Friday.

Does this app currently support this use case? If not I can create a PR for it, just wanted to check to see if I'm possibly missing something.

Use days of week without dates

Is there any way to use days of the week Monday, Tuesday, etc. without relating directly to the date?

Get availability for all Mondays for example.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.