Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add elevation tokens and documentation #643

Merged
merged 17 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
425 changes: 425 additions & 0 deletions install_nvm.sh
brentswisher marked this conversation as resolved.
Show resolved Hide resolved

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/pharos-site/src/components/Sidenav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const Sidenav: FC = () => {
</PharosSidenavSection>
<PharosSidenavSection label="Brand Guidelines" showDivider>
<PharosSidenavMenu label="Brand expressions" expanded={isExpanded('brand-expressions')}>
{['Logos', 'Typography', 'Color', 'Imagery', 'Iconography'].map(
{['Logos', 'Typography', 'Color', 'Imagery', 'Iconography', 'Elevation'].map(
createSidenavLink.bind(this, 'brand-expressions')
)}
</PharosSidenavMenu>
Expand Down
217 changes: 217 additions & 0 deletions packages/pharos-site/src/pages/brand-expressions/elevation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import DosAndDonts from '../../components/statics/DosAndDonts';
import elevationStackGuide from '../../../static/images/brand-expressions/elevation/elevation_stack_guide.jpg';
import effectStacking from '../../../static/images/brand-expressions/elevation/effect_stacking.jpg';
import topDropShadow from '../../../static/images/brand-expressions/elevation/top_drop_shadow.jpg';
import dosContentBehind from '../../../static/images/brand-expressions/elevation/dos_content_behind.png';
import upAndDown from '../../../static/images/brand-expressions/elevation/up_and_down.jpg';
import dontVisuallyPlease from '../../../static/images/brand-expressions/elevation/dont_visually_please.jpg';
import withIconography from '../../../static/images/brand-expressions/elevation/with_iconography.jpg';
import dontChangeSource from '../../../static/images/brand-expressions/elevation/dont_change_source.jpg';
import PageSection from '../../components/statics/PageSection';
import Grid from '../../components/Grid';

<PageSection
title="Elevation"
description="Elevation is used in order to provide visual cues about a components' depth from a website's surface and its distance in relation to other components. It gives users the signal that a component is being prioritized, emphasized, or requires their focus. This can come from the visual cue of dynamic elevation or static elevation."
isHeader
></PageSection>

<PageSection title="Elevation system">
<div
style={{
width: '75%',
marginBottom: '3rem',
color: 'var(--pharos-color-text-20)',
}}
>
JSTOR uses an elevation system to assign consistent elevation levels to certain components. By
following the guide, usage will uniform across all JSTOR platforms.
</div>
<PharosHeading level="3" preset="4">
Elevation guide
</PharosHeading>
<p style={{ color: 'var(--pharos-color-text-20)' }}>
<strong> View CSS Codes under Design Tokens. </strong>
</p>
<img src={elevationStackGuide} alt="Elevation stack guide" width="800px" />
<p style={{ color: 'var(--pharos-color-text-20)', marginBottom: '50px' }}>
*Move the shadow in the direction the drawer is sliding (eg. turn y from 4 to -4 for a drawer
that slides up).
</p>
<PharosHeading level="3" preset="4">
Shadow definitions
</PharosHeading>
<p style={{ color: 'var(--pharos-color-text-20)' }}>
Blur means how diffused shadow will be Spread is how big the shadow will be Z-index is how
elevated it is X is our light source. This will not be altered as our light source will be
consistently coming from 12 o'clock.
</p>
<PharosHeading level="3" preset="4">
Shadow stacking
</PharosHeading>
<p style={{ color: 'var(--pharos-color-text-20)' }}>
To avoid the harsh outline of a stroke along with it being misrepresented as a container, the
outline of a component using elevation will be achieved by stacking shadows.
</p>
<img
src={effectStacking}
alt="Two different shadow effects"
width="220px"
style={{ marginBottom: '24px' }}
/>
<p style={{ color: 'var(--pharos-color-text-20)' }}>
The top shadow gives the illusion of a stroke while the bottom shadow tackles the actual shadow.
If you only have the top shadow, the component will blend into the background, and if you only
have the bottom shadow the component will be undefined.
</p>
<Grid columns={4}>
<strong>Border only</strong>
<strong>Top shadow only</strong>
<strong>Bottom shadow only</strong>
<strong>Both shadows</strong>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; border: 1px solid var(--pharos-color-marble-gray-80);"></div>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; box-shadow: 0px 1px 2px 0px rgba(18, 18, 18, 0.30);"></div>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; box-shadow: 0px 4px 8px 3px rgba(18, 18, 18, 0.15);"></div>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; box-shadow: 0px 4px 8px 3px rgba(18, 18, 18, 0.15), 0px 1px 2px 0px rgba(18, 18, 18, 0.30);"></div>
nkamau marked this conversation as resolved.
Show resolved Hide resolved
</Grid>
</PageSection>

<PageSection title="Elevation calculations">
<p style={{ color: 'var(--pharos-color-text-20)' }}>
JSTOR uses a consistent equation to calculate elevation levels as they rise. To keep elevation
harmonious, following this 2 step system calculation is important:
</p>
<PharosHeading level="3" preset="4">
Elevation values
</PharosHeading>
<p style={{ color: 'var(--pharos-color-text-20)' }}>
1. The top shadow should consistently stay at these values no matter the elevation level: X =0,
Blur =2, Y =1, Spread =0.
</p>
<img src={topDropShadow} alt="Top drop shadow" width="220px" style={{ marginBottom: '24px' }} />
<p style={{ color: 'var(--pharos-color-text-20)' }}>
2. Starting at level 2 is when calculations are used. The bottom shadow should comply with the
following system as each level rises: X=0, Blur +2, Y +2, Spread +1
</p>
<Grid columns={3}>
<strong>Level 2</strong>
<strong>Level 3</strong>
<strong>Level 4</strong>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; box-shadow: 0px 2px 6px 2px rgba(18, 18, 18, 0.15), 0px 1px 2px 0px rgba(18, 18, 18, 0.30);"></div>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; box-shadow: 0px 4px 8px 3px rgba(18, 18, 18, 0.15), 0px 1px 2px 0px rgba(18, 18, 18, 0.30);"></div>
<div style="width: 201px; height: 142px; flex-shrink: 0; border-radius: 5px; box-shadow: 0px 6px 10px 4px rgba(18, 18, 18, 0.15), 0px 1px 2px 0px rgba(18, 18, 18, 0.30);"></div>
</Grid>
</PageSection>

<PageSection title="Principles">
<PharosHeading level="3" preset="4">
Consistent
</PharosHeading>
<div
style={{
marginBottom: 'var(--pharos-spacing-2-x)',
color: 'var(--pharos-color-text-20)',
}}
>
All elevation is used at the appropriate level assigned to that component. Always follow the
recommended shadow pairings.
</div>
<PharosHeading level="3" preset="4">
Suitable
</PharosHeading>
<div
style={{
marginBottom: 'var(--pharos-spacing-2-x)',
color: 'var(--pharos-color-text-20)',
}}
>
Dynamic elevation should only change values when suitable for a components behavior.
</div>
<PharosHeading level="3" preset="4">
Practical
</PharosHeading>
<div
style={{
marginBottom: 'var(--pharos-spacing-2-x)',
color: 'var(--pharos-color-text-20)',
}}
>
Elevation is not solely used for visually enjoyment. It should communicate to users that there
is an emphasis or prioritization when it comes to a given component.
</div>
</PageSection>

<PageSection title="Best Practices">
<DosAndDonts>
<div className="best-practice" style={{ marginBottom: '4rem' }}>
<PharosHeading
level="3"
preset="2--bold"
style={{ marginBottom: 'var(--pharos-spacing-1-x)' }}
>
Use when there is content behind the component or use when a component is available to be
interacted with.
</PharosHeading>
<img
src={dosContentBehind}
alt="For example a sticky header"
width="220px"
style={{ marginBottom: '60px' }}
/>
<PharosHeading
level="3"
preset="2--bold"
style={{ marginBottom: 'var(--pharos-spacing-1-x)' }}
>
Alter the Y-axis for directional movement. For example, changing Y =2 to Y= -2.
</PharosHeading>
<img
src={upAndDown}
alt="Y equals positive 2 when a drawer slides up, Y equals negative 2 when a drawer slides down"
width="450px"
/>
</div>
</DosAndDonts>
<DosAndDonts Dont>
<div className="best-practice">
<PharosHeading
level="3"
preset="2--bold"
style={{ marginBottom: 'var(--pharos-spacing-1-x)' }}
>
Apply elevation to components in order to be "visually pleasing".
</PharosHeading>
<img
src={dontVisuallyPlease}
alt="don't add elevation to components for fun"
width="450px"
style={{ marginBottom: '60px' }}
/>
<PharosHeading
level="3"
preset="2--bold"
style={{ marginBottom: 'var(--pharos-spacing-1-x)' }}
>
Add elevation when content already has iconography communicating user cues.
</PharosHeading>
<p style={{ color: 'var(--pharos-color-text-20)' }}>
The ability to move content is already visually communicated through the reorder icon. Hover
elevation is not needed for any purpose other than to serve visual enjoyment.
</p>
<img
src={withIconography}
alt="don't add to components that communicate user interactivity"
width="210px"
style={{ marginBottom: '60px' }}
/>
<PharosHeading
level="3"
preset="2--bold"
style={{ marginBottom: 'var(--pharos-spacing-1-x)' }}
>
Change the light source.
</PharosHeading>
<img src={dontChangeSource} alt="X value has been altered" width="215px" />
</div>
</DosAndDonts>
</PageSection>
39 changes: 39 additions & 0 deletions packages/pharos-site/src/pages/design-tokens/elevation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { TokenTable } from '../../components/statics/design-token/TokenTable';
import tokens from '@ithaka/pharos/lib/styles/tokens';
import { toTokenFormat } from '../../components/statics/design-token/toTokenFormat';
import '../../../static/styles/global.scss';
import PageSection from '../../components/statics/PageSection';

<PageSection title="Elevation" isHeader>
<TokenTable>
<thead>
<tr>
<th style={{ width: '40%' }}>Token</th>
<th style={{ width: '30%' }}>Value</th>
<th>Example</th>
</tr>
</thead>
<tbody>
{Object.keys(tokens.elevation.level)
.filter((key) => key !== 'gutter')
.map((key, index) => (
<tr key={index}>
<td>{toTokenFormat(tokens.elevation.level[key].name)}</td>
<td>{tokens.elevation.level[key].value}</td>
<td>
<div
style={{
boxShadow: tokens.elevation.level[key].value,
background: '#FFFFF',
width: '201px',
height: '142px',
display: 'inline-block',
borderRadius: '2px',
}}
/>
</td>
</tr>
))}
</tbody>
</TokenTable>
</PageSection>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
nkamau marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions packages/pharos/src/styles/tokens.react.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,45 @@ const TypeTokens = () => (
export const TypeScale = {
render: () => TypeTokens(),
};

const ElevationTokens = () => (
<>
{TokenTable(
'Elevation tokens',
<>
<thead>
<tr>
<th style={{ width: '33%' }}>Token</th>
<th style={{ width: '33%' }}>Value</th>
<th style={{ width: '33%' }}>Example</th>
</tr>
</thead>
<tbody>
{Object.keys(tokens.elevation.level).map((key, index) => (
<tr key={index}>
<td>{toTokenFormat(tokens.elevation.level[key].name)}</td>
<td>{tokens.elevation.level[key].value}</td>
<td>
<div
className="elevation-example"
style={{
boxShadow: tokens.elevation.level[key].value,
width: '100%',
height: '142px',
flexShrink: '0',
borderRadius: '5px',
background: '#FFF',
}}
/>
</td>
</tr>
))}
</tbody>
</>
)}
</>
);

export const Elevation = {
render: () => ElevationTokens(),
};
36 changes: 36 additions & 0 deletions packages/pharos/src/styles/tokens.wc.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -573,3 +573,39 @@ const TypeTokens = () => html`
export const TypeScale = {
render: () => TypeTokens(),
};

const ElevationTokens = () => html`
${TokenTable(
'Elevation tokens',
html`
<thead>
<tr>
<th style="width:33%">Token</th>
<th style="width:33%">Value</th>
<th style="width:33%">Example</th>
</tr>
</thead>
<tbody>
${Object.keys(tokens.elevation.level).map(
(key) => html`
<tr>
<td>${toTokenFormat(tokens.elevation.level[key].name)}</td>
<td>${tokens.elevation.level[key].value}</td>
<td>
<div
class="elevation-example"
style="box-shadow:${tokens.elevation.level[key].value};
width: 100%;height: 142px;flex-shrink: 0;border-radius: 5px;background: #FFF;"
/>
</td>
</tr>
`
)}
</tbody>
`
)}
`;

export const Elevation = {
render: () => ElevationTokens(),
};
11 changes: 11 additions & 0 deletions packages/pharos/tokens/elevation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"elevation": {
"level": {
"1" : { "value": "0px 1px 2px 0px rgba(18, 18, 18, 0.3),0px 1px 3px 1px rgba(18, 18, 18, 0.15)" },
"2" : { "value": "0px 1px 2px 0px rgba(18, 18, 18, 0.3),0px 2px 6px 2px rgba(18, 18, 18, 0.15)"},
"3" : { "value": "0px 1px 2px 0px rgba(18, 18, 18, 0.3),0px 4px 8px 3px rgba(18, 18, 18, 0.15)"},
"4": { "value": "0px 1px 2px 0px rgba(18, 18, 18, 0.3),0px 6px 10px 4px rgba(18, 18, 18, 0.15)"},
"5": { "value": "0px 1px 2px 0px rgba(18, 18, 18, 0.3),0px 8px 12px 6px rgba(18, 18, 18, 0.15)"}
}
}
}
nkamau marked this conversation as resolved.
Show resolved Hide resolved
Loading