@autono/open-pages 0.5.0 → 0.7.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/dist/{build-L50pau9v.js → build-CCoxDxL-.js} +11 -10
- package/dist/cli/bin.d.ts +1 -1
- package/dist/cli/bin.js +434 -28
- package/dist/{config-CDUdFE8N.js → config-D_U_aCQz.js} +484 -460
- package/dist/{config-C9or4m4J.d.ts → config-p-TWNXbv.d.ts} +4 -4
- package/dist/{design-C13iz9_4.js → design-Cpqx7SJs.js} +1 -2
- package/dist/{dev-CzJYXFOO.js → dev-CTrB263u.js} +40 -20
- package/dist/{export-DbVwSmKW.js → export-enKL9R7x.js} +7 -10
- package/dist/index.d.ts +6 -8
- package/dist/index.js +2 -3
- package/dist/locale/index.d.ts +8 -14
- package/dist/locale/index.js +67 -32
- package/dist/{open-pages-plugin-C0poXLsx.js → open-pages-plugin-C8cFhMB9.js} +23 -38
- package/dist/preview-Dmzyd1cf.js +24 -0
- package/dist/sync-ui-BzRiAGCK.js +132 -0
- package/dist/{types-C5NCdDT-.d.ts → types-DDdUFUIS.d.ts} +19 -6
- package/dist/{update-CV62NhBT.js → update-CWaCKlnl.js} +14 -5
- package/dist/{update-package-Cxt57pz7.js → update-package-GaNsVdr8.js} +50 -22
- package/dist/{version-B6AiiGvT.js → version-DZrXLoAD.js} +19 -3
- package/dist/vite/index.d.ts +3 -7
- package/dist/vite/index.js +2 -7
- package/package.json +24 -22
- package/src/app/app.tsx +19 -14
- package/src/app/assets/autono-social.png +0 -0
- package/src/app/assets/autono.svg +7 -0
- package/src/app/components/asset-view.tsx +510 -26
- package/src/app/components/command/command-menu.tsx +5 -1
- package/src/app/components/command/command.tsx +4 -2
- package/src/app/components/command/home-command-menu.tsx +6 -6
- package/src/app/components/icon-tooltip.tsx +24 -15
- package/src/app/components/sidebar/folder-item.tsx +46 -19
- package/src/app/components/sidebar/icon-picker.tsx +1 -1
- package/src/app/components/sidebar/sidebar-footer.tsx +18 -7
- package/src/app/components/sidebar/sidebar.tsx +91 -64
- package/src/app/components/theme-toggle.tsx +4 -5
- package/src/app/components/themes/theme-detail.tsx +6 -3
- package/src/app/components/themes/themes-gallery.tsx +12 -7
- package/src/app/index.html +33 -2
- package/src/app/lib/assets.ts +33 -0
- package/src/app/lib/last-home-location.ts +18 -0
- package/src/app/main.tsx +10 -1
- package/src/app/routes/home-shell.tsx +82 -61
- package/src/app/routes/home.tsx +42 -39
- package/src/app/routes/page.tsx +18 -3
- package/src/app/routes/themes.tsx +6 -8
- package/src/app/styles.css +40 -4
- package/src/app/virtual.d.ts +1 -0
- package/src/locale/en.ts +17 -6
- package/src/locale/ja.ts +18 -6
- package/src/locale/types.ts +17 -4
- package/src/locale/zh-cn.ts +19 -8
- package/src/locale/zh-tw.ts +17 -6
- package/src/shared/update-package.ts +193 -0
- package/workspace/components.json +25 -0
- package/workspace/deps.json +24 -0
- package/workspace/hooks/use-mobile.ts +19 -0
- package/workspace/lib/utils.ts +6 -0
- package/workspace/styles/globals.css +135 -0
- package/workspace/ui/accordion.tsx +79 -0
- package/workspace/ui/alert-dialog.tsx +197 -0
- package/workspace/ui/alert.tsx +76 -0
- package/workspace/ui/aspect-ratio.tsx +11 -0
- package/workspace/ui/attachment.tsx +204 -0
- package/workspace/ui/avatar.tsx +110 -0
- package/workspace/ui/badge.tsx +49 -0
- package/workspace/ui/breadcrumb.tsx +122 -0
- package/workspace/ui/bubble.tsx +125 -0
- package/workspace/ui/button-group.tsx +83 -0
- package/workspace/ui/button.tsx +67 -0
- package/workspace/ui/calendar.tsx +222 -0
- package/workspace/ui/card.tsx +103 -0
- package/workspace/ui/carousel.tsx +240 -0
- package/workspace/ui/chart.tsx +373 -0
- package/workspace/ui/checkbox.tsx +31 -0
- package/workspace/ui/collapsible.tsx +33 -0
- package/workspace/ui/combobox.tsx +297 -0
- package/workspace/ui/command.tsx +195 -0
- package/workspace/ui/context-menu.tsx +261 -0
- package/workspace/ui/dialog.tsx +168 -0
- package/workspace/ui/direction.tsx +22 -0
- package/workspace/ui/drawer.tsx +132 -0
- package/workspace/ui/dropdown-menu.tsx +269 -0
- package/workspace/ui/empty.tsx +104 -0
- package/workspace/ui/field.tsx +236 -0
- package/workspace/ui/hover-card.tsx +42 -0
- package/workspace/ui/input-group.tsx +156 -0
- package/workspace/ui/input-otp.tsx +87 -0
- package/workspace/ui/input.tsx +19 -0
- package/workspace/ui/item.tsx +196 -0
- package/workspace/ui/kbd.tsx +26 -0
- package/workspace/ui/label.tsx +22 -0
- package/workspace/ui/marker.tsx +69 -0
- package/workspace/ui/menubar.tsx +280 -0
- package/workspace/ui/message-scroller.tsx +129 -0
- package/workspace/ui/message.tsx +92 -0
- package/workspace/ui/native-select.tsx +61 -0
- package/workspace/ui/navigation-menu.tsx +164 -0
- package/workspace/ui/pagination.tsx +129 -0
- package/workspace/ui/popover.tsx +87 -0
- package/workspace/ui/progress.tsx +31 -0
- package/workspace/ui/radio-group.tsx +42 -0
- package/workspace/ui/resizable.tsx +50 -0
- package/workspace/ui/scroll-area.tsx +53 -0
- package/workspace/ui/select.tsx +192 -0
- package/workspace/ui/separator.tsx +26 -0
- package/workspace/ui/sheet.tsx +147 -0
- package/workspace/ui/sidebar.tsx +702 -0
- package/workspace/ui/skeleton.tsx +13 -0
- package/workspace/ui/slider.tsx +59 -0
- package/workspace/ui/sonner.tsx +47 -0
- package/workspace/ui/spinner.tsx +10 -0
- package/workspace/ui/switch.tsx +33 -0
- package/workspace/ui/table.tsx +114 -0
- package/workspace/ui/tabs.tsx +90 -0
- package/workspace/ui/textarea.tsx +18 -0
- package/workspace/ui/toggle-group.tsx +87 -0
- package/workspace/ui/toggle.tsx +45 -0
- package/workspace/ui/tooltip.tsx +57 -0
- package/dist/export-BsK6OCpc.js +0 -4
- package/dist/preview-CPufRmuj.js +0 -21
- package/dist/sync-Be_hxSOF.js +0 -139
- package/dist/sync-lKEXyPOh.js +0 -3
- package/dist/version-CeffgdfZ.js +0 -3
- package/src/app/components/language-toggle.tsx +0 -46
- package/src/app/favicon.ico +0 -0
package/src/app/styles.css
CHANGED
|
@@ -58,6 +58,10 @@
|
|
|
58
58
|
--radius-3xl: calc(var(--radius) * 2.2);
|
|
59
59
|
--radius-4xl: calc(var(--radius) * 2.6);
|
|
60
60
|
|
|
61
|
+
/* House motion curve — one strong ease-out for every chrome entrance,
|
|
62
|
+
instead of per-file cubic-bezier literals. */
|
|
63
|
+
--ease-swift: cubic-bezier(0.22, 1, 0.36, 1);
|
|
64
|
+
|
|
61
65
|
--shadow-edge: 0 0 0 0.5px oklch(0 0 0 / 0.06), 0 1px 0 oklch(0 0 0 / 0.025);
|
|
62
66
|
--shadow-floating:
|
|
63
67
|
0 0 0 0.5px oklch(0 0 0 / 0.08), 0 1px 1px oklch(0 0 0 / 0.04),
|
|
@@ -68,6 +72,9 @@
|
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
:root {
|
|
75
|
+
/* Runtime copy of the @theme token for inline style/JS consumers. */
|
|
76
|
+
--ease-swift: cubic-bezier(0.22, 1, 0.36, 1);
|
|
77
|
+
|
|
71
78
|
/* Pure neutral ramp — zero chroma, flat surfaces, hairline borders.
|
|
72
79
|
Near-white background with white cards floating on a slightly
|
|
73
80
|
recessed canvas. */
|
|
@@ -110,7 +117,9 @@
|
|
|
110
117
|
/* Tight, considered radius — drops the trendy 10px squish for 6px crisp. */
|
|
111
118
|
--radius: 0.375rem;
|
|
112
119
|
|
|
113
|
-
--sidebar
|
|
120
|
+
/* Chrome ground — matches --canvas so sidebar, rails, and panels sit on
|
|
121
|
+
one continuous surface; content floats above it as elevated cards. */
|
|
122
|
+
--sidebar: oklch(0.975 0 0);
|
|
114
123
|
--sidebar-foreground: oklch(0.185 0 0);
|
|
115
124
|
--sidebar-primary: oklch(0.185 0 0);
|
|
116
125
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
@@ -121,9 +130,11 @@
|
|
|
121
130
|
}
|
|
122
131
|
|
|
123
132
|
.dark {
|
|
124
|
-
--
|
|
133
|
+
/* Lifted well above the near-black chrome ground (--sidebar 0.1) so the
|
|
134
|
+
elevated content cards read at a glance on dim displays. */
|
|
135
|
+
--background: oklch(0.175 0 0);
|
|
125
136
|
--foreground: oklch(0.93 0 0);
|
|
126
|
-
--canvas: oklch(0.
|
|
137
|
+
--canvas: oklch(0.1 0 0);
|
|
127
138
|
|
|
128
139
|
--card: oklch(0.19 0 0);
|
|
129
140
|
--card-foreground: oklch(0.93 0 0);
|
|
@@ -155,7 +166,7 @@
|
|
|
155
166
|
--chart-4: oklch(0.7 0.13 160);
|
|
156
167
|
--chart-5: oklch(0.65 0 0);
|
|
157
168
|
|
|
158
|
-
--sidebar: oklch(0.
|
|
169
|
+
--sidebar: oklch(0.1 0 0);
|
|
159
170
|
--sidebar-foreground: oklch(0.93 0 0);
|
|
160
171
|
--sidebar-primary: oklch(0.925 0 0);
|
|
161
172
|
--sidebar-primary-foreground: oklch(0.17 0 0);
|
|
@@ -225,6 +236,31 @@
|
|
|
225
236
|
}
|
|
226
237
|
}
|
|
227
238
|
|
|
239
|
+
/*
|
|
240
|
+
* Grid entrance — a quiet rise used by card grids. Pair with a small
|
|
241
|
+
* per-item animation-delay for a capped stagger.
|
|
242
|
+
*/
|
|
243
|
+
@keyframes osd-rise-in {
|
|
244
|
+
from {
|
|
245
|
+
opacity: 0;
|
|
246
|
+
transform: translateY(4px);
|
|
247
|
+
}
|
|
248
|
+
to {
|
|
249
|
+
opacity: 1;
|
|
250
|
+
transform: none;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.rise-in {
|
|
255
|
+
animation: osd-rise-in 350ms var(--ease-swift) both;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
@media (prefers-reduced-motion: reduce) {
|
|
259
|
+
.rise-in {
|
|
260
|
+
animation: none;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
228
264
|
/*
|
|
229
265
|
* Comment input cue — kept from the original design but retoned to match
|
|
230
266
|
* the new palette (warm vermillion + amber instead of the AI-classic
|
package/src/app/virtual.d.ts
CHANGED
package/src/locale/en.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const en: Locale = {
|
|
|
18
18
|
title: 'Page not found',
|
|
19
19
|
},
|
|
20
20
|
home: {
|
|
21
|
-
appTitle: '
|
|
21
|
+
appTitle: 'Autono',
|
|
22
22
|
draft: 'Draft',
|
|
23
23
|
duplicate: 'Duplicate',
|
|
24
24
|
themes: 'Themes',
|
|
@@ -28,7 +28,7 @@ export const en: Locale = {
|
|
|
28
28
|
menu: 'Menu',
|
|
29
29
|
newFolder: 'New folder',
|
|
30
30
|
folderName: 'Folder name',
|
|
31
|
-
updateAvailable: '
|
|
31
|
+
updateAvailable: 'Autono {version} is available',
|
|
32
32
|
updatePackage: 'Update',
|
|
33
33
|
updatingPackage: 'Updating',
|
|
34
34
|
updatePackageDone: 'Updated. Restart the dev server to use the new version.',
|
|
@@ -124,6 +124,7 @@ export const en: Locale = {
|
|
|
124
124
|
noMatchingAssetsHint: 'Try adjusting your search or filters.',
|
|
125
125
|
clearFilters: 'Clear filters',
|
|
126
126
|
searchLogos: 'Search logos',
|
|
127
|
+
searchFonts: 'Search fonts',
|
|
127
128
|
upload: 'Upload',
|
|
128
129
|
dropToUpload: 'Drop to upload',
|
|
129
130
|
loading: 'Loading…',
|
|
@@ -161,6 +162,18 @@ export const en: Locale = {
|
|
|
161
162
|
logoSearchEmptyHintSuffix: '.',
|
|
162
163
|
logoVariantLight: 'Light',
|
|
163
164
|
logoVariantDark: 'Dark',
|
|
165
|
+
fontSearchTitle: 'Search Google Fonts',
|
|
166
|
+
fontSearchPoweredByPrefix: 'Powered by ',
|
|
167
|
+
fontSearchPlaceholder: 'Search font families…',
|
|
168
|
+
fontSearchPreviewPlaceholder: 'Preview text',
|
|
169
|
+
fontSearchErrorTitle: "Couldn't reach Google Fonts",
|
|
170
|
+
fontSearchErrorBody: 'Check your connection and try again.',
|
|
171
|
+
fontSearchNoResults: 'No fonts for "{query}"',
|
|
172
|
+
fontSearchEmpty: 'No fonts available',
|
|
173
|
+
fontSearchEmptyHintPrefix: 'Try a different family name, or browse the full catalog at ',
|
|
174
|
+
fontSearchEmptyHintSuffix: '.',
|
|
175
|
+
fontWeightLabel: 'Weight',
|
|
176
|
+
fontPreviewSample: 'The quick brown fox jumps over the lazy dog 0123456789',
|
|
164
177
|
toastUploadFailed: 'Upload failed ({status})',
|
|
165
178
|
toastReplaced: 'Replaced {name}',
|
|
166
179
|
toastUploadedAs: 'Uploaded as {name}',
|
|
@@ -170,6 +183,7 @@ export const en: Locale = {
|
|
|
170
183
|
toastDeleteFailed: 'Delete failed ({status})',
|
|
171
184
|
toastDeleted: 'Deleted {name}',
|
|
172
185
|
toastDownloadFailed: 'Failed to download logo',
|
|
186
|
+
toastFontDownloadFailed: 'Failed to download font',
|
|
173
187
|
toastSearchFailed: 'Search failed',
|
|
174
188
|
},
|
|
175
189
|
commandMenu: {
|
|
@@ -196,10 +210,7 @@ export const en: Locale = {
|
|
|
196
210
|
dark: 'Dark',
|
|
197
211
|
system: 'System',
|
|
198
212
|
},
|
|
199
|
-
|
|
200
|
-
toggleAria: 'Change language',
|
|
201
|
-
title: 'Language',
|
|
202
|
-
},
|
|
213
|
+
|
|
203
214
|
themes: {
|
|
204
215
|
title: 'Themes',
|
|
205
216
|
noThemesTitle: 'No themes yet',
|
package/src/locale/ja.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const ja: Locale = {
|
|
|
18
18
|
title: 'ページが見つかりません',
|
|
19
19
|
},
|
|
20
20
|
home: {
|
|
21
|
-
appTitle: '
|
|
21
|
+
appTitle: 'Autono',
|
|
22
22
|
draft: '下書き',
|
|
23
23
|
duplicate: '複製',
|
|
24
24
|
themes: 'テーマ',
|
|
@@ -28,7 +28,7 @@ export const ja: Locale = {
|
|
|
28
28
|
menu: 'メニュー',
|
|
29
29
|
newFolder: '新規フォルダ',
|
|
30
30
|
folderName: 'フォルダ名',
|
|
31
|
-
updateAvailable: '
|
|
31
|
+
updateAvailable: 'Autono {version} が利用可能です',
|
|
32
32
|
updatePackage: '更新',
|
|
33
33
|
updatingPackage: '更新中',
|
|
34
34
|
updatePackageDone: '更新しました。新しいバージョンを使うには dev server を再起動してください。',
|
|
@@ -124,6 +124,7 @@ export const ja: Locale = {
|
|
|
124
124
|
noMatchingAssetsHint: '検索条件またはフィルターを調整してください。',
|
|
125
125
|
clearFilters: 'フィルターをクリア',
|
|
126
126
|
searchLogos: 'ロゴを検索',
|
|
127
|
+
searchFonts: 'フォントを検索',
|
|
127
128
|
upload: 'アップロード',
|
|
128
129
|
dropToUpload: 'ドロップでアップロード',
|
|
129
130
|
loading: '読み込み中…',
|
|
@@ -163,6 +164,19 @@ export const ja: Locale = {
|
|
|
163
164
|
logoSearchEmptyHintSuffix: '。',
|
|
164
165
|
logoVariantLight: 'ライト',
|
|
165
166
|
logoVariantDark: 'ダーク',
|
|
167
|
+
fontSearchTitle: 'Google Fonts を検索',
|
|
168
|
+
fontSearchPoweredByPrefix: 'Powered by ',
|
|
169
|
+
fontSearchPlaceholder: 'フォントファミリーで検索…',
|
|
170
|
+
fontSearchPreviewPlaceholder: 'プレビューテキスト',
|
|
171
|
+
fontSearchErrorTitle: 'Google Fonts に接続できません',
|
|
172
|
+
fontSearchErrorBody: '接続を確認して再試行してください。',
|
|
173
|
+
fontSearchNoResults: '「{query}」のフォントは見つかりません',
|
|
174
|
+
fontSearchEmpty: '利用可能なフォントはありません',
|
|
175
|
+
fontSearchEmptyHintPrefix:
|
|
176
|
+
'別のファミリー名を試すか、次のサイトでカタログ全体を閲覧してください: ',
|
|
177
|
+
fontSearchEmptyHintSuffix: '。',
|
|
178
|
+
fontWeightLabel: 'ウェイト',
|
|
179
|
+
fontPreviewSample: 'いろはにほへと 永遠 ABCabc 0123456789',
|
|
166
180
|
toastUploadFailed: 'アップロードに失敗しました ({status})',
|
|
167
181
|
toastReplaced: '{name} を置き換えました',
|
|
168
182
|
toastUploadedAs: '{name} としてアップロードしました',
|
|
@@ -172,6 +186,7 @@ export const ja: Locale = {
|
|
|
172
186
|
toastDeleteFailed: '削除に失敗しました ({status})',
|
|
173
187
|
toastDeleted: '{name} を削除しました',
|
|
174
188
|
toastDownloadFailed: 'ロゴのダウンロードに失敗しました',
|
|
189
|
+
toastFontDownloadFailed: 'フォントのダウンロードに失敗しました',
|
|
175
190
|
toastSearchFailed: '検索に失敗しました',
|
|
176
191
|
},
|
|
177
192
|
commandMenu: {
|
|
@@ -198,10 +213,7 @@ export const ja: Locale = {
|
|
|
198
213
|
dark: 'ダーク',
|
|
199
214
|
system: 'システム',
|
|
200
215
|
},
|
|
201
|
-
|
|
202
|
-
toggleAria: '言語を切り替え',
|
|
203
|
-
title: '言語',
|
|
204
|
-
},
|
|
216
|
+
|
|
205
217
|
themes: {
|
|
206
218
|
title: 'テーマ',
|
|
207
219
|
noThemesTitle: 'テーマがまだありません',
|
package/src/locale/types.ts
CHANGED
|
@@ -121,6 +121,7 @@ export type Locale = {
|
|
|
121
121
|
noMatchingAssetsHint: string;
|
|
122
122
|
clearFilters: string;
|
|
123
123
|
searchLogos: string;
|
|
124
|
+
searchFonts: string;
|
|
124
125
|
upload: string;
|
|
125
126
|
dropToUpload: string;
|
|
126
127
|
loading: string;
|
|
@@ -158,6 +159,20 @@ export type Locale = {
|
|
|
158
159
|
logoSearchEmptyHintSuffix: string;
|
|
159
160
|
logoVariantLight: string;
|
|
160
161
|
logoVariantDark: string;
|
|
162
|
+
fontSearchTitle: string;
|
|
163
|
+
fontSearchPoweredByPrefix: string;
|
|
164
|
+
fontSearchPlaceholder: string;
|
|
165
|
+
fontSearchPreviewPlaceholder: string;
|
|
166
|
+
fontSearchErrorTitle: string;
|
|
167
|
+
fontSearchErrorBody: string;
|
|
168
|
+
/** template: 'No fonts for "{query}"' */
|
|
169
|
+
fontSearchNoResults: string;
|
|
170
|
+
fontSearchEmpty: string;
|
|
171
|
+
fontSearchEmptyHintPrefix: string;
|
|
172
|
+
fontSearchEmptyHintSuffix: string;
|
|
173
|
+
fontWeightLabel: string;
|
|
174
|
+
fontPreviewSample: string;
|
|
175
|
+
/** template: "Upload failed ({status})" */
|
|
161
176
|
toastUploadFailed: string;
|
|
162
177
|
toastReplaced: string;
|
|
163
178
|
toastUploadedAs: string;
|
|
@@ -167,6 +182,7 @@ export type Locale = {
|
|
|
167
182
|
toastDeleteFailed: string;
|
|
168
183
|
toastDeleted: string;
|
|
169
184
|
toastDownloadFailed: string;
|
|
185
|
+
toastFontDownloadFailed: string;
|
|
170
186
|
toastSearchFailed: string;
|
|
171
187
|
};
|
|
172
188
|
commandMenu: {
|
|
@@ -193,10 +209,7 @@ export type Locale = {
|
|
|
193
209
|
dark: string;
|
|
194
210
|
system: string;
|
|
195
211
|
};
|
|
196
|
-
|
|
197
|
-
toggleAria: string;
|
|
198
|
-
title: string;
|
|
199
|
-
};
|
|
212
|
+
|
|
200
213
|
themes: {
|
|
201
214
|
title: string;
|
|
202
215
|
noThemesTitle: string;
|
package/src/locale/zh-cn.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const zhCN: Locale = {
|
|
|
18
18
|
title: '未找到页面',
|
|
19
19
|
},
|
|
20
20
|
home: {
|
|
21
|
-
appTitle: '
|
|
21
|
+
appTitle: 'Autono',
|
|
22
22
|
draft: '草稿',
|
|
23
23
|
duplicate: '复制',
|
|
24
24
|
themes: '主题',
|
|
@@ -26,9 +26,9 @@ export const zhCN: Locale = {
|
|
|
26
26
|
folders: '頁面夹',
|
|
27
27
|
pages: '幻灯片',
|
|
28
28
|
menu: '菜单',
|
|
29
|
-
newFolder: '
|
|
30
|
-
folderName: '
|
|
31
|
-
updateAvailable: '
|
|
29
|
+
newFolder: '新建文件夹',
|
|
30
|
+
folderName: '文件夹名称',
|
|
31
|
+
updateAvailable: 'Autono {version} 已发布',
|
|
32
32
|
updatePackage: '更新',
|
|
33
33
|
updatingPackage: '更新中',
|
|
34
34
|
updatePackageDone: '已更新。请重启 dev server 以使用新版本。',
|
|
@@ -124,6 +124,7 @@ export const zhCN: Locale = {
|
|
|
124
124
|
noMatchingAssetsHint: '请调整搜索或筛选条件。',
|
|
125
125
|
clearFilters: '清除筛选',
|
|
126
126
|
searchLogos: '搜索 Logo',
|
|
127
|
+
searchFonts: '搜索字体',
|
|
127
128
|
upload: '上传',
|
|
128
129
|
dropToUpload: '拖入即可上传',
|
|
129
130
|
loading: '加载中…',
|
|
@@ -161,6 +162,18 @@ export const zhCN: Locale = {
|
|
|
161
162
|
logoSearchEmptyHintSuffix: '。',
|
|
162
163
|
logoVariantLight: '浅色',
|
|
163
164
|
logoVariantDark: '深色',
|
|
165
|
+
fontSearchTitle: '搜索 Google Fonts',
|
|
166
|
+
fontSearchPoweredByPrefix: '由 ',
|
|
167
|
+
fontSearchPlaceholder: '搜索字体家族…',
|
|
168
|
+
fontSearchPreviewPlaceholder: '预览文字',
|
|
169
|
+
fontSearchErrorTitle: '无法连接至 Google Fonts',
|
|
170
|
+
fontSearchErrorBody: '请检查网络连接后重试。',
|
|
171
|
+
fontSearchNoResults: '找不到「{query}」的字体',
|
|
172
|
+
fontSearchEmpty: '无可用字体',
|
|
173
|
+
fontSearchEmptyHintPrefix: '试试其他字体家族名,或在以下网站浏览完整目录: ',
|
|
174
|
+
fontSearchEmptyHintSuffix: '。',
|
|
175
|
+
fontWeightLabel: '字重',
|
|
176
|
+
fontPreviewSample: '永和九年 岁在癸丑 ABCabc 0123456789',
|
|
164
177
|
toastUploadFailed: '上传失败 ({status})',
|
|
165
178
|
toastReplaced: '已替换 {name}',
|
|
166
179
|
toastUploadedAs: '已以 {name} 上传',
|
|
@@ -170,6 +183,7 @@ export const zhCN: Locale = {
|
|
|
170
183
|
toastDeleteFailed: '删除失败 ({status})',
|
|
171
184
|
toastDeleted: '已删除 {name}',
|
|
172
185
|
toastDownloadFailed: '下载 Logo 失败',
|
|
186
|
+
toastFontDownloadFailed: '下载字体失败',
|
|
173
187
|
toastSearchFailed: '搜索失败',
|
|
174
188
|
},
|
|
175
189
|
commandMenu: {
|
|
@@ -196,10 +210,7 @@ export const zhCN: Locale = {
|
|
|
196
210
|
dark: '深色',
|
|
197
211
|
system: '系统',
|
|
198
212
|
},
|
|
199
|
-
|
|
200
|
-
toggleAria: '切换语言',
|
|
201
|
-
title: '语言',
|
|
202
|
-
},
|
|
213
|
+
|
|
203
214
|
themes: {
|
|
204
215
|
title: '主题',
|
|
205
216
|
noThemesTitle: '尚无主题',
|
package/src/locale/zh-tw.ts
CHANGED
|
@@ -18,7 +18,7 @@ export const zhTW: Locale = {
|
|
|
18
18
|
title: '找不到頁面',
|
|
19
19
|
},
|
|
20
20
|
home: {
|
|
21
|
-
appTitle: '
|
|
21
|
+
appTitle: 'Autono',
|
|
22
22
|
draft: '草稿',
|
|
23
23
|
duplicate: '複製',
|
|
24
24
|
themes: '主題',
|
|
@@ -28,7 +28,7 @@ export const zhTW: Locale = {
|
|
|
28
28
|
menu: '選單',
|
|
29
29
|
newFolder: '新增資料夾',
|
|
30
30
|
folderName: '資料夾名稱',
|
|
31
|
-
updateAvailable: '
|
|
31
|
+
updateAvailable: 'Autono {version} 已發布',
|
|
32
32
|
updatePackage: '更新',
|
|
33
33
|
updatingPackage: '更新中',
|
|
34
34
|
updatePackageDone: '已更新。請重新啟動 dev server 以使用新版本。',
|
|
@@ -124,6 +124,7 @@ export const zhTW: Locale = {
|
|
|
124
124
|
noMatchingAssetsHint: '請調整搜尋或篩選條件。',
|
|
125
125
|
clearFilters: '清除篩選',
|
|
126
126
|
searchLogos: '搜尋 Logo',
|
|
127
|
+
searchFonts: '搜尋字型',
|
|
127
128
|
upload: '上傳',
|
|
128
129
|
dropToUpload: '拖入即可上傳',
|
|
129
130
|
loading: '載入中…',
|
|
@@ -161,6 +162,18 @@ export const zhTW: Locale = {
|
|
|
161
162
|
logoSearchEmptyHintSuffix: '。',
|
|
162
163
|
logoVariantLight: '淺色',
|
|
163
164
|
logoVariantDark: '深色',
|
|
165
|
+
fontSearchTitle: '搜尋 Google Fonts',
|
|
166
|
+
fontSearchPoweredByPrefix: '由 ',
|
|
167
|
+
fontSearchPlaceholder: '搜尋字型家族…',
|
|
168
|
+
fontSearchPreviewPlaceholder: '預覽文字',
|
|
169
|
+
fontSearchErrorTitle: '無法連線至 Google Fonts',
|
|
170
|
+
fontSearchErrorBody: '請檢查網路連線後重試。',
|
|
171
|
+
fontSearchNoResults: '找不到「{query}」的字型',
|
|
172
|
+
fontSearchEmpty: '沒有可用的字型',
|
|
173
|
+
fontSearchEmptyHintPrefix: '試試其他字型家族名稱,或在以下網站瀏覽完整目錄: ',
|
|
174
|
+
fontSearchEmptyHintSuffix: '。',
|
|
175
|
+
fontWeightLabel: '字重',
|
|
176
|
+
fontPreviewSample: '永和九年 歲在癸丑 ABCabc 0123456789',
|
|
164
177
|
toastUploadFailed: '上傳失敗 ({status})',
|
|
165
178
|
toastReplaced: '已取代 {name}',
|
|
166
179
|
toastUploadedAs: '已以 {name} 上傳',
|
|
@@ -170,6 +183,7 @@ export const zhTW: Locale = {
|
|
|
170
183
|
toastDeleteFailed: '刪除失敗 ({status})',
|
|
171
184
|
toastDeleted: '已刪除 {name}',
|
|
172
185
|
toastDownloadFailed: '下載 Logo 失敗',
|
|
186
|
+
toastFontDownloadFailed: '下載字型失敗',
|
|
173
187
|
toastSearchFailed: '搜尋失敗',
|
|
174
188
|
},
|
|
175
189
|
commandMenu: {
|
|
@@ -196,10 +210,7 @@ export const zhTW: Locale = {
|
|
|
196
210
|
dark: '深色',
|
|
197
211
|
system: '系統',
|
|
198
212
|
},
|
|
199
|
-
|
|
200
|
-
toggleAria: '切換語言',
|
|
201
|
-
title: '語言',
|
|
202
|
-
},
|
|
213
|
+
|
|
203
214
|
themes: {
|
|
204
215
|
title: '主題',
|
|
205
216
|
noThemesTitle: '尚無主題',
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { type StdioOptions, spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
export const PKG = '@autono/open-pages';
|
|
6
|
+
const CACHE_TTL_MS = 10 * 60 * 1000;
|
|
7
|
+
const COMMAND_TIMEOUT_MS = 300_000;
|
|
8
|
+
|
|
9
|
+
export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
10
|
+
export type CommandSpec = { cmd: string; args: string[]; shell?: boolean };
|
|
11
|
+
|
|
12
|
+
let cache: { at: number; latest: string | null } | null = null;
|
|
13
|
+
|
|
14
|
+
function parseSemver(v: string): [number, number, number] | null {
|
|
15
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(v.trim());
|
|
16
|
+
if (!m) return null;
|
|
17
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isOutdated(current: string, latest: string): boolean {
|
|
21
|
+
const a = parseSemver(current);
|
|
22
|
+
const b = parseSemver(latest);
|
|
23
|
+
if (!a || !b) return false;
|
|
24
|
+
for (let i = 0; i < 3; i++) {
|
|
25
|
+
if (b[i] > a[i]) return true;
|
|
26
|
+
if (b[i] < a[i]) return false;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** npm `latest` dist-tag, cached for 10 minutes. Network failures yield null. */
|
|
32
|
+
export async function fetchLatest(now = Date.now()): Promise<string | null> {
|
|
33
|
+
if (cache && now - cache.at < CACHE_TTL_MS) return cache.latest;
|
|
34
|
+
try {
|
|
35
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG}/latest`, {
|
|
36
|
+
signal: AbortSignal.timeout(3000),
|
|
37
|
+
headers: { accept: 'application/json' },
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) throw new Error(`registry ${res.status}`);
|
|
40
|
+
const body = (await res.json()) as { version?: unknown };
|
|
41
|
+
const latest = typeof body.version === 'string' ? body.version : null;
|
|
42
|
+
cache = { at: now, latest };
|
|
43
|
+
return latest;
|
|
44
|
+
} catch {
|
|
45
|
+
return cache?.latest ?? null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function invalidateLatestCache(): void {
|
|
50
|
+
cache = null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function fileExists(file: string): Promise<boolean> {
|
|
54
|
+
try {
|
|
55
|
+
await fs.access(file);
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Lockfiles identify the workspace's package manager; npm_config_user_agent
|
|
63
|
+
// only identifies the process driving this run (e.g. `npx` in a pnpm repo).
|
|
64
|
+
const LOCKFILES: ReadonlyArray<readonly [string, PackageManager]> = [
|
|
65
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
66
|
+
['yarn.lock', 'yarn'],
|
|
67
|
+
['bun.lockb', 'bun'],
|
|
68
|
+
['bun.lock', 'bun'],
|
|
69
|
+
['package-lock.json', 'npm'],
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const PROJECT_ROOT_MARKERS = ['pnpm-workspace.yaml', '.git'];
|
|
73
|
+
|
|
74
|
+
async function declaredPackageManager(dir: string): Promise<PackageManager | null> {
|
|
75
|
+
try {
|
|
76
|
+
const raw = await fs.readFile(path.join(dir, 'package.json'), 'utf8');
|
|
77
|
+
const declared = (JSON.parse(raw) as { packageManager?: unknown }).packageManager;
|
|
78
|
+
if (typeof declared !== 'string') return null;
|
|
79
|
+
const name = declared.split('@')[0];
|
|
80
|
+
return name === 'npm' || name === 'pnpm' || name === 'yarn' || name === 'bun' ? name : null;
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function isProjectRoot(dir: string): Promise<boolean> {
|
|
87
|
+
for (const marker of PROJECT_ROOT_MARKERS) {
|
|
88
|
+
if (await fileExists(path.join(dir, marker))) return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function detectPackageManager(cwd: string): Promise<PackageManager> {
|
|
94
|
+
// Workspace members have no lockfile of their own; it lives at the root.
|
|
95
|
+
// The walk stops at the project root so a lockfile in an unrelated
|
|
96
|
+
// ancestor directory never picks the manager.
|
|
97
|
+
let dir = cwd;
|
|
98
|
+
while (true) {
|
|
99
|
+
const declared = await declaredPackageManager(dir);
|
|
100
|
+
if (declared) return declared;
|
|
101
|
+
for (const [lockfile, pm] of LOCKFILES) {
|
|
102
|
+
if (await fileExists(path.join(dir, lockfile))) return pm;
|
|
103
|
+
}
|
|
104
|
+
const parent = path.dirname(dir);
|
|
105
|
+
if (parent === dir || (await isProjectRoot(dir))) break;
|
|
106
|
+
dir = parent;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const ua = process.env.npm_config_user_agent ?? '';
|
|
110
|
+
if (ua.startsWith('pnpm')) return 'pnpm';
|
|
111
|
+
if (ua.startsWith('yarn')) return 'yarn';
|
|
112
|
+
if (ua.startsWith('bun')) return 'bun';
|
|
113
|
+
return 'npm';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function updateCommandFor(
|
|
117
|
+
packageManager: PackageManager,
|
|
118
|
+
cwd: string,
|
|
119
|
+
): Promise<CommandSpec> {
|
|
120
|
+
switch (packageManager) {
|
|
121
|
+
case 'pnpm': {
|
|
122
|
+
// pnpm rejects plain `add` at a workspace root with ERR_PNPM_ADDING_TO_ROOT.
|
|
123
|
+
const workspaceRoot = await fileExists(path.join(cwd, 'pnpm-workspace.yaml'));
|
|
124
|
+
return {
|
|
125
|
+
cmd: 'pnpm',
|
|
126
|
+
args: workspaceRoot
|
|
127
|
+
? ['add', '--workspace-root', `${PKG}@latest`]
|
|
128
|
+
: ['add', `${PKG}@latest`],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
case 'yarn':
|
|
132
|
+
return { cmd: 'yarn', args: ['add', `${PKG}@latest`] };
|
|
133
|
+
case 'bun':
|
|
134
|
+
return { cmd: 'bun', args: ['add', `${PKG}@latest`] };
|
|
135
|
+
case 'npm':
|
|
136
|
+
return { cmd: 'npm', args: ['install', `${PKG}@latest`] };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The freshly installed package's own CLI, so skills come from the new
|
|
142
|
+
* version rather than whatever process is driving the update.
|
|
143
|
+
*/
|
|
144
|
+
export function installCommandFor(packageManager: PackageManager): CommandSpec {
|
|
145
|
+
return { cmd: packageManager, args: ['install'] };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function localOpenPagesCommand(cwd: string, args: string[]): CommandSpec {
|
|
149
|
+
const bin = path.join(cwd, 'node_modules', ...PKG.split('/'), 'bin.js');
|
|
150
|
+
return { cmd: process.execPath, args: [bin, ...args], shell: false };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function formatCommand(spec: CommandSpec): string {
|
|
154
|
+
return [spec.cmd, ...spec.args].join(' ');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function runCommand(
|
|
158
|
+
spec: CommandSpec,
|
|
159
|
+
cwd: string,
|
|
160
|
+
opts: { stdio?: StdioOptions } = {},
|
|
161
|
+
): Promise<void> {
|
|
162
|
+
await new Promise<void>((resolve, reject) => {
|
|
163
|
+
const child = spawn(spec.cmd, spec.args, {
|
|
164
|
+
cwd,
|
|
165
|
+
env: process.env,
|
|
166
|
+
shell: spec.shell ?? process.platform === 'win32',
|
|
167
|
+
stdio: opts.stdio ?? ['ignore', 'ignore', 'pipe'],
|
|
168
|
+
});
|
|
169
|
+
let stderr = '';
|
|
170
|
+
const timer = setTimeout(() => {
|
|
171
|
+
child.kill();
|
|
172
|
+
reject(new Error(`${formatCommand(spec)} timed out`));
|
|
173
|
+
}, COMMAND_TIMEOUT_MS);
|
|
174
|
+
|
|
175
|
+
child.stderr?.on('data', (chunk: Buffer) => {
|
|
176
|
+
stderr += chunk.toString('utf8');
|
|
177
|
+
if (stderr.length > 2000) stderr = stderr.slice(-2000);
|
|
178
|
+
});
|
|
179
|
+
child.on('error', (err) => {
|
|
180
|
+
clearTimeout(timer);
|
|
181
|
+
reject(err);
|
|
182
|
+
});
|
|
183
|
+
child.on('close', (code) => {
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
if (code === 0) {
|
|
186
|
+
resolve();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const detail = stderr.trim();
|
|
190
|
+
reject(new Error(detail || `${formatCommand(spec)} exited with code ${code ?? 'unknown'}`));
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "radix-nova",
|
|
4
|
+
"rsc": false,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "styles/globals.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true,
|
|
11
|
+
"prefix": ""
|
|
12
|
+
},
|
|
13
|
+
"iconLibrary": "lucide",
|
|
14
|
+
"rtl": false,
|
|
15
|
+
"aliases": {
|
|
16
|
+
"components": "@/components",
|
|
17
|
+
"utils": "@/lib/utils",
|
|
18
|
+
"ui": "@/ui",
|
|
19
|
+
"lib": "@/lib",
|
|
20
|
+
"hooks": "@/hooks"
|
|
21
|
+
},
|
|
22
|
+
"menuColor": "default",
|
|
23
|
+
"menuAccent": "subtle",
|
|
24
|
+
"registries": {}
|
|
25
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"react": "^19.2.0",
|
|
3
|
+
"react-dom": "^19.2.0",
|
|
4
|
+
"@base-ui/react": "^1.7.0",
|
|
5
|
+
"@fontsource-variable/geist": "^5.3.0",
|
|
6
|
+
"@shadcn/react": "^0.3.1",
|
|
7
|
+
"class-variance-authority": "^0.7.1",
|
|
8
|
+
"clsx": "^2.1.1",
|
|
9
|
+
"cmdk": "^1.1.1",
|
|
10
|
+
"date-fns": "^4.4.0",
|
|
11
|
+
"embla-carousel-react": "^8.6.0",
|
|
12
|
+
"input-otp": "^1.5.0",
|
|
13
|
+
"lucide-react": "^1.37.0",
|
|
14
|
+
"next-themes": "^0.4.6",
|
|
15
|
+
"radix-ui": "^1.6.7",
|
|
16
|
+
"react-day-picker": "^10.0.1",
|
|
17
|
+
"react-resizable-panels": "^4.12.3",
|
|
18
|
+
"recharts": "^3.8.0",
|
|
19
|
+
"shadcn": "^4.19.0",
|
|
20
|
+
"sonner": "^2.0.8",
|
|
21
|
+
"tailwind-merge": "^3.6.0",
|
|
22
|
+
"tw-animate-css": "^1.4.0",
|
|
23
|
+
"vaul": "^1.1.2"
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
const MOBILE_BREAKPOINT = 768
|
|
4
|
+
|
|
5
|
+
export function useIsMobile() {
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
|
7
|
+
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
|
10
|
+
const onChange = () => {
|
|
11
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
12
|
+
}
|
|
13
|
+
mql.addEventListener("change", onChange)
|
|
14
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
15
|
+
return () => mql.removeEventListener("change", onChange)
|
|
16
|
+
}, [])
|
|
17
|
+
|
|
18
|
+
return !!isMobile
|
|
19
|
+
}
|