@lark-base-open/base-database-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +169 -0
- package/changelog/CHANGELOG-0.x.md +103 -0
- package/config-schema.json +28 -0
- package/dist/agent-guide.d.ts +18 -0
- package/dist/agent-guide.d.ts.map +1 -0
- package/dist/agent-guide.js +30 -0
- package/dist/agent-guide.js.map +1 -0
- package/dist/archive.d.ts +16 -0
- package/dist/archive.d.ts.map +1 -0
- package/dist/archive.js +162 -0
- package/dist/archive.js.map +1 -0
- package/dist/assets.d.ts +4 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +6 -0
- package/dist/assets.js.map +1 -0
- package/dist/auth.d.ts +17 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +63 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +50 -0
- package/dist/config.js.map +1 -0
- package/dist/database-skill.d.ts +22 -0
- package/dist/database-skill.d.ts.map +1 -0
- package/dist/database-skill.js +135 -0
- package/dist/database-skill.js.map +1 -0
- package/dist/deploy.d.ts +28 -0
- package/dist/deploy.d.ts.map +1 -0
- package/dist/deploy.js +476 -0
- package/dist/deploy.js.map +1 -0
- package/dist/environment.d.ts +12 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +27 -0
- package/dist/environment.js.map +1 -0
- package/dist/function-schema.d.ts +3 -0
- package/dist/function-schema.d.ts.map +1 -0
- package/dist/function-schema.js +310 -0
- package/dist/function-schema.js.map +1 -0
- package/dist/init.d.ts +77 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +418 -0
- package/dist/init.js.map +1 -0
- package/dist/lark-cli.d.ts +8 -0
- package/dist/lark-cli.d.ts.map +1 -0
- package/dist/lark-cli.js +228 -0
- package/dist/lark-cli.js.map +1 -0
- package/dist/npm.d.ts +13 -0
- package/dist/npm.d.ts.map +1 -0
- package/dist/npm.js +93 -0
- package/dist/npm.js.map +1 -0
- package/dist/page-title.d.ts +3 -0
- package/dist/page-title.d.ts.map +1 -0
- package/dist/page-title.js +47 -0
- package/dist/page-title.js.map +1 -0
- package/dist/preview-receipt.d.ts +23 -0
- package/dist/preview-receipt.d.ts.map +1 -0
- package/dist/preview-receipt.js +133 -0
- package/dist/preview-receipt.js.map +1 -0
- package/dist/process.d.ts +17 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +53 -0
- package/dist/process.js.map +1 -0
- package/dist/program.d.ts +12 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +204 -0
- package/dist/program.js.map +1 -0
- package/dist/pull.d.ts +18 -0
- package/dist/pull.d.ts.map +1 -0
- package/dist/pull.js +324 -0
- package/dist/pull.js.map +1 -0
- package/dist/skill.d.ts +7 -0
- package/dist/skill.d.ts.map +1 -0
- package/dist/skill.js +28 -0
- package/dist/skill.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace-fingerprint.d.ts +8 -0
- package/dist/workspace-fingerprint.d.ts.map +1 -0
- package/dist/workspace-fingerprint.js +64 -0
- package/dist/workspace-fingerprint.js.map +1 -0
- package/package.json +54 -0
- package/skills/lark-base-database/SKILL.md +307 -0
- package/skills/lark-base-database/references/base-capability-routing.md +81 -0
- package/skills/lark-base-database/references/base-sql-unsupported.md +42 -0
- package/skills/lark-base-database/references/database-capability-skill.md +24 -0
- package/skills/lark-base-database/references/development.md +642 -0
- package/skills/lark-base-database/references/file-transfer.md +275 -0
- package/skills/lark-base-database/references/permission-design.md +138 -0
- package/skills/lark-base-database/references/release.md +81 -0
- package/skills/lark-base-database/references/sql-function.md +276 -0
- package/skills/lark-base-database/references/style-guide.md +88 -0
- package/templates/database-capability/SKILL.md.tmpl +41 -0
- package/templates/database-starter/README.md +11 -0
- package/templates/database-starter/gitignore +3 -0
- package/templates/database-starter/page/.prettierignore +4 -0
- package/templates/database-starter/page/.prettierrc.json +7 -0
- package/templates/database-starter/page/README.md +29 -0
- package/templates/database-starter/page/index.html +24 -0
- package/templates/database-starter/page/package-lock.json +2675 -0
- package/templates/database-starter/page/package.json +44 -0
- package/templates/database-starter/page/public/favicon.png +0 -0
- package/templates/database-starter/page/src/App.tsx +18 -0
- package/templates/database-starter/page/src/components/UserSelectorEditor/index.tsx +267 -0
- package/templates/database-starter/page/src/components/UserSelectorPanel/index.css +32 -0
- package/templates/database-starter/page/src/components/UserSelectorPanel/index.test.ts +24 -0
- package/templates/database-starter/page/src/components/UserSelectorPanel/index.tsx +478 -0
- package/templates/database-starter/page/src/components/UserSelectorPanel/user-search.test.ts +175 -0
- package/templates/database-starter/page/src/components/UserSelectorPanel/user-search.ts +201 -0
- package/templates/database-starter/page/src/components/database-runtime-ready.tsx +21 -0
- package/templates/database-starter/page/src/components/database-user-menu/index.tsx +238 -0
- package/templates/database-starter/page/src/components/feedback/page-state.tsx +66 -0
- package/templates/database-starter/page/src/components/floating-button/chatbot-entry.test.ts +23 -0
- package/templates/database-starter/page/src/components/floating-button/chatbot-entry.tsx +873 -0
- package/templates/database-starter/page/src/components/floating-button/index.tsx +196 -0
- package/templates/database-starter/page/src/components/floating-button/local-chat-panel.test.ts +25 -0
- package/templates/database-starter/page/src/components/floating-button/local-chat-panel.tsx +197 -0
- package/templates/database-starter/page/src/components/floating-button/utils/current-user.ts +56 -0
- package/templates/database-starter/page/src/components/floating-button/utils/env.ts +18 -0
- package/templates/database-starter/page/src/components/floating-button/utils/project-meta.test.ts +79 -0
- package/templates/database-starter/page/src/components/floating-button/utils/project-meta.ts +252 -0
- package/templates/database-starter/page/src/components/ui/button.tsx +56 -0
- package/templates/database-starter/page/src/index.css +67 -0
- package/templates/database-starter/page/src/lib/cn.test.ts +9 -0
- package/templates/database-starter/page/src/lib/cn.ts +7 -0
- package/templates/database-starter/page/src/lib/database-runtime-attachment.test.ts +168 -0
- package/templates/database-starter/page/src/lib/database-runtime-context.test.ts +111 -0
- package/templates/database-starter/page/src/lib/database-runtime.test.ts +103 -0
- package/templates/database-starter/page/src/lib/database-runtime.ts +389 -0
- package/templates/database-starter/page/src/main.tsx +34 -0
- package/templates/database-starter/page/src/vite-env.d.ts +1 -0
- package/templates/database-starter/page/tsconfig.json +23 -0
- package/templates/database-starter/page/vite.config.ts +13 -0
- package/templates/database-starter/prettierignore +1 -0
- package/templates/database-starter/server-functions/.prettierignore +3 -0
- package/templates/database-starter/server-functions/.prettierrc.json +7 -0
- package/templates/database-starter/server-functions/README.md +11 -0
- package/templates/database-starter/server-functions/package-lock.json +1687 -0
- package/templates/database-starter/server-functions/package.json +22 -0
- package/templates/database-starter/server-functions/scripts/run-tsc.mjs +50 -0
- package/templates/database-starter/server-functions/tsconfig.json +20 -0
- package/templates/database-starter/sql/README.md +8 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "page",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20.19.0"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "vite",
|
|
11
|
+
"build": "tsc -b && vite build",
|
|
12
|
+
"preview": "vite preview",
|
|
13
|
+
"check": "tsc -b --noEmit",
|
|
14
|
+
"format": "prettier --write .",
|
|
15
|
+
"format:check": "prettier --check .",
|
|
16
|
+
"lint": "oxlint src --deny-warnings",
|
|
17
|
+
"quality": "npm run format:check && npm run lint && npm run check && npm run test && npm run build",
|
|
18
|
+
"test": "vitest run"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@lark-base-open/base-site-channel": "https://lf3-static.bytednsdoc.com/obj/eden-cn/vlseh7bfnuhps/@lark-base-open-base-site-channel-0.0.1-alpha.35.tgz",
|
|
22
|
+
"@lark-base-open/base-site-js": "https://lf3-static.bytednsdoc.com/obj/eden-cn/jjjpceh7nulojvhj/@lark-base-open-base-site-js-0.0.1-alpha.25.tgz",
|
|
23
|
+
"@radix-ui/react-slot": "^1.3.0",
|
|
24
|
+
"class-variance-authority": "^0.7.1",
|
|
25
|
+
"clsx": "^2.1.1",
|
|
26
|
+
"lucide-react": "^1.24.0",
|
|
27
|
+
"react": "^19.2.7",
|
|
28
|
+
"react-dom": "^19.2.7",
|
|
29
|
+
"tailwind-merge": "^3.6.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
33
|
+
"@types/node": "^26.1.1",
|
|
34
|
+
"@types/react": "^19.2.17",
|
|
35
|
+
"@types/react-dom": "^19.2.3",
|
|
36
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
37
|
+
"oxlint": "^1.42.0",
|
|
38
|
+
"prettier": "^3.7.4",
|
|
39
|
+
"tailwindcss": "^4.3.2",
|
|
40
|
+
"typescript": "~7.0.2",
|
|
41
|
+
"vite": "^8.1.4",
|
|
42
|
+
"vitest": "^4.1.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default function App() {
|
|
2
|
+
return (
|
|
3
|
+
<main className="flex min-h-screen items-center justify-center bg-background px-6 py-12 text-foreground">
|
|
4
|
+
<section className="w-full max-w-2xl rounded-3xl border border-border bg-card p-8 shadow-sm sm:p-12">
|
|
5
|
+
<p className="text-sm font-semibold tracking-[0.18em] text-primary uppercase">
|
|
6
|
+
Base Database
|
|
7
|
+
</p>
|
|
8
|
+
<h1 className="mt-4 text-3xl font-semibold tracking-tight text-balance sm:text-5xl">
|
|
9
|
+
从真实业务任务开始构建
|
|
10
|
+
</h1>
|
|
11
|
+
<p className="mt-5 max-w-xl text-base leading-7 text-muted-foreground sm:text-lg">
|
|
12
|
+
使用页面组件承载交互,通过受控 Function 连接 Base SQL 与
|
|
13
|
+
FaaS,并在交付前替换这段起始内容。
|
|
14
|
+
</p>
|
|
15
|
+
</section>
|
|
16
|
+
</main>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useRef,
|
|
5
|
+
useState,
|
|
6
|
+
type FocusEventHandler,
|
|
7
|
+
type KeyboardEventHandler,
|
|
8
|
+
type MouseEventHandler,
|
|
9
|
+
} from 'react'
|
|
10
|
+
|
|
11
|
+
import { cn } from '../../lib/cn'
|
|
12
|
+
import UserSelectorPanel, {
|
|
13
|
+
type User,
|
|
14
|
+
type UserSelectorAction,
|
|
15
|
+
type UserSelectorMode,
|
|
16
|
+
type UserSelectorSearchAction,
|
|
17
|
+
type UserSelectorValue,
|
|
18
|
+
} from '../UserSelectorPanel'
|
|
19
|
+
|
|
20
|
+
export type UserSelectorEditorValue = UserSelectorValue
|
|
21
|
+
export type { UserSelectorMode } from '../UserSelectorPanel'
|
|
22
|
+
|
|
23
|
+
export interface UserSelectorEditorProps {
|
|
24
|
+
value: UserSelectorEditorValue | null | undefined
|
|
25
|
+
loading?: boolean
|
|
26
|
+
mode?: UserSelectorMode
|
|
27
|
+
onClick?: MouseEventHandler<HTMLDivElement>
|
|
28
|
+
onChange?: (value: UserSelectorEditorValue | undefined) => void
|
|
29
|
+
onSelect?: (user: User, meta: { option: User }) => void
|
|
30
|
+
onClear?: () => void
|
|
31
|
+
onRemove?: (user: User) => void
|
|
32
|
+
onSelectRecordCreator?: () => void
|
|
33
|
+
getUserDescription?: (user: User) => string | undefined
|
|
34
|
+
onDropdownVisibleChange?: (visible: boolean) => void
|
|
35
|
+
onSearch?: (value: string, meta: { action: UserSelectorSearchAction }) => void
|
|
36
|
+
onKeyDown?: KeyboardEventHandler<HTMLInputElement>
|
|
37
|
+
onFocus?: FocusEventHandler<HTMLButtonElement>
|
|
38
|
+
onBlur?: FocusEventHandler<HTMLButtonElement>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 展示受控成员值,并闭环管理 UserSelectorPanel 的打开、关闭与值回传。
|
|
43
|
+
*/
|
|
44
|
+
export default function UserSelectorEditor(
|
|
45
|
+
props: UserSelectorEditorProps,
|
|
46
|
+
): React.JSX.Element {
|
|
47
|
+
const {
|
|
48
|
+
value,
|
|
49
|
+
loading = false,
|
|
50
|
+
mode,
|
|
51
|
+
onClick,
|
|
52
|
+
onChange,
|
|
53
|
+
onSelect,
|
|
54
|
+
onClear,
|
|
55
|
+
onRemove,
|
|
56
|
+
onSelectRecordCreator,
|
|
57
|
+
getUserDescription,
|
|
58
|
+
onDropdownVisibleChange,
|
|
59
|
+
onSearch,
|
|
60
|
+
onKeyDown,
|
|
61
|
+
onFocus,
|
|
62
|
+
onBlur,
|
|
63
|
+
} = props
|
|
64
|
+
const [open, setOpen] = useState(false)
|
|
65
|
+
const rootRef = useRef<HTMLDivElement>(null)
|
|
66
|
+
const panelOpen = open
|
|
67
|
+
const selectedUsers = Array.isArray(value) ? value : value ? [value] : []
|
|
68
|
+
const isMultiple = mode === 'multiple'
|
|
69
|
+
|
|
70
|
+
const updateOpen = useCallback(
|
|
71
|
+
(nextOpen: boolean) => {
|
|
72
|
+
setOpen(nextOpen)
|
|
73
|
+
if (nextOpen !== open) onDropdownVisibleChange?.(nextOpen)
|
|
74
|
+
},
|
|
75
|
+
[onDropdownVisibleChange, open],
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!panelOpen) return
|
|
80
|
+
|
|
81
|
+
const handlePointerDown = (event: MouseEvent) => {
|
|
82
|
+
if (!rootRef.current?.contains(event.target as Node)) {
|
|
83
|
+
updateOpen(false)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
document.addEventListener('mousedown', handlePointerDown)
|
|
88
|
+
return () => document.removeEventListener('mousedown', handlePointerDown)
|
|
89
|
+
}, [panelOpen, updateOpen])
|
|
90
|
+
|
|
91
|
+
const closePanel = () => {
|
|
92
|
+
updateOpen(false)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const updateValue = (nextValue: UserSelectorEditorValue | undefined) => {
|
|
96
|
+
onChange?.(nextValue)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const handlePanelChange = (
|
|
100
|
+
nextValue: UserSelectorEditorValue | undefined,
|
|
101
|
+
meta: { option: User | undefined; action: UserSelectorAction },
|
|
102
|
+
) => {
|
|
103
|
+
updateValue(nextValue)
|
|
104
|
+
if (meta.action === 'Remove' && meta.option) onRemove?.(meta.option)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const handleTriggerClick: MouseEventHandler<HTMLDivElement> = (event) => {
|
|
108
|
+
onClick?.(event)
|
|
109
|
+
if (event.defaultPrevented) return
|
|
110
|
+
|
|
111
|
+
updateOpen(!open)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const renderAvatar = (user: User) => {
|
|
115
|
+
const avatarUrl = user.avatar.avatar_72 || user.avatar.avatar_240
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<span className="relative flex size-5 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[#e8f0fe] text-[10px] leading-none font-medium text-[#1456f0]">
|
|
119
|
+
{user.name.slice(0, 1)}
|
|
120
|
+
{avatarUrl ? (
|
|
121
|
+
<img
|
|
122
|
+
alt=""
|
|
123
|
+
className="absolute inset-0 size-full object-cover"
|
|
124
|
+
onError={(event) => {
|
|
125
|
+
event.currentTarget.hidden = true
|
|
126
|
+
}}
|
|
127
|
+
src={avatarUrl}
|
|
128
|
+
/>
|
|
129
|
+
) : null}
|
|
130
|
+
</span>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<div className="relative w-full" ref={rootRef}>
|
|
136
|
+
<div
|
|
137
|
+
className={cn(
|
|
138
|
+
'flex min-h-8 w-full cursor-pointer items-center rounded-md border border-[#dee0e3] bg-white p-0 text-left text-sm leading-[22px] text-[#1f2329] outline-none transition-colors duration-200 hover:border-[#346df4]',
|
|
139
|
+
panelOpen && 'border-[#346df4]',
|
|
140
|
+
)}
|
|
141
|
+
onClick={handleTriggerClick}
|
|
142
|
+
>
|
|
143
|
+
<span
|
|
144
|
+
className={cn(
|
|
145
|
+
'flex w-full items-center justify-center gap-2 rounded-md px-1.5 py-[3px]',
|
|
146
|
+
isMultiple && 'items-start',
|
|
147
|
+
)}
|
|
148
|
+
>
|
|
149
|
+
<span
|
|
150
|
+
className={cn(
|
|
151
|
+
'flex min-h-6 min-w-0 flex-1 items-center gap-2 overflow-hidden',
|
|
152
|
+
isMultiple &&
|
|
153
|
+
'flex-wrap content-start gap-x-2 gap-y-1 overflow-visible [&>*]:shrink-0',
|
|
154
|
+
)}
|
|
155
|
+
>
|
|
156
|
+
{selectedUsers.length > 0 ? (
|
|
157
|
+
selectedUsers.map((selectedUser) => (
|
|
158
|
+
<span
|
|
159
|
+
className="inline-flex h-6 max-w-full min-w-0 items-center gap-1 overflow-hidden rounded-full bg-transparent pr-1.5 pl-0.5 text-[13px] leading-6 text-[#1f2329] hover:bg-[rgb(194_212_255)]"
|
|
160
|
+
key={selectedUser.user_id}
|
|
161
|
+
>
|
|
162
|
+
<button
|
|
163
|
+
aria-expanded={panelOpen}
|
|
164
|
+
aria-haspopup="listbox"
|
|
165
|
+
className="flex h-full min-w-0 flex-[0_1_auto] items-center gap-1 border-0 bg-transparent p-0 text-left text-inherit outline-none"
|
|
166
|
+
onBlur={onBlur}
|
|
167
|
+
onFocus={onFocus}
|
|
168
|
+
type="button"
|
|
169
|
+
>
|
|
170
|
+
{renderAvatar(selectedUser)}
|
|
171
|
+
<span className="min-w-0 flex-[0_1_auto] truncate">
|
|
172
|
+
{selectedUser.name}
|
|
173
|
+
</span>
|
|
174
|
+
</button>
|
|
175
|
+
<button
|
|
176
|
+
aria-label={
|
|
177
|
+
isMultiple
|
|
178
|
+
? `移除成员 ${selectedUser.name}`
|
|
179
|
+
: '清除已选成员'
|
|
180
|
+
}
|
|
181
|
+
className="relative ml-0 flex size-3.5 shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0 !text-[#646a73] outline-none hover:!text-[#0442d2]"
|
|
182
|
+
onClick={(event) => {
|
|
183
|
+
event.stopPropagation()
|
|
184
|
+
if (isMultiple) {
|
|
185
|
+
updateValue(
|
|
186
|
+
selectedUsers.filter(
|
|
187
|
+
(user) => user.user_id !== selectedUser.user_id,
|
|
188
|
+
),
|
|
189
|
+
)
|
|
190
|
+
onRemove?.(selectedUser)
|
|
191
|
+
} else {
|
|
192
|
+
updateValue(undefined)
|
|
193
|
+
onClear?.()
|
|
194
|
+
}
|
|
195
|
+
}}
|
|
196
|
+
type="button"
|
|
197
|
+
>
|
|
198
|
+
<svg
|
|
199
|
+
aria-hidden="true"
|
|
200
|
+
data-icon="CloseSmallOutlined"
|
|
201
|
+
fill="none"
|
|
202
|
+
height="1em"
|
|
203
|
+
viewBox="0 0 24 24"
|
|
204
|
+
width="1em"
|
|
205
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
206
|
+
>
|
|
207
|
+
<path
|
|
208
|
+
d="M5.636 5.636a1 1 0 0 0 0 1.414l4.95 4.95-4.95 4.95a1 1 0 1 0 1.414 1.414l4.95-4.95 4.95 4.95a1 1 0 0 0 1.414-1.414L13.414 12l4.95-4.95a1 1 0 0 0-1.415-1.414L12 10.586l-4.95-4.95a1 1 0 0 0-1.413 0Z"
|
|
209
|
+
fill="currentColor"
|
|
210
|
+
/>
|
|
211
|
+
</svg>
|
|
212
|
+
</button>
|
|
213
|
+
</span>
|
|
214
|
+
))
|
|
215
|
+
) : (
|
|
216
|
+
<button
|
|
217
|
+
aria-label="选择成员"
|
|
218
|
+
aria-expanded={panelOpen}
|
|
219
|
+
aria-haspopup="listbox"
|
|
220
|
+
className="flex h-full min-w-0 flex-1 items-center gap-1 border-0 bg-transparent p-0 text-left text-inherit outline-none"
|
|
221
|
+
onBlur={onBlur}
|
|
222
|
+
onFocus={onFocus}
|
|
223
|
+
type="button"
|
|
224
|
+
>
|
|
225
|
+
<span className="min-w-0 flex-1 truncate text-[#8f959e]">
|
|
226
|
+
选择成员
|
|
227
|
+
</span>
|
|
228
|
+
</button>
|
|
229
|
+
)}
|
|
230
|
+
</span>
|
|
231
|
+
<span
|
|
232
|
+
aria-hidden="true"
|
|
233
|
+
className={cn(
|
|
234
|
+
'flex size-3 shrink-0 items-center justify-center text-[#646a73] transition-transform duration-200',
|
|
235
|
+
isMultiple && 'mt-1.5',
|
|
236
|
+
panelOpen && 'rotate-180',
|
|
237
|
+
)}
|
|
238
|
+
>
|
|
239
|
+
<svg className="block size-3" viewBox="0 0 24 24">
|
|
240
|
+
<path
|
|
241
|
+
d="m3.414 7.086-.707.707a1 1 0 0 0 0 1.414l7.778 7.778a2 2 0 0 0 2.829 0l7.778-7.778a1 1 0 0 0 0-1.414l-.707-.707a1 1 0 0 0-1.415 0l-7.07 7.07-7.072-7.07a1 1 0 0 0-1.414 0Z"
|
|
242
|
+
fill="currentColor"
|
|
243
|
+
/>
|
|
244
|
+
</svg>
|
|
245
|
+
</span>
|
|
246
|
+
</span>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
{panelOpen ? (
|
|
250
|
+
<div className="absolute top-[calc(100%+4px)] left-px z-20 w-[calc(100%-2px)]">
|
|
251
|
+
<UserSelectorPanel
|
|
252
|
+
getUserDescription={getUserDescription}
|
|
253
|
+
loading={loading}
|
|
254
|
+
mode={mode}
|
|
255
|
+
onChange={handlePanelChange}
|
|
256
|
+
onClose={closePanel}
|
|
257
|
+
onKeyDown={onKeyDown}
|
|
258
|
+
onSearch={onSearch}
|
|
259
|
+
onSelect={onSelect}
|
|
260
|
+
onSelectRecordCreator={onSelectRecordCreator}
|
|
261
|
+
value={value}
|
|
262
|
+
/>
|
|
263
|
+
</div>
|
|
264
|
+
) : null}
|
|
265
|
+
</div>
|
|
266
|
+
)
|
|
267
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.user-selector-loading-spinner {
|
|
2
|
+
animation: user-selector-loading-rotate 1.2s linear infinite;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.user-selector-loading-spinner circle {
|
|
6
|
+
animation: user-selector-loading-dash 2.5s ease-in-out infinite;
|
|
7
|
+
stroke-dasharray: 1, 220;
|
|
8
|
+
stroke-dashoffset: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@keyframes user-selector-loading-rotate {
|
|
12
|
+
to {
|
|
13
|
+
transform: rotate(1turn);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes user-selector-loading-dash {
|
|
18
|
+
0% {
|
|
19
|
+
stroke-dasharray: 1, 220;
|
|
20
|
+
stroke-dashoffset: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
50% {
|
|
24
|
+
stroke-dasharray: 150, 220;
|
|
25
|
+
stroke-dashoffset: -68px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
100% {
|
|
29
|
+
stroke-dasharray: 150, 220;
|
|
30
|
+
stroke-dashoffset: -218px;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { isKeyboardEventComposing } from './index'
|
|
4
|
+
|
|
5
|
+
describe('isKeyboardEventComposing', () => {
|
|
6
|
+
it('recognizes native IME composition', () => {
|
|
7
|
+
expect(
|
|
8
|
+
isKeyboardEventComposing({ nativeEvent: { isComposing: true } }),
|
|
9
|
+
).toBe(true)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('recognizes the legacy IME key code', () => {
|
|
13
|
+
expect(isKeyboardEventComposing({ keyCode: 229 })).toBe(true)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('allows normal keyboard navigation', () => {
|
|
17
|
+
expect(
|
|
18
|
+
isKeyboardEventComposing({
|
|
19
|
+
keyCode: 40,
|
|
20
|
+
nativeEvent: { isComposing: false },
|
|
21
|
+
}),
|
|
22
|
+
).toBe(false)
|
|
23
|
+
})
|
|
24
|
+
})
|