search envelope-o feed check
Home Unanswered Active Tags New Question
user comment-o

React Scheduler > Difficulty with applying css on row header background and rowmove handle

Asked by Andy
21 days ago.

Hello,

We have a requirement to make the background of the row header blue on hover of the row header. However, upon hovering on the rowmove handle, the row header’s background is no longer blue.

Can you provide guidance on this? Thank you!

Context:

  • I am rendering row header’s JSX using `onBeforeRowHeaderDomAdd`

  • I am overriding the rowmove handle css using styled-component and the snippet is as seen below.

const RowMoveHandlerCssOverride = css`
  .scheduler_default_rowheader:hover {
    background-color: blue; // Make background of row header blue
  }
  
  .scheduler_default_rowmove_handle {
    left: 20px !important;
    top: 50% !important; /* Center vertically */
    transform: translateY(-50%);
    cursor: grab !important;
    background-color: transparent !important;
    background-image: ${({ theme }) =>
      `url("${createDragGripIconDataUri({ color: 'blue' })}")`} !important;
  }

  .scheduler_default_rowmove_handle:hover {
    background-image: ${({ theme }) =>
      `url("${createDragGripIconDataUri({ color: 'red' })}")`} !important;

   // TODO - `scheduler_default_rowheader` hover effect is not being applied 
   // when rowmove handle is hovered on
  }
`;

<RowMoveHandlerCssOverride />
Comment posted by Andy
21 days ago.

While I don’t think it is currently supported, I am wondering whether it’s possible expose the callback (maybe via arguments of onBeforeRowHeaderDomAdd) that Daypilot currently calls to trigger the row move process.

In that case, we can hide the default rowmove handle via css, render our own custom row move handle UI (in onBeforeRowHeaderDomAdd) and trigger the exposed callback on mouse down of the move handle.

Answer posted by Dan Letecky [DayPilot]
20 days ago.

It looks like this CSS works for me, so the problem might be somewhere else. You can try turning off your custom JSX temporarily to see if that causes the issue.

.scheduler_default_rowheader:hover {
    background-color: blue;
}

.scheduler_default_rowmove_handle {
    left: 20px !important;
    top: 50% !important;
    transform: translateY(-50%);
    cursor: grab !important;
    background-color: transparent !important;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 15 15'><g fill='%23fff'><rect x='3' y='3' width='2' height='2' rx='1'/><rect x='3' y='7' width='2' height='2' rx='1'/><rect x='3' y='11' width='2' height='2' rx='1'/><rect x='10' y='3' width='2' height='2' rx='1'/><rect x='10' y='7' width='2' height='2' rx='1'/><rect x='10' y='11' width='2' height='2' rx='1'/></g></svg>");
}

.scheduler_default_rowmove_handle:hover {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 15 15'><g fill='%23fff'><rect x='3' y='3' width='2' height='2' rx='1'/><rect x='3' y='7' width='2' height='2' rx='1'/><rect x='3' y='11' width='2' height='2' rx='1'/><rect x='10' y='3' width='2' height='2' rx='1'/><rect x='10' y='7' width='2' height='2' rx='1'/><rect x='10' y='11' width='2' height='2' rx='1'/></g></svg>");
}

You can also create a custom handle using an active area in onBeforeRowHeaderRender like this:

onBeforeRowHeaderRender: args => {
    args.row.columns[0].areas = [
        {
            left: 0,
            top: "calc(50% - 10px)",
            height: 20,
            width: 20,
            backColor: "red",
            action: "Move",
            // image, symbol, cssClass....
        }
    ];
}

With action: "Move", it automatically activates row moving on mousedown.

Comment posted by Andy
20 days ago.

Hi Dan,

You are right about the CSS. The JSX has its own background css. My bad! I decided to go with the `onBeforeRowHeaderRender` approach due to its flexibility.

Is there a field on `args` of `onBeforeRowHeaderRender` to tell whether a row is being moved (without additional state like a useRef)?

I hope to hide the custom row move handle when it’s moving. Right not it is always visible, even during move.

Comment posted by Dan Letecky [DayPilot]
20 days ago.

Hi Andy,

