Skip to content

Commit 3c85542

Browse files
twjefferychrisolsen
authored andcommitted
feat(#2956): update link to v2
1 parent 31c4749 commit 3c85542

File tree

1 file changed

+105
-13
lines changed

1 file changed

+105
-13
lines changed

libs/web-components/src/components/link/Link.svelte

Lines changed: 105 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
1616
export let leadingicon: GoAIconType | null = null;
1717
export let trailingicon: GoAIconType | null = null;
18-
export let color: "interactive" | "light" = "interactive";
18+
export let color: "interactive" | "dark" | "light" = "interactive";
19+
export let size: "xsmall" | "small" | "medium" | "large" = "medium";
1920
2021
export let action: string = "";
2122
export let actionArg: string = "";
@@ -30,6 +31,13 @@
3031
3132
let _rootEl: HTMLElement;
3233
34+
$: _iconSize = {
35+
xsmall: "2xsmall", // 12px
36+
small: "xsmall", // 16px
37+
medium: "small", // 18px
38+
large: "medium", // 20px
39+
}[size];
40+
3341
onMount(() => {
3442
if (action) {
3543
_rootEl.addEventListener("click", handleClick);
@@ -45,44 +53,128 @@
4553
<div
4654
class="link"
4755
class:interactive={color === "interactive"}
56+
class:dark={color === "dark"}
4857
class:light={color === "light"}
58+
class:xsmall={size === "xsmall"}
59+
class:small={size === "small"}
60+
class:medium={size === "medium"}
61+
class:large={size === "large"}
4962
bind:this={_rootEl}
5063
style={styles(calculateMargin(mt, mr, mb, ml))}
5164
data-testid={testid}
5265
>
53-
{#if leadingicon}<goa-icon data-testid="leading-icon" type={leadingicon} />{/if}
66+
{#if leadingicon}<goa-icon data-testid="leading-icon" type={leadingicon} size={_iconSize} />{/if}
5467
<slot />
55-
{#if trailingicon}<goa-icon data-testid="trailing-icon" type={trailingicon} />{/if}
68+
{#if trailingicon}<goa-icon data-testid="trailing-icon" type={trailingicon} size={_iconSize} />{/if}
5669
</div>
5770

5871
<style>
59-
:global(::slotted(a)) {
60-
color: var(--goa-color-interactive-default);
61-
}
62-
72+
/* Base link styles */
6373
.link {
6474
display: inline-flex;
6575
align-items: center;
6676
padding: 0;
6777
border: none;
6878
background: none;
6979
cursor: pointer;
70-
font: var(--goa-typography-body-m);
7180
text-decoration: underline;
72-
gap: 8px;
81+
/* V1: Default gap fallback (4px) */
82+
gap: var(--goa-link-gap, 0.25rem);
83+
/* V2: Size-specific gaps override below */
84+
}
85+
86+
/* Size variants - Typography and Gap */
87+
.link.xsmall {
88+
font: var(--goa-link-typography-xsmall);
89+
gap: var(--goa-link-gap-xsmall, 0.125rem);
90+
}
91+
92+
.link.small {
93+
font: var(--goa-link-typography-small);
94+
gap: var(--goa-link-gap-small, 0.1875rem);
95+
}
96+
97+
.link.medium {
98+
font: var(--goa-link-typography-medium);
99+
gap: var(--goa-link-gap-medium, 0.25rem);
100+
}
101+
102+
.link.large {
103+
font: var(--goa-link-typography-large);
104+
gap: var(--goa-link-gap-large, 0.3125rem);
73105
}
74106
107+
/* Color variant: Interactive (Blue) */
75108
.link.interactive {
76-
color: var(--goa-color-interactive-default);
109+
color: var(--goa-link-color-interactive-default, var(--goa-color-interactive-default));
110+
}
111+
112+
.link.interactive :global(::slotted(a)) {
113+
color: var(--goa-link-color-interactive-default, var(--goa-color-interactive-default)) !important;
77114
}
115+
78116
.link.interactive:hover {
79-
color: var(--goa-color-interactive-hover);
117+
color: var(--goa-link-color-interactive-hover, var(--goa-color-interactive-hover));
118+
}
119+
120+
.link.interactive:hover :global(::slotted(a)) {
121+
color: var(--goa-link-color-interactive-hover, var(--goa-color-interactive-hover)) !important;
122+
}
123+
124+
.link.interactive :global(a:visited) {
125+
color: var(--goa-link-color-interactive-visited, var(--goa-color-interactive-visited)) !important;
126+
}
127+
128+
/* Color variant: Dark (Black) */
129+
.link.dark {
130+
color: var(--goa-link-color-dark-default, var(--goa-color-greyscale-black));
80131
}
81132
133+
.link.dark :global(::slotted(a)) {
134+
color: var(--goa-link-color-dark-default, var(--goa-color-greyscale-black)) !important;
135+
}
136+
137+
.link.dark:hover {
138+
color: var(--goa-link-color-dark-hover, var(--goa-color-greyscale-700));
139+
}
140+
141+
.link.dark:hover :global(::slotted(a)) {
142+
color: var(--goa-link-color-dark-hover, var(--goa-color-greyscale-700)) !important;
143+
}
144+
145+
.link.dark :global(a:visited) {
146+
color: var(--goa-link-color-dark-visited, var(--goa-color-interactive-visited)) !important;
147+
}
148+
149+
/* Color variant: Light (White) */
82150
.link.light {
83-
color: var(--goa-color-text-light);
151+
color: var(--goa-link-color-light-default, var(--goa-color-text-light));
152+
}
153+
154+
.link.light :global(::slotted(a)) {
155+
color: var(--goa-link-color-light-default, var(--goa-color-text-light)) !important;
84156
}
157+
85158
.link.light:hover {
86-
color: var(--goa-color-text-light);
159+
color: var(--goa-link-color-light-hover, var(--goa-color-greyscale-200));
160+
}
161+
162+
.link.light:hover :global(::slotted(a)) {
163+
color: var(--goa-link-color-light-hover, var(--goa-color-greyscale-200)) !important;
164+
}
165+
166+
.link.light :global(a:visited) {
167+
color: var(--goa-link-color-light-visited, #9D8EBB) !important;
168+
}
169+
170+
/* Focus */
171+
.link:focus-within {
172+
border-radius: var(--goa-link-border-radius-focus, var(--goa-border-radius-s));
173+
outline: var(--goa-link-border-focus, var(--goa-border-width-l) solid var(--goa-color-interactive-focus));
174+
outline-offset: var(--goa-link-focus-offset, var(--goa-space-3xs));
175+
}
176+
177+
.link :global(::slotted(a:focus-visible)) {
178+
outline: none;
87179
}
88180
</style>

0 commit comments

Comments
 (0)