@v-miniapp/ui-react 1.0.41 → 1.0.45
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/README.md +1 -1
- package/dist/external/index.js +1993 -2004
- package/dist/index.js +1011 -1022
- package/dist-storybook/assets/ANIMATION-CUdn1GTK.js +99 -0
- package/dist-storybook/assets/APP_FRAMEWORK-ljbIOHYd.js +197 -0
- package/dist-storybook/assets/BOTTOM_TAB_BAR-DxCwCfBK.js +175 -0
- package/dist-storybook/assets/CUSTOM_ERROR_BOUNDARY-B4wTQNZc.js +250 -0
- package/dist-storybook/assets/Color-AVL7NMMY-1_8XTICv.js +1 -0
- package/dist-storybook/assets/DARK_MODE-CoHseCDO.js +57 -0
- package/dist-storybook/assets/DocsRenderer-PQXLIZUC-BO86igwd.js +2 -0
- package/dist-storybook/assets/GETTING_STARTED-H_vVi5cv.js +77 -0
- package/dist-storybook/assets/INFINITE_SCROLL-BtM3uoX0.js +111 -0
- package/dist-storybook/assets/KEEP_ALIVE-CL2au0al.js +126 -0
- package/dist-storybook/assets/LOCALE-XTCey55y.js +465 -0
- package/dist-storybook/assets/MIGRATION_GUIDE-2LONslE4.js +449 -0
- package/dist-storybook/assets/MOBILE_BEHAVIOURS-DZ6alKTX.js +177 -0
- package/dist-storybook/assets/PAGE_LAYOUT-BuOpN-1Y.js +192 -0
- package/dist-storybook/assets/ROUTING_NAVIGATION-BCPHXNto.js +335 -0
- package/dist-storybook/assets/TAILWIND_INTEGRATION-_T-VfvkM.js +87 -0
- package/dist-storybook/assets/_setToString-CbM921C9.js +1 -0
- package/dist-storybook/assets/alert-DLW8CoyB.js +1 -0
- package/dist-storybook/assets/alert.stories-B-vuojPh.js +110 -0
- package/dist-storybook/assets/avatar-GxcYPA1p.js +1 -0
- package/dist-storybook/assets/avatar.stories-KYFztAc8.js +136 -0
- package/dist-storybook/assets/axe-CmvD4WV5.js +20 -0
- package/dist-storybook/assets/badge-D_LzMVtw.js +1 -0
- package/dist-storybook/assets/badge.stories-Be2ItCmQ.js +262 -0
- package/dist-storybook/assets/blocks-BuaOUtiH.js +1243 -0
- package/dist-storybook/assets/bottom-tab-bar-CtcTAxuI.js +115 -0
- package/dist-storybook/assets/bottom-tab-bar.stories-CDmEve6z.js +186 -0
- package/dist-storybook/assets/button-CL7GeC23.js +1 -0
- package/dist-storybook/assets/button.stories-CaqLWQiY.js +287 -0
- package/dist-storybook/assets/calendar-dOCsjhVU.js +1 -0
- package/dist-storybook/assets/calendar.stories-DLWZldet.js +189 -0
- package/dist-storybook/assets/carousel-1Kww3hIz.js +37 -0
- package/dist-storybook/assets/carousel.stories-B8YbGOOr.js +217 -0
- package/dist-storybook/assets/checkbox-MGytNNRt.js +1 -0
- package/dist-storybook/assets/checkbox.stories-CLvfZPiw.js +201 -0
- package/dist-storybook/assets/chip-kG4p82WT.js +247 -0
- package/dist-storybook/assets/chip.stories-BbwJb5eD.js +442 -0
- package/dist-storybook/assets/classname-CUR_zgkh.js +1 -0
- package/dist-storybook/assets/colors-_6nFGM3e.js +1 -0
- package/dist-storybook/assets/date-Cg-Uk_pp.js +1 -0
- package/dist-storybook/assets/date-field.stories-Diptwqfv.js +129 -0
- package/dist-storybook/assets/date-picker-Dnq_-0Md.js +1 -0
- package/dist-storybook/assets/date-picker.stories-BuGWvzFL.js +123 -0
- package/dist-storybook/assets/default-error-BcnD8fFO.png +0 -0
- package/dist-storybook/assets/dialog.stories-DJ0WsSkA.js +212 -0
- package/dist-storybook/assets/dropdown.stories-D6JUYP73.js +200 -0
- package/dist-storybook/assets/embla-carousel-react.esm-BYjpaHZ9.js +1 -0
- package/dist-storybook/assets/en-Cs9O0XWn.js +15 -0
- package/dist-storybook/assets/icon-DdQsMyRa.js +1 -0
- package/dist-storybook/assets/icon.stories-B-ZvRzFf.js +365 -0
- package/dist-storybook/assets/iframe-CQAwSt4E.js +1071 -0
- package/dist-storybook/assets/iframe-yMKl6hJA.css +1 -0
- package/dist-storybook/assets/image-C3EsNRhz.js +9 -0
- package/dist-storybook/assets/image.stories-C4l8D3ju.js +255 -0
- package/dist-storybook/assets/index-B-Ksafg0.js +1 -0
- package/dist-storybook/assets/index-BV0AJWP6.js +1 -0
- package/dist-storybook/assets/index-CgMRTj-o.js +1 -0
- package/dist-storybook/assets/index-DHiZ-gXR.js +1 -0
- package/dist-storybook/assets/input-wrapper-BKHgnPy6.js +1 -0
- package/dist-storybook/assets/label-DV2iCDmN.js +27 -0
- package/dist-storybook/assets/label.stories-BwTIPFXX.js +138 -0
- package/dist-storybook/assets/matchers-7Z3WT2CE-Dw4MQV_s.js +14 -0
- package/dist-storybook/assets/navigation-bar-vI-FPasP.js +79 -0
- package/dist-storybook/assets/navigation-bar.stories-DYuFaJFD.js +73 -0
- package/dist-storybook/assets/number-field-CXKmnfKe.js +1 -0
- package/dist-storybook/assets/number-field.stories--fn26TJu.js +167 -0
- package/dist-storybook/assets/omit-Bsx5nTI0.js +1 -0
- package/dist-storybook/assets/option-item-LRh_OyV4.js +1 -0
- package/dist-storybook/assets/option-item.stories-snjAvgay.js +66 -0
- package/dist-storybook/assets/pagination-DZHoBs_4.js +1 -0
- package/dist-storybook/assets/pagination.stories-BoEs0jzS.js +91 -0
- package/dist-storybook/assets/pick-BhmhLmLe.js +1 -0
- package/dist-storybook/assets/preload-helper-PPVm8Dsz.js +1 -0
- package/dist-storybook/assets/radio-B5NJxG_l.js +1 -0
- package/dist-storybook/assets/radio.stories-DuN-Awi_.js +183 -0
- package/dist-storybook/assets/rating-BdXViYBv.js +1 -0
- package/dist-storybook/assets/rating.stories-BCcQjMEx.js +117 -0
- package/dist-storybook/assets/react-18-CNyWQ7je.js +9 -0
- package/dist-storybook/assets/react-hufnxGVs.js +1 -0
- package/dist-storybook/assets/search-field-CQqgFbfg.js +1 -0
- package/dist-storybook/assets/search-field.stories-DiCZbhng.js +79 -0
- package/dist-storybook/assets/section-content-DGNB4eLN.js +1 -0
- package/dist-storybook/assets/section.stories-C2I_kKhu.js +69 -0
- package/dist-storybook/assets/sheet.stories-wk1JaKU5.js +152 -0
- package/dist-storybook/assets/skeleton-C91JgehG.js +1 -0
- package/dist-storybook/assets/skeleton.stories-BCmX-VNr.js +139 -0
- package/dist-storybook/assets/store-CPumdfcU.js +1 -0
- package/dist-storybook/assets/store-D2RudmNr.js +18 -0
- package/dist-storybook/assets/switch-p-aXI-ev.js +1 -0
- package/dist-storybook/assets/switch.stories-BqPLNKB9.js +250 -0
- package/dist-storybook/assets/tab-bar-CSeCmtIZ.js +31 -0
- package/dist-storybook/assets/tab-bar.stories-Cb6v8H2w.js +136 -0
- package/dist-storybook/assets/text-area-DwSXyqOe.js +1 -0
- package/dist-storybook/assets/text-area.stories-By8bCfgc.js +87 -0
- package/dist-storybook/assets/text-field-jK6rpOo2.js +1 -0
- package/dist-storybook/assets/text-field.stories-CrWBAhvI.js +92 -0
- package/dist-storybook/assets/toast-provider-DurnMJhd.js +9 -0
- package/dist-storybook/assets/toast.stories-iWAToAZA.js +201 -0
- package/dist-storybook/assets/tooltip-QDdel5My.js +1 -0
- package/dist-storybook/assets/tooltip.stories-RC6SuPPD.js +153 -0
- package/dist-storybook/assets/typography-DEpAJl_i.js +1 -0
- package/dist-storybook/assets/typography.stories-Bu8qFugR.js +202 -0
- package/dist-storybook/assets/uploader.stories-B2wW9qVy.js +65 -0
- package/dist-storybook/assets/use-app-pause-B_tWHKJK.js +29 -0
- package/dist-storybook/assets/use-app-resume--900G-dV.js +29 -0
- package/dist-storybook/assets/use-custom-icon-event-3VExRzvC.js +29 -0
- package/dist-storybook/assets/use-did-hide-BUsL73ab.js +48 -0
- package/dist-storybook/assets/use-did-show-C1-VLDxi.js +49 -0
- package/dist-storybook/assets/use-histories-E4E2jJEY.js +50 -0
- package/dist-storybook/assets/use-history-o1im8IDj.js +67 -0
- package/dist-storybook/assets/use-location-CUEaBO4P.js +56 -0
- package/dist-storybook/assets/use-navigate-C4CTuFSZ.js +84 -0
- package/dist-storybook/assets/use-navigation-type-Dcz4hgKo.js +44 -0
- package/dist-storybook/assets/use-page-config-DSJBVQbq.js +48 -0
- package/dist-storybook/assets/use-page-scroll-dY-U1Vv4.js +69 -0
- package/dist-storybook/assets/use-page-state-CtNpwGPN.js +79 -0
- package/dist-storybook/assets/use-settings-changed-BBJwIHTE.js +29 -0
- package/dist-storybook/assets/v-mini-icon-Dn1BmJzb.woff2 +0 -0
- package/dist-storybook/assets/visibility-sensor-CwrzJO06.js +1 -0
- package/dist-storybook/iframe.html +670 -0
- package/dist-storybook/index.html +132 -0
- package/dist-storybook/index.json +1 -0
- package/dist-storybook/project.json +1 -0
- package/dist-storybook/sb-addons/a11y-2/manager-bundle.js +5 -0
- package/dist-storybook/sb-addons/docs-1/manager-bundle.js +151 -0
- package/dist-storybook/sb-addons/storybook-build-3/manager-bundle.js +3 -0
- package/dist-storybook/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +971 -0
- package/dist-storybook/sb-manager/globals-module-info.js +799 -0
- package/dist-storybook/sb-manager/globals-runtime.js +69791 -0
- package/dist-storybook/sb-manager/globals.js +34 -0
- package/dist-storybook/sb-manager/runtime.js +13198 -0
- package/dist-storybook/stories-data.json +374 -0
- package/dist-storybook/vite-inject-mocker-entry.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import{j as r}from"./iframe-CQAwSt4E.js";import{useMDXComponents as t}from"./index-CgMRTj-o.js";import{b as a}from"./blocks-BuaOUtiH.js";import"./preload-helper-PPVm8Dsz.js";import"./index-DHiZ-gXR.js";function e(o){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...t(),...o.components};return r.jsxs(r.Fragment,{children:[`
|
|
2
|
+
`,`
|
|
3
|
+
`,r.jsx(a,{title:"Use Cases/Custom Error Boundary"}),`
|
|
4
|
+
`,r.jsx(n.h1,{id:"custom-error-boundary",children:"Custom Error Boundary"}),`
|
|
5
|
+
`,r.jsx(n.p,{children:"App framework đã có sẵn ErrorBoundary global để catch tất cả lỗi, nhưng bạn có thể thêm ErrorBoundary riêng cho từng page thông qua Layouts để bắt lỗi trước và xử lý chi tiết hơn."}),`
|
|
6
|
+
`,r.jsx(n.h2,{id:"tổng-quan",children:"Tổng quan"}),`
|
|
7
|
+
`,r.jsxs(n.p,{children:["App component đã được bọc với ErrorBoundary global ở ngoài cùng để catch tất cả lỗi không được handle. Tuy nhiên, bạn có thể thêm ErrorBoundary riêng cho từng page thông qua ",r.jsx(n.code,{children:"Layouts"})," trong ",r.jsx(n.code,{children:"IPageConfig"})," để:"]}),`
|
|
8
|
+
`,r.jsxs(n.ul,{children:[`
|
|
9
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Bắt lỗi trước"}),": ErrorBoundary ở page-level sẽ bắt lỗi trước ErrorBoundary global"]}),`
|
|
10
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Xử lý chi tiết"}),": Mỗi page có thể có error UI và logic xử lý lỗi riêng phù hợp với context"]}),`
|
|
11
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Isolate errors"}),": Lỗi ở một page không ảnh hưởng đến các pages khác"]}),`
|
|
12
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Better UX"}),": User có thể tiếp tục sử dụng các pages khác khi một page bị lỗi"]}),`
|
|
13
|
+
`]}),`
|
|
14
|
+
`,r.jsx(n.h2,{id:"errorboundary-global",children:"ErrorBoundary Global"}),`
|
|
15
|
+
`,r.jsx(n.p,{children:"App component đã có ErrorBoundary global sẵn:"}),`
|
|
16
|
+
`,r.jsx(n.pre,{children:r.jsx(n.code,{className:"language-tsx",children:`<ErrorBoundary isGlobal>{/* App content */}</ErrorBoundary>
|
|
17
|
+
`})}),`
|
|
18
|
+
`,r.jsx(n.p,{children:"ErrorBoundary global sẽ catch tất cả lỗi không được handle bởi các ErrorBoundary khác."}),`
|
|
19
|
+
`,r.jsx(n.h2,{id:"thêm-errorboundary-cho-từng-page",children:"Thêm ErrorBoundary cho từng Page"}),`
|
|
20
|
+
`,r.jsxs(n.p,{children:["Bạn có thể thêm ErrorBoundary riêng cho từng page thông qua ",r.jsx(n.code,{children:"Layouts"}),":"]}),`
|
|
21
|
+
`,r.jsx(n.h3,{id:"bước-1-tạo-custom-error-boundary-layout",children:"Bước 1: Tạo Custom Error Boundary Layout"}),`
|
|
22
|
+
`,r.jsx(n.p,{children:"Bạn có thể tự viết ErrorBoundary của riêng bạn:"}),`
|
|
23
|
+
`,r.jsx(n.pre,{children:r.jsx(n.code,{className:"language-tsx",children:`import { Component } from 'react'
|
|
24
|
+
import { FC, PropsWithChildren } from 'react'
|
|
25
|
+
|
|
26
|
+
// Custom ErrorBoundary của riêng bạn
|
|
27
|
+
class CustomErrorBoundary extends Component<
|
|
28
|
+
PropsWithChildren,
|
|
29
|
+
{ hasError: boolean; error: Error | null }
|
|
30
|
+
> {
|
|
31
|
+
constructor(props: PropsWithChildren) {
|
|
32
|
+
super(props)
|
|
33
|
+
this.state = { hasError: false, error: null }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static getDerivedStateFromError(error: Error) {
|
|
37
|
+
return { hasError: true, error }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
41
|
+
// Log error to service
|
|
42
|
+
console.error('Error caught:', error, errorInfo)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
render() {
|
|
46
|
+
if (this.state.hasError) {
|
|
47
|
+
return (
|
|
48
|
+
<div>
|
|
49
|
+
<h1>Something went wrong</h1>
|
|
50
|
+
<p>{this.state.error?.message}</p>
|
|
51
|
+
</div>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return this.props.children
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const PageErrorBoundary: FC<PropsWithChildren> = ({ children }) => {
|
|
60
|
+
return <CustomErrorBoundary>{children}</CustomErrorBoundary>
|
|
61
|
+
}
|
|
62
|
+
`})}),`
|
|
63
|
+
`,r.jsx(n.h3,{id:"bước-2-sử-dụng-trong-page-config",children:"Bước 2: Sử dụng trong Page Config"}),`
|
|
64
|
+
`,r.jsx(n.pre,{children:r.jsx(n.code,{className:"language-tsx",children:`import { App, type IAppConfig } from '@v-miniapp/ui-react'
|
|
65
|
+
import { PageErrorBoundary } from './layouts/PageErrorBoundary'
|
|
66
|
+
|
|
67
|
+
const appConfig: IAppConfig = {
|
|
68
|
+
pages: [
|
|
69
|
+
{
|
|
70
|
+
pathname: '/home',
|
|
71
|
+
Component: HomePage,
|
|
72
|
+
// Wrap page với ErrorBoundary riêng
|
|
73
|
+
Layouts: [PageErrorBoundary],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
pathname: '/settings',
|
|
77
|
+
Component: SettingsPage,
|
|
78
|
+
// Page này không có ErrorBoundary riêng, sẽ dùng global
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
pathname: '/detail',
|
|
82
|
+
Component: DetailPage,
|
|
83
|
+
// Có thể kết hợp với các layouts khác
|
|
84
|
+
Layouts: [PageErrorBoundary, HeaderLayout],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function MiniApp() {
|
|
90
|
+
return <App config={appConfig} />
|
|
91
|
+
}
|
|
92
|
+
`})}),`
|
|
93
|
+
`,r.jsx(n.h2,{id:"thứ-tự-xử-lý-lỗi",children:"Thứ tự xử lý lỗi"}),`
|
|
94
|
+
`,r.jsx(n.p,{children:"Khi có lỗi xảy ra, ErrorBoundary sẽ được gọi theo thứ tự từ trong ra ngoài:"}),`
|
|
95
|
+
`,r.jsxs(n.ol,{children:[`
|
|
96
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Page-level ErrorBoundary"})," (nếu có trong Layouts) - Bắt lỗi trước"]}),`
|
|
97
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Global ErrorBoundary"})," (trong App component) - Bắt các lỗi còn lại"]}),`
|
|
98
|
+
`]}),`
|
|
99
|
+
`,r.jsx(n.p,{children:"Nếu page có ErrorBoundary riêng và nó catch được lỗi, Global ErrorBoundary sẽ không nhận được lỗi đó."}),`
|
|
100
|
+
`,r.jsx(n.h2,{id:"ví-dụ-nâng-cao",children:"Ví dụ nâng cao"}),`
|
|
101
|
+
`,r.jsx(n.h3,{id:"custom-error-ui-cho-từng-page",children:"Custom Error UI cho từng page"}),`
|
|
102
|
+
`,r.jsx(n.p,{children:"Bạn có thể tạo các ErrorBoundary khác nhau với error UI và logic xử lý riêng. Có thể sử dụng ErrorBoundary có sẵn hoặc tự viết:"}),`
|
|
103
|
+
`,r.jsx(n.pre,{children:r.jsx(n.code,{className:"language-tsx",children:`import { Component, type ReactNode } from 'react'
|
|
104
|
+
import { FC, PropsWithChildren } from 'react'
|
|
105
|
+
|
|
106
|
+
// ErrorBoundary với custom error UI cho home page
|
|
107
|
+
class HomeErrorBoundary extends Component<
|
|
108
|
+
PropsWithChildren,
|
|
109
|
+
{ hasError: boolean }
|
|
110
|
+
> {
|
|
111
|
+
constructor(props: PropsWithChildren) {
|
|
112
|
+
super(props)
|
|
113
|
+
this.state = { hasError: false }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static getDerivedStateFromError() {
|
|
117
|
+
return { hasError: true }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
render() {
|
|
121
|
+
if (this.state.hasError) {
|
|
122
|
+
return <div>Home page error occurred</div>
|
|
123
|
+
}
|
|
124
|
+
return this.props.children
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ErrorBoundary với custom error UI cho settings page
|
|
129
|
+
class SettingsErrorBoundary extends Component<
|
|
130
|
+
PropsWithChildren,
|
|
131
|
+
{ hasError: boolean }
|
|
132
|
+
> {
|
|
133
|
+
constructor(props: PropsWithChildren) {
|
|
134
|
+
super(props)
|
|
135
|
+
this.state = { hasError: false }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static getDerivedStateFromError() {
|
|
139
|
+
return { hasError: true }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
render() {
|
|
143
|
+
if (this.state.hasError) {
|
|
144
|
+
return <div>Settings page error occurred</div>
|
|
145
|
+
}
|
|
146
|
+
return this.props.children
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const HomeErrorBoundaryWrapper: FC<PropsWithChildren> = ({ children }) => {
|
|
151
|
+
return <HomeErrorBoundary>{children}</HomeErrorBoundary>
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const SettingsErrorBoundaryWrapper: FC<PropsWithChildren> = ({ children }) => {
|
|
155
|
+
return <SettingsErrorBoundary>{children}</SettingsErrorBoundary>
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const appConfig: IAppConfig = {
|
|
159
|
+
pages: [
|
|
160
|
+
{
|
|
161
|
+
pathname: '/home',
|
|
162
|
+
Component: HomePage,
|
|
163
|
+
Layouts: [HomeErrorBoundaryWrapper],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
pathname: '/settings',
|
|
167
|
+
Component: SettingsPage,
|
|
168
|
+
Layouts: [SettingsErrorBoundaryWrapper],
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
}
|
|
172
|
+
`})}),`
|
|
173
|
+
`,r.jsx(n.h3,{id:"kết-hợp-với-các-layouts-khác",children:"Kết hợp với các Layouts khác"}),`
|
|
174
|
+
`,r.jsx(n.p,{children:"Bạn có thể kết hợp ErrorBoundary với các layouts khác. Thứ tự trong array sẽ quyết định thứ tự wrap:"}),`
|
|
175
|
+
`,r.jsx(n.pre,{children:r.jsx(n.code,{className:"language-tsx",children:`import { Component } from 'react'
|
|
176
|
+
import { FC, PropsWithChildren } from 'react'
|
|
177
|
+
|
|
178
|
+
// Tự viết ErrorBoundary hoặc sử dụng từ @v-miniapp/ui-react
|
|
179
|
+
class PageErrorBoundary extends Component<
|
|
180
|
+
PropsWithChildren,
|
|
181
|
+
{ hasError: boolean }
|
|
182
|
+
> {
|
|
183
|
+
constructor(props: PropsWithChildren) {
|
|
184
|
+
super(props)
|
|
185
|
+
this.state = { hasError: false }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
static getDerivedStateFromError() {
|
|
189
|
+
return { hasError: true }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
render() {
|
|
193
|
+
if (this.state.hasError) {
|
|
194
|
+
return <div>Page error occurred</div>
|
|
195
|
+
}
|
|
196
|
+
return this.props.children
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const PageErrorBoundaryWrapper: FC<PropsWithChildren> = ({ children }) => {
|
|
201
|
+
return <PageErrorBoundary>{children}</PageErrorBoundary>
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const HeaderLayout: FC<PropsWithChildren> = ({ children }) => {
|
|
205
|
+
return (
|
|
206
|
+
<div className="header-layout">
|
|
207
|
+
<header>Header</header>
|
|
208
|
+
{children}
|
|
209
|
+
</div>
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const AuthLayout: FC<PropsWithChildren> = ({ children }) => {
|
|
214
|
+
return <div className="auth-layout">{children}</div>
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const appConfig: IAppConfig = {
|
|
218
|
+
pages: [
|
|
219
|
+
{
|
|
220
|
+
pathname: '/home',
|
|
221
|
+
Component: HomePage,
|
|
222
|
+
// Thứ tự wrap: AuthLayout → HeaderLayout → PageErrorBoundaryWrapper → HomePage
|
|
223
|
+
Layouts: [AuthLayout, HeaderLayout, PageErrorBoundaryWrapper],
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
}
|
|
227
|
+
`})}),`
|
|
228
|
+
`,r.jsxs(n.p,{children:[r.jsx(n.strong,{children:"Lưu ý:"})," Phần tử ",r.jsx(n.strong,{children:"cuối cùng"})," trong array sẽ wrap ở ",r.jsx(n.strong,{children:"trong cùng"})," (gần Component nhất). Với ",r.jsx(n.code,{children:"Layouts: [AuthLayout, HeaderLayout, PageErrorBoundaryWrapper]"}),", kết quả render sẽ là:"]}),`
|
|
229
|
+
`,r.jsx(n.pre,{children:r.jsx(n.code,{className:"language-tsx",children:`<AuthLayout>
|
|
230
|
+
<HeaderLayout>
|
|
231
|
+
<PageErrorBoundaryWrapper>
|
|
232
|
+
<HomePage />
|
|
233
|
+
</PageErrorBoundaryWrapper>
|
|
234
|
+
</HeaderLayout>
|
|
235
|
+
</AuthLayout>
|
|
236
|
+
`})}),`
|
|
237
|
+
`,r.jsx(n.h2,{id:"lưu-ý-quan-trọng",children:"Lưu ý quan trọng"}),`
|
|
238
|
+
`,r.jsxs(n.ul,{children:[`
|
|
239
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Wrap từng màn hình"}),": Layouts phải wrap từng page riêng biệt, không hỗ trợ nested routes hoặc group layout cho nhiều pages. Mỗi page cần wrap ErrorBoundary riêng nếu muốn xử lý lỗi độc lập."]}),`
|
|
240
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Không group Layout"}),": Không thể định nghĩa Layouts ở app-level để áp dụng cho nhiều pages. Layouts chỉ có thể được khai báo trong ",r.jsx(n.code,{children:"IPageConfig"})," của từng page."]}),`
|
|
241
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"ErrorBoundary scope"}),": ErrorBoundary trong Layouts chỉ catch lỗi của page component và các component con của nó, không catch lỗi của các pages khác."]}),`
|
|
242
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Bắt lỗi trước"}),": Page-level ErrorBoundary sẽ bắt lỗi trước Global ErrorBoundary, cho phép bạn xử lý lỗi chi tiết hơn cho từng page."]}),`
|
|
243
|
+
`]}),`
|
|
244
|
+
`,r.jsx(n.h2,{id:"best-practices",children:"Best Practices"}),`
|
|
245
|
+
`,r.jsxs(n.ol,{children:[`
|
|
246
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Chỉ bọc page cần thiết"}),": Không cần bọc ErrorBoundary cho tất cả pages, chỉ bọc những page có logic phức tạp hoặc cần xử lý lỗi riêng"]}),`
|
|
247
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Đặt ErrorBoundary ở trong cùng"}),": Nếu kết hợp với các layouts khác, thường nên đặt ErrorBoundary ở trong cùng (cuối array) để chỉ catch lỗi của page component"]}),`
|
|
248
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Custom error UI"}),": Tùy chỉnh error UI phù hợp với context của từng page để có UX tốt hơn"]}),`
|
|
249
|
+
`,r.jsxs(n.li,{children:[r.jsx(n.strong,{children:"Error logging"}),": Có thể thêm error logging trong ErrorBoundary để track lỗi"]}),`
|
|
250
|
+
`]})]})}function l(o={}){const{wrapper:n}={...t(),...o.components};return n?r.jsx(n,{...o,children:r.jsx(e,{...o})}):e(o)}export{l as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as ce,x as E,u as U,g as he,c as fe,e as de,f as ge,_ as be,h as I}from"./blocks-BuaOUtiH.js";import{r as p,e as v}from"./iframe-CQAwSt4E.js";import"./preload-helper-PPVm8Dsz.js";import"./index-DHiZ-gXR.js";var ve=I({"../../node_modules/color-name/index.js"(r,l){l.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}}}),Y=I({"../../node_modules/color-convert/conversions.js"(r,l){var s=ve(),h={};for(let e of Object.keys(s))h[s[e]]=e;var u={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};l.exports=u;for(let e of Object.keys(u)){if(!("channels"in u[e]))throw new Error("missing channels property: "+e);if(!("labels"in u[e]))throw new Error("missing channel labels property: "+e);if(u[e].labels.length!==u[e].channels)throw new Error("channel and label counts mismatch: "+e);let{channels:n,labels:t}=u[e];delete u[e].channels,delete u[e].labels,Object.defineProperty(u[e],"channels",{value:n}),Object.defineProperty(u[e],"labels",{value:t})}u.rgb.hsl=function(e){let n=e[0]/255,t=e[1]/255,a=e[2]/255,o=Math.min(n,t,a),i=Math.max(n,t,a),c=i-o,f,g;i===o?f=0:n===i?f=(t-a)/c:t===i?f=2+(a-n)/c:a===i&&(f=4+(n-t)/c),f=Math.min(f*60,360),f<0&&(f+=360);let b=(o+i)/2;return i===o?g=0:b<=.5?g=c/(i+o):g=c/(2-i-o),[f,g*100,b*100]},u.rgb.hsv=function(e){let n,t,a,o,i,c=e[0]/255,f=e[1]/255,g=e[2]/255,b=Math.max(c,f,g),y=b-Math.min(c,f,g),m=function(k){return(b-k)/6/y+1/2};return y===0?(o=0,i=0):(i=y/b,n=m(c),t=m(f),a=m(g),c===b?o=a-t:f===b?o=1/3+n-a:g===b&&(o=2/3+t-n),o<0?o+=1:o>1&&(o-=1)),[o*360,i*100,b*100]},u.rgb.hwb=function(e){let n=e[0],t=e[1],a=e[2],o=u.rgb.hsl(e)[0],i=1/255*Math.min(n,Math.min(t,a));return a=1-1/255*Math.max(n,Math.max(t,a)),[o,i*100,a*100]},u.rgb.cmyk=function(e){let n=e[0]/255,t=e[1]/255,a=e[2]/255,o=Math.min(1-n,1-t,1-a),i=(1-n-o)/(1-o)||0,c=(1-t-o)/(1-o)||0,f=(1-a-o)/(1-o)||0;return[i*100,c*100,f*100,o*100]};function d(e,n){return(e[0]-n[0])**2+(e[1]-n[1])**2+(e[2]-n[2])**2}u.rgb.keyword=function(e){let n=h[e];if(n)return n;let t=1/0,a;for(let o of Object.keys(s)){let i=s[o],c=d(e,i);c<t&&(t=c,a=o)}return a},u.keyword.rgb=function(e){return s[e]},u.rgb.xyz=function(e){let n=e[0]/255,t=e[1]/255,a=e[2]/255;n=n>.04045?((n+.055)/1.055)**2.4:n/12.92,t=t>.04045?((t+.055)/1.055)**2.4:t/12.92,a=a>.04045?((a+.055)/1.055)**2.4:a/12.92;let o=n*.4124+t*.3576+a*.1805,i=n*.2126+t*.7152+a*.0722,c=n*.0193+t*.1192+a*.9505;return[o*100,i*100,c*100]},u.rgb.lab=function(e){let n=u.rgb.xyz(e),t=n[0],a=n[1],o=n[2];t/=95.047,a/=100,o/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,a=a>.008856?a**(1/3):7.787*a+16/116,o=o>.008856?o**(1/3):7.787*o+16/116;let i=116*a-16,c=500*(t-a),f=200*(a-o);return[i,c,f]},u.hsl.rgb=function(e){let n=e[0]/360,t=e[1]/100,a=e[2]/100,o,i,c;if(t===0)return c=a*255,[c,c,c];a<.5?o=a*(1+t):o=a+t-a*t;let f=2*a-o,g=[0,0,0];for(let b=0;b<3;b++)i=n+1/3*-(b-1),i<0&&i++,i>1&&i--,6*i<1?c=f+(o-f)*6*i:2*i<1?c=o:3*i<2?c=f+(o-f)*(2/3-i)*6:c=f,g[b]=c*255;return g},u.hsl.hsv=function(e){let n=e[0],t=e[1]/100,a=e[2]/100,o=t,i=Math.max(a,.01);a*=2,t*=a<=1?a:2-a,o*=i<=1?i:2-i;let c=(a+t)/2,f=a===0?2*o/(i+o):2*t/(a+t);return[n,f*100,c*100]},u.hsv.rgb=function(e){let n=e[0]/60,t=e[1]/100,a=e[2]/100,o=Math.floor(n)%6,i=n-Math.floor(n),c=255*a*(1-t),f=255*a*(1-t*i),g=255*a*(1-t*(1-i));switch(a*=255,o){case 0:return[a,g,c];case 1:return[f,a,c];case 2:return[c,a,g];case 3:return[c,f,a];case 4:return[g,c,a];case 5:return[a,c,f]}},u.hsv.hsl=function(e){let n=e[0],t=e[1]/100,a=e[2]/100,o=Math.max(a,.01),i,c;c=(2-t)*a;let f=(2-t)*o;return i=t*o,i/=f<=1?f:2-f,i=i||0,c/=2,[n,i*100,c*100]},u.hwb.rgb=function(e){let n=e[0]/360,t=e[1]/100,a=e[2]/100,o=t+a,i;o>1&&(t/=o,a/=o);let c=Math.floor(6*n),f=1-a;i=6*n-c,(c&1)!==0&&(i=1-i);let g=t+i*(f-t),b,y,m;switch(c){default:case 6:case 0:b=f,y=g,m=t;break;case 1:b=g,y=f,m=t;break;case 2:b=t,y=f,m=g;break;case 3:b=t,y=g,m=f;break;case 4:b=g,y=t,m=f;break;case 5:b=f,y=t,m=g;break}return[b*255,y*255,m*255]},u.cmyk.rgb=function(e){let n=e[0]/100,t=e[1]/100,a=e[2]/100,o=e[3]/100,i=1-Math.min(1,n*(1-o)+o),c=1-Math.min(1,t*(1-o)+o),f=1-Math.min(1,a*(1-o)+o);return[i*255,c*255,f*255]},u.xyz.rgb=function(e){let n=e[0]/100,t=e[1]/100,a=e[2]/100,o,i,c;return o=n*3.2406+t*-1.5372+a*-.4986,i=n*-.9689+t*1.8758+a*.0415,c=n*.0557+t*-.204+a*1.057,o=o>.0031308?1.055*o**(1/2.4)-.055:o*12.92,i=i>.0031308?1.055*i**(1/2.4)-.055:i*12.92,c=c>.0031308?1.055*c**(1/2.4)-.055:c*12.92,o=Math.min(Math.max(0,o),1),i=Math.min(Math.max(0,i),1),c=Math.min(Math.max(0,c),1),[o*255,i*255,c*255]},u.xyz.lab=function(e){let n=e[0],t=e[1],a=e[2];n/=95.047,t/=100,a/=108.883,n=n>.008856?n**(1/3):7.787*n+16/116,t=t>.008856?t**(1/3):7.787*t+16/116,a=a>.008856?a**(1/3):7.787*a+16/116;let o=116*t-16,i=500*(n-t),c=200*(t-a);return[o,i,c]},u.lab.xyz=function(e){let n=e[0],t=e[1],a=e[2],o,i,c;i=(n+16)/116,o=t/500+i,c=i-a/200;let f=i**3,g=o**3,b=c**3;return i=f>.008856?f:(i-16/116)/7.787,o=g>.008856?g:(o-16/116)/7.787,c=b>.008856?b:(c-16/116)/7.787,o*=95.047,i*=100,c*=108.883,[o,i,c]},u.lab.lch=function(e){let n=e[0],t=e[1],a=e[2],o;o=Math.atan2(a,t)*360/2/Math.PI,o<0&&(o+=360);let i=Math.sqrt(t*t+a*a);return[n,i,o]},u.lch.lab=function(e){let n=e[0],t=e[1],a=e[2]/360*2*Math.PI,o=t*Math.cos(a),i=t*Math.sin(a);return[n,o,i]},u.rgb.ansi16=function(e,n=null){let[t,a,o]=e,i=n===null?u.rgb.hsv(e)[2]:n;if(i=Math.round(i/50),i===0)return 30;let c=30+(Math.round(o/255)<<2|Math.round(a/255)<<1|Math.round(t/255));return i===2&&(c+=60),c},u.hsv.ansi16=function(e){return u.rgb.ansi16(u.hsv.rgb(e),e[2])},u.rgb.ansi256=function(e){let n=e[0],t=e[1],a=e[2];return n===t&&t===a?n<8?16:n>248?231:Math.round((n-8)/247*24)+232:16+36*Math.round(n/255*5)+6*Math.round(t/255*5)+Math.round(a/255*5)},u.ansi16.rgb=function(e){let n=e%10;if(n===0||n===7)return e>50&&(n+=3.5),n=n/10.5*255,[n,n,n];let t=(~~(e>50)+1)*.5,a=(n&1)*t*255,o=(n>>1&1)*t*255,i=(n>>2&1)*t*255;return[a,o,i]},u.ansi256.rgb=function(e){if(e>=232){let i=(e-232)*10+8;return[i,i,i]}e-=16;let n,t=Math.floor(e/36)/5*255,a=Math.floor((n=e%36)/6)/5*255,o=n%6/5*255;return[t,a,o]},u.rgb.hex=function(e){let n=(((Math.round(e[0])&255)<<16)+((Math.round(e[1])&255)<<8)+(Math.round(e[2])&255)).toString(16).toUpperCase();return"000000".substring(n.length)+n},u.hex.rgb=function(e){let n=e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!n)return[0,0,0];let t=n[0];n[0].length===3&&(t=t.split("").map(f=>f+f).join(""));let a=parseInt(t,16),o=a>>16&255,i=a>>8&255,c=a&255;return[o,i,c]},u.rgb.hcg=function(e){let n=e[0]/255,t=e[1]/255,a=e[2]/255,o=Math.max(Math.max(n,t),a),i=Math.min(Math.min(n,t),a),c=o-i,f,g;return c<1?f=i/(1-c):f=0,c<=0?g=0:o===n?g=(t-a)/c%6:o===t?g=2+(a-n)/c:g=4+(n-t)/c,g/=6,g%=1,[g*360,c*100,f*100]},u.hsl.hcg=function(e){let n=e[1]/100,t=e[2]/100,a=t<.5?2*n*t:2*n*(1-t),o=0;return a<1&&(o=(t-.5*a)/(1-a)),[e[0],a*100,o*100]},u.hsv.hcg=function(e){let n=e[1]/100,t=e[2]/100,a=n*t,o=0;return a<1&&(o=(t-a)/(1-a)),[e[0],a*100,o*100]},u.hcg.rgb=function(e){let n=e[0]/360,t=e[1]/100,a=e[2]/100;if(t===0)return[a*255,a*255,a*255];let o=[0,0,0],i=n%1*6,c=i%1,f=1-c,g=0;switch(Math.floor(i)){case 0:o[0]=1,o[1]=c,o[2]=0;break;case 1:o[0]=f,o[1]=1,o[2]=0;break;case 2:o[0]=0,o[1]=1,o[2]=c;break;case 3:o[0]=0,o[1]=f,o[2]=1;break;case 4:o[0]=c,o[1]=0,o[2]=1;break;default:o[0]=1,o[1]=0,o[2]=f}return g=(1-t)*a,[(t*o[0]+g)*255,(t*o[1]+g)*255,(t*o[2]+g)*255]},u.hcg.hsv=function(e){let n=e[1]/100,t=e[2]/100,a=n+t*(1-n),o=0;return a>0&&(o=n/a),[e[0],o*100,a*100]},u.hcg.hsl=function(e){let n=e[1]/100,t=e[2]/100*(1-n)+.5*n,a=0;return t>0&&t<.5?a=n/(2*t):t>=.5&&t<1&&(a=n/(2*(1-t))),[e[0],a*100,t*100]},u.hcg.hwb=function(e){let n=e[1]/100,t=e[2]/100,a=n+t*(1-n);return[e[0],(a-n)*100,(1-a)*100]},u.hwb.hcg=function(e){let n=e[1]/100,t=1-e[2]/100,a=t-n,o=0;return a<1&&(o=(t-a)/(1-a)),[e[0],a*100,o*100]},u.apple.rgb=function(e){return[e[0]/65535*255,e[1]/65535*255,e[2]/65535*255]},u.rgb.apple=function(e){return[e[0]/255*65535,e[1]/255*65535,e[2]/255*65535]},u.gray.rgb=function(e){return[e[0]/100*255,e[0]/100*255,e[0]/100*255]},u.gray.hsl=function(e){return[0,0,e[0]]},u.gray.hsv=u.gray.hsl,u.gray.hwb=function(e){return[0,100,e[0]]},u.gray.cmyk=function(e){return[0,0,0,e[0]]},u.gray.lab=function(e){return[e[0],0,0]},u.gray.hex=function(e){let n=Math.round(e[0]/100*255)&255,t=((n<<16)+(n<<8)+n).toString(16).toUpperCase();return"000000".substring(t.length)+t},u.rgb.gray=function(e){return[(e[0]+e[1]+e[2])/3/255*100]}}}),me=I({"../../node_modules/color-convert/route.js"(r,l){var s=Y();function h(){let n={},t=Object.keys(s);for(let a=t.length,o=0;o<a;o++)n[t[o]]={distance:-1,parent:null};return n}function u(n){let t=h(),a=[n];for(t[n].distance=0;a.length;){let o=a.pop(),i=Object.keys(s[o]);for(let c=i.length,f=0;f<c;f++){let g=i[f],b=t[g];b.distance===-1&&(b.distance=t[o].distance+1,b.parent=o,a.unshift(g))}}return t}function d(n,t){return function(a){return t(n(a))}}function e(n,t){let a=[t[n].parent,n],o=s[t[n].parent][n],i=t[n].parent;for(;t[i].parent;)a.unshift(t[i].parent),o=d(s[t[i].parent][i],o),i=t[i].parent;return o.conversion=a,o}l.exports=function(n){let t=u(n),a={},o=Object.keys(t);for(let i=o.length,c=0;c<i;c++){let f=o[c];t[f].parent!==null&&(a[f]=e(f,t))}return a}}}),pe=I({"../../node_modules/color-convert/index.js"(r,l){var s=Y(),h=me(),u={},d=Object.keys(s);function e(t){let a=function(...o){let i=o[0];return i==null?i:(i.length>1&&(o=i),t(o))};return"conversion"in t&&(a.conversion=t.conversion),a}function n(t){let a=function(...o){let i=o[0];if(i==null)return i;i.length>1&&(o=i);let c=t(o);if(typeof c=="object")for(let f=c.length,g=0;g<f;g++)c[g]=Math.round(c[g]);return c};return"conversion"in t&&(a.conversion=t.conversion),a}d.forEach(t=>{u[t]={},Object.defineProperty(u[t],"channels",{value:s[t].channels}),Object.defineProperty(u[t],"labels",{value:s[t].labels});let a=h(t);Object.keys(a).forEach(o=>{let i=a[o];u[t][o]=n(i),u[t][o].raw=e(i)})}),l.exports=u}}),_=be(pe());function M(){return(M=Object.assign||function(r){for(var l=1;l<arguments.length;l++){var s=arguments[l];for(var h in s)Object.prototype.hasOwnProperty.call(s,h)&&(r[h]=s[h])}return r}).apply(this,arguments)}function X(r,l){if(r==null)return{};var s,h,u={},d=Object.keys(r);for(h=0;h<d.length;h++)l.indexOf(s=d[h])>=0||(u[s]=r[s]);return u}function P(r){var l=p.useRef(r),s=p.useRef(function(h){l.current&&l.current(h)});return l.current=r,s.current}var $=function(r,l,s){return l===void 0&&(l=0),s===void 0&&(s=1),r>s?s:r<l?l:r},O=function(r){return"touches"in r},L=function(r){return r&&r.ownerDocument.defaultView||self},G=function(r,l,s){var h=r.getBoundingClientRect(),u=O(l)?(function(d,e){for(var n=0;n<d.length;n++)if(d[n].identifier===e)return d[n];return d[0]})(l.touches,s):l;return{left:$((u.pageX-(h.left+L(r).pageXOffset))/h.width),top:$((u.pageY-(h.top+L(r).pageYOffset))/h.height)}},F=function(r){!O(r)&&r.preventDefault()},V=v.memo(function(r){var l=r.onMove,s=r.onKey,h=X(r,["onMove","onKey"]),u=p.useRef(null),d=P(l),e=P(s),n=p.useRef(null),t=p.useRef(!1),a=p.useMemo(function(){var f=function(y){F(y),(O(y)?y.touches.length>0:y.buttons>0)&&u.current?d(G(u.current,y,n.current)):b(!1)},g=function(){return b(!1)};function b(y){var m=t.current,k=L(u.current),x=y?k.addEventListener:k.removeEventListener;x(m?"touchmove":"mousemove",f),x(m?"touchend":"mouseup",g)}return[function(y){var m=y.nativeEvent,k=u.current;if(k&&(F(m),!(function(N,se){return se&&!O(N)})(m,t.current)&&k)){if(O(m)){t.current=!0;var x=m.changedTouches||[];x.length&&(n.current=x[0].identifier)}k.focus(),d(G(k,m,n.current)),b(!0)}},function(y){var m=y.which||y.keyCode;m<37||m>40||(y.preventDefault(),e({left:m===39?.05:m===37?-.05:0,top:m===40?.05:m===38?-.05:0}))},b]},[e,d]),o=a[0],i=a[1],c=a[2];return p.useEffect(function(){return c},[c]),v.createElement("div",M({},h,{onTouchStart:o,onMouseDown:o,className:"react-colorful__interactive",ref:u,onKeyDown:i,tabIndex:0,role:"slider"}))}),S=function(r){return r.filter(Boolean).join(" ")},D=function(r){var l=r.color,s=r.left,h=r.top,u=h===void 0?.5:h,d=S(["react-colorful__pointer",r.className]);return v.createElement("div",{className:d,style:{top:100*u+"%",left:100*s+"%"}},v.createElement("div",{className:"react-colorful__pointer-fill",style:{backgroundColor:l}}))},w=function(r,l,s){return l===void 0&&(l=0),s===void 0&&(s=Math.pow(10,l)),Math.round(s*r)/s},ye={grad:.9,turn:360,rad:360/(2*Math.PI)},xe=function(r){return Z(B(r))},B=function(r){return r[0]==="#"&&(r=r.substring(1)),r.length<6?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:r.length===4?w(parseInt(r[3]+r[3],16)/255,2):1}:{r:parseInt(r.substring(0,2),16),g:parseInt(r.substring(2,4),16),b:parseInt(r.substring(4,6),16),a:r.length===8?w(parseInt(r.substring(6,8),16)/255,2):1}},we=function(r,l){return l===void 0&&(l="deg"),Number(r)*(ye[l]||1)},ke=function(r){var l=/hsla?\(?\s*(-?\d*\.?\d+)(deg|rad|grad|turn)?[,\s]+(-?\d*\.?\d+)%?[,\s]+(-?\d*\.?\d+)%?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i.exec(r);return l?_e({h:we(l[1],l[2]),s:Number(l[3]),l:Number(l[4]),a:l[5]===void 0?1:Number(l[5])/(l[6]?100:1)}):{h:0,s:0,v:0,a:1}},_e=function(r){var l=r.s,s=r.l;return{h:r.h,s:(l*=(s<50?s:100-s)/100)>0?2*l/(s+l)*100:0,v:s+l,a:r.a}},Ee=function(r){return Ce(Q(r))},J=function(r){var l=r.s,s=r.v,h=r.a,u=(200-l)*s/100;return{h:w(r.h),s:w(u>0&&u<200?l*s/100/(u<=100?u:200-u)*100:0),l:w(u/2),a:w(h,2)}},K=function(r){var l=J(r);return"hsl("+l.h+", "+l.s+"%, "+l.l+"%)"},z=function(r){var l=J(r);return"hsla("+l.h+", "+l.s+"%, "+l.l+"%, "+l.a+")"},Q=function(r){var l=r.h,s=r.s,h=r.v,u=r.a;l=l/360*6,s/=100,h/=100;var d=Math.floor(l),e=h*(1-s),n=h*(1-(l-d)*s),t=h*(1-(1-l+d)*s),a=d%6;return{r:w(255*[h,n,e,e,t,h][a]),g:w(255*[t,h,h,n,e,e][a]),b:w(255*[e,e,t,h,h,n][a]),a:w(u,2)}},Me=function(r){var l=/rgba?\(?\s*(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?[,\s]+(-?\d*\.?\d+)(%)?,?\s*[/\s]*(-?\d*\.?\d+)?(%)?\s*\)?/i.exec(r);return l?Z({r:Number(l[1])/(l[2]?100/255:1),g:Number(l[3])/(l[4]?100/255:1),b:Number(l[5])/(l[6]?100/255:1),a:l[7]===void 0?1:Number(l[7])/(l[8]?100:1)}):{h:0,s:0,v:0,a:1}},j=function(r){var l=r.toString(16);return l.length<2?"0"+l:l},Ce=function(r){var l=r.r,s=r.g,h=r.b,u=r.a,d=u<1?j(w(255*u)):"";return"#"+j(l)+j(s)+j(h)+d},Z=function(r){var l=r.r,s=r.g,h=r.b,u=r.a,d=Math.max(l,s,h),e=d-Math.min(l,s,h),n=e?d===l?(s-h)/e:d===s?2+(h-l)/e:4+(l-s)/e:0;return{h:w(60*(n<0?n+6:n)),s:w(d?e/d*100:0),v:w(d/255*100),a:u}},ee=v.memo(function(r){var l=r.hue,s=r.onChange,h=S(["react-colorful__hue",r.className]);return v.createElement("div",{className:h},v.createElement(V,{onMove:function(u){s({h:360*u.left})},onKey:function(u){s({h:$(l+360*u.left,0,360)})},"aria-label":"Hue","aria-valuenow":w(l),"aria-valuemax":"360","aria-valuemin":"0"},v.createElement(D,{className:"react-colorful__hue-pointer",left:l/360,color:K({h:l,s:100,v:100,a:1})})))}),re=v.memo(function(r){var l=r.hsva,s=r.onChange,h={backgroundColor:K({h:l.h,s:100,v:100,a:1})};return v.createElement("div",{className:"react-colorful__saturation",style:h},v.createElement(V,{onMove:function(u){s({s:100*u.left,v:100-100*u.top})},onKey:function(u){s({s:$(l.s+100*u.left,0,100),v:$(l.v-100*u.top,0,100)})},"aria-label":"Color","aria-valuetext":"Saturation "+w(l.s)+"%, Brightness "+w(l.v)+"%"},v.createElement(D,{className:"react-colorful__saturation-pointer",top:1-l.v/100,left:l.s/100,color:K(l)})))}),te=function(r,l){if(r===l)return!0;for(var s in r)if(r[s]!==l[s])return!1;return!0},ne=function(r,l){return r.replace(/\s/g,"")===l.replace(/\s/g,"")},$e=function(r,l){return r.toLowerCase()===l.toLowerCase()||te(B(r),B(l))};function ae(r,l,s){var h=P(s),u=p.useState(function(){return r.toHsva(l)}),d=u[0],e=u[1],n=p.useRef({color:l,hsva:d});p.useEffect(function(){if(!r.equal(l,n.current.color)){var a=r.toHsva(l);n.current={hsva:a,color:l},e(a)}},[l,r]),p.useEffect(function(){var a;te(d,n.current.hsva)||r.equal(a=r.fromHsva(d),n.current.color)||(n.current={hsva:d,color:a},h(a))},[d,r,h]);var t=p.useCallback(function(a){e(function(o){return Object.assign({},o,a)})},[]);return[d,t]}var Oe=typeof window<"u"?p.useLayoutEffect:p.useEffect,Se=function(){return typeof __webpack_nonce__<"u"?__webpack_nonce__:void 0},W=new Map,oe=function(r){Oe(function(){var l=r.current?r.current.ownerDocument:document;if(l!==void 0&&!W.has(l)){var s=l.createElement("style");s.innerHTML=`.react-colorful{position:relative;display:flex;flex-direction:column;width:200px;height:200px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.react-colorful__saturation{position:relative;flex-grow:1;border-color:transparent;border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(0deg,#000,transparent),linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.react-colorful__alpha-gradient,.react-colorful__pointer-fill{content:"";position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;border-radius:inherit}.react-colorful__alpha-gradient,.react-colorful__saturation{box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}.react-colorful__alpha,.react-colorful__hue{position:relative;height:24px}.react-colorful__hue{background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red)}.react-colorful__last-control{border-radius:0 0 8px 8px}.react-colorful__interactive{position:absolute;left:0;top:0;right:0;bottom:0;border-radius:inherit;outline:none;touch-action:none}.react-colorful__pointer{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;transform:translate(-50%,-50%);background-color:#fff;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2)}.react-colorful__interactive:focus .react-colorful__pointer{transform:translate(-50%,-50%) scale(1.1)}.react-colorful__alpha,.react-colorful__alpha-pointer{background-color:#fff;background-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill-opacity=".05"><path d="M8 0h8v8H8zM0 8h8v8H0z"/></svg>')}.react-colorful__saturation-pointer{z-index:3}.react-colorful__hue-pointer{z-index:2}`,W.set(l,s);var h=Se();h&&s.setAttribute("nonce",h),l.head.appendChild(s)}},[])},Ne=function(r){var l=r.className,s=r.colorModel,h=r.color,u=h===void 0?s.defaultColor:h,d=r.onChange,e=X(r,["className","colorModel","color","onChange"]),n=p.useRef(null);oe(n);var t=ae(s,u,d),a=t[0],o=t[1],i=S(["react-colorful",l]);return v.createElement("div",M({},e,{ref:n,className:i}),v.createElement(re,{hsva:a,onChange:o}),v.createElement(ee,{hue:a.h,onChange:o,className:"react-colorful__last-control"}))},je={defaultColor:"000",toHsva:xe,fromHsva:function(r){return Ee({h:r.h,s:r.s,v:r.v,a:1})},equal:$e},Re=function(r){return v.createElement(Ne,M({},r,{colorModel:je}))},ze=function(r){var l=r.className,s=r.hsva,h=r.onChange,u={backgroundImage:"linear-gradient(90deg, "+z(Object.assign({},s,{a:0}))+", "+z(Object.assign({},s,{a:1}))+")"},d=S(["react-colorful__alpha",l]),e=w(100*s.a);return v.createElement("div",{className:d},v.createElement("div",{className:"react-colorful__alpha-gradient",style:u}),v.createElement(V,{onMove:function(n){h({a:n.left})},onKey:function(n){h({a:$(s.a+n.left)})},"aria-label":"Alpha","aria-valuetext":e+"%","aria-valuenow":e,"aria-valuemin":"0","aria-valuemax":"100"},v.createElement(D,{className:"react-colorful__alpha-pointer",left:s.a,color:z(s)})))},le=function(r){var l=r.className,s=r.colorModel,h=r.color,u=h===void 0?s.defaultColor:h,d=r.onChange,e=X(r,["className","colorModel","color","onChange"]),n=p.useRef(null);oe(n);var t=ae(s,u,d),a=t[0],o=t[1],i=S(["react-colorful",l]);return v.createElement("div",M({},e,{ref:n,className:i}),v.createElement(re,{hsva:a,onChange:o}),v.createElement(ee,{hue:a.h,onChange:o}),v.createElement(ze,{hsva:a,onChange:o,className:"react-colorful__last-control"}))},He={defaultColor:"hsla(0, 0%, 0%, 1)",toHsva:ke,fromHsva:z,equal:ne},Ie=function(r){return v.createElement(le,M({},r,{colorModel:He}))},qe={defaultColor:"rgba(0, 0, 0, 1)",toHsva:Me,fromHsva:function(r){var l=Q(r);return"rgba("+l.r+", "+l.g+", "+l.b+", "+l.a+")"},equal:ne},Pe=function(r){return v.createElement(le,M({},r,{colorModel:qe}))},Le=E.div({position:"relative",maxWidth:250,'&[aria-readonly="true"]':{opacity:.5}}),Be=E(U)({position:"absolute",zIndex:1,top:4,left:4,"[aria-readonly=true] &":{cursor:"not-allowed"}}),Ke=E.div({width:200,margin:5,".react-colorful__saturation":{borderRadius:"4px 4px 0 0"},".react-colorful__hue":{boxShadow:"inset 0 0 0 1px rgb(0 0 0 / 5%)"},".react-colorful__last-control":{borderRadius:"0 0 4px 4px"}}),Te=E(fe)(({theme:r})=>({fontFamily:r.typography.fonts.base})),Xe=E.div({display:"grid",gridTemplateColumns:"repeat(9, 16px)",gap:6,padding:3,marginTop:5,width:200}),Ve=E.div(({theme:r,active:l})=>({width:16,height:16,boxShadow:l?`${r.appBorderColor} 0 0 0 1px inset, ${r.textMutedColor}50 0 0 0 4px`:`${r.appBorderColor} 0 0 0 1px inset`,borderRadius:r.appBorderRadius})),De=`url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill-opacity=".05"><path d="M8 0h8v8H8zM0 8h8v8H0z"/></svg>')`,A=({value:r,style:l,...s})=>{let h=`linear-gradient(${r}, ${r}), ${De}, linear-gradient(#fff, #fff)`;return v.createElement(Ve,{...s,style:{...l,backgroundImage:h}})},Ge=E(de.Input)(({theme:r,readOnly:l})=>({width:"100%",paddingLeft:30,paddingRight:30,boxSizing:"border-box",fontFamily:r.typography.fonts.base})),Fe=E(ge)(({theme:r})=>({position:"absolute",zIndex:1,top:6,right:7,width:20,height:20,padding:4,boxSizing:"border-box",cursor:"pointer",color:r.input.color})),ue=(r=>(r.RGB="rgb",r.HSL="hsl",r.HEX="hex",r))(ue||{}),q=Object.values(ue),We=/\(([0-9]+),\s*([0-9]+)%?,\s*([0-9]+)%?,?\s*([0-9.]+)?\)/,Ae=/^\s*rgba?\(([0-9]+),\s*([0-9]+),\s*([0-9]+),?\s*([0-9.]+)?\)\s*$/i,Ue=/^\s*hsla?\(([0-9]+),\s*([0-9]+)%,\s*([0-9]+)%,?\s*([0-9.]+)?\)\s*$/i,T=/^\s*#?([0-9a-f]{3}|[0-9a-f]{6})\s*$/i,Ye=/^\s*#?([0-9a-f]{3})\s*$/i,Je={hex:Re,rgb:Pe,hsl:Ie},R={hex:"transparent",rgb:"rgba(0, 0, 0, 0)",hsl:"hsla(0, 0%, 0%, 0)"},ie=r=>{let l=r?.match(We);if(!l)return[0,0,0,1];let[,s,h,u,d=1]=l;return[s,h,u,d].map(Number)},Qe=r=>{let[l,s,h,u]=ie(r),[d,e,n]=_.default.rgb.hsl([l,s,h])||[0,0,0];return{valid:!0,value:r,keyword:_.default.rgb.keyword([l,s,h]),colorSpace:"rgb",rgb:r,hsl:`hsla(${d}, ${e}%, ${n}%, ${u})`,hex:`#${_.default.rgb.hex([l,s,h]).toLowerCase()}`}},Ze=r=>{let[l,s,h,u]=ie(r),[d,e,n]=_.default.hsl.rgb([l,s,h])||[0,0,0];return{valid:!0,value:r,keyword:_.default.hsl.keyword([l,s,h]),colorSpace:"hsl",rgb:`rgba(${d}, ${e}, ${n}, ${u})`,hsl:r,hex:`#${_.default.hsl.hex([l,s,h]).toLowerCase()}`}},er=r=>{let l=r.replace("#",""),s=_.default.keyword.rgb(l)||_.default.hex.rgb(l),h=_.default.rgb.hsl(s),u=r;/[^#a-f0-9]/i.test(r)?u=l:T.test(r)&&(u=`#${l}`);let d=!0;if(u.startsWith("#"))d=T.test(u);else try{_.default.keyword.hex(u)}catch{d=!1}return{valid:d,value:u,keyword:_.default.rgb.keyword(s),colorSpace:"hex",rgb:`rgba(${s[0]}, ${s[1]}, ${s[2]}, 1)`,hsl:`hsla(${h[0]}, ${h[1]}%, ${h[2]}%, 1)`,hex:u}},C=r=>{if(r)return Ae.test(r)?Qe(r):Ue.test(r)?Ze(r):er(r)},rr=(r,l,s)=>{if(!r||!l?.valid)return R[s];if(s!=="hex")return l?.[s]||R[s];if(!l.hex.startsWith("#"))try{return`#${_.default.keyword.hex(l.hex)}`}catch{return R.hex}let h=l.hex.match(Ye);if(!h)return T.test(l.hex)?l.hex:R.hex;let[u,d,e]=h[1].split("");return`#${u}${u}${d}${d}${e}${e}`},tr=(r,l)=>{let[s,h]=p.useState(r||""),[u,d]=p.useState(()=>C(s)),[e,n]=p.useState(u?.colorSpace||"hex");p.useEffect(()=>{let i=r||"",c=C(i);h(i),d(c),n(c?.colorSpace||"hex")},[r]);let t=p.useMemo(()=>rr(s,u,e).toLowerCase(),[s,u,e]),a=p.useCallback(i=>{let c=C(i),f=c?.value||i||"";h(f),f===""&&(d(void 0),l(void 0)),c&&(d(c),n(c.colorSpace),l(c.value))},[l]),o=p.useCallback(()=>{let i=(q.indexOf(e)+1)%q.length,c=q[i];n(c);let f=u?.[c]||"";h(f),l(f)},[u,e,l]);return{value:s,realValue:t,updateValue:a,color:u,colorSpace:e,cycleColorSpace:o}},H=r=>r.replace(/\s*/,"").toLowerCase(),nr=(r,l,s)=>{let[h,u]=p.useState(l?.valid?[l]:[]);p.useEffect(()=>{l===void 0&&u([])},[l]);let d=p.useMemo(()=>(r||[]).map(n=>typeof n=="string"?C(n):n.title?{...C(n.color),keyword:n.title}:C(n.color)).concat(h).filter(Boolean).slice(-27),[r,h]),e=p.useCallback(n=>{n?.valid&&(d.some(t=>t&&t[s]&&H(t[s]||"")===H(n[s]||""))||u(t=>t.concat(n)))},[s,d]);return{presets:d,addPreset:e}},ar=({name:r,value:l,onChange:s,onFocus:h,onBlur:u,presetColors:d,startOpen:e=!1,argType:n})=>{let t=p.useCallback(ce(s,200),[s]),{value:a,realValue:o,updateValue:i,color:c,colorSpace:f,cycleColorSpace:g}=tr(l,t),{presets:b,addPreset:y}=nr(d??[],c,f),m=Je[f],k=!!n?.table?.readonly;return v.createElement(Le,{"aria-readonly":k},v.createElement(Be,{startOpen:e,trigger:k?null:void 0,closeOnOutsideClick:!0,onVisibleChange:()=>c&&y(c),tooltip:v.createElement(Ke,null,v.createElement(m,{color:o==="transparent"?"#000000":o,onChange:i,onFocus:h,onBlur:u}),b.length>0&&v.createElement(Xe,null,b.map((x,N)=>v.createElement(U,{key:`${x?.value||N}-${N}`,hasChrome:!1,tooltip:v.createElement(Te,{note:x?.keyword||x?.value||""})},v.createElement(A,{value:x?.[f]||"",active:!!(c&&x&&x[f]&&H(x[f]||"")===H(c[f])),onClick:()=>x&&i(x.value||"")})))))},v.createElement(A,{value:o,style:{margin:4}})),v.createElement(Ge,{id:he(r),value:a,onChange:x=>i(x.target.value),onFocus:x=>x.target.select(),readOnly:k,placeholder:"Choose color..."}),a?v.createElement(Fe,{onClick:g}):null)},sr=ar;export{ar as ColorControl,sr as default};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import{j as n}from"./iframe-CQAwSt4E.js";import{useMDXComponents as h}from"./index-CgMRTj-o.js";import{b as c,M as o}from"./blocks-BuaOUtiH.js";import"./preload-helper-PPVm8Dsz.js";import"./index-DHiZ-gXR.js";function t(d){const e={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...h(),...d.components};return n.jsxs(n.Fragment,{children:[`
|
|
2
|
+
`,`
|
|
3
|
+
`,n.jsx(c,{title:"App Framework/Dark Mode"}),`
|
|
4
|
+
`,n.jsx(e.h1,{id:"dark-mode",children:"Dark Mode"}),`
|
|
5
|
+
`,n.jsx(e.p,{children:"Dark Mode config cho phép bạn cấu hình dark mode mặc định cho ứng dụng."}),`
|
|
6
|
+
`,n.jsx(e.h2,{id:"cấu-trúc",children:"Cấu trúc"}),`
|
|
7
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-typescript",children:`type IDarkModeConfig = {
|
|
8
|
+
defaultEnabled?: boolean
|
|
9
|
+
}
|
|
10
|
+
`})}),`
|
|
11
|
+
`,n.jsx(e.h2,{id:"thuộc-tính",children:"Thuộc tính"}),`
|
|
12
|
+
`,n.jsx(o,{children:"\n| Thuộc tính | Kiểu dữ liệu | Mặc định | Mô tả |\n| :--- | :--- | :--- | :--- |\n| `defaultEnabled` | `boolean` | `false` | Bật dark mode mặc định khi khởi động ứng dụng |\n"}),`
|
|
13
|
+
`,n.jsx(e.h2,{id:"cách-hoạt-động",children:"Cách hoạt động"}),`
|
|
14
|
+
`,n.jsxs(e.p,{children:["Khi ",n.jsx(e.code,{children:"defaultEnabled: true"}),", ứng dụng sẽ tự động set ",n.jsx(e.code,{children:'data-theme="dark"'})," trên ",n.jsx(e.code,{children:"document.documentElement"})," khi khởi động, áp dụng dark mode cho toàn bộ ứng dụng."]}),`
|
|
15
|
+
`,n.jsx(e.h2,{id:"cấu-hình",children:"Cấu hình"}),`
|
|
16
|
+
`,n.jsx(e.h3,{id:"app-level-config",children:"App-level Config"}),`
|
|
17
|
+
`,n.jsx(e.p,{children:"Cấu hình dark mode mặc định:"}),`
|
|
18
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-tsx",children:`const appConfig: IAppConfig = {
|
|
19
|
+
darkMode: {
|
|
20
|
+
defaultEnabled: true, // Bật dark mode mặc định
|
|
21
|
+
},
|
|
22
|
+
pages: [
|
|
23
|
+
// Tất cả pages sẽ hiển thị dark mode
|
|
24
|
+
],
|
|
25
|
+
}
|
|
26
|
+
`})}),`
|
|
27
|
+
`,n.jsx(e.h3,{id:"ví-dụ",children:"Ví dụ"}),`
|
|
28
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-tsx",children:`const appConfig: IAppConfig = {
|
|
29
|
+
// Bật dark mode mặc định
|
|
30
|
+
darkMode: {
|
|
31
|
+
defaultEnabled: true,
|
|
32
|
+
},
|
|
33
|
+
pages: [
|
|
34
|
+
{
|
|
35
|
+
pathname: '/home',
|
|
36
|
+
Component: HomePage,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
pathname: '/settings',
|
|
40
|
+
Component: SettingsPage,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
}
|
|
44
|
+
`})}),`
|
|
45
|
+
`,n.jsx(e.h2,{id:"lưu-ý",children:"Lưu ý"}),`
|
|
46
|
+
`,n.jsxs(e.ul,{children:[`
|
|
47
|
+
`,n.jsxs(e.li,{children:["Dark mode config chỉ có ở ",n.jsx(e.strong,{children:"app-level"}),", không có ở page-level"]}),`
|
|
48
|
+
`,n.jsxs(e.li,{children:["Khi ",n.jsx(e.code,{children:"defaultEnabled: true"}),", dark mode sẽ được áp dụng ngay khi ứng dụng khởi động"]}),`
|
|
49
|
+
`,n.jsxs(e.li,{children:["Dark mode sử dụng CSS variables và ",n.jsx(e.code,{children:"data-theme"})," attribute để thay đổi theme"]}),`
|
|
50
|
+
`,n.jsxs(e.li,{children:["Bạn có thể toggle dark mode động bằng cách thay đổi ",n.jsx(e.code,{children:"data-theme"})," attribute trên ",n.jsx(e.code,{children:"document.documentElement"}),":",`
|
|
51
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-tsx",children:`// Toggle dark mode
|
|
52
|
+
document.documentElement.setAttribute('data-theme', 'dark')
|
|
53
|
+
// hoặc
|
|
54
|
+
document.documentElement.setAttribute('data-theme', 'light')
|
|
55
|
+
`})}),`
|
|
56
|
+
`]}),`
|
|
57
|
+
`]})]})}function m(d={}){const{wrapper:e}={...h(),...d.components};return e?n.jsx(e,{...d,children:n.jsx(t,{...d})}):t(d)}export{m as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./index-CgMRTj-o.js","./iframe-CQAwSt4E.js","./preload-helper-PPVm8Dsz.js","./iframe-yMKl6hJA.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{_ as i}from"./preload-helper-PPVm8Dsz.js";import{e as t,r as p}from"./iframe-CQAwSt4E.js";import{renderElement as l,unmountElement as u}from"./react-18-CNyWQ7je.js";import{H as d,A as h,C as E,D as x}from"./blocks-BuaOUtiH.js";import"./index-DHiZ-gXR.js";var D={code:E,a:h,...d},_=class extends p.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e){let{showException:r}=this.props;r(e)}render(){let{hasError:e}=this.state,{children:r}=this.props;return e?null:t.createElement(t.Fragment,null,r)}},y=class{constructor(){this.render=async(e,r,n)=>{let s={...D,...r?.components},a=x;return new Promise((m,c)=>{i(async()=>{const{MDXProvider:o}=await import("./index-CgMRTj-o.js");return{MDXProvider:o}},__vite__mapDeps([0,1,2,3]),import.meta.url).then(({MDXProvider:o})=>l(t.createElement(_,{showException:c,key:Math.random()},t.createElement(o,{components:s},t.createElement(a,{context:e,docsParameter:r}))),n)).then(()=>m())})},this.unmount=e=>{u(e)}}};export{y as DocsRenderer,D as defaultComponents};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import{j as n}from"./iframe-CQAwSt4E.js";import{useMDXComponents as c}from"./index-CgMRTj-o.js";import{b as a}from"./blocks-BuaOUtiH.js";import"./preload-helper-PPVm8Dsz.js";import"./index-DHiZ-gXR.js";function t(e){const i={code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...c(),...e.components};return n.jsxs(n.Fragment,{children:[`
|
|
2
|
+
`,`
|
|
3
|
+
`,n.jsx(a,{title:"Getting Started",parameters:{options:{nav:{icon:""}}}}),`
|
|
4
|
+
`,n.jsx(i.h1,{id:"getting-started-với-v-miniappui-react",children:"Getting Started với @v-miniapp/ui-react"}),`
|
|
5
|
+
`,n.jsxs(i.p,{children:[n.jsx(i.strong,{children:"@v-miniapp/ui-react"})," là bộ thư viện component React mạnh mẽ được thiết kế đặc biệt cho việc phát triển V-MiniApp."]}),`
|
|
6
|
+
`,n.jsx(i.h2,{id:"cài-đặt",children:"Cài đặt"}),`
|
|
7
|
+
`,n.jsx(i.pre,{children:n.jsx(i.code,{className:"language-bash",children:`npm install @v-miniapp/ui-react
|
|
8
|
+
# hoặc
|
|
9
|
+
pnpm add @v-miniapp/ui-react
|
|
10
|
+
# hoặc
|
|
11
|
+
yarn add @v-miniapp/ui-react
|
|
12
|
+
`})}),`
|
|
13
|
+
`,n.jsx(i.h2,{id:"import-styles",children:"Import Styles"}),`
|
|
14
|
+
`,n.jsx(i.h3,{id:"option-1-sử-dụng-css-chuẩn",children:"Option 1: Sử dụng CSS chuẩn"}),`
|
|
15
|
+
`,n.jsx(i.p,{children:"Đảm bảo bạn import CSS từ phía component để UI hoạt động tốt nhất:"}),`
|
|
16
|
+
`,n.jsx(i.pre,{children:n.jsx(i.code,{className:"language-tsx",children:`import '@v-miniapp/ui-react/styles.css'
|
|
17
|
+
`})}),`
|
|
18
|
+
`,n.jsx(i.h3,{id:"option-2-tích-hợp-với-tailwind-css",children:"Option 2: Tích hợp với Tailwind CSS"}),`
|
|
19
|
+
`,n.jsx(i.p,{children:"Nếu mini app của bạn đang sử dụng Tailwind CSS, bạn có thể tích hợp dễ dàng bằng cách thêm một dòng import vào file Tailwind config:"}),`
|
|
20
|
+
`,n.jsx(i.pre,{children:n.jsx(i.code,{className:"language-css",children:`/* tailwind.css hoặc file CSS chính của bạn */
|
|
21
|
+
@import '@v-miniapp/ui-react/tailwind';
|
|
22
|
+
`})}),`
|
|
23
|
+
`,n.jsxs(i.p,{children:[n.jsx(i.strong,{children:"Lưu ý:"})," Khi tích hợp với Tailwind, bạn không cần import ",n.jsx(i.code,{children:"@v-miniapp/ui-react/styles.css"})," nữa."]}),`
|
|
24
|
+
`,n.jsx(i.h2,{id:"ví-dụ-bắt-đầu-sử-dụng",children:"Ví dụ bắt đầu sử dụng"}),`
|
|
25
|
+
`,n.jsx(i.pre,{children:n.jsx(i.code,{className:"language-tsx",children:`import { App, type IAppConfig } from '@v-miniapp/ui-react'
|
|
26
|
+
|
|
27
|
+
// Tạo các page components
|
|
28
|
+
const HomePage = () => {
|
|
29
|
+
return <div>Trang chủ</div>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const SettingsPage = () => {
|
|
33
|
+
return <div>Cài đặt</div>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const appConfig: IAppConfig = {
|
|
37
|
+
// Animation giữa các pages: 'none', 'slide_up', 'slide_left', 'fade_in'
|
|
38
|
+
animation: {
|
|
39
|
+
type: 'slide_left',
|
|
40
|
+
},
|
|
41
|
+
// Keep-alive: giữ state của pages khi navigate
|
|
42
|
+
keepAlive: {
|
|
43
|
+
enable: true,
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
pages: [
|
|
47
|
+
{
|
|
48
|
+
pathname: '/home',
|
|
49
|
+
Component: HomePage,
|
|
50
|
+
navigationBar: {
|
|
51
|
+
title: 'Trang chủ',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
pathname: '/settings',
|
|
56
|
+
Component: SettingsPage,
|
|
57
|
+
navigationBar: {
|
|
58
|
+
title: 'Cài đặt',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const MiniApp: FC = () => {
|
|
65
|
+
return <App config={appConfig} />
|
|
66
|
+
}
|
|
67
|
+
`})}),`
|
|
68
|
+
`,n.jsx(i.h2,{id:"️-lưu-ý-quan-trọng",children:"⚠️ Lưu ý quan trọng"}),`
|
|
69
|
+
`,n.jsxs(i.p,{children:["Khi sử dụng component ",n.jsx(i.code,{children:"App"})," từ ",n.jsx(i.code,{children:"@v-miniapp/ui-react"}),", bạn đã có sẵn ",n.jsx(i.code,{children:"NavigationBar"})," component được quản lý bởi SDK. Nếu bạn cấu hình ",n.jsx(i.code,{children:"window"})," trong ",n.jsx(i.code,{children:"app-config.json"})," để hiển thị title bar/navigation bar từ native, sẽ có thể bị trùng lặp với component của ",n.jsx(i.code,{children:"ui-react"}),"."]}),`
|
|
70
|
+
`,n.jsxs(i.p,{children:[n.jsx(i.strong,{children:"Giải pháp:"})," Nếu bạn sử dụng ",n.jsx(i.code,{children:"NavigationBar"})," từ ",n.jsx(i.code,{children:"@v-miniapp/ui-react"}),", bạn nên cấu hình trong ",n.jsx(i.code,{children:"app-config.json"})," để ẩn native title bar:"]}),`
|
|
71
|
+
`,n.jsx(i.pre,{children:n.jsx(i.code,{className:"language-json",children:`{
|
|
72
|
+
"window": {
|
|
73
|
+
"defaultTitle": "",
|
|
74
|
+
"transparentTitle": "always"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`})})]})}function h(e={}){const{wrapper:i}={...c(),...e.components};return i?n.jsx(i,{...e,children:n.jsx(t,{...e})}):t(e)}export{h as default};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import{j as n}from"./iframe-CQAwSt4E.js";import{useMDXComponents as i}from"./index-CgMRTj-o.js";import{b as o}from"./blocks-BuaOUtiH.js";import"./preload-helper-PPVm8Dsz.js";import"./index-DHiZ-gXR.js";function s(t){const e={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...i(),...t.components};return n.jsxs(n.Fragment,{children:[`
|
|
2
|
+
`,`
|
|
3
|
+
`,n.jsx(o,{title:"Use Cases/Infinite Scroll"}),`
|
|
4
|
+
`,n.jsx(e.h1,{id:"infinite-scroll--load-more",children:"Infinite Scroll / Load More"}),`
|
|
5
|
+
`,n.jsx(e.p,{children:"Infinite scroll cho phép tự động load thêm data khi user scroll đến cuối danh sách."}),`
|
|
6
|
+
`,n.jsx(e.h2,{id:"cách-sử-dụng",children:"Cách sử dụng"}),`
|
|
7
|
+
`,n.jsxs(e.h3,{id:"sử-dụng-hook-useloadmore",children:["Sử dụng Hook ",n.jsx(e.code,{children:"useLoadMore"})]}),`
|
|
8
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-tsx",children:`import { useLoadMore } from '@v-miniapp/ui-react'
|
|
9
|
+
import { useState } from 'react'
|
|
10
|
+
|
|
11
|
+
const ListPage: FC = () => {
|
|
12
|
+
const [items, setItems] = useState([...initialItems])
|
|
13
|
+
const [loading, setLoading] = useState(false)
|
|
14
|
+
const [hasMore, setHasMore] = useState(true)
|
|
15
|
+
|
|
16
|
+
const loadMore = async () => {
|
|
17
|
+
if (loading || !hasMore) return
|
|
18
|
+
|
|
19
|
+
setLoading(true)
|
|
20
|
+
try {
|
|
21
|
+
const newItems = await fetchMoreItems()
|
|
22
|
+
if (newItems.length === 0) {
|
|
23
|
+
setHasMore(false)
|
|
24
|
+
} else {
|
|
25
|
+
setItems([...items, ...newItems])
|
|
26
|
+
}
|
|
27
|
+
} finally {
|
|
28
|
+
setLoading(false)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
useLoadMore(loadMore)
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div>
|
|
36
|
+
{items.map(item => (
|
|
37
|
+
<Item key={item.id} data={item} />
|
|
38
|
+
))}
|
|
39
|
+
{loading && <LoadingSpinner />}
|
|
40
|
+
{!hasMore && <div>Đã hết dữ liệu</div>}
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
`})}),`
|
|
45
|
+
`,n.jsx(e.h3,{id:"sử-dụng-page-layout-config",children:"Sử dụng Page Layout Config"}),`
|
|
46
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-tsx",children:`const appConfig: IAppConfig = {
|
|
47
|
+
pages: [
|
|
48
|
+
{
|
|
49
|
+
pathname: '/list',
|
|
50
|
+
Component: ListPage,
|
|
51
|
+
pageLayout: {
|
|
52
|
+
onEndReached: async () => {
|
|
53
|
+
await loadMore()
|
|
54
|
+
},
|
|
55
|
+
onEndReachedThreshold: 100, // Trigger khi còn 100px từ bottom
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
}
|
|
60
|
+
`})}),`
|
|
61
|
+
`,n.jsx(e.h2,{id:"cách-hoạt-động",children:"Cách hoạt động"}),`
|
|
62
|
+
`,n.jsxs(e.ul,{children:[`
|
|
63
|
+
`,n.jsxs(e.li,{children:["Sử dụng ",n.jsx(e.code,{children:"VisibilitySensor"})," để detect khi scroll đến cuối page"]}),`
|
|
64
|
+
`,n.jsxs(e.li,{children:["Tự động trigger ",n.jsx(e.code,{children:"onEndReached"})," khi sensor trở nên visible"]}),`
|
|
65
|
+
`,n.jsxs(e.li,{children:[n.jsx(e.code,{children:"onEndReachedThreshold"})," xác định khoảng cách từ bottom để trigger (mặc định: 50px)"]}),`
|
|
66
|
+
`]}),`
|
|
67
|
+
`,n.jsx(e.h2,{id:"lưu-ý",children:"Lưu ý"}),`
|
|
68
|
+
`,n.jsxs(e.ul,{children:[`
|
|
69
|
+
`,n.jsxs(e.li,{children:[n.jsx(e.code,{children:"onEndReached"})," có thể được gọi nhiều lần, nên cần implement debounce/throttle hoặc flag để tránh duplicate requests"]}),`
|
|
70
|
+
`,n.jsx(e.li,{children:"Nên hiển thị loading indicator khi đang fetch data"}),`
|
|
71
|
+
`,n.jsxs(e.li,{children:["Nên check ",n.jsx(e.code,{children:"hasMore"})," để tránh fetch khi đã hết data"]}),`
|
|
72
|
+
`]}),`
|
|
73
|
+
`,n.jsx(e.h2,{id:"kết-hợp-với-pull-to-refresh",children:"Kết hợp với Pull to Refresh"}),`
|
|
74
|
+
`,n.jsx(e.p,{children:"Bạn có thể kết hợp cả pull-to-refresh và load more trong cùng một page:"}),`
|
|
75
|
+
`,n.jsx(e.pre,{children:n.jsx(e.code,{className:"language-tsx",children:`import { usePullToRefresh, useLoadMore } from '@v-miniapp/ui-react'
|
|
76
|
+
import { useState } from 'react'
|
|
77
|
+
|
|
78
|
+
const ListPage: FC = () => {
|
|
79
|
+
const [items, setItems] = useState([...initialItems])
|
|
80
|
+
const [loading, setLoading] = useState(false)
|
|
81
|
+
|
|
82
|
+
// Pull to refresh
|
|
83
|
+
const handleRefresh = async () => {
|
|
84
|
+
const newItems = await fetchInitialItems()
|
|
85
|
+
setItems(newItems)
|
|
86
|
+
}
|
|
87
|
+
usePullToRefresh(handleRefresh)
|
|
88
|
+
|
|
89
|
+
// Load more
|
|
90
|
+
const loadMore = async () => {
|
|
91
|
+
if (loading) return
|
|
92
|
+
setLoading(true)
|
|
93
|
+
try {
|
|
94
|
+
const newItems = await fetchMoreItems()
|
|
95
|
+
setItems([...items, ...newItems])
|
|
96
|
+
} finally {
|
|
97
|
+
setLoading(false)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
useLoadMore(loadMore)
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div>
|
|
104
|
+
{items.map(item => (
|
|
105
|
+
<Item key={item.id} data={item} />
|
|
106
|
+
))}
|
|
107
|
+
{loading && <LoadingSpinner />}
|
|
108
|
+
</div>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
`})})]})}function h(t={}){const{wrapper:e}={...i(),...t.components};return e?n.jsx(e,{...t,children:n.jsx(s,{...t})}):s(t)}export{h as default};
|