Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
98b6bbc
Improve examples browsing experience
martenbjork Jul 19, 2022
6196272
Design tweaks
martenbjork Jul 19, 2022
675e3ca
Remove unused import
martenbjork Jul 19, 2022
a6b3aae
Make button text strong
martenbjork Jul 20, 2022
510fd2e
Show HTML source next to React source
martenbjork Jul 20, 2022
0b3bd78
Merge branch 'main' into show-html-source
martenbjork Jul 21, 2022
42fa893
Use the same Code component to render any code block on the site
martenbjork Jul 21, 2022
a99a605
Add changeset
martenbjork Jul 21, 2022
72109a1
Fix border color
martenbjork Jul 21, 2022
bce992c
Fix link color
martenbjork Jul 21, 2022
b10dac4
Add missing alt attribute
martenbjork Jul 21, 2022
467e6a6
Remove code formatting from longform component
martenbjork Jul 21, 2022
41397ed
Remove console log
martenbjork Jul 21, 2022
cba2ffb
Use implicit returns
martenbjork Jul 21, 2022
29953db
Remove wrapper
martenbjork Jul 21, 2022
a252b7a
Rename Examples component
martenbjork Jul 21, 2022
5b8edf2
Implement copy code button
martenbjork Jul 21, 2022
929da6b
Remove import
martenbjork Jul 21, 2022
9fcdf0a
Fix typing
martenbjork Jul 21, 2022
68d2694
Update .changeset/nine-goats-leave.md
martenbjork Jul 21, 2022
ea746ca
Update polaris.shopify.com/src/components/ComponentExamples/Component…
martenbjork Jul 21, 2022
14d50e8
Merge branch 'main' into show-html-source
martenbjork Jul 21, 2022
d14db48
Refactor code component
martenbjork Jul 22, 2022
27fcb14
Use more semantic tags for code
martenbjork Jul 22, 2022
4b68771
Merge branch 'main' into show-html-source
martenbjork Jul 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nine-goats-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'polaris.shopify.com': minor
---

Simplified rendering of code blocks on site by using the same component for every code example. This makes the experience more consistent and ensures that every code block has features like copy/paste.
102 changes: 102 additions & 0 deletions polaris.shopify.com/src/components/Code/Code.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
@import "../../styles/mixins.scss";

.Code {
border-radius: var(--border-radius-400);
max-width: calc(100vw - 1.5rem);
cursor: text;
background: var(--surface);
color: var(--text-strong);
box-shadow: var(--card-shadow);
}

.TopBar {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--border-color-light);
}

.Tabs {
padding-left: 1rem;
display: flex;

.Tab {
padding-top: 0.66rem;
padding-bottom: 0.66rem;
border-radius: var(--border-radius-300);
background: transparent;
font-size: var(--font-size-100);
color: var(--text-subdued);
}

button.Tab {
padding-left: 0.5rem;
padding-right: 0.5rem;
color: var(--text-strong);

&[aria-selected="true"] {
position: relative;

&:not(:focus-visible) {
&:after {
content: "";
display: block;
position: absolute;
right: 0;
bottom: 0;
left: 0;
background: var(--text-strong);
height: 3px;
border-radius: var(--border-radius-200) var(--border-radius-200) 0 0;
}
}
}
}

&:focus-visible {
box-shadow: var(--focus-outline);
}
}

.CopyButton {
padding: 0.5rem 1rem;
background: transparent;
border-radius: var(--border-radius-200);
opacity: 0.5;
display: flex;
align-items: center;

&:hover,
&:focus {
opacity: 1;
}

svg {
width: 16px;
height: 16px;
}

&:focus-visible {
box-shadow: none;
opacity: 1;
}
}

.ActualCode {
font-family: var(--font-family-mono);
white-space: pre-wrap;
padding: 0.85rem 1rem;
font-size: 14px;
line-height: 1.6;
overflow: auto;
max-height: 50vh;

@include custom-scrollbars;
}

