Skip to content

Commit 06e6020

Browse files
dantovskaKIvanow
andauthored
RI-7263: Replace EUI empty prompt (#4778)
* create loading logo component * move import from layout to display * add sizing to the component * use $ for size and bounceSpeed instead of Omit * implement redis theme sizing * Rename folder logo-loading -> loading-logo * create and export RiEmptyPrompt component * replace the eui component with the new one * Include the ...rest in the empty prompt component * Extended spacer to support theme sizes --------- Co-authored-by: Kristiyan Ivanov <k.ivanow@gmail.com>
1 parent 8bcb187 commit 06e6020

File tree

6 files changed

+89
-16
lines changed

6 files changed

+89
-16
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React, { HTMLAttributes } from 'react'
2+
import styled from 'styled-components'
3+
import { useTheme } from '@redis-ui/styles'
4+
import { Spacer } from '../spacer'
5+
6+
interface RiEmptyPromptProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
7+
body?: React.ReactNode
8+
title?: React.ReactNode
9+
icon?: React.ReactNode
10+
}
11+
12+
const StyledEmptyPrompt = styled.div`
13+
max-width: 36em;
14+
text-align: center;
15+
padding: 24px;
16+
margin: auto;
17+
`
18+
19+
const RiEmptyPrompt = ({ body, title, icon, ...rest }: RiEmptyPromptProps) => {
20+
const theme = useTheme()
21+
22+
return (<StyledEmptyPrompt {...rest}>
23+
{icon}
24+
{title && (
25+
<>
26+
<Spacer size={theme.core.space.space100} />
27+
{title}
28+
</>
29+
)}
30+
{body && (
31+
<>
32+
<Spacer size={theme.core.space.space100} />
33+
{body}
34+
</>
35+
)}
36+
</StyledEmptyPrompt>
37+
)
38+
}
39+
40+
41+
export default RiEmptyPrompt

redisinsight/ui/src/components/base/layout/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import LoadingContent from './loading-content/LoadingContent'
33
import ResizableContainer from './resize/container/ResizableContainer'
44
import ResizablePanel from './resize/panel/ResizablePanel'
55
import ResizablePanelHandle from './resize/handle/ResizablePanelHandle'
6-
6+
import RiEmptyPrompt from './empty-prompt/RiEmptyPrompt'
77

88
export * from './card'
99
export * from './horizontal-spacer'
@@ -14,4 +14,5 @@ export {
1414
ResizablePanel,
1515
ResizableContainer,
1616
ResizablePanelHandle,
17+
RiEmptyPrompt,
1718
}

redisinsight/ui/src/components/base/layout/spacer/spacer.styles.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import { HTMLAttributes, ReactNode } from 'react'
22
import styled from 'styled-components'
33
import { CommonProps } from 'uiSrc/components/base/theme/types'
4+
import { theme } from 'uiSrc/components/base/theme'
45

56
export const SpacerSizes = ['xs', 's', 'm', 'l', 'xl', 'xxl'] as const
67
export type SpacerSize = (typeof SpacerSizes)[number]
8+
9+
// Extract only the spaceXXX keys from the theme
10+
export type ThemeSpacingKey = Extract<keyof typeof theme.semantic.core.space, `space${string}`>
11+
// Allow direct theme spacing values
12+
export type ThemeSpacingValue = typeof theme.semantic.core.space[ThemeSpacingKey]
13+
714
export type SpacerProps = CommonProps &
815
HTMLAttributes<HTMLDivElement> & {
916
children?: ReactNode
10-
size?: SpacerSize
17+
size?: SpacerSize | ThemeSpacingKey | ThemeSpacingValue
1118
}
1219

1320
export const spacerStyles = {
@@ -20,7 +27,26 @@ export const spacerStyles = {
2027
xxl: 'var(--size-xxl)',
2128
}
2229

30+
const isThemeSpacingKey = (
31+
size: SpacerSize | ThemeSpacingKey | ThemeSpacingValue
32+
): size is ThemeSpacingKey => typeof size === 'string' && size in theme.semantic.core.space
33+
34+
const getSpacingValue = (
35+
size: SpacerSize | ThemeSpacingKey | ThemeSpacingValue,
36+
): string => {
37+
const themeSpacingValues = Object.values(theme.semantic.core.space)
38+
if (typeof size === 'string' && themeSpacingValues.includes(size)) {
39+
return size
40+
}
41+
42+
if (isThemeSpacingKey(size)) {
43+
return theme?.semantic?.core?.space?.[size] || '0'
44+
}
45+
46+
return spacerStyles[size as SpacerSize]
47+
}
48+
2349
export const StyledSpacer = styled.div<SpacerProps>`
2450
flex-shrink: 0;
25-
height: ${({ size = 'l' }) => spacerStyles[size]};
51+
height: ${({ size = 'l' }) => getSpacingValue(size)};
2652
`
Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react'
22
import cx from 'classnames'
3+
import { useTheme } from '@redis-ui/styles'
34
import {
45
SpacerProps,
56
StyledSpacer,
@@ -9,17 +10,21 @@ import {
910
* A simple spacer component that can be used to add vertical spacing between
1011
* other components. The size of the spacer can be specified using the `size`
1112
* prop, which can be one of the following values:
12-
* - 'xs' = 4px
13-
* - 's' = 8px
14-
* - 'm' = 12px
15-
* - 'l' = 16px
16-
* - 'xl' = 24px
17-
* - 'xxl' = 32px.
13+
* - Legacy sizes: 'xs' = 4px, 's' = 8px, 'm' = 12px, 'l' = 16px, 'xl' = 24px, 'xxl' = 32px
14+
* - Theme spacing sizes: Any key from theme.semantic.core.space (e.g., 'space000', 'space010',
15+
* 'space025', 'space050', 'space100', 'space150', 'space200', 'space250', 'space300',
16+
* 'space400', 'space500', 'space550', 'space600', 'space800', etc.)
17+
*
18+
* The theme spacing tokens are dynamically extracted from the theme, ensuring consistency
19+
* and automatic updates when the theme changes.
1820
*
1921
* The default value for `size` is 'l'.
2022
*/
21-
export const Spacer = ({ className, children, ...rest }: SpacerProps) => (
22-
<StyledSpacer {...rest} className={cx('RI-spacer', className)}>
23+
export const Spacer = ({ className, children, ...rest }: SpacerProps) => {
24+
const theme = useTheme()
25+
return (
26+
<StyledSpacer {...rest} className={cx('RI-spacer', className)} theme={theme}>
2327
{children}
2428
</StyledSpacer>
2529
)
30+
}

redisinsight/ui/src/components/page-placeholder/PagePlaceholder.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import React from 'react'
2-
import { EuiEmptyPrompt } from '@elastic/eui'
2+
33
import LogoIcon from 'uiSrc/assets/img/logo_small.svg'
44
import { getConfig } from 'uiSrc/config'
55
import { RiLoadingLogo } from 'uiSrc/components/base/display'
6+
import { RiEmptyPrompt } from 'uiSrc/components/base/layout'
67

78
const riConfig = getConfig()
89

910
const PagePlaceholder = () => (
1011
<>
1112
{riConfig.app.env !== 'development' && (
12-
<EuiEmptyPrompt
13+
<RiEmptyPrompt
1314
data-testid="page-placeholder"
1415
icon={<RiLoadingLogo src={LogoIcon} $size="XXL" />}
15-
titleSize="s"
1616
/>
1717
)}
1818
</>

redisinsight/ui/src/components/side-panels/panels/enablement-area/EnablementArea/components/EmptyPrompt/EmptyPrompt.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React from 'react'
2-
import { EuiEmptyPrompt } from '@elastic/eui'
32

43
import { EXTERNAL_LINKS } from 'uiSrc/constants/links'
54
import { RiIcon } from 'uiSrc/components/base/icons/RiIcon'
65
import { Link } from 'uiSrc/components/base/link/Link'
6+
import { RiEmptyPrompt } from 'uiSrc/components/base/layout'
77
import styles from './styles.module.scss'
88

99
const EmptyPrompt = () => (
1010
<div className={styles.container}>
11-
<EuiEmptyPrompt
11+
<RiEmptyPrompt
1212
data-testid="enablement-area__empty-prompt"
1313
icon={<RiIcon type="ToastDangerIcon" color="danger600" size="l" />}
1414
title={<h2>No information to display</h2>}

0 commit comments

Comments
 (0)