@scality/core-ui 0.169.0 → 0.171.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 (50) hide show
  1. package/__mocks__/uuid.js +11 -0
  2. package/dist/components/barchartv2/Barchart.component.js +2 -2
  3. package/dist/components/buttonv2/Buttonv2.component.js +1 -1
  4. package/dist/components/chartlegend/ChartLegend.d.ts +3 -1
  5. package/dist/components/chartlegend/ChartLegend.d.ts.map +1 -1
  6. package/dist/components/chartlegend/ChartLegend.js +2 -2
  7. package/dist/components/chartlegend/ChartLegendWrapper.d.ts +3 -1
  8. package/dist/components/chartlegend/ChartLegendWrapper.d.ts.map +1 -1
  9. package/dist/components/chartlegend/ChartLegendWrapper.js +43 -9
  10. package/dist/components/date/FormattedDateTime.d.ts +41 -2
  11. package/dist/components/date/FormattedDateTime.d.ts.map +1 -1
  12. package/dist/components/date/FormattedDateTime.js +55 -8
  13. package/dist/components/date/FormattedDateTime.spec.js +12 -3
  14. package/dist/components/icon/Icon.component.d.ts +2 -0
  15. package/dist/components/icon/Icon.component.d.ts.map +1 -1
  16. package/dist/components/icon/Icon.component.js +2 -0
  17. package/dist/components/layout/v2/index.d.ts +2 -1
  18. package/dist/components/layout/v2/index.d.ts.map +1 -1
  19. package/dist/components/layout/v2/index.js +3 -3
  20. package/dist/components/linetemporalchart/ChartUtil.d.ts.map +1 -1
  21. package/dist/components/linetemporalchart/ChartUtil.js +12 -0
  22. package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts +10 -5
  23. package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts.map +1 -1
  24. package/dist/components/linetimeseriechart/linetimeseriechart.component.js +84 -49
  25. package/dist/components/text/Text.component.d.ts +2 -1
  26. package/dist/components/text/Text.component.d.ts.map +1 -1
  27. package/dist/next.d.ts +1 -1
  28. package/dist/next.d.ts.map +1 -1
  29. package/dist/next.js +1 -1
  30. package/dist/style/theme.js +1 -1
  31. package/package.json +3 -1
  32. package/src/lib/components/barchartv2/Barchart.component.tsx +2 -2
  33. package/src/lib/components/barchartv2/ChartTooltip.test.tsx +1 -1
  34. package/src/lib/components/buttonv2/Buttonv2.component.tsx +1 -1
  35. package/src/lib/components/chartlegend/ChartLegend.tsx +4 -2
  36. package/src/lib/components/chartlegend/ChartLegendWrapper.test.tsx +197 -0
  37. package/src/lib/components/chartlegend/ChartLegendWrapper.tsx +65 -9
  38. package/src/lib/components/date/FormattedDateTime.spec.tsx +27 -2
  39. package/src/lib/components/date/FormattedDateTime.tsx +61 -11
  40. package/src/lib/components/icon/Icon.component.tsx +2 -0
  41. package/src/lib/components/layout/v2/index.tsx +5 -3
  42. package/src/lib/components/linetemporalchart/ChartUtil.ts +26 -0
  43. package/src/lib/components/linetimeseriechart/linetimeseriechart.component.tsx +227 -157
  44. package/src/lib/components/text/Text.component.tsx +8 -1
  45. package/src/lib/next.ts +4 -1
  46. package/src/lib/style/theme.ts +1 -1
  47. package/stories/BarChart/barchart.stories.tsx +7 -1
  48. package/stories/formattedate.stories.tsx +7 -0
  49. package/stories/layout.stories.tsx +19 -0
  50. package/stories/linetimeseriechart.stories.tsx +217 -1
