From 197bf7c5735dfae618504a3f04d46b8d085f7231 Mon Sep 17 00:00:00 2001 From: DexterStorey Date: Wed, 2 Oct 2024 17:02:05 -0400 Subject: [PATCH] refactor to new biome --- .eslintrc.js | 4 - .prettierrc.js | 1 - .vscode/settings.json | 21 ++ CHANGELOG.md | 1 + bin/commands/init.js | 143 ++++++------ bin/config/globals.css | 32 +-- bin/config/rubric.preset.js | 51 +++-- bin/config/rubric.preset.ts | 53 +++-- bin/config/tailwind.config.js | 18 +- bin/config/tailwind.config.ts | 20 +- bin/execute.js | 14 +- biome.json | 3 + build.ts | 43 ++-- package.json | 47 ++-- postcss.config.js | 10 +- src/components/accordion.tsx | 103 +++++---- src/components/badge.tsx | 40 ++-- src/components/button.tsx | 64 +++--- src/components/calendar.tsx | 172 +++++++------- src/components/card.tsx | 137 +++++------- src/components/checkbox.tsx | 30 +-- src/components/codeblock.tsx | 191 ++++++++-------- src/components/context-menu.tsx | 383 ++++++++++++++++---------------- src/components/form.tsx | 268 +++++++++++----------- src/components/grid.tsx | 94 ++++---- src/components/image.tsx | 112 +++++----- src/components/input.tsx | 35 ++- src/components/label.tsx | 34 +-- src/components/link.tsx | 91 ++++---- src/components/loading.tsx | 49 ++-- src/components/markdown.tsx | 52 ++--- src/components/modal.tsx | 177 +++++++-------- src/components/nav.tsx | 185 +++++++-------- src/components/popover.tsx | 48 ++-- src/components/select.tsx | 211 +++++++++--------- src/components/stack.tsx | 50 ++--- src/components/switch.tsx | 20 +- src/components/textarea.tsx | 35 ++- src/components/toggle.tsx | 30 +-- src/components/tooltip.tsx | 56 ++--- src/components/upload.tsx | 261 +++++++++++----------- src/index.ts | 52 ++--- src/utils/cn.ts | 6 +- tsconfig.json | 42 ++-- 44 files changed, 1720 insertions(+), 1769 deletions(-) delete mode 100644 .eslintrc.js delete mode 100644 .prettierrc.js create mode 100644 .vscode/settings.json create mode 100644 biome.json diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index ee581e1..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - extends: ['@rubriclab/eslint-config'], - root: true -} diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 69791a2..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@rubriclab/prettier-config') diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6a581e6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "editor.formatOnType": true, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, + "[prisma]": { + "editor.defaultFormatter": "Prisma.prisma" + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index e96aadf..8d10c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- [2024-10-02] [refactor to new biome](https://github.com/RubricLab/ui/commit/8d2aeca6c0ae824b8bcf1f85a7bd1fecda84180e) - [2024-10-02] [Again again](https://github.com/RubricLab/ui/commit/ad0f01623966ed33b238a56e1726d89e3e1ed029) - [2024-10-02] [Bundle css](https://github.com/RubricLab/ui/commit/343655090d6f68bf065807a4552a655a5b660517) - [2024-10-02] [Bundle index.ts](https://github.com/RubricLab/ui/commit/1b141ca0383cd61cd0d481a3008f3b122cdb3544) diff --git a/bin/commands/init.js b/bin/commands/init.js index 65725e8..f047a15 100644 --- a/bin/commands/init.js +++ b/bin/commands/init.js @@ -1,115 +1,112 @@ -import { Command } from "commander"; -import prompts from "prompts"; -import { existsSync, promises as fs } from "node:fs"; -import { resolve, dirname, relative } from "node:path"; -import { fileURLToPath } from "node:url"; -import chalk from "chalk"; +import { Command } from 'commander' +import prompts from 'prompts' +import { existsSync, promises as fs } from 'node:fs' +import { resolve, dirname, relative } from 'node:path' +import { fileURLToPath } from 'node:url' +import chalk from 'chalk' -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) export const init = new Command() - .name("init") - .description("Initialize required configuration files") + .name('init') + .description('Initialize required configuration files') .action(async () => { const responses = await prompts([ { - type: "toggle", - name: "typescript", - message: "Are you using TypeScript?", + type: 'toggle', + name: 'typescript', + message: 'Are you using TypeScript?', initial: true, - active: "yes", - inactive: "no", + active: 'yes', + inactive: 'no' }, { - type: "text", - name: "tw_config_path", - message: "Enter the path where your tailwind config file is located", - initial: (prev) => - prev === true ? "./tailwind.config.ts" : "./tailwind.config.js", + type: 'text', + name: 'tw_config_path', + message: 'Enter the path where your tailwind config file is located', + initial: prev => (prev === true ? './tailwind.config.ts' : './tailwind.config.js') }, { - type: "toggle", - name: "overwrite_tw_config", - message: "Do you want to overwrite your existing tailwind config?", + type: 'toggle', + name: 'overwrite_tw_config', + message: 'Do you want to overwrite your existing tailwind config?', initial: false, - active: "yes", - inactive: "no", + active: 'yes', + inactive: 'no' }, { - type: "text", - name: "styles_path", - message: "Enter the path where your styles file is located", - initial: "./app/globals.css", - }, - ]); + type: 'text', + name: 'styles_path', + message: 'Enter the path where your styles file is located', + initial: './app/globals.css' + } + ]) - await executeConfig(responses); - }); + await executeConfig(responses) + }) async function executeConfig(responses) { - const fileEnc = "utf-8"; - const overwriteTWConfig = responses.overwrite_tw_config; - const extension = responses.typescript ? "ts" : "js"; - const configDir = resolve(__dirname, "../config"); - const presetSourcePath = resolve(configDir, `rubric.preset.${extension}`); - const tailwindConfigSourcePath = resolve( - configDir, - `tailwind.config.${extension}`, - ); - const stylesSourcePath = resolve(configDir, "globals.css"); + const fileEnc = 'utf-8' + const overwriteTWConfig = responses.overwrite_tw_config + const extension = responses.typescript ? 'ts' : 'js' + const configDir = resolve(__dirname, '../config') + const presetSourcePath = resolve(configDir, `rubric.preset.${extension}`) + const tailwindConfigSourcePath = resolve(configDir, `tailwind.config.${extension}`) + const stylesSourcePath = resolve(configDir, 'globals.css') - const tailwindConfigDestinationPath = resolve( - process.cwd(), - responses.tw_config_path, - ); + const tailwindConfigDestinationPath = resolve(process.cwd(), responses.tw_config_path) const presetDestinationPath = resolve( dirname(tailwindConfigDestinationPath), - `rubric.preset.${extension}`, - ); - const stylesDestinationPath = resolve(process.cwd(), responses.styles_path); + `rubric.preset.${extension}` + ) + const stylesDestinationPath = resolve(process.cwd(), responses.styles_path) if (existsSync(presetSourcePath)) { - const presetConfig = await fs.readFile(presetSourcePath, fileEnc); - await fs.writeFile(presetDestinationPath, presetConfig, fileEnc); + const presetConfig = await fs.readFile(presetSourcePath, fileEnc) + await fs.writeFile(presetDestinationPath, presetConfig, fileEnc) console.log( - `Preset file written to ${chalk.green(relative(process.cwd(), presetDestinationPath))}`, - ); + `Preset file written to ${chalk.green(relative(process.cwd(), presetDestinationPath))}` + ) } else { - console.error(chalk.red("Preset file not found")); + console.error(chalk.red('Preset file not found')) } if (existsSync(stylesSourcePath)) { try { const [styleInsertion, userStyles] = await Promise.all([ fs.readFile(stylesSourcePath, fileEnc), - fs.readFile(stylesDestinationPath, fileEnc), - ]); - const insertionPoint = "@tailwind utilities;"; - const index = userStyles.indexOf(insertionPoint) + insertionPoint.length; - const updatedStyles = `${userStyles.slice(0, index)}\n\n${styleInsertion}${userStyles.slice(index)}`; - await fs.writeFile(stylesDestinationPath, updatedStyles, fileEnc); + fs.readFile(stylesDestinationPath, fileEnc) + ]) + const insertionPoint = '@tailwind utilities;' + const index = userStyles.indexOf(insertionPoint) + insertionPoint.length + const updatedStyles = `${userStyles.slice(0, index)}\n\n${styleInsertion}${userStyles.slice(index)}` + await fs.writeFile(stylesDestinationPath, updatedStyles, fileEnc) console.log( - `Styles file written to ${chalk.green(relative(process.cwd(), stylesDestinationPath))}`, - ); + `Styles file written to ${chalk.green(relative(process.cwd(), stylesDestinationPath))}` + ) } catch (error) { console.error( chalk.red( - "Failed to write to styles file. Ensure the path is correct and the file is writable.", - ), - ); + 'Failed to write to styles file. Ensure the path is correct and the file is writable.' + ) + ) } } if (!overwriteTWConfig) { - const presetPrompt = `${chalk.green("+")} ${chalk.dim("presets: [")}${chalk.blue(`require("./rubric.preset.${extension}")`)}${chalk.dim("],")}`; - const contentPrompt = `${chalk.green("+")} ${chalk.dim("content: [")}${chalk.blue(`"./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}"`)}${chalk.dim("],")}`; - console.log(`\nManual changes required to ${chalk.bold(`tailwind.config.${extension}`)}:\n${presetPrompt}\n${contentPrompt}`); + const presetPrompt = `${chalk.green('+')} ${chalk.dim('presets: [')}${chalk.blue(`require("./rubric.preset.${extension}")`)}${chalk.dim('],')}` + const contentPrompt = `${chalk.green('+')} ${chalk.dim('content: [')}${chalk.blue(`"./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}"`)}${chalk.dim('],')}` + console.log( + `\nManual changes required to ${chalk.bold(`tailwind.config.${extension}`)}:\n${presetPrompt}\n${contentPrompt}` + ) } else if (existsSync(tailwindConfigSourcePath)) { - const tailwindConfig = await fs.readFile(tailwindConfigSourcePath, fileEnc); - await fs.writeFile(tailwindConfigDestinationPath, tailwindConfig, fileEnc); - console.log(`Tailwind config file written to ${chalk.green(relative(process.cwd(), tailwindConfigDestinationPath))}`); + const tailwindConfig = await fs.readFile(tailwindConfigSourcePath, fileEnc) + await fs.writeFile(tailwindConfigDestinationPath, tailwindConfig, fileEnc) + console.log( + `Tailwind config file written to ${chalk.green(relative(process.cwd(), tailwindConfigDestinationPath))}` + ) } else { - console.error(chalk.red("Tailwind config file not found")); + console.error(chalk.red('Tailwind config file not found')) } } diff --git a/bin/config/globals.css b/bin/config/globals.css index d082c6b..53c8f52 100644 --- a/bin/config/globals.css +++ b/bin/config/globals.css @@ -1,21 +1,21 @@ @layer base { - :root { - --rubricui-primary: 252 252 252; - --rubricui-contrast: 5 5 5; - } + :root { + --rubricui-primary: 252 252 252; + --rubricui-contrast: 5 5 5; + } - .dark { - --rubricui-primary: 5 5 5; - --rubricui-contrast: 252 252 252; - } + .dark { + --rubricui-primary: 5 5 5; + --rubricui-contrast: 252 252 252; + } } @layer base { - body { - @apply bg-rubricui-primary text-rubricui-contrast; - font-feature-settings: "rlig" 1, "calt" 1; - } - button:hover { - text-shadow: 0px 0px 10px rgb(var(--rubricui-primary)); - } -} \ No newline at end of file + body { + @apply bg-rubricui-primary text-rubricui-contrast; + font-feature-settings: "rlig" 1, "calt" 1; + } + button:hover { + text-shadow: 0px 0px 10px rgb(var(--rubricui-primary)); + } +} diff --git a/bin/config/rubric.preset.js b/bin/config/rubric.preset.js index 0f4ce0b..11cc3ef 100644 --- a/bin/config/rubric.preset.js +++ b/bin/config/rubric.preset.js @@ -1,40 +1,39 @@ const rubricConfig = { - content: ["./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}"], + content: ['./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}'], theme: { extend: { colors: { - "rubricui-primary": "rgb(var(--rubricui-primary) / )", - "rubricui-contrast": "rgb(var(--rubricui-contrast) / )", + 'rubricui-primary': 'rgb(var(--rubricui-primary) / )', + 'rubricui-contrast': 'rgb(var(--rubricui-contrast) / )' }, transitionDuration: { - "rubricui-duration": "300ms", + 'rubricui-duration': '300ms' }, keyframes: { - "rubricui-loading-rotate": { - "0%": { transform: "rotate(0deg)" }, - "25%": { transform: "rotate(90deg)" }, - "50%": { transform: "rotate(180deg)" }, - "75%": { transform: "rotate(270deg)" }, - "100%": { transform: "rotate(360deg)" }, + 'rubricui-loading-rotate': { + '0%': { transform: 'rotate(0deg)' }, + '25%': { transform: 'rotate(90deg)' }, + '50%': { transform: 'rotate(180deg)' }, + '75%': { transform: 'rotate(270deg)' }, + '100%': { transform: 'rotate(360deg)' } }, - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, + 'accordion-down': { + from: { height: '0' }, + to: { height: 'var(--radix-accordion-content-height)' } }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: '0' } + } }, animation: { - "rubricui-loading-rotate": - "rubricui-loading-rotate 1s steps(1) infinite", - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, + 'rubricui-loading-rotate': 'rubricui-loading-rotate 1s steps(1) infinite', + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out' + } + } }, - plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")], -}; + plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')] +} -export default rubricConfig; +export default rubricConfig diff --git a/bin/config/rubric.preset.ts b/bin/config/rubric.preset.ts index 09fa462..35e726c 100644 --- a/bin/config/rubric.preset.ts +++ b/bin/config/rubric.preset.ts @@ -1,42 +1,41 @@ -import type { Config } from "tailwindcss"; +import type { Config } from 'tailwindcss' const rubricConfig = { - content: ["./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}"], + content: ['./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}'], theme: { extend: { colors: { - "rubricui-primary": "rgb(var(--rubricui-primary) / )", - "rubricui-contrast": "rgb(var(--rubricui-contrast) / )", + 'rubricui-primary': 'rgb(var(--rubricui-primary) / )', + 'rubricui-contrast': 'rgb(var(--rubricui-contrast) / )' }, transitionDuration: { - "rubricui-duration": "300ms", + 'rubricui-duration': '300ms' }, keyframes: { - "rubricui-loading-rotate": { - "0%": { transform: "rotate(0deg)" }, - "25%": { transform: "rotate(90deg)" }, - "50%": { transform: "rotate(180deg)" }, - "75%": { transform: "rotate(270deg)" }, - "100%": { transform: "rotate(360deg)" }, + 'rubricui-loading-rotate': { + '0%': { transform: 'rotate(0deg)' }, + '25%': { transform: 'rotate(90deg)' }, + '50%': { transform: 'rotate(180deg)' }, + '75%': { transform: 'rotate(270deg)' }, + '100%': { transform: 'rotate(360deg)' } }, - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, + 'accordion-down': { + from: { height: '0' }, + to: { height: 'var(--radix-accordion-content-height)' } }, + 'accordion-up': { + from: { height: 'var(--radix-accordion-content-height)' }, + to: { height: '0' } + } }, animation: { - "rubricui-loading-rotate": - "rubricui-loading-rotate 1s steps(1) infinite", - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, + 'rubricui-loading-rotate': 'rubricui-loading-rotate 1s steps(1) infinite', + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out' + } + } }, - plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")], -} satisfies Config; + plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')] +} satisfies Config -export default rubricConfig; +export default rubricConfig diff --git a/bin/config/tailwind.config.js b/bin/config/tailwind.config.js index e757f80..f7c1646 100644 --- a/bin/config/tailwind.config.js +++ b/bin/config/tailwind.config.js @@ -1,15 +1,15 @@ /** @type {import('tailwindcss').Config} */ const tailwindConfig = { - darkMode: "class", + darkMode: 'class', content: [ - "./app/**/*.tsx", - "./src/**/*.tsx", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}" + './app/**/*.tsx', + './src/**/*.tsx', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}' ], - presets: [require("./rubric.preset.js")], -}; + presets: [require('./rubric.preset.js')] +} -export default tailwindConfig; +export default tailwindConfig diff --git a/bin/config/tailwind.config.ts b/bin/config/tailwind.config.ts index ac68850..facf805 100644 --- a/bin/config/tailwind.config.ts +++ b/bin/config/tailwind.config.ts @@ -1,15 +1,15 @@ -import type { Config } from "tailwindcss"; +import type { Config } from 'tailwindcss' const tailwindConfig = { - darkMode: "class", + darkMode: 'class', content: [ - "./app/**/*.tsx", - "./src/**/*.tsx", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}" + './app/**/*.tsx', + './src/**/*.tsx', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './node_modules/rubricui/dist/**/*.{js,jsx,ts,tsx}' ], - presets: [require("./rubric.preset.ts")], -} satisfies Config; + presets: [require('./rubric.preset.ts')] +} satisfies Config -export default tailwindConfig; +export default tailwindConfig diff --git a/bin/execute.js b/bin/execute.js index 55d85a9..16f965b 100755 --- a/bin/execute.js +++ b/bin/execute.js @@ -1,15 +1,15 @@ #!/usr/bin/env node -import { Command } from "commander"; -import { init } from "./commands/init.js"; +import { Command } from 'commander' +import { init } from './commands/init.js' async function main() { const program = new Command() - .name("rubricui") - .description("Fully customizable ui components for any aesthetic ✨"); - program.addCommand(init); + .name('rubricui') + .description('Fully customizable ui components for any aesthetic ✨') + program.addCommand(init) - program.parse(); + program.parse() } -main(); +main() diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..e8d99dd --- /dev/null +++ b/biome.json @@ -0,0 +1,3 @@ +{ + "extends": ["@rubriclab/config/biome"] +} diff --git a/build.ts b/build.ts index 8478a56..bf49013 100644 --- a/build.ts +++ b/build.ts @@ -1,33 +1,32 @@ -import { rm, rename, readdir } from "node:fs/promises"; -import path from "node:path"; +import { rm, rename, readdir } from 'node:fs/promises' +import path from 'node:path' -const outdir = "./dist"; +const outdir = './dist' // Clean dist directory before building await rm(outdir, { - recursive: true, - force: true, -}); + recursive: true, + force: true +}) try { - - // Run build - await Bun.build({ - entrypoints: ["./src/index.ts"], - outdir, - minify: true, - external: ["react", "react-dom"], - }); + // Run build + await Bun.build({ + entrypoints: ['./src/index.ts'], + outdir, + minify: true, + external: ['react', 'react-dom'] + }) } catch (error) { - console.error(error); - process.exit(1); + console.error(error) + process.exit(1) } // Rename the generated CSS file to index.css -const files = await readdir(outdir); -const cssFile = files.find((file) => file.endsWith(".css")); +const files = await readdir(outdir) +const cssFile = files.find(file => file.endsWith('.css')) if (cssFile) { - const oldPath = path.join(outdir, cssFile); - const newPath = path.join(outdir, "index.css"); - await rename(oldPath, newPath); -} \ No newline at end of file + const oldPath = path.join(outdir, cssFile) + const newPath = path.join(outdir, 'index.css') + await rename(oldPath, newPath) +} diff --git a/package.json b/package.json index e6ea9b2..23609d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rubriclab/ui", - "version": "5.0.9", + "version": "5.0.10", "main": "dist/index.js", "types": "src/index.ts", "description": "UI package by Rubric Labs", @@ -9,12 +9,12 @@ "build": "NODE_ENV=production bun run build.ts", "tailwind": "bun x tailwindcss -i ./src/styles.css -o ./dist/output.css", "watch": "bun run build --watch", - "clean": "rm -rf .next && rm -rf node_modules", + "prepare": "bun x simple-git-hooks", "bleed": "bun x npm-check-updates -u && bun i", - "format": "prettier --write .", - "lint": "eslint .", - "lint:fix": "eslint . --fix", - "prepare": "bun x simple-git-hooks" + "format": "bun x biome format --write .", + "lint": "bun x biome check .", + "lint:fix": "bun x biome lint . --write --unsafe", + "clean": "rm -rf .next && rm -rf node_modules" }, "bin": { "rubricui": "./bin/execute.js" @@ -34,26 +34,23 @@ "bun", "genui" ], - "license": "MIT", + "license": "gonuts", "homepage": "https://github.com/RubricLab/ui#readme", "repository": { "type": "git", "url": "git+https://github.com/RubricLab/ui.git" }, "bugs": "https://github.com/RubricLab/ui/issues", - "author": "Rubric Labs ", "module": "src/index.ts", "devDependencies": { - "@rubriclab/eslint-config": "^1.1.4", - "@rubriclab/prettier-config": "^1.1.1", + "@rubriclab/config": "*", "@types/bun": "latest", - "@types/react": "^18.3.3", + "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "autoprefixer": "^10.4.20", - "npm-check-updates": "^17.1.1", - "postcss": "^8.4.45", - "tailwindcss": "^3.4.10", - "typescript": "^5.5.4" + "postcss": "^8.4.47", + "tailwindcss": "^3.4.13", + "typescript": "^5.6.2" }, "peerDependencies": { "typescript": "^5.2.2", @@ -63,29 +60,29 @@ "type": "module", "dependencies": { "@hookform/resolvers": "^3.9.0", - "@radix-ui/react-accordion": "^1.2.0", - "@radix-ui/react-checkbox": "^1.1.1", - "@radix-ui/react-context-menu": "^2.2.1", - "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-accordion": "^1.2.1", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-context-menu": "^2.2.2", + "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-popover": "^1.1.1", - "@radix-ui/react-select": "^2.1.1", + "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-switch": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-toggle": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.3", "@rubriclab/package": "latest", "@tailwindcss/typography": "^0.5.15", "@types/react-grid-layout": "^1.3.5", "chalk": "^5.3.0", "clsx": "^2.1.1", "commander": "^12.1.0", - "date-fns": "^3.6.0", + "date-fns": "^4.1.0", "markdown-to-jsx": "^7.5.0", "prism-react-renderer": "^2.4.0", "prismjs": "^1.29.0", "prompts": "^2.4.2", - "react-day-picker": "^9.0.8", + "react-day-picker": "^9.1.3", "react-grid-layout": "^1.4.4", "react-hook-form": "^7.53.0", "tailwind-merge": "^2.5.2", diff --git a/postcss.config.js b/postcss.config.js index 12a703d..941cff2 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +} diff --git a/src/components/accordion.tsx b/src/components/accordion.tsx index 2cce454..1f0b7bb 100644 --- a/src/components/accordion.tsx +++ b/src/components/accordion.tsx @@ -1,57 +1,70 @@ -"use client" +"use client"; -import { forwardRef } from "react" -import * as AccordionPrimitive from "@radix-ui/react-accordion" +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { forwardRef } from "react"; -import { cn } from "../utils/cn" +import { cn } from "../utils/cn"; -const Accordion = AccordionPrimitive.Root +const Accordion = AccordionPrimitive.Root; const AccordionItem = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - -)) -AccordionItem.displayName = "AccordionItem" + +)); +AccordionItem.displayName = "AccordionItem"; const AccordionTrigger = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - svg]:rotate-180", - className - )} - {...props} - > - {children} - - - -)) -AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + + svg]:rotate-180", + className, + )} + {...props} + > + {children} + + Accordion Icon + + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; const AccordionContent = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - -
{children}
-
-)) - -AccordionContent.displayName = AccordionPrimitive.Content.displayName - -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } + +
{children}
+
+)); + +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/src/components/badge.tsx b/src/components/badge.tsx index 63bb75a..d4268de 100644 --- a/src/components/badge.tsx +++ b/src/components/badge.tsx @@ -1,28 +1,28 @@ -import { type HTMLAttributes } from "react"; -import { cn } from "../utils/cn"; +import type { HTMLAttributes } from 'react' +import { cn } from '../utils/cn' const variants = { - primary: "bg-rubricui-contrast text-rubricui-primary", - secondary: "bg-rubricui-primary text-rubricui-contrast", - destructive: "bg-red-500 text-white border-red-600", - outline: "border-rubricui-primary text-rubricui-primary", -}; + primary: 'bg-rubricui-contrast text-rubricui-primary', + secondary: 'bg-rubricui-primary text-rubricui-contrast', + destructive: 'bg-red-500 text-white border-red-600', + outline: 'border-rubricui-primary text-rubricui-primary' +} export interface BadgeProps extends HTMLAttributes { - variant?: keyof typeof variants; + variant?: keyof typeof variants } -function Badge({ className, variant = "primary", ...props }: BadgeProps) { - return ( -
- ); +function Badge({ className, variant = 'primary', ...props }: BadgeProps) { + return ( +
+ ) } -export { Badge }; +export { Badge } diff --git a/src/components/button.tsx b/src/components/button.tsx index 07aa542..a7bba46 100644 --- a/src/components/button.tsx +++ b/src/components/button.tsx @@ -1,60 +1,60 @@ -"use client"; +'use client' -import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from "react"; -import { cn } from "../utils/cn"; -import { Loading } from "./loading"; +import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react' +import { cn } from '../utils/cn' +import { Loading } from './loading' const variants = { - primary: "bg-rubricui-contrast text-rubricui-primary border-rubricui-primary", - secondary: "bg-rubricui-primary text-rubricui-contrast border-rubricui-contrast ", -}; + primary: 'bg-rubricui-contrast text-rubricui-primary border-rubricui-primary', + secondary: 'bg-rubricui-primary text-rubricui-contrast border-rubricui-contrast ' +} const sizes = { - small: "rounded-[2px] min-h-[20px] px-[6px] py-[3px] text-xs min-w-[66px]", - medium: "rounded-[3px] min-h-[28px] px-[8px] py-[4px] text-sm min-w-[80px]", - large: "rounded-[4px] min-h-[36px] px-[14px] py-[6px] text-base min-w-[115px]", -}; + small: 'rounded-[2px] min-h-[20px] px-[6px] py-[3px] text-xs min-w-[66px]', + medium: 'rounded-[3px] min-h-[28px] px-[8px] py-[4px] text-sm min-w-[80px]', + large: 'rounded-[4px] min-h-[36px] px-[14px] py-[6px] text-base min-w-[115px]' +} const states = { - default: "cursor-pointer", - loading: "cursor-wait", -}; + default: 'cursor-pointer', + loading: 'cursor-wait' +} interface ButtonProps extends ButtonHTMLAttributes { - className?: string; - variant?: keyof typeof variants; - size?: keyof typeof sizes; - state?: keyof typeof states; - prefix_icon?: ReactNode; - suffix_icon?: ReactNode; + className?: string + variant?: keyof typeof variants + size?: keyof typeof sizes + state?: keyof typeof states + prefix_icon?: ReactNode + suffix_icon?: ReactNode } const Button = forwardRef( ( { className, - variant = "primary", - size = "medium", - state = "default", + variant = 'primary', + size = 'medium', + state = 'default', prefix_icon, suffix_icon, ...props }, - ref, + ref ) => { return ( - ); - }, -); + ) + } +) -Button.displayName = "Button"; +Button.displayName = 'Button' -export { Button }; +export { Button } diff --git a/src/components/calendar.tsx b/src/components/calendar.tsx index 1bd4b55..ef5b2cd 100644 --- a/src/components/calendar.tsx +++ b/src/components/calendar.tsx @@ -1,95 +1,89 @@ -"use client"; +'use client' -import { type ComponentProps } from "react"; -import { DayPicker } from "react-day-picker"; +import type { ComponentProps } from 'react' +import { DayPicker } from 'react-day-picker' -import { cn } from "../utils/cn"; +import { cn } from '../utils/cn' -export type CalendarProps = ComponentProps; +export type CalendarProps = ComponentProps -function Calendar({ - className, - classNames, - showOutsideDays = true, - ...props -}: CalendarProps) { - const mode = props.mode ?? "single"; - return ( - { - if (props.orientation === "left") { - return ( - - - - ); - } else { - return ( - - - - ); - } - }, - }} - {...props} - /> - ); +function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { + const mode = props.mode ?? 'single' + return ( + { + if (props.orientation === 'left') { + return ( + + Chevron Left + + + ) + } + return ( + + Chevron Right + + + ) + } + }} + {...props} + /> + ) } -Calendar.displayName = "Calendar"; +Calendar.displayName = 'Calendar' -export { Calendar }; +export { Calendar } diff --git a/src/components/card.tsx b/src/components/card.tsx index bd3a317..b240d6b 100644 --- a/src/components/card.tsx +++ b/src/components/card.tsx @@ -1,92 +1,69 @@ -import { forwardRef } from "react"; +import { forwardRef } from 'react' -import { cn } from "../utils/cn"; +import { cn } from '../utils/cn' const Card = forwardRef< - HTMLDivElement, - React.HTMLAttributes & { - shadow?: boolean; - hoverable?: boolean; - } + HTMLDivElement, + React.HTMLAttributes & { + shadow?: boolean + hoverable?: boolean + } >(({ className, shadow = true, hoverable = true, ...props }, ref) => ( -
-)); -Card.displayName = "Card"; +
+)) +Card.displayName = 'Card' -const CardHeader = forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)); -CardHeader.displayName = "CardHeader"; +const CardHeader = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +) +CardHeader.displayName = 'CardHeader' -const CardTitle = forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -

