snapshot of https://github.com/shadcn-ui/ui.git (main, 2026-09-15; blobs > 131072B omitted)
All checks were successful
Release / Create Version PR or Publish Stable Release (push) Has been skipped
Release / Publish Prerelease to NPM (push) Has been skipped
Monitor Registries / Monitor registry health (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-15 22:44:43 +05:00
commit 1416db152c
5727 changed files with 630238 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
import type {
AnswerControlRegistration,
ItemRegistration,
QuestionnaireShortcutMode,
} from "./types"
function hasInputValue(value: unknown) {
if (Array.isArray(value)) {
return value.some((item) => String(item).trim().length > 0)
}
return (
value !== undefined && value !== null && String(value).trim().length > 0
)
}
function getShortcutKeys(shortcuts: QuestionnaireShortcutMode | null) {
if (shortcuts === "letters") {
return Array.from({ length: 26 }, (_, index) =>
String.fromCharCode(65 + index)
)
}
if (shortcuts === "numbers") {
return Array.from({ length: 9 }, (_, index) => String(index + 1))
}
return []
}
function getShortcutFromKey(key: string, shortcuts: QuestionnaireShortcutMode) {
const normalizedKey = shortcuts === "letters" ? key.toUpperCase() : key
return getShortcutKeys(shortcuts).includes(normalizedKey)
? normalizedKey
: null
}
function getAnswerKeyShortcuts(shortcut: string | null, filled: boolean) {
return (
[shortcut, filled ? "Enter" : null].filter(Boolean).join(" ") || undefined
)
}
function isAnswerFilled(answer: AnswerControlRegistration) {
if (answer.type === "choice") {
return answer.element.checked
}
return (
answer.element.hasAttribute("name") && hasInputValue(answer.element.value)
)
}
function isEmptyNavigableInput(answer: AnswerControlRegistration | null) {
return (
answer?.type === "input" &&
["email", "password", "search", "tel", "text", "url"].includes(
answer.element.type
) &&
!hasInputValue(answer.element.value)
)
}
function isTextEntryTarget(element: Element) {
if (
element instanceof HTMLTextAreaElement ||
element instanceof HTMLSelectElement
) {
return true
}
if (element instanceof HTMLInputElement) {
return !["button", "checkbox", "radio", "reset", "submit"].includes(
element.type
)
}
return element instanceof HTMLElement && element.isContentEditable
}
function isRadioTarget(element: Element) {
return element instanceof HTMLInputElement && element.type === "radio"
}
function compareItemOrder(
firstItem: ItemRegistration,
secondItem: ItemRegistration
) {
if (firstItem.element === secondItem.element) {
return 0
}
const position = firstItem.element.compareDocumentPosition(secondItem.element)
if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
return -1
}
if (position & Node.DOCUMENT_POSITION_PRECEDING) {
return 1
}
return 0
}
function compareAnswerOrder(
firstAnswer: AnswerControlRegistration,
secondAnswer: AnswerControlRegistration
) {
if (firstAnswer.element === secondAnswer.element) {
return 0
}
const position = firstAnswer.element.compareDocumentPosition(
secondAnswer.element
)
if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
return -1
}
if (position & Node.DOCUMENT_POSITION_PRECEDING) {
return 1
}
return 0
}
export {
compareAnswerOrder,
compareItemOrder,
getAnswerKeyShortcuts,
getShortcutFromKey,
getShortcutKeys,
hasInputValue,
isAnswerFilled,
isEmptyNavigableInput,
isRadioTarget,
isTextEntryTarget,
}