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.
- package/lib/components/accordion/accordion.js +1 -0
- package/lib/components/accordion/accordion.js.map +1 -1
- package/lib/components/forms/index.d.ts +1 -1
- package/lib/components/forms/index.d.ts.map +1 -1
- package/lib/components/forms/index.js +1 -1
- package/lib/components/forms/index.js.map +1 -1
- package/lib/components/forms/radio-button-group/RadioButton.d.ts +4 -0
- package/lib/components/forms/radio-button-group/RadioButton.d.ts.map +1 -0
- package/lib/components/forms/radio-button-group/RadioButton.js +53 -0
- package/lib/components/forms/radio-button-group/RadioButton.js.map +1 -0
- package/lib/components/forms/radio-button-group/RadioButtonGroup.d.ts +7 -0
- package/lib/components/forms/radio-button-group/RadioButtonGroup.d.ts.map +1 -0
- package/lib/components/forms/radio-button-group/RadioButtonGroup.js +41 -0
- package/lib/components/forms/radio-button-group/RadioButtonGroup.js.map +1 -0
- package/lib/components/forms/radio-button-group/index.d.ts +3 -0
- package/lib/components/forms/radio-button-group/index.d.ts.map +1 -0
- package/lib/components/forms/radio-button-group/index.js +3 -0
- package/lib/components/forms/radio-button-group/index.js.map +1 -0
- package/lib/components/forms/utils/use_input_id.d.ts +2 -0
- package/lib/components/forms/utils/use_input_id.d.ts.map +1 -0
- package/lib/components/forms/utils/use_input_id.js +9 -0
- package/lib/components/forms/utils/use_input_id.js.map +1 -0
- package/lib/components/hooks/index.d.ts +0 -1
- package/lib/components/hooks/index.d.ts.map +1 -1
- package/lib/components/hooks/index.js +0 -1
- package/lib/components/hooks/index.js.map +1 -1
- package/lib/components/info-panel/InfoPanel.d.ts.map +1 -1
- package/lib/components/info-panel/InfoPanel.js +32 -43
- package/lib/components/info-panel/InfoPanel.js.map +1 -1
- package/lib/components/root-layout/root_layout.d.ts.map +1 -1
- package/lib/components/root-layout/root_layout.js +1 -3
- package/lib/components/root-layout/root_layout.js.map +1 -1
- package/lib/components/table/table_header_cell.d.ts.map +1 -1
- package/lib/components/table/table_header_cell.js +29 -13
- package/lib/components/table/table_header_cell.js.map +1 -1
- package/lib/components/table/table_root.d.ts +9 -0
- package/lib/components/table/table_root.d.ts.map +1 -1
- package/lib/components/table/table_root.js +37 -5
- package/lib/components/table/table_root.js.map +1 -1
- package/package.json +3 -6
- package/src/components/accordion/accordion.tsx +1 -0
- package/src/components/forms/index.ts +1 -1
- package/src/components/forms/radio-button-group/RadioButton.tsx +73 -0
- package/src/components/forms/radio-button-group/RadioButtonGroup.tsx +80 -0
- package/src/components/forms/radio-button-group/index.ts +2 -0
- package/src/components/forms/utils/use_input_id.ts +13 -0
- package/src/components/hooks/index.ts +0 -1
- package/src/components/info-panel/InfoPanel.tsx +51 -56
- package/src/components/root-layout/root_layout.tsx +1 -5
- package/src/components/table/table_header_cell.tsx +53 -23
- package/src/components/table/table_root.tsx +49 -4
- package/lib/components/forms/radio-group/ButtonRadioItem.d.ts +0 -3
- package/lib/components/forms/radio-group/ButtonRadioItem.d.ts.map +0 -1
- package/lib/components/forms/radio-group/ButtonRadioItem.js +0 -50
- package/lib/components/forms/radio-group/ButtonRadioItem.js.map +0 -1
- package/lib/components/forms/radio-group/RadioGroup.d.ts +0 -18
- package/lib/components/forms/radio-group/RadioGroup.d.ts.map +0 -1
- package/lib/components/forms/radio-group/RadioGroup.js +0 -38
- package/lib/components/forms/radio-group/RadioGroup.js.map +0 -1
- package/lib/components/forms/radio-group/index.d.ts +0 -2
- package/lib/components/forms/radio-group/index.d.ts.map +0 -1
- package/lib/components/forms/radio-group/index.js +0 -2
- package/lib/components/forms/radio-group/index.js.map +0 -1
- package/lib/components/hooks/useModifiedPopper.d.ts +0 -13
- package/lib/components/hooks/useModifiedPopper.d.ts.map +0 -1
- package/lib/components/hooks/useModifiedPopper.js +0 -48
- package/lib/components/hooks/useModifiedPopper.js.map +0 -1
- package/lib/components/root-layout/query_client.d.ts +0 -3
- package/lib/components/root-layout/query_client.d.ts.map +0 -1
- package/lib/components/root-layout/query_client.js +0 -11
- package/lib/components/root-layout/query_client.js.map +0 -1
- package/src/components/forms/radio-group/ButtonRadioItem.tsx +0 -78
- package/src/components/forms/radio-group/RadioGroup.tsx +0 -75
- package/src/components/forms/radio-group/index.ts +0 -1
- package/src/components/hooks/useModifiedPopper.ts +0 -77
- 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,
|
|
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": "
|
|
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",
|
|
@@ -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,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,11 +1,12 @@
|
|
|
1
1
|
/** @jsxImportSource @emotion/react */
|
|
2
|
-
import {
|
|
2
|
+
import { Classes, Collapse, InputGroup } from '@blueprintjs/core';
|
|
3
3
|
import { css } from '@emotion/react';
|
|
4
|
-
import
|
|
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
|
-
<
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
</
|
|
242
|
-
</
|
|
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
|
-
<
|
|
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
|
|
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 {
|
|
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
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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"}
|