Skip to content

Commit

Permalink
Add 'torchlight' effect to cards in dark mode (#468)
Browse files Browse the repository at this point in the history
  • Loading branch information
rezrah authored Oct 19, 2023
1 parent 92b346e commit a6251df
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 93 deletions.
5 changes: 5 additions & 0 deletions .changeset/collect-young-ants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react-brand': patch
---

Force removal of link underlines in Card components, to prevent specificity issues with local stylesheet overrides.
7 changes: 7 additions & 0 deletions .changeset/young-ants-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@primer/react-brand': patch
---

Added 'torchlight' hover effect to dark mode Card instances.

See: https://primer.style/brand/components/Card/react#torchlight-effect
47 changes: 42 additions & 5 deletions apps/docs/content/components/Card/react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,42 @@ Use the `Image` component to add an image to the `Card`. The `Image` component i
</Card>
```

### Torchlight effect

`Card` components in dark mode feature a unique "torchlight" effect.

The color of the lit area corrosponds to the nearest active, primary accent color. The color can modified by changing the value of the respective CSS variable.

```jsx live
<ThemeProvider colorMode="dark">
<Box padding="spacious" backgroundColor="default">
<Stack direction="horizontal" padding="none">
<Card href="https://github.com">
<Card.Icon icon={CopilotIcon} color="pink" hasBackground />
<Card.Heading>Code search & code view</Card.Heading>
<Card.Description>
Enables you to rapidly search, navigate, and understand code, right
from GitHub.com.
</Card.Description>
</Card>
<Card
href="https://github.com"
style={{
['--brand-color-accent-primary']: 'var(--base-color-scale-lime-2)',
}}
>
<Card.Icon icon={ZapIcon} color="lime" hasBackground />
<Card.Heading>Code search & code view</Card.Heading>
<Card.Description>
Enables you to rapidly search, navigate, and understand code, right
from GitHub.com.
</Card.Description>
</Card>
</Stack>
</Box>
</ThemeProvider>
```

### Image and Label

Combine `Image` and `Label` when you need to add more metadata or context to the `Card`. Use either the `Icon` or `Image` as the primary visual context, but not both.
Expand Down Expand Up @@ -185,11 +221,12 @@ Use the `Stack` component to stack multiple cards horizontally or vertically.

### Card

| name | type | default | required | description |
| ----------- | --------- | ----------- | -------- | ------------------------------------------- |
| `href` | `string` | | `true` | URL to the card content |
| `ctaText` | `string` | `Read more` | `false` | Label of the link at the bottom of the Card |
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the Card |
| name | type | default | required | description |
| ------------------ | --------- | ----------- | -------- | ---------------------------------------------------------------- |
| `ctaText` | `string` | `Read more` | `false` | Label of the link at the bottom of the card |
| `disableAnimation` | `boolean` | `false` | `false` | A flag to disable the default hover animation effect of the card |
| `hasBorder` | `boolean` | `false` | `false` | A flag used to provide a border to the card |
| `href` | `string` | | `true` | URL to the card content |

### Card.Image

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/scripts/components-with-animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export const supportedComponents = [
'Pillar',
'SectionIntro',
'Stack',
'Timeline',
'Testimonial',
'Text',
'Timeline',
'Animate',
'River',
'RiverBreakout',
Expand Down
86 changes: 83 additions & 3 deletions packages/react/src/Card/Card.features.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import {StoryFn, Meta} from '@storybook/react'
import {Card, CardIconColors} from '.'
import {Stack, LabelColors, Grid} from '..'
import {Stack, LabelColors, Grid, ThemeProvider, Box} from '..'
import placeholderImage from '../fixtures/images/placeholder-600x400.png'
import {CopilotIcon, RocketIcon, GitBranchIcon, HeartIcon} from '@primer/octicons-react'
import {CopilotIcon, ZapIcon, RocketIcon, GitBranchIcon, HeartIcon} from '@primer/octicons-react'

export default {
title: 'Components/Card/features',
Expand Down Expand Up @@ -62,7 +62,7 @@ export const IconColors: StoryFn<typeof Card> = () => {
<Stack padding={'none'} direction="horizontal" gap={'normal'} style={{flexWrap: 'wrap'}}>
{CardIconColors.map((color, id) => {
return (
<Card key={id} href="https://github.com" style={{maxWidth: '25%'}}>
<Card key={id} href="https://github.com">
<Card.Icon icon={CopilotIcon} hasBackground color={color} />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>
Expand Down Expand Up @@ -200,3 +200,83 @@ export const Stacked: StoryFn<typeof Card> = () => {
</Grid>
)
}

export const DarkColorModeEffect = () => {
return (
<>
<Stack
direction={{
narrow: 'vertical',
regular: 'horizontal',
}}
gap={36}
>
<Card href="https://github.com">
<Card.Icon icon={ZapIcon} hasBackground />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>Everything you need to know about getting started with GitHub Actions.</Card.Description>
</Card>
<Card
href="https://github.com"
style={{['--brand-color-accent-primary' as string]: 'var(--base-color-scale-indigo-2)'}}
>
<Card.Icon icon={CopilotIcon} hasBackground color="indigo" />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>Everything you need to know about getting started with GitHub Actions.</Card.Description>
</Card>

<Card
href="https://github.com"
style={{['--brand-color-accent-primary' as string]: 'var(--base-color-scale-yellow-2)'}}
>
<Card.Icon icon={GitBranchIcon} hasBackground color="yellow" />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>Everything you need to know about getting started with GitHub Actions.</Card.Description>
</Card>
</Stack>
<Stack
direction={{
narrow: 'vertical',
regular: 'horizontal',
}}
gap={36}
>
<Card
href="https://github.com"
style={{['--brand-color-accent-primary' as string]: 'var(--base-color-scale-red-2)'}}
>
<Card.Icon icon={HeartIcon} hasBackground color="red" />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>Everything you need to know about getting started with GitHub Actions.</Card.Description>
</Card>

<Card
href="https://github.com"
style={{['--brand-color-accent-primary' as string]: 'var(--base-color-scale-orange-2)'}}
>
<Card.Icon icon={ZapIcon} hasBackground color="orange" />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>Everything you need to know about getting started with GitHub Actions.</Card.Description>
</Card>
<Card
href="https://github.com"
style={{['--brand-color-accent-primary' as string]: 'var(--base-color-scale-lime-2)'}}
>
<Card.Icon icon={RocketIcon} hasBackground color="lime" />
<Card.Heading>Collaboration is the key to DevOps success</Card.Heading>
<Card.Description>Everything you need to know about getting started with GitHub Actions.</Card.Description>
</Card>
</Stack>
</>
)
}

DarkColorModeEffect.decorators = [
Story => (
<ThemeProvider colorMode="dark">
<Box backgroundColor="default">
<Story />
</Box>
</ThemeProvider>
),
]
54 changes: 51 additions & 3 deletions packages/react/src/Card/Card.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
max-width: var(--brand-Card-maxWidth);
text-decoration: none;
color: var(--brand-color-text-default);
background-color: var(--brand-Card-background-default);
border-radius: var(--brand-borderRadius-large);
padding: var(--base-size-32);
transition: transform var(--brand-Card-animation-duration) var(--brand-Card-animation-easing);
Expand All @@ -21,6 +20,10 @@
height: 100%;
}

.Card--colorMode-light {
background-color: var(--brand-Card-background-default);
}

.Card:focus-within {
outline: var(--brand-borderWidth-thick) solid var(--brand-color-focus);
}
Expand All @@ -31,7 +34,11 @@

.Card__link {
color: currentColor;
text-decoration: none;
text-decoration: none !important;
}

.Card--disableAnimation:hover .Card__link {
text-decoration: underline !important;
}

/* The focus outline will appear around the entire card, not just the title */
Expand All @@ -49,6 +56,10 @@
border: var(--brand-borderWidth-thin) solid var(--brand-color-border-default);
}

.Card__outer {
height: 100%;
}

.Card--icon {
grid-template-areas:
'image image'
Expand All @@ -67,7 +78,7 @@
align-self: center;
}

.Card:hover {
.Card--colorMode-light:not(.Card--disableAnimation):hover {
transform: scale3d(1.025, 1.025, 1);
}

Expand Down Expand Up @@ -240,3 +251,40 @@
.Card__icon--color-yellow.Card__icon--badge {
background-color: var(--brand-Card-icon-background-yellow);
}

.Card--skew {
height: 100%;
display: inline-block;
overflow: hidden;
border-radius: var(--brand-borderRadius-large);
}

.Card--skew:hover .Card__torch {
opacity: 0.85;
}

.Card__skew-bounding {
border: var(--brand-borderWidth-thin) solid var(--brand-color-border-default);
border-radius: var(--brand-borderRadius-large);
position: relative;
z-index: 1;
height: 100%;
background-color: var(--brand-Card-background-default);
}

.Card__torch {
width: 650px;
height: 650px;
background-color: var(--brand-color-accent-primary);
filter: blur(180px);
border-radius: 300px;
opacity: 0;
transition: opacity 1.2s cubic-bezier(0.16, 1, 0.3, 1);
mix-blend-mode: soft-light;
will-change: transform;
pointer-events: none;
position: absolute;
bottom: 0;
right: 0;
z-index: -1;
}
60 changes: 32 additions & 28 deletions packages/react/src/Card/Card.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
declare const styles: {
readonly "Card": string;
readonly "Card__link": string;
readonly "Card--border": string;
readonly "Card--icon": string;
readonly "Card__label": string;
readonly "Card__icon": string;
readonly "Card__image": string;
readonly "Card__icon--badge": string;
readonly "Card__heading": string;
readonly "Card__description": string;
readonly "Card__action": string;
readonly "Card__icon--color-default": string;
readonly "Card__icon--color-blue": string;
readonly "Card__icon--color-coral": string;
readonly "Card__icon--color-green": string;
readonly "Card__icon--color-gray": string;
readonly "Card__icon--color-indigo": string;
readonly "Card__icon--color-lemon": string;
readonly "Card__icon--color-lime": string;
readonly "Card__icon--color-orange": string;
readonly "Card__icon--color-pink": string;
readonly "Card__icon--color-purple": string;
readonly "Card__icon--color-red": string;
readonly "Card__icon--color-teal": string;
readonly "Card__icon--color-yellow": string;
};
export = styles;

readonly Card: string
readonly 'Card--colorMode-light': string
readonly Card__link: string
readonly 'Card--border': string
readonly Card__inner: string
readonly 'Card--icon': string
readonly Card__label: string
readonly Card__icon: string
readonly Card__image: string
readonly 'Card__icon--badge': string
readonly Card__heading: string
readonly Card__description: string
readonly Card__action: string
readonly 'Card__icon--color-default': string
readonly 'Card__icon--color-blue': string
readonly 'Card__icon--color-coral': string
readonly 'Card__icon--color-green': string
readonly 'Card__icon--color-gray': string
readonly 'Card__icon--color-indigo': string
readonly 'Card__icon--color-lemon': string
readonly 'Card__icon--color-lime': string
readonly 'Card__icon--color-orange': string
readonly 'Card__icon--color-pink': string
readonly 'Card__icon--color-purple': string
readonly 'Card__icon--color-red': string
readonly 'Card__icon--color-teal': string
readonly 'Card__icon--color-yellow': string
readonly 'Card--skew': string
readonly Card__torch: string
readonly 'Card__skew-bounding': string
}
export = styles
Loading

0 comments on commit a6251df

Please sign in to comment.