Readit News logoReadit News
Posted by u/tomosterlund 2 years ago
Show HN: I built an open source web calendar inspired by the Google calendarschedule-x.dev/demos/cale...
I love the looks and UX of the Google calendar. But I wanted to have a version I could use more freely in my own projects, still looking similar to the one from Google.
adrianmsmith · 2 years ago
I have a question about the design.

On the screenshot on the homepage https://schedule-x.dev/ the events are touching the left border of the box for the day, but there's a gap between the event and the right border of the box.

Google Calendar does that as well, and I found it quite ugly. I didn't know whether they did it deliberately (maybe I'm the only one who doesn't like it? or maybe there's some functionality associated with that that I haven't worked out?)

So I can't ask the developers of Google Calendar but I can ask you :) Is there a reason for laying out the calendar that way? Or is that just the convention now that Google Calendar does that?

I see you've obviously put thought into the design so I don't think it's an oversight on your part (although it may be on Google Calendar's part).

tomosterlund · 2 years ago
This is a good question, which baffled me a bit too when studying the Google calendar.

Took me a while to figure it out, but when I first built the month grid without subtracting a few pixels per event, it got a bit hard to optically make sense of where an event ended and a new one started. This especially since events are also allowed to stretch over multiple days.

Subtracting a few pixels from each event, helps me to quicker grasp that an event ends on a given date, and isn't to be considered "one" with an event in the next day.

pimlottc · 2 years ago
This makes sense, but there doesn't appear to be a gap on the calendar demo page [0], is that intentional?

0: https://schedule-x.dev/demos/calendar

JaumeGreen · 2 years ago
On Google Calendar clicking on an event you see the information of that event, clicking on a white space let's you create a new event at that time.

Having some white space that pertains to the day, but not to an event, let's you create a new event at the same time of an existing one without having to modify the start hour.

At least that's how I use it.

tomosterlund · 2 years ago
This makes perfect sense! I'll put this into the project roadmap, to leave a few pixels for clicking next to events on also in the week grid.
ashenke · 2 years ago
I think it's to easily see if the event spans only one day or multiple days. Multi-days events don't have the gap on the right so it shows a continuous line. You need the gap to have a difference for single-day events.
adrianmsmith · 2 years ago
That makes sense, but they could instead have put an equal gap on the left and right side, as opposed to having all the gap on the right side, making the item look like it's not centered within the box?
satvikpendem · 2 years ago
It's to allow the user to click on that time to make another event manually. If the user has an event at some time and the event goes all the way to the right, there is nowhere to click to add the new event. With the gap, the user can click there and have the add event modal show up.
freetonik · 2 years ago
There is no gap on the right side in the day or week view, only in the month view for some reason.
tomosterlund · 2 years ago
This is a good point. The Google calendar actually has a gap in the week view too. I just didn't understand why. Do you think it would look better if the gap exists in the week view as well?
tanishqkanc · 2 years ago
not the op, but one reason might be to visually distinguish between two events at the same time on adjacent days versus a 2-day event. Without the gap, events blend together. I don’t think the border provides enough contrast to rely on either.
nestes · 2 years ago
Very cool! Having written a couple of web calendars myself, I found that most of the hair-tearing logical complexity was due to recurring events. I didn't see any reference to recurrence when I skimmed the docs or the demo.

Have you decided how (or if) you're going to handle recurring events? Because that has huge implications for how otherwise "simple" changes to events behave, both from whatever backend you use as well as the UI.

tomosterlund · 2 years ago
Thanks! This is a great question.

I intend to implement event recurrence, but this is definitely one of those things which will require changes across most packages of the project code. The details of how it will be implemented is still open :) Will surely look to other open source calendars for inspiration. Do you have any tips on solutions/APIs you like?

Terretta · 2 years ago
> this is definitely one of those things which will require changes across most packages of the project code

While iterative development is the best way, there's something to be said for staring at a whiteboard full of the most common calendaring use cases, and being sure before starting the basics that the data model and code factoring "plan" support foreseeable uses, particularly "must have" ones.

This gets lost sight of in most Agile™ teams, maybe even more so than with solo-dev.

One way to do this in a reasonably light and OSS-friendly way is to pre-write the essential features README for the tool (event recurrence is an essential calendaring feature), then go through and mark them as TODO or blank checkboxes or etc., letting people contribute.

If you've architected the code structure a bit towards those things, the contributions / PRs are easier too, as the third party contributor isn't trying to refactor out from under everyone.

jrm4 · 2 years ago
"Remind" calendar has been a daily driver for me for the better part of a decade, you might find some inspiration there? I could see these two things working well together?

https://dianne.skoll.ca/projects/remind/

nestes · 2 years ago
Long answer incoming, recurring events plagued me for more time than I'd care to admit. I'm perfectly happy to clarify anything I've expressed poorly.

a) I had full control of the back-end, so my solution was ultimately fully custom -- I don't have any APIs to point to, sorry.

b) Look at the iCalendar specification if you haven't already if for no other reason than to see what kinds of crazy corner cases they were expecting to support.

c) Generally speaking, making recurring series of events ('recurrence sets' or 'rsets') is "easy", but altering rsets will make you want to kick a small animal. I'm just going to throw out a couple of examples to indicate how annoying this can be.