@@ -1,36 +1,31 @@
1
1
  import {
2
+ CartesianGrid,
2
3
  Line,
3
4
  LineChart,
4
5
  ReferenceLine,
5
6
  ResponsiveContainer,
6
7
  Tooltip,
8
+ TooltipContentProps,
7
9
  XAxis,
8
10
  YAxis,
9
- CartesianGrid,
10
11
  } from 'recharts';
11
- import type { Payload } from 'recharts/types/component/DefaultTooltipContent';
12
- import { useCallback, useMemo, useRef } from 'react';
13
- import { useTheme } from 'styled-components';
14
- import { addMissingDataPoint } from '../linetemporalchart/ChartUtil';
15
- import styled from 'styled-components';
12
+ import { useCallback, useMemo, useRef, useState } from 'react';
13
+ import styled, { useTheme } from 'styled-components';
14
+ import { spacing } from '../../spacing';
16
15
  import { fontSize, fontWeight } from '../../style/theme';
16
+ import { Box } from '../box/Box';
17
17
  import { useChartLegend } from '../chartlegend/ChartLegendWrapper';
18
- import { ChartTitleText, SmallerText } from '../text/Text.component';
19
- import { Loader } from '../loader/Loader.component';
20
- import { spacing } from '../../spacing';
21
- import { getUnitLabel } from '../linetemporalchart/ChartUtil';
18
+ import { FormattedDateTime } from '../date/FormattedDateTime';
22
19
  import { Icon } from '../icon/Icon.component';
20
+ import {
21
+ addMissingDataPoint,
22
+ getUnitLabel,
23
+ } from '../linetemporalchart/ChartUtil';
24
+ import { Loader } from '../loader/Loader.component';
25
+ import { ChartTitleText, SmallerText } from '../text/Text.component';
23
26
  import { Tooltip as TooltipComponent } from '../tooltip/Tooltip.component';
24
- import { FormattedDateTime } from '../date/FormattedDateTime';
25
- import { Box } from '../box/Box';
26
27
  import { formatXAxisLabel } from './utils';
27
28
 
28
- type TooltipPayload = Payload<number, string> & {
29
- value: number;
30
- name: string;
31
- color: string;
32
- };
33
-
34
29
  const LineTemporalChartWrapper = styled.div`
35
30
  display: flex;
36
31
  flex-direction: column;
@@ -43,7 +38,7 @@ const ChartHeader = styled.div`
43
38
  align-items: center;
44
39
  `;
45
40
 
46
- const TooltipContainer = styled.div`
41
+ export const TooltipContainer = styled.div`
47
42
  background-color: ${(props) => props.theme.backgroundLevel1};
48
43
  padding: ${spacing.r8};
49
44
  border: 1px solid ${(props) => props.theme.border};
@@ -52,7 +47,7 @@ const TooltipContainer = styled.div`
52
47
  max-width: 250px;
