Oleksii Vasyliev, Railsware
Brought to you by Alexey Vasiliev, Railsware
In a nutshell: Divide layout into objects, then abstract their CSS into modules, more info
.button { padding: 10px 16px; }
.primary-skin { color: blue; }
.secondary-skin { color: green; }
<button class="button primary-skin">primary button</button>
<button class="button secondary-skin">secondary button</button>
<div class="primary-skin">primary skin div</div>
In a nutshell: Split CSS code across multiple files for better performance and organisation, more info
nav.nav-primary li {
display: inline-block;
}
nav.nav-secondary li {
display: block;
}
In a nutshell: Separation of the CSS codebase into several layers, based on the specificity level, more info
@import "objects.animations";
@import "objects.drawer";
@import "objects.list-bare";
@import "components.404";
@import "components.about";
@import "components.archive";
In a nutshell: Create a class selector for every repeating CSS declaration, more info
<div class="Bgc(#0280ae.5) C(#fff) P(20px)">
Lorem ipsum
</div>
In a nutshell: Use a standard naming convention for classes, more info
<ul class="list-block list-block--inline">
<li class="list-block__item">Item 1</li>
<li class="list-block__item">Item 2</li>
</ul>
<div
class="w-16 h-16 rounded text-white
bg-black py-1 px-2 m-1 text-sm md:w-32
md:h-32 md:rounded-md md:text-base
lg:w-48 lg:h-48 lg:rounded-lg lg:text-lg"
>
Yikes.
</div>
.c-input {
@apply block appearance-none bg-white placeholder-gray-600
border border-indigo-200 rounded w-full py-3 px-4
text-gray-700 leading-5 focus:outline-none
focus:border-indigo-400 focus:placeholder-gray-400
focus:ring-2 focus:ring-indigo-200;
}
section {
lost-utility: clearfix;
}
div {
lost-column: 1/2;
}
$blue: #056ef0;
$column: 200px;
.menu {
width: calc(4 * $column);
}
.menu_link {
background: $blue;
width: $column;
}
a
color: blue
.multiline,
.selector
box-shadow: 1px 0 9px rgba(0, 0, 0, .4),
1px 0 3px rgba(0, 0, 0, .6)
.foo {
font-size: responsive;
}
.foo {
color: rgba(#fff, 0.8);
}
.foo {
width: 240px;
}
.bar {
width: 160px;
}
@media screen and (min-width: 768px) {
.foo {
width: 576px;
}
.bar {
width: 384px;
}
}
import React from 'react'
import {render, screen} from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
//👇 Imports a specific story for the test
import {Primary} from './Button.stories'
it('renders the button in the primary state', () => {
render(<Primary {...Primary.args} />);
expect(screen.getByRole('button')).toHaveTextContent('Primary Button');
});
import initStoryshots from '@storybook/addon-storyshots'
import {imageSnapshot} from '@storybook/addon-storyshots-puppeteer'
initStoryshots({
suite: 'Basic storyshots',
test: imageSnapshot({storybookUrl: 'http://localhost:6006/'})
})
describe('<Button />', () => {
...
it('check content after clicking', async () => {
// navigate to story
await page.goto(
'http://localhost:6006/iframe.html?id=components-button--primary',
)
// click on the button
await page.click('button')
// take screenshot and compare
const screenshot = await page.screenshot()
expect(screenshot).toMatchImageSnapshot() // import {toMatchImageSnapshot} from 'jest-image-snapshot'
})
})