@flytedan/flytebot-design-system 0.49.1 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -158,27 +158,6 @@ declare function usePopoverPosition(open: boolean, anchorRef: React.RefObject<HT
158
158
  /** The rendered layer, so its real size replaces the estimates once it exists. */
159
159
  layerRef?: React.RefObject<HTMLElement>;
160
160
  }): PopoverPosition | null;
161
- /**
162
- * MP-268: a portalled overlay's z-index is no longer decided here. It used to be a second,
163
- * independently-timed mechanism (MP-142) — a value passed down through its own React context,
164
- * separate from the layer stack's ownership context (`kits/layerStack.tsx`) that already
165
- * decides Escape and Tab order. The two could disagree: a child overlay opened in the very
166
- * same commit as its parent could read the parent's not-yet-registered placeholder z-index
167
- * and mistake itself for a root overlay, racing its own parent for a root slot instead of
168
- * always outranking it (the reported bug — a Modal opened in the same commit as its Drawer
169
- * painted under it, though focus was correctly inside the Modal).
170
- *
171
- * Every overlay that escapes the DOM via `portal()` or `createPortal` directly — Popover
172
- * (and everything built on it), Drawer, Modal, Tooltip — now reads its z-index from
173
- * `useLayerZIndex(layer)` (`kits/layerStack.tsx`), passing the SAME `layer` object
174
- * `useStackedLayer` gave it. That function derives the number purely from `layer.parent` —
175
- * the same ownership fact already used for focus — so the two can never disagree again:
176
- * one fact, one mechanism. See `useLayerZIndex`'s own comment for the exact rule (child
177
- * always LAYER_STEP+ above its resolved parent; a root layer ranks by position among the
178
- * other currently-open root layers). Import `useLayerZIndex`/`LAYER_STEP`/`ROOT_STEP`/
179
- * `OVERLAY_CEILING`/`__resetLayerStackForTests` from `kits/layerStack` directly — this file
180
- * no longer re-exports them; there is exactly one place they live now.
181
- */
182
161
  /**
183
162
  * An anchored floating surface: menus, pickers, disclosure panels, meters.
184
163
  * Owns placement, dismissal, focus return — and its own layout, which is the one rule
@@ -725,9 +704,10 @@ interface AppShellProps {
725
704
  trailingPanel?: (ctx: {
726
705
  overlay: boolean;
727
706
  }) => React.ReactNode;
728
- /** Max width (px) of the centered content column. Default 1440 — every current
729
- * flytedesk app shell's own value. */
730
- contentMaxWidth?: number;
707
+ /** Max width of the centered content column: a px number, or `"none"` for a
708
+ * full-width app whose pages fill the space beside the sidebar (SMS-50). Default
709
+ * 1440 — the value most flytedesk app shells use. */
710
+ contentMaxWidth?: number | "none";
731
711
  /** The shell's own height. Default `"100vh"`, correct for the real, top-level use
732
712
  * every app mounts this at. A demo or preview embedding AppShell inside a bounded
733
713
  * container (this package's own docs site) passes e.g. `"100%"` instead. */
@@ -898,6 +878,17 @@ interface TagProps {
898
878
  tone?: "neutral" | "info" | "success" | "warning" | "danger";
899
879
  onRemove?: () => void;
900
880
  onClick?: () => void;
881
+ /** MP-282: a native tooltip for the chip's full text — the same full text that is
882
+ * already the button's accessible name (its text content), so this only helps a
883
+ * sighted mouse user whose chip a caller (FilterBar, scoped to `.fd-filterbar .fd-tag`
884
+ * in components.css) has visually truncated with an ellipsis. Harmless, and invisible,
885
+ * on a chip nobody truncates. */
886
+ title?: string;
887
+ /** The chip's accessible name, when its painted text is not a faithful name for it. FilterBar
888
+ * sets it to the chip's whole text: the painted text is split into a shrinkable head and a
889
+ * fixed tail (MiddleEllipsis), and a browser computing a name from content puts a space between
890
+ * two block-level flex items, reading "Pol itical" — an explicit name is the whole value. */
891
+ "aria-label"?: string;
901
892
  className?: string;
902
893
  }
