842 lines
18 KiB
Markdown
842 lines
18 KiB
Markdown
# uikit
|
||
|
||
Shared library for BI next.js projects.
|
||
|
||
---
|
||
|
||
## Install
|
||
|
||
```bash
|
||
yarn add git+https://git.d.aiengines.ir/bi/uikit.git
|
||
```
|
||
|
||
---
|
||
|
||
## Update
|
||
|
||
```bash
|
||
yarn upgrade uikit
|
||
```
|
||
|
||
or
|
||
|
||
```bash
|
||
rm -rf .next
|
||
rm -rf node_modules/.vite
|
||
rm -rf node_modules/.cache
|
||
rm -rf node_modules/uikit
|
||
|
||
yarn upgrade uikit
|
||
```
|
||
|
||
---
|
||
|
||
# imports
|
||
|
||
| مسیر | کاربرد | dependency اضافی |
|
||
| ------------------ | ------------------------------------- | --------------------------------------- |
|
||
| `uikit` | utility functions | - |
|
||
| `uikit/utils` | utility functions | - |
|
||
| `uikit/pagination` | pagination | Chakra + React + react-icons |
|
||
| `uikit/layout` | Header, Sidebar | Chakra + React + React Icons |
|
||
| `uikit/core` | API، BiProvider، Keycloak، Permission | Chakra + React Query + Axios + Keycloak + Query Params |
|
||
| `uikit/table` | DataTable | Chakra + TanStack Table + Pagination |
|
||
| `uikit/remote/ui` | Remote UI components مثل `GBadge` | Chakra + React + remote static file |
|
||
|
||
---
|
||
|
||
# utils
|
||
|
||
```js
|
||
import { toFaDigits, toEnDigits, toFaNumber } from "uikit/utils";
|
||
|
||
toFaDigits(123456);
|
||
toEnDigits("۱۲۳۴۵۶");
|
||
toFaNumber(123456);
|
||
```
|
||
|
||
or
|
||
|
||
```js
|
||
import { toFaDigits } from "uikit";
|
||
```
|
||
|
||
---
|
||
|
||
# pagination
|
||
|
||
required dependencies
|
||
|
||
```bash
|
||
yarn add @chakra-ui/react@2
|
||
yarn add @chakra-ui/icons@2
|
||
yarn add @emotion/react@11
|
||
yarn add @emotion/styled@11
|
||
yarn add chakra-react-select@5
|
||
yarn add react-select@5
|
||
yarn add framer-motion@10
|
||
yarn add react-icons
|
||
```
|
||
|
||
using
|
||
|
||
```jsx
|
||
import { Pagination, LightPagination, SimplePagination } from "uikit/pagination";
|
||
|
||
function Page() {
|
||
return (
|
||
<Pagination
|
||
currentPage={1}
|
||
totalCount={100}
|
||
totalPages={5}
|
||
onPageChange={(page) => console.log(page)}
|
||
/>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# Header
|
||
|
||
required dependencies:
|
||
|
||
```bash
|
||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
|
||
```
|
||
|
||
using:
|
||
|
||
```jsx
|
||
import { Header } from "uikit/layout";
|
||
|
||
function AppHeader() {
|
||
return (
|
||
<Header>
|
||
<Header.BrandSection>
|
||
<Header.Logo src="/logo.png" />
|
||
|
||
<Header.Brand>
|
||
<Header.Title>عنوان سامانه</Header.Title>
|
||
<Header.Description>توضیح کوتاه سامانه</Header.Description>
|
||
</Header.Brand>
|
||
</Header.BrandSection>
|
||
|
||
<Header.Bi />
|
||
</Header>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# Sidebar
|
||
|
||
required dependencies:
|
||
|
||
```bash
|
||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion react-icons
|
||
yarn add @tanstack/react-query axios keycloak-js
|
||
yarn add next-query-params@^5.1.0 use-query-params@^2.2.2
|
||
```
|
||
|
||
`Sidebar` همان UI ناوبری سامانه را برای دسکتاپ و موبایل ارائه میدهد. در دسکتاپ به صورت نوار آیکون کناری و در موبایل به صورت bottom navigation + drawer «بیشتر» نمایش داده میشود.
|
||
|
||
آیتمها به صورت config به کامپوننت داده میشوند:
|
||
|
||
```jsx
|
||
import { SlUserFollowing } from "react-icons/sl";
|
||
|
||
const navigationItems = [
|
||
{
|
||
title: "آنالیز شبکه متعارف - فالوور/فالووینگ",
|
||
mobileTitle: "ارتباط کاربران",
|
||
icon: SlUserFollowing,
|
||
path: "/user-connections/analyze",
|
||
perm: ["analyze"],
|
||
},
|
||
];
|
||
```
|
||
|
||
نمونه استفاده در Next.js Pages Router:
|
||
|
||
```jsx
|
||
import NextLink from "next/link";
|
||
import { useRouter } from "next/router";
|
||
import { Sidebar } from "uikit/layout";
|
||
|
||
function AppSidebar() {
|
||
const router = useRouter();
|
||
|
||
return (
|
||
<Sidebar
|
||
items={navigationItems}
|
||
currentPath={router.asPath}
|
||
linkComponent={NextLink}
|
||
/>
|
||
);
|
||
}
|
||
```
|
||
|
||
`Sidebar` باید داخل `BiProvider` استفاده شود. Permission هر آیتم از `perm` توسط خود UI Kit بررسی میشود و خروج با Keycloak توسط خود UI Kit انجام میشود. سامانه مقصد نیازی به `usePermission` یا `logoutKeycloak` برای Sidebar ندارد.
|
||
|
||
کنترل دسترسی کلی `panel_access` عمداً داخل Sidebar انجام نمیشود تا navigation هنگام render باعث redirect و لغو route در Next.js نشود. اگر سامانه به این guard نیاز دارد، از `PanelAccessGuard` موجود در `uikit/core` در سطح Layout/App استفاده کنید.
|
||
|
||
`aliases` نیز پشتیبانی میشود و برای تشخیص آیتم active استفاده میشود:
|
||
|
||
```jsx
|
||
{
|
||
title: "آنالیز شبکه های اجتماعی خارجی",
|
||
mobileTitle: "شبکه خارجی",
|
||
icon: TbAnalyze,
|
||
path: "/posts/final_analyze",
|
||
aliases: ["/posts/analyze"],
|
||
perm: ["analyze"],
|
||
}
|
||
```
|
||
|
||
اگر `perm` آرایه باشد، همه permissionهای داخل آرایه برای فعال بودن آیتم لازم هستند. آیتم بدون `perm` محدودیت permission ندارد.
|
||
|
||
---
|
||
|
||
# Core
|
||
|
||
required dependencies:
|
||
|
||
```bash
|
||
yarn add @chakra-ui/react@^2
|
||
yarn add @emotion/react@^11
|
||
yarn add @emotion/styled@^11
|
||
yarn add framer-motion@^12
|
||
yarn add @tanstack/react-query@^5
|
||
yarn add axios@^1
|
||
yarn add keycloak-js
|
||
yarn add next-query-params@^5.1.0
|
||
yarn add use-query-params@^2.2.2
|
||
```
|
||
|
||
---
|
||
|
||
## BiProvider
|
||
|
||
```jsx
|
||
import { BiProvider } from "uikit/core";
|
||
|
||
export default function App() {
|
||
return (
|
||
<BiProvider
|
||
apiBaseUrl="https://api.example.com"
|
||
keycloakClientId="front-client"
|
||
permissionClientId="permission-client"
|
||
>
|
||
<YourApp />
|
||
</BiProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## BiProvider props
|
||
|
||
| Prop |
|
||
| ----------------------------- |
|
||
| `apiBaseUrl` |
|
||
| `keycloakClientId` |
|
||
| `permissionClientId` |
|
||
| `loading` |
|
||
| `updateChecker` |
|
||
| `updateCheckerProps` |
|
||
| `keycloakUrl` |
|
||
| `keycloakRealm` |
|
||
| `permissionUrl` |
|
||
| `keycloakEnabled` |
|
||
| `permissionEnabled` |
|
||
| `remoteUiEnabled` |
|
||
| `remoteUiUrl` |
|
||
| `remoteUiChakraProviderProps` |
|
||
|
||
---
|
||
|
||
## BiProvider defaults
|
||
|
||
```js
|
||
keycloakUrl = "https://auth.ibagher.ir";
|
||
keycloakRealm = "bi";
|
||
permissionUrl = "https://api.d.aiengines.ir/user_api/v1/permissions/list";
|
||
updateChecker = false;
|
||
remoteUiEnabled = true;
|
||
remoteUiUrl = "https://uikit.d.aiengines.ir/GBadge.js";
|
||
```
|
||
|
||
---
|
||
|
||
## BiProvider with Remote UI
|
||
|
||
`BiProvider` به صورت خودکار dependencyهای لازم برای کامپوننتهای `remote/ui` را setup میکند.
|
||
|
||
پس اگر سامانه مقصد از `BiProvider` استفاده میکند، برای استفاده از `GBadge` کار اضافهای لازم نیست.
|
||
|
||
```jsx
|
||
import { BiProvider } from "uikit/core";
|
||
import { GBadge } from "uikit/remote/ui";
|
||
|
||
export default function App() {
|
||
return (
|
||
<BiProvider
|
||
apiBaseUrl="https://api.example.com"
|
||
keycloakClientId="front-client"
|
||
permissionClientId="permission-client"
|
||
>
|
||
<GBadge colorScheme="blue" py={1} px={2} borderRadius="full">
|
||
فعال
|
||
</GBadge>
|
||
</BiProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
در این حالت `GBadge` همچنان از Chakra استفاده میکند، ولی فایل remote آن، یعنی `GBadge.js`، خودش Chakra و React و font را داخل bundle نمیآورد.
|
||
|
||
dependencyهای لازم از خود سامانه مقصد گرفته میشوند.
|
||
|
||
---
|
||
|
||
## Change Remote UI URL
|
||
|
||
اگر فایل remote روی آدرس دیگری deploy شده باشد:
|
||
|
||
```jsx
|
||
import { BiProvider } from "uikit/core";
|
||
|
||
export default function App() {
|
||
return (
|
||
<BiProvider
|
||
apiBaseUrl="https://api.example.com"
|
||
keycloakClientId="front-client"
|
||
permissionClientId="permission-client"
|
||
remoteUiUrl="https://static.example.com/uikit/GBadge.js"
|
||
>
|
||
<YourApp />
|
||
</BiProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Disable Remote UI setup in BiProvider
|
||
|
||
اگر نمیخواهید `BiProvider` به صورت خودکار remote ui را setup کند:
|
||
|
||
```jsx
|
||
import { BiProvider } from "uikit/core";
|
||
|
||
export default function App() {
|
||
return (
|
||
<BiProvider
|
||
apiBaseUrl="https://api.example.com"
|
||
keycloakClientId="front-client"
|
||
permissionClientId="permission-client"
|
||
remoteUiEnabled={false}
|
||
>
|
||
<YourApp />
|
||
</BiProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
To enable `updateChecker` you should have a script `write-version.js` in the root of the project and in the `package.json` of the target project, run before the build:
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"prebuild": "node write-version.js",
|
||
"build": "next build"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# API
|
||
|
||
```js
|
||
import { api, fetcher, configureApi, getApi } from "uikit/core";
|
||
```
|
||
|
||
```js
|
||
import { api } from "uikit/core";
|
||
|
||
const response = await api.get("/users");
|
||
```
|
||
|
||
or
|
||
|
||
```js
|
||
import { fetcher } from "uikit/core";
|
||
|
||
const data = await fetcher("/users");
|
||
```
|
||
|
||
---
|
||
|
||
# createApi
|
||
|
||
```js
|
||
import { createApi } from "uikit/core";
|
||
|
||
export const sampleApi = createApi({
|
||
key: "sample",
|
||
url: "/...",
|
||
|
||
actions: {
|
||
create: {
|
||
method: "post",
|
||
url: "/...",
|
||
},
|
||
|
||
update: {
|
||
method: "patch",
|
||
url: (id) => `/.../${id}`,
|
||
},
|
||
|
||
delete: {
|
||
method: "delete",
|
||
url: (id) => `/.../${id}`,
|
||
},
|
||
|
||
confirm: {
|
||
method: "post",
|
||
url: "/...",
|
||
},
|
||
|
||
updateImage: {
|
||
method: "post",
|
||
url: (id) => `/.../${id}/image`,
|
||
body: ({ formData }) => formData,
|
||
},
|
||
},
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
# Keycloak
|
||
|
||
```js
|
||
import {
|
||
getKeycloakToken,
|
||
loginKeycloak,
|
||
logoutKeycloak,
|
||
} from "uikit/core";
|
||
|
||
const token = getKeycloakToken();
|
||
|
||
loginKeycloak();
|
||
|
||
logoutKeycloak({
|
||
redirectUri: window.location.origin,
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
# Permission
|
||
|
||
```jsx
|
||
import { Can, usePermission } from "uikit/core";
|
||
|
||
function Page() {
|
||
const { can, cannot, permissions } = usePermission();
|
||
|
||
return (
|
||
<>
|
||
{can("users:list") && <div>لیست کاربران</div>}
|
||
|
||
<Can perm="users:create" fallback={null}>
|
||
<button>ایجاد کاربر</button>
|
||
</Can>
|
||
</>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# Remote UI
|
||
|
||
`remote/ui` برای کامپوننتهایی است که باید بدون build مجدد سامانه مقصد، از طریق فایل remote بهروزرسانی شوند.
|
||
|
||
مثلاً `GBadge` از این مسیر استفاده میشود:
|
||
|
||
```jsx
|
||
import { GBadge } from "uikit/remote/ui";
|
||
|
||
function Page() {
|
||
return (
|
||
<GBadge colorScheme="blue" py={1} px={2} borderRadius="full">
|
||
فعال
|
||
</GBadge>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## GBadge
|
||
|
||
required dependencies:
|
||
|
||
```bash
|
||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
|
||
```
|
||
|
||
using:
|
||
|
||
```jsx
|
||
import { GBadge } from "uikit/remote/ui";
|
||
|
||
function Page({ item }) {
|
||
return (
|
||
<GBadge colorScheme="blue" py={1} px={2} borderRadius="full">
|
||
{item}
|
||
</GBadge>
|
||
);
|
||
}
|
||
```
|
||
|
||
`GBadge` از Chakra `Badge` استفاده میکند.
|
||
|
||
اما برای کم شدن حجم فایل remote، این موارد داخل `GBadge.js` bundle نمیشوند:
|
||
|
||
```txt
|
||
React
|
||
ReactDOM
|
||
Chakra
|
||
Emotion
|
||
theme
|
||
Fonts
|
||
font files
|
||
```
|
||
|
||
این موارد باید در سامانه مقصد وجود داشته باشند.
|
||
|
||
---
|
||
|
||
## GBadge with BiProvider
|
||
|
||
اگر سامانه مقصد از `BiProvider` استفاده میکند، نیازی به setup دستی نیست:
|
||
|
||
```jsx
|
||
import { BiProvider } from "uikit/core";
|
||
import { GBadge } from "uikit/remote/ui";
|
||
|
||
function App() {
|
||
return (
|
||
<BiProvider
|
||
apiBaseUrl="https://api.example.com"
|
||
keycloakClientId="front-client"
|
||
permissionClientId="permission-client"
|
||
>
|
||
<GBadge colorScheme="blue" py={1} px={2} borderRadius="full">
|
||
فعال
|
||
</GBadge>
|
||
</BiProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## GBadge without BiProvider
|
||
|
||
اگر سامانه مقصد از `BiProvider` استفاده نمیکند، دو حالت وجود دارد.
|
||
|
||
### حالت ساده
|
||
|
||
اگر theme خاصی ندارید، فقط استفاده از `GBadge` کافی است:
|
||
|
||
```jsx
|
||
import { GBadge } from "uikit/remote/ui";
|
||
|
||
function Page() {
|
||
return (
|
||
<GBadge colorScheme="blue" py={1} px={2} borderRadius="full">
|
||
فعال
|
||
</GBadge>
|
||
);
|
||
}
|
||
```
|
||
|
||
در این حالت wrapper مربوط به `GBadge` خودش dependencyهای لازم را setup میکند.
|
||
|
||
---
|
||
|
||
### حالت با theme اختصاصی
|
||
|
||
اگر سامانه مقصد theme اختصاصی Chakra دارد، بهتر است در entry اصلی پروژه یک بار setup انجام شود.
|
||
|
||
مثلاً در `main.jsx`، `App.jsx` یا `_app.jsx`:
|
||
|
||
```jsx
|
||
import React from "react";
|
||
import { createRoot } from "react-dom/client";
|
||
import { ChakraProvider } from "@chakra-ui/react";
|
||
import { setupUikitRemoteDeps } from "uikit/remote/ui";
|
||
import { theme } from "./theme";
|
||
import App from "./App";
|
||
|
||
setupUikitRemoteDeps({
|
||
theme,
|
||
});
|
||
|
||
createRoot(document.getElementById("root")).render(
|
||
<ChakraProvider theme={theme}>
|
||
<App />
|
||
</ChakraProvider>,
|
||
);
|
||
```
|
||
|
||
برای Next.js:
|
||
|
||
```jsx
|
||
import { ChakraProvider } from "@chakra-ui/react";
|
||
import { setupUikitRemoteDeps } from "uikit/remote/ui";
|
||
import { theme } from "@/theme";
|
||
|
||
setupUikitRemoteDeps({
|
||
theme,
|
||
});
|
||
|
||
export default function App({ Component, pageProps }) {
|
||
return (
|
||
<ChakraProvider theme={theme}>
|
||
<Component {...pageProps} />
|
||
</ChakraProvider>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Remote URL without BiProvider
|
||
|
||
اگر سامانه مقصد از `BiProvider` استفاده نمیکند و آدرس فایل remote متفاوت است:
|
||
|
||
```jsx
|
||
import { setupUikitRemoteDeps } from "uikit/remote/ui";
|
||
import { theme } from "./theme";
|
||
|
||
setupUikitRemoteDeps({
|
||
theme,
|
||
remoteUrl: "https://static.example.com/uikit/GBadge.js",
|
||
});
|
||
```
|
||
|
||
یا مستقیم روی خود کامپوننت:
|
||
|
||
```jsx
|
||
import { GBadge } from "uikit/remote/ui";
|
||
|
||
function Page() {
|
||
return (
|
||
<GBadge
|
||
remoteUrl="https://static.example.com/uikit/GBadge.js"
|
||
colorScheme="blue"
|
||
py={1}
|
||
px={2}
|
||
borderRadius="full"
|
||
>
|
||
فعال
|
||
</GBadge>
|
||
);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Font
|
||
|
||
فونت داخل فایل remote باندل نمیشود.
|
||
|
||
اگر سامانه مقصد از `BiProvider` استفاده میکند، فونت و theme اصلی از همان `BiProvider` میآید.
|
||
|
||
اگر سامانه مقصد `BiProvider` ندارد، فونت را در خود سامانه مقصد ست کنید:
|
||
|
||
```css
|
||
@font-face {
|
||
font-family: Estedad;
|
||
src: url("/fonts/estedad.woff2") format("woff2");
|
||
font-weight: 400;
|
||
font-style: normal;
|
||
font-display: swap;
|
||
}
|
||
|
||
:root {
|
||
--uikit-font-family: Estedad, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||
}
|
||
|
||
body {
|
||
font-family: var(--uikit-font-family);
|
||
}
|
||
```
|
||
|
||
`GBadge` از این مقدار استفاده میکند:
|
||
|
||
```css
|
||
var(--uikit-font-family, inherit)
|
||
```
|
||
|
||
---
|
||
|
||
## Build Remote UI
|
||
|
||
برای ساخت فایل remote:
|
||
|
||
```bash
|
||
yarn build:remote
|
||
```
|
||
|
||
خروجی remote:
|
||
|
||
```txt
|
||
dist/remote/GBadge.js
|
||
```
|
||
|
||
این فایل باید روی static server یا CDN داخلی deploy شود.
|
||
|
||
مثلاً:
|
||
|
||
```txt
|
||
https://uikit.d.aiengines.ir/GBadge.js
|
||
```
|
||
|
||
---
|
||
|
||
## Deploy Remote UI
|
||
|
||
بعد از تغییر در `GBadge.remote.jsx` یا کامپوننتهای remote:
|
||
|
||
```bash
|
||
yarn build:remote
|
||
```
|
||
|
||
سپس فایل زیر را deploy کنید:
|
||
|
||
```txt
|
||
dist/remote/GBadge.js
|
||
```
|
||
|
||
سامانههای مقصد بعد از reload صفحه، نسخه جدید remote را دریافت میکنند.
|
||
|
||
اگر cache سمت browser یا CDN فعال است، باید cache فایل remote کنترل شود.
|
||
|
||
---
|
||
|
||
## Important Notes
|
||
|
||
اگر از مسیر زیر استفاده شود:
|
||
|
||
```js
|
||
import { GBadge } from "uikit/remote/ui";
|
||
```
|
||
|
||
خود کامپوننت از فایل remote استفاده میکند.
|
||
|
||
اما اگر کامپوننتی از مسیر معمولی package import شود، مثل:
|
||
|
||
```js
|
||
import { SomeComponent } from "uikit";
|
||
```
|
||
|
||
یا:
|
||
|
||
```js
|
||
import { SomeComponent } from "uikit/table";
|
||
```
|
||
|
||
آن کامپوننت داخل build سامانه مقصد bundle میشود و برای آپدیت شدن نیاز به rebuild یا `yarn upgrade` دارد.
|
||
|
||
پس:
|
||
|
||
```txt
|
||
uikit/remote/ui => update by remote file
|
||
uikit/table => update by package upgrade
|
||
uikit/core => update by package upgrade
|
||
uikit/layout => update by package upgrade
|
||
```
|
||
|
||
---
|
||
|
||
# DataTable
|
||
|
||
required dependencies:
|
||
|
||
```bash
|
||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-table react-icons
|
||
```
|
||
|
||
using:
|
||
|
||
```jsx
|
||
import { DataTable } from "uikit/table";
|
||
|
||
function UsersTable({ data, columns }) {
|
||
return (
|
||
<DataTable
|
||
data={data}
|
||
columns={columns}
|
||
page={1}
|
||
size={20}
|
||
pagination={{
|
||
totalCount: 100,
|
||
totalPages: 5,
|
||
}}
|
||
onPageChange={(page) => console.log(page)}
|
||
getRowId={(row) => String(row.id)}
|
||
enableSelection
|
||
showIndex
|
||
>
|
||
<DataTable.Topbar>
|
||
<DataTable.Title>لیست کاربران</DataTable.Title>
|
||
<DataTable.Spacer />
|
||
<DataTable.Actions>
|
||
<DataTable.SelectAll />
|
||
</DataTable.Actions>
|
||
</DataTable.Topbar>
|
||
|
||
<DataTable.Content>
|
||
<DataTable.Table />
|
||
<DataTable.Pagination />
|
||
</DataTable.Content>
|
||
</DataTable>
|
||
);
|
||
}
|
||
```
|
||
|
||
|
||
## Sidebar.Exit
|
||
|
||
`Sidebar` بهصورت پیشفرض گزینه خروج را نمایش نمیدهد. برای فعالکردن خروج Keycloak داخلی UI Kit، آن را بهصورت compound component اضافه کنید:
|
||
|
||
```jsx
|
||
<Sidebar
|
||
items={items}
|
||
currentPath={router.asPath}
|
||
linkComponent={NextLink}
|
||
>
|
||
<Sidebar.Exit />
|
||
</Sidebar>
|
||
```
|
||
|
||
عنوان و آیکون خروج قابل تغییر هستند:
|
||
|
||
```jsx
|
||
<Sidebar.Exit title="خروج از سامانه" icon={MyExitIcon} />
|
||
```
|
||
|
||
`Sidebar.Exit` از `logoutKeycloak` داخلی UI Kit استفاده میکند و callback خروج از سامانه مقصد نیاز ندارد.
|