Skip to content

Commit

Permalink
Add accented Links
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding committed Feb 13, 2025
1 parent 84e7c46 commit 99514f9
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 118 deletions.
11 changes: 11 additions & 0 deletions .changeset/angry-beans-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@salt-ds/core": minor
---

Added accent colored Links.

```tsx
<Link href="#" color="accent">
Link text
</Link>
```
6 changes: 6 additions & 0 deletions .changeset/happy-ties-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@salt-ds/core": patch
---

When Link is set to `color="inherit"` its hover, active and focus colors will now also be inherited.
Fixed status colors being included in Link's `color` type. This was accidentally added when status color support was added to Text. If you need to achieve this behaviour you can use `color="inherit"`.
5 changes: 5 additions & 0 deletions .changeset/tiny-snails-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@salt-ds/theme": minor
---

Added `--salt-content-accent-foreground` to theme and theme-next.
46 changes: 33 additions & 13 deletions packages/core/src/link/Link.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
.saltLink {
--link-color-hover: var(--saltLink-color-hover, var(--salt-content-foreground-hover));
--link-color-active: var(--saltLink-color-active, var(--salt-content-foreground-active));
--link-color-visited: var(--saltLink-color-visited, var(--salt-content-foreground-visited));
/* When focused, we also want hover style */
--link-color-focus: var(--saltLink-color-focus, var(--link-color-hover));
--link-color: "inherit";
--link-color-hover: "inherit";
--link-color-active: "inherit";
--link-color-visited: var(--salt-content-foreground-visited);
--link-color-focus: "inherit";
--link-focus-outlineColor: "inherit";

--link-textDecoration: var(--salt-navigable-textDecoration);
--link-textDecoration-hover: var(--salt-navigable-textDecoration-hover);

--link-fontFamily: var(--salt-text-fontFamily);
--link-focus-outline: var(--salt-focused-outline);
}

/* Main css class */
Expand All @@ -21,13 +21,32 @@
}

