TimeChart icon indicating copy to clipboard operation
TimeChart copied to clipboard

Make tooltip `.name` and `.value` `max-width` configurable

Open leonard84 opened this issue 1 year ago • 6 comments

Currently, the tooltip hardcodes the .name and .value classes to max-width: 100px. Its use of a shadowRoot exacerbates the problem, making an easy fix with CSS overrides impossible.

Please offer a way to increase the max sizes for both .name and .value.

leonard84 avatar Jun 28 '24 17:06 leonard84

I've tried it once at https://github.com/huww98/TimeChart/issues/55#issuecomment-1273565906 . No satisfying interface found so far.

huww98 avatar Jun 30 '24 14:06 huww98

As I suggested back then, I would make it possible to pass in CSS styles in the tooltip config object, which you would then use to render the inner CSS.

tooltip: new TimeChart.plugins.TimeChartTooltipPlugin({
        enabled: true,
        style: {
          '.name': {
            'max-width': '50em'
          },
          '.value': {
          'max-width': '50em'
        }
      },
      xFormatter: (x) => new Date(x + baseTime).toLocaleString([], {
        // year: '2-digit',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        // fractionalSecondDigits: 3
      })
    })

This could be used something like this (code by Google Gemini).

function generateStyleSheet(config) {
  const defaultStyles = {
    ":host": {
      background: "var(--background-overlay, white)",
      border: "1px solid hsl(0, 0%, 80%)",
      "border-radius": "3px",
      padding: "2px 2px",
    },
    ".item": {
      "user-select": "none",
    },
    ".out-of-range.item": {
      display: "none",
    },
    td: {
      padding: "0px 5px",
    },
    ".name": {
      "margin-right": "10px",
      "max-width": "100px",
      "text-overflow": "ellipsis",
      overflow: "hidden",
      "white-space": "nowrap",
    },
    ".example": {
      width: "6px",
      height: "6px",
    },
    ".value": {
      "text-overflow": "ellipsis",
      overflow: "hidden",
      "white-space": "nowrap",
      "min-width": "100px",
      "max-width": "100px",
      "text-align": "right",
    },
    ".x-not-aligned .value": {
      opacity: "0.4",
    },
  };

  const mergedStyles = mergeStyles(defaultStyles, config?.style || {}); // Merge with configuration

  const style = document.createElement('style');
  style.textContent = Object.entries(mergedStyles)
    .map(([selector, properties]) => {
      const propertiesString = Object.entries(properties)
        .map(([prop, value]) => `${prop}: ${value};`)
        .join(" ");
      return `${selector} { ${propertiesString} }`;
    })
    .join("\n");

  return style;
}

// Helper to merge styles (deep merge for nested properties)
function mergeStyles(defaultStyles, customStyles) {
  const merged = { ...defaultStyles };
  for (const selector in customStyles) {
    if (merged[selector]) {
      merged[selector] = { ...merged[selector], ...customStyles[selector] }; // Deep merge
    } else {
      merged[selector] = customStyles[selector];
    }
  }
  return merged;
}

// Example Usage
const conf = {
  style: {
    ".name": {
      "max-width": "50em",
    },
    ".value": {
      "max-width": "50em",
    },
  },
};

const shadowRoot = document.createElement('div').attachShadow({ mode: 'open' });
shadowRoot.appendChild(generateStyleSheet(conf));

leonard84 avatar Jul 01 '24 10:07 leonard84

@huww98, what do you think of my suggestion?

leonard84 avatar Jul 15 '24 09:07 leonard84

I actually don't like this idea. The best way I think would be using CSS to solve the styling issue, and just not put them in JS. But since we are not using web-component yet, maybe I can just take a large string consisting of a CSS fragment, and I just append it to the default style? Browser should do the merge itself.

huww98 avatar Jul 15 '24 10:07 huww98

Fine by me, as long as it works.

How would web-components change this?

leonard84 avatar Jul 22 '24 13:07 leonard84

Any chance to get this, or do you want a PR?

leonard84 avatar Aug 22 '24 09:08 leonard84