basalt-ui 2.6.0 → 2.7.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/AGENTS.md +15 -15
- package/CHANGELOG.md +24 -0
- package/MIGRATING.md +50 -12
- package/agent/rules/basalt-batteries.md +2 -2
- package/agent/rules/basalt-controls.md +1 -1
- package/agent/skills/basalt-app/SKILL.md +2 -3
- package/agent/skills/basalt-charts/SKILL.md +1 -1
- package/agent/skills/basalt-design/SKILL.md +1 -1
- package/configs/oxlint-plugin.js +48 -0
- package/configs/oxlint-plugin.test.ts +82 -0
- package/dist/charts/Bars.d.ts +1 -1
- package/dist/charts/Bars.d.ts.map +1 -1
- package/dist/charts/Bars.js +9 -2
- package/dist/charts/legend.d.ts.map +1 -1
- package/dist/charts/legend.js +9 -1
- package/dist/controls/form-layout.d.ts +15 -6
- package/dist/controls/form-layout.d.ts.map +1 -1
- package/dist/forms/field.d.ts +42 -2
- package/dist/forms/field.d.ts.map +1 -1
- package/dist/forms/field.js +2 -2
- package/dist/forms/index.d.ts +4 -5
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/surfaces.d.ts +1 -1
- package/dist/surfaces.js +1 -1
- package/dist/table/data-table.d.ts +33 -0
- package/dist/table/data-table.d.ts.map +1 -1
- package/dist/table/data-table.js +100 -17
- package/dist/telemetry.d.ts +5 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/llms.txt +343 -11
- package/package.json +1 -1
- package/src/charts/Bars.tsx +13 -3
- package/src/charts/legend.tsx +9 -2
- package/src/controls/form-layout.tsx +15 -6
- package/src/forms/field.ts +78 -3
- package/src/forms/index.ts +4 -5
- package/src/surfaces.ts +1 -1
- package/src/table/data-table.tsx +171 -17
- package/src/telemetry.ts +5 -0
package/llms.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# basalt-ui v2.
|
|
1
|
+
# basalt-ui v2.7.0
|
|
2
2
|
# Opinionated framework for Mantine-based React apps — theme, app shell, TanStack Charts, toolchain presets
|
|
3
3
|
#
|
|
4
4
|
# Entry points: use the exact import specifier below; do not guess.
|
|
@@ -13,13 +13,39 @@
|
|
|
13
13
|
# A subpath's `Install:` line is its required peers; `OptionalPeers:` are import()-only, install on use.
|
|
14
14
|
|
|
15
15
|
Package: basalt-ui
|
|
16
|
-
Version: 2.
|
|
16
|
+
Version: 2.7.0
|
|
17
17
|
|
|
18
18
|
## basalt-ui
|
|
19
19
|
Import: import { ... } from 'basalt-ui'
|
|
20
20
|
Description: Wiring (`BasaltProvider`, `createBasaltTheme`, `createBasaltRouter`, `unwrap`), shell + nav (`BasaltShell`, `PageBar`, `PageAside`, `PageTitle`, `ThemeToggle`, `defineNav`/`navGroup`/`navTarget`/`flattenNav`, `useBasaltNav`, `useSizeClass`, `useCoarsePointer`), dashboard (`Section`, `WidgetHeader`, `StatCard`, `StatGroup`, `DeltaBadge`, `EmptyState`, `SettingsSection`/`SettingsRow`/`DangerZone`). Reaches no subpath-required peer.
|
|
21
21
|
Layer: mantine-coupled
|
|
22
22
|
Rule: basalt-mantine
|
|
23
|
+
Signature: BasaltProvider(props: BasaltProviderProps): JSX.Element
|
|
24
|
+
Signature: BasaltShell(props: BasaltShellProps<G, T>): JSX.Element
|
|
25
|
+
Signature: DangerZone(props: SettingsSectionProps): JSX.Element
|
|
26
|
+
Signature: DeltaBadge(props: DeltaBadgeProps): JSX.Element
|
|
27
|
+
Signature: EmptyState(props: EmptyStateProps): JSX.Element
|
|
28
|
+
Signature: PageAside(props: PageAsideProps): ReactNode
|
|
29
|
+
Signature: PageBar(props: PageBarProps): ReactNode
|
|
30
|
+
Signature: PageTitle(props: PageTitleProps): ReactNode
|
|
31
|
+
Signature: Section(props: SectionProps): JSX.Element
|
|
32
|
+
Signature: SettingsRow(props: SettingsRowProps): JSX.Element
|
|
33
|
+
Signature: SettingsSection(props: SettingsSectionProps): JSX.Element
|
|
34
|
+
Signature: StatCard(props: StatCardProps): JSX.Element
|
|
35
|
+
Signature: StatGroup(props: StatGroupProps): JSX.Element
|
|
36
|
+
Signature: ThemeToggle(props: ThemeToggleProps): JSX.Element
|
|
37
|
+
Signature: WidgetHeader(props: WidgetHeaderProps): JSX.Element
|
|
38
|
+
Signature: createBasaltRouter(options: { routeTree: TRouteTree; context?: TContext; query?: QueryClientConfi…): BasaltRouter<TRouteTree>
|
|
39
|
+
Signature: createBasaltTheme(overrides: Omit<PartialObjectDeep<MantineTheme, { recurseIntoArrays: false; allo…, options: CreateBasaltThemeOptions | undefined): PartialObjectDeep<Ma…
|
|
40
|
+
Signature: defineNav(config: "basalt: declare Register { router }"): NavConfig<G, T>
|
|
41
|
+
Signature: flattenNav(config: { groups: ReadonlyArray<AnyNavGroup>; }): FlatNavItem[]
|
|
42
|
+
Signature: navGroup(meta: Exact<M, NavGroupMeta>, items: NavItemsInput<T>): M & { items: T; }
|
|
43
|
+
Signature: navTarget(config: C, id: K): NavIndex<C["groups"]>[K]
|
|
44
|
+
Signature: scrollParentOf(el: Element | null): HTMLElement | null
|
|
45
|
+
Signature: unwrap(response: R): UnwrapResult<R>
|
|
46
|
+
Signature: useBasaltNav(): { currentPath: string; isActive: (href: string, opts?: { exact?: bool…
|
|
47
|
+
Signature: useCoarsePointer(): boolean
|
|
48
|
+
Signature: useSizeClass(): "compact" | "medium" | "expanded"
|
|
23
49
|
OptionalPeers: remark-gfm@^4.0.1, rehype-sanitize@^6.0.0, remend@1.4.0, shiki@^4.5.0, beautiful-mermaid@^1.1.0, @tanstack/react-router-devtools@^1.166.13
|
|
24
50
|
|
|
25
51
|
## basalt-ui/charts
|
|
@@ -27,6 +53,209 @@ Import: import { ... } from 'basalt-ui/charts'
|
|
|
27
53
|
Description: CartesianChart (the TanStack Charts rung), the Lines and Bars kinds, ChartCard and the shared chartCursor (Mantine-free; @tanstack/charts + d3-scale peers)
|
|
28
54
|
Layer: headless
|
|
29
55
|
Rule: basalt-charts
|
|
56
|
+
Signature: BandStrip(props: BandStripProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
57
|
+
className?: string
|
|
58
|
+
style?: CSSProperties
|
|
59
|
+
ariaLabel: string
|
|
60
|
+
data: readonly T[]
|
|
61
|
+
x: (d: T) => X
|
|
62
|
+
xTicks?: number | readonly X[]
|
|
63
|
+
formatX?: ((x: X) => string)
|
|
64
|
+
legend?: false | ChartLegendConfig
|
|
65
|
+
height?: number | ResponsiveChartHeight
|
|
66
|
+
state?: ChartState
|
|
67
|
+
cursorGroup?: string
|
|
68
|
+
cursorResolution?: CursorResolution
|
|
69
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
70
|
+
states: readonly BandStripSeries<T>[]
|
|
71
|
+
getBand: (d: T) => BandSpan
|
|
72
|
+
fold?: BandFold<T>
|
|
73
|
+
Signature: Bars(props: BarsProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
74
|
+
className?: string
|
|
75
|
+
style?: CSSProperties
|
|
76
|
+
ariaLabel: string
|
|
77
|
+
data: readonly T[]
|
|
78
|
+
x: (d: T) => X
|
|
79
|
+
y?: AxisConfig<T>
|
|
80
|
+
y2?: AxisConfig<T>
|
|
81
|
+
xTicks?: number | readonly X[]
|
|
82
|
+
formatX?: ((x: X) => string)
|
|
83
|
+
zones?: readonly ZoneSpec[]
|
|
84
|
+
xZones?: readonly XZoneSpec<X>[]
|
|
85
|
+
refLines?: readonly RefLine[]
|
|
86
|
+
legend?: false | ChartLegendConfig
|
|
87
|
+
height?: number | ResponsiveChartHeight
|
|
88
|
+
state?: ChartState
|
|
89
|
+
cursorGroup?: string
|
|
90
|
+
cursorResolution?: CursorResolution
|
|
91
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
92
|
+
bars: readonly BarsBar<T>[]
|
|
93
|
+
lines?: readonly BarsLine<T>[]
|
|
94
|
+
layout?: "stacked" | "grouped" | "normalized"
|
|
95
|
+
barOpacity?: ((d: T, key: string) => number)
|
|
96
|
+
Signature: CartesianChart(props: CartesianChartProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
97
|
+
className?: string
|
|
98
|
+
style?: CSSProperties
|
|
99
|
+
ariaLabel: string
|
|
100
|
+
data: readonly T[]
|
|
101
|
+
x: (d: T) => X
|
|
102
|
+
series: readonly ChartSeries<T>[]
|
|
103
|
+
marks: (plot: PlotContext<T, X>) => ChartMarks
|
|
104
|
+
y?: AxisConfig<T>
|
|
105
|
+
y2?: AxisConfig<T>
|
|
106
|
+
xTicks?: number | readonly X[]
|
|
107
|
+
formatX?: ((x: X) => string)
|
|
108
|
+
zones?: readonly ZoneSpec[]
|
|
109
|
+
xZones?: readonly XZoneSpec<X>[]
|
|
110
|
+
refLines?: readonly RefLine[]
|
|
111
|
+
legend?: false | ChartLegendConfig
|
|
112
|
+
height?: number | ResponsiveChartHeight
|
|
113
|
+
state?: ChartState
|
|
114
|
+
cursorGroup?: string
|
|
115
|
+
cursorResolution?: CursorResolution
|
|
116
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
117
|
+
Signature: ChartCard(props: ChartCardProps): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
118
|
+
className?: string
|
|
119
|
+
style?: CSSProperties
|
|
120
|
+
classNames?: Partial<Record<ChartCardSlot, string>>
|
|
121
|
+
title?: string
|
|
122
|
+
icon?: ReactNode
|
|
123
|
+
subtitle?: string
|
|
124
|
+
info?: string
|
|
125
|
+
value?: string
|
|
126
|
+
delta?: number
|
|
127
|
+
deltaPeriod?: string
|
|
128
|
+
deltaPolarity?: DeltaPolarity
|
|
129
|
+
count?: number
|
|
130
|
+
actions?: ReactNode
|
|
131
|
+
state?: ChartState
|
|
132
|
+
placeholderHeight?: number | ResponsiveChartHeight
|
|
133
|
+
stateAction?: ReactNode
|
|
134
|
+
children?: ReactNode
|
|
135
|
+
Signature: Donut(props: DonutProps<K>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
136
|
+
className?: string
|
|
137
|
+
style?: CSSProperties
|
|
138
|
+
ariaLabel: string
|
|
139
|
+
data: readonly DonutDatum<K>[]
|
|
140
|
+
colorForKey: (key: K) => string
|
|
141
|
+
formatValue: (v: number) => string
|
|
142
|
+
seriesLabel?: ((key: K) => string)
|
|
143
|
+
centerLabel?: string
|
|
144
|
+
centerSubLabel?: string
|
|
145
|
+
height?: number | ResponsiveChartHeight
|
|
146
|
+
state?: ChartState
|
|
147
|
+
Signature: DualPanel(props: DualPanelProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
148
|
+
className?: string
|
|
149
|
+
style?: CSSProperties
|
|
150
|
+
ariaLabel: string
|
|
151
|
+
data: readonly T[]
|
|
152
|
+
x: (d: T) => X
|
|
153
|
+
formatX?: ((x: X) => string)
|
|
154
|
+
legend?: false | ChartLegendConfig
|
|
155
|
+
height?: number | ResponsiveChartHeight
|
|
156
|
+
state?: ChartState
|
|
157
|
+
cursorGroup?: string
|
|
158
|
+
cursorResolution?: CursorResolution
|
|
159
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
160
|
+
series: readonly DualPanelLine<T>[]
|
|
161
|
+
top?: { domain?: readonly [number, number] | "auto" | undefined; …
|
|
162
|
+
fillBetween?: { from: string; to: string; fill: string; aboveFill?: strin…
|
|
163
|
+
bar: DualPanelBar<T>
|
|
164
|
+
topFraction?: number
|
|
165
|
+
Signature: Heatmap(props: HeatmapProps<T>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
166
|
+
className?: string
|
|
167
|
+
style?: CSSProperties
|
|
168
|
+
ariaLabel: string
|
|
169
|
+
data: readonly T[]
|
|
170
|
+
getRow: (d: T) => string
|
|
171
|
+
getCol: (d: T) => string
|
|
172
|
+
getValue: (d: T) => number | null
|
|
173
|
+
rows?: readonly string[]
|
|
174
|
+
cols?: readonly string[]
|
|
175
|
+
color?: string
|
|
176
|
+
domain?: readonly [number, number]
|
|
177
|
+
formatValue?: ((v: number) => string)
|
|
178
|
+
formatRow?: ((row: string) => string)
|
|
179
|
+
formatCol?: ((col: string) => string)
|
|
180
|
+
legend?: false | { label?: string | undefined; }
|
|
181
|
+
tooltip?: false | { rows?: ((d: T) => readonly ChartTooltipRow[]) | u…
|
|
182
|
+
height?: number | ResponsiveChartHeight
|
|
183
|
+
matchHeight?: boolean
|
|
184
|
+
state?: ChartState
|
|
185
|
+
Signature: Lines(props: LinesProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
186
|
+
className?: string
|
|
187
|
+
style?: CSSProperties
|
|
188
|
+
ariaLabel: string
|
|
189
|
+
data: readonly T[]
|
|
190
|
+
x: (d: T) => X
|
|
191
|
+
series: readonly ChartSeries<T>[]
|
|
192
|
+
y?: AxisConfig<T>
|
|
193
|
+
y2?: AxisConfig<T>
|
|
194
|
+
xTicks?: number | readonly X[]
|
|
195
|
+
formatX?: ((x: X) => string)
|
|
196
|
+
zones?: readonly ZoneSpec[]
|
|
197
|
+
xZones?: readonly XZoneSpec<X>[]
|
|
198
|
+
refLines?: readonly RefLine[]
|
|
199
|
+
legend?: false | ChartLegendConfig
|
|
200
|
+
height?: number | ResponsiveChartHeight
|
|
201
|
+
state?: ChartState
|
|
202
|
+
cursorGroup?: string
|
|
203
|
+
cursorResolution?: CursorResolution
|
|
204
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
205
|
+
thresholds?: [X] extends [string] ? never : readonly Threshold[]
|
|
206
|
+
Signature: MirroredBars(props: MirroredBarsProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
207
|
+
className?: string
|
|
208
|
+
style?: CSSProperties
|
|
209
|
+
ariaLabel: string
|
|
210
|
+
data: readonly T[]
|
|
211
|
+
x: (d: T) => X
|
|
212
|
+
formatX?: ((x: X) => string)
|
|
213
|
+
legend?: false | ChartLegendConfig
|
|
214
|
+
height?: number | ResponsiveChartHeight
|
|
215
|
+
state?: ChartState
|
|
216
|
+
cursorGroup?: string
|
|
217
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
218
|
+
series: readonly MirroredBarsSeries<T>[]
|
|
219
|
+
up: MirroredBarPane
|
|
220
|
+
down: MirroredBarPane
|
|
221
|
+
upFraction?: number
|
|
222
|
+
getAbsentFraction?: ((d: T) => number)
|
|
223
|
+
getBarOpacity?: ((d: T) => number)
|
|
224
|
+
fold?: { minBandPx?: number | undefined; merge: (group: T[]) => T;…
|
|
225
|
+
cursorResolution?: CursorResolution
|
|
226
|
+
Signature: Sparkline(props: SparklineProps): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
227
|
+
className?: string
|
|
228
|
+
style?: CSSProperties
|
|
229
|
+
ariaLabel: string
|
|
230
|
+
data: readonly number[]
|
|
231
|
+
height: number
|
|
232
|
+
width?: number
|
|
233
|
+
mark?: "line" | "bar"
|
|
234
|
+
color?: string
|
|
235
|
+
emphasizeLast?: boolean
|
|
236
|
+
emphasisColor?: string
|
|
237
|
+
state?: ChartState
|
|
238
|
+
Signature: StackedArea(props: StackedAreaProps<T, X>): ReactElement<unknown, string | JSXElementConstructor<any>>
|
|
239
|
+
className?: string
|
|
240
|
+
style?: CSSProperties
|
|
241
|
+
ariaLabel: string
|
|
242
|
+
data: readonly T[]
|
|
243
|
+
x: (d: T) => X
|
|
244
|
+
xTicks?: number | readonly X[]
|
|
245
|
+
formatX?: ((x: X) => string)
|
|
246
|
+
zones?: readonly ZoneSpec[]
|
|
247
|
+
xZones?: readonly XZoneSpec<X>[]
|
|
248
|
+
refLines?: readonly RefLine[]
|
|
249
|
+
legend?: false | ChartLegendConfig
|
|
250
|
+
height?: number | ResponsiveChartHeight
|
|
251
|
+
state?: ChartState
|
|
252
|
+
cursorGroup?: string
|
|
253
|
+
cursorResolution?: CursorResolution
|
|
254
|
+
tooltip?: false | ChartTooltipConfig<T, X>
|
|
255
|
+
series: readonly StackedAreaBand<T>[]
|
|
256
|
+
y?: Omit<AxisConfig<T>, "scale">
|
|
257
|
+
Signature: chartCursor(group: string): ChartCursorController<ChartValue, ChartValue>
|
|
258
|
+
Signature: chartCurve(name: CurveName): ChartCurve
|
|
30
259
|
Install: bun add @tanstack/charts@1.1.0 d3-scale@4.0.2
|
|
31
260
|
|
|
32
261
|
## basalt-ui/tokens
|
|
@@ -34,11 +263,24 @@ Import: import { ... } from 'basalt-ui/tokens'
|
|
|
34
263
|
Description: VX token refs, buildPaletteCss, defineSeries, seriesTokens, groupTokens, alpha (Mantine-free)
|
|
35
264
|
Layer: headless
|
|
36
265
|
Rule: basalt-tokens
|
|
266
|
+
Signature: BP: { black, white, darkGray, gray, lightGray, blue, green, orange, red, vermilion, rose, violet, indigo, cerulean, turquoise, forest, lime, gold, sepia }
|
|
267
|
+
Signature: CONTAINER_CLASSES: { micro, compact, regular, wide }
|
|
268
|
+
Signature: CONTAINER_GRID_BREAKPOINTS: { xs, sm, md, lg, xl }
|
|
269
|
+
Signature: CONTAINER_KEYS: { compact, regular, wide }
|
|
270
|
+
Signature: VX: { lineWidth, line2Width, axisFont, dotR, dashArray, legendGap, legendFontSize, text, radiusCard, radiusCtrl, radiusPill, hit, space, line2Dark, good, goodSoft, bad, …
|
|
271
|
+
Signature: alpha(token: string, a: number): string
|
|
272
|
+
Signature: buildPaletteCss(opts: BuildPaletteOpts, data: { ACCENT: { readonly accent: ColorPair; readonly accentHover: ColorPa…): string
|
|
273
|
+
Signature: defineSeries(map: T): T
|
|
274
|
+
Signature: groupTokens(name: string, map: T): { readonly [K in keyof T]: GroupRef; }
|
|
275
|
+
Signature: p(fam: readonly string[], light: number, dark: number): ColorPair
|
|
276
|
+
Signature: seriesTokens(map: T, prefix: string): { [K in keyof T]: string; }
|
|
37
277
|
|
|
38
278
|
## basalt-ui/vite
|
|
39
279
|
Import: import { ... } from 'basalt-ui/vite'
|
|
40
280
|
Description: basaltViteConfig(opts) — Vite preset for basalt-ui consumer apps; basaltAppPlugin(opts) — PWA head, manifest, and icon metadata derived from the token palette
|
|
41
281
|
Layer: build-tooling
|
|
282
|
+
Signature: basaltAppPlugin(options: BasaltAppOptions): PluginOption[]
|
|
283
|
+
Signature: basaltViteConfig(opts: BasaltViteOptions): UserConfig
|
|
42
284
|
Install: bun add 'vite@^7 || ^8'
|
|
43
285
|
OptionalPeers: vite-plugin-pwa@^1.3.0
|
|
44
286
|
|
|
@@ -46,20 +288,25 @@ OptionalPeers: vite-plugin-pwa@^1.3.0
|
|
|
46
288
|
Import: import { ... } from 'basalt-ui/format'
|
|
47
289
|
Description: integer/money/percent/durationClock/relativeTime/weekday/km/kcal — Intl-backed, Mantine-free, React-free formatting; the chart layer formats through the same implementation
|
|
48
290
|
Layer: headless
|
|
49
|
-
Signature:
|
|
50
|
-
Signature:
|
|
51
|
-
Signature:
|
|
52
|
-
Signature: km(meters: number,
|
|
53
|
-
Signature:
|
|
54
|
-
Signature:
|
|
55
|
-
Signature: relativeTime(value:
|
|
56
|
-
Signature: weekday(value:
|
|
291
|
+
Signature: durationClock(seconds: number): string
|
|
292
|
+
Signature: integer(value: number, options: LocaleOption): string
|
|
293
|
+
Signature: kcal(value: number, options: KcalOptions): string
|
|
294
|
+
Signature: km(meters: number, options: KmOptions): string
|
|
295
|
+
Signature: money(value: number, options: FmtCurrencyOptions): string
|
|
296
|
+
Signature: percent(value: number, options: FmtPercentOptions): string
|
|
297
|
+
Signature: relativeTime(value: string | number | Date, options: RelativeTimeOptions): string
|
|
298
|
+
Signature: weekday(value: string | number | Date, options: WeekdayOptions): string
|
|
57
299
|
|
|
58
300
|
## basalt-ui/forms
|
|
59
301
|
Import: import { ... } from 'basalt-ui/forms'
|
|
60
302
|
Description: Mantine form layer: useBasaltForm + inputProps/fieldKey (two calls — a spread `key` is a React 19 warning), on @mantine/form
|
|
61
303
|
Layer: mantine-coupled
|
|
62
304
|
Rule: basalt-batteries
|
|
305
|
+
Signature: fieldKey(form: UseFormReturnType<Values>, path: Path): string
|
|
306
|
+
Signature: inputProps(form: UseFormReturnType<Values>, path: Path): InputProps
|
|
307
|
+
Signature: useBasaltForm(opts: UseBasaltFormOptions<Values>): UseFormReturnType<Values>
|
|
308
|
+
mode?: "controlled" | "uncontrolled"
|
|
309
|
+
schema?: StandardSchemaV1<unknown, Values>
|
|
63
310
|
Install: bun add @mantine/form@^9.7.0
|
|
64
311
|
|
|
65
312
|
## basalt-ui/commands
|
|
@@ -67,6 +314,15 @@ Import: import { ... } from 'basalt-ui/commands'
|
|
|
67
314
|
Description: defineCommands (typed command bus), defineOverlays/overlays, setColorScheme, toggleSidebar, ShortcutsHelp, defineNotifications/emit/NotificationBell (folded in from ./notifications); BasaltProvider mounts Spotlight, Modals and Notifications
|
|
68
315
|
Layer: mantine-coupled
|
|
69
316
|
Rule: basalt-batteries
|
|
317
|
+
Signature: NotificationBell(props: NotificationBellProps): JSX.Element
|
|
318
|
+
Signature: ShortcutsHelp(props: ShortcutsHelpProps): JSX.Element | null
|
|
319
|
+
Signature: defineCommands(spec: T): T
|
|
320
|
+
Signature: defineNotifications(spec: T): T
|
|
321
|
+
Signature: defineOverlays(spec: T): T
|
|
322
|
+
Signature: emit(kind: K, args: EmitArgs<K>): string
|
|
323
|
+
Signature: overlays: { open, confirm, confirmDelete, close }
|
|
324
|
+
Signature: setColorScheme(scheme: ColorScheme): void
|
|
325
|
+
Signature: toggleSidebar(): void
|
|
70
326
|
Install: bun add @tanstack/react-hotkeys@0.13.0
|
|
71
327
|
|
|
72
328
|
## basalt-ui/table
|
|
@@ -74,6 +330,49 @@ Import: import { ... } from 'basalt-ui/table'
|
|
|
74
330
|
Description: BasaltDataTable and createColumnHelper: a data table over TanStack Table v9, rendered with Mantine (renamed from ./data/table)
|
|
75
331
|
Layer: mantine-coupled
|
|
76
332
|
Rule: basalt-batteries
|
|
333
|
+
Signature: BasaltDataTable(props: BasaltDataTableProps<T>): JSX.Element
|
|
334
|
+
className?: string
|
|
335
|
+
style?: CSSProperties
|
|
336
|
+
classNames?: Partial<Record<BasaltDataTableSlot, string>>
|
|
337
|
+
title?: string
|
|
338
|
+
icon?: ReactNode
|
|
339
|
+
subtitle?: string
|
|
340
|
+
data: T[]
|
|
341
|
+
columns: BasaltColumnDef<T>[]
|
|
342
|
+
enableSorting?: boolean
|
|
343
|
+
manualSorting?: boolean
|
|
344
|
+
striped?: boolean | "odd" | "even"
|
|
345
|
+
highlightOnHover?: boolean
|
|
346
|
+
emptyState?: ReactNode
|
|
347
|
+
isLoading?: boolean
|
|
348
|
+
query?: QueryStateLike<unknown>
|
|
349
|
+
skeletonRows?: number
|
|
350
|
+
initialSorting?: SortingState
|
|
351
|
+
onSortingChange?: (sorting: SortingState) => void
|
|
352
|
+
enableGlobalFilter?: boolean
|
|
353
|
+
globalFilterPlaceholder?: string
|
|
354
|
+
searchIcon?: ReactNode
|
|
355
|
+
initialGlobalFilter?: string
|
|
356
|
+
onGlobalFilterChange?: (value: string) => void
|
|
357
|
+
facets?: DataTableFacet<T>[]
|
|
358
|
+
onColumnFiltersChange?: (filters: ColumnFiltersState) => void
|
|
359
|
+
manualFiltering?: boolean
|
|
360
|
+
actions?: SlotActions
|
|
361
|
+
onRowActivate?: (row: T) => void
|
|
362
|
+
renderCard?: (row: T) => ReactNode
|
|
363
|
+
enableRowSelection?: boolean
|
|
364
|
+
rowSelection?: RowSelectionState
|
|
365
|
+
onRowSelectionChange?: (selection: RowSelectionState) => void
|
|
366
|
+
getRowId?: (row: T, index: number) => string
|
|
367
|
+
bulkActions?: (rows: T[]) => BarAction[]
|
|
368
|
+
rowActions?: DataTableRowAction<T>[]
|
|
369
|
+
rowLabel?: (row: T) => string
|
|
370
|
+
enablePagination?: boolean
|
|
371
|
+
pageSizeOptions?: number[]
|
|
372
|
+
initialPagination?: PaginationState
|
|
373
|
+
onPaginationChange?: (pagination: PaginationState) => void
|
|
374
|
+
… +13 more
|
|
375
|
+
Signature: createColumnHelper(): ColumnHelper<{ rowSortingFeature: TableFeature; columnFilteringFeatur…
|
|
77
376
|
Install: bun add @tanstack/react-table@9.2.8
|
|
78
377
|
|
|
79
378
|
## basalt-ui/agent
|
|
@@ -81,6 +380,14 @@ Import: import { ... } from 'basalt-ui/agent'
|
|
|
81
380
|
Description: Streaming-chat surface: aiSdkTransport, useAgentThreadRuns, parseAgentPart, the open part-registry types, the consumer-owned thread contracts (AgentThread/ThreadsStore/ChatMessage), and the Mantine chat UI folded in from ./agent-chat (ThreadFeed, ThreadFeedRow, Composer, ToolChip). motion is subpath-required: the chat UI imports it eagerly
|
|
82
381
|
Layer: mantine-coupled
|
|
83
382
|
Rule: basalt-batteries
|
|
383
|
+
Signature: Composer(props: ComposerProps): JSX.Element
|
|
384
|
+
Signature: ThreadFeed(props: ThreadFeedProps): JSX.Element
|
|
385
|
+
Signature: ThreadFeedRow(props: ThreadFeedRowProps): JSX.Element
|
|
386
|
+
Signature: ToolChip(props: ToolChipProps): JSX.Element
|
|
387
|
+
Signature: aiSdkTransport(options: AiSdkTransportOptions): AiSdkTransport<TPart>
|
|
388
|
+
Signature: parseAgentPart(raw: unknown): AgentPart | null
|
|
389
|
+
Signature: toAgentError(error: unknown): AgentError
|
|
390
|
+
Signature: useAgentThreadRuns(props: UseAgentThreadRunsArgs<TPart>): UseAgentThreadRunsReturn<TPart>
|
|
84
391
|
Install: bun add ai@^7.0.137 @ai-sdk/provider@^4.0.26 motion@14.1.0
|
|
85
392
|
OptionalPeers: use-stick-to-bottom@^1.1.6, @tanstack/react-virtual@>=3.14.0 <4
|
|
86
393
|
|
|
@@ -89,20 +396,40 @@ Import: import { ... } from 'basalt-ui/content'
|
|
|
89
396
|
Description: Prose (article/chat typography), Callout, TableOfContents, Markdown (react-markdown + remark-gfm, optional peers; `streaming` is a rendering mode ONLY — `contentTrust` is the independent security input, and any surface rendering agent/model output must pin `contentTrust="untrusted"`, the sole input to the image-origin allowlist; `fenceRenderers` extends fenced-block rendering — settledOnly/FenceRenderer/FenceRenderers; `sanitizeSchema` is an additions-only SanitizeSchemaExtension merged over the default via mergeSanitizeSchema; shiki code blocks, beautiful-mermaid diagrams and the remend streaming repair load lazily from optional peers), ArticleLayout (docs-page frame), GuideLink (contextual-help link) — the content/prose surface
|
|
90
397
|
Layer: mantine-coupled
|
|
91
398
|
Rule: basalt-batteries
|
|
399
|
+
Signature: ArticleLayout(props: ArticleLayoutProps): JSX.Element
|
|
400
|
+
Signature: Callout(props: CalloutProps): JSX.Element
|
|
401
|
+
Signature: GuideLink(props: GuideLinkProps): JSX.Element
|
|
402
|
+
Signature: Markdown(props: MarkdownProps): JSX.Element
|
|
403
|
+
Signature: Prose(props: ProseProps): JSX.Element
|
|
404
|
+
Signature: TableOfContents(props: TableOfContentsProps): JSX.Element | null
|
|
405
|
+
Signature: mergeSanitizeSchema(base: SanitizeSchemaInput, extensions: readonly (SanitizeSchemaExtension | undefined)[]): SanitizeSchema
|
|
406
|
+
Signature: settledOnly(render: FenceRenderer): FenceRenderer
|
|
92
407
|
Install: bun add react-markdown@^10.1.0
|
|
93
408
|
OptionalPeers: shiki@^4.5.0, @shikijs/langs@^4.5.0, @shikijs/themes@^4.5.0, beautiful-mermaid@^1.1.0, remark-gfm@^4.0.1, rehype-sanitize@^6.0.0, remend@1.4.0
|
|
94
409
|
|
|
95
410
|
## basalt-ui/controls
|
|
96
411
|
Import: import { ... } from 'basalt-ui/controls'
|
|
97
|
-
Description: The control tier (docs/CONTROLS-SPEC.md §3): FilterSet (nowrap row + measured +N fold + the mobile Filters (n) sheet), RangeFilter
|
|
412
|
+
Description: The control tier (docs/CONTROLS-SPEC.md §3). Exports: `FilterSet` (nowrap row + measured +N fold + the mobile Filters (n) sheet), `RangeFilter`/`SelectFilter`/`MultiSelectFilter`/`NumberFilter`/`SearchFilter`/`ToggleFilter` (each bound to a FieldHandle — no value/onChange/size, law C2/C5; `NumberFilter` is the field.number lane, a radio list over `options` or a stepper without), `ViewTabs`, `SyncButton` with the `BarAction`/`GlobalAction` types, and the form layout `FormRow`/`FormGroup` (moved here from ./forms in 1.36.0 — `FormRow` is law C1’s form row and needs no @mantine/form). THREE surfaces, picked by the home and never by a prop: pill in a PageBar row, sheet in the mobile Filters (n) drawer, panel in a PageAside body — where every control renders an inspector/facet ROW instead of a chip (docs/ASIDE-SPEC.md §3); the counts/max props on `MultiSelectFilter` render the Foundry facet list there. Every control owns its own desktop/mobile swap in CSS (C9) and renders size="ctl" internally. Resolves and renders with NO @mantine/dates installed — the custom date picker is injected through RangeFilter.customPicker from ./controls-dates.
|
|
98
413
|
Layer: mantine-coupled
|
|
99
414
|
Rule: basalt-controls
|
|
415
|
+
Signature: FilterSet(props: FilterSetProps): ReactNode
|
|
416
|
+
Signature: FormGroup(props: FormGroupProps): JSX.Element
|
|
417
|
+
Signature: FormRow(props: FormRowProps): JSX.Element
|
|
418
|
+
Signature: MultiSelectFilter(props: MultiSelectFilterProps<T>): ReactNode
|
|
419
|
+
Signature: NumberFilter(props: NumberFilterProps): ReactNode
|
|
420
|
+
Signature: RangeFilter(props: RangeFilterProps<P, C>): ReactNode
|
|
421
|
+
Signature: SearchFilter(props: SearchFilterProps): ReactNode
|
|
422
|
+
Signature: SelectFilter(props: SelectFilterEnumProps<T>): ReactNode
|
|
423
|
+
Signature: SyncButton(props: SyncButtonProps): ReactNode
|
|
424
|
+
Signature: ToggleFilter(props: ToggleFilterProps): ReactNode
|
|
425
|
+
Signature: ViewTabs(props: ViewTabsProps<T>): ReactNode
|
|
100
426
|
|
|
101
427
|
## basalt-ui/controls-dates
|
|
102
428
|
Import: import { ... } from 'basalt-ui/controls-dates'
|
|
103
429
|
Description: DateRangePicker — the @mantine/dates implementation of RangeFilter's customPicker seam. Its own subpath because @mantine/dates is an optional peer and basaltViteConfig pre-bundles the whole @mantine scope, so a consumer without the peer (linewatch) must never resolve it: nothing under src/controls may import it, statically or lazily (docs/CONTROLS-SPEC.md §3).
|
|
104
430
|
Layer: mantine-coupled
|
|
105
431
|
Rule: basalt-controls
|
|
432
|
+
Signature: DateRangePicker(props: RangeCustomPickerProps): ReactNode
|
|
106
433
|
Install: bun add @mantine/dates@^9.7.0 dayjs@^1.11.0
|
|
107
434
|
|
|
108
435
|
## basalt-ui/state
|
|
@@ -110,6 +437,11 @@ Import: import { ... } from 'basalt-ui/state'
|
|
|
110
437
|
Description: field.enum/multi/range/number/boolean/string (the store field vocabulary), createSearchStore (typed URL > localStorage > fallback store), createLocalStore (the router-free store), createPersistedState (versioned localStorage)
|
|
111
438
|
Layer: headless
|
|
112
439
|
Rule: basalt-state
|
|
440
|
+
Signature: createLocalStore(o: { key: string; fields: S; version?: number; }): LocalStore<S>
|
|
441
|
+
Signature: createPersistedState(opts: PersistedStateOptions<T>): () => readonly [T, (next: T) => void]
|
|
442
|
+
Signature: createSearchStore(o: CreateSearchStoreOptions<S>): SearchStore<S>
|
|
443
|
+
Signature: externalField(o: { values: readonly T[]; fallback: NoInfer<T>; labels?: Partial<Record…): FieldHandle<EnumField<T, ResolvedLane>>
|
|
444
|
+
Signature: field: { enum, multi, range, number, boolean, string }
|
|
113
445
|
|
|
114
446
|
## basalt-ui/styles.css
|
|
115
447
|
Asset: basalt-ui/styles.css
|
package/package.json
CHANGED
package/src/charts/Bars.tsx
CHANGED
|
@@ -57,7 +57,7 @@ export type BarsProps<T, X extends ChartX = ChartX> = Omit<
|
|
|
57
57
|
lines?: readonly BarsLine<T>[] | undefined
|
|
58
58
|
/** Default `'stacked'`. `'normalized'` stacks each x to its share of the total. */
|
|
59
59
|
layout?: 'stacked' | 'grouped' | 'normalized' | undefined
|
|
60
|
-
/** Per-bar opacity (a partial week, an estimate). Overrides the series' `fillOpacity
|
|
60
|
+
/** Per-bar opacity (a partial week, an estimate, a shade per series). Overrides the series' `fillOpacity`; the legend swatch samples it on the first row. */
|
|
61
61
|
barOpacity?: ((d: T, key: string) => number) | undefined
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -82,12 +82,22 @@ function guardLogStack(layout: string, onLog: boolean): void {
|
|
|
82
82
|
export function Bars<T, X extends ChartX = ChartX>(props: BarsProps<T, X>): ReactElement {
|
|
83
83
|
const { bars, lines, layout = 'stacked', barOpacity, ...rest } = props
|
|
84
84
|
guardLogStack(layout, bars.length > 0 && rest.y?.scale === 'log')
|
|
85
|
+
const sample = rest.data[0]
|
|
85
86
|
const series = useMemo<ChartSeries<T>[]>(
|
|
86
87
|
() => [
|
|
87
|
-
|
|
88
|
+
// The legend has no datum: its swatch wears the shade the bars draw on the first row, so
|
|
89
|
+
// per-bar shades (`barOpacity`) read the same in the legend as on the plot.
|
|
90
|
+
...bars.map((b) => ({
|
|
91
|
+
...b,
|
|
92
|
+
mark: 'bar' as const,
|
|
93
|
+
fillOpacity:
|
|
94
|
+
(sample !== undefined ? barOpacity?.(sample, b.key) : undefined) ??
|
|
95
|
+
b.fillOpacity ??
|
|
96
|
+
DEFAULT_BAR_OPACITY,
|
|
97
|
+
})),
|
|
88
98
|
...(lines ?? []).map((l) => ({ ...l, mark: 'line' as const })),
|
|
89
99
|
],
|
|
90
|
-
[bars, lines],
|
|
100
|
+
[bars, lines, barOpacity, sample],
|
|
91
101
|
)
|
|
92
102
|
|
|
93
103
|
const marks = useCallback(
|
package/src/charts/legend.tsx
CHANGED
|
@@ -87,8 +87,15 @@ function Swatch({ s, mode }: { s: SwatchStyle; mode: LegendMode }): ReactElement
|
|
|
87
87
|
<span
|
|
88
88
|
aria-hidden
|
|
89
89
|
className={classes.dot}
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
style={{
|
|
91
|
+
width: 8,
|
|
92
|
+
height: 8,
|
|
93
|
+
// theme-allow raw-surface — a legend dot is a circle, not a surface corner
|
|
94
|
+
borderRadius: '50%',
|
|
95
|
+
background: s.color,
|
|
96
|
+
opacity: s.fillOpacity ?? 1,
|
|
97
|
+
flex: 'none',
|
|
98
|
+
}}
|
|
92
99
|
/>
|
|
93
100
|
)
|
|
94
101
|
if ((s.mark ?? 'line') === 'line')
|
|
@@ -137,9 +137,10 @@ export type FormRowProps = BasaltProps &
|
|
|
137
137
|
hint?: string
|
|
138
138
|
/**
|
|
139
139
|
* The field's error, rendered under the control. Falsy renders nothing. For a Mantine input
|
|
140
|
-
* wired through `inputProps(form, path)`, Mantine's own `Input.Wrapper` already renders
|
|
141
|
-
*
|
|
142
|
-
*
|
|
140
|
+
* wired through `inputProps(form, path)`, Mantine's own `Input.Wrapper` already renders the
|
|
141
|
+
* field error — passing it here too would render it twice. Reserve this prop for children that
|
|
142
|
+
* render no error of their own (a raw input, a custom control) and read it typed:
|
|
143
|
+
* `error={inputProps(form, path).error}`.
|
|
143
144
|
*/
|
|
144
145
|
error?: ReactNode
|
|
145
146
|
/** Marks the field required: an accent `*` for sighted readers, `(required)` for assistive tech. */
|
|
@@ -172,7 +173,7 @@ export type FormRowProps = BasaltProps &
|
|
|
172
173
|
*
|
|
173
174
|
* @example
|
|
174
175
|
* // A raw control renders no error of its own — pass it explicitly.
|
|
175
|
-
* <FormRow label="Email" required error={form
|
|
176
|
+
* <FormRow label="Email" required error={inputProps(form, 'email').error}>
|
|
176
177
|
* <input value={form.values.email} onChange={(e) => form.setFieldValue('email', e.target.value)} />
|
|
177
178
|
* </FormRow>
|
|
178
179
|
*/
|
|
@@ -239,8 +240,16 @@ export type FormGroupProps = BasaltProps & {
|
|
|
239
240
|
*
|
|
240
241
|
* @example
|
|
241
242
|
* <FormGroup label="Notify me about" direction="row">
|
|
242
|
-
* <Checkbox
|
|
243
|
-
*
|
|
243
|
+
* <Checkbox
|
|
244
|
+
* key={fieldKey(form, 'onDeploy')}
|
|
245
|
+
* {...inputProps(form, 'onDeploy', { type: 'checkbox' })}
|
|
246
|
+
* label="Deploys"
|
|
247
|
+
* />
|
|
248
|
+
* <Switch
|
|
249
|
+
* key={fieldKey(form, 'onError')}
|
|
250
|
+
* {...inputProps(form, 'onError', { type: 'checkbox' })}
|
|
251
|
+
* label="Errors"
|
|
252
|
+
* />
|
|
244
253
|
* </FormGroup>
|
|
245
254
|
*/
|
|
246
255
|
export function FormGroup(props: FormGroupProps) {
|
package/src/forms/field.ts
CHANGED
|
@@ -15,7 +15,56 @@
|
|
|
15
15
|
* which was the whole reason for the rename in the first place. Write
|
|
16
16
|
* `key={fieldKey(form, path)} {...inputProps(form, path)}`.
|
|
17
17
|
*/
|
|
18
|
-
import type { LooseKeys, UseFormReturnType } from '@mantine/form'
|
|
18
|
+
import type { GetInputPropsReturnType, LooseKeys, UseFormReturnType } from '@mantine/form'
|
|
19
|
+
import type { ReactNode } from 'react'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* What `inputProps` returns: Mantine's shape with `error` typed (`any` upstream). `error` is always
|
|
23
|
+
* present — Mantine sets the key on every call, `undefined` on a clean field — so it is `ReactNode`,
|
|
24
|
+
* not optional. It is the one typed way to read a field error: `form.errors` is an index signature
|
|
25
|
+
* (dot access is TS4111), and a raw control inside `FormRow` takes
|
|
26
|
+
* `<FormRow error={inputProps(form, path).error}>`. A Mantine input spread with `inputProps` already
|
|
27
|
+
* renders it; passing it to `FormRow` as well renders it twice.
|
|
28
|
+
*/
|
|
29
|
+
export type InputProps = Omit<GetInputPropsReturnType, 'error'> & { error: ReactNode }
|
|
30
|
+
|
|
31
|
+
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
|
|
32
|
+
|
|
33
|
+
type AllDigits<S extends string> = S extends `${Digit}${infer Rest}`
|
|
34
|
+
? Rest extends ''
|
|
35
|
+
? true
|
|
36
|
+
: AllDigits<Rest>
|
|
37
|
+
: false
|
|
38
|
+
|
|
39
|
+
/** A canonical array index: digits only, no sign, no decimal point, no exponent, no leading zero. */
|
|
40
|
+
type IsIndex<S extends string> = S extends '0'
|
|
41
|
+
? true
|
|
42
|
+
: S extends `0${string}`
|
|
43
|
+
? false
|
|
44
|
+
: AllDigits<S>
|
|
45
|
+
|
|
46
|
+
/** One path segment applied to a value; `never` when the segment does not exist there. */
|
|
47
|
+
type Child<T, K extends string> =
|
|
48
|
+
NonNullable<T> extends infer N
|
|
49
|
+
? N extends readonly (infer V)[]
|
|
50
|
+
? IsIndex<K> extends true
|
|
51
|
+
? V
|
|
52
|
+
: never
|
|
53
|
+
: K extends keyof N
|
|
54
|
+
? N[K]
|
|
55
|
+
: never
|
|
56
|
+
: never
|
|
57
|
+
|
|
58
|
+
type ValueAt<T, P extends string> = P extends `${infer Head}.${infer Rest}`
|
|
59
|
+
? ValueAt<Child<T, Head>, Rest>
|
|
60
|
+
: Child<T, P>
|
|
61
|
+
|
|
62
|
+
/** `Path` if the value at that dot path is a (possibly optional/nullable) boolean, else `never`. */
|
|
63
|
+
type BooleanAt<Values, Path extends string> = [ValueAt<Values, Path>] extends [never]
|
|
64
|
+
? never
|
|
65
|
+
: [NonNullable<ValueAt<Values, Path>>] extends [boolean]
|
|
66
|
+
? Path
|
|
67
|
+
: never
|
|
19
68
|
|
|
20
69
|
// ── inputProps ────────────────────────────────────────────────────────────────
|
|
21
70
|
|
|
@@ -37,8 +86,34 @@ import type { LooseKeys, UseFormReturnType } from '@mantine/form'
|
|
|
37
86
|
export function inputProps<Values extends Record<string, unknown>, Path extends LooseKeys<Values>>(
|
|
38
87
|
form: UseFormReturnType<Values>,
|
|
39
88
|
path: Path,
|
|
40
|
-
):
|
|
41
|
-
|
|
89
|
+
): InputProps
|
|
90
|
+
/**
|
|
91
|
+
* The boolean overload: `{ type: 'checkbox' }` binds a boolean field to Mantine `Checkbox` and
|
|
92
|
+
* `Switch`. It returns `onChange` plus `defaultChecked` in `useBasaltForm`'s default `uncontrolled`
|
|
93
|
+
* mode, or `checked` under `mode: 'controlled'` (Mantine decides; there is no `value`).
|
|
94
|
+
*
|
|
95
|
+
* Only a path whose value is a boolean (optional/nullable included) type-checks; a string path is a
|
|
96
|
+
* type error, not a silently wrong binding. Two limits of that check:
|
|
97
|
+
* - The path must be a literal. A `string`-typed path is rejected here (use a literal, or the
|
|
98
|
+
* one-argument form), so the path argument does not autocomplete.
|
|
99
|
+
* - On a union parent, a key present on several members is accepted only when every member types it
|
|
100
|
+
* as boolean; array segments must be canonical indices (`flags.0`, never `flags.1.5` or `flags.01`).
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* <Switch key={fieldKey(form, 'active')} {...inputProps(form, 'active', { type: 'checkbox' })} />
|
|
104
|
+
*/
|
|
105
|
+
export function inputProps<Values extends Record<string, unknown>, Path extends string>(
|
|
106
|
+
form: UseFormReturnType<Values>,
|
|
107
|
+
path: BooleanAt<Values, Path>,
|
|
108
|
+
options: { type: 'checkbox' },
|
|
109
|
+
): InputProps
|
|
110
|
+
export function inputProps<Values extends Record<string, unknown>>(
|
|
111
|
+
form: UseFormReturnType<Values>,
|
|
112
|
+
path: string,
|
|
113
|
+
options?: { type: 'checkbox' },
|
|
114
|
+
): InputProps {
|
|
115
|
+
// Mantine types `error` optional but sets the key on every call (`withError` defaults to true).
|
|
116
|
+
return form.getInputProps(path, options) as InputProps
|
|
42
117
|
}
|
|
43
118
|
|
|
44
119
|
/**
|