warqadui 0.0.6 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +62 -10
- package/.vscode/settings.json +0 -3
- package/apps/dev-app/.env +0 -1
- package/apps/dev-app/errors.log +0 -0
- package/apps/dev-app/index.html +0 -12
- package/apps/dev-app/node_modules/.vite/deps/@tanstack_react-table.js +0 -3254
- package/apps/dev-app/node_modules/.vite/deps/@tanstack_react-table.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/_metadata.json +0 -178
- package/apps/dev-app/node_modules/.vite/deps/antd.js +0 -108982
- package/apps/dev-app/node_modules/.vite/deps/antd.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/axios.js +0 -2751
- package/apps/dev-app/node_modules/.vite/deps/axios.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-5OG7DCD7.js +0 -41
- package/apps/dev-app/node_modules/.vite/deps/chunk-5OG7DCD7.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-7YRZYZRE.js +0 -7807
- package/apps/dev-app/node_modules/.vite/deps/chunk-7YRZYZRE.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-DC5AMYBS.js +0 -39
- package/apps/dev-app/node_modules/.vite/deps/chunk-DC5AMYBS.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-DKXRQMOD.js +0 -135
- package/apps/dev-app/node_modules/.vite/deps/chunk-DKXRQMOD.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-EL47BWQR.js +0 -37
- package/apps/dev-app/node_modules/.vite/deps/chunk-EL47BWQR.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-HHL3MHGV.js +0 -288
- package/apps/dev-app/node_modules/.vite/deps/chunk-HHL3MHGV.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-IGGUWUPT.js +0 -60
- package/apps/dev-app/node_modules/.vite/deps/chunk-IGGUWUPT.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-IGXZPJXT.js +0 -928
- package/apps/dev-app/node_modules/.vite/deps/chunk-IGXZPJXT.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-L2GCM37S.js +0 -21628
- package/apps/dev-app/node_modules/.vite/deps/chunk-L2GCM37S.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-LDRT62EN.js +0 -14806
- package/apps/dev-app/node_modules/.vite/deps/chunk-LDRT62EN.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-M7DZDBHW.js +0 -14
- package/apps/dev-app/node_modules/.vite/deps/chunk-M7DZDBHW.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-S54SBVCU.js +0 -1906
- package/apps/dev-app/node_modules/.vite/deps/chunk-S54SBVCU.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/chunk-WFNHCR67.js +0 -21
- package/apps/dev-app/node_modules/.vite/deps/chunk-WFNHCR67.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/clsx.js +0 -10
- package/apps/dev-app/node_modules/.vite/deps/clsx.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/dayjs.js +0 -6
- package/apps/dev-app/node_modules/.vite/deps/dayjs.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/dayjs_plugin_customParseFormat.js +0 -6
- package/apps/dev-app/node_modules/.vite/deps/dayjs_plugin_customParseFormat.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/framer-motion.js +0 -12388
- package/apps/dev-app/node_modules/.vite/deps/framer-motion.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/html2canvas-pro.js +0 -9713
- package/apps/dev-app/node_modules/.vite/deps/html2canvas-pro.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/html2canvas.esm-VL7GM4AH.js +0 -8
- package/apps/dev-app/node_modules/.vite/deps/html2canvas.esm-VL7GM4AH.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/index.es-3WTXOFZ2.js +0 -10392
- package/apps/dev-app/node_modules/.vite/deps/index.es-3WTXOFZ2.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/jspdf.js +0 -41
- package/apps/dev-app/node_modules/.vite/deps/jspdf.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/lucide-react.js +0 -31586
- package/apps/dev-app/node_modules/.vite/deps/lucide-react.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/package.json +0 -3
- package/apps/dev-app/node_modules/.vite/deps/purify.es-JNLDEIMX.js +0 -1029
- package/apps/dev-app/node_modules/.vite/deps/purify.es-JNLDEIMX.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-dom.js +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-dom.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-dom_client.js +0 -8
- package/apps/dev-app/node_modules/.vite/deps/react-dom_client.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-hook-form.js +0 -2233
- package/apps/dev-app/node_modules/.vite/deps/react-hook-form.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-phone-number-input.js +0 -9307
- package/apps/dev-app/node_modules/.vite/deps/react-phone-number-input.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-router-dom.js +0 -14234
- package/apps/dev-app/node_modules/.vite/deps/react-router-dom.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react-to-pdf.js +0 -268
- package/apps/dev-app/node_modules/.vite/deps/react-to-pdf.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react.js +0 -6
- package/apps/dev-app/node_modules/.vite/deps/react.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react_jsx-dev-runtime.js +0 -913
- package/apps/dev-app/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react_jsx-runtime.js +0 -7
- package/apps/dev-app/node_modules/.vite/deps/react_jsx-runtime.js.map +0 -7
- package/apps/dev-app/node_modules/.vite/deps/tailwind-merge.js +0 -2534
- package/apps/dev-app/node_modules/.vite/deps/tailwind-merge.js.map +0 -7
- package/apps/dev-app/node_modules/tailwindcss/LICENSE +0 -21
- package/apps/dev-app/node_modules/tailwindcss/README.md +0 -36
- package/apps/dev-app/node_modules/tailwindcss/dist/chunk-L5IEUH3R.mjs +0 -38
- package/apps/dev-app/node_modules/tailwindcss/dist/chunk-UWKE2Z6N.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/chunk-X4GG3EDV.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/colors-C__qRT83.d.ts +0 -347
- package/apps/dev-app/node_modules/tailwindcss/dist/colors.d.mts +0 -347
- package/apps/dev-app/node_modules/tailwindcss/dist/colors.d.ts +0 -5
- package/apps/dev-app/node_modules/tailwindcss/dist/colors.js +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/colors.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.d.mts +0 -1199
- package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.d.ts +0 -1199
- package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.js +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/default-theme.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.d.mts +0 -6
- package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.d.ts +0 -6
- package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.js +0 -3
- package/apps/dev-app/node_modules/tailwindcss/dist/flatten-color-palette.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/lib.d.mts +0 -378
- package/apps/dev-app/node_modules/tailwindcss/dist/lib.d.ts +0 -3
- package/apps/dev-app/node_modules/tailwindcss/dist/lib.js +0 -38
- package/apps/dev-app/node_modules/tailwindcss/dist/lib.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/plugin.d.mts +0 -11
- package/apps/dev-app/node_modules/tailwindcss/dist/plugin.d.ts +0 -134
- package/apps/dev-app/node_modules/tailwindcss/dist/plugin.js +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/plugin.mjs +0 -1
- package/apps/dev-app/node_modules/tailwindcss/dist/resolve-config-B4yBzhca.d.ts +0 -29
- package/apps/dev-app/node_modules/tailwindcss/dist/resolve-config-QUZ9b-Gn.d.mts +0 -190
- package/apps/dev-app/node_modules/tailwindcss/dist/types-CJYAW1ql.d.mts +0 -128
- package/apps/dev-app/node_modules/tailwindcss/index.css +0 -944
- package/apps/dev-app/node_modules/tailwindcss/package.json +0 -89
- package/apps/dev-app/node_modules/tailwindcss/preflight.css +0 -393
- package/apps/dev-app/node_modules/tailwindcss/theme.css +0 -510
- package/apps/dev-app/node_modules/tailwindcss/utilities.css +0 -1
- package/apps/dev-app/package.json +0 -35
- package/apps/dev-app/src/App.tsx +0 -74
- package/apps/dev-app/src/index.css +0 -18
- package/apps/dev-app/src/main.tsx +0 -18
- package/apps/dev-app/src/pages/Buttons.tsx +0 -122
- package/apps/dev-app/src/pages/DataTable.tsx +0 -208
- package/apps/dev-app/src/pages/Fields.tsx +0 -342
- package/apps/dev-app/src/pages/Modals.tsx +0 -151
- package/apps/dev-app/src/pages/Spins.tsx +0 -161
- package/apps/dev-app/ts_errors.txt +0 -0
- package/apps/dev-app/tsconfig.json +0 -25
- package/apps/dev-app/tsconfig.node.json +0 -10
- package/apps/dev-app/vite.config.ts +0 -11
- package/packages/ui/dist/index.css +0 -3
- package/packages/ui/log.txt +0 -0
- package/packages/ui/package.json +0 -68
- package/packages/ui/postcss.config.js +0 -6
- package/packages/ui/src/components/Button.tsx +0 -85
- package/packages/ui/src/components/Card.tsx +0 -97
- package/packages/ui/src/components/CodeBlock.tsx +0 -53
- package/packages/ui/src/components/DashboardLayout.tsx +0 -442
- package/packages/ui/src/components/Fields/Input.tsx +0 -191
- package/packages/ui/src/components/Fields/PhoneInput.tsx +0 -134
- package/packages/ui/src/components/Fields/date.tsx +0 -165
- package/packages/ui/src/components/Fields/index.tsx +0 -17
- package/packages/ui/src/components/Fields/searchApi.tsx +0 -479
- package/packages/ui/src/components/Fields/select.tsx +0 -131
- package/packages/ui/src/components/Fields/textArea.tsx +0 -121
- package/packages/ui/src/components/LoadingBox.tsx +0 -11
- package/packages/ui/src/components/PageHeader.tsx +0 -34
- package/packages/ui/src/components/ThemeToggle.tsx +0 -35
- package/packages/ui/src/components/modal/Modal.tsx +0 -81
- package/packages/ui/src/components/spins/ClassicSpin.tsx +0 -18
- package/packages/ui/src/components/spins/LoadingSpin.tsx +0 -45
- package/packages/ui/src/components/spins/OverlaySpin.tsx +0 -10
- package/packages/ui/src/components/spins/index.tsx +0 -13
- package/packages/ui/src/components/tables/DataTable.tsx +0 -261
- package/packages/ui/src/components/tables/index.ts +0 -1
- package/packages/ui/src/hooks/Fetches/useApis.tsx +0 -197
- package/packages/ui/src/hooks/ThemeContext.tsx +0 -56
- package/packages/ui/src/hooks/useModal.tsx +0 -38
- package/packages/ui/src/hooks/useTheme.ts +0 -34
- package/packages/ui/src/index.ts +0 -24
- package/packages/ui/src/providers/WarqadProvider.tsx +0 -69
- package/packages/ui/src/styles.css +0 -26
- package/packages/ui/src/utils/cn.ts +0 -6
- package/packages/ui/src/utils/pdf.ts +0 -171
- package/packages/ui/tailwind.config.js +0 -13
- package/packages/ui/tsconfig.json +0 -17
- package/packages/ui/warqad-ui-0.0.1.tgz +0 -0
- package/packages/ui/warqadui-0.0.3.tgz +0 -0
- package/warqad-ui-0.0.1.tgz +0 -0
- /package/{packages/ui/dist → dist}/index.d.mts +0 -0
- /package/{packages/ui/dist → dist}/index.d.ts +0 -0
- /package/{packages/ui/dist → dist}/index.js +0 -0
- /package/{packages/ui/dist → dist}/index.mjs +0 -0
- /package/{packages/ui/dist → dist}/styles.d.mts +0 -0
- /package/{packages/ui/dist → dist}/styles.d.ts +0 -0
- /package/{packages/ui/dist → dist}/styles.js +0 -0
- /package/{packages/ui/dist → dist}/styles.mjs +0 -0
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
Modal,
|
|
4
|
-
Button,
|
|
5
|
-
CodeBlock,
|
|
6
|
-
Card,
|
|
7
|
-
LoadingSpin,
|
|
8
|
-
PageHeader,
|
|
9
|
-
useModal,
|
|
10
|
-
} from "warqadui";
|
|
11
|
-
|
|
12
|
-
const ModalsShowcase = () => {
|
|
13
|
-
const basicModal = useModal();
|
|
14
|
-
const loadingModal = useModal();
|
|
15
|
-
const [isModalLoading, setIsModalLoading] = useState(false);
|
|
16
|
-
|
|
17
|
-
const triggerLoadingModal = () => {
|
|
18
|
-
loadingModal.open();
|
|
19
|
-
setIsModalLoading(true);
|
|
20
|
-
setTimeout(() => setIsModalLoading(false), 3000);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const importCode = `import { Modal, useModalBox } from "warqadui";`;
|
|
24
|
-
|
|
25
|
-
const hookUsageCode = `const modal = useModalBox();\n\n<Button onClick={modal.open}>Open</Button>\n\n<Modal \n isOpen={modal.isOpen} \n onClose={modal.close} \n title="Title"\n>\n Content\n</Modal>`;
|
|
26
|
-
|
|
27
|
-
const loadingUsageCode = `<Modal \n isOpen={isOpen} \n onClose={onClose} \n title="Processing"\n isLoading={true}\n>\n Blurred content...\n</Modal>`;
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<div className="p-8 space-y-12 pb-20">
|
|
31
|
-
<PageHeader
|
|
32
|
-
title="Modals"
|
|
33
|
-
description="Premium, animated dialogs with built-in loading states and iOS-inspired aesthetics."
|
|
34
|
-
/>
|
|
35
|
-
|
|
36
|
-
{/* Quick Start */}
|
|
37
|
-
<section className="space-y-4">
|
|
38
|
-
<h2 className="text-xl font-bold">Usage</h2>
|
|
39
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
|
|
40
|
-
<Card variant="flat" className="space-y-3">
|
|
41
|
-
<p className="text-sm font-medium">1. Simple Import</p>
|
|
42
|
-
<CodeBlock code={importCode} />
|
|
43
|
-
</Card>
|
|
44
|
-
<Card variant="flat" className="space-y-3">
|
|
45
|
-
<p className="text-sm font-medium">
|
|
46
|
-
2. Recommended: useModalBox hook
|
|
47
|
-
</p>
|
|
48
|
-
<CodeBlock code={hookUsageCode} className="text-xs" />
|
|
49
|
-
</Card>
|
|
50
|
-
</div>
|
|
51
|
-
</section>
|
|
52
|
-
|
|
53
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
|
54
|
-
<Card className="flex flex-col justify-between">
|
|
55
|
-
<div>
|
|
56
|
-
<Card.Header>
|
|
57
|
-
<Card.Title>Basic Modal</Card.Title>
|
|
58
|
-
<Card.Description>
|
|
59
|
-
Simple dialog with a title and close button.
|
|
60
|
-
</Card.Description>
|
|
61
|
-
</Card.Header>
|
|
62
|
-
<Card.Content className="pb-6">
|
|
63
|
-
<Button
|
|
64
|
-
onClick={basicModal.open}
|
|
65
|
-
variant="primary"
|
|
66
|
-
className="w-full"
|
|
67
|
-
>
|
|
68
|
-
Open Basic Modal
|
|
69
|
-
</Button>
|
|
70
|
-
</Card.Content>
|
|
71
|
-
</div>
|
|
72
|
-
<CodeBlock
|
|
73
|
-
code={buttonUsageHtml(basicModal.isOpen)}
|
|
74
|
-
className="text-xs"
|
|
75
|
-
/>
|
|
76
|
-
</Card>
|
|
77
|
-
|
|
78
|
-
<Card className="flex flex-col justify-between">
|
|
79
|
-
<div>
|
|
80
|
-
<Card.Header>
|
|
81
|
-
<Card.Title>Loading State</Card.Title>
|
|
82
|
-
<Card.Description>
|
|
83
|
-
Built-in loading overlay that blurs and protects content.
|
|
84
|
-
</Card.Description>
|
|
85
|
-
</Card.Header>
|
|
86
|
-
<Card.Content className="pb-6">
|
|
87
|
-
<Button
|
|
88
|
-
onClick={triggerLoadingModal}
|
|
89
|
-
variant="secondary"
|
|
90
|
-
className="w-full"
|
|
91
|
-
>
|
|
92
|
-
Open Loading Modal (3s)
|
|
93
|
-
</Button>
|
|
94
|
-
</Card.Content>
|
|
95
|
-
</div>
|
|
96
|
-
<CodeBlock code={loadingUsageCode} className="text-xs" />
|
|
97
|
-
</Card>
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<Modal
|
|
101
|
-
isOpen={basicModal.isOpen}
|
|
102
|
-
onClose={basicModal.close}
|
|
103
|
-
title="Welcome to Warqad"
|
|
104
|
-
>
|
|
105
|
-
<div className="space-y-4">
|
|
106
|
-
<p className="text-gray-600 dark:text-gray-400 leading-relaxed">
|
|
107
|
-
This modal features a premium{" "}
|
|
108
|
-
<span className="text-indigo-500 font-medium">squircle</span>{" "}
|
|
109
|
-
rounding and smooth entrance.
|
|
110
|
-
</p>
|
|
111
|
-
<Button
|
|
112
|
-
onClick={basicModal.close}
|
|
113
|
-
variant="primary"
|
|
114
|
-
className="w-full"
|
|
115
|
-
>
|
|
116
|
-
Got it, thanks!
|
|
117
|
-
</Button>
|
|
118
|
-
</div>
|
|
119
|
-
</Modal>
|
|
120
|
-
|
|
121
|
-
<Modal
|
|
122
|
-
isOpen={loadingModal.isOpen}
|
|
123
|
-
onClose={loadingModal.close}
|
|
124
|
-
title="System Update"
|
|
125
|
-
isLoading={isModalLoading}
|
|
126
|
-
>
|
|
127
|
-
<div className="space-y-4">
|
|
128
|
-
<div className="flex items-center gap-3 p-4 bg-blue-50 dark:bg-blue-500/10 rounded-2xl text-blue-700 dark:text-blue-400">
|
|
129
|
-
<LoadingSpin size="sm" />
|
|
130
|
-
<span className="text-sm font-medium">
|
|
131
|
-
Synchronizing with cloud...
|
|
132
|
-
</span>
|
|
133
|
-
</div>
|
|
134
|
-
<Button
|
|
135
|
-
onClick={loadingModal.close}
|
|
136
|
-
variant="outline"
|
|
137
|
-
className="w-full"
|
|
138
|
-
disabled={isModalLoading}
|
|
139
|
-
>
|
|
140
|
-
Cancel Process
|
|
141
|
-
</Button>
|
|
142
|
-
</div>
|
|
143
|
-
</Modal>
|
|
144
|
-
</div>
|
|
145
|
-
);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const buttonUsageHtml = (isOpen: boolean) =>
|
|
149
|
-
`<Modal \n isOpen={${isOpen}} \n onClose={() => {}} \n title="..."\n>\n ...\n</Modal>`;
|
|
150
|
-
|
|
151
|
-
export default ModalsShowcase;
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
ClassicSpin,
|
|
4
|
-
OverlaySpin,
|
|
5
|
-
LoadingSpin,
|
|
6
|
-
Button,
|
|
7
|
-
CodeBlock,
|
|
8
|
-
Card,
|
|
9
|
-
PageHeader,
|
|
10
|
-
} from "warqadui";
|
|
11
|
-
|
|
12
|
-
const SpinsShowcase = () => {
|
|
13
|
-
const [showClassic, setShowClassic] = useState(false);
|
|
14
|
-
const [showOverlay, setShowOverlay] = useState(false);
|
|
15
|
-
|
|
16
|
-
const triggerClassic = () => {
|
|
17
|
-
setShowClassic(true);
|
|
18
|
-
setTimeout(() => setShowClassic(false), 3000);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const triggerOverlay = () => {
|
|
22
|
-
setShowOverlay(true);
|
|
23
|
-
setTimeout(() => setShowOverlay(false), 3000);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const importCode = `import { \n ClassicSpin, \n OverlaySpin, \n LoadingSpin \n} from "warqadui";`;
|
|
27
|
-
|
|
28
|
-
const classicCode = `<ClassicSpin msg="Loading dashboard..." />`;
|
|
29
|
-
|
|
30
|
-
const overlayCode = `<div className="relative h-64">\n {/* Content */}\n {isLoading && <OverlaySpin msg="Saving changes..." />}\n</div>`;
|
|
31
|
-
|
|
32
|
-
const rawCode = `<LoadingSpin \n size="md" \n className="text-blue-600" \n/>`;
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className="p-8 space-y-12 pb-20">
|
|
36
|
-
<PageHeader
|
|
37
|
-
title="Spins & Loaders"
|
|
38
|
-
description="A collection of premium loading states designed for the Warqad ecosystem. Includes full-page modals, container-aware overlays, and raw SVG spinners."
|
|
39
|
-
/>
|
|
40
|
-
|
|
41
|
-
{/* Quick Start Documentation */}
|
|
42
|
-
<section className="space-y-4">
|
|
43
|
-
<h2 className="text-xl font-bold flex items-center gap-2"> Usage </h2>
|
|
44
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-start">
|
|
45
|
-
<Card variant="flat">
|
|
46
|
-
<p className="text-sm text-gray-600 dark:text-gray-400 font-medium mb-3">
|
|
47
|
-
1. Import components:
|
|
48
|
-
</p>
|
|
49
|
-
<CodeBlock code={importCode} />
|
|
50
|
-
</Card>
|
|
51
|
-
<Card variant="flat">
|
|
52
|
-
<p className="text-sm text-gray-600 dark:text-gray-400 font-medium mb-3">
|
|
53
|
-
2. Example Usage:
|
|
54
|
-
</p>
|
|
55
|
-
<CodeBlock code={rawCode} />
|
|
56
|
-
</Card>
|
|
57
|
-
</div>
|
|
58
|
-
</section>
|
|
59
|
-
|
|
60
|
-
<section>
|
|
61
|
-
<h2 className="text-xl font-bold mb-6">Live Demos</h2>
|
|
62
|
-
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
63
|
-
{/* Classic Spin Card */}
|
|
64
|
-
<Card className="relative overflow-hidden group">
|
|
65
|
-
<Card.Header>
|
|
66
|
-
<Card.Title>Classic Spin</Card.Title>
|
|
67
|
-
<Card.Description>
|
|
68
|
-
Centered modal indicator for full-page or section loading.
|
|
69
|
-
</Card.Description>
|
|
70
|
-
</Card.Header>
|
|
71
|
-
<Card.Content className="space-y-4">
|
|
72
|
-
<Button
|
|
73
|
-
onClick={triggerClassic}
|
|
74
|
-
variant="primary"
|
|
75
|
-
className="w-full"
|
|
76
|
-
>
|
|
77
|
-
Preview (3s)
|
|
78
|
-
</Button>
|
|
79
|
-
<CodeBlock code={classicCode} className="text-[11px]" />
|
|
80
|
-
</Card.Content>
|
|
81
|
-
|
|
82
|
-
{showClassic && <ClassicSpin msg="Loading dashboard..." />}
|
|
83
|
-
</Card>
|
|
84
|
-
|
|
85
|
-
{/* Overlay Spin Card */}
|
|
86
|
-
<Card className="relative overflow-hidden group">
|
|
87
|
-
<Card.Header>
|
|
88
|
-
<Card.Title>Overlay Spin</Card.Title>
|
|
89
|
-
<Card.Description>
|
|
90
|
-
Container-bound overlay. Parent must be{" "}
|
|
91
|
-
<code className="text-[10px] px-1 bg-gray-100 dark:bg-gray-700 rounded text-blue-500">
|
|
92
|
-
relative
|
|
93
|
-
</code>
|
|
94
|
-
.
|
|
95
|
-
</Card.Description>
|
|
96
|
-
</Card.Header>
|
|
97
|
-
<Card.Content className="space-y-4">
|
|
98
|
-
<div className="relative h-24 w-full bg-gray-50 dark:bg-gray-900 rounded-xl flex items-center justify-center border border-dashed border-gray-300 dark:border-gray-600">
|
|
99
|
-
<span className="text-xs text-gray-400">Content Area</span>
|
|
100
|
-
{showOverlay && <OverlaySpin msg="Saving changes..." />}
|
|
101
|
-
</div>
|
|
102
|
-
<Button
|
|
103
|
-
onClick={triggerOverlay}
|
|
104
|
-
variant="secondary"
|
|
105
|
-
className="w-full"
|
|
106
|
-
>
|
|
107
|
-
Preview (3s)
|
|
108
|
-
</Button>
|
|
109
|
-
<CodeBlock code={overlayCode} className="text-[10px]" />
|
|
110
|
-
</Card.Content>
|
|
111
|
-
</Card>
|
|
112
|
-
|
|
113
|
-
{/* Raw LoadingSpin Card */}
|
|
114
|
-
<Card className="flex flex-col justify-between">
|
|
115
|
-
<div>
|
|
116
|
-
<Card.Header>
|
|
117
|
-
<Card.Title>LoadingSpin</Card.Title>
|
|
118
|
-
<Card.Description>
|
|
119
|
-
Lightweight SVG spinner for inline placements.
|
|
120
|
-
</Card.Description>
|
|
121
|
-
</Card.Header>
|
|
122
|
-
<Card.Content>
|
|
123
|
-
<div className="flex items-center justify-between bg-gray-50 dark:bg-gray-900 p-4 rounded-xl mb-4">
|
|
124
|
-
<div className="flex flex-col items-center gap-1">
|
|
125
|
-
<LoadingSpin size="sm" className="text-blue-500" />
|
|
126
|
-
<span className="text-[10px] text-gray-400">Small</span>
|
|
127
|
-
</div>
|
|
128
|
-
<div className="flex flex-col items-center gap-1">
|
|
129
|
-
<LoadingSpin size="md" className="text-indigo-500" />
|
|
130
|
-
<span className="text-[10px] text-gray-400">Medium</span>
|
|
131
|
-
</div>
|
|
132
|
-
<div className="flex flex-col items-center gap-1">
|
|
133
|
-
<LoadingSpin size="lg" className="text-purple-500" />
|
|
134
|
-
<span className="text-[10px] text-gray-400">Large</span>
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
</Card.Content>
|
|
138
|
-
</div>
|
|
139
|
-
<CodeBlock code={rawCode} className="text-[11px]" />
|
|
140
|
-
</Card>
|
|
141
|
-
</div>
|
|
142
|
-
</section>
|
|
143
|
-
|
|
144
|
-
<Card
|
|
145
|
-
variant="glass"
|
|
146
|
-
className="bg-blue-50/50 dark:bg-blue-900/10 border-blue-100 dark:border-blue-900/20"
|
|
147
|
-
>
|
|
148
|
-
<Card.Title className="text-blue-900 dark:text-blue-400 mb-2">
|
|
149
|
-
Documentation Note
|
|
150
|
-
</Card.Title>
|
|
151
|
-
<Card.Description className="text-blue-700 dark:text-blue-600">
|
|
152
|
-
The <code>CodeBlock</code> and <code>Card</code> components above are
|
|
153
|
-
also part of the <strong>warqadui</strong> package. Use them to build
|
|
154
|
-
beautiful documentation or high-end dashboard interfaces.
|
|
155
|
-
</Card.Description>
|
|
156
|
-
</Card>
|
|
157
|
-
</div>
|
|
158
|
-
);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
export default SpinsShowcase;
|
|
Binary file
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
|
|
9
|
-
/* Bundler mode */
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"allowImportingTsExtensions": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
"jsx": "react-jsx",
|
|
16
|
-
|
|
17
|
-
/* Linting */
|
|
18
|
-
"strict": true,
|
|
19
|
-
"noUnusedLocals": true,
|
|
20
|
-
"noUnusedParameters": true,
|
|
21
|
-
"noFallthroughCasesInSwitch": true
|
|
22
|
-
},
|
|
23
|
-
"include": ["src"],
|
|
24
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
25
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
import react from "@vitejs/plugin-react";
|
|
3
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
-
|
|
5
|
-
// https://vitejs.dev/config/
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
plugins: [react(), tailwindcss()],
|
|
8
|
-
server: {
|
|
9
|
-
port: 3000,
|
|
10
|
-
},
|
|
11
|
-
});
|
package/packages/ui/log.txt
DELETED
|
Binary file
|
package/packages/ui/package.json
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "warqadui",
|
|
3
|
-
"version": "0.0.5",
|
|
4
|
-
"main": "./src/index.ts",
|
|
5
|
-
"module": "./src/index.ts",
|
|
6
|
-
"types": "./src/index.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"types": "./src/index.ts",
|
|
10
|
-
"import": "./src/index.ts",
|
|
11
|
-
"default": "./src/index.ts"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"dist"
|
|
16
|
-
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "tsup src/index.ts src/styles.css --format esm,cjs --dts --injectStyle",
|
|
19
|
-
"dev": "tsup src/index.ts src/styles.css --format esm,cjs --dts --watch --injectStyle",
|
|
20
|
-
"prepublish": "npm run build"
|
|
21
|
-
},
|
|
22
|
-
"peerDependencies": {
|
|
23
|
-
"@tanstack/react-table": "^8.12.0",
|
|
24
|
-
"antd": "^6.3.1",
|
|
25
|
-
"axios": "^1.6.0",
|
|
26
|
-
"framer-motion": ">=10",
|
|
27
|
-
"react": ">=18",
|
|
28
|
-
"react-dom": ">=18",
|
|
29
|
-
"react-hook-form": ">=7",
|
|
30
|
-
"react-phone-number-input": ">=3.4.0",
|
|
31
|
-
"react-router-dom": ">=6",
|
|
32
|
-
"tailwindcss": ">=3.4.0"
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"clsx": "^2.1.0",
|
|
36
|
-
"dayjs": "^1.11.10",
|
|
37
|
-
"html2canvas-pro": "^2.0.2",
|
|
38
|
-
"jspdf": "^4.2.0",
|
|
39
|
-
"lucide-react": "^0.344.0",
|
|
40
|
-
"moment": "^2.30.1",
|
|
41
|
-
"react-to-pdf": "^3.2.1",
|
|
42
|
-
"tailwind-merge": "^2.2.1",
|
|
43
|
-
"zod": "^3.22.4",
|
|
44
|
-
"zustand": "^4.5.0"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"@tanstack/react-table": "^8.12.0",
|
|
48
|
-
"@types/react": "^18.2.55",
|
|
49
|
-
"@types/react-dom": "^18.2.19",
|
|
50
|
-
"@types/react-router-dom": "^5.3.3",
|
|
51
|
-
"antd": "^6.3.1",
|
|
52
|
-
"autoprefixer": "^10.4.17",
|
|
53
|
-
"axios": "^1.6.0",
|
|
54
|
-
"clsx": "^2.1.0",
|
|
55
|
-
"dayjs": "^1.11.10",
|
|
56
|
-
"lucide-react": "^0.344.0",
|
|
57
|
-
"moment": "^2.30.1",
|
|
58
|
-
"postcss": "^8.4.35",
|
|
59
|
-
"react-hook-form": "^7.51.0",
|
|
60
|
-
"react-phone-number-input": "^3.4.0",
|
|
61
|
-
"tailwind-merge": "^2.2.1",
|
|
62
|
-
"tailwindcss": "^3.4.1",
|
|
63
|
-
"tsup": "^8.0.2",
|
|
64
|
-
"typescript": "^5.3.3",
|
|
65
|
-
"zod": "^3.22.4",
|
|
66
|
-
"zustand": "^4.5.0"
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { cn } from "../utils/cn";
|
|
3
|
-
|
|
4
|
-
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
5
|
-
variant?:
|
|
6
|
-
| "primary"
|
|
7
|
-
| "secondary"
|
|
8
|
-
| "outline"
|
|
9
|
-
| "ghost"
|
|
10
|
-
| "danger"
|
|
11
|
-
| "warning";
|
|
12
|
-
size?: "sm" | "md" | "lg";
|
|
13
|
-
isLoading?: boolean;
|
|
14
|
-
icon?: React.ReactNode;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const Button: React.FC<ButtonProps> = ({
|
|
18
|
-
children,
|
|
19
|
-
className,
|
|
20
|
-
variant = "primary",
|
|
21
|
-
size = "md",
|
|
22
|
-
isLoading,
|
|
23
|
-
icon,
|
|
24
|
-
...props
|
|
25
|
-
}) => {
|
|
26
|
-
const variants: Record<NonNullable<ButtonProps["variant"]>, string> = {
|
|
27
|
-
primary:
|
|
28
|
-
"bg-[#007AFF] text-white hover:bg-[#0071e3] active:scale-[0.98] active:opacity-90 shadow-[0_1px_2px_rgba(0,0,0,0.1)] focus:ring-[#007AFF]",
|
|
29
|
-
secondary:
|
|
30
|
-
"bg-[#F5F5F7] text-[#1D1D1F] hover:bg-[#E8E8ED] dark:bg-[#FFFFFF]/10 dark:text-[#F5F5F7] dark:hover:bg-[#FFFFFF]/15 active:scale-[0.98] focus:ring-gray-400",
|
|
31
|
-
outline:
|
|
32
|
-
"border border-gray-200 dark:border-gray-800 bg-white/50 dark:bg-black/50 backdrop-blur-md text-[#1D1D1F] dark:text-white hover:bg-gray-50 dark:hover:bg-gray-900 active:scale-[0.98] focus:ring-gray-400",
|
|
33
|
-
ghost:
|
|
34
|
-
"bg-transparent text-[#007AFF] hover:bg-[#007AFF]/10 active:scale-[0.98] focus:ring-[#007AFF]",
|
|
35
|
-
danger:
|
|
36
|
-
"bg-[#FF3B30] text-white hover:bg-[#E03126] active:scale-[0.98] active:opacity-90 shadow-[0_1px_2px_rgba(0,0,0,0.1)] focus:ring-[#FF3B30]",
|
|
37
|
-
warning:
|
|
38
|
-
"bg-[#FF9500] text-white hover:bg-[#E68600] active:scale-[0.98] active:opacity-90 shadow-[0_1px_2px_rgba(0,0,0,0.1)] focus:ring-[#FF9500]",
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const sizes: Record<NonNullable<ButtonProps["size"]>, string> = {
|
|
42
|
-
sm: "px-3 py-1.5 text-sm rounded-[10px] gap-1.5 font-medium",
|
|
43
|
-
md: "px-5 py-2.5 rounded-[12px] gap-2 font-medium tracking-tight",
|
|
44
|
-
lg: "px-7 py-3.5 text-lg rounded-[16px] font-semibold tracking-tight gap-2.5",
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
return (
|
|
48
|
-
<button
|
|
49
|
-
className={cn(
|
|
50
|
-
"inline-flex items-center justify-center transition-all duration-200 ease-out focus:outline-none focus:ring-2 focus:ring-offset-1 disabled:opacity-50 select-none cursor-pointer disabled:cursor-not-allowed",
|
|
51
|
-
variants[variant as keyof typeof variants],
|
|
52
|
-
sizes[size as keyof typeof sizes],
|
|
53
|
-
className,
|
|
54
|
-
)}
|
|
55
|
-
disabled={isLoading || props.disabled}
|
|
56
|
-
{...props}
|
|
57
|
-
>
|
|
58
|
-
{isLoading ? (
|
|
59
|
-
<svg
|
|
60
|
-
className="animate-spin -ml-1 mr-2 h-4 w-4"
|
|
61
|
-
fill="none"
|
|
62
|
-
viewBox="0 0 24 24"
|
|
63
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
64
|
-
>
|
|
65
|
-
<circle
|
|
66
|
-
className="opacity-25"
|
|
67
|
-
cx="12"
|
|
68
|
-
cy="12"
|
|
69
|
-
r="10"
|
|
70
|
-
stroke="currentColor"
|
|
71
|
-
strokeWidth="4"
|
|
72
|
-
/>
|
|
73
|
-
<path
|
|
74
|
-
className="opacity-75"
|
|
75
|
-
fill="currentColor"
|
|
76
|
-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
77
|
-
/>
|
|
78
|
-
</svg>
|
|
79
|
-
) : (
|
|
80
|
-
icon && <span className="flex-shrink-0">{icon}</span>
|
|
81
|
-
)}
|
|
82
|
-
{children}
|
|
83
|
-
</button>
|
|
84
|
-
);
|
|
85
|
-
};
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { cn } from "../utils/cn";
|
|
3
|
-
|
|
4
|
-
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
-
children: React.ReactNode;
|
|
6
|
-
variant?: "default" | "flat" | "glass";
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const Card = ({
|
|
10
|
-
children,
|
|
11
|
-
className,
|
|
12
|
-
variant = "default",
|
|
13
|
-
...props
|
|
14
|
-
}: CardProps) => {
|
|
15
|
-
const variants = {
|
|
16
|
-
default:
|
|
17
|
-
"bg-white dark:bg-zinc-900 border-gray-200 dark:border-zinc-800 shadow-sm",
|
|
18
|
-
flat: "bg-gray-50/50 dark:bg-zinc-950/50 border-gray-100 dark:border-zinc-900",
|
|
19
|
-
glass:
|
|
20
|
-
"bg-white/70 dark:bg-black/40 backdrop-blur-md border-white/20 dark:border-white/5 shadow-xl",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<div
|
|
25
|
-
className={cn(
|
|
26
|
-
"rounded-[2rem] border p-6 transition-all duration-300",
|
|
27
|
-
variants[variant],
|
|
28
|
-
className,
|
|
29
|
-
)}
|
|
30
|
-
{...props}
|
|
31
|
-
>
|
|
32
|
-
{children}
|
|
33
|
-
</div>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const CardHeader = ({
|
|
38
|
-
children,
|
|
39
|
-
className,
|
|
40
|
-
}: {
|
|
41
|
-
children: React.ReactNode;
|
|
42
|
-
className?: string;
|
|
43
|
-
}) => <div className={cn("mb-4 space-y-1.5", className)}>{children}</div>;
|
|
44
|
-
|
|
45
|
-
export const CardTitle = ({
|
|
46
|
-
children,
|
|
47
|
-
className,
|
|
48
|
-
}: {
|
|
49
|
-
children: React.ReactNode;
|
|
50
|
-
className?: string;
|
|
51
|
-
}) => (
|
|
52
|
-
<h3
|
|
53
|
-
className={cn(
|
|
54
|
-
"text-lg font-semibold leading-none tracking-tight text-gray-900 dark:text-gray-100",
|
|
55
|
-
className,
|
|
56
|
-
)}
|
|
57
|
-
>
|
|
58
|
-
{children}
|
|
59
|
-
</h3>
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
export const CardDescription = ({
|
|
63
|
-
children,
|
|
64
|
-
className,
|
|
65
|
-
}: {
|
|
66
|
-
children: React.ReactNode;
|
|
67
|
-
className?: string;
|
|
68
|
-
}) => (
|
|
69
|
-
<p className={cn("text-sm text-gray-500 dark:text-gray-400", className)}>
|
|
70
|
-
{children}
|
|
71
|
-
</p>
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
export const CardContent = ({
|
|
75
|
-
children,
|
|
76
|
-
className,
|
|
77
|
-
}: {
|
|
78
|
-
children: React.ReactNode;
|
|
79
|
-
className?: string;
|
|
80
|
-
}) => <div className={cn("", className)}>{children}</div>;
|
|
81
|
-
|
|
82
|
-
export const CardFooter = ({
|
|
83
|
-
children,
|
|
84
|
-
className,
|
|
85
|
-
}: {
|
|
86
|
-
children: React.ReactNode;
|
|
87
|
-
className?: string;
|
|
88
|
-
}) => (
|
|
89
|
-
<div className={cn("mt-6 flex items-center pt-0", className)}>{children}</div>
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// Attach subcomponents to Card for better DX
|
|
93
|
-
Card.Header = CardHeader;
|
|
94
|
-
Card.Title = CardTitle;
|
|
95
|
-
Card.Description = CardDescription;
|
|
96
|
-
Card.Content = CardContent;
|
|
97
|
-
Card.Footer = CardFooter;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { Check, Copy } from "lucide-react";
|
|
3
|
-
import { cn } from "../utils/cn";
|
|
4
|
-
|
|
5
|
-
interface CodeBlockProps {
|
|
6
|
-
code: string;
|
|
7
|
-
language?: string;
|
|
8
|
-
className?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const CodeBlock: React.FC<CodeBlockProps> = ({
|
|
12
|
-
code,
|
|
13
|
-
language = "tsx",
|
|
14
|
-
className,
|
|
15
|
-
}) => {
|
|
16
|
-
const [copied, setCopied] = useState(false);
|
|
17
|
-
|
|
18
|
-
const handleCopy = () => {
|
|
19
|
-
navigator.clipboard.writeText(code);
|
|
20
|
-
setCopied(true);
|
|
21
|
-
setTimeout(() => setCopied(false), 2000);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<div
|
|
26
|
-
className={cn(
|
|
27
|
-
"relative group rounded-2xl overflow-hidden border border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-black/50 backdrop-blur-sm",
|
|
28
|
-
className,
|
|
29
|
-
)}
|
|
30
|
-
>
|
|
31
|
-
<div className="flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-zinc-900/50 border-b border-gray-200 dark:border-gray-800">
|
|
32
|
-
<span className="text-[10px] font-bold uppercase tracking-widest text-gray-400">
|
|
33
|
-
{language}
|
|
34
|
-
</span>
|
|
35
|
-
<button
|
|
36
|
-
onClick={handleCopy}
|
|
37
|
-
className="p-1.5 rounded-lg text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-white dark:hover:bg-zinc-800 transition-all duration-200"
|
|
38
|
-
>
|
|
39
|
-
{copied ? (
|
|
40
|
-
<Check size={14} className="text-green-500" />
|
|
41
|
-
) : (
|
|
42
|
-
<Copy size={14} />
|
|
43
|
-
)}
|
|
44
|
-
</button>
|
|
45
|
-
</div>
|
|
46
|
-
<div className="p-4 overflow-x-auto">
|
|
47
|
-
<pre className="text-sm font-mono leading-relaxed text-gray-800 dark:text-gray-300">
|
|
48
|
-
{code}
|
|
49
|
-
</pre>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
};
|