react-toolkits 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-toolkits",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "sideEffects": [
5
5
  "**/*.css"
6
6
  ],
@@ -1,72 +1,79 @@
1
1
  import { useHttpClient, usePermission } from '@/hooks'
2
- import { useQueryTriggerStore } from '@/stores'
2
+ import { useQueryListStore } from '@/stores'
3
3
  import type { ListResponse, PaginationParams } from '@/types'
4
4
  import type { FormInstance, FormProps } from 'antd'
5
5
  import { Form, Result, Table } from 'antd'
6
6
  import type { TableProps } from 'antd/es/table'
7
7
  import type { AxiosRequestConfig } from 'axios'
8
8
  import type { ReactNode } from 'react'
9
- import { useCallback, useEffect, useState } from 'react'
9
+ import { useCallback, useEffect } from 'react'
10
10
  import useSWRMutation from 'swr/mutation'
11
11
  import FilterForm from '../FilterForm'
12
12
 
13
13
  export type QueryListKey = Omit<AxiosRequestConfig, 'data' | 'params'>
14
14
 
15
- export interface QueryListProps<Item, Values>
15
+ export interface QueryListProps<Item, Values, Response>
16
16
  extends Pick<TableProps<Item>, 'columns' | 'rowKey' | 'tableLayout' | 'expandable' | 'rowSelection' | 'bordered'>,
17
17
  Pick<FormProps<Values>, 'initialValues' | 'labelCol'> {
18
- // 由于表单的值和分页数据是封装在组件内部的,不便于在组件外部构造 swr key,所以组件内部的 useSWRMutation hook 使用的 key 是排除了 arg 字段的。
19
- // 因此 swr 的缓存并未发挥作用,同一个 key 的所有页面共享缓存。
18
+ // 由于表单的值和分页数据是封装在组件内部的,不便于在组件外部构造 swr key
19
+ // 所以组件内部的 useSWRMutation hook 使用的 key 是不包含表单值和分页参数的。
20
+ // 因此 swr 并未按照分页缓存数据。
20
21
  swrKey: QueryListKey
21
22
  confirmText?: ReactNode
22
23
  code?: string
23
24
  renderForm?: (form: FormInstance<Values>) => ReactNode
24
25
  // 把表单的值和分页数据转换成请求参数
25
26
  transformArg?: (arg: Values & PaginationParams) => unknown
27
+ // 当请求的返回值不满足时进行转换
28
+ transformResponse?: (response: Response) => ListResponse<Item>
26
29
  }
27
30
 
