Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nozbe/zacs

Package Overview
Dependencies
Maintainers
8
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nozbe/zacs - npm Package Compare versions

Comparing version 0.10.0-1 to 1.0.0-0

6

CHANGELOG.md

@@ -7,4 +7,8 @@ # Changelog

- You can now declare multiple unconditional styles by passing an array of stylesets/class names
- You can now add extra styles to a ZACS component via `zacs:style={{ attr: value }}` syntax
- Strip ZACS declarations (`const Foo = zacs.foo(...)`) from output code by default. Pass `keepDeclarations: true` in Babel config to revert to previous behavior
- Strip ZACS declarations (`const Foo = zacs.foo(...)`) and ZACS import from output code by default. Pass `keepDeclarations: true` in Babel config to revert to previous behavior.
- Fix buggy behavior on `zacs.createXXX` components with both `zacs:inherit` and `zacs:style` props whitelisted
- Improved validation and error messages
- Improved Flow typing (likely to reveal new errors)

@@ -11,0 +15,0 @@ ## 0.9.3 (2019-09-27)

{
"name": "@nozbe/zacs",
"version": "0.10.0-1",
"version": "1.0.0-0",
"description": "Zero Abstraction Cost Styling (for React DOM and React Native)",

@@ -10,2 +10,3 @@ "main": "src/index.js",

"eslint": "eslint ./src -c ./.eslintrc.yml --cache --cache-location ./.cache/.eslintcache",
"playground": "chokidar \"src/babel/**/*.js\" --initial -c \"node src/babel/__playground__/index.js\"",
"prettier": "prettier-eslint --config ./.prettierrc --write \"./src/**/*.js\"",

@@ -54,2 +55,5 @@ "ci:check": "concurrently 'npm run test' 'npm run eslint' 'npm run flow' --kill-others-on-fail"

"babel-eslint": "^10.0.3",
"chalk": "^4.1.0",
"chokidar-cli": "^2.1.0",
"cli-highlight": "^2.1.4",
"concurrently": "^4.1.2",

@@ -56,0 +60,0 @@ "eslint": "^6.3.0",

@@ -232,2 +232,30 @@ <p align="center">

### Multiple unconditional styles
```js
import styles from './styles'
const TitleText = zacs.text([styles.text, styles.titleText])
const rendered = <TitleText />
```
<details>
<summary>See compiled output</summary>
**Web:**
```js
const rendered = <span className={styles.text + ' ' + styles.titleText} />
```
**React Native:**
```js
import { Text } from 'react-native'
const rendered = <Text style={[styles.text, styles.titleText]} />
```
</details>
### Styling custom components

@@ -278,4 +306,2 @@

**TODO:** I don't love the `zacs:inherit` name — if you have a better suggestion, let us know!
<details>

@@ -282,0 +308,0 @@ <summary>See compiled output</summary>

175

src/babel/index.js
/* eslint-disable no-use-before-define */
// Note: Why is this one big file? Because that makes it possible to work with it using https://astexplorer.net :)
Object.defineProperty(exports, '__esModule', {
value: true,
})
exports.__esModule = true
/*
TERMINOLOGY:
zacs.{view,text,styled}() -- styled declaration
zacs.create{View,Text,Styled}() -- styled component
styles.foo -- predefined styleset
{ foo: 'bar' } -- literal styleset
zacs.view(
styles.foo, -- unconditional styleset (uncond styleset)
{ bar: styles.bar }, -- conditional styleset spec (cond styleset)
{ width: 'width' } -- literal style spec
)
*/
function getPlatform(state) {

@@ -58,7 +74,7 @@ // return 'web'

function withoutStylingProps(t, attributes, conditionalStyles, addedStyles) {
function withoutStylingProps(t, attributes, condStyles, literalStyleSpec) {
const stylingProps = []
if (conditionalStyles && conditionalStyles.properties) {
conditionalStyles.properties.forEach(property => {
if (condStyles && condStyles.properties) {
condStyles.properties.forEach(property => {
stylingProps.push(property.key.name)

@@ -68,4 +84,4 @@ })

if (addedStyles && addedStyles.properties) {
addedStyles.properties.forEach(property => {
if (literalStyleSpec && literalStyleSpec.properties) {
literalStyleSpec.properties.forEach(property => {
stylingProps.push(property.key.name)

@@ -142,12 +158,16 @@ })

function getStyles(t, mainStyle, conditionalStyles, addedStylesDef, jsxAttributes, passedProps) {
const styles = []
const addedStyles = []
function getStyles(t, uncondStyles, condStyles, literalStyleSpec, jsxAttributes, passedProps) {
const stylesets = []
const literalStyles = []
if (mainStyle && !t.isNullLiteral(mainStyle)) {
styles.push([mainStyle])
if (uncondStyles && !t.isNullLiteral(uncondStyles)) {
if (t.isArrayExpression(uncondStyles)) {
stylesets.push(...uncondStyles.elements.map(styleset => [styleset]))
} else {
stylesets.push([uncondStyles])
}
}
if (conditionalStyles && !t.isNullLiteral(conditionalStyles)) {
conditionalStyles.properties.forEach(property => {
if (condStyles && !t.isNullLiteral(condStyles)) {
condStyles.properties.forEach(property => {
const style = property.value

@@ -165,10 +185,10 @@ const propName = property.key.name

if (flag === true) {
styles.push([style])
stylesets.push([style])
} else if (flag === false) {
// we know for a fact the style won't be used -- so ignore it
} else {
styles.push([style, flag])
stylesets.push([style, flag])
}
} else {
styles.push([style, t.memberExpression(t.identifier('props'), t.identifier(propName))])
stylesets.push([style, t.memberExpression(t.identifier('props'), t.identifier(propName))])
}

@@ -178,4 +198,4 @@ })

if (addedStylesDef && !t.isNullLiteral(addedStylesDef)) {
addedStylesDef.properties.forEach(property => {
if (literalStyleSpec && !t.isNullLiteral(literalStyleSpec)) {
literalStyleSpec.properties.forEach(property => {
const styleAttr = property.value.value

@@ -191,5 +211,5 @@ const propName = property.key.name

const styleValue = jsxAttrValue(t, attr)
addedStyles.push([styleAttr, styleValue])
literalStyles.push([styleAttr, styleValue])
} else {
addedStyles.push([
literalStyles.push([
styleAttr,

@@ -203,3 +223,3 @@ t.memberExpression(t.identifier('props'), t.identifier(propName)),

// TODO: Validate zacs:style value
// TODO: If the value is a simple object, we could merge them into addedStyles. OTOH, maybe another
// TODO: If the value is a simple object, we could merge them into literalStyles. OTOH, maybe another
// optimizer Babel plugin can do it further down the line?

@@ -221,4 +241,4 @@ const zacsStyleAttribute = jsxAttributes && findNamespacedAttr(t, jsxAttributes, 'style')

return [
styles,
addedStyles.length ? objectExpressionFromPairs(t, addedStyles) : null,
stylesets,
literalStyles.length ? objectExpressionFromPairs(t, literalStyles) : null,
inheritedProps,

@@ -266,2 +286,7 @@ zacsStyle,

// prevent Object.assign(props.__zacs_style, ...), because if it's not an object, it will crash
if (!styles && zacsStyle && inheritedProps && !t.isObjectExpression(zacsStyle)) {
allStyles.unshift(t.objectExpression([]))
}
// Object.assign({styles:'values'}, props.style)

@@ -305,9 +330,9 @@ // TODO: Maybe we can use spread operator and babel will transpile it into ES5 if necessary?

function nativeStyleAttributes(t, [styleDefs, addedStyles, inheritedProps, zacsStyle]) {
const styles = styleDefs.map(([styleName, condition]) =>
function nativeStyleAttributes(t, [stylesets, literalStyleset, inheritedProps, zacsStyle]) {
const styles = stylesets.map(([styleName, condition]) =>
condition ? t.logicalExpression('&&', condition, styleName) : styleName,
)
if (addedStyles) {
styles.push(addedStyles)
if (literalStyleset) {
styles.push(literalStyleset)
}

@@ -343,9 +368,16 @@

platform,
mainStyle,
conditionalStyles,
addedStyles,
uncondStyles,
condStyles,
literalStyleSpec,
jsxAttributes,
passedProps = [],
) {
const styles = getStyles(t, mainStyle, conditionalStyles, addedStyles, jsxAttributes, passedProps)
const styles = getStyles(
t,
uncondStyles,
condStyles,
literalStyleSpec,
jsxAttributes,
passedProps,
)
switch (platform) {

@@ -357,3 +389,3 @@ case 'web':

default:
throw new Error('Unknown platform')
throw new Error('Unknown platform passed to ZACS config')
}

@@ -451,3 +483,3 @@ }

)
const [mainStyle, conditionalStyles, addedStyles, passedPropsExpr] =
const [uncondStyles, condStyles, literalStyleSpec, passedPropsExpr] =
zacsMethod === 'styled' ? init.arguments.slice(1) : init.arguments

@@ -482,3 +514,3 @@

jsxAttributes.unshift(
...styleAttributes(t, platform, mainStyle, conditionalStyles, addedStyles, null, passedProps),
...styleAttributes(t, platform, uncondStyles, condStyles, literalStyleSpec, null, passedProps),
)

@@ -542,3 +574,3 @@

throw path.buildCodeFrameError(
`It's not allowed to export zacs declarations -- but you can export zacs components (use zacs.createView/createText/createStyled)`,
`It's not allowed to export zacs declarations. You can export zacs components (use zacs.createView/createText/createStyled), however they behave a little differently -- please check documentation for more information.`,
)

@@ -549,2 +581,3 @@ }

if (zacsMethod === 'styled') {
const componentToStyle = init.arguments[0]
if (

@@ -554,9 +587,9 @@ !(

// TODO: Validate platform specifier keys
(t.isIdentifier(init.arguments[0]) ||
t.isStringLiteral(init.arguments[0]) ||
t.isObjectExpression(init.arguments[0]))
(t.isIdentifier(componentToStyle) ||
t.isStringLiteral(componentToStyle) ||
t.isObjectExpression(componentToStyle))
)
) {
throw path.buildCodeFrameError(
'zacs.styled() requires an argument - a `Component`, a `{ web: Component, native: Component }` specifier, or a `"builtin"`',
'zacs.styled() requires an argument - a `Component`, a `{ web: Component, native: Component }` specifier, or a `"builtin"` (e.g. `"div"` on web)',
)

@@ -566,3 +599,3 @@ }

const [, conditionalStyles, addedStyles] =
const [, condStyles, literalStyleSpec] =
zacsMethod === 'styled' || zacsMethod === 'createStyled'

@@ -572,6 +605,3 @@ ? init.arguments.slice(1)

if (
conditionalStyles &&
!(t.isObjectExpression(conditionalStyles) || t.isNullLiteral(conditionalStyles))
) {
if (condStyles && !(t.isObjectExpression(condStyles) || t.isNullLiteral(condStyles))) {
throw path.buildCodeFrameError(

@@ -584,5 +614,8 @@ 'Conditional styles (second argument to ZACS) should be an object expression',

if (addedStyles && !(t.isObjectExpression(addedStyles) || t.isNullLiteral(addedStyles))) {
if (
literalStyleSpec &&
!(t.isObjectExpression(literalStyleSpec) || t.isNullLiteral(literalStyleSpec))
) {
throw path.buildCodeFrameError(
'Added styles (second argument to ZACS) should be an object expression',
'Literal styles (third argument to ZACS) should be an object expression',
)

@@ -609,2 +642,17 @@

function validateZacsImport(t, path) {
const { node } = path
if (
!(
node.specifiers.length === 1 &&
t.isImportDefaultSpecifier(node.specifiers[0]) &&
node.specifiers[0].local.name === 'zacs'
)
) {
throw path.buildCodeFrameError(
'ZACS import must say exactly `import zacs from \'@nozbe/zacs\'`. Other forms such as `import { view, text }`, `require`, `import * as zacs` are not allowed.',
)
}
}
function transformZacsAttributesOnNonZacsElement(t, platform, path) {

@@ -708,3 +756,3 @@ // this is called on a JSXElement that doesn't (directly) reference a zacs declaration

)
const [mainStyle, conditionalStyles, addedStyles] =
const [uncondStyles, condStyles, literalStyleSpec] =
zacsMethod === 'styled' ? init.arguments.slice(1) : init.arguments

@@ -725,7 +773,7 @@ const originalAttributes = openingElement.attributes

openingElement.attributes,
conditionalStyles,
addedStyles,
condStyles,
literalStyleSpec,
)
// replace definition
// replace component
if (platform === 'web') {

@@ -754,5 +802,5 @@ renameJSX(node, elementName)

platform,
mainStyle,
conditionalStyles,
addedStyles,
uncondStyles,
condStyles,
literalStyleSpec,
originalAttributes,

@@ -782,2 +830,19 @@ ),

},
ImportDeclaration(path, state) {
const { node } = path
if (
!node.source ||
// Make it work even if someone makes a fork of zacs
!(node.source.value === 'zacs' || node.source.value.endsWith('/zacs'))
) {
return
}
validateZacsImport(t, path)
if (!state.opts.keepDeclarations) {
path.remove()
}
},
},

@@ -784,0 +849,0 @@ }

@@ -10,3 +10,3 @@ /* eslint-disable */

methodName +
'method called directly (not transpiled). Your Babel file is probably misconfigured or you have a syntax error. See https://github.com/Nozbe/zacs#troubleshooting for more info',
'method was called directly (was not transpiled into zero-abstraction-cost form). This is an error. Most likely, you have a syntax error, your Babel configuration file is misconfigured, or you incorrectly use ZACS declarations as component objects. In fact, unless you pass { keepDeclarations: true } to ZACS Babel config, you should never see this file in the compiled app. See https://github.com/Nozbe/zacs#troubleshooting for more information.',
)

@@ -13,0 +13,0 @@ }

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