Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ded29bb

Browse files
committed
Initial commit
0 parents commit ded29bb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1902
-0
lines changed

‎.gitattributes‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text eol=lf

‎.gitignore‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/coverage/
2+
3+
dist/
4+
node_modules/
5+
.DS_Store
6+
package-lock.json
7+
yarn.lock
8+
*.log

‎.husky/pre-commit‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "0ドル")/_/husky.sh"
3+
4+
npm test \
5+
&& npx lint-staged \
6+
&& npm run lint

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## 1.0.0 (DEV)
4+
5+
- Initial release.

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020-2022 Vovan-VE
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# `@cubux/react-utils`
2+
3+
[![NPM latest](https://img.shields.io/npm/v/@cubux/react-utils.svg)](https://www.npmjs.com/package/@cubux/react-utils)
4+
5+
Utility functions related to React.
6+
7+
## Install
8+
9+
```sh
10+
npm i @cubux/react-utils
11+
```
12+
13+
## API
14+
15+
### `deprecated()` function
16+
17+
Wrap a component to emit deprecation warning.
18+
19+
```ts
20+
function deprecated<T extends React.ComponentType<any>>(
21+
Origin: T,
22+
options?: Options,
23+
): React.ComponentType<React.ComponentProps<T>>
24+
```
25+
26+
The `options` object can have the following properties:
27+
28+
| property | type | default | description |
29+
|-----------|-----------|---------|-------------------------------------------------------------------------------------------------------------------------------------|
30+
| `comment` | `string` || Extra comment to emit in console warning. Can also be obtained later with `getDevInfo()`. |
31+
| `tag` | `string` || A `tag` property to bypass to `setDevInfo()`. Can be obtained later with `getDevInfo()`. |
32+
| `withRef` | `boolean` | `false` | Whether to use `React.forwardRef()`, so `ref` React attribute can be used to refer to underlying element of the `Origin` component. |
33+
34+
A `getDevInfo()` can be used in development env to get details about deprecation.
35+
This can be used on "dev only" internal pages.
36+
37+
**Notice:** Component's (static) properties like `propTypes`, `defaultProps`,
38+
etc. are not touched because it was not necessary yet.
39+
40+
Does nothing in production env and returns origin component as is.
41+
42+
See also: `DevInfo`, `getDevInfo()`.
43+
44+
```tsx
45+
import { deprecated, getDevInfo } from '@cubux/react-utils';
46+
47+
function OldComponentOrigin() {
48+
return <div>...</div>;
49+
}
50+
51+
const OldComponent = deprecated(OldComponentOrigin, {
52+
comment: 'Use `NewComponent` instead.',
53+
});
54+
55+
if (process.env.NODE_ENV === 'development') {
56+
console.log(getDevInfo(OldComponent));
57+
}
58+
```
59+
60+
### `DevInfo` type
61+
62+
```ts
63+
interface DevInfo {
64+
type: string;
65+
tag?: string;
66+
Orig?: React.ComponentType<any>;
67+
comment?: string;
68+
}
69+
```
70+
71+
See also: `getDevInfo()`, `setDevInfo()`.
72+
73+
### `getDevInfo()` function
74+
75+
Get `DevInfo` for the given generated component.
76+
77+
```ts
78+
function getDevInfo<T extends DevInfo = DevInfo>(
79+
subject: ComponentType<any>,
80+
): T | undefined
81+
```
82+
83+
Does nothing in production env and always returns `undefined`.
84+
85+
An example can be found in `deprecated()`.
86+
87+
See also: `setDevInfo()`.
88+
89+
### `setDevInfo()` function
90+
91+
Set given `DevInfo` for the given component.
92+
93+
```ts
94+
function setDevInfo<T extends DevInfo>(
95+
subject: ComponentType<any>,
96+
info: T,
97+
): void
98+
```
99+
100+
Does nothing in production env.
101+
102+
See also: `getDevInfo()`.
103+
104+
### `isElementOf()` function
105+
106+
Check whether the given element is an element of the given component.
107+
108+
```ts
109+
function isElementOf<T extends React.ElementType>(
110+
element: any,
111+
component: T,
112+
): element is React.ReactElement<React.ComponentPropsWithoutRef<T>, T>
113+
```
114+
115+
**NOTICE:** The `react-is` peer dependency must be installed to use this
116+
function.
117+
118+
Enhanced version of `isElement()` from `react-is` package to use as Type Guard
119+
function.
120+
121+
```tsx
122+
import { FC, PropsWithChildren } from 'react';
123+
124+
interface FooProps {
125+
x: number;
126+
y?: string;
127+
}
128+
const Foo: FC<FooProps> = () => <div />;
129+
130+
const element = <Foo x={42} y="foo bar">baz</Foo>;
131+
if (isElementOf(element, Foo)) {
132+
const { props } = element;
133+
// `props` type is `PropsWithChildren<FooProps>`
134+
console.log(props);
135+
// { x: 42, y: "foo bar", children: "baz" }
136+
}
137+
138+
console.log(isElementOf(element, 'div'));
139+
// => `false`
140+
console.log(isElementOf(<div/>, Foo));
141+
// => `false`
142+
console.log(isElementOf(<div/>, 'a'));
143+
// => `false`
144+
console.log(isElementOf(<div/>, 'div'));
145+
// => `true`
146+
```
147+
148+
### `SvgFC` type
149+
150+
A `React.FunctionComponent` component receiving properties for `<svg/>` element.
151+
152+
```ts
153+
type SvgFC = React.FC<React.SVGProps<SVGSVGElement>>
154+
```
155+
156+
A component of this signature can be given for example with `svgo` package,
157+
which is used internally in CRA `react-scripts` for SVG files imports like
158+
following:
159+
160+
```ts
161+
// You are using CRA `react-scripts`, so
162+
import { ReactComponent } from './file.svg';
163+
```
164+
165+
Or writing such component manually:
166+
167+
```tsx
168+
const MySvg: SvgFC = (props) => (
169+
<svg
170+
{...props}
171+
width={16}
172+
height={16}
173+
viewBox="0 0 16 16"
174+
fill="currentColor"
175+
>
176+
<path d="M2,5 h12 v6 z" />
177+
</svg>
178+
);
179+
```
180+
181+
### `svgTransform` function
182+
183+
Creates new `SvgFC` component by reusing origin `SvgFC` applying a CSS
184+
`transform`.
185+
186+
```ts
187+
type CssTransform = string;
188+
type CalcTransform = (prev: CssTransform | undefined) => CssTransform;
189+
190+
function svgTransform(
191+
Orig: SvgFC,
192+
transform: CssTransform | CalcTransform,
193+
): SvgFC
194+
```
195+
196+
A `getDevInfo()` can be used in development env to get details about underlying
197+
transform. This can be used on "dev only" internal pages.
198+
199+
```tsx
200+
const MySvg: SvgFC = (props) => (
201+
<svg
202+
{...props}
203+
width={16}
204+
height={16}
205+
viewBox="0 0 16 16"
206+
fill="currentColor"
207+
>
208+
<path d="M2,5 h12 v6 z" />
209+
</svg>
210+
);
211+
212+
const MySvg1 = svgTransform(MySvg, 'scaleX(0.75), rotate(45deg)');
213+
```
214+
215+
See also: `getDevInfo()`.
216+
217+
### `svgFlipH()` function
218+
219+
Creates new `SvgFC` applying horizontal flip to origin `SvgFC` with CSS
220+
transform.
221+
222+
```ts
223+
function svgFlipH(Orig: SvgFC): SvgFC
224+
```
225+
226+
Uses `svgTransform()` internally with `'scaleX(-1)'` transform value.
227+
228+
See also: `transform()`, `svgFlipV()`, `svgRot180()`.
229+
230+
### `svgFlipV()` function
231+
232+
Creates new `SvgFC` applying vertical flip to origin `SvgFC` with CSS
233+
transform.
234+
235+
```ts
236+
function svgFlipV(Orig: SvgFC): SvgFC
237+
```
238+
239+
Uses `svgTransform()` internally with `'scaleY(-1)'` transform value.
240+
241+
See also: `transform()`, `svgFlipH()`, `svgRot180()`.
242+
243+
### `svgRot180()` function
244+
245+
Creates new `SvgFC` applying rotation 180 deg to origin `SvgFC` with CSS
246+
transform.
247+
248+
```ts
249+
function svgRot180(Orig: SvgFC): SvgFC
250+
```
251+
252+
Uses `svgTransform()` internally with `'rotate(180deg)'` transform value.
253+
254+
See also: `transform()`, `svgFlipH()`, `svgFlipV()`.
255+
256+
### `svgRot90L()` function
257+
258+
Creates new `SvgFC` applying rotation 90 deg anti-clockwise to origin `SvgFC`
259+
with CSS transform.
260+
261+
```ts
262+
function svgRot90L(Orig: SvgFC): SvgFC
263+
```
264+
265+
Uses `svgTransform()` internally with `'rotate(-90deg)'` transform value.
266+
267+
See also: `transform()`, `svgRot180()`.
268+
269+
### `svgRot90R()` function
270+
271+
Creates new `SvgFC` applying rotation 90 deg clockwise to origin `SvgFC` with
272+
CSS transform.
273+
274+
```ts
275+
function svgRot90R(Orig: SvgFC): SvgFC
276+
```
277+
278+
Uses `svgTransform()` internally with `'rotate(90deg)'` transform value.
279+
280+
See also: `transform()`, `svgRot180()`.

‎examples/react-18/index.html‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
7+
<title>Playground</title>
8+
</head>
9+
10+
<body>
11+
<div id="root"></div>
12+
<script type="module" src="./index.tsx"></script>
13+
</body>
14+
</html>

‎examples/react-18/index.tsx‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// import 'react-app-polyfill/stable';
2+
import React, { FC } from 'react';
3+
import { createRoot } from 'react-dom/client';
4+
import { svgRot90L } from '@cubux/react-utils';
5+
import { SvgFC, svgRot90R } from '@cubux/react-utils/svg';
6+
7+
const SvgIcon: SvgFC = (props) => (
8+
<svg
9+
{...props}
10+
width={16}
11+
height={16}
12+
viewBox="0 0 16 16"
13+
fill="currentColor"
14+
>
15+
<path d="M2,5 h12 v6 z" />
16+
</svg>
17+
);
18+
19+
const IconR1: SvgFC = svgRot90R(SvgIcon);
20+
const IconL1: SvgFC = svgRot90L(SvgIcon);
21+
22+
const App: FC = () => {
23+
return (
24+
<div>
25+
<h1>Foo bar</h1>
26+
<div>
27+
<IconL1 />
28+
<SvgIcon />
29+
<IconR1 />
30+
</div>
31+
</div>
32+
);
33+
};
34+
35+
createRoot(document.getElementById('root')!).render(<App />);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /