Anchor
A link — which is sometimes not a link.
import { ... } from '@corndev/ui' HTML
No JavaScript required — these classes are the whole component.
<a class="corn-anchor" data-underline="always" href="/docs">Docs</a>
Classes
| Class |
|---|
.corn-anchor |
Attributes
| Attribute | Values |
|---|---|
data-underline | hover|always |
data-muted | present or absent |
Vanilla JS
Optional. createAnchor only adds and removes the classes and attributes above, so the HTML is equivalent. Reach for it when you need to change options at runtime.
import { createAnchor } from '@corndev/ui';
import '@corndev/ui/theme';
const el = document.querySelector('#target');
const instance = createAnchor(el, { /* options */ });
Options
| Option | Type | Default | Description |
|---|---|---|---|
underline | 'always'|'hover' | 'always' | hover shows the underline only on hover. Use it for a dense list of links, not for running text — there the underline is what distinguishes a link from bold text. |
muted | boolean | false | Secondary ink, for links that are present but not the point of the sentence. |
React
Anchor — from @corndev/ui-react.
as is the polymorphic prop — <Anchor as="button"> renders a button styled as a link. It gets type="button" automatically unless you pass one, since a link-shaped control submitting a form is never the intent, and href is dropped on anything that is not an <a>.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | undefined | Where it goes, when it is a link. |
underline | 'always'|'hover' | 'always' | hover shows the underline only on hover — for dense lists, not for running text. |
muted | boolean | false | Secondary ink. |
as | string|React.ComponentType | 'a' | Element or component to render as. as="button" gets type="button" unless you set one. |
className | string | undefined | Merged with the Corn UI classes. |
children | React.ReactNode | undefined |
A link that navigates is an <a>. A “link” that scrolls to a definition,
expands a section or opens a panel goes nowhere, and should be a <button>
— otherwise a screen reader announces a destination that does not exist, and
middle-click offers to open it in a new tab.
Anchor looks the same either way, so you can be honest about which one you
have.
React usage
import { Anchor } from '@corndev/ui-react';
import '@corndev/ui/theme';
<Anchor href="/docs">Documentation</Anchor>
{/* Scrolls to a type definition — so it is a button, and looks identical */}
<Anchor as="button" onClick={() => scrollTo(type)}>Pet</Anchor>
as changes the element. A button gets type="button"
automatically, because a link-shaped control submitting a form is never what
anyone meant.
Underline
<Anchor href="/a">Always underlined</Anchor>
<Anchor href="/a" underline="hover">Underlined on hover</Anchor>
<Anchor href="/a" muted>Present, but not the point</Anchor>
Use underline="hover" for a dense list of links, where permanent rules read as
noise. Keep the underline in running text — there it is the thing that
distinguishes a link from bold text, and colour alone is not enough.
Vanilla
<a class="corn-anchor" data-underline="always" href="/docs">Documentation</a>
<button class="corn-anchor" data-underline="always">Pet</button>
import { createAnchor } from '@corndev/ui';
createAnchor(document.querySelector('#type-link'), { underline: 'hover' });