@matthieumordrel/chart-studio 0.1.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/LICENSE +21 -0
- package/README.md +371 -0
- package/dist/core/chart-capabilities.d.ts +60 -0
- package/dist/core/chart-capabilities.d.ts.map +1 -0
- package/dist/core/chart-capabilities.js +55 -0
- package/dist/core/chart-capabilities.js.map +1 -0
- package/dist/core/colors.d.ts +25 -0
- package/dist/core/colors.d.ts.map +1 -0
- package/dist/core/colors.js +55 -0
- package/dist/core/colors.js.map +1 -0
- package/dist/core/config-utils.d.ts +43 -0
- package/dist/core/config-utils.d.ts.map +1 -0
- package/dist/core/config-utils.js +81 -0
- package/dist/core/config-utils.js.map +1 -0
- package/dist/core/date-utils.d.ts +29 -0
- package/dist/core/date-utils.d.ts.map +1 -0
- package/dist/core/date-utils.js +59 -0
- package/dist/core/date-utils.js.map +1 -0
- package/dist/core/define-chart-schema.d.ts +105 -0
- package/dist/core/define-chart-schema.d.ts.map +1 -0
- package/dist/core/define-chart-schema.js +45 -0
- package/dist/core/define-chart-schema.js.map +1 -0
- package/dist/core/formatting.d.ts +47 -0
- package/dist/core/formatting.d.ts.map +1 -0
- package/dist/core/formatting.js +397 -0
- package/dist/core/formatting.js.map +1 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/infer-columns.d.ts +6 -0
- package/dist/core/infer-columns.d.ts.map +1 -0
- package/dist/core/infer-columns.js +513 -0
- package/dist/core/infer-columns.js.map +1 -0
- package/dist/core/metric-utils.d.ts +43 -0
- package/dist/core/metric-utils.d.ts.map +1 -0
- package/dist/core/metric-utils.js +142 -0
- package/dist/core/metric-utils.js.map +1 -0
- package/dist/core/pipeline-data-points.d.ts +23 -0
- package/dist/core/pipeline-data-points.d.ts.map +1 -0
- package/dist/core/pipeline-data-points.js +236 -0
- package/dist/core/pipeline-data-points.js.map +1 -0
- package/dist/core/pipeline-helpers.d.ts +38 -0
- package/dist/core/pipeline-helpers.d.ts.map +1 -0
- package/dist/core/pipeline-helpers.js +98 -0
- package/dist/core/pipeline-helpers.js.map +1 -0
- package/dist/core/pipeline.d.ts +70 -0
- package/dist/core/pipeline.d.ts.map +1 -0
- package/dist/core/pipeline.js +157 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/core/types.d.ts +1109 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +15 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/use-chart-options.d.ts +66 -0
- package/dist/core/use-chart-options.d.ts.map +1 -0
- package/dist/core/use-chart-options.js +5 -0
- package/dist/core/use-chart-options.js.map +1 -0
- package/dist/core/use-chart-resolvers.d.ts +14 -0
- package/dist/core/use-chart-resolvers.d.ts.map +1 -0
- package/dist/core/use-chart-resolvers.js +42 -0
- package/dist/core/use-chart-resolvers.js.map +1 -0
- package/dist/core/use-chart.d.ts +47 -0
- package/dist/core/use-chart.d.ts.map +1 -0
- package/dist/core/use-chart.js +266 -0
- package/dist/core/use-chart.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/chart-axis-ticks.d.ts +35 -0
- package/dist/ui/chart-axis-ticks.d.ts.map +1 -0
- package/dist/ui/chart-axis-ticks.js +80 -0
- package/dist/ui/chart-axis-ticks.js.map +1 -0
- package/dist/ui/chart-canvas.d.ts +22 -0
- package/dist/ui/chart-canvas.d.ts.map +1 -0
- package/dist/ui/chart-canvas.js +338 -0
- package/dist/ui/chart-canvas.js.map +1 -0
- package/dist/ui/chart-context.d.ts +89 -0
- package/dist/ui/chart-context.d.ts.map +1 -0
- package/dist/ui/chart-context.js +129 -0
- package/dist/ui/chart-context.js.map +1 -0
- package/dist/ui/chart-date-range-badge.d.ts +14 -0
- package/dist/ui/chart-date-range-badge.d.ts.map +1 -0
- package/dist/ui/chart-date-range-badge.js +31 -0
- package/dist/ui/chart-date-range-badge.js.map +1 -0
- package/dist/ui/chart-date-range-panel.d.ts +25 -0
- package/dist/ui/chart-date-range-panel.d.ts.map +1 -0
- package/dist/ui/chart-date-range-panel.js +126 -0
- package/dist/ui/chart-date-range-panel.js.map +1 -0
- package/dist/ui/chart-date-range.d.ts +14 -0
- package/dist/ui/chart-date-range.d.ts.map +1 -0
- package/dist/ui/chart-date-range.js +38 -0
- package/dist/ui/chart-date-range.js.map +1 -0
- package/dist/ui/chart-debug.d.ts +10 -0
- package/dist/ui/chart-debug.d.ts.map +1 -0
- package/dist/ui/chart-debug.js +127 -0
- package/dist/ui/chart-debug.js.map +1 -0
- package/dist/ui/chart-dropdown.d.ts +35 -0
- package/dist/ui/chart-dropdown.d.ts.map +1 -0
- package/dist/ui/chart-dropdown.js +77 -0
- package/dist/ui/chart-dropdown.js.map +1 -0
- package/dist/ui/chart-filters-panel.d.ts +19 -0
- package/dist/ui/chart-filters-panel.d.ts.map +1 -0
- package/dist/ui/chart-filters-panel.js +47 -0
- package/dist/ui/chart-filters-panel.js.map +1 -0
- package/dist/ui/chart-filters.d.ts +12 -0
- package/dist/ui/chart-filters.d.ts.map +1 -0
- package/dist/ui/chart-filters.js +27 -0
- package/dist/ui/chart-filters.js.map +1 -0
- package/dist/ui/chart-group-by-selector.d.ts +8 -0
- package/dist/ui/chart-group-by-selector.d.ts.map +1 -0
- package/dist/ui/chart-group-by-selector.js +20 -0
- package/dist/ui/chart-group-by-selector.js.map +1 -0
- package/dist/ui/chart-metric-panel.d.ts +18 -0
- package/dist/ui/chart-metric-panel.d.ts.map +1 -0
- package/dist/ui/chart-metric-panel.js +119 -0
- package/dist/ui/chart-metric-panel.js.map +1 -0
- package/dist/ui/chart-metric-selector.d.ts +10 -0
- package/dist/ui/chart-metric-selector.d.ts.map +1 -0
- package/dist/ui/chart-metric-selector.js +28 -0
- package/dist/ui/chart-metric-selector.js.map +1 -0
- package/dist/ui/chart-select.d.ts +25 -0
- package/dist/ui/chart-select.d.ts.map +1 -0
- package/dist/ui/chart-select.js +36 -0
- package/dist/ui/chart-select.js.map +1 -0
- package/dist/ui/chart-source-switcher.d.ts +16 -0
- package/dist/ui/chart-source-switcher.d.ts.map +1 -0
- package/dist/ui/chart-source-switcher.js +32 -0
- package/dist/ui/chart-source-switcher.js.map +1 -0
- package/dist/ui/chart-time-bucket-selector.d.ts +9 -0
- package/dist/ui/chart-time-bucket-selector.d.ts.map +1 -0
- package/dist/ui/chart-time-bucket-selector.js +26 -0
- package/dist/ui/chart-time-bucket-selector.js.map +1 -0
- package/dist/ui/chart-toolbar-overflow.d.ts +29 -0
- package/dist/ui/chart-toolbar-overflow.d.ts.map +1 -0
- package/dist/ui/chart-toolbar-overflow.js +110 -0
- package/dist/ui/chart-toolbar-overflow.js.map +1 -0
- package/dist/ui/chart-toolbar.d.ts +45 -0
- package/dist/ui/chart-toolbar.d.ts.map +1 -0
- package/dist/ui/chart-toolbar.js +45 -0
- package/dist/ui/chart-toolbar.js.map +1 -0
- package/dist/ui/chart-type-selector.d.ts +8 -0
- package/dist/ui/chart-type-selector.d.ts.map +1 -0
- package/dist/ui/chart-type-selector.js +23 -0
- package/dist/ui/chart-type-selector.js.map +1 -0
- package/dist/ui/chart-x-axis-selector.d.ts +8 -0
- package/dist/ui/chart-x-axis-selector.d.ts.map +1 -0
- package/dist/ui/chart-x-axis-selector.js +15 -0
- package/dist/ui/chart-x-axis-selector.js.map +1 -0
- package/dist/ui/index.d.ts +25 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +24 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/theme.css +62 -0
- package/dist/ui/toolbar-types.d.ts +43 -0
- package/dist/ui/toolbar-types.d.ts.map +1 -0
- package/dist/ui/toolbar-types.js +51 -0
- package/dist/ui/toolbar-types.js.map +1 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matthieu Mordrel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# chart-studio
|
|
2
|
+
|
|
3
|
+
Composable charting for React with two adoption paths:
|
|
4
|
+
|
|
5
|
+
- use the **headless core** if you want chart state, filtering, grouping, and transformed data
|
|
6
|
+
- use the **optional UI layer** if you also want ready-made controls and a Recharts canvas
|
|
7
|
+
|
|
8
|
+
Package: `@matthieumordrel/chart-studio`
|
|
9
|
+
|
|
10
|
+
## Start Here
|
|
11
|
+
|
|
12
|
+
Choose the path that matches your app:
|
|
13
|
+
|
|
14
|
+
### 1. Headless core
|
|
15
|
+
|
|
16
|
+
Use this if you already have your own design system or chart renderer.
|
|
17
|
+
|
|
18
|
+
You get:
|
|
19
|
+
|
|
20
|
+
- `useChart`
|
|
21
|
+
- optional `schema` via `defineChartSchema`
|
|
22
|
+
- transformed chart data
|
|
23
|
+
- filtering, grouping, metrics, and time bucketing logic
|
|
24
|
+
|
|
25
|
+
Install:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun add @matthieumordrel/chart-studio react
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Import from:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { useChart } from '@matthieumordrel/chart-studio'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Ready-made UI
|
|
38
|
+
|
|
39
|
+
Use this if you want the package to render the controls and chart for you.
|
|
40
|
+
|
|
41
|
+
You get:
|
|
42
|
+
|
|
43
|
+
- everything from the headless core
|
|
44
|
+
- `<Chart>`
|
|
45
|
+
- `<ChartToolbar>`
|
|
46
|
+
- `<ChartCanvas>`
|
|
47
|
+
- granular UI controls from `@matthieumordrel/chart-studio/ui`
|
|
48
|
+
|
|
49
|
+
Install:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
bun add @matthieumordrel/chart-studio react recharts lucide-react
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then import the package theme once in your app stylesheet:
|
|
56
|
+
|
|
57
|
+
```css
|
|
58
|
+
@import 'tailwindcss';
|
|
59
|
+
@import '@matthieumordrel/chart-studio/ui/theme.css';
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Import from:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { useChart } from '@matthieumordrel/chart-studio'
|
|
66
|
+
import { Chart, ChartToolbar, ChartCanvas } from '@matthieumordrel/chart-studio/ui'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Smallest Working Example (Single Source)
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { useChart } from '@matthieumordrel/chart-studio'
|
|
73
|
+
import { Chart, ChartToolbar, ChartCanvas } from '@matthieumordrel/chart-studio/ui'
|
|
74
|
+
import { data } from './data.json'
|
|
75
|
+
|
|
76
|
+
export function JobsChart() {
|
|
77
|
+
const chart = useChart({ data })
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<Chart chart={chart}>
|
|
81
|
+
<ChartToolbar />
|
|
82
|
+
<ChartCanvas height={320} />
|
|
83
|
+
</Chart>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## How It Works
|
|
89
|
+
|
|
90
|
+
1. Pass your raw data to `useChart()`.
|
|
91
|
+
2. Add an optional `schema` with `defineChartSchema<Row>()(...)` when you need labels, type overrides, derived columns, or control restrictions (allowed metrics, groupings, chart types, etc.).
|
|
92
|
+
3. Either render your own UI from the returned state, or use the components from `@matthieumordrel/chart-studio/ui`.
|
|
93
|
+
|
|
94
|
+
## Column Types
|
|
95
|
+
|
|
96
|
+
| Type | What it is for |
|
|
97
|
+
| ---------- | --------------------------------------- |
|
|
98
|
+
| `date` | time-series X-axis |
|
|
99
|
+
| `category` | categorical X-axis, grouping, filtering |
|
|
100
|
+
| `boolean` | grouping, filtering |
|
|
101
|
+
| `number` | metrics such as sum, avg, min, max |
|
|
102
|
+
|
|
103
|
+
## Declarative Schema and Control Restrictions
|
|
104
|
+
|
|
105
|
+
If you want to expose only a subset of groupings, metrics, chart types, or axes, use `defineChartSchema<Row>()()` with the control sections:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { defineChartSchema, useChart } from '@matthieumordrel/chart-studio'
|
|
109
|
+
|
|
110
|
+
type Row = { periodEnd: string; segment: string; revenue: number; netIncome: number }
|
|
111
|
+
|
|
112
|
+
const schema = defineChartSchema<Row>()({
|
|
113
|
+
columns: {
|
|
114
|
+
periodEnd: { type: 'date', label: 'Period End' },
|
|
115
|
+
segment: { type: 'category' },
|
|
116
|
+
revenue: { type: 'number' },
|
|
117
|
+
netIncome: { type: 'number' }
|
|
118
|
+
},
|
|
119
|
+
xAxis: { allowed: ['periodEnd'] },
|
|
120
|
+
groupBy: { allowed: ['segment'] },
|
|
121
|
+
metric: {
|
|
122
|
+
allowed: [
|
|
123
|
+
{ kind: 'count' },
|
|
124
|
+
{ kind: 'aggregate', columnId: 'revenue', aggregate: ['sum', 'avg'] },
|
|
125
|
+
{ kind: 'aggregate', columnId: 'netIncome', aggregate: 'sum' }
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
chartType: { allowed: ['bar', 'line'] },
|
|
129
|
+
timeBucket: { allowed: ['year', 'quarter', 'month'] }
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const chart = useChart({ data, schema })
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Why this pattern:
|
|
136
|
+
|
|
137
|
+
- `columns` defines types, labels, and formats for raw fields; use `false` to exclude a column from the chart
|
|
138
|
+
- Derived columns use `{ kind: 'derived', type, label?, accessor, format? }` for computed values from each row
|
|
139
|
+
- `xAxis`, `groupBy`, `metric`, `chartType`, `timeBucket` restrict the allowed options
|
|
140
|
+
- invalid column IDs and config keys are rejected at compile time
|
|
141
|
+
- metric restrictions preserve the order you declare, so the first allowed metric becomes the default
|
|
142
|
+
|
|
143
|
+
## Headless Example
|
|
144
|
+
|
|
145
|
+
If you want to render your own UI or your own charting library, use only the core state:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { defineChartSchema, useChart } from '@matthieumordrel/chart-studio'
|
|
149
|
+
|
|
150
|
+
type Job = {
|
|
151
|
+
dateAdded: string
|
|
152
|
+
ownerName: string
|
|
153
|
+
salary: number
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const jobSchema = defineChartSchema<Job>()({
|
|
157
|
+
columns: {
|
|
158
|
+
dateAdded: { type: 'date', label: 'Date Added' },
|
|
159
|
+
ownerName: { type: 'category', label: 'Consultant' },
|
|
160
|
+
salary: { type: 'number', label: 'Salary' }
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
export function JobsChartHeadless({ data }: { data: Job[] }) {
|
|
165
|
+
const chart = useChart({ data, schema: jobSchema })
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<div>
|
|
169
|
+
<div>Chart type: {chart.chartType}</div>
|
|
170
|
+
<div>Rows: {chart.transformedData.length}</div>
|
|
171
|
+
<pre>{JSON.stringify(chart.transformedData, null, 2)}</pre>
|
|
172
|
+
</div>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Styling Requirements
|
|
178
|
+
|
|
179
|
+
The headless core has no styling requirements.
|
|
180
|
+
|
|
181
|
+
The `ui` layer is Tailwind-based and uses semantic classes such as:
|
|
182
|
+
|
|
183
|
+
- `bg-background`
|
|
184
|
+
- `text-foreground`
|
|
185
|
+
- `border-border`
|
|
186
|
+
- `bg-popover`
|
|
187
|
+
- `text-muted-foreground`
|
|
188
|
+
|
|
189
|
+
For those classes to render correctly, Tailwind needs real values behind tokens like `background`, `foreground`, `border`, and `popover`.
|
|
190
|
+
|
|
191
|
+
You can use `ui` in two ways:
|
|
192
|
+
|
|
193
|
+
### 1. Recommended: import the built-in theme
|
|
194
|
+
|
|
195
|
+
This is the easiest setup:
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
@import 'tailwindcss';
|
|
199
|
+
@import '@matthieumordrel/chart-studio/ui/theme.css';
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
This does three things for you:
|
|
203
|
+
|
|
204
|
+
- Tailwind utilities for the package components
|
|
205
|
+
- automatic scanning of the package UI classes
|
|
206
|
+
- default fallback values for all semantic UI tokens
|
|
207
|
+
- built-in light and dark default themes
|
|
208
|
+
|
|
209
|
+
If your app already defines matching shadcn-style variables, those values take over automatically. If not, the built-in defaults are used.
|
|
210
|
+
|
|
211
|
+
The shipped theme supports dark mode through either:
|
|
212
|
+
|
|
213
|
+
- `.dark`
|
|
214
|
+
- `[data-theme="dark"]`
|
|
215
|
+
|
|
216
|
+
### 2. Advanced: define everything yourself
|
|
217
|
+
|
|
218
|
+
If you do not want to import `@matthieumordrel/chart-studio/ui/theme.css`, you can provide all the required semantic tokens yourself in your app theme.
|
|
219
|
+
|
|
220
|
+
If neither of those is true, use the headless core and render your own controls.
|
|
221
|
+
|
|
222
|
+
### Minimum UI theme contract
|
|
223
|
+
|
|
224
|
+
You do not need shadcn itself to use `@matthieumordrel/chart-studio/ui`.
|
|
225
|
+
|
|
226
|
+
If you import `@matthieumordrel/chart-studio/ui/theme.css`, every token below gets a built-in fallback automatically.
|
|
227
|
+
|
|
228
|
+
If your app already defines some of these variables, your values override the defaults for those specific tokens only. Missing ones still fall back to the package defaults.
|
|
229
|
+
|
|
230
|
+
These are the tokens currently expected by the UI layer:
|
|
231
|
+
|
|
232
|
+
| Token | Purpose |
|
|
233
|
+
| -------------------- | -------------------------------------- |
|
|
234
|
+
| `background` | control backgrounds and input surfaces |
|
|
235
|
+
| `foreground` | primary text |
|
|
236
|
+
| `muted` | subtle backgrounds and hover states |
|
|
237
|
+
| `muted-foreground` | secondary text and icons |
|
|
238
|
+
| `border` | outlines and separators |
|
|
239
|
+
| `popover` | dropdowns and floating panels |
|
|
240
|
+
| `popover-foreground` | popover text color |
|
|
241
|
+
| `primary` | selected and active states |
|
|
242
|
+
| `primary-foreground` | text on filled primary surfaces |
|
|
243
|
+
| `ring` | focus-visible ring color |
|
|
244
|
+
|
|
245
|
+
Minimal example:
|
|
246
|
+
|
|
247
|
+
```css
|
|
248
|
+
:root {
|
|
249
|
+
--background: 0 0% 100%;
|
|
250
|
+
--foreground: 222.2 84% 4.9%;
|
|
251
|
+
--muted: 210 40% 96.1%;
|
|
252
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
253
|
+
--border: 214.3 31.8% 91.4%;
|
|
254
|
+
--popover: 0 0% 100%;
|
|
255
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
256
|
+
--primary: 222.2 47.4% 11.2%;
|
|
257
|
+
--primary-foreground: 210 40% 98%;
|
|
258
|
+
--ring: 221.2 83.2% 53.3%;
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
How this works in practice:
|
|
263
|
+
|
|
264
|
+
- import `ui/theme.css` and do nothing else: the package uses its own defaults
|
|
265
|
+
- toggle dark mode with either `.dark` or `[data-theme="dark"]`: the package uses its built-in dark defaults
|
|
266
|
+
- import `ui/theme.css` and define only a few variables: your values win for those variables, defaults cover the rest
|
|
267
|
+
- skip `ui/theme.css`: you must define the whole token contract yourself
|
|
268
|
+
|
|
269
|
+
That makes the package usable out of the box while still being easy to theme.
|
|
270
|
+
|
|
271
|
+
### Optional chart color tokens
|
|
272
|
+
|
|
273
|
+
Chart series colors also support shadcn-style chart variables:
|
|
274
|
+
|
|
275
|
+
| Token | Purpose |
|
|
276
|
+
| --------- | ------------------- |
|
|
277
|
+
| `chart-1` | first series color |
|
|
278
|
+
| `chart-2` | second series color |
|
|
279
|
+
| `chart-3` | third series color |
|
|
280
|
+
| `chart-4` | fourth series color |
|
|
281
|
+
| `chart-5` | fifth series color |
|
|
282
|
+
|
|
283
|
+
These are also optional when you import `ui/theme.css`.
|
|
284
|
+
|
|
285
|
+
If your app defines `--chart-1` through `--chart-5`, those colors are used automatically.
|
|
286
|
+
|
|
287
|
+
If they are not defined, `chart-studio` falls back to a built-in OKLCH palette, with separate light and dark defaults. That is why you may see blue, rose, cyan, or other fallback colors in charts when your app does not provide chart variables.
|
|
288
|
+
|
|
289
|
+
Minimal example:
|
|
290
|
+
|
|
291
|
+
```css
|
|
292
|
+
:root {
|
|
293
|
+
--chart-1: 221.2 83.2% 53.3%;
|
|
294
|
+
--chart-2: 262.1 83.3% 57.8%;
|
|
295
|
+
--chart-3: 24.6 95% 53.1%;
|
|
296
|
+
--chart-4: 142.1 76.2% 36.3%;
|
|
297
|
+
--chart-5: 346.8 77.2% 49.8%;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Compatibility
|
|
302
|
+
|
|
303
|
+
- `react`: `>=18.2.0 <20`
|
|
304
|
+
- `recharts`: `>=2.15.4 <3` for the UI layer
|
|
305
|
+
- `lucide-react`: `>=0.577.0 <1` for the UI layer
|
|
306
|
+
|
|
307
|
+
## Common Questions
|
|
308
|
+
|
|
309
|
+
### Which import path should I use?
|
|
310
|
+
|
|
311
|
+
- Use `@matthieumordrel/chart-studio` for the headless core.
|
|
312
|
+
- Use `@matthieumordrel/chart-studio/ui` for the optional UI components.
|
|
313
|
+
|
|
314
|
+
### Do I need Recharts?
|
|
315
|
+
|
|
316
|
+
Only for the UI layer. The headless core works without it.
|
|
317
|
+
|
|
318
|
+
### Do I need Tailwind?
|
|
319
|
+
|
|
320
|
+
Only for the UI layer. The headless core does not require it.
|
|
321
|
+
|
|
322
|
+
### Can I use multiple datasets?
|
|
323
|
+
|
|
324
|
+
Yes:
|
|
325
|
+
|
|
326
|
+
```tsx
|
|
327
|
+
import { defineChartSchema, useChart } from '@matthieumordrel/chart-studio'
|
|
328
|
+
|
|
329
|
+
const chart = useChart({
|
|
330
|
+
sources: [
|
|
331
|
+
{
|
|
332
|
+
id: 'jobs',
|
|
333
|
+
label: 'Jobs',
|
|
334
|
+
data: jobs,
|
|
335
|
+
schema: defineChartSchema<Job>()({
|
|
336
|
+
columns: { dateAdded: { type: 'date', label: 'Date Added' } }
|
|
337
|
+
})
|
|
338
|
+
},
|
|
339
|
+
{ id: 'candidates', label: 'Candidates', data: candidates }
|
|
340
|
+
]
|
|
341
|
+
})
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### What chart types are available?
|
|
345
|
+
|
|
346
|
+
- date X-axis: `bar`, `line`, `area`
|
|
347
|
+
- category or boolean X-axis: `bar`, `pie`, `donut`
|
|
348
|
+
- `pie` and `donut` do not support `groupBy`
|
|
349
|
+
|
|
350
|
+
## Troubleshooting
|
|
351
|
+
|
|
352
|
+
### The UI looks mostly unstyled
|
|
353
|
+
|
|
354
|
+
If the components render but look plain, compressed, or layout incorrectly, the most common cause is that the package theme file is not imported.
|
|
355
|
+
|
|
356
|
+
Start with:
|
|
357
|
+
|
|
358
|
+
```css
|
|
359
|
+
@import 'tailwindcss';
|
|
360
|
+
@import '@matthieumordrel/chart-studio/ui/theme.css';
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
If you are importing the package source directly in a local playground or monorepo, make sure Tailwind is scanning those source files too.
|
|
364
|
+
|
|
365
|
+
If your app already uses shadcn-style tokens, also make sure tokens such as `background`, `foreground`, `muted`, `border`, `popover`, `primary`, `ring`, and optionally `chart-1` through `chart-5` are defined in your theme.
|
|
366
|
+
|
|
367
|
+
## Release
|
|
368
|
+
|
|
369
|
+
- `bun run release:check`
|
|
370
|
+
- `bun run release:publish -- --tag=latest`
|
|
371
|
+
- `npm publish` runs `prepublishOnly`, which calls `bun run release:check`
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ChartType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* X-axis kinds understood by chart-studio when validating chart types.
|
|
4
|
+
*/
|
|
5
|
+
export type ChartAxisType = 'date' | 'category' | 'boolean';
|
|
6
|
+
/**
|
|
7
|
+
* Declarative chart-type capability matrix.
|
|
8
|
+
*
|
|
9
|
+
* Centralizing these rules keeps UI controls and state validation aligned as
|
|
10
|
+
* more chart types are added later.
|
|
11
|
+
*/
|
|
12
|
+
export type ChartTypeCapabilities = {
|
|
13
|
+
supportedXAxisTypes: readonly ChartAxisType[];
|
|
14
|
+
supportsGrouping: boolean;
|
|
15
|
+
supportsTimeBucketing: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Capabilities for each supported chart type.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CHART_TYPE_CONFIG: {
|
|
21
|
+
readonly bar: {
|
|
22
|
+
readonly supportedXAxisTypes: readonly ["date", "category", "boolean"];
|
|
23
|
+
readonly supportsGrouping: true;
|
|
24
|
+
readonly supportsTimeBucketing: true;
|
|
25
|
+
};
|
|
26
|
+
readonly line: {
|
|
27
|
+
readonly supportedXAxisTypes: readonly ["date"];
|
|
28
|
+
readonly supportsGrouping: true;
|
|
29
|
+
readonly supportsTimeBucketing: true;
|
|
30
|
+
};
|
|
31
|
+
readonly area: {
|
|
32
|
+
readonly supportedXAxisTypes: readonly ["date"];
|
|
33
|
+
readonly supportsGrouping: true;
|
|
34
|
+
readonly supportsTimeBucketing: true;
|
|
35
|
+
};
|
|
36
|
+
readonly pie: {
|
|
37
|
+
readonly supportedXAxisTypes: readonly ["category", "boolean"];
|
|
38
|
+
readonly supportsGrouping: false;
|
|
39
|
+
readonly supportsTimeBucketing: false;
|
|
40
|
+
};
|
|
41
|
+
readonly donut: {
|
|
42
|
+
readonly supportedXAxisTypes: readonly ["category", "boolean"];
|
|
43
|
+
readonly supportsGrouping: false;
|
|
44
|
+
readonly supportsTimeBucketing: false;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
type ChartTypeAvailability = {
|
|
48
|
+
hasGroupBy: boolean;
|
|
49
|
+
xAxisType: ChartAxisType | null;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Whether a chart type can represent the current chart state.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isChartTypeAvailable(chartType: ChartType, availability: ChartTypeAvailability): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Chart types valid for the current axis + feature combination.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getAvailableChartTypes(availability: ChartTypeAvailability): ChartType[];
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=chart-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-capabilities.d.ts","sourceRoot":"","sources":["../../src/core/chart-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,YAAY,CAAA;AAGzC;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;AAE3D;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,mBAAmB,EAAE,SAAS,aAAa,EAAE,CAAA;IAC7C,gBAAgB,EAAE,OAAO,CAAA;IACzB,qBAAqB,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;CA0B+B,CAAA;AAE7D,KAAK,qBAAqB,GAAG;IAC3B,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;CAChC,CAAA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,qBAAqB,GAClC,OAAO,CAeT;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,qBAAqB,GAAG,SAAS,EAAE,CAEvF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CHART_TYPE_ORDER } from './config-utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* Capabilities for each supported chart type.
|
|
4
|
+
*/
|
|
5
|
+
export const CHART_TYPE_CONFIG = {
|
|
6
|
+
bar: {
|
|
7
|
+
supportedXAxisTypes: ['date', 'category', 'boolean'],
|
|
8
|
+
supportsGrouping: true,
|
|
9
|
+
supportsTimeBucketing: true,
|
|
10
|
+
},
|
|
11
|
+
line: {
|
|
12
|
+
supportedXAxisTypes: ['date'],
|
|
13
|
+
supportsGrouping: true,
|
|
14
|
+
supportsTimeBucketing: true,
|
|
15
|
+
},
|
|
16
|
+
area: {
|
|
17
|
+
supportedXAxisTypes: ['date'],
|
|
18
|
+
supportsGrouping: true,
|
|
19
|
+
supportsTimeBucketing: true,
|
|
20
|
+
},
|
|
21
|
+
pie: {
|
|
22
|
+
supportedXAxisTypes: ['category', 'boolean'],
|
|
23
|
+
supportsGrouping: false,
|
|
24
|
+
supportsTimeBucketing: false,
|
|
25
|
+
},
|
|
26
|
+
donut: {
|
|
27
|
+
supportedXAxisTypes: ['category', 'boolean'],
|
|
28
|
+
supportsGrouping: false,
|
|
29
|
+
supportsTimeBucketing: false,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Whether a chart type can represent the current chart state.
|
|
34
|
+
*/
|
|
35
|
+
export function isChartTypeAvailable(chartType, availability) {
|
|
36
|
+
const { hasGroupBy, xAxisType } = availability;
|
|
37
|
+
if (xAxisType === null)
|
|
38
|
+
return false;
|
|
39
|
+
const capabilities = CHART_TYPE_CONFIG[chartType];
|
|
40
|
+
const supportedXAxisTypes = capabilities.supportedXAxisTypes;
|
|
41
|
+
if (!supportedXAxisTypes.includes(xAxisType)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (hasGroupBy && !capabilities.supportsGrouping) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Chart types valid for the current axis + feature combination.
|
|
51
|
+
*/
|
|
52
|
+
export function getAvailableChartTypes(availability) {
|
|
53
|
+
return CHART_TYPE_ORDER.filter((chartType) => isChartTypeAvailable(chartType, availability));
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=chart-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-capabilities.js","sourceRoot":"","sources":["../../src/core/chart-capabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAmBlD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,EAAE;QACH,mBAAmB,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC;QACpD,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,IAAI;KAC5B;IACD,IAAI,EAAE;QACJ,mBAAmB,EAAE,CAAC,MAAM,CAAC;QAC7B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,IAAI;KAC5B;IACD,IAAI,EAAE;QACJ,mBAAmB,EAAE,CAAC,MAAM,CAAC;QAC7B,gBAAgB,EAAE,IAAI;QACtB,qBAAqB,EAAE,IAAI;KAC5B;IACD,GAAG,EAAE;QACH,mBAAmB,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;QAC5C,gBAAgB,EAAE,KAAK;QACvB,qBAAqB,EAAE,KAAK;KAC7B;IACD,KAAK,EAAE;QACL,mBAAmB,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;QAC5C,gBAAgB,EAAE,KAAK;QACvB,qBAAqB,EAAE,KAAK;KAC7B;CAC0D,CAAA;AAO7D;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAAoB,EACpB,YAAmC;IAEnC,MAAM,EAAC,UAAU,EAAE,SAAS,EAAC,GAAG,YAAY,CAAA;IAC5C,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAEpC,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAA;IACjD,MAAM,mBAAmB,GAA6B,YAAY,CAAC,mBAAmB,CAAA;IACtF,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,UAAU,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;QACjD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,YAAmC;IACxE,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,oBAAoB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAA;AAC9F,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color assignment for chart series.
|
|
3
|
+
*
|
|
4
|
+
* Uses shadcn chart CSS variables (`--chart-1` through `--chart-5`) by default.
|
|
5
|
+
* Falls back to a built-in OKLCH palette when CSS variables are not available.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Get a color for the Nth series.
|
|
9
|
+
* Cycles through the palette when index exceeds palette length.
|
|
10
|
+
*
|
|
11
|
+
* @param index - Zero-based series index
|
|
12
|
+
* @param useShadcn - Whether to use shadcn CSS variables (default: true)
|
|
13
|
+
* @returns CSS color value
|
|
14
|
+
*/
|
|
15
|
+
export declare function getSeriesColor(index: number, useShadcn?: boolean): string;
|
|
16
|
+
/**
|
|
17
|
+
* Generate a color map for a list of group labels.
|
|
18
|
+
* Assigns colors deterministically based on array order.
|
|
19
|
+
*
|
|
20
|
+
* @param groups - Array of group labels
|
|
21
|
+
* @param useShadcn - Whether to use shadcn CSS variables (default: true)
|
|
22
|
+
* @returns Map from group label to CSS color
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildColorMap(groups: string[], useShadcn?: boolean): Map<string, string>;
|
|
25
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/core/colors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,UAAO,GAAG,MAAM,CAGtE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAS,UAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAMrF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color assignment for chart series.
|
|
3
|
+
*
|
|
4
|
+
* Uses shadcn chart CSS variables (`--chart-1` through `--chart-5`) by default.
|
|
5
|
+
* Falls back to a built-in OKLCH palette when CSS variables are not available.
|
|
6
|
+
*/
|
|
7
|
+
/** Fallback palette using OKLCH for perceptually uniform colors. */
|
|
8
|
+
const FALLBACK_COLORS = [
|
|
9
|
+
'oklch(0.65 0.15 250)', // blue
|
|
10
|
+
'oklch(0.65 0.15 350)', // rose
|
|
11
|
+
'oklch(0.65 0.15 200)', // cyan
|
|
12
|
+
'oklch(0.65 0.15 70)', // amber
|
|
13
|
+
'oklch(0.65 0.15 150)', // teal
|
|
14
|
+
'oklch(0.65 0.15 30)', // orange
|
|
15
|
+
'oklch(0.65 0.15 300)', // purple
|
|
16
|
+
'oklch(0.65 0.15 120)', // green
|
|
17
|
+
'oklch(0.65 0.12 170)', // mint
|
|
18
|
+
'oklch(0.65 0.12 220)', // slate blue
|
|
19
|
+
];
|
|
20
|
+
/** Shadcn chart CSS variables (5 colors) with safe fallbacks. */
|
|
21
|
+
const SHADCN_CHART_COLORS = [
|
|
22
|
+
`hsl(var(--chart-1, var(--cs-chart-1, 245 72% 57%)))`,
|
|
23
|
+
`hsl(var(--chart-2, var(--cs-chart-2, 271 72% 55%)))`,
|
|
24
|
+
`hsl(var(--chart-3, var(--cs-chart-3, 330 68% 54%)))`,
|
|
25
|
+
`hsl(var(--chart-4, var(--cs-chart-4, 170 65% 38%)))`,
|
|
26
|
+
`hsl(var(--chart-5, var(--cs-chart-5, 30 90% 54%)))`,
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Get a color for the Nth series.
|
|
30
|
+
* Cycles through the palette when index exceeds palette length.
|
|
31
|
+
*
|
|
32
|
+
* @param index - Zero-based series index
|
|
33
|
+
* @param useShadcn - Whether to use shadcn CSS variables (default: true)
|
|
34
|
+
* @returns CSS color value
|
|
35
|
+
*/
|
|
36
|
+
export function getSeriesColor(index, useShadcn = true) {
|
|
37
|
+
const palette = useShadcn ? SHADCN_CHART_COLORS : FALLBACK_COLORS;
|
|
38
|
+
return palette[index % palette.length];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generate a color map for a list of group labels.
|
|
42
|
+
* Assigns colors deterministically based on array order.
|
|
43
|
+
*
|
|
44
|
+
* @param groups - Array of group labels
|
|
45
|
+
* @param useShadcn - Whether to use shadcn CSS variables (default: true)
|
|
46
|
+
* @returns Map from group label to CSS color
|
|
47
|
+
*/
|
|
48
|
+
export function buildColorMap(groups, useShadcn = true) {
|
|
49
|
+
const map = new Map();
|
|
50
|
+
for (let i = 0; i < groups.length; i++) {
|
|
51
|
+
map.set(groups[i], getSeriesColor(i, useShadcn));
|
|
52
|
+
}
|
|
53
|
+
return map;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../../src/core/colors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oEAAoE;AACpE,MAAM,eAAe,GAAG;IACtB,sBAAsB,EAAE,OAAO;IAC/B,sBAAsB,EAAE,OAAO;IAC/B,sBAAsB,EAAE,OAAO;IAC/B,qBAAqB,EAAE,QAAQ;IAC/B,sBAAsB,EAAE,OAAO;IAC/B,qBAAqB,EAAE,SAAS;IAChC,sBAAsB,EAAE,SAAS;IACjC,sBAAsB,EAAE,QAAQ;IAChC,sBAAsB,EAAE,OAAO;IAC/B,sBAAsB,EAAE,aAAa;CAC7B,CAAA;AAEV,iEAAiE;AACjE,MAAM,mBAAmB,GAAG;IAC1B,qDAAqD;IACrD,qDAAqD;IACrD,qDAAqD;IACrD,qDAAqD;IACrD,oDAAoD;CAC5C,CAAA;AAEV;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,SAAS,GAAG,IAAI;IAC5D,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,eAAe,CAAA;IACjE,OAAO,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAE,CAAA;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAgB,EAAE,SAAS,GAAG,IAAI;IAC9D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAA;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,EAAE,cAAc,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ChartType, TimeBucket } from './types.js';
|
|
2
|
+
type IdOption<TId extends string> = {
|
|
3
|
+
id: TId;
|
|
4
|
+
};
|
|
5
|
+
type IdControlConfig<TId extends string> = {
|
|
6
|
+
allowed?: readonly TId[];
|
|
7
|
+
hidden?: readonly TId[];
|
|
8
|
+
default?: TId;
|
|
9
|
+
};
|
|
10
|
+
type ValueControlConfig<TValue extends string> = {
|
|
11
|
+
allowed?: readonly TValue[];
|
|
12
|
+
hidden?: readonly TValue[];
|
|
13
|
+
default?: TValue;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Restrict an ID-keyed option list with `allowed`/`hidden`.
|
|
17
|
+
*
|
|
18
|
+
* When `fallbackToBaseIfEmpty` is enabled, required controls keep their base
|
|
19
|
+
* runtime options even if the config does not match the active source.
|
|
20
|
+
*/
|
|
21
|
+
export declare function restrictConfiguredIdOptions<TId extends string, TOption extends IdOption<TId>>(options: readonly TOption[], config: IdControlConfig<TId> | undefined, fallbackToBaseIfEmpty?: boolean): TOption[];
|
|
22
|
+
/**
|
|
23
|
+
* Resolve one ID-based selection against the current option list.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveConfiguredIdSelection<TId extends string>(currentValue: TId | null, options: readonly IdOption<TId>[], configuredDefault: TId | undefined, fallbackValue: TId | null, preferFirstAvailable?: boolean): TId | null;
|
|
26
|
+
/**
|
|
27
|
+
* Restrict a primitive option list with `allowed`/`hidden`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function restrictConfiguredValues<TValue extends string>(values: readonly TValue[], config: ValueControlConfig<TValue> | undefined, fallbackToBaseIfEmpty?: boolean): TValue[];
|
|
30
|
+
/**
|
|
31
|
+
* Resolve one primitive selection against the current option list.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveConfiguredValue<TValue extends string>(currentValue: TValue, values: readonly TValue[], configuredDefault: TValue | undefined): TValue;
|
|
34
|
+
/**
|
|
35
|
+
* Ordered time buckets exposed by the headless API.
|
|
36
|
+
*/
|
|
37
|
+
export declare const TIME_BUCKET_ORDER: readonly TimeBucket[];
|
|
38
|
+
/**
|
|
39
|
+
* Ordered chart types exposed by the headless API.
|
|
40
|
+
*/
|
|
41
|
+
export declare const CHART_TYPE_ORDER: readonly ChartType[];
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=config-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-utils.d.ts","sourceRoot":"","sources":["../../src/core/config-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACX,MAAM,YAAY,CAAA;AAEnB,KAAK,QAAQ,CAAC,GAAG,SAAS,MAAM,IAAI;IAClC,EAAE,EAAE,GAAG,CAAA;CACR,CAAA;AAED,KAAK,eAAe,CAAC,GAAG,SAAS,MAAM,IAAI;IACzC,OAAO,CAAC,EAAE,SAAS,GAAG,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,SAAS,GAAG,EAAE,CAAA;IACvB,OAAO,CAAC,EAAE,GAAG,CAAA;CACd,CAAA;AAED,KAAK,kBAAkB,CAAC,MAAM,SAAS,MAAM,IAAI;IAC/C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AA+CD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,SAAS,MAAM,EAAE,OAAO,SAAS,QAAQ,CAAC,GAAG,CAAC,EAC3F,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,SAAS,EACxC,qBAAqB,UAAQ,GAC5B,OAAO,EAAE,CAEX;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,SAAS,MAAM,EAC7D,YAAY,EAAE,GAAG,GAAG,IAAI,EACxB,OAAO,EAAE,SAAS,QAAQ,CAAC,GAAG,CAAC,EAAE,EACjC,iBAAiB,EAAE,GAAG,GAAG,SAAS,EAClC,aAAa,EAAE,GAAG,GAAG,IAAI,EACzB,oBAAoB,UAAO,GAC1B,GAAG,GAAG,IAAI,CAcZ;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,SAAS,MAAM,EAC5D,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAAG,SAAS,EAC9C,qBAAqB,UAAQ,GAC5B,MAAM,EAAE,CAEV;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,SAAS,MAAM,EAC1D,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,iBAAiB,EAAE,MAAM,GAAG,SAAS,GACpC,MAAM,CAUR;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,UAAU,EAAgD,CAAA;AAEnG;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,SAAS,EAA4C,CAAA"}
|