@bundle-stats/ui 4.16.0-beta.1 → 4.16.0-beta.11

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 (116) hide show
  1. package/lib/components/bundle-assets/bundle-assets.js +5 -3
  2. package/lib/components/bundle-assets/bundle-assets.js.map +1 -1
  3. package/lib/components/bundle-assets-totals/bundle-assets-totals.js +4 -2
  4. package/lib/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
  5. package/lib/components/bundle-modules/bundle-modules.js +4 -2
  6. package/lib/components/bundle-modules/bundle-modules.js.map +1 -1
  7. package/lib/components/bundle-packages/bundle-packages.js +4 -2
  8. package/lib/components/bundle-packages/bundle-packages.js.map +1 -1
  9. package/lib/components/insights/insights.module.css +1 -0
  10. package/lib/components/metrics-table-export/metrics-table-export.js +10 -12
  11. package/lib/components/metrics-table-export/metrics-table-export.js.map +1 -1
  12. package/lib/components/metrics-table-options/metrics-table-options.js +7 -5
  13. package/lib/components/metrics-table-options/metrics-table-options.js.map +1 -1
  14. package/lib/components/metrics-table-options/metrics-table-options.module.css +5 -0
  15. package/lib/components/preview-source/preview-source.js +8 -5
  16. package/lib/components/preview-source/preview-source.js.map +1 -1
  17. package/lib/components/preview-source/preview-source.module.css +12 -0
  18. package/lib/css/variables.css +4 -0
  19. package/lib/i18n.js +2 -0
  20. package/lib/i18n.js.map +1 -1
  21. package/lib/ui/dialog/dialog.module.css +3 -3
  22. package/lib/ui/index.js +3 -1
  23. package/lib/ui/index.js.map +1 -1
  24. package/lib/ui/markdown/index.js +18 -0
  25. package/lib/ui/markdown/index.js.map +1 -0
  26. package/lib/ui/markdown/markdown.js +40 -0
  27. package/lib/ui/markdown/markdown.js.map +1 -0
  28. package/lib/ui/markdown/markdown.module.css +7 -0
  29. package/lib/ui/skeleton/skeleton.module.css +3 -3
  30. package/lib/ui/tabs/index.js +15 -3
  31. package/lib/ui/tabs/index.js.map +1 -1
  32. package/lib/ui/tabs/tabs.js +9 -20
  33. package/lib/ui/tabs/tabs.js.map +1 -1
  34. package/lib/ui/tabs/tabs.module.css +6 -5
  35. package/lib/ui/textarea/textarea.js +2 -2
  36. package/lib/ui/textarea/textarea.js.map +1 -1
  37. package/lib/ui/textarea/textarea.module.css +0 -7
  38. package/lib-esm/components/bundle-assets/bundle-assets.js +6 -4
  39. package/lib-esm/components/bundle-assets/bundle-assets.js.map +1 -1
  40. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js +5 -3
  41. package/lib-esm/components/bundle-assets-totals/bundle-assets-totals.js.map +1 -1
  42. package/lib-esm/components/bundle-modules/bundle-modules.js +5 -3
  43. package/lib-esm/components/bundle-modules/bundle-modules.js.map +1 -1
  44. package/lib-esm/components/bundle-packages/bundle-packages.js +5 -3
  45. package/lib-esm/components/bundle-packages/bundle-packages.js.map +1 -1
  46. package/lib-esm/components/insights/insights.module.css +1 -0
  47. package/lib-esm/components/metrics-table-export/metrics-table-export.js +11 -10
  48. package/lib-esm/components/metrics-table-export/metrics-table-export.js.map +1 -1
  49. package/lib-esm/components/metrics-table-options/metrics-table-options.js +7 -5
  50. package/lib-esm/components/metrics-table-options/metrics-table-options.js.map +1 -1
  51. package/lib-esm/components/metrics-table-options/metrics-table-options.module.css +5 -0
  52. package/lib-esm/components/preview-source/preview-source.js +8 -5
  53. package/lib-esm/components/preview-source/preview-source.js.map +1 -1
  54. package/lib-esm/components/preview-source/preview-source.module.css +12 -0
  55. package/lib-esm/css/variables.css +4 -0
  56. package/lib-esm/i18n.js +2 -0
  57. package/lib-esm/i18n.js.map +1 -1
  58. package/lib-esm/ui/dialog/dialog.module.css +3 -3
  59. package/lib-esm/ui/index.js +1 -0
  60. package/lib-esm/ui/index.js.map +1 -1
  61. package/lib-esm/ui/markdown/index.js +2 -0
  62. package/lib-esm/ui/markdown/index.js.map +1 -0
  63. package/lib-esm/ui/markdown/markdown.js +10 -0
  64. package/lib-esm/ui/markdown/markdown.js.map +1 -0
  65. package/lib-esm/ui/markdown/markdown.module.css +7 -0
  66. package/lib-esm/ui/skeleton/skeleton.module.css +3 -3
  67. package/lib-esm/ui/tabs/index.js +1 -1
  68. package/lib-esm/ui/tabs/index.js.map +1 -1
  69. package/lib-esm/ui/tabs/tabs.js +7 -19
  70. package/lib-esm/ui/tabs/tabs.js.map +1 -1
  71. package/lib-esm/ui/tabs/tabs.module.css +6 -5
  72. package/lib-esm/ui/textarea/textarea.js +2 -2
  73. package/lib-esm/ui/textarea/textarea.js.map +1 -1
  74. package/lib-esm/ui/textarea/textarea.module.css +0 -7
  75. package/package.json +11 -10
  76. package/src/components/bundle-assets/bundle-assets.jsx +16 -8
  77. package/src/components/bundle-assets-totals/bundle-assets-totals.jsx +11 -3
  78. package/src/components/bundle-modules/bundle-modules.tsx +11 -3
  79. package/src/components/bundle-packages/bundle-packages.jsx +11 -3
  80. package/src/components/insights/insights.module.css +1 -0
  81. package/src/components/metrics-table-export/metrics-table-export.tsx +28 -20
  82. package/src/components/metrics-table-options/metrics-table-options.module.css +5 -0
  83. package/src/components/metrics-table-options/metrics-table-options.tsx +14 -6
  84. package/src/components/preview-source/preview-source.module.css +12 -0
  85. package/src/components/preview-source/preview-source.stories.tsx +19 -1
  86. package/src/components/preview-source/preview-source.tsx +30 -21
  87. package/src/css/variables.css +4 -0
  88. package/src/i18n.js +2 -0
  89. package/src/ui/dialog/dialog.module.css +3 -3
  90. package/src/ui/index.js +1 -0
  91. package/src/ui/markdown/index.ts +1 -0
  92. package/src/ui/markdown/markdown.module.css +7 -0
  93. package/src/ui/markdown/markdown.stories.tsx +29 -0
  94. package/src/ui/markdown/markdown.tsx +24 -0
  95. package/src/ui/skeleton/skeleton.module.css +3 -3
  96. package/src/ui/tabs/index.ts +1 -0
  97. package/src/ui/tabs/tabs.module.css +6 -5
  98. package/src/ui/tabs/tabs.stories.tsx +25 -0
  99. package/src/ui/tabs/tabs.tsx +32 -0
  100. package/src/ui/textarea/textarea.module.css +0 -7
  101. package/src/ui/textarea/textarea.tsx +2 -8
  102. package/types/components/metrics-table-export/metrics-table-export.d.ts +1 -0
  103. package/types/components/metrics-table-options/metrics-table-options.d.ts +1 -1
  104. package/types/components/preview-source/preview-source.d.ts +2 -1
  105. package/types/i18n.d.ts +2 -0
  106. package/types/ui/index.d.ts +1 -0
  107. package/types/ui/markdown/index.d.ts +1 -0
  108. package/types/ui/markdown/markdown.d.ts +7 -0
  109. package/types/ui/tabs/index.d.ts +1 -1
  110. package/types/ui/tabs/tabs.d.ts +11 -41
  111. package/types/ui/textarea/textarea.d.ts +0 -1
  112. package/lib/components/metrics-table-export/metrics-table-export.module.css +0 -8
  113. package/lib-esm/components/metrics-table-export/metrics-table-export.module.css +0 -8
  114. package/src/components/metrics-table-export/metrics-table-export.module.css +0 -8
  115. package/src/ui/tabs/index.js +0 -1
  116. package/src/ui/tabs/tabs.jsx +0 -39
