@allbluecn/ui 0.2.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.
Files changed (49) hide show
  1. package/package.json +85 -0
  2. package/src/ai-command-button.tsx +36 -0
  3. package/src/ai-stream-text.tsx +37 -0
  4. package/src/alert-dialog.tsx +216 -0
  5. package/src/animated-theme-toggler.tsx +272 -0
  6. package/src/auth-client.ts +108 -0
  7. package/src/auth-layout.tsx +66 -0
  8. package/src/avatar.tsx +129 -0
  9. package/src/badge.tsx +66 -0
  10. package/src/button.tsx +84 -0
  11. package/src/card.tsx +120 -0
  12. package/src/checkbox.tsx +50 -0
  13. package/src/context-menu.tsx +280 -0
  14. package/src/dialog.tsx +183 -0
  15. package/src/dropdown-menu.tsx +286 -0
  16. package/src/empty.tsx +121 -0
  17. package/src/grid-pattern.tsx +87 -0
  18. package/src/icon-packs/index.ts +27 -0
  19. package/src/icon-packs/knowledge.ts +55 -0
  20. package/src/icon-packs/prd.ts +63 -0
  21. package/src/icon-packs/project.ts +59 -0
  22. package/src/icon-picker.tsx +68 -0
  23. package/src/index.ts +23 -0
  24. package/src/input.tsx +36 -0
  25. package/src/item.tsx +213 -0
  26. package/src/kbd.tsx +33 -0
  27. package/src/label.tsx +39 -0
  28. package/src/layout-panel-top.tsx +160 -0
  29. package/src/name-confirm-dialog.tsx +153 -0
  30. package/src/nav-float-button.tsx +301 -0
  31. package/src/notion-avatar.tsx +126 -0
  32. package/src/placeholder-page.tsx +42 -0
  33. package/src/popover.tsx +106 -0
  34. package/src/reference-inline.tsx +53 -0
  35. package/src/reference-search.tsx +52 -0
  36. package/src/resizable.tsx +67 -0
  37. package/src/select.tsx +207 -0
  38. package/src/separator.tsx +45 -0
  39. package/src/sheet.tsx +164 -0
  40. package/src/sidebar.tsx +708 -0
  41. package/src/skeleton.tsx +30 -0
  42. package/src/sonner.tsx +37 -0
  43. package/src/switch.tsx +48 -0
  44. package/src/textarea.tsx +35 -0
  45. package/src/timezone-provider.tsx +55 -0
  46. package/src/tooltip.tsx +72 -0
  47. package/src/use-mobile.ts +36 -0
  48. package/src/user-avatar.tsx +79 -0
  49. package/src/utils.ts +6 -0
