@allbluecn/admin-app 0.2.6 → 0.3.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 (204) hide show
  1. package/package.json +16 -12
  2. package/src/components/admin/admin-user-menu.tsx +2 -4
  3. package/src/components/admin/developer-log.tsx +3 -5
  4. package/src/components/ai-memory/memory-facts-panel.tsx +383 -0
  5. package/src/components/ai-prompts/preview-panel.tsx +165 -0
  6. package/src/components/ai-prompts/prompt-editor.tsx +328 -0
  7. package/src/components/ai-prompts/prompt-table.tsx +141 -0
  8. package/src/components/ai-prompts/prompt-utils.ts +124 -0
  9. package/src/components/ai-prompts/section-editor.tsx +135 -0
  10. package/src/components/ai-prompts/variable-panel.tsx +128 -0
  11. package/src/components/ai-prompts/version-history.tsx +157 -0
  12. package/src/components/ai-provider/provider-form.tsx +6 -10
  13. package/src/components/ai-provider/provider-table.tsx +33 -13
  14. package/src/components/auth/admin-login-form.tsx +1 -1
  15. package/src/components/component/component-form-dialog.tsx +4 -4
  16. package/src/components/component/component-import-dialog.tsx +2 -2
  17. package/src/components/dependency/changelog-dialog.tsx +2 -4
  18. package/src/components/dependency/columns.tsx +4 -8
  19. package/src/components/dependency/dependency-table.tsx +2 -2
  20. package/src/components/dependency/edit-dialog.tsx +7 -11
  21. package/src/components/invitations/invitations-page.tsx +4 -8
  22. package/src/components/knowledge-public/bookmark-form-dialog.tsx +1 -1
  23. package/src/components/knowledge-public/compliance-form-dialog.tsx +1 -1
  24. package/src/components/knowledge-public/legal-form-dialog.tsx +2 -2
  25. package/src/components/layout/sidebar-02/app-sidebar.tsx +17 -9
  26. package/src/components/layout/sidebar-02/nav-main.tsx +6 -14
  27. package/src/components/layout/sidebar-02/nav-notifications.tsx +3 -7
  28. package/src/components/magicui/rainbow-button.tsx +2 -2
  29. package/src/components/market/columns.tsx +2 -4
  30. package/src/components/market/market-app-form.tsx +2 -2
  31. package/src/components/market/market-app-list.tsx +1 -1
  32. package/src/components/oauth-providers/provider-page.tsx +1 -1
  33. package/src/components/ui/alert-dialog.tsx +28 -57
  34. package/src/components/ui/alert.tsx +3 -4
  35. package/src/components/ui/avatar.tsx +5 -28
  36. package/src/components/ui/badge.tsx +19 -34
  37. package/src/components/ui/button.tsx +14 -41
  38. package/src/components/ui/card.tsx +6 -24
  39. package/src/components/ui/checkbox.tsx +4 -26
  40. package/src/components/ui/collapsible.tsx +6 -37
  41. package/src/components/ui/dialog.tsx +30 -60
  42. package/src/components/ui/dropdown-menu.tsx +118 -137
  43. package/src/components/ui/field.tsx +8 -27
  44. package/src/components/ui/input-group.tsx +13 -26
  45. package/src/components/ui/input.tsx +4 -21
  46. package/src/components/ui/label.tsx +3 -27
  47. package/src/components/ui/pagination.tsx +17 -31
  48. package/src/components/ui/select.tsx +101 -76
  49. package/src/components/ui/separator.tsx +4 -27
  50. package/src/components/ui/sheet.tsx +29 -58
  51. package/src/components/ui/sidebar.tsx +119 -117
  52. package/src/components/ui/skeleton.tsx +1 -18
  53. package/src/components/ui/switch.tsx +5 -24
  54. package/src/components/ui/table.tsx +1 -19
  55. package/src/components/ui/textarea.tsx +2 -20
  56. package/src/components/ui/toast.tsx +282 -0
  57. package/src/components/ui/tooltip.tsx +34 -45
  58. package/src/components/user/settings-activity-log.tsx +1 -1
  59. package/src/components/user/user-create-dialog.tsx +2 -2
  60. package/src/components/user/user-filters.tsx +2 -2
  61. package/src/hooks/use-mobile.ts +0 -17
  62. package/src/lib/pacer.ts +21 -0
  63. package/src/lib/utils.ts +1 -23
  64. package/src/paraglide/messages/_index.js +95 -0
  65. package/src/paraglide/messages/admin_ai_memory_action_clearuser1.js +30 -0
  66. package/src/paraglide/messages/admin_ai_memory_action_query.js +30 -0
  67. package/src/paraglide/messages/admin_ai_memory_clear_cancel.js +30 -0
  68. package/src/paraglide/messages/admin_ai_memory_clear_confirm_action.js +30 -0
  69. package/src/paraglide/messages/admin_ai_memory_clear_confirm_description.js +30 -0
  70. package/src/paraglide/messages/admin_ai_memory_clear_confirm_title.js +30 -0
  71. package/src/paraglide/messages/admin_ai_memory_columns_actions.js +30 -0
  72. package/src/paraglide/messages/admin_ai_memory_columns_content.js +30 -0
  73. package/src/paraglide/messages/admin_ai_memory_columns_createdat1.js +30 -0
  74. package/src/paraglide/messages/admin_ai_memory_columns_threadid1.js +30 -0
  75. package/src/paraglide/messages/admin_ai_memory_delete_cancel.js +30 -0
  76. package/src/paraglide/messages/admin_ai_memory_delete_confirm_action.js +30 -0
  77. package/src/paraglide/messages/admin_ai_memory_delete_confirm_description.js +30 -0
  78. package/src/paraglide/messages/admin_ai_memory_delete_confirm_title.js +30 -0
  79. package/src/paraglide/messages/admin_ai_memory_empty.js +30 -0
  80. package/src/paraglide/messages/admin_ai_memory_emptyhint1.js +30 -0
  81. package/src/paraglide/messages/admin_ai_memory_error_nouserid2.js +30 -0
  82. package/src/paraglide/messages/admin_ai_memory_error_query.js +30 -0
  83. package/src/paraglide/messages/admin_ai_memory_error_title.js +30 -0
  84. package/src/paraglide/messages/admin_ai_memory_form_user.js +30 -0
  85. package/src/paraglide/messages/admin_ai_memory_page_description.js +30 -0
  86. package/src/paraglide/messages/admin_ai_memory_page_title.js +30 -0
  87. package/src/paraglide/messages/admin_ai_memory_placeholder_user.js +30 -0
  88. package/src/paraglide/messages/admin_ai_memory_stat_count.js +30 -0
  89. package/src/paraglide/messages/admin_ai_memory_stat_lastwrite1.js +30 -0
  90. package/src/paraglide/messages/admin_ai_memory_toast_cleared.js +30 -0
  91. package/src/paraglide/messages/admin_ai_memory_toast_deleted.js +30 -0
  92. package/src/paraglide/messages/admin_ai_prompts_active.js +30 -0
  93. package/src/paraglide/messages/admin_ai_prompts_back.js +30 -0
  94. package/src/paraglide/messages/admin_ai_prompts_badge_protected.js +30 -0
  95. package/src/paraglide/messages/admin_ai_prompts_cache_hint.js +30 -0
  96. package/src/paraglide/messages/admin_ai_prompts_columns_active.js +30 -0
  97. package/src/paraglide/messages/admin_ai_prompts_columns_key.js +30 -0
  98. package/src/paraglide/messages/admin_ai_prompts_columns_name.js +30 -0
  99. package/src/paraglide/messages/admin_ai_prompts_columns_protected.js +30 -0
  100. package/src/paraglide/messages/admin_ai_prompts_columns_updatedat1.js +30 -0
  101. package/src/paraglide/messages/admin_ai_prompts_columns_version.js +30 -0
  102. package/src/paraglide/messages/admin_ai_prompts_description.js +30 -0
  103. package/src/paraglide/messages/admin_ai_prompts_description_placeholder.js +30 -0
  104. package/src/paraglide/messages/admin_ai_prompts_edit.js +30 -0
  105. package/src/paraglide/messages/admin_ai_prompts_name.js +30 -0
  106. package/src/paraglide/messages/admin_ai_prompts_name_placeholder.js +30 -0
  107. package/src/paraglide/messages/admin_ai_prompts_note_placeholder.js +30 -0
  108. package/src/paraglide/messages/admin_ai_prompts_page_description.js +30 -0
  109. package/src/paraglide/messages/admin_ai_prompts_page_title.js +30 -0
  110. package/src/paraglide/messages/admin_ai_prompts_preview_empty.js +30 -0
  111. package/src/paraglide/messages/admin_ai_prompts_preview_generating.js +30 -0
  112. package/src/paraglide/messages/admin_ai_prompts_preview_hint.js +30 -0
  113. package/src/paraglide/messages/admin_ai_prompts_preview_nocontent1.js +30 -0
  114. package/src/paraglide/messages/admin_ai_prompts_preview_placeholder.js +30 -0
  115. package/src/paraglide/messages/admin_ai_prompts_preview_section.js +30 -0
  116. package/src/paraglide/messages/admin_ai_prompts_preview_title.js +30 -0
  117. package/src/paraglide/messages/admin_ai_prompts_protected_hint.js +30 -0
  118. package/src/paraglide/messages/admin_ai_prompts_rollback.js +30 -0
  119. package/src/paraglide/messages/admin_ai_prompts_rollback_confirm_action.js +30 -0
  120. package/src/paraglide/messages/admin_ai_prompts_rollback_confirm_description.js +30 -0
  121. package/src/paraglide/messages/admin_ai_prompts_rollback_confirm_title.js +30 -0
  122. package/src/paraglide/messages/admin_ai_prompts_save.js +30 -0
  123. package/src/paraglide/messages/admin_ai_prompts_section_add.js +30 -0
  124. package/src/paraglide/messages/admin_ai_prompts_section_id.js +30 -0
  125. package/src/paraglide/messages/admin_ai_prompts_section_movedown1.js +30 -0
  126. package/src/paraglide/messages/admin_ai_prompts_section_moveup1.js +30 -0
  127. package/src/paraglide/messages/admin_ai_prompts_section_order.js +30 -0
  128. package/src/paraglide/messages/admin_ai_prompts_section_remove.js +30 -0
  129. package/src/paraglide/messages/admin_ai_prompts_section_template_placeholder.js +30 -0
  130. package/src/paraglide/messages/admin_ai_prompts_sections_empty.js +30 -0
  131. package/src/paraglide/messages/admin_ai_prompts_sections_hint.js +30 -0
  132. package/src/paraglide/messages/admin_ai_prompts_sections_title.js +30 -0
  133. package/src/paraglide/messages/admin_ai_prompts_toast_activated.js +30 -0
  134. package/src/paraglide/messages/admin_ai_prompts_toast_failed.js +30 -0
  135. package/src/paraglide/messages/admin_ai_prompts_toast_protected_locked.js +30 -0
  136. package/src/paraglide/messages/admin_ai_prompts_toast_rolled_back.js +30 -0
  137. package/src/paraglide/messages/admin_ai_prompts_toast_save_failed.js +30 -0
  138. package/src/paraglide/messages/admin_ai_prompts_toast_saved.js +30 -0
  139. package/src/paraglide/messages/admin_ai_prompts_variable_add.js +30 -0
  140. package/src/paraglide/messages/admin_ai_prompts_variable_declarehint1.js +30 -0
  141. package/src/paraglide/messages/admin_ai_prompts_variable_description_placeholder.js +30 -0
  142. package/src/paraglide/messages/admin_ai_prompts_variable_name_placeholder.js +30 -0
  143. package/src/paraglide/messages/admin_ai_prompts_variable_remove.js +30 -0
  144. package/src/paraglide/messages/admin_ai_prompts_variable_undeclared.js +30 -0
  145. package/src/paraglide/messages/admin_ai_prompts_variables_empty.js +30 -0
  146. package/src/paraglide/messages/admin_ai_prompts_variables_title.js +30 -0
  147. package/src/paraglide/messages/admin_ai_prompts_versions_current.js +30 -0
  148. package/src/paraglide/messages/admin_ai_prompts_versions_empty.js +30 -0
  149. package/src/paraglide/messages/admin_ai_prompts_versions_hint.js +30 -0
  150. package/src/paraglide/messages/admin_ai_prompts_versions_nonote1.js +30 -0
  151. package/src/paraglide/messages/admin_ai_prompts_versions_title.js +30 -0
  152. package/src/paraglide/messages/admin_ai_prompts_versions_unknowncreator1.js +30 -0
  153. package/src/paraglide/messages/admin_ai_table_seedfromseed2.js +30 -0
  154. package/src/paraglide/messages/admin_ai_table_toast_seedcreated1.js +30 -0
  155. package/src/paraglide/messages/admin_ai_table_toast_seedfailed1.js +30 -0
  156. package/src/paraglide/messages/admin_ai_table_toast_seednonew2.js +30 -0
  157. package/src/paraglide/messages/common_monitoring_aiusage_sandbox1.js +30 -0
  158. package/src/paraglide/messages/common_monitoring_aiusage_sandboxvalue2.js +30 -0
  159. package/src/paraglide/messages/common_nav_aiprompts1.js +30 -0
  160. package/src/routeTree.gen.ts +101 -0
  161. package/src/routes/__root.tsx +2 -2
  162. package/src/{components/ui/sonner.tsx → routes/_nav/ai-memory/route.lazy.tsx} +24 -16
  163. package/src/routes/_nav/ai-memory/route.tsx +31 -0
  164. package/src/routes/_nav/ai-prompts/$key/route.lazy.tsx +32 -0
  165. package/src/routes/_nav/ai-prompts/$key/route.tsx +37 -0
  166. package/src/routes/_nav/ai-prompts/index/route.lazy.tsx +47 -0
  167. package/src/routes/_nav/ai-prompts/route.lazy.tsx +26 -0
  168. package/src/routes/_nav/ai-prompts/route.tsx +31 -0
  169. package/src/routes/_nav/compliance/route.lazy.tsx +2 -4
  170. package/src/routes/_nav/components/route.lazy.tsx +1 -1
  171. package/src/routes/_nav/knowledge-public/bookmarks/route.lazy.tsx +1 -1
  172. package/src/routes/_nav/knowledge-public/compliance/route.lazy.tsx +1 -1
  173. package/src/routes/_nav/knowledge-public/legal/route.lazy.tsx +1 -1
  174. package/src/routes/_nav/licenses/$licenseId/route.lazy.tsx +1 -1
  175. package/src/routes/_nav/monitoring/ai-usage/route.lazy.tsx +10 -1
  176. package/src/routes/_nav/monitoring/errors/route.lazy.tsx +1 -1
  177. package/src/routes/_nav/monitoring/health/route.lazy.tsx +1 -1
  178. package/src/routes/_nav/monitoring/logs/route.lazy.tsx +1 -1
  179. package/src/routes/_nav/monitoring/metrics/route.lazy.tsx +1 -1
  180. package/src/routes/_nav/monitoring/sentry/route.lazy.tsx +1 -1
  181. package/src/routes/_nav/permissions/route.lazy.tsx +2 -2
  182. package/src/routes/_nav/sso/route.lazy.tsx +1 -1
  183. package/src/routes/_nav/users/$userId/route.lazy.tsx +3 -3
  184. package/src/routes/setup/route.lazy.tsx +1 -1
  185. package/src/server/__tests__/prompt-defaults.test.ts +139 -0
  186. package/src/server/admin-ai-usage.ts +22 -4
  187. package/src/server/ai-memory/store.ts +103 -0
  188. package/src/server/serverFns/ai-memory/clear.ts +31 -0
  189. package/src/server/serverFns/ai-memory/delete.ts +31 -0
  190. package/src/server/serverFns/ai-memory/list-users.ts +40 -0
  191. package/src/server/serverFns/ai-memory/list.ts +54 -0
  192. package/src/server/serverFns/ai-prompts/activate.ts +53 -0
  193. package/src/server/serverFns/ai-prompts/get.ts +74 -0
  194. package/src/server/serverFns/ai-prompts/list.ts +55 -0
  195. package/src/server/serverFns/ai-prompts/preview.ts +66 -0
  196. package/src/server/serverFns/ai-prompts/prompt-defaults.ts +63 -0
  197. package/src/server/serverFns/ai-prompts/prompt-schemas.ts +47 -0
  198. package/src/server/serverFns/ai-prompts/rollback.ts +86 -0
  199. package/src/server/serverFns/ai-prompts/save.ts +129 -0
  200. package/src/server/serverFns/ai-provider/seed-from-seed.ts +64 -0
  201. package/src/styles/globals.css +92 -77
  202. package/src/components/layout/sidebar-02/logo.tsx +0 -40
  203. package/src/components/layout/sidebar-02/team-switcher.tsx +0 -106
  204. package/src/components/providers/theme-toggle.tsx +0 -59