903
894
  declare function Tag({ children, icon, selected, tone, onRemove, onClick, className, ...rest }: TagProps): React.JSX.Element;
@@ -967,7 +958,8 @@ interface TrendChartProps {
967
958
  label: string;
968
959
  /** Value formatter for axis ticks, point tooltips and the data table. */
969
960
  valueFormat?: (n: number) => string;
970
- /** Height in px. Width is always fluid (100% of the container). */
961
+ /** Plot height in px. Width is always fluid (100% of the container); the SVG is drawn in
962
+ * real pixels at the container's measured width, so text never scales with the card. */
971
963
  height?: number;
972
964
  /** Number of horizontal gridlines (excluding the zero baseline). */
973
965
  yTicks?: number;
@@ -1339,8 +1331,14 @@ interface FilterBarProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "on
1339
1331
  * clearFilter(id). Apply it synchronously, exactly like onFilterChange. */
1340
1332
  onFilterRemove: (key: string) => void;
1341
1333
  /** Which edge the "add filter" popover aligns to. Default "left" — the trigger sits
1342
- * at the end of a left-to-right chip row, so its menu opens under its left edge. */
1334
+ * in the leading column, left of the chips, so its menu opens under its left edge. */
1343
1335
  align?: "left" | "right";
1336
+ /** Controls that sit at the bar's right edge, in a column of their own: a date range, an
1337
+ * export button. They are laid out beside the Filter button and the chips and stay put
1338
+ * however many chips wrap (they top-align to the Filter button, never to the chips), and
1339
+ * drop below the chips on a row of their own, still right-aligned, when the bar is too
1340
+ * narrow to hold them all on one line. */
1341
+ actions?: React.ReactNode;
1344
1342
  className?: string;
1345
1343
  }
1346
1344
  type FilterValidation = {
@@ -1392,7 +1390,7 @@ declare function validateFilterValue(field: FilterField, value: unknown): Filter
1392
1390
  * string value; multiSelect/range/date each read/write a small typed object of their own
1393
1391
  * (see FilterValue).
1394
1392
  */
1395
- declare function FilterBar({ fields, filters, onFilterChange, onFilterRemove, align, className, ...rest }: FilterBarProps): React.JSX.Element;
1393
+ declare function FilterBar({ fields, filters, onFilterChange, onFilterRemove, align, actions, className, ...rest }: FilterBarProps): React.JSX.Element;
1396
1394
 
1397
1395
  /**
1398
1396
  * A flat figure tile — no shadow, no background color, never more than four in a row.
@@ -2452,6 +2450,8 @@ interface SelectProps {
2452
2450
  label?: string;
2453
2451
  help?: string;
2454
2452
  error?: string;
2453
+ /** Names the field when it has no visible `label` (the trigger is then named "<aria-label> <selected option>"). */
2454
+ "aria-label"?: string;
2455
2455
  options: Array<string | SelectOption>;
2456
2456
  placeholder?: string;
2457
2457
  required?: boolean;
@@ -2477,13 +2477,15 @@ interface SelectProps {
2477
2477
  * from it. Generated when omitted, so `label` names the trigger either way. */
2478
2478
  id?: string;
2479
2479
  }
2480
- declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style }: SelectProps): React.JSX.Element;
2480
+ declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style, "aria-label": hiddenLabel }: SelectProps): React.JSX.Element;
2481
2481
 
2482
2482
  /** Calendar popover date field. Click the title to drill month -> year; range mode picks start then end with live hover preview. Values are ISO strings ("2026-03-01"). */
