Git Product home page Git Product logo

electron-vite-react's Introduction

Tailwind + CSS in JS

Full featured Tailwind compiler with CSS in JS support, with blazing fast build and runtime performance

Why does this exist

You may have encountered some of these problems when using Tailwind CSS.

  • You have to use PurgeCSS to get the minimal CSS file, PurgeCSS relies on string matching
  • No warnings when misspelling, refactoring or using a class that doesn't exist
  • Inline classes can get very long and hard to read
  • You have to specify the variants for utility classes in tailwind.config.js
  • No escape hatch to CSS when needed
  • No logic support to allow loops, conditionals, variables, state-based styling, and more
  • No built in theming support
  • No dedicated string support in React classes <MyComponent tw="bg-blue-500" />
  • No dedicate properties in React classes <MyComponent bg-blue-500- >
  • No styled-system-like shorthands <MyComponent bg-="blue-500" >
  • No IDE support typeahead and hover hints for tailwind properties
  • No easy pathway if coming from styled-system
  • Adding a CSS in JS solution like Emotion or Style-Components brings runtime bloat and poorer performance
  • Compile time CSS in JS solutions do not have simple inline support <MyComponent css="line-height: 1.15;" /> and do not support Tailwind
    `
  • Custom Tailwind CSS in JS solutions reimplement Tailwind CSS and so do not keep up to date with Tailwind CSS releases or all the standard plugins
  • Compile time solutions do not pre-evaluate template strings thus requiring a runtime in all but the simplest use cases
  • Require webpack loader or other bundler plugins to generate the CSS classes, requiring more complex build setups and often retraversing the
  • Hard to use the built-in CSS support in in Next.js and other frameworks

Features / Goals

  • Solves all of the above problems
  • No runtime impact all transformations happen during build time
  • Wraps Arthie's @xwind/core low level API to provide new syntax to apply variants to multiple utility classes md:hover[text-xs font-normal] with zero runtime dependencies from Arthie
  • Uses vanilla Tailwind CSS package in static generation logic (thanks to Arthie's great low level API that has done this)
  • Wraps Callstack's @linaria/ low level babel logic to provide zero runtime escape hatch to CSS with zero runtime dependencies from Callstack without requiring extra Babel plugins or presets
  • Pre-evaluates template strings for both CSS and Tailwind classes thanks to Linaria's comprehensive Shaker methodology and new API hooks added to Linaria core package by twstyled contributors
  • Extends @linaria/ to extend zero runtime CSS in JS experience to Tailwind classes
  • Unopionated on whether tailwind is used in JSX attributes, using embedded tw\`` helpers inside css, or as a simple CSS rule @tailwind bg-blue-500 text-white-300`
  • Mix and match Tailwind classnames and regular CSS
  • When using React, adds new JSX properties tw= and css= to inline Tailwind directly in the component, with full variable / logic support
  • Zero runtime when using inline styles, and 1.59Kb runtime (GZip compressed) when using styled components with dynamic variables based on properties only known at runtime
  • Great developer experience with Typescript definitions for every Tailwind property
  • Great developer experience with VS Code extension
  • No dependency on xwind package
  • Encapsulates all build time logic into a single Babel plugin @twstyled/babel-preset
  • Writes all Tailwind css to single twstyled.global.css with all potential styles needed as well as the Tailwind base and global classes, and to individual css files associated with each component that has other CSS in JS included beyond Tailwind
  • Writes generated css directly from the single Babel plugin with no webpack or bundler plugin required
  • Complementary Next.js plugin allows the CSS files to be included directly from each component without requiring changes to _app or _document for CSS in JS code and without requiring a slower webpack loader
  • Babel plugin contains no Next.js, React or other framework specific code and can be re-used in any module bundler or framework
  • Support Tailwind properties directly on React component with full typeahead and hover support
  • Plugin for Babel
  • Plugin for Rollup
  • Plugin for Next.js
  • Plugin for Vite

Installation

npm install --save twstyled @twstyled/babel-preset

or

yarn add twstyled  @twstyled/babel-preset

Use of linaria fork

Until our linaria enhancements to open the API to wrapper packages like this one are included in linaria upstream, please also add the follow resolutions to your package.json file in your workspace root folder to point to our fork of linaria which is published on npm as @twstyled/linaria-babel-preset

// package.json
"resolutions": {
    "@linaria/babel-preset": "npm:@twstyled/[email protected]",
    "@linaria/preeval": "npm:@twstyled/[email protected]"
  },

Usage: installing the Babel preset

Create a babel.config.js in your project

// babel.config.js
"use strict";

module.exports = {
    presets: [
        '@twstyled/babel-preset',
        [
            'next/babel',
            {
                'preset-react': {
                    runtime: 'automatic',
                },
            }
        ],
    ],
    plugins: [],
}

Usage: installing the Next.js plugin (optional)

In addition to the babel preset above, add a next.config.js file to your project:

npm install --save @twstyled/next next-compose-plugins

or

yarn add  @twstyled/next next-compose-plugins
const { withPlugins } = require('next-compose-plugins');

// next.config.js
module.exports = withPlugins(
  [
    require('@twstyled/next'),
  ],
  {}
)

This plugin does not change the bundling but allows any CSS generated by Linaria to be included as CSS modules in each respective component; this is optimal for code-splitting and HTTP delivery of code

Example Code

Simple react code with no extra imports required

export const HeroHeading = (props) => (
  <h1
    tw="font-semibold text-3xl md:text-4xl lg:text-5xl not-italic"
    {...props}
  />
)

This is the recommended approach if you want to share your components with other developers, as the string format is 100% compatible with any Tailwind implementation.

Alternative react code, still with no extra imports required

If you find these strings long and hard to read, you might prefer to have Tailwind utilities directly on the React classes. Every Tailwind class can be used as a (boolean) property directly on the React component, with a suffix of - to keep all Tailwind classes visually and logically distinct from your own properties. Negative properties should use the JSX Expression format below as it would otherwise be hard to see all these minus signs. Variants like hover:, focus: and screen hints are all supported using an array format and a suffix of -- again just to keep these visually distinct.

export const HeroHeading = (props) => (
  <h1 font-semibold- text-3xl- md--={['text-4xl']} lg--={['text-5xl']} not-italic->
    {...props}
  />
)

JSX Expression (Styled-system-like) react code, still with no extra imports required

Every Tailwind class can be used as a prefix and a value property directly on the React component, with a suffix of - to keep all Tailwind classes visually and logically distinct from your own properties.

export const HeroHeading = (props) => (
  <h1 m-={-2} px-={3} font-={theme.fonts.headings} text-="3xl" md--:{['text-4xl']} lg--:{['text-5xl']} not-italic- >
    {...props}
  />
)

Note how you can mix and match any of these formats together.

We recommend this option in all cases that you want to add a small number of style overrides for a given component. One advantage in the IDE and in code excerpts in blogs, is that you can quickly distinguish the type of style override from the actual value of style override. It is also useful if you are converting another library that has used styled system.

Use standard styled syntax like any other CSS in JS library, mix and match CSS and Tailwind code with custom @tailwind rule

import { styled } from '@twstyled/core'

export const HeroHeading styled.h1`
  @tailwind font-semibold text-3xl md:text-4xl lg:text-5xl not-italic;
  line-height: 1.15;

