@grafana/ui
Version:
Grafana Components Library
1 lines • 11.4 kB
Source Map (JSON)
{"version":3,"file":"UserIcon.cjs","sources":["../../../../src/components/UsersIndicator/UserIcon.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { useMemo, type PropsWithChildren } from 'react';\n\nimport { dateTime, type DateTimeInput, type GrafanaTheme2 } from '@grafana/data';\nimport { t, Trans } from '@grafana/i18n';\n\nimport { useTheme2 } from '../../themes/ThemeContext';\nimport { Tooltip } from '../Tooltip/Tooltip';\n\nimport { type UserView } from './types';\n\nexport interface UserIconProps {\n /** An object that contains the user's details and an optional 'lastActiveAt' status */\n userView: UserView;\n /** A boolean value that determines whether the tooltip should be shown or not */\n showTooltip?: boolean;\n /** An optional class name to be added to the icon element */\n className?: string;\n /** onClick handler to be called when the icon is clicked */\n onClick?: () => void;\n}\n\n/**\n * A helper function that takes in a dateString parameter\n * and returns the user's last viewed date in a specific format.\n */\nconst formatViewed = (dateString: DateTimeInput): string => {\n const date = dateTime(dateString);\n const diffHours = date.diff(dateTime(), 'hours', false);\n return `Active last ${(Math.floor(-diffHours / 24) + 1) * 24}h`;\n};\n\n/**\n * Output the initials of the first and last name (if given), capitalized and concatenated together.\n * If name is not provided, an empty string is returned.\n * @param {string} [name] The name to extract initials from.\n * @returns {string} The uppercase initials of the first and last name.\n * @example\n * // Returns 'JD'\n * getUserInitials('John Doe');\n * // Returns 'A'\n * getUserInitials('Alice');\n * // Returns ''\n * getUserInitials();\n */\nconst getUserInitials = (name?: string) => {\n if (!name) {\n return '';\n }\n const [first, last] = name.split(' ');\n return `${first?.[0] ?? ''}${last?.[0] ?? ''}`.toUpperCase();\n};\n\n/**\n * UserIcon renders a user icon and displays the user's name or initials along with the user's active status or last viewed date.\n *\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/iconography-usericon--docs\n */\nexport const UserIcon = ({\n userView,\n className,\n children,\n onClick,\n showTooltip = true,\n}: PropsWithChildren<UserIconProps>) => {\n const { user, lastActiveAt } = userView;\n const hasActive = lastActiveAt !== undefined && lastActiveAt !== null;\n const isActive = hasActive && dateTime(lastActiveAt).diff(dateTime(), 'minutes', true) >= -15;\n const theme = useTheme2();\n const styles = useMemo(() => getStyles(theme, isActive), [theme, isActive]);\n\n const content = children ? (\n <div className={cx(styles.content, styles.textContent)}>{children}</div>\n ) : user.avatarUrl ? (\n <img className={styles.content} src={user.avatarUrl} alt={`${user.name} avatar`} />\n ) : (\n <div className={cx(styles.content, styles.textContent)}>{getUserInitials(user.name)}</div>\n );\n\n const wrapper = onClick ? (\n <button\n type={'button'}\n onClick={onClick}\n className={cx(styles.container, styles.hover, styles.pointer, className)}\n aria-label={t('grafana-ui.user-icon.label', '{{name}} icon', { name: user.name })}\n >\n {content}\n </button>\n ) : (\n // a11y: don't render an interactive button if icon is not clickable\n <div\n aria-label={t('grafana-ui.user-icon.label', '{{name}} icon', { name: user.name })}\n className={cx(styles.container, className)}\n >\n {content}\n </div>\n );\n\n if (showTooltip) {\n const tooltip = (\n <div className={styles.tooltipContainer} data-testid=\"user-icon-tooltip\">\n <div className={styles.tooltipName}>{user.name}</div>\n {hasActive && (\n <div className={styles.tooltipDate}>\n {isActive ? (\n <div className={styles.dotContainer}>\n <span>\n <Trans i18nKey=\"grafana-ui.user-icon.active-text\">Active last 15m</Trans>\n </span>\n <span className={styles.dot}></span>\n </div>\n ) : (\n formatViewed(lastActiveAt)\n )}\n </div>\n )}\n </div>\n );\n\n return <Tooltip content={tooltip}>{wrapper}</Tooltip>;\n } else {\n return wrapper;\n }\n};\n\nconst getIconBorder = (color: string): string => {\n return `0 0 0 1px ${color}`;\n};\n\nconst getStyles = (theme: GrafanaTheme2, isActive: boolean) => {\n const shadowColor = isActive ? theme.colors.primary.main : theme.colors.border.medium;\n const shadowHoverColor = isActive ? theme.colors.primary.text : theme.colors.border.strong;\n\n return {\n container: css({\n padding: 0,\n width: '30px',\n height: '30px',\n background: 'none',\n border: 'none',\n borderRadius: theme.shape.radius.circle,\n cursor: 'default',\n '& > *': {\n borderRadius: theme.shape.radius.circle,\n },\n }),\n content: css({\n lineHeight: '24px',\n maxWidth: '100%',\n border: `3px ${theme.colors.background.primary} solid`,\n boxShadow: getIconBorder(shadowColor),\n backgroundClip: 'padding-box',\n }),\n textContent: css({\n background: theme.colors.background.primary,\n padding: 0,\n color: theme.colors.text.secondary,\n textAlign: 'center',\n fontSize: theme.typography.size.sm,\n '&:focus': {\n boxShadow: getIconBorder(shadowColor),\n },\n }),\n tooltipContainer: css({\n textAlign: 'center',\n padding: theme.spacing(0, 1),\n }),\n tooltipName: css({\n fontWeight: theme.typography.fontWeightBold,\n }),\n tooltipDate: css({\n fontWeight: theme.typography.fontWeightRegular,\n }),\n dotContainer: css({\n display: 'flex',\n alignItems: 'center',\n }),\n dot: css({\n height: '6px',\n width: '6px',\n backgroundColor: theme.colors.primary.main,\n borderRadius: theme.shape.radius.circle,\n display: 'inline-block',\n marginLeft: theme.spacing(1),\n }),\n pointer: css({\n cursor: 'pointer',\n }),\n hover: css({\n '&:hover > *': {\n boxShadow: getIconBorder(shadowHoverColor),\n },\n }),\n };\n};\n"],"names":["dateTime","useTheme2","useMemo","jsx","cx","t","jsxs","Trans","Tooltip","css"],"mappings":"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"}