-
Notifications
You must be signed in to change notification settings - Fork 30
Restructure styles, improve code and docs #150
Conversation
Pull Request Test Coverage Report for Build 592
💛 - Coveralls |
I've also noticed that we're doing things like: Integer.defaultProps = {
value: undefined,
defaultValue: undefined,
// other stuff
}; in order to satisfy the |
f2f4ee4
to
4319568
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vojtechszocs thank you for explaining BEM! It was really helpful. Can you please take a look at my review comments and rebase ?
@@ -0,0 +1,3 @@ | |||
.kubevirt-dropdown-group .dropdown-menu { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to call this .kubevirt-dropdown__dropdown-group .dropdown-menu
and move it to sass/components/Form/dropdown.scss
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sass/components/Form/dropdown.scss
contains styles for the DropdownButton
component.
sass/components/Form/dropdown-group.scss
contains styles for the ButtonGroup
component, which wraps the DropdownButton
component.
<ButtonGroup className="kubevirt-dropdown-group">
<DropdownButton className="kubevirt-dropdown">
{/* stuff */}
</DropdownButton>
</ButtonGroup>
The motivation behind this was to impose style granularity per logical React component.
However, looking at sass/components/Form/form-group.scss
there's some redundancy - notice the width: 100%
rule:
.kubevirt-form-group .dropdown > .dropdown-menu {
width: 100%;
display: none;
z-index: 1001;
}
I'll fix this redundancy by moving the width: 100%
rule into sass/components/Form/dropdown.scss
as suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @vojtechszocs , sounds good to me. Lets remove the redundancy.
@@ -1,7 +1,8 @@ | |||
import React from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import { Button, ButtonGroup, Alert } from 'patternfly-react'; | |||
import EditableDraggableTable from './EditableDraggableTable'; | |||
|
|||
import { default as EditableDraggableTable } from './EditableDraggableTable'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this approach have any benefits or is this just a consistency issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a consistency issue.
@@ -4,10 +4,8 @@ import { Table } from 'patternfly-react'; | |||
// HACK: DragableRow gives this error: | |||
// Stateless function components cannot be given refs. Attempts to access this ref will fail. | |||
// eslint-disable-next-line react/prefer-stateless-function | |||
class InlineEditRow extends React.Component { | |||
export class InlineEditRow extends React.Component { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the preferred approach? using default exports or exports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For our React components, we should use named exports (i.e. not default exports).
That's the convention we started with, so we should stick with it consistently.
$ grep -r 'export default' src/components --include="*.js"
One exception is the EditableDraggableTable
component, which uses a HoC function:
export default DragDropContext(HTML5Backend)(EditableDraggableTable);
and I didn't like having neither _EditableDraggableTable
for the actual component nor redefining EditableDraggableTable
variable (ESLint will warn about that).
So unless it really hurts readability/complexity, I'd always favor named exports in modules representing our React components.
Thanks guys for your review. @rawagner please see my replies and let me know what you think. I'm going to add one more commit to this PR - improve React component file structure validation & bring test coverage of @rawagner also, please see my comment on PR #101 - validations are used in production builds and should deserve to be treated as such. |
TODO(me): still needs a rebase & addressing Rasto's review comment. |
This is probably OT, but could we have an extra build (script) without tests and validations? This would be useful in development when linking components with web-ui. |
+1 i would find this useful too. It would be build step without prebuild. |
@@ -0,0 +1,3 @@ | |||
.kubevirt-create-disk-row__action-buttons { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was .createDiskRow__actionButtons button
previously so the new style should look like .kubevirt-create-disk-row__action-buttons button
or .kubevirt-create-disk-row__action-buttons .btn
(i think the latter is better). I need to target nested buttons inside .kubevirt-create-disk-row__action-buttons
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct, I've missed that.
Since we need to target specific buttons, we can use .kubevirt-create-disk-row__action-button
(singular) class name on <Button>
components, if you agree.
We don't have to declare .kubevirt-create-disk-row__action-buttons
(plural) if we don't need to style the enclosing <div>
(button panel/container).
.kubevirt-create-disk-row__action-buttons button
.kubevirt-create-disk-row__action-buttons .btn
Nested CSS selectors should only be used when we don't have full control over the logical component's parts. In this case, we can simply use .kubevirt-create-disk-row__action-button
, since PF-React's <Button>
allows us to specify CSS class name.
.block tag
selectors should be avoided if possible. CSS rules shouldn't be tied to HTML tags.
.block .nested-part
selectors are possible, but unnecessary in this case.
Agreed, this can be useful. (Right now, you can temporarily change
In this project, we can use a |
- use BEM convention with 'kubevirt' prefix - impose linting rules on import statements - update React component structure validation - update README & add docs
3b4d02a
to
52f90ee
Compare
PR rebased & addressed all review comments. Notable changes:
Also, the Please treat Cosmos fixtures with same care as other code, as they demonstrate real-world usage of the given component and allow UX designers to review the current implementation. |
LGTM. action buttons in create disk row are broken https://github.com/kubevirt/web-ui-components/pull/150/files#r245651699 but lets fix it in a follow up #162 |
Fixes #137 and #2 (with regards to better documentation).
Styles
Adopting the BEM (Block Element Modifier) convention for CSS classes along with the
kubevirt
prefix to avoid potential conflicts with the consuming application.For example, a fictional
FancyForm
component could use the following class names:kubevirt-fancy-form
kubevirt-fancy-form__submit-button
kubevirt-fancy-form__submit-button--disabled
@rawagner Each BEM "fragment" (block, element or modifier) should comply with
[a-z-]+
regexp, using__
and--
to separate the block and modifier. See also this StackOverflow answer for additional context.Using stylelint-selector-bem-pattern / postcss-bem-linter to ensure that all
sass/components/**/*.scss
stylesheets conform with the BEM format.The BEM block (or "component" in
postcss-bem-linter
lingo) is automatically inferred from the file name, e.g. all selectors insass/components/Form/form-group.scss
should start with.kubevirt-form-group
. Different BEM blocks should go into different stylesheets.Q: What about nested CSS selectors like
.kubevirt-form-group .dropdown > .dropdown-menu
?A: These should be OK from BEM point of view. In short, each block represents an independent entity, so nesting CSS selectors under a block shouldn't affect other blocks. That said, try to avoid nested CSS selectors if possible - try to keep things simple.
PF-React overrides are placed in
sass/patternfly-tweaks
directory. These should be treated as temporary until being backported to the corresponding PF-React npm package.Check out "Stylesheet file structure" in
docs/DevGuide.md
for more details.Code
Using the
import/order
ESLint rule in hopes of reducing the chaos in module imports. Anything that isn't project-related should be imported first, followed by a newline and then followed by anything that is project-related:Added dependency on classnames to reduce complexity when computing the space-separated React/JSX
className
prop, for example:Docs
Added a
docs
directory with following content:Updated the
README
file with links to above documents.Dependencies
Bumped the @patternfly/react-console version to pull in the fix for unnecessary peer deps, reducing the amount of warnings upon
yarn install
.Miscellaneous
Removed
HelloWorld
andButtonWithIcon
components after a previous discussion with @rawagner.Checkbox
,Dropdown
,Integer
,Text
andTextArea
components now have theirid
prop marked as required for better end user accessibility (a11y).Updated all component test snapshots to match the newly introduced CSS class names.
Fixed the console error when running tests (related to prop types validation):
Also, when passing React components as props, I'd highly suggest using
PropTypes.element
instead of e.g.PropTypes.func
. (Didn't make this change now to avoid potential breakages.)