Skip to content

Commit

Permalink
feat: make tsup compatible with tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeirojose committed Oct 26, 2023
1 parent d8f753e commit fc7af47
Show file tree
Hide file tree
Showing 17 changed files with 21,287 additions and 14,125 deletions.
2 changes: 0 additions & 2 deletions .github/FUNDING.yml

This file was deleted.

17 changes: 9 additions & 8 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
with:
node-version: lts/*
cache: 'yarn'
registry-url: 'https://npm.pkg.github.com'
scope: '@bleu'

- name: Install dependencies
run: yarn install --frozen-lockfile
Expand All @@ -30,11 +32,10 @@ jobs:
env:
GH_TOKEN: ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}

# - name: Build and publish to npm
# if: github.ref == 'refs/tags/v*' # Only run on version tags
# run: |
# yarn build
# npm login --registry=https://registry.npmjs.org/ --scope=your-scope
# npm publish
# env:
# NODE_AUTH_TOKEN: ${{ secrets.YOUR_NPM_AUTH_TOKEN }}
- name: Build and publish to npm
if: github.ref == 'refs/tags/v*'
run: |
yarn build
npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,11 @@ yarn-error.log*
.env.production.local

storybook-static

.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
35 changes: 35 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import type { StorybookConfig } from '@storybook/react-webpack5';

import { withThemeByDataAttribute } from '@storybook/addon-themes';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-styling-webpack',
{
name: '@storybook/addon-styling-webpack',

options: {
rules: [
{
test: /\.css$/,
sideEffects: true,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {},
},
],
},
],
},
},
],
framework: {
name: '@storybook/react-webpack5',
Expand All @@ -14,4 +37,16 @@ const config: StorybookConfig = {
autodocs: 'tag',
},
};

export const decorators = [
withThemeByDataAttribute({
themes: {
light: 'light',
dark: 'dark',
},
defaultTheme: 'light',
attributeName: 'data-mode',
}),
];

export default config;
2 changes: 2 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import '../dist/index.css';

import type { Preview } from '@storybook/react';

const preview: Preview = {
Expand Down
893 changes: 893 additions & 0 deletions .yarn/releases/yarn-4.0.0.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.0.0.cjs
69 changes: 69 additions & 0 deletions classesExtractor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* eslint-disable global-require, @typescript-eslint/no-var-requires */
const { defaultExtractor } = require('tailwindcss/lib/lib/defaultExtractor');

/**
* Injects the given prefix to the class string
*
* @param prefix - The prefix to be added
* @param className - The class string
*
* @returns The prefixed class string
*/
const prefixClassName = (prefix, className) => {
const parts = className.split(':');
const modifiers = parts.slice(0, parts.length - 1);
const actualClass = parts[parts.length - 1];
let classWithPrefix = `${prefix}${actualClass}`;

if (actualClass.startsWith('-')) {
classWithPrefix = `-${prefix}${actualClass.slice(1, actualClass.length)}`;
}

if (modifiers.length === 0) {
return classWithPrefix;
}

return `${modifiers.join(':')}:${classWithPrefix}`;
};

