@astryxdesign/core 0.3.0-canary.2d2dba1 → 0.3.0-canary.5f9896c

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.
@@ -77,8 +77,12 @@ export interface ProgressBarProps extends BaseProps<HTMLDivElement> {
77
77
  /**
78
78
  * Target marks drawn on the track at fixed points in the same `0..max`
79
79
  * scale as `value` — e.g. a goal line. Marks stay visible whether progress
80
- * is below or past them. Each mark's required `label` names it for assistive
81
- * tech and is revealed via a `Tooltip` on hover/focus. Ignored when
80
+ * is below or past them, and take their color from what they sit on: a mark
81
+ * inside the filled area uses the fill variant's on-color (on-accent,
82
+ * on-warning, on-error, …), while a mark still out on the bare track uses
83
+ * `--color-text-primary` (`--color-text-secondary` on a disabled bar, which
84
+ * dims everything it draws). Each mark's required `label` names it for
85
+ * assistive tech and is revealed via a `Tooltip` on hover/focus. Ignored when
82
86
  * `isIndeterminate` is true.
83
87
  */
84
88
  marks?: ReadonlyArray<ProgressBarMark>;
@@ -119,8 +123,11 @@ export interface ProgressBarProps extends BaseProps<HTMLDivElement> {
119
123
  * ```
120
124
  *
121
125
  * A mark's height, width, and color are directly themeable via the
122
- * `progressbar-mark` target — e.g. a taller "goal flag" tick that overhangs the
123
- * bar (centered, so the overhang is symmetric):
126
+ * `progressbar-mark` target. The target reflects `data-placement`
127
+ * (`"fill"` when the mark sits inside the filled area, `"track"` when it is
128
+ * still out on the bare track) and `data-variant` (the fill's variant), so a
129
+ * theme can style the two cases separately — e.g. a taller "goal flag" tick
130
+ * that overhangs the bar (centered, so the overhang is symmetric):
124
131
  *
125
132
  * @example
126
133
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/ProgressBar/ProgressBar.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,SAAS,CAAC;AAUnD;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACjE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA+KD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAqB,EACrB,aAAqB,EACrB,gBAA0C,EAC1C,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BAqIlB;yBAtJe,WAAW"}
1
+ {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../src/ProgressBar/ProgressBar.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,SAAS,CAAC;AAUnD;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACjE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA2OD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAqB,EACrB,aAAqB,EACrB,gBAA0C,EAC1C,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BAmKlB;yBApLe,WAAW"}
@@ -84,6 +84,16 @@ const styles = {
84
84
  kyAemX: "x4hg4is",
85
85
  ko0y90: "xa4qsjk",
86
86
  $$css: true
87
+ },
88
+ mark: {
89
+ kVAEAm: "x10l6tqk",
90
+ k87sOh: "xwa60dl",
91
+ kzqmXN: "xfo62xy",
92
+ kZKoxP: "xdk7pt",
93
+ kI3sdo: "x1a2a7pz x17nn4n9",
94
+ kInvED: "x1wfwxd8 x7s97pk",
95
+ k3aq6I: "x11lhmoz xoffwj3",
96
+ $$css: true
87
97
  }
88
98
  };
89
99
  const variantStyles = {
@@ -112,6 +122,69 @@ const variantStyles = {
112
122
  $$css: true
113
123
  }
114
124
  };
125
+
126
+ // A mark sitting inside the filled area is drawn *on* the bar, so it takes the
127
+ // on-color that pairs with the fill's own variant color — the same pairing
128
+ // Badge uses for solid semantic backgrounds.
129
+ //
130
+ // `neutral` and `disabled` both fill with the muted `--color-text-disabled`
131
+ // gray, which carries no semantic weight and has no dedicated on-token, so
132
+ // they fall back to a plain foreground. They pick different ones: a `neutral`
133
+ // bar is live, so its mark keeps the full-contrast `--color-text-primary` a
134
+ // mark uses out on the track; a `disabled` bar is deliberately low-emphasis —
135
+ // its own label and value text drop to muted colors — so its mark steps down
136
+ // to `--color-text-secondary` rather than becoming the loudest thing on a
137
+ // grayed-out component.
138
+ const markOnFillStyles = {
139
+ accent: {
140
+ kWkggS: "x1azo05",
141
+ $$css: true
142
+ },
143
+ success: {
144
+ kWkggS: "x9mohwv",
145
+ $$css: true
146
+ },
147
+ warning: {
148
+ kWkggS: "xmgwp2l",
149
+ $$css: true
150
+ },
151
+ error: {
152
+ kWkggS: "xfba6wv",
153
+ $$css: true
154
+ },
155
+ neutral: {
156
+ kWkggS: "x19aspcf",
157
+ $$css: true
158
+ },
159
+ disabled: {
160
+ kWkggS: "xdomwnj",
161
+ $$css: true
162
+ }
163
+ };
164
+
165
+ // A mark out on the bare track is a foreground tick over the muted track
166
+ // background, so it takes `--color-text-primary`.
167
+ //
168
+ // The obvious candidate was `--color-border-emphasized` — the emphasized
169
+ // divider color `Divider`'s `strong` variant and `Slider`'s marks use — but
170
+ // divider tokens sit a step or two from the track on the same neutral ramp, so
171
+ // a mark drawn in one is at or near invisible: measured against each shipped
172
+ // theme's track it lands between 1.00:1 (theme-neutral, both modes, where the
173
+ // track is aliased to that very token) and 2.9:1, under the 3:1 WCAG 1.4.11
174
+ // non-text floor in 7 of 8 themes. `--color-text-secondary` still misses in
175
+ // two. `--color-text-primary` is the one foreground guaranteed to read against
176
+ // every surface a theme defines: 5.8:1 to 15.7:1 on the track across all
177
+ // themes and both modes.
178
+ const markOnTrackStyles = {
179
+ track: {
180
+ kWkggS: "x19aspcf",
181
+ $$css: true
182
+ },
183
+ trackDisabled: {
184
+ kWkggS: "xdomwnj",
185
+ $$css: true
186
+ }
187
+ };
115
188
  function defaultFormatValueLabel(value, max) {
116
189
  const pct = max > 0 ? Math.round(value / max * 100) : 0;
117
190
  return `${pct}%`;
@@ -143,8 +216,11 @@ function defaultFormatValueLabel(value, max) {
143
216
  * ```
144
217
  *
145
218
  * A mark's height, width, and color are directly themeable via the
146
- * `progressbar-mark` target — e.g. a taller "goal flag" tick that overhangs the
147
- * bar (centered, so the overhang is symmetric):
219
+ * `progressbar-mark` target. The target reflects `data-placement`
220
+ * (`"fill"` when the mark sits inside the filled area, `"track"` when it is
221
+ * still out on the bare track) and `data-variant` (the fill's variant), so a
222
+ * theme can style the two cases separately — e.g. a taller "goal flag" tick
223
+ * that overhangs the bar (centered, so the overhang is symmetric):
148
224
  *
149
225
  * @example
150
226
  * ```
@@ -190,13 +266,21 @@ export function ProgressBar({
190
266
  // Marks make no sense without a determinate value, so they are only drawn
191
267
  // in determinate mode. Non-finite mark values are dropped; the rest are
192
268
  // clamped to the track edges, matching the bar's own `clampedValue`.
269
+ //
270
+ // Each mark also records whether it lands on the filled part of the bar
271
+ // (`isOnFill`), which decides its color: a mark inside the fill reads against
272
+ // the variant color, one out on the bare track reads against the track. A
273
+ // mark exactly at the fill's leading edge counts as on the fill — it is the
274
+ // "reached the target" moment — except at zero progress, where there is no
275
+ // fill for it to sit on.
193
276
  const resolvedMarks = !isIndeterminate && marks ? marks.filter(mark => Number.isFinite(mark.value)).map(mark => {
194
277
  const clamped = Math.min(Math.max(0, mark.value), safeMax);
195
278
  const pct = safeMax > 0 ? clamped / safeMax * 100 : 0;
196
279
  return {
197
280
  value: mark.value,
198
281
  label: mark.label,
199
- pct
282
+ pct,
283
+ isOnFill: percentage > 0 && pct <= percentage
200
284
  };
201
285
  }) : [];
202
286
  return /*#__PURE__*/_jsxs("div", {
@@ -272,11 +356,17 @@ export function ProgressBar({
272
356
  // fallback shown while the lazy Tooltip chunk loads, so the tick is
273
357
  // always visible and the label attaches once ready. The list `key`
274
358
  // lives on the mapped <Suspense>, not here.
359
+ //
360
+ // `placement` is reflected as `data-placement` (and a class) so a
361
+ // theme can style the two cases separately on the
362
+ // `progressbar-mark` target; `variant` mirrors the fill's variant
363
+ // for the same reason.
275
364
  const markEl = /*#__PURE__*/_jsx("span", {
276
365
  tabIndex: 0,
277
- ...mergeProps(themeProps('progressbar-mark'), {
278
- className: "x10l6tqk xwa60dl xfo62xy xdk7pt x19aspcf x1a2a7pz x17nn4n9 x1wfwxd8 x7s97pk x11lhmoz xoffwj3"
279
- }),
366
+ ...mergeProps(themeProps('progressbar-mark', {
367
+ variant: fillVariant,
368
+ placement: mark.isOnFill ? 'fill' : 'track'
369
+ }), stylex.props(styles.mark, mark.isOnFill ? markOnFillStyles[fillVariant] : isDisabled ? markOnTrackStyles.trackDisabled : markOnTrackStyles.track)),
280
370
  style: {
281
371
  insetInlineStart: `${mark.pct}%`
282
372
  }
@@ -170,12 +170,12 @@ export declare function stack({ crossAlign, direction, gap, mainAlign, wrap, }:
170
170
  }> | Readonly<{
171
171
  readonly columnGap: stylex.StyleXClassNameFor<"columnGap", "24px">;
172
172
  readonly rowGap: stylex.StyleXClassNameFor<"rowGap", "24px">;
173
- }> | Readonly<{
174
- readonly columnGap: stylex.StyleXClassNameFor<"columnGap", "2px">;
175
- readonly rowGap: stylex.StyleXClassNameFor<"rowGap", "2px">;
176
173
  }> | Readonly<{
177
174
  readonly columnGap: stylex.StyleXClassNameFor<"columnGap", "4px">;
178
175
  readonly rowGap: stylex.StyleXClassNameFor<"rowGap", "4px">;
176
+ }> | Readonly<{
177
+ readonly columnGap: stylex.StyleXClassNameFor<"columnGap", "2px">;
178
+ readonly rowGap: stylex.StyleXClassNameFor<"rowGap", "2px">;
179
179
  }> | Readonly<{
180
180
  readonly columnGap: stylex.StyleXClassNameFor<"columnGap", "6px">;
181
181
  readonly rowGap: stylex.StyleXClassNameFor<"rowGap", "6px">;
package/dist/astryx.css CHANGED
@@ -576,6 +576,9 @@
576
576
  .x1q5y3ey:not(#\#):not(#\#):not(#\#){background-color:var(--color-icon-secondary)}
577
577
  .x17x4s8c:not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}
578
578
  .x1azo05:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-accent)}
579
+ .xfba6wv:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-error)}
580
+ .x9mohwv:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-success)}
581
+ .xmgwp2l:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-warning)}
579
582
  .x1lmrjuc:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-hover)}
580
583
  .xi89dp7:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-pressed)}
581
584
  .x1u4601x:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay)}
@@ -585,6 +588,7 @@
585
588
  .xzyc27v:not(#\#):not(#\#):not(#\#){background-color:var(--color-syntax-background)}
586
589
  .x16fr6go:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-disabled)}
587
590
  .x19aspcf:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-primary)}
591
+ .xdomwnj:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-secondary)}
588
592
  .xdsb6cv:not(#\#):not(#\#):not(#\#){background-color:var(--color-track)}
589
593
  .x24i8r5:not(#\#):not(#\#):not(#\#){background-color:var(--color-warning-muted)}
590
594
  .x1q8g9m5:not(#\#):not(#\#):not(#\#){background-color:var(--color-warning)}