Socket
Socket
Sign inDemoInstall

emotion

Package Overview
Dependencies
Maintainers
1
Versions
144
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

emotion - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

44

dist/emotion.es.js
import React from 'react';
import css from 'glam';
var h = React.createElement;
function emotion (tag, ref) {
var emotion = function (tag, ref) {
var cls = ref[0];
var vars = ref[1]; if ( vars === void 0 ) vars = [];
return (function (superclass) {
function Target () {
superclass.apply(this, arguments);
}
return function (props) { return React.createElement(
tag,
Object.assign({}, props, {
className: (props.className || '') +
' ' +
css(
cls,
vars.map(function (v) { return (v && typeof v === 'function' ? v(props) : v); })
)
})
); };
};
if ( superclass ) Target.__proto__ = superclass;
Target.prototype = Object.create( superclass && superclass.prototype );
Target.prototype.constructor = Target;
Target.prototype.render = function render () {
var this$1 = this;
var finalClassName = css(
cls,
vars.map(function (v) { return (v && typeof v === 'function' ? v(this$1.props) : v); })
);
return h(
tag,
Object.assign({}, this.props, {
className: (this.props.className || '') + ' ' + finalClassName
})
)
};
return Target;
}(React.Component))
}
export { emotion };
//# sourceMappingURL=emotion.es.js.map

@@ -1,2 +0,2 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("glam")):"function"==typeof define&&define.amd?define(["exports","react","glam"],t):t(e.emotion=e.emotion||{},e.React,e.glam)}(this,function(e,t,o){function n(e,n){var i=n[0],p=n[1];return void 0===p&&(p=[]),function(t){function n(){t.apply(this,arguments)}return t&&(n.__proto__=t),n.prototype=Object.create(t&&t.prototype),n.prototype.constructor=n,n.prototype.render=function(){var t=this,n=o(i,p.map(function(e){return e&&"function"==typeof e?e(t.props):e}));return r(e,Object.assign({},this.props,{className:(this.props.className||"")+" "+n}))},n}(t.Component)}t="default"in t?t.default:t,o="default"in o?o.default:o;var r=t.createElement;e.emotion=n,Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("glam")):"function"==typeof define&&define.amd?define(["exports","react","glam"],t):t(e.emotion=e.emotion||{},e.React,e.glam)}(this,function(e,t,n){t="default"in t?t.default:t,n="default"in n?n.default:n;var o=function(e,o){var i=o[0],a=o[1];return void 0===a&&(a=[]),function(o){return t.createElement(e,Object.assign({},o,{className:(o.className||"")+" "+n(i,a.map(function(e){return e&&"function"==typeof e?e(o):e}))}))}};e.emotion=o,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=emotion.umd.js.map

@@ -1,2 +0,2 @@

function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}function e(t,e){var p=e[0],u=e[1];return void 0===u&&(u=[]),function(e){function r(){e.apply(this,arguments)}return e&&(r.__proto__=e),r.prototype=Object.create(e&&e.prototype),r.prototype.constructor=r,r.prototype.render=function(){var e=this,r=o(p,u.map(function(t){return t&&"function"==typeof t?t(e.props):t}));return n(t,Object.assign({},this.props,{className:(this.props.className||"")+" "+r}))},r}(r.Component)}Object.defineProperty(exports,"__esModule",{value:!0});var r=t(require("react")),o=t(require("glam")),n=r.createElement;exports.emotion=e;
function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("react")),r=e(require("glam")),n=function(e,n){var o=n[0],u=n[1];return void 0===u&&(u=[]),function(n){return t.createElement(e,Object.assign({},n,{className:(n.className||"")+" "+r(o,u.map(function(e){return e&&"function"==typeof e?e(n):e}))}))}};exports.emotion=n;
//# sourceMappingURL=glam.js.map
{
"name": "emotion",
"version": "1.0.5",
"version": "1.0.6",
"description": "👩‍🎤 Glam + React",

@@ -27,3 +27,3 @@ "jsnext:main": "dist/emotion.es.js",

"babel-plugin-syntax-jsx": "^6.18.0",
"glam": "^4.0.3"
"glam": "^4.0.4"
},

