@devdiary/ui
v8.4.0
Published
DevDiary UI Components
Downloads
12
Readme
devdiary-ui
devdiary-ui
is a UI component library written in Vue.js.
See https://kero-stack.github.io/devdiary-ui/ for documentation.
Prerequisites
Make sure you have Node 8.x (LTS) and Yarn 1.2 or newer.
Quick start
# Clone the project
git clone [email protected]:kero-stack/devdiary-ui.git
# Navigate to the root of the project
cd devdiary-ui
# Install all the dependencies of the project
yarn # or yarn install
# Build and launch storybook to see the components in the browser
yarn storybook
Go to http://localhost:9001/
Testing
Unit tests
Components’ unit tests live in the tests/components
. The tests are organized following the same directory structure used to organize components.
yarn test:unit
runs all unit tests.
yarn test:unit:watch
runs all unit tests in watch mode.
yarn test:unit:debug
runs all unit tests and allow to attach a debugger to the test runner process.
yarn jest [name_pattern]
runs spec files that match the specified name pattern.
Examples
yarn jest datepicker
will match all spec files with a name that contains the word datepicker.
yarn jest datepicker -t "when draw event is emitted"
goes a step further and only runs the test with a description that matches the argument passed to the t
flag.
SCSS tests
Even though we try to avoid writing complex SASS code to maintain CSS complexity low, we’ve implemented some functions that benefit from automated testing. SASS tests live in the tests/scss
directory. devdiary-ui use sass-true to implement these tests, and jest run them.
yarn jest run_scss_tests
runs all SCSS tests.
Visual regression tests
devdiary-ui uses visual snapshot tests to prevent introducing unexpected regressions with CSS and layout changes on components. The tool we use is storyshots, a storybook addon. Read the project documentation to understand how visual snapshots work.
There is a visual snapshot of every component’s storybook story. To run the tests, use the yarn test:visual
command. This command runs on the CI environment and will fail if the component visual appearance changes.
Updating visual snapshot baseline images
In some occasions, the changes in a component’s appearance are justified. In those cases, we have to update the baseline images to match the new look. To do that, follow this troubleshooting guide
Devdiary visual regression tests
devdiary-ui components are a reference implementation of the Pajamas Design System components. These components should conform with the design system specs, and they should look correct in the pajamas website and the devdiary product. To make sure devdiary-ui’s components look precisely as their design specs dictate in devdiary, we created the yarn run test:visual:devdiary
command.
This command only runs visual tests for components that have the followsDesignSystem: true
flag activated in their *.documentation.js
file. It will include devdiary product’s final CSS output in storybook and run the visual snapshots against this version.
The tests will fail if after including devdiary CSS, one or more components look different. These failures highlight how CSS that leaks from devdiary will affect a component’s final look in the product.
Running visual regression tests locally
Visual difference tests form part of the test suite. Rendered output can vary
from host to host (e.g., due to available fonts and how each platform renders
them), so these can fail when run locally. The easiest way to work around this
is to increase the failure threshold with the FAILURE_THRESHOLD
environment
variable:
# Sets a 2% threshold
FAILURE_THRESHOLD=.02 yarn test
If the variable is unset, it defaults to 0
.
Installation
Install with Yarn:
yarn add @devdiary/ui
Install with NPM:
npm install @devdiary/ui
Adding CSS
From DevDiary 12.2 on, we are moving components styles into DevDiary UI, as described in the approved RFC #2. This approach will let us progressively decouple DevDiary UI's styles from DevDiary CE's styles.
Within the components' CSS, you should include utility mixins. See
utility-mixins
for a comprehensive list of the available utilities. If what you are
looking for is not available, add it following the naming conventions
indicated in that file.
Files should be structured like this:
.
├── components
│ └── base
│ ├── button
│ │ ├── button.scss
│ │ ├── button.stories.js
│ │ └── button.vue
│ └── popover
│ ├── popover.scss
│ ├── popover.stories.js
│ └── popover.vue
└── assets
├──components.scss
└── devdiary_ui.scss
Where each component's stylesheet contains its "modularized" style:
// button.scss
.gl-button {
// style
@include some-utility-mixin;
}
And the assets/components.scss
file imports all components' stylesheets:
// components.scss
@import '../components/base/button/button';
@import '../components/base/popover/popover';
Within the component and when the component is integrated
into the application, you should still follow the
utility-first
approach for basic layout and other styles.
See !623 for an example and !624 for the first pass implementation of silent classes. Follow along with the development epic at &1590.
Why are we doing it like this?
The current SCSS architecture was designed to allow us both to gain the advantages of a utility CSS approach while also applying the same styles to both Vue components here in devdiary-ui
and HAML components in devdiary
.
With utility-first CSS, styles are applied as a combination of single-attribute classes:
.flex {
display: flex;
}
.hot-pink {
color: $gl-pink-500
}
..
<my-component class='flex hot-pink ...' />
The advantages of this approach are:
It keeps CSS file-size from growing too fast. With combinations applied in markup instead of separately named classes, new CSS usually does not need to be added.
It clarifies which colors, sizes, and other options are available within the design system. Rather than pulling values from specs or guessing, engineers are able to use already-vetted values. This also means that adding a new value becomes more deliberate and easier to check in reviews.
It increases confidence that adding or removing a class will not have unintended consequences.
It makes it easier to cascade design-system changes, especially around text and spacing. That is because the utility classes lend themselves to being updatable, like variables, in just one place. Consider the case of spacing: the values are taken from a scale (
gl-spacing-0
,gl-spacing-10
), which means updating from a base of4px
to6px
means updating just those classes but keeping the relations the same.
We've decided to build both component classes and utility classes from the same mixins in order to get these benefits while also having component CSS that can be applied in devdiary-ui
and devdiary
, Vue
and HAML
, without undue or repeated effort.
For even more detail on our decision making, RFCs #2 and #4 contain historical discussion around these issues. After RFC #4 was approved, we realized the silent class plus @extend
approach generated large amounts of CSS and the approach was modified to use mixins and @include
instead. For more context, see also this relevant discussion.
For more information about utility-first CSS, consider a post from Mike Crittenden, Ollie Williams on CSS Tricks or Sarah Dayan's Frontstuff.
Finally, to join in on discussion about HAML components, check out the following ongoing conversations:
So wait, when do I add a variable? a utility class? a component class?
Add a variable (in variables.scss
) if you are setting a base value in the design system — this is rare.
Add a component class when writing styles that should apply to both HAML and Vue instances of a component. You may also want to use component classes when you find the same classes are being grouped together for functionality, like .d-flex-center
.
Add or apply a utility class the rest of the time.
Other Stylish Questions
More answers and details can be found in the SCSS Styleguide
Contributing guide
Please refer to CONTRIBUTING.md for details on how to add new components and contribute in general to devdiary-ui
.
FAQs
Any question? Have a look at our FAQ.md, you might find the answer there.