-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(documentation,styles): add position utilities (#3988)
- Loading branch information
Showing
9 changed files
with
477 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'@swisspost/design-system-documentation': minor | ||
'@swisspost/design-system-styles': minor | ||
--- | ||
|
||
Internalized bootstrap position utilities into the design system. |
7 changes: 7 additions & 0 deletions
7
packages/documentation/cypress/snapshots/utilities/position.snapshot.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
describe('Position', () => { | ||
it('position', () => { | ||
cy.visit('/iframe.html?id=snapshots--position'); | ||
cy.get('.position-example', { timeout: 30000 }).should('be.visible'); | ||
cy.percySnapshot('Position', { widths: [320, 1440] }); | ||
}); | ||
}); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions
47
packages/documentation/src/stories/utilities/position/position.docs.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Canvas, Controls, Meta, Source } from '@storybook/blocks'; | ||
import * as PositionStories from './position.stories'; | ||
|
||
<Meta of={PositionStories} /> | ||
|
||
# Position | ||
|
||
<div className="lead"> | ||
Define the positioning method of an element, as well as its position relative to top, bottom, | ||
start and end easily with utility classes. | ||
</div> | ||
<br /> | ||
<div className="alert alert-info">Note that these utility classes are not responsive.</div> | ||
|
||
<Canvas sourceState="shown" of={PositionStories.Default} /> | ||
<div className="hide-col-default"> | ||
<Controls of={PositionStories.Default} /> | ||
</div> | ||
|
||
## Properties | ||
|
||
### Positioning method of elements | ||
|
||
Here are the different positioning methods available for elements. | ||
|
||
- `position-static` (default) positions the element according to the flow of the page. | ||
- `position-relative` positions the element according to the flow of the page, but you can offset it relatively to itself by settings values for `top`, `bottom`, `start` and `end`. | ||
- `position-absolute` removes the element from the flow of the page and positions it relatively to its closest positioned element. | ||
- `position-fixed` removes the element from the flow of the page and positions it relatively to the viewport. | ||
- `position-sticky` positions the element according to the flow of the page but "sticks" it in place in the case of a scrolling container. | ||
|
||
### Arrangement of elements | ||
|
||
Some utility classes are here to define the position from the edges of the container more easily. | ||
|
||
- `top-{0|50|100}` to set the position of the element from the top of the container by 0, 50% or 100%. | ||
- `bottom-{0|50|100}` to set the position of the element from the bottom of the container by 0, 50% or 100%. | ||
- `start-{0|50|100}` to set the position of the element from the start of the container (left in LTR) by 0, 50% or 100%. | ||
- `end-{0|50|100}` to set the position of the element from the end of the container (right in LTR) by 0, 50% or 100%. | ||
|
||
### Translate-middle | ||
|
||
The class `.translate-middle` is there to center an element horizontally and vertically on their x and y position. You can also use `.translate-middle-x` to only center the element horizontally and `.translate-middle-y` to center it vertically. | ||
|
||
<Canvas sourceState="hidden" of={PositionStories.TranslateMiddle} /> | ||
|
||
On the example above, the black dot is the center of the container. Both squares are positioned 50% from the top and 50% from the start. The blue square has the `translate-middle` class and the yellow one doesn't. |
82 changes: 82 additions & 0 deletions
82
packages/documentation/src/stories/utilities/position/position.snapshot.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import type { StoryObj } from '@storybook/web-components'; | ||
import { html } from 'lit'; | ||
import meta from './position.stories'; | ||
import { bombArgs } from '@/utils'; | ||
import './position.styles.scss'; | ||
import { schemes } from '@/shared/snapshots/schemes'; | ||
|
||
const { id, ...metaWithoutId } = meta; | ||
|
||
export default { | ||
...metaWithoutId, | ||
title: 'Snapshots', | ||
}; | ||
|
||
type Story = StoryObj; | ||
|
||
export const Position: Story = { | ||
render: () => { | ||
return schemes( | ||
() => html` | ||
<div class="position-example"> | ||
<h1>Position</h1> | ||
<h2>Position methods</h2> | ||
<div class="py-16"> | ||
${(meta.argTypes?.position?.options ?? []).map((position: string) => { | ||
return html` | ||
<p>Position ${position}</p> | ||
<div class="snapshot-outer-container"> | ||
<div class="snapshot-container bg-gray m-0 position-relative"> | ||
<div class="bg-dark"></div> | ||
<div class="bg-yellow position-${position} top-0 start-50">I'm ${position}</div> | ||
<div class="bg-dark"></div> | ||
<div class="bg-dark"></div> | ||
<div class="bg-dark"></div> | ||
</div> | ||
</div> | ||
`; | ||
})} | ||
<h3>Position arrangement with position absolute</h3> | ||
${bombArgs({ | ||
x: ['start-0', 'start-50', 'start-100', 'end-0', 'end-50', 'end-100'], | ||
y: ['top-0', 'top-50', 'top-100', 'bottom-0', 'bottom-50', 'bottom-100'], | ||
}).map(args => { | ||
const xArgName = (args.x as string).split('-')[0]; | ||
const xArgValue = (args.x as string).split('-')[1]; | ||
const yArgName = (args.y as string).split('-')[0]; | ||
const yArgValue = (args.y as string).split('-')[1]; | ||
return html` | ||
<p class="mt-12">${xArgName}: ${xArgValue}% / ${yArgName}: ${yArgValue}%</p> | ||
<div class="snapshot-arrange-container"> | ||
<div class="bg-info ${args.x} ${args.y}"></div> | ||
</div> | ||
`; | ||
})} | ||
<h3>Translate middle with position absolute</h3> | ||
<p><b>Start: 50% / Top: 50%</b></p> | ||
${bombArgs({ | ||
translateMiddle: ['', 'both', 'x', 'y'], | ||
}).map(args => { | ||
let translateMiddleValue = ''; | ||
if (args.translateMiddle === 'both') { | ||
translateMiddleValue = ' translate-middle'; | ||
} else if (args.translateMiddle === 'x') { | ||
translateMiddleValue = ' translate-middle-x'; | ||
} else if (args.translateMiddle === 'y') { | ||
translateMiddleValue = ' translate-middle-y'; | ||
} | ||
return html` | ||
<p class="mt-12"> | ||
Translate middle: ${args.translateMiddle ? args.translateMiddle : 'none'} | ||
</p> | ||
<div class="snapshot-translate-middle-container"> | ||
<div class="bg-yellow start-50 top-50 ${translateMiddleValue}"></div> | ||
</div> | ||
`; | ||
})} | ||
</div> | ||
</div> | ||
`, | ||
); | ||
}, | ||
}; |
156 changes: 156 additions & 0 deletions
156
packages/documentation/src/stories/utilities/position/position.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import type { Args, StoryObj } from '@storybook/web-components'; | ||
import { html } from 'lit/static-html.js'; | ||
import { MetaExtended } from '@root/types'; | ||
import './position.styles.scss'; | ||
import { bombArgs } from '@/utils'; | ||
|
||
const meta: MetaExtended = { | ||
id: '803a58e8-c734-4ad7-80a8-62da1bb29d4b', | ||
title: 'Utilities/Position', | ||
args: { | ||
position: 'absolute', | ||
start: '50', | ||
top: '0', | ||
translateMiddle: 'both', | ||
}, | ||
argTypes: { | ||
position: { | ||
name: 'Position', | ||
description: 'Sets the position. ', | ||
control: { | ||
type: 'select', | ||
}, | ||
options: ['relative', 'static', 'absolute', 'fixed', 'sticky'], | ||
table: { | ||
category: 'General', | ||
}, | ||
}, | ||
top: { | ||
name: 'Top', | ||
description: 'Sets the distance from top. ', | ||
control: { | ||
type: 'select', | ||
}, | ||
options: ['', '0', '50', '100'], | ||
table: { | ||
category: 'General', | ||
}, | ||
if: { | ||
arg: 'bottom', | ||
truthy: false, | ||
}, | ||
}, | ||
bottom: { | ||
name: 'Bottom', | ||
description: 'Sets the distance from bottom. ', | ||
control: { | ||
type: 'select', | ||
}, | ||
options: ['', '0', '50', '100'], | ||
table: { | ||
category: 'General', | ||
}, | ||
if: { | ||
arg: 'top', | ||
truthy: false, | ||
}, | ||
}, | ||
start: { | ||
name: 'Start', | ||
description: 'Sets the distance from start (left in LTR). ', | ||
control: { | ||
type: 'select', | ||
}, | ||
options: ['', '0', '50', '100'], | ||
table: { | ||
category: 'General', | ||
}, | ||
if: { | ||
arg: 'end', | ||
truthy: false, | ||
}, | ||
}, | ||
end: { | ||
name: 'End', | ||
description: 'Sets the distance from end (right in LTR). ', | ||
control: { | ||
type: 'select', | ||
}, | ||
options: ['', '0', '50', '100'], | ||
table: { | ||
category: 'General', | ||
}, | ||
if: { | ||
arg: 'start', | ||
truthy: false, | ||
}, | ||
}, | ||
translateMiddle: { | ||
name: 'Translate middle', | ||
description: 'Set to true to center align an element based on its x and y position.', | ||
control: { | ||
type: 'select', | ||
}, | ||
options: ['', 'both', 'x', 'y'], | ||
table: { | ||
category: 'General', | ||
}, | ||
}, | ||
}, | ||
render: (args: Args) => { | ||
let translateMiddleValue = ''; | ||
if (args.translateMiddle === 'both') { | ||
translateMiddleValue = ' translate-middle'; | ||
} else if (args.translateMiddle === 'x') { | ||
translateMiddleValue = ' translate-middle-x'; | ||
} else if (args.translateMiddle === 'y') { | ||
translateMiddleValue = ' translate-middle-y'; | ||
} | ||
return html` | ||
<div | ||
class="bg-yellow position-${args.position} ${args.top ? 'top-' + args.top : ''}${args.bottom | ||
? 'bottom-' + args.bottom | ||
: ''} ${args.start ? 'start-' + args.start : ''}${args.end | ||
? 'end-' + args.end | ||
: ''}${translateMiddleValue}" | ||
></div> | ||
`; | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj; | ||
|
||
export const Default: Story = { | ||
decorators: [ | ||
(story, context) => | ||
html` | ||
<div class="position-outer-container position-outer-container-${context.args.position}"> | ||
${context.args.position === 'fixed' | ||
? html`<img src="../images/browser-bg-top.png" />` | ||
: ''} | ||
<div class="position-container position-relative"> | ||
${story()} | ||
${bombArgs({ | ||
start: ['0', '50', '100'], | ||
top: ['0', '50', '100'], | ||
}).map( | ||
args => html` <div class="pos-element top-${args.top} start-${args.start}"></div> `, | ||
)} | ||
</div> | ||
</div> | ||
`, | ||
], | ||
}; | ||
|
||
export const TranslateMiddle: Story = { | ||
decorators: [ | ||
story => | ||
html` <div class="translate-middle-container position-relative bg-gray">${story()}</div> `, | ||
], | ||
render: () => { | ||
return html`<div class="position-absolute start-50 top-50 bg-yellow"></div> | ||
<div class="position-absolute start-50 top-50 translate-middle bg-info"></div>`; | ||
}, | ||
}; |
Oops, something went wrong.