full refactor
This commit is contained in:
parent
67cd686868
commit
c0a058e183
619
README.md
619
README.md
@ -1,13 +1,10 @@
|
||||
# کتابخانه uikit
|
||||
این README رو جایگزین قبلی کن. importها با ساختار جدید هماهنگه: `utils`, `pagination`, `layout`, `core`, `table`. چون ظاهراً README قبلی هم مثل خیلی از READMEها بیشتر آرزو بود تا واقعیت.
|
||||
|
||||
یک کتابخانهی React برای استفادهی مشترک بین پروژهها.
|
||||
# uikit
|
||||
|
||||
این پکیج شامل این موارد است:
|
||||
کتابخانهی مشترک React برای استفاده بین پروژههای BI.
|
||||
|
||||
* base api config
|
||||
* keycloak config
|
||||
* permissions config
|
||||
* BiProvider
|
||||
این پکیج به چند entry جدا تقسیم شده تا پروژهها فقط همان بخشی را import کنند که لازم دارند و مجبور نباشند برای یک helper ساده، dependencyهای سنگین مثل Chakra، Keycloak یا React Query نصب کنند.
|
||||
|
||||
---
|
||||
|
||||
@ -17,10 +14,10 @@
|
||||
yarn add git+https://git.d.aiengines.ir/bi/uikit.git
|
||||
```
|
||||
|
||||
اگر این پکیج روی پروژه نصب شد ولی خطای dependency گرفتی، اینها را هم نصب کن:
|
||||
یا اگر branch/tag خاصی لازم داری:
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion keycloak-js axios @tanstack/react-query react-icons
|
||||
yarn add git+https://git.d.aiengines.ir/bi/uikit.git#main
|
||||
```
|
||||
|
||||
---
|
||||
@ -31,19 +28,153 @@ yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion keycloak-
|
||||
yarn upgrade uikit
|
||||
```
|
||||
|
||||
اگر از git dependency استفاده میکنی و نسخه جدید نگرفتی، lockfile را هم بررسی کن:
|
||||
|
||||
```bash
|
||||
yarn remove uikit
|
||||
yarn add git+https://git.d.aiengines.ir/bi/uikit.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## استفاده اصلی
|
||||
# ساختار importها
|
||||
|
||||
| مسیر | کاربرد | dependency اضافی |
|
||||
| ------------------ | ------------------------------------- | --------------------------------------- |
|
||||
| `uikit` | خروجی سبک، فعلاً فقط utils | ندارد |
|
||||
| `uikit/utils` | helperهای ساده مثل تبدیل عدد | ندارد |
|
||||
| `uikit/pagination` | کامپوننتهای pagination | Chakra + React + react-icons |
|
||||
| `uikit/layout` | کامپوننتهای layout مثل Header | Chakra + React |
|
||||
| `uikit/core` | API، BiProvider، Keycloak، Permission | Chakra + React Query + Axios + Keycloak |
|
||||
| `uikit/table` | DataTable | Chakra + TanStack Table + Pagination |
|
||||
|
||||
---
|
||||
|
||||
# استفاده از utils
|
||||
|
||||
برای helperهای ساده نیازی به نصب هیچ dependency اضافهای نیست.
|
||||
|
||||
```js
|
||||
import { toFaDigits, toEnDigits, toFaNumber } from "uikit/utils";
|
||||
|
||||
toFaDigits(123456); // ۱۲۳۴۵۶
|
||||
toEnDigits("۱۲۳۴۵۶"); // 123456
|
||||
toFaNumber(123456); // عدد فارسیشده
|
||||
```
|
||||
|
||||
همچنین چون root package فقط utils را export میکند، این هم قابل استفاده است:
|
||||
|
||||
```js
|
||||
import { toFaDigits } from "uikit";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# استفاده از pagination
|
||||
|
||||
اگر از pagination استفاده میکنی، این dependencyها باید در پروژه نصب باشند:
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion react-icons
|
||||
```
|
||||
|
||||
استفاده:
|
||||
|
||||
```jsx
|
||||
import { BiProvider } from "uikit";
|
||||
import { Pagination, LightPagination, SimplePagination } from "uikit/pagination";
|
||||
|
||||
function Page() {
|
||||
return (
|
||||
<Pagination
|
||||
currentPage={1}
|
||||
totalCount={100}
|
||||
totalPages={5}
|
||||
onPageChange={(page) => console.log(page)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# استفاده از Header
|
||||
|
||||
`Header` داخل مسیر `uikit/layout` قرار دارد.
|
||||
|
||||
dependencyهای لازم:
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
|
||||
```
|
||||
|
||||
استفاده:
|
||||
|
||||
```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>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
اجزای موجود:
|
||||
|
||||
```jsx
|
||||
<Header />
|
||||
<Header.BrandSection />
|
||||
<Header.Logo />
|
||||
<Header.Brand />
|
||||
<Header.Title />
|
||||
<Header.Description />
|
||||
<Header.Bi />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# استفاده از core
|
||||
|
||||
بخش core شامل این موارد است:
|
||||
|
||||
* API config
|
||||
* `createApi`
|
||||
* `BiProvider`
|
||||
* Keycloak
|
||||
* Permission
|
||||
* React Query provider
|
||||
* Chakra provider
|
||||
|
||||
برای استفاده از core این dependencyها باید در پروژه نصب باشند:
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-query axios keycloak-js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## استفاده از BiProvider
|
||||
|
||||
```jsx
|
||||
import { BiProvider } from "uikit/core";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<BiProvider
|
||||
apiBaseUrl="https://api.example.com"
|
||||
keycloakClientId="client_id"
|
||||
permissionClientId="client_id"
|
||||
keycloakClientId="front-client"
|
||||
permissionClientId="permission-client"
|
||||
>
|
||||
<YourApp />
|
||||
</BiProvider>
|
||||
@ -51,107 +182,451 @@ export default function App() {
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
`BiProvider` به صورت داخلی این کارها را انجام میدهد:
|
||||
|
||||
## پراپس های `BiProvider`
|
||||
|
||||
| Prop | توضیح |
|
||||
| -------------------- | ----------------------------------------------- |
|
||||
| `apiBaseUrl` | آدرس اصلی API |
|
||||
| `keycloakClientId` | client id مربوط به Keycloak |
|
||||
| `permissionClientId` | client id مربوط به Permission |
|
||||
| `keycloakUrl` | آدرس Keycloak |
|
||||
| `keycloakRealm` | realm مربوط به Keycloak |
|
||||
| `permissionUrl` | آدرس API مربوط به permission |
|
||||
| `loading` | کامپوننت loading |
|
||||
| `updateChecker` | فعال یا غیرفعال کردن بررسی آپدیت |
|
||||
| `updateCheckerProps` | props مربوط به UpdateChecker |
|
||||
* تنظیم base url برای API
|
||||
* راهاندازی Keycloak در صورت فعال بودن
|
||||
* گرفتن permissionها در صورت فعال بودن
|
||||
* اضافه کردن `ChakraProvider`
|
||||
* اضافه کردن `QueryClientProvider`
|
||||
* اضافه کردن فونت و theme داخلی
|
||||
* فعال کردن اختیاری `UpdateChecker`
|
||||
|
||||
---
|
||||
|
||||
## مقدارهای پیشفرض
|
||||
## props مربوط به BiProvider
|
||||
|
||||
| Prop | توضیح |
|
||||
| -------------------- | ------------------------------------------------------ |
|
||||
| `apiBaseUrl` | آدرس اصلی API |
|
||||
| `keycloakClientId` | client id مربوط به Keycloak |
|
||||
| `permissionClientId` | client id مربوط به Permission |
|
||||
| `loading` | کامپوننت loading هنگام init شدن Keycloak یا Permission |
|
||||
| `updateChecker` | فعال یا غیرفعال کردن بررسی آپدیت |
|
||||
| `updateCheckerProps` | props مربوط به UpdateChecker |
|
||||
| `keycloakUrl` | آدرس Keycloak |
|
||||
| `keycloakRealm` | realm مربوط به Keycloak |
|
||||
| `permissionUrl` | آدرس API مربوط به permission |
|
||||
| `keycloakEnabled` | فعال یا غیرفعال کردن Keycloak به صورت دستی |
|
||||
| `permissionEnabled` | فعال یا غیرفعال کردن Permission به صورت دستی |
|
||||
|
||||
---
|
||||
|
||||
## مقدارهای پیشفرض BiProvider
|
||||
|
||||
```js
|
||||
keycloakUrl = "https://auth.ibagher.ir"
|
||||
keycloakRealm = "bi"
|
||||
permissionUrl = "https://api.d.aiengines.ir/user_api/v1/permissions/list"
|
||||
updateChecker = true
|
||||
keycloakUrl = "https://auth.ibagher.ir";
|
||||
keycloakRealm = "bi";
|
||||
permissionUrl = "https://api.d.aiengines.ir/user_api/v1/permissions/list";
|
||||
updateChecker = false;
|
||||
```
|
||||
|
||||
نکته: اگر `keycloakClientId` داده شود، Keycloak فعال میشود. اگر `permissionClientId` داده شود، Permission فعال میشود.
|
||||
|
||||
برای کنترل دستی:
|
||||
|
||||
```jsx
|
||||
<BiProvider
|
||||
apiBaseUrl="https://api.example.com"
|
||||
keycloakEnabled={false}
|
||||
permissionEnabled={false}
|
||||
>
|
||||
<YourApp />
|
||||
</BiProvider>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## غیرفعال کردن `UpdateChecker`
|
||||
# UpdateChecker
|
||||
|
||||
اگر پروژه فایل نیاز به چک کردن مداوم نسخه ندارد، بهتر است `updateChecker` را خاموش کنی:
|
||||
به صورت پیشفرض `updateChecker` خاموش است.
|
||||
|
||||
برای فعال کردن:
|
||||
|
||||
```jsx
|
||||
<BiProvider
|
||||
apiBaseUrl="https://api.example.com"
|
||||
keycloakClientId="front-client"
|
||||
permissionClientId="permission-client"
|
||||
updateChecker={false}
|
||||
updateChecker
|
||||
>
|
||||
<YourApp />
|
||||
</BiProvider>
|
||||
```
|
||||
|
||||
و اگر `true` باشد نیاز هست تا فایل `write-version.js` در روت پروژه گذاشته شود و اسکریپت `prebuild` نیز به `package.json` اضافه شود.
|
||||
اگر `updateChecker` را فعال میکنی، پروژه باید فایل version تولید کند. معمولاً باید یک اسکریپت مثل `write-version.js` در root پروژه داشته باشی و در `package.json` پروژه target، قبل از build اجرا شود.
|
||||
|
||||
---
|
||||
نمونه:
|
||||
|
||||
## استفاده از `Header`
|
||||
|
||||
```jsx
|
||||
<Header>
|
||||
<Header.BrandSection>
|
||||
<Header.Logo src="/logo.png" />
|
||||
<Header.Brand>
|
||||
<Header.Title>Title</Header.Title>
|
||||
<Header.Description>Description</Header.Description>
|
||||
</Header.Brand>
|
||||
</Header.BrandSection>
|
||||
|
||||
<Header.Bi />
|
||||
</Header>
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"prebuild": "node write-version.js",
|
||||
"build": "next build"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## موارد دیگر `js`
|
||||
# استفاده از API پایه
|
||||
|
||||
```js
|
||||
toFaDigits();
|
||||
toEnDigits();
|
||||
toFaNumber();
|
||||
import { api, fetcher, configureApi, getApi } from "uikit/core";
|
||||
```
|
||||
|
||||
---
|
||||
اگر از `BiProvider` استفاده میکنی، معمولاً نیازی نیست دستی `configureApi` را صدا بزنی، چون `BiProvider` این کار را انجام میدهد.
|
||||
|
||||
## موارد دیگر `jsx`
|
||||
|
||||
```jsx
|
||||
<Pagination />
|
||||
<LightPagination />
|
||||
<SimplePagination />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## موارد دیگر `keycloak`
|
||||
نمونه استفاده مستقیم:
|
||||
|
||||
```js
|
||||
import { api } from "uikit/core";
|
||||
|
||||
const response = await api.get("/users");
|
||||
```
|
||||
|
||||
یا:
|
||||
|
||||
```js
|
||||
import { fetcher } from "uikit/core";
|
||||
|
||||
const data = await fetcher("/users");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# استفاده از createApi
|
||||
|
||||
`createApi` برای ساختن یک API ساده بر پایه React Query استفاده میشود.
|
||||
|
||||
```js
|
||||
import { createApi } from "uikit/core";
|
||||
|
||||
export const profileApi = createApi({
|
||||
key: "profile",
|
||||
url: "/content/rokn/profiles",
|
||||
|
||||
actions: {
|
||||
update: {
|
||||
method: "patch",
|
||||
url: (id) => `/content/rokn/profiles/${id}`,
|
||||
},
|
||||
|
||||
delete: {
|
||||
method: "delete",
|
||||
},
|
||||
|
||||
generate: {
|
||||
method: "post",
|
||||
url: "/content/rokn/generate/profile",
|
||||
},
|
||||
|
||||
updateImages: {
|
||||
method: "post",
|
||||
url: (id) => `/content/rokn/profile-update/${id}/images`,
|
||||
body: ({ formData }) => formData,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## گرفتن لیست
|
||||
|
||||
```jsx
|
||||
const { data, isLoading, error } = profileApi.useGet({
|
||||
page: 1,
|
||||
size: 20,
|
||||
is_confirmed: true,
|
||||
});
|
||||
```
|
||||
|
||||
این request ساخته میشود:
|
||||
|
||||
```txt
|
||||
GET /content/rokn/profiles?page=1&size=20&is_confirmed=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## اجرای action
|
||||
|
||||
```jsx
|
||||
const updateProfile = profileApi.useAction("update");
|
||||
|
||||
await updateProfile.mutateAsync({
|
||||
id: 10,
|
||||
username: "new_username",
|
||||
});
|
||||
```
|
||||
|
||||
در این حالت:
|
||||
|
||||
```txt
|
||||
PATCH /content/rokn/profiles/10
|
||||
```
|
||||
|
||||
body:
|
||||
|
||||
```js
|
||||
{
|
||||
username: "new_username"
|
||||
}
|
||||
```
|
||||
|
||||
`id` به صورت پیشفرض از body حذف میشود، چون برای ساختن URL استفاده شده است.
|
||||
|
||||
---
|
||||
|
||||
## action با همان URL اصلی
|
||||
|
||||
اگر action همان URL اصلی را لازم دارد، نیازی نیست `url` را دوباره بنویسی.
|
||||
|
||||
```js
|
||||
export const identityGenerateApi = createApi({
|
||||
key: "identity-generate",
|
||||
url: "/content/rokn/identity-generate/logs",
|
||||
|
||||
actions: {
|
||||
delete: {
|
||||
method: "delete",
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
یعنی:
|
||||
|
||||
```txt
|
||||
DELETE /content/rokn/identity-generate/logs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## action با FormData
|
||||
|
||||
```js
|
||||
const updateImages = profileApi.useAction("updateImages");
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("image", file);
|
||||
|
||||
await updateImages.mutateAsync({
|
||||
id: 10,
|
||||
formData,
|
||||
});
|
||||
```
|
||||
|
||||
در تعریف action:
|
||||
|
||||
```js
|
||||
updateImages: {
|
||||
method: "post",
|
||||
url: (id) => `/content/rokn/profile-update/${id}/images`,
|
||||
body: ({ formData }) => formData,
|
||||
}
|
||||
```
|
||||
|
||||
`body` مشخص میکند چه چیزی واقعاً به عنوان body ارسال شود.
|
||||
|
||||
---
|
||||
|
||||
# استفاده از Keycloak
|
||||
|
||||
```js
|
||||
import {
|
||||
getKeycloakToken,
|
||||
loginKeycloak,
|
||||
logoutKeycloak,
|
||||
updateKeycloakToken,
|
||||
} from "uikit/core";
|
||||
|
||||
const token = getKeycloakToken();
|
||||
logoutKeycloak();
|
||||
|
||||
await updateKeycloakToken(30);
|
||||
|
||||
loginKeycloak();
|
||||
|
||||
logoutKeycloak({
|
||||
redirectUri: window.location.origin,
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## موارد دیگر `permission`
|
||||
# استفاده از Permission
|
||||
|
||||
```js
|
||||
<Can permission="users.list">
|
||||
<L />
|
||||
```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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
نکته: prop کامپوننت `Can` برابر `perm` است.
|
||||
|
||||
```jsx
|
||||
<Can perm="users:list">
|
||||
<UsersList />
|
||||
</Can>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# استفاده از DataTable
|
||||
|
||||
`DataTable` داخل مسیر `uikit/table` قرار دارد.
|
||||
|
||||
dependencyهای لازم:
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-table react-icons
|
||||
```
|
||||
|
||||
استفاده:
|
||||
|
||||
```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>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# dependencyهای پیشنهادی بر اساس نیاز
|
||||
|
||||
## فقط utils
|
||||
|
||||
نیازی به نصب dependency اضافه نیست.
|
||||
|
||||
```bash
|
||||
yarn add git+https://git.d.aiengines.ir/bi/uikit.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## pagination یا layout
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion react-icons
|
||||
```
|
||||
|
||||
برای `layout` معمولاً `react-icons` لازم نیست، ولی اگر پروژه از pagination هم استفاده میکند، نصبش کن.
|
||||
|
||||
---
|
||||
|
||||
## core
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-query axios keycloak-js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## table
|
||||
|
||||
```bash
|
||||
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion @tanstack/react-table react-icons
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# نکات مهم توسعه
|
||||
|
||||
بعد از تغییر فایلها، build بگیر:
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
|
||||
فایلهای خروجی مورد انتظار:
|
||||
|
||||
```txt
|
||||
dist/index.js
|
||||
dist/utils.js
|
||||
dist/pagination.js
|
||||
dist/layout.js
|
||||
dist/core.js
|
||||
dist/table.js
|
||||
```
|
||||
|
||||
اگر entry جدید اضافه شد، باید هم در `vite.config.js` و هم در `package.json > exports` ثبت شود.
|
||||
|
||||
---
|
||||
|
||||
# قانون کلی
|
||||
|
||||
هر چیزی که dependency سنگین ندارد:
|
||||
|
||||
```txt
|
||||
uikit/utils
|
||||
```
|
||||
|
||||
هر چیزی که UI سبک است و Chakra میخواهد:
|
||||
|
||||
```txt
|
||||
uikit/pagination
|
||||
uikit/layout
|
||||
```
|
||||
|
||||
هر چیزی که مربوط به API، auth، permission و provider است:
|
||||
|
||||
```txt
|
||||
uikit/core
|
||||
```
|
||||
|
||||
هر چیزی که مربوط به table است:
|
||||
|
||||
```txt
|
||||
uikit/table
|
||||
```
|
||||
|
||||
Root package یعنی:
|
||||
|
||||
```txt
|
||||
uikit
|
||||
```
|
||||
|
||||
باید سبک بماند و فقط چیزهایی مثل utils را export کند.
|
||||
|
||||
147
dist/chunks/Pagination-6xafzB0w.js
vendored
Normal file
147
dist/chunks/Pagination-6xafzB0w.js
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
import { jsxs as x, jsx as l } from "react/jsx-runtime";
|
||||
import { useState as B, useRef as A, useEffect as v } from "react";
|
||||
import { HStack as w, Text as u, IconButton as y, Button as S, Input as E } from "@chakra-ui/react";
|
||||
import { IoChevronForwardOutline as M, IoChevronBackOutline as N } from "react-icons/io5";
|
||||
import { toFaDigits as e, toEnDigits as C } from "../utils.js";
|
||||
const V = ({
|
||||
currentPage: i,
|
||||
totalPages: r,
|
||||
totalCount: I,
|
||||
onPageChange: c
|
||||
}) => {
|
||||
const [p, o] = B(e(i)), [m, d] = B(!1), [h, f] = B(null), a = A(null), D = Array.from(
|
||||
/* @__PURE__ */ new Set([1, i, i + 1, r])
|
||||
).filter((n) => n >= 1 && n <= r).sort((n, t) => n - t);
|
||||
v(() => {
|
||||
if (h !== null) {
|
||||
i === h && (f(null), d(!1), o(e(i)));
|
||||
return;
|
||||
}
|
||||
m || o(e(i));
|
||||
}, [i, m, h]), v(() => {
|
||||
if (!m || !p || h !== null) return;
|
||||
const n = parseInt(C(p), 10);
|
||||
if (isNaN(n)) return;
|
||||
const t = setTimeout(() => {
|
||||
var b;
|
||||
const s = Math.min(Math.max(n, 1), r);
|
||||
s !== i ? (f(s), o(e(s)), c(s)) : (d(!1), o(e(i))), (b = a.current) == null || b.blur();
|
||||
}, 1e3);
|
||||
return () => clearTimeout(t);
|
||||
}, [
|
||||
p,
|
||||
m,
|
||||
h,
|
||||
r,
|
||||
i,
|
||||
c
|
||||
]);
|
||||
const k = () => {
|
||||
var s, b;
|
||||
const n = parseInt(C(p), 10);
|
||||
if (isNaN(n)) {
|
||||
o(e(i)), d(!1), f(null), (s = a.current) == null || s.blur();
|
||||
return;
|
||||
}
|
||||
const t = Math.min(Math.max(n, 1), r);
|
||||
t !== i ? (f(t), o(e(t)), c(t)) : (o(e(i)), d(!1), f(null)), (b = a.current) == null || b.blur();
|
||||
};
|
||||
return r === 0 || !I ? null : /* @__PURE__ */ x(
|
||||
w,
|
||||
{
|
||||
justifyContent: "space-around",
|
||||
backgroundColor: "white",
|
||||
py: "10px",
|
||||
px: "16px",
|
||||
rounded: "lg",
|
||||
border: "1px",
|
||||
borderColor: "blue.200",
|
||||
w: "100%",
|
||||
children: [
|
||||
/* @__PURE__ */ x(w, { spacing: 2, whiteSpace: "nowrap", children: [
|
||||
/* @__PURE__ */ l(u, { fontWeight: "bold", children: "صفحه" }),
|
||||
/* @__PURE__ */ l(u, { children: e(i) }),
|
||||
/* @__PURE__ */ l(u, { fontWeight: "bold", children: "از" }),
|
||||
/* @__PURE__ */ l(u, { children: e(r) })
|
||||
] }),
|
||||
/* @__PURE__ */ x(w, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||||
/* @__PURE__ */ l(
|
||||
y,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => c(i - 1),
|
||||
isDisabled: i === 1,
|
||||
icon: /* @__PURE__ */ l(M, {}),
|
||||
"aria-label": "صفحه قبلی"
|
||||
}
|
||||
),
|
||||
D.map((n) => /* @__PURE__ */ l(
|
||||
S,
|
||||
{
|
||||
size: "md",
|
||||
bg: i === n ? "#4B49AC" : "#e6e6f1",
|
||||
color: i === n ? "#e6e6f1" : "#4B49AC",
|
||||
_hover: { bg: i === n ? "#4B49AC" : "#cbcbe8" },
|
||||
onClick: () => c(n),
|
||||
variant: "soft",
|
||||
children: e(n)
|
||||
},
|
||||
n
|
||||
)),
|
||||
/* @__PURE__ */ l(
|
||||
y,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => c(i + 1),
|
||||
isDisabled: i === r,
|
||||
icon: /* @__PURE__ */ l(N, {}),
|
||||
"aria-label": "صفحه بعدی"
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ l(
|
||||
E,
|
||||
{
|
||||
ref: a,
|
||||
type: "text",
|
||||
inputMode: "numeric",
|
||||
placeholder: "صفحه",
|
||||
w: "100px",
|
||||
value: p,
|
||||
onFocus: () => {
|
||||
d(!0), f(null), o("");
|
||||
},
|
||||
onChange: (n) => {
|
||||
const t = n.target.value, s = C(t).replace(/\D/g, "");
|
||||
o(e(s));
|
||||
},
|
||||
onBlur: () => {
|
||||
p || (o(e(i)), d(!1), f(null));
|
||||
},
|
||||
onKeyDown: (n) => {
|
||||
n.key === "Enter" && k();
|
||||
},
|
||||
textAlign: "center",
|
||||
color: "#1D2939",
|
||||
px: 1,
|
||||
minW: 0,
|
||||
dir: "ltr"
|
||||
}
|
||||
)
|
||||
] }),
|
||||
/* @__PURE__ */ x(w, { spacing: 2, whiteSpace: "nowrap", children: [
|
||||
/* @__PURE__ */ l(u, { fontWeight: "bold", children: "تعداد کل:" }),
|
||||
/* @__PURE__ */ l(u, { children: e(I) })
|
||||
] })
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
export {
|
||||
V as P
|
||||
};
|
||||
149
dist/chunks/Pagination-LRiUo8_9.js
vendored
149
dist/chunks/Pagination-LRiUo8_9.js
vendored
@ -1,149 +0,0 @@
|
||||
import { jsxs as w, jsx as t } from "react/jsx-runtime";
|
||||
import { useState as S, useRef as D, useEffect as C } from "react";
|
||||
import { HStack as I, Text as p, IconButton as N, Button as k, Input as A } from "@chakra-ui/react";
|
||||
import { IoChevronForwardOutline as E, IoChevronBackOutline as F } from "react-icons/io5";
|
||||
const O = (i) => new Intl.NumberFormat("fa-IR").format(Number(i)), e = (i) => String(i).replace(/\d/g, (o) => "۰۱۲۳۴۵۶۷۸۹"[Number(o)]), B = (i) => String(i).replace(/[۰-۹]/g, (m) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(m))), R = ({
|
||||
currentPage: i,
|
||||
totalPages: o,
|
||||
totalCount: m,
|
||||
onPageChange: f
|
||||
}) => {
|
||||
const [u, l] = S(e(i)), [h, d] = S(!1), [a, c] = S(null), x = D(null), v = Array.from(
|
||||
/* @__PURE__ */ new Set([1, i, i + 1, o])
|
||||
).filter((n) => n >= 1 && n <= o).sort((n, r) => n - r);
|
||||
C(() => {
|
||||
if (a !== null) {
|
||||
i === a && (c(null), d(!1), l(e(i)));
|
||||
return;
|
||||
}
|
||||
h || l(e(i));
|
||||
}, [i, h, a]), C(() => {
|
||||
if (!h || !u || a !== null) return;
|
||||
const n = parseInt(B(u), 10);
|
||||
if (isNaN(n)) return;
|
||||
const r = setTimeout(() => {
|
||||
var b;
|
||||
const s = Math.min(Math.max(n, 1), o);
|
||||
s !== i ? (c(s), l(e(s)), f(s)) : (d(!1), l(e(i))), (b = x.current) == null || b.blur();
|
||||
}, 1e3);
|
||||
return () => clearTimeout(r);
|
||||
}, [
|
||||
u,
|
||||
h,
|
||||
a,
|
||||
o,
|
||||
i,
|
||||
f
|
||||
]);
|
||||
const y = () => {
|
||||
var s, b;
|
||||
const n = parseInt(B(u), 10);
|
||||
if (isNaN(n)) {
|
||||
l(e(i)), d(!1), c(null), (s = x.current) == null || s.blur();
|
||||
return;
|
||||
}
|
||||
const r = Math.min(Math.max(n, 1), o);
|
||||
r !== i ? (c(r), l(e(r)), f(r)) : (l(e(i)), d(!1), c(null)), (b = x.current) == null || b.blur();
|
||||
};
|
||||
return o === 0 || !m ? null : /* @__PURE__ */ w(
|
||||
I,
|
||||
{
|
||||
justifyContent: "space-around",
|
||||
backgroundColor: "white",
|
||||
py: "10px",
|
||||
px: "16px",
|
||||
rounded: "lg",
|
||||
border: "1px",
|
||||
borderColor: "blue.200",
|
||||
w: "100%",
|
||||
children: [
|
||||
/* @__PURE__ */ w(I, { spacing: 2, whiteSpace: "nowrap", children: [
|
||||
/* @__PURE__ */ t(p, { fontWeight: "bold", children: "صفحه" }),
|
||||
/* @__PURE__ */ t(p, { children: e(i) }),
|
||||
/* @__PURE__ */ t(p, { fontWeight: "bold", children: "از" }),
|
||||
/* @__PURE__ */ t(p, { children: e(o) })
|
||||
] }),
|
||||
/* @__PURE__ */ w(I, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||||
/* @__PURE__ */ t(
|
||||
N,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => f(i - 1),
|
||||
isDisabled: i === 1,
|
||||
icon: /* @__PURE__ */ t(E, {}),
|
||||
"aria-label": "صفحه قبلی"
|
||||
}
|
||||
),
|
||||
v.map((n) => /* @__PURE__ */ t(
|
||||
k,
|
||||
{
|
||||
size: "md",
|
||||
bg: i === n ? "#4B49AC" : "#e6e6f1",
|
||||
color: i === n ? "#e6e6f1" : "#4B49AC",
|
||||
_hover: { bg: i === n ? "#4B49AC" : "#cbcbe8" },
|
||||
onClick: () => f(n),
|
||||
variant: "soft",
|
||||
children: e(n)
|
||||
},
|
||||
n
|
||||
)),
|
||||
/* @__PURE__ */ t(
|
||||
N,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => f(i + 1),
|
||||
isDisabled: i === o,
|
||||
icon: /* @__PURE__ */ t(F, {}),
|
||||
"aria-label": "صفحه بعدی"
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ t(
|
||||
A,
|
||||
{
|
||||
ref: x,
|
||||
type: "text",
|
||||
inputMode: "numeric",
|
||||
placeholder: "صفحه",
|
||||
w: "100px",
|
||||
value: u,
|
||||
onFocus: () => {
|
||||
d(!0), c(null), l("");
|
||||
},
|
||||
onChange: (n) => {
|
||||
const r = n.target.value, s = B(r).replace(/\D/g, "");
|
||||
l(e(s));
|
||||
},
|
||||
onBlur: () => {
|
||||
u || (l(e(i)), d(!1), c(null));
|
||||
},
|
||||
onKeyDown: (n) => {
|
||||
n.key === "Enter" && y();
|
||||
},
|
||||
textAlign: "center",
|
||||
color: "#1D2939",
|
||||
px: 1,
|
||||
minW: 0,
|
||||
dir: "ltr"
|
||||
}
|
||||
)
|
||||
] }),
|
||||
/* @__PURE__ */ w(I, { spacing: 2, whiteSpace: "nowrap", children: [
|
||||
/* @__PURE__ */ t(p, { fontWeight: "bold", children: "تعداد کل:" }),
|
||||
/* @__PURE__ */ t(p, { children: e(m) })
|
||||
] })
|
||||
]
|
||||
}
|
||||
);
|
||||
};
|
||||
export {
|
||||
R as P,
|
||||
B as a,
|
||||
O as b,
|
||||
e as t
|
||||
};
|
||||
470
dist/core.js
vendored
Normal file
470
dist/core.js
vendored
Normal file
File diff suppressed because one or more lines are too long
807
dist/index.js
vendored
807
dist/index.js
vendored
File diff suppressed because one or more lines are too long
74
dist/layout.js
vendored
Normal file
74
dist/layout.js
vendored
Normal file
File diff suppressed because one or more lines are too long
268
dist/pagination.js
vendored
Normal file
268
dist/pagination.js
vendored
Normal file
@ -0,0 +1,268 @@
|
||||
import { jsxs as I, jsx as s } from "react/jsx-runtime";
|
||||
import { useState as C, useRef as N, useEffect as v, useCallback as E } from "react";
|
||||
import { HStack as y, IconButton as A, Button as g, Input as j, Text as M } from "@chakra-ui/react";
|
||||
import { IoChevronForwardOutline as z, IoChevronBackOutline as S } from "react-icons/io5";
|
||||
import { toFaDigits as f, toEnDigits as k } from "./utils.js";
|
||||
import { P as G } from "./chunks/Pagination-6xafzB0w.js";
|
||||
const L = ({
|
||||
currentPage: e,
|
||||
totalPages: l,
|
||||
totalCount: D,
|
||||
onPageChange: a
|
||||
}) => {
|
||||
const [r, n] = C(f(e)), [d, c] = C(!1), [b, o] = C(null), x = N(null), h = [.../* @__PURE__ */ new Set([1, e, l])].filter(
|
||||
(i) => i >= 1 && i <= l
|
||||
);
|
||||
v(() => {
|
||||
if (b !== null) {
|
||||
e === b && (o(null), c(!1), n(f(e)));
|
||||
return;
|
||||
}
|
||||
d || n(f(e));
|
||||
}, [e, d, b]), v(() => {
|
||||
if (!d || !r || b !== null) return;
|
||||
const i = parseInt(k(r), 10);
|
||||
if (isNaN(i)) return;
|
||||
const m = setTimeout(() => {
|
||||
var B;
|
||||
const u = Math.min(Math.max(i, 1), l);
|
||||
u !== e ? (o(u), n(f(u)), a(u)) : (c(!1), n(f(e))), (B = x.current) == null || B.blur();
|
||||
}, 1e3);
|
||||
return () => clearTimeout(m);
|
||||
}, [
|
||||
r,
|
||||
d,
|
||||
b,
|
||||
l,
|
||||
e,
|
||||
a
|
||||
]);
|
||||
const w = () => {
|
||||
var u, B;
|
||||
const i = parseInt(k(r), 10);
|
||||
if (isNaN(i)) {
|
||||
n(f(e)), c(!1), o(null), (u = x.current) == null || u.blur();
|
||||
return;
|
||||
}
|
||||
const m = Math.min(Math.max(i, 1), l);
|
||||
m !== e ? (o(m), n(f(m)), a(m)) : (n(f(e)), c(!1), o(null)), (B = x.current) == null || B.blur();
|
||||
};
|
||||
return l === 0 || !D ? null : /* @__PURE__ */ I(
|
||||
y,
|
||||
{
|
||||
justifyContent: "space-around",
|
||||
backgroundColor: "white",
|
||||
py: "10px",
|
||||
px: "16px",
|
||||
rounded: "lg",
|
||||
border: "1px",
|
||||
borderColor: "blue.200",
|
||||
w: "100%",
|
||||
children: [
|
||||
/* @__PURE__ */ I(y, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||||
/* @__PURE__ */ s(
|
||||
A,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => a(e - 1),
|
||||
isDisabled: e === 1,
|
||||
icon: /* @__PURE__ */ s(z, {}),
|
||||
"aria-label": "صفحه قبلی"
|
||||
}
|
||||
),
|
||||
h.map((i) => /* @__PURE__ */ s(
|
||||
g,
|
||||
{
|
||||
size: "md",
|
||||
px: 2,
|
||||
bg: e === i ? "#4B49AC" : "#e6e6f1",
|
||||
color: e === i ? "#e6e6f1" : "#4B49AC",
|
||||
_hover: { bg: e === i ? "#4B49AC" : "#cbcbe8" },
|
||||
onClick: () => a(i),
|
||||
variant: "soft",
|
||||
children: f(i)
|
||||
},
|
||||
i
|
||||
)),
|
||||
/* @__PURE__ */ s(
|
||||
A,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => a(e + 1),
|
||||
isDisabled: e === l,
|
||||
icon: /* @__PURE__ */ s(S, {}),
|
||||
"aria-label": "صفحه بعدی"
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ s(
|
||||
j,
|
||||
{
|
||||
ref: x,
|
||||
type: "text",
|
||||
inputMode: "numeric",
|
||||
placeholder: "صفحه",
|
||||
w: "56px",
|
||||
value: r,
|
||||
onFocus: () => {
|
||||
c(!0), o(null), n("");
|
||||
},
|
||||
onChange: (i) => {
|
||||
const m = i.target.value, u = k(m).replace(/\D/g, "");
|
||||
n(f(u));
|
||||
},
|
||||
onBlur: () => {
|
||||
r || (n(f(e)), c(!1), o(null));
|
||||
},
|
||||
onKeyDown: (i) => {
|
||||
i.key === "Enter" && w();
|
||||
},
|
||||
textAlign: "center",
|
||||
color: "#1D2939",
|
||||
px: 1,
|
||||
minW: 0,
|
||||
dir: "ltr"
|
||||
}
|
||||
)
|
||||
] }),
|
||||
/* @__PURE__ */ I(y, { spacing: 2, children: [
|
||||
/* @__PURE__ */ s(M, { w: "auto", fontWeight: "bold", whiteSpace: "nowrap", children: "تعداد کل:" }),
|
||||
/* @__PURE__ */ s(M, { children: f(D) })
|
||||
] })
|
||||
]
|
||||
}
|
||||
);
|
||||
}, O = ({
|
||||
currentPage: e,
|
||||
totalPages: l,
|
||||
totalCount: D,
|
||||
onPageChange: a
|
||||
}) => {
|
||||
const [r, n] = C(""), [d, c] = C(!1), [b, o] = C(null), x = N(null), h = b ?? e, w = E(
|
||||
(t) => {
|
||||
const p = Math.min(Math.max(t, 1), l);
|
||||
c(!1), n(""), o(null), p !== e && a(p);
|
||||
},
|
||||
[e, l, a]
|
||||
), i = E(() => {
|
||||
if (!r) {
|
||||
c(!1), n(""), o(null);
|
||||
return;
|
||||
}
|
||||
const t = parseInt(k(r), 10);
|
||||
if (isNaN(t)) {
|
||||
c(!1), n(""), o(null);
|
||||
return;
|
||||
}
|
||||
const p = Math.min(Math.max(t, 1), l);
|
||||
c(!1), n(""), p !== e ? (o(p), a(p)) : o(null);
|
||||
}, [r, e, l, a]);
|
||||
v(() => {
|
||||
var t;
|
||||
d && ((t = x.current) == null || t.focus());
|
||||
}, [d]), v(() => {
|
||||
b !== null && e === b && o(null);
|
||||
}, [e, b]), v(() => {
|
||||
if (!d || !r) return;
|
||||
const t = setTimeout(() => {
|
||||
i();
|
||||
}, 1e3);
|
||||
return () => clearTimeout(t);
|
||||
}, [r, d, i]);
|
||||
const m = () => {
|
||||
o(null), n(""), c(!0);
|
||||
}, u = (t, p = !1) => /* @__PURE__ */ s(
|
||||
g,
|
||||
{
|
||||
size: "md",
|
||||
bg: p ? "#4B49AC" : "#e6e6f1",
|
||||
color: p ? "#e6e6f1" : "#4B49AC",
|
||||
_hover: { bg: p ? "#4B49AC" : "#cbcbe8" },
|
||||
onClick: p ? m : () => w(t),
|
||||
variant: "soft",
|
||||
children: f(t)
|
||||
},
|
||||
t
|
||||
);
|
||||
if (l === 0 || !D) return null;
|
||||
const B = l > 1 && h !== 1, T = l > 1 && h !== l;
|
||||
return /* @__PURE__ */ s(
|
||||
y,
|
||||
{
|
||||
justifyContent: "center",
|
||||
backgroundColor: "white",
|
||||
py: "10px",
|
||||
px: "16px",
|
||||
rounded: "lg",
|
||||
border: "1px",
|
||||
borderColor: "blue.200",
|
||||
w: "100%",
|
||||
children: /* @__PURE__ */ I(y, { spacing: 2, alignItems: "center", justifyContent: "center", children: [
|
||||
/* @__PURE__ */ s(
|
||||
A,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => w(h - 1),
|
||||
isDisabled: h === 1,
|
||||
icon: /* @__PURE__ */ s(z, {}),
|
||||
"aria-label": "صفحه قبلی"
|
||||
}
|
||||
),
|
||||
B && u(1),
|
||||
d ? /* @__PURE__ */ s(
|
||||
j,
|
||||
{
|
||||
ref: x,
|
||||
type: "text",
|
||||
inputMode: "numeric",
|
||||
placeholder: "صفحه",
|
||||
w: "48px",
|
||||
value: r,
|
||||
onChange: (t) => {
|
||||
const p = t.target.value, V = k(p).replace(/\D/g, "");
|
||||
n(f(V));
|
||||
},
|
||||
onBlur: () => {
|
||||
r ? i() : (n(""), c(!1), o(null));
|
||||
},
|
||||
onKeyDown: (t) => {
|
||||
t.key === "Enter" && i(), t.key === "Escape" && (n(""), c(!1), o(null));
|
||||
},
|
||||
textAlign: "center",
|
||||
color: "#1D2939",
|
||||
px: 1,
|
||||
minW: 0,
|
||||
dir: "ltr"
|
||||
}
|
||||
) : u(h, !0),
|
||||
T && u(l),
|
||||
/* @__PURE__ */ s(
|
||||
A,
|
||||
{
|
||||
size: "md",
|
||||
bg: "#e6e6f1",
|
||||
color: "#4B49AC",
|
||||
_hover: { bg: "#cbcbe8" },
|
||||
onClick: () => w(h + 1),
|
||||
isDisabled: h === l,
|
||||
icon: /* @__PURE__ */ s(S, {}),
|
||||
"aria-label": "صفحه بعدی"
|
||||
}
|
||||
)
|
||||
] })
|
||||
}
|
||||
);
|
||||
};
|
||||
export {
|
||||
L as LightPagination,
|
||||
G as Pagination,
|
||||
O as SimplePagination
|
||||
};
|
||||
55
dist/table.js
vendored
55
dist/table.js
vendored
@ -1,7 +1,8 @@
|
||||
import { jsx as r, jsxs as X, Fragment as ne } from "react/jsx-runtime";
|
||||
import { VStack as oe, Box as _, Tbody as re, Tr as H, Td as F, Text as R, Thead as le, Th as ce, Table as se, Checkbox as W, HStack as Y, Spacer as ie } from "@chakra-ui/react";
|
||||
import { P as ae, t as q } from "./chunks/Pagination-LRiUo8_9.js";
|
||||
import { useReactTable as ue, getCoreRowModel as de, flexRender as J } from "@tanstack/react-table";
|
||||
import { P as ue } from "./chunks/Pagination-6xafzB0w.js";
|
||||
import { toFaDigits as q } from "./utils.js";
|
||||
import { useReactTable as ae, getCoreRowModel as de, flexRender as J } from "@tanstack/react-table";
|
||||
import { createContext as me, useMemo as P, useCallback as p, useState as fe, useRef as ge, useEffect as he, useContext as be } from "react";
|
||||
const K = me(null);
|
||||
function C() {
|
||||
@ -17,7 +18,7 @@ function xe({
|
||||
page: s = 1,
|
||||
size: c = 10,
|
||||
pagination: l,
|
||||
onPageChange: u,
|
||||
onPageChange: a,
|
||||
getRowId: g = (d) => String(d == null ? void 0 : d.id),
|
||||
enableSelection: b = !1,
|
||||
showIndex: S = !0,
|
||||
@ -30,15 +31,15 @@ function xe({
|
||||
pageSize: h
|
||||
}), [d, h]), Q = p(
|
||||
(n) => {
|
||||
const a = (typeof n == "function" ? n(z) : n).pageIndex + 1;
|
||||
a !== d && (u == null || u(a));
|
||||
const u = (typeof n == "function" ? n(z) : n).pageIndex + 1;
|
||||
u !== d && (a == null || a(u));
|
||||
},
|
||||
[z, d, u]
|
||||
[z, d, a]
|
||||
), [A, U] = fe(L), m = p(
|
||||
(n) => {
|
||||
U((i) => {
|
||||
const a = typeof n == "function" ? n(i) : n;
|
||||
return k == null || k(a), a;
|
||||
const u = typeof n == "function" ? n(i) : n;
|
||||
return k == null || k(u), u;
|
||||
});
|
||||
},
|
||||
[k]
|
||||
@ -59,7 +60,7 @@ function xe({
|
||||
m([]);
|
||||
}, [m]), B = p(
|
||||
(n) => {
|
||||
m((i) => f.includes(n) ? i.includes(n) ? i.filter((a) => a !== n) : [...i, n] : i);
|
||||
m((i) => f.includes(n) ? i.includes(n) ? i.filter((u) => u !== n) : [...i, n] : i);
|
||||
},
|
||||
[f, m]
|
||||
), Z = B, I = p(() => {
|
||||
@ -80,20 +81,20 @@ function xe({
|
||||
return b && n.push({
|
||||
id: "__selection",
|
||||
header: ({ table: i }) => {
|
||||
const a = i.options.meta;
|
||||
const u = i.options.meta;
|
||||
return /* @__PURE__ */ r(
|
||||
W,
|
||||
{
|
||||
isChecked: a.isAllSelected,
|
||||
isIndeterminate: a.isIndeterminate,
|
||||
onChange: (x) => a.toggleSelectAll(x.target.checked),
|
||||
isChecked: u.isAllSelected,
|
||||
isIndeterminate: u.isIndeterminate,
|
||||
onChange: (x) => u.toggleSelectAll(x.target.checked),
|
||||
colorScheme: "purple",
|
||||
size: "md"
|
||||
}
|
||||
);
|
||||
},
|
||||
cell: ({ row: i, table: a }) => {
|
||||
const x = a.options.meta, D = x.getRowId(i.original);
|
||||
cell: ({ row: i, table: u }) => {
|
||||
const x = u.options.meta, D = x.getRowId(i.original);
|
||||
return /* @__PURE__ */ r(
|
||||
W,
|
||||
{
|
||||
@ -108,14 +109,14 @@ function xe({
|
||||
}), S && n.push({
|
||||
id: "__index",
|
||||
header: "ردیف",
|
||||
cell: ({ row: i, table: a }) => {
|
||||
const { pageIndex: x, pageSize: D } = a.getState().pagination, te = x * D + i.index + 1;
|
||||
cell: ({ row: i, table: u }) => {
|
||||
const { pageIndex: x, pageSize: D } = u.getState().pagination, te = x * D + i.index + 1;
|
||||
return /* @__PURE__ */ r(R, { fontWeight: "bold", sx: { fontVariantNumeric: "normal" }, children: q(te) });
|
||||
},
|
||||
meta: { isCentered: !0 }
|
||||
}), [...n, ...o];
|
||||
}, [o, b, S]), ee = {
|
||||
table: ue({
|
||||
table: ae({
|
||||
data: t,
|
||||
columns: E,
|
||||
getCoreRowModel: de(),
|
||||
@ -148,7 +149,7 @@ function xe({
|
||||
page: d,
|
||||
size: h,
|
||||
pagination: l,
|
||||
onPageChange: u,
|
||||
onPageChange: a,
|
||||
paginationState: z,
|
||||
totalCount: y,
|
||||
totalPages: v,
|
||||
@ -192,14 +193,14 @@ function ke({ children: e = "انتخاب همه", ...t }) {
|
||||
enableSelection: s,
|
||||
isAllSelected: c,
|
||||
isIndeterminate: l,
|
||||
toggleSelectAll: u
|
||||
toggleSelectAll: a
|
||||
} = C();
|
||||
return !s || o.length === 0 ? null : /* @__PURE__ */ r(
|
||||
W,
|
||||
{
|
||||
isChecked: c,
|
||||
isIndeterminate: l,
|
||||
onChange: (g) => u(g.target.checked),
|
||||
onChange: (g) => a(g.target.checked),
|
||||
colorScheme: "purple",
|
||||
size: "lg",
|
||||
...t,
|
||||
@ -321,7 +322,7 @@ function De({ emptyText: e = "موردی وجود ندارد" }) {
|
||||
_hover: { bg: "blue.50" },
|
||||
transition: "0.2s",
|
||||
children: c.getVisibleCells().map((l) => {
|
||||
var u;
|
||||
var a;
|
||||
return /* @__PURE__ */ r(
|
||||
F,
|
||||
{
|
||||
@ -330,7 +331,7 @@ function De({ emptyText: e = "موردی وجود ندارد" }) {
|
||||
color: "gray.700",
|
||||
borderRightWidth: "1px",
|
||||
borderRightColor: "gray.200",
|
||||
textAlign: (u = l.column.columnDef.meta) != null && u.isCentered ? "center" : "start",
|
||||
textAlign: (a = l.column.columnDef.meta) != null && a.isCentered ? "center" : "start",
|
||||
verticalAlign: "middle",
|
||||
children: l.column.columnDef.cell ? J(l.column.columnDef.cell, l.getContext()) : l.getValue()
|
||||
},
|
||||
@ -345,20 +346,20 @@ function Pe({
|
||||
pagination: e,
|
||||
onPageChange: t
|
||||
}) {
|
||||
const o = C(), { table: s } = o, c = e ?? o.pagination, l = (c == null ? void 0 : c.total) ?? (c == null ? void 0 : c.totalCount) ?? o.totalCount ?? 0, u = (c == null ? void 0 : c.total_pages) ?? (c == null ? void 0 : c.totalPages) ?? o.totalPages ?? s.getPageCount() ?? 0, g = s.getState().pagination.pageIndex + 1, b = (S) => {
|
||||
const o = C(), { table: s } = o, c = e ?? o.pagination, l = (c == null ? void 0 : c.total) ?? (c == null ? void 0 : c.totalCount) ?? o.totalCount ?? 0, a = (c == null ? void 0 : c.total_pages) ?? (c == null ? void 0 : c.totalPages) ?? o.totalPages ?? s.getPageCount() ?? 0, g = s.getState().pagination.pageIndex + 1, b = (S) => {
|
||||
if (t) {
|
||||
t(S);
|
||||
return;
|
||||
}
|
||||
s.setPageIndex(S - 1);
|
||||
};
|
||||
return !o.onPageChange && !t || u <= 0 ? null : /* @__PURE__ */ r(_, { mt: 1, flexShrink: 0, children: /* @__PURE__ */ r(
|
||||
ae,
|
||||
return !o.onPageChange && !t || a <= 0 ? null : /* @__PURE__ */ r(_, { mt: 1, flexShrink: 0, children: /* @__PURE__ */ r(
|
||||
ue,
|
||||
{
|
||||
currentPage: g,
|
||||
onPageChange: b,
|
||||
totalCount: l,
|
||||
totalPages: u
|
||||
totalPages: a
|
||||
}
|
||||
) });
|
||||
}
|
||||
|
||||
6
dist/utils.js
vendored
Normal file
6
dist/utils.js
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
const e = (r) => new Intl.NumberFormat("fa-IR").format(Number(r)), i = (r) => String(r).replace(/\d/g, (t) => "۰۱۲۳۴۵۶۷۸۹"[Number(t)]), o = (r) => String(r).replace(/[۰-۹]/g, (n) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(n)));
|
||||
export {
|
||||
o as toEnDigits,
|
||||
i as toFaDigits,
|
||||
e as toFaNumber
|
||||
};
|
||||
40
package.json
40
package.json
@ -6,6 +6,10 @@
|
||||
"module": "./dist/index.js",
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./utils": "./dist/utils.js",
|
||||
"./pagination": "./dist/pagination.js",
|
||||
"./layout": "./dist/layout.js",
|
||||
"./core": "./dist/core.js",
|
||||
"./table": "./dist/table.js"
|
||||
},
|
||||
"files": [
|
||||
@ -17,24 +21,60 @@
|
||||
"peerDependencies": {
|
||||
"@chakra-ui/react": "^2.0.0",
|
||||
"@emotion/react": "^11.0.0",
|
||||
"@emotion/styled": "^11.0.0",
|
||||
"@tanstack/react-query": "^5.0.0",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"axios": "^1.0.0",
|
||||
"framer-motion": "^10.0.0 || ^11.0.0 || ^12.0.0",
|
||||
"keycloak-js": "^26.0.0",
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0",
|
||||
"react-icons": "^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@chakra-ui/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@emotion/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@emotion/styled": {
|
||||
"optional": true
|
||||
},
|
||||
"@tanstack/react-query": {
|
||||
"optional": true
|
||||
},
|
||||
"@tanstack/react-table": {
|
||||
"optional": true
|
||||
},
|
||||
"axios": {
|
||||
"optional": true
|
||||
},
|
||||
"framer-motion": {
|
||||
"optional": true
|
||||
},
|
||||
"keycloak-js": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"react-icons": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chakra-ui/react": "^2.0.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.0",
|
||||
"@tanstack/react-query": "^5.0.0",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"@vitejs/plugin-react": "4.3.4",
|
||||
"axios": "^1.17.0",
|
||||
"framer-motion": "^12.0.0",
|
||||
"keycloak-js": "^26.2.4",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { ChakraProvider, Spinner } from "@chakra-ui/react";
|
||||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import { KeycloakProvider } from "../core/keycloak.jsx";
|
||||
import { PermissionProvider } from "../core/permission.jsx";
|
||||
import { UpdateChecker } from "../components/UpdateChecker.jsx";
|
||||
import { configureApi } from "../core/api.js";
|
||||
import { queryClient } from "../core/query.js";
|
||||
import { Fonts, theme } from "../core/style.jsx";
|
||||
import { KeycloakProvider } from "./keycloak.jsx";
|
||||
import { PermissionProvider } from "./permission.jsx";
|
||||
import { UpdateChecker } from "./UpdateChecker.jsx";
|
||||
import { configureApi } from "./api.js";
|
||||
import { queryClient } from "./query.js";
|
||||
import { Fonts, theme } from "./style.jsx";
|
||||
|
||||
export function BiProvider({
|
||||
children,
|
||||
@ -73,7 +73,7 @@ export function createApi({
|
||||
|
||||
mutationFn: async (data = {}) => {
|
||||
const method = action.method || "post";
|
||||
const requestUrl = resolveUrl(action.url, data);
|
||||
const requestUrl = resolveUrl(action.url || url, data);
|
||||
|
||||
const payload = action.body
|
||||
? action.body(data)
|
||||
|
||||
31
src/core/index.js
Normal file
31
src/core/index.js
Normal file
@ -0,0 +1,31 @@
|
||||
export { configureApi, getApi, api, fetcher } from "./api.js";
|
||||
export { createApi } from "./createApi.js";
|
||||
|
||||
export {
|
||||
KeycloakProvider,
|
||||
initKeycloak,
|
||||
isKeycloakInitialized,
|
||||
isKeycloakAuthenticated,
|
||||
getKeycloakToken,
|
||||
updateKeycloakToken,
|
||||
logoutKeycloak,
|
||||
loginKeycloak
|
||||
} from "./keycloak.jsx";
|
||||
|
||||
export {
|
||||
PermissionProvider,
|
||||
usePermission,
|
||||
usePermissionsQuery,
|
||||
Can,
|
||||
AdminGuard,
|
||||
PanelAccessGuard,
|
||||
getCachedPermissions,
|
||||
setCachedPermissions,
|
||||
clearCachedPermissions,
|
||||
createPermissionSet,
|
||||
checkPermission,
|
||||
permissionKeys,
|
||||
getPermissions
|
||||
} from "./permission.jsx";
|
||||
|
||||
export { BiProvider } from "./BiProvider.jsx";
|
||||
41
src/index.js
41
src/index.js
@ -1,40 +1 @@
|
||||
export { toFaNumber, toFaDigits, toEnDigits } from "./utils/numbers.js";
|
||||
|
||||
export { LightPagination } from "./components/pagination/LightPagination.jsx";
|
||||
export { Pagination } from "./components/pagination/Pagination.jsx";
|
||||
export { SimplePagination } from "./components/pagination/SimplePagination.jsx";
|
||||
|
||||
export {
|
||||
KeycloakProvider,
|
||||
initKeycloak,
|
||||
isKeycloakInitialized,
|
||||
isKeycloakAuthenticated,
|
||||
getKeycloakToken,
|
||||
updateKeycloakToken,
|
||||
logoutKeycloak,
|
||||
loginKeycloak,
|
||||
} from "./core/keycloak.jsx";
|
||||
|
||||
export {
|
||||
PermissionProvider,
|
||||
usePermission,
|
||||
usePermissionsQuery,
|
||||
Can,
|
||||
AdminGuard,
|
||||
PanelAccessGuard,
|
||||
getCachedPermissions,
|
||||
setCachedPermissions,
|
||||
clearCachedPermissions,
|
||||
createPermissionSet,
|
||||
checkPermission,
|
||||
permissionKeys,
|
||||
getPermissions,
|
||||
} from "./core/permission.jsx";
|
||||
|
||||
export { configureApi, getApi, api, fetcher } from "./core/api.js";
|
||||
|
||||
export { createApi } from "./core/createApi";
|
||||
|
||||
export { BiProvider } from "./provider/BiProvider.jsx";
|
||||
|
||||
export { Header } from "./components/Header.jsx";
|
||||
export * from "./utils/index.js";
|
||||
|
||||
1
src/layout/index.js
Normal file
1
src/layout/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { Header } from "./Header.jsx";
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Button, HStack, IconButton, Input, Text } from "@chakra-ui/react";
|
||||
import { IoChevronBackOutline, IoChevronForwardOutline } from "react-icons/io5";
|
||||
import { toEnDigits, toFaDigits } from "../../utils/numbers.js";
|
||||
import { toEnDigits, toFaDigits } from "../utils/numbers.js";
|
||||
|
||||
export const LightPagination = ({
|
||||
currentPage,
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Button, HStack, IconButton, Input, Text } from "@chakra-ui/react";
|
||||
import { IoChevronBackOutline, IoChevronForwardOutline } from "react-icons/io5";
|
||||
import { toEnDigits, toFaDigits } from "../../utils/numbers.js";
|
||||
import { toEnDigits, toFaDigits } from "../utils/numbers.js";
|
||||
|
||||
export const Pagination = ({
|
||||
currentPage,
|
||||
@ -1,7 +1,7 @@
|
||||
import { Button, HStack, IconButton, Input } from "@chakra-ui/react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { IoChevronBackOutline, IoChevronForwardOutline } from "react-icons/io5";
|
||||
import { toEnDigits, toFaDigits } from "../../utils/numbers.js";
|
||||
import { toEnDigits, toFaDigits } from "../utils/numbers.js";
|
||||
|
||||
export const SimplePagination = ({
|
||||
currentPage,
|
||||
3
src/pagination/index.js
Normal file
3
src/pagination/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
export { LightPagination } from "./LightPagination.jsx";
|
||||
export { Pagination } from "./Pagination.jsx";
|
||||
export { SimplePagination } from "./SimplePagination.jsx";
|
||||
@ -14,7 +14,7 @@ import {
|
||||
Tr,
|
||||
VStack,
|
||||
} from "@chakra-ui/react";
|
||||
import { Pagination as UIKitPagination } from "../components/pagination/Pagination.jsx";
|
||||
import { Pagination as UIKitPagination } from "../pagination/Pagination.jsx";
|
||||
import { toFaDigits } from "../utils/numbers.js";
|
||||
import {
|
||||
flexRender,
|
||||
|
||||
1
src/utils/index.js
Normal file
1
src/utils/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { toFaNumber, toFaDigits, toEnDigits } from "./numbers.js";
|
||||
@ -9,6 +9,8 @@ const externalPackages = [
|
||||
|
||||
"@chakra-ui/react",
|
||||
"@emotion/react",
|
||||
"@emotion/styled",
|
||||
"framer-motion",
|
||||
|
||||
"keycloak-js",
|
||||
"axios",
|
||||
@ -21,21 +23,33 @@ const externalPackages = [
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
|
||||
build: {
|
||||
lib: {
|
||||
entry: {
|
||||
index: path.resolve(process.cwd(), "src/index.js"),
|
||||
utils: path.resolve(process.cwd(), "src/utils/index.js"),
|
||||
pagination: path.resolve(process.cwd(), "src/pagination/index.js"),
|
||||
layout: path.resolve(process.cwd(), "src/layout/index.js"),
|
||||
core: path.resolve(process.cwd(), "src/core/index.js"),
|
||||
table: path.resolve(process.cwd(), "src/table/index.js"),
|
||||
},
|
||||
formats: ["es"],
|
||||
},
|
||||
|
||||
rollupOptions: {
|
||||
external: (id) => {
|
||||
return externalPackages.includes(id) || id.startsWith("react-icons/");
|
||||
return (
|
||||
externalPackages.includes(id) ||
|
||||
id.startsWith("react-icons/") ||
|
||||
id.startsWith("@emotion/")
|
||||
);
|
||||
},
|
||||
|
||||
output: {
|
||||
entryFileNames: "[name].js",
|
||||
chunkFileNames: "chunks/[name]-[hash].js",
|
||||
assetFileNames: "assets/[name]-[hash][extname]",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user