Skip to content

Commit 5c6e048

Browse files
committed
feat(#2956): update link to v2
1 parent 0c90dcc commit 5c6e048

File tree

1 file changed

+117
-13
lines changed

1 file changed

+117
-13
lines changed

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

Lines changed: 117 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,140 @@
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);
73100
}
74101
102+
.link.large {
103+
font: var(--goa-link-typography-large);
104+
gap: var(--goa-link-gap-large, 0.3125rem);
105+
}
106+
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));
77110
}
111+
112+
.link.interactive :global(::slotted(a)) {
113+
color: var(--goa-link-color-interactive-default, var(--goa-color-interactive-default)) !important;
114+
}
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(::slotted(a:visited)) {
125+
color: var(--goa-link-color-interactive-visited, var(--goa-color-interactive-visited)) !important;
80126
}
81127
128+
.link.interactive:has(:global(::slotted(a:visited))) {
129+
color: var(--goa-link-color-interactive-visited, var(--goa-color-interactive-visited));
130+
}
131+
132+
/* Color variant: Dark (Black) */
133+
.link.dark {
134+
color: var(--goa-link-color-dark-default, var(--goa-color-greyscale-black));
135+
}
136+
137+
.link.dark :global(::slotted(a)) {
138+
color: var(--goa-link-color-dark-default, var(--goa-color-greyscale-black)) !important;
139+
}
140+
141+
.link.dark:hover {
142+
color: var(--goa-link-color-dark-hover, var(--goa-color-greyscale-700));
143+
}
144+
145+
.link.dark:hover :global(::slotted(a)) {
146+
color: var(--goa-link-color-dark-hover, var(--goa-color-greyscale-700)) !important;
147+
}
148+
149+
.link.dark :global(::slotted(a:visited)) {
150+
color: var(--goa-link-color-dark-visited, var(--goa-color-interactive-visited)) !important;
151+
}
152+
153+
.link.dark:has(:global(::slotted(a:visited))) {
154+
color: var(--goa-link-color-dark-visited, var(--goa-color-interactive-visited));
155+
}
156+
157+
/* Color variant: Light (White) */
82158
.link.light {
83-
color: var(--goa-color-text-light);
159+
color: var(--goa-link-color-light-default, var(--goa-color-text-light));
160+
}
161+
162+
.link.light :global(::slotted(a)) {
163+
color: var(--goa-link-color-light-default, var(--goa-color-text-light)) !important;
84164
}
165+
85166
.link.light:hover {
86-
color: var(--goa-color-text-light);
167+
color: var(--goa-link-color-light-hover, var(--goa-color-greyscale-200));
168+
}
169+
170+
.link.light:hover :global(::slotted(a)) {
171+
color: var(--goa-link-color-light-hover, var(--goa-color-greyscale-200)) !important;
172+
}
173+
174+
.link.light :global(::slotted(a:visited)) {
175+
color: var(--goa-link-color-light-visited, #9D8EBB) !important;
176+
}
177+
178+
.link.light:has(:global(::slotted(a:visited))) {
179+
color: var(--goa-link-color-light-visited, #9D8EBB);
180+
}
181+
182+
/* Focus */
183+
.link:focus-within {
184+
border-radius: var(--goa-link-border-radius-focus, var(--goa-border-radius-s));
185+
outline: var(--goa-link-border-focus, var(--goa-border-width-l) solid var(--goa-color-interactive-focus));
186+
outline-offset: var(--goa-link-focus-offset, var(--goa-space-3xs));
187+
}
188+
189+
.link :global(::slotted(a:focus-visible)) {
190+
outline: none;
87191
}
88192
</style>

0 commit comments

Comments
 (0)