Skip to content

Commit

Permalink
Component System: Add Elevation Component (#28593)
Browse files Browse the repository at this point in the history
* Add Elevation component

* Add aria-hidden to the Elevation element

* Update type for borderRadius

* Update snapshot tests

* Move elevation into ui

* Update snapshot

* Fix types

* Update elevation stories + active vs. focus style rendering order

Co-authored-by: Sara Marcondes <saram@fastmail.com>
  • Loading branch information
Q and sarayourfriend committed Feb 11, 2021
1 parent 6853c1c commit 4c69dae
Show file tree
Hide file tree
Showing 10 changed files with 781 additions and 0 deletions.
70 changes: 70 additions & 0 deletions packages/components/src/ui/elevation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Elevation

`Elevation` is a core component that renders shadow, using the component system's shadow system.

## Usage

The shadow effect is generated using the `value` prop.

```jsx live
import {
__experimentalElevation as Elevation,
__experimetnalSurface as Surface,
__experimetnalText as Text,
__experimetnalView as View,
} from '@wp-g2/components';

function Example() {
return (
<Surface>
<Text>Elevation</Text>
<Elevation value={ 5 } />
</Surface>
);
}
```

## Props

##### active

**Type**: `boolean`

Renders the active (interaction) shadow value.

##### borderRadius

**Type**: `string`,`number`

Renders the border-radius of the shadow.

##### focus

**Type**: `boolean`

Renders the focus (interaction) shadow value.

##### hover

**Type**: `boolean`

Renders the hover (interaction) shadow value.

##### isInteractive

**Type**: `boolean`

Determines if hover, active, and focus shadow values should be automatically calculated and rendered.

##### offset

**Type**: `number`

Dimensional offsets (margin) for the shadow.

##### value

**Type**: `number`

Size of the shadow, based on the Style system's elevation system. The `value` determines the strength of the shadow, which sense of depth.
In the example below, `isInteractive` is activated to give a better sense of depth.
13 changes: 13 additions & 0 deletions packages/components/src/ui/elevation/elevation-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* External dependencies
*/
import { css } from '@wp-g2/styles';

export const Elevation = css`
background: transparent;
display: block;
margin: 0 !important;
pointer-events: none;
position: absolute;
will-change: box-shadow;
`;
32 changes: 32 additions & 0 deletions packages/components/src/ui/elevation/elevation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Internal dependencies
*/
import { useElevation } from './use-elevation';
import { createComponent } from '../utils';

/**
* `Elevation` is a core component that renders shadow, using the library's shadow system.
*
* The shadow effect is generated using the `value` prop.
*
* @example
* ```jsx
* function Example() {
* return (
* <View css={ [ ui.padding( 5 ) ] }>
* <Surface css={ [ ui.padding( 5 ) ] }>
* <Text>Into The Unknown</Text>
* <Elevation value={ 5 } />
* </Surface>
* </View>
* );
* }
* ```
*/
const Elevation = createComponent( {
as: 'div',
useHook: useElevation,
name: 'Elevation',
} );

export default Elevation;
2 changes: 2 additions & 0 deletions packages/components/src/ui/elevation/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Elevation } from './elevation';
export * from './use-elevation';
114 changes: 114 additions & 0 deletions packages/components/src/ui/elevation/stories/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* External dependencies
*/
import { boolean, number } from '@storybook/addon-knobs';

/**
* Internal dependencies
*/
import { Elevation } from '../index';
import { Grid } from '../../grid';
import { View } from '../../view';

/**
* WordPress dependencies
*/
import { useCallback } from '@wordpress/element';

export default {
component: Elevation,
title: 'G2 Components (Experimental)/Elevation',
};

export const _default = () => {
const value = number( 'value', 5 );
const borderRadius = number( 'borderRadius', 0 );
const hover = number( 'hover', undefined );
const active = number( 'active', undefined );
const isInteractive = boolean( 'isInteractive', true );

return (
<View
css={ {
padding: '10vh',
position: 'relative',
margin: '20vh auto 10vw',
maxWidth: 200,
} }
>
<Elevation
isInteractive={ isInteractive }
value={ value }
borderRadius={ borderRadius }
hover={ hover }
active={ active }
/>
</View>
);
};

export const Focus = () => {
const borderRadius = number( 'borderRadius', 0 );
const value = number( 'value', 5 );
const hover = number( 'hover', 5 );
const active = number( 'active', 1 );
const focus = number( 'focus', 10 );

const Card = useCallback(
( props ) => (
<View
{ ...props }
as="a"
href="#"
onClick={ ( e ) => e.preventDefault() }
css={ {
display: 'block',
width: 100,
height: 100,
borderRadius,
position: 'relative',
margin: '20vh auto 10vw',
} }
/>
),
[]
);

return (
<View
css={ {
padding: '10vh',
} }
>
<Grid columns={ 3 }>
<Card>
<Elevation
borderRadius={ borderRadius }
value={ value }
focus={ focus }
active={ active }
hover={ hover }
/>
</Card>
<Card>
<Elevation
borderRadius={ borderRadius }
value={ value }
focus={ focus }
active={ active }
hover={ hover }
/>
</Card>
<Card>
<Elevation
borderRadius={ borderRadius }
value={ value }
focus={ focus }
active={ active }
hover={ hover }
/>
</Card>
</Grid>
</View>
);
};

0 comments on commit 4c69dae

Please sign in to comment.