@autoguru/overdrive 4.62.0 → 4.64.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.
Files changed (87) hide show
  1. package/dist/components/Alert/Alert.d.ts +4 -1
  2. package/dist/components/Alert/Alert.d.ts.map +1 -1
  3. package/dist/components/Alert/Alert.js +11 -5
  4. package/dist/components/Button/Button.css.d.ts +13 -1
  5. package/dist/components/Button/Button.css.d.ts.map +1 -1
  6. package/dist/components/Button/Button.css.js +35 -0
  7. package/dist/components/Button/Button.d.ts.map +1 -1
  8. package/dist/components/Button/Button.js +5 -1
  9. package/dist/components/CheckBox/CheckBox.css.d.ts.map +1 -1
  10. package/dist/components/CheckBox/CheckBox.css.js +5 -2
  11. package/dist/components/FilterChip/FilterChip.css.d.ts +64 -0
  12. package/dist/components/FilterChip/FilterChip.css.d.ts.map +1 -0
  13. package/dist/components/FilterChip/FilterChip.css.js +243 -0
  14. package/dist/components/FilterChip/FilterChip.d.ts +112 -0
  15. package/dist/components/FilterChip/FilterChip.d.ts.map +1 -0
  16. package/dist/components/FilterChip/FilterChip.js +152 -0
  17. package/dist/components/FilterChip/default.d.ts +2 -0
  18. package/dist/components/FilterChip/default.d.ts.map +1 -0
  19. package/dist/components/FilterChip/default.js +1 -0
  20. package/dist/components/FilterChip/index.d.ts +3 -0
  21. package/dist/components/FilterChip/index.d.ts.map +1 -0
  22. package/dist/components/FilterChip/index.js +1 -0
  23. package/dist/components/MinimalModal/MinimalModal.css.js +4 -4
  24. package/dist/components/OverdriveProvider/OverdriveProvider.d.ts +13 -1
  25. package/dist/components/OverdriveProvider/OverdriveProvider.d.ts.map +1 -1
  26. package/dist/components/OverdriveProvider/OverdriveProvider.js +6 -1
  27. package/dist/components/OverdriveProvider/useColorOverrides.d.ts +3 -2
  28. package/dist/components/OverdriveProvider/useColorOverrides.d.ts.map +1 -1
  29. package/dist/components/OverdriveProvider/useColorOverrides.js +158 -22
  30. package/dist/components/OverdriveProvider/useColorOverrides.spec.d.ts +2 -0
  31. package/dist/components/OverdriveProvider/useColorOverrides.spec.d.ts.map +1 -0
  32. package/dist/components/OverdriveProvider/useColorOverrides.spec.js +226 -0
  33. package/dist/components/Radio/Radio.css.d.ts.map +1 -1
  34. package/dist/components/Radio/Radio.css.js +3 -2
  35. package/dist/components/StandardModal/StandardModal.css.js +2 -2
  36. package/dist/components/StandardModal/StandardModal.js +3 -2
  37. package/dist/components/Switch/Switch.css.d.ts.map +1 -1
  38. package/dist/components/Switch/Switch.css.js +3 -1
  39. package/dist/components/Tabs/Tab.css.d.ts +40 -0
  40. package/dist/components/Tabs/Tab.css.d.ts.map +1 -1
  41. package/dist/components/Tabs/Tab.css.js +69 -8
  42. package/dist/components/Tabs/Tab.js +1 -1
  43. package/dist/components/Tabs/TabList.css.d.ts +1 -0
  44. package/dist/components/Tabs/TabList.css.d.ts.map +1 -1
  45. package/dist/components/Tabs/TabList.css.js +2 -1
  46. package/dist/components/Tabs/TabList.d.ts.map +1 -1
  47. package/dist/components/Tabs/TabList.js +5 -2
  48. package/dist/components/Tabs/TabPane.js +2 -1
  49. package/dist/components/Tabs/TabPanes.js +2 -1
  50. package/dist/components/Tabs/Tabs.d.ts +2 -0
  51. package/dist/components/Tabs/Tabs.d.ts.map +1 -1
  52. package/dist/components/Tabs/Tabs.js +4 -1
  53. package/dist/components/Tabs/index.d.ts +4 -3
  54. package/dist/components/Tabs/index.d.ts.map +1 -1
  55. package/dist/components/index.d.ts +2 -1
  56. package/dist/components/index.d.ts.map +1 -1
  57. package/dist/components/index.js +1 -0
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +1 -1
  61. package/dist/styles/intentColorset.css.d.ts +3 -3
  62. package/dist/styles/sprinkles.css.d.ts +12 -12
  63. package/dist/styles/typography.css.d.ts +1 -1
  64. package/dist/themes/base/contrastGuide.spec.js +11 -2
  65. package/dist/themes/base/index.d.ts +8 -0
  66. package/dist/themes/base/index.d.ts.map +1 -1
  67. package/dist/themes/base/tokens.d.ts +17 -0
  68. package/dist/themes/base/tokens.d.ts.map +1 -1
  69. package/dist/themes/base/tokens.js +18 -0
  70. package/dist/themes/flat_red/index.d.ts +13 -0
  71. package/dist/themes/flat_red/index.d.ts.map +1 -1
  72. package/dist/themes/flat_red/tokens.d.ts +9 -0
  73. package/dist/themes/flat_red/tokens.d.ts.map +1 -1
  74. package/dist/themes/flat_red/tokens.js +10 -0
  75. package/dist/themes/index.d.ts +8 -0
  76. package/dist/themes/index.d.ts.map +1 -1
  77. package/dist/themes/makeTheme.d.ts +4 -0
  78. package/dist/themes/makeTheme.d.ts.map +1 -1
  79. package/dist/themes/neutral/index.d.ts +13 -0
  80. package/dist/themes/neutral/index.d.ts.map +1 -1
  81. package/dist/themes/neutral/tokens.d.ts +9 -0
  82. package/dist/themes/neutral/tokens.d.ts.map +1 -1
  83. package/dist/themes/neutral/tokens.js +11 -0
  84. package/dist/themes/theme.css.d.ts +4 -0
  85. package/dist/themes/theme.css.d.ts.map +1 -1
  86. package/dist/themes/theme.css.js +16 -0
  87. package/package.json +1 -1
