Comparing version 1.6.3 to 3.0.0-alpha
363
lib/index.js
@@ -1,363 +0,6 @@ | ||
/* eslint no-invalid-this: 0 */ | ||
import pseudos from './pseudos.js' | ||
import popular from './popular.js' | ||
import create from './create.js' | ||
import { | ||
classPrefix, | ||
createClass, | ||
setDebug, | ||
getSheet, | ||
getRules, | ||
insert | ||
} from './sheet' | ||
const bss = create() | ||
bss.create = create | ||
import { | ||
hyphenToCamelCase, | ||
vendorValuePrefix, | ||
lowercaseFirst, | ||
objectToRules, | ||
selectorSplit, | ||
cssProperties, | ||
stylesToCss, | ||
vendorRegex, | ||
vendorMap, | ||
initials, | ||
memoize, | ||
isProp, | ||
assign, | ||
add | ||
} from './utils' | ||
const shorts = Object.create(null) | ||
function bss(input, value) { | ||
const b = chain(bss) | ||
input && assign(b.__style, parse.apply(null, arguments)) | ||
return b | ||
} | ||
function setProp(prop, value) { | ||
Object.defineProperty(bss, prop, { | ||
configurable: true, | ||
value | ||
}) | ||
} | ||
Object.defineProperties(bss, { | ||
__style: { | ||
configurable: true, | ||
writable: true, | ||
value: {} | ||
}, | ||
valueOf: { | ||
configurable: true, | ||
writable: true, | ||
value: function() { | ||
return '.' + this.class | ||
} | ||
}, | ||
toString: { | ||
configurable: true, | ||
writable: true, | ||
value: function() { | ||
return this.class | ||
} | ||
} | ||
}) | ||
setProp('setDebug', setDebug) | ||
setProp('$keyframes', keyframes) | ||
setProp('$media', $media) | ||
setProp('$import', $import) | ||
setProp('$nest', $nest) | ||
setProp('getSheet', getSheet) | ||
setProp('getRules', getRules) | ||
setProp('helper', helper) | ||
setProp('css', css) | ||
setProp('classPrefix', classPrefix) | ||
function chain(instance) { | ||
const newInstance = Object.create(bss, { | ||
__style: { | ||
value: assign({}, instance.__style) | ||
}, | ||
style: { | ||
enumerable: true, | ||
get: function() { | ||
return Object.keys(this.__style).reduce((acc, key) => { | ||
if (typeof this.__style[key] === 'number' || typeof this.__style[key] === 'string') | ||
acc[key.replace(/^!/, '')] = this.__style[key] | ||
return acc | ||
}, {}) | ||
} | ||
} | ||
}) | ||
if (instance === bss) | ||
bss.__style = {} | ||
return newInstance | ||
} | ||
cssProperties.forEach(prop => { | ||
const vendor = prop.match(vendorRegex) | ||
if (vendor) { | ||
const unprefixed = lowercaseFirst(prop.replace(vendorRegex, '$2')) | ||
if (cssProperties.indexOf(unprefixed) === -1) { | ||
if (unprefixed === 'flexDirection') | ||
vendorValuePrefix.flex = '-' + vendor[1].toLowerCase() + '-flex' | ||
vendorMap[unprefixed] = prop | ||
setProp(unprefixed, setter(prop)) | ||
setProp(short(unprefixed), bss[unprefixed]) | ||
return | ||
} | ||
} | ||
setProp(prop, setter(prop)) | ||
setProp(short(prop), bss[prop]) | ||
}) | ||
setProp('content', function Content(arg) { | ||
const b = chain(this) | ||
arg === null || arg === undefined || arg === false | ||
? delete b.__style.content | ||
: b.__style.content = '"' + arg + '"' | ||
return b | ||
}) | ||
Object.defineProperty(bss, 'class', { | ||
set: function(value) { | ||
this.__class = value | ||
}, | ||
get: function() { | ||
return this.__class || createClass(this.__style) | ||
} | ||
}) | ||
function $media(value, style) { | ||
const b = chain(this) | ||
if (value) | ||
b.__style['@media ' + value] = parse(style) | ||
return b | ||
} | ||
function $import(value) { | ||
if (value && !/^('|"|url\('|url\(")/.test(value)) | ||
value = '"' + value + '"' | ||
if (value) | ||
insert('@import ' + value + ';', 0) | ||
return chain(this) | ||
} | ||
function $nest(selector, properties) { | ||
const b = chain(this) | ||
if (arguments.length === 1) | ||
Object.keys(selector).forEach(x => addNest(b.__style, x, selector[x])) | ||
else if (selector) | ||
addNest(b.__style, selector, properties) | ||
return b | ||
} | ||
function addNest(style, selector, properties) { | ||
const prop = selector.split(selectorSplit).map(x => { | ||
x = x.trim() | ||
return (x.charAt(0) === ':' || x.charAt(0) === '[' ? '' : ' ') + x | ||
}).join(',&') | ||
prop in style | ||
? assign(style[prop], parse(properties)) | ||
: style[prop] = parse(properties) | ||
} | ||
pseudos.forEach(name => | ||
setProp('$' + hyphenToCamelCase(name.replace(/:/g, '')), function Pseudo(value, style) { | ||
const b = chain(this) | ||
if (isTagged(value)) | ||
b.__style[name] = parse.apply(null, arguments) | ||
else if (value || style) | ||
b.__style[name + (style ? '(' + value + ')' : '')] = parse(style || value) | ||
return b | ||
}) | ||
) | ||
function setter(prop) { | ||
return function CssProperty(value) { | ||
const b = chain(this) | ||
if (!value && value !== 0) | ||
delete b.__style[prop] | ||
else if (arguments.length > 0) | ||
add(b.__style, prop, Array.prototype.slice.call(arguments)) | ||
return b | ||
} | ||
} | ||
function css(selector, style) { | ||
if (arguments.length === 1) | ||
Object.keys(selector).forEach(key => addCss(key, selector[key])) | ||
else | ||
addCss(selector, style) | ||
return chain(this) | ||
} | ||
function addCss(selector, style) { | ||
objectToRules(parse(style), selector, '', true).forEach(rule => insert(rule)) | ||
} | ||
function helper(name, styling) { | ||
if (arguments.length === 1) | ||
return Object.keys(name).forEach(key => helper(key, name[key])) | ||
delete bss[name] // Needed to avoid weird get calls in chrome | ||
if (typeof styling === 'function') { | ||
helper[name] = styling | ||
Object.defineProperty(bss, name, { | ||
configurable: true, | ||
value: function Helper(input) { | ||
const b = chain(this) | ||
const result = isTagged(input) | ||
? styling(raw(input, arguments)) | ||
: styling.apply(null, arguments) | ||
assign(b.__style, result.__style) | ||
return b | ||
} | ||
}) | ||
} else { | ||
helper[name] = parse(styling) | ||
Object.defineProperty(bss, name, { | ||
configurable: true, | ||
get: function() { | ||
const b = chain(this) | ||
assign(b.__style, parse(styling)) | ||
return b | ||
} | ||
}) | ||
} | ||
} | ||
bss.helper('$animate', (value, props) => | ||
bss.animation(bss.$keyframes(props) + ' ' + value) | ||
) | ||
function short(prop) { | ||
const acronym = initials(prop) | ||
, short = popular[acronym] && popular[acronym] !== prop ? prop : acronym | ||
shorts[short] = prop | ||
return short | ||
} | ||
const stringToObject = memoize(string => { | ||
let last = '' | ||
, prev | ||
return string.trim().replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*(?![^("]*[)"])/g, '').split(/;(?![^("]*[)"])|\n/).reduce((acc, line) => { | ||
if (!line) | ||
return acc | ||
line = last + line.trim() | ||
const [key, ...tokens] = line.replace(/[ :]+/, ' ').split(' ') | ||
last = line.charAt(line.length - 1) === ',' ? line : '' | ||
if (last) | ||
return acc | ||
if (line.charAt(0) === ',' || !isProp.test(key)) { | ||
acc[prev] += ' ' + line | ||
return acc | ||
} | ||
if (!key) | ||
return acc | ||
const prop = key.charAt(0) === '-' && key.charAt(1) === '-' | ||
? key | ||
: hyphenToCamelCase(key) | ||
prev = shorts[prop] || prop | ||
if (key in helper) { | ||
typeof helper[key] === 'function' | ||
? assign(acc, helper[key](...tokens).__style) | ||
: assign(acc, helper[key]) | ||
} else if (prop in helper) { | ||
typeof helper[prop] === 'function' | ||
? assign(acc, helper[prop](...tokens).__style) | ||
: assign(acc, helper[prop]) | ||
} else if (tokens.length > 0) { | ||
add(acc, prev, tokens) | ||
} | ||
return acc | ||
}, {}) | ||
}) | ||
let count = 0 | ||
const keyframeCache = {} | ||
function keyframes(props) { | ||
const content = Object.keys(props).reduce((acc, key) => | ||
acc + key + '{' + stylesToCss(parse(props[key])) + '}' | ||
, '') | ||
if (content in keyframeCache) | ||
return keyframeCache[content] | ||
const name = classPrefix + count++ | ||
keyframeCache[content] = name | ||
insert('@keyframes ' + name + '{' + content + '}') | ||
return name | ||
} | ||
function parse(input, value) { | ||
if (typeof input === 'string') { | ||
if (typeof value === 'string' || typeof value === 'number') | ||
return ({ [input] : value }) | ||
return stringToObject(input) | ||
} else if (isTagged(input)) { | ||
return stringToObject(raw(input, arguments)) | ||
} | ||
return input.__style || sanitize(input) | ||
} | ||
function isTagged(input) { | ||
return Array.isArray(input) && typeof input[0] === 'string' | ||
} | ||
function raw(input, args) { | ||
let str = '' | ||
for (let i = 0; i < input.length; i++) | ||
str += input[i] + (args[i + 1] || args[i + 1] === 0 ? args[i + 1] : '') | ||
return str | ||
} | ||
function sanitize(styles) { | ||
return Object.keys(styles).reduce((acc, key) => { | ||
const value = styles[key] | ||
key = shorts[key] || key | ||
if (!value && value !== 0 && value !== '') | ||
return acc | ||
if (key === 'content' && value.charAt(0) !== '"') | ||
acc[key] = '"' + value + '"' | ||
else if (typeof value === 'object') | ||
acc[key] = sanitize(value) | ||
else | ||
add(acc, key, value) | ||
return acc | ||
}, {}) | ||
} | ||
export default bss |
{ | ||
"name": "bss", | ||
"version": "1.6.3", | ||
"version": "3.0.0-alpha", | ||
"description": "Better Style Sheets", | ||
"main": "bss.js", | ||
"module": "bss.esm.js", | ||
"main": "dist/bss.js", | ||
"module": "dist/bss.esm.js", | ||
"scripts": { | ||
@@ -20,4 +20,4 @@ "test": "TEST=true npm run build && ospec", | ||
"rollup-plugin-filesize": "6.1.0", | ||
"rollup-plugin-uglify": "6.0.2" | ||
"rollup-plugin-terser": "5.1.2" | ||
} | ||
} |
import buble from 'rollup-plugin-buble' | ||
import { uglify } from 'rollup-plugin-uglify' | ||
import { terser } from 'rollup-plugin-terser' | ||
import filesize from 'rollup-plugin-filesize' | ||
@@ -9,3 +9,3 @@ | ||
output: { | ||
file: 'bss.js', | ||
file: 'dist/bss.js', | ||
exports: 'default', | ||
@@ -25,3 +25,3 @@ format: 'umd', | ||
output: { | ||
file: 'bss.min.js', | ||
file: 'dist/bss.min.js', | ||
exports: 'default', | ||
@@ -34,3 +34,3 @@ format: 'umd', | ||
buble(), | ||
uglify({ mangle: true, compress: true }), | ||
terser({ mangle: true, compress: true }), | ||
filesize() | ||
@@ -41,3 +41,3 @@ ] | ||
output: { | ||
file: 'bss.esm.js', | ||
file: 'dist/bss.esm.js', | ||
format: 'esm', | ||
@@ -44,0 +44,0 @@ sourcemap: true |
@@ -53,354 +53,108 @@ const o = require('ospec') | ||
const b = require('../bss') | ||
const b = require('../dist/bss') | ||
const cn = () => '.' + b.prefix + b.count | ||
o.spec('bss', function() { | ||
o('inputs', function() { | ||
o(b`foo: bar; baz: boo;`.style).deepEquals({ foo: 'bar', baz: 'boo' }) | ||
o(b`foo: bar;`.style).deepEquals({ foo: 'bar' }) | ||
o(b`foo: bar`.style).deepEquals({ foo: 'bar' }) | ||
o(b`foo bar`.style).deepEquals({ foo: 'bar' }) | ||
o(b({ foo: 'bar' }).style).deepEquals({ foo: 'bar' }) | ||
o(b('foo', 'bar').style).deepEquals({ foo: 'bar' }) | ||
}) | ||
o('object input with pseduos', function() { | ||
const cls = b({ ':hover': { background: 'red' } }).class | ||
o(b.getSheet()).equals(`.${cls}.${cls}:hover{background:red;}`) | ||
o('White space around colon', () => { | ||
b`position:absolute; | ||
position: absolute; | ||
position :absolute; | ||
position : absolute; | ||
position: | ||
absolute; | ||
position: | ||
absolute` | ||
o(b.rules.pop()).equals(cn() + '{position:absolute;position:absolute;position:absolute;position:absolute;position:absolute;position:absolute;}') | ||
}) | ||
o('object input with at-rules', function() { | ||
const cls = b({ '@media (max-width:600px)': { background: 'red' } }).class | ||
o(b.getSheet()).equals(`@media (max-width:600px){.${cls}.${cls}{background:red;}}`) | ||
o('Multiline property values', () => { | ||
b`position: absolute; | ||
transform: translate(-50%, -50%) | ||
rotate(-45deg);` | ||
o(b.rules.pop()).equals(cn() + '{position:absolute;transform:translate(-50%, -50%) rotate(-45deg);}') | ||
}) | ||
o('Chained $nest in @', function() { | ||
const cls = b.$media('(min-width: 0px)', | ||
b` | ||
font-family: Helvetica; | ||
`.$nest('h1', b.c('red')) | ||
).class | ||
o(b.getSheet()).equals(`@media (min-width: 0px){.${cls}.${cls}{font-family:Helvetica;}.${cls} h1{color:red;}}`) | ||
o('Comments in strings', () => { | ||
b`position: absolute; // This is absolute | ||
transform: translate(-50%, -50%) // This is multi line | ||
rotate(-45deg); // And here it ends` | ||
o(b.rules.pop()).equals(cn() + '{position:absolute;transform:translate(-50%, -50%) rotate(-45deg);}') | ||
}) | ||
o('object input using shortname properties', function() { | ||
o(b({ bc: 'red' }).style).deepEquals({ backgroundColor: 'red' }) | ||
o('@keyframes', () => { | ||
b` | ||
@keyframes wat { | ||
from { margin-top: 50px; } | ||
50% { margin-top: 150px; } | ||
to { margin-top: 100px; } | ||
} | ||
` | ||
o(b.rules.pop()).equals('@keyframes wat{from{margin-top:50px;}50%{margin-top:150px;}to{margin-top:100px;}}') | ||
}) | ||
o('multiline input', function() { | ||
o(b('transform scale(1)\nrotate(0)').style).deepEquals({ transform: 'scale(1) rotate(0)' }) | ||
o('@media', () => { | ||
b` | ||
@media screen and (min-width: 900px) { | ||
article { | ||
padding: 1rem 3rem; | ||
} | ||
} | ||
` | ||
o(b.rules.pop()).equals('@media screen and (min-width: 900px){' + cn() + ' article{padding:1rem 3rem;}}') | ||
}) | ||
o('default css properties', function() { | ||
o(b.bc('green').style).deepEquals({ backgroundColor: 'green' }) | ||
o(b.p(20, 10, '50%').style).deepEquals({ padding: '20px 10px 50%' }) | ||
o(b`p 20 10 50%`.style).deepEquals({ padding: '20px 10px 50%' }) | ||
o(b({ padding: '20 10 50%' }).style).deepEquals({ padding: '20px 10px 50%' }) | ||
o(b.backgroundColor('red').style).deepEquals({ backgroundColor: 'red' }) | ||
o('@supports', () => { | ||
b` | ||
@supports (display: flex) { | ||
article { | ||
display: flex; | ||
} | ||
} | ||
` | ||
o(b.rules.pop()).equals('@supports (display: flex){' + cn() + ' article{display:flex;}}') | ||
}) | ||
o('css doulbe class for specificity generation', function() { | ||
const cls = b`foo: bar;`.class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{foo:bar;}`) | ||
o('@media inside @supports', () => { | ||
b` | ||
@supports (display: flex) { | ||
@media screen and (min-width: 900px) { | ||
article { | ||
display: flex; | ||
} | ||
} | ||
} | ||
` | ||
o(b.rules.pop()).equals('@supports (display: flex){@media screen and (min-width: 900px){' + cn() + ' article{display:flex;}}}') | ||
}) | ||
o('common style class reuse', function() { | ||
const cls = b`foo: bar;`.class | ||
, cls2 = b`foo: bar;`.class | ||
o(cls).equals(cls2) | ||
o(b.getSheet()).equals(`.${cls}.${cls}{foo:bar;}`) | ||
/* | ||
o('Inline animation', () => { | ||
b` | ||
animation 1s { | ||
from { margin-bottom 0 }, | ||
50% { margin-top 50 }, | ||
to { margin-top 100 } | ||
} | ||
` | ||
o(b.rules.pop()).equals('') | ||
}) | ||
o('values can have colons', function() { | ||
const cls = b` | ||
backgroundImage: url(https://bss.com/) | ||
`.class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{background-image:url(https://bss.com/);}`) | ||
o('Multiple inline animation', () => { | ||
b` | ||
animation 1s { | ||
from { margin-top 50px } | ||
50% { margin-top 150px } | ||
to { margin-top 100px } | ||
}, { | ||
20% { transform translateX(50px) } | ||
50% { transform translateX(150px) } | ||
80% { transform translateX(100px) } | ||
} | ||
` | ||
o(b.rules.pop()).equals('') | ||
}) | ||
*/ | ||
o('values can have valid semicolons', function() { | ||
const cls = b` | ||
backgroundImage: url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==) | ||
content: "a;here" | ||
`.class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{background-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==);content:"a;here";}`) | ||
}) | ||
o('@import', function() { | ||
b.$import('sanitize.css') | ||
o(b.getSheet()).equals('@import "sanitize.css";') | ||
b.$import('"sanitize.css"') | ||
o(b.getSheet()).equals('@import "sanitize.css";') | ||
b.$import('url("sanitize.css")') | ||
o(b.getSheet()).equals('@import url("sanitize.css");') | ||
}) | ||
o('pseudo', function() { | ||
const cls = b.$hover(b.bc('green')).class | ||
o(b.getSheet()).equals(`.${cls}.${cls}:hover{background-color:green;}`) | ||
}) | ||
o('same named props', function() { | ||
const cls1 = b` | ||
c blue | ||
bc white | ||
`.class | ||
const cls2 = b` | ||
c blue | ||
bc white | ||
c white | ||
`.class | ||
o(b.getSheet()).equals([ | ||
`.${cls1}.${cls1}{color:blue;background-color:white;}`, | ||
`.${cls2}.${cls2}{color:blue;background-color:white;color:white;}` | ||
].join('')) | ||
}) | ||
o('same named properties string', function() { | ||
const cls = b` | ||
display -webkit-flex | ||
display flex | ||
`.class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{display:-webkit-flex;display:flex;}`) | ||
}) | ||
o('same named properties function', function() { | ||
const cls = b.d('-webkit-flex').d('flex').class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{display:-webkit-flex;display:flex;}`) | ||
}) | ||
o('same named properties style', function() { | ||
o(b.d('-webkit-flex').d('flex').style).deepEquals({ display:'flex' }) | ||
}) | ||
o('empty content string is set to ""', function() { | ||
const cls = b.$before(b.content('')).$after(b({ content: '' })).class | ||
o(b.getSheet()).equals(`.${cls}.${cls}::before{content:"";}.${cls}.${cls}::after{content:"";}`) | ||
}) | ||
o('adds vendor prefix', function() { | ||
const cls = b({ overflowScrolling: 'none' }).class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{-webkit-overflow-scrolling:none;}`) | ||
const cls2 = b({ appearance: 'none' }).class | ||
o(b.getSheet()).equals(`.${cls2}.${cls2}{-moz-appearance:none;}`) | ||
const cls3 = b('appearance none').class | ||
o(b.getSheet()).equals(`.${cls3}.${cls3}{-moz-appearance:none;}`) | ||
}) | ||
o('support variables in tagged template literals', function() { | ||
o(b`display ${ 'flex' }`.style).deepEquals({ display: 'flex' }) | ||
}) | ||
o('support 0 in tagged template literals', function() { | ||
o(b`top ${ 0 }`.style).deepEquals({ top: '0' }) | ||
}) | ||
o('support variables in tagged template literals in pseudos', function() { | ||
const cls = b.$hover`display ${ 'flex' }`.class | ||
o(b.getSheet()).equals(`.${cls}.${cls}:hover{display:flex;}`) | ||
}) | ||
o('allows vendor prefix', function() { | ||
const cls = b('-webkit-overflow-scrolling touch').class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{-webkit-overflow-scrolling:touch;}`) | ||
}) | ||
o('allows css variables', function() { | ||
const cls = b('--primaryColor 250 250 250').class | ||
o(b.getSheet()).equals(`.${cls}.${cls}{--primaryColor:250 250 250;}`) | ||
}) | ||
o('single class for less specificity when using $nest', function() { | ||
const cls = b.$nest('li', b('-webkit-overflow-scrolling touch')).class | ||
o(b.getSheet()).equals(`.${cls} li{-webkit-overflow-scrolling:touch;}`) | ||
}) | ||
o('nest multiple selectors', function() { | ||
const cls = b.$nest('th, tr', b('background blue')).class | ||
o(b.getSheet()).equals(`.${cls} th,.${cls} tr{background:blue;}`) | ||
}) | ||
o('nest objects', function() { | ||
const cls = b.$nest({ th : b('background blue') }).class | ||
o(b.getSheet()).equals(`.${cls} th{background:blue;}`) | ||
}) | ||
o('nest with ampersand', function() { | ||
const cls = b.$nest({ 'th &' : b('background blue') }).class | ||
o(b.getSheet()).equals(`th .${cls}{background:blue;}`) | ||
const cls2 = b.$nest({ 'th&' : b('background blue') }).class | ||
o(b.getSheet()).equals(`th.${cls2}{background:blue;}`) | ||
const cls3 = b.$nest({ '& th' : b('background blue') }).class | ||
o(b.getSheet()).equals(`.${cls3} th{background:blue;}`) | ||
}) | ||
o('nest multiple identical selectors', function() { | ||
const cls = b.$nest('p.broken', 'background: purple') | ||
.$nest('p.broken', 'color: yellow').class | ||
o(b.getSheet()).equals(`.${cls} p.broken{background:purple;color:yellow;}`) | ||
}) | ||
o('add px', function() { | ||
o(b`w 1`.style).deepEquals({ width: '1px' }) | ||
o(b('width 1').style).deepEquals({ width: '1px' }) | ||
o(b({ width: 1 }).style).deepEquals({ width: '1px' }) | ||
o(b({ width: true }).style).deepEquals({ width: 'true' }) | ||
o(b`boxShadow 1 1 10 black`.style).deepEquals({ boxShadow: '1px 1px 10px black' }) | ||
o(b`border 1 solid black`.style).deepEquals({ border: '1px solid black' }) | ||
o(b({ boxShadow: '1 1 10 black'}).style).deepEquals({ boxShadow: '1px 1px 10px black' }) | ||
o(b({ border: '1 solid black' }).style).deepEquals({ border: '1px solid black' }) | ||
o(b.w(1).style).deepEquals({ width: '1px' }) | ||
}) | ||
o('do not add px to 0', function() { | ||
o(b`w 0`.style).deepEquals({ width: '0' }) | ||
}) | ||
o('clears empty', function() { | ||
o(b.width(false && 20).style).deepEquals({}) | ||
o(b.width(undefined && 20).style).deepEquals({}) | ||
o(b.width(null && 20).style).deepEquals({}) | ||
o(b.width('').style).deepEquals({}) | ||
}) | ||
o.spec('helpers', function() { | ||
o('can have any name', function() { | ||
b.helper('fooBar', b`foo bar`) | ||
b.helper('foo-bar', b`fiz baz`) | ||
o(b` | ||
fooBar | ||
foo-bar | ||
`.style).deepEquals({ foo: 'bar', fiz: 'baz' }) | ||
}) | ||
o('without args', function() { | ||
b.helper('foobar', b`foo bar`) | ||
o(b.foobar.style).deepEquals({ foo: 'bar' }) | ||
}) | ||
o('parsed', function() { | ||
b.helper('foobar', `foo bar`) | ||
o(b.foobar.style).deepEquals({ foo: 'bar' }) | ||
}) | ||
o('with args (object notation)', function() { | ||
b.helper('foo', arg => b({ foo: arg })) | ||
o(b.foo('bar').style).deepEquals({ foo: 'bar' }) | ||
}) | ||
o('with args (bss notation)', function() { | ||
b.helper('foo', arg => b`foo ${arg}`) | ||
o(b.foo('bar').style).deepEquals({ foo: 'bar' }) | ||
}) | ||
o('with and without args mixed', function() { | ||
b.helper('foo', arg => b`foo ${arg}`) | ||
b.helper('baz', b`baz foz`) | ||
o(b.foo('bar').baz.style).deepEquals({ foo: 'bar', baz: 'foz' }) | ||
}) | ||
o('multiple helpers in object', function() { | ||
b.helper({ | ||
foo: b`bar baz`, | ||
bar: b`foo bar` | ||
}) | ||
o(b.foo.bar.style).deepEquals({ bar: 'baz', foo: 'bar' }) | ||
}) | ||
o('helpers in strings', function() { | ||
b.helper({ | ||
size: (w, h) => b(`width ${w};height ${h}`), | ||
pointer: b('cursor pointer') | ||
}) | ||
o(b` | ||
size 20 20 | ||
pointer | ||
`.style).deepEquals({ width: '20px', height: '20px', cursor: 'pointer' }) | ||
}) | ||
o('helpers as template literals', function() { | ||
b.helper({ | ||
desktop: s => b.$media('(min-width:1024px)', s) | ||
}) | ||
const cls = b.desktop`display flex`.class | ||
o(b.getSheet()).equals(`@media (min-width:1024px){.${cls}.${cls}{display:flex;}}`) | ||
}) | ||
o('helpers as template literals with variables', function() { | ||
b.helper({ | ||
desktop: s => b.$media('(min-width:1024px)', s) | ||
}) | ||
const cls = b.desktop`display ${ 'flex' }`.class | ||
o(b.getSheet()).equals(`@media (min-width:1024px){.${cls}.${cls}{display:flex;}}`) | ||
}) | ||
}) | ||
o('css', function() { | ||
b.css('html', 'background blue') | ||
o(b.getSheet()).equals('html{background:blue;}') | ||
}) | ||
o('css objects', function() { | ||
b.css({ html: 'background blue' }) | ||
o(b.getSheet()).equals('html{background:blue;}') | ||
}) | ||
o('css nest', function() { | ||
b.css('html', b('background blue').$nest('li', 'background red')) | ||
o(b.getSheet()).equals('html{background:blue;}html li{background:red;}') | ||
}) | ||
o('$keyframes', function() { | ||
const anim = b.$keyframes({ | ||
from: 'bc red' | ||
}) | ||
o(b.getSheet()).equals(`@keyframes ${anim}{from{background-color:red;}}`) | ||
}) | ||
o('$animate', function() { | ||
const cls = b.$animate('1s', { | ||
from: 'bc black' | ||
}).class | ||
const sheet = b.getSheet() | ||
o(sheet).equals(`@keyframes ${cls}{from{background-color:black;}}.${cls}.${cls}{animation:${cls} 1s;}`) | ||
}) | ||
o('Override valueOf', function() { | ||
const newValueOf = function() { | ||
return 'test' | ||
} | ||
b.valueOf = newValueOf | ||
o(b.valueOf).equals(newValueOf) | ||
o('' + b.bc('red')).equals('test') | ||
}) | ||
o('Multiline css', function() { | ||
o(b` | ||
position : absolute; | ||
transform : translate(-50%, -50%) | ||
rotate(-45deg); | ||
`.style).deepEquals({ | ||
position: 'absolute', | ||
transform: 'translate(-50%, -50%) rotate(-45deg)' | ||
}) | ||
}) | ||
o('Comments in strings', function() { | ||
o(b` | ||
position : absolute; // This is absolute | ||
transform : translate(-50%, -50%) // This is multi line | ||
rotate(-45deg); // And here it ends | ||
`.style).deepEquals({ | ||
position: 'absolute', | ||
transform: 'translate(-50%, -50%) rotate(-45deg)' | ||
}) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
157227
19
1639
2
1