@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.
- package/dist/charts/BarChart.d.ts +26 -1
- package/dist/charts/BarChart.js +5 -3
- package/dist/charts/barChartGeometry.d.ts +7 -1
- package/dist/charts/barChartGeometry.js +84 -5
- package/dist/inputs/SelectInput.d.ts +1 -1
- package/dist/inputs/SelectInput.js +102 -115
- package/dist/styles.css +6 -6
- package/package.json +1 -1
|
@@ -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;
|
package/dist/charts/BarChart.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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 =
|
|
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.
|
|
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 = () => ({ $
|
|
76
|
-
var _exp15 = () => ({ $
|
|
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
|
|
90
|
+
var _exp16 = () => ({ theme, $isSelected, $isFocused }) => {
|
|
97
91
|
if ($isSelected || $isFocused) return theme.color.background.secondary;
|
|
98
92
|
return "transparent";
|
|
99
93
|
};
|
|
100
|
-
var
|
|
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": [
|
|
107
|
-
"so10ras-1": [
|
|
100
|
+
"so10ras-0": [_exp16()],
|
|
101
|
+
"so10ras-1": [_exp18()]
|
|
108
102
|
}
|
|
109
103
|
}));
|
|
110
|
-
var
|
|
104
|
+
var _exp19 = () => ({ theme, $isSelected, $isFocused }) => {
|
|
111
105
|
if ($isSelected || $isFocused) return theme.color.background.tertiary;
|
|
112
106
|
return "transparent";
|
|
113
107
|
};
|
|
114
|
-
var
|
|
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": [
|
|
121
|
-
"poe2ind-1": [
|
|
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
|
|
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
|
-
$
|
|
289
|
-
$width:
|
|
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
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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:
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
/* @__PURE__ */ jsx(
|
|
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
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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:
|
|
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);}
|