-)); -CardTitle.displayName = "CardTitle"; +const CardTitle = forwardRef>( + ({ className, ...props }, ref) => ( +

+ ) +) +CardTitle.displayName = 'CardTitle' const CardDescription = forwardRef< - HTMLParagraphElement, - React.HTMLAttributes + HTMLParagraphElement, + React.HTMLAttributes >(({ className, ...props }, ref) => ( -

-)); -CardDescription.displayName = "CardDescription"; +

+)) +CardDescription.displayName = 'CardDescription' -const CardContent = forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -

-)); -CardContent.displayName = "CardContent"; +const CardContent = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +) +CardContent.displayName = 'CardContent' -const CardFooter = forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)); -CardFooter.displayName = "CardFooter"; +const CardFooter = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +) +CardFooter.displayName = 'CardFooter' -export { - Card, - CardHeader, - CardFooter, - CardTitle, - CardDescription, - CardContent, -}; +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/src/components/checkbox.tsx b/src/components/checkbox.tsx index e4f7538..6b57751 100644 --- a/src/components/checkbox.tsx +++ b/src/components/checkbox.tsx @@ -1,8 +1,8 @@ -"use client"; +'use client' -import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; -import clsx from "clsx"; -import { forwardRef } from "react"; +import * as CheckboxPrimitive from '@radix-ui/react-checkbox' +import clsx from 'clsx' +import { forwardRef } from 'react' const Checkbox = forwardRef< React.ElementRef, @@ -11,23 +11,15 @@ const Checkbox = forwardRef< - + Checkbox -)); -Checkbox.displayName = "Checkbox"; +)) +Checkbox.displayName = 'Checkbox' -export { Checkbox }; +export { Checkbox } diff --git a/src/components/codeblock.tsx b/src/components/codeblock.tsx index f3c6a79..b265e05 100644 --- a/src/components/codeblock.tsx +++ b/src/components/codeblock.tsx @@ -1,109 +1,116 @@ "use client"; -import { useState } from "react"; -import { Highlight, themes, type PrismTheme } from "prism-react-renderer"; +import { Highlight, type PrismTheme, themes } from "prism-react-renderer"; import Prism from "prismjs"; +import { useState } from "react"; import { cn } from "../utils/cn"; - (typeof global !== "undefined" ? global : window).Prism = Prism; require("prismjs/components/prism-python"); require("prismjs/components/prism-javascript"); require("prismjs/components/prism-json"); const CodeBlock = ({ - language, - children, - fileName, - className, - headerClassName, - theme = themes.github, + language, + children, + fileName, + className, + headerClassName, + theme = themes.github, }: { - language: string; - children: string; - fileName?: string; - className?: string; - headerClassName?: string; - theme?: PrismTheme; + language: string; + children: string; + fileName?: string; + className?: string; + headerClassName?: string; + theme?: PrismTheme; }) => { - const [copied, setCopied] = useState(false); + const [copied, setCopied] = useState(false); - const copyToClipboard = () => { - navigator.clipboard.writeText(children); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - }; + const copyToClipboard = () => { + navigator.clipboard.writeText(children); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; - return ( -
- {fileName && ( -
- {fileName} - -
- )} - - {({ tokens, getLineProps, getTokenProps }) => ( -
-            
-              {tokens.map((line, i) => (
-                
- - {i + 1} - - - {line.map((token, key) => ( - - ))} - -
- ))} -
-
- )} -
-
- ); + return ( +
+ {fileName && ( +
+ {fileName} + +
+ )} + + {({ tokens, getLineProps, getTokenProps }) => ( +
+						
+							{tokens.map((line, i) => (
+								
+ + {i + 1} + + + {line.map((token, key) => ( + + ))} + +
+ ))} +
+
+ )} +
+
+ ); }; CodeBlock.displayName = "CodeBlock"; diff --git a/src/components/context-menu.tsx b/src/components/context-menu.tsx index f7d8e74..07e12d1 100644 --- a/src/components/context-menu.tsx +++ b/src/components/context-menu.tsx @@ -1,24 +1,24 @@ "use client"; -import { forwardRef } from "react"; import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"; +import { forwardRef } from "react"; import { cn } from "../utils/cn"; const ContextMenu = ContextMenuPrimitive.Root; const ContextMenuTrigger = ({ - children, - className, + children, + className, }: { - children: React.ReactNode; - className?: string; + children: React.ReactNode; + className?: string; }) => ( - - {children} - + + {children} + ); const ContextMenuGroup = ContextMenuPrimitive.Group; @@ -30,229 +30,232 @@ const ContextMenuSub = ContextMenuPrimitive.Sub; const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup; const ContextMenuSubTrigger = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } >(({ className, inset, children, ...props }, ref) => ( - - {children} - - - - + + {children} + + Chevron Right Icon + + + )); ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName; const ContextMenuSubContent = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName; const ContextMenuContent = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - - - + + + )); ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName; const ContextMenuItem = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - icon?: React.ReactNode; - destructive?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + icon?: React.ReactNode; + destructive?: boolean; + } >(({ className, inset, icon, children, destructive, ...props }, ref) => ( - - {icon && ( - - {icon} - - )} - {children} - + + {icon && ( + + {icon} + + )} + {children} + )); ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName; const ContextMenuCheckboxItem = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( - - - - - - - - - {children} - + + + + + Checkbox Item + + + + + {children} + )); ContextMenuCheckboxItem.displayName = - ContextMenuPrimitive.CheckboxItem.displayName; + ContextMenuPrimitive.CheckboxItem.displayName; const ContextMenuRadioItem = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - - - - - - - - - {children} - + + + + + Radio Item + + + + + {children} + )); ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName; const ContextMenuLabel = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } >(({ className, inset, ...props }, ref) => ( - + )); ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName; const ContextMenuSeparator = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName; const ContextMenuShortcut = ({ - className, - ...props + className, + ...props }: React.HTMLAttributes) => { - return ( - - ); + return ( + + ); }; ContextMenuShortcut.displayName = "ContextMenuShortcut"; export { - ContextMenu, - ContextMenuTrigger, - ContextMenuContent, - ContextMenuItem, - ContextMenuCheckboxItem, - ContextMenuRadioItem, - ContextMenuLabel, - ContextMenuSeparator, - ContextMenuShortcut, - ContextMenuGroup, - ContextMenuPortal, - ContextMenuSub, - ContextMenuSubContent, - ContextMenuSubTrigger, - ContextMenuRadioGroup, + ContextMenu, + ContextMenuTrigger, + ContextMenuContent, + ContextMenuItem, + ContextMenuCheckboxItem, + ContextMenuRadioItem, + ContextMenuLabel, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuGroup, + ContextMenuPortal, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuRadioGroup, }; diff --git a/src/components/form.tsx b/src/components/form.tsx index aff73bf..897ceb4 100644 --- a/src/components/form.tsx +++ b/src/components/form.tsx @@ -1,178 +1,168 @@ -"use client" +'use client' -import {forwardRef, createContext, useContext, useId} from "react" -import * as LabelPrimitive from "@radix-ui/react-label" -import { Slot } from "@radix-ui/react-slot" +import { forwardRef, createContext, useContext, useId } from 'react' +import type * as LabelPrimitive from '@radix-ui/react-label' +import { Slot } from '@radix-ui/react-slot' import { - Controller, - type ControllerProps, - type FieldPath, - type FieldValues, - FormProvider, - useFormContext, -} from "react-hook-form" + Controller, + type ControllerProps, + type FieldPath, + type FieldValues, + FormProvider, + useFormContext +} from 'react-hook-form' -import { cn } from "../utils/cn" -import { Label } from "./label" +import { cn } from '../utils/cn' +import { Label } from './label' const Form = FormProvider type FormFieldContextValue< - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath > = { - name: TName + name: TName } -const FormFieldContext = createContext( - {} as FormFieldContextValue -) +const FormFieldContext = createContext({} as FormFieldContextValue) const FormField = < - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath >({ - ...props + ...props }: ControllerProps) => { - return ( - - - - ) + return ( + + + + ) } const useFormField = () => { - const fieldContext = useContext(FormFieldContext) - const itemContext = useContext(FormItemContext) - const { getFieldState, formState } = useFormContext() - - const fieldState = getFieldState(fieldContext.name, formState) - - if (!fieldContext) { - throw new Error("useFormField should be used within ") - } - - const { id } = itemContext - - return { - id, - name: fieldContext.name, - formItemId: `${id}-form-item`, - formDescriptionId: `${id}-form-item-description`, - formMessageId: `${id}-form-item-message`, - ...fieldState, - } + const fieldContext = useContext(FormFieldContext) + const itemContext = useContext(FormItemContext) + const { getFieldState, formState } = useFormContext() + + const fieldState = getFieldState(fieldContext.name, formState) + + if (!fieldContext) { + throw new Error('useFormField should be used within ') + } + + const { id } = itemContext + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState + } } type FormItemContextValue = { - id: string + id: string } -const FormItemContext = createContext( - {} as FormItemContextValue -) +const FormItemContext = createContext({} as FormItemContextValue) -const FormItem = forwardRef< - HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => { - const id = useId() +const FormItem = forwardRef>( + ({ className, ...props }, ref) => { + const id = useId() - return ( - -
- - ) -}) -FormItem.displayName = "FormItem" + return ( + +
+ + ) + } +) +FormItem.displayName = 'FormItem' const FormLabel = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - const { error, formItemId } = useFormField() - - return ( -