Skip to content

Commit

Permalink
feat: jss package and fix to native test
Browse files Browse the repository at this point in the history
  • Loading branch information
mauroerta committed May 18, 2021
1 parent a59ca92 commit 30b6c4a
Show file tree
Hide file tree
Showing 19 changed files with 411 additions and 9 deletions.
153 changes: 153 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# @morfeo

Morfeo it's a set of tools that helps you to build **consistent UIs** based on a single source of truth: the **theme**.

You can use it with any framework like `React`, `React Native`, `Vue`, `Angular`, `svelte` or `vanilla`.

In other words, morfeo will transform this:

```typescript
{
componentName: 'Button',
variant: 'primary',
}
```

into this:

```typescript
{
color: '#e3e3e3',
backgroundColor: '#fff',
borderRadius: '20px',
'&:hover': {
opacity: 0.4,
},
}
```

Or, into a plain css:

```css
.button-primary {
color: #e3e3e3;
background-color: #fff;
border-radius: 20px;
}

.button-primary:hover {
opacity: 0.4;
}
```

By using a bit of magic explained [here](#how-it-works)

morfeo is cross-framework, but to have a faster implementation and a better developer experience we create a set of packages that integrates morfeo with the most used frameworks like:

**@morfeo/web** required if you're run in a browser

**@morfeo/native** perfect for React native

**@morfeo/styled-components-web** deep integration with styled-components

**@morfeo/angular** **_coming soon_**

**@morfeo/jss** perfect for svelte

**@morfeo/hooks** hook for React/React Native

| Branches | Functions | Lines | Statements |
| ------------------------------------------- | -------------------------------------------- | ---------------------------------------- | --------------------------------------------- |
| ![logo](./assets/badges/badge-branches.svg) | ![logo](./assets/badges/badge-functions.svg) | ![logo](./assets/badges/badge-lines.svg) | ![logo](./assets/badges/badge-statements.svg) |

## Motivations

When your application start to grow, maintain UI consistency it's not easy.
Even in popular applications we often face **wrong typographies**, different **color pallettes** used across different pages or inconsistent **spacings** in each component.

These problems are even more frequent in large applications where different teams works on different features (maybe with different technologies and frameworks).

**morfeo** solves this problem by sharing across all the application a customizable `theme` that contains the "language" of the application design and a `parser` that generate styles based on this language, in this way the UIs an the components are always consistent.

## How it works

The main concepts around morfeo are 2 entities, **theme** and **parsers**:

`theme` it's an handler that contains the **design language** of your application, for example a set of colors, spacings, shadows, sizes and gradients, and example of theme could be the following:

```typescript
import { theme } from '@morfeo/core';

const defaultTheme = {
color: {
primary: '#000',
secondary: '#e3e3e3',
danger: '#eb2f06',
success: '#78e08f',
warning: '#fa983a',
},
space: {
xxs: '8px',
xs: '16px',
s: '24px',
m: '32px',
l: '40px',
xl: '48px',
xxl: '56px',
},
components: {
Button: {
style: {
color: 'primary',
padding: 's',
},
},
},
};

// From now on the theme will be available in all your application
theme.set(defaultTheme);

console.log(theme.get()); // will log an object equals to `defaultTheme`
console.log(theme.getValue('colors', 'primary')); // will log #000
```

Once you have a centralized theme, you need to parse this theme to generate the style for your components an layouts, here is where the `parsers` handler start to play!

This is an example with React

```tsx
import { theme, parsers } from '@morfeo/core';

function Button() {
const style = parsers.resolve({ style: { componentName: 'Button' } });

return <button style={style}>Click me</button>;
}
```

Or if you want, you can use the hooks inside the package `@morfeo/hook`

```tsx
import { theme } from '@morfeo/core';
import { useStyle } from '@morfeo/hooks';

function Button() {
const style = useStyle({ componentName: 'Button' });

return <button style={style}>Click me</button>;
}
```

The value of `style` will be in this example equals to:

```json
{
"color": "#000",
"padding": "16px"
}
```

## Features

WIP
8 changes: 5 additions & 3 deletions apps/benchmarks/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "benchmarks",
"version": "0.0.7",
"version": "0.0.1",
"private": true,
"author": {
"name": "Mauro Erta",
Expand All @@ -9,13 +9,15 @@
"scripts": {
"morfeo-vs": "node src/morfeo-vs/index.js",
"core": "node src/core/index.js",
"all": "npm run core && npm run morfeo-vs"
"jss": "node src/jss/index.js",
"all": "npm run core && npm run jss && npm run morfeo-vs"
},
"devDependencies": {
"benchmark": "^2.1.4"
},
"dependencies": {
"@morfeo/core": "^0.0.7",
"@morfeo/core": "^0.0.8",
"@morfeo/jss": "^0.0.8",
"styled-system": "5.1.5"
}
}
17 changes: 17 additions & 0 deletions apps/benchmarks/results/jss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# @morfeo/jss

## @morfeo/jss speed compared to @morfeo/core

```json
{
"button": {
"color": "primary"
}
}
```

**regular parsing** 2,588,520 ops/sec ±1.37% (89 runs sampled)

**with cache enabled** 213,422 ops/sec ±2.30% (85 runs sampled)

Fastest is **regular parsing**
37 changes: 37 additions & 0 deletions apps/benchmarks/src/jss/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { theme } = require('@morfeo/core');
const { writeMdTitle } = require('./utils');
const jssVsCoreSuite = require('./jssVsCore');

theme.set({
colors: {
primary: 'black',
secondary: 'white',
},
space: {
s: '10px',
m: '20px',
},
shadows: {
light: {
color: 'primary',
offset: { width: 2, height: 2 },
opacity: 0.4,
radius: 20,
},
},
components: {
Box: {
style: {
bg: 'primary',
color: 'secondary',
px: 'm',
my: 's',
shadow: 'light',
},
},
},
});

writeMdTitle(`# @morfeo/jss`);

jssVsCoreSuite.run({ async: false });
29 changes: 29 additions & 0 deletions apps/benchmarks/src/jss/jssVsCore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const Benchmark = require('benchmark');
const { parsers } = require('@morfeo/core');
const { getStyle } = require('@morfeo/jss');
const { onCycle, onComplete, onStart } = require('./utils');

const suite = new Benchmark.Suite();

const styles = { button: { color: 'primary' } };

suite
.add('regular parsing', () => {
Object.keys(styles).reduce((acc, key) => {
const style = styles[key];
return {
...acc,
[key]: parsers.resolve({ style }),
};
}, {});
})
.add('with cache enabled', () => {
getStyle(styles);
})
.on('start', () =>
onStart('@morfeo/jss speed compared to @morfeo/core', styles),
)
.on('cycle', onCycle)
.on('complete', () => onComplete(suite));

module.exports = suite;
45 changes: 45 additions & 0 deletions apps/benchmarks/src/jss/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const {
getMdPath,
onCycle: _onCycle,
onStart: _onStart,
writeInMd: _writeInMd,
appendInMd: _appendInMd,
onComplete: _onComplete,
writeMdTitle: _writeMdTitle,
} = require('../utils');

const mdPath = getMdPath('jss');

function writeInMd(text) {
_writeInMd(mdPath, text);
}

function appendInMd(text) {
appendInMd(mdPath, `\n\n${text}`);
}

function writeMdTitle(title) {
_writeInMd(mdPath, `${title}`);
}

function onStart(title, style) {
_onStart(mdPath, title, style);
}

function onCycle(event) {
_onCycle(mdPath, event);
}

function onComplete(suite) {
_onComplete(mdPath, suite);
}

module.exports = {
onCycle,
onStart,
getMdPath,
writeInMd,
appendInMd,
onComplete,
writeMdTitle,
};
1 change: 1 addition & 0 deletions assets/badges/badge-branches.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/badges/badge-functions.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/badges/badge-lines.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/badges/badge-statements.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ module.exports = {
},
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
branches: 90,
functions: 90,
lines: 90,
statements: 90,
},
},
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"test": "jest --updateSnapshot",
"test:watch": "jest --watch --updateSnapshot",
"test:coverage": "jest --coverage --updateSnapshot",
"test:badges": "npm run test:coverage && jest-coverage-badges",
"test:badges": "npm run test:coverage && jest-coverage-badges output \"./assets/badges\"",
"publish": "npx lerna publish from-package --yes",
"version": "npx lerna version patch --no-push --no-git-tag-version --conventional-commits"
},
Expand Down
34 changes: 34 additions & 0 deletions packages/jss/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@morfeo/jss",
"author": {
"name": "Mauro Erta",
"email": "mauro@vlkstudio.com"
},
"private": false,
"version": "0.0.8",
"license": "MIT",
"main": "build/index.js",
"module": "build/index.js",
"types": "build/index",
"typings": "build/index",
"keywords": [
"design",
"system",
"jss"
],
"scripts": {
"build": "rimraf build && tsc",
"watch": "tsc -w"
},
"dependencies": {
"@morfeo/web": "^0.0.8",
"jss": "^10.6.0",
"jss-preset-default": "^10.6.0"
},
"publishConfig": {
"access": "public"
},
"files": [
"build"
]
}
Loading

0 comments on commit 30b6c4a

Please sign in to comment.