@@ -30,0 +30,0 @@ "devDependencies": {

@@ -71,3 +71,42 @@ # emotion

#### attr
The [attr](https://developer.mozilla.org/en-US/docs/Web/CSS/attr) CSS function is supported in
a basic capacity.
```css
/* get value from `width` prop */
width: attr(width vw);
/* specify type or unit to apply to value */
width: attr(width vw);
/* fallback value if props.width is falsey */
width: attr(width vw, 50);
```
```jsx
const H1 = emotion.h1`
font-size: attr(fontSize px);
margin: attr(margin rem, 4);
font-family: sans-serif;
color: ${colors.pink[5]};
@media (min-width: 680px) {
color: attr(desktopColor);
}
`
const Title = ({ title, scale }) => {
return (
<H1 fontSize={16 * scale} desktopColor={colors.gray[5]}>
{title}
</H1>
)
}
```
##### Supported value types
`em|ex|px|rem|vw|vh|vmin|vmax|mm|cm|in|pt|pc`
### css prop

@@ -74,0 +113,0 @@

/* eslint-disable jsx-quotes,no-useless-escape,no-template-curly-in-string */
/* eslint-env jest */
import React from 'react'
import renderer from 'react-test-renderer'
import plugin from '../babel'
import css, {fragment} from 'glam'
const babel = require('babel-core')
describe('emotion/glam', () => {
describe('emotion/babel', () => {
describe('babel emotion component', () => {
test('basic', () => {
const basic = 'emotion.h1\`font-size: \$\{fontSize\}px;\`'
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('function call', () => {
const basic = 'emotion(MyComponent)\`font-size: \$\{fontSize\}px;\`'
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('attr', () => {
const basic = `emotion('input')\`
margin: attr(margin);
color: #ffffff;
height: \$\{props => props.height * props.scale\};
width: attr(width);
color: blue;
display: \$\{flex\};
\``
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('attr with value type', () => {
const basic = `emotion('input')\`
margin: attr(margin px);
\``
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('attr with default value', () => {
const basic = `emotion('input')\`
margin: attr(margin, 16);
\``
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('attr with value type and default value', () => {
const basic = `emotion('input')\`
margin: attr(margin px, 16);
\``
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('match works on multiple', () => {
const basic = `emotion('input')\`
margin: attr(margin px, 16);
color: blue;
padding: attr(padding em, 16);
\``
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('attr kitchen sink', () => {
const basic = `emotion('input')\`
margin: attr(margin px, 16);
padding: attr(padding em, 16);
font-size: attr(fontSize ch, 8);
width: attr(width %, 95);
height: attr(height vw, 90);
display: attr(display, flex);
\``
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
})
describe('babel css prop', () => {

@@ -66,93 +137,2 @@ test('basic', () => {

})
describe('real', () => {
test('basic', () => {
const tree = renderer
.create(
<p css={`color: red;`}>
hello world
</p>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
test('string expression', () => {
const tree = renderer
.create(
<p css="color:red;background:blue;font-size:48px;">
hello world
</p>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
test('kitchen sink', () => {
const props = {online: false, error: false, radius: 5}
const huge = 100
const tiny = 6
const bold = fragment`
display: flex;
font-weight: bold;`
const big = fragment`
@apply ${bold};
font-size: ${huge}`
const small = fragment`
font-size: ${tiny}`
const flexCenter = fragment`
display: flex;
justify-content: center;
align-items: center`
const tree = renderer
.create(
<div
className="css__legacy-stuff"
css={`
@apply ${bold}
@apply ${flexCenter};
`}
>
<h1
css={`
@apply ${props.error ? big : small};
color: red
`}
>
BOOM
</h1>
<p className="test_class1" css={`color: blue;`}>Hello</p>
<p
className="test_class1 test___class45"
css={`display: inline-flex`}
>
World
</p>
<p
css={`
color: red;
border-radius: ${props.radius};
&:hover {
font-weight: bold;
color: ${props.online ? 'green' : 'gray'};
}
`}
>
hello world
</p>
</div>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})
})

@@ -7,21 +7,4 @@ /* eslint-disable jsx-quotes,no-useless-escape,no-template-curly-in-string */

import {emotion} from '../react'
import plugin from '../babel'
const babel = require('babel-core')
describe('glam react', () => {
describe('babel glam component', () => {
test('basic', () => {
const basic = 'emotion.h1\`font-size: \$\{fontSize\}px;\`'
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
test('function call', () => {
const basic = 'emotion(MyComponent)\`font-size: \$\{fontSize\}px;\`'
const {code} = babel.transform(basic, {plugins: [plugin, 'glam/babel']})
expect(code).toMatchSnapshot()
})
})
test('basic render', () => {

@@ -44,2 +27,25 @@ const fontSize = 20

test('attr', () => {
const H1 = emotion.h1`
font-size: attr(fontSize);
margin: attr(margin rem, 4);
`
const Title = ({title}) => {
return (
<H1 fontSize={48}>
{title}
</H1>
)
}
const tree = renderer
.create(
<Title />
)
.toJSON()
expect(tree).toMatchSnapshot()
})
test('call expression', () => {

@@ -100,3 +106,3 @@ const fontSize = 20

test('function in expression', () => {
test('higher order component', () => {
const fontSize = 20

@@ -118,2 +124,4 @@ const Content = emotion('div')`

expect(ColumnContent.displayName).toBe('flexColumnundefined')
const tree = renderer

@@ -140,2 +148,91 @@ .create(

})
test('basic', () => {
const tree = renderer
.create(
<p css={`color: red;`}>
hello world
</p>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
test('string expression', () => {
const tree = renderer
.create(
<p css="color:red;background:blue;font-size:48px;">
hello world
</p>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
test('kitchen sink', () => {
const props = {online: false, error: false, radius: 5}
const huge = 100
const tiny = 6
const bold = fragment`
display: flex;
font-weight: bold;`
const big = fragment`
@apply ${bold};
font-size: ${huge}`
const small = fragment`
font-size: ${tiny}`
const flexCenter = fragment`
display: flex;
justify-content: center;
align-items: center`
const tree = renderer
.create(
<div
className="css__legacy-stuff"
css={`
@apply ${bold}
@apply ${flexCenter};
`}
>
<h1
css={`
@apply ${props.error ? big : small};
color: red
`}
>
BOOM
</h1>
<p className="test_class1" css={`color: blue;`}>Hello</p>
<p
className="test_class1 test___class45"
css={`display: inline-flex`}
>
World
</p>
<p
css={`
color: red;
border-radius: ${props.radius};
&:hover {
font-weight: bold;
color: ${props.online ? 'green' : 'gray'};
}
`}
>
hello world
</p>
</div>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

@@ -15,2 +15,112 @@ module.exports = function (babel) {

function findAndReplaceAttrs (path) {
let quasis = path.node.quasi.quasis
let stubs = path.node.quasi.expressions
let didFindAtLeastOneMatch = false
let [nextQuasis, nextStubs] = quasis.reduce(
(accum, quasi, i) => {
const str = quasi.value.cooked
const regex = /attr\(([\S]+)(?:\s*(em|ex|px|rem|vw|vh|vmin|vmax|mm|cm|in|pt|pc)?)(?:,\s*([\S^)]+))?\)/gm
let attrMatch
let matches = []
while ((attrMatch = regex.exec(str)) !== null) {
didFindAtLeastOneMatch = true
matches.push({
value: attrMatch[0],
propName: attrMatch[1],
valueType: attrMatch[2],
defaultValue: attrMatch[3],
index: attrMatch.index
})
}
let cursor = 0
for (let j = 0; j < matches.length; ++j) {
const match = matches[j]
const value = match.value
const propName = match.propName
const valueType = match.valueType
const defaultValue = match.defaultValue
const index = match.index
const preAttr = `${str.slice(cursor, index)}`
cursor = index + value.length
const postAttr = `${str.slice(cursor)}`
if (preAttr) {
accum[0].push(
t.templateElement({raw: preAttr, cooked: preAttr}, false)
)
}
if (postAttr && j === matches.length - 1) {
accum[0].push(
t.templateElement(
{raw: postAttr, cooked: postAttr},
i === quasis.length - 1
)
)
}
let createMemberExpression = () =>
t.memberExpression(t.identifier('props'), t.identifier(propName))
let returnValue = createMemberExpression()
if (valueType) {
returnValue = t.binaryExpression(
'+',
createMemberExpression(),
t.stringLiteral(valueType)
)
}
if (defaultValue) {
returnValue = t.conditionalExpression(
createMemberExpression(),
createMemberExpression(),
t.parenthesizedExpression(
t.binaryExpression(
'+',
t.stringLiteral(defaultValue),
t.stringLiteral(valueType || '')
)
)
)
}
const body = t.blockStatement([t.returnStatement(returnValue)])
const expr = t.functionExpression(
t.identifier(
`get${propName.charAt(0).toUpperCase() + propName.slice(1)}`
),
[t.identifier('props')],
body
)
accum[1].push(expr)
}
if (stubs[i]) {
accum[1].push(stubs[i])
}
if (matches.length === 0) {
accum[0].push(quasi)
if (stubs[i]) {
accum[1].push(stubs[i])
}
}
return accum
},
[[], []]
)
if (didFindAtLeastOneMatch) {
return t.templateLiteral(nextQuasis, nextStubs)
}
return path.node.quasi
}
return {

@@ -21,2 +131,3 @@ name: 'emotion-for-glam', // not required

CallExpression (path) {
// emotion('h1', css(css-12, [color])) -> emotion('h1', [css-12, [color]])
if (path.node.callee.name === 'css') {

@@ -123,2 +234,3 @@ const parentPath = path.parentPath

if (
// emotion.h1`color:${color};` -> emotion('h1', css`color:${color};`)
t.isMemberExpression(path.node.tag) &&

@@ -128,9 +240,12 @@ path.node.tag.object.name === 'emotion' &&

) {
const built = findAndReplaceAttrs(path)
path.replaceWith(
t.callExpression(t.identifier(path.node.tag.object.name), [
t.callExpression(path.node.tag.object, [
t.stringLiteral(path.node.tag.property.name),
t.taggedTemplateExpression(t.identifier('css'), path.node.quasi)
t.taggedTemplateExpression(t.identifier('css'), built)
])
)
} else if (
// emotion('h1')`color:${color};` -> emotion('h1', css`color:${color};`)
t.isCallExpression(path.node.tag) &&

@@ -140,6 +255,7 @@ path.node.tag.callee.name === 'emotion' &&

) {
const built = findAndReplaceAttrs(path)
path.replaceWith(
t.callExpression(t.identifier(path.node.tag.callee.name), [
t.callExpression(path.node.tag.callee, [
path.node.tag.arguments[0],
t.taggedTemplateExpression(t.identifier('css'), path.node.quasi)
t.taggedTemplateExpression(t.identifier('css'), built)
])

@@ -146,0 +262,0 @@ )

import React from 'react'
import css from 'glam'
const h = React.createElement
export function emotion (tag, [cls, vars = []]) {
return class Target extends React.Component {
render () {
const finalClassName = css(
cls,
vars.map(v => (v && typeof v === 'function' ? v(this.props) : v))
)
return h(
tag,
Object.assign({}, this.props, {
className: (this.props.className || '') + ' ' + finalClassName
})
)
}
}
}
export const emotion = (tag, [cls, vars = []]) => props =>
React.createElement(
tag,
Object.assign({}, props, {
className: (props.className || '') +
' ' +
css(
cls,
vars.map(v => (v && typeof v === 'function' ? v(props) : v))
)
})
)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc