@luscii-healthtech/web-ui 42.13.0 → 42.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5988,7 +5988,8 @@ const Collapse = (props) => {
5988
5988
  function isColorTuple(color) {
5989
5989
  return Array.isArray(color) && color.length === 2;
5990
5990
  }
5991
- const validateNoOverlaps = (sections) => {
5991
+ const hasSectionOverlaps = (sections) => {
5992
+ let overlapFound = false;
5992
5993
  sections.forEach((sectionA, i) => {
5993
5994
  sections.slice(i + 1).forEach((sectionB) => {
5994
5995
  const aMin = Math.min(sectionA.from, sectionA.to);
@@ -5997,10 +5998,11 @@ const validateNoOverlaps = (sections) => {
5997
5998
  const bMax = Math.max(sectionB.from, sectionB.to);
5998
5999
  const overlaps = aMin < bMax && bMin < aMax;
5999
6000
  if (overlaps) {
6000
- throw new Error(`RangeCoverage: Sections cannot overlap. Section [${sectionA.from}, ${sectionA.to}] overlaps with section [${sectionB.from}, ${sectionB.to}].`);
6001
+ overlapFound = true;
6001
6002
  }
6002
6003
  });
6003
6004
  });
6005
+ return overlapFound;
6004
6006
  };
6005
6007
  const generateIntermediateTicks = (args) => {
6006
6008
  const { step, start, end } = args;
@@ -6021,13 +6023,49 @@ const generateIntermediateTicks = (args) => {
6021
6023
  }
6022
6024
  return Array.from(tickSet).sort((a, b) => isDescending ? b - a : a - b);
6023
6025
  };
6026
+ const colorsAreEqual = (colorA, colorB) => {
6027
+ const aIsStriped = isColorTuple(colorA);
6028
+ const bIsStriped = isColorTuple(colorB);
6029
+ if (aIsStriped !== bIsStriped) {
6030
+ return false;
6031
+ }
6032
+ if (aIsStriped && bIsStriped) {
6033
+ return colorA[0] === colorB[0] && colorA[1] === colorB[1];
6034
+ }
6035
+ return colorA === colorB;
6036
+ };
6037
+ const mergeAdjacentSections = (sections) => {
6038
+ if (sections.length === 0) {
6039
+ return [];
6040
+ }
6041
+ const sorted = [...sections].sort((a, b) => {
6042
+ const aStart = Math.min(a.from, a.to);
6043
+ const bStart = Math.min(b.from, b.to);
6044
+ return aStart - bStart;
6045
+ });
6046
+ const merged = [Object.assign({}, sorted[0])];
6047
+ for (let i = 1; i < sorted.length; i++) {
6048
+ const current = sorted[i];
6049
+ const previous = merged[merged.length - 1];
6050
+ const prevEnd = Math.max(previous.from, previous.to);
6051
+ const currentStart = Math.min(current.from, current.to);
6052
+ const currentEnd = Math.max(current.from, current.to);
6053
+ if (prevEnd === currentStart && colorsAreEqual(previous.color, current.color)) {
6054
+ previous.to = currentEnd;
6055
+ } else {
6056
+ merged.push(Object.assign({}, current));
6057
+ }
6058
+ }
6059
+ return merged;
6060
+ };
6024
6061
  const calculateSegments = (sections, start, end) => {
6025
6062
  const isDescending = start > end;
6026
6063
  const rangeMin = Math.min(start, end);
6027
6064
  const rangeMax = Math.max(start, end);
6028
6065
  const totalRange = Math.abs(end - start);
6029
6066
  const segments = [];
6030
- const normalizedSections = sections.map((section) => {
6067
+ const mergedSections = mergeAdjacentSections(sections);
6068
+ const normalizedSections = mergedSections.map((section) => {
6031
6069
  const clampedFrom = Math.max(rangeMin, Math.min(rangeMax, section.from));
6032
6070
  const clampedTo = Math.max(rangeMin, Math.min(rangeMax, section.to));
6033
6071
  const higher = Math.max(clampedFrom, clampedTo);
@@ -6062,14 +6100,19 @@ const calculateSegments = (sections, start, end) => {
6062
6100
  }
6063
6101
  return segments;
6064
6102
  };
6065
- const createStripedPattern = (colorA, colorB) => `repeating-linear-gradient(-45deg, ${colorA}, ${colorA} 4px, ${colorB} 4px, ${colorB} 8px)`;
6103
+ const createStripedPattern = (options) => {
6104
+ const { colorA, colorB, startOffset = 0 } = options;
6105
+ const STRIPE_THICKNESS = 4;
6106
+ const STRIPE_GAP = STRIPE_THICKNESS + 3;
6107
+ return `repeating-linear-gradient(-45deg, ${colorA} ${startOffset}px, ${colorA} ${startOffset + STRIPE_THICKNESS}px, ${colorB} ${startOffset + STRIPE_THICKNESS}px, ${colorB} ${startOffset + STRIPE_GAP + STRIPE_THICKNESS}px)`;
6108
+ };
6066
6109
  const getSegmentStyle = (color) => {
6067
6110
  const baseStyle = {
6068
6111
  height: "18px",
6069
6112
  boxSizing: "content-box"
6070
6113
  };
6071
6114
  if (isColorTuple(color)) {
6072
- return Object.assign(Object.assign({}, baseStyle), { background: createStripedPattern(color[0], color[1]) });
6115
+ return Object.assign(Object.assign({}, baseStyle), { background: createStripedPattern({ colorA: color[0], colorB: color[1] }) });
6073
6116
  }
6074
6117
  return Object.assign(Object.assign({}, baseStyle), { background: color });
6075
6118
  };
@@ -6079,12 +6122,12 @@ const legendSwatchStyle = {
6079
6122
  borderRadius: "2px",
6080
6123
  flexShrink: 0
6081
6124
  };
6082
- const COLOR_RED = "var(--ui-color-red-800)";
6083
- const COLOR_AMBER = "var(--ui-color-amber-700)";
6084
- const COLOR_GREY_DARK = "var(--ui-color-slate-700)";
6085
- const COLOR_GREY_LIGHT = "var(--ui-color-slate-300)";
6086
- const COLOR_BLUE = "var(--ui-color-blue-200)";
6087
- const BORDER_COLOR = COLOR_GREY_LIGHT;
6125
+ const COLOR_GREY_LIGHT = "var(--ui-color-background-info-secondary-hovered)";
6126
+ const COLOR_GREY_DARK = "var(--ui-color-border-info-secondary-hovered)";
6127
+ const COLOR_RED = "var(--ui-color-border-error-primary-default)";
6128
+ const COLOR_AMBER = "var(--ui-color-icon-warning-secondary-default)";
6129
+ const COLOR_BLUE = COLOR_GREY_LIGHT;
6130
+ const BORDER_COLOR = "var(--ui-color-border-neutral-secondary-default)";
6088
6131
  const BORDER_RADIUS = "var(--ui-radius-sm, 4px)";
6089
6132
  const barContainerStyle = {
6090
6133
  width: "100%",
@@ -6106,11 +6149,17 @@ const ticksContainerStyle = {
6106
6149
  width: "100%",
6107
6150
  height: "20px"
6108
6151
  };
6109
- const RangeCoverageComponent = ({ sections, start, end, ticks = [], title, legendSwatches, className }) => {
6110
- validateNoOverlaps(sections);
6152
+ const RangeCoverageComponent = ({ sections, start, end, ticks = [], title, legendSwatches, translations, className }) => {
6153
+ if (hasSectionOverlaps(sections)) {
6154
+ return jsxRuntime.jsx(Text, { variant: "strong", children: translations.sectionOverlapsMessage });
6155
+ }
6111
6156
  const segments = calculateSegments(sections, start, end);
6112
6157
  return jsxRuntime.jsx(Box, { className, children: jsxRuntime.jsxs(Stack, { gap: "xs", width: "full", align: "stretch", children: [jsxRuntime.jsxs(Stack, { justify: "between", axis: "x", align: "center", children: [jsxRuntime.jsx(Title, { variant: "xs", level: "3", children: title }), legendSwatches && (legendSwatches === null || legendSwatches === void 0 ? void 0 : legendSwatches.length) > 0 && jsxRuntime.jsx(Stack, { axis: "x", gap: "m", children: jsxRuntime.jsx(Stack, { axis: "x", gap: "xxs", align: "center", children: legendSwatches === null || legendSwatches === void 0 ? void 0 : legendSwatches.map((swatch) => {
6113
- const background = isColorTuple(swatch.color) ? createStripedPattern(swatch.color[0], swatch.color[1]) : swatch.color;
6158
+ const background = isColorTuple(swatch.color) ? createStripedPattern({
6159
+ colorA: swatch.color[0],
6160
+ colorB: swatch.color[1],
6161
+ startOffset: -6
6162
+ }) : swatch.color;
6114
6163
  return jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("div", { style: Object.assign(Object.assign({}, legendSwatchStyle), { background }) }), jsxRuntime.jsx(Text, { as: "span", children: swatch.label })] }, swatch.label);
6115
6164
  }) }) })] }), jsxRuntime.jsxs(Stack, { gap: "xs", width: "full", align: "stretch", children: [jsxRuntime.jsx("div", { style: barContainerStyle, children: jsxRuntime.jsx("div", { style: barStyle, children: segments.map((segment, index) => jsxRuntime.jsx("div", { style: Object.assign({ flexBasis: `${segment.widthPercent}%`, flexGrow: 0, flexShrink: 0 }, getSegmentStyle(segment.color)) }, index)) }) }), ticks.length > 0 && jsxRuntime.jsx("div", { style: ticksContainerStyle, children: ticks.map((tick, index) => {
6116
6165
  const totalRange = Math.abs(end - start);
@@ -6120,7 +6169,7 @@ const RangeCoverageComponent = ({ sections, start, end, ticks = [], title, legen
6120
6169
  const isLast = index === ticks.length - 1;
6121
6170
  return jsxRuntime.jsx(Text, { style: {
6122
6171
  position: "absolute",
6123
- color: COLOR_GREY_DARK,
6172
+ color: "var(--ui-color-text-neutral-secondary-default)",
6124
6173
  whiteSpace: "nowrap",
6125
6174
  left: `${position}%`,
6126
6175
  transform: isFirst ? "translateX(0%)" : isLast ? "translateX(-100%)" : "translateX(-50%)"