vkurko / calendar

Full-sized drag & drop JavaScript event calendar with resource & timeline views

Home Page:https://vkurko.github.io/calendar/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Utilities/extras module

amoscicki opened this issue · comments

Hi,

I am very impressed by the project and I would like to contribute by creating utilities module. I would essentially see this as a module that is not part of the core functionality but it would provide some additional useful things that may help popularize the project. The demo presenting the example setup utilizing and showcasing every available feature of the calendar could also be included in a form of exported object, so people could simply import it, and then cherry-pick options from that to build on top of those.
Whilst documentation is necessity, often the case for me is that I find it much easier to understand some concepts after seeing some examples, and I think having some easy to customize "Out Of the Box" implementations and additional utilities would potentially help people when they use this inside their projects.

The idea is to improve developer experience when using the event-calendar.

My first thoughts on this is to contain the following:

  • TimeGrid slot duration controller component (providing convenient interface to give zoom in zoom out using the slotDuration option, it could take props such as object reference to the calendar component, refs to elements controlling zoom in/zoom out, prop with definition of available zoom levels (collection of Duration objects)). This would be somewhat similar in concept of a paginator Components I have stumbled upon.
  • Example custom theme overlay showcasing how can you neatly prepare custom theme for the calendar with some demonstration (this would utilize existing theme option)

If this is seen as a valid and useful idea, happy to build on it.

Yes, I agree that the documentation lacks examples, so I'd be happy if you can make some useful demo code that can be used as a base.

I have created a repo to show what I have so far.

link

By the way, it is possible to override theme for each view separately:

views: {
  dayGridMonth: {
    theme() {
      // return theme
    }
  }
  timeGridWeek: {
    theme() {
       // return theme
    }
  }
}

Ok, I thought that if I provide separate options object to specific view the theme prop would still trigger processing each callback for rest of the enabled views under the hood. Is that not the case?

Anyway in current form that should still work with the plugin I made (I'll test after work)

My idea is to provide ability to define single and easy to digest template config file with ability to build a theme configurator at later point, so it's easier and more convenient :).

 @amoscicki  i agree 100% in what you said, that would be really helpful if you’re willing to share your outcomes too. The calendar is a nice representation of the data, but generating the data should happen outside that element.

Originally posted by @steveb85 in #28 (comment)

I prepared a simple example implementation for how you could potentially style your event to indicate it is recurring.
I wouldn't recommend this as a production code but it would be a good starting point to grasp the idea and build on top of it.
image

Code:

  • example event ( extendedProps used to keep the information, this of course is something that is completely adjustable )
  let exampleEvent = {
    start: new Date("2023-11-14 08:00:00"),
    end: new Date("2023-11-14 10:00:00"),
    resourceId: 1,
    color: "steelblue",
    extendedProps: {
      icon: "fas fa-sync fa-sm top-3 right-2 absolute",
      titleExt: " every 2 weeks",
      descriptionClasses: "mt-2 font-bold truncate",
      description: " 1:1 with Bob",
      descriptionExtClasses:
        "font-normal mt-2 text-xs w-full max-h-[3.6rem] line-clamp-3",
      descriptionExt:
        " Project bi-weekly catchup meeting. Checking current progress, managing risks and issues, planning next steps.",
    },
  };
  • I used eventDidMount method. Just because it allows me to access DOM document object at that point of runtime
let options = {
    eventDidMount: (info) => {
      generateEvenhtHtml(info);
    },
}
  • and the example function:
  const generateEvenhtHtml = (info) => {

    // this is where I am escaping mounting on the pointer event 
    // (the one that is used to drag, resize, select area etc.)
    // if needed you could for example check some event props,
    // to find out if mount was triggered by event you want to template
    if (info.event.id === "{pointer}") return; 

    const result = { domNodes: [] };
    
    // extract the extended props from the event
    const {
      icon,
      titleExt,
      descriptionClasses,
      description,
      descriptionExtClasses,
      descriptionExt,
    } = info.event.extendedProps;

    const iconElement = document.createElement("i");
    const descriptionElement = document.createElement("div");
    const descriptionExtElement = document.createElement("div");

    icon.split(" ").forEach((item) => {
      iconElement.classList.add(item);
    });
    descriptionClasses.split(" ").forEach((item) => {
      descriptionElement.classList.add(item);
    });
    descriptionExtClasses.split(" ").forEach((item) => {
      descriptionExtElement.classList.add(item);
    });

    iconElement.title = titleExt;
    descriptionExtElement.title = descriptionExt;

    descriptionExtElement.append(document.createTextNode(descriptionExt));
    descriptionElement.append(document.createTextNode(description));
    
    result.domNodes.push(descriptionElement);
    result.domNodes.push(descriptionExtElement);

    info.event.title = result;

    ec.updateEvent(info.event);
    ec.refetchEvents();
    info.el.appendChild(iconElement);
  };

@amoscicki thanks so much for sharing! much appreciated. IT's definitely a place i can work from and get ready for production! really appreciate it! I like the eventdidMount idea!

one thing to mention - in this example I had font-awesome and tailwind installed.