react-science 11.2.0 → 12.1.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 (76) hide show
  1. package/lib/components/accordion/accordion.js +1 -0
  2. package/lib/components/accordion/accordion.js.map +1 -1
  3. package/lib/components/forms/index.d.ts +1 -1
  4. package/lib/components/forms/index.d.ts.map +1 -1
  5. package/lib/components/forms/index.js +1 -1
  6. package/lib/components/forms/index.js.map +1 -1
  7. package/lib/components/forms/radio-button-group/RadioButton.d.ts +4 -0
  8. package/lib/components/forms/radio-button-group/RadioButton.d.ts.map +1 -0
  9. package/lib/components/forms/radio-button-group/RadioButton.js +53 -0
  10. package/lib/components/forms/radio-button-group/RadioButton.js.map +1 -0
  11. package/lib/components/forms/radio-button-group/RadioButtonGroup.d.ts +7 -0
  12. package/lib/components/forms/radio-button-group/RadioButtonGroup.d.ts.map +1 -0
  13. package/lib/components/forms/radio-button-group/RadioButtonGroup.js +41 -0
  14. package/lib/components/forms/radio-button-group/RadioButtonGroup.js.map +1 -0
  15. package/lib/components/forms/radio-button-group/index.d.ts +3 -0
  16. package/lib/components/forms/radio-button-group/index.d.ts.map +1 -0
  17. package/lib/components/forms/radio-button-group/index.js +3 -0
  18. package/lib/components/forms/radio-button-group/index.js.map +1 -0
  19. package/lib/components/forms/utils/use_input_id.d.ts +2 -0
  20. package/lib/components/forms/utils/use_input_id.d.ts.map +1 -0
  21. package/lib/components/forms/utils/use_input_id.js +9 -0
  22. package/lib/components/forms/utils/use_input_id.js.map +1 -0
  23. package/lib/components/hooks/index.d.ts +0 -1
  24. package/lib/components/hooks/index.d.ts.map +1 -1
  25. package/lib/components/hooks/index.js +0 -1
  26. package/lib/components/hooks/index.js.map +1 -1
  27. package/lib/components/info-panel/InfoPanel.d.ts.map +1 -1
  28. package/lib/components/info-panel/InfoPanel.js +32 -43
  29. package/lib/components/info-panel/InfoPanel.js.map +1 -1
  30. package/lib/components/root-layout/root_layout.d.ts.map +1 -1
  31. package/lib/components/root-layout/root_layout.js +1 -3
  32. package/lib/components/root-layout/root_layout.js.map +1 -1
  33. package/lib/components/table/table_header_cell.d.ts.map +1 -1
  34. package/lib/components/table/table_header_cell.js +29 -13
  35. package/lib/components/table/table_header_cell.js.map +1 -1
  36. package/lib/components/table/table_root.d.ts +9 -0
  37. package/lib/components/table/table_root.d.ts.map +1 -1
  38. package/lib/components/table/table_root.js +37 -5
  39. package/lib/components/table/table_root.js.map +1 -1
  40. package/package.json +3 -6
  41. package/src/components/accordion/accordion.tsx +1 -0
  42. package/src/components/forms/index.ts +1 -1
  43. package/src/components/forms/radio-button-group/RadioButton.tsx +73 -0
  44. package/src/components/forms/radio-button-group/RadioButtonGroup.tsx +80 -0
  45. package/src/components/forms/radio-button-group/index.ts +2 -0
  46. package/src/components/forms/utils/use_input_id.ts +13 -0
  47. package/src/components/hooks/index.ts +0 -1
  48. package/src/components/info-panel/InfoPanel.tsx +51 -56
  49. package/src/components/root-layout/root_layout.tsx +1 -5
  50. package/src/components/table/table_header_cell.tsx +53 -23
  51. package/src/components/table/table_root.tsx +49 -4
  52. package/lib/components/forms/radio-group/ButtonRadioItem.d.ts +0 -3
  53. package/lib/components/forms/radio-group/ButtonRadioItem.d.ts.map +0 -1
  54. package/lib/components/forms/radio-group/ButtonRadioItem.js +0 -50
  55. package/lib/components/forms/radio-group/ButtonRadioItem.js.map +0 -1
  56. package/lib/components/forms/radio-group/RadioGroup.d.ts +0 -18
  57. package/lib/components/forms/radio-group/RadioGroup.d.ts.map +0 -1
  58. package/lib/components/forms/radio-group/RadioGroup.js +0 -38
  59. package/lib/components/forms/radio-group/RadioGroup.js.map +0 -1
  60. package/lib/components/forms/radio-group/index.d.ts +0 -2
  61. package/lib/components/forms/radio-group/index.d.ts.map +0 -1
  62. package/lib/components/forms/radio-group/index.js +0 -2
  63. package/lib/components/forms/radio-group/index.js.map +0 -1
  64. package/lib/components/hooks/useModifiedPopper.d.ts +0 -13
  65. package/lib/components/hooks/useModifiedPopper.d.ts.map +0 -1
  66. package/lib/components/hooks/useModifiedPopper.js +0 -48
  67. package/lib/components/hooks/useModifiedPopper.js.map +0 -1
  68. package/lib/components/root-layout/query_client.d.ts +0 -3
  69. package/lib/components/root-layout/query_client.d.ts.map +0 -1
  70. package/lib/components/root-layout/query_client.js +0 -11
  71. package/lib/components/root-layout/query_client.js.map +0 -1
  72. package/src/components/forms/radio-group/ButtonRadioItem.tsx +0 -78
  73. package/src/components/forms/radio-group/RadioGroup.tsx +0 -75
  74. package/src/components/forms/radio-group/index.ts +0 -1
  75. package/src/components/hooks/useModifiedPopper.ts +0 -77
  76. package/src/components/root-layout/query_client.ts +0 -11