> I hope to hide the custom row move handle when it’s moving. Right now it is always visible, even during move.

Do you need the handle to be always visible (not just on hover)? Areas with visibility: "Hover" are hidden automatically during moving.

Comment posted by Andy
20 days ago.

Hi Dan,

Yes, I have a `isAlwaysVisible` flag that will always show the handle icon, but this flag can be true while the row is moving. When the row is moving, I want to make it `visibility: Hover` so handle icon is hidden.

I am trying to see if `onBeforeRowHeaderRender` has a way to indicate that a row is being moved via `args` (ie: `isRowMoving`).

  const onBeforeRowHeaderRender = useCallback((args) => {
    args.row.areas = [{
      action: 'Move',
      visibility: isAlwaysVisible ? 'Visible' : 'Hover'
    }]

    // Ideal 
    visibility: isAlwaysVisible && !isRowMoving ? 'Visible' : 'Hover'
  }, [isAlwaysVisible]);
Comment posted by Dan Letecky [DayPilot]
20 days ago.

Hi Andy,

Please let me check the options. This can’t be done in onBeforeRowHeaderRender because row headers are not re-rendered during dragging. That means onBeforeRowHeaderRender is not triggered.

Do you want to hide the handle in the source row or in all rows?

Comment posted by Andy
20 days ago.

Hi Dan,

It will be to hide handle for all rows while dragging. Thank you!

Comment posted by Andy
19 days ago.

Hi Dan,

Another issue we found is while a row is being moved, the row header background also turns blue due to this css snippet (since we are technically hovering on the row header while dragging it).

.scheduler_default_rowheader:hover {
    background-color: blue;
}

I think having a way to detect if a row is being moved in `onBeforeRowHeaderRender` will be really helpful, so a class can be added to disable this hover effect. Though I am not sure if this can be achieved if `onBeforeRowHeaderRender` isn’t re-triggered when dragging as you mentioned.

Open for suggestion!

Comment posted by Dan Letecky [DayPilot]
19 days ago.

Hi Andy,

The best way (no updates required) would probably be to add a special CSS class to the main Scheduler element during dragging. That would let you target all special elements using CSS only.

Something like this:

onRowMoveStart: args => {
  scheduler.nav.top.classList.add("row-drag");
},
rowMoveFireOnForbiddenTarget: true,
onRowMove: args => {
  scheduler.nav.top.classList.remove("row-drag");
}

This would cover this second requirement as well.

Comment posted by Andy
19 days ago.

Thank you Dan,

I tried the approach to add `timeline-row-drag-in-progress` class, but I can’t find it via upon inspecting the elements.

Do you which element gets this class?

In this case, `scheduler = controlRef.current`

Comment posted by Andy
19 days ago.

Hmm it looks like it is added, but immediately gets removed due to rerendering…

Comment posted by Andy
19 days ago.

I forgot to attached screenshot of the class

Comment posted by Andy
19 days ago.

I was able to persist the class by continuously adding it in `onRowMoving` instead of `onRowMoveStart`. I am not sure if that’s the way go to.

   if (scheduler?.nav?.top && !scheduler.nav.top.classList.contains(ROW_DRAG_IN_PROGRESS_CLASS)) {
        scheduler.nav.top.classList.add(ROW_DRAG_IN_PROGRESS_CLASS);
      }

However, there is an edge case where if user drags then drops the row outside of the scheduler, `onRowMove` won’t be called, which makes the class remains on the the main element, instead of removing it.

Comment posted by Dan Letecky [DayPilot]
19 days ago.

If I remember correctly, you expand the siblings during drag and drop - that causes the refresh.

It is also possible to add the CSS class to the Scheduler top element permanently using the cssClass prop but adding/removing it forces a refresh. The refresh is quite fast, but in this case you’d probably need to check if it doesn’t hurt performance.

But: It’s not necessary to add it to the Scheduler, you can also add it to any of its parents (or to the body).

Adding the class in onRowMoving might be another option.

To remove the class, you can handle the global onmouseup event (possibly in the capture phase).

New Reply
This reply is
Attachments:
or drop files here
Your name (optional):