@galaxy-io/dls 1.5.14 → 1.5.16

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.
@@ -16,6 +16,31 @@ export type BarChartProps<TMetric extends string, TComponentKey extends string =
16
16
  /** Tint the active category's full band, marking the hover position even
17
17
  * where there is no data. @default true */
18
18
  showCursor?: boolean;
19
+ /**
20
+ * Floor, in px, for how short a *stack segment* may render — so a series
21
+ * that is a rounding error next to its neighbours still leaves a visible
22
+ * mark instead of disappearing. `0`, the default, draws segments at their
23
+ * true size.
24
+ *
25
+ * Opt-in because it is a lie, and a small one is worth being deliberate
26
+ * about: the pixels a sliver gains are taken from the other segments in the
27
+ * same stack, in proportion to how much slack each has. The stack's total
28
+ * height, its cap position and every value in the tooltip stay exactly
29
+ * right — only the split between segments shifts, by at most a couple of
30
+ * pixels per rescued sliver. Reach for it when presence/absence is the
31
+ * thing being read (an error series, a small cohort); leave it off when the
32
+ * chart is being read for proportion.
33
+ *
34
+ * Ignored on unstacked bars, which already have a 2px floor — there is no
35
+ * neighbour to take from, so it costs nothing there. Ignored, too, when a
36
+ * stack is so crowded that honouring it would pin every segment to the
37
+ * minimum: at that point the bar would stop describing its data, and the
38
+ * chart is better off saying so. Fold the tail into an "Other" component
39
+ * instead.
40
+ *
41
+ * @default 0
42
+ */
43
+ minSegmentLength?: number;
19
44
  /**
20
45
  * Fires when a bar segment or a category is clicked. Supplying it is what
21
46
  * makes the plot clickable.
@@ -48,5 +73,5 @@ export type BarChartProps<TMetric extends string, TComponentKey extends string =
48
73
  * `bars` in a group render side by side, several `components` in a bar stack,
49
74
  * and a chart doing both at once needs no extra configuration.
50
75
  */
51
- declare const BarChart: <TMetric extends string, TComponentKey extends string = string>({ series, groups, width, height, fillWidth, fillHeight, aspectRatio, margin, normalization, showCursor, onSelect, selection, valueUnit, valueFormatter, labelFormatter, valueDomain, categoryLabelMode, categoryAxisTitle, valueAxisTitle, showGrid, showLegend, legendMaxItems, noTooltip, tooltipRenderer, tooltipMaxItems, isLoading, contentWhenEmpty, ariaLabel, ariaDescription, }: BarChartProps<TMetric, TComponentKey>) => import("react").JSX.Element;
76
+ declare const BarChart: <TMetric extends string, TComponentKey extends string = string>({ series, groups, width, height, fillWidth, fillHeight, aspectRatio, margin, normalization, showCursor, minSegmentLength, onSelect, selection, valueUnit, valueFormatter, labelFormatter, valueDomain, categoryLabelMode, categoryAxisTitle, valueAxisTitle, showGrid, showLegend, legendMaxItems, noTooltip, tooltipRenderer, tooltipMaxItems, isLoading, contentWhenEmpty, ariaLabel, ariaDescription, }: BarChartProps<TMetric, TComponentKey>) => import("react").JSX.Element;
52
77
  export default BarChart;
@@ -17,7 +17,7 @@ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
17
  * `bars` in a group render side by side, several `components` in a bar stack,
18
18
  * and a chart doing both at once needs no extra configuration.
19
19
  */