@@ -0,0 +1,226 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import { renderHook } from '@testing-library/react';
5
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
6
+ import { colourMap } from "../../themes/base/colours.js";
7
+ import { tokens as baseTokens } from "../../themes/base/tokens.js";
8
+ import { getColourLuminance, getRGBValues } from "../../themes/helpers.js";
9
+ import { useColorOverrides } from "./useColorOverrides.js";
10
+ const BRAND = '#6d39a8'; // Merchant Finder's purple — dark, wants white on it
11
+ const BRIGHT = '#e5bc01'; // a bright yellow — wants dark ink on it
12
+
13
+ const vars = (overrides, tokens = baseTokens) => renderHook(() => useColorOverrides(overrides, tokens)).result.current;
14
+ const luminance = colour => getColourLuminance(getRGBValues(colour));
15
+ describe('useColorOverrides', () => {
16
+ beforeEach(() => {
17
+ vi.restoreAllMocks();
18
+ });
19
+ it('generates nothing when no overrides are supplied', () => {
20
+ expect(vars()).toEqual({});
21
+ });
22
+ describe('back-compat with the existing five keys', () => {
23
+ it('writes the legacy primary intent vars it always has', () => {
24
+ const result = vars({
25
+ primaryBackground: BRAND,
26
+ primaryForeground: '#ffffff',
27
+ primaryBorder: '#000000'
28
+ });
29
+ expect(result['--od-colours-intent-primary-background-standard']).toBe(BRAND);
30
+ expect(result['--od-colours-intent-primary-foreground']).toBe('#ffffff');
31
+ expect(result['--od-colours-intent-primary-border']).toBe('#000000');
32
+ expect(result['--od-typography-colour-primary']).toBe(BRAND);
33
+ });
34
+ it('honours explicitly supplied mild and strong values', () => {
35
+ const result = vars({
36
+ primaryBackground: BRAND,
37
+ primaryBackgroundMild: '#eeeeee',
38
+ primaryBackgroundStrong: '#111111'
39
+ });
40
+ expect(result['--od-colours-intent-primary-background-mild']).toBe('#eeeeee');
41
+ expect(result['--od-colours-intent-primary-background-strong']).toBe('#111111');
42
+ });
43
+ it('derives mild lighter and strong darker than the brand, not identical', () => {
44
+ const result = vars({
45
+ primaryBackground: BRAND
46
+ });
47
+ const mild = result['--od-colours-intent-primary-background-mild'];
48
+ const strong = result['--od-colours-intent-primary-background-strong'];
49
+
50
+ // regression guard: these were derived with identical arguments and
51
+ // both resolved to the same lightened colour, so a branded button's
52
+ // hover and active states were indistinguishable from resting
53
+ expect(mild).not.toBe(strong);
54
+ expect(luminance(mild)).toBeGreaterThan(luminance(BRAND));
55
+ expect(luminance(strong)).toBeLessThan(luminance(BRAND));
56
+ });
57
+ });
58
+ describe('brand accent', () => {
59
+ it('writes the brand pair from the supplied background', () => {
60
+ const result = vars({
61
+ primaryBackground: BRAND
62
+ });
63
+ expect(result['--od-color-brand-solid']).toBe(BRAND);
64
+ });
65
+ it('picks white as on-brand content for a dark brand', () => {
66
+ const result = vars({
67
+ primaryBackground: BRAND
68
+ });
69
+ expect(result['--od-color-brand-on-solid']).toBe(colourMap.white);
70
+ });
71
+ it('picks dark ink as on-brand content for a bright brand', () => {
72
+ const result = vars({
73
+ primaryBackground: BRIGHT
74
+ });
75
+ expect(result['--od-color-brand-on-solid']).toBe(colourMap.gray['900']);
76
+ });
77
+ it('prefers an explicit primaryForeground over the derived value', () => {
78
+ const result = vars({
79
+ primaryBackground: BRIGHT,
80
+ primaryForeground: '#123456'
81
+ });
82
+ expect(result['--od-color-brand-on-solid']).toBe('#123456');
83
+ });
84
+ it('ignores a primaryForeground that would be illegible on the brand', () => {
85
+ // a tenant pairing a light brand with white button text: taken
86
+ // verbatim this puts a white tick on a light checkbox, which is
87
+ // worse than the fixed dark ink these controls had before they
88
+ // followed the brand at all
89
+ const result = vars({
90
+ primaryBackground: '#ff6d00',
91
+ primaryForeground: '#ffffff'
92
+ });
93
+ expect(result['--od-color-brand-on-solid']).toBe(colourMap.gray['900']);
94
+ // the button label still honours what the tenant asked for — that
95
+ // is their stated brand pairing, and it was already the behaviour
96
+ expect(result['--od-colours-intent-primary-foreground']).toBe('#ffffff');
97
+ });
98
+ it('derives the button label too when no primaryForeground is given', () => {
99
+ // otherwise a light brand keeps the theme's white label and the
100
+ // solid button is unreadable, which the prop docs promise against
101
+ const result = vars({
102
+ primaryBackground: BRIGHT
103
+ });
104
+ expect(result['--od-colours-intent-primary-foreground']).toBe(colourMap.gray['900']);
105
+ expect(result['--od-color-brand-on-solid']).toBe(colourMap.gray['900']);
106
+ });
107
+ it('picks its contrast candidates from the active theme, not the base one', () => {
108
+ // the two candidates are the theme's own page background and body
109
+ // ink, so a theme that changes either gets decisions made against
110
+ // what it actually renders
111
+ const recoloured = _objectSpread(_objectSpread({}, baseTokens), {}, {
112
+ color: _objectSpread(_objectSpread({}, baseTokens.color), {}, {
113
+ background: _objectSpread(_objectSpread({}, baseTokens.color.background), {}, {
114
+ default: '#fff8e1'
115
+ }),
116
+ foreground: _objectSpread(_objectSpread({}, baseTokens.color.foreground), {}, {
117
+ primary: '#1a0033'
118
+ })
119
+ })
120
+ });
121
+ const result = vars({
122
+ primaryBackground: BRIGHT
123
+ }, recoloured);
124
+ expect(result['--od-color-brand-on-solid']).toBe('#1a0033');
125
+ });
126
+ });
127
+ describe('outlined button', () => {
128
+ it('takes the brand verbatim for border and label', () => {
129
+ const result = vars({
130
+ primaryBackground: BRAND
131
+ });
132
+ expect(result['--od-color-button-primary-outlined-border']).toBe(BRAND);
133
+ expect(result['--od-color-button-primary-outlined-text']).toBe(BRAND);
134
+ });
135
+ it('derives a hover wash paler than the pressed wash', () => {
136
+ const result = vars({
137
+ primaryBackground: BRAND
138
+ });
139
+ const hover = result['--od-color-button-primary-outlined-hover'];
140
+ const pressed = result['--od-color-button-primary-outlined-pressed'];
141
+ expect(luminance(hover)).toBeGreaterThan(luminance(pressed));
142
+ expect(luminance(pressed)).toBeGreaterThan(luminance(BRAND));
143
+ });
144
+ });
145
+ describe('links and focus rings', () => {
146
+ it('leaves them alone when only a brand background is supplied', () => {
147
+ const result = vars({
148
+ primaryBackground: BRAND
149
+ });
150
+ expect(result['--od-colours-foreground-link']).toBeUndefined();
151
+ expect(result['--od-typography-colour-link']).toBeUndefined();
152
+ });
153
+ it('brands them only when linkColor is passed explicitly', () => {
154
+ const result = vars({
155
+ primaryBackground: BRAND,
156
+ linkColor: BRAND
157
+ });
158
+ expect(result['--od-colours-foreground-link']).toBe(BRAND);
159
+ expect(result['--od-typography-colour-link']).toBe(BRAND);
160
+ });
161
+ });
162
+ describe('invalid values', () => {
163
+ it('warns, drops the key, and does not mutate the caller object', () => {
164
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
165
+ const supplied = {
166
+ primaryBackground: 'not-a-colour',
167
+ primaryForeground: '#ffffff'
168
+ };
169
+ const result = vars(supplied);
170
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining('primaryBackground'));
171
+ expect(result['--od-color-brand-solid']).toBeUndefined();
172
+ // the hook used to `delete` off the prop object itself, which
173
+ // mutates state an MFE may be holding in a GraphQL cache
174
+ expect(supplied.primaryBackground).toBe('not-a-colour');
175
+ });
176
+ });
177
+ describe('contrast warning', () => {
178
+ it('warns when the brand is too light to read on the page background', () => {
179
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
180
+ // a colour not warned about elsewhere in this file, since the
181
+ // warning is deduplicated for the life of the module
182
+ vars({
183
+ primaryBackground: '#ffd54a'
184
+ });
185
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining('does not meet WCAG AA'));
186
+ });
187
+ it('stays quiet for a brand with enough contrast', () => {
188
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
189
+ vars({
190
+ primaryBackground: BRAND
191
+ });
192
+ expect(warn).not.toHaveBeenCalled();
193
+ });
194
+ it('warns only once for a repeated colour, since the provider re-renders freely', () => {
195
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
196
+ vars({
197
+ primaryBackground: '#ffe08a'
198
+ });
199
+ vars({
200
+ primaryBackground: '#ffe08a'
201
+ });
202
+ vars({
203
+ primaryBackground: '#ffe08a'
204
+ });
205
+ expect(warn).toHaveBeenCalledTimes(1);
206
+ });
207
+ });
208
+ describe('server rendering', () => {
209
+ it('keeps overrides when the DOM colour check is unavailable', () => {
210
+ // `isValidColor` uses `Option`, a DOM global. Failing closed on the
211
+ // server stripped every override, so a branded page shipped no
212
+ // inline vars and only picked up the brand on hydration.
213
+ const original = globalThis.Option;
214
+ // @ts-expect-error simulating a non-DOM environment
215
+ delete globalThis.Option;
216
+ try {
217
+ const result = vars({
218
+ primaryBackground: BRAND
219
+ });
220
+ expect(result['--od-color-brand-solid']).toBe(BRAND);
221
+ } finally {
222
+ globalThis.Option = original;
223
+ }
224
+ });
225
+ });
226
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Radio/Radio.css.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,KAAK,QAehB,CAAC;AAEH,eAAO,MAAM,aAAa,QAGxB,CAAC;AAEH,eAAO,MAAM,KAAK,QAYhB,CAAC;AAEH,eAAO,MAAM,aAAa,QAOxB,CAAC"}
1
+ {"version":3,"file":"Radio.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Radio/Radio.css.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,KAAK,QAehB,CAAC;AAEH,eAAO,MAAM,aAAa,QAGxB,CAAC;AAEH,eAAO,MAAM,KAAK,QAYhB,CAAC;AAEH,eAAO,MAAM,aAAa,QAQxB,CAAC"}
@@ -3,7 +3,7 @@ __vanilla_filescope__.setFileScope("lib/components/Radio/Radio.css.ts", "@autogu
3
3
  import { style } from '@vanilla-extract/css';
4
4
  import { overdriveTokens as vars } from "../../themes/theme.css.js";
5
5
  import { checkable, nativeInput } from "../private/CheckableBase/CheckableBase.css.js";
6
- const colorAccent = vars.color.foreground.primary;
6
+ const colorAccent = vars.color.brand.solid;
7
7
  const colorContrast = vars.color.background.default;
8
8
  const colorMid = vars.colours.background.neutral;
9
9
  const outerSize = vars.space['6'];
@@ -42,7 +42,8 @@ export const inner = style([circleBase, {
42
42
  }
43
43
  }], "inner");
