gladvn 0.2.17 → 0.2.19
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/bin/cli.js +9 -6
- package/dist/components/macro/accordion-preset.d.ts.map +1 -1
- package/dist/components/macro/alert-dialog-preset.d.ts.map +1 -1
- package/dist/components/macro/alert-preset.d.ts.map +1 -1
- package/dist/components/macro/avatar-preset.d.ts.map +1 -1
- package/dist/components/macro/breadcrumb-preset.d.ts.map +1 -1
- package/dist/components/macro/card-preset.d.ts.map +1 -1
- package/dist/components/macro/carousel-preset.d.ts.map +1 -1
- package/dist/components/macro/checkbox-preset.d.ts.map +1 -1
- package/dist/components/macro/combobox-preset.d.ts.map +1 -1
- package/dist/components/macro/command-preset.d.ts +1 -1
- package/dist/components/macro/command-preset.d.ts.map +1 -1
- package/dist/components/macro/date-picker.d.ts.map +1 -1
- package/dist/components/macro/dialog-preset.d.ts.map +1 -1
- package/dist/components/macro/empty-preset.d.ts.map +1 -1
- package/dist/components/macro/field-preset.d.ts.map +1 -1
- package/dist/components/macro/input-otp-preset.d.ts +6 -0
- package/dist/components/macro/input-otp-preset.d.ts.map +1 -1
- package/dist/components/macro/input-preset.d.ts +1 -1
- package/dist/components/macro/input-preset.d.ts.map +1 -1
- package/dist/components/macro/pagination-preset.d.ts.map +1 -1
- package/dist/components/macro/progress-preset.d.ts.map +1 -1
- package/dist/components/macro/radio-group-preset.d.ts.map +1 -1
- package/dist/components/macro/select-preset.d.ts.map +1 -1
- package/dist/components/macro/slider-preset.d.ts.map +1 -1
- package/dist/components/macro/switch-preset.d.ts.map +1 -1
- package/dist/components/macro/tabs-preset.d.ts +1 -1
- package/dist/components/macro/tabs-preset.d.ts.map +1 -1
- package/dist/components/macro/textarea-preset.d.ts +1 -1
- package/dist/components/macro/textarea-preset.d.ts.map +1 -1
- package/dist/components/micro/accordion.d.ts +7 -0
- package/dist/components/micro/accordion.d.ts.map +1 -1
- package/dist/components/micro/alert-dialog.d.ts.map +1 -1
- package/dist/components/micro/alert.d.ts +7 -0
- package/dist/components/micro/alert.d.ts.map +1 -1
- package/dist/components/micro/aspect-ratio.d.ts +7 -0
- package/dist/components/micro/aspect-ratio.d.ts.map +1 -1
- package/dist/components/micro/avatar.d.ts.map +1 -1
- package/dist/components/micro/badge.d.ts +8 -1
- package/dist/components/micro/badge.d.ts.map +1 -1
- package/dist/components/micro/breadcrumb.d.ts +7 -0
- package/dist/components/micro/breadcrumb.d.ts.map +1 -1
- package/dist/components/micro/button.d.ts +8 -1
- package/dist/components/micro/button.d.ts.map +1 -1
- package/dist/components/micro/calendar.d.ts +2 -2
- package/dist/components/micro/calendar.d.ts.map +1 -1
- package/dist/components/micro/carousel.d.ts.map +1 -1
- package/dist/components/micro/chart.d.ts.map +1 -1
- package/dist/components/micro/checkbox.d.ts.map +1 -1
- package/dist/components/micro/collapsible.d.ts.map +1 -1
- package/dist/components/micro/combobox.d.ts.map +1 -1
- package/dist/components/micro/command.d.ts.map +1 -1
- package/dist/components/micro/context-menu.d.ts.map +1 -1
- package/dist/components/micro/dialog.d.ts.map +1 -1
- package/dist/components/micro/drawer.d.ts.map +1 -1
- package/dist/components/micro/dropdown-menu.d.ts.map +1 -1
- package/dist/components/micro/empty.d.ts +7 -0
- package/dist/components/micro/empty.d.ts.map +1 -1
- package/dist/components/micro/field.d.ts.map +1 -1
- package/dist/components/micro/hover-card.d.ts +1 -1
- package/dist/components/micro/hover-card.d.ts.map +1 -1
- package/dist/components/micro/input-group.d.ts.map +1 -1
- package/dist/components/micro/input-otp.d.ts.map +1 -1
- package/dist/components/micro/input.d.ts +7 -0
- package/dist/components/micro/input.d.ts.map +1 -1
- package/dist/components/micro/item.d.ts.map +1 -1
- package/dist/components/micro/label.d.ts.map +1 -1
- package/dist/components/micro/menubar.d.ts.map +1 -1
- package/dist/components/micro/navigation-menu.d.ts +8 -1
- package/dist/components/micro/navigation-menu.d.ts.map +1 -1
- package/dist/components/micro/pagination.d.ts.map +1 -1
- package/dist/components/micro/popover.d.ts.map +1 -1
- package/dist/components/micro/progress.d.ts.map +1 -1
- package/dist/components/micro/radio-group.d.ts.map +1 -1
- package/dist/components/micro/select.d.ts +1 -1
- package/dist/components/micro/select.d.ts.map +1 -1
- package/dist/components/micro/sheet.d.ts.map +1 -1
- package/dist/components/micro/sidebar.d.ts.map +1 -1
- package/dist/components/micro/skeleton.d.ts +7 -0
- package/dist/components/micro/skeleton.d.ts.map +1 -1
- package/dist/components/micro/slider.d.ts +7 -0
- package/dist/components/micro/slider.d.ts.map +1 -1
- package/dist/components/micro/sonner.d.ts.map +1 -1
- package/dist/components/micro/spinner.d.ts.map +1 -1
- package/dist/components/micro/switch.d.ts.map +1 -1
- package/dist/components/micro/table.d.ts.map +1 -1
- package/dist/components/micro/tabs.d.ts +1 -1
- package/dist/components/micro/tabs.d.ts.map +1 -1
- package/dist/components/micro/textarea.d.ts +7 -0
- package/dist/components/micro/textarea.d.ts.map +1 -1
- package/dist/components/micro/toggle-group.d.ts.map +1 -1
- package/dist/components/micro/toggle.d.ts.map +1 -1
- package/dist/components/micro/tooltip.d.ts +1 -1
- package/dist/components/micro/tooltip.d.ts.map +1 -1
- package/dist/dev/App.d.ts.map +1 -1
- package/dist/dev/components/code-highlighter.d.ts.map +1 -1
- package/dist/dev/components/dev-context.d.ts.map +1 -1
- package/dist/dev/components/showcase.d.ts +1 -1
- package/dist/dev/components/showcase.d.ts.map +1 -1
- package/dist/dev/data.d.ts.map +1 -1
- package/dist/dev/main.d.ts.map +1 -1
- package/dist/dev/sections/buttons.d.ts.map +1 -1
- package/dist/dev/sections/feedback.d.ts.map +1 -1
- package/dist/dev/sections/overview.d.ts.map +1 -1
- package/dist/dev/showcase/accordion.d.ts.map +1 -1
- package/dist/dev/showcase/alert-dialog.d.ts.map +1 -1
- package/dist/dev/showcase/alert.d.ts.map +1 -1
- package/dist/dev/showcase/aspect-ratio.d.ts.map +1 -1
- package/dist/dev/showcase/avatar.d.ts.map +1 -1
- package/dist/dev/showcase/breadcrumb.d.ts.map +1 -1
- package/dist/dev/showcase/button.d.ts.map +1 -1
- package/dist/dev/showcase/calendar.d.ts.map +1 -1
- package/dist/dev/showcase/card.d.ts.map +1 -1
- package/dist/dev/showcase/carousel.d.ts.map +1 -1
- package/dist/dev/showcase/chart.d.ts.map +1 -1
- package/dist/dev/showcase/checkbox.d.ts.map +1 -1
- package/dist/dev/showcase/collapsible.d.ts.map +1 -1
- package/dist/dev/showcase/combobox.d.ts.map +1 -1
- package/dist/dev/showcase/command.d.ts.map +1 -1
- package/dist/dev/showcase/context-menu.d.ts.map +1 -1
- package/dist/dev/showcase/dialog.d.ts.map +1 -1
- package/dist/dev/showcase/drawer.d.ts.map +1 -1
- package/dist/dev/showcase/dropdown-menu.d.ts.map +1 -1
- package/dist/dev/showcase/empty.d.ts.map +1 -1
- package/dist/dev/showcase/hover-card.d.ts.map +1 -1
- package/dist/dev/showcase/input-group.d.ts.map +1 -1
- package/dist/dev/showcase/input-otp.d.ts.map +1 -1
- package/dist/dev/showcase/input.d.ts.map +1 -1
- package/dist/dev/showcase/item.d.ts.map +1 -1
- package/dist/dev/showcase/kbd.d.ts.map +1 -1
- package/dist/dev/showcase/label.d.ts.map +1 -1
- package/dist/dev/showcase/menubar.d.ts.map +1 -1
- package/dist/dev/showcase/navigation-menu.d.ts.map +1 -1
- package/dist/dev/showcase/overview.d.ts.map +1 -1
- package/dist/dev/showcase/pagination.d.ts.map +1 -1
- package/dist/dev/showcase/popover.d.ts.map +1 -1
- package/dist/dev/showcase/progress.d.ts.map +1 -1
- package/dist/dev/showcase/radio-group.d.ts.map +1 -1
- package/dist/dev/showcase/resizable.d.ts.map +1 -1
- package/dist/dev/showcase/scroll-area.d.ts.map +1 -1
- package/dist/dev/showcase/select.d.ts.map +1 -1
- package/dist/dev/showcase/separator.d.ts.map +1 -1
- package/dist/dev/showcase/sheet.d.ts.map +1 -1
- package/dist/dev/showcase/sidebar.d.ts.map +1 -1
- package/dist/dev/showcase/skeleton.d.ts.map +1 -1
- package/dist/dev/showcase/slider.d.ts.map +1 -1
- package/dist/dev/showcase/sonner.d.ts.map +1 -1
- package/dist/dev/showcase/spinner.d.ts.map +1 -1
- package/dist/dev/showcase/switch.d.ts.map +1 -1
- package/dist/dev/showcase/table.d.ts.map +1 -1
- package/dist/dev/showcase/tabs.d.ts.map +1 -1
- package/dist/dev/showcase/textarea.d.ts.map +1 -1
- package/dist/dev/showcase/theme-provider.d.ts.map +1 -1
- package/dist/dev/showcase/toast.d.ts.map +1 -1
- package/dist/dev/showcase/toggle-group.d.ts.map +1 -1
- package/dist/dev/showcase/toggle.d.ts.map +1 -1
- package/dist/dev/showcase/tooltip.d.ts.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/package.json +3 -1
- package/scripts/format-codestrings.ts +87 -0
- package/scripts/organize-imports.ts +21 -0
- package/scripts/regex-format.cjs +67 -0
- package/scripts/tmp.tsx +25 -0
- package/src/components/macro/accordion-preset.test.tsx +1 -0
- package/src/components/macro/accordion-preset.tsx +2 -1
- package/src/components/macro/alert-dialog-preset.tsx +44 -43
- package/src/components/macro/alert-preset.tsx +7 -3
- package/src/components/macro/avatar-preset.tsx +2 -1
- package/src/components/macro/breadcrumb-preset.tsx +2 -1
- package/src/components/macro/card-preset.tsx +2 -1
- package/src/components/macro/carousel-preset.tsx +5 -2
- package/src/components/macro/checkbox-preset.test.tsx +1 -0
- package/src/components/macro/checkbox-preset.tsx +6 -2
- package/src/components/macro/combobox-preset.tsx +6 -3
- package/src/components/macro/command-preset.tsx +7 -3
- package/src/components/macro/date-picker.tsx +77 -59
- package/src/components/macro/dialog-preset.tsx +42 -38
- package/src/components/macro/empty-preset.tsx +2 -1
- package/src/components/macro/field-preset.test.tsx +1 -0
- package/src/components/macro/field-preset.tsx +2 -1
- package/src/components/macro/input-otp-preset.tsx +6 -2
- package/src/components/macro/input-preset.test.tsx +1 -0
- package/src/components/macro/input-preset.tsx +4 -2
- package/src/components/macro/pagination-preset.tsx +3 -1
- package/src/components/macro/progress-preset.test.tsx +1 -0
- package/src/components/macro/progress-preset.tsx +2 -1
- package/src/components/macro/radio-group-preset.tsx +4 -1
- package/src/components/macro/select-preset.tsx +35 -30
- package/src/components/macro/slider-preset.test.tsx +1 -0
- package/src/components/macro/slider-preset.tsx +4 -1
- package/src/components/macro/switch-preset.test.tsx +1 -0
- package/src/components/macro/switch-preset.tsx +4 -1
- package/src/components/macro/tabs-preset.test.tsx +1 -0
- package/src/components/macro/tabs-preset.tsx +4 -2
- package/src/components/macro/textarea-preset.test.tsx +1 -0
- package/src/components/macro/textarea-preset.tsx +4 -1
- package/src/components/micro/accordion.tsx +3 -2
- package/src/components/micro/alert-dialog.tsx +2 -1
- package/src/components/micro/alert.tsx +3 -2
- package/src/components/micro/aspect-ratio.tsx +2 -1
- package/src/components/micro/avatar.tsx +2 -1
- package/src/components/micro/badge.tsx +3 -3
- package/src/components/micro/breadcrumb.tsx +3 -2
- package/src/components/micro/button.test.tsx +1 -0
- package/src/components/micro/button.tsx +3 -3
- package/src/components/micro/calendar.tsx +10 -9
- package/src/components/micro/carousel.tsx +3 -2
- package/src/components/micro/chart.tsx +1 -0
- package/src/components/micro/checkbox.tsx +2 -2
- package/src/components/micro/collapsible.tsx +4 -2
- package/src/components/micro/combobox.tsx +41 -29
- package/src/components/micro/command.tsx +23 -16
- package/src/components/micro/context-menu.tsx +3 -2
- package/src/components/micro/dialog.tsx +2 -1
- package/src/components/micro/drawer.tsx +2 -1
- package/src/components/micro/dropdown-menu.tsx +3 -2
- package/src/components/micro/empty.tsx +2 -1
- package/src/components/micro/field.tsx +4 -3
- package/src/components/micro/hover-card.tsx +20 -19
- package/src/components/micro/input-group.tsx +2 -1
- package/src/components/micro/input-otp.tsx +3 -2
- package/src/components/micro/input.tsx +3 -2
- package/src/components/micro/item.tsx +1 -0
- package/src/components/micro/label.tsx +2 -1
- package/src/components/micro/menubar.tsx +2 -1
- package/src/components/micro/navigation-menu.tsx +18 -17
- package/src/components/micro/pagination.tsx +2 -1
- package/src/components/micro/popover.tsx +2 -1
- package/src/components/micro/progress.tsx +2 -1
- package/src/components/micro/radio-group.tsx +3 -3
- package/src/components/micro/select.tsx +5 -4
- package/src/components/micro/sheet.tsx +2 -1
- package/src/components/micro/sidebar.tsx +4 -1
- package/src/components/micro/skeleton.tsx +2 -1
- package/src/components/micro/slider.tsx +4 -1
- package/src/components/micro/sonner.tsx +2 -1
- package/src/components/micro/spinner.tsx +1 -2
- package/src/components/micro/switch.tsx +2 -2
- package/src/components/micro/table.tsx +2 -1
- package/src/components/micro/tabs.tsx +4 -3
- package/src/components/micro/textarea.tsx +2 -1
- package/src/components/micro/toggle-group.tsx +1 -0
- package/src/components/micro/toggle.tsx +1 -3
- package/src/components/micro/tooltip.tsx +9 -3
- package/src/dev/App.tsx +66 -41
- package/src/dev/components/code-highlighter.tsx +2 -1
- package/src/dev/components/dev-context.tsx +1 -0
- package/src/dev/components/showcase.tsx +13 -14
- package/src/dev/data.ts +206 -52
- package/src/dev/main.tsx +4 -4
- package/src/dev/sections/buttons.tsx +14 -12
- package/src/dev/sections/feedback.tsx +7 -2
- package/src/dev/sections/forms.tsx +11 -11
- package/src/dev/sections/overview.tsx +2 -1
- package/src/dev/showcase/accordion.tsx +399 -314
- package/src/dev/showcase/alert-dialog.tsx +387 -384
- package/src/dev/showcase/alert.tsx +271 -258
- package/src/dev/showcase/aspect-ratio.tsx +102 -105
- package/src/dev/showcase/avatar.tsx +216 -145
- package/src/dev/showcase/badge.tsx +78 -50
- package/src/dev/showcase/breadcrumb.tsx +88 -85
- package/src/dev/showcase/button.tsx +72 -96
- package/src/dev/showcase/calendar.tsx +41 -39
- package/src/dev/showcase/card.tsx +170 -148
- package/src/dev/showcase/carousel.tsx +239 -77
- package/src/dev/showcase/chart.tsx +5 -4
- package/src/dev/showcase/checkbox.tsx +206 -140
- package/src/dev/showcase/collapsible.tsx +108 -84
- package/src/dev/showcase/combobox.tsx +272 -199
- package/src/dev/showcase/command.tsx +31 -28
- package/src/dev/showcase/context-menu.tsx +94 -77
- package/src/dev/showcase/dialog.tsx +445 -424
- package/src/dev/showcase/drawer.tsx +142 -135
- package/src/dev/showcase/dropdown-menu.tsx +165 -161
- package/src/dev/showcase/empty.tsx +173 -158
- package/src/dev/showcase/hover-card.tsx +92 -52
- package/src/dev/showcase/input-group.tsx +193 -160
- package/src/dev/showcase/input-otp.tsx +109 -99
- package/src/dev/showcase/input.tsx +78 -42
- package/src/dev/showcase/item.tsx +101 -98
- package/src/dev/showcase/kbd.tsx +78 -62
- package/src/dev/showcase/label.tsx +16 -23
- package/src/dev/showcase/menubar.tsx +274 -251
- package/src/dev/showcase/navigation-menu.tsx +175 -170
- package/src/dev/showcase/overview.tsx +164 -148
- package/src/dev/showcase/pagination.tsx +101 -69
- package/src/dev/showcase/popover.tsx +113 -86
- package/src/dev/showcase/progress.tsx +99 -69
- package/src/dev/showcase/radio-group.tsx +217 -134
- package/src/dev/showcase/resizable.tsx +65 -55
- package/src/dev/showcase/scroll-area.tsx +32 -22
- package/src/dev/showcase/select.tsx +192 -136
- package/src/dev/showcase/separator.tsx +28 -24
- package/src/dev/showcase/sheet.tsx +182 -134
- package/src/dev/showcase/sidebar.tsx +9 -5
- package/src/dev/showcase/skeleton.tsx +54 -59
- package/src/dev/showcase/slider.tsx +158 -129
- package/src/dev/showcase/sonner.tsx +3 -5
- package/src/dev/showcase/spinner.tsx +22 -18
- package/src/dev/showcase/switch.tsx +207 -110
- package/src/dev/showcase/table.tsx +44 -32
- package/src/dev/showcase/tabs.tsx +272 -267
- package/src/dev/showcase/textarea.tsx +162 -116
- package/src/dev/showcase/theme-provider.tsx +596 -534
- package/src/dev/showcase/toast.tsx +37 -38
- package/src/dev/showcase/toggle-group.tsx +87 -39
- package/src/dev/showcase/toggle.tsx +36 -27
- package/src/dev/showcase/tooltip.tsx +154 -119
- package/src/lib/utils.test.ts +1 -0
- package/src/lib/utils.ts +1 -1
- package/src/styles/gladvn.css +0 -1
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Tooltip,
|
|
3
|
-
TooltipContent,
|
|
4
|
-
TooltipPortal,
|
|
5
|
-
TooltipProvider,
|
|
6
|
-
TooltipTrigger,
|
|
7
|
-
} from "../../components/micro/tooltip";
|
|
8
|
-
import { MoonIcon, SunIcon } from "lucide-react";
|
|
9
1
|
import { useState } from "react";
|
|
10
2
|
|
|
3
|
+
import { MoonIcon, SunIcon } from "lucide-react";
|
|
4
|
+
|
|
11
5
|
import { Button } from "../../components/micro/button";
|
|
12
6
|
import {
|
|
13
7
|
Dialog,
|
|
@@ -50,19 +44,23 @@ import {
|
|
|
50
44
|
SheetTitle,
|
|
51
45
|
SheetTrigger,
|
|
52
46
|
} from "../../components/micro/sheet";
|
|
53
|
-
|
|
54
|
-
|
|
55
47
|
import {
|
|
48
|
+
type ThemeMode,
|
|
56
49
|
ThemeProvider,
|
|
57
50
|
ThemeWrapper,
|
|
58
51
|
useTheme,
|
|
59
|
-
type ThemeMode,
|
|
60
52
|
} from "../../components/micro/theme-provider";
|
|
53
|
+
import {
|
|
54
|
+
Tooltip,
|
|
55
|
+
TooltipContent,
|
|
56
|
+
TooltipPortal,
|
|
57
|
+
TooltipProvider,
|
|
58
|
+
TooltipTrigger,
|
|
59
|
+
} from "../../components/micro/tooltip";
|
|
61
60
|
import {
|
|
62
61
|
DocsCode,
|
|
63
62
|
DocsH3,
|
|
64
63
|
DocsP,
|
|
65
|
-
ExampleGrid,
|
|
66
64
|
ExampleSection,
|
|
67
65
|
SectionHeader,
|
|
68
66
|
Showcase,
|
|
@@ -93,8 +91,12 @@ function ThemeAwareCard({ readOnly }: { readOnly?: boolean } = {}) {
|
|
|
93
91
|
variant="ghost"
|
|
94
92
|
size="sm"
|
|
95
93
|
iconOnly
|
|
96
|
-
aria-label={
|
|
97
|
-
|
|
94
|
+
aria-label={
|
|
95
|
+
theme?.mode === "dark" ? "Chuyển sang Light" : "Chuyển sang Dark"
|
|
96
|
+
}
|
|
97
|
+
onClick={() =>
|
|
98
|
+
theme?.setMode(theme.mode === "dark" ? "light" : "dark")
|
|
99
|
+
}
|
|
98
100
|
>
|
|
99
101
|
{theme?.mode === "dark" ? (
|
|
100
102
|
<SunIcon aria-hidden="true" />
|
|
@@ -223,374 +225,444 @@ function ThemeProviderMicroShowcase() {
|
|
|
223
225
|
/>
|
|
224
226
|
</div>
|
|
225
227
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
className="bg-card text-card-foreground border border-border shadow-md"
|
|
246
|
-
>
|
|
247
|
-
Trắng toát! Lạc quẻ với nền đen.
|
|
248
|
-
</TooltipContent>
|
|
249
|
-
</TooltipPortal>
|
|
250
|
-
</Tooltip>
|
|
251
|
-
</TooltipProvider>
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
255
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
256
|
-
Có ThemeWrapper
|
|
257
|
-
</span>
|
|
258
|
-
<TooltipProvider>
|
|
259
|
-
<Tooltip>
|
|
260
|
-
<TooltipTrigger
|
|
261
|
-
render={<Button variant="solid">Hover tôi</Button>}
|
|
262
|
-
/>
|
|
263
|
-
<TooltipPortal>
|
|
264
|
-
<ThemeWrapper>
|
|
228
|
+
{/* Tooltip */}
|
|
229
|
+
<ExampleSection
|
|
230
|
+
fullWidth
|
|
231
|
+
label="Tooltip"
|
|
232
|
+
description="Tooltip được định vị gần trigger và hiển thị khi hover. Không có ThemeWrapper, tooltip của bạn sẽ trắng toát giữa một dark section — dười đây là bằng chứng trực quan."
|
|
233
|
+
codeString={`<ThemeProvider defaultMode="dark">
|
|
234
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
235
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
236
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
237
|
+
Không dùng ThemeWrapper
|
|
238
|
+
</span>
|
|
239
|
+
<TooltipProvider>
|
|
240
|
+
<Tooltip>
|
|
241
|
+
<TooltipTrigger
|
|
242
|
+
render={
|
|
243
|
+
<Button variant="solid">Hover tôi</Button>
|
|
244
|
+
}
|
|
245
|
+
/>
|
|
246
|
+
<TooltipPortal>
|
|
265
247
|
<TooltipContent
|
|
266
248
|
sideOffset={8}
|
|
267
249
|
className="bg-card text-card-foreground border border-border shadow-md"
|
|
268
250
|
>
|
|
269
|
-
|
|
251
|
+
Trắng toát! Lạc quẻ với nền đen.
|
|
270
252
|
</TooltipContent>
|
|
271
|
-
</
|
|
272
|
-
</
|
|
273
|
-
</
|
|
274
|
-
</
|
|
253
|
+
</TooltipPortal>
|
|
254
|
+
</Tooltip>
|
|
255
|
+
</TooltipProvider>
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
259
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
260
|
+
Có ThemeWrapper
|
|
261
|
+
</span>
|
|
262
|
+
<TooltipProvider>
|
|
263
|
+
<Tooltip>
|
|
264
|
+
<TooltipTrigger
|
|
265
|
+
render={
|
|
266
|
+
<Button variant="solid">Hover tôi</Button>
|
|
267
|
+
}
|
|
268
|
+
/>
|
|
269
|
+
<TooltipPortal>
|
|
270
|
+
<ThemeWrapper>
|
|
271
|
+
<TooltipContent
|
|
272
|
+
sideOffset={8}
|
|
273
|
+
className="bg-card text-card-foreground border border-border shadow-md"
|
|
274
|
+
>
|
|
275
|
+
Màu Tối! Đồng bộ với provider cha.
|
|
276
|
+
</TooltipContent>
|
|
277
|
+
</ThemeWrapper>
|
|
278
|
+
</TooltipPortal>
|
|
279
|
+
</Tooltip>
|
|
280
|
+
</TooltipProvider>
|
|
281
|
+
</div>
|
|
275
282
|
</div>
|
|
276
|
-
</
|
|
277
|
-
|
|
278
|
-
>
|
|
279
|
-
<
|
|
280
|
-
<div className="
|
|
281
|
-
<
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
<
|
|
286
|
-
<
|
|
287
|
-
<
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
<
|
|
283
|
+
</ThemeProvider>`}
|
|
284
|
+
>
|
|
285
|
+
<ThemeProvider defaultMode="dark">
|
|
286
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
287
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
288
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
289
|
+
Không dùng ThemeWrapper
|
|
290
|
+
</span>
|
|
291
|
+
<TooltipProvider>
|
|
292
|
+
<Tooltip>
|
|
293
|
+
<TooltipTrigger
|
|
294
|
+
render={<Button variant="solid">Hover tôi</Button>}
|
|
295
|
+
/>
|
|
296
|
+
<TooltipPortal>
|
|
297
|
+
<TooltipContent
|
|
298
|
+
sideOffset={8}
|
|
299
|
+
className="bg-card text-card-foreground border border-border shadow-md"
|
|
300
|
+
>
|
|
301
|
+
Trắng toát! Lạc quẻ với nền đen.
|
|
302
|
+
</TooltipContent>
|
|
303
|
+
</TooltipPortal>
|
|
304
|
+
</Tooltip>
|
|
305
|
+
</TooltipProvider>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
309
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
310
|
+
Có ThemeWrapper
|
|
311
|
+
</span>
|
|
312
|
+
<TooltipProvider>
|
|
313
|
+
<Tooltip>
|
|
314
|
+
<TooltipTrigger
|
|
315
|
+
render={<Button variant="solid">Hover tôi</Button>}
|
|
316
|
+
/>
|
|
317
|
+
<TooltipPortal>
|
|
318
|
+
<ThemeWrapper>
|
|
291
319
|
<TooltipContent
|
|
292
320
|
sideOffset={8}
|
|
293
321
|
className="bg-card text-card-foreground border border-border shadow-md"
|
|
294
322
|
>
|
|
295
|
-
|
|
323
|
+
Màu Tối! Đồng bộ với provider cha.
|
|
296
324
|
</TooltipContent>
|
|
297
|
-
</
|
|
298
|
-
</
|
|
299
|
-
</
|
|
300
|
-
</
|
|
301
|
-
|
|
302
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
303
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
304
|
-
Có ThemeWrapper
|
|
305
|
-
</span>
|
|
306
|
-
<TooltipProvider>
|
|
307
|
-
<Tooltip>
|
|
308
|
-
<TooltipTrigger
|
|
309
|
-
render={<Button variant="solid">Hover tôi</Button>}
|
|
310
|
-
/>
|
|
311
|
-
<TooltipPortal>
|
|
312
|
-
<ThemeWrapper>
|
|
313
|
-
<TooltipContent
|
|
314
|
-
sideOffset={8}
|
|
315
|
-
className="bg-card text-card-foreground border border-border shadow-md"
|
|
316
|
-
>
|
|
317
|
-
Màu Tối! Đồng bộ với provider cha.
|
|
318
|
-
</TooltipContent>
|
|
319
|
-
</ThemeWrapper>
|
|
320
|
-
</TooltipPortal>
|
|
321
|
-
</Tooltip>
|
|
322
|
-
</TooltipProvider>
|
|
323
|
-
</div>
|
|
324
|
-
</div>
|
|
325
|
-
</ThemeProvider>
|
|
326
|
-
</ExampleSection>
|
|
327
|
-
|
|
328
|
-
{/* Popover */}
|
|
329
|
-
<ExampleSection
|
|
330
|
-
fullWidth
|
|
331
|
-
label="Popover"
|
|
332
|
-
description="Popover chứa content phức tạp và mở khi click. Vì portal hướng tới `document.body`, toàn bộ nền popover lấy CSS variable từ root — sẽ trắng hoàn toàn dù trigger đang nằm trong dark section."
|
|
333
|
-
codeString={`<ThemeProvider defaultMode="dark">
|
|
334
|
-
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
335
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
336
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
337
|
-
Không dùng ThemeWrapper
|
|
338
|
-
</span>
|
|
339
|
-
<Popover>
|
|
340
|
-
<PopoverTrigger
|
|
341
|
-
render={<Button variant="outline">Click Popover</Button>}
|
|
342
|
-
/>
|
|
343
|
-
<PopoverPortal>
|
|
344
|
-
<PopoverContent className="w-64">
|
|
345
|
-
<div className="space-y-2">
|
|
346
|
-
<h4 className="font-medium leading-none">
|
|
347
|
-
Nội dung Popover
|
|
348
|
-
</h4>
|
|
349
|
-
<p className="text-sm text-muted-foreground">
|
|
350
|
-
Lỗi: Hiển thị giao diện sáng.
|
|
351
|
-
</p>
|
|
325
|
+
</ThemeWrapper>
|
|
326
|
+
</TooltipPortal>
|
|
327
|
+
</Tooltip>
|
|
328
|
+
</TooltipProvider>
|
|
352
329
|
</div>
|
|
353
|
-
</
|
|
354
|
-
</
|
|
355
|
-
</
|
|
356
|
-
</div>
|
|
330
|
+
</div>
|
|
331
|
+
</ThemeProvider>
|
|
332
|
+
</ExampleSection>
|
|
357
333
|
|
|
358
|
-
|
|
359
|
-
<
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
<
|
|
367
|
-
|
|
334
|
+
{/* Popover */}
|
|
335
|
+
<ExampleSection
|
|
336
|
+
fullWidth
|
|
337
|
+
label="Popover"
|
|
338
|
+
description="Popover chứa content phức tạp và mở khi click. Vì portal hướng tới `document.body`, toàn bộ nền popover lấy CSS variable từ root — sẽ trắng hoàn toàn dù trigger đang nằm trong dark section."
|
|
339
|
+
codeString={`<ThemeProvider defaultMode="dark">
|
|
340
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
341
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
342
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
343
|
+
Không dùng ThemeWrapper
|
|
344
|
+
</span>
|
|
345
|
+
<Popover>
|
|
346
|
+
<PopoverTrigger
|
|
347
|
+
render={
|
|
348
|
+
<Button variant="outline">
|
|
349
|
+
Click Popover
|
|
350
|
+
</Button>
|
|
351
|
+
}
|
|
352
|
+
/>
|
|
353
|
+
<PopoverPortal>
|
|
368
354
|
<PopoverContent className="w-64">
|
|
369
355
|
<div className="space-y-2">
|
|
370
356
|
<h4 className="font-medium leading-none">
|
|
371
357
|
Nội dung Popover
|
|
372
358
|
</h4>
|
|
373
359
|
<p className="text-sm text-muted-foreground">
|
|
374
|
-
|
|
360
|
+
Lỗi: Hiển thị giao diện sáng.
|
|
375
361
|
</p>
|
|
376
362
|
</div>
|
|
377
363
|
</PopoverContent>
|
|
378
|
-
</
|
|
379
|
-
</
|
|
380
|
-
</
|
|
364
|
+
</PopoverPortal>
|
|
365
|
+
</Popover>
|
|
366
|
+
</div>
|
|
367
|
+
|
|
368
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
369
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
370
|
+
Có ThemeWrapper
|
|
371
|
+
</span>
|
|
372
|
+
<Popover>
|
|
373
|
+
<PopoverTrigger
|
|
374
|
+
render={
|
|
375
|
+
<Button variant="outline">
|
|
376
|
+
Click Popover
|
|
377
|
+
</Button>
|
|
378
|
+
}
|
|
379
|
+
/>
|
|
380
|
+
<PopoverPortal>
|
|
381
|
+
<ThemeWrapper>
|
|
382
|
+
<PopoverContent className="w-64">
|
|
383
|
+
<div className="space-y-2">
|
|
384
|
+
<h4 className="font-medium leading-none">
|
|
385
|
+
Nội dung Popover
|
|
386
|
+
</h4>
|
|
387
|
+
<p className="text-sm text-muted-foreground">
|
|
388
|
+
Lớp Portal Tunnel đã hoạt động chính
|
|
389
|
+
xác.
|
|
390
|
+
</p>
|
|
391
|
+
</div>
|
|
392
|
+
</PopoverContent>
|
|
393
|
+
</ThemeWrapper>
|
|
394
|
+
</PopoverPortal>
|
|
395
|
+
</Popover>
|
|
396
|
+
</div>
|
|
381
397
|
</div>
|
|
382
|
-
</
|
|
383
|
-
|
|
384
|
-
>
|
|
385
|
-
<
|
|
386
|
-
<div className="
|
|
387
|
-
<
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
<
|
|
392
|
-
<
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
<
|
|
398
|
+
</ThemeProvider>`}
|
|
399
|
+
>
|
|
400
|
+
<ThemeProvider defaultMode="dark">
|
|
401
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
402
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
403
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
404
|
+
Không dùng ThemeWrapper
|
|
405
|
+
</span>
|
|
406
|
+
<Popover>
|
|
407
|
+
<PopoverTrigger
|
|
408
|
+
render={<Button variant="outline">Click Popover</Button>}
|
|
409
|
+
/>
|
|
410
|
+
<PopoverPortal>
|
|
411
|
+
<PopoverContent className="w-64">
|
|
412
|
+
<div className="space-y-2">
|
|
413
|
+
<h4 className="font-medium leading-none">
|
|
414
|
+
Nội dung Popover
|
|
415
|
+
</h4>
|
|
416
|
+
<p className="text-sm text-muted-foreground">
|
|
417
|
+
Lỗi: Hiển thị giao diện sáng.
|
|
418
|
+
</p>
|
|
419
|
+
</div>
|
|
420
|
+
</PopoverContent>
|
|
421
|
+
</PopoverPortal>
|
|
422
|
+
</Popover>
|
|
423
|
+
</div>
|
|
424
|
+
|
|
425
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
426
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
427
|
+
Có ThemeWrapper
|
|
428
|
+
</span>
|
|
429
|
+
<Popover>
|
|
430
|
+
<PopoverTrigger
|
|
431
|
+
render={<Button variant="outline">Click Popover</Button>}
|
|
432
|
+
/>
|
|
433
|
+
<PopoverPortal>
|
|
434
|
+
<ThemeWrapper>
|
|
396
435
|
<PopoverContent className="w-64">
|
|
397
436
|
<div className="space-y-2">
|
|
398
437
|
<h4 className="font-medium leading-none">
|
|
399
438
|
Nội dung Popover
|
|
400
439
|
</h4>
|
|
401
440
|
<p className="text-sm text-muted-foreground">
|
|
402
|
-
|
|
441
|
+
Lớp Portal Tunnel đã hoạt động chính xác.
|
|
403
442
|
</p>
|
|
404
443
|
</div>
|
|
405
444
|
</PopoverContent>
|
|
406
|
-
</
|
|
407
|
-
</
|
|
408
|
-
</
|
|
409
|
-
|
|
410
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
411
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
412
|
-
Có ThemeWrapper
|
|
413
|
-
</span>
|
|
414
|
-
<Popover>
|
|
415
|
-
<PopoverTrigger
|
|
416
|
-
render={<Button variant="outline">Click Popover</Button>}
|
|
417
|
-
/>
|
|
418
|
-
<PopoverPortal>
|
|
419
|
-
<ThemeWrapper>
|
|
420
|
-
<PopoverContent className="w-64">
|
|
421
|
-
<div className="space-y-2">
|
|
422
|
-
<h4 className="font-medium leading-none">
|
|
423
|
-
Nội dung Popover
|
|
424
|
-
</h4>
|
|
425
|
-
<p className="text-sm text-muted-foreground">
|
|
426
|
-
Lớp Portal Tunnel đã hoạt động chính xác.
|
|
427
|
-
</p>
|
|
428
|
-
</div>
|
|
429
|
-
</PopoverContent>
|
|
430
|
-
</ThemeWrapper>
|
|
431
|
-
</PopoverPortal>
|
|
432
|
-
</Popover>
|
|
433
|
-
</div>
|
|
445
|
+
</ThemeWrapper>
|
|
446
|
+
</PopoverPortal>
|
|
447
|
+
</Popover>
|
|
434
448
|
</div>
|
|
435
|
-
</
|
|
436
|
-
</
|
|
437
|
-
|
|
438
|
-
{/* Select */}
|
|
439
|
-
<ExampleSection
|
|
440
|
-
fullWidth
|
|
441
|
-
label="Select"
|
|
442
|
-
description="SelectContent được render tách biệt hoàn toàn khỏi trigger. Thiếu ThemeWrapper, dropdown option sẽ trắng xuộa trong khi trigger vẫn tối — mù quáng và khó đọc."
|
|
443
|
-
codeString={`<ThemeProvider defaultMode="dark">
|
|
444
|
-
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
445
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
446
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
447
|
-
Không dùng ThemeWrapper
|
|
448
|
-
</span>
|
|
449
|
-
<Select items={{ next: "Next.js", vite: "Vite", remix: "Remix" }}>
|
|
450
|
-
<SelectTrigger className="w-[140px]">
|
|
451
|
-
<SelectValue placeholder="Chọn framework..." />
|
|
452
|
-
</SelectTrigger>
|
|
453
|
-
<SelectPortal>
|
|
454
|
-
<SelectContent>
|
|
455
|
-
<SelectItem value="next">Next.js</SelectItem>
|
|
456
|
-
<SelectItem value="vite">Vite</SelectItem>
|
|
457
|
-
<SelectItem value="remix">Remix</SelectItem>
|
|
458
|
-
</SelectContent>
|
|
459
|
-
</SelectPortal>
|
|
460
|
-
</Select>
|
|
461
|
-
</div>
|
|
449
|
+
</div>
|
|
450
|
+
</ThemeProvider>
|
|
451
|
+
</ExampleSection>
|
|
462
452
|
|
|
463
|
-
|
|
464
|
-
<
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
<
|
|
472
|
-
|
|
453
|
+
{/* Select */}
|
|
454
|
+
<ExampleSection
|
|
455
|
+
fullWidth
|
|
456
|
+
label="Select"
|
|
457
|
+
description="SelectContent được render tách biệt hoàn toàn khỏi trigger. Thiếu ThemeWrapper, dropdown option sẽ trắng xuộa trong khi trigger vẫn tối — mù quáng và khó đọc."
|
|
458
|
+
codeString={`<ThemeProvider defaultMode="dark">
|
|
459
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
460
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
461
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
462
|
+
Không dùng ThemeWrapper
|
|
463
|
+
</span>
|
|
464
|
+
<Select
|
|
465
|
+
items={{
|
|
466
|
+
next: "Next.js",
|
|
467
|
+
vite: "Vite",
|
|
468
|
+
remix: "Remix",
|
|
469
|
+
}}
|
|
470
|
+
>
|
|
471
|
+
<SelectTrigger className="w-[140px]">
|
|
472
|
+
<SelectValue placeholder="Chọn framework..." />
|
|
473
|
+
</SelectTrigger>
|
|
474
|
+
<SelectPortal>
|
|
473
475
|
<SelectContent>
|
|
474
476
|
<SelectItem value="next">Next.js</SelectItem>
|
|
475
477
|
<SelectItem value="vite">Vite</SelectItem>
|
|
476
478
|
<SelectItem value="remix">Remix</SelectItem>
|
|
477
479
|
</SelectContent>
|
|
478
|
-
</
|
|
479
|
-
</
|
|
480
|
-
</
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
480
|
+
</SelectPortal>
|
|
481
|
+
</Select>
|
|
482
|
+
</div>
|
|
483
|
+
|
|
484
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
485
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
486
|
+
Có ThemeWrapper
|
|
487
|
+
</span>
|
|
488
|
+
<Select
|
|
489
|
+
items={{
|
|
490
|
+
next: "Next.js",
|
|
491
|
+
vite: "Vite",
|
|
492
|
+
remix: "Remix",
|
|
493
|
+
}}
|
|
484
494
|
>
|
|
485
|
-
<
|
|
486
|
-
<
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
<
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
495
|
+
<SelectTrigger className="w-[140px]">
|
|
496
|
+
<SelectValue placeholder="Chọn framework..." />
|
|
497
|
+
</SelectTrigger>
|
|
498
|
+
<SelectPortal>
|
|
499
|
+
<ThemeWrapper>
|
|
500
|
+
<SelectContent>
|
|
501
|
+
<SelectItem value="next">
|
|
502
|
+
Next.js
|
|
503
|
+
</SelectItem>
|
|
504
|
+
<SelectItem value="vite">Vite</SelectItem>
|
|
505
|
+
<SelectItem value="remix">Remix</SelectItem>
|
|
506
|
+
</SelectContent>
|
|
507
|
+
</ThemeWrapper>
|
|
508
|
+
</SelectPortal>
|
|
509
|
+
</Select>
|
|
510
|
+
</div>
|
|
511
|
+
</div>
|
|
512
|
+
</ThemeProvider>`}
|
|
513
|
+
>
|
|
514
|
+
<ThemeProvider defaultMode="dark">
|
|
515
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
516
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
517
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
518
|
+
Không dùng ThemeWrapper
|
|
519
|
+
</span>
|
|
520
|
+
<Select items={{ next: "Next.js", vite: "Vite", remix: "Remix" }}>
|
|
521
|
+
<SelectTrigger className="w-[140px]">
|
|
522
|
+
<SelectValue placeholder="Chọn framework..." />
|
|
523
|
+
</SelectTrigger>
|
|
524
|
+
<SelectPortal>
|
|
525
|
+
<SelectContent>
|
|
526
|
+
<SelectItem value="next">Next.js</SelectItem>
|
|
527
|
+
<SelectItem value="vite">Vite</SelectItem>
|
|
528
|
+
<SelectItem value="remix">Remix</SelectItem>
|
|
529
|
+
</SelectContent>
|
|
530
|
+
</SelectPortal>
|
|
531
|
+
</Select>
|
|
532
|
+
</div>
|
|
533
|
+
|
|
534
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
535
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
536
|
+
Có ThemeWrapper
|
|
537
|
+
</span>
|
|
538
|
+
<Select items={{ next: "Next.js", vite: "Vite", remix: "Remix" }}>
|
|
539
|
+
<SelectTrigger className="w-[140px]">
|
|
540
|
+
<SelectValue placeholder="Chọn framework..." />
|
|
541
|
+
</SelectTrigger>
|
|
542
|
+
<SelectPortal>
|
|
543
|
+
<ThemeWrapper>
|
|
496
544
|
<SelectContent>
|
|
497
545
|
<SelectItem value="next">Next.js</SelectItem>
|
|
498
546
|
<SelectItem value="vite">Vite</SelectItem>
|
|
499
547
|
<SelectItem value="remix">Remix</SelectItem>
|
|
500
548
|
</SelectContent>
|
|
501
|
-
</
|
|
502
|
-
</
|
|
503
|
-
</
|
|
504
|
-
|
|
505
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
506
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
507
|
-
Có ThemeWrapper
|
|
508
|
-
</span>
|
|
509
|
-
<Select items={{ next: "Next.js", vite: "Vite", remix: "Remix" }}>
|
|
510
|
-
<SelectTrigger className="w-[140px]">
|
|
511
|
-
<SelectValue placeholder="Chọn framework..." />
|
|
512
|
-
</SelectTrigger>
|
|
513
|
-
<SelectPortal>
|
|
514
|
-
<ThemeWrapper>
|
|
515
|
-
<SelectContent>
|
|
516
|
-
<SelectItem value="next">Next.js</SelectItem>
|
|
517
|
-
<SelectItem value="vite">Vite</SelectItem>
|
|
518
|
-
<SelectItem value="remix">Remix</SelectItem>
|
|
519
|
-
</SelectContent>
|
|
520
|
-
</ThemeWrapper>
|
|
521
|
-
</SelectPortal>
|
|
522
|
-
</Select>
|
|
523
|
-
</div>
|
|
549
|
+
</ThemeWrapper>
|
|
550
|
+
</SelectPortal>
|
|
551
|
+
</Select>
|
|
524
552
|
</div>
|
|
525
|
-
</
|
|
526
|
-
</
|
|
527
|
-
|
|
528
|
-
{/* DropdownMenu */}
|
|
529
|
-
<ExampleSection
|
|
530
|
-
fullWidth
|
|
531
|
-
label="DropdownMenu"
|
|
532
|
-
description="DropdownMenu thường dùng cho navigation actions (profile, settings, logout). Khi hover qua từng item, màu highlight cũng lấy từ CSS variable — thiếu ThemeWrapper, cả nền menu lẫn trạng thái hover cùng lúc đều hiển thị sai màu."
|
|
533
|
-
codeString={`<ThemeProvider defaultMode="dark">
|
|
534
|
-
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
535
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
536
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
537
|
-
Không dùng ThemeWrapper
|
|
538
|
-
</span>
|
|
539
|
-
<DropdownMenu>
|
|
540
|
-
<DropdownMenuTrigger
|
|
541
|
-
render={<Button variant="outline">Open Dropdown</Button>}
|
|
542
|
-
/>
|
|
543
|
-
<DropdownMenuPortal>
|
|
544
|
-
<DropdownMenuContent className="w-48">
|
|
545
|
-
<DropdownMenuGroup>
|
|
546
|
-
<DropdownMenuLabel>Tài khoản</DropdownMenuLabel>
|
|
547
|
-
<DropdownMenuItem>Trang cá nhân</DropdownMenuItem>
|
|
548
|
-
<DropdownMenuItem>Cài đặt</DropdownMenuItem>
|
|
549
|
-
</DropdownMenuGroup>
|
|
550
|
-
<DropdownMenuSeparator />
|
|
551
|
-
<DropdownMenuItem>Đăng xuất</DropdownMenuItem>
|
|
552
|
-
</DropdownMenuContent>
|
|
553
|
-
</DropdownMenuPortal>
|
|
554
|
-
</DropdownMenu>
|
|
555
|
-
</div>
|
|
553
|
+
</div>
|
|
554
|
+
</ThemeProvider>
|
|
555
|
+
</ExampleSection>
|
|
556
556
|
|
|
557
|
-
|
|
558
|
-
<
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
<
|
|
566
|
-
|
|
557
|
+
{/* DropdownMenu */}
|
|
558
|
+
<ExampleSection
|
|
559
|
+
fullWidth
|
|
560
|
+
label="DropdownMenu"
|
|
561
|
+
description="DropdownMenu thường dùng cho navigation actions (profile, settings, logout). Khi hover qua từng item, màu highlight cũng lấy từ CSS variable — thiếu ThemeWrapper, cả nền menu lẫn trạng thái hover cùng lúc đều hiển thị sai màu."
|
|
562
|
+
codeString={`<ThemeProvider defaultMode="dark">
|
|
563
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
564
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
565
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
566
|
+
Không dùng ThemeWrapper
|
|
567
|
+
</span>
|
|
568
|
+
<DropdownMenu>
|
|
569
|
+
<DropdownMenuTrigger
|
|
570
|
+
render={
|
|
571
|
+
<Button variant="outline">
|
|
572
|
+
Open Dropdown
|
|
573
|
+
</Button>
|
|
574
|
+
}
|
|
575
|
+
/>
|
|
576
|
+
<DropdownMenuPortal>
|
|
567
577
|
<DropdownMenuContent className="w-48">
|
|
568
578
|
<DropdownMenuGroup>
|
|
569
|
-
<DropdownMenuLabel>
|
|
570
|
-
|
|
579
|
+
<DropdownMenuLabel>
|
|
580
|
+
Tài khoản
|
|
581
|
+
</DropdownMenuLabel>
|
|
582
|
+
<DropdownMenuItem>
|
|
583
|
+
Trang cá nhân
|
|
584
|
+
</DropdownMenuItem>
|
|
571
585
|
<DropdownMenuItem>Cài đặt</DropdownMenuItem>
|
|
572
586
|
</DropdownMenuGroup>
|
|
573
587
|
<DropdownMenuSeparator />
|
|
574
588
|
<DropdownMenuItem>Đăng xuất</DropdownMenuItem>
|
|
575
589
|
</DropdownMenuContent>
|
|
576
|
-
</
|
|
577
|
-
</
|
|
578
|
-
</
|
|
590
|
+
</DropdownMenuPortal>
|
|
591
|
+
</DropdownMenu>
|
|
592
|
+
</div>
|
|
593
|
+
|
|
594
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
595
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
596
|
+
Có ThemeWrapper
|
|
597
|
+
</span>
|
|
598
|
+
<DropdownMenu>
|
|
599
|
+
<DropdownMenuTrigger
|
|
600
|
+
render={
|
|
601
|
+
<Button variant="outline">
|
|
602
|
+
Open Dropdown
|
|
603
|
+
</Button>
|
|
604
|
+
}
|
|
605
|
+
/>
|
|
606
|
+
<DropdownMenuPortal>
|
|
607
|
+
<ThemeWrapper>
|
|
608
|
+
<DropdownMenuContent className="w-48">
|
|
609
|
+
<DropdownMenuGroup>
|
|
610
|
+
<DropdownMenuLabel>
|
|
611
|
+
Tài khoản
|
|
612
|
+
</DropdownMenuLabel>
|
|
613
|
+
<DropdownMenuItem>
|
|
614
|
+
Trang cá nhân
|
|
615
|
+
</DropdownMenuItem>
|
|
616
|
+
<DropdownMenuItem>
|
|
617
|
+
Cài đặt
|
|
618
|
+
</DropdownMenuItem>
|
|
619
|
+
</DropdownMenuGroup>
|
|
620
|
+
<DropdownMenuSeparator />
|
|
621
|
+
<DropdownMenuItem>
|
|
622
|
+
Đăng xuất
|
|
623
|
+
</DropdownMenuItem>
|
|
624
|
+
</DropdownMenuContent>
|
|
625
|
+
</ThemeWrapper>
|
|
626
|
+
</DropdownMenuPortal>
|
|
627
|
+
</DropdownMenu>
|
|
628
|
+
</div>
|
|
579
629
|
</div>
|
|
580
|
-
</
|
|
581
|
-
|
|
582
|
-
>
|
|
583
|
-
<
|
|
584
|
-
<div className="
|
|
585
|
-
<
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
<
|
|
590
|
-
<
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
<
|
|
630
|
+
</ThemeProvider>`}
|
|
631
|
+
>
|
|
632
|
+
<ThemeProvider defaultMode="dark">
|
|
633
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
634
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
635
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
636
|
+
Không dùng ThemeWrapper
|
|
637
|
+
</span>
|
|
638
|
+
<DropdownMenu>
|
|
639
|
+
<DropdownMenuTrigger
|
|
640
|
+
render={<Button variant="outline">Open Dropdown</Button>}
|
|
641
|
+
/>
|
|
642
|
+
<DropdownMenuPortal>
|
|
643
|
+
<DropdownMenuContent className="w-48">
|
|
644
|
+
<DropdownMenuGroup>
|
|
645
|
+
<DropdownMenuLabel>Tài khoản</DropdownMenuLabel>
|
|
646
|
+
<DropdownMenuItem>Trang cá nhân</DropdownMenuItem>
|
|
647
|
+
<DropdownMenuItem>Cài đặt</DropdownMenuItem>
|
|
648
|
+
</DropdownMenuGroup>
|
|
649
|
+
<DropdownMenuSeparator />
|
|
650
|
+
<DropdownMenuItem>Đăng xuất</DropdownMenuItem>
|
|
651
|
+
</DropdownMenuContent>
|
|
652
|
+
</DropdownMenuPortal>
|
|
653
|
+
</DropdownMenu>
|
|
654
|
+
</div>
|
|
655
|
+
|
|
656
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
657
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
658
|
+
Có ThemeWrapper
|
|
659
|
+
</span>
|
|
660
|
+
<DropdownMenu>
|
|
661
|
+
<DropdownMenuTrigger
|
|
662
|
+
render={<Button variant="outline">Open Dropdown</Button>}
|
|
663
|
+
/>
|
|
664
|
+
<DropdownMenuPortal>
|
|
665
|
+
<ThemeWrapper>
|
|
594
666
|
<DropdownMenuContent className="w-48">
|
|
595
667
|
<DropdownMenuGroup>
|
|
596
668
|
<DropdownMenuLabel>Tài khoản</DropdownMenuLabel>
|
|
@@ -600,232 +672,222 @@ function ThemeProviderMicroShowcase() {
|
|
|
600
672
|
<DropdownMenuSeparator />
|
|
601
673
|
<DropdownMenuItem>Đăng xuất</DropdownMenuItem>
|
|
602
674
|
</DropdownMenuContent>
|
|
603
|
-
</
|
|
604
|
-
</
|
|
605
|
-
</
|
|
606
|
-
|
|
607
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
608
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
609
|
-
Có ThemeWrapper
|
|
610
|
-
</span>
|
|
611
|
-
<DropdownMenu>
|
|
612
|
-
<DropdownMenuTrigger
|
|
613
|
-
render={<Button variant="outline">Open Dropdown</Button>}
|
|
614
|
-
/>
|
|
615
|
-
<DropdownMenuPortal>
|
|
616
|
-
<ThemeWrapper>
|
|
617
|
-
<DropdownMenuContent className="w-48">
|
|
618
|
-
<DropdownMenuGroup>
|
|
619
|
-
<DropdownMenuLabel>Tài khoản</DropdownMenuLabel>
|
|
620
|
-
<DropdownMenuItem>Trang cá nhân</DropdownMenuItem>
|
|
621
|
-
<DropdownMenuItem>Cài đặt</DropdownMenuItem>
|
|
622
|
-
</DropdownMenuGroup>
|
|
623
|
-
<DropdownMenuSeparator />
|
|
624
|
-
<DropdownMenuItem>Đăng xuất</DropdownMenuItem>
|
|
625
|
-
</DropdownMenuContent>
|
|
626
|
-
</ThemeWrapper>
|
|
627
|
-
</DropdownMenuPortal>
|
|
628
|
-
</DropdownMenu>
|
|
629
|
-
</div>
|
|
675
|
+
</ThemeWrapper>
|
|
676
|
+
</DropdownMenuPortal>
|
|
677
|
+
</DropdownMenu>
|
|
630
678
|
</div>
|
|
631
|
-
</
|
|
632
|
-
</
|
|
633
|
-
|
|
634
|
-
{/* Dialog */}
|
|
635
|
-
<ExampleSection
|
|
636
|
-
fullWidth
|
|
637
|
-
label="Dialog"
|
|
638
|
-
description="Dialog là trường hợp phức tạp nhất: portal chứa cả Overlay backdrop lẫn Content panel. Cả hai layer đều cần được bọc trong ThemeWrapper để đảm bảo đồng bộ hoàn toàn."
|
|
639
|
-
codeString={`<ThemeProvider defaultMode="dark">
|
|
640
|
-
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
641
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
642
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
643
|
-
Không dùng ThemeWrapper
|
|
644
|
-
</span>
|
|
645
|
-
<Dialog>
|
|
646
|
-
<DialogTrigger
|
|
647
|
-
render={<Button variant="outline">Open Dialog</Button>}
|
|
648
|
-
/>
|
|
649
|
-
<DialogPortal>
|
|
650
|
-
<DialogContent className="sm:max-w-md">
|
|
651
|
-
<DialogHeader>
|
|
652
|
-
<DialogTitle>Mất Dark Mode!</DialogTitle>
|
|
653
|
-
<DialogDescription>
|
|
654
|
-
Lỗi: Hiển thị giao diện sáng mặc định.
|
|
655
|
-
</DialogDescription>
|
|
656
|
-
</DialogHeader>
|
|
657
|
-
</DialogContent>
|
|
658
|
-
</DialogPortal>
|
|
659
|
-
</Dialog>
|
|
660
|
-
</div>
|
|
679
|
+
</div>
|
|
680
|
+
</ThemeProvider>
|
|
681
|
+
</ExampleSection>
|
|
661
682
|
|
|
662
|
-
|
|
663
|
-
<
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
<
|
|
671
|
-
|
|
683
|
+
{/* Dialog */}
|
|
684
|
+
<ExampleSection
|
|
685
|
+
fullWidth
|
|
686
|
+
label="Dialog"
|
|
687
|
+
description="Dialog là trường hợp phức tạp nhất: portal chứa cả Overlay backdrop lẫn Content panel. Cả hai layer đều cần được bọc trong ThemeWrapper để đảm bảo đồng bộ hoàn toàn."
|
|
688
|
+
codeString={`<ThemeProvider defaultMode="dark">
|
|
689
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
690
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
691
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
692
|
+
Không dùng ThemeWrapper
|
|
693
|
+
</span>
|
|
694
|
+
<Dialog>
|
|
695
|
+
<DialogTrigger
|
|
696
|
+
render={
|
|
697
|
+
<Button variant="outline">Open Dialog</Button>
|
|
698
|
+
}
|
|
699
|
+
/>
|
|
700
|
+
<DialogPortal>
|
|
672
701
|
<DialogContent className="sm:max-w-md">
|
|
673
702
|
<DialogHeader>
|
|
674
|
-
<DialogTitle>
|
|
703
|
+
<DialogTitle>Mất Dark Mode!</DialogTitle>
|
|
675
704
|
<DialogDescription>
|
|
676
|
-
|
|
677
|
-
Portal Tunnel vẫn bảo vệ được scope Dark Mode.
|
|
705
|
+
Lỗi: Hiển thị giao diện sáng mặc định.
|
|
678
706
|
</DialogDescription>
|
|
679
707
|
</DialogHeader>
|
|
680
708
|
</DialogContent>
|
|
681
|
-
</
|
|
682
|
-
</
|
|
683
|
-
</
|
|
709
|
+
</DialogPortal>
|
|
710
|
+
</Dialog>
|
|
711
|
+
</div>
|
|
712
|
+
|
|
713
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
714
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
715
|
+
Có ThemeWrapper
|
|
716
|
+
</span>
|
|
717
|
+
<Dialog>
|
|
718
|
+
<DialogTrigger
|
|
719
|
+
render={
|
|
720
|
+
<Button variant="outline">Open Dialog</Button>
|
|
721
|
+
}
|
|
722
|
+
/>
|
|
723
|
+
<DialogPortal>
|
|
724
|
+
<ThemeWrapper>
|
|
725
|
+
<DialogContent className="sm:max-w-md">
|
|
726
|
+
<DialogHeader>
|
|
727
|
+
<DialogTitle>
|
|
728
|
+
Màu tối toàn vẹn
|
|
729
|
+
</DialogTitle>
|
|
730
|
+
<DialogDescription>
|
|
731
|
+
Ngay cả khi mở Dialog bọc ngoài toàn bộ
|
|
732
|
+
màn hình, Portal Tunnel vẫn bảo vệ được
|
|
733
|
+
scope Dark Mode.
|
|
734
|
+
</DialogDescription>
|
|
735
|
+
</DialogHeader>
|
|
736
|
+
</DialogContent>
|
|
737
|
+
</ThemeWrapper>
|
|
738
|
+
</DialogPortal>
|
|
739
|
+
</Dialog>
|
|
740
|
+
</div>
|
|
684
741
|
</div>
|
|
685
|
-
</
|
|
686
|
-
|
|
687
|
-
>
|
|
688
|
-
<
|
|
689
|
-
<div className="
|
|
690
|
-
<
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
<
|
|
695
|
-
<
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
<
|
|
742
|
+
</ThemeProvider>`}
|
|
743
|
+
>
|
|
744
|
+
<ThemeProvider defaultMode="dark">
|
|
745
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
746
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
747
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
748
|
+
Không dùng ThemeWrapper
|
|
749
|
+
</span>
|
|
750
|
+
<Dialog>
|
|
751
|
+
<DialogTrigger
|
|
752
|
+
render={<Button variant="outline">Open Dialog</Button>}
|
|
753
|
+
/>
|
|
754
|
+
<DialogPortal>
|
|
755
|
+
<DialogContent className="sm:max-w-md">
|
|
756
|
+
<DialogHeader>
|
|
757
|
+
<DialogTitle>Mất Dark Mode!</DialogTitle>
|
|
758
|
+
<DialogDescription>
|
|
759
|
+
Lỗi: Hiển thị giao diện sáng mặc định.
|
|
760
|
+
</DialogDescription>
|
|
761
|
+
</DialogHeader>
|
|
762
|
+
</DialogContent>
|
|
763
|
+
</DialogPortal>
|
|
764
|
+
</Dialog>
|
|
765
|
+
</div>
|
|
766
|
+
|
|
767
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
768
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
769
|
+
Có ThemeWrapper
|
|
770
|
+
</span>
|
|
771
|
+
<Dialog>
|
|
772
|
+
<DialogTrigger
|
|
773
|
+
render={<Button variant="outline">Open Dialog</Button>}
|
|
774
|
+
/>
|
|
775
|
+
<DialogPortal>
|
|
776
|
+
<ThemeWrapper>
|
|
699
777
|
<DialogContent className="sm:max-w-md">
|
|
700
778
|
<DialogHeader>
|
|
701
|
-
<DialogTitle>
|
|
779
|
+
<DialogTitle>Màu tối toàn vẹn</DialogTitle>
|
|
702
780
|
<DialogDescription>
|
|
703
|
-
|
|
781
|
+
Ngay cả khi mở Dialog bọc ngoài toàn bộ màn hình,
|
|
782
|
+
Portal Tunnel vẫn bảo vệ được scope Dark Mode.
|
|
704
783
|
</DialogDescription>
|
|
705
784
|
</DialogHeader>
|
|
706
785
|
</DialogContent>
|
|
707
|
-
</
|
|
708
|
-
</
|
|
709
|
-
</
|
|
710
|
-
|
|
711
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
712
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
713
|
-
Có ThemeWrapper
|
|
714
|
-
</span>
|
|
715
|
-
<Dialog>
|
|
716
|
-
<DialogTrigger
|
|
717
|
-
render={<Button variant="outline">Open Dialog</Button>}
|
|
718
|
-
/>
|
|
719
|
-
<DialogPortal>
|
|
720
|
-
<ThemeWrapper>
|
|
721
|
-
<DialogContent className="sm:max-w-md">
|
|
722
|
-
<DialogHeader>
|
|
723
|
-
<DialogTitle>Màu tối toàn vẹn</DialogTitle>
|
|
724
|
-
<DialogDescription>
|
|
725
|
-
Ngay cả khi mở Dialog bọc ngoài toàn bộ màn hình,
|
|
726
|
-
Portal Tunnel vẫn bảo vệ được scope Dark Mode.
|
|
727
|
-
</DialogDescription>
|
|
728
|
-
</DialogHeader>
|
|
729
|
-
</DialogContent>
|
|
730
|
-
</ThemeWrapper>
|
|
731
|
-
</DialogPortal>
|
|
732
|
-
</Dialog>
|
|
733
|
-
</div>
|
|
786
|
+
</ThemeWrapper>
|
|
787
|
+
</DialogPortal>
|
|
788
|
+
</Dialog>
|
|
734
789
|
</div>
|
|
735
|
-
</
|
|
736
|
-
</
|
|
737
|
-
|
|
738
|
-
{/* Sheet */}
|
|
739
|
-
<ExampleSection
|
|
740
|
-
fullWidth
|
|
741
|
-
label="Sheet"
|
|
742
|
-
description="Sheet trượt từ cạnh màn hình và phủ một vùng diện tích lớn — lỗi theme dễ nhận biết nhất vì panel thông thường chứa layout phức tạp hơn Popover hay Tooltip."
|
|
743
|
-
codeString={`<ThemeProvider defaultMode="dark">
|
|
744
|
-
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
745
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
746
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
747
|
-
Không dùng ThemeWrapper
|
|
748
|
-
</span>
|
|
749
|
-
<Sheet>
|
|
750
|
-
<SheetTrigger
|
|
751
|
-
render={<Button variant="outline">Open Sheet</Button>}
|
|
752
|
-
/>
|
|
753
|
-
<SheetPortal>
|
|
754
|
-
<SheetContent side="right">
|
|
755
|
-
<SheetHeader>
|
|
756
|
-
<SheetTitle>Mất Dark Mode!</SheetTitle>
|
|
757
|
-
</SheetHeader>
|
|
758
|
-
</SheetContent>
|
|
759
|
-
</SheetPortal>
|
|
760
|
-
</Sheet>
|
|
761
|
-
</div>
|
|
790
|
+
</div>
|
|
791
|
+
</ThemeProvider>
|
|
792
|
+
</ExampleSection>
|
|
762
793
|
|
|
763
|
-
|
|
764
|
-
<
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
<
|
|
772
|
-
|
|
794
|
+
{/* Sheet */}
|
|
795
|
+
<ExampleSection
|
|
796
|
+
fullWidth
|
|
797
|
+
label="Sheet"
|
|
798
|
+
description="Sheet trượt từ cạnh màn hình và phủ một vùng diện tích lớn — lỗi theme dễ nhận biết nhất vì panel thông thường chứa layout phức tạp hơn Popover hay Tooltip."
|
|
799
|
+
codeString={`<ThemeProvider defaultMode="dark">
|
|
800
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
801
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
802
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
803
|
+
Không dùng ThemeWrapper
|
|
804
|
+
</span>
|
|
805
|
+
<Sheet>
|
|
806
|
+
<SheetTrigger
|
|
807
|
+
render={
|
|
808
|
+
<Button variant="outline">Open Sheet</Button>
|
|
809
|
+
}
|
|
810
|
+
/>
|
|
811
|
+
<SheetPortal>
|
|
773
812
|
<SheetContent side="right">
|
|
774
813
|
<SheetHeader>
|
|
775
|
-
<SheetTitle>
|
|
814
|
+
<SheetTitle>Mất Dark Mode!</SheetTitle>
|
|
776
815
|
</SheetHeader>
|
|
777
|
-
<div className="py-4">Màu tối đồng bộ hoàn hảo!</div>
|
|
778
816
|
</SheetContent>
|
|
779
|
-
</
|
|
780
|
-
</
|
|
781
|
-
</
|
|
817
|
+
</SheetPortal>
|
|
818
|
+
</Sheet>
|
|
819
|
+
</div>
|
|
820
|
+
|
|
821
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
822
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
823
|
+
Có ThemeWrapper
|
|
824
|
+
</span>
|
|
825
|
+
<Sheet>
|
|
826
|
+
<SheetTrigger
|
|
827
|
+
render={
|
|
828
|
+
<Button variant="outline">Open Sheet</Button>
|
|
829
|
+
}
|
|
830
|
+
/>
|
|
831
|
+
<SheetPortal>
|
|
832
|
+
<ThemeWrapper>
|
|
833
|
+
<SheetContent side="right">
|
|
834
|
+
<SheetHeader>
|
|
835
|
+
<SheetTitle>Sheet Demo</SheetTitle>
|
|
836
|
+
</SheetHeader>
|
|
837
|
+
<div className="py-4">
|
|
838
|
+
Màu tối đồng bộ hoàn hảo!
|
|
839
|
+
</div>
|
|
840
|
+
</SheetContent>
|
|
841
|
+
</ThemeWrapper>
|
|
842
|
+
</SheetPortal>
|
|
843
|
+
</Sheet>
|
|
844
|
+
</div>
|
|
782
845
|
</div>
|
|
783
|
-
</
|
|
784
|
-
|
|
785
|
-
>
|
|
786
|
-
<
|
|
787
|
-
<div className="
|
|
788
|
-
<
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
<
|
|
793
|
-
<
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
<
|
|
846
|
+
</ThemeProvider>`}
|
|
847
|
+
>
|
|
848
|
+
<ThemeProvider defaultMode="dark">
|
|
849
|
+
<div className="w-full flex gap-10 rounded-xl border border-border bg-background p-10">
|
|
850
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
851
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
852
|
+
Không dùng ThemeWrapper
|
|
853
|
+
</span>
|
|
854
|
+
<Sheet>
|
|
855
|
+
<SheetTrigger
|
|
856
|
+
render={<Button variant="outline">Open Sheet</Button>}
|
|
857
|
+
/>
|
|
858
|
+
<SheetPortal>
|
|
859
|
+
<SheetContent side="right">
|
|
860
|
+
<SheetHeader>
|
|
861
|
+
<SheetTitle>Mất Dark Mode!</SheetTitle>
|
|
862
|
+
</SheetHeader>
|
|
863
|
+
</SheetContent>
|
|
864
|
+
</SheetPortal>
|
|
865
|
+
</Sheet>
|
|
866
|
+
</div>
|
|
867
|
+
|
|
868
|
+
<div className="flex-1 flex flex-col items-center gap-4">
|
|
869
|
+
<span className="text-sm font-medium text-muted-foreground">
|
|
870
|
+
Có ThemeWrapper
|
|
871
|
+
</span>
|
|
872
|
+
<Sheet>
|
|
873
|
+
<SheetTrigger
|
|
874
|
+
render={<Button variant="outline">Open Sheet</Button>}
|
|
875
|
+
/>
|
|
876
|
+
<SheetPortal>
|
|
877
|
+
<ThemeWrapper>
|
|
797
878
|
<SheetContent side="right">
|
|
798
879
|
<SheetHeader>
|
|
799
|
-
<SheetTitle>
|
|
880
|
+
<SheetTitle>Sheet Demo</SheetTitle>
|
|
800
881
|
</SheetHeader>
|
|
882
|
+
<div className="py-4">Màu tối đồng bộ hoàn hảo!</div>
|
|
801
883
|
</SheetContent>
|
|
802
|
-
</
|
|
803
|
-
</
|
|
804
|
-
</
|
|
805
|
-
|
|
806
|
-
<div className="flex-1 flex flex-col items-center gap-4">
|
|
807
|
-
<span className="text-sm font-medium text-muted-foreground">
|
|
808
|
-
Có ThemeWrapper
|
|
809
|
-
</span>
|
|
810
|
-
<Sheet>
|
|
811
|
-
<SheetTrigger
|
|
812
|
-
render={<Button variant="outline">Open Sheet</Button>}
|
|
813
|
-
/>
|
|
814
|
-
<SheetPortal>
|
|
815
|
-
<ThemeWrapper>
|
|
816
|
-
<SheetContent side="right">
|
|
817
|
-
<SheetHeader>
|
|
818
|
-
<SheetTitle>Sheet Demo</SheetTitle>
|
|
819
|
-
</SheetHeader>
|
|
820
|
-
<div className="py-4">Màu tối đồng bộ hoàn hảo!</div>
|
|
821
|
-
</SheetContent>
|
|
822
|
-
</ThemeWrapper>
|
|
823
|
-
</SheetPortal>
|
|
824
|
-
</Sheet>
|
|
825
|
-
</div>
|
|
884
|
+
</ThemeWrapper>
|
|
885
|
+
</SheetPortal>
|
|
886
|
+
</Sheet>
|
|
826
887
|
</div>
|
|
827
|
-
</
|
|
828
|
-
</
|
|
888
|
+
</div>
|
|
889
|
+
</ThemeProvider>
|
|
890
|
+
</ExampleSection>
|
|
829
891
|
</div>
|
|
830
892
|
);
|
|
831
893
|
}
|
|
@@ -845,8 +907,8 @@ export default function ThemeProviderShowcase() {
|
|
|
845
907
|
<DocsCode>ThemeProvider</DocsCode> bọc children trong một{" "}
|
|
846
908
|
<DocsCode>{"div[display:contents]"}</DocsCode> và gắn class{" "}
|
|
847
909
|
<DocsCode>light</DocsCode> hoặc <DocsCode>dark</DocsCode> lên đó,
|
|
848
|
-
kích hoạt CSS variable cascade mà không ảnh hưởng layout. Hỗ trợ
|
|
849
|
-
|
|
910
|
+
kích hoạt CSS variable cascade mà không ảnh hưởng layout. Hỗ trợ hai
|
|
911
|
+
chế độ: <strong>Uncontrolled</strong> (truyền{" "}
|
|
850
912
|
<DocsCode>defaultMode</DocsCode> — tự quản lý state) và{" "}
|
|
851
913
|
<strong>Controlled</strong> (truyền <DocsCode>mode</DocsCode> +{" "}
|
|
852
914
|
<DocsCode>onModeChange</DocsCode> — state do component cha sở hữu).
|
|
@@ -859,8 +921,8 @@ export default function ThemeProviderShowcase() {
|
|
|
859
921
|
React component tree. Khi một component render qua Portal (ra{" "}
|
|
860
922
|
<DocsCode>document.body</DocsCode>), nó thoát khỏi hoàn toàn chuỗi
|
|
861
923
|
DOM ancestry — không còn tổ tiên nào mang class{" "}
|
|
862
|
-
<DocsCode>.dark</DocsCode>, và mọi CSS variable rơi thẳng về giá
|
|
863
|
-
|
|
924
|
+
<DocsCode>.dark</DocsCode>, và mọi CSS variable rơi thẳng về giá trị{" "}
|
|
925
|
+
<DocsCode>:root</DocsCode> (thường là light).
|
|
864
926
|
</DocsP>
|
|
865
927
|
<DocsP>
|
|
866
928
|
<DocsCode>ThemeWrapper</DocsCode> giải quyết vấn đề này bằng cách
|
|
@@ -875,10 +937,10 @@ export default function ThemeProviderShowcase() {
|
|
|
875
937
|
runtime warning, nhưng UI sẽ hiển thị sai màu âm thầm.
|
|
876
938
|
</DocsP>
|
|
877
939
|
<DocsP>
|
|
878
|
-
Trách nhiệm đặt <DocsCode>ThemeWrapper</DocsCode> không thể
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
940
|
+
Trách nhiệm đặt <DocsCode>ThemeWrapper</DocsCode> không thể delegate
|
|
941
|
+
tuỳ tiện: Micro component không được tự ôm nó bên trong (vi phạm
|
|
942
|
+
nguyên tắc pure composition). Tầng nào kiểm soát Portal — Macro
|
|
943
|
+
component hoặc consumer trực tiếp — tầng đó phải tự đặt{" "}
|
|
882
944
|
<DocsCode>ThemeWrapper</DocsCode> ngay sau Portal boundary.
|
|
883
945
|
</DocsP>
|
|
884
946
|
</ShowcaseDocs>
|