28
- const QueryList = <Item extends object, Values = NonNullable<unknown>>(props: QueryListProps<Item, Values>) => {
29
- const { code, confirmText, labelCol, swrKey, renderForm, transformArg, initialValues, ...tableProps } = props
31
+ const QueryList = <Item extends object, Values = NonNullable<unknown>, Response = ListResponse<Item>>(
32
+ props: QueryListProps<Item, Values, Response>,
33
+ ) => {
34
+ const {
35
+ code,
36
+ confirmText,
37
+ labelCol,
38
+ swrKey,
39
+ initialValues,
40
+ renderForm,
41
+ transformArg,
42
+ transformResponse,
43
+ ...tableProps
44
+ } = props
30
45
  const { accessible } = usePermission(code ?? '')
31
46
  const [form] = Form.useForm<Values>()
32
- const setTrigger = useQueryTriggerStore(state => state.setTrigger)
33
-
34
- const [paginationData, setPaginationData] = useState<PaginationParams>({
35
- page: 1,
36
- perPage: 10,
37
- })
47
+ const setRefresh = useQueryListStore(state => state.setRefresh)
48
+ const getPaginationData = useQueryListStore(state => state.getPaginationData)
49
+ const setPaginationData = useQueryListStore(state => state.setPaginationData)
50
+ const paginationData = getPaginationData(swrKey)
38
51
 
39
52
  const httpClient = useHttpClient()
40
53
 
41
54
  const { data, isMutating, trigger } = useSWRMutation(
42
55
  swrKey,
43
- async (
44
- key,
45
- {
46
- arg,
47
- }: {
48
- arg?: Partial<PaginationParams>
49
- },
50
- ) => {
56
+ async (key, { arg }: { arg?: Partial<PaginationParams> }) => {
51
57
  const newPaginationData = {
52
- page: arg?.page ?? paginationData.page ?? 1,
53
- perPage: arg?.perPage ?? paginationData.perPage ?? 10,
58
+ page: arg?.page ?? paginationData.page,
59
+ size: arg?.size ?? paginationData.size,
54
60
  }
55
61
 
56
- setPaginationData(newPaginationData)
62
+ setPaginationData(swrKey, arg)
57
63
 
58
64
  const values = form.getFieldsValue()
59
65
 
60
- const fetcherArg = {
66
+ const _arg = {
61
67
  ...values,
62
68
  ...newPaginationData,
63
69
  }
64
70
 
65
- return httpClient.request<ListResponse<Item>>({
66
- ...key,
67
- [key.method === 'POST' ? 'data' : 'params']:
68
- typeof transformArg === 'function' ? transformArg(fetcherArg) : fetcherArg,
69
- })
71
+ return httpClient
72
+ .request<Response>({
73
+ ...key,
74
+ [key.method === 'POST' ? 'data' : 'params']: transformArg?.(_arg) ?? _arg,
75
+ })
76
+ .then(response => transformResponse?.(response) ?? (response as ListResponse<Item>))
70
77
  },
71
78
  )
72
79
 
@@ -88,15 +95,15 @@ const QueryList = <Item extends object, Values = NonNullable<unknown>>(props: Qu
88
95
  async (currentPage: number, currentSize: number) => {
89
96
  await trigger({
90
97
  page: currentPage,
91
- perPage: currentSize,
98
+ size: currentSize,
92
99
  })
93
100
  },
94
101
  [trigger],
95
102
  )
96
103
 
97
104
  useEffect(() => {
98
- setTrigger(swrKey, trigger)
99
- }, [swrKey, trigger, setTrigger])
105
+ setRefresh(swrKey, trigger)
106
+ }, [swrKey, trigger, setRefresh])
100
107
 
101
108
  useEffect(() => {
102
109
  ;(async () => {
@@ -133,7 +140,7 @@ const QueryList = <Item extends object, Values = NonNullable<unknown>>(props: Qu
133
140
  showSizeChanger: true,
134
141
  showQuickJumper: true,
135
142
  current: paginationData.page,
136
- pageSize: paginationData.perPage,
143
+ pageSize: paginationData.size,
137
144
  total: data?.Total,
138
145
  onChange: onPaginationChange,
139
146
  }}
@@ -2,7 +2,7 @@ import { Checkbox, Collapse, Skeleton, Typography } from 'antd'
2
2
  import type { CheckboxChangeEvent } from 'antd/es/checkbox'
3
3
  import type { CheckboxValueType } from 'antd/es/checkbox/Group'
4
4
  import { useEffect, useState } from 'react'
5
- import { useAllPermissions } from '../hooks'
5
+ import { useAllPermissions } from '../../hooks'
6
6
 
7
7
  const { Text } = Typography
8
8
 
@@ -3,12 +3,13 @@ import { useFormModal } from '@/components/FormModal/hooks'
3
3
  import type { Role, RoleListItem } from '@/features/permission'
4
4
  import { PermissionList, useCreateRole, useRemoveRole, useUpdateRole } from '@/features/permission'
5
5
  import { useHttpClient, usePermission } from '@/hooks'
6
- import { useQueryTriggerStore } from '@/stores'
6
+ import { useQueryListStore } from '@/stores'
7
7
  import { UsergroupAddOutlined } from '@ant-design/icons'
8
8
  import type { TableColumnsType } from 'antd'
9
9
  import { App, Card, Form, Input, Space } from 'antd'
10
10
  import { useMemo } from 'react'
11
11
  import { Link } from 'react-router-dom'
12
+ import type { ListResponse } from '@/types'
12
13
 
13
14
  export const swrKey = {
14
15
  url: '/api/usystem/role/list',
@@ -21,7 +22,7 @@ const RoleList = () => {
21
22
  const create = useCreateRole()
22
23
  const remove = useRemoveRole()
23
24
  const update = useUpdateRole()
24
- const trigger = useQueryTriggerStore(state => state.trigger)
25
+ const refresh = useQueryListStore(state => state.refresh)
25
26
 
26
27
  const { showModal: showCreateModal, Modal: CreateModal } = useFormModal<{
27
28
  name: string
@@ -49,7 +50,7 @@ const RoleList = () => {
49
50
  {
50
51
  async onSuccess() {
51
52
  await message.success('角色创建成功')
52
- trigger(swrKey)
53
+ refresh(swrKey, { page: 1 })
53
54
  },
54
55
  },
55
56
  )
@@ -87,7 +88,7 @@ const RoleList = () => {
87
88
  {
88
89
  async onSuccess() {
89
90
  await message.success('角色更新成功')
90
- trigger(swrKey)
91
+ refresh(swrKey, { page: 1 })
91
92
  },
92
93
  },
93
94
  )
@@ -167,7 +168,7 @@ const RoleList = () => {
167
168
  {
168
169
  async onSuccess() {
169
170
  await message.success('角色删除成功')
170
- trigger(swrKey)
171
+ refresh(swrKey, { page: 1 })
171
172
  },
172
173
  },
173
174
  )
@@ -182,7 +183,7 @@ const RoleList = () => {
182
183
  },
183
184
  },
184
185
  ],
185
- [trigger, viewable, httpClient, modal, message, remove, showUpdateModal],
186
+ [refresh, viewable, httpClient, modal, message, remove, showUpdateModal],
186
187
  )
187
188
 
188
189
  return (
@@ -202,18 +203,15 @@ const RoleList = () => {
202
203
  </PermissionButton>
203
204
  }
204
205
  >
205
- <QueryList
206
+ <QueryList<RoleListItem, NonNullable<unknown>, ListResponse<RoleListItem>>
206
207
  rowKey="name"
207
208
  columns={columns}
208
209
  code="200001"
209
210
  swrKey={swrKey}
210
- transformArg={arg => {
211
- const { page, perPage, ...restValues } = arg
212
- return {
213
- ...restValues,
214
- page,
215
- size: perPage,
216
- }
211
+ // NOTE: 后端接口返回的数据不满足时转换一下
212
+ transformResponse={response => {
213
+ const { List, Total } = response
214
+ return { List, Total }
217
215
  }}
218
216
  />
219
217
  </Card>
@@ -2,7 +2,7 @@ import { Highlight, PermissionButton, QueryList } from '@/components'
2
2
  import { useFormModal } from '@/components/FormModal/hooks'
3
3
  import type { UserListItem } from '@/features/permission'
4
4
  import { useAllRoles, useCreateUser, useRemoveUser, useUpdateUser } from '@/features/permission'
5
- import { useQueryTriggerStore } from '@/stores'
5
+ import { useQueryListStore } from '@/stores'
6
6
  import { UserAddOutlined } from '@ant-design/icons'
7
7
  import type { TableColumnsType } from 'antd'
8
8
  import { App, Card, Col, Form, Input, Row, Select, Space, Tag } from 'antd'
@@ -20,7 +20,7 @@ function useCreatingUserModal() {
20
20
  const { message } = App.useApp()
21
21
  const create = useCreateUser()
22
22
  const { data: roles, isLoading } = useAllRoles()
23
- const trigger = useQueryTriggerStore(state => state.trigger)
23
+ const refresh = useQueryListStore(state => state.refresh)
24
24
 
25
25
  return useFormModal<{ id: string; name: string; roles: string[] }>({
26
26
  title: '创建角色',
@@ -49,7 +49,7 @@ function useCreatingUserModal() {
49
49
  await create.trigger(values, {
50
50
  onSuccess() {
51
51
  message.success('用户创建成功')
52
- trigger(swrKey)
52
+ refresh(swrKey, { page: 1 })
53
53
  },
54
54
  })
55
55
  },
@@ -60,7 +60,7 @@ function useUpdatingUserModal() {
60
60
  const { message } = App.useApp()
61
61
  const update = useUpdateUser()
62
62
  const { data: roles, isLoading } = useAllRoles()
63
- const trigger = useQueryTriggerStore(state => state.trigger)
63
+ const refresh = useQueryListStore(state => state.refresh)
64
64
 
65
65
  return useFormModal<{ id: string; name: string; roles: string[] }>({
66
66
  title: '更新角色',
@@ -92,7 +92,7 @@ function useUpdatingUserModal() {
92
92
  await update.trigger(values, {
93
93
  onSuccess() {
94
94
  message.success('用户更新成功')
95
- trigger(swrKey)
95
+ refresh(swrKey, { page: 1 })
96
96
  },
97
97
  })
98
98
  },
@@ -102,7 +102,7 @@ function useUpdatingUserModal() {
102
102
  const UserList: FC = () => {
103
103
  const { modal, message } = App.useApp()
104
104
  const remove = useRemoveUser()
105
- const trigger = useQueryTriggerStore(state => state.trigger)
105
+ const refresh = useQueryListStore(state => state.refresh)
106
106
  const { showModal: showCreatingModal, Modal: CreatingModal } = useCreatingUserModal()
107
107
  const { showModal: showUpdatingModal, Modal: UpdatingModal } = useUpdatingUserModal()
108
108
 
@@ -176,11 +176,13 @@ const UserList: FC = () => {
176
176
  onClick={() => {
177
177
  modal.confirm({
178
178
  title: '删除用户',
179
- content: <Highlight texts={[value.name]}>
180
- 确定要删除用户&nbsp;
181
- {value.name}
182
- &nbsp;吗?
183
- </Highlight>,
179
+ content: (
180
+ <Highlight texts={[value.name]}>
181
+ 确定要删除用户&nbsp;
182
+ {value.name}
183
+ &nbsp;吗?
184
+ </Highlight>
185
+ ),
184
186
  async onOk() {
185
187
  await remove.trigger(
186
188
  {
@@ -190,7 +192,7 @@ const UserList: FC = () => {
190
192
  {
191
193
  async onSuccess() {
192
194
  await message.success('用户删除成功')
193
- trigger(swrKey)
195
+ refresh(swrKey, { page: 1 })
194
196
  },
195
197
  },
196
198
  )
@@ -204,7 +206,7 @@ const UserList: FC = () => {
204
206
  ),
205
207
  },
206
208
  ]
207
- }, [trigger, remove, message, modal, showUpdatingModal])
209
+ }, [refresh, remove, message, modal, showUpdatingModal])
208
210
 
209
211
  return (
210
212
  <>
@@ -223,21 +225,7 @@ const UserList: FC = () => {
223
225
  </PermissionButton>
224
226
  }
225
227
  >
226
- <QueryList
227
- code="100001"
228
- swrKey={swrKey}
229
- rowKey="id"
230
- columns={columns}
231
- transformArg={arg => {
232
- const { page, perPage, ...restValues } = arg
233
-
234
- return {
235
- ...(restValues ?? {}),
236
- page,
237
- size: perPage,
238
- }
239
- }}
240
- />
228
+ <QueryList code="100001" swrKey={swrKey} rowKey="id" columns={columns} />
241
229
  </Card>
242
230
  {CreatingModal}
243
231
  {UpdatingModal}
@@ -1,3 +1,3 @@
1
1
  export * from './menu'
2
2
  export * from './token'
3
- export * from './queryTrigger'
3
+ export * from './query-list'
@@ -0,0 +1,61 @@
1
+ import type { QueryListKey } from '@/components/QueryList'
2
+ import type { PaginationParams } from '@/types'
3
+ import { create } from 'zustand'
4
+
5
+ type RefreshFunction = (arg?: Partial<PaginationParams>) => void
6
+
7
+ export interface QueryListState {
8
+ data: Map<
9
+ QueryListKey,
10
+ {
11
+ pagination?: PaginationParams
12
+ refresh?: RefreshFunction
13
+ }
14
+ >
15
+ getPaginationData: (key: QueryListKey) => PaginationParams
16
+ setPaginationData: (key: QueryListKey, pagination?: Partial<PaginationParams>) => void
17
+ refresh: (key: QueryListKey, arg?: Partial<PaginationParams>) => void
18
+ setRefresh: (key: QueryListKey, trigger: RefreshFunction) => void
19
+ }
20
+
21
+ export const useQueryListStore = create<QueryListState>((set, get) => ({
22
+ data: new Map(),
23
+ getPaginationData: (key: QueryListKey) => {
24
+ const pagination = get().data.get(key)?.pagination
25
+ return {
26
+ page: pagination?.page ?? 1,
27
+ size: pagination?.size ?? 10,
28
+ }
29
+ },
30
+ setPaginationData: (key: QueryListKey, pagination?: Partial<PaginationParams>) => {
31
+ set({
32
+ data: new Map(get().data).set(key, {
33
+ ...get().data.get(key),
34
+ pagination: {
35
+ page: pagination?.page ?? get().getPaginationData(key).page,
36
+ size: pagination?.size ?? get().getPaginationData(key).size,
37
+ },
38
+ }),
39
+ })
40
+ },
41
+ refresh: (key: QueryListKey, pagination?: Partial<PaginationParams>) => {
42
+ const refresh = get().data.get(key)?.refresh
43
+
44
+ if (refresh) {
45
+ refresh({
46
+ page: pagination?.page ?? get().getPaginationData(key).page,
47
+ size: pagination?.size ?? get().getPaginationData(key).size,
48
+ })
49
+ }
50
+ },
51
+ setRefresh: (key: QueryListKey, refresh: RefreshFunction) => {
52
+ const data = get().data
53
+
54
+ set({
55
+ data: new Map(data).set(key, {
56
+ ...data.get(key),
57
+ refresh,
58
+ }),
59
+ })
60
+ },
61
+ }))
@@ -1,10 +1,10 @@
1
1
  export interface ListResponse<T> {
2
2
  List: T[]
3
- Page: number
3
+ Page?: number
4
4
  Total: number
5
5
  }
6
6
 
7
7
  export type PaginationParams = {
8
8
  page: number
9
- perPage: number
9
+ size: number
10
10
  }
package/tsup.config.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import type { Options } from 'tsup'
2
2
  import { defineConfig } from 'tsup'
3
+ import * as process from 'process'
3
4
 
4
5
  export default defineConfig((options: Options) => ({
5
6
  entry: ['src/index.ts'],
7
+ format: ['esm'],
8
+ sourcemap: process.env.NODE_ENV !== 'production',
9
+ minify: process.env.NODE_ENV === 'production',
6
10
  treeshake: true,
7
11
  splitting: false,
8
- format: ['esm'],
9
- sourcemap: true,
10
12
  dts: true,
11
- minify: false,
12
13
  clean: true,
13
14
  shims: true,
14
15
  external: ['react', 'react-dom'],
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/styles/index.css"],"sourcesContent":["@import \"antd/dist/reset.css\";\n\n*, ::before, ::after{\n\n --tw-border-spacing-x: 0;\n\n --tw-border-spacing-y: 0;\n\n --tw-translate-x: 0;\n\n --tw-translate-y: 0;\n\n --tw-rotate: 0;\n\n --tw-skew-x: 0;\n\n --tw-skew-y: 0;\n\n --tw-scale-x: 1;\n\n --tw-scale-y: 1;\n\n --tw-pan-x: ;\n\n --tw-pan-y: ;\n\n --tw-pinch-zoom: ;\n\n --tw-scroll-snap-strictness: proximity;\n\n --tw-gradient-from-position: ;\n\n --tw-gradient-via-position: ;\n\n --tw-gradient-to-position: ;\n\n --tw-ordinal: ;\n\n --tw-slashed-zero: ;\n\n --tw-numeric-figure: ;\n\n --tw-numeric-spacing: ;\n\n --tw-numeric-fraction: ;\n\n --tw-ring-inset: ;\n\n --tw-ring-offset-width: 0px;\n\n --tw-ring-offset-color: #fff;\n\n --tw-ring-color: rgb(59 130 246 / 0.5);\n\n --tw-ring-offset-shadow: 0 0 #0000;\n\n --tw-ring-shadow: 0 0 #0000;\n\n --tw-shadow: 0 0 #0000;\n\n --tw-shadow-colored: 0 0 #0000;\n\n --tw-blur: ;\n\n --tw-brightness: ;\n\n --tw-contrast: ;\n\n --tw-grayscale: ;\n\n --tw-hue-rotate: ;\n\n --tw-invert: ;\n\n --tw-saturate: ;\n\n --tw-sepia: ;\n\n --tw-drop-shadow: ;\n\n --tw-backdrop-blur: ;\n\n --tw-backdrop-brightness: ;\n\n --tw-backdrop-contrast: ;\n\n --tw-backdrop-grayscale: ;\n\n --tw-backdrop-hue-rotate: ;\n\n --tw-backdrop-invert: ;\n\n --tw-backdrop-opacity: ;\n\n --tw-backdrop-saturate: ;\n\n --tw-backdrop-sepia: \n}\n\n::backdrop{\n\n --tw-border-spacing-x: 0;\n\n --tw-border-spacing-y: 0;\n\n --tw-translate-x: 0;\n\n --tw-translate-y: 0;\n\n --tw-rotate: 0;\n\n --tw-skew-x: 0;\n\n --tw-skew-y: 0;\n\n --tw-scale-x: 1;\n\n --tw-scale-y: 1;\n\n --tw-pan-x: ;\n\n --tw-pan-y: ;\n\n --tw-pinch-zoom: ;\n\n --tw-scroll-snap-strictness: proximity;\n\n --tw-gradient-from-position: ;\n\n --tw-gradient-via-position: ;\n\n --tw-gradient-to-position: ;\n\n --tw-ordinal: ;\n\n --tw-slashed-zero: ;\n\n --tw-numeric-figure: ;\n\n --tw-numeric-spacing: ;\n\n --tw-numeric-fraction: ;\n\n --tw-ring-inset: ;\n\n --tw-ring-offset-width: 0px;\n\n --tw-ring-offset-color: #fff;\n\n --tw-ring-color: rgb(59 130 246 / 0.5);\n\n --tw-ring-offset-shadow: 0 0 #0000;\n\n --tw-ring-shadow: 0 0 #0000;\n\n --tw-shadow: 0 0 #0000;\n\n --tw-shadow-colored: 0 0 #0000;\n\n --tw-blur: ;\n\n --tw-brightness: ;\n\n --tw-contrast: ;\n\n --tw-grayscale: ;\n\n --tw-hue-rotate: ;\n\n --tw-invert: ;\n\n --tw-saturate: ;\n\n --tw-sepia: ;\n\n --tw-drop-shadow: ;\n\n --tw-backdrop-blur: ;\n\n --tw-backdrop-brightness: ;\n\n --tw-backdrop-contrast: ;\n\n --tw-backdrop-grayscale: ;\n\n --tw-backdrop-hue-rotate: ;\n\n --tw-backdrop-invert: ;\n\n --tw-backdrop-opacity: ;\n\n --tw-backdrop-saturate: ;\n\n --tw-backdrop-sepia: \n}\n.container{\n\n width: 100%\n}\n@media (min-width: 640px){\n\n .container{\n\n max-width: 640px\n }\n}\n@media (min-width: 768px){\n\n .container{\n\n max-width: 768px\n }\n}\n@media (min-width: 1024px){\n\n .container{\n\n max-width: 1024px\n }\n}\n@media (min-width: 1280px){\n\n .container{\n\n max-width: 1280px\n }\n}\n@media (min-width: 1536px){\n\n .container{\n\n max-width: 1536px\n }\n}\n.fixed{\n\n position: fixed\n}\n.absolute{\n\n position: absolute\n}\n.relative{\n\n position: relative\n}\n.-top-12{\n\n top: -3rem\n}\n.left-0{\n\n left: 0px\n}\n.right-0{\n\n right: 0px\n}\n.top-1\\/2{\n\n top: 50%\n}\n.mb-6{\n\n margin-bottom: 1.5rem\n}\n.ml-2{\n\n margin-left: 0.5rem\n}\n.ml-64{\n\n margin-left: 16rem\n}\n.inline{\n\n display: inline\n}\n.flex{\n\n display: flex\n}\n.hidden{\n\n display: none\n}\n.h-8{\n\n height: 2rem\n}\n.h-screen{\n\n height: 100vh\n}\n.w-8{\n\n width: 2rem\n}\n.w-full{\n\n width: 100%\n}\n.-translate-y-1\\/2{\n\n --tw-translate-y: -50%;\n\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))\n}\n.transform{\n\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))\n}\n.items-end{\n\n align-items: flex-end\n}\n.items-center{\n\n align-items: center\n}\n.justify-end{\n\n justify-content: flex-end\n}\n.justify-center{\n\n justify-content: center\n}\n.overflow-auto{\n\n overflow: auto\n}\n.bg-gray-50{\n\n --tw-bg-opacity: 1;\n\n background-color: rgb(249 250 251 / var(--tw-bg-opacity))\n}\n.p-6{\n\n padding: 1.5rem\n}\n.px-6{\n\n padding-left: 1.5rem;\n\n padding-right: 1.5rem\n}\n.py-4{\n\n padding-top: 1rem;\n\n padding-bottom: 1rem\n}\n.text-center{\n\n text-align: center\n}\n.text-lg{\n\n font-size: 1.125rem;\n\n line-height: 1.75rem\n}\n.font-bold{\n\n font-weight: 700\n}\n.filter{\n\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)\n}\n"],"mappings":"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","names":[]}