Skip to content

Commit

Permalink
Implement prop-attr sync for Dialog & Quote component
Browse files Browse the repository at this point in the history
  • Loading branch information
nizniz187 committed Sep 19, 2021
1 parent b86833d commit 7417149
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 30 deletions.
8 changes: 5 additions & 3 deletions wc/WComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ class WComponent extends HTMLElement{
this.attachShadow({ mode: 'open' });
this.setStylesheet(this.stylesheet);
this.init();
//this.tabIndex = '0'; // Make component focusable
this.key = new Date().getTime() + Math.random();
}
/**
* Call update method in attribute changed callback if attribute name is acceptable
*/
attributeChangedCallback(name, oldValue, newValue){
if(typeof this.constructor.attributes[name] === 'object'){
if(this.hasDefinedAttribute(name)){
this.update({name, oldValue, newValue});
}
}
Expand Down Expand Up @@ -72,12 +71,15 @@ class WComponent extends HTMLElement{
}
return this.constructor.attributes[name].parser;
}
getDefaultValueByName(name) {
getDefaultAttributeValueByName(name) {
if(typeof name !== 'string') {
return undefined;
}
return this.constructor.attributes[name].defaultValue;
}
hasDefinedAttribute(name) {
return typeof name === 'string' && typeof this.constructor.attributes[name] === 'object';
}
setStylesheet(stylesheet, id){ // id is optional, for style overwrite
if(id){
const styleElement=this.shadowRoot.querySelector("#"+id);
Expand Down
24 changes: 17 additions & 7 deletions wc/components/Dialog.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WComponent, { DOM } from "../WComponent.js";
import WComponent, { DOM, AttributeParser } from "../WComponent.js";
const stylesheet=`
.dialog{
width:300px;
Expand All @@ -13,9 +13,19 @@ const stylesheet=`
}
`;
class Dialog extends WComponent{
static get observedAttributes(){
return ["open"];

static attributes = {
open: {
name: 'open', defaultValue: false,
parser: (value, attr) => AttributeParser.parseBoolAttr(
value, attr.defaultValue
)
}
};
static get observedAttributes() {
return this.getObservedAttributes(this.attributes);
}

constructor(){
super();
}
Expand All @@ -24,10 +34,10 @@ class Dialog extends WComponent{
this.head=DOM.create("slot", {props:{name:"head"}}, this.dialog);
this.main=DOM.create("slot", {props:{name:"main"}}, this.dialog);
}
connectedCallback(){}
attributeChangedCallback(name, oldValue, newValue){
if(name==="open"){
if(newValue==="true"){
update({ name, newValue }){
const attr = this.constructor.attributes.open;
if(name === attr.name){
if(attr.parser(newValue, attr.defaultValue)){
this.shadowRoot.appendChild(this.dialog);
}else{
this.dialog.remove();
Expand Down
37 changes: 17 additions & 20 deletions wc/components/Quote.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import WComponent, { DOM } from "../WComponent.js";
import WComponent, { DOM, AttributeParser } from "../WComponent.js";

const stylesheet = `
.left { text-align: left; }
.center { text-align: center; }
Expand All @@ -12,33 +13,29 @@ const stylesheet = `
content: '— '
}
`;

class Quote extends WComponent{
constructor(){
super();
}
static defaultValues = {
align: 'left'

static attributes = {
align: {
name: 'align', defaultValue: 'left',
parser: (value, attr) => AttributeParser.parseStringAttr(
value, attr.defaultValue, /^left$|^center$|^right$/
)
}
};

getDefaultValueByName(name) {
return this.constructor.defaultValues[name];
static get observedAttributes() {
return this.getObservedAttributes(this.attributes);
}
/**
* Parse align attribute to a valid value
* @param {string} align
* @returns {string} Alignment class name
*/
parseAlign(align = this.getAttribute('align')) {
if(align == 'left' || align == 'center' || align == 'right') {
return align;
}
return this.getDefaultValueByName('align');

constructor(){
super();
}

init() {
DOM.create('style', { props: { textContent: stylesheet } }, this.shadowRoot);

const container = DOM.create('div', { props: { className: this.parseAlign() } }, this.shadowRoot);
const container = DOM.create('div', { props: { className: this.align } }, this.shadowRoot);

const quoteContainer = DOM.create('div', {}, container);
DOM.create('slot', { props: { name: 'quote' } }, quoteContainer);
Expand Down

0 comments on commit 7417149

Please sign in to comment.