|
15 | 15 |
|
16 | 16 | export let leadingicon: GoAIconType | null = null; |
17 | 17 | 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"; |
19 | 20 |
|
20 | 21 | export let action: string = ""; |
21 | 22 | export let actionArg: string = ""; |
|
40 | 41 | e.preventDefault(); |
41 | 42 | dispatch(e.target as Element, action, actionArg || actionArgs, { bubbles: true }); |
42 | 43 | } |
| 44 | +
|
| 45 | + function getIconSize(linkSize: string): string { |
| 46 | + const sizeMap: Record<string, string> = { |
| 47 | + xsmall: "2xsmall", // 12px |
| 48 | + small: "xsmall", // 16px |
| 49 | + medium: "small", // 18px |
| 50 | + large: "medium" // 20px |
| 51 | + }; |
| 52 | + return sizeMap[linkSize] || "small"; |
| 53 | + } |
43 | 54 | </script> |
44 | 55 |
|
45 | 56 | <div |
46 | 57 | class="link" |
47 | 58 | class:interactive={color === "interactive"} |
| 59 | + class:dark={color === "dark"} |
48 | 60 | class:light={color === "light"} |
| 61 | + class:xsmall={size === "xsmall"} |
| 62 | + class:small={size === "small"} |
| 63 | + class:medium={size === "medium"} |
| 64 | + class:large={size === "large"} |
49 | 65 | bind:this={_rootEl} |
50 | 66 | style={styles(calculateMargin(mt, mr, mb, ml))} |
51 | 67 | data-testid={testid} |
52 | 68 | > |
53 | | - {#if leadingicon}<goa-icon data-testid="leading-icon" type={leadingicon} />{/if} |
| 69 | + {#if leadingicon}<goa-icon data-testid="leading-icon" type={leadingicon} size={getIconSize(size)} />{/if} |
54 | 70 | <slot /> |
55 | | - {#if trailingicon}<goa-icon data-testid="trailing-icon" type={trailingicon} />{/if} |
| 71 | + {#if trailingicon}<goa-icon data-testid="trailing-icon" type={trailingicon} size={getIconSize(size)} />{/if} |
56 | 72 | </div> |
57 | 73 |
|
58 | 74 | <style> |
59 | 75 | :global(::slotted(a)) { |
60 | | - color: var(--goa-color-interactive-default); |
| 76 | + color: var(--goa-link-color-interactive-default, var(--goa-color-interactive-default)); |
61 | 77 | } |
62 | 78 |
|
| 79 | + /* Base link styles */ |
63 | 80 | .link { |
64 | 81 | display: inline-flex; |
65 | 82 | align-items: center; |
66 | 83 | padding: 0; |
67 | 84 | border: none; |
68 | 85 | background: none; |
69 | 86 | cursor: pointer; |
70 | | - font: var(--goa-typography-body-m); |
71 | 87 | text-decoration: underline; |
72 | | - gap: 8px; |
| 88 | + /* V1: Default gap fallback (4px) */ |
| 89 | + gap: var(--goa-link-gap, 0.25rem); |
| 90 | + /* V2: Size-specific gaps override below */ |
| 91 | + } |
| 92 | +
|
| 93 | + /* Size variants - Typography and Gap */ |
| 94 | + .link.xsmall { |
| 95 | + font: var(--goa-link-typography-xsmall); |
| 96 | + gap: var(--goa-link-gap-xsmall, 0.125rem); |
| 97 | + } |
| 98 | +
|
| 99 | + .link.small { |
| 100 | + font: var(--goa-link-typography-small); |
| 101 | + gap: var(--goa-link-gap-small, 0.1875rem); |
73 | 102 | } |
74 | 103 |
|
| 104 | + .link.medium { |
| 105 | + font: var(--goa-link-typography-medium); |
| 106 | + gap: var(--goa-link-gap-medium, 0.25rem); |
| 107 | + } |
| 108 | +
|
| 109 | + .link.large { |
| 110 | + font: var(--goa-link-typography-large); |
| 111 | + gap: var(--goa-link-gap-large, 0.3125rem); |
| 112 | + } |
| 113 | +
|
| 114 | + /* Color variant: Interactive (Blue) */ |
75 | 115 | .link.interactive { |
76 | | - color: var(--goa-color-interactive-default); |
| 116 | + color: var(--goa-link-color-interactive-default, var(--goa-color-interactive-default)); |
77 | 117 | } |
| 118 | +
|
78 | 119 | .link.interactive:hover { |
79 | | - color: var(--goa-color-interactive-hover); |
| 120 | + color: var(--goa-link-color-interactive-hover, var(--goa-color-interactive-hover)); |
80 | 121 | } |
81 | 122 |
|
| 123 | + .link.interactive :global(::slotted(a:visited)) { |
| 124 | + color: var(--goa-link-color-interactive-visited, var(--goa-color-interactive-visited)); |
| 125 | + } |
| 126 | +
|
| 127 | + /* Color variant: Dark (Black) */ |
| 128 | + .link.dark { |
| 129 | + color: var(--goa-link-color-dark-default, var(--goa-color-greyscale-black)); |
| 130 | + } |
| 131 | +
|
| 132 | + .link.dark:hover { |
| 133 | + color: var(--goa-link-color-dark-hover, var(--goa-color-greyscale-700)); |
| 134 | + } |
| 135 | +
|
| 136 | + .link.dark :global(::slotted(a:visited)) { |
| 137 | + color: var(--goa-link-color-dark-visited, var(--goa-color-interactive-visited)); |
| 138 | + } |
| 139 | +
|
| 140 | + /* Color variant: Light (White) */ |
82 | 141 | .link.light { |
83 | | - color: var(--goa-color-text-light); |
| 142 | + color: var(--goa-link-color-light-default, var(--goa-color-text-light)); |
84 | 143 | } |
| 144 | +
|
85 | 145 | .link.light:hover { |
86 | | - color: var(--goa-color-text-light); |
| 146 | + color: var(--goa-link-color-light-hover, var(--goa-color-greyscale-100)); |
| 147 | + } |
| 148 | +
|
| 149 | + .link.light :global(::slotted(a:visited)) { |
| 150 | + color: var(--goa-link-color-light-visited, var(--goa-color-greyscale-300)); |
87 | 151 | } |
88 | 152 | </style> |
0 commit comments