@allbluecn/ui 0.3.13 → 0.4.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 (146) hide show
  1. package/dist/ai-command-button.d.ts +10 -0
  2. package/dist/ai-command-button.js +12 -0
  3. package/dist/ai-stream-text.d.ts +9 -0
  4. package/dist/ai-stream-text.js +12 -0
  5. package/dist/alert-dialog.d.ts +20 -0
  6. package/dist/alert-dialog.js +101 -0
  7. package/dist/animated-theme-toggler.d.ts +11 -0
  8. package/dist/animated-theme-toggler.js +169 -0
  9. package/dist/auth-client.d.ts +27 -0
  10. package/dist/auth-client.js +86 -0
  11. package/dist/auth-layout.d.ts +14 -0
  12. package/dist/auth-layout.js +43 -0
  13. package/dist/avatar.d.ts +13 -0
  14. package/dist/avatar.js +51 -0
  15. package/dist/badge.d.ts +11 -0
  16. package/dist/badge.js +28 -0
  17. package/dist/button.d.ts +12 -0
  18. package/dist/button.js +48 -0
  19. package/dist/card.d.ts +13 -0
  20. package/dist/card.js +56 -0
  21. package/dist/checkbox.d.ts +6 -0
  22. package/dist/checkbox.js +22 -0
  23. package/dist/context-menu.d.ts +33 -0
  24. package/dist/context-menu.js +125 -0
  25. package/dist/dialog.d.ts +19 -0
  26. package/dist/dialog.js +95 -0
  27. package/dist/dropdown-menu.d.ts +31 -0
  28. package/dist/dropdown-menu.js +128 -0
  29. package/dist/empty.d.ts +13 -0
  30. package/dist/empty.js +59 -0
  31. package/dist/grid-pattern.d.ts +14 -0
  32. package/dist/grid-pattern.js +47 -0
  33. package/dist/icon-packs/index.d.ts +2 -0
  34. package/dist/icon-packs/index.js +4 -0
  35. package/dist/icon-packs/knowledge.d.ts +2 -0
  36. package/dist/icon-packs/knowledge.js +70 -0
  37. package/dist/icon-packs/prd.d.ts +2 -0
  38. package/dist/icon-packs/prd.js +86 -0
  39. package/dist/icon-packs/project.d.ts +2 -0
  40. package/dist/icon-packs/project.js +74 -0
  41. package/dist/icon-picker.d.ts +11 -0
  42. package/dist/icon-picker.js +39 -0
  43. package/dist/index-CQsbeClc.d.ts +17 -0
  44. package/dist/index.d.ts +7 -0
  45. package/dist/index.js +7 -0
  46. package/dist/input.d.ts +5 -0
  47. package/dist/input.js +14 -0
  48. package/dist/item.d.ts +25 -0
  49. package/dist/item.js +118 -0
  50. package/dist/kbd.d.ts +4 -0
  51. package/dist/kbd.js +12 -0
  52. package/dist/label.d.ts +6 -0
  53. package/dist/label.js +14 -0
  54. package/dist/layout-panel-top.d.ts +12 -0
  55. package/dist/layout-panel-top.js +127 -0
  56. package/dist/name-confirm-dialog.d.ts +15 -0
  57. package/dist/name-confirm-dialog.js +105 -0
  58. package/dist/nav-float-button.d.ts +12 -0
  59. package/dist/nav-float-button.js +249 -0
  60. package/dist/notion-avatar.d.ts +13 -0
  61. package/dist/notion-avatar.js +83 -0
  62. package/dist/placeholder-page.d.ts +10 -0
  63. package/dist/placeholder-page.js +28 -0
  64. package/dist/popover.d.ts +12 -0
  65. package/dist/popover.js +56 -0
  66. package/dist/reference-inline.d.ts +10 -0
  67. package/dist/reference-inline.js +35 -0
  68. package/dist/reference-search.d.ts +12 -0
  69. package/dist/reference-search.js +26 -0
  70. package/dist/resizable.d.ts +9 -0
  71. package/dist/resizable.js +28 -0
  72. package/dist/select.d.ts +17 -0
  73. package/dist/select.js +99 -0
  74. package/dist/separator.d.ts +6 -0
  75. package/dist/separator.js +17 -0
  76. package/dist/sheet.d.ts +16 -0
  77. package/dist/sheet.js +90 -0
  78. package/dist/sidebar.d.ts +71 -0
  79. package/dist/sidebar.js +369 -0
  80. package/dist/skeleton.d.ts +4 -0
  81. package/dist/skeleton.js +12 -0
  82. package/dist/sonner.d.ts +5 -0
  83. package/dist/sonner.js +19 -0
  84. package/dist/switch.d.ts +8 -0
  85. package/dist/switch.js +19 -0
  86. package/dist/textarea.d.ts +5 -0
  87. package/dist/textarea.js +13 -0
  88. package/dist/timezone-provider.d.ts +18 -0
  89. package/dist/timezone-provider.js +29 -0
  90. package/dist/tooltip.d.ts +9 -0
  91. package/dist/tooltip.js +35 -0
  92. package/dist/use-mobile.d.ts +4 -0
  93. package/dist/use-mobile.js +18 -0
  94. package/dist/user-avatar.d.ts +14 -0
  95. package/dist/user-avatar.js +34 -0
  96. package/dist/utils.d.ts +5 -0
  97. package/dist/utils.js +8 -0
  98. package/package.json +178 -49
  99. package/src/ai-command-button.tsx +0 -36
  100. package/src/ai-stream-text.tsx +0 -37
  101. package/src/alert-dialog.tsx +0 -216
  102. package/src/animated-theme-toggler.tsx +0 -272
  103. package/src/auth-client.ts +0 -108
  104. package/src/auth-layout.tsx +0 -66
  105. package/src/avatar.tsx +0 -129
  106. package/src/badge.tsx +0 -66
  107. package/src/button.tsx +0 -84
  108. package/src/card.tsx +0 -120
  109. package/src/checkbox.tsx +0 -50
  110. package/src/context-menu.tsx +0 -280
  111. package/src/dialog.tsx +0 -183
  112. package/src/dropdown-menu.tsx +0 -286
  113. package/src/empty.tsx +0 -121
  114. package/src/grid-pattern.tsx +0 -87
  115. package/src/icon-packs/index.ts +0 -27
  116. package/src/icon-packs/knowledge.ts +0 -55
  117. package/src/icon-packs/prd.ts +0 -63
  118. package/src/icon-packs/project.ts +0 -59
  119. package/src/icon-picker.tsx +0 -68
  120. package/src/index.ts +0 -23
  121. package/src/input.tsx +0 -36
  122. package/src/item.tsx +0 -213
  123. package/src/kbd.tsx +0 -33
  124. package/src/label.tsx +0 -39
  125. package/src/layout-panel-top.tsx +0 -160
  126. package/src/name-confirm-dialog.tsx +0 -153
  127. package/src/nav-float-button.tsx +0 -301
  128. package/src/notion-avatar.tsx +0 -126
  129. package/src/placeholder-page.tsx +0 -42
  130. package/src/popover.tsx +0 -106
  131. package/src/reference-inline.tsx +0 -53
  132. package/src/reference-search.tsx +0 -52
  133. package/src/resizable.tsx +0 -67
  134. package/src/select.tsx +0 -207
  135. package/src/separator.tsx +0 -45
  136. package/src/sheet.tsx +0 -164
  137. package/src/sidebar.tsx +0 -708
  138. package/src/skeleton.tsx +0 -30
  139. package/src/sonner.tsx +0 -37
  140. package/src/switch.tsx +0 -48
  141. package/src/textarea.tsx +0 -35
  142. package/src/timezone-provider.tsx +0 -55
  143. package/src/tooltip.tsx +0 -72
  144. package/src/use-mobile.ts +0 -36
  145. package/src/user-avatar.tsx +0 -79
  146. package/src/utils.ts +0 -6