53
48
  `;
54
49
 
55
- const TooltipTime = styled.div`
50
+ export const TooltipTime = styled.div`
56
51
  margin-bottom: ${spacing.r8};
57
52
  color: ${(props) => props.theme.textPrimary};
58
53
  font-size: ${fontSize.smaller};
@@ -113,16 +108,18 @@ export type Serie = {
113
108
 
114
109
  type NonSymmetricalChartSerie = {
115
110
  yAxisType?: 'default' | 'percentage';
116
- series: Serie[];
111
+ series: Serie[] | undefined;
117
112
  };
118
113
 
119
114
  // The symmetrical chart props are used to display two series on the same chart, such as in/out, write/read
120
115
  type SymmetricalChartSerie = {
121
116
  yAxisType: 'symmetrical';
122
- series: {
123
- above: Serie[];
124
- below: Serie[];
125
- };
117
+ series:
118
+ | {
119
+ above: Serie[] | undefined;
120
+ below: Serie[] | undefined;
121
+ }
122
+ | undefined;
126
123
  };
127
124
 
128
125
  export type LineChartProps = (
@@ -138,6 +135,7 @@ export type LineChartProps = (
138
135
  threshold: number;
139
136
  label: string;
140
137
  }[];
138
+ syncId?: string;
141
139
  isLoading?: boolean;
142
140
  /**
143
141
  * The format of the x axis, default is 'date-time' which is like 01 Sep 16:00
@@ -147,22 +145,38 @@ export type LineChartProps = (
147
145
  timeFormat?: 'date-time' | 'date';
148
146
  yAxisTitle?: string;
149
147
  helpText?: string;
148
+ renderTooltip?: (
149
+ tooltipProps: TooltipContentProps<number, string>,
150
+ unitLabel?: string,
151
+ timeFormat?: 'date-time' | 'date',
152
+ ) => React.ReactNode;
150
153
  };
151
154
 
152
155
  const CustomTooltip = ({
153
- active,
154
- payload,
155
- label,
156
156
  unitLabel,
157
157
  timeFormat,
158
+ isChartActive,
159
+ tooltipProps,
160
+ renderTooltip,
158
161
  }: {
159
- active?: boolean;
160
- payload?: Array<TooltipPayload>;
161
- label?: string;
162
+ tooltipProps: TooltipContentProps<number, string>;
162
163
  unitLabel?: string;
163
164
  timeFormat?: 'date-time' | 'date';
165
+ isChartActive?: boolean;
166
+ renderTooltip?: (
167
+ tooltipProps: TooltipContentProps<number, string>,
168
+ unitLabel?: string,
169
+ timeFormat?: 'date-time' | 'date',
170
+ ) => React.ReactNode;
164
171
  }) => {
165
- if (!active || !payload || !payload.length || !label) return null;
172
+ const { active, payload, label, ...rest } = tooltipProps;
173
+
174
+ if (!active || !payload || !payload.length || !label || !isChartActive)
175
+ return null;
176
+
177
+ if (renderTooltip) {
178
+ return renderTooltip(tooltipProps, unitLabel, timeFormat);
179
+ }
166
180
  // We can't use the default itemSorter method because it's a custom tooltip.
167
181
  // Sort the payload here instead
168
182
  const sortedPayload = [...payload].sort((a, b) => {
@@ -208,7 +222,7 @@ const CustomTooltip = ({
208
222
  };
209
223
 
210
224
  const isSymmetricalSeries = (
211
- series: Serie[] | { above: Serie[]; below: Serie[] },
225
+ series: Serie[] | { above: Serie[] | undefined; below: Serie[] | undefined },
212
226
  ): series is { above: Serie[]; below: Serie[] } => {
213
227
  return 'above' in series && 'below' in series;
214
228
  };
@@ -226,42 +240,65 @@ export function LineTimeSerieChart({
226
240
  yAxisType = 'default',
227
241
  yAxisTitle,
228
242
  helpText,
243
+ syncId,
244
+ renderTooltip,
229
245
  ...rest
230
246
  }: LineChartProps) {
231
247
  const theme = useTheme();
232
- const { getColor } = useChartLegend();
248
+ const { getColor, selectedResources } = useChartLegend();
233
249
  const chartRef = useRef(null);
234
250
 
251
+ const [isChartActive, setIsChartActive] = useState(false);
252
+
235
253
  const chartData = useMemo(() => {
254
+ // Guard against empty/undefined series data
255
+ if (!series || (Array.isArray(series) && series.length === 0)) {
256
+ return [];
257
+ }
258
+
259
+ // Handle symmetrical series with empty above/below arrays
260
+ if (isSymmetricalSeries(series)) {
261
+ if (
262
+ (!series.above || series.above.length === 0) &&
263
+ (!series.below || series.below.length === 0)
264
+ ) {
265
+ return [];
266
+ }
267
+ }
268
+
236
269
  // 1. Add missing data points
237
270
  const normalizedSeries =
238
271
  yAxisType === 'symmetrical' && isSymmetricalSeries(series)
239
272
  ? {
240
- above: series.above.map((line) => ({
241
- ...line,
242
- data: addMissingDataPoint(
243
- line.data,
244
- startingTimeStamp,
245
- duration,
246
- interval,
247
- ),
248
- })),
273
+ above: series.above
274
+ ? series.above.map((line) => ({
275
+ ...line,
276
+ data: addMissingDataPoint(
277
+ line.data,
278
+ startingTimeStamp,
279
+ duration,
280
+ interval,
281
+ ),
282
+ }))
283
+ : [],
249
284
  // Convert positive values to negative values
250
- below: series.below.map((line) => ({
251
- ...line,
252
- data: addMissingDataPoint(
253
- line.data,
254
- startingTimeStamp,
255
- duration,
256
- interval,
257
- ).map(
258
- ([timestamp, value]) =>
259
- [timestamp, value === null ? null : `-${Number(value)}`] as [
260
- number,
261
- string | null,
262
- ],
263
- ),
264
- })),
285
+ below: series.below
286
+ ? series.below.map((line) => ({
287
+ ...line,
288
+ data: addMissingDataPoint(
289
+ line.data,
290
+ startingTimeStamp,
291
+ duration,
292
+ interval,
293
+ ).map(
294
+ ([timestamp, value]) =>
295
+ [
296
+ timestamp,
297
+ value === null ? null : `-${Number(value)}`,
298
+ ] as [number, string | null],
299
+ ),
300
+ }))
301
+ : [],
265
302
  }
266
303
  : (series as Serie[]).map((line) => ({
267
304
  ...line,
@@ -356,6 +393,15 @@ export function LineTimeSerieChart({
356
393
  .filter((value): value is number => value !== null),
357
394
  );
358
395
 
396
+ // Guard against empty values array
397
+ if (values.length === 0) {
398
+ return {
399
+ topValue: 100, // Default value for empty charts
400
+ unitLabel: '',
401
+ rechartsData: [],
402
+ };
403
+ }
404
+
359
405
  const top = Math.abs(Math.max(...values));
360
406
  const bottom = Math.abs(Math.min(...values));
361
407
  const maxValue = Math.max(top, bottom);
@@ -380,22 +426,30 @@ export function LineTimeSerieChart({
380
426
  // Group series by resource and create color mapping
381
427
  const { colorMapping, groupedSeries } = useMemo(() => {
382
428
  const mapping: Record<string, string> = {};
429
+
430
+ // Guard against empty/undefined series
431
+ if (!series) {
432
+ return { colorMapping: mapping, groupedSeries: {} };
433
+ }
434
+
383
435
  const allSeries = isSymmetricalSeries(series)
384
- ? [...series.above, ...series.below]
436
+ ? [...(series.above || []), ...(series.below || [])]
385
437
  : (series as Serie[]);
386
438
 
387
439
  // Group series by resource
388
- const groups = allSeries.reduce(
389
- (acc, serie) => {
390
- const key = serie.resource;
391
- if (!acc[key]) {
392
- acc[key] = [];
393
- }
394
- acc[key].push(serie);
395
- return acc;
396
- },
397
- {} as Record<string, Serie[]>,
398
- );
440
+ const groups = allSeries
441
+ .filter((serie) => selectedResources.includes(serie.resource))
442
+ .reduce(
443
+ (acc, serie) => {
444
+ const key = serie.resource;
445
+ if (!acc[key]) {
446
+ acc[key] = [];
447
+ }
448
+ acc[key].push(serie);
449
+ return acc;
450
+ },
451
+ {} as Record<string, Serie[]>,
452
+ );
399
453
 
400
454
  // Get colors from the ChartLegend context
401
455
  Object.keys(groups).forEach((resource) => {
@@ -411,7 +465,7 @@ export function LineTimeSerieChart({
411
465
  colorMapping: mapping,
412
466
  groupedSeries: groups,
413
467
  };
414
- }, [series, getColor]);
468
+ }, [series, getColor, selectedResources]);
415
469
 
416
470
  // Format time for display the tick in the x axis
417
471
  const formatXAxisLabelCallback = useCallback(
@@ -437,95 +491,111 @@ export function LineTimeSerieChart({
437
491
  )}
438
492
  {isLoading && <Loader />}
439
493
  </ChartHeader>
440
- <ResponsiveContainer width="100%" height={height}>
441
- <LineChart
442
- data={rechartsData}
443
- ref={chartRef}
444
- margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
445
- aria-label={`Time series chart for ${title}`}
446
- >
447
- <CartesianGrid
448
- vertical={true}
449
- horizontal={true}
450
- verticalPoints={[0]}
451
- horizontalPoints={[0]}
452
- stroke={theme.border}
453
- fill={theme.backgroundLevel4}
454
- strokeWidth={1}
455
- />
456
- <XAxis
457
- dataKey="timestamp"
458
- type="number"
459
- domain={['dataMin', 'dataMax']}
460
- ticks={xAxisTicks}
461
- tickFormatter={formatXAxisLabelCallback}
462
- tickCount={5}
463
- tick={{
464
- fill: theme.textSecondary,
465
- fontSize: fontSize.smaller,
466
- }}
467
- axisLine={{ stroke: theme.border }}
468
- />
469
- <YAxis
470
- orientation="right"
471
- allowDataOverflow={false}
472
- label={{
473
- value: yAxisTitle,
474
- angle: 90,
475
- position: 'insideRight',
476
- style: {
477
- textAnchor: 'middle',
494
+ <div
495
+ onFocus={() => setIsChartActive(true)}
496
+ onBlur={() => setIsChartActive(false)}
497
+ onFocusCapture={() => setIsChartActive(true)}
498
+ onBlurCapture={() => setIsChartActive(false)}
499
+ >
500
+ <ResponsiveContainer width="100%" height={height}>
501
+ <LineChart
502
+ data={rechartsData}
503
+ ref={chartRef}
504
+ margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
505
+ aria-label={`Time series chart for ${title}`}
506
+ syncId={syncId}
507
+ onMouseEnter={() => setIsChartActive(true)}
508
+ onMouseLeave={() => setIsChartActive(false)}
509
+ >
510
+ <CartesianGrid
511
+ vertical={true}
512
+ horizontal={true}
513
+ verticalPoints={[0]}
514
+ horizontalPoints={[0]}
515
+ stroke={theme.border}
516
+ fill={theme.backgroundLevel4}
517
+ strokeWidth={1}
518
+ />
519
+ <XAxis
520
+ dataKey="timestamp"
521
+ type="number"
522
+ domain={['dataMin', 'dataMax']}
523
+ ticks={xAxisTicks}
524
+ tickFormatter={formatXAxisLabelCallback}
525
+ tickCount={5}
526
+ tick={{
527
+ fill: theme.textSecondary,
528
+ fontSize: fontSize.smaller,
529
+ }}
530
+ axisLine={{ stroke: theme.border }}
531
+ />
532
+ <YAxis
533
+ orientation="right"
534
+ allowDataOverflow={false}
535
+ label={{
536
+ value: yAxisTitle,
537
+ angle: 90,
538
+ position: 'insideRight',
539
+ style: {
540
+ textAnchor: 'middle',
541
+ fill: theme.textSecondary,
542
+ fontSize: fontSize.smaller,
543
+ },
544
+ }}
545
+ domain={
546
+ yAxisType === 'percentage'
547
+ ? [0, 100]
548
+ : yAxisType === 'symmetrical'
549
+ ? [-topValue, topValue]
550
+ : [0, topValue]
551
+ }
552
+ axisLine={{ stroke: theme.border }}
553
+ tick={{
478
554
  fill: theme.textSecondary,
479
555
  fontSize: fontSize.smaller,
480
- },
481
- }}
482
- domain={
483
- yAxisType === 'percentage'
484
- ? [0, 100]
485
- : yAxisType === 'symmetrical'
486
- ? [-topValue, topValue]
487
- : [0, topValue]
488
- }
489
- axisLine={{ stroke: theme.border }}
490
- tick={{
491
- fill: theme.textSecondary,
492
- fontSize: fontSize.smaller,
493
- }}
494
- tickFormatter={(value) => Math.round(value).toString()}
495
- tickCount={5}
496
- interval={'preserveStartEnd'}
497
- />
498
- <Tooltip
499
- content={
500
- <CustomTooltip unitLabel={unitLabel} timeFormat={timeFormat} />
501
- }
502
- />
503
- {/* Add horizontal line at y=0 for symmetrical charts */}
504
- {yAxisType === 'symmetrical' && (
505
- <ReferenceLine y={0} stroke={theme.border} />
506
- )}
507
-
508
- {/* Chart lines */}
509
- {Object.entries(groupedSeries).map(([resource, resourceSeries]) =>
510
- resourceSeries.map((serie, serieIndex) => {
511
- const label = serie.getTooltipLabel(
512
- serie.metricPrefix,
513
- serie.resource,
514
- );
515
- return (
516
- <Line
517
- key={`${title}-${resource}-${serieIndex}`}
518
- type="monotone"
519
- dataKey={label}
520
- stroke={colorMapping[resource]}
521
- dot={false}
522
- isAnimationActive={false}
556
+ }}
557
+ tickFormatter={(value) => Math.round(value).toString()}
558
+ tickCount={5}
559
+ interval={'preserveStartEnd'}
560
+ />
561
+ <Tooltip
562
+ content={(props: TooltipContentProps<number, string>) => (
563
+ <CustomTooltip
564
+ unitLabel={unitLabel}
565
+ timeFormat={timeFormat}
566
+ renderTooltip={renderTooltip}
567
+ tooltipProps={props}
568
+ isChartActive={isChartActive}
523
569
  />
524
- );
525
- }),
526
- )}
527
- </LineChart>
528
- </ResponsiveContainer>
570
+ )}
571
+ />
572
+ {/* Add horizontal line at y=0 for symmetrical charts */}
573
+ {yAxisType === 'symmetrical' && (
574
+ <ReferenceLine y={0} stroke={theme.border} />
575
+ )}
576
+
577
+ {/* Chart lines */}
578
+ {Object.entries(groupedSeries).map(([resource, resourceSeries]) =>
579
+ resourceSeries.map((serie, serieIndex) => {
580
+ const label = serie.getTooltipLabel(
581
+ serie.metricPrefix,
582
+ serie.resource,
583
+ );
584
+ return (
585
+ <Line
586
+ key={`${title}-${resource}-${serieIndex}`}
587
+ type="monotone"
588
+ dataKey={label}
589
+ stroke={colorMapping[resource]}
590
+ dot={false}
591
+ isAnimationActive={false}
592
+ />
593
+ );
594
+ }),
595
+ )}
596
+ </LineChart>
597
+ </ResponsiveContainer>
598
+ </div>
529
599
  </LineTemporalChartWrapper>
530
600
  );
531
601
  }
@@ -3,6 +3,13 @@ import { spacing } from '../../spacing';
3
3
  import { CoreUITheme } from '../../style/theme';
4
4
  import { FocusVisibleStyle } from '../buttonv2/Buttonv2.component';
5
5
 
6
+ export type TextVariant =
7
+ | 'ChartTitle'
8
+ | 'Basic'
9
+ | 'Smaller'
10
+ | 'Larger'
11
+ | 'Large';
12
+
6
13
  type Status = 'unknown' | 'healthy' | 'warning' | 'critical';
7
14
  type Props = {
8
15
  children: React.ReactNode | string;
@@ -128,7 +135,7 @@ export const GentleEmphaseSecondaryText = styled(SecondaryText)<{
128
135
  `;