20
- var BarChart = ({ series, groups, width, height, fillWidth, fillHeight, aspectRatio, margin, normalization = BarChartNormalization.NONE, showCursor = true, onSelect, selection, valueUnit, valueFormatter, labelFormatter, valueDomain, categoryLabelMode, categoryAxisTitle, valueAxisTitle, showGrid = true, showLegend = true, legendMaxItems, noTooltip = false, tooltipRenderer, tooltipMaxItems, isLoading = false, contentWhenEmpty, ariaLabel, ariaDescription }) => {
20
+ var BarChart = ({ series, groups, width, height, fillWidth, fillHeight, aspectRatio, margin, normalization = BarChartNormalization.NONE, showCursor = true, minSegmentLength = 0, onSelect, selection, valueUnit, valueFormatter, labelFormatter, valueDomain, categoryLabelMode, categoryAxisTitle, valueAxisTitle, showGrid = true, showLegend = true, legendMaxItems, noTooltip = false, tooltipRenderer, tooltipMaxItems, isLoading = false, contentWhenEmpty, ariaLabel, ariaDescription }) => {
21
21
  const containerRef = useRef(null);
22
22
  const colors = useSeriesColorResolver(series);
23
23
  /**
@@ -78,7 +78,8 @@ var BarChart = ({ series, groups, width, height, fillWidth, fillHeight, aspectRa
78
78
  normalization,
79
79
  isStacked,
80
80
  domain,
81
- resolveColor
81
+ resolveColor,
82
+ minSegmentLength
82
83
  }), [
83
84
  groups,
84
85
  plotWidth,
@@ -86,7 +87,8 @@ var BarChart = ({ series, groups, width, height, fillWidth, fillHeight, aspectRa
86
87
  normalization,
87
88
  isStacked,
88
89
  domain,
89
- resolveColor
90
+ resolveColor,
91
+ minSegmentLength
90
92
  ]);
91
93
  const isEmpty = groups.length === 0;
92
94
  const legendItems = useMemo(() => getBarLegendItems({
@@ -106,6 +106,12 @@ interface BuildBarChartGeometryArgs<TMetric extends string, TComponentKey extend
106
106
  * record to answer, which this module has no business importing.
107
107
  */
108
108
  resolveColor: (args: ResolveBarColorArgs<TMetric>) => string;
109
+ /**
110
+ * Minimum rendered length for a stack segment, in px. `0` disables it.
111
+ *
112
+ * See the prop of the same name on `BarChart` for what it costs.
113
+ */
114
+ minSegmentLength: number;
109
115
  }
110
116
  export interface ResolveBarColorArgs<TMetric extends string> {
111
117
  metric: TMetric;
@@ -116,5 +122,5 @@ export interface ResolveBarColorArgs<TMetric extends string> {
116
122
  /** The component's own palette override, if it declared one. */
117
123
  explicit?: ChartPalette;
118
124
  }
119
- export declare function buildBarChartGeometry<TMetric extends string, TComponentKey extends string = string>({ groups, plotWidth, plotHeight, normalization, isStacked, domain, resolveColor, }: BuildBarChartGeometryArgs<TMetric, TComponentKey>): BarChartGeometry<TMetric, TComponentKey>;
125
+ export declare function buildBarChartGeometry<TMetric extends string, TComponentKey extends string = string>({ groups, plotWidth, plotHeight, normalization, isStacked, domain, resolveColor, minSegmentLength, }: BuildBarChartGeometryArgs<TMetric, TComponentKey>): BarChartGeometry<TMetric, TComponentKey>;
120
126
  export {};
@@ -111,7 +111,86 @@ function getBarValueDomain(groups, normalization) {
111
111
  }
112
112
  return [min, max];
113
113
  }
114
- function buildBarChartGeometry({ groups, plotWidth, plotHeight, normalization, isStacked, domain, resolveColor }) {
114
+ /**
115
+ * Grow every under-sized segment to its minimum, paying for it out of the
116
+ * segments that have room to spare.
117
+ *
118
+ * `lengths` and `minima` are one side of one stack, in baseline-outward order.
119
+ * Returns `null` when nothing needs doing, and — deliberately — also when the
120
+ * bill cannot be paid: if the surplus across the whole side is smaller than the
121
+ * total deficit, every segment would end up pinned at its minimum and the bar
122
+ * would no longer be a picture of its data. A stack that crowded is telling the
123
+ * caller to drop the minimum or fold the tail into an "Other" component, and
124
+ * silently redrawing it as a ladder of equal blocks would hide that.
125
+ */
126
+ function distributeMinSegmentLengths(lengths, minima) {
127
+ const result = [...lengths];
128
+ let deficit = 0;
129
+ let surplus = 0;
130
+ lengths.forEach((length, index) => {
131
+ if (length < minima[index]) {
132
+ deficit += minima[index] - length;
133
+ result[index] = minima[index];
134
+ } else surplus += length - minima[index];
135
+ });
136
+ if (deficit === 0 || surplus < deficit) return null;
137
+ const donors = result.map((length, index) => ({
138
+ index,
139
+ slack: length - minima[index]
140
+ })).filter((donor) => donor.slack > 0).sort((a, b) => b.slack - a.slack);
141
+ let remainingSlack = surplus;
142
+ for (const donor of donors) {
143
+ if (deficit <= 0) break;
144
+ const share = Math.min(donor.slack, Math.ceil(donor.slack / remainingSlack * deficit));
145
+ result[donor.index] -= share;
146
+ remainingSlack -= donor.slack;
147
+ deficit -= share;
148
+ }
149
+ return result;
150
+ }
151
+ /**
152
+ * Snapped pixel spans for one bar's segments, with {@link minSegmentLength}
153
+ * enforced.
154
+ *
155
+ * The enforcement re-lays the affected side of the stack *cumulatively* from the
156
+ * baseline outward, rather than nudging each segment's own edges. That is the
157
+ * only way to grow a sliver without breaking the invariant the rounding above
158
+ * exists to protect: each segment starts exactly where the previous one ended,
159
+ * so there is still one shared edge per seam and no overlap. And because the
160
+ * redistribution is zero-sum, the side's total extent is unchanged — the cap
161
+ * still lands on the same axis value it did before.
162
+ */
163
+ function resolveSegmentExtents(intervals, valueScale, minSegmentLength) {
164
+ const extents = intervals.map(({ from, to }) => ({
165
+ fromY: Math.round(valueScale(from)),
166
+ toY: Math.round(valueScale(to))
167
+ }));
168
+ if (minSegmentLength <= 0) return extents;
169
+ const adjustSide = (sign) => {
170
+ const indices = intervals.map((interval, index) => ({
171
+ interval,
172
+ index
173
+ })).filter(({ interval }) => Math.sign(interval.value) === sign).map(({ index }) => index);
174
+ if (indices.length === 0) return;
175
+ const adjusted = distributeMinSegmentLengths(indices.map((index) => Math.abs(extents[index].fromY - extents[index].toY)), indices.map((_, position) => position === 0 ? minSegmentLength : minSegmentLength + 2));
176
+ if (!adjusted) return;
177
+ const direction = sign > 0 ? -1 : 1;
178
+ const first = extents[indices[0]];
179
+ let cursor = sign > 0 ? first.fromY : first.toY;
180
+ indices.forEach((index, position) => {
181
+ const next = cursor + direction * adjusted[position];
182
+ extents[index] = {
183
+ fromY: cursor,
184
+ toY: next
185
+ };
186
+ cursor = next;
187
+ });
188
+ };
189
+ adjustSide(1);
190
+ adjustSide(-1);
191
+ return extents;
192
+ }
193
+ function buildBarChartGeometry({ groups, plotWidth, plotHeight, normalization, isStacked, domain, resolveColor, minSegmentLength }) {
115
194
  const valueScale = buildValueScale(domain, [plotHeight, 0]);
116
195
  const baselineY = valueScale(0);
117
196
  const rects = [];
@@ -139,6 +218,8 @@ function buildBarChartGeometry({ groups, plotWidth, plotHeight, normalization, i
139
218
  const barX = barsStartX + barIndex * (barWidth + effectiveBarGap);
140
219
  const values = bar.components.map((component) => sanitizeValue(component.value));
141
220
  const intervals = stackComponents(values, normalization);
221
+ const isStackedBar = bar.components.length > 1;
222
+ const extents = resolveSegmentExtents(intervals, valueScale, isStackedBar ? minSegmentLength : 0);
142
223
  let firstPositive = -1;
143
224
  let lastPositive = -1;
144
225
  let firstNegative = -1;
@@ -154,15 +235,13 @@ function buildBarChartGeometry({ groups, plotWidth, plotHeight, normalization, i
154
235
  }
155
236
  });
156
237
  bar.components.forEach((component, componentIndex) => {
157
- const { value, from, to } = intervals[componentIndex];
238
+ const { value } = intervals[componentIndex];
158
239
  if (value === 0) return;
159
240
  const isNegative = value < 0;
160
241
  const isCap = componentIndex === (isNegative ? lastNegative : lastPositive);
161
- const fromY = Math.round(valueScale(from));
162
- const toY = Math.round(valueScale(to));
242
+ const { fromY, toY } = extents[componentIndex];
163
243
  const topY = Math.min(fromY, toY);
164
244
  const rawHeight = Math.abs(fromY - toY);
165
- const isStackedBar = bar.components.length > 1;
166
245
  const shave = componentIndex === (isNegative ? firstNegative : firstPositive) ? 0 : 2;
167
246
  const height = Math.max(isStackedBar ? 0 : 2, rawHeight - shave);
168
247
  const y = isNegative ? topY + shave : topY;
@@ -38,7 +38,7 @@ export interface SelectInputProps {
38
38
  /** Trigger width. A number is px. */
39
39
  width?: number | string;
40
40
  fillWidth?: boolean;
41
- /** Panel width. Defaults to matching the trigger. */
41
+ /** Panel width. By default, fits the options and is at least as wide as the trigger. */
42
42
  dropdownWidth?: number | string;
43
43
  isDisabled?: boolean;
44
44
  isRequired?: boolean;
@@ -6,7 +6,6 @@ import FlexItem from "../containers/FlexItem.js";
6
6
  import Dropdown, { DropdownVariant } from "../dropdown/Dropdown.js";
7
7
  import Icon, { IconVariant, IconWeight } from "../icons/Icon.js";
8
8
  import FlexWrapper, { AlignItems, FlexDirection } from "../containers/FlexWrapper.js";
9
- import Spacing from "../containers/Spacing.js";
10
9
  import { InputLabel, InputSize, InputVariant, getInputBorderColor, getInputFontSize, getInputHeight, getInputIconSize, getInputLineHeight, getInputPadding, getInputSurfaceColor, getInputTextSize } from "./Input.js";
11
10
  import HorizontalDivider from "../dividers/HorizontalDivider.js";
12
11
  import { useElementWidth } from "../hooks/useElementWidth.js";
@@ -72,11 +71,8 @@ var StyledSearchInput = withTheme(/*#__PURE__*/ styled("input")({
72
71
  "s14m69un-6": [_exp13()]
73
72
  }
74
73
  }));
75
- var _exp14 = () => ({ $width }) => getCssSizeValue($width, 200);
76
- var _exp15 = () => ({ $fillWidth, $width }) => {
77
- if ($width) return getCssSizeValue($width);
78
- return $fillWidth ? "100%" : "auto";
79
- };
74
+ var _exp14 = () => ({ $minWidth }) => `min(${getCssSizeValue($minWidth)}, calc(100vw - 16px))`;
75
+ var _exp15 = () => ({ $width }) => getCssSizeValue($width, "max-content");
80
76
  var SelectInputContent = /*#__PURE__*/ styled("div")({
81
77
  name: "SelectInputContent",
82
78
  class: "sbfl8n6",
@@ -86,39 +82,37 @@ var SelectInputContent = /*#__PURE__*/ styled("div")({
86
82
  "sbfl8n6-1": [_exp15()]
87
83
  }
88
84
  });
89
- var _exp16 = () => ({ $fillWidth, $width }) => $fillWidth || $width ? "100%" : "auto";
90
85
  var SelectInputOptionsContainer = /*#__PURE__*/ styled("div")({
91
86
  name: "SelectInputOptionsContainer",
92
87
  class: "sk260f0",
93
- propsAsIs: false,
94
- vars: { "sk260f0-0": [_exp16()] }
88
+ propsAsIs: false
95
89
  });
96
- var _exp17 = () => ({ theme, $isSelected, $isFocused }) => {
90
+ var _exp16 = () => ({ theme, $isSelected, $isFocused }) => {
97
91
  if ($isSelected || $isFocused) return theme.color.background.secondary;
98
92
  return "transparent";
99
93
  };
100
- var _exp19 = () => ({ theme }) => theme.color.background.secondary;
94
+ var _exp18 = () => ({ theme }) => theme.color.background.secondary;
101
95
  var SelectInputOption = withTheme(/*#__PURE__*/ styled("button")({
102
96
  name: "SelectInputOption",
103
97
  class: "so10ras",
104
98
  propsAsIs: false,
105
99
  vars: {
106
- "so10ras-0": [_exp17()],
107
- "so10ras-1": [_exp19()]
100
+ "so10ras-0": [_exp16()],
101
+ "so10ras-1": [_exp18()]
108
102
  }
109
103
  }));
110
- var _exp20 = () => ({ theme, $isSelected, $isFocused }) => {
104
+ var _exp19 = () => ({ theme, $isSelected, $isFocused }) => {
111
105
  if ($isSelected || $isFocused) return theme.color.background.tertiary;
112
106
  return "transparent";
113
107
  };
114
- var _exp22 = () => ({ theme }) => theme.color.background.tertiary;
108
+ var _exp21 = () => ({ theme }) => theme.color.background.tertiary;
115
109
  var PinnedOptionButton = withTheme(/*#__PURE__*/ styled("button")({
116
110
  name: "PinnedOptionButton",
117
111
  class: "poe2ind",
118
112
  propsAsIs: false,
119
113
  vars: {
120
- "poe2ind-0": [_exp20()],
121
- "poe2ind-1": [_exp22()]
114
+ "poe2ind-0": [_exp19()],
115
+ "poe2ind-1": [_exp21()]
122
116
  }
123
117
  }));
124
118
  var OptionIconSlot = /*#__PURE__*/ styled("span")({
@@ -153,11 +147,7 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
153
147
  onOpenChange
154
148
  });
155
149
  const triggerWidth = useElementWidth(triggerRef);
156
- const resolvedDropdownWidth = useMemo(() => dropdownWidth ?? triggerWidth ?? width, [
157
- dropdownWidth,
158
- triggerWidth,
159
- width
160
- ]);
150
+ const dropdownMinWidth = dropdownWidth ?? triggerWidth ?? width ?? 200;
161
151
  const selectedOption = value ?? null;
162
152
  const effectiveIsDisabled = isDisabled || options.length <= 1;
163
153
  const visible = isOpen;
@@ -285,8 +275,8 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
285
275
  return isSearchable && focusedOptionIndex === index + filteredPinnedOptions.length && index >= 0;
286
276
  };
287
277
  const dropdownBody = /* @__PURE__ */ jsxs(SelectInputContent, {
288
- $fillWidth: fillWidth,
289
- $width: resolvedDropdownWidth,
278
+ $minWidth: dropdownMinWidth,
279
+ $width: dropdownWidth,
290
280
  children: [
291
281
  filteredPinnedOptions.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [filteredPinnedOptions.map((pinnedOption, index) => /* @__PURE__ */ jsxs(PinnedOptionButton, {
292
282
  ref: (el) => {
@@ -304,58 +294,55 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
304
294
  cursor: !effectiveIsDisabled ? "pointer" : "not-allowed",
305
295
  isEllipsis: true,
306
296
  children: pinnedOption.label
307
- }), isPinnedOptionSelected(pinnedOption) && /* @__PURE__ */ jsx(Icon, {
297
+ }), isPinnedOptionSelected(pinnedOption) && /* @__PURE__ */ jsx(OptionIconSlot, { children: /* @__PURE__ */ jsx(Icon, {
308
298
  component: CheckIcon,
309
299
  variant: IconVariant.TERTIARY,
310
300
  weight: IconWeight.BOLD,
311
301
  size: 12
312
- })]
302
+ }) })]
313
303
  }, pinnedOption.id)), /* @__PURE__ */ jsx(HorizontalDivider, {})] }),
314
- /* @__PURE__ */ jsx(SelectInputOptionsContainer, {
315
- $fillWidth: fillWidth,
316
- $width: resolvedDropdownWidth,
317
- children: filteredOptions.length > 0 ? filteredOptions.map((option, index) => {
318
- const absoluteIndex = filteredPinnedOptions.length + index;
319
- return /* @__PURE__ */ jsxs(SelectInputOption, {
320
- ref: (el) => {
321
- optionsRefs.current[absoluteIndex] = el;
322
- },
323
- $isSelected: option.id === value?.id,
324
- $isFocused: isOptionFocused(index),
325
- onClick: () => handleOptionSelect(option),
326
- onMouseEnter: () => setFocusedOptionIndex(absoluteIndex),
327
- children: [/* @__PURE__ */ jsxs(FlexWrapper, {
328
- alignItems: AlignItems.CENTER,
329
- gap: 8,
330
- fillWidth: true,
331
- children: [option.icon && /* @__PURE__ */ jsx(OptionIconSlot, { children: option.icon }), /* @__PURE__ */ jsx(FlexItem, {
332
- grow: 1,
333
- shrink: 1,
334
- minWidth: 0,
335
- children: /* @__PURE__ */ jsx(Text, {
336
- size: getInputTextSize(size),
337
- cursor: !effectiveIsDisabled ? "pointer" : "not-allowed",
338
- isEllipsis: true,
339
- variant: option.variant ?? TextVariant.PRIMARY,
340
- children: option.label
341
- })
342
- })]
343
- }), option.id === value?.id && /* @__PURE__ */ jsx(Icon, {
344
- component: CheckIcon,
345
- variant: IconVariant.TERTIARY,
346
- weight: IconWeight.BOLD,
347
- size: 12
304
+ /* @__PURE__ */ jsx(SelectInputOptionsContainer, { children: filteredOptions.length > 0 ? filteredOptions.map((option, index) => {
305
+ const absoluteIndex = filteredPinnedOptions.length + index;
306
+ return /* @__PURE__ */ jsxs(SelectInputOption, {
307
+ ref: (el) => {
308
+ optionsRefs.current[absoluteIndex] = el;
309
+ },
310
+ $isSelected: option.id === value?.id,
311
+ $isFocused: isOptionFocused(index),
312
+ onClick: () => handleOptionSelect(option),
313
+ onMouseEnter: () => setFocusedOptionIndex(absoluteIndex),
314
+ children: [/* @__PURE__ */ jsxs(FlexWrapper, {
315
+ alignItems: AlignItems.CENTER,
316
+ gap: 8,
317
+ minWidth: 0,
318
+ grow: 1,
319
+ children: [option.icon && /* @__PURE__ */ jsx(OptionIconSlot, { children: option.icon }), /* @__PURE__ */ jsx(FlexItem, {
320
+ grow: 1,
321
+ shrink: 1,
322
+ minWidth: 0,
323
+ children: /* @__PURE__ */ jsx(Text, {
324
+ size: getInputTextSize(size),
325
+ cursor: !effectiveIsDisabled ? "pointer" : "not-allowed",
326
+ isEllipsis: true,
327
+ variant: option.variant ?? TextVariant.PRIMARY,
328
+ children: option.label
329
+ })
348
330
  })]
349
- }, option.id);
350
- }) : /* @__PURE__ */ jsx("div", {
351
- style: { padding: "8px" },
352
- children: /* @__PURE__ */ jsx(Text, {
353
- variant: TextVariant.TERTIARY,
354
- size: getInputTextSize(size),
355
- children: "No options found"
356
- })
331
+ }), option.id === value?.id && /* @__PURE__ */ jsx(OptionIconSlot, { children: /* @__PURE__ */ jsx(Icon, {
332
+ component: CheckIcon,
333
+ variant: IconVariant.TERTIARY,
334
+ weight: IconWeight.BOLD,
335
+ size: 12
336
+ }) })]
337
+ }, option.id);
338
+ }) : /* @__PURE__ */ jsx(FlexWrapper, {
339
+ padding: 8,
340
+ children: /* @__PURE__ */ jsx(Text, {
341
+ variant: TextVariant.TERTIARY,
342
+ size: getInputTextSize(size),
343
+ children: "No options found"
357
344
  })
358
- }),
345
+ }) }),
359
346
  onReset && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HorizontalDivider, {}), /* @__PURE__ */ jsx(PinnedOptionButton, {
360
347
  onClick: handleReset,
361
348
  $isSelected: false,
@@ -390,6 +377,7 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
390
377
  return /* @__PURE__ */ jsxs(FlexWrapper, {
391
378
  direction: FlexDirection.COLUMN,
392
379
  gap: 4,
380
+ minWidth: 0,
393
381
  fillWidth,
394
382
  children: [
395
383
  label && /* @__PURE__ */ jsx(InputLabel, {
@@ -401,7 +389,7 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
401
389
  body: dropdownBody,
402
390
  isOpen: visible,
403
391
  onClose: handleClose,
404
- minWidth: resolvedDropdownWidth ?? 200,
392
+ minWidth: 0,
405
393
  offset: [0, 3],
406
394
  fillWidth,
407
395
  noPadding: true,
@@ -417,27 +405,26 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
417
405
  onMouseEnter: handleMouseEnter,
418
406
  onMouseLeave: handleMouseLeave,
419
407
  onClick: handleToggle,
420
- children: [
421
- /* @__PURE__ */ jsx(StyledSearchInput, {
422
- ref: inputRef,
423
- $size: size,
424
- $isActive: visible ?? false,
425
- $isDisabled: effectiveIsDisabled,
426
- $isError: !!error,
427
- $width: width,
428
- $fillWidth: fillWidth,
429
- type: "text",
430
- placeholder,
431
- value: searchTerm,
432
- onChange: handleInputChange,
433
- onKeyDown: handleSearchKeyDown,
434
- autoComplete: "off",
435
- autoCorrect: "off",
436
- disabled: effectiveIsDisabled,
437
- onClick: (e) => e.stopPropagation()
438
- }),
439
- /* @__PURE__ */ jsx(Spacing, { left: 8 }),
440
- /* @__PURE__ */ jsx(FlexWrapper, { children: /* @__PURE__ */ jsx(Rotate, {
408
+ children: [/* @__PURE__ */ jsx(StyledSearchInput, {
409
+ ref: inputRef,
410
+ $size: size,
411
+ $isActive: visible ?? false,
412
+ $isDisabled: effectiveIsDisabled,
413
+ $isError: !!error,
414
+ $width: width,
415
+ $fillWidth: fillWidth,
416
+ type: "text",
417
+ placeholder,
418
+ value: searchTerm,
419
+ onChange: handleInputChange,
420
+ onKeyDown: handleSearchKeyDown,
421
+ autoComplete: "off",
422
+ autoCorrect: "off",
423
+ disabled: effectiveIsDisabled,
424
+ onClick: (e) => e.stopPropagation()
425
+ }), /* @__PURE__ */ jsx(FlexWrapper, {
426
+ shrink: 0,
427
+ children: /* @__PURE__ */ jsx(Rotate, {
441
428
  isRotated: visible,
442
429
  deg: -180,
443
430
  children: /* @__PURE__ */ jsx(Icon, {
@@ -445,8 +432,8 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
445
432
  size: getInputIconSize(size),
446
433
  variant: !effectiveIsDisabled && (isHovered || visible) ? IconVariant.SECONDARY : IconVariant.TERTIARY
447
434
  })
448
- }) })
449
- ]
435
+ })
436
+ })]
450
437
  }) : /* @__PURE__ */ jsxs(StyledSelectInput, {
451
438
  ref: triggerRef,
452
439
  $variant: variant,
@@ -465,26 +452,26 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
465
452
  "aria-haspopup": "listbox",
466
453
  "aria-expanded": visible,
467
454
  "aria-label": selectedOption ? selectedOption.label : placeholder,
468
- children: [
469
- /* @__PURE__ */ jsxs(FlexWrapper, {
470
- alignItems: AlignItems.CENTER,
471
- gap: 8,
472
- fillWidth: true,
473
- children: [selectedOption?.icon && /* @__PURE__ */ jsx(OptionIconSlot, { children: selectedOption.icon }), /* @__PURE__ */ jsx(FlexItem, {
474
- grow: 1,
475
- shrink: 1,
476
- minWidth: 0,
477
- children: /* @__PURE__ */ jsx(Text, {
478
- variant: textVariant,
479
- size: getInputTextSize(size),
480
- cursor: !effectiveIsDisabled ? "pointer" : "not-allowed",
481
- isEllipsis: true,
482
- children: selectedOption ? selectedOption.label : placeholder
483
- })
484
- })]
485
- }),
486
- /* @__PURE__ */ jsx(Spacing, { left: 8 }),
487
- /* @__PURE__ */ jsx(FlexWrapper, { children: /* @__PURE__ */ jsx(Rotate, {
455
+ children: [/* @__PURE__ */ jsxs(FlexWrapper, {
456
+ alignItems: AlignItems.CENTER,
457
+ gap: 8,
458
+ minWidth: 0,
459
+ grow: 1,
460
+ children: [selectedOption?.icon && /* @__PURE__ */ jsx(OptionIconSlot, { children: selectedOption.icon }), /* @__PURE__ */ jsx(FlexItem, {
461
+ grow: 1,
462
+ shrink: 1,
463
+ minWidth: 0,
464
+ children: /* @__PURE__ */ jsx(Text, {
465
+ variant: textVariant,
466
+ size: getInputTextSize(size),
467
+ cursor: !effectiveIsDisabled ? "pointer" : "not-allowed",
468
+ isEllipsis: true,
469
+ children: selectedOption ? selectedOption.label : placeholder
470
+ })
471
+ })]
472
+ }), /* @__PURE__ */ jsx(FlexWrapper, {
473
+ shrink: 0,
474
+ children: /* @__PURE__ */ jsx(Rotate, {
488
475
  isRotated: visible,
489
476
  deg: -180,
490
477
  children: /* @__PURE__ */ jsx(Icon, {
@@ -492,8 +479,8 @@ var SelectInput = ({ label, variant = InputVariant.PRIMARY, size = InputSize.MED
492
479
  size: getInputIconSize(size),
493
480
  variant: !effectiveIsDisabled && (isHovered || visible) ? IconVariant.SECONDARY : IconVariant.TERTIARY
494
481
  })
495
- }) })
496
- ]
482
+ })
483
+ })]
497
484
  })
498
485
  }),
499
486
  error && /* @__PURE__ */ jsx(Text, {
package/dist/styles.css CHANGED
@@ -95,12 +95,12 @@
95
95
  .s1902pw9{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;padding:var(--s1902pw9-0);height:var(--s1902pw9-1);width:var(--s1902pw9-2);cursor:var(--s1902pw9-3);opacity:var(--s1902pw9-4);background-color:var(--s1902pw9-5);border:0.5px solid var(--s1902pw9-6);border-radius:5px;-webkit-transition:border-color 0.075s ease-in-out;transition:border-color 0.075s ease-in-out;}.s1902pw9:hover{border-color:var(--s1902pw9-7);}
96
96
  .c179xo5d{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}
97
97
  .d60emtx{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;width:36px;height:36px;border:none;border-radius:4px;cursor:var(--d60emtx-0);opacity:var(--d60emtx-1);background-color:var(--d60emtx-2);border:var(--d60emtx-3);-webkit-transition:all 0.075s ease-in-out;transition:all 0.075s ease-in-out;}.d60emtx:hover:not(:disabled){background-color:var(--d60emtx-4);}.d60emtx:focus{outline:none;}
98
- .s1ecxi56{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;padding:var(--s1ecxi56-0);height:var(--s1ecxi56-1);width:var(--s1ecxi56-2);cursor:var(--s1ecxi56-3);opacity:var(--s1ecxi56-4);background-color:var(--s1ecxi56-5);border:0.5px solid var(--s1ecxi56-6);border-radius:4px;-webkit-transition:border-color 0.075s ease-in-out;transition:border-color 0.075s ease-in-out;}.s1ecxi56:hover{border:0.5px solid var(--s1ecxi56-7);}
99
- .s14m69un{-webkit-flex:1;-ms-flex:1;flex:1;outline:none;border:none;background:transparent;padding:0;margin:0;height:var(--s14m69un-0);color:var(--s14m69un-1);font-size:var(--s14m69un-2);line-height:var(--s14m69un-3);font-weight:var(--s14m69un-4);font-family:var(--s14m69un-5);}.s14m69un:disabled{cursor:not-allowed;}.s14m69un::-webkit-input-placeholder{color:var(--s14m69un-6);}.s14m69un::-moz-placeholder{color:var(--s14m69un-6);}.s14m69un:-ms-input-placeholder{color:var(--s14m69un-6);}.s14m69un::placeholder{color:var(--s14m69un-6);}
100
- .sbfl8n6{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-width:var(--sbfl8n6-0);max-height:300px;width:var(--sbfl8n6-1);}
101
- .sk260f0{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex:1;-ms-flex:1;flex:1;overflow-y:auto;min-height:0;width:var(--sk260f0-0);}
102
- .so10ras{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;width:100%;padding:8px;background:var(--so10ras-0);border:none;border-radius:4px;cursor:pointer;}.so10ras:hover{background-color:var(--so10ras-1);}.so10ras:focus{outline:none;background-color:var(--so10ras-1);}
103
- .poe2ind{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;width:100%;padding:8px;background:var(--poe2ind-0);border-radius:4px;border:none;cursor:pointer;}.poe2ind:hover{background-color:var(--poe2ind-1);}.poe2ind:focus{outline:none;background-color:var(--poe2ind-1);}
98
+ .s1ecxi56{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;box-sizing:border-box;min-width:0;gap:8px;padding:var(--s1ecxi56-0);height:var(--s1ecxi56-1);width:var(--s1ecxi56-2);cursor:var(--s1ecxi56-3);opacity:var(--s1ecxi56-4);background-color:var(--s1ecxi56-5);border:0.5px solid var(--s1ecxi56-6);border-radius:4px;-webkit-transition:border-color 0.075s ease-in-out;transition:border-color 0.075s ease-in-out;}.s1ecxi56:hover{border:0.5px solid var(--s1ecxi56-7);}
99
+ .s14m69un{-webkit-flex:1;-ms-flex:1;flex:1;min-width:0;text-overflow:ellipsis;outline:none;border:none;background:transparent;padding:0;margin:0;height:var(--s14m69un-0);color:var(--s14m69un-1);font-size:var(--s14m69un-2);line-height:var(--s14m69un-3);font-weight:var(--s14m69un-4);font-family:var(--s14m69un-5);}.s14m69un:disabled{cursor:not-allowed;}.s14m69un::-webkit-input-placeholder{color:var(--s14m69un-6);}.s14m69un::-moz-placeholder{color:var(--s14m69un-6);}.s14m69un:-ms-input-placeholder{color:var(--s14m69un-6);}.s14m69un::placeholder{color:var(--s14m69un-6);}
100
+ .sbfl8n6{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-width:var(--sbfl8n6-0);max-width:calc(100vw - 16px);max-height:300px;width:var(--sbfl8n6-1);}
101
+ .sk260f0{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex:1;-ms-flex:1;flex:1;overflow-y:auto;min-height:0;width:100%;}
102
+ .so10ras{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;gap:8px;width:100%;padding:8px;background:var(--so10ras-0);border:none;border-radius:4px;cursor:pointer;}.so10ras:hover{background-color:var(--so10ras-1);}.so10ras:focus{outline:none;background-color:var(--so10ras-1);}
103
+ .poe2ind{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;gap:8px;width:100%;padding:8px;background:var(--poe2ind-0);border-radius:4px;border:none;cursor:pointer;}.poe2ind:hover{background-color:var(--poe2ind-1);}.poe2ind:focus{outline:none;background-color:var(--poe2ind-1);}
104
104
  .o9236d8{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}
105
105
  .sf4kgcu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:space-between;-webkit-justify-content:space-between;justify-content:space-between;gap:4px;padding:var(--sf4kgcu-0);height:var(--sf4kgcu-1);width:var(--sf4kgcu-2);cursor:var(--sf4kgcu-3);opacity:var(--sf4kgcu-4);background-color:var(--sf4kgcu-5);border:0.5px solid var(--sf4kgcu-6);border-radius:4px;-webkit-transition:border-color 0.075s ease-in-out;transition:border-color 0.075s ease-in-out;}.sf4kgcu:hover{border:0.5px solid var(--sf4kgcu-7);}
106
106
  .s15yoqwu{-webkit-flex:1;-ms-flex:1;flex:1;outline:none;border:none;background:transparent;padding:0;margin:0;height:var(--s15yoqwu-0);color:var(--s15yoqwu-1);font-size:var(--s15yoqwu-2);line-height:var(--s15yoqwu-3);font-weight:var(--s15yoqwu-4);font-family:var(--s15yoqwu-5);}.s15yoqwu:disabled{cursor:not-allowed;}.s15yoqwu::-webkit-input-placeholder{color:var(--s15yoqwu-6);}.s15yoqwu::-moz-placeholder{color:var(--s15yoqwu-6);}.s15yoqwu:-ms-input-placeholder{color:var(--s15yoqwu-6);}.s15yoqwu::placeholder{color:var(--s15yoqwu-6);}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@galaxy-io/dls",
3
- "version": "1.5.14",
3
+ "version": "1.5.16",
4
4
  "description": "Galaxy Design Language System",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",