@galaxy-io/dls 2.9.0 → 2.10.1

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.
Files changed (103) hide show
  1. package/dist/beacons/Beacon.d.ts +1 -1
  2. package/dist/beacons/Beacon.js +12 -28
  3. package/dist/brand/GalaxyAlchemyWordmark.d.ts +4 -1
  4. package/dist/brand/GalaxyAlchemyWordmark.js +7 -1
  5. package/dist/brand/GalaxyFilamentWordmark.d.ts +5 -2
  6. package/dist/brand/GalaxyFilamentWordmark.js +9 -2
  7. package/dist/brand/GalaxyLogomark.js +3 -0
  8. package/dist/brand/PoweredBy.d.ts +27 -0
  9. package/dist/brand/PoweredBy.js +96 -0
  10. package/dist/brand/internal/svg/GalaxyFilamentWordmarkSvg.d.ts +1 -1
  11. package/dist/brand/internal/svg/GalaxyFilamentWordmarkSvg.js +2 -2
  12. package/dist/charts/Heatmap.js +25 -9
  13. package/dist/charts/Sparkline.d.ts +1 -1
  14. package/dist/charts/Sparkline.js +10 -26
  15. package/dist/charts/chartFormat.d.ts +1 -1
  16. package/dist/charts/chartFormat.js +2 -2
  17. package/dist/charts/heatmapGeometry.d.ts +14 -0
  18. package/dist/charts/heatmapGeometry.js +17 -1
  19. package/dist/chips/Chip.d.ts +2 -2
  20. package/dist/chips/Chip.js +15 -31
  21. package/dist/drawer/Drawer.d.ts +2 -2
  22. package/dist/drawer/Drawer.js +1 -1
  23. package/dist/editor/CodeEditor.d.ts +1 -1
  24. package/dist/editor/CodeEditor.js +2 -1
  25. package/dist/feedback/Alert.d.ts +36 -9
  26. package/dist/feedback/Alert.js +26 -8
  27. package/dist/feedback/ProgressBar.d.ts +4 -1
  28. package/dist/feedback/ProgressBar.js +17 -30
  29. package/dist/feedback/ProgressCircle.d.ts +1 -1
  30. package/dist/feedback/ProgressCircle.js +14 -30
  31. package/dist/hooks/useEndReached.d.ts +40 -0
  32. package/dist/hooks/useEndReached.js +69 -0
  33. package/dist/icons/Icon.d.ts +36 -8
  34. package/dist/icons/Icon.js +14 -7
  35. package/dist/inputs/CronInput.js +114 -78
  36. package/dist/inputs/DateInput.d.ts +1 -1
  37. package/dist/inputs/DateInput.js +10 -10
  38. package/dist/inputs/MultiSelectInput.d.ts +3 -1
  39. package/dist/inputs/MultiSelectInput.js +8 -3
  40. package/dist/inputs/SelectInput.d.ts +8 -1
  41. package/dist/inputs/SelectInput.js +52 -25
  42. package/dist/inputs/internal/selectAll.d.ts +11 -0
  43. package/dist/inputs/internal/selectAll.js +28 -0
  44. package/dist/json/JsonViewer.js +7 -6
  45. package/dist/layout/AppFrame.d.ts +20 -0
  46. package/dist/layout/AppFrame.js +71 -0
  47. package/dist/layout/EmptyLayout.d.ts +53 -0
  48. package/dist/layout/EmptyLayout.js +59 -0
  49. package/dist/layout/ErrorLayout.d.ts +42 -0
  50. package/dist/layout/ErrorLayout.js +60 -0
  51. package/dist/layout/PageLayout.d.ts +26 -0
  52. package/dist/layout/PageLayout.js +116 -0
  53. package/dist/layout/PendingLayout.d.ts +30 -0
  54. package/dist/layout/PendingLayout.js +57 -0
  55. package/dist/layout/internal/errorState.d.ts +14 -0
  56. package/dist/layout/internal/errorState.js +49 -0
  57. package/dist/layout/internal/region.d.ts +10 -0
  58. package/dist/layout/internal/region.js +24 -0
  59. package/dist/lists/DescriptionList.js +1 -0
  60. package/dist/menu/Menu.d.ts +2 -2
  61. package/dist/menu/Menu.js +6 -13
  62. package/dist/modal/Modal.d.ts +2 -2
  63. package/dist/modal/Modal.js +1 -1
  64. package/dist/navigation/CommandPalette.js +4 -11
  65. package/dist/navigation/SidebarNav.d.ts +5 -0
  66. package/dist/navigation/SidebarNav.js +41 -22
  67. package/dist/navigation/Tabs.d.ts +4 -2
  68. package/dist/navigation/Tabs.js +52 -32
  69. package/dist/navigation/Topbar.js +4 -0
  70. package/dist/shapes/Circle.d.ts +1 -1
  71. package/dist/shapes/Circle.js +10 -26
  72. package/dist/shapes/Square.d.ts +1 -1
  73. package/dist/shapes/Square.js +10 -26
  74. package/dist/styles/internal/roleColor.d.ts +3 -0
  75. package/dist/styles/internal/roleColor.js +42 -0
  76. package/dist/styles/mixins.js +1 -1
  77. package/dist/styles.css +1 -1
  78. package/dist/table/InfiniteSpreadsheet.js +6 -6
  79. package/dist/table/InfiniteTable.d.ts +52 -20
  80. package/dist/table/InfiniteTable.js +3 -2
  81. package/dist/table/TableCore.d.ts +7 -1
  82. package/dist/table/TableCore.js +93 -83
  83. package/dist/table/VirtualizedInfiniteTable.d.ts +53 -21
  84. package/dist/table/VirtualizedInfiniteTable.js +7 -5
  85. package/dist/table/useInfiniteScrollSentinel.d.ts +13 -13
  86. package/dist/table/useInfiniteScrollSentinel.js +7 -51
  87. package/dist/theme/tokens/dark.js +1 -1
  88. package/dist/theme/tokens/light.js +4 -3
  89. package/dist/theme/tokens/types.d.ts +7 -7
  90. package/dist/timeline/Timeline.d.ts +1 -1
  91. package/dist/timeline/Timeline.js +6 -24
  92. package/dist/tokens.css +1 -1
  93. package/dist/utils/format.d.ts +35 -10
  94. package/dist/utils/format.js +60 -12
  95. package/dist/utils/search.d.ts +15 -0
  96. package/dist/utils/search.js +24 -0
  97. package/dist/vite/index.d.ts +16 -2
  98. package/dist/vite/index.js +28 -19
  99. package/dist/vite/internal/themeBoot.d.ts +25 -0
  100. package/dist/vite/internal/themeBoot.js +44 -0
  101. package/dist/vite/internal/wywOptions.d.ts +46 -0
  102. package/dist/vite/internal/wywOptions.js +44 -0
  103. package/package.json +34 -1
