mirror of
https://github.com/tale/headplane.git
synced 2026-08-31 01:09:25 +00:00
feat: redesign chip attribute
This commit is contained in:
@@ -6,41 +6,35 @@ export interface AttributeProps {
|
|||||||
name: string;
|
name: string;
|
||||||
value: string;
|
value: string;
|
||||||
isCopyable?: boolean;
|
isCopyable?: boolean;
|
||||||
link?: string;
|
|
||||||
suppressHydrationWarning?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Attribute({
|
export default function Attribute({ name, value, isCopyable }: AttributeProps) {
|
||||||
name,
|
|
||||||
value,
|
|
||||||
link,
|
|
||||||
isCopyable,
|
|
||||||
suppressHydrationWarning,
|
|
||||||
}: AttributeProps) {
|
|
||||||
return (
|
return (
|
||||||
<dl className="flex items-center w-full gap-x-1">
|
<dl className="flex gap-1 items-center text-sm">
|
||||||
<dt className="font-semibold w-1/4 shrink-0 text-sm">
|
<dt
|
||||||
{link ? (
|
className={cn(
|
||||||
<a className="hover:underline" href={link}>
|
'w-1/3 sm:w-1/4 lg:w-1/3 shrink-0 min-w-0 truncate',
|
||||||
{name}
|
'text-headplane-500 dark:text-headplane-400',
|
||||||
</a>
|
|
||||||
) : (
|
|
||||||
name
|
|
||||||
)}
|
)}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
</dt>
|
</dt>
|
||||||
<dd
|
<dd
|
||||||
suppressHydrationWarning={suppressHydrationWarning}
|
|
||||||
className={cn(
|
className={cn(
|
||||||
'rounded-lg truncate w-full px-2.5 py-1 text-sm',
|
'min-w-0 px-1.5 py-1 rounded-lg border border-transparent',
|
||||||
'flex items-center gap-x-1',
|
...(isCopyable
|
||||||
'focus-within:outline-none focus-within:ring-2',
|
? [
|
||||||
isCopyable && 'hover:bg-headplane-100 dark:hover:bg-headplane-800',
|
'cursor-pointer hover:shadow-sm',
|
||||||
|
'hover:bg-headplane-50 dark:hover:bg-headplane-800',
|
||||||
|
'hover:border-headplane-100 dark:hover:border-headplane-700',
|
||||||
|
]
|
||||||
|
: []),
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isCopyable ? (
|
{isCopyable ? (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="w-full flex items-center gap-x-1 outline-none"
|
className="flex items-center gap-1.5 relative min-w-0 w-full"
|
||||||
onClick={async (event) => {
|
onClick={async (event) => {
|
||||||
const svgs = event.currentTarget.querySelectorAll('svg');
|
const svgs = event.currentTarget.querySelectorAll('svg');
|
||||||
for (const svg of svgs) {
|
for (const svg of svgs) {
|
||||||
@@ -48,7 +42,7 @@ export default function Attribute({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await navigator.clipboard.writeText(value);
|
await navigator.clipboard.writeText(value);
|
||||||
toast('Copied to clipboard');
|
toast(`Copied ${name} to clipboard`);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
for (const svg of svgs) {
|
for (const svg of svgs) {
|
||||||
@@ -57,17 +51,20 @@ export default function Attribute({
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p
|
<div suppressHydrationWarning className="truncate">
|
||||||
suppressHydrationWarning={suppressHydrationWarning}
|
|
||||||
className="truncate"
|
|
||||||
>
|
|
||||||
{value}
|
{value}
|
||||||
</p>
|
</div>
|
||||||
<Check className="h-4.5 w-4.5 p-1 hidden data-[copied]:block" />
|
{isCopyable ? (
|
||||||
<Copy className="h-4.5 w-4.5 p-1 block data-[copied]:hidden" />
|
<div>
|
||||||
|
<Check className="size-4 hidden data-[copied]:block" />
|
||||||
|
<Copy className="size-4 block data-[copied]:hidden" />
|
||||||
|
</div>
|
||||||
|
) : undefined}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
value
|
<div className="relative min-w-0 truncate" suppressHydrationWarning>
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|||||||
Reference in New Issue
Block a user