|
|
|
@ -1,5 +1,6 @@ |
|
|
|
|
import { css, cx } from '@emotion/css'; |
|
|
|
|
import React from 'react'; |
|
|
|
|
import Skeleton from 'react-loading-skeleton'; |
|
|
|
|
|
|
|
|
|
import { DataFrameView, GrafanaTheme2, textUtil, dateTimeFormat } from '@grafana/data'; |
|
|
|
|
import { useStyles2 } from '@grafana/ui'; |
|
|
|
@ -45,68 +46,93 @@ export function News({ width, showImage, data, index }: NewsItemProps) { |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const NewsSkeleton = ({ width, showImage }: Pick<NewsItemProps, 'width' | 'showImage'>) => { |
|
|
|
|
const styles = useStyles2(getStyles); |
|
|
|
|
const useWideLayout = width > 600; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div className={cx(styles.item, useWideLayout && styles.itemWide)}> |
|
|
|
|
{showImage && ( |
|
|
|
|
<Skeleton |
|
|
|
|
containerClassName={cx(styles.socialImage, useWideLayout && styles.socialImageWide)} |
|
|
|
|
width={useWideLayout ? '250px' : '100%'} |
|
|
|
|
height={useWideLayout ? '150px' : width * 0.5} |
|
|
|
|
/> |
|
|
|
|
)} |
|
|
|
|
<div className={styles.body}> |
|
|
|
|
<Skeleton containerClassName={styles.date} width={60} /> |
|
|
|
|
<Skeleton containerClassName={styles.title} width={250} /> |
|
|
|
|
<Skeleton containerClassName={styles.content} width="100%" count={6} /> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
News.Skeleton = NewsSkeleton; |
|
|
|
|
|
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({ |
|
|
|
|
container: css` |
|
|
|
|
height: 100%; |
|
|
|
|
`,
|
|
|
|
|
item: css` |
|
|
|
|
display: flex; |
|
|
|
|
padding: ${theme.spacing(1)}; |
|
|
|
|
position: relative; |
|
|
|
|
margin-bottom: 4px; |
|
|
|
|
margin-right: ${theme.spacing(1)}; |
|
|
|
|
border-bottom: 2px solid ${theme.colors.border.weak}; |
|
|
|
|
background: ${theme.colors.background.primary}; |
|
|
|
|
flex-direction: column; |
|
|
|
|
flex-shrink: 0; |
|
|
|
|
`,
|
|
|
|
|
itemWide: css` |
|
|
|
|
flex-direction: row; |
|
|
|
|
`,
|
|
|
|
|
body: css` |
|
|
|
|
display: flex; |
|
|
|
|
flex-direction: column; |
|
|
|
|
`,
|
|
|
|
|
socialImage: css` |
|
|
|
|
display: flex; |
|
|
|
|
align-items: center; |
|
|
|
|
margin-bottom: ${theme.spacing(1)}; |
|
|
|
|
> img { |
|
|
|
|
width: 100%; |
|
|
|
|
border-radius: ${theme.shape.radius.default} ${theme.shape.radius.default} 0 0; |
|
|
|
|
} |
|
|
|
|
`,
|
|
|
|
|
socialImageWide: css` |
|
|
|
|
margin-right: ${theme.spacing(2)}; |
|
|
|
|
margin-bottom: 0; |
|
|
|
|
> img { |
|
|
|
|
width: 250px; |
|
|
|
|
border-radius: ${theme.shape.radius.default}; |
|
|
|
|
} |
|
|
|
|
`,
|
|
|
|
|
link: css` |
|
|
|
|
color: ${theme.colors.text.link}; |
|
|
|
|
display: inline-block; |
|
|
|
|
container: css({ |
|
|
|
|
height: '100%', |
|
|
|
|
}), |
|
|
|
|
item: css({ |
|
|
|
|
display: 'flex', |
|
|
|
|
padding: theme.spacing(1), |
|
|
|
|
position: 'relative', |
|
|
|
|
marginBottom: theme.spacing(0.5), |
|
|
|
|
marginRight: theme.spacing(1), |
|
|
|
|
borderBottom: `2px solid ${theme.colors.border.weak}`, |
|
|
|
|
background: theme.colors.background.primary, |
|
|
|
|
flexDirection: 'column', |
|
|
|
|
flexShrink: 0, |
|
|
|
|
}), |
|
|
|
|
itemWide: css({ |
|
|
|
|
flexDirection: 'row', |
|
|
|
|
}), |
|
|
|
|
body: css({ |
|
|
|
|
display: 'flex', |
|
|
|
|
flexDirection: 'column', |
|
|
|
|
flex: 1, |
|
|
|
|
}), |
|
|
|
|
socialImage: css({ |
|
|
|
|
display: 'flex', |
|
|
|
|
alignItems: 'center', |
|
|
|
|
marginBottom: theme.spacing(1), |
|
|
|
|
'> img': { |
|
|
|
|
width: '100%', |
|
|
|
|
borderRadius: `${theme.shape.radius.default} ${theme.shape.radius.default} 0 0`, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
socialImageWide: css({ |
|
|
|
|
marginRight: theme.spacing(2), |
|
|
|
|
marginBottom: 0, |
|
|
|
|
'> img': { |
|
|
|
|
width: '250px', |
|
|
|
|
borderRadius: theme.shape.radius.default, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
link: css({ |
|
|
|
|
color: theme.colors.text.link, |
|
|
|
|
display: 'inline-block', |
|
|
|
|
|
|
|
|
|
&:hover { |
|
|
|
|
color: ${theme.colors.text.link}; |
|
|
|
|
text-decoration: underline; |
|
|
|
|
} |
|
|
|
|
`,
|
|
|
|
|
title: css` |
|
|
|
|
font-size: 16px; |
|
|
|
|
margin-bottom: ${theme.spacing(0.5)}; |
|
|
|
|
`,
|
|
|
|
|
content: css` |
|
|
|
|
p { |
|
|
|
|
margin-bottom: 4px; |
|
|
|
|
color: ${theme.colors.text}; |
|
|
|
|
} |
|
|
|
|
`,
|
|
|
|
|
date: css` |
|
|
|
|
margin-bottom: ${theme.spacing(0.5)}; |
|
|
|
|
font-weight: 500; |
|
|
|
|
border-radius: 0 0 0 ${theme.shape.radius.default}; |
|
|
|
|
color: ${theme.colors.text.secondary}; |
|
|
|
|
`,
|
|
|
|
|
'&:hover': { |
|
|
|
|
color: theme.colors.text.link, |
|
|
|
|
textDecoration: 'underline', |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
title: css({ |
|
|
|
|
fontSize: '16px', |
|
|
|
|
marginBottom: theme.spacing(0.5), |
|
|
|
|
}), |
|
|
|
|
content: css({ |
|
|
|
|
p: { |
|
|
|
|
marginBottom: theme.spacing(0.5), |
|
|
|
|
color: theme.colors.text.primary, |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
date: css({ |
|
|
|
|
marginBottom: theme.spacing(0.5), |
|
|
|
|
fontWeight: 500, |
|
|
|
|
borderRadius: `0 0 0 ${theme.shape.radius.default}`, |
|
|
|
|
color: theme.colors.text.secondary, |
|
|
|
|
}), |
|
|
|
|
}); |
|
|
|
|