@rozenite/storage-plugin 1.13.0 → 2.0.0
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/CHANGELOG.md +28 -0
- package/README.md +6 -1
- package/dist/devtools/assets/panel-B6Wp0eie.css +1 -0
- package/dist/devtools/assets/panel-D7MFc4HG.js +32 -0
- package/dist/devtools/panel.html +2 -2
- package/dist/react-native/chunks/async-storage.require.cjs +1 -1
- package/dist/react-native/chunks/async-storage.require.js +8 -7
- package/dist/react-native/chunks/index.require.cjs +1 -1
- package/dist/react-native/chunks/index.require.js +70 -64
- package/dist/react-native/chunks/secure-storage.require.cjs +1 -1
- package/dist/react-native/chunks/secure-storage.require.js +22 -14
- package/dist/react-native/chunks/useRozeniteStoragePlugin.require.cjs +1 -1
- package/dist/react-native/chunks/useRozeniteStoragePlugin.require.js +863 -315
- package/dist/react-native/index.d.ts +154 -18
- package/dist/react-native/index.js +10 -2
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.cjs +1 -1
- package/dist/sdk/index.d.ts +13 -5
- package/dist/sdk/index.js +21 -12
- package/package.json +13 -15
- package/react-native.ts +29 -14
- package/rozenite.config.ts +78 -0
- package/src/react-native/__tests__/entry-preview-pagination.test.ts +262 -0
- package/src/react-native/__tests__/export-snapshot.test.ts +142 -0
- package/src/react-native/__tests__/full-entry-request.test.ts +155 -0
- package/src/react-native/__tests__/import.test.ts +172 -10
- package/src/react-native/__tests__/storage-discovery.test.ts +155 -0
- package/src/react-native/__tests__/storage-view.test.ts +172 -0
- package/src/react-native/__tests__/stress-verification.test.ts +153 -0
- package/src/react-native/__tests__/use-storage-agent-tools.test.ts +231 -0
- package/src/react-native/adapters/async-storage.ts +9 -7
- package/src/react-native/adapters/mmkv.ts +5 -0
- package/src/react-native/adapters/secure-storage.ts +9 -1
- package/src/react-native/entry-preview-pagination.ts +277 -0
- package/src/react-native/export-snapshot.ts +94 -0
- package/src/react-native/full-entry-request.ts +96 -0
- package/src/react-native/import.ts +190 -16
- package/src/react-native/storage-discovery.ts +96 -0
- package/src/react-native/storage-view.ts +45 -103
- package/src/react-native/useRozeniteStoragePlugin.ts +108 -72
- package/src/react-native/useStorageAgentTools.ts +207 -86
- package/src/shared/__tests__/entry-preview.test.ts +117 -0
- package/src/shared/__tests__/snapshot.test.ts +21 -0
- package/src/shared/agent-tools.ts +27 -11
- package/src/shared/entry-preview.ts +59 -0
- package/src/shared/messaging.ts +136 -21
- package/src/shared/snapshot.ts +8 -1
- package/src/shared/types.ts +20 -1
- package/src/ui/__tests__/binary-value-editor-state.test.ts +13 -0
- package/src/ui/__tests__/binary.test.ts +18 -0
- package/src/ui/__tests__/large-value-viewer-state.test.ts +21 -0
- package/src/ui/__tests__/large-value-viewer.test.tsx +63 -0
- package/src/ui/__tests__/panel.test.tsx +409 -0
- package/src/ui/__tests__/storage-groups.test.ts +91 -0
- package/src/ui/__tests__/use-storage-entries.test.tsx +353 -0
- package/src/ui/add-entry-dialog.tsx +65 -105
- package/src/ui/binary-value-editor-state.ts +10 -1
- package/src/ui/binary-value-editor.tsx +57 -33
- package/src/ui/binary.ts +56 -4
- package/src/ui/edit-entry-dialog.tsx +71 -99
- package/src/ui/editor-switcher.tsx +7 -5
- package/src/ui/entry-detail-dialog.tsx +69 -179
- package/src/ui/format-value.tsx +32 -0
- package/src/ui/globals.css +1 -123
- package/src/ui/import-dialog.tsx +66 -91
- package/src/ui/large-value-viewer-state.ts +32 -0
- package/src/ui/large-value-viewer.tsx +71 -0
- package/src/ui/panel.tsx +724 -496
- package/src/ui/query-client.tsx +34 -0
- package/src/ui/storage-groups.ts +66 -0
- package/src/ui/typed-value-editor.tsx +14 -15
- package/src/ui/use-storage-entries.ts +207 -0
- package/tsconfig.json +5 -1
- package/dist/devtools/assets/panel-Bm-SWF7d.js +0 -33
- package/dist/devtools/assets/panel-DIqI4WSp.css +0 -1
- package/postcss.config.js +0 -6
- package/src/ui/confirm-dialog.tsx +0 -100
- package/src/ui/editable-table.tsx +0 -300
- package/tailwind.config.ts +0 -94
|
@@ -1,36 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { JSONTree } from 'react-json-tree';
|
|
3
|
-
import { StorageEntry } from '../shared/types';
|
|
1
|
+
import { Badge, Button, Dialog, JsonInspector } from '@rozenite/ui';
|
|
4
2
|
import { useMemo } from 'react';
|
|
5
|
-
import {
|
|
3
|
+
import { Edit3, Info } from 'lucide-react';
|
|
4
|
+
import type { StorageEntry } from '../shared/types';
|
|
5
|
+
import { formatValue } from './format-value';
|
|
6
|
+
import { HexdumpValueViewer, TextValueViewer } from './large-value-viewer';
|
|
6
7
|
|
|
7
8
|
export type EntryDetailDialogProps = {
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
open: boolean;
|
|
10
|
+
onOpenChange: (open: boolean) => void;
|
|
10
11
|
onEdit?: (entry: StorageEntry) => void;
|
|
11
12
|
entry: StorageEntry | null;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
const
|
|
15
|
-
base00: 'transparent',
|
|
16
|
-
base01: '#374151', // bg-gray-700
|
|
17
|
-
base02: '#4b5563', // bg-gray-600
|
|
18
|
-
base03: '#6b7280', // text-gray-500
|
|
19
|
-
base04: '#9ca3af', // text-gray-400
|
|
20
|
-
base05: '#d1d5db', // text-gray-300
|
|
21
|
-
base06: '#e5e7eb', // text-gray-200
|
|
22
|
-
base07: '#f9fafb', // text-gray-100
|
|
23
|
-
base08: '#ef4444', // text-red-500
|
|
24
|
-
base09: '#f59e0b', // text-yellow-500
|
|
25
|
-
base0A: '#10b981', // text-green-500
|
|
26
|
-
base0B: '#3b82f6', // text-blue-500
|
|
27
|
-
base0C: '#06b6d4', // text-cyan-500
|
|
28
|
-
base0D: '#8b5cf6', // text-purple-500
|
|
29
|
-
base0E: '#ec4899', // text-pink-500
|
|
30
|
-
base0F: '#f97316', // text-orange-500
|
|
31
|
-
};
|
|
15
|
+
const MAX_AUTO_JSON_INSPECTION_LENGTH = 50_000;
|
|
32
16
|
|
|
33
|
-
const jsonSafeParse = (
|
|
17
|
+
export const jsonSafeParse = (
|
|
34
18
|
value: string,
|
|
35
19
|
): Record<string, unknown> | unknown[] | null => {
|
|
36
20
|
try {
|
|
@@ -50,179 +34,85 @@ const jsonSafeParse = (
|
|
|
50
34
|
}
|
|
51
35
|
};
|
|
52
36
|
|
|
53
|
-
const getTypeColorClass = (type: string) => {
|
|
54
|
-
switch (type) {
|
|
55
|
-
case 'string':
|
|
56
|
-
return 'bg-green-600';
|
|
57
|
-
case 'number':
|
|
58
|
-
return 'bg-blue-600';
|
|
59
|
-
case 'boolean':
|
|
60
|
-
return 'bg-yellow-600';
|
|
61
|
-
case 'buffer':
|
|
62
|
-
return 'bg-purple-600';
|
|
63
|
-
default:
|
|
64
|
-
return 'bg-gray-600';
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const formatValue = (entry: StorageEntry) => {
|
|
69
|
-
switch (entry.type) {
|
|
70
|
-
case 'string':
|
|
71
|
-
return (
|
|
72
|
-
<span className="text-green-300 font-mono break-all">
|
|
73
|
-
"{entry.value as string}"
|
|
74
|
-
</span>
|
|
75
|
-
);
|
|
76
|
-
case 'number':
|
|
77
|
-
return (
|
|
78
|
-
<span className="text-blue-300 font-mono">{entry.value as number}</span>
|
|
79
|
-
);
|
|
80
|
-
case 'boolean':
|
|
81
|
-
return (
|
|
82
|
-
<span
|
|
83
|
-
className={`font-mono ${
|
|
84
|
-
entry.value ? 'text-green-400' : 'text-red-400'
|
|
85
|
-
}`}
|
|
86
|
-
>
|
|
87
|
-
{entry.value ? 'true' : 'false'}
|
|
88
|
-
</span>
|
|
89
|
-
);
|
|
90
|
-
case 'buffer': {
|
|
91
|
-
const bufferArray = entry.value as number[];
|
|
92
|
-
return (
|
|
93
|
-
<div className="space-y-2">
|
|
94
|
-
<div className="text-xs text-gray-400">
|
|
95
|
-
{bufferArray.length} {bufferArray.length === 1 ? 'byte' : 'bytes'}
|
|
96
|
-
</div>
|
|
97
|
-
<pre className="text-purple-200 font-mono text-xs whitespace-pre overflow-auto leading-snug">
|
|
98
|
-
{bytesToHexdump(bufferArray)}
|
|
99
|
-
</pre>
|
|
100
|
-
</div>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
default:
|
|
104
|
-
return <span className="text-gray-400">Unknown</span>;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
37
|
export const EntryDetailDialog = ({
|
|
109
|
-
|
|
110
|
-
|
|
38
|
+
open,
|
|
39
|
+
onOpenChange,
|
|
111
40
|
onEdit,
|
|
112
41
|
entry,
|
|
113
42
|
}: EntryDetailDialogProps) => {
|
|
114
43
|
const isStringValue = entry?.type === 'string';
|
|
115
|
-
const stringValue = isStringValue ?
|
|
116
|
-
const jsonValue = useMemo(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
122
|
-
if (e.key === 'Escape') {
|
|
123
|
-
onClose();
|
|
44
|
+
const stringValue = isStringValue ? entry.value : '';
|
|
45
|
+
const jsonValue = useMemo(() => {
|
|
46
|
+
if (!isStringValue || stringValue.length > MAX_AUTO_JSON_INSPECTION_LENGTH) {
|
|
47
|
+
return null;
|
|
124
48
|
}
|
|
125
|
-
};
|
|
126
49
|
|
|
127
|
-
|
|
50
|
+
return jsonSafeParse(stringValue);
|
|
51
|
+
}, [isStringValue, stringValue]);
|
|
128
52
|
|
|
129
53
|
return (
|
|
130
|
-
<
|
|
131
|
-
className="
|
|
132
|
-
|
|
133
|
-
>
|
|
134
|
-
<div
|
|
135
|
-
className="bg-gray-800 rounded-lg p-6 w-[90vw] max-w-2xl max-h-[90vh] flex flex-col"
|
|
136
|
-
onClick={(e) => e.stopPropagation()}
|
|
137
|
-
onKeyDown={handleKeyDown}
|
|
138
|
-
>
|
|
139
|
-
<div className="flex items-center justify-between mb-4">
|
|
54
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
55
|
+
<Dialog.Content className="max-w-2xl">
|
|
56
|
+
<Dialog.Header>
|
|
140
57
|
<div className="flex items-center gap-2">
|
|
141
|
-
<Info className="h-
|
|
142
|
-
<
|
|
143
|
-
Entry Details
|
|
144
|
-
</h2>
|
|
58
|
+
<Info className="h-4 w-4 text-muted-foreground" />
|
|
59
|
+
<Dialog.Title>Entry Details</Dialog.Title>
|
|
145
60
|
</div>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
<div>
|
|
158
|
-
<label className="block text-sm font-medium text-gray-200 mb-1">
|
|
159
|
-
Key
|
|
160
|
-
</label>
|
|
161
|
-
<div className="w-full px-3 py-2 text-sm bg-gray-700 border border-gray-600 rounded text-gray-100 font-mono break-all">
|
|
162
|
-
{entry.key}
|
|
61
|
+
</Dialog.Header>
|
|
62
|
+
|
|
63
|
+
{entry && (
|
|
64
|
+
<div className="flex max-h-[70vh] flex-col gap-4 overflow-auto">
|
|
65
|
+
<div>
|
|
66
|
+
<div className="mb-1 text-sm font-medium text-foreground">
|
|
67
|
+
Key
|
|
68
|
+
</div>
|
|
69
|
+
<div className="w-full break-all rounded-md border border-input bg-muted px-3 py-2 font-mono text-sm text-foreground">
|
|
70
|
+
{entry.key}
|
|
71
|
+
</div>
|
|
163
72
|
</div>
|
|
164
|
-
</div>
|
|
165
73
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
<div className="flex items-center">
|
|
172
|
-
<span
|
|
173
|
-
className={`px-2 py-1 text-xs font-medium rounded text-white ${getTypeColorClass(
|
|
174
|
-
entry.type,
|
|
175
|
-
)}`}
|
|
176
|
-
>
|
|
177
|
-
{entry.type}
|
|
178
|
-
</span>
|
|
74
|
+
<div>
|
|
75
|
+
<div className="mb-1 text-sm font-medium text-foreground">
|
|
76
|
+
Type
|
|
77
|
+
</div>
|
|
78
|
+
<Badge variant="outline">{entry.type}</Badge>
|
|
179
79
|
</div>
|
|
180
|
-
</div>
|
|
181
80
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
81
|
+
<div className="flex min-h-0 flex-1 flex-col">
|
|
82
|
+
<div className="mb-1 text-sm font-medium text-foreground">
|
|
83
|
+
Value
|
|
84
|
+
</div>
|
|
85
|
+
<div className="max-h-96 overflow-auto rounded-md border border-input bg-muted p-3">
|
|
86
|
+
{jsonValue ? (
|
|
87
|
+
<JsonInspector data={jsonValue} />
|
|
88
|
+
) : entry.type === 'buffer' ? (
|
|
89
|
+
<div className="flex flex-col gap-2">
|
|
90
|
+
<div className="text-xs text-muted-foreground">
|
|
91
|
+
{entry.value.length}{' '}
|
|
92
|
+
{entry.value.length === 1 ? 'byte' : 'bytes'}
|
|
93
|
+
</div>
|
|
94
|
+
<HexdumpValueViewer bytes={entry.value} />
|
|
95
|
+
</div>
|
|
96
|
+
) : entry.type === 'string' ? (
|
|
97
|
+
<TextValueViewer value={entry.value} />
|
|
98
|
+
) : (
|
|
99
|
+
<div className="text-sm">{formatValue(entry)}</div>
|
|
100
|
+
)}
|
|
101
|
+
</div>
|
|
198
102
|
</div>
|
|
199
103
|
</div>
|
|
200
|
-
|
|
104
|
+
)}
|
|
201
105
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
onClick={() => {
|
|
207
|
-
if (entry && onEdit) {
|
|
208
|
-
onEdit(entry);
|
|
209
|
-
}
|
|
210
|
-
}}
|
|
211
|
-
className="flex items-center gap-2 px-4 py-2 text-sm bg-gray-700 hover:bg-gray-600 text-white rounded transition-colors"
|
|
212
|
-
>
|
|
213
|
-
<Edit3 className="h-4 w-4" />
|
|
106
|
+
<Dialog.Footer>
|
|
107
|
+
{entry && onEdit && (
|
|
108
|
+
<Button variant="outline" onClick={() => onEdit(entry)}>
|
|
109
|
+
<Edit3 className="h-3.5 w-3.5" />
|
|
214
110
|
Edit
|
|
215
|
-
</
|
|
111
|
+
</Button>
|
|
216
112
|
)}
|
|
217
|
-
<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
>
|
|
222
|
-
Close
|
|
223
|
-
</button>
|
|
224
|
-
</div>
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
113
|
+
<Dialog.Close render={<Button />}>Close</Dialog.Close>
|
|
114
|
+
</Dialog.Footer>
|
|
115
|
+
</Dialog.Content>
|
|
116
|
+
</Dialog>
|
|
227
117
|
);
|
|
228
118
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cn } from '@rozenite/ui';
|
|
2
|
+
import type { StorageEntry } from '../shared/types';
|
|
3
|
+
import { compactBufferPreview } from './binary';
|
|
4
|
+
|
|
5
|
+
export const formatValue = (entry: StorageEntry) => {
|
|
6
|
+
if (entry.type === 'string') {
|
|
7
|
+
return <span className="font-mono text-foreground">"{entry.value}"</span>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (entry.type === 'number') {
|
|
11
|
+
return <span className="font-mono text-foreground">{entry.value}</span>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (entry.type === 'boolean') {
|
|
15
|
+
return (
|
|
16
|
+
<span
|
|
17
|
+
className={cn(
|
|
18
|
+
'font-mono',
|
|
19
|
+
entry.value ? 'text-primary' : 'text-destructive',
|
|
20
|
+
)}
|
|
21
|
+
>
|
|
22
|
+
{entry.value ? 'true' : 'false'}
|
|
23
|
+
</span>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<span className="font-mono text-muted-foreground">
|
|
29
|
+
{compactBufferPreview(entry.value)}
|
|
30
|
+
</span>
|
|
31
|
+
);
|
|
32
|
+
};
|
package/src/ui/globals.css
CHANGED
|
@@ -1,123 +1 @@
|
|
|
1
|
-
@
|
|
2
|
-
@tailwind components;
|
|
3
|
-
@tailwind utilities;
|
|
4
|
-
|
|
5
|
-
@layer utilities {
|
|
6
|
-
.text-balance {
|
|
7
|
-
text-wrap: balance;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.wrap-anywhere {
|
|
11
|
-
overflow-wrap: anywhere;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@layer base {
|
|
16
|
-
:root {
|
|
17
|
-
--background: 0 0% 100%;
|
|
18
|
-
--foreground: 0 0% 3.9%;
|
|
19
|
-
--card: 0 0% 100%;
|
|
20
|
-
--card-foreground: 0 0% 3.9%;
|
|
21
|
-
--popover: 0 0% 100%;
|
|
22
|
-
--popover-foreground: 0 0% 3.9%;
|
|
23
|
-
--primary: 0 0% 9%;
|
|
24
|
-
--primary-foreground: 0 0% 98%;
|
|
25
|
-
--secondary: 0 0% 96.1%;
|
|
26
|
-
--secondary-foreground: 0 0% 9%;
|
|
27
|
-
--muted: 0 0% 96.1%;
|
|
28
|
-
--muted-foreground: 0 0% 45.1%;
|
|
29
|
-
--accent: 0 0% 96.1%;
|
|
30
|
-
--accent-foreground: 0 0% 9%;
|
|
31
|
-
--destructive: 0 84.2% 60.2%;
|
|
32
|
-
--destructive-foreground: 0 0% 98%;
|
|
33
|
-
--border: 0 0% 89.8%;
|
|
34
|
-
--input: 0 0% 89.8%;
|
|
35
|
-
--ring: 0 0% 3.9%;
|
|
36
|
-
--chart-1: 12 76% 61%;
|
|
37
|
-
--chart-2: 173 58% 39%;
|
|
38
|
-
--chart-3: 197 37% 24%;
|
|
39
|
-
--chart-4: 43 74% 66%;
|
|
40
|
-
--chart-5: 27 87% 67%;
|
|
41
|
-
--radius: 0.5rem;
|
|
42
|
-
--sidebar-background: 0 0% 98%;
|
|
43
|
-
--sidebar-foreground: 240 5.3% 26.1%;
|
|
44
|
-
--sidebar-primary: 240 5.9% 10%;
|
|
45
|
-
--sidebar-primary-foreground: 0 0% 98%;
|
|
46
|
-
--sidebar-accent: 240 4.8% 95.9%;
|
|
47
|
-
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
48
|
-
--sidebar-border: 220 13% 91%;
|
|
49
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
50
|
-
}
|
|
51
|
-
.dark {
|
|
52
|
-
--background: 0 0% 3.9%;
|
|
53
|
-
--foreground: 0 0% 98%;
|
|
54
|
-
--card: 0 0% 3.9%;
|
|
55
|
-
--card-foreground: 0 0% 98%;
|
|
56
|
-
--popover: 0 0% 3.9%;
|
|
57
|
-
--popover-foreground: 0 0% 98%;
|
|
58
|
-
--primary: 0 0% 98%;
|
|
59
|
-
--primary-foreground: 0 0% 9%;
|
|
60
|
-
--secondary: 0 0% 14.9%;
|
|
61
|
-
--secondary-foreground: 0 0% 98%;
|
|
62
|
-
--muted: 0 0% 14.9%;
|
|
63
|
-
--muted-foreground: 0 0% 63.9%;
|
|
64
|
-
--accent: 0 0% 14.9%;
|
|
65
|
-
--accent-foreground: 0 0% 98%;
|
|
66
|
-
--destructive: 0 62.8% 30.6%;
|
|
67
|
-
--destructive-foreground: 0 0% 98%;
|
|
68
|
-
--border: 0 0% 14.9%;
|
|
69
|
-
--input: 0 0% 14.9%;
|
|
70
|
-
--ring: 0 0% 83.1%;
|
|
71
|
-
--chart-1: 220 70% 50%;
|
|
72
|
-
--chart-2: 160 60% 45%;
|
|
73
|
-
--chart-3: 30 80% 55%;
|
|
74
|
-
--chart-4: 280 65% 60%;
|
|
75
|
-
--chart-5: 340 75% 55%;
|
|
76
|
-
--sidebar-background: 240 5.9% 10%;
|
|
77
|
-
--sidebar-foreground: 240 4.8% 95.9%;
|
|
78
|
-
--sidebar-primary: 224.3 76.3% 48%;
|
|
79
|
-
--sidebar-primary-foreground: 0 0% 100%;
|
|
80
|
-
--sidebar-accent: 240 3.7% 15.9%;
|
|
81
|
-
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
82
|
-
--sidebar-border: 240 3.7% 15.9%;
|
|
83
|
-
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@layer base {
|
|
88
|
-
* {
|
|
89
|
-
@apply border-border;
|
|
90
|
-
}
|
|
91
|
-
body {
|
|
92
|
-
@apply bg-background text-foreground;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/* Custom scrollbar styles to match plugin theme */
|
|
97
|
-
::-webkit-scrollbar {
|
|
98
|
-
width: 8px;
|
|
99
|
-
height: 8px;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
::-webkit-scrollbar-track {
|
|
103
|
-
background: #1f2937; /* gray-800 */
|
|
104
|
-
border-radius: 4px;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
::-webkit-scrollbar-thumb {
|
|
108
|
-
background: #374151; /* gray-700 */
|
|
109
|
-
border-radius: 4px;
|
|
110
|
-
border: 1px solid #1f2937; /* gray-800 */
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
::-webkit-scrollbar-thumb:hover {
|
|
114
|
-
background: #4b5563; /* gray-600 */
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
::-webkit-scrollbar-thumb:active {
|
|
118
|
-
background: #6b7280; /* gray-500 */
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
::-webkit-scrollbar-corner {
|
|
122
|
-
background: #1f2937; /* gray-800 */
|
|
123
|
-
}
|
|
1
|
+
@import '@rozenite/ui/styles.css';
|