@@ -1 +1 @@
1
- {"version":3,"file":"table_root.js","sourceRoot":"","sources":["../../../src/components/table/table_root.tsx"],"names":[],"mappings":";AAAA,sCAAsC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAErC,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,yFAAyF;AACzF,kFAAkF;AAClF,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,EAAE;IACxC,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS;CAChD,CAAC,CAAA;;kBAEgB,CAAC,KAAK,EAAE,EAAE,CACtB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,SAAS;;CAE5D,CAAC;AAyEF,MAAM,UAAU,KAAK,CAAwB,KAAwB;IACnE,MAAM,EACJ,IAAI,EACJ,OAAO,EAEP,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,WAAW,GAAG,KAAK,EACnB,OAAO,GAAG,KAAK,EACf,YAAY,GAAG,KAAK,EAEpB,UAAU,EACV,UAAU,EACV,WAAW,EACX,gBAAgB,EAEhB,cAAc,GACf,GAAG,KAAK,CAAC;IAEV,MAAM,gBAAgB,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,aAAa,CAAQ;QACjC,GAAG,UAAU;QACb,IAAI;QACJ,OAAO,EAAE,UAAU;QACnB,eAAe,EAAE,eAAe,EAAE;QAClC,iBAAiB,EAAE,iBAAiB,EAAE;KACvC,CAAC,CAAC;IAEH,MAAM,mBAAmB,GAAG,cAAc,CAAC;QACzC,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,gBAAgB,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO;QAChD,YAAY,EACV,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACjE,QAAQ,EAAE,CAAC;KACZ,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,SAAS,IAAC,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,YACpE,MAAC,eAAe,IACd,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO,KACZ,UAAU,aAEd,KAAC,WAAW,IACV,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,KAAK,CAAC,cAAc,EAAE,EAC/B,gBAAgB,EAAE,gBAAgB,GAClC,EACF,KAAC,SAAS,IACR,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAC9B,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,mBAAmB,EAChC,cAAc,EAAE,cAAc,GAC9B,IACc,GACR,CACb,CAAC;AACJ,CAAC;AAED,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA;;;CAG9B,CAAC;AAEF,SAAS,SAAS,CAAC,EACjB,cAAc,EACd,SAAS,EACT,QAAQ,GAKT;IACC,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,KAAC,YAAY,IAAC,GAAG,EAAE,SAAS,YAAG,QAAQ,GAAgB,CAAC;IACjE,CAAC;IACD,OAAO,4BAAG,QAAQ,GAAI,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"table_root.js","sourceRoot":"","sources":["../../../src/components/table/table_root.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-science",
3
- "version": "11.2.0",
3
+ "version": "12.1.0",
4
4
  "description": "React components to build scientific applications UI",
5
5
  "type": "module",
6
6
  "exports": {
@@ -56,10 +56,6 @@
56
56
  "@blueprintjs/select": "^5.3.5",
57
57
  "@emotion/react": "^11.13.5",
58
58
  "@emotion/styled": "^11.13.5",
59
- "@popperjs/core": "^2.11.8",
60
- "@radix-ui/react-collapsible": "^1.1.1",
61
- "@radix-ui/react-radio-group": "^1.2.1",
62
- "@tanstack/react-query": "^5.61.5",
63
59
  "@tanstack/react-table": "^8.20.5",
64
60
  "@tanstack/react-virtual": "^3.10.9",
65
61
  "d3-scale-chromatic": "^3.1.0",
@@ -68,7 +64,6 @@
68
64
  "react-dropzone": "14.3.5",
69
65
  "react-icons": "^5.3.0",
70
66
  "react-inspector": "^6.0.2",
71
- "react-popper": "^2.3.0",
72
67
  "tinycolor2": "^1.6.0",
73
68
  "ts-pattern": "^5.5.0",
74
69
  "use-resize-observer": "^9.1.0"
@@ -76,6 +71,7 @@
76
71
  "devDependencies": {
77
72
  "@blueprintjs/core": "^5.16.0",
78
73
  "@blueprintjs/icons": "^5.15.0",
74
+ "@floating-ui/react": "^0.26.28",
79
75
  "@playwright/experimental-ct-react": "^1.49.0",
80
76
  "@playwright/test": "^1.49.0",
81
77
  "@storybook/addon-essentials": "^8.4.5",
@@ -83,6 +79,7 @@
83
79
  "@storybook/blocks": "^8.4.5",
84
80
  "@storybook/react": "^8.4.5",
85
81
  "@storybook/react-vite": "^8.4.5",
82
+ "@tanstack/react-query": "^5.62.3",
86
83
  "@types/babel__core": "^7.20.5",
87
84
  "@types/d3-scale-chromatic": "^3.1.0",
88
85
  "@types/lodash": "^4.17.13",
@@ -93,6 +93,7 @@ Accordion.Item = function AccordionItem(props: AccordionItemProps) {
93
93
  flex: item?.isOpen ? '1 1 1px' : 'none',
94
94
  display: 'flex',
95
95
  flexDirection: 'column',
96
+ isolation: 'isolate',
96
97
  }}
97
98
  >
98
99
  <div
@@ -1 +1 @@
1
- export * from './radio-group/index.js';
1
+ export * from './radio-button-group/index.js';
@@ -0,0 +1,73 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import type { RadioProps } from '@blueprintjs/core';
3
+ import styled from '@emotion/styled';
4
+
5
+ import { enabledColor } from '../styles.js';
6
+ import { useInputId } from '../utils/use_input_id.js';
7
+
8
+ const HiddenInput = styled.input`
9
+ // Those styles are taken from the sr-only class in tailwind CSS.
10
+ position: absolute;
11
+ width: 1px;
12
+ height: 1px;
13
+ padding: 0;
14
+ margin: -1px;
15
+ overflow: hidden;
16
+ clip: rect(0, 0, 0, 0);
17
+ white-space: nowrap;
18
+ border-width: 0;
19
+
20
+ // Label associated with the checked input
21
+ &:checked + label {
22
+ color: ${enabledColor};
23
+ border-color: ${enabledColor};
24
+ opacity: ${(props) => (props.disabled ? 0.25 : 1)};
25
+ border-width: 1px;
26
+ }
27
+
28
+ // Next label after the one that is checked
29
+ &:checked + label + input + label {
30
+ border-left-width: 0;
31
+ }
32
+ `;
33
+
34
+ const RadioContent = styled.div<{ large?: boolean }>`
35
+ place-content: center;
36
+ padding: ${(props) => (props.large ? '0px 15px' : '0px 7px')};
37
+ line-height: 0;
38
+ `;
39
+
40
+ const Label = styled.label<{ large?: boolean; disabled?: boolean }>`
41
+ display: flex;
42
+ height: ${(props) => (props.large ? '40px' : '30px')};
43
+ opacity: ${(props) => (props.disabled ? 0.25 : 1)};
44
+ border-width: 1px 0 1px 1px;
45
+ border-color: rgba(0, 0, 0, ${(props) => (props.disabled ? 1 : 0.25)});
46
+ border-style: solid;
47
+ cursor: ${(props) => (props.disabled ? 'not-allowed' : 'pointer')};
48
+ white-space: nowrap;
49
+ &:hover {
50
+ color: ${enabledColor};
51
+ }
52
+ `;
53
+
54
+ export function RadioButton(props: RadioProps) {
55
+ const { large, disabled, label, name, value, id, checked, onChange } = props;
56
+ const uniqId = useInputId(id, name);
57
+ return (
58
+ <>
59
+ <HiddenInput
60
+ checked={checked}
61
+ id={uniqId}
62
+ name={name}
63
+ value={value}
64
+ type="radio"
65
+ disabled={disabled}
66
+ onChange={onChange}
67
+ />
68
+ <Label large={large} disabled={disabled} htmlFor={uniqId}>
69
+ <RadioContent large={large}>{label}</RadioContent>
70
+ </Label>
71
+ </>
72
+ );
73
+ }
@@ -0,0 +1,80 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import type { RadioGroupProps } from '@blueprintjs/core';
3
+ import { RadioGroup } from '@blueprintjs/core';
4
+ import styled from '@emotion/styled';
5
+ import { Children, cloneElement } from 'react';
6
+
7
+ import { RadioButton } from './RadioButton.js';
8
+
9
+ export interface RadioButtonGroupProps extends RadioGroupProps {
10
+ large?: boolean;
11
+ }
12
+
13
+ const RadioButtonContainer = styled.div<{ large?: boolean }>`
14
+ display: flex;
15
+ & label:first-of-type {
16
+ border-bottom-left-radius: ${(props) => (props.large ? '6px' : '4px')};
17
+ border-top-left-radius: ${(props) => (props.large ? '6px' : '4px')};
18
+ }
19
+ & label:last-of-type {
20
+ border-right-width: 1px;
21
+ border-bottom-right-radius: ${(props) => (props.large ? '6px' : '4px')};
22
+ border-top-right-radius: ${(props) => (props.large ? '6px' : '4px')};
23
+ }
24
+ `;
25
+
26
+ export function RadioButtonGroup(props: RadioButtonGroupProps) {
27
+ const {
28
+ disabled: groupDisabled = false,
29
+ options = [],
30
+ name,
31
+ large,
32
+ selectedValue,
33
+ onChange,
34
+ children,
35
+ ...restProps
36
+ } = props;
37
+
38
+ return (
39
+ <RadioGroup
40
+ name={name}
41
+ selectedValue={selectedValue}
42
+ onChange={onChange}
43
+ {...restProps}
44
+ >
45
+ <RadioButtonContainer large={large}>
46
+ {options?.map(({ value, label, disabled }, index) => {
47
+ return (
48
+ <RadioButton
49
+ // eslint-disable-next-line react/no-array-index-key
50
+ key={index}
51
+ value={value}
52
+ label={label}
53
+ large={large}
54
+ name={name}
55
+ onChange={onChange}
56
+ checked={value === selectedValue}
57
+ disabled={groupDisabled || disabled}
58
+ />
59
+ );
60
+ })}
61
+ {Children.map(children, (child) => {
62
+ if (!child || typeof child !== 'object' || !('type' in child)) {
63
+ return child;
64
+ }
65
+ if (child.type === RadioButton) {
66
+ return cloneElement(child, {
67
+ ...child.props,
68
+ large,
69
+ name,
70
+ onChange,
71
+ checked: child.props.value === selectedValue,
72
+ disabled: groupDisabled || child.props.disabled,
73
+ });
74
+ }
75
+ return child;
76
+ })}
77
+ </RadioButtonContainer>
78
+ </RadioGroup>
79
+ );
80
+ }
@@ -0,0 +1,2 @@
1
+ export * from './RadioButtonGroup.js';
2
+ export * from './RadioButton.js';
@@ -0,0 +1,13 @@
1
+ import { useId } from 'react';
2
+
3
+ export function useInputId(
4
+ id: string | null | undefined,
5
+ name: string | null | undefined,
6
+ ) {
7
+ const reactId = useId();
8
+
9
+ // If an id is provided, use it
10
+ // Else if a name is specified, join name with reactId to simplify debug in devtools
11
+ // else use the id from useId()
12
+ return id ?? (name ? `${name}_${reactId}` : reactId);
13
+ }
@@ -1,6 +1,5 @@
1
1
  export * from './useDoubleClick.js';
2
2
  export * from './useHashSearchParams.js';
3
- export * from './useModifiedPopper.js';
4
3
  export * from './useOnClickOutside.js';
5
4
  export * from './useOnOff.js';
6
5
  export * from './useToggle.js';
@@ -1,11 +1,12 @@
1
1
  /** @jsxImportSource @emotion/react */
2
- import { Icon, InputGroup } from '@blueprintjs/core';
2
+ import { Classes, Collapse, InputGroup } from '@blueprintjs/core';
3
3
  import { css } from '@emotion/react';
4
- import * as Collapsible from '@radix-ui/react-collapsible';
4
+ import styled from '@emotion/styled';
5
5
  import type { CSSProperties } from 'react';
6
6
  import { memo, useCallback, useMemo, useState } from 'react';
7
7
  import { match, P } from 'ts-pattern';
8
8
 
9
+ import { Button } from '../button/Button.js';
9
10
  import { SelectedTotal } from '../selected-total/index.js';
10
11
  import { createTableColumnHelper, Table } from '../table/index.js';
11
12
  import * as ValueRenderers from '../value-renderers/index.js';
@@ -23,27 +24,34 @@ interface InfoPanelProps {
23
24
  inputStyle?: CSSProperties;
24
25
  }
25
26
 
27
+ const AccordionButton = styled(Button, {
28
+ shouldForwardProp: (propName) => propName !== 'open',
29
+ })<{ open?: boolean }>`
30
+ z-index: 1;
31
+ position: sticky;
32
+ height: 30px;
33
+ top: 0;
34
+ .${Classes.ICON} {
35
+ rotate: ${(props) => (props.open ? '90deg' : '')};
36
+ transition: all 0.3s ease-in-out;
37
+ }
38
+ cursor: pointer;
39
+ border-bottom: 1px solid #f5f5f5;
40
+ display: flex;
41
+ align-items: center;
42
+ padding: 5px 2px;
43
+ width: 100%;
44
+ &.${Classes.MINIMAL} {
45
+ background-color: white;
46
+ }
47
+ :hover {
48
+ background-color: #f5f5f5;
49
+ }
50
+ `;
51
+
26
52
  const style = {
27
53
  content: css({
28
54
  overflow: 'hidden',
29
- "&[data-state='open']": {
30
- animation: 'slideDown 300ms ease-out',
31
- },
32
- '&[data-state="closed"]': {
33
- animation: 'slideUp 300ms ease-out',
34
- },
35
- '@keyframes slideDown': {
36
- from: {
37
- height: 0,
38
- },
39
- to: { height: 'var(--radix-collapsible-content-height)' },
40
- },
41
- '@keyframes slideUp': {
42
- from: {
43
- height: 'var(--radix-collapsible-content-height)',
44
- },
45
- to: { height: 0 },
46
- },
47
55
  }),
48
56
  container: css({
49
57
  padding: '5px 0 0 0',
@@ -51,28 +59,6 @@ const style = {
51
59
  display: 'flex',
52
60
  flexDirection: 'column',
53
61
  }),
54
- chevron: css({
55
- transition: 'all 0.3s ease-in-out',
56
- }),
57
- button: css({
58
- zIndex: 10,
59
- position: 'sticky',
60
- height: 30,
61
- top: 0,
62
- "&[data-state='open'] > span": {
63
- rotate: '90deg',
64
- },
65
- cursor: 'pointer',
66
- borderBottom: '1px solid #f5f5f5',
67
- backgroundColor: 'white',
68
- display: 'flex',
69
- alignItems: 'center',
70
- padding: '5px 2px',
71
- width: '100%',
72
- ':hover': {
73
- backgroundColor: '#f5f5f5',
74
- },
75
- }),
76
62
  };
77
63
 
78
64
  interface InfoPanelDatum {
@@ -206,6 +192,9 @@ interface InfoPanelContentProps {
206
192
 
207
193
  const InfoPanelContent = memo((props: InfoPanelContentProps) => {
208
194
  const { filteredData } = props;
195
+ const [isOpen, setIsOpen] = useState<string[]>(
196
+ filteredData.map(({ description }) => description),
197
+ );
209
198
  return (
210
199
  <div
211
200
  style={{
@@ -218,19 +207,25 @@ const InfoPanelContent = memo((props: InfoPanelContentProps) => {
218
207
  }}
219
208
  >
220
209
  {filteredData.map(({ description, data }) => {
210
+ const open = isOpen.includes(description);
221
211
  return (
222
- <Collapsible.Root
223
- key={description}
224
- className="CollapsibleRoot"
225
- defaultOpen
226
- >
227
- <Collapsible.Trigger asChild css={style.button}>
228
- <div>
229
- <Icon icon="chevron-right" css={style.chevron} />
230
- {description}
231
- </div>
232
- </Collapsible.Trigger>
233
- <Collapsible.Content css={style.content}>
212
+ <div key={description}>
213
+ <AccordionButton
214
+ open={open}
215
+ minimal
216
+ onClick={() =>
217
+ setIsOpen((pred) =>
218
+ open
219
+ ? pred.filter((o) => o !== description)
220
+ : [...pred, description],
221
+ )
222
+ }
223
+ alignText="left"
224
+ icon="chevron-right"
225
+ >
226
+ {description}
227
+ </AccordionButton>
228
+ <Collapse isOpen={open} css={style.content}>
234
229
  <Table
235
230
  data={data}
236
231
  columns={columns}
@@ -238,8 +233,8 @@ const InfoPanelContent = memo((props: InfoPanelContentProps) => {
238
233
  tableProps={{ style: { width: '100%' } }}
239
234
  compact
240
235
  />
241
- </Collapsible.Content>
242
- </Collapsible.Root>
236
+ </Collapse>
237
+ </div>
243
238
  );
244
239
  })}
245
240
  </div>
@@ -1,12 +1,10 @@
1
1
  import { BlueprintProvider, FocusStyleManager } from '@blueprintjs/core';
2
- import { QueryClientProvider } from '@tanstack/react-query';
3
2
  import type { CSSProperties, ReactNode } from 'react';
4
3
  import { useCallback, useState } from 'react';
5
4
 
6
5
  import { AccordionProvider } from '../accordion/index.js';
7
6
 
8
7
  import { CustomDivPreflight } from './css-reset/customPreflight.js';
9
- import { queryClient } from './query_client.js';
10
8
  import { RootLayoutProvider } from './root_layout_context.provider.js';
11
9
 
12
10
  FocusStyleManager.onlyShowFocusOnTabs();
@@ -48,9 +46,7 @@ export function RootLayout(props: RootLayoutProps) {
48
46
  {...(rootRef ? { portalContainer: rootRef } : undefined)}
49
47
  >
50
48
  <RootLayoutProvider innerRef={rootRef}>
51
- <QueryClientProvider client={queryClient}>
52
- <AccordionProvider>{props.children}</AccordionProvider>
53
- </QueryClientProvider>
49
+ <AccordionProvider>{props.children}</AccordionProvider>
54
50
  </RootLayoutProvider>
55
51
  </BlueprintProvider>
56
52
  </CustomDivPreflight>
@@ -1,6 +1,9 @@
1
- import type { Header, RowData } from '@tanstack/react-table';
1
+ import { Icon } from '@blueprintjs/core';
2
+ import type { IconName } from '@blueprintjs/icons';
3
+ import type { Header, RowData, SortingFnOption } from '@tanstack/react-table';
2
4
  import { flexRender } from '@tanstack/react-table';
3
- import type { CSSProperties, HTMLAttributes, ReactNode } from 'react';
5
+ import type { HTMLAttributes, ReactNode } from 'react';
6
+ import { match } from 'ts-pattern';
4
7
 
5
8
  type ThProps = Pick<
6
9
  HTMLAttributes<HTMLTableCellElement>,
@@ -32,26 +35,53 @@ export function TableHeaderCell<TData extends RowData>(
32
35
  function getThProps<TData extends RowData>(
33
36
  header: Header<TData, unknown>,
34
37
  ): ThProps {
35
- const sorted = header.column.getIsSorted();
36
- const canSort = header.column.getCanSort();
37
- const style: CSSProperties = {
38
- position: 'relative',
39
- cursor: canSort ? 'pointer' : undefined,
40
- };
41
- const onClick = canSort ? header.column.getToggleSortingHandler() : undefined;
42
- const children = (
43
- <div style={{ display: 'flex', flexDirection: 'row', gap: '5px' }}>
44
- <div>
45
- {flexRender(header.column.columnDef.header, header.getContext())}
38
+ const { column } = header;
39
+
40
+ const sorted = column.getIsSorted();
41
+ const canSort = column.getCanSort();
42
+ const sortingIcon = getSortingIcon(column.columnDef.sortingFn)[
43
+ sorted || 'asc'
44
+ ];
45
+
46
+ return {
47
+ onClick: canSort ? column.getToggleSortingHandler() : undefined,
48
+ style: {
49
+ position: 'relative',
50
+ cursor: canSort ? 'pointer' : undefined,
51
+ },
52
+ children: (
53
+ <div style={{ display: 'flex', flexDirection: 'row', gap: '5px' }}>
54
+ <div>{flexRender(column.columnDef.header, header.getContext())}</div>
55
+ {sorted && <Icon icon={sortingIcon} />}
46
56
  </div>
47
- {sorted
48
- ? {
49
- asc: '🔼',
50
- desc: '🔽',
51
- }[sorted]
52
- : null}
53
- </div>
54
- );
55
-
56
- return { style, children, onClick };
57
+ ),
58
+ };
59
+ }
60
+
61
+ function getSortingIcon<TData extends RowData>(
62
+ type: SortingFnOption<TData> | undefined,
63
+ ): { asc: IconName; desc: IconName } {
64
+ return match<
65
+ SortingFnOption<TData> | undefined,
66
+ { asc: IconName; desc: IconName }
67
+ >(type)
68
+ .with(
69
+ 'auto',
70
+ 'datetime',
71
+ 'alphanumeric',
72
+ 'alphanumericCaseSensitive',
73
+ () => ({
74
+ asc: 'sort-asc',
75
+ desc: 'sort-desc',
76
+ }),
77
+ )
78
+ .with('text', 'textCaseSensitive', () => ({
79
+ asc: 'sort-alphabetical',
80
+ desc: 'sort-alphabetical-desc',
81
+ }))
82
+ .with('basic', () => ({
83
+ asc: 'sort-numerical',
84
+ desc: 'sort-numerical-desc',
85
+ }))
86
+ .otherwise(() => ({ asc: 'sort-asc', desc: 'sort-desc' }));
57
87
  }
@@ -18,11 +18,34 @@ import type { HeaderCellRenderer } from './table_header_cell.js';
18
18
  import type { TableColumnDef, TableRowTrRenderer } from './table_utils.js';
19
19
  import { useTableColumns } from './use_table_columns.js';
20
20
 
21
- // Blueprint's HTMLTable `striped` prop's implementation is based on nth-child odd / even
22
- // We cannot use that with virtualization, so we override its implementation here.
23
21
  const CustomHTMLTable = styled(HTMLTable, {
24
- shouldForwardProp: (prop) => prop !== 'striped',
25
- })`
22
+ shouldForwardProp: (prop) => prop !== 'striped' && prop !== 'stickyHeader',
23
+ })<{ stickyHeader: boolean }>`
24
+ // When using a sticky header, ensure that the borders are located below the last header instead of above the first row.
25
+ ${(props) => {
26
+ if (!props.stickyHeader) return '';
27
+
28
+ return `
29
+ thead tr:last-child {
30
+ box-shadow: inset 0 -1px #11141826;
31
+ }
32
+
33
+ tbody tr:first-child td {
34
+ box-shadow: ${
35
+ props.bordered
36
+ ? 'inset 1px 0 0 0 #11141826 !important'
37
+ : 'none !important'
38
+ };
39
+ }
40
+
41
+ tbody tr:first-child td:first-child {
42
+ box-shadow: none !important;
43
+ }
44
+ `;
45
+ }}
46
+
47
+ // Blueprint's HTMLTable \`striped\` prop's implementation is based on nth-child odd / even
48
+ // We cannot use that with virtualization, so we override its implementation here.
26
49
  tbody tr.odd td {
27
50
  background: ${(props) =>
28
51
  props.striped ? 'rgba(143, 153, 168, 0.15)' : 'inherit'};
@@ -68,7 +91,16 @@ interface TableBaseProps<TData extends RowData> {
68
91
  TableOptions<TData>,
69
92
  'data' | 'columns' | 'getCoreRowModel' | 'getSortedRowModel'
70
93
  >;
94
+ /**
95
+ * Props which are forwarded to the underlying HTML table element.
96
+ */
71
97
  tableProps?: Omit<TableHTMLAttributes<HTMLTableElement>, 'children'>;
98
+ /**
99
+ * An alias for `tableProps.className`. Exists to ensure the Table component
100
+ * can be styled with styled components library (e.g. emotion).
101
+ * If you use both the alias and `tableProps.className`, they will be merged together.
102
+ */
103
+ className?: string;
72
104
  /**
73
105
  * Override the default row rendering.
74
106
  * Make sure to spread the passed `trProps` onto the rendered `<tr>` element.
@@ -113,6 +145,7 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
113
145
 
114
146
  reactTable,
115
147
  tableProps,
148
+ className,
116
149
  renderRowTr,
117
150
  renderHeaderCell,
118
151
 
@@ -138,6 +171,16 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
138
171
  overscan: 5,
139
172
  });
140
173
 
174
+ // Make the table component compatible with styled components libraries.
175
+ let finalClassName: string | undefined;
176
+ if (tableProps?.className && className) {
177
+ finalClassName = `${tableProps.className} ${className}`;
178
+ } else if (className) {
179
+ finalClassName = className;
180
+ } else {
181
+ finalClassName = tableProps?.className;
182
+ }
183
+
141
184
  return (
142
185
  <Container virtualizeRows={virtualizeRows} scrollRef={scrollElementRef}>
143
186
  <CustomHTMLTable
@@ -145,7 +188,9 @@ export function Table<TData extends RowData>(props: TableProps<TData>) {
145
188
  compact={compact}
146
189
  interactive={interactive}
147
190
  striped={striped}
191
+ stickyHeader={stickyHeader}
148
192
  {...tableProps}
193
+ className={finalClassName}
149
194
  >
150
195
  <TableHeader
151
196
  sticky={stickyHeader}
@@ -1,3 +0,0 @@
1
- import type { RadioGroupProps, RadioOption } from './RadioGroup.js';
2
- export declare function ButtonRadioItem(prop: RadioOption & Pick<RadioGroupProps, 'onSelect' | 'variant' | 'name'>): import("@emotion/react/jsx-runtime").JSX.Element;
3
- //# sourceMappingURL=ButtonRadioItem.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ButtonRadioItem.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/radio-group/ButtonRadioItem.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA6CpE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC,oDAwB3E"}
@@ -1,50 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
- /** @jsxImportSource @emotion/react */
3
- import { css } from '@emotion/react';
4
- import * as RadioGroup from '@radix-ui/react-radio-group';
5
- import { enabledColor } from '../styles.js';
6
- const buttonStyles = {
7
- container: css({
8
- border: '1px solid rgba(0, 0, 0, 0.25)',
9
- borderRightWidth: 0,
10
- position: 'relative',
11
- }),
12
- item: (disabled, variant) => css({
13
- opacity: disabled ? 0.25 : 1,
14
- padding: variant === 'default' ? '0px 15px' : '0px 7px',
15
- width: '100%',
16
- height: '100%',
17
- cursor: 'pointer',
18
- ':hover': {
19
- '& > label': {
20
- color: disabled ? '' : enabledColor,
21
- },
22
- },
23
- }),
24
- indicator: css({
25
- position: 'absolute',
26
- top: -1,
27
- left: -1,
28
- right: -1,
29
- bottom: -1,
30
- zIndex: 10,
31
- border: '1px solid',
32
- borderColor: enabledColor,
33
- '& ~ label': {
34
- color: enabledColor,
35
- },
36
- }),
37
- label: (variant) => css({
38
- cursor: 'pointer',
39
- fontSize: variant === 'small' ? '1em' : '1.125em',
40
- lineHeight: variant === 'default' ? '30px' : '22px',
41
- }),
42
- };
43
- export function ButtonRadioItem(prop) {
44
- const { value, label, disabled = false, onSelect, variant, name } = prop;
45
- return (_jsx("div", { css: buttonStyles.container, children: _jsxs(RadioGroup.Item, { css: buttonStyles.item(disabled, variant), value: value, id: `${value}${name}`, onClick: () => {
46
- if (!disabled)
47
- onSelect?.(prop);
48
- }, children: [_jsx(RadioGroup.Indicator, { css: buttonStyles.indicator }), _jsx("label", { css: buttonStyles.label(variant), htmlFor: `${value}${name}`, style: {}, children: label })] }) }));
49
- }
50
- //# sourceMappingURL=ButtonRadioItem.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ButtonRadioItem.js","sourceRoot":"","sources":["../../../../src/components/forms/radio-group/ButtonRadioItem.tsx"],"names":[],"mappings":";AAAA,sCAAsC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,UAAU,MAAM,6BAA6B,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAI5C,MAAM,YAAY,GAAG;IACnB,SAAS,EAAE,GAAG,CAAC;QACb,MAAM,EAAE,+BAA+B;QACvC,gBAAgB,EAAE,CAAC;QACnB,QAAQ,EAAE,UAAU;KACrB,CAAC;IACF,IAAI,EAAE,CAAC,QAAiB,EAAE,OAAsB,EAAE,EAAE,CAClD,GAAG,CAAC;QACF,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QACvD,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE;YACR,WAAW,EAAE;gBACX,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY;aACpC;SACF;KACF,CAAC;IAEJ,SAAS,EAAE,GAAG,CAAC;QACb,QAAQ,EAAE,UAAU;QACpB,GAAG,EAAE,CAAC,CAAC;QACP,IAAI,EAAE,CAAC,CAAC;QACR,KAAK,EAAE,CAAC,CAAC;QACT,MAAM,EAAE,CAAC,CAAC;QACV,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,WAAW;QACnB,WAAW,EAAE,YAAY;QAEzB,WAAW,EAAE;YACX,KAAK,EAAE,YAAY;SACpB;KACF,CAAC;IAEF,KAAK,EAAE,CAAC,OAAsB,EAAE,EAAE,CAChC,GAAG,CAAC;QACF,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACjD,UAAU,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;KACpD,CAAC;CACL,CAAC;AAEF,MAAM,UAAU,eAAe,CAC7B,IAA0E;IAE1E,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACzE,OAAO,CACL,cAAK,GAAG,EAAE,YAAY,CAAC,SAAS,YAC9B,MAAC,UAAU,CAAC,IAAI,IACd,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EACzC,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,GAAG,KAAK,GAAG,IAAI,EAAE,EACrB,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,QAAQ;oBAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC,aAED,KAAC,UAAU,CAAC,SAAS,IAAC,GAAG,EAAE,YAAY,CAAC,SAAS,GAAI,EACrD,gBACE,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAChC,OAAO,EAAE,GAAG,KAAK,GAAG,IAAI,EAAE,EAC1B,KAAK,EAAE,EAAE,YAER,KAAK,GACA,IACQ,GACd,CACP,CAAC;AACJ,CAAC"}