2483
2483
  interface DatePickerProps {
2484
2484
  label?: string;
2485
2485
  help?: string;
2486
2486
  error?: string;
2487
+ /** Names the field when it has no visible `label` (the trigger is then named "<aria-label> <what it displays>"). */
2488
+ "aria-label"?: string;
2487
2489
  required?: boolean;
2488
2490
  disabled?: boolean;
2489
2491
  /** false: value is "YYYY-MM-DD". true: value is {start, end}. */
@@ -2507,7 +2509,7 @@ interface CalendarProps {
2507
2509
  months?: number;
2508
2510
  }
2509
2511
  declare function Calendar({ value, range, onPick, initialMonth, months }: CalendarProps): React.JSX.Element;
2510
- declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, id, className, style, ...rest }: DatePickerProps): React.JSX.Element;
2512
+ declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, id, className, style, "aria-label": hiddenLabel, ...rest }: DatePickerProps): React.JSX.Element;
2511
2513
 
2512
2514
  /** Analog clock-face time field: tap or drag the hand to set the hour, auto-advances to minutes; AM/PM chips; "Now" shortcut. Value is 24h "HH:MM". */
2513
2515
  interface TimePickerProps {
@@ -4899,8 +4901,8 @@ declare const LAYER_STEP = 10;
4899
4901
  * page chrome (a sticky header, the off-canvas rail's own resting z-index) must stay under
4900
4902
  * this, so no page z-index can ever outrank an overlay. */
4901
4903
  declare const ROOT_STEP = 100;
4902
- /** Guaranteed to sit above any z-index this mechanism can ever compute — see Popover.tsx's
4903
- * TransferList drag-ghost use. Not part of the layer tree; nothing derives from it. */
4904
+ /** Guaranteed to sit above any z-index this mechanism can ever compute — see
4905
+ * TransferList.tsx's drag-ghost use. Not part of the layer tree; nothing derives from it. */
4904
4906
  declare const OVERLAY_CEILING = 10000;
4905
4907
  /** The z-index `layer` should render at right now — 0 while it is closed (nothing should be
4906
4908
  * positioning off it then). Re-renders whenever any layer anywhere opens or closes, since
package/dist/index.d.ts CHANGED
@@ -158,27 +158,6 @@ declare function usePopoverPosition(open: boolean, anchorRef: React.RefObject<HT
158
158
  /** The rendered layer, so its real size replaces the estimates once it exists. */
159
159
  layerRef?: React.RefObject<HTMLElement>;
160
160
  }): PopoverPosition | null;
161
- /**
162
- * MP-268: a portalled overlay's z-index is no longer decided here. It used to be a second,
163
- * independently-timed mechanism (MP-142) — a value passed down through its own React context,
164
- * separate from the layer stack's ownership context (`kits/layerStack.tsx`) that already
165
- * decides Escape and Tab order. The two could disagree: a child overlay opened in the very
166
- * same commit as its parent could read the parent's not-yet-registered placeholder z-index
167
- * and mistake itself for a root overlay, racing its own parent for a root slot instead of
168
- * always outranking it (the reported bug — a Modal opened in the same commit as its Drawer
169
- * painted under it, though focus was correctly inside the Modal).
170
- *
171
- * Every overlay that escapes the DOM via `portal()` or `createPortal` directly — Popover
172
- * (and everything built on it), Drawer, Modal, Tooltip — now reads its z-index from
173
- * `useLayerZIndex(layer)` (`kits/layerStack.tsx`), passing the SAME `layer` object
174
- * `useStackedLayer` gave it. That function derives the number purely from `layer.parent` —
175
- * the same ownership fact already used for focus — so the two can never disagree again:
176
- * one fact, one mechanism. See `useLayerZIndex`'s own comment for the exact rule (child
177
- * always LAYER_STEP+ above its resolved parent; a root layer ranks by position among the
178
- * other currently-open root layers). Import `useLayerZIndex`/`LAYER_STEP`/`ROOT_STEP`/
179
- * `OVERLAY_CEILING`/`__resetLayerStackForTests` from `kits/layerStack` directly — this file
180
- * no longer re-exports them; there is exactly one place they live now.
181
- */
182
161
  /**
183
162
  * An anchored floating surface: menus, pickers, disclosure panels, meters.
184
163
  * Owns placement, dismissal, focus return — and its own layout, which is the one rule
@@ -725,9 +704,10 @@ interface AppShellProps {
725
704
  trailingPanel?: (ctx: {
726
705
  overlay: boolean;
727
706
  }) => React.ReactNode;
728
- /** Max width (px) of the centered content column. Default 1440 — every current
729
- * flytedesk app shell's own value. */
730
- contentMaxWidth?: number;
707
+ /** Max width of the centered content column: a px number, or `"none"` for a
708
+ * full-width app whose pages fill the space beside the sidebar (SMS-50). Default
709
+ * 1440 — the value most flytedesk app shells use. */
710
+ contentMaxWidth?: number | "none";
731
711
  /** The shell's own height. Default `"100vh"`, correct for the real, top-level use
732
712
  * every app mounts this at. A demo or preview embedding AppShell inside a bounded
733
713
  * container (this package's own docs site) passes e.g. `"100%"` instead. */