@@ -1,77 +1,74 @@
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
1
  "use client"
19
2
 
20
3
  import * as React from "react"
21
- import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"
22
-
23
- import { cn } from "@/lib/utils"
24
- import { CheckIcon, ChevronRightIcon } from "lucide-react"
4
+ import { Menu as MenuPrimitive } from "@base-ui/react/menu"
5
+ import { cn } from "cn"
6
+ import { ChevronRightIcon, CheckIcon } from "lucide-react"
25
7
 
26
- function DropdownMenu({
27
- ...props
28
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
29
- return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
8
+ function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
9
+ return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />
30
10
  }
31
11
 
32
- function DropdownMenuPortal({
33
- ...props
34
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
35
- return (
36
- <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
37
- )
12
+ function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
13
+ return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
38
14
  }
39
15
 
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
- )
16
+ function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
17
+ return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />
49
18
  }
50
19
 
51
20
  function DropdownMenuContent({
52
- className,
53
21
  align = "start",
22
+ alignOffset = 0,
23
+ side = "bottom",
54
24
  sideOffset = 4,
25
+ className,
55
26
  ...props
56
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
27
+ }: MenuPrimitive.Popup.Props &
28
+ Pick<
29
+ MenuPrimitive.Positioner.Props,
30
+ "align" | "alignOffset" | "side" | "sideOffset"
31
+ >) {
57
32
  return (
58
- <DropdownMenuPrimitive.Portal>
59
- <DropdownMenuPrimitive.Content
60
- data-slot="dropdown-menu-content"
61
- sideOffset={sideOffset}
33
+ <MenuPrimitive.Portal>
34
+ <MenuPrimitive.Positioner
35
+ className="isolate z-50 outline-none"
62
36
  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>
37
+ alignOffset={alignOffset}
38
+ side={side}
39
+ sideOffset={sideOffset}
40
+ >
41
+ <MenuPrimitive.Popup
42
+ data-slot="dropdown-menu-content"
43
+ className={cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className )}
44
+ {...props}
45
+ />
46
+ </MenuPrimitive.Positioner>
47
+ </MenuPrimitive.Portal>
67
48
  )