@@ -1 +1 @@
1
- {"version":3,"file":"preview-source.js","sourceRoot":"","sources":["../../../src/components/preview-source/preview-source.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,GAAG,MAAM,6BAA6B,CAAC;AAY9C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAyB,EAAE,EAAE;IACzD,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAEzE,OAAO,CACL,6BAAK,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,KAAM,SAAS;QACpD,oBAAC,YAAY,IAAC,SAAS,EAAE,GAAG,CAAC,OAAO;YAClC,oBAAC,eAAe,IAAC,OAAO,QAAC,IAAI,EAAC,OAAO,EAAC,IAAI,EAAE,MAAM,GAAI;YACrD,QAAQ,IAAI,CACX,oBAAC,OAAO,IAAC,KAAK,EAAE,YAAY,QAAQ,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,eAAe;gBACpE,oBAAC,MAAM,IACL,OAAO,QACP,UAAU,EAAE,aAAa,CAAC,QAAQ,EAClC,IAAI,EAAC,OAAO,EACZ,EAAE,EAAC,GAAG,EACN,IAAI,EAAE,yBAAyB,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAC3D,QAAQ,EAAE,QAAQ,GAClB,CACM,CACX,CACY;QACf,oBAAC,QAAQ,IAAC,aAAa,QAAC,QAAQ,QAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,IAC9D,MAAM,CACE,CACP,CACP,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"preview-source.js","sourceRoot":"","sources":["../../../src/components/preview-source/preview-source.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,GAAG,MAAM,6BAA6B,CAAC;AAE9C,MAAM,YAAY,GAAG,EAAE,CAAC;AAgBxB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAyB,EAAE,EAAE;IACzD,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,YAAY,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAE9F,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC;IACxB,MAAM,aAAa,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAEtE,OAAO,CACL,6BAAK,SAAS,EAAE,aAAa,KAAM,SAAS;QACzC,MAAM,IAAI,CACT,oBAAC,YAAY,IAAC,SAAS,EAAE,GAAG,CAAC,OAAO;YAClC,oBAAC,eAAe,IAAC,OAAO,QAAC,IAAI,EAAC,OAAO,EAAC,IAAI,EAAE,MAAM,GAAI;YACrD,QAAQ,IAAI,CACX,oBAAC,OAAO,IAAC,KAAK,EAAE,YAAY,QAAQ,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,eAAe;gBACpE,oBAAC,MAAM,IACL,OAAO,QACP,UAAU,EAAE,aAAa,CAAC,QAAQ,EAClC,IAAI,EAAC,OAAO,EACZ,EAAE,EAAC,GAAG,EACN,IAAI,EAAE,yBAAyB,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAC3D,QAAQ,EAAE,QAAQ,GAClB,CACM,CACX,CACY,CAChB;QACD,oBAAC,QAAQ,IAAC,QAAQ,QAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,GAAI,CACpE,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -7,6 +7,8 @@
7
7
  z-index: 2;
8
8
  top: var(--space-xsmall);
9
9
  right: var(--space-xsmall);
10
+ background: var(--color-background);
11
+ border-radius: var(--radius-medium);
10
12
  }
11
13
 
12
14
  /** fix control group with nested components */
@@ -21,8 +23,18 @@
21
23
  box-shadow: none;
22
24
  }