/**
* This function injects the given prefix to all possible class elements
* in a project. This is useful to guarantee that tailwind classes without
* the prefix will also be taken into consideration by PurgeCSS
*
* For instance, let us say that we have an application A, which sets the
* prefix `sf-`. All classes of this application must have the `sf-`
* prefix (e.g. `sf-w-50`)
*
* We also have package B, with no prefix set. Classes inside this package do not
* require any prefix (e.g. `w-100`)
*
* If application A uses a component from package B, tailwind will purge classes
* that don't have the `sf-` prefix, including the classes from package B. By using
* this extractor instead will tell tailwind to add `sf-` to classes from package B,
* so their CSS is also included in the final build
*
* @example
*
* // On tailwind.config.js
* module.exports = {
* content: {
* files: [...],
* extract: classesExtractor("ANY-PREFIX"),
* }
* };
*
* @param prefix - The project's prefix
*/
module.exports = (prefix) => {
if (!prefix) return defaultExtractor;

return (content) =>
defaultExtractor(content).map((element) =>
element
.replace(prefix, '')
.split(' ')
.map((className) => prefixClassName(prefix, className))
.join(' ')
);
};
82 changes: 47 additions & 35 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "tsup-react-package-starter",
"name": "@bleu/ui",
"description": "",
"version": "0.0.0",
"author": "",
Expand All @@ -25,6 +25,7 @@
"release": "yarn build && yarn release-it",
"link:self": "yarn yalc publish && yarn link"
},
"main": "dist/index.js",
"tsup": {
"entry": [
"src/index.ts"
Expand All @@ -49,7 +50,8 @@
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
},
"./index.css": "./dist/index.css"
},
"files": [
"dist"
Expand Down Expand Up @@ -80,65 +82,70 @@
"node": ">=14.0.0"
},
"devDependencies": {
"@babel/core": "7.23.0",
"@babel/preset-env": "7.22.20",
"@babel/core": "7.23.2",
"@babel/preset-env": "7.23.2",
"@babel/preset-react": "7.22.15",
"@babel/preset-typescript": "7.23.0",
"@commitlint/cli": "17.7.2",
"@commitlint/config-conventional": "17.7.0",
"@babel/preset-typescript": "7.23.2",
"@commitlint/cli": "18.2.0",
"@commitlint/config-conventional": "18.1.0",
"@ryansonshine/commitizen": "4.2.8",
"@ryansonshine/cz-conventional-changelog": "3.3.4",
"@storybook/addon-essentials": "7.4.5",
"@storybook/addon-interactions": "7.4.5",
"@storybook/addon-links": "7.4.5",
"@storybook/blocks": "7.4.5",
"@storybook/react": "7.4.5",
"@storybook/react-webpack5": "7.4.5",
"@storybook/addon-essentials": "7.5.1",
"@storybook/addon-interactions": "7.5.1",
"@storybook/addon-links": "7.5.1",
"@storybook/addon-styling-webpack": "^0.0.5",
"@storybook/addon-themes": "^7.5.1",
"@storybook/blocks": "7.5.1",
"@storybook/react": "7.5.1",
"@storybook/react-webpack5": "7.5.1",
"@storybook/storybook-deployer": "2.8.16",
"@storybook/testing-library": "0.2.1",
"@testing-library/jest-dom": "^6.0.0",
"@storybook/testing-library": "0.2.2",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.0.0",
"@types/node": "20.8.0",
"@types/react": "18.2.24",
"@types/react-dom": "18.2.8",
"@types/react-test-renderer": "18.0.3",
"@typescript-eslint/eslint-plugin": "6.7.3",
"@typescript-eslint/parser": "6.7.3",
"@vitejs/plugin-react": "^4.0.3",
"@vitest/coverage-v8": "^0.34.0",
"@types/node": "20.8.9",
"@types/react": "18.2.33",
"@types/react-dom": "18.2.14",
"@types/react-test-renderer": "18.0.5",
"@typescript-eslint/eslint-plugin": "6.9.0",
"@typescript-eslint/parser": "6.9.0",
"@vitejs/plugin-react": "^4.1.0",
"@vitest/coverage-v8": "^0.34.6",
"babel-loader": "9.1.3",
"concurrently": "8.2.1",
"eslint": "8.50.0",
"concurrently": "8.2.2",
"css-loader": "^6.8.1",
"eslint": "8.52.0",
"eslint-config-airbnb": "19.0.4",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-prettier": "5.0.0",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-react": "7.33.2",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-sort-class-members": "^1.18.0",
"eslint-plugin-storybook": "0.6.14",
"eslint-plugin-typescript-sort-keys": "3.0.0",
"eslint-plugin-sort-class-members": "^1.19.0",
"eslint-plugin-storybook": "0.6.15",
"eslint-plugin-typescript-sort-keys": "3.1.0",
"eslint-plugin-unused-imports": "3.0.0",
"husky": "8.0.3",
"jsdom": "^22.1.0",
"lint-staged": "14.0.1",
"lint-staged": "15.0.2",
"prettier": "3.0.3",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-test-renderer": "18.2.0",
"release-it": "16.2.1",
"storybook": "7.4.5",
"storybook": "7.5.1",
"style-loader": "^3.3.3",
"tailwindcss": "^3.3.5",
"tsup": "7.2.0",
"typescript": "5.2.2",
"vitest": "^0.34.0",
"vitest": "^0.34.6",
"yalc": "1.0.0-pre.53"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
"react": ">=18",
"react-dom": ">=18"
},
"resolutions": {
"glob-parent": ">=5.1.2",
Expand All @@ -147,5 +154,10 @@
"trim": ">=0.0.3",
"trim-newlines": ">=3.0.1",
"yaml": ">=2.2.2"
},
"packageManager": "[email protected]",
"dependencies": {
"autoprefixer": "^10.4.16",
"client-only": "^0.0.1"
}
}
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
3 changes: 3 additions & 0 deletions src/Example.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'client-only';

import './Example.css';

import React from 'react';
Expand All @@ -13,6 +15,7 @@ export function Example(props: ExampleProps) {
onClick={() => setCount(count + 1)}
type="button"
id="example-button"
className="ui-bg-blue-500 ui-font-bold"
>
{`${props.text} ${count}`}
</button>
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
import './tailwind.css';

export * from './Example';
1 change: 0 additions & 1 deletion src/stories/Example.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import { Meta, StoryFn } from '@storybook/react';

import { Example } from '..';
Expand Down
3 changes: 3 additions & 0 deletions src/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
15 changes: 15 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const CLASSES_PREFIX = 'ui-';

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{html,js,ts,jsx,tsx}'],
theme: {
extend: {},
},
plugins: [],
prefix: CLASSES_PREFIX,
corePlugins: {
preflight: false,
},
darkMode: ['class', 'html[class~="dark"]'],
};
20 changes: 20 additions & 0 deletions tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineConfig } from 'tsup';

export default defineConfig({
minify: true,
// The file we created above that will be the entrypoint to the library.
entry: ['src/index.tsx'],
// Enable TypeScript type definitions to be generated in the output.
// This provides type-definitions to consumers.
dts: true,
// Clean the `dist` directory before building.
// This is useful to ensure the output is only the latest.
clean: true,
// Sourcemaps for easier debugging.
sourcemap: true,
esbuildOptions(options) {
options.banner = {
js: '"use client"',
};
},
});
Loading

0 comments on commit fc7af47

Please sign in to comment.