Git Product home page Git Product logo

navita's Introduction

Navita Logo

Navita is a powerful CSS-in-JS library that brings type-safe compile-time Atomic CSS-in-JS with zero runtime to your projects.

It allows you to easily style your components and apply themes without the need for any additional runtime dependencies.

With Navita, you can write clean and maintainable CSS in JavaScript, without sacrificing runtime performance.

🔥   All styles generated at build time — just like Sass, Less, etc.

✨   Minimal abstraction over standard CSS.

🦄   Works with any JS-based front-end framework — or even without one.

🎨   High-level theme system with support for simultaneous themes.

💪   Type-safe styles via CSSType.

🌳   Co-locate your styles with your components — if you want to.

🛠   Integrations with popular bundlers such as Webpack, Vite, and Next.js.


🌐 Check out the documentation site for setup guides, examples and API docs.


Installation

To start using Navita in your project, simply follow these steps:

Install Navita using npm:

npm install @navita/css --save

You'll also need to install the Navita integration for your preferred bundler. Navita currently supports Webpack, Vite, and Next.js.

Choose the integration for your preferred bundler:

If you are using Webpack, install the Webpack integration:

npm install @navita/webpack-plugin mini-css-extract-plugin --save-dev

Update your webpack.config.js file to include both MiniCssExtractPlugin and NavitaPlugin:

const { NavitaPlugin } = require('@navita/webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  // Other webpack options,
  plugins: [
    new MiniCssExtractPlugin(),
    new NavitaPlugin(),
  ],
};

Read more about the Webpack integration in the Webpack documentation.

If you are using Vite, install the Vite integration:

npm install @navita/vite-plugin --save-dev

And add it to your vite.config.js file:

import { defineConfig } from 'vite';
import { navita } from '@navita/vite-plugin';

export default defineConfig({
  plugins: [
    // Other plugins
    navita(/* Additional options */)
  ],
});

Read more about the Vite integration in the Vite documentation.

If you are using Next.js, install the Next.js integration:

🚀   React Server Components support!

npm install @navita/next-plugin --save-dev

And add it to your next.config.js file:

const { createNavitaStylePlugin } = require("@navita/next-plugin");

/** @type {import('next').NextConfig} */
const nextConfig = {};

module.exports = createNavitaStylePlugin({
  // Additional options
})(nextConfig);

Read more about the Next.js integration in the Next.js documentation.

Usage

The main entry point for Navita is the style function. Make sure you read the reset of the documentation on https://navita.style to learn more about the APIs.

import { style } from '@navita/css';

const container = style({
  padding: '2rem',
  background: 'hotpink',
  color: 'white',
});

document.write(`
  <div class="${container}">
    Hello World!
  </div>
`);

That's it!

💡 Only references to the classNames will be included in the bundle.

Note: Navita doesn't require special file extensions for your styles. You can co-locate your CSS styles with your components.

Documentation

For detailed documentation, examples, and usage guidelines, please visit the official Navita website: https://navita.style

Contributing

We welcome contributions from the community to make Navita even better!

Thanks

  • Vanilla-Extract and Linaria for the inspiration and the great work on the CSS-in-JS ecosystem.
  • Fela for the fantastic work on Atomic css-in-js.
  • Eagerpatch for giving us the space to do interesting work.

MIT Licensed—A project by Eagerpatch.
Made with ❤️ by zn4rk and contributors.

navita's People

Contributors

github-actions[bot] avatar zn4rk 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

Watchers

 avatar  avatar

navita's Issues

Fix esm exports in next-plugin

Next.js has changed their default config file name to next.config.mjs.

When running with import createNavitaStylePlugin from '@navita/next-plugin', we get a runtime error saying that the MiniCssExtractPlugin can't be found. Probably just needs the file extension.

Introduce a runtime API

It would require creating a runtime adapter that uses the engine and inserts styles into the DOM.

Run `transformContentProperty` on keyframes.

This should be possible:

const animation = keyframes({
  '0%': { content: '' },
  '25%': { content: '.' },
  '50%': { content: '..' },
  '75%': { content: '...' },
  '100%': { content: '' },
});

Without having to explicitly quote the values.

webpack-plugin: run loaders on everything that looks like urls

Our loader runs too early in some cases. If we include our loader too late in the process, some of our identifiers might've been three shaken away (such as globalStyle).

If we include it too early, and user code in Navita rely on other transforms that also happens, our evaluation process will fail.

So, maybe two loaders? One that finds modules that might be tree shaken away, and does something to/with them, and then the one we have now, but to make sure it runs last.

