Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 10 additions & 0 deletions polaris-react/src/components/Bleed/Bleed.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import '../../styles/common';

.Bleed {
/* stylelint-disable declaration-block-no-redundant-longhand-properties */
margin-bottom: calc(-1 * var(--pc-bleed-margin-bottom));
margin-left: calc(-1 * var(--pc-bleed-margin-left));
margin-right: calc(-1 * var(--pc-bleed-margin-right));
margin-top: calc(-1 * var(--pc-bleed-margin-top));
/* stylelint-enable declaration-block-no-redundant-longhand-properties */
}
64 changes: 64 additions & 0 deletions polaris-react/src/components/Bleed/Bleed.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';
import type {ComponentMeta} from '@storybook/react';
import {Bleed, Box} from '@shopify/polaris';

export default {
component: Bleed,
} as ComponentMeta<typeof Bleed>;

const styles = {
background: 'var(--p-surface-neutral-subdued-dark)',
borderRadius: 'var(--p-border-radius-05)',
padding: 'var(--p-space-4)',
height: 'var(--p-space-12)',
};

export function Default() {
return (
<Box background="surface" padding="4">
<Bleed>
<div style={styles} />
</Bleed>
</Box>
);
}

export function WithVerticalDirection() {
return (
<Box background="surface" padding="4">
<Bleed vertical="6">
<div style={styles} />
</Bleed>
</Box>
);
}

export function WithHorizontalDirection() {
return (
<Box background="surface" padding="4">
<Bleed horizontal="6">
<div style={styles} />
</Bleed>
</Box>
);
}

export function WithSpecificDirection() {
return (
<Box background="surface" padding="4">
<Bleed top="6">
<div style={styles} />
</Bleed>
</Box>
);
}

export function WithAllDirection() {
return (
<Box background="surface" padding="4">
<Bleed spacing="6">
<div style={styles} />
</Bleed>
</Box>
);
}
95 changes: 95 additions & 0 deletions polaris-react/src/components/Bleed/Bleed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from 'react';
import type {spacing} from '@shopify/polaris-tokens';

import {sanitizeCustomProperties} from '../../utilities/css';

import styles from './Bleed.scss';

type SpacingTokenName = keyof typeof spacing;

// TODO: Bring this logic into tokens
type SpacingTokenScale = SpacingTokenName extends `space-${infer Scale}`
? Scale
: never;

interface Spacing {
bottom: SpacingTokenScale;
left: SpacingTokenScale;
right: SpacingTokenScale;
top: SpacingTokenScale;
}

export interface BleedProps {
/** Elements to display inside tile */
children: React.ReactNode;
spacing?: SpacingTokenScale;
horizontal?: SpacingTokenScale;
vertical?: SpacingTokenScale;
top?: SpacingTokenScale;
bottom?: SpacingTokenScale;
left?: SpacingTokenScale;
right?: SpacingTokenScale;
}

export const Bleed = ({
spacing,
horizontal,
vertical,
top,
bottom,
left,
right,
children,
}: BleedProps) => {
const getNegativeMargins = (direction: string) => {
const xAxis = ['left', 'right'];
const yAxis = ['top', 'bottom'];

const directionValues: {[key: string]: string | undefined} = {
top,
bottom,
left,
right,
horizontal,
vertical,
};

if (directionValues[direction]) {
return directionValues[direction];
} else if (!yAxis.includes(direction) && horizontal) {
return directionValues.horizontal;
} else if (!xAxis.includes(direction) && vertical) {
return directionValues.vertical;
} else {
return spacing;
}
};

const negativeMargins = {
top: getNegativeMargins('top'),
left: getNegativeMargins('left'),
right: getNegativeMargins('right'),
bottom: getNegativeMargins('bottom'),
} as Spacing;

const style = {
...(negativeMargins.bottom
? {'--pc-bleed-margin-bottom': `var(--p-space-${negativeMargins.bottom})`}
: undefined),
...(negativeMargins.left
? {'--pc-bleed-margin-left': `var(--p-space-${negativeMargins.left})`}
: undefined),
...(negativeMargins.right
? {'--pc-bleed-margin-right': `var(--p-space-${negativeMargins.right})`}
: undefined),
...(negativeMargins.top
? {'--pc-bleed-margin-top': `var(--p-space-${negativeMargins.top})`}
: undefined),
} as React.CSSProperties;

return (
<div className={styles.Bleed} style={sanitizeCustomProperties(style)}>
{children}
</div>
);
};
1 change: 1 addition & 0 deletions polaris-react/src/components/Bleed/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Bleed';
59 changes: 59 additions & 0 deletions polaris-react/src/components/Bleed/tests/Bleed.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import {mountWithApp} from 'tests/utilities';

import {Bleed} from '../Bleed';

const Children = () => <p>This is a tile</p>;

describe('<Bleed />', () => {
it('renders children', () => {
const bleed = mountWithApp(
<Bleed>
<Children />
</Bleed>,
);

expect(bleed).toContainReactComponent(Children);
});

it('does not render custom properties by default', () => {
const bleed = mountWithApp(
<Bleed>
<Children />
</Bleed>,
);

expect(bleed).toContainReactComponent('div', {style: undefined});
});

it('only renders the custom property that matches the property passed in', () => {
const bleed = mountWithApp(
<Bleed left="2">
<Children />
</Bleed>,
);

expect(bleed).toContainReactComponent('div', {
style: {
'--pc-bleed-margin-left': 'var(--p-space-2)',
} as React.CSSProperties,
});
});

it('renders custom properties combined with any overrides if they are passed in', () => {
const bleed = mountWithApp(
<Bleed spacing="1" left="2" horizontal="3">
<Children />
</Bleed>,
);

expect(bleed).toContainReactComponent('div', {
style: {
'--pc-bleed-margin-bottom': 'var(--p-space-1)',
'--pc-bleed-margin-left': 'var(--p-space-2)',
'--pc-bleed-margin-right': 'var(--p-space-3)',
'--pc-bleed-margin-top': 'var(--p-space-1)',
} as React.CSSProperties,
});
});
});
3 changes: 3 additions & 0 deletions polaris-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export type {
BannerHandles,
} from './components/Banner';

export {Bleed} from './components/Bleed';
export type {BleedProps} from './components/Bleed';

export {Box} from './components/Box';
export type {BoxProps} from './components/Box';

Expand Down