Skip to content

Commit 242078e

Browse files
castastrophekylebuch8
authored andcommitted
Band container <pfe-band> (#254)
* Add dynamic doc listing * Remove index file from git project * Initialize band layout * Add updates to theme for band layout support * Revert changes from doc listing update branch * Revert doc changes from dynamic listing branch * Updating and tidying up structure for band layout * Update documentation for new sass functions * Updating values and fixing attribute push * JS tidy and rhelement cleanup * Remove deprecated functions * Tidy up styles for the band layout * Updating syntax to support aside positioning * Clean up the storybook template * Clean up storybook template * Update band logic to fix error * Update band layout; fix discrepency in aside alignment * US162827-band-layout-CSS-fork Added in cp-theme, added some helper text to the demo file to show what layouts are being applied; Adjusted CSS relating to padding and width for the band wrapper, container, & aside regions * Got the local function working, update band demo file to include more examples, update band sass to accommodate for css var overrides + flexbox * origin/US162827-band-layout-CSS-fork put back order of band demos; comment out cp theme suggestions - needs discussion * origin/US162827-band-layout-CSS-fork adjust padding variable naming convention to match BEM * origin/US162827-band-layout-CSS-fork adjust values of default widths on aside regions, comment out override examples * origin/US162827-band-layout-CSS-fork put back paragraph styles into CP theme * origin/US162827-band-layout-CSS-fork remove commented out code from CP theme * Update cp-theme.scss clean up spaces * Rename rh-band to pfe-band * Fussing with adding schema and building dynamic storybook * Commit updated compiled assets * Add dynamic schema rendering * Clean up storybook implementation for previewing * Add tooling for storybook to auto-generate components and content; dynamically pull in schema * Update compile task to work if schema is present or not; update pfe-card to set container type and update ctas too; fix style issues in pfe-band * Fix prefixing issue * Recompile and update variable name to pfe- * Fix issue with storybook not rendering aside * Fallbacks for Grid * Commit current test state * adding pfe-band header to demo page * Remove unnecessary file edits from this PR * Update tests for pfe-band * Add a todo for aside tests * Update readme * Update logic and fix layout but in pfe-band * Compile and add polyfills * Add a README update to clarify slot names * Remove inline comments for unused code * Fix issue with storybook instance * Reduce complexity in the band styles; simplify and bring together grid styles * Compile after merging in master * Fix band layout!!! * Update rendering for storybook * Update storybook to honor input fields for content * Revert files that were edited by IDE * Add context setting on card layout as well * Updating functionality for json schema implementation * Update pfelement to clean up the commented out code; beautify run on pfe-band.story.js * Update BEM naming in band styles; update the demo page for band; add the context update to card; added a fill-height helper class for layouts to allow a flex-grow approach with grid too; updated the pfe-local function to accept fallbacks * Push up BEM updates; getting IE to work with demo page * Commit UMD compiled assets * Add this.props abstraction for properties in pfelement; update demo page with better comments * Add variables for horizontal and vertical gutters * Add viewport in demo template * Updated demo listing page * Update pfe-band test for new slot names * Documentation updates requested in code review * updating the readme * Pull out files that are unrelated; note that we need to open a PR to run the build on all assets in the repo to prevent this in future * Update prerelease versions * Update test defaults for weird CI failure * Comment out tests that depend on viewport width
1 parent 3004b8d commit 242078e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2770
-134
lines changed

.storybook/utils.js

Lines changed: 102 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,121 @@ String.prototype.sentenceCase = function() {
1919
};
2020

2121
// Print attributes based on an object
22-
const listProperties = obj =>
22+
const listProperties = (obj, prefix = "") =>
2323
Object.entries(obj)
2424
.map(set => {
2525
let p = set[0];
2626
let v = set[1];
2727
let print = set[2] || true;
28-
return print && v && v !== "null" ? ` ${p}="${v}"` : "";
28+
return print && v && v !== "null" ? ` ${p !== "slot" ? `${prefix ? `${prefix}-` : ""}` : ""}${p}="${v}"` : "";
2929
})
3030
.join("");
3131

3232
// Create a tag based on a provided object
33-
export function customTag(obj) {
34-
return `<${obj.tag ? obj.tag : "div"} ${
35-
obj.slot ? `slot="${obj.slot}"` : ""
36-
}${listProperties(obj.attributes || {})}>${obj.content || autoContent()}</${
37-
obj.tag ? obj.tag : "div"
38-
}>`;
33+
// Accepts an object that can contain (all optional):
34+
// -- tag: html tag such as h1 or p, default is div
35+
// -- slot: rendered as slot="<input>"
36+
// -- attributes: passed through the listProperties function
37+
// -- content: Accepts html or plain text or renders default content
38+
export function customTag(obj, prefix = "") {
39+
let start = "";
40+
let end = "";
41+
// If a tag is defined, or it has slots or attributes to apply
42+
// render an open and close tag
43+
if (obj.tag || obj.slot || obj.attributes) {
44+
start += "<";
45+
end += "</";
46+
// If a tag is defined, use that, else use a div
47+
if (obj.tag) {
48+
start += obj.tag;
49+
end += obj.tag;
50+
} else {
51+
start += "div";
52+
end += "div";
53+
}
54+
start += obj.slot ? ` slot="${obj.slot}"` : "";
55+
start += obj.attributes ? listProperties(obj.attributes || {}, prefix) : "";
56+
start += ">";
57+
end += ">";
58+
}
59+
return `${start}${obj.content || autoContent()}${end}`;
3960
}
4061

62+
const parseMarkup = string => {
63+
// Define the regex for use below
64+
let find = /<(\w+[-\w]*)(.*?)>/;
65+
let quotes = /['\"]+/g;
66+
// Initialize the empty return object
67+
let obj = {};
68+
// Initialize the attributes object
69+
obj.attributes = {};
70+
// Capture the tag name and properties
71+
let result = string.match(find);
72+
// If results remain in the array, get the tag
73+
if (result !== null && result.length > 0 && typeof result[1] === "string") {
74+
obj.tag = result[1];
75+
// If results remain in the array, get the attributes
76+
if (result.length > 1 && typeof result[2] === "string") {
77+
// Break the attributes apart using the spaces
78+
let attr = result[2].trim().split(" ");
79+
// If any attributes exist, break them down further
80+
if (attr.length > 0) {
81+
attr.forEach(set => {
82+
// Break the attributes apart using the equal sign
83+
let items = set.trim().split("=");
84+
// If items are returned and they are both strings, add them to the attributes object
85+
if (items.length > 1 && typeof items[0] === "string" && typeof items[1] === "string") {
86+
obj.attributes[items[0].trim()] = items[1].replace(quotes, "").trim();
87+
}
88+
});
89+
}
90+
}
91+
// Strip the original string of the wrapper element
92+
obj.content = string.replace(new RegExp(`<\/?${obj.tag}.*?>`, "g"), "");
93+
} else {
94+
obj.tag = "div";
95+
obj.content = string;
96+
}
97+
// Return the new object with the metadata
98+
return obj;
99+
};
100+
41101
// If a slot is a component or content, render that raw
42102
// if it's got a tag defined, run the custom tag function
43103
const renderSlots = (slots = []) =>
44-
slots.map(slot => (slot.content ? slot.content : "")).join("");
104+
slots
105+
.map(slot => {
106+
// If there are slot or attribute values but no tag defined
107+
// Grep the content to see if we can use the first tag passed in
108+
let has_tag = typeof slot.tag !== "undefined";
109+
let has_slot = typeof slot.slot !== "undefined" && slot.slot.length > 0;
110+
let has_attr = typeof slot.attributes !== "undefined" && Object.keys(slot.attributes).length > 0;
111+
if (!has_tag && (has_slot || has_attr)) {
112+
Object.assign(slot, parseMarkup(slot.content));
113+
}
114+
return slot.content
115+
? customTag({
116+
tag: slot.tag,
117+
slot: slot.slot,
118+
attributes: slot.attributes,
119+
content: slot.content
120+
})
121+
: "";
122+
})
123+
.join("");
45124

46125
// Creates a component dynamically based on inputs
47-
export function component(tag, attributes = {}, slots = []) {
48-
return `<${tag}${listProperties(attributes)}>${
49-
slots.length > 0 ? renderSlots(slots) : autoContent()
50-
}</${tag}>`;
126+
export function component(tag, attributes = {}, slots = [], prefix = "") {
127+
return `<${tag}${listProperties(attributes, prefix)}>${slots.length > 0 ? renderSlots(slots) : autoContent()}</${tag}>`;
51128
}
52129

53130
// Create an automatic heading
54131
export function autoHeading(short = false) {
55132
let length = short ? Math.random() + 2 : Math.random() * 10 + 5;
56-
return loremIpsum({ count: length, units: "words" }).sentenceCase();
133+
return loremIpsum({
134+
count: length,
135+
units: "words"
136+
}).sentenceCase();
57137
}
58138

59139
// Create a set of automatic content
@@ -121,43 +201,11 @@ export function autoContentKnobs(slots, bridge) {
121201
}
122202

123203
export function demo(markup) {
124-
// Prettify and clean the markup for rendering
125-
cleaner.clean(
126-
markup,
127-
{
128-
indent: " ",
129-
"remove-attributes": [],
130-
"break-around-tags": [
131-
"body",
132-
"blockquote",
133-
"br",
134-
"div",
135-
"h1",
136-
"h2",
137-
"h3",
138-
"h4",
139-
"h5",
140-
"h6",
141-
"head",
142-
"hr",
143-
"link",
144-
"meta",
145-
"p",
146-
"table",
147-
"title",
148-
"td",
149-
"tr",
150-
"a"
151-
],
152-
wrap: 0
153-
},
154-
html => (markup = html)
155-
);
156-
157204
// Return the rendered markup and the code snippet output
158205
return `${markup}`;
159206
}
160207

208+
// prettier-ignore-start
161209
export function code(markup) {
162210
// Prettify and clean the markup for rendering
163211
cleaner.clean(
@@ -185,18 +233,21 @@ export function code(markup) {
185233
"title",
186234
"td",
187235
"tr",
188-
"a"
236+
"a",
237+
"section",
238+
"article",
239+
"footer",
240+
"aside"
189241
],
190242
wrap: 0
191243
},
192244
html => (markup = html)
193245
);
194246

195247
// Return the rendered markup and the code snippet output
196-
return `<pre style="white-space: pre-wrap; padding: 20px 50px; background-color: #f0f0f0; font-weight: bold; border: 1px solid #bccc;">${escapeHTML(
197-
markup
198-
)}</pre>`;
248+
return `<pre style="white-space: pre-wrap; padding: 20px 50px; background-color: #f0f0f0; font-weight: bold; border: 1px solid #bccc;">${escapeHTML(markup)}</pre>`;
199249
}
250+
// prettier-ignore-end
200251

201252
export function preview(markup) {
202253
return demo(markup) + code(markup);

doc/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ <h1>Demos</h1>
1212
<ul id="demos">
1313
<li><a href="../elements/pfe-accordion/demo">pfe-accordion</a></li>
1414
<li><a href="../elements/pfe-autocomplete/demo">pfe-autocomplete</a></li>
15+
<li><a href="../elements/pfe-band/demo">pfe-band</a></li>
1516
<li><a href="../elements/pfe-card/demo">pfe-card</a></li>
1617
<li><a href="../elements/pfe-content-set/demo">pfe-content-set</a></li>
1718
<li><a href="../elements/pfe-cta/demo">pfe-cta</a></li>

elements/pfe-band/.babelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"presets": [["env", { "modules": false }]],
3+
"plugins": ["external-helpers"]
4+
}

elements/pfe-band/.editorconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# EditorConfig: http://EditorConfig.org
2+
3+
# Top-most EditorConfig file
4+
root = true
5+
6+
# Rules for JavaScript files:
7+
8+
[*.{js,py,json,sh,html}]
9+
# 4 space indentation
10+
indent_style = space
11+
indent_size = 2
12+
# No trailing spaces
13+
trim_trailing_whitespace = true
14+
# Unix-style newlines
15+
end_of_line = lf
16+
# Newline ending every file
17+
insert_final_newline = true

elements/pfe-band/.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

elements/pfe-band/.travis.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
language: node_js
2+
dist: trusty
3+
sudo: required
4+
addons:
5+
firefox: "latest"
6+
apt:
7+
sources:
8+
- google-chrome
9+
packages:
10+
- google-chrome-stable
11+
node_js: stable
12+
before_install:
13+
- npm install -g web-component-tester
14+
install:
15+
- npm install
16+
before_script:
17+
script:
18+
- xvfb-run npm run test

elements/pfe-band/LICENSE.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright 2018 Red Hat, Inc.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

elements/pfe-band/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# PatternFly Element | Band container
2+
3+
This container element provides a set of slots in which to render banded content.
4+
5+
## Slots
6+
7+
All slots other than `pfe-band--body` are optional. If the slot is not defined, the container tag for it will not be rendered in the template.
8+
9+
- `pfe-band--header`: This slot renders at the top of the container and generally contains the title, headline, and or subheadline content. Other possible candidates include a set of social sharing links or tags that describe the content below. The recommended tag for this slot is the `header` tag with h-level or p tags contained within it.
10+
- **Default slot**: This is the default slot and contains the bulk of the content in this element. Paragraph text or a grid of cards or images might be rendered in this region. Recommended tag for this slot is the `article` tag. Any content not assigned to a slot will be rendered here.
11+
- `pfe-band--footer`: This slot is typically used for calls-to-action or footnotes and is pushed to the bottom of the container. Recommended tags include `pfe-cta` or `footer`.
12+
- `pfe-band--aside`: This slot is for content that should be rendered to the right or left of the default slot on desktop. Asides often contain `pfe-card` or interest forms which provide users a little more information or context for the band.
13+
14+
## Attributes
15+
16+
<style>
17+
.color-preview {
18+
display: inline-block;
19+
width: 1em;
20+
height: 1em;
21+
vertical-align: middle;
22+
background-color: var(--bg, #ffffff);
23+
border: 1px solid #444444;
24+
}
25+
</style>
26+
27+
There are several attributes available for customizing the visual treatment of this container.
28+
29+
- `pfe-color`: Options include darkest, darker, accent, complement, lighter, lightest. The band has a default value of `#dfdfdf`. Your theme will influence these colors so check there first if you are seeing inconsistencies.
30+
31+
| color | hex |
32+
|-------|-----|
33+
| default | <span class="color-preview" style="--bg:#dfdfdf"></span> #dfdfdf |
34+
| darker | <span class="color-preview" style="--bg:#464646"></span> #464646 |
35+
| darkest | <span class="color-preview" style="--bg:#131313"></span> #131313 |
36+
| accent | <span class="color-preview" style="--bg:#fe460d"></span> #fe460d |
37+
| complement | <span class="color-preview" style="--bg:#0477a4"></span> #0477a4 |
38+
| lighter | <span class="color-preview" style="--bg:#ececec"></span> #ececec |
39+
| lightest | <span class="color-preview" style="--bg:#ffffff"></span> #ffffff |
40+
41+
- `pfe-img-src`: Optional background image applied to the entire band container. Alignment of this image can be managed using the `--pfe-band--BackgroundPosition` variable which is set to `center center` by default.
42+
- `pfe-size`: Optionally adjusts the padding on the container. Accepts: `small`.
43+
44+
### Aside settings
45+
The aside settings have defaults and if no attribute is defined on the element's main tag, these attributes will be injected with their default values automatically.
46+
47+
- `pfe-aside-desktop`: This influences where the aside is rendered at the desktop view and are indicated relative to the body content. Options are `right` or `left`. **Right is the default.**
48+
- `pfe-aside-mobile`: This influences the position of the aside in the mobile view as well as where in the DOM the aside markup is rendered. These names are relative to the body content. Options are `top` or `bottom`. **Bottom is the default.**
49+
- `pfe-aside-height`: This influences the height of the aside region relative to the body content. Options are `full` or `body`. A `full` height starts at the top of the band and spans the header, body, and footer regions. A `body` height spans the body and footer regions only with the header region sitting above it in the rendered view. **Body is the default.**
50+
51+
## Variables
52+
There are several powerful variables available to hook into and override default styles.
53+
54+
- Verical and horizontal padding: `--pfe-band--Padding--vertical` and `--pfe-band--Padding--horizontal` accept size values such as px, em, rem, etc.
55+
- Background color: Though using the `pfe-color` attribute is strongly recommended when setting the background color for the band, you can also use completely custom colors by updating the `--pfe-band--BackgroundColor` variable. If you update this value manually, you should also update the `--pfe-broadcasted--color--text`, `--pfe-broadcasted--color--ui-link`[--visited, --hover, --focus] at the same time so that the text and links rendered on this background color show up correctly.
56+
- Background position: This is designed for use with the `pfe-img-src` attribute to allow you to align your background image. Default value is `center center`.
57+
- Border: This allows the customization of a border around the entire container and is primarily designed to be used to add a top and/or bottom border line. This variable accepts the entire border shorthand and is set to transparent by default.
58+
- Layout: The band has a rudimentary layout system designed to be used inside the slot regions for the header, body, footer, and aside. It uses the CSS grid spec and creates a stacked layout by default. By updating these values, you will be able to create simple grid layouts. Please note that these do not include fallbacks for older browsers. Possible values include: `1fr 1fr`, `repeat(3, 1fr)`, `repeat(auto-fill, minmax(300px, 1fr))`
59+
* `--pfe-band--layout`: Applied to `.pfe-band__container`.
60+
* `--pfe-band_header--layout`: Applied to `.pfe-band__header`.
61+
* `--pfe-band_body--layout`: Applied to `.pfe-band__body`.
62+
* `--pfe-band_footer--layout`: Applied to `.pfe-band__footer`.
63+
* `--pfe-band_aside--layout`: Applied to `.pfe-band__aside`.
64+
65+
## Test
66+
67+
npm run test
68+
69+
## Build
70+
71+
npm run build
72+
73+
## Demo
74+
75+
From the PFElements root directory, run:
76+
77+
npm start
78+
79+
## Code style
80+
81+
Band (and all PatternFly Elements) use [Prettier][prettier] to auto-format JS and JSON. The style rules get applied when you commit a change. If you choose to, you can [integrate your editor][prettier-ed] with Prettier to have the style rules applied on every save.
82+
83+
[prettier]: https://github.com/prettier/prettier/
84+
[prettier-ed]: https://github.com/prettier/prettier/#editor-integration
85+
[web-component-tester]: https://github.com/Polymer/web-component-tester

0 commit comments

Comments
 (0)