CSS specificity for certain rules

I've come across at least one case where we need to control the CSS specificity better. It's mainly if the user is specifying the declaration:

all: unset;

Rules in a specific list needs to be rendered before rest of the CSS, and possibly live in a separate layer. Right now I can only think of "all: unset" specifically, but it should be pretty easy to just sort the rules in the css printer.

How does dynamic styles work?

Can this be a solid replacement to styled components?

How would this work with dynamic styling based on props similar to styled-components? Also can you update the docs with a section that talks about migrating from styled-components?

Better grouping for identical value pseudo rules

const x = style({
  '&:hover': {
    background: 'red',
  }
});

const x2 = style({
  '&:active': {
    background: 'red',
  }
});

Will produce the following css:

.a1:hover {
  background: red;
}

.b1:active {
  background: red;
}

But it could produce the following CSS to save a few bytes:

.a1:hover, .b1:active {
   background: red;
}

[Next.js] Edge Runtime not behaving correctly

Using Navita imports directly inside routes that has

export const runtime = 'edge';

Causes the compiler to hang.

I can't remember the details of the Next.js implementation completely, but it might be caused by this line:
https://github.com/vercel/next.js/blob/f3132354285fb18c290bf9aad7f8dc7e0550105d/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts#L614

Needs investigation and replication.

Lines in Navita that we need to look into:

const findPagesDirResult = findPagesDir(dir, !!resolvedNextConfig.experimental.appDir);
const hasAppDir = !!(findPagesDirResult && findPagesDirResult.appDir);
const isServer = options.isServer && !(options.nextRuntime === 'edge')
const outputCss = !isServer || hasAppDir;
if (!hasAppDir && !isServer) {
const filename = dev
? 'static/css/[name].css'
: 'static/css/[contenthash].css';
// https://github.com/vercel/next.js/blob/930db5c1afbe541a0b2357c26123c2b365b56624/packages/next/src/build/webpack/config/blocks/css/index.ts#L595
config.plugins.push(
new MiniCssExtractPlugin({
filename,
chunkFilename: filename,
ignoreOrder: true,
}),
);
}

CSS variables in `style` gets converted to snake-case.

const borderBottomColor = createVar('borderBottomColor');

const x = style({
  [borderBottomColor]: 'red',
});

The generated css from "x" is --border-bottom-color: red. The variables should probably be left as they are, and createVar etc should generate snake-case vars instead - maybe.

Using @navita/css without an adapter

This looks like an interesting project so I thought I'd give it a go for a use case of mine.

I'm building a component library which would then use @navita/css to then generate the css for the component.

In the application, component is imported and styles would be overridden using @navita/css. Moreover, it would be a case of last object wins.

2 questions:

  1. I've tried to use @navita/css within the component lib, however I get the error

Error: Could not find an adapter. Please ensure you have added a bundler integration:

Is it possible to run @navita/css without an adapter present? In this case, only react is present.

  1. How does the creation of styles work? Is it like pandacss where it runs through the whole of the html payload and generates the styles? Would style creation work over the file boundary?

Here is an example from pandacss: https://panda-playground.vercel.app/tZQo-P_psO

Thanks

Make sure `normalizeCSSVarsValue` runs for more cases

const color = createVar('color');

const x = style({
   background: `rgba(${color}, 0.15)`,
});

Will produce this css:

.a1 {
   background: rgba(--color, 0.15);
}

Instead of this:

.a1 {
   background: rgba(var(--color), 0.15);
}

Source:
https://github.com/eagerpatch/navita/blob/main/packages/engine/src/helpers/normalizeCSSVarsValue.ts#L3

At first glance, it looks like the regex is still valid, but we need to expand the test cases, and modify or remove the if-statement that decides if we should normalize CSS var values.

Clean up Engine's caching

As I almost mentioned in #43, the caching mechanism we're using right now, always assumes in-memory usage.

This works very well as it is right now, but the way the code is structured could be better. If we reach for a more flat structure, it would be easier to expand/replace to another type of persistent storage later. Right now we're also pretty inefficient in the way we are storing data for the cache

Here's an example entry:

"{\"type\":\"rule\",\"selector\":\"\",\"property\":\"padding\",\"value\":\"20px\",\"pseudo\":\"\",\"media\":\"\",\"support\":\"\",\"container\":\"\"}": {
  "id": "b1",
  "type": "rule",
  "selector": "",
  "property": "padding",
  "value": "20px",
  "pseudo": "",
  "media": "",
  "support": "",
  "container": ""
},

The key is the value, just stringified, and without the id.

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.