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.
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).
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.
Correct! In the week- and day views there is still no gap, only in the month view. The discussions here today though convinced me I should also allow for a gap in the week/day views (not sure yet if per default or configuration).
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.
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.
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?
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.
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?
> 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?
The gap is functional in Google Calendar.
If you are adding functionality to add overlapping events by clicking the gap,
I'd say yes
I am quoting /u/JaumeGreen
> 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.
I appreciate that you are taking the time and effort to gather feedback.
Ultimately, it is up to you whether you want to implement this feature.
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.
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.
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?
> 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.
"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?
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).
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.
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
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!
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?
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.
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
Cool! I like the idea. This would also be possible to implement as a custom view in Schedule-X. If you want I can bump this thread once I've documented how to build a custom view? Or you could also join the Discord chat where I'll try and post new feature releases.
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.
I have read many comments on this thread pointing towards other calendar libraries. I appreciate projects like this because I believe it's healthy for our industry to rethink "solved" issues. You put a cool spin on this topic and I hope that it taught you lots while building it.
Yes, as of now, the demo does not utilize the APIs for adding, editing or removing events. But this definitely helps me understand that it might make sense to do so! I'll put this in the project backlog; the APIs exist, the demo just doesn't use them.
I wonder, what would be cheapest way for backend to store calendar events and share between own devices? We are talking only about ten or so events per month, for one year ahead. Maybe connect to github repo and commit each change into some text or json file?
I text or email myself all the time, setup a feed to watch your tweets to yourself with the calendar events - it gets stored on twitter infra, accessible via browser, client, whatever, sharable, screenshotable and can be made private - and you just subscribe the calendar to that feed and replicate the tweet's payload into your offline, personal calendar from the feed.
Tweets are already timestamped - and for self and the following, BlueChecks can be used to ensure that event invites are only from validated people, or whitelist invites from only those you follow...
Others could invite you via tweets, and have "invites" show up in a bucket/panel in your calendar, and you can click to add them to the calendar and autotweet an RSVP/Reject via same.
This would be one way. Another way, which fullcalendar does, and which I intend to implement down the road, is Google calendar. You can actually use their calendar as a backend, and fetch the events from it to display elsewhere.
One feature I wish Google calendar had is "weekend" view; a condensed view of upcoming weekends, hiding weekdays. You can hide weekends, but in my personal account planning weekends is more important to me than planning weekdays.
I did something like this for a personal project that I use to track my time and it is a massive undertaking full of little gotchas. Kudos for getting this working so smoothly, this is really awesome!
And about the gotchas: Yea, I feel ya! This is my third stab at building a regular event calendar. At work I also build scheduling tools. Still, I discover these gotchas anew on a regular basis.
Most important learning so far, which also costed me the most before I knew it, was to always run my CI-pipelines in different time zones.
if it's like, an event you don't want to forget about, you can add a bunch of reminders for an event in google calendar. So, for someone's birthday you might want reminders every week a few weeks leading up to it, so you don't forget to get a gift.
Congrats! I tried before to build a calendar from scratch with no libraries at all and it was a real pain, especially figuring out how to make an event span through multiple days.
I find calendars to be interesting projects for some reason. I built one for a personal project recently using Phoenix LiveView and have really enjoyed it a lot.
Thank you so much! I really enjoy it as well. I build them privately since 2 years, and at work too. For some reason I'm also still having a great time doing so.
In this type of components, the worst is always the display of parallel events, i.e. events that have the same. I don't see such an example unfortunately.
You're right, the demo does not show it yet. Perhaps I should change that. However, in the demo you could drag one event onto another, and then you'll see how it looks when it's overlapping with another one.
Thanks for sharing. Will look into Kiko! Though my main focus for now is to build the best possible open source calendar, I'm also pondering on ideas for possible business models to accompany it later on.
Do you mean if any existing calendar can be used a backend? In that case, not out of the box. But I do intend to build a plugin for using Google Calendar as a backend.
For several years, I worked at a fairly large company as the CTO. All C-level executives (and some managers) had G-suite accounts, and all executive meetings or calls were to be on the shared calendar, allowing anyone to enter any call without prior request. Of course, as in all companies, people would leave the company (by personal choice or the company's decision) and new people would join. Often, people would forget and add random things to the calendar (like picking up a son from school, dentist appointments, etc.).
Our CFO left our company to work at a large investment fund. As usual, I would have removed her from our Gsuite, but the C-levels wanted to keep the email so we could still access her contacts and "impersonate" her in ongoing deals. She created a new password, sent it to us, and stopped using the account.
However, two years passed and some calendar events started to appear. They were from an unknown user but with the old CFO's email, involving random professional meetings with random people. We called her, and she said that she didn't have the account credentials or even the cellphone she previously used.
So we did what most companies do: We ignored it.
Fast forward a few months, our head of marketing was at a startup event with investors when a guy he didn't know introduced himself. He was from another company in the same market as ours and was concerned that he had started negotiating to buy an IP from us but we stopped responding. We had never sold any IP, so my coworker asked with whom he had been talking. Of course, it was with the impersonator. When we checked the email, there weren’t any recent emails sent or received. Weird.
A few days later, we called him to the office, offered him some coffee, and he showed us the conversation. It contained a lot of internal details, a full 9-page PDF with specifications and valuation, pricing, and payment details, with the payment destination being our company's account!
It didn't make any sense. It wasn’t just an error. It wasn’t just a scam. Why would the person direct the money to us?
We tried to investigate, but with many things on our plate, the mystery was again sidelined.
A few weeks later, we had a large sales event inland. By local legislation, all events of a certain size must have a paramedic present. We hired a recent college graduate for this role. She reported some sexual harassment from the construction workers we had hired to build the stage and event structure. As we were investigating this and talking with the authorities, we noticed some calendar events between the medic and the impersonator. Our CEO joined one of these meetings, with me beside him at his desk. Neither party turned on their camera. The impersonator's voice, calm and professional, stated that since our CEO had joined the meeting, he could leave the rest to him and then exited the meeting. We talked to the medic; the impersonator had offered her the equivalent of 20k dollars to not make any public claims about the harassment. We had never discussed any of this during our board meetings.
We started to panic. What else could the impersonator have done? How long had he been posing as us?
We contacted a security company to investigate. They deployed four agents who began to analyze data, track everyone, call people for interrogation, and so on.
In a couple of days, they identified a 23-year-old guy from accounting as the impersonator. We called him into a meeting with all directors. He was visibly nervous but explained his story. A few months before joining the company, he had bought a used cellphone online, on an eBay-like website. This cellphone had belonged to the former CFO, who hadn't wiped it before selling. He began reading the saved emails and documents and got excited about the company's strategy, then applied and got the job. He even shared this story with his recruiter (as in "look at God's will"), but nobody reported it to us, as it seemed irrelevant.
So, he occasionally received emails and acted on them, with the best intentions. He actually had the authority to send and receive money, since he worked in the accounting department. He said that initially, he would ask for advice on what to do, but never received any good suggestions, so he stopped asking. From the first CFO to him, we had two other CFOs. Apparently, during this time, we also had a shadow one. He solved many issues, from workers asking for money to renegotiating payment deadlines. He was actually very good at it.
He showed us all the emails and deals he made, and everything was, in fact, recorded in our system, with invoices sent and everything.
The directors debated whether what he had done was good, bad, illegal, and whether he should receive a reward
, etc.
We voted and then promoted him to a position akin to vice-CFO and gave him a substantial bonus, considering all the legal expenses he saved us.
I left the company a few months after that, but I heard he went on to work at a 'cool' startup, I think Notion or Spotify, something like that.
He was a very intelligent and humble guy, and we met him just because of a series of coincidences with a calendar app.
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).