Component, layout, demo creation
Naming blocks
Components, layouts, and demos (blocks) should be in individual folders named using Pascal case (AaaBbb). This is the name that will appear in the navigation of the workspace.
Example: Button
, SecondaryNav
Handlebars names
The main handlebars file for a block should be named using kebab case. For example, the secondary navigation would be made up of secondary-nav.hbs
with elements defined in secondary-nav-item.hbs
and secondary-nav-link.hbs
.
Handlebars utilities
Property | Usage | Example |
---|---|---|
uniqueId | Creates a unique id | badge-{{uniqueId}} |
concat | Join multiple strings or variables together | {{concat 'Hello' ' world' '!!!'}} results in Hello world!!! |
contains | Tests to see if a string contains another string | {{#contains alert--modifier 'pf-m-amazingmodifier'}} <span>Text</span> {{else}} <span>Alternate text</span> {{/contains}} |
Documentation
For each example you should provide the relevant accessibility and usage guidance as well as any additional notes that could be helpful. Any information that is not specific to an example should be included at the bottom of the page.
A good example of this approach is the table component.
Modifiers
Modifier parameter
Every block and element should have a parameter allowing for modifier classes and attributes to be passed in. These should be named in kebab case with the block/element name plus --modifier
and --attribute
respectively.
For example:
<!-- Component definition -->
<div class="pf-c-grid{{#if grid--modifier}} {{grid--modifier}}{{/if}}"
{{#if grid--attribute}}
{{{grid--attribute}}}
{{/if}}>
{{> @partial-block}}
</div>
---
<!-- Using the component in handlebars -->
{{#> grid grid--modifier="pf-m-gutter" grid--attribute='id="grid-id" aria-label="Grid usage example"'}}
[content]
{{/grid}}
When including a partial within a partial, by default, handlebars will pass along the parent context to it's children. This would mean the value of any property specified by the parent is also used by the children.
If there is a possibility of a block nested inside another block of the same type and you want to isolate that nested block, add a new context. For example - see how the nested box is defined below with 'newcontext' added as an attribute:
{{#> grid grid--modifier="pf-m-gutter" grid--attribute='id="base-grid" aria-label="Base grid"'}}
{{#> grid-item grid-item--modifier="pf-m-6-col" grid-item--attribute='id="base-grid-item" aria-label="Base grid item"'}}
{{#> grid newcontext}}
{{#> grid-item}}
(nested grid and grid-item will not inherit --modifier or --attribute values)
{{/grid-item}}
{{/grid}}
{{/grid-item}}
{{/grid}}
Common modifier class names
Modifier classes help us to create variations of blocks. Reuse names as much as possible to avoid confusion.
Modifier class name | Outcome |
---|---|
pf-m-gutter | Adds vertical (if applicable) and horizontal gutters to the element |
Pull request guidelines
In order to streamline reviews and set expectations, the following should be expected when submitting a pull request:
All pull requests should have an issue that the work relates to.
A single reviewer should follow the PR through from start to finish after it has been submitted - if somebody else needs to follow it through to completion, please make that transition clear in the PR comments.
As much as possible, comments should be actionable. It should be clear to the contributor exactly what needs to change. If there are open questions that require in-depth conversation, consider meeting or using slack to quickly arrive at an actionable conclusion.
If the main issue has been addressed but there is still work that arises from the PR, please open an issue with the necessary information (and referencing this original PR) to follow up on afterwards.
The reviewer should consider the following as they review: 1) Have all css naming conventions been followed? 2) Have the classes been documented? 3) Are all variables declared locally and referencing global defaults? 4) Have you verified the examples match the design? 5) Does the responsive behavior work correctly? 6) Have the accessibility standards been followed? 7) Is the example resilient - if you put more content in it, do things start to break?
Adding a custom icon
Below are the steps for adding a custom icon to the pficon icons icon font. Adding this icon in core will also add the icon to the react-icons library as an SVG.
- Get the new source SVG from design.
- Edit
src/icons/definitions/pf-icons.json
to add the new icon.- Add a new entry with a unique name (placed in alphabetical order) and the height, width, and path from the source SVG.
- Remove the existing pficons SVGs from
src/icons/PfIcons/
. Any files there are just used to build the icon font. - Run
npm run build:pficons
to create the SVGs (stored insrc/icons/PfIcons/
) frompf-icons.json
that will be used to build the icon font. - Run
npm run build:pficonfont
to build the icon font files (stored insrc/patternfly/assets/pficon/
) from the SVGs insrc/icons/PfIcons/
. - Edit
src/patternfly/assets/pficon/pficon.scss
and prefix thesrc: url()
paths for the icon font files with the global icon font path (e.g.,url('#{$pf-global--fonticon-path}/pficon.woff2')
). - Run
./scripts/iconList.sh
to updatesrc/site/pages/icons.md
, which serves the pficon icon preview page on the dev server served at/icons
. - Restart the dev server and verify the icons look correct on
/icons
.- Note: This step may require clearing your cache.
View source on GitHub