Use advanced styled syntax like any other CSS in JS library

import { styled } from '@twstyled/core'

export const HeroHeading styled.h1`
  @tailwind font-semibold text-3xl md:text-4xl lg:text-5xl not-italic;

  ${mediaqueries.desktop} {
    @tailwind p-1;
    line-height: ${props => props.theme.largeSpacing && 1.15};
  }

Use standard css syntax like any other CSS in JS library, mix and match CSS and Tailwind code with custom @tailwind rule

import { css } from '@twstyled/core'

export const styles = {
  heading1: css`@tailwind font-semibold text-3xl md:text-4xl lg:text-5xl not-italic;  /* standard CSS here */ line-height: 1.15;`
}

const HeroHeading = (props) => (
  <h1 className={styles.heading1}  />
)

React code with deterministic template strings (zero runtime impact)

import { tw } from '@twstyled/core'

const mixin = `font-semibold text-3xl`

const HeroHeading = (props) => (
  <h1 tw={`${mixin} md:text-4xl lg:text-5xl not-italic`}
    {...props}
  />
)

React code with dynamic template strings (automatic conversion to CSS variables)

import { tw } from '@twstyled/core'

const special = `font-semibold text-3xl`

const HeroHeading = (props) => (
  <h1 tw={`md:text-4xl lg:text-5xl ${props => props.isSpecial && special} not-italic`}
    {...props}
  />
)

Advanced -- escape hatch to css when required (and still zero runtime)

import { css } from '@linaria/css'

const HeroHeadingAdvanced = (props) => (
  <h1
    tw="font-semibold text-3xl md:text-4xl lg:text-5xl not-italic"
    css={`
      line-height: 1.15;
    `}
    {...props}
  />
)

Advanced -- escape hatch to css when required (and still zero runtime)

Does not use the slower styles attributes behind the scenes but actually generates unique CSS classes and auto injects an import of the CSS file at build time for normal CSS handling by whatever bundler you use

import { css } from '@linaria/css'

const HeroHeadingAdvanced = (props) => (
  <h1
    tw="font-semibold text-3xl md:text-4xl lg:text-5xl not-italic"
    css={`
      line-height: 1.15;
    `}
    {...props}
  />
)

Advanced -- escape hatch to css with dynamic properties when required, no extra imports required

Converts to a twstyled component behind the scenes with tiny runtime to handle the dynamic property; automatically recognizes the scope of expressions and if needed adds a property to the generated class to handle locally scoped expressions and pre-evaluates globally scoped expressions.

const isLarge = true

const HeroHeadingAdvanced = (props) => {
  const isItalic = true
  return (<h1
    tw=(`font-semibold ${isLarge ? "text-4xl" : "text-3xl"} ${isItalic ? "not-italic" : ""}`}
    css={`
      line-height: ${props => props.theme.linespacing};
    `}
    {...props}
  />)
}

is converted to the equivalent of

import { css, styled } from '@twstyled/core'

const TwCssH1 = styled.h1`
@tailwind font-semibold text-4xl ${props => props.$cssp1 ? "not-italic" : ""};
line-height: ${props => props.theme.linespacing};
`

const HeroHeadingAdvanced = (props) => (
  const isItalic = true
  <MyWrapperComponent>
  <TwCssH1 $cssp1={isItalic} {...props}/>
  </MyWrapperComponent>
)

Markdown MDX code allows class instead of className for compatibility with common Tailwind example kits

  <h1 class="font-semibold text-3xl md:text-4xl lg:text-5xl not-italic">Hello</h1>

Prior Art

  • xwind The inspiration and embedded logic for the Tailwind CSS processing; chosen because it was the best build-time solution and relied on the standard Tailwind CSS packages instead of recreating it; we do not use the actual xwind package here but instead use the smaller and more focused @xwind/core and @xwind/class-utilities packages. The xwind solution does not at time of development include a build time CSS in JS capabilty, does not support dedicated tw= JSX attribute and has not split out the import package, babel and webpack plugins
  • twind Was the smallest, fastest, most feature complete Tailwind-in-JS solution, but we now believe this solution twstyled is smaller (zero runtime in most cases), faster (no evaluation at runtime), and more feature complete (custom tw and css )
  • linaria A build time CSS-in-JS solution that has one of the best pre-evaluation capabiltiies we've seen in a Babel plugin; we re-use a lot of the Linaria logic, but provide a thin wrapper over it to handle Tailwind classes, and also provide a new css attribute similar to emotion and styled-components but missing in Linaria, and to allow all the CSS generation to happen in the Babel plugin instead of reparsing each source file in a separate Webpack loader. We had to expose the API of Linaria a bit to accomplish this and have added our contributions to the core linaria package
  • Windi CSS Windi CSS is a well-written, well-documented rewrite of Tailwind CSS that generates CSS dynamically. It's a good alternative to twstyled but is focused on scanning HTML and CSS files and has rewritten the generation from scratch, whereas twstyled is scans the abstract syntax tree of your components and generates the exact same CSS that tailwindcss does, thus avoiding the risk of upstream sync issues, and additionally brings all the benefits of a CSS in JS solution. We are React-ready out of the box and use a highly efficient Babel parser that plugs right into rollup, webpack, Next.js vite, esbuild and many other build pipelines.
  • Tailwind CSS The inspiration for twstyled and the actual source of the CSS used for each class; the vanilla implementation requires PostCSS purge processing which is less efficient as it uses string parsing and does not make use of the AST parsing that all bundlers include anyway

License

The MIT License (MIT)

electron-vite-react's People

Contributors

guybarnard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

electron-vite-react's Issues

Router

Consider adding a router?

Bad alias resolution when the main process references the common folder

I'm sorry I'm not a native English speaker. This is my problem
When I tried to reference the common configuration, I couldn't find the correct path in the packed dist directory,
It seems that my configuration is not bundled correctly

import { app, BrowserWindow, Tray, Menu } from 'electron'
import type { BrowserWindowConstructorOptions } from 'electron'
import windowStateKeeper from 'electron-window-state'
import config from '@/common/config'

index.js in dist directory

var import_electron = __toModule(require("electron"));
var import_electron_window_state = __toModule(require("electron-window-state"));
var import_config = __toModule(require("@/common/config"));
...

error stack

Error: Cannot find module '@/common/config'
Require stack:
- F:\code\project\electron-vite-react\dist\index.js
- F:\code\project\electron-vite-react\node_modules\electron\dist\resources\default_app.asar\main.js
-
    at Module._resolveFilename (internal/modules/cjs/loader.js:887:15)
    at Function.n._resolveFilename (electron/js2c/browser_init.js:261:1128)
    at Module._load (internal/modules/cjs/loader.js:732:27)
    at Function.f._load (electron/js2c/asar_bundle.js:5:12684)
    at Module.require (internal/modules/cjs/loader.js:959:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (F:\code\project\electron-vite-react\dist\index.js:22:32)
    at Module._compile (internal/modules/cjs/loader.js:1078:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1108:10)
    at Module.load (internal/modules/cjs/loader.js:935:32)

tree

├─.config
├─.vscode
├─public
├─scripts
└─src
    ├─common
    │  ├─config
    │  └─event
    ├─main
    │  ├─ipc
    │  └─work_thread
    └─renderer
        ├─components
        │  ├─DropZone
        │  └─HtmlHead
        ├─layouts
        └─pages
            └─home

how can i fix it ?

typeorm

any way to add typeorm for this template

How to use twstyled?

Hello. I see not all tw properties are there when you do tw=".." , and there doesn't appear to be any config file where to change what properties are activated. How is this done?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.