@indico-data/design-system 2.53.0 → 2.54.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/index.d.ts +3 -0
- package/lib/components/loading-indicators/BarSpinner/BarSpinner.d.ts +8 -0
- package/lib/components/loading-indicators/BarSpinner/BarSpinner.stories.d.ts +7 -0
- package/lib/components/loading-indicators/BarSpinner/__tests__/BarSpinner.test.d.ts +1 -0
- package/lib/components/loading-indicators/CirclePulse/CirclePulse.d.ts +7 -0
- package/lib/components/loading-indicators/CirclePulse/CirclePulse.stories.d.ts +6 -0
- package/lib/components/tooltip/Tooltip.d.ts +13 -0
- package/lib/components/tooltip/Tooltip.stories.d.ts +6 -0
- package/lib/index.css +149 -0
- package/lib/index.d.ts +50 -46
- package/lib/index.esm.css +149 -0
- package/lib/index.esm.js +5789 -6001
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +5787 -5999
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/index.ts +3 -0
- package/src/components/loading-indicators/BarSpinner/BarSpinner.mdx +21 -0
- package/src/components/loading-indicators/BarSpinner/BarSpinner.stories.tsx +89 -0
- package/src/components/loading-indicators/BarSpinner/BarSpinner.tsx +25 -0
- package/src/components/loading-indicators/BarSpinner/__tests__/BarSpinner.test.tsx +16 -0
- package/src/{legacy/components/loading-indicators/BarSpinner/BarSpinner.styles.ts → components/loading-indicators/BarSpinner/styles/BarSpinner.scss} +11 -11
- package/src/components/loading-indicators/CirclePulse/CirclePulse.mdx +20 -0
- package/src/components/loading-indicators/CirclePulse/CirclePulse.scss +83 -0
- package/src/components/loading-indicators/CirclePulse/CirclePulse.stories.tsx +78 -0
- package/src/components/loading-indicators/CirclePulse/CirclePulse.tsx +15 -0
- package/src/components/tanstackTable/components/TableBody/TableBody.tsx +1 -1
- package/src/components/tooltip/Tooltip.mdx +25 -0
- package/src/components/tooltip/Tooltip.stories.tsx +113 -0
- package/src/components/tooltip/Tooltip.tsx +38 -0
- package/src/components/tooltip/styles/Tooltip.scss +8 -0
- package/src/index.ts +4 -2
- package/src/styles/globals.scss +9 -0
- package/src/styles/index.scss +3 -0
- package/lib/legacy/components/Tooltip/Tooltip.d.ts +0 -15
- package/lib/legacy/components/Tooltip/Tooltip.stories.d.ts +0 -9
- package/lib/legacy/components/Tooltip/Tooltip.styles.d.ts +0 -1
- package/lib/legacy/components/index.d.ts +0 -2
- package/lib/legacy/components/loading-indicators/BarSpinner/BarSpinner.d.ts +0 -7
- package/lib/legacy/components/loading-indicators/BarSpinner/BarSpinner.stories.d.ts +0 -10
- package/lib/legacy/components/loading-indicators/BarSpinner/BarSpinner.styles.d.ts +0 -1
- package/lib/legacy/components/loading-indicators/CirclePulse/CirclePulse.d.ts +0 -10
- package/lib/legacy/components/loading-indicators/CirclePulse/CirclePulse.stories.d.ts +0 -12
- package/lib/legacy/components/loading-indicators/CirclePulse/CirclePulse.styles.d.ts +0 -7
- package/lib/legacy/components/loading-indicators/CircleSpinner/CircleSpinner.d.ts +0 -10
- package/lib/legacy/components/loading-indicators/CircleSpinner/CircleSpinner.stories.d.ts +0 -10
- package/lib/legacy/components/loading-indicators/CircleSpinner/index.d.ts +0 -1
- package/lib/legacy/components/loading-indicators/index.d.ts +0 -3
- package/src/legacy/components/Tooltip/Tooltip.stories.tsx +0 -107
- package/src/legacy/components/Tooltip/Tooltip.styles.ts +0 -64
- package/src/legacy/components/Tooltip/Tooltip.tsx +0 -70
- package/src/legacy/components/index.ts +0 -2
- package/src/legacy/components/loading-indicators/BarSpinner/BarSpinner.stories.tsx +0 -14
- package/src/legacy/components/loading-indicators/BarSpinner/BarSpinner.tsx +0 -21
- package/src/legacy/components/loading-indicators/CirclePulse/CirclePulse.stories.tsx +0 -22
- package/src/legacy/components/loading-indicators/CirclePulse/CirclePulse.styles.ts +0 -77
- package/src/legacy/components/loading-indicators/CirclePulse/CirclePulse.tsx +0 -57
- package/src/legacy/components/loading-indicators/CircleSpinner/CircleSpinner.stories.tsx +0 -16
- package/src/legacy/components/loading-indicators/CircleSpinner/CircleSpinner.tsx +0 -36
- package/src/legacy/components/loading-indicators/CircleSpinner/index.ts +0 -1
- package/src/legacy/components/loading-indicators/index.ts +0 -3
- /package/lib/{legacy/components → components}/loading-indicators/BarSpinner/index.d.ts +0 -0
- /package/lib/{legacy/components → components}/loading-indicators/CirclePulse/index.d.ts +0 -0
- /package/lib/{legacy/components/Tooltip → components/tooltip}/index.d.ts +0 -0
- /package/src/{legacy/components → components}/loading-indicators/BarSpinner/index.ts +0 -0
- /package/src/{legacy/components → components}/loading-indicators/CirclePulse/index.ts +0 -0
- /package/src/{legacy/components/Tooltip → components/tooltip}/index.ts +0 -0
package/package.json
CHANGED
package/src/components/index.ts
CHANGED
|
@@ -22,3 +22,6 @@ export { Modal } from './modal';
|
|
|
22
22
|
export { Badge } from './badge';
|
|
23
23
|
export { Pagination } from './pagination';
|
|
24
24
|
export { TanstackTable } from './tanstackTable';
|
|
25
|
+
export { Tooltip } from './tooltip';
|
|
26
|
+
export { BarSpinner } from './loading-indicators/BarSpinner/BarSpinner';
|
|
27
|
+
export { CirclePulse } from './loading-indicators/CirclePulse/CirclePulse';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Canvas, Meta, Controls, Story } from '@storybook/blocks';
|
|
2
|
+
import * as BarSpinner from './BarSpinner.stories';
|
|
3
|
+
|
|
4
|
+
<Meta title="Utilities/BarSpinner" name="BarSpinner" of={BarSpinner} />
|
|
5
|
+
|
|
6
|
+
# BarSpinner
|
|
7
|
+
|
|
8
|
+
This is a simple looping animation component that can indicate a loading state
|
|
9
|
+
|
|
10
|
+
<Canvas of={BarSpinner.Default} />
|
|
11
|
+
|
|
12
|
+
### The following props are available for the BarSpinner component:
|
|
13
|
+
|
|
14
|
+
<Controls of={BarSpinner.Default} />
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
Simple usage of the BarSpinner component:
|
|
18
|
+
<Canvas of={BarSpinner.WithWidthAndHeight} />
|
|
19
|
+
```tsx
|
|
20
|
+
<BarSpinner id="bar-spinner-optional-id" className="optional-class-name" width={200} height={10} />
|
|
21
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { BarSpinner } from './BarSpinner';
|
|
3
|
+
import { Col, Container, Row } from '../../grid';
|
|
4
|
+
|
|
5
|
+
const meta: Meta = {
|
|
6
|
+
title: 'Utilities/BarSpinner',
|
|
7
|
+
component: BarSpinner,
|
|
8
|
+
argTypes: {
|
|
9
|
+
className: {
|
|
10
|
+
control: false,
|
|
11
|
+
description: 'The class name of the bar spinner',
|
|
12
|
+
table: {
|
|
13
|
+
category: 'Props',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
'data-testid': {
|
|
17
|
+
table: {
|
|
18
|
+
disable: true,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
width: {
|
|
22
|
+
control: false,
|
|
23
|
+
description: 'The width of the bar spinner',
|
|
24
|
+
table: {
|
|
25
|
+
category: 'Props',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
height: {
|
|
29
|
+
control: false,
|
|
30
|
+
description: 'The height of the bar spinner',
|
|
31
|
+
table: {
|
|
32
|
+
category: 'Props',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
id: {
|
|
36
|
+
control: false,
|
|
37
|
+
description:
|
|
38
|
+
"The id of the tooltip. This needs to match the element that holds it's data attribute",
|
|
39
|
+
table: {
|
|
40
|
+
category: 'Props',
|
|
41
|
+
type: {
|
|
42
|
+
summary: 'string',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default meta;
|
|
50
|
+
|
|
51
|
+
type Story = StoryObj<typeof BarSpinner>;
|
|
52
|
+
|
|
53
|
+
export const Default: Story = {
|
|
54
|
+
args: {
|
|
55
|
+
id: 'bar-spinner-1',
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
render: (args) => {
|
|
59
|
+
return (
|
|
60
|
+
<Container>
|
|
61
|
+
<Row>
|
|
62
|
+
<Col sm={4}>
|
|
63
|
+
<BarSpinner id={args.id} />
|
|
64
|
+
</Col>
|
|
65
|
+
</Row>
|
|
66
|
+
</Container>
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const WithWidthAndHeight: Story = {
|
|
72
|
+
args: {
|
|
73
|
+
id: 'bar-spinner-1',
|
|
74
|
+
width: 200,
|
|
75
|
+
height: 10,
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
render: (args) => {
|
|
79
|
+
return (
|
|
80
|
+
<Container>
|
|
81
|
+
<Row>
|
|
82
|
+
<Col sm={4}>
|
|
83
|
+
<BarSpinner id={args.id} width={args.width} height={args.height} />
|
|
84
|
+
</Col>
|
|
85
|
+
</Row>
|
|
86
|
+
</Container>
|
|
87
|
+
);
|
|
88
|
+
},
|
|
89
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function BarSpinner({
|
|
2
|
+
width,
|
|
3
|
+
id,
|
|
4
|
+
height,
|
|
5
|
+
className,
|
|
6
|
+
...rest
|
|
7
|
+
}: {
|
|
8
|
+
'data-testid'?: string;
|
|
9
|
+
width?: number;
|
|
10
|
+
id?: string;
|
|
11
|
+
height?: number;
|
|
12
|
+
className?: string;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}) {
|
|
15
|
+
// Create style object only if width or height exist
|
|
16
|
+
const style: React.CSSProperties = {};
|
|
17
|
+
if (width !== undefined) style.width = `${width}px`;
|
|
18
|
+
if (height !== undefined) style.height = `${height}px`;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className={`bar-spinner ${className}`} id={id} style={style} {...rest}>
|
|
22
|
+
<span />
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { BarSpinner } from '../BarSpinner';
|
|
3
|
+
|
|
4
|
+
describe('BarSpinner Component', () => {
|
|
5
|
+
it('Renders the bar spinner without style props', () => {
|
|
6
|
+
render(<BarSpinner id="bar-spinner-1" data-testid="bar-spinner-1" />);
|
|
7
|
+
expect(screen.getByTestId('bar-spinner-1')).toBeInTheDocument();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('Renders the bar spinner with prop width and height', () => {
|
|
11
|
+
render(<BarSpinner id="bar-spinner-1" width={200} height={10} data-testid="bar-spinner-1" />);
|
|
12
|
+
expect(screen.getByTestId('bar-spinner-1')).toBeInTheDocument();
|
|
13
|
+
expect(screen.getByTestId('bar-spinner-1')).toHaveStyle('width: 200px');
|
|
14
|
+
expect(screen.getByTestId('bar-spinner-1')).toHaveStyle('height: 10px');
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const moveBg = keyframes`
|
|
4
|
-
from {
|
|
1
|
+
@keyframes moveBg {
|
|
2
|
+
0% {
|
|
5
3
|
transform: translateX(0);
|
|
6
4
|
}
|
|
7
|
-
|
|
5
|
+
100% {
|
|
8
6
|
transform: translateX(46px);
|
|
9
7
|
}
|
|
10
|
-
|
|
8
|
+
}
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
.bar-spinner {
|
|
13
11
|
display: inline-block;
|
|
14
|
-
width: 200px;
|
|
15
|
-
height: 14px; /* Can be anything */
|
|
16
12
|
position: relative;
|
|
13
|
+
width: 100%;
|
|
14
|
+
height: 100%;
|
|
15
|
+
min-height: 14px;
|
|
17
16
|
border-radius: 25px;
|
|
17
|
+
background-color: var(--pf-primary-color-800);
|
|
18
18
|
|
|
19
19
|
> span {
|
|
20
20
|
display: block;
|
|
@@ -39,7 +39,7 @@ export const StyledBarSpinner = styled.div`
|
|
|
39
39
|
transparent 12px,
|
|
40
40
|
transparent 20px
|
|
41
41
|
);
|
|
42
|
-
animation-name:
|
|
42
|
+
animation-name: moveBg;
|
|
43
43
|
animation-duration: 1s;
|
|
44
44
|
animation-timing-function: linear;
|
|
45
45
|
animation-iteration-count: infinite;
|
|
@@ -47,4 +47,4 @@ export const StyledBarSpinner = styled.div`
|
|
|
47
47
|
overflow: hidden;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Canvas, Meta, Controls, Story } from '@storybook/blocks';
|
|
2
|
+
import * as CirclePulse from './CirclePulse.stories';
|
|
3
|
+
|
|
4
|
+
<Meta title="Utilities/CirclePulse" name="CirclePulse" of={CirclePulse} />
|
|
5
|
+
|
|
6
|
+
# CirclePulse
|
|
7
|
+
|
|
8
|
+
This is a simple looping animation component that can indicate a loading state
|
|
9
|
+
|
|
10
|
+
<Canvas of={CirclePulse.Default} />
|
|
11
|
+
|
|
12
|
+
### The following props are available for the CirclePulse component:
|
|
13
|
+
|
|
14
|
+
<Controls of={CirclePulse.Default} />
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
<CirclePulse size="md" id="circle-pulse-optional-id" className="optional-class-name" />
|
|
20
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--circle-pulse-animation-speed: 1.4s;
|
|
3
|
+
--circle-pulse-border-width: var(--pf-border-xl);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// Size map with increments of 20px
|
|
7
|
+
$circle-pulse-sizes: (
|
|
8
|
+
'xxs': 20px,
|
|
9
|
+
'xs': 40px,
|
|
10
|
+
'sm': 60px,
|
|
11
|
+
'md': 80px,
|
|
12
|
+
'lg': 100px,
|
|
13
|
+
'xl': 120px,
|
|
14
|
+
'xxl': 140px,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
// Generate size classes for the pulse only
|
|
18
|
+
@each $size, $value in $circle-pulse-sizes {
|
|
19
|
+
.circle-pulse-#{$size} {
|
|
20
|
+
--circle-pulse-size: #{$value};
|
|
21
|
+
--circle-pulse-ripple-size: calc(#{$value} * 1.7);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@keyframes ripple {
|
|
26
|
+
0% {
|
|
27
|
+
transform: translate(-50%, -50%) scale(0);
|
|
28
|
+
opacity: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
20% {
|
|
32
|
+
opacity: 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
100% {
|
|
36
|
+
transform: translate(-50%, -50%) scale(1);
|
|
37
|
+
opacity: 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.circle-pulse {
|
|
42
|
+
display: grid;
|
|
43
|
+
place-items: center;
|
|
44
|
+
position: relative;
|
|
45
|
+
|
|
46
|
+
width: var(--circle-pulse-size);
|
|
47
|
+
height: var(--circle-pulse-size);
|
|
48
|
+
|
|
49
|
+
margin-left: auto;
|
|
50
|
+
margin-right: auto;
|
|
51
|
+
|
|
52
|
+
&:before,
|
|
53
|
+
&:after {
|
|
54
|
+
content: '';
|
|
55
|
+
position: absolute;
|
|
56
|
+
border: var(--circle-pulse-border-width) solid var(--pf-primary-color-300);
|
|
57
|
+
border-radius: 50%;
|
|
58
|
+
|
|
59
|
+
/* Set initial dimensions */
|
|
60
|
+
width: var(--circle-pulse-ripple-size);
|
|
61
|
+
height: var(--circle-pulse-ripple-size);
|
|
62
|
+
|
|
63
|
+
/* Position at center */
|
|
64
|
+
top: 50%;
|
|
65
|
+
left: 50%;
|
|
66
|
+
transform: translate(-50%, -50%) scale(0);
|
|
67
|
+
transform-origin: center;
|
|
68
|
+
|
|
69
|
+
animation: ripple var(--circle-pulse-animation-speed) cubic-bezier(0, 0.2, 0.8, 1) infinite;
|
|
70
|
+
|
|
71
|
+
@media (prefers-reduced-motion) {
|
|
72
|
+
animation-duration: calc(var(--circle-pulse-animation-speed) * 2);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&:after {
|
|
77
|
+
animation-delay: calc(var(--circle-pulse-animation-speed) * -0.5);
|
|
78
|
+
|
|
79
|
+
@media (prefers-reduced-motion) {
|
|
80
|
+
animation-delay: calc(var(--circle-pulse-animation-speed) * -1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { CirclePulse } from './CirclePulse';
|
|
3
|
+
import { Col, Container, Row } from '../../grid';
|
|
4
|
+
|
|
5
|
+
const meta: Meta = {
|
|
6
|
+
title: 'Utilities/CirclePulse',
|
|
7
|
+
component: CirclePulse,
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (
|
|
10
|
+
<div
|
|
11
|
+
style={{
|
|
12
|
+
width: '300px',
|
|
13
|
+
height: '300px',
|
|
14
|
+
display: 'flex',
|
|
15
|
+
justifyContent: 'center',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
}}
|
|
18
|
+
>
|
|
19
|
+
<Story />
|
|
20
|
+
</div>
|
|
21
|
+
),
|
|
22
|
+
],
|
|
23
|
+
argTypes: {
|
|
24
|
+
size: {
|
|
25
|
+
control: 'select',
|
|
26
|
+
description: 'The size of the circle',
|
|
27
|
+
options: ['xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'],
|
|
28
|
+
table: {
|
|
29
|
+
category: 'Props',
|
|
30
|
+
type: {
|
|
31
|
+
summary: 'xxs | xs | sm | md | lg | xl | xxl',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
id: {
|
|
36
|
+
control: false,
|
|
37
|
+
description: 'The id of the circle pulse',
|
|
38
|
+
table: {
|
|
39
|
+
category: 'Props',
|
|
40
|
+
type: {
|
|
41
|
+
summary: 'string',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
className: {
|
|
46
|
+
control: false,
|
|
47
|
+
description: 'The class name of the circle pulse',
|
|
48
|
+
table: {
|
|
49
|
+
category: 'Props',
|
|
50
|
+
type: {
|
|
51
|
+
summary: 'string',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default meta;
|
|
59
|
+
|
|
60
|
+
type Story = StoryObj<typeof CirclePulse>;
|
|
61
|
+
|
|
62
|
+
export const Default: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
size: 'md',
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
render: (args) => {
|
|
68
|
+
return (
|
|
69
|
+
<Container>
|
|
70
|
+
<Row>
|
|
71
|
+
<Col sm={4}>
|
|
72
|
+
<CirclePulse {...args} />
|
|
73
|
+
</Col>
|
|
74
|
+
</Row>
|
|
75
|
+
</Container>
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface CirclePulseProps {
|
|
2
|
+
size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
|
|
3
|
+
className?: string;
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function CirclePulse({ size = 'md', className, ...rest }: CirclePulseProps) {
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
className={`circle-pulse circle-pulse-${size} ${className}`}
|
|
11
|
+
aria-hidden={true}
|
|
12
|
+
{...rest}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -2,7 +2,7 @@ import { flexRender, Table } from '@tanstack/react-table';
|
|
|
2
2
|
import { Row } from '@tanstack/react-table';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import { getTdStyles } from '../../helpers';
|
|
5
|
-
import { CirclePulse } from '@/
|
|
5
|
+
import { CirclePulse } from '@/components/loading-indicators/CirclePulse';
|
|
6
6
|
import { Dispatch, SetStateAction } from 'react';
|
|
7
7
|
|
|
8
8
|
export type Props<T> = {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Canvas, Meta, Controls, Story } from '@storybook/blocks';
|
|
2
|
+
import * as Tooltip from './Tooltip.stories';
|
|
3
|
+
|
|
4
|
+
<Meta title="Utilities/Tooltip" name="Tooltip" of={Tooltip} />
|
|
5
|
+
|
|
6
|
+
# Tooltip
|
|
7
|
+
|
|
8
|
+
The tooltip component is simply a wrapper around react-tooltip(https://www.npmjs.com/package/react-tooltip). It is meant to serve as a package include as well as style wrapper.
|
|
9
|
+
|
|
10
|
+
<Canvas of={Tooltip.Default} />
|
|
11
|
+
|
|
12
|
+
### The following props are available for the Tooltip component:
|
|
13
|
+
|
|
14
|
+
<Controls of={Tooltip.Default} />
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
In the example below, the tooltip is triggered by hovering over the icon. The `data-tooltip-id` attribute is used to match the tooltip to the icon. IDs should be unique when rendering multiple tooltips on the same view.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<Icon icon="info" data-tooltip-id="tooltip-1" />
|
|
22
|
+
<Tooltip id="tooltip-1">
|
|
23
|
+
<div>Tooltip Content</div>
|
|
24
|
+
</Tooltip>
|
|
25
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Tooltip } from './Tooltip';
|
|
3
|
+
import { Col, Container, Row } from '../grid';
|
|
4
|
+
import { Button } from '../button';
|
|
5
|
+
|
|
6
|
+
const meta: Meta = {
|
|
7
|
+
title: 'Utilities/Tooltip',
|
|
8
|
+
component: Tooltip,
|
|
9
|
+
argTypes: {
|
|
10
|
+
id: {
|
|
11
|
+
control: false,
|
|
12
|
+
description:
|
|
13
|
+
"The id of the tooltip. This needs to match the element that holds it's data attribute",
|
|
14
|
+
table: {
|
|
15
|
+
category: 'Props',
|
|
16
|
+
type: {
|
|
17
|
+
summary: 'string',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
place: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
description: 'The placement of the tooltip',
|
|
24
|
+
options: ['top', 'top-start', 'top-end', 'right', 'right-start', 'right-end', 'bottom'],
|
|
25
|
+
table: {
|
|
26
|
+
category: 'Props',
|
|
27
|
+
type: {
|
|
28
|
+
summary: 'top | top-start | top-end | right | right-start | right-end | bottom',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
clickToShow: {
|
|
33
|
+
control: 'boolean',
|
|
34
|
+
description: 'Whether the tooltip should be shown on click',
|
|
35
|
+
table: {
|
|
36
|
+
category: 'Props',
|
|
37
|
+
type: {
|
|
38
|
+
summary: 'boolean',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
delayShow: {
|
|
43
|
+
control: 'number',
|
|
44
|
+
description: 'The delay in milliseconds before the tooltip is shown',
|
|
45
|
+
table: {
|
|
46
|
+
category: 'Props',
|
|
47
|
+
type: {
|
|
48
|
+
summary: 'number',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
delayHide: {
|
|
53
|
+
control: 'number',
|
|
54
|
+
description: 'The delay in milliseconds before the tooltip is hidden',
|
|
55
|
+
table: {
|
|
56
|
+
category: 'Props',
|
|
57
|
+
type: {
|
|
58
|
+
summary: 'number',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
zIndex: {
|
|
63
|
+
control: 'number',
|
|
64
|
+
description: 'This is an override for the z-index of the tooltip',
|
|
65
|
+
table: {
|
|
66
|
+
category: 'Props',
|
|
67
|
+
type: {
|
|
68
|
+
summary: 'number',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
children: {
|
|
73
|
+
control: false,
|
|
74
|
+
description: 'The content of the tooltip',
|
|
75
|
+
table: {
|
|
76
|
+
category: 'Props',
|
|
77
|
+
type: {
|
|
78
|
+
summary: 'React.ReactNode',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export default meta;
|
|
86
|
+
|
|
87
|
+
type Story = StoryObj<typeof Tooltip>;
|
|
88
|
+
|
|
89
|
+
export const Default: Story = {
|
|
90
|
+
args: {
|
|
91
|
+
place: 'bottom',
|
|
92
|
+
id: 'tooltip-1',
|
|
93
|
+
clickToShow: false,
|
|
94
|
+
delayShow: 0,
|
|
95
|
+
delayHide: 0,
|
|
96
|
+
zIndex: 1000,
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
render: (args) => {
|
|
100
|
+
return (
|
|
101
|
+
<Container>
|
|
102
|
+
<Row>
|
|
103
|
+
<Col sm={4}>
|
|
104
|
+
<Button ariaLabel="Tooltip Button" data-tooltip-id="tooltip-1">
|
|
105
|
+
Tooltip!
|
|
106
|
+
</Button>
|
|
107
|
+
<Tooltip {...args}>Tooltip Content</Tooltip>
|
|
108
|
+
</Col>
|
|
109
|
+
</Row>
|
|
110
|
+
</Container>
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { PlacesType, Tooltip as ReactTooltip } from 'react-tooltip';
|
|
2
|
+
|
|
3
|
+
interface TooltipProps {
|
|
4
|
+
id: string;
|
|
5
|
+
clickToShow?: boolean;
|
|
6
|
+
delayShow?: number;
|
|
7
|
+
delayHide?: number;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
zIndex?: number;
|
|
10
|
+
place?: PlacesType;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const Tooltip = ({
|
|
15
|
+
id,
|
|
16
|
+
clickToShow,
|
|
17
|
+
delayShow,
|
|
18
|
+
delayHide,
|
|
19
|
+
children,
|
|
20
|
+
zIndex = 1000,
|
|
21
|
+
place = 'top',
|
|
22
|
+
...rest
|
|
23
|
+
}: TooltipProps) => {
|
|
24
|
+
return (
|
|
25
|
+
<ReactTooltip
|
|
26
|
+
border="solid 1px var(--pf-border-color)"
|
|
27
|
+
id={id}
|
|
28
|
+
place={place}
|
|
29
|
+
openOnClick={clickToShow}
|
|
30
|
+
delayShow={delayShow}
|
|
31
|
+
delayHide={delayHide}
|
|
32
|
+
style={{ zIndex }}
|
|
33
|
+
{...rest}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</ReactTooltip>
|
|
37
|
+
);
|
|
38
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -4,8 +4,6 @@ import './setup/setupIcons';
|
|
|
4
4
|
// This is so consumers of the DS can import floating ui functions/hooks/types from the DS rather than the (peer dependency) floating-ui package
|
|
5
5
|
export * from '@floating-ui/react-dom';
|
|
6
6
|
|
|
7
|
-
export { BarSpinner, CirclePulse, CircleSpinner, Tooltip } from './legacy/components';
|
|
8
|
-
|
|
9
7
|
export { Container, Row, Col } from './components/grid';
|
|
10
8
|
export { Button } from './components/button';
|
|
11
9
|
export { Icon } from './components/icons';
|
|
@@ -30,6 +28,10 @@ export { Pill } from './components/pill';
|
|
|
30
28
|
export { Badge } from './components/badge';
|
|
31
29
|
export { Modal } from './components/modal';
|
|
32
30
|
export { TanstackTable } from './components/tanstackTable';
|
|
31
|
+
export { Tooltip } from './components/tooltip';
|
|
32
|
+
export { Pagination } from './components/pagination';
|
|
33
|
+
export { CirclePulse } from './components/loading-indicators/CirclePulse';
|
|
34
|
+
export { BarSpinner } from './components/loading-indicators/BarSpinner/BarSpinner';
|
|
33
35
|
|
|
34
36
|
// Utilities
|
|
35
37
|
export { registerFontAwesomeIcons } from './setup/setupIcons';
|
package/src/styles/globals.scss
CHANGED
|
@@ -74,3 +74,12 @@ a,
|
|
|
74
74
|
.theme {
|
|
75
75
|
background-color: var(--pf-background-color);
|
|
76
76
|
}
|
|
77
|
+
|
|
78
|
+
// Tooltip
|
|
79
|
+
.react-tooltip {
|
|
80
|
+
z-index: 5;
|
|
81
|
+
background-color: var(--pf-tooltip-background-color);
|
|
82
|
+
border: var(--pf-border-sm) solid var(--pf-border-color);
|
|
83
|
+
opacity: 1 !important;
|
|
84
|
+
text-wrap: wrap;
|
|
85
|
+
}
|
package/src/styles/index.scss
CHANGED
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
@import '../components/tanstackTable/styles/table.scss';
|
|
29
29
|
@import '../components/forms/timePicker/styles/TimePicker.scss';
|
|
30
30
|
@import '../components/pill/styles/Pill.scss';
|
|
31
|
+
@import '../components/tooltip/styles/Tooltip.scss';
|
|
32
|
+
@import '../components/loading-indicators/BarSpinner/styles/BarSpinner.scss';
|
|
33
|
+
@import '../components/loading-indicators/CirclePulse/CirclePulse.scss';
|
|
31
34
|
@import 'sheets'; // Port to an sheets component when we build it
|
|
32
35
|
@import 'typography';
|
|
33
36
|
@import 'colors';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { PermafrostComponent } from '../../../types';
|
|
3
|
-
type Props = PermafrostComponent & {
|
|
4
|
-
questionMark?: boolean;
|
|
5
|
-
for?: string | null;
|
|
6
|
-
place?: string;
|
|
7
|
-
clickToShow?: boolean;
|
|
8
|
-
delayShow?: number;
|
|
9
|
-
delayHide?: number;
|
|
10
|
-
questionMarkClassName?: string;
|
|
11
|
-
children: React.ReactNode;
|
|
12
|
-
block?: boolean;
|
|
13
|
-
};
|
|
14
|
-
export declare const Tooltip: (props: Props) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
-
export {};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { Tooltip } from './Tooltip';
|
|
3
|
-
declare const meta: Meta<typeof Tooltip>;
|
|
4
|
-
export default meta;
|
|
5
|
-
type Story = StoryObj<typeof Tooltip>;
|
|
6
|
-
export declare const Single: Story;
|
|
7
|
-
export declare const NoQuestionMark: Story;
|
|
8
|
-
export declare const Bottom: Story;
|
|
9
|
-
export declare const Right: Story;
|