@@ -898,6 +878,17 @@ interface TagProps {
898
878
  tone?: "neutral" | "info" | "success" | "warning" | "danger";
899
879
  onRemove?: () => void;
900
880
  onClick?: () => void;
881
+ /** MP-282: a native tooltip for the chip's full text — the same full text that is
882
+ * already the button's accessible name (its text content), so this only helps a
883
+ * sighted mouse user whose chip a caller (FilterBar, scoped to `.fd-filterbar .fd-tag`
884
+ * in components.css) has visually truncated with an ellipsis. Harmless, and invisible,
885
+ * on a chip nobody truncates. */
886
+ title?: string;
887
+ /** The chip's accessible name, when its painted text is not a faithful name for it. FilterBar
888
+ * sets it to the chip's whole text: the painted text is split into a shrinkable head and a
889
+ * fixed tail (MiddleEllipsis), and a browser computing a name from content puts a space between
890
+ * two block-level flex items, reading "Pol itical" — an explicit name is the whole value. */
891
+ "aria-label"?: string;
901
892
  className?: string;
902
893
  }
903
894
  declare function Tag({ children, icon, selected, tone, onRemove, onClick, className, ...rest }: TagProps): React.JSX.Element;
@@ -967,7 +958,8 @@ interface TrendChartProps {
967
958
  label: string;
968
959
  /** Value formatter for axis ticks, point tooltips and the data table. */
969
960
  valueFormat?: (n: number) => string;
970
- /** Height in px. Width is always fluid (100% of the container). */
961
+ /** Plot height in px. Width is always fluid (100% of the container); the SVG is drawn in
962
+ * real pixels at the container's measured width, so text never scales with the card. */
971
963
  height?: number;
972
964
  /** Number of horizontal gridlines (excluding the zero baseline). */
973
965
  yTicks?: number;
@@ -1339,8 +1331,14 @@ interface FilterBarProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "on
1339
1331
  * clearFilter(id). Apply it synchronously, exactly like onFilterChange. */
1340
1332
  onFilterRemove: (key: string) => void;
1341
1333
  /** Which edge the "add filter" popover aligns to. Default "left" — the trigger sits
1342
- * at the end of a left-to-right chip row, so its menu opens under its left edge. */
1334
+ * in the leading column, left of the chips, so its menu opens under its left edge. */
1343
1335
  align?: "left" | "right";
1336
+ /** Controls that sit at the bar's right edge, in a column of their own: a date range, an
1337
+ * export button. They are laid out beside the Filter button and the chips and stay put
1338
+ * however many chips wrap (they top-align to the Filter button, never to the chips), and
1339
+ * drop below the chips on a row of their own, still right-aligned, when the bar is too
1340
+ * narrow to hold them all on one line. */
1341
+ actions?: React.ReactNode;
1344
1342
  className?: string;
1345
1343
  }
