mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-29 23:12:38 +08:00
feat: enhance Prettier configuration and update store components
- Added Tailwind CSS support to Prettier configuration with new settings for styles and functions. - Updated package.json to include the prettier-plugin-tailwindcss dependency. - Refactored various store components for improved layout and organization, including adjustments to error handling and component structure. - Enhanced CSS styles for better responsiveness and visual consistency across components.
This commit is contained in:
parent
c799f15fcc
commit
ef16558947
@ -4,5 +4,8 @@
|
||||
"printWidth": 120,
|
||||
"trailingComma": "none",
|
||||
"endOfLine": "lf",
|
||||
"bracketSameLine": true
|
||||
"bracketSameLine": true,
|
||||
"tailwindStylesheet": "./src/renderer/src/assets/styles/tailwind.css",
|
||||
"tailwindFunctions": ["clsx"],
|
||||
"plugins": ["prettier-plugin-tailwindcss"],
|
||||
}
|
||||
|
||||
@ -191,6 +191,7 @@
|
||||
"openai": "patch:openai@npm%3A4.96.0#~/.yarn/patches/openai-npm-4.96.0-0665b05cb9.patch",
|
||||
"p-queue": "^8.1.0",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"rc-virtual-list": "^3.18.5",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
@import 'tailwindcss';
|
||||
@import 'tailwindcss' source('../../../src');
|
||||
@import 'tw-animate-css';
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
/* 如需自定义:
|
||||
1. 清晰地组织自定义 CSS 到相应的层中。
|
||||
2. 基础样式(如全局重置、链接样式)放入 base 层;
|
||||
3. 可复用的组件样式(如果仍使用 @apply 或原生 CSS 嵌套创建)放入 components 层;
|
||||
4. 新的自定义工具类放入 utilities 层。
|
||||
*/
|
||||
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(1 0 0);
|
||||
@ -112,19 +119,19 @@
|
||||
--animate-marquee: marquee var(--duration) infinite linear;
|
||||
--animate-marquee-vertical: marquee-vertical var(--duration) linear infinite;
|
||||
@keyframes marquee {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
from {
|
||||
transform: translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: translateX(calc(-100% - var(--gap)));
|
||||
to {
|
||||
transform: translateX(calc(-100% - var(--gap)));
|
||||
}
|
||||
}
|
||||
@keyframes marquee-vertical {
|
||||
from {
|
||||
transform: translateY(0);
|
||||
from {
|
||||
transform: translateY(0);
|
||||
}
|
||||
to {
|
||||
transform: translateY(calc(-100% - var(--gap)));
|
||||
to {
|
||||
transform: translateY(calc(-100% - var(--gap)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,4 +143,4 @@
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,9 +20,9 @@ export function GridView({ items }: { items: CherryStoreItem[] }) {
|
||||
<>
|
||||
<div className="columns-4 gap-4">
|
||||
{items.map((item) => (
|
||||
<BlurFade key={item.id} delay={0.2} inView className="mb-4 cursor-pointer ">
|
||||
<BlurFade key={item.id} delay={0.2} inView className="mb-4 cursor-pointer">
|
||||
<Card
|
||||
className="overflow-hidden hover:scale-105 transition-transform"
|
||||
className="overflow-hidden transition-transform hover:scale-105"
|
||||
onClick={() => handleCardClick(item)}>
|
||||
<CardHeader className="p-0">
|
||||
{item.icon ? (
|
||||
|
||||
@ -46,10 +46,10 @@ export function ItemDetailDialog({
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>
|
||||
<DialogContent className="max-h-[90vh] sm:max-w-4xl overflow-y-auto">
|
||||
<DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-4xl">
|
||||
<DialogHeader className="flex flex-row items-start justify-between">
|
||||
<div>
|
||||
<DialogTitle className="flex items-center text-xl space-x-1">
|
||||
<DialogTitle className="flex items-center space-x-1 text-xl">
|
||||
{item.title}
|
||||
<Badge variant="outline" className="ml-2">
|
||||
{item.type}
|
||||
@ -62,7 +62,7 @@ export function ItemDetailDialog({
|
||||
|
||||
<div className="mt-4 grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||
<div className="md:col-span-2">
|
||||
<div className="rounded-lg border bg-card p-6 text-card-foreground shadow-sm mt-4">
|
||||
<div className="mt-4 rounded-lg border bg-card p-6 text-card-foreground shadow-sm">
|
||||
<ReactMarkdown>{item.prompt}</ReactMarkdown>
|
||||
</div>
|
||||
|
||||
@ -84,7 +84,7 @@ export function ItemDetailDialog({
|
||||
<div className="space-y-4">
|
||||
<div className="overflow-hidden">
|
||||
{item.image && (
|
||||
<div className="aspect-square w-full rounded-lg border overflow-hidden bg-muted">
|
||||
<div className="aspect-square w-full overflow-hidden rounded-lg border bg-muted">
|
||||
<img src={item.image || '/placeholder.svg'} alt={item.title} className="h-full w-full object-cover" />
|
||||
</div>
|
||||
)}
|
||||
@ -125,7 +125,7 @@ export function ItemDetailDialog({
|
||||
{/* )} */}
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border bg-card p-4 text-card-foreground shadow-sm space-y-2">
|
||||
<div className="space-y-2 rounded-lg border bg-card p-4 text-card-foreground shadow-sm">
|
||||
<h3 className="mb-2 text-sm font-medium">标签</h3>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{item.tags.map((tag: string) => (
|
||||
|
||||
@ -20,10 +20,10 @@ export function ListView({ items }: { items: CherryStoreItem[] }) {
|
||||
{items.map((item) => (
|
||||
<Card
|
||||
key={item.id}
|
||||
className="p-0 cursor-pointer hover:shadow-lg transition-shadow"
|
||||
className="cursor-pointer p-0 transition-shadow hover:shadow-lg"
|
||||
onClick={() => handleCardClick(item)}>
|
||||
<div className="flex flex-col sm:flex-row">
|
||||
<div className="h-24 w-24 shrink-0 overflow-hidden rounded-l-lg bg-muted sm:h-auto flex items-center justify-center">
|
||||
<div className="flex h-24 w-24 shrink-0 items-center justify-center overflow-hidden rounded-l-lg bg-muted sm:h-auto">
|
||||
{item.icon ? (
|
||||
<div
|
||||
className="flex h-full w-full items-center justify-center text-3xl"
|
||||
|
||||
@ -26,14 +26,14 @@ export function StoreContent({
|
||||
onViewModeChange
|
||||
}: StoreContentProps) {
|
||||
return (
|
||||
<div className="flex-1 overflow-auto w-full">
|
||||
<div className="w-full flex-1 overflow-auto">
|
||||
{/* Sticky Header for Search, Filter, View Mode, and Category Tabs */}
|
||||
<div className="sticky top-0 z-10 border-b bg-background p-4">
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Top row: Search, Filter, View buttons */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Search className="absolute top-2.5 left-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
type="search"
|
||||
placeholder="Search store..."
|
||||
@ -84,7 +84,7 @@ export function StoreContent({
|
||||
</div>
|
||||
|
||||
{/* Main Content Area: Grid or List View */}
|
||||
<div className="p-4 w-full">
|
||||
<div className="w-full p-4">
|
||||
{items.length === 0 ? (
|
||||
<div className="flex h-[400px] items-center justify-center">
|
||||
<p className="text-center text-muted-foreground">No items found matching your criteria.</p>
|
||||
|
||||
@ -18,7 +18,7 @@ export function StoreSidebar({
|
||||
}: StoreSidebarProps) {
|
||||
if (!categories || categories.length === 0) {
|
||||
return (
|
||||
<Sidebar className="absolute left-0 top-0 h-full border-r">
|
||||
<Sidebar className="absolute top-0 left-0 h-full border-r">
|
||||
<SidebarContent>
|
||||
<p className="p-4 text-sm text-gray-500">No categories loaded.</p>
|
||||
</SidebarContent>
|
||||
@ -27,7 +27,7 @@ export function StoreSidebar({
|
||||
}
|
||||
|
||||
return (
|
||||
<Sidebar className="absolute left-0 top-0 h-full border-r">
|
||||
<Sidebar className="absolute top-0 left-0 h-full border-r">
|
||||
<SidebarContent>
|
||||
<SidebarMenu className="gap-0">
|
||||
{categories.map((category, index) => (
|
||||
@ -41,7 +41,7 @@ export function StoreSidebar({
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="overflow-hidden text-sm transition-all data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down">
|
||||
<SidebarMenu className="py-1 pl-4 pr-1">
|
||||
<SidebarMenu className="py-1 pr-1 pl-4">
|
||||
{category.items.map((subItem) => (
|
||||
<SidebarMenuItem key={subItem.id}>
|
||||
<SidebarMenuButton
|
||||
|
||||
@ -78,7 +78,7 @@ export default function StoreLayout() {
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div className="p-4 text-red-500 text-center">Error: {error}</div>
|
||||
return <div className="p-4 text-center text-red-500">Error: {error}</div>
|
||||
}
|
||||
|
||||
return (
|
||||
@ -87,7 +87,7 @@ export default function StoreLayout() {
|
||||
<NavbarCenter>{t('store.title')}</NavbarCenter>
|
||||
</Navbar>
|
||||
<div id="content-container" className="h-full w-full">
|
||||
<SidebarProvider className="h-full w-full relative min-h-full">
|
||||
<SidebarProvider className="relative h-full min-h-full w-full">
|
||||
<StoreSidebar
|
||||
categories={categories}
|
||||
selectedCategory={selectedCategory}
|
||||
|
||||
59
yarn.lock
59
yarn.lock
@ -5348,6 +5348,7 @@ __metadata:
|
||||
os-proxy-config: "npm:^1.1.2"
|
||||
p-queue: "npm:^8.1.0"
|
||||
prettier: "npm:^3.5.3"
|
||||
prettier-plugin-tailwindcss: "npm:^0.6.11"
|
||||
proxy-agent: "npm:^6.5.0"
|
||||
rc-virtual-list: "npm:^3.18.5"
|
||||
react: "npm:^19.0.0"
|
||||
@ -14867,6 +14868,64 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier-plugin-tailwindcss@npm:^0.6.11":
|
||||
version: 0.6.11
|
||||
resolution: "prettier-plugin-tailwindcss@npm:0.6.11"
|
||||
peerDependencies:
|
||||
"@ianvs/prettier-plugin-sort-imports": "*"
|
||||
"@prettier/plugin-pug": "*"
|
||||
"@shopify/prettier-plugin-liquid": "*"
|
||||
"@trivago/prettier-plugin-sort-imports": "*"
|
||||
"@zackad/prettier-plugin-twig": "*"
|
||||
prettier: ^3.0
|
||||
prettier-plugin-astro: "*"
|
||||
prettier-plugin-css-order: "*"
|
||||
prettier-plugin-import-sort: "*"
|
||||
prettier-plugin-jsdoc: "*"
|
||||
prettier-plugin-marko: "*"
|
||||
prettier-plugin-multiline-arrays: "*"
|
||||
prettier-plugin-organize-attributes: "*"
|
||||
prettier-plugin-organize-imports: "*"
|
||||
prettier-plugin-sort-imports: "*"
|
||||
prettier-plugin-style-order: "*"
|
||||
prettier-plugin-svelte: "*"
|
||||
peerDependenciesMeta:
|
||||
"@ianvs/prettier-plugin-sort-imports":
|
||||
optional: true
|
||||
"@prettier/plugin-pug":
|
||||
optional: true
|
||||
"@shopify/prettier-plugin-liquid":
|
||||
optional: true
|
||||
"@trivago/prettier-plugin-sort-imports":
|
||||
optional: true
|
||||
"@zackad/prettier-plugin-twig":
|
||||
optional: true
|
||||
prettier-plugin-astro:
|
||||
optional: true
|
||||
prettier-plugin-css-order:
|
||||
optional: true
|
||||
prettier-plugin-import-sort:
|
||||
optional: true
|
||||
prettier-plugin-jsdoc:
|
||||
optional: true
|
||||
prettier-plugin-marko:
|
||||
optional: true
|
||||
prettier-plugin-multiline-arrays:
|
||||
optional: true
|
||||
prettier-plugin-organize-attributes:
|
||||
optional: true
|
||||
prettier-plugin-organize-imports:
|
||||
optional: true
|
||||
prettier-plugin-sort-imports:
|
||||
optional: true
|
||||
prettier-plugin-style-order:
|
||||
optional: true
|
||||
prettier-plugin-svelte:
|
||||
optional: true
|
||||
checksum: 10c0/e5688a86f457b4eaa682d83a86702826d2d828db4cfc153b8b1f0b8409c94530a4bde8deb3e819497ba8e4bd0eda08ed55468a41a8138f82db43d633cf332121
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^3.5.3":
|
||||
version: 3.5.3
|
||||
resolution: "prettier@npm:3.5.3"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user