23
25
 
26
+ /** Source content */
24
27
  .content {
25
28
  position: relative;
26
29
  z-index: 1;
27
30
  height: 100%;
31
+ background: var(--color-highlight);
32
+ color: var(--color-text);
33
+ font-family: var(--font-family-fixed);
34
+ }
35
+
36
+ /** Empty / loading state */
37
+ .isEmpty .content {
38
+ pointer-events: none;
39
+ background: var(--color-highlight);
28
40
  }
@@ -201,6 +201,10 @@
201
201
 
202
202
  --outline-hover: 0 0 0 var(--space-xxxsmall) var(--color-highlight);
203
203
 
204
+ --skeleton-inline-background: linear-gradient(transparent 10%, currentColor 10.1%, currentColor 89.9%, transparent 90%);
205
+ --skeleton-block-background: currentColor;
206
+ --skeleton-opacity: 0.06;
207
+
204
208
  /** Layout */
205
209
  --max-width: 88rem;
206
210
  --entry-info-width: 64rem;
package/lib-esm/i18n.js CHANGED
@@ -15,6 +15,8 @@ export default {
15
15
  RESET_FILTERS: 'Reset filters',
16
16
  VIEW_ALL: 'View all entries',
17
17
  EXPORT: 'Export',
18
+ EXPORT_CSV: 'Export CSV',
19
+ EXPORT_JSON: 'Export JSON',
18
20
  COPY_TO_CLIPBOARD: 'Copy to clipboard',
19
21
  COPY_TO_CLIPBOARD_DONE: 'Copied to clipboard',
20
22
  GITHUB_LINK_TITLE: 'View BundleStats project on GitHub',
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.js"],"names":[],"mappings":"AAAA,eAAe;IACb,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,oBAAoB;IAClC,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IAEpB,OAAO,EAAE,oBAAoB;IAE7B,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IAEpB,SAAS,EAAE,WAAW;IAEtB,WAAW,EAAE,2DAA2D;IACxE,iBAAiB,EAAE,mEAAmE;IACtF,YAAY,EACV,uFAAuF;IACzF,aAAa,EACX,qGAAqG;IAEvG,aAAa,EAAE,eAAe;IAC9B,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,QAAQ;IAEhB,iBAAiB,EAAE,mBAAmB;IACtC,sBAAsB,EAAE,qBAAqB;IAE7C,iBAAiB,EAAE,oCAAoC;IACvD,YAAY,EAAE,cAAc;IAC5B,uBAAuB,EAAE,sBAAsB;IAC/C,cAAc,EAAE,kEAAkE;CACnF,CAAC"}
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.js"],"names":[],"mappings":"AAAA,eAAe;IACb,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,YAAY,EAAE,oBAAoB;IAClC,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IAEpB,OAAO,EAAE,oBAAoB;IAE7B,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IAEpB,SAAS,EAAE,WAAW;IAEtB,WAAW,EAAE,2DAA2D;IACxE,iBAAiB,EAAE,mEAAmE;IACtF,YAAY,EACV,uFAAuF;IACzF,aAAa,EACX,qGAAqG;IAEvG,aAAa,EAAE,eAAe;IAC9B,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,WAAW,EAAE,aAAa;IAE1B,iBAAiB,EAAE,mBAAmB;IACtC,sBAAsB,EAAE,qBAAqB;IAE7C,iBAAiB,EAAE,oCAAoC;IACvD,YAAY,EAAE,cAAc;IAC5B,uBAAuB,EAAE,sBAAsB;IAC/C,cAAc,EAAE,kEAAkE;CACnF,CAAC"}
@@ -61,11 +61,11 @@
61
61
 
62
62
  /** Width variation */
63
63
  .width--narrow {
64
- max-width: 480px;
64
+ max-width: 360px;
65
65
  }
66
66
 
67
67
  .width--medium {
68
- max-width: 748px;
68
+ max-width: 640px;
69
69
  }
70
70
 
71
71
  .width--wide {
@@ -73,7 +73,7 @@
73
73
  }
74
74
 
75
75
  .width--extra-wide {
76
- max-width: var(--max-width);
76
+ max-width: calc(var(--max-width) + 2 * var(--space-medium));
77
77
  }
78
78
 
79
79
  /** Center variation */
@@ -13,6 +13,7 @@ export { Icon } from './icon';
13
13
  export { Input } from './input';
14
14
  export { InputSearch } from './input-search';
15
15
  export { Loader } from './loader';
16
+ export { Markdown } from './markdown';
16
17
  export { Skeleton } from './skeleton';
17
18
  export { Table } from './table';
18
19
  export { Tabs } from './tabs';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './markdown';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/markdown/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
@@ -0,0 +1,10 @@
1
+ import React, { useMemo } from 'react';
2
+ import cx from 'classnames';
3
+ import snarkdown from 'snarkdown';
4
+ import css from './markdown.module.css';
5
+ export const Markdown = (props) => {
6
+ const { className = '', content = '', as: Component = 'div', ...restProps } = props;
7
+ const html = useMemo(() => snarkdown(content), [content]);
8
+ return (React.createElement(Component, { className: cx(css.root, className), ...restProps, dangerouslySetInnerHTML: { __html: html } }));
9
+ };
10
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/ui/markdown/markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAA+B,OAAO,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,GAAG,MAAM,uBAAuB,CAAC;AAOxC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAoB,EAAE,EAAE;IAC/C,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAEpF,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAE1D,OAAO,CACL,oBAAC,SAAS,IACR,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,KAC9B,SAAS,EACb,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GACzC,CACH,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ .root code {
2
+ padding: 2px var(--space-xxxsmall);
3
+ background: var(--color-highlight);
4
+ outline: 1px solid var(--color-outline);
5
+ border-radius: var(--radius-small);
6
+ color: var(--color-text);
7
+ }
@@ -1,6 +1,6 @@
1
1
  .root {
2
- background: linear-gradient(transparent 10%, currentColor 10.1%, currentColor 89.9%, transparent 90%);
3
- opacity: 0.05;
2
+ background: var(--skeleton-inline-background);
3
+ opacity: var(--skeleton-opacity);
4
4
  pointer-events: none;
5
5
  min-width: 6em;
6
6
  border-radius: var(--radius-medium);
@@ -14,5 +14,5 @@
14
14
  }
15
15
 
16
16
  .block {
17
- background: currentColor;
17
+ background: var(--skeleton-block-background);
18
18
  }
@@ -1,2 +1,2 @@
1
- export { Tabs } from './tabs';
1
+ export * from './tabs';
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/tabs/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/tabs/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
@@ -1,25 +1,13 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import cx from 'classnames';
4
3
  import css from './tabs.module.css';
5
- const Item = ({ isTabActive, as: Component = 'span', className = '', ...restProps }) => (React.createElement(Component, { className: cx(css.item, className, isTabActive && css.itemActive), ...restProps }));
6
- Item.defaultProps = {
7
- isTabActive: false,
8
- className: '',
9
- as: 'span',
4
+ export const TabItem = (props) => {
5
+ const { className = '', as: Component = 'button', isTabActive = false, ...restProps } = props;
6
+ return (React.createElement(Component, { role: "tab", className: cx(css.item, className, isTabActive && css.itemActive), ...restProps }));
10
7
  };
11
- Item.propTypes = {
12
- isTabActive: PropTypes.bool,
13
- className: PropTypes.string,
14
- as: PropTypes.elementType,
8
+ export const Tabs = (props) => {
9
+ const { className = '', ...restProps } = props;
10
+ return React.createElement("div", { role: "tablist", className: cx(css.root, className), ...restProps });
15
11
  };
16
- export const Tabs = ({ className = '', ...restProps }) => (React.createElement("nav", { className: cx(css.root, className), ...restProps }));
17
- Tabs.defaultProps = {
18
- className: '',
19
- };
20
- Tabs.propTypes = {
21
- className: PropTypes.string,
22
- children: PropTypes.node.isRequired,
23
- };
24
- Tabs.Item = Item;
12
+ Tabs.Item = TabItem;
25
13
  //# sourceMappingURL=tabs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/ui/tabs/tabs.jsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,GAAG,MAAM,mBAAmB,CAAC;AAEpC,MAAM,IAAI,GAAG,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,GAAG,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,CAAC,CACtF,oBAAC,SAAS,IAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,IAAI,GAAG,CAAC,UAAU,CAAC,KAAM,SAAS,GAAI,CAChG,CAAC;AAEF,IAAI,CAAC,YAAY,GAAG;IAClB,WAAW,EAAE,KAAK;IAClB,SAAS,EAAE,EAAE;IACb,EAAE,EAAE,MAAM;CACX,CAAC;AAEF,IAAI,CAAC,SAAS,GAAG;IACf,WAAW,EAAE,SAAS,CAAC,IAAI;IAC3B,SAAS,EAAE,SAAS,CAAC,MAAM;IAC3B,EAAE,EAAE,SAAS,CAAC,WAAW;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,CAAC,CACxD,6BAAK,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,KAAM,SAAS,GAAI,CAC3D,CAAC;AAEF,IAAI,CAAC,YAAY,GAAG;IAClB,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,IAAI,CAAC,SAAS,GAAG;IAEf,SAAS,EAAE,SAAS,CAAC,MAAM;IAG3B,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU;CACpC,CAAC;AAEF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/ui/tabs/tabs.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,GAAG,MAAM,mBAAmB,CAAC;AAOpC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAmC,KAAsB,EAAE,EAAE;IAClF,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,EAAE,EAAE,SAAS,GAAG,QAAQ,EAAE,WAAW,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAE9F,OAAO,CACL,oBAAC,SAAS,IACR,IAAI,EAAC,KAAK,EACV,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,IAAI,GAAG,CAAC,UAAU,CAAC,KAC7D,SAAS,GACb,CACH,CAAC;AACJ,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAgB,EAAE,EAAE;IACvC,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAE/C,OAAO,6BAAK,IAAI,EAAC,SAAS,EAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,KAAM,SAAS,GAAI,CAAC;AACnF,CAAC,CAAC;AAEF,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC"}
@@ -4,12 +4,16 @@
4
4
  }
5
5
 
6
6
  .item {
7
+ appearance: none;
8
+ background: none;
9
+ border: 0;
7
10
  position: relative;
8
11
  display: inline-block;
9
12
  padding: var(--space-xsmall) var(--space-small);
10
13
  color: var(--color-text-ultra-light);
11
14
  font-weight: bold;
12
15
  text-decoration: none;
16
+ transition: var(--ui-transition-out);
13
17
  }
14
18
 
15
19
  .item::after {
@@ -26,8 +30,9 @@
26
30
  .item:hover,
27
31
  .item:active,
28
32
  .item:focus {
29
- color: var(--color-primary-dark);
33
+ color: var(--color-primary);
30
34
  outline: none;
35
+ transition: var(--ui-transition-out);
31
36
  }
32
37
 
33
38
  .item:hover::after,
@@ -43,7 +48,3 @@
43
48
  .itemActive::after {
44
49
  background: currentColor;
45
50
  }
46
-
47
- .item + .item {
48
- _margin-left: var(--space-medium);
49
- }
@@ -2,8 +2,8 @@ import React from 'react';
2
2
  import cx from 'classnames';
3
3
  import css from './textarea.module.css';
4
4
  export const Textarea = (props) => {
5
- const { className = '', previewSource = false, size = '', ...restProps } = props;
6
- const rootClassName = cx(css.root, previewSource && css.previewSource, size && css[size], className);
5
+ const { className = '', size = '', ...restProps } = props;
6
+ const rootClassName = cx(css.root, size && css[size], className);
7
7
  return React.createElement("textarea", { className: rootClassName, ...restProps });
8
8
  };
9
9
  //# sourceMappingURL=textarea.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/ui/textarea/textarea.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,GAAG,MAAM,uBAAuB,CAAC;AAOxC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAoB,EAAE,EAAE;IAC/C,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,aAAa,GAAG,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAEjF,MAAM,aAAa,GAAG,EAAE,CACtB,GAAG,CAAC,IAAI,EACR,aAAa,IAAI,GAAG,CAAC,aAAa,EAClC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,EACjB,SAAS,CACV,CAAC;IAEF,OAAO,kCAAU,SAAS,EAAE,aAAa,KAAM,SAAS,GAAI,CAAC;AAC/D,CAAC,CAAC"}
1
+ {"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../../src/ui/textarea/textarea.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,GAAG,MAAM,uBAAuB,CAAC;AAMxC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAoB,EAAE,EAAE;IAC/C,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,IAAI,GAAG,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAE1D,MAAM,aAAa,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IAEjE,OAAO,kCAAU,SAAS,EAAE,aAAa,KAAM,SAAS,GAAI,CAAC;AAC/D,CAAC,CAAC"}
@@ -36,13 +36,6 @@
36
36
  color: var(--color-text-light);
37
37
  }
38
38
 
39
- /**
40
- * Source variation
41
- */
42
- .previewSource {
43
- font-family: var(--font-family-fixed);
44
- }
45
-
46
39
  /** Size modifier */
47
40
  /* default - medium */
48
41
  .root {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bundle-stats/ui",
3
- "version": "4.16.0-beta.1",
3
+ "version": "4.16.0-beta.11",
4
4
  "description": "UI components for BundleStats projects.",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",
@@ -39,10 +39,10 @@
39
39
  "@babel/preset-env": "7.25.7",
40
40
  "@babel/preset-react": "7.25.7",
41
41
  "@babel/preset-typescript": "7.25.7",
42
- "@storybook/addon-essentials": "8.3.4",
42
+ "@storybook/addon-essentials": "8.3.5",
43
43
  "@storybook/addon-webpack5-compiler-babel": "3.0.3",
44
- "@storybook/react": "8.3.4",
45
- "@storybook/react-webpack5": "8.3.4",
44
+ "@storybook/react": "8.3.5",
45
+ "@storybook/react-webpack5": "8.3.5",
46
46
  "@types/d3": "7.4.3",
47
47
  "@types/react": "18.3.11",
48
48
  "@types/react-router-dom": "5.3.3",
@@ -61,8 +61,8 @@
61
61
  "react-dom": "18.3.1",
62
62
  "react-router-dom": "5.3.4",
63
63
  "rimraf": "6.0.1",
64
- "storybook": "8.3.4",
65
- "typescript": "5.6.2",
64
+ "storybook": "8.3.5",
65
+ "typescript": "5.6.3",
66
66
  "typescript-plugin-css-modules": "5.1.0"
67
67
  },
68
68
  "peerDependencies": {
@@ -74,12 +74,13 @@
74
74
  "react-router-dom": "^5.0.0"
75
75
  },
76
76
  "dependencies": {
77
- "@bundle-stats/utils": "^4.16.0-beta.1",
77
+ "@bundle-stats/utils": "^4.16.0-beta.11",
78
78
  "ariakit": "2.0.0-next.44",
79
- "d3": "^7.8.5",
79
+ "d3": "7.9.0",
80
80
  "modern-css-reset": "1.4.0",
81
- "react-use": "^17.5.0",
81
+ "react-use": "17.5.1",
82
+ "snarkdown": "2.0.0",
82
83
  "use-query-params": "2.2.1"
83
84
  },
84
- "gitHead": "db71907f2916c3bc5f4367041f4368a8f0a47c17"
85
+ "gitHead": "aa941593c1a41262e8b90fb53d74b9ade61e9b7d"
85
86
  }
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useMemo } from 'react';
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import cx from 'classnames';
4
4
  import get from 'lodash/get';