1346
1344
  type FilterValidation = {
@@ -1392,7 +1390,7 @@ declare function validateFilterValue(field: FilterField, value: unknown): Filter
1392
1390
  * string value; multiSelect/range/date each read/write a small typed object of their own
1393
1391
  * (see FilterValue).
1394
1392
  */
1395
- declare function FilterBar({ fields, filters, onFilterChange, onFilterRemove, align, className, ...rest }: FilterBarProps): React.JSX.Element;
1393
+ declare function FilterBar({ fields, filters, onFilterChange, onFilterRemove, align, actions, className, ...rest }: FilterBarProps): React.JSX.Element;
1396
1394
 
1397
1395
  /**
1398
1396
  * A flat figure tile — no shadow, no background color, never more than four in a row.
@@ -2452,6 +2450,8 @@ interface SelectProps {
2452
2450
  label?: string;
2453
2451
  help?: string;
2454
2452
  error?: string;
2453
+ /** Names the field when it has no visible `label` (the trigger is then named "<aria-label> <selected option>"). */
2454
+ "aria-label"?: string;
2455
2455
  options: Array<string | SelectOption>;
2456
2456
  placeholder?: string;
2457
2457
  required?: boolean;
@@ -2477,13 +2477,15 @@ interface SelectProps {
2477
2477
  * from it. Generated when omitted, so `label` names the trigger either way. */
2478
2478
  id?: string;
2479
2479
  }
2480
- declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style }: SelectProps): React.JSX.Element;
2480
+ declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style, "aria-label": hiddenLabel }: SelectProps): React.JSX.Element;
2481
2481
 
2482
2482
  /** Calendar popover date field. Click the title to drill month -> year; range mode picks start then end with live hover preview. Values are ISO strings ("2026-03-01"). */
2483
2483
  interface DatePickerProps {
2484
2484
  label?: string;
2485
2485
  help?: string;
2486
2486
  error?: string;
2487
+ /** Names the field when it has no visible `label` (the trigger is then named "<aria-label> <what it displays>"). */
2488
+ "aria-label"?: string;
2487
2489
  required?: boolean;
2488
2490
  disabled?: boolean;
2489
2491
  /** false: value is "YYYY-MM-DD". true: value is {start, end}. */
@@ -2507,7 +2509,7 @@ interface CalendarProps {
2507
2509
  months?: number;
2508
2510
  }
2509
2511
  declare function Calendar({ value, range, onPick, initialMonth, months }: CalendarProps): React.JSX.Element;
2510
- declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, id, className, style, ...rest }: DatePickerProps): React.JSX.Element;
2512
+ declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, id, className, style, "aria-label": hiddenLabel, ...rest }: DatePickerProps): React.JSX.Element;
2511
2513
 
2512
2514
  /** Analog clock-face time field: tap or drag the hand to set the hour, auto-advances to minutes; AM/PM chips; "Now" shortcut. Value is 24h "HH:MM". */
2513
2515
  interface TimePickerProps {
@@ -4899,8 +4901,8 @@ declare const LAYER_STEP = 10;
4899
4901
  * page chrome (a sticky header, the off-canvas rail's own resting z-index) must stay under
4900
4902
  * this, so no page z-index can ever outrank an overlay. */
4901
4903
  declare const ROOT_STEP = 100;
4902
- /** Guaranteed to sit above any z-index this mechanism can ever compute — see Popover.tsx's
4903
- * TransferList drag-ghost use. Not part of the layer tree; nothing derives from it. */
4904
+ /** Guaranteed to sit above any z-index this mechanism can ever compute — see
4905
+ * TransferList.tsx's drag-ghost use. Not part of the layer tree; nothing derives from it. */
4904
4906
  declare const OVERLAY_CEILING = 10000;
4905
4907
  /** The z-index `layer` should render at right now — 0 while it is closed (nothing should be
4906
4908
  * positioning off it then). Re-renders whenever any layer anywhere opens or closes, since