App Layout
@gravity-ui/app-layout ·

설치
npm install --save-dev @gravity-ui/app-layout
사용법
express와 함께 사용:
import express from 'express';
import {createRenderFunction} from '@gravity-ui/app-layout';
const app = express();
const renderLayout = createRenderFunction();
app.get('/', function (req, res) {
res.send(
renderLayout({
// RenderParams
title: '홈 페이지',
bodyContent: {
root: '안녕하세요!',
},
}),
);
});
app.listen(3000);
여기서
interface RenderParams<Data, Plugins> {
// window.__DATA__에 설정될 JSON 호환 데이터
data?: Data;
// favicon
icon?: Icon;
// 적절한 태그에 설정될 nonce
nonce?: string;
// base 태그 속성
base?: Base;
// 공통 옵션
// 페이지 제목
title: string;
// 페이지 언어, html 태그에 설정됨
lang?: string;
isMobile?: boolean;
// html 속성
htmlAttributes?: string;
// 헤더 태그 내용
// meta 태그
meta?: Meta[];
// link 태그
links?: Link[];
// script 태그
scripts?: Script[];
// style 태그
styleSheets?: Stylesheet[];
// 인라인 코드 스크립트 태그
inlineScripts?: string[];
// 인라인 스타일 태그
inlineStyleSheets?: string[];
// body 태그 내용
bodyContent?: {
// body 태그 클래스 이름
className?: string;
// body 속성
attributes?: string;
// root div 태그 이전의 body 내용
beforeRoot?: string;
// root div 태그의 innerHtml 내용
root?: string;
// root div 태그 이후의 body 내용
afterRoot?: string;
};
// 플러그인 옵션
pluginsOptions?: Partial<PluginsOptions<Plugins>>;
}
Base
base 태그를 설명합니다:
interface Base {
href?: string;
target?: HTMLBaseElement['target'];
}
예시:
renderLayout({
title: '홈 페이지',
base: {target: '_top'},
});
다음과 같이 렌더링됩니다:
<base target="_top" />
Meta
meta 태그를 설명합니다:
interface Meta {
name: string;
content: string;
}
예시:
const meta = [
{name: 'description', content: 'some text'},
{name: 'robots', content: 'noindex'},
{name: 'og:title', content: 'Some title'},
];
다음과 같이 렌더링됩니다:
<meta name="description" content="some text" />
<meta name="robots" content="noindex" />
<meta property="og:title" content="Some title" />
Icon
페이지 favicon을 설명합니다:
interface Icon {
type?: string;
sizes?: string;
href?: string;
}
기본값은 다음과 같습니다:
const icon = {
type: 'image/png',
sizes: '16x16',
href: '/favicon.png',
};
Links
link 태그를 설명합니다:
interface Link {
as?: string;
href: string;
rel?: string;
type?: string;
sizes?: string;
title?: HTMLLinkElement['title'];
crossOrigin?: '' | 'anonymous' | 'use-credentials';
}
예시:
const link = {
href: 'myFont.woff2',
rel: 'preload',
as: 'font',
type: 'font/woff2',
crossOrigin: 'anonymous',
};
다음과 같이 렌더링됩니다:
<link href="myFont.woff2" rel="preload" as="font" type="font/woff2" crossorigin="anonymous" />
Scripts
스크립트 사전 로드 링크를 설명합니다:
interface Script {
src: string;
defer?: boolean;
async?: boolean;
crossOrigin?: '' | 'anonymous' | 'use-credentials';
type?: 'importmap' | 'module' | string;
}
예시:
const script = {
src: 'url/to/script',
defer: true,
async: false,
crossOrigin: 'anonymous',
};
다음과 같이 렌더링됩니다:
<link href="url/to/script" rel="preload" as="script" crossorigin="anonymous" />
<script src="url/to/script" defer="true" async="false" crossorigin="anonymous" nonce="..."></script>
Style sheets
스타일 링크를 설명합니다:
interface Stylesheet {
href: string;
}
예시:
const styleSheet = {
href: 'url/to/stylesheet',
};
다음과 같이 렌더링됩니다:
<link href="url/to/stylesheet" rel="stylesheet" />
Plugins
렌더 함수는 플러그인으로 확장될 수 있습니다. 플러그인은 사용자 정의 렌더링 콘텐츠를 재작성할 수 있습니다.
플러그인은 name과 apply 속성을 가진 객체입니다:
interface Plugin<Options = any, Name = string> {
name: Name;
apply: (params: {
options: Options | undefined; // `pluginsOptions` 매개변수의 `renderLayout` 함수를 통해 전달됩니다.
commonOptions: CommonOptions;
renderContent: RenderContent;
/** @deprecated `renderContent.helpers`를 사용하세요 */
utils: RenderHelpers;
}) => void;
}
interface CommonOptions {
name: string;
title: string;
lang?: string;
isMobile?: boolean;
}
export interface HeadContent {
base?: Base;
scripts: Script[];
helpers: RenderHelpers;
links: Link[];
meta: Meta[];
styleSheets: Stylesheet[];
inlineStyleSheets: string[];
inlineScripts: string[];
title: string;
}
export interface BodyContent {
attributes: Attributes;
beforeRoot: string[];
root?: string;
afterRoot: string[];
}
export interface RenderContent extends HeadContent {
htmlAttributes: Attributes;
bodyContent: BodyContent;
}
export interface RenderHelpers {
renderScript(script: Script): string;
renderInlineScript(content: string): string;
renderStyle(style: Stylesheet): string;
renderInlineStyle(content: string): string;
renderMeta(meta: Meta): string;
renderLink(link: Link): string;
attrs(obj: Attributes): string;
}
이 패키지에는 몇 가지 플러그인이 있습니다:
Google analytics
페이지에 Google Analytics 카운터를 추가합니다.
사용법:
import {createRenderFunction, createGoogleAnalyticsPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([createGoogleAnalyticsPlugin()]);
app.get((req, res) => {
res.send(
renderLayout({
title: '홈 페이지',
pluginsOptions: {
googleAnalytics: {
useBeaconTransport: true, // navigator.sendBeacon 사용을 활성화합니다.
counter: {
id: 'some id',
},
},
},
}),
);
});
플러그인 옵션:
interface GoogleAnalyticsCounter {
id: string;
}
interface GoogleAnalyticsOptions {
useBeaconTransport?: boolean;
counter: GoogleAnalyticsCounter;
}
Yandex Metrika
페이지에 Yandex Metrika 카운터를 추가합니다.
사용법:
import {createRenderFunction, createYandexMetrikaPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([createYandexMetrikaPlugin()]);
app.get((req, res) => {
res.send(
renderLayout({
title: '홈 페이지',
pluginsOptions: {
yandexMetrika: {
counter: {
id: 123123123,
defer: true,
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
},
},
},
}),
);
});
플러그인 옵션:
export type UserParams = {
[x: string]: boolean | string | number | null | UserParams;
};
export interface MetrikaCounter {
id: number;
defer: boolean;
clickmap: boolean;
trackLinks: boolean;
accurateTrackBounce: boolean | number;
webvisor?: boolean;
nonce?: string;
encryptedExperiments?: string;
triggerEvent?: boolean;
trackHash?: boolean;
ecommerce?: boolean | string;
type?: number;
userParams?: UserParams;
}
export type MetrikaOptions = {
src?: string;
counter: MetrikaCounter | MetrikaCounter[];
};
Layout
Webpack assets manifest 파일에서 스크립트와 스타일을 추가합니다.
사용법:
import {createRenderFunction, createLayoutPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([
createLayoutPlugin({manifest: 'path/to/assets-manifest.json', publicPath: '/build/'}),
]);
app.get((req, res) => {
res.send(
renderLayout({
title: '홈 페이지',
pluginsOptions: {
layout: {
name: 'home',
},
},
}),
);
});
플러그인 옵션:
export interface LayoutOptions {
name: string;
prefix?: string;
}
@gravity-ui/uikit
body 속성을 추가합니다.
사용법:
import {createRenderFunction, createUikitPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([createUikitPlugin()]);
app.get((req, res) => {
res.send(
renderLayout({
title: '홈 페이지',
pluginsOptions: {
uikit: {
theme: 'dark',
direction: 'ltr',
},
},
}),
);
});
플러그인 옵션:
interface UikitPluginOptions {
theme: string;
direction?: 'ltr' | 'rtl';
}
Remote Versions
마이크로프론트엔드 버전 정보를 페이지에 추가합니다.
이 플러그인은 제공된 마이크로프론트엔드 버전을 포함하는 전역 window.__REMOTE_VERSIONS__ 객체를 생성하며, 이는 모듈 페더레이션 또는 유사한 마이크로프론트엔드 아키텍처에서 로드할 원격 모듈의 버전을 결정하는 데 사용될 수 있습니다.
App Builder 및 moduleFederation.remotesRuntimeVersioning 옵션과 함께 사용하여 해당 버전의 원격 모듈을 자동으로 로드할 수 있습니다.
사용법:
import {createRenderFunction, createRemoteVersionsPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([createRemoteVersionsPlugin()]);
app.get((req, res) => {
res.send(
renderLayout({
title: '홈 페이지',
pluginsOptions: {
remoteVersions: {
header: '1.2.3',
footer: '2.1.0',
sidebar: '0.5.1',
},
},
}),
);
});
플러그인 옵션:
type RemoteVersionsPluginOptions = Record<string, string>;
Helpers
모든 플러그인을 생성하는 헬퍼가 있습니다:
import {createMiddleware, createDefaultPlugins} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction(
createDefaultPlugins({layout: {manifest: 'path/to/assets-manifest.json'}})
);
app.get((req, res) => {
res.send(renderLayout({
title: '홈 페이지',
pluginsOptions: {
layout: {
name: 'home'
},
googleAnalytics: {
counter: {...}
},
yandexMetrika: {
counter: {...}
},
},
}));
})
Alternative usage
generateRenderContent, renderHeadContent, renderBodyContent 파트 렌더러를 사용하여 HTML 스트리밍으로:
import express from 'express';
import htmlescape from 'htmlescape';
import {
generateRenderContent,
renderHeadContent,
renderBodyContent,
createDefaultPlugins,
} from '@gravity-ui/app-layout';
const app = express();
app.get('/', async function (req, res) {
res.writeHead(200, {
'Content-Type': 'text/html',
'Transfer-Encoding': 'chunked',
});
```markdown
# @gravity/uikit
이 라이브러리는 React 애플리케이션을 위한 UI 컴포넌트 모음입니다.
## 설치
```bash
npm install @gravity/uikit
# 또는
yarn add @gravity/uikit
사용법
기본 사용법
import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from '@gravity/uikit';
function App() {
return (
<div>
<Button onClick={() => alert('Hello!')}>Click me</Button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
테마 설정
@gravity/uikit은 테마를 지원합니다. 테마를 설정하려면 ThemeProvider 컴포넌트를 사용하세요.
import React from 'react';
import ReactDOM from 'react-dom';
import { ThemeProvider, Button } from '@gravity/uikit';
const customTheme = {
colors: {
primary: 'blue',
secondary: 'green',
},
};
function App() {
return (
<ThemeProvider theme={customTheme}>
<Button>Themed Button</Button>
</ThemeProvider>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
컴포넌트
Button
버튼 컴포넌트입니다.
<Button
variant="primary" // 'primary', 'secondary', 'outline', 'text'
size="medium" // 'small', 'medium', 'large'
disabled={false}
onClick={() => console.log('Button clicked!')}
>
Click Me
</Button>
Input
입력 필드 컴포넌트입니다.
<Input
placeholder="Enter text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
error={inputError}
/>
Card
카드 컴포넌트입니다.
<Card title="Card Title">
<p>This is the content of the card.</p>
</Card>
기여
기여하고 싶으신가요? CONTRIBUTING.md 파일을 참고해주세요.
라이선스
MIT 라이선스 하에 배포됩니다. 자세한 내용은 LICENSE 파일을 참고해주세요.