Skip to content

Commit

Permalink
[PLAY-1479] Beta Link Kit (#3852)
Browse files Browse the repository at this point in the history
**What does this PR do?**

- Create a Link Kit for Rails and React.
- Add color, dark, disabled, icon, icon right, tag, and underline props

[PLAY-1479](https://runway.powerhrg.com/backlog_items/PLAY-1479)

**Screenshots:** Screenshots to visualize your addition/change
![Screenshot 2024-10-25 at 9 52
18 AM](https://github.com/user-attachments/assets/45f0d1af-a340-4558-a9cc-909bbc4a813a)

**How to test?** Steps to confirm the desired behavior:
1. Go to /kits/link/
2. Test Rails and React
3. Compare the handoff to each prop
4. Visit the link (in a non-incognito window). Go back, the link should
be purple and "visited"
5. Hover over links to see the color
6. "Focus" on the link by tabbing until you hit the link
7. Use dark mode


#### Checklist:
- [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [x] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
- [x] **TESTS** I have added test coverage to my code.
  • Loading branch information
kangaree authored Oct 29, 2024
1 parent da11402 commit 7a92d5e
Show file tree
Hide file tree
Showing 23 changed files with 667 additions and 1 deletion.
3 changes: 3 additions & 0 deletions playbook-website/config/menu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,9 @@ kits:
be followed by Title 2s followed by Title 3s and so on, without skipping any
levels.
status: stable
- name: link
platforms: *1
status: beta
- category: user
description:
components:
Expand Down
2 changes: 2 additions & 0 deletions playbook/app/entrypoints/playbook-doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import * as Layout from 'kits/pb_layout/docs'
import * as LegendDocs from 'kits/pb_legend/docs'
import * as Lightbox from 'kits/pb_lightbox/docs'
import * as LineGraphDocs from 'kits/pb_line_graph/docs'
import * as Link from 'kits/pb_link/docs'
import * as List from 'kits/pb_list/docs'
import * as LoadingInline from 'kits/pb_loading_inline/docs'
import * as Map from 'kits/pb_map/docs'
Expand Down Expand Up @@ -167,6 +168,7 @@ WebpackerReact.registerComponents({
...LegendDocs,
...Lightbox,
...LineGraphDocs,
...Link,
...List,
...LoadingInline,
...Map,
Expand Down
3 changes: 2 additions & 1 deletion playbook/app/entrypoints/playbook.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@import 'kits/pb_dialog/dialog';
@import 'kits/pb_distribution_bar/distribution_bar';
@import 'kits/pb_draggable/draggable';
@import 'kits/pb_drawer/drawer';
@import 'kits/pb_dropdown/dropdown';
@import 'kits/pb_file_upload/file_upload';
@import 'kits/pb_filter/filter';
Expand All @@ -54,6 +55,7 @@
@import 'kits/pb_legend/legend';
@import 'kits/pb_lightbox/lightbox';
@import 'kits/pb_line_graph/line_graph';
@import 'kits/pb_link/link';
@import 'kits/pb_list/list';
@import 'kits/pb_loading_inline/loading_inline';
@import 'kits/pb_map/map';
Expand Down Expand Up @@ -106,7 +108,6 @@
@import 'kits/pb_user_badge/user_badge';
@import 'kits/pb_walkthrough/walkthrough';
@import 'kits/pb_weekday_stacked/weekday_stacked';
@import 'kits/pb_drawer/drawer';
@import 'utilities/mixins';
@import 'utilities/spacing';
@import 'utilities/cursor';
Expand Down
1 change: 1 addition & 0 deletions playbook/app/javascript/kits.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export { default as Layout } from '../pb_kits/playbook/pb_layout/_layout'
export { default as Legend } from '../pb_kits/playbook/pb_legend/_legend'
export { default as Lightbox } from '../pb_kits/playbook/pb_lightbox/_lightbox'
export { default as LineGraph } from '../pb_kits/playbook/pb_line_graph/_line_graph'
export { default as Link} from '../pb_kits/playbook/pb_link/_link'
export { default as List } from '../pb_kits/playbook/pb_list/_list'
export { default as ListItem } from '../pb_kits/playbook/pb_list/_list_item'
export { default as LoadingInline } from '../pb_kits/playbook/pb_loading_inline/_loading_inline'
Expand Down
66 changes: 66 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/_link.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@import "../tokens/colors";
@import "../tokens/line_height";
@import "../tokens/typography";
@import "../tokens/border_radius";

[class^=pb_link_kit]{
@include pb_link($primary);
&:hover {
color: $text_lt_default;
}
&:focus {
outline: none;
}
&:focus-visible {
border-radius: $border_rad_light;
outline: 1px solid $primary;
outline-offset: 2px;
}
&:visited {
color: $data_3;
}
&.dark {
@include pb_link($active_dark);
&:hover {
color: $text_dk_default;
}
}
@each $color_name, $color_value in $pb_link_colors {
&[class*=_#{"" + $color_name}] {
@include pb_link($color_value);

&:hover {
color: map-get($pb_link_hover_colors, $color_name);
}

&:visited {
color: $data_3;
}
}
}

@each $dark_color_name, $dark_color_value in $pb_dark_link_colors{
&[class*=_#{$dark_color_name}][class*=dark]{
@include pb_link($dark_color_value);

&:hover {
color: map-get($pb_dark_link_hover_colors, $dark_color_name);
}

&:visited {
color: $data_3;
}
}
}

&[class*=_underline] {
text-decoration: underline;
}

&[class*=_disabled] {
pointer-events: none;
cursor: default;
color: $text_lt_lighter;
}

}
107 changes: 107 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/_link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react'
import classnames from 'classnames'

import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
import { globalProps, GlobalProps } from '../utilities/globalProps'

import Icon from '../pb_icon/_icon'

type LinkProps = {
aria?: {[key: string]: string},
className?: string,
children?: React.ReactChild[] | React.ReactChild,
color?: 'default' | 'body' | 'muted' | 'destructive',
dark?: boolean,
data?: {[key: string]: string},
disabled?: boolean,
href?: string,
htmlOptions?: {[key: string]: string | number | boolean | (() => void) | ((arg?: Event) => void)},
icon?: string,
iconRight?: string,
id?: string,
tag?: 'a' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div',
text?: string,
underline?: boolean,
} & GlobalProps

const Link = (props: LinkProps): React.ReactElement => {
const {
aria = {},
children,
className,
color = '',
data = {},
disabled = false,
href= '',
htmlOptions = {},
icon = '',
iconRight = '',
id = '',
tag = 'a',
text = '',
underline = false,
} = props

const ariaProps: {[key: string]: string} = buildAriaProps(aria)
const dataProps: {[key: string]: string} = buildDataProps(data)
const htmlProps = buildHtmlProps(htmlOptions);
const classes = classnames(
buildCss('pb_link_kit', color, underline ? 'underline' : '', disabled ? 'disabled' : ''),
globalProps(props),
className
)
const Tag = tag as keyof JSX.IntrinsicElements

const renderContent = () => (
<>
{icon && (
<Icon
fixedWidth
icon={icon}
marginRight="xxs"
size="xs"
/>
)}
{text || children}
{iconRight && (
<Icon
fixedWidth
icon={iconRight}
marginLeft="xxs"
size="xs"
/>
)}
</>
)

const commonProps = {
...ariaProps,
...dataProps,
...htmlProps,
className: classes,
id,
}

if (tag === 'a') {
return (
<a
{...commonProps}
href={href}
>
{renderContent()}
</a>
)
} else {
return (
<a
{...commonProps}
href={href}
>
<Tag>{renderContent()}</Tag>
</a>
)
}

}

export default Link
30 changes: 30 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/docs/_link_color.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div>
<%= pb_rails("link", props: {
text: "link example",
href: "https://www.google.com/search?q=playbook+design+system",
}) %>
</div>

<div>
<%= pb_rails("link", props: {
text: "link example",
href: "https://www.youtube.com/@PowerHRG",
color: "body",
}) %>
</div>

<div>
<%= pb_rails("link", props: {
text: "link example",
href: "https://github.com/powerhome/.github/blob/main/profile/README.md",
color: "muted",
}) %>
</div>

<div>
<%= pb_rails("link", props: {
text: "link example",
href: "https://rubygems.org/gems/playbook_ui/",
color: "destructive",
}) %>
</div>
40 changes: 40 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/docs/_link_color.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import { Link } from 'playbook-ui'

const LinkColor = (props) => (
<div>
<div>
<Link
href="https://www.google.com/search?q=playbook+design+system"
text="link example"
{...props}
/>
</div>
<div>
<Link
color="body"
href="https://www.youtube.com/@PowerHRG"
text="link example"
{...props}
/>
</div>
<div>
<Link
color="muted"
href="https://github.com/powerhome/.github/blob/main/profile/README.md"
text="link example"
{...props}
/>
</div>
<div>
<Link
color="destructive"
href="https://rubygems.org/gems/playbook_ui/"
text="link example"
{...props}
/>
</div>
</div>
)

export default LinkColor
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= pb_rails("link", props: {
text: "link example",
href: "#disabled",
disabled: true,
}) %>
15 changes: 15 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/docs/_link_disabled.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import { Link } from 'playbook-ui'

const LinkDisabled = (props) => (
<div>
<Link
disabled
href="#disabled"
text="link example"
{...props}
/>
</div>
)

export default LinkDisabled
15 changes: 15 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/docs/_link_icon.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div>
<%= pb_rails("link", props: {
text: "link example",
href: "#icon",
icon: "arrow-up-right-from-square",
}) %>
</div>

<div>
<%= pb_rails("link", props: {
text: "link example",
href: "#icon2",
icon_right: "chevron-right",
}) %>
</div>
25 changes: 25 additions & 0 deletions playbook/app/pb_kits/playbook/pb_link/docs/_link_icon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import { Link } from 'playbook-ui'

const LinkIcon = (props) => (
<div>
<div>
<Link
href="#icon"
icon="arrow-up-right-from-square"
text="link example"
{...props}
/>
</div>
<div>
<Link
href="#icon2"
iconRight="chevron-right"
text="link example"
{...props}
/>
</div>
</div>
)

export default LinkIcon
Loading

0 comments on commit 7a92d5e

Please sign in to comment.