Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/css extraction (WIP) #1903

Open
wants to merge 15 commits into
base: patch
Choose a base branch
from
Open
6 changes: 6 additions & 0 deletions packages/styled/babel-plugin/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
"module:metro-react-native-babel-preset"
]
// "plugins": ["transform-remove-console"]
}
28 changes: 28 additions & 0 deletions packages/styled/babel-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
.pnp
.pnp.js

# misc
.DS_Store
*.pem

# build
dist
lib

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# turbo
.turbo
1 change: 1 addition & 0 deletions packages/styled/babel-plugin/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16.13.0
29 changes: 29 additions & 0 deletions packages/styled/babel-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# @gluestack-style/babel-plugin-styled-resolver

## 1.0.2

### Patch Changes

- Added dynamic config resolution [PR](https://github.com/gluestack/gluestack-style/pull/550)

## 1.0.1

### Features

- Added utility props resolution [PR](https://github.com/gluestack/gluestack-style/pull/519)

## 0.1.14

### Patch Changes

- Fixes

- Support for `createConfig` API.

## 0.1.0

## Features

- Add path based resolution
- Add library name alias
- Add support for styled function aliasing
35 changes: 35 additions & 0 deletions packages/styled/babel-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# @gluestack-style/babel-plugin-styled-resolver

## Installation

To use `@gluestack-style/babel-plugin-styled-resolver`, all you need to do is install the
`@gluestack-style/babel-plugin-styled-resolver` package:

```sh
$ yarn add @gluestack-style/babel-plugin-styled-resolver

# or

$ npm i @gluestack-style/babel-plugin-styled-resolver
```

## Usage

Add Babel plugin to your app `babel.config.js`.

```jsx
const path = require('path');
const gluestackStyleResolver = require('@gluestack-style/babel-plugin-styled-resolver');
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [gluestackStyleResolver],
};
};
```

Just make sure your babel.config.js and gluestack-style.config.js/ts are in the same directory. We suggest you keep both of them at the root of your app codebase.

More guides on how to get started are available
[here](https://gluestack.io/style).
69 changes: 69 additions & 0 deletions packages/styled/babel-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"name": "@gluestack-style/extract-styles",
"version": "0.0.1",
"description": "A gluestack-style babel plugin that transpiles your styled function calls and resolves the component styling in build time.",
"keywords": [
"css-in-js",
"babel-plugin",
"server-side rendering",
"ssr"
],
"homepage": "https://github.com/gluestack/gluestack-ui/tree/main/packages/styled/babel-plugin-styled-resolver#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/gluestack/gluestack-ui.git"
},
"main": "lib/commonjs/index",
"types": "lib/typescript/index.d.ts",
"module": "lib/module/index",
"react-native": "src/index",
"source": "src/index",
"typings": "lib/typescript/index.d.ts",
"scripts": {
"prepare": "bob build",
"release": "release-it",
"build": "bob build",
"clean": "rm -rf lib",
"watch": "npx nodemon --watch src/index.js --watch src/extract-styles.js --watch src/extract-config.ts --exec 'yarn build'"
},
"peerDependencies": {
"@gluestack-style/react": ">=1.0"
},
"devDependencies": {
"@babel/cli": "^7.19.3",
"@babel/preset-env": "^7.20.2",
"@types/lodash.merge": "^4.6.7",
"babel-plugin-transform-remove-console": "^6.9.4",
"react-native-builder-bob": "^0.20.1",
"tsconfig": "*",
"typescript": "^4.7.4"
},
"dependencies": {
"@babel/core": "^7.23.5",
"@babel/generator": "^7.20.5",
"@babel/parser": "^7.20.5",
"@babel/plugin-transform-typescript": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@babel/traverse": "^7.20.5",
"@gluestack-style/build-config": "*",
"lodash.merge": "^4.6.2"
},
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"typescript",
[
"module",
{
"babelrc": true
}
]
]
},
"files": [
"lib/",
"src/"
]
}
94 changes: 94 additions & 0 deletions packages/styled/babel-plugin/src/extract-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
convertTokensToCssVariables,
platformSpecificSpaceUnits,
//@ts-ignore
} from '@gluestack-style/react/lib/commonjs/utils';
//@ts-ignore
import { resolveThemes } from '@gluestack-style/react/lib/commonjs/createConfig';
//@ts-ignore
import { updateOrderUnResolvedMap } from '@gluestack-style/react/lib/commonjs/updateOrderUnResolvedMap';
import {
convertStyledToStyledVerbosed,
//@ts-ignore
} from '@gluestack-style/react/lib/commonjs/convertSxToSxVerbosed';
const {
stableHash,
} = require('@gluestack-style/react/lib/commonjs/stableHash');
//@ts-ignore
import { StyleInjector } from '@gluestack-style/react/lib/commonjs/style-sheet';
//@ts-ignore
import { propertyTokenMap } from '@gluestack-style/react/lib/commonjs/propertyTokenMap';

function extractGlobalStyles(CONFIG: any = {}, theme: any = {}) {
const GluestackStyleSheet = new StyleInjector();
const verbosedTheme = convertStyledToStyledVerbosed(theme);

const globalStyleHash = stableHash({
...theme,
});

const { styledIds } = updateOrderUnResolvedMap(
verbosedTheme,
globalStyleHash,
'global',
{},
GluestackStyleSheet,
'web'
);

const toBeInjected = GluestackStyleSheet.resolve(styledIds, CONFIG, {
propertyTokenMap,
});

const current_global_map = GluestackStyleSheet.getStyleMap();

const orderedResolvedTheme = [];

current_global_map?.forEach((styledResolved: any) => {
if (styledIds.includes(styledResolved?.meta?.cssId)) {
orderedResolvedTheme.push(styledResolved);
}
});

return toBeInjected;
}

export function extractGluestackConfig(gluestackConfig: any) {
let configWithPlatformSpecificUnits: any = platformSpecificSpaceUnits(
{ ...gluestackConfig },
'web'
);

if (gluestackConfig?.themes) {
Object.keys(gluestackConfig.themes).forEach((key) => {
configWithPlatformSpecificUnits.themes[key] = platformSpecificSpaceUnits(
//@ts-ignore
{ tokens: gluestackConfig.themes[key] },
'web'
)?.tokens;
});
}

configWithPlatformSpecificUnits = resolveThemes(
configWithPlatformSpecificUnits
);

let cssVariablesConovertedTokens = convertTokensToCssVariables(
configWithPlatformSpecificUnits
)?.trim('\n');

cssVariablesConovertedTokens += '\n';

const globalStylesCSS = extractGlobalStyles(
configWithPlatformSpecificUnits,
configWithPlatformSpecificUnits?.globalStyle
);

Object.keys(globalStylesCSS).forEach((type) => {
globalStylesCSS[type].forEach(({ cssRuleset }: any) => {
cssVariablesConovertedTokens += `${cssRuleset}\n`;
});
});

return cssVariablesConovertedTokens;
}
Loading
Loading