diff --git a/apps/docs/content/docs/components/actions/link.mdx b/apps/docs/content/docs/components/actions/link.mdx
index 9fa51de4..0191956e 100644
--- a/apps/docs/content/docs/components/actions/link.mdx
+++ b/apps/docs/content/docs/components/actions/link.mdx
@@ -14,26 +14,28 @@ description: Link component for inline and standalone navigation.
| Guidance | Practices |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
-| Do | Use `tone="inverted"` only on dark backgrounds. On light backgrounds, it is hard to read. |
+| Do | Use the default `accent` tone for links that should draw attention. |
| Do | Use `isStandalone` for links that are not part of a sentence, such as card links and nav items. Leave it `false` for inline links. |
## Tone
-`Link` has three tones: `brand` (default), `neutral`, and `inverted`. Use `neutral` for a more
-subtle link. Use `inverted` on dark backgrounds.
+`Link` has two tones: `accent` (default) and `neutral`. Use `neutral` when the surrounding content
+should have more emphasis.
## Standalone
Use `isStandalone` when a link stands on its own. Leave it `false` for links inside paragraph text.
-- `isStandalone={true}`: no underline until hover.
-- `isStandalone={false}`: underlined inline link style.
+- `isStandalone={true}`: no underline until hover or press and a structural target of at least 24 ×
+ 24 CSS pixels.
+- `isStandalone={false}`: underlined inline link style that retains the target-size exception for
+ links within prose.
- Brand
+ Accent
Neutral
-
-
- Inverted
-
-
);
}
diff --git a/packages/@luke-ui/react/src/link/index.tsx b/packages/@luke-ui/react/src/link/index.tsx
index 8fac704f..b9a3d0bd 100644
--- a/packages/@luke-ui/react/src/link/index.tsx
+++ b/packages/@luke-ui/react/src/link/index.tsx
@@ -9,9 +9,9 @@ import { cx } from '../utils/index.js';
interface LinkVariantProps extends NonNullable {}
interface LinkStyleProps {
- /** Hides underline until hover. */
+ /** Hides the underline until hover or press and provides a structural 24px target. */
isStandalone?: LinkVariantProps['isStandalone'];
- /** Sets the link tone. */
+ /** Sets the link tone. @default 'accent' */
tone?: LinkVariantProps['tone'];
}
diff --git a/packages/@luke-ui/react/src/link/link.stories.tsx b/packages/@luke-ui/react/src/link/link.stories.tsx
index 579a22ad..2f2bbc77 100644
--- a/packages/@luke-ui/react/src/link/link.stories.tsx
+++ b/packages/@luke-ui/react/src/link/link.stories.tsx
@@ -1,7 +1,7 @@
import type { LinkProps } from '@luke-ui/react/link';
import { Link } from '@luke-ui/react/link';
import type { CSSProperties } from 'react';
-import { expect } from 'storybook/test';
+import { expect, fn, userEvent } from 'storybook/test';
import preview from '../../.storybook/preview.js';
const meta = preview.meta({
@@ -23,12 +23,6 @@ const stackStyle = {
maxInlineSize: '40rem',
} as const satisfies CSSProperties;
-const darkPanelStyle = {
- backgroundColor: 'oklch(0.2 0 0)',
- paddingBlock: '0.125rem',
- paddingInline: '0.25rem',
-} as const satisfies CSSProperties;
-
/**
* Use `Link` for navigation and external destinations while preserving native
* anchor behavior.
@@ -36,30 +30,30 @@ const darkPanelStyle = {
export const Default = meta.story({
args: baseArgs,
play: async ({ canvas }) => {
- await expect(canvas.getByRole('link', { name: 'Link' })).toBeInTheDocument();
+ const link = canvas.getByRole('link', { name: 'Link' });
+ await userEvent.tab();
+ await expect(link).toHaveFocus();
+ await expect(getComputedStyle(link).outlineStyle).toBe('solid');
+ await expect(getComputedStyle(link).outlineWidth).toBe('2px');
+ await expect(getComputedStyle(link).outlineOffset).toBe('2px');
},
});
/**
- * Link tone controls contrast against surrounding UI. Use `neutral` for
- * reduced emphasis and `inverted` on dark surfaces.
+ * Use the default `accent` tone for emphasis or `neutral` when the surrounding
+ * content should lead.
*/
export const Tone = meta.story({
args: {
...baseArgs,
- children: 'Brand (default)',
+ children: 'Accent (default)',
} satisfies Partial,
render: (props) => (