@@ -1,6 +1,7 @@
1
1
  import Skeleton, { SkeletonSize, SkeletonVariant } from "../feedback/Skeleton.js";
2
2
  import Text, { TextSize, TextVariant } from "../text/Text.js";
3
3
  import Tooltip from "../tooltip/Tooltip.js";
4
+ import { ROLE_COLOR_TO_CSS_MAP } from "../styles/internal/roleColor.js";
4
5
  import Beacon, { BeaconSize, BeaconVariant } from "../beacons/Beacon.js";
5
6
  import Icon, { IconVariant } from "../icons/Icon.js";
6
7
  /* empty css */
@@ -45,8 +46,8 @@ var ChipSize = /* @__PURE__ */ function(ChipSize) {
45
46
  return ChipSize;
46
47
  }({});
47
48
  /**
48
- * Color role (Constitution V-A color set; meaning only): tints the fill, the text and the border
49
- * together. Categories take `color` instead.
49
+ * Color role (AGENTS.md "Variant": color set, meaning only): tints the fill, the text and the
50
+ * border together. Categories take `color` instead.
50
51
  */
51
52
  var ChipVariant = /* @__PURE__ */ function(ChipVariant) {
52
53
  /** `background.primary` fill, `text.primary`. */
@@ -150,36 +151,19 @@ var CHIP_VARIANT_TO_CSS_MAP = {
150
151
  ["WARNING"]: "gx-Chip-WARNING-wmla4eg",
151
152
  ["ERROR"]: "gx-Chip-ERROR-ey90mc4"
152
153
  };
153
- /** Categorical `color`: the family's text, fill and border, as a status variant renders. */
154
- var CHIP_COLOR_TO_CSS_MAP = {
155
- success: "gx-Chip-success-s1buqu4j",
156
- warning: "gx-Chip-warning-w1xofe8u",
157
- error: "gx-Chip-error-elle9kf",
158
- red: "gx-Chip-red-rvehr9v",
159
- orange: "gx-Chip-orange-o6qjmz2",
160
- amber: "gx-Chip-amber-atd4jog",
161
- yellow: "gx-Chip-yellow-yvlk44e",
162
- lime: "gx-Chip-lime-l1pq316v",
163
- green: "gx-Chip-green-gm0lqld",
164
- emerald: "gx-Chip-emerald-eyyt7c0",
165
- teal: "gx-Chip-teal-t11ah2de",
166
- cyan: "gx-Chip-cyan-czbiez9",
167
- sky: "gx-Chip-sky-s9o9u3v",
168
- blue: "gx-Chip-blue-b1ec95in",
169
- indigo: "gx-Chip-indigo-iptfyqj",
170
- violet: "gx-Chip-violet-v1fzme42",
171
- purple: "gx-Chip-purple-piztats",
172
- fuchsia: "gx-Chip-fuchsia-f1g78mhs",
173
- pink: "gx-Chip-pink-p1t4qqih",
174
- rose: "gx-Chip-rose-r1na9n10"
175
- };
154
+ /**
155
+ * Categorical `color`: the family's text, fill and border, as a status variant renders. Reads the
156
+ * shared `--gx-role-*` variables `ROLE_COLOR_TO_CSS_MAP` sets per family, so the twenty families
157
+ * are written once (`styles/internal/roleColor`).
158
+ */
159
+ var CHIP_COLOR_CSS = "gx-Chip-CHIP_COLOR_CSS-c1buqu4j";
176
160
  /** `hex`: declared after the variant and color maps so it wins over them. */
177
- var HEX_CSS = "gx-Chip-HEX_CSS-hy859dk";
178
- var HAS_BORDER_CSS = "gx-Chip-HAS_BORDER_CSS-htyaijm";
161
+ var HEX_CSS = "gx-Chip-HEX_CSS-h1xofe8u";
162
+ var HAS_BORDER_CSS = "gx-Chip-HAS_BORDER_CSS-hlle9kf";
179
163
  /** Declared after `HAS_BORDER_CSS`, so selection wins. */
180
- var SELECTED_CSS = "gx-Chip-SELECTED_CSS-s94m49k";
181
- var PILL_CSS = "gx-Chip-PILL_CSS-p10jj8uz";
182
- /** Label and count type step per rung (Constitution III-A.4). */
164
+ var SELECTED_CSS = "gx-Chip-SELECTED_CSS-svehr9v";
165
+ var PILL_CSS = "gx-Chip-PILL_CSS-p6qjmz2";
166
+ /** Label and count type step per rung (AGENTS.md "Control rungs"). */
183
167
  var CHIP_SIZE_TO_TEXT_SIZE_MAP = {
184
168
  ["X_SMALL"]: TextSize.CAPTION,
185
169
  ["SMALL"]: TextSize.BODY_SM,
@@ -337,7 +321,7 @@ var Chip = forwardRef(function Chip({ label, icon, leading, hasDot = false, coun
337
321
  ...rootRest,
338
322
  ref,
339
323
  id,
340
- className: cx(CHIP_SIZE_TO_CSS_MAP[size], hasColor ? CHIP_COLOR_TO_CSS_MAP[color] : CHIP_VARIANT_TO_CSS_MAP[shownVariant], hasHex && HEX_CSS, hasBorder && HAS_BORDER_CSS, isSelected === true && SELECTED_CSS, isPill && PILL_CSS, className),
324
+ className: cx(CHIP_SIZE_TO_CSS_MAP[size], hasColor ? cx(ROLE_COLOR_TO_CSS_MAP[color], CHIP_COLOR_CSS) : CHIP_VARIANT_TO_CSS_MAP[shownVariant], hasHex && HEX_CSS, hasBorder && HAS_BORDER_CSS, isSelected === true && SELECTED_CSS, isPill && PILL_CSS, className),
341
325
  style: {
342
326
  ...variables,
343
327
  ...style
@@ -3,7 +3,7 @@ import { type AriaAttributes, type CSSProperties, type ReactNode } from "react";
3
3
  import { Side } from "../theme/enums.js";
4
4
  /**
5
5
  * Panel width (`LEFT` / `RIGHT`) or height (`TOP` / `BOTTOM`). Canonical rung names
6
- * (Constitution V); the values are lengths, not control heights.
6
+ * (AGENTS.md "Size"); the values are lengths, not control heights.
7
7
  */
8
8
  export declare enum DrawerSize {
9
9
  /** 400px wide / 240px tall. */
@@ -60,7 +60,7 @@ interface DrawerBaseProps extends AriaAttributes {
60
60
  * @default true
61
61
  */
62
62
  isDismissable?: boolean;
63
- /** Controlled open state. When set, Drawer calls `onOpenChange` and lets the caller decide. */
63
+ /** Controlled open state. When set, Drawer calls `onOpenChange` and lets the caller decide. While it closes, the panel keeps the `children` and slots it had when `isOpen` turned false, so pass the open record as a prop with no hook to retain it. */
64
64
  isOpen?: boolean;
65
65
  /**
66
66
  * Initial open state while uncontrolled.
@@ -49,7 +49,7 @@ import { AnimatePresence, motion } from "framer-motion";
49
49
  */
50
50
  /**
51
51
  * Panel width (`LEFT` / `RIGHT`) or height (`TOP` / `BOTTOM`). Canonical rung names
52
- * (Constitution V); the values are lengths, not control heights.
52
+ * (AGENTS.md "Size"); the values are lengths, not control heights.
53
53
  */
54
54
  var DrawerSize = /* @__PURE__ */ function(DrawerSize) {
55
55
  /** 400px wide / 240px tall. */
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import type { Extension } from "@codemirror/state";
17
17
  import { type AriaAttributes, type CSSProperties } from "react";
18
- /** Resting fill of the editor frame (Constitution V-A surface set; 1.x members). 1.x `noBorder` is `isGhost`. */
18
+ /** Resting fill of the editor frame (AGENTS.md "Variant": surface set; 1.x members). 1.x `noBorder` is `isGhost`. */
19
19
  export declare enum CodeEditorVariant {
20
20
  /** `background.base`. */
21
21
  BASE = "BASE",
@@ -15,7 +15,7 @@ import { tags } from "@lezer/highlight";
15
15
  import { createTheme } from "@uiw/codemirror-themes";
16
16
  import CodeMirror from "@uiw/react-codemirror";
17
17
  //#region src/editor/CodeEditor.tsx
18
- /** Resting fill of the editor frame (Constitution V-A surface set; 1.x members). 1.x `noBorder` is `isGhost`. */
18
+ /** Resting fill of the editor frame (AGENTS.md "Variant": surface set; 1.x members). 1.x `noBorder` is `isGhost`. */
19
19
  var CodeEditorVariant = /* @__PURE__ */ function(CodeEditorVariant) {
20
20
  /** `background.base`. */
21
21
  CodeEditorVariant["BASE"] = "BASE";
@@ -259,6 +259,7 @@ function getEditorViewTheme() {
259
259
  lineHeight: t.font.mono.height.body_lg,
260
260
  letterSpacing: t.font.mono.spacing.body_md
261
261
  },
262
+ ".cm-scroller:focus": { outline: "none" },
262
263
  ".cm-content": { padding: `${t.space[8]} 0` },
263
264
  ".cm-line": { padding: `0 ${t.space[12]}` },
264
265
  ".cm-gutters": {
@@ -1,6 +1,7 @@
1
1
  import { type Icon as PhosphorIcon } from "@phosphor-icons/react";
2
2
  import { type AriaAttributes, type CSSProperties, type ReactNode } from "react";
3
- /** Severity (Constitution V-A color set, subset; Alert is listed in that column). */
3
+ import type { RoleColor } from "../theme/tokens/types.js";
4
+ /** Severity (AGENTS.md "Variant": color set, subset). */
4
5
  export declare enum AlertVariant {
5
6
  /** Neutral note: `background.secondary` surface, `InfoIcon` in `text.secondary`. The default. */
6
7
  PRIMARY = "PRIMARY",
@@ -11,19 +12,15 @@ export declare enum AlertVariant {
11
12
  /** Broken, blocked: error surface, `WarningCircleIcon`, `role="alert"`. */
12
13
  ERROR = "ERROR"
13
14
  }
14
- export interface AlertProps extends AriaAttributes {
15
- /**
16
- * Severity: sets the surface tint, the border, the icon and the ARIA role.
17
- * @default AlertVariant.PRIMARY
18
- */
19
- variant?: AlertVariant;
15
+ /** Every Alert prop except the color axis (`variant` or `color`). */
16
+ interface AlertBaseProps extends AriaAttributes {
20
17
  /** Short headline ("Schema drift detected"). Medium weight; above the body inline, before it in a banner. */
21
18
  header?: string;
22
19
  /** The message. Rendered in a `Text`, so inline `Span`, `Code` and `Link` inherit its size and color. */
23
20
  children?: ReactNode;
24
21
  /**
25
- * Replaces the variant's default icon. Pass the component (`PlugsIcon`), not an element.
26
- * @default the variant's icon
22
+ * Replaces the default icon. Pass the component (`PlugsIcon`), not an element.
23
+ * @default the variant's icon, or `InfoIcon` with `color`
27
24
  */
28
25
  icon?: PhosphorIcon;
29
26
  /** The way out: one `ButtonVariant.PRIMARY` button at `ButtonSize.SMALL`, any second action `TERTIARY`. A row under the body inline; trailing in a banner. */
@@ -44,6 +41,36 @@ export interface AlertProps extends AriaAttributes {
44
41
  /** Inline style on the root `<div>`; only for setting CSS custom properties. */
45
42
  style?: CSSProperties;
46
43
  }
44
+ /** An alert colored by severity (`variant`), or the default `PRIMARY`. */
45
+ interface AlertVariantProps {
46
+ /**
47
+ * Severity: sets the surface tint, the border, the icon and the ARIA role. Not with `color`.
48
+ * @default AlertVariant.PRIMARY
49
+ */
50
+ variant?: AlertVariant;
51
+ /**
52
+ * Categorical palette family (`"yellow"`) or a status name used as data: the family's surface,
53
+ * hairline and icon color, `role="status"`, announced as a "Note". For a notice tied to a
54
+ * category the page already shows; never a generic "info" tone. Not with `variant`.
55
+ */
56
+ color?: undefined;
57
+ }
58
+ /** An alert colored by category (`color`). */
59
+ interface AlertColorProps {
60
+ /**
61
+ * Severity: sets the surface tint, the border, the icon and the ARIA role. Not with `color`.
62
+ * @default AlertVariant.PRIMARY
63
+ */
64
+ variant?: undefined;
65
+ /**
66
+ * Categorical palette family (`"yellow"`) or a status name used as data: the family's surface,
67
+ * hairline and icon color, `role="status"`, announced as a "Note". For a notice tied to a
68
+ * category the page already shows; never a generic "info" tone. Not with `variant`.
69
+ */
70
+ color: RoleColor;
71
+ }
72
+ /** Alert props. An alert with both `variant` and `color` is a type error. */
73
+ export type AlertProps = AlertBaseProps & (AlertVariantProps | AlertColorProps);
47
74
  /** A tinted, bordered message with a severity icon, optional header, actions and dismiss. */
48
75
  declare const Alert: import("react").ForwardRefExoticComponent<AlertProps & import("react").RefAttributes<HTMLDivElement>>;
49
76
  export default Alert;
@@ -1,4 +1,5 @@
1
1
  import Text, { TextSize, TextVariant, TextWeight } from "../text/Text.js";
2
+ import { ROLE_COLOR_TO_CSS_MAP } from "../styles/internal/roleColor.js";
2
3
  import Icon, { IconVariant, IconWeight } from "../icons/Icon.js";
3
4
  import Button, { ButtonSize, ButtonVariant } from "../buttons/Button.js";
4
5
  /* empty css */
@@ -21,11 +22,17 @@ import { CheckCircleIcon, InfoIcon, WarningCircleIcon, WarningIcon, XIcon } from
21
22
  * A live region announces content that arrives after it is in the DOM, so mount the Alert when
22
23
  * the condition becomes true rather than rendering it hidden and revealing it.
23
24
  *
25
+ * `color` ties a notice to a category the page already shows (a schedule banner in the schedule's
26
+ * yellow): the surface is `background.<color>` and `border.<color>` through the shared
27
+ * `--gx-role-*` variables, the icon is `Icon color` (default `InfoIcon`), the role is `status` and
28
+ * the icon's accessible name is "Note". It is not an "info" tone: neutral news stays `PRIMARY`.
29
+ * `variant` and `color` are exclusive by type (the Chip union).
30
+ *
24
31
  * Inline it is a rounded panel; `isBanner` makes it a full-width strip across the top of a page
25
32
  * or panel (square corners, bottom hairline only, one line). No motion of its own: wrap it in
26
33
  * `Fade` (or the app's own height animation) for an animated dismiss.
27
34
  */
28
- /** Severity (Constitution V-A color set, subset; Alert is listed in that column). */
35
+ /** Severity (AGENTS.md "Variant": color set, subset). */
29
36
  var AlertVariant = /* @__PURE__ */ function(AlertVariant) {
30
37
  /** Neutral note: `background.secondary` surface, `InfoIcon` in `text.secondary`. The default. */
31
38
  AlertVariant["PRIMARY"] = "PRIMARY";
@@ -80,6 +87,8 @@ var ALERT_VARIANT_TO_CSS_MAP = {
80
87
  ["WARNING"]: "gx-Alert-WARNING-w6btz5r",
81
88
  ["ERROR"]: "gx-Alert-ERROR-e1rogvwo"
82
89
  };
90
+ /** Categorical `color`: the family's surface and hairline, read from the shared role variables. */
91
+ var COLOR_CSS = "gx-Alert-COLOR_CSS-cr7k6o5";
83
92
  /** Default glyph per severity. `ERROR` differs in shape from `WARNING`, so severity is never color-only. */
84
93
  var ALERT_VARIANT_TO_ICON_MAP = {
85
94
  ["PRIMARY"]: InfoIcon,
@@ -108,14 +117,17 @@ var ALERT_VARIANT_TO_SEVERITY_LABEL_MAP = {
108
117
  ["WARNING"]: "Warning",
109
118
  ["ERROR"]: "Error"
110
119
  };
120
+ /** The icon's accessible name with `color`: a category is a note, never a severity. */
121
+ var COLOR_SEVERITY_LABEL = "Note";
111
122
  /** Banner: square corners, bottom hairline only, centered one-line row. */
112
- var BANNER_CSS = "gx-Alert-BANNER_CSS-br7k6o5";
123
+ var BANNER_CSS = "gx-Alert-BANNER_CSS-b11mdnwt";
113
124
  /** Banner: the header and body read as one line, wrapping when narrow. */
114
- var BANNER_CONTENT_CSS = "gx-Alert-BANNER_CONTENT_CSS-b11mdnwt";
125
+ var BANNER_CONTENT_CSS = "gx-Alert-BANNER_CONTENT_CSS-by507ww";
115
126
  /** Banner: the actions trail and never shrink. */
116
- var BANNER_ACTIONS_CSS = "gx-Alert-BANNER_ACTIONS_CSS-by507ww";
127
+ var BANNER_ACTIONS_CSS = "gx-Alert-BANNER_ACTIONS_CSS-b1imlr6o";
117
128
  /** A tinted, bordered message with a severity icon, optional header, actions and dismiss. */
118
- var Alert = forwardRef(function Alert({ variant = "PRIMARY", header, children, icon, actions, onDismiss, isBanner = false, id, className, style, ...rest }, ref) {
129
+ var Alert = forwardRef(function Alert({ variant = "PRIMARY", color, header, children, icon, actions, onDismiss, isBanner = false, id, className, style, ...rest }, ref) {
130
+ const hasColor = color !== void 0;
119
131
  const hasHeader = header !== void 0 && header !== "";
120
132
  const hasBody = children !== void 0 && children !== null && children !== false;
121
133
  const actionsRow = actions !== void 0 && actions !== null && actions !== false && /* @__PURE__ */ jsx(Actions, {
@@ -123,14 +135,20 @@ var Alert = forwardRef(function Alert({ variant = "PRIMARY", header, children, i
123
135
  children: actions
124
136
  });
125
137
  return /* @__PURE__ */ jsxs(Root, {
126
- role: ALERT_VARIANT_TO_ROLE_MAP[variant],
138
+ role: hasColor ? "status" : ALERT_VARIANT_TO_ROLE_MAP[variant],
127
139
  ...rest,
128
140
  ref,
129
141
  id,
130
- className: cx(ALERT_VARIANT_TO_CSS_MAP[variant], isBanner && BANNER_CSS, className),
142
+ className: cx(hasColor ? cx(ROLE_COLOR_TO_CSS_MAP[color], COLOR_CSS) : ALERT_VARIANT_TO_CSS_MAP[variant], isBanner && BANNER_CSS, className),
131
143
  style,
132
144
  children: [
133
- /* @__PURE__ */ jsx(IconSlot, { children: /* @__PURE__ */ jsx(Icon, {
145
+ /* @__PURE__ */ jsx(IconSlot, { children: hasColor ? /* @__PURE__ */ jsx(Icon, {
146
+ component: icon ?? InfoIcon,
147
+ size: 16,
148
+ weight: IconWeight.FILL,
149
+ color,
150
+ ariaLabel: COLOR_SEVERITY_LABEL
151
+ }) : /* @__PURE__ */ jsx(Icon, {
134
152
  component: icon ?? ALERT_VARIANT_TO_ICON_MAP[variant],
135
153
  size: 16,
136
154
  weight: IconWeight.FILL,
@@ -13,7 +13,10 @@ export declare enum ProgressBarSize {
13
13
  /** 8px track, body_lg label. */
14
14
  X_LARGE = "X_LARGE"
15
15
  }
16
- /** Fill color (Constitution V-A color set, subset; the same members as `ProgressCircleVariant`). */
16
+ /**
17
+ * Fill color (AGENTS.md "Variant": color set, subset; the same members as
18
+ * `ProgressCircleVariant`).
19
+ */
17
20
  export declare enum ProgressBarVariant {
18
21
  /** `text.primary`. The default. */
19
22
  PRIMARY = "PRIMARY",
@@ -1,4 +1,5 @@
1
1
  import Text, { TextSize, TextVariant } from "../text/Text.js";
2
+ import { ROLE_COLOR_TO_CSS_MAP } from "../styles/internal/roleColor.js";
2
3
  import { formatPercent } from "../utils/format.js";
3
4
  /* empty css */
4
5
  import { styled } from "@linaria/react";
@@ -34,7 +35,10 @@ var ProgressBarSize = /* @__PURE__ */ function(ProgressBarSize) {
34
35
  ProgressBarSize["X_LARGE"] = "X_LARGE";
35
36
  return ProgressBarSize;
36
37
  }({});
37
- /** Fill color (Constitution V-A color set, subset; the same members as `ProgressCircleVariant`). */
38
+ /**
39
+ * Fill color (AGENTS.md "Variant": color set, subset; the same members as
40
+ * `ProgressCircleVariant`).
41
+ */
38
42
  var ProgressBarVariant = /* @__PURE__ */ function(ProgressBarVariant) {
39
43
  /** `text.primary`. The default. */
40
44
  ProgressBarVariant["PRIMARY"] = "PRIMARY";
@@ -95,36 +99,19 @@ var PROGRESS_BAR_VARIANT_TO_CSS_MAP = {
95
99
  ["WARNING"]: "gx-ProgressBar-WARNING-w1w2olvo",
96
100
  ["ERROR"]: "gx-ProgressBar-ERROR-e1qre8wf"
97
101
  };
98
- /** Categorical `color`: `mark.<family>` on the root, the way a status variant renders. */
99
- var PROGRESS_BAR_COLOR_TO_CSS_MAP = {
100
- success: "gx-ProgressBar-success-seiy0oi",
101
- warning: "gx-ProgressBar-warning-w1epzlep",
102
- error: "gx-ProgressBar-error-easg8k0",
103
- red: "gx-ProgressBar-red-r1kkinrj",
104
- orange: "gx-ProgressBar-orange-ocvje08",
105
- amber: "gx-ProgressBar-amber-ab5j54q",
106
- yellow: "gx-ProgressBar-yellow-ylbvi15",
107
- lime: "gx-ProgressBar-lime-lwaqggx",
108
- green: "gx-ProgressBar-green-g6fb74o",
109
- emerald: "gx-ProgressBar-emerald-e13m8tjk",
110
- teal: "gx-ProgressBar-teal-t195062s",
111
- cyan: "gx-ProgressBar-cyan-c1tjg1hb",
112
- sky: "gx-ProgressBar-sky-s1hc7niq",
113
- blue: "gx-ProgressBar-blue-b31v6jj",
114
- indigo: "gx-ProgressBar-indigo-i1idth2y",
115
- violet: "gx-ProgressBar-violet-vsz64tr",
116
- purple: "gx-ProgressBar-purple-p121jrhu",
117
- fuchsia: "gx-ProgressBar-fuchsia-foqk5ch",
118
- pink: "gx-ProgressBar-pink-p1luqk3n",
119
- rose: "gx-ProgressBar-rose-r1hbdj3k"
120
- };
102
+ /**
103
+ * Categorical `color`: `mark.<family>` on the root, the way a status variant renders. Reads the
104
+ * shared `--gx-role-*` variables `ROLE_COLOR_TO_CSS_MAP` sets per family, so the twenty families
105
+ * are written once (`styles/internal/roleColor`).
106
+ */
107
+ var PROGRESS_BAR_COLOR_CSS = "gx-ProgressBar-PROGRESS_BAR_COLOR_CSS-peiy0oi";
121
108
  /** Track thickness and the gap between the label line and the track. */
122
109
  var PROGRESS_BAR_SIZE_TO_CSS_MAP = {
123
- ["X_SMALL"]: "gx-ProgressBar-X_SMALL-x17skgql",
124
- ["SMALL"]: "gx-ProgressBar-SMALL-s1i0eise",
125
- ["MEDIUM"]: "gx-ProgressBar-MEDIUM-mnhve48",
126
- ["LARGE"]: "gx-ProgressBar-LARGE-l1p1szbl",
127
- ["X_LARGE"]: "gx-ProgressBar-X_LARGE-xu0asu0"
110
+ ["X_SMALL"]: "gx-ProgressBar-X_SMALL-x1epzlep",
111
+ ["SMALL"]: "gx-ProgressBar-SMALL-sasg8k0",
112
+ ["MEDIUM"]: "gx-ProgressBar-MEDIUM-m1kkinrj",
113
+ ["LARGE"]: "gx-ProgressBar-LARGE-lcvje08",
114
+ ["X_LARGE"]: "gx-ProgressBar-X_LARGE-xb5j54q"
128
115
  };
129
116
  /** The label and value are the rung's text step (the ProgressCircle table). */
130
117
  var PROGRESS_BAR_SIZE_TO_TEXT_SIZE_MAP = {
@@ -158,7 +145,7 @@ var ProgressBar = forwardRef(function ProgressBar({ value, isIndeterminate = fal
158
145
  "aria-valuetext": isIndeterminate ? void 0 : rest["aria-valuetext"] ?? percentText,
159
146
  "aria-label": hasLabel ? rest["aria-label"] : ariaLabel ?? rest["aria-label"],
160
147
  "aria-labelledby": hasLabel ? labelId : rest["aria-labelledby"],
161
- className: cx(color !== void 0 ? PROGRESS_BAR_COLOR_TO_CSS_MAP[color] : PROGRESS_BAR_VARIANT_TO_CSS_MAP[variant], PROGRESS_BAR_SIZE_TO_CSS_MAP[size], className),
148
+ className: cx(color !== void 0 ? cx(ROLE_COLOR_TO_CSS_MAP[color], PROGRESS_BAR_COLOR_CSS) : PROGRESS_BAR_VARIANT_TO_CSS_MAP[variant], PROGRESS_BAR_SIZE_TO_CSS_MAP[size], className),
162
149
  style: {
163
150
  ...variables,
164
151
  ...style
@@ -13,7 +13,7 @@ export declare enum ProgressCircleSize {
13
13
  /** 40px rung: 16px ring, body_lg label. */
14
14
  X_LARGE = "X_LARGE"
15
15
  }
16
- /** Arc color (Constitution V-A color set, subset; the same members as `ProgressBarVariant`). */
16
+ /** Arc color (AGENTS.md "Variant": color set, subset; the same members as `ProgressBarVariant`). */
17
17
  export declare enum ProgressCircleVariant {
18
18
  /** `text.primary`. The default. */
19
19
  PRIMARY = "PRIMARY",
@@ -1,4 +1,5 @@
1
1
  import Text, { TextSize, TextVariant } from "../text/Text.js";
2
+ import { ROLE_COLOR_TO_CSS_MAP } from "../styles/internal/roleColor.js";
2
3
  import { formatPercent } from "../utils/format.js";
3
4
  /* empty css */
4
5
  import { styled } from "@linaria/react";
@@ -34,7 +35,7 @@ var ProgressCircleSize = /* @__PURE__ */ function(ProgressCircleSize) {
34
35
  ProgressCircleSize["X_LARGE"] = "X_LARGE";
35
36
  return ProgressCircleSize;
36
37
  }({});
37
- /** Arc color (Constitution V-A color set, subset; the same members as `ProgressBarVariant`). */
38
+ /** Arc color (AGENTS.md "Variant": color set, subset; the same members as `ProgressBarVariant`). */
38
39
  var ProgressCircleVariant = /* @__PURE__ */ function(ProgressCircleVariant) {
39
40
  /** `text.primary`. The default. */
40
41
  ProgressCircleVariant["PRIMARY"] = "PRIMARY";
@@ -82,36 +83,19 @@ var PROGRESS_CIRCLE_VARIANT_TO_CSS_MAP = {
82
83
  ["WARNING"]: "gx-ProgressCircle-WARNING-w1ii09vl",
83
84
  ["ERROR"]: "gx-ProgressCircle-ERROR-e149xl4a"
84
85
  };
85
- /** Categorical `color`: `mark.<family>` on the root, the way a status variant renders. */
86
- var PROGRESS_CIRCLE_COLOR_TO_CSS_MAP = {
87
- success: "gx-ProgressCircle-success-s5wr4fy",
88
- warning: "gx-ProgressCircle-warning-w3cpdk8",
89
- error: "gx-ProgressCircle-error-e3bcytf",
90
- red: "gx-ProgressCircle-red-r1b1indu",
91
- orange: "gx-ProgressCircle-orange-os32e8h",
92
- amber: "gx-ProgressCircle-amber-a1z891t",
93
- yellow: "gx-ProgressCircle-yellow-y169l71b",
94
- lime: "gx-ProgressCircle-lime-l7wy6jh",
95
- green: "gx-ProgressCircle-green-gid9v1r",
96
- emerald: "gx-ProgressCircle-emerald-ephjv2k",
97
- teal: "gx-ProgressCircle-teal-t14y8mwv",
98
- cyan: "gx-ProgressCircle-cyan-c1gpmklw",
99
- sky: "gx-ProgressCircle-sky-s15o8mw",
100
- blue: "gx-ProgressCircle-blue-b865hhm",
101
- indigo: "gx-ProgressCircle-indigo-i1lkh9dd",
102
- violet: "gx-ProgressCircle-violet-v4a8qsx",
103
- purple: "gx-ProgressCircle-purple-pzljd4b",
104
- fuchsia: "gx-ProgressCircle-fuchsia-foz9zwb",
105
- pink: "gx-ProgressCircle-pink-pi0gudm",
106
- rose: "gx-ProgressCircle-rose-r1tg3t7s"
107
- };
86
+ /**
87
+ * Categorical `color`: `mark.<family>` on the root, the way a status variant renders. Reads the
88
+ * shared `--gx-role-*` variables `ROLE_COLOR_TO_CSS_MAP` sets per family, so the twenty families
89
+ * are written once (`styles/internal/roleColor`).
90
+ */
91
+ var PROGRESS_CIRCLE_COLOR_CSS = "gx-ProgressCircle-PROGRESS_CIRCLE_COLOR_CSS-p5wr4fy";
108
92
  /** Ring box, root height (the rung's text line height) and gap: the Spinner table. */
109
93
  var PROGRESS_CIRCLE_SIZE_TO_CSS_MAP = {
110
- ["X_SMALL"]: "gx-ProgressCircle-X_SMALL-x1tizbqg",
111
- ["SMALL"]: "gx-ProgressCircle-SMALL-suuqsnf",
112
- ["MEDIUM"]: "gx-ProgressCircle-MEDIUM-mrsjl86",
113
- ["LARGE"]: "gx-ProgressCircle-LARGE-lzwqtuj",
114
- ["X_LARGE"]: "gx-ProgressCircle-X_LARGE-x1omzhlm"
94
+ ["X_SMALL"]: "gx-ProgressCircle-X_SMALL-x3cpdk8",
95
+ ["SMALL"]: "gx-ProgressCircle-SMALL-s3bcytf",
96
+ ["MEDIUM"]: "gx-ProgressCircle-MEDIUM-m1b1indu",
97
+ ["LARGE"]: "gx-ProgressCircle-LARGE-ls32e8h",
98
+ ["X_LARGE"]: "gx-ProgressCircle-X_LARGE-x1z891t"
115
99
  };
116
100
  /** The label and value are the rung's text step (the ProgressBar table). */
117
101
  var PROGRESS_CIRCLE_SIZE_TO_TEXT_SIZE_MAP = {
@@ -144,7 +128,7 @@ var ProgressCircle = forwardRef(function ProgressCircle({ value, shouldShowValue
144
128
  "aria-valuetext": rest["aria-valuetext"] ?? percentText,
145
129
  "aria-label": hasLabel ? rest["aria-label"] : ariaLabel ?? rest["aria-label"],
146
130
  "aria-labelledby": hasLabel ? labelId : rest["aria-labelledby"],
147
- className: cx(color !== void 0 ? PROGRESS_CIRCLE_COLOR_TO_CSS_MAP[color] : PROGRESS_CIRCLE_VARIANT_TO_CSS_MAP[variant], PROGRESS_CIRCLE_SIZE_TO_CSS_MAP[size], className),
131
+ className: cx(color !== void 0 ? cx(ROLE_COLOR_TO_CSS_MAP[color], PROGRESS_CIRCLE_COLOR_CSS) : PROGRESS_CIRCLE_VARIANT_TO_CSS_MAP[variant], PROGRESS_CIRCLE_SIZE_TO_CSS_MAP[size], className),
148
132
  style: {
149
133
  ...variables,
150
134
  ...style
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Calls `onEndReached` when the end of a growing list comes within reach, for infinite scrolling.
3
+ * The caller renders a zero-size sentinel after its last item and attaches the returned ref; the
4
+ * hook observes it with an `IntersectionObserver` whose bottom margin is `marginPx`.
5
+ *
6
+ * The sentinel is zero-height on purpose: a 1px sentinel inside a scroll container makes it
7
+ * overflow by a pixel, which traps the wheel at the end of the list (AGENTS.md "Scrolling is the
8
+ * browser's"). Render it as `<div ref={ref} />` with no size of its own.
9
+ *
10
+ * The root is `scrollRef` when that element overflows, otherwise the viewport, so a list in an
11
+ * unbounded parent pages on page scroll. It is armed only while `isEnabled` (pause it while a page
12
+ * loads or after an error), re-armed when `itemCount` changes, and calls `onEndReached` at most
13
+ * once per `itemCount`: a list with no next page adds no items, so it is not called again. Without
14
+ * `IntersectionObserver` it falls back to a passive `scroll` listener. Nothing runs at module scope.
15
+ *
16
+ * The tables (InfiniteTable, VirtualizedInfiniteTable, InfiniteSpreadsheet) page through it; use it
17
+ * for an app list that is not a table.
18
+ */
19
+ import { type RefObject } from "react";
20
+ /** Options for `useEndReached`. */
21
+ export interface UseEndReachedOptions {
22
+ /** Called when the end comes within reach; `undefined` observes nothing (no next page to load). */
23
+ onEndReached: (() => void) | undefined;
24
+ /** `false` while a page loads or after an error: paging pauses until it is `true` again. */
25
+ isEnabled: boolean;
26
+ /** Items loaded so far. A change re-arms the observer; the callback fires at most once per count. */
27
+ itemCount: number;
28
+ /**
29
+ * The list's own scroll container. Omitted (or not overflowing), the viewport is the root.
30
+ * @default the viewport
31
+ */
32
+ scrollRef?: RefObject<HTMLElement | null>;
33
+ /**
34
+ * How far below the visible area the end counts as reached, in px.
35
+ * @default 500
36
+ */
37
+ marginPx?: number;
38
+ }
39
+ /** Observes a zero-size sentinel after the last item and calls `onEndReached`; returns the sentinel's ref. */
40
+ export declare function useEndReached<TElement extends Element = HTMLDivElement>({ onEndReached, isEnabled, itemCount, scrollRef, marginPx, }: UseEndReachedOptions): RefObject<TElement | null>;
@@ -0,0 +1,69 @@
1
+ import { useEffect, useRef } from "react";
2
+ //#region src/hooks/useEndReached.ts
3
+ /**
4
+ * Calls `onEndReached` when the end of a growing list comes within reach, for infinite scrolling.
5
+ * The caller renders a zero-size sentinel after its last item and attaches the returned ref; the
6
+ * hook observes it with an `IntersectionObserver` whose bottom margin is `marginPx`.
7
+ *
8
+ * The sentinel is zero-height on purpose: a 1px sentinel inside a scroll container makes it
9
+ * overflow by a pixel, which traps the wheel at the end of the list (AGENTS.md "Scrolling is the
10
+ * browser's"). Render it as `<div ref={ref} />` with no size of its own.
11
+ *
12
+ * The root is `scrollRef` when that element overflows, otherwise the viewport, so a list in an
13
+ * unbounded parent pages on page scroll. It is armed only while `isEnabled` (pause it while a page
14
+ * loads or after an error), re-armed when `itemCount` changes, and calls `onEndReached` at most
15
+ * once per `itemCount`: a list with no next page adds no items, so it is not called again. Without
16
+ * `IntersectionObserver` it falls back to a passive `scroll` listener. Nothing runs at module scope.
17
+ *
18
+ * The tables (InfiniteTable, VirtualizedInfiniteTable, InfiniteSpreadsheet) page through it; use it
19
+ * for an app list that is not a table.
20
+ */
21
+ /** How far below the visible area the end counts as reached by default: the tables' 500px. */
22
+ var DEFAULT_MARGIN_PX = 500;
23
+ /** Observes a zero-size sentinel after the last item and calls `onEndReached`; returns the sentinel's ref. */
24
+ function useEndReached({ onEndReached, isEnabled, itemCount, scrollRef, marginPx = DEFAULT_MARGIN_PX }) {
25
+ const sentinelRef = useRef(null);
26
+ const onEndReachedRef = useRef(onEndReached);
27
+ onEndReachedRef.current = onEndReached;
28
+ const calledForCountRef = useRef(null);
29
+ const hasHandler = onEndReached !== void 0;
30
+ useEffect(() => {
31
+ const scroll = scrollRef?.current ?? null;
32
+ const sentinel = sentinelRef.current;
33
+ if (!hasHandler || !isEnabled || sentinel === null) return;
34
+ if (calledForCountRef.current === itemCount) return;
35
+ const reach = () => {
36
+ if (calledForCountRef.current === itemCount) return;
37
+ calledForCountRef.current = itemCount;
38
+ onEndReachedRef.current?.();
39
+ };
40
+ const scrollRoot = scroll !== null && scroll.scrollHeight > scroll.clientHeight ? scroll : null;
41
+ if (typeof IntersectionObserver === "undefined") {
42
+ const target = scrollRoot ?? window;
43
+ const check = () => {
44
+ const bottom = scrollRoot?.getBoundingClientRect().bottom ?? window.innerHeight;
45
+ if (sentinel.getBoundingClientRect().top - bottom < marginPx) reach();
46
+ };
47
+ check();
48
+ target.addEventListener("scroll", check, { passive: true });
49
+ return () => target.removeEventListener("scroll", check);
50
+ }
51
+ const observer = new IntersectionObserver((entries) => {
52
+ if (entries.some((entry) => entry.isIntersecting)) reach();
53
+ }, {
54
+ root: scrollRoot,
55
+ rootMargin: `0px 0px ${marginPx}px 0px`
56
+ });
57
+ observer.observe(sentinel);
58
+ return () => observer.disconnect();
59
+ }, [
60
+ scrollRef,
61
+ hasHandler,
62
+ isEnabled,
63
+ itemCount,
64
+ marginPx
65
+ ]);
66
+ return sentinelRef;
67
+ }
68
+ //#endregion
69
+ export { useEndReached };
@@ -1,7 +1,7 @@
1
1
  import type { Icon as PhosphorIcon } from "@phosphor-icons/react";
2
2
  import { type AriaAttributes, type CSSProperties, type ReactNode } from "react";
3
- import type { Hex } from "../theme/tokens/types.js";
4
- /** Color role of the icon (color set, Constitution V-A). Resolves to `color.text.*`. */
3
+ import type { Hex, RoleColor } from "../theme/tokens/types.js";
4
+ /** Color role of the icon (AGENTS.md "Variant": color set). Resolves to `color.text.*`. */
5
5
  export declare enum IconVariant {
6
6
  /** `text.primary`. The default. */
7
7
  PRIMARY = "PRIMARY",
@@ -35,7 +35,8 @@ export declare enum IconWeight {
35
35
  /** Stroke over a 20% fill. */
36
36
  DUOTONE = "DUOTONE"
37
37
  }
38
- export interface IconProps extends AriaAttributes {
38
+ /** Every Icon prop except the color axis (`variant` or `color`). */
39
+ interface IconBaseProps extends AriaAttributes {
39
40
  /** Phosphor icon *component*: pass `PlusIcon`, not `<PlusIcon />`. */
40
41
  component: PhosphorIcon;
41
42
  /**
@@ -48,11 +49,6 @@ export interface IconProps extends AriaAttributes {
48
49
  * @default IconWeight.REGULAR
49
50
  */
50
51
  weight?: IconWeight;
51
- /**
52
- * Color role. `INHERIT` follows the parent's color (used inside Button).
53
- * @default IconVariant.PRIMARY
54
- */
55
- variant?: IconVariant;
56
52
  /** Raw color override that bypasses `variant`. Discouraged: prefer a `variant`. */
57
53
  hex?: Hex;
58
54
  /** Accessible name. Set it when the icon carries meaning on its own; when absent the icon is `aria-hidden`. */
@@ -73,6 +69,38 @@ export interface IconProps extends AriaAttributes {
73
69
  /** Inline style on the `<svg>`; only for setting CSS custom properties. */
74
70
  style?: CSSProperties;
75
71
  }
72
+ /** An icon colored by meaning (`variant`), or the default `PRIMARY`. */
73
+ interface IconVariantProps {
74
+ /**
75
+ * Color role. `INHERIT` follows the parent's color (used inside Button). Not with `color`.
76
+ * @default IconVariant.PRIMARY
77
+ */
78
+ variant?: IconVariant;
79
+ /**
80
+ * Categorical palette family (`"blue"`, `"yellow"`, …) or a status role as a string
81
+ * (`"success"`): the family's `text.<color>`. For a glyph that names a category the page
82
+ * already shows (a run status map, a source type); a status that is meaning takes `variant`.
83
+ * Not with `variant`.
84
+ */
85
+ color?: undefined;
86
+ }
87
+ /** An icon colored by category (`color`). */
88
+ interface IconColorProps {
89
+ /**
90
+ * Color role. `INHERIT` follows the parent's color (used inside Button). Not with `color`.
91
+ * @default IconVariant.PRIMARY
92
+ */
93
+ variant?: undefined;
94
+ /**
95
+ * Categorical palette family (`"blue"`, `"yellow"`, …) or a status role as a string
96
+ * (`"success"`): the family's `text.<color>`. For a glyph that names a category the page
97
+ * already shows (a run status map, a source type); a status that is meaning takes `variant`.
98
+ * Not with `variant`.
99
+ */
100
+ color: RoleColor;
101
+ }
102
+ /** Icon props. An icon with both `variant` and `color` is a type error. */
103
+ export type IconProps = IconBaseProps & (IconVariantProps | IconColorProps);
76
104
  /** Wraps a Phosphor icon so its color, weight and motion come from the DLS. Never render a Phosphor icon bare. */
77
105
  declare const Icon: import("react").ForwardRefExoticComponent<IconProps & import("react").RefAttributes<SVGSVGElement>>;
78
106
  export default Icon;