uploaderkit 1.0.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/LICENSE +21 -0
- package/NOTICE +16 -0
- package/README.es.md +1140 -0
- package/README.md +1135 -0
- package/dist/FileViewer-ChTf7-uY.d.cts +49 -0
- package/dist/FileViewer-nuD-GEdJ.d.ts +49 -0
- package/dist/adapters/gcs.cjs +83 -0
- package/dist/adapters/gcs.cjs.map +1 -0
- package/dist/adapters/gcs.d.cts +31 -0
- package/dist/adapters/gcs.d.ts +31 -0
- package/dist/adapters/gcs.js +81 -0
- package/dist/adapters/gcs.js.map +1 -0
- package/dist/adapters/memory.cjs +27 -0
- package/dist/adapters/memory.cjs.map +1 -0
- package/dist/adapters/memory.d.cts +18 -0
- package/dist/adapters/memory.d.ts +18 -0
- package/dist/adapters/memory.js +25 -0
- package/dist/adapters/memory.js.map +1 -0
- package/dist/adapters/s3.cjs +75 -0
- package/dist/adapters/s3.cjs.map +1 -0
- package/dist/adapters/s3.d.cts +27 -0
- package/dist/adapters/s3.d.ts +27 -0
- package/dist/adapters/s3.js +73 -0
- package/dist/adapters/s3.js.map +1 -0
- package/dist/chunk-3FI44IOW.js +150 -0
- package/dist/chunk-3FI44IOW.js.map +1 -0
- package/dist/chunk-H7BRW5IY.js +308 -0
- package/dist/chunk-H7BRW5IY.js.map +1 -0
- package/dist/chunk-PDKAF4GX.js +707 -0
- package/dist/chunk-PDKAF4GX.js.map +1 -0
- package/dist/chunk-PTEX7F4R.js +309 -0
- package/dist/chunk-PTEX7F4R.js.map +1 -0
- package/dist/chunk-T5YZG6JW.js +511 -0
- package/dist/chunk-T5YZG6JW.js.map +1 -0
- package/dist/index.cjs +220 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -170
- package/dist/index.d.ts +57 -170
- package/dist/index.js +1 -324
- package/dist/index.js.map +1 -1
- package/dist/presets.cjs +1665 -0
- package/dist/presets.cjs.map +1 -0
- package/dist/presets.d.cts +100 -0
- package/dist/presets.d.ts +100 -0
- package/dist/presets.js +405 -0
- package/dist/presets.js.map +1 -0
- package/dist/react.cjs +981 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +106 -0
- package/dist/react.d.ts +106 -0
- package/dist/react.js +5 -0
- package/dist/react.js.map +1 -0
- package/dist/server/express.cjs +179 -0
- package/dist/server/express.cjs.map +1 -0
- package/dist/server/express.d.cts +64 -0
- package/dist/server/express.d.ts +64 -0
- package/dist/server/express.js +111 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/next.cjs +165 -0
- package/dist/server/next.cjs.map +1 -0
- package/dist/server/next.d.cts +38 -0
- package/dist/server/next.d.ts +38 -0
- package/dist/server/next.js +107 -0
- package/dist/server/next.js.map +1 -0
- package/dist/server.cjs +550 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +19 -0
- package/dist/server.d.ts +19 -0
- package/dist/server.js +80 -0
- package/dist/server.js.map +1 -0
- package/dist/storage-CYkSHWZX.d.cts +133 -0
- package/dist/storage-Qc9epG0G.d.ts +133 -0
- package/dist/types-BSlJJwti.d.cts +341 -0
- package/dist/types-BSlJJwti.d.ts +341 -0
- package/dist/ui.cjs +2325 -0
- package/dist/ui.cjs.map +1 -0
- package/dist/ui.d.cts +331 -0
- package/dist/ui.d.ts +331 -0
- package/dist/ui.js +749 -0
- package/dist/ui.js.map +1 -0
- package/dist/useSlottedUploader-BzT5jV8c.d.cts +139 -0
- package/dist/useSlottedUploader-IkG5RhEO.d.ts +139 -0
- package/dist/useUploader-BiBdS-7y.d.cts +117 -0
- package/dist/useUploader-CQHpj_oI.d.ts +117 -0
- package/package.json +189 -3
- package/tailwind.css +80 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { o as StoredFile, p as UploadStatus, d as ScopeConfig, e as ScopeRegistry, U as UploaderLabels } from './types-BSlJJwti.js';
|
|
2
|
+
|
|
3
|
+
/** Signals the strategy receives while a file is in flight. */
|
|
4
|
+
type UploadStrategyOptions = {
|
|
5
|
+
/** 0–100. Driven by the transport when it can measure (XHR can). */
|
|
6
|
+
onProgress: (percent: number) => void;
|
|
7
|
+
/** Aborting must reject the promise with an `AbortError`-named error. */
|
|
8
|
+
signal: AbortSignal;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Deletes one persisted object from storage. The uploaders run it themselves
|
|
12
|
+
* on a confirmed removal — unless the scope is marked `keepOnRemove`, the
|
|
13
|
+
* history contract — so a consumer that wires a strategy can no longer orphan
|
|
14
|
+
* by forgetting a callback. Resolve `false` when the server refused.
|
|
15
|
+
*/
|
|
16
|
+
type RemoveStrategy = (stored: StoredFile, scope: string, entityId: string) => Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* The physical transport for one file. Injected into `useUploader` so the hook
|
|
19
|
+
* owns state and validation while the app owns how bytes travel — swap the
|
|
20
|
+
* endpoint, the auth header or the whole protocol without touching the hook.
|
|
21
|
+
*/
|
|
22
|
+
type UploadStrategy = (file: File, scope: string, entityId: string, options: UploadStrategyOptions) => Promise<StoredFile>;
|
|
23
|
+
/** One file tracked by the hook, from selection to stored (or failed). */
|
|
24
|
+
type UploaderFile = {
|
|
25
|
+
id: string;
|
|
26
|
+
file: File;
|
|
27
|
+
status: UploadStatus;
|
|
28
|
+
/** 0–100 while uploading; 100 on success. */
|
|
29
|
+
progress: number;
|
|
30
|
+
/** Human, Spanish — comes from validation or the strategy's failure. */
|
|
31
|
+
error?: string;
|
|
32
|
+
/** Object URL for image files, for a local thumbnail before upload. */
|
|
33
|
+
preview?: string;
|
|
34
|
+
/** Present once the server confirmed the upload. */
|
|
35
|
+
stored?: StoredFile;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* When the machine sends: `'manual'` holds files in `idle` until the app calls
|
|
40
|
+
* `upload()` — the form-submit flow, where the file travels together with the
|
|
41
|
+
* rest of the fields' action. `'select'` fires as soon as a valid file lands.
|
|
42
|
+
*/
|
|
43
|
+
type UploadTrigger = 'select' | 'manual';
|
|
44
|
+
type RetryOptions = {
|
|
45
|
+
/** Total attempts per file, the first one included. @defaultValue 1 */
|
|
46
|
+
attempts?: number;
|
|
47
|
+
/** Delay before the first retry; doubles on each further one. @defaultValue 500 */
|
|
48
|
+
backoffMs?: number;
|
|
49
|
+
};
|
|
50
|
+
type UseUploaderOptions<T extends Record<string, ScopeConfig>> = {
|
|
51
|
+
/** The app's registry — the same object the server authorizes against. */
|
|
52
|
+
scopes: ScopeRegistry<T>;
|
|
53
|
+
scope: keyof T & string;
|
|
54
|
+
/** Owner of the uploads (customerId, userId, …), forwarded to the strategy. */
|
|
55
|
+
entityId: string;
|
|
56
|
+
/** Transport. Omit for local-only selection + validation (no `upload`). */
|
|
57
|
+
strategy?: UploadStrategy;
|
|
58
|
+
/**
|
|
59
|
+
* Overrides the arity derived from the scope's `maxFiles`. Rarely needed:
|
|
60
|
+
* the registry is what the server validates against.
|
|
61
|
+
*/
|
|
62
|
+
multiple?: boolean;
|
|
63
|
+
/** Overrides the scope's own `maxFiles`, downward. */
|
|
64
|
+
maxFiles?: number;
|
|
65
|
+
/** @defaultValue 'manual' — the styled `Uploader` flips it to `'select'`. */
|
|
66
|
+
uploadOn?: UploadTrigger;
|
|
67
|
+
/**
|
|
68
|
+
* Fired when a batch actually starts travelling — from either trigger — with
|
|
69
|
+
* the files it carries. The place to flip a form into its "sending" state.
|
|
70
|
+
*/
|
|
71
|
+
onUploadStart?: (files: UploaderFile[]) => void;
|
|
72
|
+
/** Fired once per batch with the files the server confirmed. */
|
|
73
|
+
onUploaded?: (stored: StoredFile[]) => void;
|
|
74
|
+
onError?: (message: string) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Re-run a failed strategy call before surfacing the error. A number is
|
|
77
|
+
* shorthand for `{ attempts }`. Aborts never retry, and validation failures
|
|
78
|
+
* never reach the strategy in the first place.
|
|
79
|
+
*/
|
|
80
|
+
retry?: number | RetryOptions;
|
|
81
|
+
/** Max uploads in flight per batch; the rest queue. @defaultValue Infinity */
|
|
82
|
+
concurrency?: number;
|
|
83
|
+
/**
|
|
84
|
+
* Rename each file before it enters the machine — a client-side input, a
|
|
85
|
+
* folio, a slug. Runs before validation, so a rename that changes the
|
|
86
|
+
* extension is rejected like any other invalid file. The stored key comes
|
|
87
|
+
* from the scope's `path(entityId, file)`, which reads this name.
|
|
88
|
+
*/
|
|
89
|
+
rename?: (file: File) => string;
|
|
90
|
+
labels?: Partial<UploaderLabels>;
|
|
91
|
+
};
|
|
92
|
+
type UseUploaderReturn = {
|
|
93
|
+
files: UploaderFile[];
|
|
94
|
+
/** Ready-made value for `<input accept>`, derived from the scope. */
|
|
95
|
+
accept: string;
|
|
96
|
+
isUploading: boolean;
|
|
97
|
+
/** `true` while any file waits in `idle` — a manual trigger has work to do. */
|
|
98
|
+
hasPending: boolean;
|
|
99
|
+
addFiles: (incoming: FileList | File[]) => Promise<void>;
|
|
100
|
+
/** Uploads every file still in `idle`. Resolves with the confirmed ones. */
|
|
101
|
+
upload: () => Promise<StoredFile[]>;
|
|
102
|
+
/** Abort one in-flight upload, or all of them when no id is given. */
|
|
103
|
+
abort: (id?: string) => void;
|
|
104
|
+
removeFile: (id: string) => void;
|
|
105
|
+
clear: () => void;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Headless upload state machine: selection → validation → (compression) →
|
|
109
|
+
* upload with progress and abort. Owns no markup — render `files` however the
|
|
110
|
+
* screen needs and wire `addFiles` to an input or a drop zone.
|
|
111
|
+
*
|
|
112
|
+
* Validation runs here with the same `validateForScope` the server runs, so
|
|
113
|
+
* the user sees the rejection before any byte leaves the machine.
|
|
114
|
+
*/
|
|
115
|
+
declare const useUploader: <T extends Record<string, ScopeConfig>>({ scopes, scope, entityId, strategy, multiple: multipleOption, maxFiles: maxFilesOption, uploadOn, onUploadStart, onUploaded, onError, retry, concurrency, rename, labels, }: UseUploaderOptions<T>) => UseUploaderReturn;
|
|
116
|
+
|
|
117
|
+
export { type RemoveStrategy as R, type UseUploaderOptions as U, type UploadStrategy as a, type RetryOptions as b, type UploadStrategyOptions as c, type UploadTrigger as d, type UploaderFile as e, type UseUploaderReturn as f, useUploader as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uploaderkit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "One upload contract for every storage provider — scope registry, isomorphic validation, headless React and a server router.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"upload",
|
|
@@ -35,7 +35,9 @@
|
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"dist",
|
|
38
|
+
"tailwind.css",
|
|
38
39
|
"README.md",
|
|
40
|
+
"README.es.md",
|
|
39
41
|
"LICENSE",
|
|
40
42
|
"NOTICE"
|
|
41
43
|
],
|
|
@@ -53,6 +55,97 @@
|
|
|
53
55
|
"default": "./dist/index.cjs"
|
|
54
56
|
}
|
|
55
57
|
},
|
|
58
|
+
"./react": {
|
|
59
|
+
"import": {
|
|
60
|
+
"types": "./dist/react.d.ts",
|
|
61
|
+
"default": "./dist/react.js"
|
|
62
|
+
},
|
|
63
|
+
"require": {
|
|
64
|
+
"types": "./dist/react.d.cts",
|
|
65
|
+
"default": "./dist/react.cjs"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"./server": {
|
|
69
|
+
"import": {
|
|
70
|
+
"types": "./dist/server.d.ts",
|
|
71
|
+
"default": "./dist/server.js"
|
|
72
|
+
},
|
|
73
|
+
"require": {
|
|
74
|
+
"types": "./dist/server.d.cts",
|
|
75
|
+
"default": "./dist/server.cjs"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"./server/express": {
|
|
79
|
+
"import": {
|
|
80
|
+
"types": "./dist/server/express.d.ts",
|
|
81
|
+
"default": "./dist/server/express.js"
|
|
82
|
+
},
|
|
83
|
+
"require": {
|
|
84
|
+
"types": "./dist/server/express.d.cts",
|
|
85
|
+
"default": "./dist/server/express.cjs"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"./server/next": {
|
|
89
|
+
"import": {
|
|
90
|
+
"types": "./dist/server/next.d.ts",
|
|
91
|
+
"default": "./dist/server/next.js"
|
|
92
|
+
},
|
|
93
|
+
"require": {
|
|
94
|
+
"types": "./dist/server/next.d.cts",
|
|
95
|
+
"default": "./dist/server/next.cjs"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"./adapters/memory": {
|
|
99
|
+
"import": {
|
|
100
|
+
"types": "./dist/adapters/memory.d.ts",
|
|
101
|
+
"default": "./dist/adapters/memory.js"
|
|
102
|
+
},
|
|
103
|
+
"require": {
|
|
104
|
+
"types": "./dist/adapters/memory.d.cts",
|
|
105
|
+
"default": "./dist/adapters/memory.cjs"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"./adapters/gcs": {
|
|
109
|
+
"import": {
|
|
110
|
+
"types": "./dist/adapters/gcs.d.ts",
|
|
111
|
+
"default": "./dist/adapters/gcs.js"
|
|
112
|
+
},
|
|
113
|
+
"require": {
|
|
114
|
+
"types": "./dist/adapters/gcs.d.cts",
|
|
115
|
+
"default": "./dist/adapters/gcs.cjs"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"./ui": {
|
|
119
|
+
"import": {
|
|
120
|
+
"types": "./dist/ui.d.ts",
|
|
121
|
+
"default": "./dist/ui.js"
|
|
122
|
+
},
|
|
123
|
+
"require": {
|
|
124
|
+
"types": "./dist/ui.d.cts",
|
|
125
|
+
"default": "./dist/ui.cjs"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"./presets": {
|
|
129
|
+
"import": {
|
|
130
|
+
"types": "./dist/presets.d.ts",
|
|
131
|
+
"default": "./dist/presets.js"
|
|
132
|
+
},
|
|
133
|
+
"require": {
|
|
134
|
+
"types": "./dist/presets.d.cts",
|
|
135
|
+
"default": "./dist/presets.cjs"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"./adapters/s3": {
|
|
139
|
+
"import": {
|
|
140
|
+
"types": "./dist/adapters/s3.d.ts",
|
|
141
|
+
"default": "./dist/adapters/s3.js"
|
|
142
|
+
},
|
|
143
|
+
"require": {
|
|
144
|
+
"types": "./dist/adapters/s3.d.cts",
|
|
145
|
+
"default": "./dist/adapters/s3.cjs"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"./tailwind.css": "./tailwind.css",
|
|
56
149
|
"./package.json": "./package.json"
|
|
57
150
|
},
|
|
58
151
|
"scripts": {
|
|
@@ -65,18 +158,111 @@
|
|
|
65
158
|
"size": "size-limit",
|
|
66
159
|
"size:why": "size-limit --why",
|
|
67
160
|
"check:publish": "publint",
|
|
68
|
-
"docs": "typedoc"
|
|
161
|
+
"docs": "typedoc",
|
|
162
|
+
"check:types": "attw --pack . --exclude-entrypoints ./tailwind.css"
|
|
69
163
|
},
|
|
70
164
|
"size-limit": [
|
|
71
165
|
{
|
|
72
166
|
"name": "core (index)",
|
|
73
167
|
"path": "dist/index.js",
|
|
74
168
|
"limit": "6 kB"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "react",
|
|
172
|
+
"path": "dist/react.js",
|
|
173
|
+
"limit": "9 kB",
|
|
174
|
+
"ignore": [
|
|
175
|
+
"react",
|
|
176
|
+
"react-dom"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "ui",
|
|
181
|
+
"path": "dist/ui.js",
|
|
182
|
+
"limit": "17 kB",
|
|
183
|
+
"ignore": [
|
|
184
|
+
"react",
|
|
185
|
+
"react-dom"
|
|
186
|
+
]
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"name": "presets",
|
|
190
|
+
"path": "dist/presets.js",
|
|
191
|
+
"limit": "14 kB",
|
|
192
|
+
"ignore": [
|
|
193
|
+
"react",
|
|
194
|
+
"react-dom"
|
|
195
|
+
]
|
|
75
196
|
}
|
|
76
197
|
],
|
|
77
198
|
"devDependencies": {
|
|
199
|
+
"@aws-sdk/client-s3": "^3.1109.0",
|
|
200
|
+
"@aws-sdk/s3-request-presigner": "^3.1109.0",
|
|
201
|
+
"@google-cloud/storage": "^7.22.0",
|
|
202
|
+
"@testing-library/react": "^16.3.2",
|
|
203
|
+
"@types/node": "^26.2.0",
|
|
204
|
+
"@types/react": "^18.3.12",
|
|
205
|
+
"happy-dom": "^20.11.2",
|
|
206
|
+
"react": "^18.3.1",
|
|
207
|
+
"react-dom": "^18.3.1",
|
|
78
208
|
"tsup": "^8.5.0",
|
|
79
209
|
"typescript": "^5.9.3",
|
|
80
|
-
"vitest": "^3.2.4"
|
|
210
|
+
"vitest": "^3.2.4",
|
|
211
|
+
"@types/react-dom": "^18.3.1"
|
|
212
|
+
},
|
|
213
|
+
"typesVersions": {
|
|
214
|
+
"*": {
|
|
215
|
+
"react": [
|
|
216
|
+
"./dist/react.d.ts"
|
|
217
|
+
],
|
|
218
|
+
"server": [
|
|
219
|
+
"./dist/server.d.ts"
|
|
220
|
+
],
|
|
221
|
+
"server/express": [
|
|
222
|
+
"./dist/server/express.d.ts"
|
|
223
|
+
],
|
|
224
|
+
"server/next": [
|
|
225
|
+
"./dist/server/next.d.ts"
|
|
226
|
+
],
|
|
227
|
+
"adapters/memory": [
|
|
228
|
+
"./dist/adapters/memory.d.ts"
|
|
229
|
+
],
|
|
230
|
+
"adapters/gcs": [
|
|
231
|
+
"./dist/adapters/gcs.d.ts"
|
|
232
|
+
],
|
|
233
|
+
"ui": [
|
|
234
|
+
"./dist/ui.d.ts"
|
|
235
|
+
],
|
|
236
|
+
"presets": [
|
|
237
|
+
"./dist/presets.d.ts"
|
|
238
|
+
],
|
|
239
|
+
"adapters/s3": [
|
|
240
|
+
"./dist/adapters/s3.d.ts"
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"peerDependencies": {
|
|
245
|
+
"@aws-sdk/client-s3": ">=3",
|
|
246
|
+
"@aws-sdk/s3-request-presigner": ">=3",
|
|
247
|
+
"@google-cloud/storage": ">=7",
|
|
248
|
+
"react": ">=18",
|
|
249
|
+
"react-dom": ">=18"
|
|
250
|
+
},
|
|
251
|
+
"peerDependenciesMeta": {
|
|
252
|
+
"@aws-sdk/client-s3": {
|
|
253
|
+
"optional": true
|
|
254
|
+
},
|
|
255
|
+
"@aws-sdk/s3-request-presigner": {
|
|
256
|
+
"optional": true
|
|
257
|
+
},
|
|
258
|
+
"@google-cloud/storage": {
|
|
259
|
+
"optional": true
|
|
260
|
+
},
|
|
261
|
+
"react": {
|
|
262
|
+
"optional": true
|
|
263
|
+
},
|
|
264
|
+
"react-dom": {
|
|
265
|
+
"optional": true
|
|
266
|
+
}
|
|
81
267
|
}
|
|
82
268
|
}
|
package/tailwind.css
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* uploaderkit — Tailwind v4 entry.
|
|
3
|
+
*
|
|
4
|
+
* Consumers add, in this order:
|
|
5
|
+
* @import 'tailwindcss';
|
|
6
|
+
* @import 'uploaderkit/tailwind.css';
|
|
7
|
+
*
|
|
8
|
+
* `@source` registers the compiled output so the utilities the components use
|
|
9
|
+
* are generated by the consumer's own Tailwind build.
|
|
10
|
+
*
|
|
11
|
+
* `@theme` declares DEFAULTS only. Every token is a CSS variable, so an app
|
|
12
|
+
* rebrands the whole styled layer by redeclaring the ones it cares about:
|
|
13
|
+
*
|
|
14
|
+
* :root {
|
|
15
|
+
* --color-ui-primary: #c41e3a;
|
|
16
|
+
* --color-ui-primary-hover: #8b1529;
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
@source './dist/ui.js';
|
|
21
|
+
@source './dist/ui.cjs';
|
|
22
|
+
|
|
23
|
+
@theme {
|
|
24
|
+
/* Surfaces */
|
|
25
|
+
--color-ui-surface: #ffffff;
|
|
26
|
+
--color-ui-surface-subtle: #fafafa;
|
|
27
|
+
--color-ui-surface-muted: #f4f4f5;
|
|
28
|
+
|
|
29
|
+
/* Text */
|
|
30
|
+
--color-ui-fg: #111827;
|
|
31
|
+
--color-ui-muted: #6b7280;
|
|
32
|
+
--color-ui-placeholder: #9ca3af;
|
|
33
|
+
|
|
34
|
+
/* Borders & focus */
|
|
35
|
+
--color-ui-border: #e5e7eb;
|
|
36
|
+
--color-ui-border-strong: #d1d5db;
|
|
37
|
+
--color-ui-ring: #93c5fd;
|
|
38
|
+
|
|
39
|
+
/* Primary action */
|
|
40
|
+
--color-ui-primary: #2563eb;
|
|
41
|
+
--color-ui-primary-hover: #1d4ed8;
|
|
42
|
+
--color-ui-primary-fg: #ffffff;
|
|
43
|
+
--color-ui-primary-soft: #eff6ff;
|
|
44
|
+
--color-ui-primary-soft-fg: #1d4ed8;
|
|
45
|
+
|
|
46
|
+
/* Semantic — danger */
|
|
47
|
+
--color-ui-danger: #dc2626;
|
|
48
|
+
--color-ui-danger-hover: #b91c1c;
|
|
49
|
+
--color-ui-danger-fg: #ffffff;
|
|
50
|
+
--color-ui-danger-soft: #fef2f2;
|
|
51
|
+
--color-ui-danger-soft-fg: #b91c1c;
|
|
52
|
+
|
|
53
|
+
/* Semantic — success */
|
|
54
|
+
--color-ui-success: #16a34a;
|
|
55
|
+
--color-ui-success-soft: #f0fdf4;
|
|
56
|
+
|
|
57
|
+
/* Semantic — warning */
|
|
58
|
+
--color-ui-warning: #d97706;
|
|
59
|
+
--color-ui-warning-soft: #fffbeb;
|
|
60
|
+
|
|
61
|
+
/* Overlay scrim behind the viewer and dialogs */
|
|
62
|
+
--color-ui-overlay: oklch(0.28 0.03 265 / 0.45);
|
|
63
|
+
|
|
64
|
+
/* Control radii */
|
|
65
|
+
--radius-ui: 0.5rem;
|
|
66
|
+
--radius-ui-lg: 0.75rem;
|
|
67
|
+
--radius-ui-xl: 1rem;
|
|
68
|
+
|
|
69
|
+
/* Motion */
|
|
70
|
+
--animate-ui-fade-in: ui-fade-in 200ms ease-out;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@keyframes ui-fade-in {
|
|
74
|
+
from {
|
|
75
|
+
opacity: 0;
|
|
76
|
+
}
|
|
77
|
+
to {
|
|
78
|
+
opacity: 1;
|
|
79
|
+
}
|
|
80
|
+
}
|