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.9.3 to 0.10.0-1

3

CHANGELOG.md

@@ -7,2 +7,5 @@ # Changelog

- 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
## 0.9.3 (2019-09-27)

@@ -9,0 +12,0 @@

2

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

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -25,2 +25,6 @@ <p align="center">

| <a href="https://youtube.com/watch?v=ryMvNklnDjU"><img src="https://github.com/Nozbe/ZACS/raw/master/assets/youtube-thumbnail.jpg" alt="React Native EU: A Successful Web & React Native Sharing Strategy" width="400" /></a> |
| ---- |
| <p align="center"><a href="https://youtube.com/watch?v=ryMvNklnDjU">📺 <strong>A Successful Web & React Native Sharing Strategy</strong></p> |
**ZACS** turns React components that look like this:

@@ -78,3 +82,4 @@

+ "platform": "web", // or "native"
+ "production": true // pass `false` to enable debug attributes
+ "production": true, // pass `false` to enable debug attributes
+ "keepDeclarations": false // pass `true` to keep zacs.xxx variable declarations in output
+ }]

@@ -185,3 +190,3 @@ ]

### Adding style attributes
### Adding style attributes (via individual props)

@@ -219,2 +224,13 @@ ```js

### Adding styles directly
```js
const Box = zacs.view(styles.box)
const rendered = <Box zacs:style={{ width: 100, color: '#80EADC' }} />
```
This is equivalent to the example above, but instead of predefining list of props that turn into styles,
we pass styles directly. Note that this only works on ZACS components.
### Styling custom components

@@ -305,2 +321,8 @@

If you're only building for one platform, you can also reference built-ins like this:
```js
const Paragraph = zacs.styled('p', styles.paragraph) // NOTE: No web/native, because this is web-only code
```
**TODO:** Passing `zacs.text/view` as parameter seems magic and gross. If you have a better idea for this API, let us know!

@@ -342,3 +364,3 @@

You must declare (in the last argument) all non-zacs props you want to be able to pass into the component you're styling (component props, DOM attributes, `ref`, and `zacs:inherit`).
You must declare (in the last argument) all non-zacs props you want to be able to pass into the component you're styling (component props, DOM attributes, `ref`, and `zacs:inherit`, `zacs:style`).

@@ -412,2 +434,14 @@ <details>

### Style precedence
From least important to most important:
- main style (first argument to `zacs.xxx()`)
- conditional styles (second argument to `zacs.xxx()`)
- styles added via props (third argument to `zacs.xxx()`)
- styles added via `zacs:style`
- styles added via `zacs:inherit`
For example, `width` passed via `zacs:inherit` will override `width` added via props.
## Defining styles

@@ -414,0 +448,0 @@

@@ -133,6 +133,6 @@ /* eslint-disable no-use-before-define */

function findZacsInherited(t, attributes) {
function findNamespacedAttr(t, attributes, attrName) {
return attributes.find(
({ name }) =>
t.isJSXNamespacedName(name) && name.namespace.name === 'zacs' && name.name.name === 'inherit',
t.isJSXNamespacedName(name) && name.namespace.name === 'zacs' && name.name.name === attrName,
)

@@ -197,4 +197,14 @@ }

// TODO: Validate zacs:style value
// TODO: If the value is a simple object, we could merge them into addedStyles. OTOH, maybe another
// optimizer Babel plugin can do it further down the line?
const zacsStyleAttribute = jsxAttributes && findNamespacedAttr(t, jsxAttributes, 'style')
const hasZacsStyleAttr = zacsStyleAttribute || passedProps.includes('zacs:style')
const zacsStyle = hasZacsStyleAttr
? (zacsStyleAttribute && zacsStyleAttribute.value.expression) ||
t.memberExpression(t.identifier('props'), t.identifier('__zacs_style'))
: null
// TODO: Validate inherited props value
const inheritedPropsAttr = jsxAttributes && findZacsInherited(t, jsxAttributes)
const inheritedPropsAttr = jsxAttributes && findNamespacedAttr(t, jsxAttributes, 'inherit')
const hasInheritedProps = inheritedPropsAttr || passedProps.includes('zacs:inherit')

@@ -209,2 +219,3 @@ const inheritedProps = hasInheritedProps

inheritedProps,
zacsStyle,
]

@@ -238,24 +249,23 @@ }

function webStyleExpr(t, styles, inheritedProps) {
if (inheritedProps) {
const inheritedStyles = t.memberExpression(inheritedProps, t.identifier('style'))
function webStyleExpr(t, styles, inheritedProps, zacsStyle) {
const inheritedStyles = inheritedProps
? t.memberExpression(inheritedProps, t.identifier('style'))
: null
const allStyles = [styles, zacsStyle, inheritedStyles].filter(Boolean)
if (styles) {
// Object.assign({styles:'values'}, props.style)
// TODO: Maybe we can use spread operator and babel will transpile it into ES5 if necessary?
return t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('assign')), [
styles,
inheritedStyles,
])
}
// only inherited styles
return inheritedStyles
if (!allStyles.length) {
return null
} else if (allStyles.length === 1) {
return allStyles[0]
}
// only defined styles
return styles
// Object.assign({styles:'values'}, props.style)
// TODO: Maybe we can use spread operator and babel will transpile it into ES5 if necessary?
return t.callExpression(
t.memberExpression(t.identifier('Object'), t.identifier('assign')),
allStyles,
)
}
function webStyleAttributes(t, [classNames, styles, inheritedProps]) {
function webStyleAttributes(t, [classNames, styles, inheritedProps, zacsStyle]) {
const attributes = []

@@ -282,3 +292,3 @@

const stylesValue = webStyleExpr(t, styles, inheritedProps)
const stylesValue = webStyleExpr(t, styles, inheritedProps, zacsStyle)
if (stylesValue) {

@@ -291,3 +301,3 @@ attributes.push(jsxAttr(t, 'style', stylesValue))

function nativeStyleAttributes(t, [styleDefs, addedStyles, inheritedProps]) {
function nativeStyleAttributes(t, [styleDefs, addedStyles, inheritedProps, zacsStyle]) {
const styles = styleDefs.map(([styleName, condition]) =>

@@ -301,2 +311,6 @@ condition ? t.logicalExpression('&&', condition, styleName) : styleName,

if (zacsStyle) {
styles.push(zacsStyle)
}
if (!styles.length && !inheritedProps) {

@@ -450,3 +464,3 @@ return []

platform === 'web' && htmlElements.has(elementName) ? isAttributeWebSafe(prop) : true
if (prop !== 'zacs:inherit' && prop !== 'ref' && isAttrWebSafe) {
if (prop !== 'zacs:inherit' && prop !== 'zacs:style' && prop !== 'ref' && isAttrWebSafe) {
jsxAttributes.push(

@@ -502,2 +516,8 @@ jsxAttr(t, prop, t.memberExpression(t.identifier('props'), t.identifier(prop))),

// Validate variable name
if (!t.isIdentifier(node.id)) {
throw path.buildCodeFrameError('Expected zacs declaration to be assigned to a simple variable')
}
// Validate declaration

@@ -580,25 +600,41 @@ if (

// this is called on a JSXElement that doesn't (directly) reference a zacs declaration
// we need to spread zacs:inherit into separate props or it won't work
// we need to spread zacs:inherit and zacs:style into separate props or it won't work
const { node } = path
const { openingElement } = node
const inheritedPropsAttr = findZacsInherited(t, openingElement.attributes)
if (!inheritedPropsAttr) {
const inheritedPropsAttr = findNamespacedAttr(t, openingElement.attributes, 'inherit')
const zacsStyleAttr = findNamespacedAttr(t, openingElement.attributes, 'style')
if (!inheritedPropsAttr && !zacsStyleAttr) {
return
}
const inheritedProps = inheritedPropsAttr.value.expression
const styleAttr = jsxAttr(t, 'style', t.memberExpression(inheritedProps, t.identifier('style')))
const classNameAttr = jsxAttr(
t,
'className',
t.memberExpression(inheritedProps, t.identifier('className')),
)
const addedAttrs = platform === 'web' ? [styleAttr, classNameAttr] : [styleAttr]
const addedAttrs = []
if (inheritedPropsAttr) {
const inheritedProps = inheritedPropsAttr.value.expression
const styleAttr = jsxAttr(t, 'style', t.memberExpression(inheritedProps, t.identifier('style')))
addedAttrs.push(styleAttr)
if (platform === 'web') {
const classNameAttr = jsxAttr(
t,
'className',
t.memberExpression(inheritedProps, t.identifier('className')),
)
addedAttrs.push(classNameAttr)
}
}
if (zacsStyleAttr) {
// rewrite zacs:style to __zacs_style, otherwise React babel plugin will have a problem
addedAttrs.push(jsxAttr(t, '__zacs_style', zacsStyleAttr.value.expression))
}
openingElement.attributes = openingElement.attributes
.filter(attr => attr !== inheritedPropsAttr)
.filter(attr => attr !== inheritedPropsAttr && attr !== zacsStyleAttr)
.concat(addedAttrs)
}
const componentKey = name => `declaration_${name}`
exports.default = function(babel) {

@@ -623,2 +659,13 @@ const { types: t } = babel

node.init = createZacsComponent(t, state, path)
} else {
const id = node.id.name
const stateKey = componentKey(id)
if (state.get(stateKey)) {
throw path.buildCodeFrameError(`Duplicate ZACS declaration for name: ${id}`)
}
state.set(stateKey, node)
if (!state.opts.keepDeclarations) {
path.remove()
}
}

@@ -630,13 +677,7 @@ },

const { name } = openingElement.name
const platform = getPlatform(state)
// check if element is referenced (i.e. not built-in element)
const binding = path.scope.getBinding(name)
if (!binding) {
return
}
// check if it's a ZACS element
const elementDeclarator = binding.path.node
const platform = getPlatform(state)
if (!isZacsDeclaration(t, elementDeclarator)) {
const declaration = state.get(componentKey(name))
if (!declaration) {
transformZacsAttributesOnNonZacsElement(t, platform, path)

@@ -649,3 +690,3 @@ return

// get ZACS element info
const { id, init } = elementDeclarator
const { id, init } = declaration
const originalName = id.name

@@ -652,0 +693,0 @@ const zacsMethod = init.callee.property.name

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