gridsmith-ui 0.17.1 → 0.17.3

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/index.d.ts CHANGED
@@ -294,8 +294,13 @@ interface SliderRangeProps {
294
294
  * accent fill is hidden so the custom track stays fully visible.
295
295
  */
296
296
  trackStyle?: CSSProperties;
297
+ /**
298
+ * The value in words, for a slider whose number alone means nothing ("Weekly" for 2): each thumb's aria-valuetext and
299
+ * the value shown beside the label (Sprint 25.9, A7; APG slider pattern). Leave it out and the number is shown and read.
300
+ */
301
+ formatValue?: (value: number) => string;
297
302
  }
298
- declare function SliderRange({ value, onChange, min, max, step, disabled, showValue, className, ref, error, label, "aria-label": ariaLabel, "aria-describedby": describedByProp, trackStyle }: SliderRangeProps): react_jsx_runtime.JSX.Element;
303
+ declare function SliderRange({ value, onChange, min, max, step, disabled, showValue, className, ref, error, label, "aria-label": ariaLabel, "aria-describedby": describedByProp, trackStyle, formatValue }: SliderRangeProps): react_jsx_runtime.JSX.Element;
299
304
 
300
305
  interface TimePickerProps {
301
306
  value: string;
@@ -422,6 +427,9 @@ interface FieldProps {
422
427
  * (aria-describedby), that the control is marked invalid, and that the error
423
428
  * sits directly below the field (forms-002/006/009/010). Use one Field per
424
429
  * control; do not add a separate <Label> or a label prop on the child.
430
+ *
431
+ * In a SettingsLayout panel a Field keeps the narrow page's reading width however wide the page is (the panel's
432
+ * --ds-form-max, Sprint 25.9); a `max-w-*` class of your own wins.
425
433
  */
426
434
  declare function Field({ label, children, hint, error, required, labelAction, id: idProp, className }: FieldProps): react_jsx_runtime.JSX.Element;
427
435
 
@@ -469,6 +477,10 @@ interface FormWrapperProps {
469
477
  * A function renders your own from the list.
470
478
  */
471
479
  errorSummary?: boolean | ((errors: FormFieldError[]) => ReactNode);
480
+ /**
481
+ * Classes for the form. In a SettingsLayout panel the form keeps the narrow page's reading width however wide the
482
+ * page is (the panel's --ds-form-max, Sprint 25.9); a `max-w-*` class here wins.
483
+ */
472
484
  className?: string;
473
485
  ref?: React.Ref<HTMLFormElement>;
474
486
  }
@@ -588,7 +600,12 @@ interface DescriptionListProps {
588
600
  columns?: 1 | 2 | 3 | 4;
589
601
  size?: DescriptionListSize;
590
602
  dividers?: boolean;
591
- /** Below this breakpoint a multi-column list becomes one column. Default "sm" when columns > 1 (a phone never shows two columns of pairs); "none" keeps the columns at every width. */
603
+ /**
604
+ * A multi-column list re-flows by its own width (Sprint 25.9, A5): a column never gets narrower than a pair needs
605
+ * (20rem beside, 8rem stacked), so in a drawer, a pane or a settings panel it shows fewer columns, and one when a
606
+ * second will not fit. `stackBelow` adds a viewport rule on top: below this breakpoint the list is one column.
607
+ * Default "sm" when columns > 1 (a phone never shows two columns of pairs); "none" keeps the columns at every width.
608
+ */
592
609
  stackBelow?: "sm" | "md" | "lg" | "none";
593
610
  className?: string;
594
611
  }
@@ -661,9 +678,20 @@ interface TableProps {
661
678
  onRowClick?: (row: Record<string, string | number | ReactNode>, index: number) => void;
662
679
  /** Breakpoint at which the table switches to card layout. Defaults to "md" (768px). */
663
680
  mobileBreakpoint?: BreakpointKey;
681
+ /**
682
+ * The table's title inside its frame (Sprint 25.9, A1): a heading in CardTitle's style at CardHeader's inset, in a band
683
+ * above the scroll area that never scrolls sideways, and the `<table>`'s name. Title a table this way or with a
684
+ * SectionHeading above it — the same way as the blocks beside it (page_composition#45). In card mode, and while it
685
+ * loads or is empty there, the same heading sits above the cards. Without a title the table renders as before.
686
+ */
687
+ title?: string;
688
+ /** A line under the title, which also describes the `<table>` (aria-describedby). Needs `title`. */
689
+ description?: string;
690
+ /** The table's buttons, at the end of the title band as in a CardHeader. Needs `title`. */
691
+ actions?: ReactNode;
664
692
  ref?: Ref<HTMLDivElement>;
665
693
  }
666
- declare function Table({ columns, data, className, sortable, sortKey: controlledSortKey, sortDir: controlledSortDir, onSortChange, selectable, selectedRows, onSelectionChange, expandable, renderExpanded, density, stickyHeader, striped, loading, emptyState, onRowClick, mobileBreakpoint: mobileBreakpointProp, ref, }: TableProps): react_jsx_runtime.JSX.Element;
694
+ declare function Table({ columns, data, className, sortable, sortKey: controlledSortKey, sortDir: controlledSortDir, onSortChange, selectable, selectedRows, onSelectionChange, expandable, renderExpanded, density, stickyHeader, striped, loading, emptyState, onRowClick, mobileBreakpoint: mobileBreakpointProp, title, description, actions, ref, }: TableProps): react_jsx_runtime.JSX.Element;
667
695
 
668
696
  interface CalendarEvent {
669
697
  id: string;
@@ -1257,16 +1285,18 @@ type TimeZoom = "day" | "week" | "month" | "quarter";
1257
1285
  declare const TIME_ZOOMS: readonly TimeZoom[];
1258
1286
  /**
1259
1287
  * The day index of a date: "2026-03-03" → that calendar day's index; a Date or a date-time string → its local calendar
1260
- * day plus the fraction of the day its local clock shows. NaN for anything that is not a date.
1288
+ * day plus the fraction of the day its local clock shows (a day's first instant is the whole day); a number is a day
1289
+ * index already, as the scale's own functions take it. NaN for anything else: null from JSON, a string that is no date.
1261
1290
  */
1262
- declare function dayOf(value: DateInput): number;
1291
+ declare function dayOf(value: DateInput | number): number;
1263
1292
  /** Local midnight of that calendar day; a fraction adds that much of the day on the local clock. */
1264
1293
  declare function dateOfDay(day: number): Date;
1265
1294
  /**
1266
1295
  * Where a range that ends at `value` stops. A whole-day end is inclusive: "2026-03-14" (or a Date at local midnight,
1267
- * as the date pickers give) → the start of 15 March. A date-time end is half-open: it stops at that moment.
1296
+ * as the date pickers give) → the start of 15 March. A date-time end is half-open: it stops at that moment, as a day
1297
+ * index does. A range's start can make a midnight Date half-open too (scale.span, formatDateRange, timeExtent).
1268
1298
  */
1269
- declare function endDayOf(value: DateInput): number;
1299
+ declare function endDayOf(value: DateInput | number): number;
1270
1300
  interface TimeTick {
1271
1301
  /** Stable: "2026-09" for September 2026, "2026-09-07" for a day or the week starting on it, "2026-Q3", "2026". */
1272
1302
  key: string;
@@ -1278,7 +1308,10 @@ interface TimeTick {
1278
1308
  width: number;
1279
1309
  /** The weekday of the day it starts on: 0 is Sunday, as Date's getDay. */
1280
1310
  weekday: number;
1281
- /** Longest first, from Intl in the locale: ["September", "Sept", "S"], ["Mon 7", "7"], ["2026", "26"]. */
1311
+ /**
1312
+ * Longest first, from Intl in the locale: ["September", "Sept", "S"], ["Mon 7", "7"], ["2026", "26"]. Every tick in a
1313
+ * row has one form per level, so a form can repeat ("May", "May", "M").
1314
+ */
1282
1315
  labels: string[];
1283
1316
  }
1284
1317
  /** A calendar day, as shadeDays sees it: its index, its weekday (0 is Sunday) and its "YYYY-MM-DD" key. */
@@ -1299,7 +1332,8 @@ interface TimeScale {
1299
1332
  x(value: DateInput | number): number;
1300
1333
  /**
1301
1334
  * Where a range sits: px from the scale's start and its width. The end is inclusive for a whole day, as endDayOf
1302
- * (so a day's bar is never a day short); a day index is where the range stops. Default: the start's own day.
1335
+ * (so a day's bar is never a day short), but a Date at midnight after a time-of-day start is where the range stops
1336
+ * (an evening shift); a day index is where the range stops. Default: the start's own day.
1303
1337
  */
1304
1338
  span(start: DateInput | number, end?: DateInput | number): {
1305
1339
  x: number;
@@ -1324,7 +1358,10 @@ interface TimeScaleOptions {
1324
1358
  /** Inclusive for a whole day, as endDayOf. A day index is where the range stops. */
1325
1359
  end: DateInput | number;
1326
1360
  zoom: TimeZoom;
1327
- /** Default now; demos and tests pass a fixed date (a date-time gives an hourly view its "now"). */
1361
+ /**
1362
+ * Default: the moment the view mounted, on the device that shows it. The server's render, and the render that
1363
+ * hydrates its HTML, draw no today. Demos and tests pass a fixed date; a date-time gives an hourly view its "now".
1364
+ */
1328
1365
  today?: DateInput;
1329
1366
  /** Default 1 (Monday), as Calendar's. */
1330
1367
  weekStartsOn?: 0 | 1;
@@ -1343,7 +1380,7 @@ declare function useTimeScale({ start, end, zoom, today, weekStartsOn, locale, p
1343
1380
  /**
1344
1381
  * The earliest start and the latest end of some ranges, as day indices for useTimeScale: the end is where the last
1345
1382
  * range stops (inclusive for a whole day, as endDayOf), and a range with no end ends where it starts (a milestone).
1346
- * NaN for no dated range, which the scale shows as today.
1383
+ * NaN for no dated range, which the scale shows as today. A range, a start or an end that is null is skipped.
1347
1384
  */
1348
1385
  declare function timeExtent(ranges: Iterable<{
1349
1386
  start: DateInput;
@@ -1363,12 +1400,13 @@ interface DateRangeWords {
1363
1400
  }
1364
1401
  /**
1365
1402
  * A range in words, in the locale, for accessible names: "3 to 14 March", "28 September to 3 October", "16 September"
1366
- * for one day. The end is inclusive for a whole day, as endDayOf (a day index is where the range stops). A date-time
1403
+ * for one day. The end is inclusive for a whole day, as scale.span (a day index is where the range stops). A date-time
1367
1404
  * range is named by its times, and the end's day only when it differs: "Friday 23 October, 06:00 to 14:00". Intl
1368
1405
  * joins each day and time in the locale's own way, and outside English the two ends too ("10/31(土曜日)~11/01(日曜日)");
1369
- * the year shows when the two ends are in different years.
1406
+ * the year shows when the two ends are in different years. A null end is the start's own day; a start that is no date
1407
+ * gives "".
1370
1408
  */
1371
- declare function formatDateRange(start: DateInput | number, end?: DateInput | number, { locale, to, day, time }?: DateRangeWords): string;
1409
+ declare function formatDateRange(start: DateInput | number, end?: DateInput | number, words?: DateRangeWords): string;
1372
1410
 
1373
1411
  /**
1374
1412
  * What a TimeViewport gives the things drawn inside it (Sprint 25.7, Part D). The scroll position lives in a store of
@@ -1377,7 +1415,10 @@ declare function formatDateRange(start: DateInput | number, end?: DateInput | nu
1377
1415
  interface TimeViewportApi {
1378
1416
  /** Scroll so the date (or day index) sits a little clear of the pinned column ("start"), or in the middle of the view. */
1379
1417
  scrollToDate(value: DateInput | number, align?: "start" | "center"): void;
1380
- /** One visible width back or on (the previous and next period), ending on a minor tick. */
1418
+ /**
1419
+ * One visible width back or on (the previous and next period), ending on the minor tick nearest there when one is
1420
+ * within half a view of it. It always moves: where a period is wider than the view it moves by the view's width.
1421
+ */
1381
1422
  page(direction: -1 | 1): void;
1382
1423
  /**
1383
1424
  * Scroll the least to show [x0, x1] (px on the scale) clear of the pinned column. A range wider than the view is
@@ -1634,10 +1675,13 @@ type GanttTone = "neutral" | "info" | "success" | "warning" | "error" | "accent"
1634
1675
  interface GanttItem {
1635
1676
  id: string;
1636
1677
  title: string;
1637
- /** A Date, or "YYYY-MM-DD" for a calendar day in the user's zone. */
1638
- start: DateInput;
1639
- /** Inclusive for a whole day ("3 to 14 March" covers the 14th); required unless `milestone`. */
1640
- end?: DateInput;
1678
+ /**
1679
+ * A Date, or "YYYY-MM-DD" for a calendar day in the user's zone. Null for a task with no dates yet: like a date that
1680
+ * does not parse, its row says "no dates", it has no bar and no arrows, and it has no part in the scale.
1681
+ */
1682
+ start: DateInput | null;
1683
+ /** Inclusive for a whole day ("3 to 14 March" covers the 14th). Left out, the task is its start's day; a milestone uses its start alone. */
1684
+ end?: DateInput | null;
1641
1685
  /** A GanttGroup's id. */
1642
1686
  group?: string;
1643
1687
  /** A key of `statuses`. */
@@ -1655,17 +1699,23 @@ interface GanttGroup {
1655
1699
  interface GanttStatus {
1656
1700
  label: string;
1657
1701
  tone: GanttTone;
1702
+ /** The cue beside the colour, on its bars and in the legend (colour is never the only one). Default the tone's own. */
1703
+ icon?: IconName;
1658
1704
  }
1659
- interface GanttProps {
1660
- items: GanttItem[];
1705
+ interface GanttProps<T extends GanttItem = GanttItem> {
1706
+ items: T[];
1661
1707
  /** Rows grouped under collapsible headers, in this order; items with no group come last. A group with no items is left out. */
1662
1708
  groups?: GanttGroup[];
1663
- /** Controlled selection; leave it out for the Gantt to keep its own. */
1709
+ /**
1710
+ * The selected item's id. The selection is controlled once this has held a value, and from then on undefined means
1711
+ * none too, so selectedId={task?.id} works. Leave it out for the Gantt to keep its own.
1712
+ */
1664
1713
  selectedId?: string | null;
1665
1714
  /** Enter, Space or a click: the item. Escape, or a click on the selected item: null. */
1666
- onSelect?: (item: GanttItem | null) => void;
1667
- /** The bars' colours and the legend; an item with no known status is neutral. */
1715
+ onSelect?: (item: T | null) => void;
1716
+ /** The bars' colours and cues, and the legend; an item with no known status is neutral. */
1668
1717
  statuses?: Record<string, GanttStatus>;
1718
+ /** Controlled. With no onZoomChange it is fixed, and there are no zoom controls. */
1669
1719
  zoom?: TimeZoom;
1670
1720
  /** Default "week". */
1671
1721
  defaultZoom?: TimeZoom;
@@ -1677,13 +1727,18 @@ interface GanttProps {
1677
1727
  /** Default the browser's: the scale's labels and the items' dates. */
1678
1728
  locale?: string;
1679
1729
  /**
1680
- * Beside the title in the name column (assignees' avatars): shown, not announced, and left out when the column is
1681
- * too narrow for it and the title (a phone). Nothing in it may take focus.
1730
+ * Beside the title in the name column (assignees' avatars): shown, not announced (say it in `describe`), and left out
1731
+ * when the column is too narrow for it and the title (a phone). Nothing in it may take focus.
1732
+ */
1733
+ renderLabel?: (item: T) => ReactNode;
1734
+ /**
1735
+ * Words added to an item's accessible name after its title, dates, status and dependencies: what renderLabel shows
1736
+ * ("assigned to Amara Haddad"). Called as the rows render, so an inline function is fine.
1682
1737
  */
1683
- renderLabel?: (item: GanttItem) => ReactNode;
1738
+ describe?: (item: T) => string;
1684
1739
  /** The name column's heading. Default "Task". */
1685
- labelHeader?: string;
1686
- /** Controls after the built-in zoom, period and Today buttons, before the legend; false hides the bar. */
1740
+ labelHeader?: ReactNode;
1741
+ /** Controls after the built-in zoom, period and Today buttons, before the legend; false hides the bar (the legend stays). */
1687
1742
  toolbar?: ReactNode | false;
1688
1743
  "aria-label": string;
1689
1744
  className?: string;
@@ -1693,15 +1748,16 @@ interface GanttProps {
1693
1748
  * milestones and finish-to-start dependencies. Assembled from the time blocks: the scale and date model
1694
1749
  * (useTimeScale), the viewport with its pinned name column, sticky scale, zoom, pan and Today (TimeViewport), labels
1695
1750
  * that fit (TimeScaleHeader) and the one-Tab-stop keyboard (useGridKeyboard). It does no date maths and no scrolling
1696
- * of its own.
1751
+ * of its own. A task whose dates do not parse keeps its row, marked "no dates".
1697
1752
  *
1698
- * Keyboard (APG tree view): the chart is one Tab stop. Up and Down move between rows; Right opens a group, or moves
1699
- * into it; Left closes it, or moves to it; Home and End go to the first and last row; typing jumps by title. Enter or
1700
- * Space selects, and opens or closes a group; Escape clears the selection. + and − zoom and Shift+Left and Right pan,
1701
- * from the viewport. Each item's accessible name carries its title, dates, status and dependencies; the arrows and
1702
- * the scale are for sight only.
1753
+ * Keyboard (APG tree view): the chart is one Tab stop, the selected row when focus comes in from outside. Up and Down
1754
+ * move between rows; Right opens a group, or moves into it; Left closes it, or moves to it; Home and End go to the
1755
+ * first and last row; typing jumps by title. Enter or Space selects, and opens or closes a group; Escape clears the
1756
+ * selection. + and − zoom and Shift+Left and Right pan, from the viewport. When the focused row goes (a deletion, a
1757
+ * filter), focus moves to the row before it. Each item's accessible name carries its title, dates, status and
1758
+ * dependencies; the arrows and the scale are for sight only.
1703
1759
  */
1704
- declare function Gantt({ items, groups, selectedId, onSelect, statuses, zoom: zoomProp, defaultZoom, onZoomChange, today, weekStartsOn, locale, renderLabel, labelHeader, toolbar, "aria-label": ariaLabel, className, }: GanttProps): react_jsx_runtime.JSX.Element;
1760
+ declare function Gantt<T extends GanttItem = GanttItem>({ items, groups, selectedId, onSelect, statuses, zoom: zoomProp, defaultZoom, onZoomChange, today, weekStartsOn, locale, renderLabel, describe, labelHeader, toolbar, "aria-label": ariaLabel, className, }: GanttProps<T>): react_jsx_runtime.JSX.Element;
1705
1761
 
1706
1762
  type LinkUnderline = "hover" | "always" | "none";
1707
1763
  type LinkTone = "accent" | "muted" | "inherit";
@@ -1903,8 +1959,10 @@ interface SettingsLayoutProps {
1903
1959
  /** Width of the rail in px (sidebar layout). */
1904
1960
  railWidth?: number;
1905
1961
  /**
1906
- * Below this width of the layout itself (not the viewport) the rail becomes a Dropdown. Default: the rail plus a
1907
- * usable panel (railWidth + 480). Measured on the layout, so a narrow PageContainer or a sidebar shell counts.
1962
+ * Below this width of the layout itself (not the viewport) the rail becomes a Dropdown. Default: the rail, the gap
1963
+ * beside it and a usable panel (railWidth + gap + 560). Measured on the layout, so a narrow PageContainer or a
1964
+ * sidebar shell counts. A narrow page holding the rail is wider by the rail and its gap, so the panel keeps the narrow
1965
+ * width (roots.css, Sprint 25.9).
1908
1966
  */
1909
1967
  collapseBelow?: number;
1910
1968
  /** Accessible name of the section navigation. */
@@ -1925,7 +1983,7 @@ interface SettingsLayoutProps {
1925
1983
  * The rail is a Tabs (vertical) styled by the theme's in-page vertical style;
1926
1984
  * the page assembles the sections' contents and nothing else.
1927
1985
  */
1928
- declare function SettingsLayout({ sections, value, onChange, layout: layoutProp, railWidth, collapseBelow, "aria-label": ariaLabel, children, className, }: SettingsLayoutProps): react_jsx_runtime.JSX.Element;
1986
+ declare function SettingsLayout({ sections, value, onChange, layout: layoutProp, railWidth, collapseBelow: collapseBelowProp, "aria-label": ariaLabel, children, className, }: SettingsLayoutProps): react_jsx_runtime.JSX.Element;
1929
1987
 
1930
1988
  interface BreadcrumbItem$1 {
1931
1989
  label: string;
@@ -2988,7 +3046,10 @@ type PageContainerWidth = "constrained" | "full" | "narrow";
2988
3046
  type Padding = "none" | "default" | "wide";
2989
3047
  type VerticalPadding = "none" | "default" | "spacious";
2990
3048
  interface PageContainerProps {
2991
- /** Semantic width — maps to maxWidth internally. Takes precedence over maxWidth when both are set. */
3049
+ /**
3050
+ * Semantic width — maps to maxWidth internally. Takes precedence over maxWidth when both are set. A narrow page that
3051
+ * holds a SettingsLayout rail is wider by the rail and its gap, so the panel keeps the narrow width (Sprint 25.9).
3052
+ */
2992
3053
  width?: PageContainerWidth;
2993
3054
  /** Lower-level max-width escape hatch. Use `width` for standard cases. */
2994
3055
  maxWidth?: MaxWidth;
@@ -3034,6 +3095,7 @@ declare function useContentWidth(width: PageContainerWidth): void;
3034
3095
  declare const PageContainer: react.ForwardRefExoticComponent<PageContainerProps & react.RefAttributes<HTMLDivElement>>;
3035
3096
 
3036
3097
  interface SectionHeadingProps {
3098
+ /** Wraps onto more lines rather than being cut (an insight above a chart); a pane's title keeps one line. */
3037
3099
  title: string;
3038
3100
  description?: string;
3039
3101
  /** The section's buttons. Below sm they sit under the title, like PageHeader's actions. */