@quarklab/rad-ui 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +111 -44
- package/package.json +3 -5
- package/templates/web/aspect-ratio.tsx +0 -5
- package/templates/web/avatar.tsx +0 -47
- package/templates/web/badge.tsx +0 -35
- package/templates/web/button.tsx +0 -54
- package/templates/web/checkbox.tsx +0 -34
- package/templates/web/field.tsx +0 -291
- package/templates/web/input/input.tsx +0 -454
- package/templates/web/input/validation.ts +0 -202
- package/templates/web/input-group.tsx +0 -209
- package/templates/web/input-otp.tsx +0 -85
- package/templates/web/kbd.tsx +0 -37
- package/templates/web/label.tsx +0 -23
- package/templates/web/lib/utils.ts +0 -7
- package/templates/web/native-select.tsx +0 -71
- package/templates/web/radio-group.tsx +0 -43
- package/templates/web/separator.tsx +0 -29
- package/templates/web/skeleton.tsx +0 -15
- package/templates/web/slider.tsx +0 -46
- package/templates/web/spinner.tsx +0 -44
- package/templates/web/switch.tsx +0 -32
- package/templates/web/textarea.tsx +0 -28
- package/templates/web/toggle-group.tsx +0 -58
- package/templates/web/toggle.tsx +0 -45
package/dist/index.js
CHANGED
|
@@ -743,7 +743,6 @@ function getInstallCommand(pm, packages) {
|
|
|
743
743
|
|
|
744
744
|
// src/commands/add.ts
|
|
745
745
|
import path4 from "path";
|
|
746
|
-
import { fileURLToPath } from "url";
|
|
747
746
|
import fs4 from "fs-extra";
|
|
748
747
|
import * as p2 from "@clack/prompts";
|
|
749
748
|
import chalk3 from "chalk";
|
|
@@ -813,9 +812,9 @@ var components = [
|
|
|
813
812
|
},
|
|
814
813
|
{
|
|
815
814
|
name: "input",
|
|
816
|
-
description: "A text input field with
|
|
815
|
+
description: "A text input field with validation, keyboard filtering, and file validation",
|
|
817
816
|
platform: "web",
|
|
818
|
-
files: ["input.tsx"],
|
|
817
|
+
files: ["input/input.tsx", "input/validation.ts"],
|
|
819
818
|
npmDependencies: {
|
|
820
819
|
"class-variance-authority": "^0.7.1",
|
|
821
820
|
"lucide-react": "^0.309.0"
|
|
@@ -1007,7 +1006,7 @@ function collectNpmDependencies(names) {
|
|
|
1007
1006
|
function transformImports(source, config) {
|
|
1008
1007
|
const utilsAlias = config.aliases.utils;
|
|
1009
1008
|
let result = source.replace(
|
|
1010
|
-
/from\s+["']
|
|
1009
|
+
/from\s+["'](?:\.\.\/)+lib\/utils["']/g,
|
|
1011
1010
|
`from "${utilsAlias}"`
|
|
1012
1011
|
);
|
|
1013
1012
|
result = result.replace(
|
|
@@ -1036,46 +1035,19 @@ async function fetchRegistryIndex(registryUrl) {
|
|
|
1036
1035
|
}
|
|
1037
1036
|
|
|
1038
1037
|
// src/commands/add.ts
|
|
1039
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
1040
|
-
var __dirname = path4.dirname(__filename);
|
|
1041
|
-
function getTemplatesDir() {
|
|
1042
|
-
return path4.resolve(__dirname, "..", "templates");
|
|
1043
|
-
}
|
|
1044
|
-
async function readBundledTemplate(name, platform) {
|
|
1045
|
-
const comp = getComponent(name);
|
|
1046
|
-
if (!comp) return null;
|
|
1047
|
-
const platformDir = platform === "mobile" ? "mobile" : "web";
|
|
1048
|
-
const templatesDir = getTemplatesDir();
|
|
1049
|
-
const sourceDir = path4.resolve(templatesDir, platformDir);
|
|
1050
|
-
const files = [];
|
|
1051
|
-
for (const file of comp.files) {
|
|
1052
|
-
const filePath = path4.resolve(sourceDir, file);
|
|
1053
|
-
if (await fs4.pathExists(filePath)) {
|
|
1054
|
-
const content = await fs4.readFile(filePath, "utf-8");
|
|
1055
|
-
files.push({ path: `ui/${file}`, type: "registry:ui", content });
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
const utilsPath = path4.resolve(sourceDir, "lib", "utils.ts");
|
|
1059
|
-
const utilsContent = await fs4.pathExists(utilsPath) ? await fs4.readFile(utilsPath, "utf-8") : void 0;
|
|
1060
|
-
return {
|
|
1061
|
-
name: comp.name,
|
|
1062
|
-
type: "registry:ui",
|
|
1063
|
-
description: comp.description,
|
|
1064
|
-
platform: comp.platform,
|
|
1065
|
-
dependencies: Object.keys(comp.npmDependencies),
|
|
1066
|
-
registryDependencies: comp.internalDependencies,
|
|
1067
|
-
files,
|
|
1068
|
-
utils: utilsContent ? { path: "lib/utils.ts", content: utilsContent } : void 0
|
|
1069
|
-
};
|
|
1070
|
-
}
|
|
1071
1038
|
async function getComponentContent(name, config) {
|
|
1072
|
-
if (config.registry) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1039
|
+
if (!config.registry) {
|
|
1040
|
+
throw new Error(
|
|
1041
|
+
"No registry URL configured. Run `rad-ui init` first."
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
try {
|
|
1045
|
+
return await fetchComponent(config.registry, name);
|
|
1046
|
+
} catch {
|
|
1047
|
+
throw new Error(
|
|
1048
|
+
`Failed to fetch component "${name}" from ${config.registry}. Is the registry available?`
|
|
1049
|
+
);
|
|
1077
1050
|
}
|
|
1078
|
-
return readBundledTemplate(name, config.platform);
|
|
1079
1051
|
}
|
|
1080
1052
|
async function addCommand(componentNames, opts) {
|
|
1081
1053
|
const cwd = process.cwd();
|
|
@@ -1188,8 +1160,8 @@ async function addCommand(componentNames, opts) {
|
|
|
1188
1160
|
for (const file of item.files) {
|
|
1189
1161
|
let content = file.content;
|
|
1190
1162
|
content = transformImports(content, config);
|
|
1191
|
-
const
|
|
1192
|
-
const destPath = path4.resolve(componentsDir,
|
|
1163
|
+
const relPath = file.path.replace(/^ui\//, "");
|
|
1164
|
+
const destPath = path4.resolve(componentsDir, relPath);
|
|
1193
1165
|
await fs4.ensureDir(path4.dirname(destPath));
|
|
1194
1166
|
await fs4.writeFile(destPath, content, "utf-8");
|
|
1195
1167
|
copiedCount++;
|
|
@@ -1254,6 +1226,100 @@ function getInstallCommand2(pm, packages) {
|
|
|
1254
1226
|
}
|
|
1255
1227
|
}
|
|
1256
1228
|
|
|
1229
|
+
// src/commands/build.ts
|
|
1230
|
+
import path5 from "path";
|
|
1231
|
+
import fs5 from "fs-extra";
|
|
1232
|
+
import * as p3 from "@clack/prompts";
|
|
1233
|
+
import chalk4 from "chalk";
|
|
1234
|
+
function parseDep(dep) {
|
|
1235
|
+
const atIndex = dep.lastIndexOf("@");
|
|
1236
|
+
if (atIndex > 0) {
|
|
1237
|
+
return {
|
|
1238
|
+
name: dep.slice(0, atIndex),
|
|
1239
|
+
version: dep.slice(atIndex + 1)
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
return { name: dep };
|
|
1243
|
+
}
|
|
1244
|
+
function getRelativePath(registryDir, filePath) {
|
|
1245
|
+
return filePath.replace(`${registryDir}/`, "");
|
|
1246
|
+
}
|
|
1247
|
+
async function buildCommand(registryPath, opts) {
|
|
1248
|
+
const cwd = opts.cwd ? path5.resolve(opts.cwd) : process.cwd();
|
|
1249
|
+
const registryJsonPath = path5.resolve(cwd, registryPath);
|
|
1250
|
+
const outputDir = path5.resolve(cwd, opts.output ?? "./public/r");
|
|
1251
|
+
p3.intro(chalk4.bold("Build Rad UI Registry"));
|
|
1252
|
+
if (!await fs5.pathExists(registryJsonPath)) {
|
|
1253
|
+
p3.log.error(
|
|
1254
|
+
`Registry file not found: ${chalk4.cyan(registryJsonPath)}`
|
|
1255
|
+
);
|
|
1256
|
+
p3.log.info(
|
|
1257
|
+
`Create a ${chalk4.cyan("registry.json")} file or specify a path: ${chalk4.gray("rad-ui build ./path/to/registry.json")}`
|
|
1258
|
+
);
|
|
1259
|
+
process.exit(1);
|
|
1260
|
+
}
|
|
1261
|
+
const s = p3.spinner();
|
|
1262
|
+
s.start("Reading registry.json...");
|
|
1263
|
+
const registry = await fs5.readJson(registryJsonPath);
|
|
1264
|
+
s.message(`Building ${registry.items.length} components...`);
|
|
1265
|
+
await fs5.ensureDir(outputDir);
|
|
1266
|
+
const utilsPath = path5.resolve(cwd, registry.registryDir, "lib", "utils.ts");
|
|
1267
|
+
const utilsContent = await fs5.pathExists(utilsPath) ? await fs5.readFile(utilsPath, "utf-8") : null;
|
|
1268
|
+
let built = 0;
|
|
1269
|
+
const warnings = [];
|
|
1270
|
+
for (const item of registry.items) {
|
|
1271
|
+
const files = [];
|
|
1272
|
+
for (const file of item.files) {
|
|
1273
|
+
const filePath = path5.resolve(cwd, file.path);
|
|
1274
|
+
if (!await fs5.pathExists(filePath)) {
|
|
1275
|
+
warnings.push(`${item.name}: ${file.path} not found, skipped`);
|
|
1276
|
+
continue;
|
|
1277
|
+
}
|
|
1278
|
+
const content = await fs5.readFile(filePath, "utf-8");
|
|
1279
|
+
files.push({
|
|
1280
|
+
path: getRelativePath(registry.registryDir, file.path),
|
|
1281
|
+
type: file.type,
|
|
1282
|
+
content
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
const depNames = item.dependencies.map((d) => parseDep(d).name);
|
|
1286
|
+
const registryItem = {
|
|
1287
|
+
name: item.name,
|
|
1288
|
+
type: item.type,
|
|
1289
|
+
description: item.description,
|
|
1290
|
+
platform: item.platform,
|
|
1291
|
+
dependencies: depNames,
|
|
1292
|
+
registryDependencies: item.registryDependencies,
|
|
1293
|
+
files,
|
|
1294
|
+
utils: utilsContent ? { path: "lib/utils.ts", content: utilsContent } : void 0
|
|
1295
|
+
};
|
|
1296
|
+
const outputPath = path5.resolve(outputDir, `${item.name}.json`);
|
|
1297
|
+
await fs5.writeFile(
|
|
1298
|
+
outputPath,
|
|
1299
|
+
JSON.stringify(registryItem, null, 2),
|
|
1300
|
+
"utf-8"
|
|
1301
|
+
);
|
|
1302
|
+
built++;
|
|
1303
|
+
}
|
|
1304
|
+
const index = registry.items.map((item) => ({
|
|
1305
|
+
name: item.name,
|
|
1306
|
+
description: item.description,
|
|
1307
|
+
platform: item.platform,
|
|
1308
|
+
dependencies: item.dependencies.map((d) => parseDep(d).name),
|
|
1309
|
+
registryDependencies: item.registryDependencies
|
|
1310
|
+
}));
|
|
1311
|
+
const indexPath = path5.resolve(outputDir, "index.json");
|
|
1312
|
+
await fs5.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
1313
|
+
s.stop(`Built ${built} components + index.json`);
|
|
1314
|
+
if (warnings.length > 0) {
|
|
1315
|
+
for (const w of warnings) {
|
|
1316
|
+
p3.log.warn(w);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
p3.log.info(`Output: ${chalk4.cyan(outputDir)}`);
|
|
1320
|
+
p3.outro("Registry built successfully!");
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1257
1323
|
// src/index.ts
|
|
1258
1324
|
var program = new Command();
|
|
1259
1325
|
program.name("rad-ui").description(
|
|
@@ -1261,4 +1327,5 @@ program.name("rad-ui").description(
|
|
|
1261
1327
|
).version("0.1.0");
|
|
1262
1328
|
program.command("init").description("Initialize Rad UI in your project").option("-y, --yes", "Skip confirmation prompts and use defaults").action(initCommand);
|
|
1263
1329
|
program.command("add").description("Add components to your project").argument("[components...]", "Components to add (space-separated)").option("-a, --all", "Add all available components").option("-o, --overwrite", "Overwrite existing components").option("-p, --path <path>", "Custom path for components").action(addCommand);
|
|
1330
|
+
program.command("build").description("Build registry JSON from registry.json").argument("[registry]", "Path to registry.json", "./registry.json").option("-o, --output <dir>", "Output directory", "./public/r").option("--cwd <path>", "Working directory").action(buildCommand);
|
|
1264
1331
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quarklab/rad-ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "A CLI for adding Rad UI components to your project. Beautiful Persian-themed React components built on Radix UI and Tailwind CSS.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -9,14 +9,12 @@
|
|
|
9
9
|
"rad-ui": "dist/index.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
|
-
"dist"
|
|
13
|
-
"templates"
|
|
12
|
+
"dist"
|
|
14
13
|
],
|
|
15
14
|
"scripts": {
|
|
16
|
-
"prebuild": "node scripts/sync-templates.js",
|
|
17
15
|
"build": "tsup",
|
|
18
16
|
"dev": "tsup --watch",
|
|
19
|
-
"clean": "rm -rf dist
|
|
17
|
+
"clean": "rm -rf dist"
|
|
20
18
|
},
|
|
21
19
|
"dependencies": {
|
|
22
20
|
"commander": "^12.1.0",
|
package/templates/web/avatar.tsx
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
3
|
-
import { cn } from "../lib/utils";
|
|
4
|
-
|
|
5
|
-
const Avatar = React.forwardRef<
|
|
6
|
-
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
7
|
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
8
|
-
>(({ className, ...props }, ref) => (
|
|
9
|
-
<AvatarPrimitive.Root
|
|
10
|
-
ref={ref}
|
|
11
|
-
className={cn(
|
|
12
|
-
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
13
|
-
className
|
|
14
|
-
)}
|
|
15
|
-
{...props}
|
|
16
|
-
/>
|
|
17
|
-
));
|
|
18
|
-
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
19
|
-
|
|
20
|
-
const AvatarImage = React.forwardRef<
|
|
21
|
-
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
22
|
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
23
|
-
>(({ className, ...props }, ref) => (
|
|
24
|
-
<AvatarPrimitive.Image
|
|
25
|
-
ref={ref}
|
|
26
|
-
className={cn("aspect-square h-full w-full", className)}
|
|
27
|
-
{...props}
|
|
28
|
-
/>
|
|
29
|
-
));
|
|
30
|
-
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
31
|
-
|
|
32
|
-
const AvatarFallback = React.forwardRef<
|
|
33
|
-
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
34
|
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
35
|
-
>(({ className, ...props }, ref) => (
|
|
36
|
-
<AvatarPrimitive.Fallback
|
|
37
|
-
ref={ref}
|
|
38
|
-
className={cn(
|
|
39
|
-
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
|
40
|
-
className
|
|
41
|
-
)}
|
|
42
|
-
{...props}
|
|
43
|
-
/>
|
|
44
|
-
));
|
|
45
|
-
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
46
|
-
|
|
47
|
-
export { Avatar, AvatarImage, AvatarFallback };
|
package/templates/web/badge.tsx
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { type VariantProps, cva } from "class-variance-authority";
|
|
3
|
-
import { cn } from "../lib/utils";
|
|
4
|
-
|
|
5
|
-
const badgeVariants = cva(
|
|
6
|
-
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
7
|
-
{
|
|
8
|
-
variants: {
|
|
9
|
-
variant: {
|
|
10
|
-
default:
|
|
11
|
-
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
12
|
-
secondary:
|
|
13
|
-
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
14
|
-
destructive:
|
|
15
|
-
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
16
|
-
outline: "text-foreground",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
defaultVariants: {
|
|
20
|
-
variant: "default",
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
export interface BadgeProps
|
|
26
|
-
extends React.HTMLAttributes<HTMLDivElement>,
|
|
27
|
-
VariantProps<typeof badgeVariants> {}
|
|
28
|
-
|
|
29
|
-
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
30
|
-
return (
|
|
31
|
-
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { Badge, badgeVariants };
|
package/templates/web/button.tsx
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { type VariantProps, cva } from "class-variance-authority";
|
|
3
|
-
import { cn } from "../lib/utils";
|
|
4
|
-
|
|
5
|
-
const buttonVariants = cva(
|
|
6
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
7
|
-
{
|
|
8
|
-
variants: {
|
|
9
|
-
variant: {
|
|
10
|
-
default:
|
|
11
|
-
"bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80",
|
|
12
|
-
destructive:
|
|
13
|
-
"bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-destructive/80",
|
|
14
|
-
outline:
|
|
15
|
-
"border border-border bg-background hover:bg-muted hover:text-foreground active:bg-muted/80",
|
|
16
|
-
ghost:
|
|
17
|
-
"hover:bg-muted hover:text-foreground active:bg-muted/80",
|
|
18
|
-
link:
|
|
19
|
-
"text-primary underline-offset-4 hover:underline active:text-primary/80",
|
|
20
|
-
},
|
|
21
|
-
size: {
|
|
22
|
-
sm: "h-9 px-3 text-xs rounded-md",
|
|
23
|
-
md: "h-10 px-4 py-2",
|
|
24
|
-
lg: "h-11 px-8 text-base rounded-lg",
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
defaultVariants: {
|
|
28
|
-
variant: "default",
|
|
29
|
-
size: "md",
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
export interface ButtonProps
|
|
35
|
-
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
36
|
-
VariantProps<typeof buttonVariants> {
|
|
37
|
-
asChild?: boolean;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
41
|
-
({ className, variant, size, ...props }, ref) => {
|
|
42
|
-
return (
|
|
43
|
-
<button
|
|
44
|
-
className={cn(buttonVariants({ variant, size, className }))}
|
|
45
|
-
ref={ref}
|
|
46
|
-
{...props}
|
|
47
|
-
/>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
Button.displayName = "Button";
|
|
53
|
-
|
|
54
|
-
export { Button, buttonVariants };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
3
|
-
import { Check } from "lucide-react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
|
|
6
|
-
export interface CheckboxProps
|
|
7
|
-
extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {}
|
|
8
|
-
|
|
9
|
-
const Checkbox = React.forwardRef<
|
|
10
|
-
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
|
11
|
-
CheckboxProps
|
|
12
|
-
>(({ className, ...props }, ref) => (
|
|
13
|
-
<CheckboxPrimitive.Root
|
|
14
|
-
ref={ref}
|
|
15
|
-
className={cn(
|
|
16
|
-
"peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow transition-colors",
|
|
17
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
18
|
-
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
19
|
-
"data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
|
20
|
-
className
|
|
21
|
-
)}
|
|
22
|
-
{...props}
|
|
23
|
-
>
|
|
24
|
-
<CheckboxPrimitive.Indicator
|
|
25
|
-
className={cn("flex items-center justify-center text-current")}
|
|
26
|
-
>
|
|
27
|
-
<Check className="h-4 w-4" />
|
|
28
|
-
</CheckboxPrimitive.Indicator>
|
|
29
|
-
</CheckboxPrimitive.Root>
|
|
30
|
-
));
|
|
31
|
-
|
|
32
|
-
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
33
|
-
|
|
34
|
-
export { Checkbox };
|