@@ -16,6 +16,11 @@ Your Sass file will initially import additional Sass from the pfe-sass node modu
1616
1717```
1818@import "../../pfe-sass/pfe-sass";
19+
20+ $LOCAL: cool-element;
21+
22+ $LOCAL-VARIABLES: ();
23+
1924:host {
2025 display: block;
2126}
@@ -25,37 +30,126 @@ Your Sass file will initially import additional Sass from the pfe-sass node modu
2530}
2631```
2732
33+ When structuring your Sass, a good rule of thumb for organization is:
34+
35+ ```
36+ // Define your hooks and their default values at the top of the file
37+ $LOCAL-VARIABLES: (
38+ Property: default-value,
39+ region: (
40+ Property: default-value
41+ )
42+ );
43+
44+ :host {
45+ // Apply the hooks to the appropriate properties
46+ property: pfe-local(Property);
47+ }
48+
49+ // Modifiers should update local variables
50+ // this will override any variables set externally
51+ // attributes are always stronger than variable overrides
52+ :host([modifiers]) {
53+ $modifier: ( Property: updated-value );
54+ @include pfe-print-local($modifier); // outputs: --pfe-cool-element--Property: updated-value;
55+ }
56+
57+ // Light DOM styles
58+ ::slotted(*) {
59+ > typography defaults
60+ }
61+
62+ // Class-based shadow DOM styles
63+ .pfe-cool-element {
64+ &__region {
65+ // Apply the hooks to the appropriate properties in their regions too
66+ property: pfe-local(Property, $region: region);
67+
68+ // 1. default styles
69+ // 2. media queries
70+
71+ &[modifiers] {
72+ --pfe-cool-element__region--Property: updated;
73+ }
74+ }
75+ // Modifiers can also be set using classes and scoped to the Shadow DOM
76+ &--modifier {
77+ --pfe-cool-element--Property: updated;
78+ }
79+ }
80+ ```
81+
2882Now we can update our styles, like so:
2983
3084```
3185@import "../../pfe-sass/pfe-sass";
86+
87+ $LOCAL: cool-element;
88+
89+ $LOCAL-VARIABLES: (
90+ Width: 128px,
91+ Padding: calc(#{pfe-var(container-spacer)} * 2),
92+ profile: (
93+ BackgroundColor: pfe-var(surface--base),
94+ theme: pfe-var(surface--base--theme),
95+ Border: 2px solid #333
96+ )
97+ );
98+
3299:host {
100+ // Hardcoded, not connected to theme
33101 display: flex;
34102 flex-direction: column;
35103 align-items: center;
36104 justify-content: center;
37- width: 128px;
38- padding: 32px;
39- font-family: Arial;
40- box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),
41- 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
105+
106+ // Local variable hooks
107+ width: pfe-local(Width);
108+ padding: pfe-local(Padding);
109+
110+ // Global theme variable hooks only
111+ font-family: pfe-var(font-family);
112+ box-shadow: pfe-var(box-shadow--sm);
42113}
43114
44115:host([hidden]) {
45116 display: none;
46117}
47118
48- #profile-pic {
49- width: 50px;
50- height: 50px;
51- margin-bottom: 16px;
52- border: 2px solid #333;
53- border-radius: 50%;
54- background-color: #efefef;
55- }
56-
57- button {
58- margin-top: 16px;
119+ .pfe-cool-element {
120+ &__profile {
121+ background-color: pfe-local(BackgroundColor, $region: profile);
122+ // Any time background color is updated, theme should be set too
123+ // This sets the `on=` attribute on the component
124+ --theme: #{pfe-local(theme, $region: profile)};
125+
126+ // Invoke the broadcasted default typography styles
127+ @include pfe-theme-contexts;
128+
129+ // The above mixins outputs:
130+ // :host([on="dark"]) {
131+ // --pfe-broadcasted--text: var(--pfe-theme--color--text--on-dark, #fff);
132+ // --pfe-broadcasted--link: var(--pfe-theme--color--link--on-dark, #99ccff);
133+ // --pfe-broadcasted--link--hover: var(--pfe-theme--color--link--hover--on-dark, #cce6ff);
134+ // --pfe-broadcasted--link--focus: var(--pfe-theme--color--link--focus--on-dark, #cce6ff);
135+ // --pfe-broadcasted--link--visited: var(--pfe-theme--color--link--visited--on-dark, #b38cd9);
136+ // --pfe-broadcasted--link-decoration: none;
137+ // --pfe-broadcasted--link-decoration--hover: underline;
138+ // --pfe-broadcasted--link-decoration--focus: underline;
139+ // --pfe-broadcasted--link-decoration--visited: none;
140+ // }
141+
142+ border: pfe-local(Border, $region: profile);
143+ border-radius: pfe-var(surface--border-radius);
144+
145+ // Hardcoded values
146+ width: 50px;
147+ height: 50px;
148+ margin-bottom: 16px;
149+ }
150+ &__social--follow {
151+ margin-top: 16px;
152+ }
59153}
60154```
61155
@@ -75,33 +169,13 @@ import PFElement from '../pfelement/dist/pfelement.js';
75169
76170class PfeCoolElement extends PFElement {
77171 get html() {
78- return `<style>:host {
79- display: flex;
80- flex-direction: column;
81- align-items: center;
82- justify-content: center;
83- width: 128px;
84- padding: 32px;
85- font-family: Arial;
86- box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); }
87-
88- :host([hidden]) {
89- display: none; }
90-
91- #profile-pic {
92- width: 50px;
93- height: 50px;
94- margin-bottom: 16px;
95- border: 2px solid #333;
96- border-radius: 50%;
97- background-color: #efefef; }
98-
99- button {
100- margin-top: 16px; }</style>
101- <div id="profile-pic"></div>
172+ return `<style>:host{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:128px;width:var(--pfe-cool-element--Width,128px);padding:calc(16px * 2);padding:var(--pfe-cool-element--Padding,calc(var(--pfe-theme--container-spacer,16px) * 2));font-family:Overpass,Overpass,Helvetica,helvetica,arial,sans-serif;font-family:var(--pfe-theme--font-family, "Overpass", Overpass, Helvetica, helvetica, arial, sans-serif);-webkit-box-shadow:0 .0625rem .125rem 0 rgba(19,19,19,.2);box-shadow:0 .0625rem .125rem 0 rgba(19,19,19,.2);-webkit-box-shadow:var(--pfe-theme--box-shadow--sm,0 .0625rem .125rem 0 rgba(19,19,19,.2));box-shadow:var(--pfe-theme--box-shadow--sm,0 .0625rem .125rem 0 rgba(19,19,19,.2))}:host([hidden]){display:none}.pfe-cool-element__profile{background-color:#dfdfdf;background-color:var(--pfe-cool-element__profile--BackgroundColor,var(--pfe-theme--surface--base,#dfdfdf));--theme:var(--pfe-cool-element__profile--theme,var(--pfe-theme--surface-base--theme,light));border:2px solid #333;border:var(--pfe-cool-element__profile--Border,2px solid #333);border-radius:3px;border-radius:var(--pfe-theme--surface--border-radius,3px);width:50px;height:50px;margin-bottom:16px}.pfe-cool-element__profile :host([on=dark]){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-dark, #fff);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-dark, #99ccff);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-dark, #cce6ff);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-dark, #cce6ff);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-dark, #b38cd9);--pfe-broadcasted--link-decoration:none;--pfe-broadcasted--link-decoration--hover:underline;--pfe-broadcasted--link-decoration--focus:underline;--pfe-broadcasted--link-decoration--visited:none}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){.pfe-cool-element__profile :host{color:#333!important;color:var(--pfe-theme--text,#333)!important}}.pfe-cool-element__profile :host([on=saturated]){--pfe-broadcasted--text:var(--pfe-theme--color--text--on-saturated, #fff);--pfe-broadcasted--link:var(--pfe-theme--color--link--on-saturated, #fff);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover--on-saturated, white);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus--on-saturated, white);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited--on-saturated, #b38cd9);--pfe-broadcasted--link-decoration:underline;--pfe-broadcasted--link-decoration--hover:underline;--pfe-broadcasted--link-decoration--focus:underline;--pfe-broadcasted--link-decoration--visited:underline}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){.pfe-cool-element__profile :host{color:#333!important;color:var(--pfe-theme--text,#333)!important}}.pfe-cool-element__profile :host([on=light]){--pfe-broadcasted--text:var(--pfe-theme--color--text, #333);--pfe-broadcasted--link:var(--pfe-theme--color--link, #06c);--pfe-broadcasted--link--hover:var(--pfe-theme--color--link--hover, #003366);--pfe-broadcasted--link--focus:var(--pfe-theme--color--link--focus, #003366);--pfe-broadcasted--link--visited:var(--pfe-theme--color--link--visited, rebeccapurple);--pfe-broadcasted--link-decoration:none;--pfe-broadcasted--link-decoration--hover:underline;--pfe-broadcasted--link-decoration--focus:underline;--pfe-broadcasted--link-decoration--visited:none}@media screen and (-ms-high-contrast:active),screen and (-ms-high-contrast:none){.pfe-cool-element__profile :host{color:#333!important;color:var(--pfe-theme--text,#333)!important}}.pfe-cool-element__social--follow{margin-top:16px}
173+ /*# sourceMappingURL=pfe-card.min.css.map */
174+ </style>
175+ <div class="pfe-cool-element__profile" id="profile-pic"></div>
102176<slot></slot>
103- <div>
104- <button>Follow</button>
177+ <div class="pfe-cool-element__social" >
178+ <button class="pfe-cool-element__social--follow" >Follow</button>
105179</div>`;
106180 }
107181
@@ -127,7 +201,7 @@ PFElement.create(PfeCoolElement);
127201export default PfeCoolElement;
128202```
129203
130- You'll notice ` <style> ` contains everything we just wrote in our Sass file. Sass variables will also compiled their values and get included in the changes above .
204+ You'll notice ` <style> ` contains everything we just wrote in our Sass file. Sass variables and functions will resolve into vanilla CSS before being injected into the web component. An autoprefixer and minifier will also be run on your styles before being injected so you don't need to worry about vendor prefixing when writing styles .
131205
132206Now that our ` pfe-cool-element ` is more appealing, we'll add the follow button's interaction and fill in the profile photo. We can accomplish both of these tasks by updating the ` /src/pfe-cool-element.js ` file.
133207
0 commit comments