@@ -0,0 +1,286 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ "use client"
19
+
20
+ import * as React from "react"
21
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
22
+
23
+ import { cn } from "./utils"
24
+ import { CheckIcon, ChevronRightIcon } from "lucide-react"
25
+
26
+ function DropdownMenu({
27
+ ...props
28
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
29
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
30
+ }
31
+
32
+ function DropdownMenuPortal({
33
+ ...props
34
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
35
+ return (
36
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
37
+ )
38
+ }
39
+
40
+ function DropdownMenuTrigger({
41
+ ...props
42
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
43
+ return (
44
+ <DropdownMenuPrimitive.Trigger
45
+ data-slot="dropdown-menu-trigger"
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ function DropdownMenuContent({
52
+ className,
53
+ align = "start",
54
+ sideOffset = 4,
55
+ ...props
56
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
57
+ return (
58
+ <DropdownMenuPrimitive.Portal>
59
+ <DropdownMenuPrimitive.Content
60
+ data-slot="dropdown-menu-content"
61
+ sideOffset={sideOffset}
62
+ align={align}
63
+ className={cn("z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 dark:border dark:border-border dark:ring-0 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
64
+ {...props}
65
+ />
66
+ </DropdownMenuPrimitive.Portal>
67
+ )
68
+ }
69
+
70
+ function DropdownMenuGroup({
71
+ ...props
72
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
73
+ return (
74
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
75
+ )
76
+ }
77
+
78
+ function DropdownMenuItem({
79
+ className,
80
+ inset,
81
+ variant = "default",
82
+ ...props
83
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
84
+ inset?: boolean
85
+ variant?: "default" | "destructive"
86
+ }) {
87
+ return (
88
+ <DropdownMenuPrimitive.Item
89
+ data-slot="dropdown-menu-item"
90
+ data-inset={inset}
91
+ data-variant={variant}
92
+ className={cn(
93
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:*:[svg]:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
94
+ className
95
+ )}
96
+ {...props}
97
+ />
98
+ )
99
+ }
100
+
101
+ function DropdownMenuCheckboxItem({
102
+ className,
103
+ children,
104
+ checked,
105
+ inset,
106
+ ...props
107
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
108
+ inset?: boolean
109
+ }) {
110
+ return (
111
+ <DropdownMenuPrimitive.CheckboxItem
112
+ data-slot="dropdown-menu-checkbox-item"
113
+ data-inset={inset}
114
+ className={cn(
115
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:*:[svg]:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
116
+ className
117
+ )}
118
+ checked={checked}
119
+ {...props}
120
+ >
121
+ <span
122
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
123
+ data-slot="dropdown-menu-checkbox-item-indicator"
124
+ >
125
+ <DropdownMenuPrimitive.ItemIndicator>
126
+ <CheckIcon
127
+ />
128
+ </DropdownMenuPrimitive.ItemIndicator>
129
+ </span>
130
+ {children}
131
+ </DropdownMenuPrimitive.CheckboxItem>
132
+ )
133
+ }
134
+
135
+ function DropdownMenuRadioGroup({
136
+ ...props
137
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
138
+ return (
139
+ <DropdownMenuPrimitive.RadioGroup
140
+ data-slot="dropdown-menu-radio-group"
141
+ {...props}
142
+ />
143
+ )
144
+ }
145
+
146
+ function DropdownMenuRadioItem({
147
+ className,
148
+ children,
149
+ inset,
150
+ ...props
151
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
152
+ inset?: boolean
153
+ }) {
154
+ return (
155
+ <DropdownMenuPrimitive.RadioItem
156
+ data-slot="dropdown-menu-radio-item"
157
+ data-inset={inset}
158
+ className={cn(
159
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:*:[svg]:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
160
+ className
161
+ )}
162
+ {...props}
163
+ >
164
+ <span
165
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
166
+ data-slot="dropdown-menu-radio-item-indicator"
167
+ >
168
+ <DropdownMenuPrimitive.ItemIndicator>
169
+ <CheckIcon
170
+ />
171
+ </DropdownMenuPrimitive.ItemIndicator>
172
+ </span>
173
+ {children}
174
+ </DropdownMenuPrimitive.RadioItem>
175
+ )
176
+ }
177
+
178
+ function DropdownMenuLabel({
179
+ className,
180
+ inset,
181
+ ...props
182
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
183
+ inset?: boolean
184
+ }) {
185
+ return (
186
+ <DropdownMenuPrimitive.Label
187
+ data-slot="dropdown-menu-label"
188
+ data-inset={inset}
189
+ className={cn(
190
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
191
+ className
192
+ )}
193
+ {...props}
194
+ />
195
+ )
196
+ }
197
+
198
+ function DropdownMenuSeparator({
199
+ className,
200
+ ...props
201
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
202
+ return (
203
+ <DropdownMenuPrimitive.Separator
204
+ data-slot="dropdown-menu-separator"
205
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
206
+ {...props}
207
+ />
208
+ )
209
+ }
210
+
211
+ function DropdownMenuShortcut({
212
+ className,
213
+ ...props
214
+ }: React.ComponentProps<"span">) {
215
+ return (
216
+ <span
217
+ data-slot="dropdown-menu-shortcut"
218
+ className={cn(
219
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
220
+ className
221
+ )}
222
+ {...props}
223
+ />
224
+ )
225
+ }
226
+
227
+ function DropdownMenuSub({
228
+ ...props
229
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
230
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
231
+ }
232
+
233
+ function DropdownMenuSubTrigger({
234
+ className,
235
+ inset,
236
+ children,
237
+ ...props
238
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
239
+ inset?: boolean
240
+ }) {
241
+ return (
242
+ <DropdownMenuPrimitive.SubTrigger
243
+ data-slot="dropdown-menu-sub-trigger"
244
+ data-inset={inset}
245
+ className={cn(
246
+ "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:*:[svg]:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
247
+ className
248
+ )}
249
+ {...props}
250
+ >
251
+ {children}
252
+ <ChevronRightIcon className="ml-auto" />
253
+ </DropdownMenuPrimitive.SubTrigger>
254
+ )
255
+ }
256
+
257
+ function DropdownMenuSubContent({
258
+ className,
259
+ ...props
260
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
261
+ return (
262
+ <DropdownMenuPrimitive.SubContent
263
+ data-slot="dropdown-menu-sub-content"
264
+ className={cn("z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 dark:border dark:border-border dark:ring-0 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
265
+ {...props}
266
+ />
267
+ )
268
+ }
269
+
270
+ export {
271
+ DropdownMenu,
272
+ DropdownMenuPortal,
273
+ DropdownMenuTrigger,
274
+ DropdownMenuContent,
275
+ DropdownMenuGroup,
276
+ DropdownMenuLabel,
277
+ DropdownMenuItem,
278
+ DropdownMenuCheckboxItem,
279
+ DropdownMenuRadioGroup,
280
+ DropdownMenuRadioItem,
281
+ DropdownMenuSeparator,
282
+ DropdownMenuShortcut,
283
+ DropdownMenuSub,
284
+ DropdownMenuSubTrigger,
285
+ DropdownMenuSubContent,
286
+ }
package/src/empty.tsx ADDED
@@ -0,0 +1,121 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { cva, type VariantProps } from "class-variance-authority"
19
+
20
+ import { cn } from "./utils"
21
+
22
+ function Empty({ className, ...props }: React.ComponentProps<"div">) {
23
+ return (
24
+ <div
25
+ data-slot="empty"
26
+ className={cn(
27
+ "flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-xl border-dashed p-6 text-center text-balance",
28
+ className
29
+ )}
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
36
+ return (
37
+ <div
38
+ data-slot="empty-header"
39
+ className={cn("flex max-w-sm flex-col items-center gap-2", className)}
40
+ {...props}
41
+ />
42
+ )
43
+ }
44
+
45
+ const emptyMediaVariants = cva(
46
+ "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
47
+ {
48
+ variants: {
49
+ variant: {
50
+ default: "bg-transparent",
51
+ icon: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-4",
52
+ },
53
+ },
54
+ defaultVariants: {
55
+ variant: "default",
56
+ },
57
+ }
58
+ )
59
+
60
+ function EmptyMedia({
61
+ className,
62
+ variant = "default",
63
+ ...props
64
+ }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
65
+ return (
66
+ <div
67
+ data-slot="empty-icon"
68
+ data-variant={variant}
69
+ className={cn(emptyMediaVariants({ variant, className }))}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
76
+ return (
77
+ <div
78
+ data-slot="empty-title"
79
+ className={cn(
80
+ "font-heading text-sm font-medium tracking-tight",
81
+ className
82
+ )}
83
+ {...props}
84
+ />
85
+ )
86
+ }
87
+
88
+ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
89
+ return (
90
+ <div
91
+ data-slot="empty-description"
92
+ className={cn(
93
+ "text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
94
+ className
95
+ )}
96
+ {...props}
97
+ />
98
+ )
99
+ }
100
+
101
+ function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
102
+ return (
103
+ <div
104
+ data-slot="empty-content"
105
+ className={cn(
106
+ "flex w-full max-w-sm min-w-0 flex-col items-center gap-2.5 text-sm text-balance",
107
+ className
108
+ )}
109
+ {...props}
110
+ />
111
+ )
112
+ }
113
+
114
+ export {
115
+ Empty,
116
+ EmptyHeader,
117
+ EmptyTitle,
118
+ EmptyDescription,
119
+ EmptyContent,
120
+ EmptyMedia,
121
+ }
@@ -0,0 +1,87 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { useId } from "react"
19
+
20
+ import { cn } from "./utils"
21
+
22
+ interface GridPatternProps extends React.SVGProps<SVGSVGElement> {
23
+ width?: number
24
+ height?: number
25
+ x?: number
26
+ y?: number
27
+ squares?: Array<[x: number, y: number]>
28
+ strokeDasharray?: string
29
+ className?: string
30
+ [key: string]: unknown
31
+ }
32
+
33
+ export function GridPattern({
34
+ width = 40,
35
+ height = 40,
36
+ x = -1,
37
+ y = -1,
38
+ strokeDasharray = "0",
39
+ squares,
40
+ className,
41
+ ...props
42
+ }: GridPatternProps) {
43
+ const id = useId()
44
+
45
+ return (
46
+ <svg
47
+ aria-hidden="true"
48
+ className={cn(
49
+ "pointer-events-none absolute inset-0 h-full w-full fill-gray-400/30 stroke-gray-400/30",
50
+ className
51
+ )}
52
+ {...props}
53
+ >
54
+ <defs>
55
+ <pattern
56
+ id={id}
57
+ width={width}
58
+ height={height}
59
+ patternUnits="userSpaceOnUse"
60
+ x={x}
61
+ y={y}
62
+ >
63
+ <path
64
+ d={`M.5 ${height}V.5H${width}`}
65
+ fill="none"
66
+ strokeDasharray={strokeDasharray}
67
+ />
68
+ </pattern>
69
+ </defs>
70
+ <rect width="100%" height="100%" strokeWidth={0} fill={`url(#${id})`} />
71
+ {squares && (
72
+ <svg x={x} y={y} className="overflow-visible">
73
+ {squares.map(([x, y], i) => (
74
+ <rect
75
+ strokeWidth="0"
76
+ key={`${i}-${x}-${y}`}
77
+ width={width - 1}
78
+ height={height - 1}
79
+ x={x * width + 1}
80
+ y={y * height + 1}
81
+ />
82
+ ))}
83
+ </svg>
84
+ )}
85
+ </svg>
86
+ )
87
+ }
@@ -0,0 +1,27 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import type { LucideIcon } from "lucide-react";
19
+
20
+ export interface IconItem {
21
+ value: string;
22
+ icon: LucideIcon;
23
+ }
24
+
25
+ export { PROJECT_ICONS } from "./project";
26
+ export { PRD_ICONS } from "./prd";
27
+ export { KNOWLEDGE_ICONS } from "./knowledge";
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import {
19
+ BookOpen,
20
+ FileText,
21
+ Library,
22
+ Archive,
23
+ Bookmark,
24
+ Tags,
25
+ Lightbulb,
26
+ GraduationCap,
27
+ Brain,
28
+ NotebookPen,
29
+ Files,
30
+ FolderOpen,
31
+ ScrollText,
32
+ Newspaper,
33
+ PencilLine,
34
+ Quote,
35
+ } from "lucide-react";
36
+ import type { IconItem } from "./index";
37
+
38
+ export const KNOWLEDGE_ICONS: IconItem[] = [
39
+ { value: "bookOpen", icon: BookOpen },
40
+ { value: "fileText", icon: FileText },
41
+ { value: "library", icon: Library },
42
+ { value: "archive", icon: Archive },
43
+ { value: "bookmark", icon: Bookmark },
44
+ { value: "tags", icon: Tags },
45
+ { value: "lightbulb", icon: Lightbulb },
46
+ { value: "graduationCap", icon: GraduationCap },
47
+ { value: "brain", icon: Brain },
48
+ { value: "notebookPen", icon: NotebookPen },
49
+ { value: "files", icon: Files },
50
+ { value: "folderOpen", icon: FolderOpen },
51
+ { value: "scrollText", icon: ScrollText },
52
+ { value: "newspaper", icon: Newspaper },
53
+ { value: "pencilLine", icon: PencilLine },
54
+ { value: "quote", icon: Quote },
55
+ ];
@@ -0,0 +1,63 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import {
19
+ FileText,
20
+ LayoutGrid,
21
+ MousePointerClick,
22
+ TextCursorInput,
23
+ Table2,
24
+ Image,
25
+ ShoppingCart,
26
+ User,
27
+ Settings2,
28
+ Mail,
29
+ Bell,
30
+ Search,
31
+ Calendar,
32
+ BarChart3,
33
+ MessageSquare,
34
+ Smile,
35
+ Monitor,
36
+ Smartphone,
37
+ Layout,
38
+ AppWindow,
39
+ } from "lucide-react";
40
+ import type { IconItem } from "./index";
41
+
42
+ export const PRD_ICONS: IconItem[] = [
43
+ { value: "fileText", icon: FileText },
44
+ { value: "layoutGrid", icon: LayoutGrid },
45
+ { value: "mousePointerClick", icon: MousePointerClick },
46
+ { value: "textCursorInput", icon: TextCursorInput },
47
+ { value: "table2", icon: Table2 },
48
+ { value: "image", icon: Image },
49
+ { value: "shoppingCart", icon: ShoppingCart },
50
+ { value: "user", icon: User },
51
+ { value: "settings2", icon: Settings2 },
52
+ { value: "mail", icon: Mail },
53
+ { value: "bell", icon: Bell },
54
+ { value: "search", icon: Search },
55
+ { value: "calendar", icon: Calendar },
56
+ { value: "barChart3", icon: BarChart3 },
57
+ { value: "messageSquare", icon: MessageSquare },
58
+ { value: "smile", icon: Smile },
59
+ { value: "monitor", icon: Monitor },
60
+ { value: "smartphone", icon: Smartphone },
61
+ { value: "layout", icon: Layout },
62
+ { value: "appWindow", icon: AppWindow },
63
+ ];
@@ -0,0 +1,59 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import {
19
+ FolderKanban,
20
+ BriefcaseBusiness,
21
+ Rocket,
22
+ FlaskConical,
23
+ Terminal,
24
+ Contrast,
25
+ MessageSquare,
26
+ GraduationCap,
27
+ HeartPulse,
28
+ ShoppingCart,
29
+ Layers,
30
+ Users,
31
+ Globe,
32
+ Sparkles,
33
+ Compass,
34
+ ShieldCheck,
35
+ Sprout,
36
+ } from "lucide-react";
37
+ import type { IconItem } from "./index";
38
+
39
+ // 项目图标集(静态 lucide,用于 IconPicker 选择器、列表/侧边栏等静态展示)
40
+ // value 与 ProjectAnimatedIcon 的动画映射一一对应
41
+ export const PROJECT_ICONS: IconItem[] = [
42
+ { value: "folder-kanban", icon: FolderKanban },
43
+ { value: "briefcase-business", icon: BriefcaseBusiness },
44
+ { value: "rocket", icon: Rocket },
45
+ { value: "flask", icon: FlaskConical },
46
+ { value: "terminal", icon: Terminal },
47
+ { value: "contrast", icon: Contrast },
48
+ { value: "message-square", icon: MessageSquare },
49
+ { value: "graduation-cap", icon: GraduationCap },
50
+ { value: "heart-pulse", icon: HeartPulse },
51
+ { value: "cart", icon: ShoppingCart },
52
+ { value: "layers", icon: Layers },
53
+ { value: "users", icon: Users },
54
+ { value: "earth", icon: Globe },
55
+ { value: "sparkles", icon: Sparkles },
56
+ { value: "compass", icon: Compass },
57
+ { value: "shield-check", icon: ShieldCheck },
58
+ { value: "sprout", icon: Sprout },
59
+ ];