feat: sync deployed v1.0.0-rc.38-custom.42

Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
cneicy committed 2026-09-26 04:49:11 +08:00
1 parent aa6c3f50f4
commit ceddfd3d6b
828 files changed
+122253 -13702

No files matched your search

+58 -2
View File
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Add01Icon } from '@hugeicons/core-free-icons'
import { HugeiconsIcon } from '@hugeicons/react'
import { ArrowRightLeft } from 'lucide-react'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
@@ -41,6 +42,11 @@ import { cn } from '@/lib/utils'
export type Option = {
label: string
value: string
/**
* Secondary text shown beside the option in the dropdown. Chips for hinted
* values also carry a marker icon whose tooltip repeats the hint.
*/
hint?: string
}
interface MultiSelectProps {
@@ -139,6 +145,14 @@ export function MultiSelect(props: MultiSelectProps) {
return map
}, [props.options])
const hintMap = React.useMemo(() => {
const map = new Map<string, string>()
for (const option of props.options) {
if (option.hint) map.set(option.value, option.hint)
}
return map
}, [props.options])
const trimmedInput = inputValue.trim()
const inputMatchesExisting =
trimmedInput.length > 0 &&
@@ -164,7 +178,7 @@ export function MultiSelect(props: MultiSelectProps) {
if (canCreate) {
set.add(trimmedInput)
}
return Array.from(set)
return [...set]
}, [props.options, props.selected, canCreate, trimmedInput])
const addValues = React.useCallback(
@@ -198,6 +212,25 @@ export function MultiSelect(props: MultiSelectProps) {
setInputValue(value)
}
const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>): void => {
if (!props.allowCreate || props.disabled) return
const pasted = event.clipboardData.getData('text/plain')
if (!COMMA_REGEX.test(pasted)) return
event.preventDefault()
const input = event.currentTarget
const value =
input.value.slice(0, input.selectionStart ?? input.value.length) +
pasted +
input.value.slice(input.selectionEnd ?? input.value.length)
// A pasted batch is complete, including its final value. Read the clipboard
// before the single-line input can strip newline separators.
addValues(value.split(COMMA_REGEX))
setInputValue('')
}
const handleValueChange = (next: string[]) => {
props.onChange(next)
// When an item is picked (multiple mode), Base UI keeps the input but most
@@ -282,6 +315,7 @@ export function MultiSelect(props: MultiSelectProps) {
<>
{visibleValues.map((value) => {
const label = labelMap.get(value) ?? value
const hint = hintMap.get(value)
return (
<ComboboxChip key={value}>
{props.copyChipOnClick ? (
@@ -299,6 +333,15 @@ export function MultiSelect(props: MultiSelectProps) {
) : (
<span className='max-w-[16rem] truncate'>{label}</span>
)}
{hint && (
<span
title={hint}
aria-hidden='true'
className='text-muted-foreground inline-flex shrink-0'
>
<ArrowRightLeft className='size-3' />
</span>
)}
</ComboboxChip>
)
})}
@@ -346,6 +389,7 @@ export function MultiSelect(props: MultiSelectProps) {
: undefined
}
onKeyDown={handleKeyDown}
onPaste={handlePaste}
aria-label={placeholder}
/>
</ComboboxChips>
@@ -356,11 +400,13 @@ export function MultiSelect(props: MultiSelectProps) {
{(item: string) => {
const isCreate = canCreate && item === trimmedInput
const label = labelMap.get(item) ?? item
const hint = hintMap.get(item)
return (
<ComboboxItem
key={item}
value={item}
className={isCreate ? 'text-foreground' : undefined}
aria-description={hint}
>
{isCreate ? (
<>
@@ -377,7 +423,17 @@ export function MultiSelect(props: MultiSelectProps) {
</span>
</>
) : (
<span className='truncate'>{label}</span>
<>
<span className='truncate'>{label}</span>
{hint && (
<span
aria-hidden='true'
className='text-muted-foreground ml-auto max-w-40 shrink-0 truncate text-xs'
>
{hint}
</span>
)}
</>
)}
</ComboboxItem>
)