44
44
  export const innerSelected = style({
45
- backgroundColor: colorContrast,
45
+ // on the brand fill, unlike the unselected hover dot above
46
+ backgroundColor: vars.color.brand.onSolid,
46
47
  selectors: {
47
48
  [`${nativeInput}:hover ~${checkable} &`]: {
48
49
  transform: 'scale(0.85)'
@@ -11,7 +11,7 @@ export const container = style({
11
11
  }, "container");
12
12
  export const modal = style(_objectSpread({
13
13
  alignSelf: 'flex-end',
14
- borderRadius: `${vars.border.radius['2xl']} ${vars.border.radius['2xl']} 0 0`,
14
+ borderRadius: `${vars.border.radius.medium} ${vars.border.radius.medium} 0 0`,
15
15
  height: 'auto',
16
16
  maxHeight: `calc(100vh - ${vars.space['9']})`,
17
17
  minHeight: `calc(3 * ${vars.space['9']})`,
@@ -19,7 +19,7 @@ export const modal = style(_objectSpread({
19
19
  }, responsiveStyle({
20
20
  tablet: {
21
21
  alignSelf: 'center',
22
- borderRadius: vars.border.radius['2xl']
22
+ borderRadius: vars.border.radius.medium
23
23
  },
24
24
  desktop: {
25
25
  maxWidth: `calc(100% - ${vars.space['12']} * 2)`,
@@ -74,7 +74,7 @@ export const StandardModal = ({
74
74
  "aria-labelledby": titleId,
75
75
  display: "flex",
76
76
  flexDirection: "column",
77
- backgroundColor: "white",
77
+ backgroundColor: "default",
78
78
  marginTop: "9",
79
79
  className: clsx([styles.modal, {
80
80
  [styles.modalSizeStandard]: size === 'standard'
@@ -100,7 +100,8 @@ export const StandardModal = ({
100
100
  flexGrow: "0",
101
101
  id: titleId,
102
102
  children: /*#__PURE__*/_jsx(Heading, {
103
- as: "h4",
103
+ as: "h2",
104
+ color: "primary",
104
105
  children: title
105
106
  })
106
107
  }), /*#__PURE__*/_jsx(Button, {
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Switch/Switch.css.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,IAAI,QAMf,CAAC;AAEH,eAAO,MAAM,MAAM,QAqBjB,CAAC;AAEH,eAAO,MAAM,QAAQ,QAMnB,CAAC;AAEH,eAAO,MAAM,QAAQ,QAOnB,CAAC;AAKH,eAAO,MAAM,MAAM,sCAkCjB,CAAC;AAEH,eAAO,MAAM,UAAU,QAOrB,CAAC"}
1
+ {"version":3,"file":"Switch.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Switch/Switch.css.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,IAAI,QAMf,CAAC;AAEH,eAAO,MAAM,MAAM,QAqBjB,CAAC;AAEH,eAAO,MAAM,QAAQ,QAMnB,CAAC;AAEH,eAAO,MAAM,QAAQ,QAOnB,CAAC;AAKH,eAAO,MAAM,MAAM,sCAoCjB,CAAC;AAEH,eAAO,MAAM,UAAU,QAOrB,CAAC"}
@@ -5,7 +5,7 @@ import { focusOutlineStyle } from "../../styles/focusOutline.css.js";
5
5
  import { LAYER_ORDER, cssLayerComponent } from "../../styles/layers.css.js";
6
6
  import { overdriveTokens as vars } from "../../themes/theme.css.js";
7
7
  globalLayer(LAYER_ORDER);
8
- const colorAccent = vars.color.foreground.primary;
8
+ const colorAccent = vars.color.brand.solid;
9
9
  const colorContrast = vars.color.background.default;
10
10
  const colorMid = vars.colours.background.neutral;
11
11
  const colorLight = vars.colours.background.light;
@@ -78,6 +78,8 @@ export const handle = styleVariants({
78
78
  [cssLayerComponent]: {
79
79
  selectors: {
80
80
  [`${toggleOn} &`]: {
81
+ // on the brand track, so on-brand rather than page
82
+ backgroundColor: vars.color.brand.onSolid,
81
83
  transform: handleTranslate
82
84
  },
83
85
  [`${toggle}:not([data-disabled]):hover &`]: {
@@ -30,6 +30,39 @@ export declare const styledTab: import("@vanilla-extract/recipes").RuntimeFn<{
30
30
  };
31
31
  };
32
32
  };
33
+ segmented: {
34
+ borderColor: `var(--${string})`;
35
+ borderStyle: "solid";
36
+ borderWidth: `var(--${string})`;
37
+ color: `var(--${string})`;
38
+ flex: "1 0 0";
39
+ fontSize: `var(--${string})`;
40
+ fontWeight: `var(--${string})`;
41
+ lineHeight: `var(--${string})`;
42
+ minHeight: `var(--${string})`;
43
+ minWidth: number;
44
+ overflow: "hidden";
45
+ padding: `var(--${string}) var(--${string})`;
46
+ ':focus-visible': {
47
+ outlineOffset: "-1px";
48
+ };
49
+ selectors: {
50
+ '&:first-child': {
51
+ borderBottomLeftRadius: `var(--${string})`;
52
+ borderTopLeftRadius: `var(--${string})`;
53
+ };
54
+ '&:last-child': {
55
+ borderBottomRightRadius: `var(--${string})`;
56
+ borderTopRightRadius: `var(--${string})`;
57
+ };
58
+ '&+&': {
59
+ marginLeft: `calc(-1 * var(--${string}))`;
60
+ };
61
+ '&:not([aria-selected=true]):hover': {
62
+ backgroundColor: `var(--${string})`;
63
+ };
64
+ };
65
+ };
33
66
  };
34
67
  active: {
35
68
  true: {};
@@ -47,6 +80,13 @@ export declare const indication: import("@vanilla-extract/recipes").RuntimeFn<{
47
80
  };
48
81
  };
49
82
  minimal: {};
83
+ segmented: {
84
+ selectors: {
85
+ [x: string]: {
86
+ backgroundColor: `var(--${string})`;
87
+ };
88
+ };
89
+ };
50
90
  };
51
91
  active: {
52
92
  true: {};
@@ -1 +1 @@
1
- {"version":3,"file":"Tab.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/Tab.css.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsFpB,CAAC;AAEH,eAAO,MAAM,IAAI,QAIf,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EAsDrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"Tab.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/Tab.css.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmIpB,CAAC;AAEH,eAAO,MAAM,IAAI,QAIf,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;EAwErB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC"}
@@ -51,6 +51,39 @@ export const styledTab = recipe({
51
51
  marginLeft: vars.space['6']
52
52
  }
53
53
  }
54
+ },
55
+ segmented: {
56
+ borderColor: vars.color.border.default,
57
+ borderStyle: 'solid',
58
+ borderWidth: vars.border.width['1'],
59
+ color: vars.color.foreground.secondary,
60
+ flex: '1 0 0',
61
+ fontSize: vars.typography.size.p2.fontSize,
62
+ fontWeight: vars.typography.fontWeight.semiBold,
63
+ lineHeight: vars.typography.size.p2.lineHeight,
64
+ minHeight: vars.space['8'],
65
+ minWidth: 0,
66
+ overflow: 'hidden',
67
+ padding: `${vars.space['2']} ${vars.space['4']}`,
68
+ ':focus-visible': {
69
+ outlineOffset: '-1px'
70
+ },
71
+ selectors: {
72
+ '&:first-child': {
73
+ borderBottomLeftRadius: vars.border.radius.small,
74
+ borderTopLeftRadius: vars.border.radius.small
75
+ },
76
+ '&:last-child': {
77
+ borderBottomRightRadius: vars.border.radius.small,
78
+ borderTopRightRadius: vars.border.radius.small
79
+ },
80
+ '&+&': {
81
+ marginLeft: `calc(-1 * ${vars.border.width['1']})`
82
+ },
83
+ '&:not([aria-selected=true]):hover': {
84
+ backgroundColor: vars.color.background.emphasisInactive
85
+ }
86
+ }
54
87
  }
55
88
  },
56
89
  active: {
@@ -63,8 +96,8 @@ export const styledTab = recipe({
63
96
  active: true
64
97
  },
65
98
  style: {
66
- color: vars.colours.intent.neutral.background.strong,
67
- borderBottomColor: vars.colours.intent.neutral.background.strong
99
+ color: vars.color.foreground.primary,
100
+ borderBottomColor: vars.color.border.strong
68
101
  }
69
102
  }, {
70
103
  variants: {
@@ -84,6 +117,18 @@ export const styledTab = recipe({
84
117
  color: vars.color.content.normal,
85
118
  borderBottomColor: vars.color.content.normal
86
119
  }
120
+ }, {
121
+ variants: {
122
+ appearance: 'segmented',
123
+ active: true
124
+ },
125
+ style: {
126
+ backgroundColor: vars.color.background.reverse,
127
+ borderColor: vars.color.background.reverse,
128
+ color: vars.color.foreground.reverse,
129
+ position: 'relative',
130
+ zIndex: 1
131
+ }
87
132
  }],
88
133
  defaultVariants: {
89
134
  appearance: 'underlined'
@@ -96,14 +141,14 @@ export const item = style({
96
141
  }, "item");
97
142
  export const indication = recipe({
98
143
  base: [{
99
- backgroundColor: vars.colours.background.light,
144
+ backgroundColor: vars.color.background.emphasisInactive,
100
145
  borderRadius: vars.border.radius.pill,
101
146
  display: 'inline-block',
102
147
  minWidth: size,
103
148
  height: size,
104
149
  padding: `0 ${vars.space['1']}`,
105
150
  lineHeight: size,
106
- transition: `color 0.2s ${vars.animation.easing.decelerate} 0s, backgroundColor 0.2s ${vars.animation.easing.decelerate} 0s`
151
+ transition: `color 0.2s ${vars.animation.easing.decelerate} 0s, background-color 0.2s ${vars.animation.easing.decelerate} 0s`
107
152
  }],
108
153
  variants: {
109
154
  appearance: {
@@ -111,11 +156,18 @@ export const indication = recipe({
111
156
  pill: {
112
157
  selectors: {
113
158
  [`${styledTab.classNames.base}:not([aria-selected=true]):hover &`]: {
114
- backgroundColor: vars.colours.background.neutral
159
+ backgroundColor: vars.color.background.inactive
115
160
  }
116
161
  }
117
162
  },
118
- minimal: {}
163
+ minimal: {},
164
+ segmented: {
165
+ selectors: {
166
+ [`${styledTab.classNames.base}:not([aria-selected=true]):hover &`]: {
167
+ backgroundColor: vars.color.background.inactive
168
+ }
169
+ }
170
+ }
119
171
  },
120
172
  active: {
121
173
  true: {}
@@ -127,7 +179,7 @@ export const indication = recipe({
127
179
  active: true
128
180
  },
129
181
  style: {
130
- backgroundColor: vars.colours.intent.neutral.background.strong
182
+ backgroundColor: vars.color.foreground.primary
131
183
  }
132
184
  }, {
133
185
  variants: {
@@ -135,7 +187,16 @@ export const indication = recipe({
135
187
  active: true
136
188
  },
137
189
  style: {
138
- backgroundColor: vars.colours.background.light,
190
+ backgroundColor: vars.color.background.emphasisInactive,
191
+ color: vars.color.foreground.primary
192
+ }
193
+ }, {
194
+ variants: {
195
+ appearance: 'segmented',
196
+ active: true
197
+ },
198
+ style: {
199
+ backgroundColor: vars.color.background.emphasisInactive,
139
200
  color: vars.color.foreground.primary
140
201
  }
141
202
  }],
@@ -43,7 +43,7 @@ export const Tab = /*#__PURE__*/forwardRef(({
43
43
  justifyContent: 'center',
44
44
  backgroundColor: 'transparent'
45
45
  }), textStyles({
46
- colour: 'light',
46
+ color: 'secondary',
47
47
  noWrap: true,
48
48
  size: '3',
49
49
  weight: 'bold'
@@ -5,6 +5,7 @@ export declare const styledTabList: import("@vanilla-extract/recipes").RuntimeFn
5
5
  };
6
6
  pill: {};
7
7
  minimal: {};
8
+ segmented: {};
8
9
  };
9
10
  scroll: {
10
11
  true: {
@@ -1 +1 @@
1
- {"version":3,"file":"TabList.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/TabList.css.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;EAkBxB,CAAC;AAEH,eAAO,MAAM,iBAAiB,QAW5B,CAAC"}
1
+ {"version":3,"file":"TabList.css.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/TabList.css.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;EAmBxB,CAAC;AAEH,eAAO,MAAM,iBAAiB,QAW5B,CAAC"}
@@ -11,7 +11,8 @@ export const styledTabList = recipe({
11
11
  boxShadow: `inset 0 -1px 0 0 ${vars.color.border.default}`
12
12
  },
13
13
  pill: {},
14
- minimal: {}
14
+ minimal: {},
15
+ segmented: {}
15
16
  },
16
17
  scroll: {
17
18
  true: {
@@ -1 +1 @@
1
- {"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/TabList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAEb,KAAK,iBAAiB,EAGtB,KAAK,SAAS,EAMd,MAAM,OAAO,CAAC;AAYf,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB;AASD,eAAO,MAAM,cAAc,8BAAqC,CAAC;AAEjE,eAAO,MAAM,OAAO,EAAE,iBAAiB,CAAC,YAAY,CAwLnD,CAAC"}
1
+ {"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/TabList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAEb,KAAK,iBAAiB,EAGtB,KAAK,SAAS,EAMd,MAAM,OAAO,CAAC;AAYf,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACrB;AASD,eAAO,MAAM,cAAc,8BAAqC,CAAC;AAEjE,eAAO,MAAM,OAAO,EAAE,iBAAiB,CAAC,YAAY,CA+LnD,CAAC"}
@@ -42,6 +42,8 @@ export const TabList = ({
42
42
  activeIndex,
43
43
  onChange
44
44
  } = tabsContext;
45
+ const isSegmented = appearance === 'segmented';
46
+ !!(scrollable && isSegmented) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Tabs: `scrollable={true}` cannot be used with `appearance="segmented"`.') : invariant(false) : void 0;
45
47
  const [displayScroll, setDisplayScroll] = useState({
46
48
  start: false,
47
49
  end: false
@@ -141,7 +143,7 @@ export const TabList = ({
141
143
  onScroll: handleOnScroll,
142
144
  children: /*#__PURE__*/_jsx(Box, {
143
145
  ref: innerRef,
144
- display: stretch ? 'flex' : 'block',
146
+ display: stretch || isSegmented ? 'flex' : 'block',
145
147
  flexWrap: "nowrap",
146
148
  width: "full",
147
149
  role: "tablist",
@@ -165,4 +167,5 @@ export const TabList = ({
165
167
  })
166
168
  }) : null]
167
169
  });
168
- };
170
+ };
171
+ TabList.displayName = 'TabList';
@@ -28,4 +28,5 @@ export const TabPane = ({
28
28
  width: "full",
29
29
  children: isActive || renderInactive ? children : undefined
30
30
  });
31
- };
31
+ };
32
+ TabPane.displayName = 'TabPane';
@@ -21,4 +21,5 @@ export const TabPanes = ({
21
21
  },
22
22
  children: child
23
23
  }))
24
- });
24
+ });
25
+ TabPanes.displayName = 'TabPanes';
@@ -48,6 +48,8 @@ export declare const TabsContext: React.Context<TabsContextValue | null>;
48
48
  * - `"underlined"` (default) - Tabs with bottom border indication
49
49
  * - `"pill"`
50
50
  * - `"minimal"`
51
+ * - `"segmented"` - Equal-width bordered segments with a filled selected segment.
52
+ * Always full width; cannot be combined with `TabList`'s `scrollable`.
51
53
  */
52
54
  export interface TabsProps {
53
55
  /** Custom ID for the tabs container. Auto-generated if not provided. */
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEb,KAAK,iBAAiB,EACtB,KAAK,SAAS,EAId,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,UAAU,gBAAgB;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IACnD,WAAW,EAAE,MAAM,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,WAAW,wCAA+C,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,SAAS;IACzB,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAuD7C,CAAC"}
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEb,KAAK,iBAAiB,EACtB,KAAK,SAAS,EAId,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,UAAU,gBAAgB;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IACnD,WAAW,EAAE,MAAM,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,WAAW,wCAA+C,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,SAAS;IACzB,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,IAAI,EAAE,iBAAiB,CAAC,SAAS,CAuD7C,CAAC"}
@@ -41,6 +41,8 @@ export const TabsContext = /*#__PURE__*/createContext(null);
41
41
  * - `"underlined"` (default) - Tabs with bottom border indication
42
42
  * - `"pill"`
43
43
  * - `"minimal"`
44
+ * - `"segmented"` - Equal-width bordered segments with a filled selected segment.
45
+ * Always full width; cannot be combined with `TabList`'s `scrollable`.
44
46
  */
45
47
 
46
48
  export const Tabs = ({
@@ -72,4 +74,5 @@ export const Tabs = ({
72
74
  }), [id, activeState, appearance, setActiveState, registerTab, getTab, getTabCount]),
73
75
  children: children
74
76
  });
75
- };
77
+ };
78
+ Tabs.displayName = 'Tabs';
@@ -1,6 +1,7 @@
1
- export { Tabs } from './Tabs';
2
- export { Tab } from './Tab';
3
- export { TabList } from './TabList';
1
+ export { Tabs, type TabsProps } from './Tabs';
2
+ export { Tab, type TabProps } from './Tab';
3
+ export { TabList, type TabListProps } from './TabList';
4
+ export type { TabAppearance } from './Tab.css';
4
5
  export { TabPane } from './TabPane';
5
6
  export { TabPanes } from './TabPanes';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/components/Tabs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -19,6 +19,7 @@ export { DividerLine } from './DividerLine';
19
19
  export { DropDown, DropDownOption } from './DropDown';
20
20
  export { EditableText } from './EditableText';
21
21
  export { FillHeightBox } from './FillHeightBox';
22
+ export { FilterChip, type FilterChipProps, type FilterChipType, } from './FilterChip';
22
23
  export { FlexInline, type FlexInlineComponentProps, FlexStack, type FlexStackComponentProps, type FlexComponentProps, inline, stack, } from './Flex';
23
24
  export { Flyout } from './Flyout';
24
25
  export { Heading } from './Heading';
@@ -62,7 +63,7 @@ export { Stepper } from './Stepper';
62
63
  export { StickyBox } from './StickyBox';
63
64
  export { Switch } from './Switch';
64
65
  export { Table, TableCell, TableHeadCell, TableRow, TableRowGroup, } from './Table';
65
- export { Tabs, Tab, TabList, TabPane, TabPanes } from './Tabs';
66
+ export { Tabs, Tab, TabList, TabPane, TabPanes, type TabsProps, type TabProps, type TabListProps, type TabAppearance, } from './Tabs';
66
67
  export { Text } from './Text';
67
68
  export { TextAreaInput } from './TextAreaInput';
68
69
  export { TextBubble } from './TextBubble';