@maskedeng-tom/use-css
TypeScript icon, indicating that this package has built-in type declarations

0.2.7 • Public • Published

use-css

npm version License: MIT

  • input (入力)
<html lang='ja'>
  <head>
    <meta charset='UTF-8'>
    <title>use-css</title>
  </head>
  <body>
    <div id='root'></div>
  </body>
</html>
import { useScopedCss } from '@maskedeng-tom/use-css';

const App = () => {
  const scope = useScopedCss({
    '.title':{
      color: 'red',
    }
  });
  return <div {...scope} className="title">use-css useScopedCss sample !</div>;
};

export default App;
// index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const root = createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>
);

  • output (出力)
<html lang='ja'>
  <head>
    <meta charset='UTF-8'>
    <title>use-css</title>
    <style>.title[sc000000]{color:red;}</style>
  </head>
  <body>
    <div id='root'><div sc000000="" className="title">use-css useScopedCss sample !</div></div>
  </body>
</html>

Reactで、一般的なCSSやスコープ付きCSSを、各種バンドラー(webpackなど)に依存せず、JavaScript、Typescriptで利用するためのReact hooksライブラリーです。簡単に導入でき、他のnpmライブラリへの依存はありません。

This is a React hooks library that allows you to use common CSS and scoped CSS in JavaScript and TypeScript without relying on various bundlers (such as webpack). It is easy to integrate and does not have any dependencies on other npm libraries.


Prerequisites

React hooksライブラリーなので、React Version 16.8以降に対応しています。Typescriptにも対応しています。

This is a React hooks library, so it is compatible with React version 16.8 and above. It also supports TypeScript.


Table of contents


Getting Started

適当なReactを用意してください。関数コンポーネントを利用するため、React Version 16.8以降が必要です。 すでに作成済みのReactプロジェクトにも適用できます。作成済みのReactプロジェクトへの導入にあたって、破壊的な変更は行われません(React本体以外への依存はありません)。

シンプルなReactプロジェクトの作り方については、以下を参考にしてください。 Getting Started with a Simple React Project

Please prepare a suitable React project. React version 16.8 or above is required to use function components. It can also be applied to existing React projects. There will be no destructive changes when introducing it to an existing React project (no dependencies on anything other than React itself). Please refer to the following for instructions on how to create a simple React project. Getting Started with a Simple React Project


Installation

Using npm (npmを利用する場合)

npm install @maskedeng-tom/use-css

Using yarn (yarnを利用する場合)

yarn add @maskedeng-tom/use-css

Usage

Base program

以下の基本プログラムに沿って解説します。

We will explain according to the following basic program.

<!-- index.html -->
<html lang='ja'>
  <head>
    <meta charset='UTF-8'>
    <title>use-css</title>
  </head>
  <body>
    <div id='root'></div>
  </body>
</html>
// index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

const root = createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>
);
// App.tsx
const App = () => {
  return <div>use-css sample!</div>;
};

export default App;

How to use useScopedCss

useScopedCssの使い方

// App.tsx
import { useScopedCss } from '@maskedeng-tom/use-css';

const App = () => {
  const scope = useScopedCss({
    '.title':{
      color: 'red',
    }
  });
  return <div {...scope} className="title">use-css useScopedCss sample !</div>;
};

export default App;

上記のコードは、以下のような style タグと html を生成します。

The above code generates the following style tag and html.

<!-- index.html -->
<html lang='ja'>
  <head>
    <meta charset='UTF-8'>
    <title>use-css</title>
    <style>.title[sc000000]{color:red;}</style>
  </head>
  <body>
    <div id='root'><div sc000000="" className="title">use-css useScopedCss sample !</div></div>
  </body>
</html>

useScopedCssは、cssをスコープ付きでstyleタグとして適用します。上記の例では sc000000 というスコープ名が付与されています。また、スコープ名は自動でユニークなものが付与され、useScopedCssの戻り値に含まれています。

useScopedCss applies css with a scoped style tag. In the above example, the scope name sc000000 is added. Also, a unique scope name is automatically added and included in the return value of useScopedCss.

  <style>.title[sc000000]{color:red;}</style>

useScopedCssの戻り値は、以下のようなオブジェクトです。

The return value of useScopedCss is an object like the following.

{
  "sc000000": ""
}

useScopedCssの戻り値を、divタグの属性に展開することで({...scope}の付与)、スコープ付きのcssが適用されるタグが生成されます。

By expanding the return value of useScopedCss to the attributes of the div tag (by adding {...scope}), a tag with scoped css applied is generated.

  return <div {...scope} className="title">use-css useScopedCss sample !</div>;

上記が下記に展開されます。

The above is expanded to the following.

  <div sc000000="" className="title">use-css useScopedCss sample !</div>

この機能は、Vueの、スコープドスタイルに似ています。

