@gtivr4/a1-design-system-react 0.3.1 → 0.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtivr4/a1-design-system-react",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "React components for the A1 token-driven design system.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -16,6 +16,7 @@ export function ChoiceGroup({
16
16
  size = "default",
17
17
  columns,
18
18
  multiple = false,
19
+ inlineIcon = false,
19
20
  required = false,
20
21
  name,
21
22
  options = [],
@@ -76,6 +77,7 @@ export function ChoiceGroup({
76
77
  "a1-choice-group",
77
78
  resolvedSize !== "default" && `a1-choice-group--${resolvedSize}`,
78
79
  multiple ? "a1-choice-group--multiple" : "a1-choice-group--single",
80
+ inlineIcon && "a1-choice-group--inline-icon",
79
81
  isFixedColumns && "a1-choice-group--fixed-columns",
80
82
  responsiveClass,
81
83
  error && "a1-choice-group--error",
@@ -317,6 +317,17 @@
317
317
  background-size: 80%;
318
318
  }
319
319
 
320
+ /* ─── Inline icon layout ────────────────────────────────────────────────────── */
321
+
322
+ .a1-choice-group--inline-icon .a1-choice-item {
323
+ flex-direction: row;
324
+ align-items: center;
325
+ }
326
+
327
+ .a1-choice-group--inline-icon .a1-choice-item__icon {
328
+ flex-shrink: 0;
329
+ }
330
+
320
331
  /* ─── Error state ───────────────────────────────────────────────────────────── */
321
332
 
322
333
  .a1-choice-group--error
@@ -22,8 +22,8 @@ import "./data-table.css";
22
22
  * }>
23
23
  * rows: Array<Record<string, any>>
24
24
  * getRowId?: (row: Record<string, any>, index: number) => string | number
25
- * density?: "auto" | "comfortable" | "default" | "compact"
26
- * "auto" (default) — switches between densities based on available width and column definitions
25
+ * size?: "comfortable" | "default" | "compact"
26
+ * omit (default) — switches between densities automatically based on available container width
27
27
  */
28
28
 
29
29
  // Estimated minimum content width per column type at a "neutral" padding level
@@ -193,7 +193,7 @@ function SelectionCheckbox({ checked, indeterminate = false, label, onChange })
193
193
  export function DataTable({
194
194
  columns = [],
195
195
  rows = [],
196
- density = "default",
196
+ size,
197
197
  zebra = false,
198
198
  scrollable = false,
199
199
  caption,
@@ -238,14 +238,14 @@ export function DataTable({
238
238
  const [internalSearchColumn, setInternalSearchColumn] = useState(defaultSearchColumn);
239
239
  const [internalSelectedRowIds, setInternalSelectedRowIds] = useState(() => normalizeRowIds(defaultSelectedRowIds));
240
240
 
241
- const isAuto = density === "auto";
241
+ const isAuto = size === undefined;
242
242
  const isSortControlled = sort !== undefined;
243
243
  const isPageControlled = page !== undefined;
244
244
  const isFilterControlled = filterValue !== undefined;
245
245
  const isSearchControlled = searchValue !== undefined;
246
246
  const isSearchColumnControlled = searchColumn !== undefined;
247
247
  const isSelectionControlled = selectedRowIds !== undefined;
248
- const activeDensity = isAuto ? autoDensity : density;
248
+ const activeDensity = isAuto ? autoDensity : size;
249
249
  const activeSort = isSortControlled ? normalizeSort(sort) : internalSort;
250
250
  const activePage = isPageControlled ? page : internalPage;
251
251
  const activeFilterValue = isFilterControlled
@@ -6,7 +6,7 @@ import { FieldsetContext } from "../fieldset/FieldsetContext.js";
6
6
  import "./field.css";
7
7
 
8
8
  const SIZES = ["comfortable", "default", "compact"];
9
- const LABEL_POSITIONS = ["above", "side"];
9
+ const LABEL_POSITIONS = ["above", "before"];
10
10
 
11
11
  export const SelectField = forwardRef(function SelectField({
12
12
  label,
@@ -5,7 +5,7 @@ import { FieldsetContext } from "../fieldset/FieldsetContext.js";
5
5
  import "./field.css";
6
6
 
7
7
  const SIZES = ["comfortable", "default", "compact"];
8
- const LABEL_POSITIONS = ["above", "side"];
8
+ const LABEL_POSITIONS = ["above", "before"];
9
9
 
10
10
  export const TextField = forwardRef(function TextField({
11
11
  label,
@@ -6,7 +6,7 @@ import "./field.css";
6
6
  import "./textarea-field.css";
7
7
 
8
8
  const SIZES = ["comfortable", "default", "compact"];
9
- const LABEL_POSITIONS = ["above", "side"];
9
+ const LABEL_POSITIONS = ["above", "before"];
10
10
  const ROW_SIZES = { sm: 2, md: 4, lg: 8, xl: 12 };
11
11
 
12
12
  function resolveRows(rows) {
@@ -336,9 +336,9 @@
336
336
  color: var(--semantic-color-status-error-background);
337
337
  }
338
338
 
339
- /* ─── Side label layout ────────────────────────────────────────────────────── */
339
+ /* ─── Before label layout ───────────────────────────────────────────────────── */
340
340
 
341
- .a1-field--label-side {
341
+ .a1-field--label-before {
342
342
  display: grid;
343
343
  grid-template-columns: var(--a1-field-side-label-width) 1fr;
344
344
  column-gap: var(--base-spacing-16);
@@ -346,12 +346,12 @@
346
346
  align-items: start;
347
347
  }
348
348
 
349
- .a1-field--label-side .a1-field__label {
349
+ .a1-field--label-before .a1-field__label {
350
350
  padding-top: calc((var(--a1-field-height) - 1lh) / 2);
351
351
  padding-bottom: 0;
352
352
  }
353
353
 
354
- .a1-field--label-side .a1-field__message {
354
+ .a1-field--label-before .a1-field__message {
355
355
  grid-column: 1;
356
356
  grid-row: 2;
357
357
  /* Fine-tuned margin: overrides the base margin-top added for the above-label
@@ -359,22 +359,22 @@
359
359
  margin-top: calc((var(--a1-field-label-size) * 1.5 - var(--a1-field-height)) / 2 + var(--base-spacing-2));
360
360
  }
361
361
 
362
- /* ─── Side label → stacked on xs/sm ───────────────────────────────────────── */
362
+ /* ─── Before label → stacked on xs/sm ─────────────────────────────────────── */
363
363
 
364
364
  @media (--bp-sm-down) {
365
- .a1-field--label-side {
365
+ .a1-field--label-before {
366
366
  display: flex;
367
367
  flex-direction: column;
368
368
  gap: var(--a1-field-gap); /* restore: grid overrode row-gap to base-spacing-4 */
369
369
  align-items: stretch; /* restore: grid set align-items: start */
370
370
  }
371
371
 
372
- .a1-field--label-side .a1-field__label {
372
+ .a1-field--label-before .a1-field__label {
373
373
  padding-top: 0;
374
374
  padding-bottom: var(--a1-field-gap);
375
375
  }
376
376
 
377
- .a1-field--label-side .a1-field__message {
377
+ .a1-field--label-before .a1-field__message {
378
378
  margin-top: var(--a1-field-gap);
379
379
  }
380
380
  }
@@ -5,9 +5,9 @@ import "./field-row.css";
5
5
  export function FieldRow({ children, className = "", ...props }) {
6
6
  const ctx = useContext(FieldsetContext);
7
7
 
8
- // Side-label fields already use an internal two-column grid;
8
+ // Before-label fields already use an internal two-column grid;
9
9
  // stacking the row prevents layout conflicts.
10
- const stacked = ctx?.labelPosition === "side";
10
+ const stacked = ctx?.labelPosition === "before";
11
11
 
12
12
  const classes = [
13
13
  "a1-field-row",
@@ -2,7 +2,7 @@ import { FieldsetContext } from "./FieldsetContext.js";
2
2
  import "./fieldset.css";
3
3
 
4
4
  const SIZES = ["comfortable", "default", "compact"];
5
- const LABEL_POSITIONS = ["above", "side"];
5
+ const LABEL_POSITIONS = ["above", "before"];
6
6
 
7
7
  export function Fieldset({
8
8
  legend,
@@ -2,6 +2,7 @@ import "./grid.css";
2
2
 
3
3
  const SPACING_KEYS = [1, 2, 4, 6, 8, 12, 16, 20, 24, 32, 40, 64, 96, 128];
4
4
  const gapSizes = {
5
+ xs: "var(--base-spacing-4)",
5
6
  sm: "var(--base-spacing-8)",
6
7
  md: "var(--base-spacing-16)",
7
8
  lg: "var(--base-spacing-24)",
@@ -7,7 +7,7 @@ const margins = ["sm", "md", "lg"];
7
7
  const levels = ["h1", "h2", "h3", "h4", "h5", "h6"];
8
8
  const breakpoints = ["xs", "sm", "md", "lg", "xl"];
9
9
  const textWraps = ["balance"];
10
- const aligns = ["left", "center", "right"];
10
+ const aligns = ["left", "center", "right", "start", "end"];
11
11
 
12
12
  const levelDefaults = { h1: "xl", h2: "lg", h3: "md", h4: "sm", h5: "xs", h6: "xs" };
13
13
 
@@ -88,6 +88,8 @@
88
88
  .a1-heading--align-left { text-align: start; }
89
89
  .a1-heading--align-center { text-align: center; }
90
90
  .a1-heading--align-right { text-align: end; }
91
+ .a1-heading--align-start { text-align: start; }
92
+ .a1-heading--align-end { text-align: end; }
91
93
 
92
94
  /* Expressive marks */
93
95
  .a1-heading-mark {
@@ -1,6 +1,6 @@
1
1
  import "./notification.css";
2
2
 
3
- const variants = ["default", "error", "success", "warn", "info"];
3
+ const statuses = ["neutral", "error", "success", "warn", "info"];
4
4
  const positions = ["top-right", "top-left", "bottom-right", "bottom-left"];
5
5
 
6
6
  function formatCount(n, max) {
@@ -15,11 +15,11 @@ export function Notification({
15
15
  count,
16
16
  label,
17
17
  dot = false,
18
- variant = "default",
18
+ status = "neutral",
19
19
  position = "top-right",
20
20
  max = 99,
21
21
  }) {
22
- const resolvedVariant = variants.includes(variant) ? variant : "default";
22
+ const resolvedStatus = statuses.includes(status) ? status : "neutral";
23
23
  const resolvedPosition = positions.includes(position) ? position : "top-right";
24
24
 
25
25
  const isDot = dot || (count === undefined && label === undefined);
@@ -35,7 +35,7 @@ export function Notification({
35
35
 
36
36
  const classes = [
37
37
  "a1-notification",
38
- `a1-notification--${resolvedVariant}`,
38
+ `a1-notification--${resolvedStatus}`,
39
39
  `a1-notification--${resolvedPosition}`,
40
40
  isDot && "a1-notification--dot",
41
41
  ]
@@ -43,7 +43,7 @@
43
43
 
44
44
  /* ── Variants ───────────────────────────────────────────────────────────── */
45
45
 
46
- .a1-notification--default {
46
+ .a1-notification--neutral {
47
47
  --a1-notification-background: var(--base-color-neutral-600);
48
48
  --a1-notification-foreground: var(--base-color-neutral-0);
49
49
  }
@@ -4,7 +4,7 @@ const sizes = ["xs", "sm", "md", "lg", "xl"];
4
4
  const colors = ["default", "muted"];
5
5
  const breakpoints = ["xs", "sm", "md", "lg", "xl"];
6
6
  const textWraps = ["balance"];
7
- const aligns = ["left", "center", "right"];
7
+ const aligns = ["left", "center", "right", "start", "end"];
8
8
 
9
9
  function isResponsiveSize(size) {
10
10
  return size && typeof size === "object" && !Array.isArray(size);
@@ -46,6 +46,8 @@
46
46
  .a1-paragraph--align-left { text-align: start; }
47
47
  .a1-paragraph--align-center { text-align: center; }
48
48
  .a1-paragraph--align-right { text-align: end; }
49
+ .a1-paragraph--align-start { text-align: start; }
50
+ .a1-paragraph--align-end { text-align: end; }
49
51
 
50
52
  .a1-paragraph + .a1-paragraph,
51
53
  .a1-paragraph + .a1-heading {
@@ -31,7 +31,7 @@ export function Section({
31
31
  inverse = false,
32
32
  contentWidth,
33
33
  height,
34
- alignment,
34
+ align,
35
35
  className = "",
36
36
  children,
37
37
  ...props
@@ -72,14 +72,14 @@ export function Section({
72
72
  classes.push(`a1-section--height-${height}`);
73
73
  }
74
74
 
75
- if (typeof alignment === "string") {
76
- if (VALID_ALIGNMENTS.includes(alignment)) {
77
- classes.push(`a1-section--align-${alignment}`);
75
+ if (typeof align === "string") {
76
+ if (VALID_ALIGNMENTS.includes(align)) {
77
+ classes.push(`a1-section--align-${align}`);
78
78
  }
79
- } else if (alignment && typeof alignment === "object") {
80
- for (const [bp, align] of Object.entries(alignment)) {
81
- if (VALID_ALIGNMENTS.includes(align)) {
82
- classes.push(`a1-section--${bp}-align-${align}`);
79
+ } else if (align && typeof align === "object") {
80
+ for (const [bp, alignVal] of Object.entries(align)) {
81
+ if (VALID_ALIGNMENTS.includes(alignVal)) {
82
+ classes.push(`a1-section--${bp}-align-${alignVal}`);
83
83
  }
84
84
  }
85
85
  }
@@ -111,7 +111,7 @@
111
111
  /* ── Alignment ─────────────────────────────────────────────────────────────── */
112
112
  /*
113
113
  * Aligns direct children as layout items.
114
- * Use the object prop for responsive changes: alignment={{ xs: "center", lg: "left" }}
114
+ * Use the object prop for responsive changes: align={{ xs: "center", lg: "left" }}
115
115
  */
116
116
 
117
117
  .a1-section[class*="-align-"] {
@@ -206,10 +206,11 @@
206
206
 
207
207
  /* ── Padding — static (with built-in responsive scaling) ───────────────────── */
208
208
  /*
209
- * Three tiers scale across three breakpoints:
209
+ * Four tiers scale across three breakpoints:
210
210
  * lg 96/64 → 96/40 at ≤1024 → 64/24 at ≤640
211
211
  * md 64/40 → 40/24 at ≤1024 → 32/16 at ≤640
212
212
  * sm 32/24 → 24/16 at ≤1024 → 16/12 at ≤640
213
+ * xs 16/16 → 12/12 at ≤1024 → 8/8 at ≤640
213
214
  * Block (top/bottom) / Inline (left/right)
214
215
  */
215
216
 
@@ -42,7 +42,6 @@
42
42
  .a1-segment[aria-checked="true"] {
43
43
  background: var(--semantic-color-surface-page);
44
44
  color: var(--semantic-color-text-default);
45
- font-weight: var(--component-segmented-font-weight-active);
46
45
  box-shadow: var(--semantic-shadow-xs);
47
46
  }
48
47
 
@@ -0,0 +1,92 @@
1
+ import { useId, useState, useEffect } from "react";
2
+ import { Button } from "../button/Button.jsx";
3
+ import { useLabel } from "../labels/Labels.jsx";
4
+ import "./status-bar.css";
5
+
6
+ const SIZES = ["sm", "md", "lg"];
7
+ const POSITIONS = ["above", "below", "before", "after"];
8
+
9
+ export function StatusBar({
10
+ value = 0,
11
+ max = 100,
12
+ label,
13
+ labelPosition = "above",
14
+ size = "md",
15
+ indeterminate = false,
16
+ className = "",
17
+ ...props
18
+ }) {
19
+ const labelId = useId();
20
+
21
+ const pauseLabel = useLabel("statusBar.pause", "Pause");
22
+ const playLabel = useLabel("statusBar.play", "Play");
23
+
24
+ const [paused, setPaused] = useState(false);
25
+ const [showPause, setShowPause] = useState(false);
26
+
27
+ useEffect(() => {
28
+ if (!indeterminate) {
29
+ setShowPause(false);
30
+ setPaused(false);
31
+ return;
32
+ }
33
+ const t = setTimeout(() => setShowPause(true), 3000);
34
+ return () => clearTimeout(t);
35
+ }, [indeterminate]);
36
+
37
+ const resolvedSize = SIZES.includes(size) ? size : "md";
38
+ const resolvedPosition = POSITIONS.includes(labelPosition) ? labelPosition : "above";
39
+
40
+ const pct = Math.min(100, Math.max(0, max > 0 ? (value / max) * 100 : 0));
41
+ const isLabelFirst = resolvedPosition === "above" || resolvedPosition === "before";
42
+
43
+ const classes = [
44
+ "a1-status-bar",
45
+ resolvedSize !== "md" && `a1-status-bar--${resolvedSize}`,
46
+ `a1-status-bar--${resolvedPosition}`,
47
+ indeterminate && "a1-status-bar--indeterminate",
48
+ indeterminate && paused && "a1-status-bar--paused",
49
+ className,
50
+ ].filter(Boolean).join(" ");
51
+
52
+ const labelEl = label ? (
53
+ <span id={labelId} className="a1-status-bar__label">{label}</span>
54
+ ) : null;
55
+
56
+ return (
57
+ <div className={classes}>
58
+ {isLabelFirst && labelEl}
59
+ <div className="a1-status-bar__bar-row">
60
+ <div
61
+ className="a1-status-bar__track"
62
+ role="progressbar"
63
+ aria-valuenow={indeterminate ? undefined : value}
64
+ aria-valuemin={0}
65
+ aria-valuemax={max}
66
+ aria-labelledby={label ? labelId : undefined}
67
+ {...props}
68
+ >
69
+ <div
70
+ className={[
71
+ "a1-status-bar__fill",
72
+ indeterminate && "a1-status-bar__fill--indeterminate",
73
+ ].filter(Boolean).join(" ")}
74
+ style={indeterminate ? undefined : { inlineSize: `${pct}%` }}
75
+ />
76
+ </div>
77
+ {showPause && (
78
+ <Button
79
+ size="sm"
80
+ variant="secondary"
81
+ icon={paused ? "play_arrow" : "pause"}
82
+ className="a1-status-bar__pause"
83
+ onClick={() => setPaused(p => !p)}
84
+ >
85
+ {paused ? playLabel : pauseLabel}
86
+ </Button>
87
+ )}
88
+ </div>
89
+ {!isLabelFirst && labelEl}
90
+ </div>
91
+ );
92
+ }
@@ -0,0 +1,146 @@
1
+ /* ─── StatusBar ─────────────────────────────────────────────────────────────── */
2
+
3
+ .a1-status-bar {
4
+ --a1-sb-height: var(--component-status-bar-md-height);
5
+ --a1-sb-track-bg: var(--component-status-bar-track-background);
6
+ --a1-sb-fill-bg: var(--component-status-bar-fill-background);
7
+ --a1-sb-radius: var(--component-status-bar-border-radius);
8
+ --a1-sb-border-width: var(--component-status-bar-border-width);
9
+ --a1-sb-border-color: var(--component-status-bar-border-color);
10
+ --a1-sb-label-gap: var(--component-status-bar-label-gap);
11
+
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: var(--a1-sb-label-gap);
15
+ inline-size: 100%;
16
+ }
17
+
18
+ /* ─── Sizes ─────────────────────────────────────────────────────────────────── */
19
+
20
+ .a1-status-bar--sm { --a1-sb-height: var(--component-status-bar-sm-height); }
21
+ .a1-status-bar--lg { --a1-sb-height: var(--component-status-bar-lg-height); }
22
+
23
+ /* ─── Label positions ───────────────────────────────────────────────────────── */
24
+
25
+ /* below: column layout, DOM order is [bar-row, label] so no CSS change needed */
26
+
27
+ .a1-status-bar--before,
28
+ .a1-status-bar--after {
29
+ flex-direction: row;
30
+ align-items: center;
31
+ }
32
+
33
+ .a1-status-bar--before .a1-status-bar__bar-row,
34
+ .a1-status-bar--after .a1-status-bar__bar-row {
35
+ flex: 1;
36
+ min-inline-size: 0;
37
+ }
38
+
39
+ .a1-status-bar--before .a1-status-bar__label,
40
+ .a1-status-bar--after .a1-status-bar__label {
41
+ flex-shrink: 0;
42
+ }
43
+
44
+ /* ─── Bar row (track + optional pause button) ───────────────────────────────── */
45
+
46
+ .a1-status-bar__bar-row {
47
+ display: flex;
48
+ flex-direction: row;
49
+ align-items: center;
50
+ gap: var(--base-spacing-8);
51
+ }
52
+
53
+ .a1-status-bar__bar-row .a1-status-bar__track {
54
+ flex: 1;
55
+ min-inline-size: 0;
56
+ inline-size: auto;
57
+ }
58
+
59
+ /* ─── Label ─────────────────────────────────────────────────────────────────── */
60
+
61
+ .a1-status-bar__label {
62
+ display: block;
63
+ font-family: var(--component-paragraph-font-family);
64
+ font-size: var(--semantic-font-size-body-sm);
65
+ font-weight: var(--base-font-weight-regular);
66
+ color: var(--semantic-color-text-default);
67
+ line-height: var(--semantic-font-line-height-body);
68
+ }
69
+
70
+ /* ─── Track ─────────────────────────────────────────────────────────────────── */
71
+
72
+ .a1-status-bar__track {
73
+ position: relative;
74
+ display: flex; /* flex direction inherits writing mode — fills from inline-start in RTL */
75
+ block-size: var(--a1-sb-height);
76
+ inline-size: 100%;
77
+ background-color: var(--a1-sb-track-bg);
78
+ border-radius: var(--a1-sb-radius);
79
+ border: var(--a1-sb-border-width) solid var(--a1-sb-border-color);
80
+ overflow: hidden;
81
+ }
82
+
83
+ /* ─── Fill ──────────────────────────────────────────────────────────────────── */
84
+
85
+ /* Flex child — grows from inline-start, which in RTL means it grows from the right */
86
+ .a1-status-bar__fill {
87
+ flex-shrink: 0;
88
+ block-size: 100%;
89
+ inline-size: 0;
90
+ background-color: var(--a1-sb-fill-bg);
91
+ border-radius: inherit;
92
+ transition: inline-size var(--semantic-motion-duration-normal) var(--semantic-motion-easing-standard);
93
+ }
94
+
95
+ /* ─── Indeterminate (loading) ───────────────────────────────────────────────── */
96
+
97
+ /* Absolute positioning takes the fill out of flex flow for the sweep animation */
98
+ .a1-status-bar__fill--indeterminate {
99
+ position: absolute;
100
+ inset-block: 0;
101
+ left: 0;
102
+ inline-size: 35%;
103
+ animation: a1-sb-indeterminate var(--component-status-bar-indeterminate-duration) ease-in-out infinite;
104
+ }
105
+
106
+ /* RTL: anchor to the physical right and reverse the sweep direction */
107
+ [dir="rtl"] .a1-status-bar__fill--indeterminate {
108
+ left: auto;
109
+ right: 0;
110
+ animation-direction: reverse;
111
+ }
112
+
113
+ .a1-status-bar--paused .a1-status-bar__fill--indeterminate {
114
+ animation-play-state: paused;
115
+ }
116
+
117
+ @keyframes a1-sb-indeterminate {
118
+ 0% { transform: translateX(-115%); }
119
+ 100% { transform: translateX(300%); }
120
+ }
121
+
122
+ @media (prefers-reduced-motion: reduce) {
123
+ .a1-status-bar__fill--indeterminate {
124
+ animation: none;
125
+ inline-size: 100%;
126
+ opacity: 0.4;
127
+ }
128
+ }
129
+
130
+ /* ─── Pause / play button ────────────────────────────────────────────────────── */
131
+
132
+ .a1-status-bar__pause {
133
+ flex-shrink: 0;
134
+ animation: a1-sb-pause-appear var(--semantic-motion-duration-normal) var(--semantic-motion-easing-enter);
135
+ }
136
+
137
+ @keyframes a1-sb-pause-appear {
138
+ from { opacity: 0; transform: scale(0.75); }
139
+ to { opacity: 1; transform: scale(1); }
140
+ }
141
+
142
+ @media (prefers-reduced-motion: reduce) {
143
+ .a1-status-bar__pause {
144
+ animation: none;
145
+ }
146
+ }
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ export { Blockquote } from "./components/blockquote/Blockquote.jsx";
5
5
  export { Breadcrumb } from "./components/breadcrumb/Breadcrumb.jsx";
6
6
  export { Notification } from "./components/notification/Notification.jsx";
7
7
  export { Snackbar } from "./components/snackbar/Snackbar.jsx";
8
+ export { StatusBar } from "./components/status-bar/StatusBar.jsx";
8
9
  export { Bleed } from "./components/bleed/Bleed.jsx";
9
10
  export { IconButton } from "./components/icon-button/IconButton.jsx";
10
11
  export { Button } from "./components/button/Button.jsx";export { ButtonContainer } from "./components/button-container/ButtonContainer.jsx";
package/src/themes.css CHANGED
@@ -52,6 +52,7 @@ html.a1-theme-accessible {
52
52
  --component-side-nav-border-width: 2px;
53
53
  --component-tab-border-width: 2px;
54
54
  --component-top-header-border-width: 2px;
55
+ --component-status-bar-border-width: 2px;
55
56
  --component-button-font-family: var(--theme-a1-accessible-font-family-body);
56
57
  --component-paragraph-font-family: var(--theme-a1-accessible-font-family-body);
57
58
  --component-heading-font-family-heading: var(--theme-a1-accessible-font-family-heading);
package/src/tokens.css CHANGED
@@ -646,6 +646,16 @@
646
646
  --component-side-nav-item-font-line-height: 1.5;
647
647
  --component-side-nav-item-active-font-weight: 500;
648
648
  --component-side-nav-item-chevron-size: 1.125rem;
649
+ --component-status-bar-sm-height: 0.25rem;
650
+ --component-status-bar-md-height: 0.5rem;
651
+ --component-status-bar-lg-height: 0.75rem;
652
+ --component-status-bar-border-radius: 624.9375rem;
653
+ --component-status-bar-border-width: 0;
654
+ --component-status-bar-border-color: #a6b2c4;
655
+ --component-status-bar-track-background: #e1e8f3;
656
+ --component-status-bar-fill-background: #7c3aed;
657
+ --component-status-bar-label-gap: 0.5rem;
658
+ --component-status-bar-indeterminate-duration: 1400ms;
649
659
  --component-switch-track-width: 2.5rem;
650
660
  --component-switch-track-height: 1.375rem;
651
661
  --component-switch-thumb-size: 1rem;