@carto/ps-react-ui 4.8.0 → 4.9.0
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/range-l4fNHLEg.js +213 -0
- package/dist/range-l4fNHLEg.js.map +1 -0
- package/dist/resolve-theme-color-BdojIw0K.js +47 -0
- package/dist/resolve-theme-color-BdojIw0K.js.map +1 -0
- package/dist/table-CQCAnDLb.js +388 -0
- package/dist/table-CQCAnDLb.js.map +1 -0
- package/dist/types/widgets-v2/bar/types.d.ts +8 -3
- package/dist/types/widgets-v2/category/types.d.ts +8 -4
- package/dist/types/widgets-v2/formula/types.d.ts +10 -7
- package/dist/types/widgets-v2/histogram/types.d.ts +7 -3
- package/dist/types/widgets-v2/index.d.ts +1 -0
- package/dist/types/widgets-v2/pie/types.d.ts +10 -3
- package/dist/types/widgets-v2/range/range-ui.d.ts +12 -4
- package/dist/types/widgets-v2/range/range.d.ts +13 -8
- package/dist/types/widgets-v2/scatterplot/types.d.ts +7 -3
- package/dist/types/widgets-v2/table/style.d.ts +0 -4
- package/dist/types/widgets-v2/table/table-ui.d.ts +7 -1
- package/dist/types/widgets-v2/table/table.d.ts +1 -1
- package/dist/types/widgets-v2/table/types.d.ts +13 -2
- package/dist/types/widgets-v2/timeseries/types.d.ts +7 -3
- package/dist/types/widgets-v2/types.d.ts +25 -0
- package/dist/types/widgets-v2/utils/index.d.ts +1 -0
- package/dist/types/widgets-v2/utils/resolve-theme-color.d.ts +18 -0
- package/dist/types/widgets-v2/utils/resolve-theme-color.test.d.ts +1 -0
- package/dist/widgets-v2/bar.js +58 -55
- package/dist/widgets-v2/bar.js.map +1 -1
- package/dist/widgets-v2/histogram.js +65 -62
- package/dist/widgets-v2/histogram.js.map +1 -1
- package/dist/widgets-v2/pie.js +100 -94
- package/dist/widgets-v2/pie.js.map +1 -1
- package/dist/widgets-v2/range.js +1 -1
- package/dist/widgets-v2/scatterplot.js +107 -101
- package/dist/widgets-v2/scatterplot.js.map +1 -1
- package/dist/widgets-v2/table.js +2 -2
- package/dist/widgets-v2/timeseries.js +85 -79
- package/dist/widgets-v2/timeseries.js.map +1 -1
- package/dist/widgets-v2/utils.js +4 -3
- package/dist/widgets-v2.js +2 -2
- package/dist/widgets-v2.js.map +1 -1
- package/package.json +3 -3
- package/src/widgets-v2/bar/options.test.ts +19 -2
- package/src/widgets-v2/bar/options.ts +9 -3
- package/src/widgets-v2/bar/types.ts +8 -3
- package/src/widgets-v2/category/types.ts +9 -4
- package/src/widgets-v2/formula/types.ts +11 -7
- package/src/widgets-v2/histogram/options.test.ts +16 -2
- package/src/widgets-v2/histogram/options.ts +5 -4
- package/src/widgets-v2/histogram/types.ts +7 -3
- package/src/widgets-v2/index.ts +3 -0
- package/src/widgets-v2/pie/options.test.ts +20 -4
- package/src/widgets-v2/pie/options.ts +21 -17
- package/src/widgets-v2/pie/types.ts +10 -3
- package/src/widgets-v2/range/range-ui.test.tsx +8 -2
- package/src/widgets-v2/range/range-ui.tsx +81 -14
- package/src/widgets-v2/range/range.tsx +14 -8
- package/src/widgets-v2/scatterplot/options.test.ts +15 -3
- package/src/widgets-v2/scatterplot/options.ts +15 -11
- package/src/widgets-v2/scatterplot/types.ts +7 -3
- package/src/widgets-v2/table/style.ts +2 -5
- package/src/widgets-v2/table/table-ui.tsx +40 -7
- package/src/widgets-v2/table/table.tsx +6 -1
- package/src/widgets-v2/table/types.ts +13 -2
- package/src/widgets-v2/timeseries/options.test.ts +17 -2
- package/src/widgets-v2/timeseries/options.ts +10 -3
- package/src/widgets-v2/timeseries/types.ts +7 -3
- package/src/widgets-v2/types.ts +25 -0
- package/src/widgets-v2/utils/index.ts +1 -0
- package/src/widgets-v2/utils/resolve-theme-color.test.ts +43 -0
- package/src/widgets-v2/utils/resolve-theme-color.ts +34 -0
- package/dist/merge-options-DCkkHZIf.js +0 -34
- package/dist/merge-options-DCkkHZIf.js.map +0 -1
- package/dist/range-DsqTjSpg.js +0 -186
- package/dist/range-DsqTjSpg.js.map +0 -1
- package/dist/table-HIpXuq4G.js +0 -390
- package/dist/table-HIpXuq4G.js.map +0 -1
|
@@ -5,12 +5,9 @@ export const styles = {
|
|
|
5
5
|
width: '100%',
|
|
6
6
|
overflowX: 'auto',
|
|
7
7
|
},
|
|
8
|
-
|
|
9
|
-
* Minimum table width so columns don't collapse to unreadable widths on
|
|
10
|
-
* narrow widget shells. Mirrors v1.
|
|
11
|
-
*/
|
|
8
|
+
|
|
12
9
|
table: {
|
|
13
|
-
minWidth:
|
|
10
|
+
minWidth: 0,
|
|
14
11
|
},
|
|
15
12
|
headerCell: {
|
|
16
13
|
fontWeight: 600,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo } from 'react'
|
|
1
|
+
import { useCallback, useMemo } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
Checkbox,
|
|
@@ -38,6 +38,12 @@ export interface TableUIProps<T extends TableRow = TableRow> {
|
|
|
38
38
|
pageSize: number
|
|
39
39
|
pageSizeOptions?: readonly number[]
|
|
40
40
|
sort?: TableSortState
|
|
41
|
+
/**
|
|
42
|
+
* Column name to use as the row identity. Drives selection lookup,
|
|
43
|
+
* React keys, and aria labels. Defaults to `'id'` — point it at
|
|
44
|
+
* another column when your rows don't carry an `id` field.
|
|
45
|
+
*/
|
|
46
|
+
keyColumn?: string
|
|
41
47
|
/** Selected row ids. Destination-owned. */
|
|
42
48
|
selection?: readonly (string | number)[]
|
|
43
49
|
selectable?: boolean
|
|
@@ -71,6 +77,7 @@ export function TableUI<T extends TableRow = TableRow>({
|
|
|
71
77
|
pageSize,
|
|
72
78
|
pageSizeOptions = DEFAULT_TABLE_PAGE_SIZE_OPTIONS,
|
|
73
79
|
sort,
|
|
80
|
+
keyColumn = 'id',
|
|
74
81
|
selection,
|
|
75
82
|
selectable = false,
|
|
76
83
|
onSortChange,
|
|
@@ -83,6 +90,20 @@ export function TableUI<T extends TableRow = TableRow>({
|
|
|
83
90
|
emptyContent,
|
|
84
91
|
size,
|
|
85
92
|
}: TableUIProps<T>) {
|
|
93
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
94
|
+
// Dev-time guard: a nullish identity collapses every row into the
|
|
95
|
+
// same selection-set entry, which manifests as "click one → all
|
|
96
|
+
// appear selected". Surface it loudly instead of silently degrading.
|
|
97
|
+
const missing = rows.some((r) => r[keyColumn] == null)
|
|
98
|
+
if (missing) {
|
|
99
|
+
// eslint-disable-next-line no-console
|
|
100
|
+
console.error(
|
|
101
|
+
`<TableUI>: rows are missing the identity column \`${keyColumn}\`. ` +
|
|
102
|
+
'Set the `keyColumn` prop to a column present on every row, or ' +
|
|
103
|
+
'add the column to the data.',
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
86
107
|
const _labels = useMemo(
|
|
87
108
|
() => ({ ...DEFAULT_TABLE_LABELS, ...labels }),
|
|
88
109
|
[labels],
|
|
@@ -106,7 +127,18 @@ export function TableUI<T extends TableRow = TableRow>({
|
|
|
106
127
|
() => new Set<string | number>(selection ?? []),
|
|
107
128
|
[selection],
|
|
108
129
|
)
|
|
109
|
-
|
|
130
|
+
// Resolve each row's identity from `keyColumn`, falling back to the row's
|
|
131
|
+
// index when the cell is nullish. The dev-time guard above surfaces the
|
|
132
|
+
// misconfiguration loudly, but in production we must NOT collapse every
|
|
133
|
+
// nullish-keyed row into the same selection-set entry (that's the
|
|
134
|
+
// "click one → all selected" bug) — a per-index fallback keeps ids
|
|
135
|
+
// distinct and React keys stable for a given page.
|
|
136
|
+
const resolveRowId = useCallback(
|
|
137
|
+
(row: T, index: number): string | number =>
|
|
138
|
+
(row[keyColumn] ?? index) as string | number,
|
|
139
|
+
[keyColumn],
|
|
140
|
+
)
|
|
141
|
+
const pageRowIds = useMemo(() => rows.map(resolveRowId), [rows, resolveRowId])
|
|
110
142
|
const allOnPageSelected =
|
|
111
143
|
pageRowIds.length > 0 && pageRowIds.every((id) => selectionSet.has(id))
|
|
112
144
|
const someOnPageSelected =
|
|
@@ -197,11 +229,12 @@ export function TableUI<T extends TableRow = TableRow>({
|
|
|
197
229
|
</TableCell>
|
|
198
230
|
</MuiTableRow>
|
|
199
231
|
) : (
|
|
200
|
-
rows.map((row) => {
|
|
201
|
-
const
|
|
232
|
+
rows.map((row, index) => {
|
|
233
|
+
const rowId = resolveRowId(row, index)
|
|
234
|
+
const isSelected = selectionSet.has(rowId)
|
|
202
235
|
return (
|
|
203
236
|
<MuiTableRow
|
|
204
|
-
key={
|
|
237
|
+
key={rowId}
|
|
205
238
|
hover
|
|
206
239
|
selected={isSelected}
|
|
207
240
|
onClick={() => onRowClick?.(row)}
|
|
@@ -218,10 +251,10 @@ export function TableUI<T extends TableRow = TableRow>({
|
|
|
218
251
|
checked={isSelected}
|
|
219
252
|
onClick={(e) => {
|
|
220
253
|
e.stopPropagation()
|
|
221
|
-
handleSelectRow(
|
|
254
|
+
handleSelectRow(rowId)
|
|
222
255
|
}}
|
|
223
256
|
inputProps={{
|
|
224
|
-
'aria-label': _labels.selectRow(
|
|
257
|
+
'aria-label': _labels.selectRow(rowId),
|
|
225
258
|
}}
|
|
226
259
|
/>
|
|
227
260
|
</TableCell>
|
|
@@ -17,7 +17,12 @@ import { deriveVisibleRows, resolveColumns } from './helpers'
|
|
|
17
17
|
|
|
18
18
|
export interface TableProps<T extends TableRow = TableRow> extends Pick<
|
|
19
19
|
TableUIProps<T>,
|
|
20
|
-
|
|
20
|
+
| 'pageSizeOptions'
|
|
21
|
+
| 'selectable'
|
|
22
|
+
| 'labels'
|
|
23
|
+
| 'emptyContent'
|
|
24
|
+
| 'size'
|
|
25
|
+
| 'keyColumn'
|
|
21
26
|
> {
|
|
22
27
|
/**
|
|
23
28
|
* Column definitions. Order can be overridden by ChangeColumn via the
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import type { ReactNode } from 'react'
|
|
2
2
|
import type { WidgetState } from '../stores'
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Single row of tabular data.
|
|
6
|
+
*
|
|
7
|
+
* The default row-identity column is `id`. Consumers that don't have a
|
|
8
|
+
* literal `id` field can point `<Table>` / `<TableUI>` at a different
|
|
9
|
+
* column via the `keyColumn` prop; the library reads `row[keyColumn]`
|
|
10
|
+
* for selection lookup, React keys, and aria labels.
|
|
11
|
+
*/
|
|
5
12
|
export interface TableRow extends Record<string, unknown> {
|
|
6
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Default row identity. Required when no `keyColumn` is configured.
|
|
15
|
+
* Omit when wiring `keyColumn` to a different column.
|
|
16
|
+
*/
|
|
17
|
+
id?: string | number
|
|
7
18
|
}
|
|
8
19
|
|
|
9
20
|
export type TableWidgetData = readonly TableRow[]
|
|
@@ -194,10 +194,10 @@ describe('createTimeseriesOptionFactory', () => {
|
|
|
194
194
|
expect(multi.grid.bottom).toBe(56)
|
|
195
195
|
})
|
|
196
196
|
|
|
197
|
-
it('uses
|
|
197
|
+
it('uses series[i].name for series.name when provided', () => {
|
|
198
198
|
const merge = createTimeseriesOptionFactory({
|
|
199
199
|
theme,
|
|
200
|
-
|
|
200
|
+
series: [{ name: '2024' }, { name: '2025' }],
|
|
201
201
|
})
|
|
202
202
|
const out = merge({}, [
|
|
203
203
|
[{ name: 'a', value: 1 }],
|
|
@@ -207,6 +207,21 @@ describe('createTimeseriesOptionFactory', () => {
|
|
|
207
207
|
expect(out.series[1]?.name).toBe('2025')
|
|
208
208
|
})
|
|
209
209
|
|
|
210
|
+
it('applies series[i].color as both root color and lineStyle.color', () => {
|
|
211
|
+
const merge = createTimeseriesOptionFactory({
|
|
212
|
+
theme,
|
|
213
|
+
series: [{ name: '2024', color: '#ff0000' }, { name: '2025' }],
|
|
214
|
+
})
|
|
215
|
+
const out = merge({}, [
|
|
216
|
+
[{ name: 'a', value: 1 }],
|
|
217
|
+
[{ name: 'a', value: 2 }],
|
|
218
|
+
]) as { series: { color?: string; lineStyle?: { color?: string } }[] }
|
|
219
|
+
expect(out.series[0]?.color).toBe('#ff0000')
|
|
220
|
+
expect(out.series[0]?.lineStyle?.color).toBe('#ff0000')
|
|
221
|
+
expect(out.series[1]?.color).toBeUndefined()
|
|
222
|
+
expect(out.series[1]?.lineStyle?.color).toBeUndefined()
|
|
223
|
+
})
|
|
224
|
+
|
|
210
225
|
it('returns empty dataset/series for empty data', () => {
|
|
211
226
|
const merge = createTimeseriesOptionFactory({ theme })
|
|
212
227
|
const out = merge({}, []) as { dataset: unknown[]; series: unknown[] }
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from '../../widgets/utils/chart-config'
|
|
11
11
|
import { ZOOM_LAYOUT } from '../actions/zoom-toggle'
|
|
12
12
|
import type { OptionFactory } from '../echart'
|
|
13
|
-
import { mergeOptions } from '../utils'
|
|
13
|
+
import { mergeOptions, resolveThemeColor } from '../utils'
|
|
14
14
|
import { positionDataZoomForLegend } from '../utils/data-zoom-layout'
|
|
15
15
|
import type {
|
|
16
16
|
TimeseriesEChartsOption,
|
|
@@ -152,7 +152,7 @@ export function createTimeseriesOptionFactory(
|
|
|
152
152
|
options: TimeseriesOptionFactoryInput,
|
|
153
153
|
): OptionFactory {
|
|
154
154
|
const { theme, formatter, labelFormatter, optionsOverride } = options
|
|
155
|
-
const
|
|
155
|
+
const series = options.series
|
|
156
156
|
const smooth = options.smooth ?? true
|
|
157
157
|
const area = options.area ?? false
|
|
158
158
|
const selection = options.selection
|
|
@@ -250,11 +250,15 @@ export function createTimeseriesOptionFactory(
|
|
|
250
250
|
const template =
|
|
251
251
|
(seriesTemplates[i] as object | undefined) ??
|
|
252
252
|
(broadcastTemplate as object)
|
|
253
|
+
// For line series, set BOTH `series[i].color` (legend swatch +
|
|
254
|
+
// markers) AND `series[i].lineStyle.color` (the line itself) so
|
|
255
|
+
// the override paints everywhere a series has a colour slot.
|
|
256
|
+
const overrideColor = resolveThemeColor(theme, series?.[i]?.color)
|
|
253
257
|
return {
|
|
254
258
|
...(typeof template === 'object' ? template : {}),
|
|
255
259
|
type: 'line' as const,
|
|
256
260
|
datasetIndex: i,
|
|
257
|
-
name:
|
|
261
|
+
name: series?.[i]?.name ?? `Series ${i + 1}`,
|
|
258
262
|
encode: { x: 'name', y: 'value' },
|
|
259
263
|
smooth,
|
|
260
264
|
// When a selection is active, surface markers so the per-point
|
|
@@ -264,6 +268,9 @@ export function createTimeseriesOptionFactory(
|
|
|
264
268
|
...(area ? { areaStyle: {} } : {}),
|
|
265
269
|
emphasis: { focus: 'series' },
|
|
266
270
|
itemStyle: dimItemStyle,
|
|
271
|
+
...(overrideColor
|
|
272
|
+
? { color: overrideColor, lineStyle: { color: overrideColor } }
|
|
273
|
+
: {}),
|
|
267
274
|
}
|
|
268
275
|
}),
|
|
269
276
|
legend: { ...baseLegend, show: hasLegend },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Theme } from '@mui/material'
|
|
2
2
|
import type { EChartsOption } from 'echarts'
|
|
3
|
+
import type { WidgetSeries } from '../types'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* A single point on a time series. `name` is the time coordinate — accepts a
|
|
@@ -26,7 +27,7 @@ export interface TimeseriesOptionsInput {
|
|
|
26
27
|
* Combined inputs for the timeseries option factory creator. Carries
|
|
27
28
|
* everything the widget needs across BOTH phases — the structural-build
|
|
28
29
|
* (`theme`, `formatter`, `labelFormatter`, `optionsOverride`) AND the
|
|
29
|
-
* data merge (`
|
|
30
|
+
* data merge (`series`, `smooth`, `area`, `selection`).
|
|
30
31
|
*/
|
|
31
32
|
export interface TimeseriesOptionFactoryInput {
|
|
32
33
|
theme: Theme
|
|
@@ -38,8 +39,11 @@ export interface TimeseriesOptionFactoryInput {
|
|
|
38
39
|
* RelativeData's reactive formatter swaps.
|
|
39
40
|
*/
|
|
40
41
|
labelFormatter?: (value: Date) => string
|
|
41
|
-
/**
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Per-series metadata — drives the legend, `series[i].name`, and
|
|
44
|
+
* (when `color` is set) per-series line + marker colour overrides.
|
|
45
|
+
*/
|
|
46
|
+
series?: readonly WidgetSeries[]
|
|
43
47
|
/** Smooth lines (default `true`). */
|
|
44
48
|
smooth?: boolean
|
|
45
49
|
/** Filled area below each line (default `false`). */
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical cross-widget series metadata.
|
|
3
|
+
*
|
|
4
|
+
* Every widget that can carry multiple series (Bar, Pie, Histogram,
|
|
5
|
+
* Scatterplot, Timeseries, Category, Formula, Spread) accepts a
|
|
6
|
+
* `series: readonly WidgetSeries[]` prop. The `name` drives legends,
|
|
7
|
+
* tooltips, and category-row avatars; the optional `color` overrides
|
|
8
|
+
* the default palette assignment.
|
|
9
|
+
*
|
|
10
|
+
* For backward compatibility, the widget-specific names
|
|
11
|
+
* (`FormulaSeries`, `CategorySeriesConfig`) are kept as type aliases of
|
|
12
|
+
* `WidgetSeries` — see `formula/types.ts` and `category/types.ts`.
|
|
13
|
+
*
|
|
14
|
+
* Colours accept MUI theme paths (e.g. `'primary.main'`) as well as raw
|
|
15
|
+
* CSS strings (`'#ff0000'`, `'rgb(…)'`). The echart-based widgets
|
|
16
|
+
* resolve them through `resolveThemeColor` (see
|
|
17
|
+
* `widgets-v2/utils/resolve-theme-color.ts`); Category and Formula/Spread
|
|
18
|
+
* resolve them implicitly via MUI's `sx` prop.
|
|
19
|
+
*/
|
|
20
|
+
export interface WidgetSeries {
|
|
21
|
+
/** Display name — drives legend, tooltip, and avatar glyphs. */
|
|
22
|
+
name: string
|
|
23
|
+
/** Optional colour override. MUI theme path or raw CSS string. */
|
|
24
|
+
color?: string
|
|
25
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { createTheme } from '@mui/material'
|
|
3
|
+
import { resolveThemeColor } from './resolve-theme-color'
|
|
4
|
+
|
|
5
|
+
describe('resolveThemeColor', () => {
|
|
6
|
+
const theme = createTheme({
|
|
7
|
+
palette: {
|
|
8
|
+
primary: { main: '#1976d2', dark: '#0d47a1' },
|
|
9
|
+
secondary: { main: '#9c27b0' },
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('returns undefined when the input is undefined', () => {
|
|
14
|
+
expect(resolveThemeColor(theme, undefined)).toBeUndefined()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('passes raw CSS colors through unchanged', () => {
|
|
18
|
+
expect(resolveThemeColor(theme, '#ff0000')).toBe('#ff0000')
|
|
19
|
+
expect(resolveThemeColor(theme, 'rgb(255, 0, 0)')).toBe('rgb(255, 0, 0)')
|
|
20
|
+
expect(resolveThemeColor(theme, 'red')).toBe('red')
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('resolves dotted MUI theme palette paths', () => {
|
|
24
|
+
expect(resolveThemeColor(theme, 'primary.main')).toBe('#1976d2')
|
|
25
|
+
expect(resolveThemeColor(theme, 'primary.dark')).toBe('#0d47a1')
|
|
26
|
+
expect(resolveThemeColor(theme, 'secondary.main')).toBe('#9c27b0')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('returns the raw input when the theme path does not resolve', () => {
|
|
30
|
+
// Non-existent palette path → caller's responsibility to recover; we
|
|
31
|
+
// pass the string through so ECharts can at least attempt to parse it.
|
|
32
|
+
expect(resolveThemeColor(theme, 'primary.does-not-exist')).toBe(
|
|
33
|
+
'primary.does-not-exist',
|
|
34
|
+
)
|
|
35
|
+
expect(resolveThemeColor(theme, 'nope.anywhere')).toBe('nope.anywhere')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('handles a path that traverses but yields a non-string', () => {
|
|
39
|
+
// `primary` itself is an object, not a string — we return the raw
|
|
40
|
+
// input rather than `[object Object]`.
|
|
41
|
+
expect(resolveThemeColor(theme, 'primary')).toBe('primary')
|
|
42
|
+
})
|
|
43
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Theme } from '@mui/material'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a colour string against the MUI theme palette.
|
|
5
|
+
*
|
|
6
|
+
* - `'primary.main'`, `'secondary.dark'`, `'success.contrastText'`, … →
|
|
7
|
+
* walks `theme.palette` along the dot-separated path and returns the
|
|
8
|
+
* resolved string when traversal succeeds.
|
|
9
|
+
* - `'#ff0000'`, `'rgb(255, 0, 0)'`, `'red'` → returned as-is (assumed
|
|
10
|
+
* raw CSS; ECharts consumes them directly).
|
|
11
|
+
* - `undefined` → `undefined` (callers fall back to ECharts' palette).
|
|
12
|
+
*
|
|
13
|
+
* Used by the echart option factories (Bar, Pie, Histogram, Scatterplot,
|
|
14
|
+
* Timeseries) so per-series colours specified as theme paths in the
|
|
15
|
+
* unified `WidgetSeries` shape paint correctly. Category, Formula, and
|
|
16
|
+
* Spread render colours through MUI's `sx` resolver, which already
|
|
17
|
+
* handles theme paths — they don't need this helper.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveThemeColor(
|
|
20
|
+
theme: Theme,
|
|
21
|
+
raw: string | undefined,
|
|
22
|
+
): string | undefined {
|
|
23
|
+
if (raw == null) return undefined
|
|
24
|
+
if (!raw.includes('.')) return raw
|
|
25
|
+
const parts = raw.split('.')
|
|
26
|
+
let cursor: unknown = theme.palette
|
|
27
|
+
for (const part of parts) {
|
|
28
|
+
if (cursor == null || typeof cursor !== 'object') {
|
|
29
|
+
return raw
|
|
30
|
+
}
|
|
31
|
+
cursor = (cursor as Record<string, unknown>)[part]
|
|
32
|
+
}
|
|
33
|
+
return typeof cursor === 'string' ? cursor : raw
|
|
34
|
+
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
function u(t, n) {
|
|
2
|
-
if (!n) return t;
|
|
3
|
-
const c = {
|
|
4
|
-
...t
|
|
5
|
-
};
|
|
6
|
-
for (const r of Object.keys(n)) {
|
|
7
|
-
const e = t[r], o = n[r];
|
|
8
|
-
o !== void 0 && (c[r] = f(e, o));
|
|
9
|
-
}
|
|
10
|
-
return c;
|
|
11
|
-
}
|
|
12
|
-
function f(t, n) {
|
|
13
|
-
if (Array.isArray(t) && Array.isArray(n)) {
|
|
14
|
-
const c = Math.max(t.length, n.length), r = new Array(c);
|
|
15
|
-
for (let e = 0; e < c; e++) {
|
|
16
|
-
const o = t[e], i = n[e];
|
|
17
|
-
i === void 0 ? r[e] = o : o === void 0 ? r[e] = i : r[e] = f(o, i);
|
|
18
|
-
}
|
|
19
|
-
return r;
|
|
20
|
-
}
|
|
21
|
-
return s(t) && s(n) ? {
|
|
22
|
-
...t,
|
|
23
|
-
...n
|
|
24
|
-
} : n;
|
|
25
|
-
}
|
|
26
|
-
function s(t) {
|
|
27
|
-
if (t === null || typeof t != "object") return !1;
|
|
28
|
-
const n = Object.getPrototypeOf(t);
|
|
29
|
-
return n === Object.prototype || n === null;
|
|
30
|
-
}
|
|
31
|
-
export {
|
|
32
|
-
u as m
|
|
33
|
-
};
|
|
34
|
-
//# sourceMappingURL=merge-options-DCkkHZIf.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"merge-options-DCkkHZIf.js","sources":["../src/widgets-v2/utils/merge-options.ts"],"sourcesContent":["/**\n * Shallow-merges two ECharts option objects:\n * - Top-level keys from both are combined.\n * - Arrays are merged by index (element-wise shallow merge, primitive override).\n * - Plain objects are shallow-merged.\n * - Primitives are overridden by the override value.\n *\n * Designed for the two-stage memoization pattern: first build a base option\n * object from data + theme + formatters, then call `mergeOptions(base, override)`\n * inside a second `useMemo` keyed on `[base, override]`.\n */\nexport function mergeOptions<T extends Record<string, unknown>>(\n base: T,\n override?: Partial<T>,\n): T {\n if (!override) return base\n const out: Record<string, unknown> = { ...base }\n for (const key of Object.keys(override) as (keyof T)[]) {\n const a = base[key]\n const b = override[key]\n if (b === undefined) continue\n out[key as string] = mergeValue(a, b)\n }\n return out as T\n}\n\nfunction mergeValue(a: unknown, b: unknown): unknown {\n if (Array.isArray(a) && Array.isArray(b)) {\n const len = Math.max(a.length, b.length)\n const result = new Array<unknown>(len)\n for (let i = 0; i < len; i++) {\n const av: unknown = a[i]\n const bv: unknown = b[i]\n if (bv === undefined) result[i] = av\n else if (av === undefined) result[i] = bv\n else result[i] = mergeValue(av, bv)\n }\n return result\n }\n if (isPlainObject(a) && isPlainObject(b)) {\n return { ...a, ...b }\n }\n return b\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false\n const proto = Object.getPrototypeOf(v) as unknown\n return proto === Object.prototype || proto === null\n}\n"],"names":["mergeOptions","base","override","out","key","Object","keys","a","b","undefined","mergeValue","Array","isArray","len","Math","max","length","result","i","av","bv","isPlainObject","v","proto","getPrototypeOf","prototype"],"mappings":"AAWO,SAASA,EACdC,GACAC,GACG;AACH,MAAI,CAACA,EAAU,QAAOD;AACtB,QAAME,IAA+B;AAAA,IAAE,GAAGF;AAAAA,EAAAA;AAC1C,aAAWG,KAAOC,OAAOC,KAAKJ,CAAQ,GAAkB;AACtD,UAAMK,IAAIN,EAAKG,CAAG,GACZI,IAAIN,EAASE,CAAG;AACtB,IAAII,MAAMC,WACVN,EAAIC,CAAa,IAAIM,EAAWH,GAAGC,CAAC;AAAA,EACtC;AACA,SAAOL;AACT;AAEA,SAASO,EAAWH,GAAYC,GAAqB;AACnD,MAAIG,MAAMC,QAAQL,CAAC,KAAKI,MAAMC,QAAQJ,CAAC,GAAG;AACxC,UAAMK,IAAMC,KAAKC,IAAIR,EAAES,QAAQR,EAAEQ,MAAM,GACjCC,IAAS,IAAIN,MAAeE,CAAG;AACrC,aAASK,IAAI,GAAGA,IAAIL,GAAKK,KAAK;AAC5B,YAAMC,IAAcZ,EAAEW,CAAC,GACjBE,IAAcZ,EAAEU,CAAC;AACvB,MAAIE,MAAOX,SAAWQ,EAAOC,CAAC,IAAIC,IACzBA,MAAOV,SAAWQ,EAAOC,CAAC,IAAIE,IAClCH,EAAOC,CAAC,IAAIR,EAAWS,GAAIC,CAAE;AAAA,IACpC;AACA,WAAOH;AAAAA,EACT;AACA,SAAII,EAAcd,CAAC,KAAKc,EAAcb,CAAC,IAC9B;AAAA,IAAE,GAAGD;AAAAA,IAAG,GAAGC;AAAAA,EAAAA,IAEbA;AACT;AAEA,SAASa,EAAcC,GAA0C;AAC/D,MAAIA,MAAM,QAAQ,OAAOA,KAAM,SAAU,QAAO;AAChD,QAAMC,IAAQlB,OAAOmB,eAAeF,CAAC;AACrC,SAAOC,MAAUlB,OAAOoB,aAAaF,MAAU;AACjD;"}
|
package/dist/range-DsqTjSpg.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { jsx as v, jsxs as N } from "react/jsx-runtime";
|
|
2
|
-
import { c as _ } from "react/compiler-runtime";
|
|
3
|
-
import { u as O } from "./widget-context-DTGO0Yta.js";
|
|
4
|
-
import { u as P } from "./widget-store-registry-_W4Z4xp-.js";
|
|
5
|
-
import { useState as z } from "react";
|
|
6
|
-
import "zustand";
|
|
7
|
-
import { Box as B, Slider as U, Typography as q, TextField as G } from "@mui/material";
|
|
8
|
-
const $ = {
|
|
9
|
-
root: {
|
|
10
|
-
display: "flex",
|
|
11
|
-
flexDirection: "column",
|
|
12
|
-
gap: 3,
|
|
13
|
-
py: 1
|
|
14
|
-
},
|
|
15
|
-
item: {
|
|
16
|
-
display: "flex",
|
|
17
|
-
flexDirection: "column",
|
|
18
|
-
gap: 1.5
|
|
19
|
-
},
|
|
20
|
-
sliderContainer: {
|
|
21
|
-
display: "flex",
|
|
22
|
-
flexDirection: "column",
|
|
23
|
-
gap: 1,
|
|
24
|
-
px: 1
|
|
25
|
-
},
|
|
26
|
-
slider: {
|
|
27
|
-
width: "100%",
|
|
28
|
-
"&.Mui-disabled": {
|
|
29
|
-
color: (a) => a.palette.text.disabled
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
inputsRow: {
|
|
33
|
-
display: "flex",
|
|
34
|
-
gap: 2,
|
|
35
|
-
alignItems: "center"
|
|
36
|
-
},
|
|
37
|
-
input: {
|
|
38
|
-
flex: 1,
|
|
39
|
-
"& .MuiInputBase-input": {
|
|
40
|
-
textAlign: "center"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
note: {
|
|
44
|
-
color: "text.secondary"
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
function H(a) {
|
|
48
|
-
const e = _(9), {
|
|
49
|
-
items: i,
|
|
50
|
-
onChange: t,
|
|
51
|
-
formatter: l
|
|
52
|
-
} = a, o = l ?? J;
|
|
53
|
-
let s;
|
|
54
|
-
if (e[0] !== o || e[1] !== i || e[2] !== t) {
|
|
55
|
-
let r;
|
|
56
|
-
e[4] !== o || e[5] !== t ? (r = (x, p) => /* @__PURE__ */ v(Q, { index: p, item: x, fmt: o, onChange: t }, `range-${x.min}-${x.max}-${p}`), e[4] = o, e[5] = t, e[6] = r) : r = e[6], s = i.map(r), e[0] = o, e[1] = i, e[2] = t, e[3] = s;
|
|
57
|
-
} else
|
|
58
|
-
s = e[3];
|
|
59
|
-
let n;
|
|
60
|
-
return e[7] !== s ? (n = /* @__PURE__ */ v(B, { sx: $.root, children: s }), e[7] = s, e[8] = n) : n = e[8], n;
|
|
61
|
-
}
|
|
62
|
-
function J(a) {
|
|
63
|
-
return String(a);
|
|
64
|
-
}
|
|
65
|
-
function Q(a) {
|
|
66
|
-
const e = _(54), {
|
|
67
|
-
index: i,
|
|
68
|
-
item: t,
|
|
69
|
-
fmt: l,
|
|
70
|
-
onChange: o
|
|
71
|
-
} = a;
|
|
72
|
-
let s;
|
|
73
|
-
e[0] !== t.max || e[1] !== t.min || e[2] !== t.value ? (s = t.value ?? [t.min, t.max], e[0] = t.max, e[1] = t.min, e[2] = t.value, e[3] = s) : s = e[3];
|
|
74
|
-
const n = s, [r, x] = z("");
|
|
75
|
-
let p;
|
|
76
|
-
e[4] !== i || e[5] !== t.max || e[6] !== t.min || e[7] !== o ? (p = (j) => {
|
|
77
|
-
const [I, k] = j, L = Math.min(Math.max(I, t.min), t.max), T = Math.min(Math.max(k, t.min), t.max), K = L <= T ? [L, T] : [T, L];
|
|
78
|
-
o?.(i, K);
|
|
79
|
-
}, e[4] = i, e[5] = t.max, e[6] = t.min, e[7] = o, e[8] = p) : p = e[8];
|
|
80
|
-
const m = p;
|
|
81
|
-
let C;
|
|
82
|
-
e[9] !== m || e[10] !== t.max || e[11] !== t.min ? (C = (j, I) => {
|
|
83
|
-
if (!Array.isArray(I))
|
|
84
|
-
return;
|
|
85
|
-
const k = I[0] ?? t.min, L = I[1] ?? t.max;
|
|
86
|
-
m([k, L]);
|
|
87
|
-
}, e[9] = m, e[10] = t.max, e[11] = t.min, e[12] = C) : C = e[12];
|
|
88
|
-
const y = C;
|
|
89
|
-
let h;
|
|
90
|
-
e[13] !== t.color ? (h = t.color ? {
|
|
91
|
-
color: t.color
|
|
92
|
-
} : null, e[13] = t.color, e[14] = h) : h = e[14];
|
|
93
|
-
let d;
|
|
94
|
-
e[15] !== h ? (d = {
|
|
95
|
-
...$.slider,
|
|
96
|
-
...h
|
|
97
|
-
}, e[15] = h, e[16] = d) : d = e[16];
|
|
98
|
-
let u;
|
|
99
|
-
e[17] !== n ? (u = [...n], e[17] = n, e[18] = u) : u = e[18];
|
|
100
|
-
const S = t.min, D = t.max, w = t.step ?? 1;
|
|
101
|
-
let f;
|
|
102
|
-
e[19] !== t.marks ? (f = V(t.marks), e[19] = t.marks, e[20] = f) : f = e[20];
|
|
103
|
-
let g;
|
|
104
|
-
e[21] !== l || e[22] !== y || e[23] !== t.disabled || e[24] !== t.max || e[25] !== t.min || e[26] !== f || e[27] !== d || e[28] !== u || e[29] !== w ? (g = /* @__PURE__ */ v(B, { sx: $.sliderContainer, children: /* @__PURE__ */ v(U, { sx: d, value: u, min: S, max: D, step: w, marks: f, disabled: t.disabled, valueLabelDisplay: "auto", valueLabelFormat: l, onChange: y }) }), e[21] = l, e[22] = y, e[23] = t.disabled, e[24] = t.max, e[25] = t.min, e[26] = f, e[27] = d, e[28] = u, e[29] = w, e[30] = g) : g = e[30];
|
|
105
|
-
const R = `min-${n[0]}`;
|
|
106
|
-
let c;
|
|
107
|
-
e[31] !== m || e[32] !== n || e[33] !== r || e[34] !== l || e[35] !== t || e[36] !== R ? (c = /* @__PURE__ */ v(W, { name: "min", value: n[0], item: t, fmt: l, editing: r, setEditing: x, commit: m, current: n, ariaLabel: "Minimum value" }, R), e[31] = m, e[32] = n, e[33] = r, e[34] = l, e[35] = t, e[36] = R, e[37] = c) : c = e[37];
|
|
108
|
-
const E = `max-${n[1]}`;
|
|
109
|
-
let b;
|
|
110
|
-
e[38] !== m || e[39] !== n || e[40] !== r || e[41] !== l || e[42] !== t || e[43] !== E ? (b = /* @__PURE__ */ v(W, { name: "max", value: n[1], item: t, fmt: l, editing: r, setEditing: x, commit: m, current: n, ariaLabel: "Maximum value" }, E), e[38] = m, e[39] = n, e[40] = r, e[41] = l, e[42] = t, e[43] = E, e[44] = b) : b = e[44];
|
|
111
|
-
let M;
|
|
112
|
-
e[45] !== c || e[46] !== b ? (M = /* @__PURE__ */ N(B, { sx: $.inputsRow, children: [
|
|
113
|
-
c,
|
|
114
|
-
b
|
|
115
|
-
] }), e[45] = c, e[46] = b, e[47] = M) : M = e[47];
|
|
116
|
-
let F;
|
|
117
|
-
e[48] !== t.note ? (F = t.note ? /* @__PURE__ */ v(q, { variant: "caption", sx: $.note, children: t.note }) : null, e[48] = t.note, e[49] = F) : F = e[49];
|
|
118
|
-
let A;
|
|
119
|
-
return e[50] !== g || e[51] !== M || e[52] !== F ? (A = /* @__PURE__ */ N(B, { sx: $.item, children: [
|
|
120
|
-
g,
|
|
121
|
-
M,
|
|
122
|
-
F
|
|
123
|
-
] }), e[50] = g, e[51] = M, e[52] = F, e[53] = A) : A = e[53], A;
|
|
124
|
-
}
|
|
125
|
-
function W(a) {
|
|
126
|
-
const e = _(26), {
|
|
127
|
-
name: i,
|
|
128
|
-
value: t,
|
|
129
|
-
item: l,
|
|
130
|
-
fmt: o,
|
|
131
|
-
editing: s,
|
|
132
|
-
setEditing: n,
|
|
133
|
-
commit: r,
|
|
134
|
-
current: x,
|
|
135
|
-
ariaLabel: p
|
|
136
|
-
} = a, [m, C] = z(String(t));
|
|
137
|
-
let y;
|
|
138
|
-
e[0] !== i || e[1] !== n ? (y = () => {
|
|
139
|
-
n(i);
|
|
140
|
-
}, e[0] = i, e[1] = n, e[2] = y) : y = e[2];
|
|
141
|
-
const h = y;
|
|
142
|
-
let d, u;
|
|
143
|
-
if (e[3] !== r || e[4] !== x || e[5] !== i || e[6] !== n || e[7] !== t) {
|
|
144
|
-
let R = function(c) {
|
|
145
|
-
const E = parseFloat(c), b = Number.isFinite(E) ? E : t, M = i === "min" ? [b, x[1]] : [x[0], b];
|
|
146
|
-
r(M);
|
|
147
|
-
};
|
|
148
|
-
u = (c) => {
|
|
149
|
-
n(""), R(c.target.value);
|
|
150
|
-
}, d = (c) => {
|
|
151
|
-
c.key === "Enter" && (R(c.target.value), c.target.blur());
|
|
152
|
-
}, e[3] = r, e[4] = x, e[5] = i, e[6] = n, e[7] = t, e[8] = d, e[9] = u;
|
|
153
|
-
} else
|
|
154
|
-
d = e[8], u = e[9];
|
|
155
|
-
let S;
|
|
156
|
-
e[10] !== s || e[11] !== o || e[12] !== i || e[13] !== m ? (S = s === i ? m : o(Number(m)), e[10] = s, e[11] = o, e[12] = i, e[13] = m, e[14] = S) : S = e[14];
|
|
157
|
-
const D = S;
|
|
158
|
-
let w;
|
|
159
|
-
e[15] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (w = (R) => C(R.target.value), e[15] = w) : w = e[15];
|
|
160
|
-
let f;
|
|
161
|
-
e[16] !== p ? (f = {
|
|
162
|
-
"aria-label": p
|
|
163
|
-
}, e[16] = p, e[17] = f) : f = e[17];
|
|
164
|
-
let g;
|
|
165
|
-
return e[18] !== h || e[19] !== d || e[20] !== D || e[21] !== u || e[22] !== l.disabled || e[23] !== i || e[24] !== f ? (g = /* @__PURE__ */ v(G, { name: i, value: D, onChange: w, onFocus: h, onBlur: u, onKeyDown: d, disabled: l.disabled, size: "small", sx: $.input, inputProps: f }), e[18] = h, e[19] = d, e[20] = D, e[21] = u, e[22] = l.disabled, e[23] = i, e[24] = f, e[25] = g) : g = e[25], g;
|
|
166
|
-
}
|
|
167
|
-
function V(a) {
|
|
168
|
-
if (a != null)
|
|
169
|
-
return typeof a == "boolean" ? a : [...a];
|
|
170
|
-
}
|
|
171
|
-
const X = (a) => ({
|
|
172
|
-
data: a.data ?? [],
|
|
173
|
-
formatter: a.formatter
|
|
174
|
-
});
|
|
175
|
-
function ae(a) {
|
|
176
|
-
const e = _(4), {
|
|
177
|
-
onChange: i
|
|
178
|
-
} = a, t = O(), l = P(t, X);
|
|
179
|
-
let o;
|
|
180
|
-
return e[0] !== i || e[1] !== l.data || e[2] !== l.formatter ? (o = /* @__PURE__ */ v(H, { items: l.data, formatter: l.formatter, onChange: i }), e[0] = i, e[1] = l.data, e[2] = l.formatter, e[3] = o) : o = e[3], o;
|
|
181
|
-
}
|
|
182
|
-
export {
|
|
183
|
-
ae as R,
|
|
184
|
-
H as a
|
|
185
|
-
};
|
|
186
|
-
//# sourceMappingURL=range-DsqTjSpg.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"range-DsqTjSpg.js","sources":["../src/widgets-v2/range/style.ts","../src/widgets-v2/range/range-ui.tsx","../src/widgets-v2/range/range.tsx"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 3,\n py: 1,\n },\n item: {\n display: 'flex',\n flexDirection: 'column',\n gap: 1.5,\n },\n sliderContainer: {\n display: 'flex',\n flexDirection: 'column',\n gap: 1,\n px: 1,\n },\n slider: {\n width: '100%',\n '&.Mui-disabled': {\n color: (theme: Theme) => theme.palette.text.disabled,\n },\n },\n inputsRow: {\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n },\n input: {\n flex: 1,\n '& .MuiInputBase-input': {\n textAlign: 'center',\n },\n },\n note: {\n color: 'text.secondary',\n },\n} satisfies Record<string, SxProps<Theme>>\n","import {\n useCallback,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n} from 'react'\nimport { Box, Slider, TextField, Typography } from '@mui/material'\nimport type { RangeDataItem, RangeItemValue } from './types'\nimport { styles } from './style'\n\nexport interface RangeUIProps {\n items: readonly RangeDataItem[]\n /**\n * Fires when the user drags a thumb or commits a new value via the text\n * inputs. Per the destination-owned principle, the consumer owns the\n * value — this widget surfaces changes but does not store them.\n */\n onChange?: (index: number, value: RangeItemValue) => void\n /** Number formatter for the slider tooltip and the text input display. */\n formatter?: (value: number) => string\n}\n\ntype Bound = 'min' | 'max'\n\n/**\n * Pure presentational component for the Range widget. Renders one MUI Slider\n * per item with editable min/max text inputs below — matching the Range v1\n * UX. Each item is always a two-thumb range; supply `value` to seed the\n * starting selection, otherwise it defaults to `[min, max]`.\n */\nexport function RangeUI({ items, onChange, formatter }: RangeUIProps) {\n const fmt = formatter ?? ((n: number) => String(n))\n return (\n <Box sx={styles.root}>\n {items.map((item, i) => (\n // Composite of the row's track bounds — stable across reorders for\n // any realistic widget configuration. Falls back to a literal +\n // index when bounds collide (degenerate same-min-same-max rows).\n <RangeRow\n key={`range-${item.min}-${item.max}-${i}`}\n index={i}\n item={item}\n fmt={fmt}\n onChange={onChange}\n />\n ))}\n </Box>\n )\n}\n\ninterface RangeRowProps {\n index: number\n item: RangeDataItem\n fmt: (n: number) => string\n onChange?: (index: number, value: RangeItemValue) => void\n}\n\nfunction RangeRow({ index, item, fmt, onChange }: RangeRowProps) {\n const current: readonly [number, number] = item.value ?? [item.min, item.max]\n const [editing, setEditing] = useState<'' | Bound>('')\n\n const commit = useCallback(\n (next: readonly [number, number]) => {\n // Clamp inside [min, max] and keep `low <= high`.\n const [lowRaw, highRaw] = next\n const low = Math.min(Math.max(lowRaw, item.min), item.max)\n const high = Math.min(Math.max(highRaw, item.min), item.max)\n const ordered: readonly [number, number] =\n low <= high ? [low, high] : [high, low]\n onChange?.(index, ordered)\n },\n [index, item.min, item.max, onChange],\n )\n\n const handleSlider = (_: Event, raw: number | number[]) => {\n if (!Array.isArray(raw)) return\n // Hoist defaults out of the destructure: react-compiler can't safely\n // reorder MemberExpression defaults inside an array pattern.\n const low = raw[0] ?? item.min\n const high = raw[1] ?? item.max\n commit([low, high])\n }\n\n return (\n <Box sx={styles.item}>\n <Box sx={styles.sliderContainer}>\n <Slider\n sx={{\n ...styles.slider,\n ...(item.color ? { color: item.color } : null),\n }}\n value={[...current]}\n min={item.min}\n max={item.max}\n step={item.step ?? 1}\n marks={resolveMarks(item.marks)}\n disabled={item.disabled}\n valueLabelDisplay='auto'\n valueLabelFormat={fmt}\n onChange={handleSlider}\n />\n </Box>\n <Box sx={styles.inputsRow}>\n <BoundInput\n // Bumping the key on a fresh external value resets the local\n // editing state — matches v1's RangeItem behaviour.\n key={`min-${current[0]}`}\n name='min'\n value={current[0]}\n item={item}\n fmt={fmt}\n editing={editing}\n setEditing={setEditing}\n commit={commit}\n current={current}\n ariaLabel='Minimum value'\n />\n <BoundInput\n key={`max-${current[1]}`}\n name='max'\n value={current[1]}\n item={item}\n fmt={fmt}\n editing={editing}\n setEditing={setEditing}\n commit={commit}\n current={current}\n ariaLabel='Maximum value'\n />\n </Box>\n {item.note ? (\n <Typography variant='caption' sx={styles.note}>\n {item.note}\n </Typography>\n ) : null}\n </Box>\n )\n}\n\ninterface BoundInputProps {\n name: Bound\n value: number\n item: RangeDataItem\n fmt: (n: number) => string\n editing: '' | Bound\n setEditing: (next: '' | Bound) => void\n commit: (next: readonly [number, number]) => void\n current: readonly [number, number]\n ariaLabel: string\n}\n\nfunction BoundInput({\n name,\n value,\n item,\n fmt,\n editing,\n setEditing,\n commit,\n current,\n ariaLabel,\n}: BoundInputProps) {\n const [raw, setRaw] = useState<string>(String(value))\n\n const beginEditing = () => {\n setEditing(name)\n }\n const finishEditingAndCommit = (e: FocusEvent<HTMLInputElement>) => {\n setEditing('')\n commitFromText(e.target.value)\n }\n const commitOnEnter = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n commitFromText((e.target as HTMLInputElement).value)\n ;(e.target as HTMLInputElement).blur()\n }\n }\n\n function commitFromText(input: string) {\n const parsed = parseFloat(input)\n const safe = Number.isFinite(parsed) ? parsed : value\n const next: readonly [number, number] =\n name === 'min' ? [safe, current[1]] : [current[0], safe]\n commit(next)\n }\n\n const display = editing === name ? raw : fmt(Number(raw))\n\n return (\n <TextField\n name={name}\n value={display}\n onChange={(e) => setRaw(e.target.value)}\n onFocus={beginEditing}\n onBlur={finishEditingAndCommit}\n onKeyDown={commitOnEnter}\n disabled={item.disabled}\n size='small'\n sx={styles.input}\n inputProps={{ 'aria-label': ariaLabel }}\n />\n )\n}\n\nfunction resolveMarks(\n marks: RangeDataItem['marks'],\n): boolean | { value: number; label?: string }[] | undefined {\n if (marks == null) return undefined\n if (typeof marks === 'boolean') return marks\n return [...marks]\n}\n","import { useWidgetId, useWidgetShallow } from '../stores'\nimport { RangeUI } from './range-ui'\nimport type { RangeItemValue, RangeWidgetData } from './types'\n\ninterface RangeSlice {\n data: RangeWidgetData\n formatter?: (value: number) => string\n}\n\nconst rangeSelector = (s: {\n data: unknown\n formatter?: (value: number) => string\n}): RangeSlice => ({\n data: (s.data ?? []) as RangeWidgetData,\n formatter: s.formatter,\n})\n\nexport interface RangeProps {\n /**\n * Fires when the user moves a slider thumb or commits a new value via the\n * text inputs. Receives the item index in `state.data` and the new\n * `[low, high]` tuple. The consumer owns the data state — the widget\n * surfaces changes but does not persist them.\n */\n onChange?: (index: number, value: RangeItemValue) => void\n}\n\n/**\n * Stateful Range bridge — reads `data` (post-pipeline) and `formatter` from\n * the per-widget store and forwards them to the pure {@link RangeUI}. Per\n * the destination-owned principle, value changes flow back through\n * `onChange` — the consumer is expected to update the data prop on\n * `<Provider>`. Use `disabled` on individual `RangeDataItem`s to disable\n * specific rows.\n */\nexport function Range({ onChange }: RangeProps) {\n const id = useWidgetId()\n const slice = useWidgetShallow(id, rangeSelector)\n return (\n <RangeUI\n items={slice.data}\n formatter={slice.formatter}\n onChange={onChange}\n />\n )\n}\n"],"names":["styles","root","display","flexDirection","gap","py","item","sliderContainer","px","slider","width","color","theme","palette","text","disabled","inputsRow","alignItems","input","flex","textAlign","note","RangeUI","t0","$","_c","items","onChange","formatter","fmt","_temp","t1","t2","i","jsx","RangeRow","min","max","map","Box","n","String","index","value","current","editing","setEditing","useState","next","lowRaw","highRaw","low","Math","high","ordered","commit","t3","_","raw","Array","isArray","low_0","high_0","handleSlider","t4","t5","t6","t7","t8","t9","step","t10","marks","resolveMarks","t11","Slider","t12","t13","BoundInput","t14","t15","t16","t17","Typography","t18","jsxs","name","ariaLabel","setRaw","beginEditing","commitOnEnter","finishEditingAndCommit","commitFromText","parsed","parseFloat","safe","Number","isFinite","e","target","e_0","key","blur","Symbol","for","e_1","TextField","rangeSelector","s","data","Range","id","useWidgetId","slice","useWidgetShallow"],"mappings":"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"}
|