This feature is similar to Vue's scoped style.


How to use useGlobalCss

useGlobalCssの使い方

useScopedCssと違い、単純にCSSを適用します。スコープは付与されません。

Unlike useScopedCss, it simply applies CSS. No scope is added.

// App.tsx
import { useGlobalCss } from '@maskedeng-tom/use-css';

const App = () => {
  useGlobalCss({
    '.title':{
      color: 'red',
    }
  });
  return <div className="title">use-css useGlobalCss sample !</div>;
};

export default App;

上記のコードは、以下のような style タグと html を生成します。

The above code generates the following style tag and html.

<!-- index.html -->
<html lang='ja'>
  <head>
    <meta charset='UTF-8'>
    <title>use-css</title>
    <style>.title{color:red;}</style>
  </head>
  <body>
    <div id='root'><div className="title">use-css useGlobalCss sample !</div></div>
  </body>
</html>

一般的な各種バンドラーを利用してcssをインポートする場合と同様の結果が得られます。

You will get the same result as when you import css using a general bundler.

// sample
import "./styles.css";

CSS using @scope,:scope (@scope,:scope を用いたCSS)

今後サポートが増えていくと思われる、@scope,:scopeuseGlobalCssは今後相性のよい実装となるでしょう。

In the future, @scope,:scope and useGlobalCss will be a good implementation for future compatibility.

MDN @scope

const App = () => {
  useGlobalCss({
    '@scope (.title)':{
      ':scope':{
        color: 'green',
      },
      '.text':{
        color: 'red',
      },
    }
  });
  return <>
    <div className="title">
      title:
      <span className="text">
        use-css in scope!
      </span>
    </div>
    <div className="title-2">
      title-2:
      <span className="text">
        use-css out of scope!
      </span>
    </div>
  </>;
};

Using nested CSS

useScopedCssuseGlobalCssは、ネストしたCSSを利用することができます。(useGlobalCssでは、scopeは付与されません)

useScopedCss and useGlobalCss can use nested CSS. (No scope is added with useGlobalCss)

// App.tsx
import { useScopedCss } from '@maskedeng-tom/use-css';

const App = () => {
  const scope = useScopedCss({
    '.title':{
      fontSize: '24px',
      '.text':{
        color: 'red',
      },
      '.description':{
        fontSize: '12px',
      },
    }
  });
  return <>
    <div {...scope} className="title">
      <div {...scope} className="text">
        use-css!
      </div>
      <div {...scope} className="description">
        useScopedCss sample 
      </div>
    </div>
  </>;
};

export default App;

上記のコードは、以下のような style タグを生成します。(実際には改行コードは省かれます)

The above code generates the following style tag. (In fact, line breaks are omitted.)

<style>
.title[sc000000]{
  font-size:24px;
}
.title .text[sc000000]{
  color:red;
}
.title .description[sc000000]{
  font-size:12px;
}
</style>
  <div sc000000="" className="title">
    <div sc000000="" className="text">
      use-css!
    </div>
    <div sc000000="" className="description">
      useScopedCss sample 
    </div>
  </div>

スコープ名(sc000000)は、ネストしたCSSの場合、セレクタの末尾に付与されます。よって、HTML上のすべてのタグに{...scope}を付与していることに注目してください。

In the case of nested CSS, the scope name (sc000000) is added at the end of the selector. Therefore, please note that {...scope} is added to all tags on the HTML.


Specifying the scope indicator position

スコープ指示位置の指定方法(::v-deep)

::v-deepを利用することでスコープ指示位置を指定することが可能です。(この機能もVueに似た機能です)

It is possible to specify the scope indicator position by using ::v-deep. (This feature is also similar to Vue)

// App.tsx
import { useScopedCss } from '@maskedeng-tom/use-css';

const App = () => {
  const scope = useScopedCss({
    '.title ::v-deep':{
      fontSize: '24px',
      '.text':{
        color: 'red',
      },
      '.description':{
        fontSize: '12px',
      },
    }
  });
  return <>
    <div {...scope} className="title">
      <div className="text">
        use-css!
      </div>
      <div className="description">
        useScopedCss sample 
      </div>
    </div>
  </>;
};

export default App;

上記のコードは、以下のような style タグを生成します。(実際には改行コードは省かれます)

The above code generates the following style tag. (In fact, line breaks are omitted.)

<style>
.title[sc000000]{
  font-size:12px;
}
.title[sc000000] .text{
  color:red;
}
.title[sc000000] .description{
  font-size:8px;
}
</style>
  <div sc000000="" className="title">
    <div className="text">
      use-css!
    </div>
    <div className="description">
      useScopedCss sample 
    </div>
  </div>

スコープ名(sc000000)は、::v-deepで指定された場所に挿入されます。よって、HTML上の先頭タグのみに{...scope}を付与していることに注目してください。

