mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
fix(components): standardize ExternalLink styling and add copy functionality
- Fix inconsistent icon sizes in ExternalLink component by removing hardcoded props. - Standardize icon alignment using new CSS class. - Add copy-to-clipboard functionality when clicking the link text.
This commit is contained in:
parent
2c91d4e68d
commit
95074fa38d
3 changed files with 35 additions and 7 deletions
14
src/components/common/ExternalLink.module.css
Normal file
14
src/components/common/ExternalLink.module.css
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
.link {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconLink {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: var(--base-color-10);
|
||||||
|
}
|
||||||
|
|
@ -1,23 +1,36 @@
|
||||||
import { Icon, Row, Text } from '@umami/react-zen';
|
'use client';
|
||||||
|
import { Icon, Row, Text, useToast } from '@umami/react-zen';
|
||||||
import Link, { type LinkProps } from 'next/link';
|
import Link, { type LinkProps } from 'next/link';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
import { useMessages } from '@/components/hooks';
|
||||||
import { ExternalLink as LinkIcon } from '@/components/icons';
|
import { ExternalLink as LinkIcon } from '@/components/icons';
|
||||||
|
import styles from './ExternalLink.module.css';
|
||||||
|
|
||||||
export function ExternalLink({
|
export function ExternalLink({
|
||||||
href,
|
href,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}: LinkProps & { href: string; children: ReactNode }) {
|
}: Omit<LinkProps, 'href'> & { href: string; children: ReactNode }) {
|
||||||
|
const { toast } = useToast();
|
||||||
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
||||||
|
const handleCopy = () => {
|
||||||
|
navigator.clipboard.writeText(href);
|
||||||
|
toast(formatMessage(labels.copied));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row alignItems="center" overflow="hidden" gap>
|
<Row alignItems="center" overflow="hidden" gap>
|
||||||
<Text title={href} truncate>
|
<Text title={href} truncate>
|
||||||
<Link {...props} href={href} target="_blank">
|
<span onClick={handleCopy} className={styles.link}>
|
||||||
{children}
|
{children}
|
||||||
</Link>
|
</span>
|
||||||
</Text>
|
</Text>
|
||||||
<Icon size="sm" strokeColor="muted">
|
<Link {...props} href={href} target="_blank" className={styles.iconLink}>
|
||||||
<LinkIcon />
|
<Icon>
|
||||||
</Icon>
|
<LinkIcon />
|
||||||
|
</Icon>
|
||||||
|
</Link>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -364,6 +364,7 @@ export const labels = defineMessages({
|
||||||
documentation: { id: 'label.documentation', defaultMessage: 'Documentation' },
|
documentation: { id: 'label.documentation', defaultMessage: 'Documentation' },
|
||||||
switchAccount: { id: 'label.switch-account', defaultMessage: 'Switch account' },
|
switchAccount: { id: 'label.switch-account', defaultMessage: 'Switch account' },
|
||||||
advanced: { id: 'label.advanced', defaultMessage: 'Advanced' },
|
advanced: { id: 'label.advanced', defaultMessage: 'Advanced' },
|
||||||
|
copied: { id: 'label.copied', defaultMessage: 'Copied to clipboard' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const messages = defineMessages({
|
export const messages = defineMessages({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue