feat: add Base UI Tailwind component library
Add composable wrappers for 37 Base UI component families. Expose primitive and convenience APIs with shared styling utilities. Add the registry manifest, installer CLI, generation and export checks. Include a smoke example covering primitive and shadcn-style imports.
This commit is contained in:
Executable
+308
@@ -0,0 +1,308 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
import { accessSync } from "node:fs"
|
||||||
|
import { access, copyFile, mkdir, readFile, writeFile } from "node:fs/promises"
|
||||||
|
import path from "node:path"
|
||||||
|
import process from "node:process"
|
||||||
|
import { fileURLToPath } from "node:url"
|
||||||
|
|
||||||
|
const command = process.argv[2]
|
||||||
|
const args = process.argv.slice(3)
|
||||||
|
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
|
||||||
|
const bundledManifestPath = path.join(packageRoot, "manifest.json")
|
||||||
|
const configFileName = "base-ui-tailwind.json"
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error instanceof Error ? error.message : String(error))
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
if (!command || command === "-h" || command === "--help") {
|
||||||
|
printHelp()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === "init") {
|
||||||
|
await initProject(parseOptions(args))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === "add") {
|
||||||
|
await addItems(parseOptions(args))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Unknown command: ${command}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initProject(options) {
|
||||||
|
const cwd = path.resolve(options.cwd ?? process.cwd())
|
||||||
|
const configPath = path.join(cwd, configFileName)
|
||||||
|
const localManifestPath = path.join(cwd, "manifest.json")
|
||||||
|
const config = {
|
||||||
|
manifest: options.manifest ?? ((await exists(localManifestPath)) ? "manifest.json" : bundledManifestPath),
|
||||||
|
aliases: {
|
||||||
|
ui: "components/ui",
|
||||||
|
lib: "lib",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.force && (await exists(configPath))) {
|
||||||
|
console.log(`${configFileName} already exists. Use --force to overwrite it.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await mkdir(path.join(cwd, config.aliases.ui), { recursive: true })
|
||||||
|
await mkdir(path.join(cwd, config.aliases.lib), { recursive: true })
|
||||||
|
await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`)
|
||||||
|
console.log(`Created ${path.relative(process.cwd(), configPath) || configFileName}.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addItems(options) {
|
||||||
|
const names = options._.filter((item) => !item.startsWith("-"))
|
||||||
|
if (names.length === 0) {
|
||||||
|
throw new Error("Usage: base-ui-tailwind add <name...>")
|
||||||
|
}
|
||||||
|
|
||||||
|
const cwd = path.resolve(options.cwd ?? process.cwd())
|
||||||
|
const config = await loadConfig(cwd)
|
||||||
|
const manifestRef = options.manifest ?? config.manifest ?? bundledManifestPath
|
||||||
|
const manifest = await loadManifest(manifestRef, cwd)
|
||||||
|
const selected = resolveItems(manifest, names)
|
||||||
|
const files = collectFiles(manifest, selected)
|
||||||
|
const written = []
|
||||||
|
const skipped = []
|
||||||
|
const packageDependencies = collectPackageDependencies(manifest, selected)
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
const targetPath = path.join(cwd, resolveTargetPath(file.target, config.aliases))
|
||||||
|
if (!options.overwrite && (await exists(targetPath))) {
|
||||||
|
skipped.push(path.relative(cwd, targetPath))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.dryRun) {
|
||||||
|
await mkdir(path.dirname(targetPath), { recursive: true })
|
||||||
|
const source = await readSourceFile(file.path, manifestRef, cwd)
|
||||||
|
if (source.kind === "local") {
|
||||||
|
await copyFile(source.path, targetPath)
|
||||||
|
} else {
|
||||||
|
await writeFile(targetPath, source.contents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
written.push(path.relative(cwd, targetPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written.length > 0) {
|
||||||
|
console.log(`${options.dryRun ? "Would add" : "Added"}:`)
|
||||||
|
for (const file of written) {
|
||||||
|
console.log(` ${file}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipped.length > 0) {
|
||||||
|
console.log("Skipped existing files:")
|
||||||
|
for (const file of skipped) {
|
||||||
|
console.log(` ${file}`)
|
||||||
|
}
|
||||||
|
console.log("Use --overwrite to replace existing files.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packageDependencies.length > 0) {
|
||||||
|
console.log("Required packages:")
|
||||||
|
console.log(` ${packageDependencies.join(" ")}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveItems(manifest, names) {
|
||||||
|
const resolved = new Set()
|
||||||
|
const queue = [...names]
|
||||||
|
|
||||||
|
while (queue.length > 0) {
|
||||||
|
const name = queue.shift()
|
||||||
|
const item = manifest.items?.[name]
|
||||||
|
if (!item) {
|
||||||
|
throw new Error(`Manifest item not found: ${name}`)
|
||||||
|
}
|
||||||
|
if (resolved.has(name)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved.add(name)
|
||||||
|
for (const dependency of item.localDependencies ?? []) {
|
||||||
|
queue.push(dependency)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...resolved]
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectFiles(manifest, names) {
|
||||||
|
const files = []
|
||||||
|
const seen = new Set()
|
||||||
|
|
||||||
|
for (const name of names) {
|
||||||
|
for (const file of manifest.items[name].files ?? []) {
|
||||||
|
const key = file.target
|
||||||
|
if (!seen.has(key)) {
|
||||||
|
seen.add(key)
|
||||||
|
files.push(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectPackageDependencies(manifest, names) {
|
||||||
|
const dependencies = new Set()
|
||||||
|
|
||||||
|
for (const name of names) {
|
||||||
|
for (const dependency of manifest.items[name].dependencies ?? []) {
|
||||||
|
dependencies.add(dependency)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...dependencies].sort((a, b) => a.localeCompare(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadConfig(cwd) {
|
||||||
|
const configPath = path.join(cwd, configFileName)
|
||||||
|
if (!(await exists(configPath))) {
|
||||||
|
return {
|
||||||
|
manifest: undefined,
|
||||||
|
aliases: {
|
||||||
|
ui: "components/ui",
|
||||||
|
lib: "lib",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = JSON.parse(await readFile(configPath, "utf8"))
|
||||||
|
return {
|
||||||
|
manifest: config.manifest,
|
||||||
|
aliases: {
|
||||||
|
ui: config.aliases?.ui ?? "components/ui",
|
||||||
|
lib: config.aliases?.lib ?? "lib",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadManifest(manifestRef, cwd) {
|
||||||
|
const contents = isUrl(manifestRef)
|
||||||
|
? await fetchText(manifestRef)
|
||||||
|
: await readFile(resolveLocalPath(manifestRef, cwd), "utf8")
|
||||||
|
|
||||||
|
const manifest = JSON.parse(contents)
|
||||||
|
if (!manifest.items || typeof manifest.items !== "object") {
|
||||||
|
throw new Error("Invalid manifest: missing items.")
|
||||||
|
}
|
||||||
|
return manifest
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readSourceFile(filePath, manifestRef, cwd) {
|
||||||
|
if (isUrl(manifestRef)) {
|
||||||
|
return {
|
||||||
|
kind: "remote",
|
||||||
|
contents: await fetchText(new URL(filePath, manifestRef).toString()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
kind: "local",
|
||||||
|
path: path.join(path.dirname(resolveLocalPath(manifestRef, cwd)), filePath),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTargetPath(target, aliases) {
|
||||||
|
if (target.startsWith("src/components/ui/")) {
|
||||||
|
return path.join(aliases.ui, target.slice("src/components/ui/".length))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.startsWith("src/lib/")) {
|
||||||
|
return path.join(aliases.lib, target.slice("src/lib/".length))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.startsWith("components/ui/")) {
|
||||||
|
return path.join(aliases.ui, target.slice("components/ui/".length))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.startsWith("lib/")) {
|
||||||
|
return path.join(aliases.lib, target.slice("lib/".length))
|
||||||
|
}
|
||||||
|
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveLocalPath(value, cwd) {
|
||||||
|
if (path.isAbsolute(value)) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
const projectPath = path.resolve(cwd, value)
|
||||||
|
return value === "manifest.json" && !existsSync(projectPath) ? bundledManifestPath : projectPath
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOptions(values) {
|
||||||
|
const options = { _: [] }
|
||||||
|
|
||||||
|
for (let index = 0; index < values.length; index += 1) {
|
||||||
|
const value = values[index]
|
||||||
|
|
||||||
|
if (value === "--cwd") {
|
||||||
|
options.cwd = values[++index]
|
||||||
|
} else if (value === "--manifest") {
|
||||||
|
options.manifest = values[++index]
|
||||||
|
} else if (value === "--force") {
|
||||||
|
options.force = true
|
||||||
|
} else if (value === "--overwrite") {
|
||||||
|
options.overwrite = true
|
||||||
|
} else if (value === "--dry-run") {
|
||||||
|
options.dryRun = true
|
||||||
|
} else {
|
||||||
|
options._.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchText(url) {
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`)
|
||||||
|
}
|
||||||
|
return response.text()
|
||||||
|
}
|
||||||
|
|
||||||
|
function existsSync(filePath) {
|
||||||
|
try {
|
||||||
|
accessSync(filePath)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function exists(filePath) {
|
||||||
|
try {
|
||||||
|
await access(filePath)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isUrl(value) {
|
||||||
|
return /^https?:\/\//.test(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function printHelp() {
|
||||||
|
console.log(`base-ui-tailwind
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
base-ui-tailwind init [--manifest <path-or-url>] [--cwd <dir>] [--force]
|
||||||
|
base-ui-tailwind add <name...> [--manifest <path-or-url>] [--cwd <dir>] [--overwrite] [--dry-run]
|
||||||
|
`)
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import Dialog, {
|
||||||
|
Dialog as ShadcnDialog,
|
||||||
|
DialogClose,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog"
|
||||||
|
import Button, { Button as UIButton } from "@/components/ui/button"
|
||||||
|
|
||||||
|
export function Smoke() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button focusableWhenDisabled>Primitive-style button</Button>
|
||||||
|
<UIButton>Named button</UIButton>
|
||||||
|
|
||||||
|
<Dialog.Root>
|
||||||
|
<Dialog.Trigger>Primitive dialog</Dialog.Trigger>
|
||||||
|
<Dialog.Portal>
|
||||||
|
<Dialog.Backdrop />
|
||||||
|
<Dialog.Popup>
|
||||||
|
<Dialog.Title>Primitive dialog</Dialog.Title>
|
||||||
|
<Dialog.Description>Default namespace API.</Dialog.Description>
|
||||||
|
<Dialog.Close>Close</Dialog.Close>
|
||||||
|
</Dialog.Popup>
|
||||||
|
</Dialog.Portal>
|
||||||
|
</Dialog.Root>
|
||||||
|
|
||||||
|
<ShadcnDialog>
|
||||||
|
<DialogTrigger>Named dialog</DialogTrigger>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogTitle>Named dialog</DialogTitle>
|
||||||
|
<DialogDescription>Named shadcn-style API.</DialogDescription>
|
||||||
|
<DialogClose>Close</DialogClose>
|
||||||
|
</DialogContent>
|
||||||
|
</ShadcnDialog>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
+1777
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,33 @@
|
|||||||
|
import { readdir, readFile } from "node:fs/promises"
|
||||||
|
import path from "node:path"
|
||||||
|
|
||||||
|
const uiComponentsPath = path.join("src", "components", "ui")
|
||||||
|
const componentEntries = await readdir(uiComponentsPath, { withFileTypes: true })
|
||||||
|
const components = componentEntries
|
||||||
|
.filter((entry) => entry.isDirectory())
|
||||||
|
.map((entry) => entry.name)
|
||||||
|
.sort((a, b) => a.localeCompare(b))
|
||||||
|
|
||||||
|
const failures = []
|
||||||
|
|
||||||
|
for (const component of components) {
|
||||||
|
const indexPath = path.join(uiComponentsPath, component, "index.ts")
|
||||||
|
try {
|
||||||
|
const source = await readFile(indexPath, "utf8")
|
||||||
|
if (!source.includes("export default")) {
|
||||||
|
failures.push(`${indexPath}: missing default export`)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code !== "ENOENT") {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
failures.push(`${indexPath}: missing file`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures.length > 0) {
|
||||||
|
console.error(failures.join("\n"))
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Checked ${components.length} component exports.`)
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
import { readdir, readFile, writeFile } from "node:fs/promises"
|
||||||
|
import path from "node:path"
|
||||||
|
import process from "node:process"
|
||||||
|
|
||||||
|
const root = process.cwd()
|
||||||
|
const sourceDir = path.join(root, "src")
|
||||||
|
const componentsDir = path.join(sourceDir, "components", "ui")
|
||||||
|
const libDir = path.join(sourceDir, "lib")
|
||||||
|
const outputPath = path.join(root, "manifest.json")
|
||||||
|
|
||||||
|
const packageJson = JSON.parse(await readFile(path.join(root, "package.json"), "utf8"))
|
||||||
|
const components = await listDirectories(componentsDir)
|
||||||
|
const utils = await listFiles(libDir)
|
||||||
|
|
||||||
|
const items = {}
|
||||||
|
|
||||||
|
for (const file of utils) {
|
||||||
|
const name = path.basename(file, path.extname(file))
|
||||||
|
const source = await readFile(path.join(root, file), "utf8")
|
||||||
|
const target = stripSourcePrefix(file)
|
||||||
|
items[`utils/${name}`] = {
|
||||||
|
name: `utils/${name}`,
|
||||||
|
type: "util",
|
||||||
|
description: `Utility source for ${name}.`,
|
||||||
|
dependencies: collectPackageDependencies(source),
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
path: file,
|
||||||
|
target,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const component of components) {
|
||||||
|
const componentFiles = await listFiles(path.join("src", "components", "ui", component))
|
||||||
|
const sources = await Promise.all(
|
||||||
|
componentFiles.map(async (file) => readFile(path.join(root, file), "utf8")),
|
||||||
|
)
|
||||||
|
const source = sources.join("\n")
|
||||||
|
|
||||||
|
items[component] = {
|
||||||
|
name: component,
|
||||||
|
type: "component",
|
||||||
|
description: `${toTitle(component)} component wrapper for Base UI and Tailwind CSS.`,
|
||||||
|
dependencies: collectPackageDependencies(source),
|
||||||
|
localDependencies: collectLocalDependencies(source, component, components, utils),
|
||||||
|
files: componentFiles.map((file) => ({
|
||||||
|
path: file,
|
||||||
|
target: stripSourcePrefix(file),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const manifest = {
|
||||||
|
name: "base-ui-tailwind",
|
||||||
|
version: packageJson.version ?? "0.0.0",
|
||||||
|
generatedAt: new Date().toISOString(),
|
||||||
|
command: "base-ui-tailwind",
|
||||||
|
configFile: "base-ui-tailwind.json",
|
||||||
|
dependencies: {
|
||||||
|
"@base-ui/react": packageJson.dependencies?.["@base-ui/react"],
|
||||||
|
"clsx": packageJson.dependencies?.clsx,
|
||||||
|
"lucide-react": packageJson.dependencies?.["lucide-react"],
|
||||||
|
"tailwind-merge": packageJson.dependencies?.["tailwind-merge"],
|
||||||
|
},
|
||||||
|
items,
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(outputPath, `${JSON.stringify(manifest, null, 2)}\n`)
|
||||||
|
console.log(`Generated manifest.json with ${Object.keys(items).length} items.`)
|
||||||
|
|
||||||
|
async function listDirectories(directory) {
|
||||||
|
const entries = await readdir(directory, { withFileTypes: true })
|
||||||
|
return entries
|
||||||
|
.filter((entry) => entry.isDirectory())
|
||||||
|
.map((entry) => entry.name)
|
||||||
|
.sort((a, b) => a.localeCompare(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function listFiles(relativeOrAbsoluteDirectory) {
|
||||||
|
const absoluteDirectory = path.isAbsolute(relativeOrAbsoluteDirectory)
|
||||||
|
? relativeOrAbsoluteDirectory
|
||||||
|
: path.join(root, relativeOrAbsoluteDirectory)
|
||||||
|
const relativeDirectory = path.relative(root, absoluteDirectory)
|
||||||
|
const entries = await readdir(absoluteDirectory, { withFileTypes: true })
|
||||||
|
const files = []
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const relativePath = path.join(relativeDirectory, entry.name)
|
||||||
|
const absolutePath = path.join(absoluteDirectory, entry.name)
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
files.push(...(await listFiles(absolutePath)))
|
||||||
|
} else if (entry.isFile()) {
|
||||||
|
files.push(relativePath.split(path.sep).join("/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files.sort((a, b) => a.localeCompare(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectPackageDependencies(source) {
|
||||||
|
const dependencies = new Set()
|
||||||
|
const importPattern = /from\s+["']([^"']+)["']|import\s+["']([^"']+)["']/g
|
||||||
|
|
||||||
|
for (const match of source.matchAll(importPattern)) {
|
||||||
|
const specifier = match[1] ?? match[2]
|
||||||
|
if (!specifier || specifier.startsWith(".") || specifier.startsWith("@/")) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies.add(getPackageName(specifier))
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...dependencies].sort((a, b) => a.localeCompare(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectLocalDependencies(source, component, components, utils) {
|
||||||
|
const dependencies = new Set()
|
||||||
|
const localPattern = /from\s+["']@\/([^"']+)["']|import\s+["']@\/([^"']+)["']/g
|
||||||
|
|
||||||
|
for (const match of source.matchAll(localPattern)) {
|
||||||
|
const specifier = match[1] ?? match[2]
|
||||||
|
if (!specifier) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const componentMatch = specifier.match(/^components\/ui\/([^/]+)/)
|
||||||
|
if (componentMatch && componentMatch[1] !== component && components.includes(componentMatch[1])) {
|
||||||
|
dependencies.add(componentMatch[1])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const utilMatch = specifier.match(/^lib\/([^/]+)/)
|
||||||
|
if (utilMatch) {
|
||||||
|
const utilPath = utils.find(
|
||||||
|
(file) => file === `src/lib/${utilMatch[1]}.ts` || file === `src/lib/${utilMatch[1]}.tsx`,
|
||||||
|
)
|
||||||
|
if (utilPath) {
|
||||||
|
dependencies.add(`utils/${path.basename(utilPath, path.extname(utilPath))}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...dependencies].sort((a, b) => a.localeCompare(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripSourcePrefix(file) {
|
||||||
|
return file.startsWith("src/") ? file.slice("src/".length) : file
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPackageName(specifier) {
|
||||||
|
if (specifier.startsWith("@")) {
|
||||||
|
const [scope, name] = specifier.split("/")
|
||||||
|
return `${scope}/${name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return specifier.split("/")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
function toTitle(value) {
|
||||||
|
return value
|
||||||
|
.split("-")
|
||||||
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
||||||
|
.join(" ")
|
||||||
|
}
|
||||||
@@ -0,0 +1,338 @@
|
|||||||
|
import fs from "node:fs"
|
||||||
|
import path from "node:path"
|
||||||
|
|
||||||
|
const root = process.cwd()
|
||||||
|
const contentDir = path.join(root, "site/src/content/components")
|
||||||
|
const uiDir = path.join(root, "src/components/ui")
|
||||||
|
const examplesDir = path.join(root, "site/src/examples/components")
|
||||||
|
const finished = new Set(["menu", "context-menu", "navigation-menu"])
|
||||||
|
|
||||||
|
const names = {
|
||||||
|
"alert-dialog": "AlertDialog",
|
||||||
|
"checkbox-group": "CheckboxGroup",
|
||||||
|
"context-menu": "ContextMenu",
|
||||||
|
"navigation-menu": "NavigationMenu",
|
||||||
|
"number-field": "NumberField",
|
||||||
|
"otp-field": "OtpField",
|
||||||
|
"preview-card": "PreviewCard",
|
||||||
|
"scroll-area": "ScrollArea",
|
||||||
|
"toggle-group": "ToggleGroup",
|
||||||
|
}
|
||||||
|
|
||||||
|
const officialSlugs = {
|
||||||
|
"otp-field": "otp-field",
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of fs.readdirSync(contentDir).sort()) {
|
||||||
|
if (!file.endsWith(".mdx")) continue
|
||||||
|
|
||||||
|
const slug = file.replace(/\.mdx$/, "")
|
||||||
|
if (finished.has(slug)) continue
|
||||||
|
|
||||||
|
const filePath = path.join(contentDir, file)
|
||||||
|
const current = fs.readFileSync(filePath, "utf8")
|
||||||
|
const title = current.match(/^# (.+)$/m)?.[1] ?? titleCase(slug)
|
||||||
|
const component = names[slug] ?? title.replace(/[^A-Za-z0-9]/g, "")
|
||||||
|
const parts = readParts(slug)
|
||||||
|
const exampleSrc = `components/${slug}/${slug}.tsx`
|
||||||
|
const hasTopExample = fs.existsSync(path.join(examplesDir, slug, `${slug}.tsx`))
|
||||||
|
const intro = readIntro(current, title)
|
||||||
|
const baseStyle = readSectionCode(current, "Base UI Style") ?? makeBaseStyle(slug, component, parts)
|
||||||
|
const shadcnStyle =
|
||||||
|
readSectionCode(current, "Shadcn Style") ??
|
||||||
|
readSectionCode(current, "Named Import Style") ??
|
||||||
|
makeNamedStyle(slug, component, parts)
|
||||||
|
const examples = readExamples(current, title, slug, exampleSrc, hasTopExample)
|
||||||
|
|
||||||
|
const next = [
|
||||||
|
`# ${title}`,
|
||||||
|
"",
|
||||||
|
intro || `${title} wraps Base UI's ${title.toLowerCase()} primitive with the Tailwind classes from the official Base UI example.`,
|
||||||
|
"",
|
||||||
|
hasTopExample ? `::example{src="${exampleSrc}"}` : "",
|
||||||
|
"",
|
||||||
|
"## Anatomy",
|
||||||
|
"",
|
||||||
|
"### Base UI Style",
|
||||||
|
"",
|
||||||
|
fenced(baseStyle),
|
||||||
|
"",
|
||||||
|
"### Shadcn Style",
|
||||||
|
"",
|
||||||
|
fenced(shadcnStyle),
|
||||||
|
"",
|
||||||
|
"## Composition",
|
||||||
|
"",
|
||||||
|
`Use the following composition to build \`${component}\`:`,
|
||||||
|
"",
|
||||||
|
"```txt",
|
||||||
|
makeComposition(component, parts).join("\n"),
|
||||||
|
"```",
|
||||||
|
"",
|
||||||
|
"## Examples",
|
||||||
|
"",
|
||||||
|
examples.trim(),
|
||||||
|
"",
|
||||||
|
makeApi(slug, title, component, parts),
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
.filter((line, index, array) => !(line === "" && array[index - 1] === ""))
|
||||||
|
.join("\n")
|
||||||
|
|
||||||
|
fs.writeFileSync(filePath, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
function readParts(slug) {
|
||||||
|
const indexPath = path.join(uiDir, slug, "index.ts")
|
||||||
|
if (!fs.existsSync(indexPath)) return ["Root"]
|
||||||
|
|
||||||
|
const source = fs.readFileSync(indexPath, "utf8")
|
||||||
|
const objectMatch = source.match(/const\s+\w+\s*=\s*\{([\s\S]*?)\n\}/)
|
||||||
|
if (!objectMatch) return ["Root"]
|
||||||
|
|
||||||
|
const parts = []
|
||||||
|
for (const line of objectMatch[1].split("\n")) {
|
||||||
|
const match = line.match(/^\s*([A-Za-z][A-Za-z0-9]*):/)
|
||||||
|
if (!match) continue
|
||||||
|
const part = match[1]
|
||||||
|
if (part[0] === part[0].toLowerCase()) continue
|
||||||
|
if (!parts.includes(part)) parts.push(part)
|
||||||
|
}
|
||||||
|
return parts.length ? parts : ["Root"]
|
||||||
|
}
|
||||||
|
|
||||||
|
function readIntro(source, title) {
|
||||||
|
const start = source.indexOf(`# ${title}`)
|
||||||
|
if (start === -1) return ""
|
||||||
|
let rest = source.slice(start + title.length + 3)
|
||||||
|
const stops = ["\n<ComponentPreview", "\nexport ", "\n## ", "\n::example"]
|
||||||
|
let end = rest.length
|
||||||
|
for (const stop of stops) {
|
||||||
|
const index = rest.indexOf(stop)
|
||||||
|
if (index !== -1 && index < end) end = index
|
||||||
|
}
|
||||||
|
rest = rest.slice(0, end)
|
||||||
|
return rest
|
||||||
|
.replace(/^import .+$/gm, "")
|
||||||
|
.replace(/\n{3,}/g, "\n\n")
|
||||||
|
.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
function readSectionCode(source, heading) {
|
||||||
|
const start = source.indexOf(`## ${heading}`)
|
||||||
|
if (start === -1) return null
|
||||||
|
const fenceStart = source.indexOf("```", start)
|
||||||
|
if (fenceStart === -1) return null
|
||||||
|
const lineEnd = source.indexOf("\n", fenceStart)
|
||||||
|
const fenceEnd = source.indexOf("\n```", lineEnd)
|
||||||
|
if (fenceEnd === -1) return null
|
||||||
|
return source.slice(lineEnd + 1, fenceEnd).trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
function readExamples(source, title, slug, exampleSrc, hasTopExample) {
|
||||||
|
const start = source.indexOf("## Examples")
|
||||||
|
if (start === -1) return ""
|
||||||
|
const nextHeading = source.slice(start + 1).search(/\n## /)
|
||||||
|
const end = nextHeading === -1 ? source.length : start + 1 + nextHeading
|
||||||
|
|
||||||
|
let content = source.slice(start + "## Examples".length, end).trim()
|
||||||
|
if (hasTopExample) {
|
||||||
|
const escapedTitle = escapeRegExp(title)
|
||||||
|
const escapedSrc = escapeRegExp(exampleSrc)
|
||||||
|
const duplicate = new RegExp(`^### ${escapedTitle}\\n\\n::example\\{src="${escapedSrc}"\\}\\n*`, "m")
|
||||||
|
content = content.replace(duplicate, "").trim()
|
||||||
|
}
|
||||||
|
return content || "No additional examples yet."
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeBaseStyle(slug, component, parts) {
|
||||||
|
const lines = [`import ${component} from "@/components/ui/${slug}"`, "", `<${component}.Root>`]
|
||||||
|
for (const part of parts.filter((part) => part !== "Root").slice(0, 5)) {
|
||||||
|
lines.push(` <${component}.${part} />`)
|
||||||
|
}
|
||||||
|
lines.push(`</${component}.Root>`)
|
||||||
|
return lines.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeNamedStyle(slug, component, parts) {
|
||||||
|
const named = parts.map((part) => (part === "Root" ? component : `${component}${part}`))
|
||||||
|
return [
|
||||||
|
"import {",
|
||||||
|
...named.slice(0, 8).map((name) => ` ${name},`),
|
||||||
|
`} from "@/components/ui/${slug}"`,
|
||||||
|
].join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeComposition(component, parts) {
|
||||||
|
const has = (part) => parts.includes(part)
|
||||||
|
const portalChildren = []
|
||||||
|
if (has("Backdrop")) portalChildren.push(`${component}Backdrop`)
|
||||||
|
if (has("Positioner")) {
|
||||||
|
const popupChildren = []
|
||||||
|
for (const part of ["Arrow", "Viewport", "List", "Collection", "Group", "Item", "Empty"]) {
|
||||||
|
if (has(part)) popupChildren.push(`${component}${part}`)
|
||||||
|
}
|
||||||
|
portalChildren.push({
|
||||||
|
label: `${component}Positioner`,
|
||||||
|
children: has("Popup") ? [{ label: `${component}Popup`, children: popupChildren }] : popupChildren,
|
||||||
|
})
|
||||||
|
} else if (has("Popup")) {
|
||||||
|
portalChildren.push(`${component}Popup`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const children = []
|
||||||
|
const leading = ["Trigger", "Label", "Input", "Control", "Track", "Thumb", "Image", "Fallback", "Group"]
|
||||||
|
for (const part of leading) {
|
||||||
|
if (has(part)) children.push(`${component}${part}`)
|
||||||
|
}
|
||||||
|
if (has("Portal")) {
|
||||||
|
children.push({ label: `${component}Portal`, children: portalChildren })
|
||||||
|
}
|
||||||
|
for (const part of parts) {
|
||||||
|
if (part === "Root" || leading.includes(part) || part === "Portal" || part === "Backdrop" || part === "Positioner" || part === "Popup") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const label = part === "Separator" ? `${component}.Separator` : `${component}${part}`
|
||||||
|
if (!treeHas(children, label)) children.push(label)
|
||||||
|
}
|
||||||
|
return renderTree({ label: component, children })
|
||||||
|
}
|
||||||
|
|
||||||
|
function treeHas(children, label) {
|
||||||
|
for (const child of children) {
|
||||||
|
if (typeof child === "string" && child === label) return true
|
||||||
|
if (typeof child === "object") {
|
||||||
|
if (child.label === label) return true
|
||||||
|
if (treeHas(child.children ?? [], label)) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTree(node, prefix = "") {
|
||||||
|
const lines = [prefix ? `${prefix}${node.label}` : node.label]
|
||||||
|
const children = node.children ?? []
|
||||||
|
children.forEach((child, index) => {
|
||||||
|
const last = index === children.length - 1
|
||||||
|
const branch = last ? "└── " : "├── "
|
||||||
|
const nextPrefix = prefix + (last ? " " : "│ ")
|
||||||
|
if (typeof child === "string") {
|
||||||
|
lines.push(`${prefix}${branch}${child}`)
|
||||||
|
} else {
|
||||||
|
lines.push(`${prefix}${branch}${child.label}`)
|
||||||
|
lines.push(...renderChildren(child.children ?? [], nextPrefix))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderChildren(children, prefix) {
|
||||||
|
const lines = []
|
||||||
|
children.forEach((child, index) => {
|
||||||
|
const last = index === children.length - 1
|
||||||
|
const branch = last ? "└── " : "├── "
|
||||||
|
const nextPrefix = prefix + (last ? " " : "│ ")
|
||||||
|
if (typeof child === "string") {
|
||||||
|
lines.push(`${prefix}${branch}${child}`)
|
||||||
|
} else {
|
||||||
|
lines.push(`${prefix}${branch}${child.label}`)
|
||||||
|
lines.push(...renderChildren(child.children ?? [], nextPrefix))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeApi(slug, title, component, parts) {
|
||||||
|
const official = `https://base-ui.com/react/components/${officialSlugs[slug] ?? slug}#api-reference`
|
||||||
|
const sections = parts.map((part) => makeApiPart(component, part)).join("\n\n")
|
||||||
|
return [
|
||||||
|
"## API Reference",
|
||||||
|
"",
|
||||||
|
`Official API: [Base UI ${title} API](${official}).`,
|
||||||
|
"",
|
||||||
|
`This wrapper preserves the underlying Base UI ${title} API. Styled parts forward \`className\`, \`style\`, and \`render\` where Base UI supports them.`,
|
||||||
|
"",
|
||||||
|
sections,
|
||||||
|
].join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeApiPart(component, part) {
|
||||||
|
const heading = part === "Root" ? "Root" : part
|
||||||
|
const label = part === "Root" ? component : `${component}.${part}`
|
||||||
|
const rows = apiRows(part)
|
||||||
|
return [
|
||||||
|
`### ${heading}`,
|
||||||
|
"",
|
||||||
|
`\`${label}\` exposes the corresponding Base UI part with the wrapper's Tailwind styles.`,
|
||||||
|
"",
|
||||||
|
"| Prop | Type | Default | Description |",
|
||||||
|
"| --- | --- | --- | --- |",
|
||||||
|
...rows,
|
||||||
|
].join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function apiRows(part) {
|
||||||
|
if (part === "Root") {
|
||||||
|
return [
|
||||||
|
"| `defaultValue` / `defaultOpen` | `any` | - | Initial uncontrolled value or open state when supported. |",
|
||||||
|
"| `value` / `open` | `any` | - | Controlled value or open state when supported. |",
|
||||||
|
"| `onValueChange` / `onOpenChange` | `function` | - | Called when controlled state changes. |",
|
||||||
|
"| `children` | `React.ReactNode` | - | Child parts rendered inside the root. |",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (part === "Portal") {
|
||||||
|
return [
|
||||||
|
"| `container` | `HTMLElement \\| RefObject<HTMLElement>` | `document.body` | Element that receives portal content. |",
|
||||||
|
"| `keepMounted` | `boolean` | `false` | Keeps children mounted when closed. |",
|
||||||
|
"| `children` | `React.ReactNode` | - | Floating content. |",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (part === "Positioner") {
|
||||||
|
return [
|
||||||
|
"| `side` | `Side` | - | Preferred side for floating content. |",
|
||||||
|
"| `align` | `Align` | - | Alignment on the selected side. |",
|
||||||
|
"| `sideOffset` | `number \\| OffsetFunction` | `0` | Distance from the anchor. |",
|
||||||
|
"| `collisionAvoidance` | `CollisionAvoidance` | - | Controls flip and shift behavior. |",
|
||||||
|
"| `className` | `string \\| (state) => string` | - | Classes for placement state. |",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (["Trigger", "Item", "LinkItem", "Link", "Button", "Close", "Action"].includes(part)) {
|
||||||
|
return [
|
||||||
|
"| `disabled` | `boolean` | `false` | Prevents user interaction when supported. |",
|
||||||
|
"| `onClick` | `function` | - | Called when the element is pressed. |",
|
||||||
|
"| `className` | `string \\| (state) => string` | - | Classes for interactive state. |",
|
||||||
|
"| `render` | `ReactElement \\| (props, state) => ReactElement` | - | Replaces the rendered element. |",
|
||||||
|
"| `children` | `React.ReactNode` | - | Visible content. |",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if (["CheckboxItem", "RadioGroup", "RadioItem"].includes(part)) {
|
||||||
|
return [
|
||||||
|
"| `checked` / `value` | `any` | - | Controlled checked or selected state when supported. |",
|
||||||
|
"| `defaultChecked` / `defaultValue` | `any` | - | Initial uncontrolled state when supported. |",
|
||||||
|
"| `onCheckedChange` / `onValueChange` | `function` | - | Called when selection changes. |",
|
||||||
|
"| `disabled` | `boolean` | `false` | Prevents user interaction. |",
|
||||||
|
"| `className` | `string \\| (state) => string` | - | Classes for checked, highlighted, and disabled state. |",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
"| `className` | `string \\| (state) => string` | - | Classes for the part state. |",
|
||||||
|
"| `style` | `React.CSSProperties \\| (state) => React.CSSProperties` | - | Inline style or state-based style. |",
|
||||||
|
"| `render` | `ReactElement \\| (props, state) => ReactElement` | - | Replaces the rendered element when supported. |",
|
||||||
|
"| `children` | `React.ReactNode` | - | Child content when the part accepts children. |",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function fenced(value) {
|
||||||
|
return ["```tsx", value.trim(), "```"].join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function titleCase(slug) {
|
||||||
|
return slug
|
||||||
|
.split("-")
|
||||||
|
.map((word) => word[0].toUpperCase() + word.slice(1))
|
||||||
|
.join(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeRegExp(value) {
|
||||||
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Accordion as BaseAccordion } from "@base-ui/react/accordion"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AccordionHeaderProps = React.ComponentPropsWithoutRef<typeof BaseAccordion.Header> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAccordionHeader = BaseAccordion.Header as React.ElementType
|
||||||
|
|
||||||
|
export const AccordionHeader = React.forwardRef<HTMLElement, AccordionHeaderProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAccordionHeader
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AccordionHeader.displayName = "AccordionHeader"
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { AccordionRoot } from "./root"
|
||||||
|
import { AccordionItem } from "./item"
|
||||||
|
import { AccordionHeader } from "./header"
|
||||||
|
import { AccordionTrigger } from "./trigger"
|
||||||
|
import { AccordionPanel } from "./panel"
|
||||||
|
|
||||||
|
const AccordionPrimitive = {
|
||||||
|
Root: AccordionRoot,
|
||||||
|
Item: AccordionItem,
|
||||||
|
Header: AccordionHeader,
|
||||||
|
Trigger: AccordionTrigger,
|
||||||
|
Panel: AccordionPanel,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AccordionPrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
AccordionRoot as Accordion,
|
||||||
|
AccordionRoot,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionHeader,
|
||||||
|
AccordionTrigger,
|
||||||
|
AccordionPanel,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { AccordionRootProps } from "./root"
|
||||||
|
export type { AccordionItemProps } from "./item"
|
||||||
|
export type { AccordionHeaderProps } from "./header"
|
||||||
|
export type { AccordionTriggerProps } from "./trigger"
|
||||||
|
export type { AccordionPanelProps } from "./panel"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Accordion as BaseAccordion } from "@base-ui/react/accordion"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AccordionItemProps = React.ComponentPropsWithoutRef<typeof BaseAccordion.Item> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAccordionItem = BaseAccordion.Item as React.ElementType
|
||||||
|
|
||||||
|
export const AccordionItem = React.forwardRef<HTMLElement, AccordionItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAccordionItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AccordionItem.displayName = "AccordionItem"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Accordion as BaseAccordion } from "@base-ui/react/accordion"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AccordionPanelProps = React.ComponentPropsWithoutRef<typeof BaseAccordion.Panel> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAccordionPanel = BaseAccordion.Panel as React.ElementType
|
||||||
|
|
||||||
|
export const AccordionPanel = React.forwardRef<HTMLElement, AccordionPanelProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAccordionPanel
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"h-(--accordion-panel-height) overflow-hidden text-sm transition-[height] duration-150 ease-[ease-out] data-ending-style:h-0 data-starting-style:h-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AccordionPanel.displayName = "AccordionPanel"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Accordion as BaseAccordion } from "@base-ui/react/accordion"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AccordionRootProps = React.ComponentPropsWithoutRef<typeof BaseAccordion.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAccordionRoot = BaseAccordion.Root as React.ElementType
|
||||||
|
|
||||||
|
export const AccordionRoot = React.forwardRef<HTMLElement, AccordionRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAccordionRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex w-full max-w-80 flex-col border border-neutral-950 text-neutral-950 dark:border-white dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AccordionRoot.displayName = "AccordionRoot"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Accordion as BaseAccordion } from "@base-ui/react/accordion"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AccordionTriggerProps = React.ComponentPropsWithoutRef<typeof BaseAccordion.Trigger> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAccordionTrigger = BaseAccordion.Trigger as React.ElementType
|
||||||
|
|
||||||
|
export const AccordionTrigger = React.forwardRef<HTMLElement, AccordionTriggerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAccordionTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"group flex w-full items-center justify-between gap-4 bg-transparent px-3 py-2 text-left text-sm font-normal text-neutral-950 select-none [&:not([data-disabled]):hover]:bg-neutral-100 focus-visible:relative focus-visible:z-1 focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:text-white dark:[&:not([data-disabled]):hover]:bg-neutral-800",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AccordionTrigger.displayName = "AccordionTrigger"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogBackdropProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Backdrop> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogBackdrop = BaseAlertDialog.Backdrop as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogBackdrop = React.forwardRef<HTMLElement, AlertDialogBackdropProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogBackdrop
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"z-40",
|
||||||
|
"fixed inset-0 min-h-dvh bg-black opacity-20 transition-opacity duration-350 ease-out data-ending-style:duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:opacity-50 supports-[-webkit-touch-callout:none]:absolute",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogBackdrop.displayName = "AlertDialogBackdrop"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogCloseProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Close> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogClose = BaseAlertDialog.Close as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogClose = React.forwardRef<HTMLElement, AlertDialogCloseProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogClose
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-8 items-center justify-center gap-2 border border-neutral-950 bg-white px-3 text-sm leading-none whitespace-nowrap font-normal text-neutral-950 select-none [&:not([data-disabled]):hover]:bg-neutral-100 [&:not([data-disabled]):active]:bg-neutral-200 data-disabled:border-neutral-500 data-disabled:text-neutral-500 disabled:border-neutral-500 disabled:text-neutral-500 focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:border-white dark:bg-neutral-950 dark:text-white dark:[&:not([data-disabled]):hover]:bg-neutral-800 dark:[&:not([data-disabled]):active]:bg-neutral-700 dark:data-disabled:border-neutral-400 dark:data-disabled:text-neutral-400 dark:focus-visible:outline-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogClose.displayName = "AlertDialogClose"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { AlertDialogBackdrop } from "./backdrop"
|
||||||
|
import { AlertDialogPortal } from "./portal"
|
||||||
|
import { AlertDialogPopup, type AlertDialogPopupProps } from "./popup"
|
||||||
|
|
||||||
|
export type AlertDialogContentProps = AlertDialogPopupProps
|
||||||
|
|
||||||
|
export const AlertDialogContent = React.forwardRef<HTMLElement, AlertDialogContentProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogBackdrop />
|
||||||
|
<AlertDialogPopup ref={ref} className={cn(className)} {...props} />
|
||||||
|
</AlertDialogPortal>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogContent.displayName = "AlertDialogContent"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogDescriptionProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Description> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogDescription = BaseAlertDialog.Description as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogDescription = React.forwardRef<HTMLElement, AlertDialogDescriptionProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogDescription
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-sm text-neutral-600 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogDescription.displayName = "AlertDialogDescription"
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { AlertDialogRoot } from "./root"
|
||||||
|
import { AlertDialogBackdrop } from "./backdrop"
|
||||||
|
import { AlertDialogClose } from "./close"
|
||||||
|
import { AlertDialogDescription } from "./description"
|
||||||
|
import { AlertDialogPopup } from "./popup"
|
||||||
|
import { AlertDialogPortal } from "./portal"
|
||||||
|
import { AlertDialogTitle } from "./title"
|
||||||
|
import { AlertDialogTrigger } from "./trigger"
|
||||||
|
import { AlertDialogViewport } from "./viewport"
|
||||||
|
import { AlertDialogContent } from "./content"
|
||||||
|
|
||||||
|
const AlertDialogPrimitive = {
|
||||||
|
Root: AlertDialogRoot,
|
||||||
|
Backdrop: AlertDialogBackdrop,
|
||||||
|
Close: AlertDialogClose,
|
||||||
|
Description: AlertDialogDescription,
|
||||||
|
Popup: AlertDialogPopup,
|
||||||
|
Portal: AlertDialogPortal,
|
||||||
|
Title: AlertDialogTitle,
|
||||||
|
Trigger: AlertDialogTrigger,
|
||||||
|
Viewport: AlertDialogViewport,
|
||||||
|
createHandle: BaseAlertDialog.createHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AlertDialogPrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
AlertDialogRoot as AlertDialog,
|
||||||
|
AlertDialogRoot,
|
||||||
|
AlertDialogBackdrop,
|
||||||
|
AlertDialogClose,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogPopup,
|
||||||
|
AlertDialogPortal,
|
||||||
|
AlertDialogTitle,
|
||||||
|
AlertDialogTrigger,
|
||||||
|
AlertDialogViewport,
|
||||||
|
AlertDialogContent,
|
||||||
|
BaseAlertDialog,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { AlertDialogRootProps } from "./root"
|
||||||
|
export type { AlertDialogBackdropProps } from "./backdrop"
|
||||||
|
export type { AlertDialogCloseProps } from "./close"
|
||||||
|
export type { AlertDialogDescriptionProps } from "./description"
|
||||||
|
export type { AlertDialogPopupProps } from "./popup"
|
||||||
|
export type { AlertDialogPortalProps } from "./portal"
|
||||||
|
export type { AlertDialogTitleProps } from "./title"
|
||||||
|
export type { AlertDialogTriggerProps } from "./trigger"
|
||||||
|
export type { AlertDialogViewportProps } from "./viewport"
|
||||||
|
export type { AlertDialogContentProps } from "./content"
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogPopupProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Popup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogPopup = BaseAlertDialog.Popup as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogPopup = React.forwardRef<HTMLElement, AlertDialogPopupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogPopup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"z-50",
|
||||||
|
"fixed top-1/2 left-1/2 -mt-8 flex w-96 max-w-[calc(100vw-3rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-4 bg-white dark:bg-neutral-950 p-4 text-neutral-950 dark:text-white border border-neutral-950 dark:border-white shadow-[0.25rem_0.25rem_0_rgb(0_0_0/12%)] dark:shadow-none transition-[transform,opacity] duration-350 ease-[cubic-bezier(0.22,1,0.36,1)] data-ending-style:duration-150 data-ending-style:ease-out data-ending-style:scale-[0.98] data-ending-style:opacity-0 data-starting-style:scale-[0.98] data-starting-style:opacity-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogPopup.displayName = "AlertDialogPopup"
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { usePortalContainer } from "@/lib/portal-container"
|
||||||
|
|
||||||
|
export type AlertDialogPortalProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Portal> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogPortal = BaseAlertDialog.Portal as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogPortal = React.forwardRef<HTMLElement, AlertDialogPortalProps>(
|
||||||
|
({ className, container, ...props }, ref) => {
|
||||||
|
const portalContainer = usePortalContainer()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BaseAlertDialogPortal
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
container={container ?? portalContainer ?? undefined}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogPortal.displayName = "AlertDialogPortal"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogRootProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogRoot = BaseAlertDialog.Root as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogRoot = React.forwardRef<HTMLElement, AlertDialogRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogRoot.displayName = "AlertDialogRoot"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogTitleProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Title> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogTitle = BaseAlertDialog.Title as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogTitle = React.forwardRef<HTMLElement, AlertDialogTitleProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogTitle
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-base font-bold",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogTitle.displayName = "AlertDialogTitle"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogTriggerProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Trigger> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogTrigger = BaseAlertDialog.Trigger as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogTrigger = React.forwardRef<HTMLElement, AlertDialogTriggerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-8 items-center justify-center gap-2 border border-neutral-950 bg-white px-3 text-sm leading-none whitespace-nowrap font-normal text-neutral-950 select-none [&:not([data-disabled]):hover]:bg-neutral-100 [&:not([data-disabled]):active]:bg-neutral-200 data-disabled:border-neutral-500 data-disabled:text-neutral-500 disabled:border-neutral-500 disabled:text-neutral-500 focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:border-white dark:bg-neutral-950 dark:text-white dark:[&:not([data-disabled]):hover]:bg-neutral-800 dark:[&:not([data-disabled]):active]:bg-neutral-700 dark:data-disabled:border-neutral-400 dark:data-disabled:text-neutral-400 dark:focus-visible:outline-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogTrigger.displayName = "AlertDialogTrigger"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { AlertDialog as BaseAlertDialog } from "@base-ui/react/alert-dialog"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AlertDialogViewportProps = React.ComponentPropsWithoutRef<typeof BaseAlertDialog.Viewport> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAlertDialogViewport = BaseAlertDialog.Viewport as React.ElementType
|
||||||
|
|
||||||
|
export const AlertDialogViewport = React.forwardRef<HTMLElement, AlertDialogViewportProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAlertDialogViewport
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"z-50 outline-none",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AlertDialogViewport.displayName = "AlertDialogViewport"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteArrowProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Arrow> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteArrow = BaseAutocomplete.Arrow as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteArrow = React.forwardRef<HTMLElement, AutocompleteArrowProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteArrow
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center text-neutral-500 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteArrow.displayName = "AutocompleteArrow"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteBackdropProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Backdrop> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteBackdrop = BaseAutocomplete.Backdrop as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteBackdrop = React.forwardRef<HTMLElement, AutocompleteBackdropProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteBackdrop
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] transition-opacity data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/50",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteBackdrop.displayName = "AutocompleteBackdrop"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteClearProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Clear> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteClear = BaseAutocomplete.Clear as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteClear = React.forwardRef<HTMLElement, AutocompleteClearProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteClear
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"combobox-clear flex h-full w-6 items-center justify-center border-0 bg-transparent p-0 text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteClear.displayName = "AutocompleteClear"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteCollectionProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Collection> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteCollection = BaseAutocomplete.Collection as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteCollection = React.forwardRef<HTMLElement, AutocompleteCollectionProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteCollection
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteCollection.displayName = "AutocompleteCollection"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteEmptyProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Empty> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteEmpty = BaseAutocomplete.Empty as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteEmpty = React.forwardRef<HTMLElement, AutocompleteEmptyProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteEmpty
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-sm text-neutral-600 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteEmpty.displayName = "AutocompleteEmpty"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteGroupLabelProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.GroupLabel> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteGroupLabel = BaseAutocomplete.GroupLabel as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteGroupLabel = React.forwardRef<HTMLElement, AutocompleteGroupLabelProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteGroupLabel
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex min-h-8 items-center pr-6 pl-3 text-sm leading-none font-normal text-neutral-500 select-none outline-none dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteGroupLabel.displayName = "AutocompleteGroupLabel"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteGroupProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Group> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteGroup = BaseAutocomplete.Group as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteGroup = React.forwardRef<HTMLElement, AutocompleteGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteGroup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"not-last:mb-1",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteGroup.displayName = "AutocompleteGroup"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteIconProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Icon> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteIcon = BaseAutocomplete.Icon as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteIcon = React.forwardRef<HTMLElement, AutocompleteIconProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteIcon
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center text-neutral-500 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteIcon.displayName = "AutocompleteIcon"
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { AutocompleteRoot } from "./root"
|
||||||
|
import { AutocompleteValue } from "./value"
|
||||||
|
import { AutocompleteTrigger } from "./trigger"
|
||||||
|
import { AutocompleteInput } from "./input"
|
||||||
|
import { AutocompleteInputGroup } from "./input-group"
|
||||||
|
import { AutocompleteIcon } from "./icon"
|
||||||
|
import { AutocompleteClear } from "./clear"
|
||||||
|
import { AutocompleteList } from "./list"
|
||||||
|
import { AutocompletePortal } from "./portal"
|
||||||
|
import { AutocompleteBackdrop } from "./backdrop"
|
||||||
|
import { AutocompletePositioner } from "./positioner"
|
||||||
|
import { AutocompletePopup } from "./popup"
|
||||||
|
import { AutocompleteArrow } from "./arrow"
|
||||||
|
import { AutocompleteGroup } from "./group"
|
||||||
|
import { AutocompleteGroupLabel } from "./group-label"
|
||||||
|
import { AutocompleteItem } from "./item"
|
||||||
|
import { AutocompleteRow } from "./row"
|
||||||
|
import { AutocompleteCollection } from "./collection"
|
||||||
|
import { AutocompleteEmpty } from "./empty"
|
||||||
|
|
||||||
|
const AutocompletePrimitive = {
|
||||||
|
Root: AutocompleteRoot,
|
||||||
|
Value: AutocompleteValue,
|
||||||
|
Trigger: AutocompleteTrigger,
|
||||||
|
Input: AutocompleteInput,
|
||||||
|
InputGroup: AutocompleteInputGroup,
|
||||||
|
Icon: AutocompleteIcon,
|
||||||
|
Clear: AutocompleteClear,
|
||||||
|
List: AutocompleteList,
|
||||||
|
Portal: AutocompletePortal,
|
||||||
|
Backdrop: AutocompleteBackdrop,
|
||||||
|
Positioner: AutocompletePositioner,
|
||||||
|
Popup: AutocompletePopup,
|
||||||
|
Arrow: AutocompleteArrow,
|
||||||
|
Group: AutocompleteGroup,
|
||||||
|
GroupLabel: AutocompleteGroupLabel,
|
||||||
|
Item: AutocompleteItem,
|
||||||
|
Row: AutocompleteRow,
|
||||||
|
Collection: AutocompleteCollection,
|
||||||
|
Empty: AutocompleteEmpty,
|
||||||
|
Separator: BaseAutocomplete.Separator,
|
||||||
|
Status: BaseAutocomplete.Status,
|
||||||
|
useFilter: BaseAutocomplete.useFilter,
|
||||||
|
useFilteredItems: BaseAutocomplete.useFilteredItems,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AutocompletePrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
AutocompleteRoot as Autocomplete,
|
||||||
|
AutocompleteRoot,
|
||||||
|
AutocompleteValue,
|
||||||
|
AutocompleteTrigger,
|
||||||
|
AutocompleteInput,
|
||||||
|
AutocompleteInputGroup,
|
||||||
|
AutocompleteIcon,
|
||||||
|
AutocompleteClear,
|
||||||
|
AutocompleteList,
|
||||||
|
AutocompletePortal,
|
||||||
|
AutocompleteBackdrop,
|
||||||
|
AutocompletePositioner,
|
||||||
|
AutocompletePopup,
|
||||||
|
AutocompleteArrow,
|
||||||
|
AutocompleteGroup,
|
||||||
|
AutocompleteGroupLabel,
|
||||||
|
AutocompleteItem,
|
||||||
|
AutocompleteRow,
|
||||||
|
AutocompleteCollection,
|
||||||
|
AutocompleteEmpty,
|
||||||
|
BaseAutocomplete,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { AutocompleteRootProps } from "./root"
|
||||||
|
export type { AutocompleteValueProps } from "./value"
|
||||||
|
export type { AutocompleteTriggerProps } from "./trigger"
|
||||||
|
export type { AutocompleteInputProps } from "./input"
|
||||||
|
export type { AutocompleteInputGroupProps } from "./input-group"
|
||||||
|
export type { AutocompleteIconProps } from "./icon"
|
||||||
|
export type { AutocompleteClearProps } from "./clear"
|
||||||
|
export type { AutocompleteListProps } from "./list"
|
||||||
|
export type { AutocompletePortalProps } from "./portal"
|
||||||
|
export type { AutocompleteBackdropProps } from "./backdrop"
|
||||||
|
export type { AutocompletePositionerProps } from "./positioner"
|
||||||
|
export type { AutocompletePopupProps } from "./popup"
|
||||||
|
export type { AutocompleteArrowProps } from "./arrow"
|
||||||
|
export type { AutocompleteGroupProps } from "./group"
|
||||||
|
export type { AutocompleteGroupLabelProps } from "./group-label"
|
||||||
|
export type { AutocompleteItemProps } from "./item"
|
||||||
|
export type { AutocompleteRowProps } from "./row"
|
||||||
|
export type { AutocompleteCollectionProps } from "./collection"
|
||||||
|
export type { AutocompleteEmptyProps } from "./empty"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteInputGroupProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.InputGroup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteInputGroup = BaseAutocomplete.InputGroup as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteInputGroup = React.forwardRef<HTMLElement, AutocompleteInputGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteInputGroup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex items-center gap-2",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteInputGroup.displayName = "AutocompleteInputGroup"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteInputProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Input> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteInput = BaseAutocomplete.Input as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteInput = React.forwardRef<HTMLElement, AutocompleteInputProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteInput
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"h-8 w-[16rem] border border-neutral-950 bg-white dark:bg-neutral-950 px-2 text-sm any-pointer-coarse:text-base font-normal text-neutral-950 placeholder:opacity-100 placeholder:text-neutral-500 placeholder:[-webkit-text-fill-color:var(--color-neutral-500)] dark:placeholder:text-neutral-400 dark:placeholder:[-webkit-text-fill-color:var(--color-neutral-400)] focus:outline-2 focus:outline-solid focus:-outline-offset-1 focus:outline-neutral-950 dark:focus:outline-white dark:border-white dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteInput.displayName = "AutocompleteInput"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteItemProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Item> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteItem = BaseAutocomplete.Item as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteItem = React.forwardRef<HTMLElement, AutocompleteItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center gap-2 py-2 pr-2 pl-2 text-sm leading-4 outline-none select-none data-highlighted:relative data-highlighted:z-0 data-highlighted:text-white data-highlighted:before:absolute data-highlighted:before:inset-x-0 data-highlighted:before:inset-y-0 data-highlighted:before:z-[-1] data-highlighted:before:bg-neutral-950 dark:data-highlighted:text-neutral-950 dark:data-highlighted:before:bg-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteItem.displayName = "AutocompleteItem"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteListProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.List> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteList = BaseAutocomplete.List as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteList = React.forwardRef<HTMLElement, AutocompleteListProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteList
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"outline-0 overflow-y-auto scroll-py-1 py-1 overscroll-contain max-h-[min(22.5rem,var(--available-height))] data-empty:p-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteList.displayName = "AutocompleteList"
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompletePopupProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Popup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompletePopup = BaseAutocomplete.Popup as React.ElementType
|
||||||
|
const defaultAutocompletePopupClassName =
|
||||||
|
"w-[var(--anchor-width)] max-w-[var(--available-width)] border border-neutral-950 bg-white text-neutral-950 shadow-[0.25rem_0.25rem_0_rgb(0_0_0_/_12%)] dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none"
|
||||||
|
|
||||||
|
export const AutocompletePopup = React.forwardRef<HTMLElement, AutocompletePopupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompletePopup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className ?? defaultAutocompletePopupClassName)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompletePopup.displayName = "AutocompletePopup"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompletePortalProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Portal> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompletePortal = BaseAutocomplete.Portal as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompletePortal = React.forwardRef<HTMLElement, AutocompletePortalProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompletePortal
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompletePortal.displayName = "AutocompletePortal"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompletePositionerProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Positioner> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompletePositioner = BaseAutocomplete.Positioner as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompletePositioner = React.forwardRef<HTMLElement, AutocompletePositionerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompletePositioner
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"outline-none",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompletePositioner.displayName = "AutocompletePositioner"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteRootProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteRoot = BaseAutocomplete.Root as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteRoot = React.forwardRef<HTMLElement, AutocompleteRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteRoot.displayName = "AutocompleteRoot"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteRowProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Row> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteRow = BaseAutocomplete.Row as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteRow = React.forwardRef<HTMLElement, AutocompleteRowProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteRow
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"grid grid-cols-5",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteRow.displayName = "AutocompleteRow"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteTriggerProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Trigger> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteTrigger = BaseAutocomplete.Trigger as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteTrigger = React.forwardRef<HTMLElement, AutocompleteTriggerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-8 items-center justify-center border border-neutral-950 bg-transparent text-xl leading-none text-neutral-950 outline-none hover:bg-neutral-100 active:bg-neutral-200 focus-visible:outline-2 focus-visible:[outline-style:solid] focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white data-[popup-open]:bg-neutral-100 dark:border-white dark:text-white dark:hover:bg-neutral-800 dark:active:bg-neutral-700 dark:data-[popup-open]:bg-neutral-800",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteTrigger.displayName = "AutocompleteTrigger"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Autocomplete as BaseAutocomplete } from "@base-ui/react/autocomplete"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AutocompleteValueProps = React.ComponentPropsWithoutRef<typeof BaseAutocomplete.Value> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAutocompleteValue = BaseAutocomplete.Value as React.ElementType
|
||||||
|
|
||||||
|
export const AutocompleteValue = React.forwardRef<HTMLElement, AutocompleteValueProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAutocompleteValue
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-sm text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AutocompleteValue.displayName = "AutocompleteValue"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Avatar as BaseAvatar } from "@base-ui/react/avatar"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AvatarFallbackProps = React.ComponentPropsWithoutRef<typeof BaseAvatar.Fallback> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAvatarFallback = BaseAvatar.Fallback as React.ElementType
|
||||||
|
|
||||||
|
export const AvatarFallback = React.forwardRef<HTMLElement, AvatarFallbackProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAvatarFallback
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-full items-center justify-center text-sm",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AvatarFallback.displayName = "AvatarFallback"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Avatar as BaseAvatar } from "@base-ui/react/avatar"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AvatarImageProps = React.ComponentPropsWithoutRef<typeof BaseAvatar.Image> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAvatarImage = BaseAvatar.Image as React.ElementType
|
||||||
|
|
||||||
|
export const AvatarImage = React.forwardRef<HTMLElement, AvatarImageProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAvatarImage
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"size-full object-cover",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AvatarImage.displayName = "AvatarImage"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { AvatarRoot } from "./root"
|
||||||
|
import { AvatarImage } from "./image"
|
||||||
|
import { AvatarFallback } from "./fallback"
|
||||||
|
|
||||||
|
const AvatarPrimitive = {
|
||||||
|
Root: AvatarRoot,
|
||||||
|
Image: AvatarImage,
|
||||||
|
Fallback: AvatarFallback,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AvatarPrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
AvatarRoot as Avatar,
|
||||||
|
AvatarRoot,
|
||||||
|
AvatarImage,
|
||||||
|
AvatarFallback,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { AvatarRootProps } from "./root"
|
||||||
|
export type { AvatarImageProps } from "./image"
|
||||||
|
export type { AvatarFallbackProps } from "./fallback"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Avatar as BaseAvatar } from "@base-ui/react/avatar"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type AvatarRootProps = React.ComponentPropsWithoutRef<typeof BaseAvatar.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseAvatarRoot = BaseAvatar.Root as React.ElementType
|
||||||
|
|
||||||
|
export const AvatarRoot = React.forwardRef<HTMLElement, AvatarRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseAvatarRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"inline-flex size-8 items-center justify-center overflow-hidden rounded-full bg-neutral-200 align-middle text-sm leading-none font-normal text-neutral-950 select-none dark:bg-neutral-800 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
AvatarRoot.displayName = "AvatarRoot"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { Button } from "./root"
|
||||||
|
|
||||||
|
export { Button, type ButtonProps } from "./root"
|
||||||
|
export default Button
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Button as BaseButton } from "@base-ui/react/button"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ButtonProps = React.ComponentPropsWithoutRef<typeof BaseButton> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseButtonElement = BaseButton as React.ElementType
|
||||||
|
|
||||||
|
export const Button = React.forwardRef<HTMLElement, ButtonProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseButtonElement
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-8 items-center justify-center gap-2 rounded-none border border-neutral-950 bg-white px-3 text-sm leading-none whitespace-nowrap font-normal text-neutral-950 select-none [&:not([data-disabled]):hover]:bg-neutral-100 [&:not([data-disabled]):active]:bg-neutral-200 focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white data-disabled:cursor-default data-disabled:border-neutral-500 data-disabled:text-neutral-500 disabled:cursor-default disabled:border-neutral-500 disabled:text-neutral-500 dark:border-white dark:bg-neutral-950 dark:text-white dark:[&:not([data-disabled]):hover]:bg-neutral-800 dark:[&:not([data-disabled]):active]:bg-neutral-700 dark:data-disabled:border-neutral-400 dark:data-disabled:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Button.displayName = "Button"
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { CheckboxGroup } from "./root"
|
||||||
|
|
||||||
|
export { CheckboxGroup, type CheckboxGroupProps } from "./root"
|
||||||
|
export default CheckboxGroup
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { CheckboxGroup as BaseCheckboxGroup } from "@base-ui/react/checkbox-group"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type CheckboxGroupProps = React.ComponentPropsWithoutRef<typeof BaseCheckboxGroup> & { className?: string }
|
||||||
|
|
||||||
|
const BaseCheckboxGroupElement = BaseCheckboxGroup as React.ElementType
|
||||||
|
|
||||||
|
export const CheckboxGroup = React.forwardRef<HTMLElement, CheckboxGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseCheckboxGroupElement
|
||||||
|
ref={ref}
|
||||||
|
className={cn("flex flex-col items-start gap-1 text-neutral-950 dark:text-white", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
CheckboxGroup.displayName = "CheckboxGroup"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { CheckboxRoot } from "./root"
|
||||||
|
import { CheckboxIndicator } from "./indicator"
|
||||||
|
|
||||||
|
const CheckboxPrimitive = {
|
||||||
|
Root: CheckboxRoot,
|
||||||
|
Indicator: CheckboxIndicator,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CheckboxPrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
CheckboxRoot as Checkbox,
|
||||||
|
CheckboxRoot,
|
||||||
|
CheckboxIndicator,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { CheckboxRootProps } from "./root"
|
||||||
|
export type { CheckboxIndicatorProps } from "./indicator"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type CheckboxIndicatorProps = React.ComponentPropsWithoutRef<typeof BaseCheckbox.Indicator> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseCheckboxIndicator = BaseCheckbox.Indicator as React.ElementType
|
||||||
|
|
||||||
|
export const CheckboxIndicator = React.forwardRef<HTMLElement, CheckboxIndicatorProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseCheckboxIndicator
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex data-unchecked:hidden",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
CheckboxIndicator.displayName = "CheckboxIndicator"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type CheckboxRootProps = React.ComponentPropsWithoutRef<typeof BaseCheckbox.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseCheckboxRoot = BaseCheckbox.Root as React.ElementType
|
||||||
|
|
||||||
|
export const CheckboxRoot = React.forwardRef<HTMLElement, CheckboxRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseCheckboxRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center rounded-none border border-neutral-950 bg-white p-0 text-white data-checked:bg-neutral-950 data-checked:text-white focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-neutral-950 dark:border-white dark:bg-neutral-950 dark:text-neutral-950 dark:data-checked:bg-white dark:data-checked:text-neutral-950 dark:focus-visible:outline-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
CheckboxRoot.displayName = "CheckboxRoot"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { CollapsibleRoot } from "./root"
|
||||||
|
import { CollapsibleTrigger } from "./trigger"
|
||||||
|
import { CollapsiblePanel } from "./panel"
|
||||||
|
|
||||||
|
const CollapsiblePrimitive = {
|
||||||
|
Root: CollapsibleRoot,
|
||||||
|
Trigger: CollapsibleTrigger,
|
||||||
|
Panel: CollapsiblePanel,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CollapsiblePrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
CollapsibleRoot as Collapsible,
|
||||||
|
CollapsibleRoot,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
CollapsiblePanel,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { CollapsibleRootProps } from "./root"
|
||||||
|
export type { CollapsibleTriggerProps } from "./trigger"
|
||||||
|
export type { CollapsiblePanelProps } from "./panel"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Collapsible as BaseCollapsible } from "@base-ui/react/collapsible"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type CollapsiblePanelProps = React.ComponentPropsWithoutRef<typeof BaseCollapsible.Panel> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseCollapsiblePanel = BaseCollapsible.Panel as React.ElementType
|
||||||
|
|
||||||
|
export const CollapsiblePanel = React.forwardRef<HTMLElement, CollapsiblePanelProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseCollapsiblePanel
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-(--collapsible-panel-height) flex-col justify-end overflow-hidden text-sm transition-[height] duration-150 ease-[ease-out] [&[hidden]:not([hidden='until-found'])]:hidden data-ending-style:h-0 data-starting-style:h-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
CollapsiblePanel.displayName = "CollapsiblePanel"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Collapsible as BaseCollapsible } from "@base-ui/react/collapsible"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type CollapsibleRootProps = React.ComponentPropsWithoutRef<typeof BaseCollapsible.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseCollapsibleRoot = BaseCollapsible.Root as React.ElementType
|
||||||
|
|
||||||
|
export const CollapsibleRoot = React.forwardRef<HTMLElement, CollapsibleRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseCollapsibleRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex min-h-36 w-48 flex-col justify-center text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
CollapsibleRoot.displayName = "CollapsibleRoot"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Collapsible as BaseCollapsible } from "@base-ui/react/collapsible"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type CollapsibleTriggerProps = React.ComponentPropsWithoutRef<typeof BaseCollapsible.Trigger> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseCollapsibleTrigger = BaseCollapsible.Trigger as React.ElementType
|
||||||
|
|
||||||
|
export const CollapsibleTrigger = React.forwardRef<HTMLElement, CollapsibleTriggerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseCollapsibleTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"group flex h-8 items-center justify-between gap-2 rounded-none border border-neutral-950 dark:border-white bg-white dark:bg-neutral-950 pl-3 pr-2 text-sm leading-none whitespace-nowrap font-normal text-neutral-950 dark:text-white select-none [&:not([data-disabled]):hover]:bg-neutral-100 dark:[&:not([data-disabled]):hover]:bg-neutral-800 [&:not([data-disabled]):active]:bg-neutral-200 dark:[&:not([data-disabled]):active]:bg-neutral-700 focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white data-disabled:border-neutral-500 data-disabled:text-neutral-500 disabled:border-neutral-500 disabled:text-neutral-500 dark:data-disabled:border-neutral-400 dark:data-disabled:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
CollapsibleTrigger.displayName = "CollapsibleTrigger"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxArrowProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Arrow> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxArrow = BaseCombobox.Arrow as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxArrow = React.forwardRef<HTMLElement, ComboboxArrowProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxArrow
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center text-neutral-500 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxArrow.displayName = "ComboboxArrow"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxBackdropProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Backdrop> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxBackdrop = BaseCombobox.Backdrop as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxBackdrop = React.forwardRef<HTMLElement, ComboboxBackdropProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxBackdrop
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] transition-opacity data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/50",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxBackdrop.displayName = "ComboboxBackdrop"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxChipRemoveProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.ChipRemove> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxChipRemove = BaseCombobox.ChipRemove as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxChipRemove = React.forwardRef<HTMLElement, ComboboxChipRemoveProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxChipRemove
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxChipRemove.displayName = "ComboboxChipRemove"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxChipProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Chip> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxChip = BaseCombobox.Chip as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxChip = React.forwardRef<HTMLElement, ComboboxChipProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxChip
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxChip.displayName = "ComboboxChip"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxChipsProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Chips> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxChips = BaseCombobox.Chips as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxChips = React.forwardRef<HTMLElement, ComboboxChipsProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxChips
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxChips.displayName = "ComboboxChips"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxClearProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Clear> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxClear = BaseCombobox.Clear as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxClear = React.forwardRef<HTMLElement, ComboboxClearProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxClear
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"combobox-clear flex h-full w-6 items-center justify-center border-0 bg-transparent p-0 text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxClear.displayName = "ComboboxClear"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxCollectionProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Collection> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxCollection = BaseCombobox.Collection as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxCollection = React.forwardRef<HTMLElement, ComboboxCollectionProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxCollection
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxCollection.displayName = "ComboboxCollection"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxEmptyProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Empty> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxEmpty = BaseCombobox.Empty as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxEmpty = React.forwardRef<HTMLElement, ComboboxEmptyProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxEmpty
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-sm text-neutral-600 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxEmpty.displayName = "ComboboxEmpty"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxGroupLabelProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.GroupLabel> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxGroupLabel = BaseCombobox.GroupLabel as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxGroupLabel = React.forwardRef<HTMLElement, ComboboxGroupLabelProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxGroupLabel
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"py-2 pr-2 pl-8 text-sm leading-4 text-neutral-500 select-none dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxGroupLabel.displayName = "ComboboxGroupLabel"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxGroupProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Group> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxGroup = BaseCombobox.Group as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxGroup = React.forwardRef<HTMLElement, ComboboxGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxGroup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"block pb-2 last:pb-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxGroup.displayName = "ComboboxGroup"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxIconProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Icon> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxIcon = BaseCombobox.Icon as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxIcon = React.forwardRef<HTMLElement, ComboboxIconProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxIcon
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxIcon.displayName = "ComboboxIcon"
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { ComboboxRoot } from "./root"
|
||||||
|
import { ComboboxLabel } from "./label"
|
||||||
|
import { ComboboxValue } from "./value"
|
||||||
|
import { ComboboxInput } from "./input"
|
||||||
|
import { ComboboxInputGroup } from "./input-group"
|
||||||
|
import { ComboboxTrigger } from "./trigger"
|
||||||
|
import { ComboboxList } from "./list"
|
||||||
|
import { ComboboxPortal } from "./portal"
|
||||||
|
import { ComboboxBackdrop } from "./backdrop"
|
||||||
|
import { ComboboxPositioner } from "./positioner"
|
||||||
|
import { ComboboxPopup } from "./popup"
|
||||||
|
import { ComboboxArrow } from "./arrow"
|
||||||
|
import { ComboboxIcon } from "./icon"
|
||||||
|
import { ComboboxGroup } from "./group"
|
||||||
|
import { ComboboxGroupLabel } from "./group-label"
|
||||||
|
import { ComboboxItem } from "./item"
|
||||||
|
import { ComboboxItemIndicator } from "./item-indicator"
|
||||||
|
import { ComboboxChips } from "./chips"
|
||||||
|
import { ComboboxChip } from "./chip"
|
||||||
|
import { ComboboxChipRemove } from "./chip-remove"
|
||||||
|
import { ComboboxRow } from "./row"
|
||||||
|
import { ComboboxCollection } from "./collection"
|
||||||
|
import { ComboboxEmpty } from "./empty"
|
||||||
|
import { ComboboxClear } from "./clear"
|
||||||
|
|
||||||
|
const ComboboxPrimitive = {
|
||||||
|
Root: ComboboxRoot,
|
||||||
|
Label: ComboboxLabel,
|
||||||
|
Value: ComboboxValue,
|
||||||
|
Input: ComboboxInput,
|
||||||
|
InputGroup: ComboboxInputGroup,
|
||||||
|
Trigger: ComboboxTrigger,
|
||||||
|
List: ComboboxList,
|
||||||
|
Portal: ComboboxPortal,
|
||||||
|
Backdrop: ComboboxBackdrop,
|
||||||
|
Positioner: ComboboxPositioner,
|
||||||
|
Popup: ComboboxPopup,
|
||||||
|
Arrow: ComboboxArrow,
|
||||||
|
Icon: ComboboxIcon,
|
||||||
|
Group: ComboboxGroup,
|
||||||
|
GroupLabel: ComboboxGroupLabel,
|
||||||
|
Item: ComboboxItem,
|
||||||
|
ItemIndicator: ComboboxItemIndicator,
|
||||||
|
Chips: ComboboxChips,
|
||||||
|
Chip: ComboboxChip,
|
||||||
|
ChipRemove: ComboboxChipRemove,
|
||||||
|
Row: ComboboxRow,
|
||||||
|
Collection: ComboboxCollection,
|
||||||
|
Empty: ComboboxEmpty,
|
||||||
|
Clear: ComboboxClear,
|
||||||
|
Separator: BaseCombobox.Separator,
|
||||||
|
Status: BaseCombobox.Status,
|
||||||
|
useFilter: BaseCombobox.useFilter,
|
||||||
|
useFilteredItems: BaseCombobox.useFilteredItems,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ComboboxPrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
ComboboxRoot as Combobox,
|
||||||
|
ComboboxRoot,
|
||||||
|
ComboboxLabel,
|
||||||
|
ComboboxValue,
|
||||||
|
ComboboxInput,
|
||||||
|
ComboboxInputGroup,
|
||||||
|
ComboboxTrigger,
|
||||||
|
ComboboxList,
|
||||||
|
ComboboxPortal,
|
||||||
|
ComboboxBackdrop,
|
||||||
|
ComboboxPositioner,
|
||||||
|
ComboboxPopup,
|
||||||
|
ComboboxArrow,
|
||||||
|
ComboboxIcon,
|
||||||
|
ComboboxGroup,
|
||||||
|
ComboboxGroupLabel,
|
||||||
|
ComboboxItem,
|
||||||
|
ComboboxItemIndicator,
|
||||||
|
ComboboxChips,
|
||||||
|
ComboboxChip,
|
||||||
|
ComboboxChipRemove,
|
||||||
|
ComboboxRow,
|
||||||
|
ComboboxCollection,
|
||||||
|
ComboboxEmpty,
|
||||||
|
ComboboxClear,
|
||||||
|
BaseCombobox,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { ComboboxRootProps } from "./root"
|
||||||
|
export type { ComboboxLabelProps } from "./label"
|
||||||
|
export type { ComboboxValueProps } from "./value"
|
||||||
|
export type { ComboboxInputProps } from "./input"
|
||||||
|
export type { ComboboxInputGroupProps } from "./input-group"
|
||||||
|
export type { ComboboxTriggerProps } from "./trigger"
|
||||||
|
export type { ComboboxListProps } from "./list"
|
||||||
|
export type { ComboboxPortalProps } from "./portal"
|
||||||
|
export type { ComboboxBackdropProps } from "./backdrop"
|
||||||
|
export type { ComboboxPositionerProps } from "./positioner"
|
||||||
|
export type { ComboboxPopupProps } from "./popup"
|
||||||
|
export type { ComboboxArrowProps } from "./arrow"
|
||||||
|
export type { ComboboxIconProps } from "./icon"
|
||||||
|
export type { ComboboxGroupProps } from "./group"
|
||||||
|
export type { ComboboxGroupLabelProps } from "./group-label"
|
||||||
|
export type { ComboboxItemProps } from "./item"
|
||||||
|
export type { ComboboxItemIndicatorProps } from "./item-indicator"
|
||||||
|
export type { ComboboxChipsProps } from "./chips"
|
||||||
|
export type { ComboboxChipProps } from "./chip"
|
||||||
|
export type { ComboboxChipRemoveProps } from "./chip-remove"
|
||||||
|
export type { ComboboxRowProps } from "./row"
|
||||||
|
export type { ComboboxCollectionProps } from "./collection"
|
||||||
|
export type { ComboboxEmptyProps } from "./empty"
|
||||||
|
export type { ComboboxClearProps } from "./clear"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxInputGroupProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.InputGroup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxInputGroup = BaseCombobox.InputGroup as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxInputGroup = React.forwardRef<HTMLElement, ComboboxInputGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxInputGroup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative h-8 w-56 border border-neutral-950 bg-white dark:bg-neutral-950 focus-within:outline-2 focus-within:outline-solid focus-within:-outline-offset-1 focus-within:outline-neutral-950 dark:focus-within:outline-white dark:border-white [&>input]:pr-10 has-[.combobox-clear]:[&>input]:pr-18",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxInputGroup.displayName = "ComboboxInputGroup"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxInputProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Input> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxInput = BaseCombobox.Input as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxInput = React.forwardRef<HTMLElement, ComboboxInputProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxInput
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"h-full w-full border-0 bg-white pl-2 dark:bg-neutral-950 text-sm any-pointer-coarse:text-base font-normal text-neutral-950 outline-none placeholder:text-neutral-500 dark:placeholder:text-neutral-400 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxInput.displayName = "ComboboxInput"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxItemIndicatorProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.ItemIndicator> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxItemIndicator = BaseCombobox.ItemIndicator as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxItemIndicator = React.forwardRef<HTMLElement, ComboboxItemIndicatorProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxItemIndicator
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"col-start-1",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxItemIndicator.displayName = "ComboboxItemIndicator"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxItemProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Item> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxItem = BaseCombobox.Item as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxItem = React.forwardRef<HTMLElement, ComboboxItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"grid cursor-default grid-cols-[1rem_1fr] items-center gap-2 p-2 text-sm leading-4 outline-none select-none data-highlighted:relative data-highlighted:z-0 data-highlighted:text-white data-highlighted:before:absolute data-highlighted:before:inset-0 data-highlighted:before:z-[-1] data-highlighted:before:bg-neutral-950 dark:data-highlighted:text-neutral-950 dark:data-highlighted:before:bg-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxItem.displayName = "ComboboxItem"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxLabelProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Label> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxLabel = BaseCombobox.Label as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxLabel = React.forwardRef<HTMLElement, ComboboxLabelProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxLabel
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"cursor-default text-sm leading-5 font-bold text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxLabel.displayName = "ComboboxLabel"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxListProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.List> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxList = BaseCombobox.List as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxList = React.forwardRef<HTMLElement, ComboboxListProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxList
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"max-h-[min(22.5rem,var(--available-height))] overflow-y-auto overscroll-contain py-1 scroll-py-1 outline-0 data-empty:p-0",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxList.displayName = "ComboboxList"
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxPopupProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Popup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxPopup = BaseCombobox.Popup as React.ElementType
|
||||||
|
const defaultComboboxPopupClassName =
|
||||||
|
"w-[var(--anchor-width)] max-w-[var(--available-width)] origin-[var(--transform-origin)] border border-neutral-950 bg-white text-neutral-950 shadow-[0.25rem_0.25rem_0_rgb(0_0_0_/_12%)] transition-[transform,opacity] duration-[350ms] ease-[cubic-bezier(0.22,1,0.36,1)] data-ending-style:duration-150 data-ending-style:ease-out data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0 dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none"
|
||||||
|
|
||||||
|
export const ComboboxPopup = React.forwardRef<HTMLElement, ComboboxPopupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxPopup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className ?? defaultComboboxPopupClassName)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxPopup.displayName = "ComboboxPopup"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxPortalProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Portal> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxPortal = BaseCombobox.Portal as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxPortal = React.forwardRef<HTMLElement, ComboboxPortalProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxPortal
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxPortal.displayName = "ComboboxPortal"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxPositionerProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Positioner> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxPositioner = BaseCombobox.Positioner as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxPositioner = React.forwardRef<HTMLElement, ComboboxPositionerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxPositioner
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"outline-none",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxPositioner.displayName = "ComboboxPositioner"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxRootProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxRoot = BaseCombobox.Root as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxRoot = React.forwardRef<HTMLElement, ComboboxRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxRoot.displayName = "ComboboxRoot"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxRowProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Row> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxRow = BaseCombobox.Row as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxRow = React.forwardRef<HTMLElement, ComboboxRowProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxRow
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"grid grid-cols-5",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxRow.displayName = "ComboboxRow"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxTriggerProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Trigger> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxTrigger = BaseCombobox.Trigger as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxTrigger = React.forwardRef<HTMLElement, ComboboxTriggerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-full w-6 items-center justify-center border-0 bg-transparent p-0 text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxTrigger.displayName = "ComboboxTrigger"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { Combobox as BaseCombobox } from "@base-ui/react/combobox"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ComboboxValueProps = React.ComponentPropsWithoutRef<typeof BaseCombobox.Value> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseComboboxValue = BaseCombobox.Value as React.ElementType
|
||||||
|
|
||||||
|
export const ComboboxValue = React.forwardRef<HTMLElement, ComboboxValueProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseComboboxValue
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"text-sm text-neutral-950 dark:text-white",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ComboboxValue.displayName = "ComboboxValue"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuArrowProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Arrow> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuArrow = BaseContextMenu.Arrow as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuArrow = React.forwardRef<HTMLElement, ContextMenuArrowProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuArrow
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center text-neutral-500 dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuArrow.displayName = "ContextMenuArrow"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuBackdropProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Backdrop> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuBackdrop = BaseContextMenu.Backdrop as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuBackdrop = React.forwardRef<HTMLElement, ContextMenuBackdropProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuBackdrop
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] transition-opacity data-ending-style:opacity-0 data-starting-style:opacity-0 dark:bg-black/50",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuBackdrop.displayName = "ContextMenuBackdrop"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuCheckboxItemIndicatorProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.CheckboxItemIndicator> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuCheckboxItemIndicator = BaseContextMenu.CheckboxItemIndicator as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuCheckboxItemIndicator = React.forwardRef<HTMLElement, ContextMenuCheckboxItemIndicatorProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuCheckboxItemIndicator
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center text-current",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuCheckboxItemIndicator.displayName = "ContextMenuCheckboxItemIndicator"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuCheckboxItemProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.CheckboxItem> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuCheckboxItem = BaseContextMenu.CheckboxItem as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuCheckboxItem = React.forwardRef<HTMLElement, ContextMenuCheckboxItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuCheckboxItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center gap-2 py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-white data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:bg-neutral-950 data-[highlighted]:before:content-[''] data-[disabled]:text-neutral-500 dark:data-[highlighted]:text-neutral-950 dark:data-[highlighted]:before:bg-white dark:data-[disabled]:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuCheckboxItem.displayName = "ContextMenuCheckboxItem"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuGroupLabelProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.GroupLabel> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuGroupLabel = BaseContextMenu.GroupLabel as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuGroupLabel = React.forwardRef<HTMLElement, ContextMenuGroupLabelProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuGroupLabel
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex min-h-8 items-center pr-6 pl-3 text-sm leading-none font-normal text-neutral-500 select-none outline-none dark:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuGroupLabel.displayName = "ContextMenuGroupLabel"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuGroupProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Group> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuGroup = BaseContextMenu.Group as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuGroup = React.forwardRef<HTMLElement, ContextMenuGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuGroup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuGroup.displayName = "ContextMenuGroup"
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { ContextMenuRoot } from "./root"
|
||||||
|
import { ContextMenuTrigger } from "./trigger"
|
||||||
|
import { ContextMenuBackdrop } from "./backdrop"
|
||||||
|
import { ContextMenuPortal } from "./portal"
|
||||||
|
import { ContextMenuPositioner } from "./positioner"
|
||||||
|
import { ContextMenuPopup } from "./popup"
|
||||||
|
import { ContextMenuArrow } from "./arrow"
|
||||||
|
import { ContextMenuGroup } from "./group"
|
||||||
|
import { ContextMenuGroupLabel } from "./group-label"
|
||||||
|
import { ContextMenuItem } from "./item"
|
||||||
|
import { ContextMenuCheckboxItem } from "./checkbox-item"
|
||||||
|
import { ContextMenuCheckboxItemIndicator } from "./checkbox-item-indicator"
|
||||||
|
import { ContextMenuLinkItem } from "./link-item"
|
||||||
|
import { ContextMenuRadioGroup } from "./radio-group"
|
||||||
|
import { ContextMenuRadioItem } from "./radio-item"
|
||||||
|
import { ContextMenuRadioItemIndicator } from "./radio-item-indicator"
|
||||||
|
import { ContextMenuSubmenuRoot } from "./submenu-root"
|
||||||
|
import { ContextMenuSubmenuTrigger } from "./submenu-trigger"
|
||||||
|
|
||||||
|
const ContextMenuPrimitive = {
|
||||||
|
Root: ContextMenuRoot,
|
||||||
|
Trigger: ContextMenuTrigger,
|
||||||
|
Backdrop: ContextMenuBackdrop,
|
||||||
|
Portal: ContextMenuPortal,
|
||||||
|
Positioner: ContextMenuPositioner,
|
||||||
|
Popup: ContextMenuPopup,
|
||||||
|
Arrow: ContextMenuArrow,
|
||||||
|
Group: ContextMenuGroup,
|
||||||
|
GroupLabel: ContextMenuGroupLabel,
|
||||||
|
Item: ContextMenuItem,
|
||||||
|
CheckboxItem: ContextMenuCheckboxItem,
|
||||||
|
CheckboxItemIndicator: ContextMenuCheckboxItemIndicator,
|
||||||
|
LinkItem: ContextMenuLinkItem,
|
||||||
|
RadioGroup: ContextMenuRadioGroup,
|
||||||
|
RadioItem: ContextMenuRadioItem,
|
||||||
|
RadioItemIndicator: ContextMenuRadioItemIndicator,
|
||||||
|
SubmenuRoot: ContextMenuSubmenuRoot,
|
||||||
|
SubmenuTrigger: ContextMenuSubmenuTrigger,
|
||||||
|
Separator: BaseContextMenu.Separator,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ContextMenuPrimitive
|
||||||
|
|
||||||
|
export {
|
||||||
|
ContextMenuRoot as ContextMenu,
|
||||||
|
ContextMenuRoot,
|
||||||
|
ContextMenuTrigger,
|
||||||
|
ContextMenuBackdrop,
|
||||||
|
ContextMenuPortal,
|
||||||
|
ContextMenuPositioner,
|
||||||
|
ContextMenuPopup,
|
||||||
|
ContextMenuArrow,
|
||||||
|
ContextMenuGroup,
|
||||||
|
ContextMenuGroupLabel,
|
||||||
|
ContextMenuItem,
|
||||||
|
ContextMenuCheckboxItem,
|
||||||
|
ContextMenuCheckboxItemIndicator,
|
||||||
|
ContextMenuLinkItem,
|
||||||
|
ContextMenuRadioGroup,
|
||||||
|
ContextMenuRadioItem,
|
||||||
|
ContextMenuRadioItemIndicator,
|
||||||
|
ContextMenuSubmenuRoot,
|
||||||
|
ContextMenuSubmenuTrigger,
|
||||||
|
BaseContextMenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { ContextMenuRootProps } from "./root"
|
||||||
|
export type { ContextMenuTriggerProps } from "./trigger"
|
||||||
|
export type { ContextMenuBackdropProps } from "./backdrop"
|
||||||
|
export type { ContextMenuPortalProps } from "./portal"
|
||||||
|
export type { ContextMenuPositionerProps } from "./positioner"
|
||||||
|
export type { ContextMenuPopupProps } from "./popup"
|
||||||
|
export type { ContextMenuArrowProps } from "./arrow"
|
||||||
|
export type { ContextMenuGroupProps } from "./group"
|
||||||
|
export type { ContextMenuGroupLabelProps } from "./group-label"
|
||||||
|
export type { ContextMenuItemProps } from "./item"
|
||||||
|
export type { ContextMenuCheckboxItemProps } from "./checkbox-item"
|
||||||
|
export type { ContextMenuCheckboxItemIndicatorProps } from "./checkbox-item-indicator"
|
||||||
|
export type { ContextMenuLinkItemProps } from "./link-item"
|
||||||
|
export type { ContextMenuRadioGroupProps } from "./radio-group"
|
||||||
|
export type { ContextMenuRadioItemProps } from "./radio-item"
|
||||||
|
export type { ContextMenuRadioItemIndicatorProps } from "./radio-item-indicator"
|
||||||
|
export type { ContextMenuSubmenuRootProps } from "./submenu-root"
|
||||||
|
export type { ContextMenuSubmenuTriggerProps } from "./submenu-trigger"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuItemProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Item> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuItem = BaseContextMenu.Item as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuItem = React.forwardRef<HTMLElement, ContextMenuItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-white data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:bg-neutral-950 data-[highlighted]:before:content-[''] data-[disabled]:text-neutral-500 dark:data-[highlighted]:text-neutral-950 dark:data-[highlighted]:before:bg-white dark:data-[disabled]:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuItem.displayName = "ContextMenuItem"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuLinkItemProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.LinkItem> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuLinkItem = BaseContextMenu.LinkItem as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuLinkItem = React.forwardRef<HTMLElement, ContextMenuLinkItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuLinkItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 text-inherit no-underline outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-white data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:bg-neutral-950 data-[highlighted]:before:content-[''] data-[disabled]:text-neutral-500 dark:data-[highlighted]:text-neutral-950 dark:data-[highlighted]:before:bg-white dark:data-[disabled]:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuLinkItem.displayName = "ContextMenuLinkItem"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuPopupProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Popup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuPopup = BaseContextMenu.Popup as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuPopup = React.forwardRef<HTMLElement, ContextMenuPopupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuPopup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"origin-[var(--transform-origin)] border border-neutral-950 bg-white py-1 text-neutral-950 shadow-[0.25rem_0.25rem_0_rgb(0_0_0_/_12%)] outline-none transition-[transform,opacity] duration-[350ms] ease-[cubic-bezier(0.22,1,0.36,1)] data-ending-style:duration-150 data-ending-style:ease-out data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuPopup.displayName = "ContextMenuPopup"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuPortalProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Portal> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuPortal = BaseContextMenu.Portal as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuPortal = React.forwardRef<HTMLElement, ContextMenuPortalProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuPortal
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuPortal.displayName = "ContextMenuPortal"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuPositionerProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Positioner> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuPositioner = BaseContextMenu.Positioner as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuPositioner = React.forwardRef<HTMLElement, ContextMenuPositionerProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuPositioner
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"outline-none",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuPositioner.displayName = "ContextMenuPositioner"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuRadioGroupProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.RadioGroup> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuRadioGroup = BaseContextMenu.RadioGroup as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuRadioGroup = React.forwardRef<HTMLElement, ContextMenuRadioGroupProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuRadioGroup
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuRadioGroup.displayName = "ContextMenuRadioGroup"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuRadioItemIndicatorProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.RadioItemIndicator> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuRadioItemIndicator = BaseContextMenu.RadioItemIndicator as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuRadioItemIndicator = React.forwardRef<HTMLElement, ContextMenuRadioItemIndicatorProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuRadioItemIndicator
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex size-4 shrink-0 items-center justify-center text-current",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuRadioItemIndicator.displayName = "ContextMenuRadioItemIndicator"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuRadioItemProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.RadioItem> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuRadioItem = BaseContextMenu.RadioItem as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuRadioItem = React.forwardRef<HTMLElement, ContextMenuRadioItemProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuRadioItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center gap-2 py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-white data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:bg-neutral-950 data-[highlighted]:before:content-[''] data-[disabled]:text-neutral-500 dark:data-[highlighted]:text-neutral-950 dark:data-[highlighted]:before:bg-white dark:data-[disabled]:text-neutral-400",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuRadioItem.displayName = "ContextMenuRadioItem"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuRootProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.Root> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuRoot = BaseContextMenu.Root as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuRoot = React.forwardRef<HTMLElement, ContextMenuRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuRoot.displayName = "ContextMenuRoot"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export type ContextMenuSubmenuRootProps = React.ComponentPropsWithoutRef<typeof BaseContextMenu.SubmenuRoot> & {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const BaseContextMenuSubmenuRoot = BaseContextMenu.SubmenuRoot as React.ElementType
|
||||||
|
|
||||||
|
export const ContextMenuSubmenuRoot = React.forwardRef<HTMLElement, ContextMenuSubmenuRootProps>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<BaseContextMenuSubmenuRoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
ContextMenuSubmenuRoot.displayName = "ContextMenuSubmenuRoot"
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user