@@ -1,126 +0,0 @@
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 { useEffect, useState } from "react"
21
- import type { AvatarConfig, AvatarPart, ShapeType } from "@allbluecn/shared"
22
-
23
- const noneParts: AvatarPart[] = ["glasses", "hair", "accessories", "details", "beard"]
24
-
25
- const partOrder: AvatarPart[] = [
26
- "face",
27
- "nose",
28
- "mouth",
29
- "eyes",
30
- "eyebrows",
31
- "glasses",
32
- "hair",
33
- "accessories",
34
- "details",
35
- "beard",
36
- ]
37
-
38
- function getPreviewImagePath(part: AvatarPart, index: number): string {
39
- return `/avatar/preview/${part}/${index}.svg`
40
- }
41
-
42
- const SVGFilter = `<defs>
43
- <filter id="notion-avatar-filter" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="linearRGB">
44
- <feMorphology operator="dilate" radius="20" in="SourceAlpha" result="morphology"/>
45
- <feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/>
46
- <feComposite in="flood" in2="morphology" operator="in" result="composite"/>
47
- <feMerge result="merge">
48
- <feMergeNode in="composite" result="mergeNode"/>
49
- <feMergeNode in="SourceGraphic" result="mergeNode1"/>
50
- </feMerge>
51
- </filter>
52
- </defs>`
53
-
54
- function extractInnerSvg(svgText: string): string {
55
- return svgText.replace(/<svg[^>]*>/i, "").replace(/<\/svg>/i, "").trim()
56
- }
57
-
58
- const shapeStyle: Record<ShapeType, string> = {
59
- circle: "rounded-full",
60
- rounded: "rounded-lg",
61
- square: "rounded-none",
62
- }
63
-
64
- type NotionAvatarProps = {
65
- config: AvatarConfig
66
- bgColor?: string
67
- shape?: ShapeType
68
- className?: string
69
- style?: React.CSSProperties
70
- flip?: boolean
71
- }
72
-
73
- export function NotionAvatar({
74
- config,
75
- bgColor = "transparent",
76
- shape = "circle",
77
- className,
78
- style,
79
- flip = false,
80
- }: NotionAvatarProps) {
81
- const [svgContent, setSvgContent] = useState<string>("")
82
-
83
- useEffect(() => {
84
- async function buildAvatar() {
85
- const groups = await Promise.all(
86
- partOrder.map(async (part) => {
87
- const index = config[part]
88
- if (noneParts.includes(part) && index === 0) return ""
89
- try {
90
- const res = await fetch(getPreviewImagePath(part, index))
91
- const svgText = await res.text()
92
- const inner = extractInnerSvg(svgText)
93
- return `\n<g id="avatar-${part}"${part === "face" ? ' fill="#ffffff"' : ""}>${inner}</g>`
94
- } catch {
95
- return ""
96
- }
97
- }),
98
- )
99
- const flipAttr = flip ? ' transform="scale(-1,1) translate(-1080, 0)"' : ""
100
- const avatarSvg = `<svg viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:100%;height:100%">${SVGFilter}<g id="avatar"${flipAttr}>${groups.join("")}</g></svg>`
101
- setSvgContent(avatarSvg)
102
- }
103
- buildAvatar()
104
- }, [config, flip])
105
-
106
- if (!svgContent) {
107
- return (
108
- <div
109
- className={`${shapeStyle[shape]} overflow-hidden bg-muted animate-pulse ${className ?? ""}`}
110
- style={{ aspectRatio: "1 / 1", ...style }}
111
- />
112
- )
113
- }
114
-
115
- return (
116
- <div
117
- className={`${shapeStyle[shape]} ${className ?? ""}`}
118
- style={{
119
- backgroundColor: bgColor === "transparent" ? undefined : bgColor,
120
- aspectRatio: "1 / 1",
121
- ...style,
122
- }}
123
- dangerouslySetInnerHTML={{ __html: svgContent }}
124
- />
125
- )
126
- }
@@ -1,42 +0,0 @@
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 { useTranslation } from "react-i18next";
19
- import type { LucideIcon } from "lucide-react";
20
-
21
- type PlaceholderPageProps = {
22
- title: string;
23
- description?: string;
24
- icon: LucideIcon;
25
- };
26
-
27
- export function PlaceholderPage({ title, description, icon: Icon }: PlaceholderPageProps) {
28
- const { t } = useTranslation('common')
29
- return (
30
- <div className="flex h-full min-h-[60vh] items-center justify-center">
31
- <div className="flex flex-col items-center gap-4 rounded-xl border bg-card p-12 text-center shadow-sm">
32
- <div className="flex size-16 items-center justify-center rounded-full bg-muted">
33
- <Icon className="size-8 text-muted-foreground" />
34
- </div>
35
- <h1 className="text-xl font-semibold">{title}</h1>
36
- <p className="text-sm text-muted-foreground">
37
- {description ?? t('placeholder.developing')}
38
- </p>
39
- </div>
40
- </div>
41
- );
42
- }
package/src/popover.tsx DELETED
@@ -1,106 +0,0 @@
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 { Popover as PopoverPrimitive } from "radix-ui"
22
-
23
- import { cn } from "./utils"
24
-
25
- function Popover({
26
- ...props
27
- }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
28
- return <PopoverPrimitive.Root data-slot="popover" {...props} />
29
- }
30
-
31
- function PopoverTrigger({
32
- ...props
33
- }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
34
- return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
35
- }
36
-
37
- function PopoverContent({
38
- className,
39
- align = "center",
40
- sideOffset = 4,
41
- ...props
42
- }: React.ComponentProps<typeof PopoverPrimitive.Content>) {
43
- return (
44
- <PopoverPrimitive.Portal>
45
- <PopoverPrimitive.Content
46
- data-slot="popover-content"
47
- align={align}
48
- sideOffset={sideOffset}
49
- className={cn(
50
- "z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg dark:border dark:border-primary/15 bg-popover p-2.5 text-sm text-popover-foreground shadow-md outline-hidden 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",
51
- className
52
- )}
53
- {...props}
54
- />
55
- </PopoverPrimitive.Portal>
56
- )
57
- }
58
-
59
- function PopoverAnchor({
60
- ...props
61
- }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
62
- return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />
63
- }
64
-
65
- function PopoverHeader({ className, ...props }: React.ComponentProps<"div">) {
66
- return (
67
- <div
68
- data-slot="popover-header"
69
- className={cn("flex flex-col gap-0.5 text-sm", className)}
70
- {...props}
71
- />
72
- )
73
- }
74
-
75
- function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">) {
76
- return (
77
- <div
78
- data-slot="popover-title"
79
- className={cn("font-medium", className)}
80
- {...props}
81
- />
82
- )
83
- }
84
-
85
- function PopoverDescription({
86
- className,
87
- ...props
88
- }: React.ComponentProps<"p">) {
89
- return (
90
- <p
91
- data-slot="popover-description"
92
- className={cn("text-muted-foreground", className)}
93
- {...props}
94
- />
95
- )
96
- }
97
-
98
- export {
99
- Popover,
100
- PopoverAnchor,
101
- PopoverContent,
102
- PopoverDescription,
103
- PopoverHeader,
104
- PopoverTitle,
105
- PopoverTrigger,
106
- }
@@ -1,53 +0,0 @@
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 { useState, useEffect } from "react"
21
- import type { RefDisplay, EntityUpdateEvent } from "@allbluecn/shared"
22
-
23
- interface ReferenceInlineProps {
24
- display: RefDisplay
25
- entityId?: string
26
- updateEvent?: EntityUpdateEvent | null
27
- }
28
-
29
- export function ReferenceInline({ display, entityId, updateEvent }: ReferenceInlineProps) {
30
- const [currentDisplay, setCurrentDisplay] = useState(display)
31
-
32
- useEffect(() => {
33
- if (updateEvent && entityId && updateEvent.id === entityId) {
34
- setCurrentDisplay(prev => ({ ...prev, ...updateEvent.fields as Partial<RefDisplay> }))
35
- }
36
- }, [updateEvent, entityId])
37
-
38
- useEffect(() => {
39
- setCurrentDisplay(display)
40
- }, [display])
41
-
42
- return (
43
- <span className="inline-flex items-center gap-1.5 px-1.5 py-0.5 rounded bg-muted text-sm">
44
- <span className="font-medium">{currentDisplay.title}</span>
45
- {currentDisplay.status && (
46
- <span className="text-xs text-muted-foreground">{currentDisplay.status}</span>
47
- )}
48
- {currentDisplay.priority && (
49
- <span className="text-xs text-muted-foreground">{currentDisplay.priority}</span>
50
- )}
51
- </span>
52
- )
53
- }
@@ -1,52 +0,0 @@
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 { SearchResult } from "@allbluecn/shared";
19
-
20
- interface Props {
21
- open: boolean;
22
- query: string;
23
- results: SearchResult[];
24
- onSelect: (result: SearchResult) => void;
25
- onClose: () => void;
26
- }
27
-
28
- export function ReferenceSearch({ open, query, results, onSelect, onClose }: Props) {
29
- if (!open) return null;
30
- return (
31
- <div className="absolute z-50 w-80 rounded-md border bg-popover shadow-md">
32
- <div className="p-2 border-b">
33
- <input
34
- className="w-full bg-transparent text-sm outline-none"
35
- placeholder="搜索需求、Bug、原型..."
36
- defaultValue={query}
37
- autoFocus
38
- />
39
- </div>
40
- {results.map((r) => (
41
- <button
42
- key={r.id}
43
- className="w-full px-3 py-2 text-left text-sm hover:bg-accent"
44
- onClick={() => onSelect(r)}
45
- >
46
- <span className="text-xs text-muted-foreground">{r.module}/</span>
47
- {r.title}
48
- </button>
49
- ))}
50
- </div>
51
- );
52
- }
package/src/resizable.tsx DELETED
@@ -1,67 +0,0 @@
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 ResizablePrimitive from "react-resizable-panels"
21
-
22
- import { cn } from "./utils"
23
-
24
- function ResizablePanelGroup({
25
- className,
26
- ...props
27
- }: ResizablePrimitive.GroupProps) {
28
- return (
29
- <ResizablePrimitive.Group
30
- data-slot="resizable-panel-group"
31
- className={cn(
32
- "flex h-full w-full aria-[orientation=vertical]:flex-col",
33
- className
34
- )}
35
- {...props}
36
- />
37
- )
38
- }
39
-
40
- function ResizablePanel({ ...props }: ResizablePrimitive.PanelProps) {
41
- return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />
42
- }
43
-
44
- function ResizableHandle({
45
- withHandle,
46
- className,
47
- ...props
48
- }: ResizablePrimitive.SeparatorProps & {
49
- withHandle?: boolean
50
- }) {
51
- return (
52
- <ResizablePrimitive.Separator
53
- data-slot="resizable-handle"
54
- className={cn(
55
- "relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90",
56
- className
57
- )}
58
- {...props}
59
- >
60
- {withHandle && (
61
- <div className="z-10 flex h-6 w-1 shrink-0 rounded-full bg-muted-foreground/25" />
62
- )}
63
- </ResizablePrimitive.Separator>
64
- )
65
- }
66
-
67
- export { ResizableHandle, ResizablePanel, ResizablePanelGroup }
package/src/select.tsx DELETED
@@ -1,207 +0,0 @@
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 * as React from "react"
19
- import { Select as SelectPrimitive } from "radix-ui"
20
-
21
- import { cn } from "./utils"
22
- import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
23
-
24
- function Select({
25
- ...props
26
- }: React.ComponentProps<typeof SelectPrimitive.Root>) {
27
- return <SelectPrimitive.Root data-slot="select" {...props} />
28
- }
29
-
30
- function SelectGroup({
31
- className,
32
- ...props
33
- }: React.ComponentProps<typeof SelectPrimitive.Group>) {
34
- return (
35
- <SelectPrimitive.Group
36
- data-slot="select-group"
37
- className={cn("scroll-my-1 p-1", className)}
38
- {...props}
39
- />
40
- )
41
- }
42
-
43
- function SelectValue({
44
- ...props
45
- }: React.ComponentProps<typeof SelectPrimitive.Value>) {
46
- return <SelectPrimitive.Value data-slot="select-value" {...props} />
47
- }
48
-
49
- function SelectTrigger({
50
- className,
51
- size = "default",
52
- children,
53
- ...props
54
- }: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
55
- size?: "sm" | "default"
56
- }) {
57
- return (
58
- <SelectPrimitive.Trigger
59
- data-slot="select-trigger"
60
- data-size={size}
61
- className={cn(
62
- "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
63
- className
64
- )}
65
- {...props}
66
- >
67
- {children}
68
- <SelectPrimitive.Icon asChild>
69
- <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
70
- </SelectPrimitive.Icon>
71
- </SelectPrimitive.Trigger>
72
- )
73
- }
74
-
75
- function SelectContent({
76
- className,
77
- children,
78
- position = "item-aligned",
79
- align = "center",
80
- ...props
81
- }: React.ComponentProps<typeof SelectPrimitive.Content>) {
82
- return (
83
- <SelectPrimitive.Portal>
84
- <SelectPrimitive.Content
85
- data-slot="select-content"
86
- data-align-trigger={position === "item-aligned"}
87
- className={cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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", position ==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className )}
88
- position={position}
89
- align={align}
90
- {...props}
91
- >
92
- <SelectScrollUpButton />
93
- <SelectPrimitive.Viewport
94
- data-position={position}
95
- className={cn(
96
- "data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
97
- position === "popper" && ""
98
- )}
99
- >
100
- {children}
101
- </SelectPrimitive.Viewport>
102
- <SelectScrollDownButton />
103
- </SelectPrimitive.Content>
104
- </SelectPrimitive.Portal>
105
- )
106
- }
107
-
108
- function SelectLabel({
109
- className,
110
- ...props
111
- }: React.ComponentProps<typeof SelectPrimitive.Label>) {
112
- return (
113
- <SelectPrimitive.Label
114
- data-slot="select-label"
115
- className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
116
- {...props}
117
- />
118
- )
119
- }
120
-
121
- function SelectItem({
122
- className,
123
- children,
124
- ...props
125
- }: React.ComponentProps<typeof SelectPrimitive.Item>) {
126
- return (
127
- <SelectPrimitive.Item
128
- data-slot="select-item"
129
- className={cn(
130
- "relative flex w-full 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 not-data-[variant=destructive]:focus:*:[svg]:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
131
- className
132
- )}
133
- {...props}
134
- >
135
- <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
136
- <SelectPrimitive.ItemIndicator>
137
- <CheckIcon className="pointer-events-none" />
138
- </SelectPrimitive.ItemIndicator>
139
- </span>
140
- <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
141
- </SelectPrimitive.Item>
142
- )
143
- }
144
-
145
- function SelectSeparator({
146
- className,
147
- ...props
148
- }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
149
- return (
150
- <SelectPrimitive.Separator
151
- data-slot="select-separator"
152
- className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
153
- {...props}
154
- />
155
- )
156
- }
157
-
158
- function SelectScrollUpButton({
159
- className,
160
- ...props
161
- }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
162
- return (
163
- <SelectPrimitive.ScrollUpButton
164
- data-slot="select-scroll-up-button"
165
- className={cn(
166
- "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
167
- className
168
- )}
169
- {...props}
170
- >
171
- <ChevronUpIcon
172
- />
173
- </SelectPrimitive.ScrollUpButton>
174
- )
175
- }
176
-
177
- function SelectScrollDownButton({
178
- className,
179
- ...props
180
- }: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
181
- return (
182
- <SelectPrimitive.ScrollDownButton
183
- data-slot="select-scroll-down-button"
184
- className={cn(
185
- "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
186
- className
187
- )}
188
- {...props}
189
- >
190
- <ChevronDownIcon
191
- />
192
- </SelectPrimitive.ScrollDownButton>
193
- )
194
- }
195
-
196
- export {
197
- Select,
198
- SelectContent,
199
- SelectGroup,
200
- SelectItem,
201
- SelectLabel,
202
- SelectScrollDownButton,
203
- SelectScrollUpButton,
204
- SelectSeparator,
205
- SelectTrigger,
206
- SelectValue,
207
- }