React UI

ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
yarn add @skbkontur/react-ui
import { Button, Toast } from '@skbkontur/react-ui';
const MyApp = () => (
<div>
Click this button <Button onClick={() => Toast.push('Hey!')}>Click me</Button>
</div>
);
StrictMode
ΠΠ°ΡΠΈΠ½Π°Ρ Ρ Π²Π΅ΡΡΠΈΠΉ @skbkontur/react-ui@3.10.0
ΠΈ @skbkontur/react-ui-validations@1.7.0
, Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠ°Π±ΠΎΡΡ
Π² React.StrictMode.
ΠΠ΅ΠΊΠΎΡΠΎΡΡΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠΌΠ΅ΡΡ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠΉ DOM-Π½ΠΎΠ΄Ρ ΡΠ²ΠΎΠΈΡ
children. Π Π°Π½Π΅Π΅ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ ΠΌΠ΅ΡΠΎΠ΄ findDomNode, ΠΊΠΎΡΠΎΡΡΠΉ Π² StrictMode Π·Π°ΠΏΡΠ΅ΡΡΠ½. Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ DOM-Π½ΠΎΠ΄Ρ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅ ΡΠ΅ΡΠ΅Π·
ref, ΠΈΠ·-Π·Π° ΡΠ΅Π³ΠΎ ΠΏΠΎΡΠ²ΠΈΠ»ΠΈΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌ, ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΠΌ Π² Hint, Tooltip, Popup ΠΈΠ»ΠΈ Tab:
- ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΡ
ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
React.ForwardRef
:
import { Hint } from '@skbkontur/react-ui';
const CustomFunctionComponent = React.forwardRef(
(props, ref) => <div ref={ref}>children text</div>
);
export const WithFunctionChildren = () => (
<React.StrictMode>
<Hint pos="top" text="Something will never be changed" manual opened>
<CustomFunctionComponent/>
</Hint>
</React.StrictMode>
);
- ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Ρ
ΡΠΊΠ°
useImperativeHandle
, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ getRootNode
,
Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΠΈΠΉ DOM-Π½ΠΎΠ΄Ρ:
import { Hint } from '@skbkontur/react-ui';
const ImperativeHandleComponent = React.forwardRef(function FN(_, ref) {
const rootNode = React.useRef < HTMLDivElement > (null);
React.useImperativeHandle(ref, () => ({
foo: 'bar',
getRootNode: () => rootNode.current,
}));
return <div ref={rootNode}>children text</div>;
});
export const WithImperativeHandleChildren = () => (
<React.StrictMode>
<Hint pos="top" text="Something will never be changed" manual opened>
<ImperativeHandleComponent/>
</Hint>
</React.StrictMode>
);
- ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ΅ ΠΊΠ»Π°ΡΡΠΎΠ²ΡΡ
ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΠΈΡ
ΠΈΠ½ΡΡΠ°Π½Ρ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄
getRootNode
, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΠΈΠΉ DOM-Π½ΠΎΠ΄Ρ:
import { Hint } from '@skbkontur/react-ui';
class CustomClassComponent extends React.Component {
rootNode = React.createRef();
render() {
return <div ref={this.rootNode}>children text</div>;
}
getRootNode() {
return this.rootNode.current;
}
}
export const WithClassChildren = () => (
<React.StrictMode>
<Hint pos="top" text="Something will never be changed" manual opened>
<CustomClassComponent/>
</Hint>
</React.StrictMode>
);
Π ΡΠ»ΡΡΠ°Π΅ Π½Π΅ΡΠΎΠ±Π»ΡΠ΄Π΅Π½ΠΈΡ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ, Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΡΠ°ΡΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ findDomNode, ΠΊΠΎΡΠΎΡΡΠΉ Π½Π΅ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌ Ρ StrictMode.
ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ Π² ΠΏΡΠ»Π»-ΡΠ΅ΠΊΠ²Π΅ΡΡΠ΅
FAQ
ΠΡΠΏΠ°Π΄Π°ΡΠΊΠΈ ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ react-ΡΡΡΠΎΠ²
Π Π΅Π°ΠΊΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΡΡ Π²Π½ΡΡΡΠΈ ΡΡΡΠ°. ΠΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΠΌΠ΅ΠΆΠ΄Ρ Π½ΠΈΠΌΠΈ Π½Π΅ ΠΏΡΠΎΠΊΠΈΠ΄ΡΠ²Π°Π΅ΡΡΡ. ΠΡΠΎ Π²ΡΠ·ΡΠ²Π°Π΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π² ΡΠ°Π±ΠΎΡΠ΅
ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ
Π²ΡΠΏΠ°Π΄Π°ΡΠ΅ΠΊ, ΡΠΈΠΏΠ° Tooltip
, Select
, Modal
ΠΈ Π΄ΡΡΠ³ΠΈΡ
.
Π Π²Π΅ΡΡΠΈΠΈ 4.26.0
ΠΏΠΎΡΠ²ΠΈΠ»ΡΡ ΠΌΠ΅Ρ
Π½ΠΈΠ·ΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ΅ΡΠ°Π΅Ρ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΡΡΠΈΡ
ΠΏΡΠΎΠ±Π»Π΅ΠΌ. ΠΡΠ»ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΡΠ΅Π°ΠΊΡ-ΡΡΡ ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΠΈΠ΄ΠΆΠ΅ΡΠΎΠΌ,
ΡΠΎ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ ΡΠΎΠ»ΡΠΊΠΎ Π² Π½ΡΠΌ.
ΠΠ΄Π½Π°ΠΊΠΎ, ΠΏΡΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΠΈ html-ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ» ΡΠ΅Π°ΠΊΡ-ΡΡΡΠΎΠΌ, Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠ²Π½ΠΎ ΡΠ°Π·ΠΌΠΎΠ½ΡΠΈΡΠΎΠ²Π°ΡΡ:
React.useLayoutEffect(
() => () => {
if (React.version === 17) {
rootRef.current && ReactDOM.unmountComponentAtNode(rootRef.current);
} else if (React.version === 18) {
setTimeout(() => reactRoot.current?.unmount());
}
},
[],
);
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π°Π½ΠΈΠΌΠ°ΡΠΈΠΉ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ
ΠΠ½ΠΈΠΌΠ°ΡΠΈΠΈ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°Ρ
ΠΎΡΠΊΠ»ΡΡΠ°ΡΡΡΡ Π»ΡΠ±ΠΎΠΉ ΠΈΠ· ΡΠ»Π΅Π΄ΡΡΡΠΈΡ
Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΡ
ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
:
REACT_UI_TEST
process.env.NODE_ENV === 'test'
process.env.REACT_UI_TEST
process.env.REACT_APP_REACT_UI_TEST
process.env.STORYBOOK_REACT_UI_TEST
ΠΡΠΎΠΊΠΈΠ΄ΡΠ²Π°Π½ΠΈΠ΅ className ΠΈ style ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌ
ΠΠ°ΡΠΈΠ½Π°Ρ Ρ Π²Π΅ΡΡΠΈΠΈ 2.14.0, ΡΡΠ°Π»ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠ²ΠΎΠΈ css-ΠΊΠ»Π°ΡΡΡ Π΄Π»Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ ΡΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠ΄Π½Π°ΠΊΠΎ,
Π½Π΅ ΡΡΠΎΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΡΠΎΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΡ Π΄Π»Ρ Π²ΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΡΡΠ²Π° Π²ΠΎ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠ΅ ΡΡΠΈΠ»ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ². ΠΠ΅ΡΡΡΠΊΠ° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ
Π±ΡΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π° Π² Π»ΡΠ±ΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π±Π΅Π· ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΡ, ΡΡΠΎ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ ΠΏΠΎΠ»ΠΎΠΌΠΊΠ΅ Π²Π°ΡΠΈΡ
ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ
ΡΡΠΈΠ»Π΅ΠΉ.
ΠΠΎΠ±ΠΈΠ»ΡΠ½Π°Ρ Π²Π΅ΡΡΡΠΊΠ°
Π‘ Π²Π΅ΡΡΠΈΠΈ 4.0 ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠΌΠ΅ΡΡ Π°Π΄Π°ΠΏΡΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΏΠΎΠ΄ ΠΌΠΎΠ±ΠΈΠ»ΡΠ½ΡΠ΅ ΡΡΡΡΠΎΠΉΡΡΠ²Π°. ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΎΠ± ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΈ ΡΡΠΈΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ
Π² MOBILES.md.
ΠΠΎΠΌΠΎΡΡ Π² ΡΠ°Π·Π²ΠΈΡΠΈΠΈ
ΠΡ ΡΠ°Π΄Ρ Π»ΡΠ±ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Π½Π΅ΠΉ ΠΏΠΎΠΌΠΎΡΠΈ. ΠΠ΅ ΡΡΠ΅ΡΠ½ΡΠΉΡΠ΅ΡΡ ΠΏΠΈΡΠ°ΡΡ Π² issues
Π±Π°Π³ΠΈ ΠΈ ΠΈΠ΄Π΅ΠΈ Π΄Π»Ρ ΡΠ°Π·Π²ΠΈΡΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ.