Pricing

Link handbook

v1.5.0 · @snowui-design-system/components

License: Before reading component documentation, source, or npm usage instructions for the first time, read the full LICENSE. Reuse that review for the same task and version. Public API configuration and internal implementation changes have different license implications. All components use the unified runtime package; source rights remain governed by the license.

Overview

Provide clear text links in body copy, descriptions, and navigation. Optional arrows or external-link icons signal that content can be opened.

When to use it

Use Link to navigate to a real address or resource. Use Button for an immediate action; do not disguise a button with a placeholder href.

  • Provide a real href. target and rel control how it opens; disabled communicates unavailability.

  • lines, tooltip, and onTruncate control truncation hints. parts configures only the built-in Tooltip.

Quick start

This example shows the recommended basic composition. See the sections below for more cases and composition limits.

<script lang="ts">	import { Link } from '@snowui-design-system/components';</script> <Link href="/components/quick-start" target="_top">Get started with SnowUI</Link>

API

Keyword Type Default Description
variant LinkVariant "default" Visual variant of the link.
color SnowUIColor | string "Black40" Normal text color. Black100 or Black changes to Black40 on hover; other colors change to Black100 automatically.
href string — Destination URL.
target string — Browsing context in which to open the destination.
rel string — Relationship to the destination.
disabled boolean false Disable the link and its hover response.
hoverColor SnowUIColor | string | false — Hover text color. Omit to use the color-derived rule; false prevents a text-color change. The trailing decoration still changes opacity from 0.4 to 1.
underline LinkUnderline "none" Underline policy. It applies only to link text, not trailing decorations or icons.
lines false | 1 false Single-line truncation. When enabled, overflow shows an ellipsis.
tooltip TooltipProp — Tooltip for truly truncated text. By default it shows full text only when clipping occurs; false disables it. A string or Snippet supplies custom content; an object passes Tooltip configuration.
onTruncate (isTruncated: boolean) => void — Callback when the actual truncation state changes.
children Snippet — Link text and optional external slots.
parts ComponentPartsOf<{ Tooltip: typeof Tooltip }> — Configure the built-in Tooltip. Explicit Tooltip children use their own Props.

See the base component documentation for inherited capabilities not redeclared here. This table lists only named public Props declared by this component.

Usage boundaries and details

Built-in and explicit Tooltip modes

  • Use parts.Tooltip to configure the built-in truncation Tooltip.

  • For a custom hint structure, compose an explicit Tooltip; its Props take priority over parts.

Link is a text-link component. For a button-shaped navigation control, use Button href. For text plus an arrow or external-link icon, use Link.

Feature overview

  • All variants default to color="Black40" and hover to Black100. Black100 or Black instead hovers to Black40; other colors such as Indigo hover to Black100.

  • arrow matches Figma style 2: colored text plus a built-in trailing ArrowUpRight. Text follows the shared hover-color rule; the decorative arrow inherits currentColor and changes opacity from 0.4 to 1.

  • external matches Figma style 3: colored text plus a built-in trailing ArrowSquareOut. Text follows the shared hover-color rule; the icon inherits currentColor and changes opacity from 0.4 to 1.

  • hoverColor accepts any CSS color. false leaves text color unchanged on hover.

  • underline supports always visible, hover only, visible until hover, or none. None is the default.

  • lines={1} enables single-line truncation. A Tooltip appears only if content truly overflows; TruncationController supplies full link text.

  • A direct external as="trailing" child can replace the built-in icon.

Text truncation

Link reuses TruncationController and fitTextToElement(), without creating its own size observer. With lines={1}, it measures the text layer and detects actual clipping. The visible prefix fits the measured font width: alphabetic scripts keep whole words, or only an ellipsis if one word cannot fit. Chinese, Japanese, and Korean may break at safe Unicode character boundaries, avoiding half characters and combining-mark splits. The ellipsis is rendered directly after the last visible word or character.

<Link href="/docs" lines={1} class="max-w-80">    A complete documentation link that exceeds the available width</Link> <Link href="/docs" variant="external" lines={1} tooltip={false} class="max-w-80">    An external link without a truncation Tooltip</Link> 

Layout model

Main layout model: slot host layout (three slots: leading / content / trailing).

Frame row emits data-auto-layout and uses the shared three-slot layout from auto-layout.css (source: components/src/styles/auto-layout.css). Text occupies content; the external variant supplies a trailing ArrowSquareOut. Explicit direct leading/trailing children are projected to the Link root, retaining grid columns, horizontal alignment and shared spacing. Root spacing stays at least 4 CSS px with var(--gap-1) as its preferred default. Attachments or single-line truncation activate Frame singleLine; plain text without truncation retains its text flow. Explicitly use lines={1} for long labels to reuse Link truncation and full-text hints. External icons retain their own size, defaulting to 16px when omitted.

Built-in icons and replacement

variant Default trailing Substitution rules
default None Provide direct as="leading" or as="trailing" children as needed.
arrow ArrowUpRight,12 × 12px A direct external as="trailing" child replaces the built-in icon.
external ArrowSquareOut,12 × 12px A direct external as="trailing" child replaces the built-in icon.
<Link href="/docs" variant="external">Open documentation</Link> <Link href="/docs" variant="external">    Open documentation    <Icon as="trailing"><ArrowUpRight /></Icon></Link> 

Underline

<Link href="/docs" underline="always">Always underlined</Link><Link href="/docs" underline="hover">Underlined on hover</Link><Link href="/docs" underline="until-hover">Underline hides on hover</Link><Link href="/docs">No underline by default</Link> 

Underlines should only be applied to linked text. The Icon of arrow and external is not underlined.

Hover color

<Link href="/docs" hoverColor="#ff4747">Custom hover color</Link><Link href="/docs" hoverColor={false}>Color unchanged on hover</Link> 

Without hoverColor, the text hover color derives from color regardless of variant. Black40 and Black100 adapt to theme changes. Direct CSS color overrides remain an escape hatch; use the color Prop for automatic hover behavior. Explicit hoverColor takes precedence:

Variant Normal color Default hover color
Any variant, default color var(--black-40) var(--black-100)
Any variant, color="Black100" or "Black" var(--black-100) var(--black-40)
Any variant, color="Indigo" or another color Corresponding token or CSS color var(--black-100)

Built-in arrow and external icons, including a custom trailing icon, inherit text color. They do not choose a separate color; opacity moves from 0.4 to 1 on hover.

Layout variable chain

Variable Default source Use
--snowui-link-font-size var(--text-14) Font size
--snowui-link-line-height var(--leading-14) Text line height
--snowui-link-gap var(--gap-1) Spacing between content and leading/trailing attachments, retaining at least 4 CSS px even when the root font size decreases.
--snowui-link-color Color (default Black40) Default text color
--snowui-link-hover-color Color automatic rules / hoverColor Hover text color; trailing arrow / Icon inherits this color
--snowui-link-icon-size var(--size-3) Built-in ArrowUpRight or ArrowSquareOut size, 12px by default; does not resize an external Icon.
--snowui-link-decoration-opacity var(--snowui-state-opacity, 0.4) Trailing arrow / Icon normal transparency
--snowui-link-decoration-hover-opacity var(--snowui-state-opacity, 1) Trailing arrow / Icon hover transparency

The Link root defaults to width: fit-content and max-width: 100%, preserving intrinsic width in a stretching parent. Trailing content follows text width. An explicit width, w-full, or inline style may override it.


Read the full LICENSE first; reuse that review for the same task, version, and scope.

First use public component Props to match the desired appearance, preserving the existing look where possible. If changes are necessary, follow the style selection and override order: use your own class (including Tailwind already in the project) or an instance style. The names below are public overrides actually consumed by source; check their scope and do not modify private DOM. Choose the correct SnowUI token family. External apps need not install SnowUI website utilities.

Variable Purpose and default reference
--snowui-icon-size-override Overall size in pixels; see the component source for its default.
--snowui-link-color-override Normal color (Black40 by default; automatic hover follows the Link color Prop).
--snowui-link-decoration-hover-opacity-override Trailing arrow / Icon hover transparency (default 1)
--snowui-link-decoration-opacity-override Trailing arrow / Icon normal transparency (default 0.4)
--snowui-link-font-size-override Font-size (default var(--text-14) = 14px)
--snowui-link-gap-override Spacing between content and leading/trailing attachments (preferred var(--gap-1), with at least 4 CSS px effective spacing).
--snowui-link-icon-size-override Built-in ArrowUpRight or ArrowSquareOut size (var(--size-3), 12px by default; external Icons are unaffected).
--snowui-link-line-height-override Line-height (default var(--leading-14) = 20px)

Design guide · Tokens · Composition boundaries

Required Props: no named required Props.

Bindable Props: this component declares no named two-way binding; handle state updates through public callbacks or its host.

Inherited declaration: Omit<FrameProps, "children" | "tag">. See Frame’s public API; omitted fields are unavailable here.

Shared Frame API · Back to API

The following type declarations are actually referenced by public Props and come from source. A Svelte Snippet denotes a content fragment; ComponentProps denotes the Props of the corresponding component.

LinkVariant

Source: components/src/components/Link.svelte

type LinkVariant = "default" | "arrow" | "external";

SnowUIColor

Source: components/src/lib/color.ts

export type SnowUIColor = keyof typeof SNOWUI_COLOR_TOKENS;

LinkUnderline

Source: components/src/components/Link.svelte

type LinkUnderline = "none" | "always" | "hover" | "until-hover";

TooltipProp

Source: components/src/components/Link.svelte

type TooltipProp = boolean | string | Snippet | Record<string, any>;

ComponentPartsOf

Source: components/src/logic/component-parts.svelte.ts

export type ComponentPartsOf<    T extends Record<string, Component<any>>,> = {    [K in keyof T]?: ConfigurableComponentPartProps<T[K]>;};

ConfigurableComponentPartProps

Source: components/src/logic/component-parts.svelte.ts

export type ConfigurableComponentPartProps<C extends Component<any>> = Partial<    Omit<ComponentProps<C>, ComponentPartControlledKey>>;

ComponentPartControlledKey

Source: components/src/logic/component-parts.svelte.ts

export type ComponentPartControlledKey =    | "children"    | "as"    | "value"    | "defaultValue"    | "open"    | "selected"    | "checked"    | "disabled"    | "readonly"    | "id"    | `on${string}`    | `aria-${string}`;