Assuming each event is in a rset. 1) I move an event on a week calendar from Tuesday to Thursday. Is there an event in the rset in the preceding week that should now be visible on my calendar? 2) I move an event in a series recurring on T/R from T->R. Is the set now R/Sa or is it still T/Th? 3) Do I permit changes to a single event while still allowing it to be a member of its recurrence set (iCalendar allows this!)? More to the point, do subsequent changes of that rset affect the event that you've now changed? 4) I move event from a T/R rset to a Friday. Does it even exist anymore? It's not on a Thursday or Tuesday after all (not joking!). And there are so many "gotchas" of this variety.

Granted, a lot of this complexity will be the job of the backend, for which you may or may not be responsible. But you still need to affirmatively decide if you're going to ask the user if they want to make a ("this"/"this and following"/"all") type of edit on certain actions and what an action maps to in terms of the API you're using. And if you ever want to implement your own backend, you're locked into that decision and you might hate yourself later.

As for my personal solution (again, I was writing the backend): Most calendar implementations of recurring events (if the iCalendar specification is followed) comprise a "base" event and a recurrence rule from which the other events may be calculated. I personally settled on a much more rudimentary solution where each event was initially calculated via a recurrence rule but was stored a first-class entity in my database. I also prohibited changing the recurrence rule of for a set of events that was already created. This made it so that the recurrence rule actually had no semantic meaning besides at creation. The individual events were linked in a "group" and things like drag and drop operations were done just by computing the time delta and shifting each individual event by that amount. I NEVER regretted making my calendar "dumber" and almost always regretted making it more clever.

A last word of warning -- if you do not know precisely the "specification" you want to achieve in terms of what actions are permitted on rsets, you are 100% going to rewrite it multiple times (ask me how I know :p).

pandatigox · 2 years ago
Woo I have a question! I have attempted something similar but my biggest issue was fixing the layout of overlapping events. Online solutions attempt to divide the column width by the number of overlapping events. But then another issue is the "tolerance" of overlapping events - Apple Calendar, for example, only begins overlapping events if they're > 5min of each other.

How were you able to overcome this challenge?

tomosterlund · 2 years ago
Ah, never even thought of having a kind of overlap tolerance. I might look into if this would make sense for Schedule-X too.

Solving overlapping events was definitely one of the things were a couple of days went into finding a nice and performant solution. My solution is here: https://github.com/schedule-x/schedule-x/blob/main/packages/...

Basically what I do is iterate over a list of events, sorted by start time, and for each: 1) figure out if it has an overlap with its next 2) if no, all good -> do nothing. If yes: 3) recursively check upcoming events until none is found with an overlap. 4) for each event in the recursion, set an integer property for how many previous overlapping events there were 5) Use this integer property for adjusting the position of the event with CSS

raybb · 2 years ago
Have you seen the Hey Calendar that was demo'd yesterday? https://www.youtube.com/watch?v=SztU4232u_o

I know you're following Google Calendar but I think Hey has some great ideas here :)

tomosterlund · 2 years ago
"Hey" there ^^ Thanks a lot, I neither knew Hey nor their new calendar. I'll be sure to check it out tonight.
IshKebab · 2 years ago
Why do you have months on separate pages that scroll left to right, instead of a continuous vertical scrolling view?

It's so weird, I don't know why almost all calendars have this bonkers design. We don't paginate web documents anymore. Why calendars?

Google actually got this right at one point with their Android app (the open source one), but then they broke it again with the newer closed source app!

tomosterlund · 2 years ago
Simple answer: I never thought of it.

But when I think about it, it absolutely makes sense. I'll definitely consider if this should be the default behavior of the month grid in v2.

Thanks a lot for your input!

uallo · 2 years ago
There is a similar but established library already: https://github.com/nhn/tui.calendar. Did you take a look at that one before starting your own? If yes, what were you missing?
tomosterlund · 2 years ago
I've looked into this one a bit too. The one main thing I'm missing there, is the ability to extend it with custom views. One thing Schedule-X does, which isn't documented yet, is to allow the implementer to only use the calendar header, and then implement the "view" part completely on their own. In that case Schedule-X just provides a control center type of core, with a bunch of utility APIs; basically a framework/DIY calendar.

Also I wanted to lean more towards the Material Design 3 specification.

tegiddrone · 2 years ago
This is significant. I have been pondering about how to build upon a gcal-style week view but with no sense of month navigation. Very similar to Continuous Calendar https://madebyevan.com/calendar
pimlottc · 2 years ago
Nice work, looks very clean.

Small suggestion for the date picker:

I appreciate that you can click on the month+year to navigate between years much more quickly than using the previous/next month arrows, but it's a bit non-obvious. There should be a hover effect when the cursor is over the month+year, e.g. a gray rounded rectangle, just like a gray circle appears when you're hovering over the arrows or a date. This would make it clearer that this is clickable.

tomosterlund · 2 years ago
Ah of course! Thanks a lot
safouen · 2 years ago
I think this looks exactly like https://fullcalendar.io/demos
tomosterlund · 2 years ago
I respect your opinion, but I strongly disagree :) Fullcalendar is a great calendar, but it is not material design.