Skip to content

Commit

Permalink
fixed issue with utilities which have parent
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinmcfarland committed Jul 15, 2019
1 parent 0dc54f5 commit 5edafb4
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 139 deletions.
2 changes: 1 addition & 1 deletion .tape.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
'custom-properties': {
message: 'supports basic custom properties'
},
'complex': {
complex: {
message: 'supports flattened classes and custom properties'
}
};
19 changes: 13 additions & 6 deletions src/custom-properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,30 @@ export default function(node) {

// Extract values required for style attr
_.each(classNames, function(className) {
if (className.match(REGEX)) {
let propName = className.match(REGEX)[1];
if (className.match(re.decl)) {
let propName = className.match(re.decl)[1];
let newClassName = propName;

propValue = className.match(REGEX)[2];
propValue = className.match(re.decl)[2];

styleValues.push({ [propName]: propValue });

// TODO: check for duplicate props as well because only needs one in output

if (newClassNames.includes(newClassName) === false)
if (newClassNames.includes(newClassName) === false) {
// console.log(className + ' --- a utility');
newClassNames.push(newClassName);
}
} else {
// console.log(className + ' --- not a utility');
newClassNames.push(className);
}
});

// Add new class names to element
node.attrs.add({ class: newClassNames.join(' ') });
// node.attrs.add({ class: newClassNames.join(' ') });

// Add new styles to element
_.each(styleValues, function(item) {
_.each(item, function(value, key) {
newProps.push(`--${key}: ${value}`);
Expand All @@ -66,11 +71,13 @@ export default function(node) {
'^(' + re.property.source + ')' + '(t|l|b|r)' + '$',
'gmi'
);

// TODO: Look for a more robust way to check for exact match ^

if (item.match(exact)) {
if (newerClassNames.includes(item.match(re.property)[0]) === false)
newerClassNames.push(item.match(re.property)[0]);
console.log(item.match(re.property)[0]);
newerClassNames.push(item.match(re.property)[0]);
} else {
newerClassNames.push(item);
}
Expand Down
14 changes: 6 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import phtml from 'phtml'
import _ from 'lodash'
import phtml from 'phtml';
import _ from 'lodash';

import flattenClasses from './flatten-classes.js'
import customProperties from './custom-properties.js'
import flattenClasses from './flatten-classes.js';
import customProperties from './custom-properties.js';

export default new phtml.Plugin('phtml-phthml-shorthand-utility', opts => {
console.log({ opts });

return {
Element (node) {

Element(node) {
flattenClasses(node);
customProperties(node);

// customProperties(node);
}
};
});
231 changes: 136 additions & 95 deletions src/props/margin.js
Original file line number Diff line number Diff line change
@@ -1,123 +1,164 @@
import _ from 'lodash';
import re from '../util/generate-regex.js';

// export default function(node) {
// const side = {
// top: { _abbr: 't' },
// right: { _abbr: 'r' },
// bottom: { _abbr: 'b' },
// left: { _abbr: 'l' }
// };

// const props = {
// margin: {
// ...(() => {
// return side;
// })(),
// _abbr: 'm'
// },
// padding: {
// ...(() => {
// return side;
// })(),
// _abbr: 'p'
// }
// };

// console.log(props);

// const hasClass = node.attrs.get('class');

// const classNames = node.attrs.get('class').split(' ');
// const newClassNames = [];

// if (hasClass) {
// _.each(classNames, function(className) {
// if (className.match(re.decl)) {
// className.replace(re.decl, function(decl, name, args) {
// if (name === props.margin._abbr || name === props.padding._abbr) {
// console.log(name);
// let values = [];
// let sides = ['t', 'r', 'b', 'l'];

// args.replace(re.arg, function(arg) {
// values.push(arg);
// });

// if (values.length === 1) {
// values.push(values[0]);
// }
// if (values.length === 2) {
// values.push(values[0]);
// }
// if (values.length === 3) {
// values.push(values[1]);
// }

// _.each(sides, function(side, index) {
// newClassNames.push(`${name}${side}-${values[index]}`);
// });
// }
// });
// } else {
// newClassNames.push(className);
// }
// });

// node.attrs.add({ class: newClassNames.join(' ') });
// }
// }
const side = {
top: { _abbr: 't' },
right: { _abbr: 'r' },
bottom: { _abbr: 'b' },
left: { _abbr: 'l' }
};

const props = {
margin: {
...(() => {
return side;
})(),
_abbr: 'm'
},
padding: {
...(() => {
return side;
})(),
_abbr: 'p'
}
};

var abbrs = (() => {
let abbrs = {};
_.each(props, function(prop, key) {
let args = [];
_.each(prop, function(arg) {
if (arg._abbr) {
args.push(prop._abbr + arg._abbr);
}
});

return (abbrs[props[key]._abbr] = args);
});
return abbrs;
})();

var otherAbbrs = (() => {
let abbrs = {};
_.each(props, function(prop, key) {
let args = [];
_.each(prop, function(arg) {
if (arg._abbr) {
let newName = prop._abbr + arg._abbr;
abbrs[newName] = prop._abbr;
}
});
});

return abbrs;
})();

function getUtility(str) {
let match = re.decl.exec(str);

let utility = {};

if (match !== null) {
utility.name = match[1];
utility.args = [];
utility.decl = match[0];
match[2].replace(re.arg, function(arg) {
utility.args.push(arg);
});

_.each(abbrs, function(value, key) {
if (key === utility.name) {
utility.params = value;
}
});

_.each(otherAbbrs, function(value, key) {
if (key === utility.name) {
utility.parent = value;
}
});

return utility;
} else {
return false;
}
}

export default function(node) {
const hasClass = node.attrs.get('class');

const classNames = node.attrs.get('class').split(' ');
const flattened = [];
const newClassNames = [];

if (hasClass) {
_.each(classNames, function(className) {
// example: word-10px
if (className.match(re.decl)) {
className.replace(re.decl, function(decl, name, args) {
// for margin and padding
if (name === 'm' || name === 'p') {
let values = [];
let sides = ['t', 'r', 'b', 'l'];

// get each arg in decl and add to array
args.replace(re.arg, function(arg) {
values.push(arg);
});

// start to build full array
if (values.length === 1) {
// For each class name flatten (currently only supports m and p)
utility = getUtility(className);

if (utility) {
// console.log(className);

if (utility.name === 'm' || utility.name === 'p') {
let values = utility.args;

switch (values.length) {
case 1:
values.push(values[0]);
}
if (values.length === 2) {
case 2:
values.push(values[0]);
}
if (values.length === 3) {
case 3:
values.push(values[1]);
}

// for each side push new class names into newClassNames array
_.each(sides, function(side, index) {
newClassNames.push(`${name}${side}-${values[index]}`);
});
}
// if doesn't match margin or padding push into array
else {
newClassNames.push(className);

newClassNames.push(utility.name);

// for each side push new class names into array
_.each(utility.params, function(side, index) {
className = `${side}-${values[index]}`;
flattened.push(className);
});
} else {
if (utility.parent) {
// Avoid pushing a duplicate
if (newClassNames.includes(utility.parent) === false) {
newClassNames.push(utility.parent);
}
} else {
// Avoid pushing a duplicate
if (newClassNames.includes(utility.name) === false) {
newClassNames.push(utility.name);
}
}
});
flattened.push(className);
}
}
// if normal word push into array
else {
newClassNames.push(className);
flattened.push(className);
}
});

let styles = [];

// Get styles values from utilities
_.each(flattened, function(newClassName) {
if (newClassName.match(re.decl)) {
let propName = newClassName.match(re.decl)[1];
let propValue = newClassName.match(re.decl)[2];

// Get styles
styles.push(`--${propName}: ${propValue}`);
}
});

// console.log(newClassNames);

// Add new array back to element
node.attrs.add({ class: newClassNames.join(' ') });

// Apply new style attr
node.attrs.add({ style: styles.join('; ') }); // TODO: add to existing style attr values
}
}
Loading

0 comments on commit 5edafb4

Please sign in to comment.