129
136
 
130
137
  export const Text = styled.span<{
131
- variant?: 'ChartTitle' | 'Basic' | 'Smaller' | 'Larger' | 'Large';
138
+ variant?: TextVariant;
132
139
  color?: keyof CoreUITheme;
133
140
  isEmphazed?: boolean;
134
141
  isGentleEmphazed?: boolean;
package/src/lib/next.ts CHANGED
@@ -22,7 +22,10 @@ export {
22
22
  BarchartTooltipFn,
23
23
  } from './components/barchartv2/Barchart.component';
24
24
  export { ChartTooltip } from './components/barchartv2/ChartTooltip';
25
- export { ChartLegendWrapper } from './components/chartlegend/ChartLegendWrapper';
25
+ export {
26
+ ChartLegendWrapper,
27
+ useChartId,
28
+ } from './components/chartlegend/ChartLegendWrapper';
26
29
  export { ChartLegend } from './components/chartlegend/ChartLegend';
27
30
  export { LineTimeSerieChart } from './components/linetimeseriechart/linetimeseriechart.component';
28
31
  export { CoreUITheme } from './style/theme';
@@ -150,7 +150,7 @@ export const coreUIAvailableThemes: Record<CoreUIThemeName, CoreUITheme> = {
150
150
  selectedActive: '#037AFF',
151
151
  highlight: '#1A3C75',
152
152
  border: '#4A4A4A',
153
- buttonPrimary: 'linear-gradient(130deg, #9355E7 0%, #2E4AA3 100%)',
153
+ buttonPrimary: 'linear-gradient(130deg, #9355E7 0%, #2E4AA3 60%)',
154
154
  buttonSecondary: 'linear-gradient(130deg, #595A78 0%, #44455F 100%)',
155
155
  buttonDelete: '#3D0808',
156
156
  infoPrimary: '#8E8EAC',
@@ -987,7 +987,13 @@ export const StackedHistogram: Story = {
987
987
  ] as const;
988
988
  const theme = useTheme() as CoreUITheme;
989
989
  return (
990
- <div style={{ width: '50%', padding: spacing.r16 }}>
990
+ <div
991
+ style={{
992
+ width: '50%',
993
+ padding: spacing.r16,
994
+ backgroundColor: theme.backgroundLevel2,
995
+ }}
996
+ >
991
997
  <ChartLegendWrapper
992
998
  colorSet={{
993
999
  'Test 1': theme.statusHealthy,
@@ -24,6 +24,13 @@ export const FormattedDate = {
24
24
  'time' as const,
25
25
  'time-second' as const,
26
26
  'relative' as const,
27
+ 'day-month-abbreviated-hour-minute' as const,
28
+ 'day-month-abbreviated-hour-minute-second' as const,
29
+ 'long-date' as const,
30
+ 'long-date-without-weekday' as const,
31
+ 'chart-date' as const,
32
+ 'year-month-day' as const,
33
+ 'month-day' as const,
27
34
  ].map((format) => (
28
35
  <tr key={format}>
29
36
  <td>{format}</td>
@@ -123,6 +123,25 @@ export const Layout2MainContentOnly = {
123
123
  ),
124
124
  };
125
125
 
126
+ export const Layout2TransparentBackground = {
127
+ render: () => (
128
+ <Layout2
129
+ variant='transparent'
130
+ headerNavigation={
131
+ <HeaderComponent>
132
+ <h3>Header navigation</h3>
133
+ </HeaderComponent>
134
+ }
135
+ >
136
+ <AppContainer>
137
+ <AppContainer.MainContent hasTopMargin>
138
+ Main content
139
+ </AppContainer.MainContent>
140
+ </AppContainer>
141
+ </Layout2>
142
+ ),
143
+ };
144
+
126
145
  export const Layout2OverallSummaryAndMainContent = {
127
146
  render: () => (
128
147
  <Layout2