The scope name (sc000000) is inserted at the position specified by ::v-deep. Therefore, please note that {...scope} is added only to the first tag on the HTML.


Use dependency parameter

useScopedCssuseGlobalCssは、dependencyパラメーターを利用することができます。

useScopedCss and useGlobalCss can use the dependency parameter.

// App.tsx
import { useScopedCss } from '@maskedeng-tom/use-css';

const App = () => {

  const [color, setColor] = useState('red');

  const scope = useScopedCss({
    '.title':{
      color: color,
    }
  }, [color]);

  return <>
    <div {...scope} className="title">
        use-css!
      <button
        type="button"
        onClick={()=>{
          setColor('blue');
        }}
      >change color</button>
    </div>
  </>;
};

export default App;

上記のコードは、初期には以下の style タグを生成します。(実際には改行コードは省かれます)

The above code generates the following style tag at the beginning. (In fact, line breaks are omitted.)

<style>
.title[sc000000]{
  color:red;
}
</style>
<div id="root">
  <div class="title" sc000000="">
    use-css!
    <button type="button">change color</button>
  </div>
</div>

その後、ボタンタグをクリックすると、以下のように style タグが変更されます。

After that, when you click the button tag, the style tag will be changed as follows.

<style>
.title[sc000001]{
  color:blue;
}
</style>
<div id="root">
  <div class="title" sc000001="">
    use-css!
    <button type="button">change color</button>
  </div>
</div>

カラーテーマなどを構築する際に、便利に利用できます。

It can be used conveniently when building a color theme.


API

useScopedCss

useScopedCss(css: SassStyles, dependency: unknown[] = []): {[scope: string]: ''}

スコープ付きのCSSを適用します。スコープは戻り値に含まれます。戻り値を、{...scope}のようにhtmlタグに適用してください。

Applies CSS with a scope. The scope is included in the return value. Apply the return value to the html tag as {...scope}.

Options

css

Type Default value
SassStyles n/a

type SassStylesを参照してください。

Please refer to type SassStyles.

dependency

Type Default value
unknown[] []

この値が指定された場合には、useEffectuseCallbackと同様に、依存関係の変更を検知して再度CSSを適用します(useEffectuseCallbackと違い、デフォルトで []が指定されるため、デフォルトでは変更されません)。

If this value is specified, the CSS will be reapplied when the dependency changes, similar to useEffect and useCallback (unlike useEffect and useCallback, the default is [], so it will not be changed by default).

Return value

Type
{[scope: string]: ''}

スコープ名をキーとしたオブジェクトが返されます。スコープ名は、{...scope}のようにhtmlタグに適用してください。

An object with the scope name as the key is returned. Apply the scope name to the html tag as {...scope}.


useGlobalCss

useGlobalCss(css: SassStyles, dependency: unknown[] = []): void

スコープ無しのCSSを適用します。戻り値はありません。

Applies CSS without a scope. There is no return value.

Options

css

Type Default value
SassStyles n/a

type SassStylesを参照してください。

Please refer to type SassStyles.

dependency

Type Default value
unknown[] []

この値が指定された場合には、useEffectuseCallbackと同様に、依存関係の変更を検知して再度CSSを適用します(useEffectuseCallbackと違い、デフォルトで []が指定されるため、デフォルトでは変更されません)。

If this value is specified, the CSS will be reapplied when the dependency changes, similar to useEffect and useCallback (unlike useEffect and useCallback, the default is [], so it will not be changed by default).


type SassStyles

In the case of simple CSS

シンプルなCSS

{
  '.selector': {
    color: 'red',
  };
}
<style>
.selector{
  color: red;
}
</style>

CSS contains the pixel unit

'px'単位を含むCSSの場合、number型で指定することができます。

If the CSS contains the unit 'px', it can be specified as number type.

{
  '.selector': {
    borderLeft: 1,
  };
}
<style>
.selector{
  border-left: 1px;
}
</style>

CSS containing multiple parameters

複数パラメータを持つ一部のCSSは配列で指定することができます。

Some CSS with multiple parameters can be specified as an array.

{
  '.selector': {
    border: [1, 'solid', 'red'],
  };
}
<style>
.selector{
  border: 1px solid red;
}
</style>

CSS containing nested CSS

sassのようなネストしたCSSを指定することができます。

You can specify nested CSS like sass.

{
  '.selector': {
    color: 'red',
    '.text': {
      border: [1, 'solid', 'red'],
    },
  };
}
<style>
.selector{
  color: red;
}
.selector .text{
  border: 1px solid red;
}
</style>

sass '&' selector

sassのようにセレクターの先頭に'&'を付与すると、セレクターを結合します。

You can specify CSS with '&' selectors like sass.