.LineNumber {
display: none;
opacity: 0.5;
margin-right: 0.5rem;
user-select: none;
}
98 changes: 98 additions & 0 deletions polaris.shopify.com/src/components/Code/Code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import Tooltip from "../Tooltip";
import Prism from "prismjs";
import { useCopyToClipboard } from "../../utils/hooks";
import styles from "./Code.module.scss";
import { Tab } from "@headlessui/react";
import Image from "../Image";
import { useState } from "react";

interface Props {
tabs: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tabs: {
tabs?: {

title: string;
code: string;
}[];
}

function Code({ tabs }: Props) {
Copy link
Member

@chloerice chloerice Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I first read the PR description I assumed that the Code component was a generic wrapper for any code sample on the site, but it looks like it's specific to ComponentExamples. Should we move the sub-component into a components directory inside of the ComponentExamples directory? Can the component be more generic, maybe the tabs prop could be optional? For example, rendering the Code component for the /contributing/shipping-your-contribution code page doesn't completely translate for things like yarn commands.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is generic! Is there anything about it that made you think otherwise?

The tabs are optional — if you pass in a single example, Code will render it without tabs.

Copy link
Member

@alex-page alex-page Jul 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just have two components? CodeTabs and CodeBlock or something? We kind of already do with HighlightedCode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I clarified the component props a bit which maybe (?) makes the component clearer:

To render some code:

<Code code={{ title: "My example", code }} />

To render multiple pieces of code:

<Code code={[
  { title: "Styles", code: cssCode },
  { title: "HTML", code: htmlCode },
]} />

In short: It's not about the tabs, it's about what you want to render. The tabs are just a happy side effect.

Happy to refactor this down the road if it causes confusion!

const [selectedIndex, setSelectedIndex] = useState(0);

return (
<div className={styles.Code}>
{tabs.length === 1 ? (
<>
<div className={styles.TopBar}>
<div className={styles.Tabs}>
<div className={styles.Tab}>{tabs[0].title}</div>
</div>
<CopyButton code={tabs[0].code} />
</div>
<HighlightedCode code={tabs[0].code} />
</>
) : (
<Tab.Group selectedIndex={selectedIndex} onChange={setSelectedIndex}>
<div className={styles.TopBar}>
<Tab.List className={styles.Tabs}>
{tabs.map(({ title }) => (
<Tab key={title} className={styles.Tab}>
{title}
</Tab>
))}
</Tab.List>
{tabs[selectedIndex] && (
<CopyButton code={tabs[selectedIndex].code} />
)}
</div>

<Tab.Panels>
{tabs.map(({ title, code }) => (
<Tab.Panel key={title}>
<HighlightedCode code={code} />
</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
)}
</div>
);
}

function HighlightedCode({ code }: { code: string }) {
return (
<div
className={styles.ActualCode}
dangerouslySetInnerHTML={{
__html: Prism.highlight(code, Prism.languages.javascript, "javasript"),
}}
></div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be pre instead of div

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? It seems like prism does some stuff...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixed!

);
}

function CopyButton({ code }: { code: string }) {
const [copy, didJustCopy] = useCopyToClipboard(code);

return (
<div className={styles.CopyButtonWrapper}>
<Tooltip
ariaLabel="Copy to clipboard"
renderContent={() => <p>{didJustCopy ? "Copied" : "Copy"}</p>}
>
<button
type="button"
className={styles.CopyButton}
onClick={copy}
aria-label="Copy to clipboard"
>
<Image
src="/icons/ClipboardMinor.svg"
alt="Clipboard icon"
width={16}
height={16}
icon
/>
</button>
</Tooltip>
</div>
);
}

export default Code;
3 changes: 3 additions & 0 deletions polaris.shopify.com/src/components/Code/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Code from "./Code";

export default Code;

This file was deleted.

73 changes: 0 additions & 73 deletions polaris.shopify.com/src/components/CodeExample/CodeExample.tsx

This file was deleted.

3 changes: 0 additions & 3 deletions polaris.shopify.com/src/components/CodeExample/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
&:focus {
box-shadow: var(--focus-outline);
}
}
}
}
}

Expand All @@ -40,7 +40,7 @@
.Buttons {
display: flex;
justify-content: flex-end;
border-top: var(--border);
border-top: 1px solid rgba(0, 0, 0, 0.075);
color: var(--text-link);

button {
Expand Down
Loading