68
49
  }
69
50
 
70
- function DropdownMenuGroup({
51
+ function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
52
+ return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
53
+ }
54
+
55
+ function DropdownMenuLabel({
56
+ className,
57
+ inset,
71
58
  ...props
72
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
59
+ }: MenuPrimitive.GroupLabel.Props & {
60
+ inset?: boolean
61
+ }) {
73
62
  return (
74
- <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
63
+ <MenuPrimitive.GroupLabel
64
+ data-slot="dropdown-menu-label"
65
+ data-inset={inset}
66
+ className={cn(
67
+ "px-2 py-1.5 text-xs font-medium text-muted-foreground data-inset:pl-8",
68
+ className
69
+ )}
70
+ {...props}
71
+ />
75
72
  )
76
73
  }
77
74
 
@@ -80,20 +77,69 @@ function DropdownMenuItem({
80
77
  inset,
81
78
  variant = "default",
82
79
  ...props
83
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
80
+ }: MenuPrimitive.Item.Props & {
84
81
  inset?: boolean
85
82
  variant?: "default" | "destructive"
86
83
  }) {
87
84
  return (
88
- <DropdownMenuPrimitive.Item
85
+ <MenuPrimitive.Item
89
86
  data-slot="dropdown-menu-item"
90
87
  data-inset={inset}
91
88
  data-variant={variant}
92
89
  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:**: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",
90
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 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",
91
+ className
92
+ )}
93
+ {...props}
94
+ />
95
+ )
96
+ }
97
+
98
+ function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
99
+ return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />
100
+ }
101
+
102
+ function DropdownMenuSubTrigger({
103
+ className,
104
+ inset,
105
+ children,
106
+ ...props
107
+ }: MenuPrimitive.SubmenuTrigger.Props & {
108
+ inset?: boolean
109
+ }) {
110
+ return (
111
+ <MenuPrimitive.SubmenuTrigger
112
+ data-slot="dropdown-menu-sub-trigger"
113
+ data-inset={inset}
114
+ className={cn(
115
+ "flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
94
116
  className
95
117
  )}
96
118
  {...props}
119
+ >
120
+ {children}
121
+ <ChevronRightIcon className="ml-auto" />
122
+ </MenuPrimitive.SubmenuTrigger>
123
+ )
124
+ }
125
+
126
+ function DropdownMenuSubContent({
127
+ align = "start",
128
+ alignOffset = -3,
129
+ side = "right",
130
+ sideOffset = 0,
131
+ className,
132
+ ...props
133
+ }: React.ComponentProps<typeof DropdownMenuContent>) {
134
+ return (
135
+ <DropdownMenuContent
136
+ data-slot="dropdown-menu-sub-content"
137
+ className={cn("w-auto min-w-[96px] rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 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 )}
138
+ align={align}
139
+ alignOffset={alignOffset}
140
+ side={side}
141
+ sideOffset={sideOffset}
142
+ {...props}
97
143
  />
98
144
  )
99
145
  }
@@ -104,15 +150,15 @@ function DropdownMenuCheckboxItem({
104
150
  checked,
105
151
  inset,
106
152
  ...props
107
- }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
153
+ }: MenuPrimitive.CheckboxItem.Props & {
108
154
  inset?: boolean
109
155
  }) {
110
156
  return (
111
- <DropdownMenuPrimitive.CheckboxItem
157
+ <MenuPrimitive.CheckboxItem
112
158
  data-slot="dropdown-menu-checkbox-item"
113
159
  data-inset={inset}
114
160
  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:**: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",
161
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
116
162
  className
117
163
  )}
118
164
  checked={checked}
@@ -122,21 +168,19 @@ function DropdownMenuCheckboxItem({
122
168
  className="pointer-events-none absolute right-2 flex items-center justify-center"
123
169
  data-slot="dropdown-menu-checkbox-item-indicator"
124
170
  >
125
- <DropdownMenuPrimitive.ItemIndicator>
171
+ <MenuPrimitive.CheckboxItemIndicator>
126
172
  <CheckIcon
127
173
  />
128
- </DropdownMenuPrimitive.ItemIndicator>
174
+ </MenuPrimitive.CheckboxItemIndicator>
129
175
  </span>
130
176
  {children}
131
- </DropdownMenuPrimitive.CheckboxItem>
177
+ </MenuPrimitive.CheckboxItem>
132
178
  )
133
179
  }
134
180
 
135
- function DropdownMenuRadioGroup({
136
- ...props
137
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
181
+ function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
138
182
  return (
139
- <DropdownMenuPrimitive.RadioGroup
183
+ <MenuPrimitive.RadioGroup
140
184
  data-slot="dropdown-menu-radio-group"
141
185
  {...props}
142
186
  />
@@ -148,15 +192,15 @@ function DropdownMenuRadioItem({
148
192
  children,
149
193
  inset,
150
194
  ...props
151
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
195
+ }: MenuPrimitive.RadioItem.Props & {
152
196
  inset?: boolean
153
197
  }) {
154
198
  return (
155
- <DropdownMenuPrimitive.RadioItem
199
+ <MenuPrimitive.RadioItem
156
200
  data-slot="dropdown-menu-radio-item"
157
201
  data-inset={inset}
158
202
  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:**: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",
203
+ "relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
160
204
  className
161
205
  )}
162
206
  {...props}
@@ -165,42 +209,22 @@ function DropdownMenuRadioItem({
165
209
  className="pointer-events-none absolute right-2 flex items-center justify-center"
166
210
  data-slot="dropdown-menu-radio-item-indicator"
167
211
  >
168
- <DropdownMenuPrimitive.ItemIndicator>
212
+ <MenuPrimitive.RadioItemIndicator>
169
213
  <CheckIcon
170
214
  />
171
- </DropdownMenuPrimitive.ItemIndicator>
215
+ </MenuPrimitive.RadioItemIndicator>
172
216
  </span>
173
217
  {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
- />
218
+ </MenuPrimitive.RadioItem>
195
219
  )
196
220
  }
197
221
 
198
222
  function DropdownMenuSeparator({
199
223
  className,
200
224
  ...props
201
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
225
+ }: MenuPrimitive.Separator.Props) {
202
226
  return (
203
- <DropdownMenuPrimitive.Separator
227
+ <MenuPrimitive.Separator
204
228
  data-slot="dropdown-menu-separator"
205
229
  className={cn("-mx-1 my-1 h-px bg-border", className)}
206
230
  {...props}
@@ -224,49 +248,6 @@ function DropdownMenuShortcut({
224
248
  )
225
249
  }
226
250
 
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:**: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
251
  export {
271
252
  DropdownMenu,
272
253
  DropdownMenuPortal,
@@ -1,26 +1,7 @@
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
1
  import { useMemo } from "react"
21
2
  import { cva, type VariantProps } from "class-variance-authority"
3
+ import { cn } from "cn"
22
4
 
23
- import { cn } from "@/lib/utils"
24
5
  import { Label } from "@/components/ui/label"
25
6
  import { Separator } from "@/components/ui/separator"
26
7
 
@@ -29,7 +10,7 @@ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
29
10
  <fieldset
30
11
  data-slot="field-set"
31
12
  className={cn(
32
- "flex flex-col gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
13
+ "flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
33
14
  className
34
15
  )}
35
16
  {...props}
@@ -47,7 +28,7 @@ function FieldLegend({
47
28
  data-slot="field-legend"
48
29
  data-variant={variant}
49
30
  className={cn(
50
- "mb-1.5 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
31
+ "mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
51
32
  className
52
33
  )}
53
34
  {...props}
@@ -60,7 +41,7 @@ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
60
41
  <div
61
42
  data-slot="field-group"
62
43
  className={cn(
63
- "group/field-group @container/field-group flex w-full flex-col gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
44
+ "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
64
45
  className
65
46
  )}
66
47
  {...props}
@@ -69,7 +50,7 @@ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
69
50
  }
70
51
 
71
52
  const fieldVariants = cva(
72
- "group/field flex w-full gap-2 data-[invalid=true]:text-destructive",
53
+ "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
73
54
  {
74
55
  variants: {
75
56
  orientation: {
@@ -107,7 +88,7 @@ function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
107
88
  <div
108
89
  data-slot="field-content"
109
90
  className={cn(
110
- "group/field-content flex flex-1 flex-col gap-0.5 leading-snug",
91
+ "group/field-content flex flex-1 flex-col gap-1 leading-snug",
111
92
  className
112
93
  )}
113
94
  {...props}
@@ -123,7 +104,7 @@ function FieldLabel({
123
104
  <Label
124
105
  data-slot="field-label"
125
106
  className={cn(
126
- "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border *:data-[slot=field]:p-2.5 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10",
107
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-muted/50 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-3 has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 *:data-[slot=field]:p-3 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10",
127
108
  "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
128
109
  className
129
110
  )}
@@ -172,7 +153,7 @@ function FieldSeparator({
172
153
  data-slot="field-separator"
173
154
  data-content={!!children}
174
155
  className={cn(
175
- "relative -my-2 h-0.5 text-sm group-data-[variant=outline]/field-group:-mb-2",
156
+ "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
176
157
  className
177
158
  )}
178
159
  {...props}
@@ -1,24 +1,9 @@
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/>.
1
+ "use client"
17
2
 
18
3
  import * as React from "react"
19
4
  import { cva, type VariantProps } from "class-variance-authority"
5
+ import { cn } from "cn"
20
6
 
21
- import { cn } from "@/lib/utils"
22
7
  import { Button } from "@/components/ui/button"
23
8
  import { Input } from "@/components/ui/input"
24
9
  import { Textarea } from "@/components/ui/textarea"
@@ -29,7 +14,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
29
14
  data-slot="input-group"
30
15
  role="group"
31
16
  className={cn(
32
- "group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
17
+ "group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
33
18
  className
34
19
  )}
35
20
  {...props}
@@ -43,9 +28,9 @@ const inputGroupAddonVariants = cva(
43
28
  variants: {
44
29
  align: {
45
30
  "inline-start":
46
- "order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
31
+ "order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]",
47
32
  "inline-end":
48
- "order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
33
+ "order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]",
49
34
  "block-start":
50
35
  "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
51
36
  "block-end":
@@ -85,10 +70,10 @@ const inputGroupButtonVariants = cva(
85
70
  {
86
71
  variants: {
87
72
  size: {
88
- xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
73
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
89
74
  sm: "",
90
75
  "icon-xs":
91
- "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
76
+ "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
92
77
  "icon-sm": "size-8 p-0 has-[>svg]:p-0",
93
78
  },
94
79
  },
@@ -104,8 +89,10 @@ function InputGroupButton({
104
89
  variant = "ghost",
105
90
  size = "xs",
106
91
  ...props
107
- }: Omit<React.ComponentProps<typeof Button>, "size"> &
108
- VariantProps<typeof inputGroupButtonVariants>) {
92
+ }: Omit<React.ComponentProps<typeof Button>, "size" | "type"> &
93
+ VariantProps<typeof inputGroupButtonVariants> & {
94
+ type?: "button" | "submit" | "reset"
95
+ }) {
109
96
  return (
110
97
  <Button
111
98
  type={type}
@@ -137,7 +124,7 @@ function InputGroupInput({
137
124
  <Input
138
125
  data-slot="input-group-control"
139
126
  className={cn(
140
- "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
127
+ "flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
141
128
  className
142
129
  )}
143
130
  {...props}
@@ -153,7 +140,7 @@ function InputGroupTextarea({
153
140
  <Textarea
154
141
  data-slot="input-group-control"
155
142
  className={cn(
156
- "flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent",
143
+ "flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
157
144
  className
158
145
  )}
159
146
  {...props}
@@ -1,31 +1,14 @@
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
1
  import * as React from "react"
19
-
20
- import { cn } from "@/lib/utils"
2
+ import { Input as InputPrimitive } from "@base-ui/react/input"
3
+ import { cn } from "cn"
21
4
 
22
5
  function Input({ className, type, ...props }: React.ComponentProps<"input">) {
23
6
  return (
24
- <input
7
+ <InputPrimitive
25
8
  type={type}
26
9
  data-slot="input"
27
10
  className={cn(
28
- "h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
11
+ "h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
29
12
  className
30
13
  )}
31
14
  {...props}
@@ -1,33 +1,9 @@
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
1
  import * as React from "react"
21
- import { Label as LabelPrimitive } from "radix-ui"
22
-
23
- import { cn } from "@/lib/utils"
2
+ import { cn } from "cn"
24
3
 
25
- function Label({
26
- className,
27
- ...props
28
- }: React.ComponentProps<typeof LabelPrimitive.Root>) {
4
+ function Label({ className, ...props }: React.ComponentProps<"label">) {
29
5
  return (
30
- <LabelPrimitive.Root
6
+ <label
31
7
  data-slot="label"
32
8
  className={cn(
33
9
  "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",