@@ -52,10 +52,10 @@ const DISPLAY_TYPE_GROUPS = {
52
52
 
53
53
  const getFileTypeFilters = (filters) =>
54
54
  Object.entries(FILE_TYPE_LABELS).map(([key, label]) => ({
55
- key,
56
- label,
57
- defaultValue: get(filters, `${ASSET_FILE_TYPE}.${key}`, true),
58
- }));
55
+ key,
56
+ label,
57
+ defaultValue: get(filters, `${ASSET_FILE_TYPE}.${key}`, true),
58
+ }));
59
59
 
60
60
  const getFilters = ({ compareMode, filters }) => ({
61
61
  [ASSET_FILTERS.CHANGED]: {
@@ -64,7 +64,7 @@ const getFilters = ({ compareMode, filters }) => ({
64
64
  disabled: !compareMode,
65
65
  },
66
66
  [ASSET_ENTRY_TYPE]: {
67
- label: 'Entry type',
67
+ label: 'Type',
68
68
  children: [
69
69
  {
70
70
  key: ASSET_FILTERS.ENTRY,
@@ -316,8 +316,10 @@ export const BundleAssets = (props) => {
316
316
  }, [allItems, entryId]);
317
317
 
318
318
  const exportDialog = useDialogState();
319
+ const [exportSourceType, setExportSourceType] = useState(undefined);
319
320
 
320
- const handleExportClick = useCallback(() => {
321
+ const handleExportClick = useCallback((sourceType) => {
322
+ setExportSourceType(sourceType);
321
323
  exportDialog.toggle();
322
324
  }, []);
323
325
 
@@ -396,7 +398,13 @@ export const BundleAssets = (props) => {
396
398
  )}
397
399
 
398
400
  <Dialog title={I18N.EXPORT} width="wide" state={exportDialog}>
399
- {exportDialog.open && <MetricsTableExport items={items} download="bundle-stats--assets"/>}
401
+ {exportDialog.open && (
402
+ <MetricsTableExport
403
+ items={items}
404
+ initialSourceType={exportSourceType}
405
+ download="bundle-stats--assets"
406
+ />
407
+ )}
400
408
  </Dialog>
401
409
  </>
402
410
  );
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useMemo } from 'react';
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useHistory } from 'react-router-dom';
4
4
  import {
@@ -73,8 +73,10 @@ export const BundleAssetsTotals = ({
73
73
  );
74
74
 
75
75
  const exportDialog = useDialogState();
76
+ const [exportSourceType, setExportSourceType] = useState(undefined);
76
77
 
77
- const handleExportClick = useCallback(() => {
78
+ const handleExportClick = useCallback((sourceType) => {
79
+ setExportSourceType(sourceType);
78
80
  exportDialog.toggle();
79
81
  }, []);
80
82
 
@@ -120,7 +122,13 @@ export const BundleAssetsTotals = ({
120
122
  </Stack>
121
123
 
122
124
  <Dialog title={I18N.EXPORT} width="wide" state={exportDialog}>
123
- {exportDialog.open && <MetricsTableExport items={items} download="bundle-stats--totals" />}
125
+ {exportDialog.open && (
126
+ <MetricsTableExport
127
+ items={items}
128
+ initialSourceType={exportSourceType}
129
+ download="bundle-stats--totals"
130
+ />
131
+ )}
124
132
  </Dialog>
125
133
  </>
126
134
  );
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useMemo } from 'react';
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
2
  import cx from 'classnames';
3
3
  import { SECTIONS, COMPONENT, type Job, ReportMetricRow } from '@bundle-stats/utils';
4
4
  import escapeRegExp from 'lodash/escapeRegExp';
@@ -255,8 +255,10 @@ export const BundleModules = (props: BundleModulesProps) => {
255
255
  }, [allItems, entryId]);
256
256
 
257
257
  const exportDialog = useDialogState();
258
+ const [exportSourceType, setExportSourceType] = useState<string | undefined>(undefined);
258
259
 
259
- const handleExportClick = useCallback(() => {
260
+ const handleExportClick = useCallback((sourceType: string) => {
261
+ setExportSourceType(sourceType);
260
262
  exportDialog.toggle();
261
263
  }, []);
262
264
 
@@ -374,7 +376,13 @@ export const BundleModules = (props: BundleModulesProps) => {
374
376
  )}
375
377
 
376
378
  <Dialog title={I18N.EXPORT} width="wide" state={exportDialog}>
377
- {exportDialog.open && <MetricsTableExport items={items} download="bundle-stats--modules"/>}
379
+ {exportDialog.open && (
380
+ <MetricsTableExport
381
+ items={items}
382
+ initialSourceType={exportSourceType}
383
+ download="bundle-stats--modules"
384
+ />
385
+ )}
378
386
  </Dialog>
379
387
  </>
380
388
  );
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useMemo } from 'react';
1
+ import React, { useCallback, useMemo, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import cx from 'classnames';
4
4
  import escapeRegExp from 'lodash/escapeRegExp';
@@ -264,8 +264,10 @@ export const BundlePackages = (props) => {
264
264
  }, [allItems, entryId]);
265
265
 
266
266
  const exportDialog = useDialogState();
267
+ const [exportSourceType, setExportSourceType] = useState(undefined);
267
268
 
268
- const handleExportClick = useCallback(() => {
269
+ const handleExportClick = useCallback((sourceType) => {
270
+ setExportSourceType(sourceType);
269
271
  exportDialog.toggle();
270
272
  }, []);
271
273
 
@@ -338,7 +340,13 @@ export const BundlePackages = (props) => {
338
340
  )}
339
341
 
340
342
  <Dialog title={I18N.EXPORT} width="wide" state={exportDialog}>
341
- {exportDialog.open && <MetricsTableExport items={items} download="bundle-stats--packages"/>}
343
+ {exportDialog.open && (
344
+ <MetricsTableExport
345
+ items={items}
346
+ initialSourceType={exportSourceType}
347
+ download="bundle-stats--packages"
348
+ />
349
+ )}
342
350
  </Dialog>
343
351
  </>
344
352
  );
@@ -4,6 +4,7 @@
4
4
 
5
5
  .entry {
6
6
  color: inherit;
7
+ line-height: var(--line-height-heading);
7
8
  text-decoration: none;
8
9
  }
9
10
 
@@ -3,9 +3,8 @@ import React, { useState } from 'react';
3
3
  import type { ReportMetricRow } from '@bundle-stats/utils';
4
4
 
5
5
  import { Stack } from '../../layout/stack';
6
- import { Tabs } from '../../ui/tabs';
6
+ import { Tabs, TabItem } from '../../ui/tabs';
7
7
  import { PreviewSource } from '../preview-source';
8
- import css from './metrics-table-export.module.css';
9
8
 
10
9
  const generateSourceJSON = (items: Array<ReportMetricRow>): string => {
11
10
  const output = items.map((item) => ({
@@ -50,49 +49,58 @@ const generateSourceCSV = (items: Array<ReportMetricRow>): string => {
50
49
  return output.join('\r');
51
50
  };
52
51
 
53
- const SOURCES = [
54
- {
52
+ const SOURCES = {
53
+ csv: {
55
54
  label: 'CSV',
56
55
  transformFn: generateSourceCSV,
57
56
  extension: '.csv',
58
57
  },
59
- {
58
+ json: {
60
59
  label: 'JSON',
61
60
  transformFn: generateSourceJSON,
62
61
  extension: '.json',
63
62
  },
64
- ];
63
+ };
64
+
65
+ const SOURCE_ENTRIES = Object.entries(SOURCES);
66
+ const SOURCE_KEYS = Object.keys(SOURCES);
65
67
 
66
68
  type MetricsTableExportProps = {
67
69
  items: Array<ReportMetricRow>;
70
+ initialSourceType?: string;
68
71
  download: string;
69
72
  } & ComponentProps<typeof Stack>;
70
73
 
71
74
  export const MetricsTableExport = (props: MetricsTableExportProps) => {
72
- const { items, download, ...restProps } = props;
73
- const [selectedId, setSelectedId] = useState(SOURCES[0].label);
75
+ const { initialSourceType = SOURCE_KEYS[0], items, download, ...restProps } = props;
76
+ const [selectedSourceType, setSelectedSourceType] = useState(initialSourceType);
74
77
 
75
78
  return (
76
79
  <Stack space="small" {...restProps}>
77
80
  <Tabs>
78
- {SOURCES.map((source) => (
79
- <Tabs.Item
80
- onClick={() => setSelectedId(source.label)}
81
- isTabActive={selectedId === source.label}
82
- key={source.label}
81
+ {SOURCE_ENTRIES.map(([sourceId, source]) => (
82
+ <TabItem
83
+ onClick={() => setSelectedSourceType(sourceId)}
84
+ isTabActive={selectedSourceType === sourceId}
85
+ id={`metrics-table-export-tab-${sourceId}`}
86
+ aria-controls={`metrics-table-export-panel-${sourceId}`}
87
+ key={sourceId}
83
88
  >
84
89
  {source.label}
85
- </Tabs.Item>
90
+ </TabItem>
86
91
  ))}
87
92
  </Tabs>
88
- <div className={css.panels}>
89
- {SOURCES.map(
90
- (source) =>
91
- selectedId === source.label && (
93
+ <div>
94
+ {SOURCE_ENTRIES.map(
95
+ ([sourceId, source]) =>
96
+ selectedSourceType === sourceId && (
92
97
  <PreviewSource
93
98
  source={source.transformFn(items)}
94
- download={`${download}.${source.extension}`}
95
- className={css.panel}
99
+ rows={20}
100
+ download={`${download}${source.extension}`}
101
+ role="tabpanel"
102
+ id={`metrics-table-export-panel-${sourceId}`}
103
+ aria-labelledby={`metrics-table-export-tab-${sourceId}`}
96
104
  key={source.label}
97
105
  />
98
106
  ),
@@ -0,0 +1,5 @@
1
+ :not(.group:empty) ~ .group {
2
+ margin-top: calc(var(--space-xxxsmall) / 2);
3
+ padding-top: calc(var(--space-xxxsmall) / 2);
4
+ border-top: 1px solid var(--color-outline);
5
+ }
@@ -3,12 +3,12 @@ import React from 'react';
3
3
 
4
4
  import I18N from '../../i18n';
5
5
  import { Dropdown, DropdownItem } from '../../ui/dropdown';
6
- import { Separator } from '../../layout/separator';
6
+ import css from './metrics-table-options.module.css';
7
7
 
8
8
  type MetricsTableOptionsProps = {
9
9
  onViewAllClick?: () => void;
10
10
  onResetClick?: () => void;
11
- onExportClick?: () => void;
11
+ onExportClick?: (sourceType: string) => void;
12
12
  } & ComponentProps<typeof Dropdown>;
13
13
 
14
14
  export const MetricsTableOptions = (props: MetricsTableOptionsProps) => {
@@ -16,10 +16,18 @@ export const MetricsTableOptions = (props: MetricsTableOptionsProps) => {
16
16
 
17
17
  return (
18
18
  <Dropdown glyph="more-vertical" {...restProps}>
19
- {onResetClick && <DropdownItem onClick={onResetClick}>{I18N.RESET_FILTERS}</DropdownItem>}
20
- {onViewAllClick && <DropdownItem onClick={onViewAllClick}>{I18N.VIEW_ALL}</DropdownItem>}
21
- {((onResetClick || onViewAllClick) && onExportClick) && <Separator />}
22
- {onExportClick && <DropdownItem onClick={onExportClick}>{I18N.EXPORT}</DropdownItem>}
19
+ <div className={css.group}>
20
+ {onResetClick && <DropdownItem onClick={onResetClick}>{I18N.RESET_FILTERS}</DropdownItem>}
21
+ {onViewAllClick && <DropdownItem onClick={onViewAllClick}>{I18N.VIEW_ALL}</DropdownItem>}
22
+ </div>
23
+ <div className={css.group}>
24
+ {onExportClick && (
25
+ <>
26
+ <DropdownItem onClick={() => onExportClick('csv')}>{I18N.EXPORT_CSV}</DropdownItem>
27
+ <DropdownItem onClick={() => onExportClick('json')}>{I18N.EXPORT_JSON}</DropdownItem>
28
+ </>
29
+ )}
30
+ </div>
23
31
  </Dropdown>
24
32
  );
25
33
  };