calendar-tsx

Rendering parts

Props on parts, and swapping a part's element with render.

Props

Every part accepts the props of its element. They merge with the part's own, and merged props stay reactive:

  • Most props: yours win, so you can replace role, aria-label or type.
  • class: joined. Parts take class, not className.
  • style: shallow-merged, so you can add styles without losing the --cal-* geometry.
  • Event handlers and ref: both run, in order. On day triggers your onClick runs before the navigation, so preventDefault() can skip it.
export const ColoredEvent = (props: { segment: Calendar_TimeGridSegment<Booking> }) => (
  <TimeGridViewEvent segment={props.segment} class='event' style={{ background: props.segment.event.data.color }}>
    {props.segment.event.data.title}
  </TimeGridViewEvent>
);

A handler in Solid's bound form, onClick={[handler, data]}, replaces the part's handler instead of chaining with it. Use a plain function on triggers.

render

render swaps the element a part renders. It takes a function only: Solid has no elements to clone, so there is no element form.

export const LinkedEvent = (props: { event: Calendar_Event<Booking> }) => (
  <ListViewEvent
    event={props.event}
    render={(partProps, event) => <a {...partProps({ href: `/bookings/${event().id}` })} />}
  >
    {props.event.data.title}
  </ListViewEvent>
);
  • props(yours?) returns the part's props, including children and ref, merged with yours by the rules above. Pass your props to it rather than spreading them separately, so handlers and refs chain instead of overwriting.
  • The second argument is an accessor for the part's model: the segment, day, column, …
export const TitledDay = (props: { day: Calendar_DayGridDay<Booking> }) => (
  <DayGridViewDay
    day={props.day}
    render={(partProps, day) => <div {...partProps({ title: day().isToday ? 'Today' : undefined })} />}
  />
);

The function may return any JSX, including text. A part reads render once, when it is created: switching a live part between render and no render does not re-render it.