{
  '.selector': {
    color: 'red',
    '&:hover': {
      color: 'blue',
    },
  };
}
<style>
.selector{
  color: red;
}
.selector:hover{
  color: blue;
}
</style>

::v-deep selector

::v-deepを使って、scope指示位置を指定することができます。

You can use ::v-deep to specify the scope indicator position.

{
  '.selector ::v-deep': {
    color: 'red',
    '.text': {
      border: [1, 'solid', 'red'],
    },
  };
}
<style>
.selector[sc000000]{
  color: red;
}
.selector[sc000000] .text{
  border: 1px solid red;
}
</style>

Getting Started with a Simple React Project(with webpack)

シンプルなReactプロジェクトのはじめかた(webpack利用例)


Create project folder (プロジェクトフォルダの作成)

mkdir test-app
cd test-app

Initializing package (パッケージの初期化)

npm -y init

Package Installation (パッケージのインストール)

npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin
npm install --save-dev typescript ts-loader
npm install --save-dev react react-dom @types/react @types/react-dom

Changes to package.json (package.jsonの変更)

// package.json
  "scripts": {
+    "start": "webpack-cli serve --mode development",
+    "build": "webpack-cli --node-env=production --mode production",
  },

Adding webpack.config.js (webpack.config.jsの追加)

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const dist = path.resolve(__dirname, './dist');

module.exports = (env, { mode }) => {

  // build mode
  let buildMode = 'production';
  if (mode === 'development') {
    buildMode = 'development';
  }

  return {
    mode: buildMode,
    devtool: ((buildMode === 'development') ? 'inline-source-map' : 'source-map'),

    entry: {'index': './src/index.tsx'},
    output: {
      filename: '[name].js',
      path: dist,
    },

    resolve: {
      extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },

    module: {
      rules: [
        {
          test: /\.(ts|tsx)$/,
          exclude: /node_modules/,
          use: 'ts-loader',
        },
      ],
    },

    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html',
        filename: './index.html',
        chunks: ['index']
      }),
    ],

    devServer: {
      port: '3000',
      host: '0.0.0.0',
      open: true,
    },
  }
};

Initializing TypeScript (Typescriptの初期化)

npx tsc --init

Changes to tsconfig.json (tsconfig.jsonの変更)

// tsconfig.json
{
  "compilerOptions": {
-    // "jsx": "",
+    "jsx": "react-jsx",
-    // "outDir": "./",
+    "outDir": "./dist",
-  }
+  },
+  "files": [
+    "src/index.tsx",
+  ],
+  "include": [
+    "src/**/*",
+  ],
+  "exclude": [
+    "./node_modules",
+    "./dist"
+  ]
}

Adding src/index.html (src/index.htmlの追加)

mkdir src
<!-- src/index.html -->
<html lang='ja'>
  <head>
    <meta charset='UTF-8'>
    <title>Simple React app with webpack</title>
  </head>
  <body>
    <div id='root'></div>
  </body>
</html>

Adding src/index.tsx (src/index.tsxの追加)

// src/index.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';

const App = () => {
  return <h1>Simple React App with webpack!</h1>;
};

const root = createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <React.StrictMode>
    <App/>
  </React.StrictMode>
);

Run (実行)

npm start

Build (ビルド)

npm run build

Contributing

CONTRIBUTING.mdをお読みください。ここには行動規範やプルリクエストの提出手順が詳細に記載されています。

  1. フォークする
  2. フィーチャーブランチを作成する:git checkout -b my-new-feature
  3. 変更を追加:git add .
  4. 変更をコミット:git commit -am 'Add some feature'
  5. ブランチをプッシュ:git push origin my-new-feature
  6. プルリクエストを提出 😎

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Add your changes: git add .
  4. Commit your changes: git commit -am 'Add some feature'
  5. Push to the branch: git push origin my-new-feature
  6. Submit a pull request 😎

Credits

昨今の複雑化していく開発現場にシンプルな力を! 💪

Simplify the complex development landscape of today! 💪


Authors

Maskedeng Tom - Initial work - Maskedeng Tom

😄 プロジェクト貢献者リスト 😄

See also the list of contributors who participated in this project.


Show your support

お役に立った場合はぜひ ⭐ を!

Please ⭐ this repository if this project helped you!


License

MIT License © Maskedeng Tom

Versions

Current Tags

VersionDownloads (Last 7 Days)Tag
0.2.70latest

Version History

VersionDownloads (Last 7 Days)Published
0.2.70
0.2.60
0.2.50
0.2.40
0.2.30
0.2.20
0.2.10
0.1.90
0.1.80
0.1.70
0.1.60

Package Sidebar

Install

npm i @maskedeng-tom/use-css

Weekly Downloads

0

Version

0.2.7

License

MIT

Unpacked Size

64.9 kB

Total Files

32

Last publish

Collaborators

  • maskedeng-tom