DEV Community

Cover image for Calendario - A small calendar library for creating flexible calendars
Devi Prasad
Devi Prasad

Posted on

Calendario - A small calendar library for creating flexible calendars

Yet another Calendar app, gosh, Do we need more? Maybe, I'll leave that on you to decide. Let's go over the facts first.

Fullcalendar - This is a great library, comes with various components and is full-featured. But it renders the calendar and you have to "Theme". If you want a calendar up and running, in seconds it's probably the way to go but if you want to carefully design one with great CSS, it's a lot of documentation to read and change.

Same goes for Mobiscroll and http://ui.toast.com/tui-calendar

What if you treat a Calendar as native api in the browser, just another object supplying information with Internalization and parsing events, the rest is on the developer to build the UI. The developer now has flexibility to do whatever they want and come up with a beautiful calendar if not in seconds.

Let's check out the library first https://github.com/CalendarioFX/Calendario. It's in alpha phase, but is complete 90%.

  • Written in TypeScript
  • Each Calendario object is immutable
  • Supports Internationalization through Intl api
  • TimeZones with DST support
  • CJS and ESM modules
  • Very light weight, 75kb (probably including all the LICENSE, README.md ...)

Let me show you how easy it is to build one in svelte. Download the svelte template to get started in seconds

npx degit sveltejs/template svelte-app
cd svelte-app
npm install
npm install calendariofx-calendario
npm run dev

In App.svelte let's import Calendario and give it some events

<script context="module">
    import calendario from 'calendariofx-calendario'
</script>

<script>
    let cal = calendario({
        '01-01-1970' : [{content: 'New Year\'s', repeat: 'YEARLY', allDay: true, endDate: '12-31-2100'}],
        '12-25-1970' : [{content: 'Christmas Day', repeat: 'YEARLY', allDay: true, endDate: '12-31-2100'}], 
        '08-02-2019' : [
            {content: 'Yeah Monthly', repeat: 'MONTHLY', allDay: true, endDate: '09-02-2019'},
            {content : 'Graduation Exams', repeat: 'INTERVAL', allDay: true, endDate: '08-20-2019'}
        ],
        '01-07-2019' : [{content: 'Monthly And Yearly', repeat: 'MONTHLY', allDay: true, endDate: '02-07-2020'}],
        '08-01-2019' : [{content : 'MONDAY (WEEKLY)', repeat: 'MON', allDay: true, endDate: '08-30-2019'}]
    })
    $: rows = cal.rows
    $: body = cal.body
</script>

Then, add Month name, year, buttons to navigate to different dates

<h3 class="custom-month-year">
    <span id="custom-month" class="custom-month">{ cal.monthName }</span>
    <span id="custom-year" class="custom-year">{ cal.year }</span>
    <nav>
        <span id="custom-prev" class="custom-prev" on:click={() => cal = cal.previousMonth() } title="Go to previous month"></span>
        <span id="custom-next" class="custom-next" on:click={() => cal = cal.nextMonth() } title="Go to next month"></span>
        <span id="custom-current" class="custom-current" on:click={() => cal = cal.now() } title="Go to current date"></span>
    </nav>
</h3>

Then we generate the calendars and events

<div id="calendar" class="fc-calendar-container">
    <div class="fc-calendar" 
        class:fc-four-rows={rows === 4} 
        class:fc-five-rows={rows === 5} 
        class:fc-six-rows={rows === 6}>

        <div class="fc-head">
            {#each cal.head as weekday}
                <div>{weekday}</div>
            {/each}
        </div>

        <div class="fc-body">
            {#each Array.from(Array(rows).keys()) as ri}
                <div class="fc-row">
                    {#each body[ri] as dt}
                        <div 
                            class="{dt.dateClass} {dt.weekday}" 
                            class:fc-past={dt.past}
                            class:fc-future={dt.future}
                            class:fc-today={dt.today}
                            class:fc-content={dt.events.length > 0}>
                            <span class="fc-date" class:fc-emptydate={dt.events.length === 0}>{dt.date.day}</span>
                            <span class="fc-weekday">{dt.weekday}</span>

                            <div class="fc-calendar-events">
                                {#each dt.events as event}
                                    <div class="fc-calendar-event">
                                        {#if event.url}
                                            <a class="{event.category}" href="{event.url}">{event.content}</a>
                                        {:else}
                                            <span class="{event.category}">{event.content}</span>
                                        {/if}
                                    </div>
                                {/each}
                            </div>
                        </div>
                    {/each}
                </div>
            {/each}
        </div>

    </div>
</div>

I then added some css, and this is my result. It's that easy!

You can checkout the full example at https://github.com/CalendarioFX/example-calendario-svelte

P.S. I'm Calendario's developer. I'm posting this to get some constructive criticism, feedback, and see if it is helping the fellow developers out there and making their life easier. I'm also analyzing what potential this concept of Calendario holds, so don't hold back bash, appraise, like, dislike just don't ignore it 🎉. Have fun with Calendario

Top comments (1)

Collapse
 
joeattardi profile image
Joe Attardi

Nice work!