/* Primary variant */
.saltText-primary {
.saltLink-primary {
--link-color: var(--salt-content-primary-foreground);
--link-color-hover: var(--salt-content-foreground-hover);
--link-color-active: var(--salt-content-foreground-active);
--link-color-visited: var(--salt-content-foreground-visited);
--link-color-focus: var(--salt-content-foreground-hover);
--link-focus-outlineColor: var(--salt-focused-outlineColor);
}

/* Secondary variant */
.saltText-secondary {
.saltLink-secondary {
--link-color: var(--salt-content-secondary-foreground);
--link-color-hover: var(--salt-content-foreground-hover);
--link-color-active: var(--salt-content-foreground-active);
--link-color-visited: var(--salt-content-foreground-visited);
--link-color-focus: var(--salt-content-foreground-hover);
--link-focus-outlineColor: var(--salt-focused-outlineColor);
}

.saltLink-accent {
--link-color: var(--salt-content-accent-foreground);
--link-color-hover: var(--salt-content-foreground-hover);
--link-color-active: var(--salt-content-foreground-active);
--link-color-visited: var(--salt-content-foreground-visited);
--link-color-focus: var(--salt-content-foreground-hover);
--link-focus-outlineColor: var(--salt-focused-outlineColor);
}

/* External link's icon */
Expand All @@ -38,24 +57,25 @@

/* Set color for visited link */
.saltLink:visited {
color: var(--link-color-visited);
color: var(--saltLink-color-visited, var(--link-color-visited));
}

/* Set color for hovered link */
.saltLink:hover {
color: var(--link-color-hover);
color: var(--saltLink-color-hover, var(--link-color-hover));
text-decoration: var(--link-textDecoration-hover);
}

/* Set color for active link */
.saltLink:active {
color: var(--link-color-active);
color: var(--saltLink-color-active, var(--link-color-active));
}

/* Set color for focused link */
.saltLink:focus {
outline: var(--link-focus-outline);
color: var(--link-color-focus);
color: var(--saltLink-color-focus, var(--link-color-focus));
outline: var(--salt-focused-outline);
outline-color: var(--link-focus-outlineColor);
text-decoration: var(--link-textDecoration-hover);
}

Expand Down
16 changes: 13 additions & 3 deletions packages/core/src/link/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ const withBaseName = makePrefixer("saltLink");
*/
export interface LinkProps
extends Omit<ComponentPropsWithoutRef<"a">, "color">,
Pick<TextProps<"a">, "maxRows" | "styleAs" | "color" | "variant"> {
Pick<TextProps<"a">, "maxRows" | "styleAs" | "variant"> {
IconComponent?: ComponentType<IconProps> | null;
/**
* Render prop to enable customisation of anchor element.
*/
render?: RenderPropsType["render"];
/*
* The color of the text. Defaults to "primary".
*/
color?: "inherit" | "primary" | "secondary" | "accent";
}

export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
Expand Down Expand Up @@ -60,11 +64,17 @@ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
return (
<Text
as={LinkAction}
className={clsx(withBaseName(), className)}
className={clsx(
withBaseName(),
{
[withBaseName(color)]: color !== "inherit",
},
className,
)}
href={href}
ref={ref}
target={target}
color={color}
color="inherit"
{...rest}
>
{children}
Expand Down
32 changes: 19 additions & 13 deletions packages/core/stories/link/link.qa.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from "@salt-ds/core";
import { Link, Text } from "@salt-ds/core";
import { UserIcon } from "@salt-ds/icons";
import type { Meta, StoryFn } from "@storybook/react";
import {
Expand Down Expand Up @@ -27,14 +27,14 @@ export const AllVariantsGrid: StoryFn<QAContainerProps> = (props) => (
<Link href="https://www.google.com" color="secondary">
Secondary Link
</Link>
<Link href="https://www.google.com" color="secondary" target="_blank">
Secondary Link target blank
<Link href="https://www.google.com" color="accent">
Accent Link
</Link>
<div style={{ width: 150 }}>
<Link href="https://www.google.com" maxRows={1} color="secondary">
<strong>Strong</strong> and <small>small</small> truncation example
<Text color="error">
<Link href="https://www.google.com" color="inherit">
Inherit Link
</Link>
</div>
</Text>
<Link
href="https://www.google.com"
style={{ color: "var(--salt-content-foreground-visited)" }}
Expand Down Expand Up @@ -87,14 +87,20 @@ export const NoStyleInjectionGrid: StoryFn<QAContainerNoStyleInjectionProps> = (
<Link href="https://www.google.com" color="secondary">
Secondary Link
</Link>
<Link href="https://www.google.com" color="secondary" target="_blank">
Secondary Link target blank
<Link href="https://www.google.com" color="accent">
Accent Link
</Link>
<div style={{ width: 150 }}>
<Link href="https://www.google.com" maxRows={1} color="secondary">
<strong>Strong</strong> and <small>small</small> truncation example
<Text color="error">
<Link href="https://www.google.com" color="inherit">
Inherit Link
</Link>
</div>
</Text>
<Link
href="https://www.google.com"
style={{ color: "var(--salt-content-foreground-visited)" }}
>
Forced visited
</Link>
<Link
href="https://www.google.com"
target="_blank"
Expand Down
147 changes: 72 additions & 75 deletions packages/core/stories/link/link.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from "@salt-ds/core";
import { Link, Text } from "@salt-ds/core";
import { StackoverflowIcon } from "@salt-ds/icons";
import type { Meta, StoryFn } from "@storybook/react";

Expand All @@ -7,116 +7,113 @@ export default {
component: Link,
} as Meta<typeof Link>;

export const Primary: StoryFn<typeof Link> = () => {
return <Link href="https://www.google.com">Link to URL</Link>;
const LinkTemplate: StoryFn<typeof Link> = (args) => <Link {...args} />;

export const Primary = LinkTemplate.bind({});
Primary.args = {
href: "https://github.com/salt-ds/core",
children: "Link to URL",
};

export const Secondary: StoryFn<typeof Link> = () => {
return (
<Link color="secondary" href="https://www.google.com">
Link to URL
</Link>
);
export const Secondary = LinkTemplate.bind({});
Secondary.args = {
color: "secondary",
href: "https://github.com/salt-ds/core",
children: "Link to URL",
};

export const InheritColor: StoryFn<typeof Link> = () => {
return (
<Link color="inherit" href="https://www.google.com">
Link to URL
</Link>
);
export const Accent = LinkTemplate.bind({});
Accent.args = {
color: "accent",
href: "https://github.com/salt-ds/core",
children: "Link to URL",
};

export const TargetBlank: StoryFn<typeof Link> = () => {
export const InheritColor: StoryFn<typeof Link> = (args) => {
return (
<Link href="https://www.google.com" target="_blank">
Link to URL
</Link>
<Text color="error">
You've encountered an error{" "}
<Link href="https://github.com/salt-ds/core" color="inherit" {...args}>
(#5417)
</Link>
</Text>
);
};

export const TargetBlankCustomIcon: StoryFn<typeof Link> = () => {
return (
<Link
IconComponent={StackoverflowIcon}
href="https://www.google.com"
target="_blank"
>
Link to URL
</Link>
);
export const TargetBlank = LinkTemplate.bind({});
TargetBlank.args = {
href: "https://github.com/salt-ds/core",
children: "Link to URL",
target: "_blank",
};

export const Strong: StoryFn<typeof Link> = () => {
return (
<Link href="#root" target="_blank">
export const TargetBlankCustomIcon = LinkTemplate.bind({});
TargetBlankCustomIcon.args = {
href: "https://github.com/salt-ds/core",
children: "Link to URL",
target: "_blank",
IconComponent: StackoverflowIcon,
};

export const Strong = LinkTemplate.bind({});
Strong.args = {
href: "https://github.com/salt-ds/core",
children: (
<span>
This is a <strong>strong</strong> link example
</Link>
);
</span>
),
};

export const Small: StoryFn<typeof Link> = () => {
return (
<Link href="#root">
export const Small = LinkTemplate.bind({});
Small.args = {
href: "https://github.com/salt-ds/core",
children: (
<span>
This is a <small>small</small> link example
</Link>
);
</span>
),
};

export const StyleAs: StoryFn<typeof Link> = () => {
return (
<Link href="#root" styleAs="label">
This is a styleAs label example
</Link>
);
export const StyleAs = LinkTemplate.bind({});
StyleAs.args = {
href: "https://github.com/salt-ds/core",
children: "This is a styleAs label example",
styleAs: "label",
};

export const TargetBlankNoIcon: StoryFn<typeof Link> = () => {
return (
<Link IconComponent={null} href="#root" target="_blank">
This has no icon
</Link>
);
export const TargetBlankNoIcon = LinkTemplate.bind({});
TargetBlankNoIcon.args = {
href: "https://github.com/salt-ds/core",
children: "This has no icon",
target: "_blank",
IconComponent: null,
};

export const Truncation: StoryFn<typeof Link> = () => {
export const Truncation: StoryFn<typeof Link> = (args) => {
return (
<div style={{ width: 150 }}>
<Link href="#root" maxRows={1}>
<Link href="#root" maxRows={1} {...args}>
This is a truncation example
</Link>
</div>
);
};

// export const WithTooltip: StoryFn<typeof Link> = () => {
// return (
// <div style={{ width: 50 }}>
// <Link
// // truncate={true} maxRows={1}
// href="https://www.google.com"
// >
// Link to URL with tooltip
// </Link>
// </div>
// );
// };

const CustomLinkImplementation = (props: any) => (
<a href="#root" aria-label={"overridden-label"} {...props}>
Your own Link implementation
</a>
);

export const RenderElement: StoryFn<typeof Link> = () => {
return <Link href="#root" render={<CustomLinkImplementation />} />;
export const RenderElement = LinkTemplate.bind({});
RenderElement.args = {
href: "https://github.com/salt-ds/core",
render: <CustomLinkImplementation />,
};

export const RenderProp: StoryFn<typeof Link> = () => {
return (
<Link
href="#root"
render={(props) => <CustomLinkImplementation {...props} />}
/>
);
export const RenderProp = LinkTemplate.bind({});
RenderProp.args = {
href: "https://github.com/salt-ds/core",
render: (props) => <CustomLinkImplementation {...props} />,
};
Loading

0 comments on commit 99514f9

Please sign in to comment.