commit 467962dbb26eecf21a8f6659d159179bce6a6486 Author: Tom-lyz Date: Tue Aug 26 17:41:23 2025 +0800 first_commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c64d8f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + + +pnpm-lock.yaml +yarn.lock +package-lock.json +bun.lockb \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..1e54ebc --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=true \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fb37c88 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "tailwindCSS.experimental.classRegex": [ + ["([\"'`][^\"'`]*.*?[\"'`])", "[\"'`]([^\"'`]*).*?[\"'`]"] + ], +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d3006aa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Next UI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..30476e8 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# Vite & HeroUI Template + +This is a template for creating applications using Vite and HeroUI (v2). + +[Try it on CodeSandbox](https://githubbox.com/frontio-ai/vite-template) + +## Technologies Used + +- [Vite](https://vitejs.dev/guide/) +- [HeroUI](https://heroui.com) +- [Tailwind CSS](https://tailwindcss.com) +- [Tailwind Variants](https://tailwind-variants.org) +- [TypeScript](https://www.typescriptlang.org) +- [Framer Motion](https://www.framer.com/motion) + +## How to Use + +To clone the project, run the following command: + +```bash +git clone https://github.com/frontio-ai/vite-template.git +``` + +### Install dependencies + +You can use one of them `npm`, `yarn`, `pnpm`, `bun`, Example using `npm`: + +```bash +npm install +``` + +### Run the development server + +```bash +npm run dev +``` + +### Setup pnpm (optional) + +If you are using `pnpm`, you need to add the following code to your `.npmrc` file: + +```bash +public-hoist-pattern[]=*@heroui/* +``` + +After modifying the `.npmrc` file, you need to run `pnpm install` again to ensure that the dependencies are installed correctly. + +## License + +Licensed under the [MIT license](https://github.com/frontio-ai/vite-template/blob/main/LICENSE). diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..6b26484 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,175 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { defineConfig, globalIgnores } from "eslint/config"; +import { fixupConfigRules, fixupPluginRules } from "@eslint/compat"; +import react from "eslint-plugin-react"; +import unusedImports from "eslint-plugin-unused-imports"; +import _import from "eslint-plugin-import"; +import typescriptEslint from "@typescript-eslint/eslint-plugin"; +import jsxA11Y from "eslint-plugin-jsx-a11y"; +import prettier from "eslint-plugin-prettier"; +import globals from "globals"; +import tsParser from "@typescript-eslint/parser"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default defineConfig([ + globalIgnores([ + ".now/*", + "**/*.css", + "**/.changeset", + "**/dist", + "esm/*", + "public/*", + "tests/*", + "scripts/*", + "**/*.config.js", + "**/.DS_Store", + "**/node_modules", + "**/coverage", + "**/.next", + "**/build", + "!**/.commitlintrc.cjs", + "!**/.lintstagedrc.cjs", + "!**/jest.config.js", + "!**/plopfile.js", + "!**/react-shim.js", + "!**/tsup.config.ts", + ]), + { + extends: fixupConfigRules( + compat.extends( + "plugin:react/recommended", + "plugin:prettier/recommended", + "plugin:react-hooks/recommended", + "plugin:jsx-a11y/recommended", + ), + ), + + plugins: { + react: fixupPluginRules(react), + "unused-imports": unusedImports, + import: fixupPluginRules(_import), + "@typescript-eslint": typescriptEslint, + "jsx-a11y": fixupPluginRules(jsxA11Y), + prettier: fixupPluginRules(prettier), + }, + + languageOptions: { + globals: { + ...Object.fromEntries( + Object.entries(globals.browser).map(([key]) => [key, "off"]), + ), + ...globals.node, + }, + + parser: tsParser, + ecmaVersion: 12, + sourceType: "module", + + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + + settings: { + react: { + version: "detect", + }, + }, + + + files: ["**/*.ts", "**/*.tsx"], + + rules: { + "no-console": "warn", + "react/prop-types": "off", + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off", + "react-hooks/exhaustive-deps": "off", + "jsx-a11y/click-events-have-key-events": "warn", + "jsx-a11y/interactive-supports-focus": "warn", + "prettier/prettier": "warn", + "no-unused-vars": "off", + "unused-imports/no-unused-vars": "off", + "unused-imports/no-unused-imports": "warn", + + "@typescript-eslint/no-unused-vars": [ + "warn", + { + args: "after-used", + ignoreRestSiblings: false, + argsIgnorePattern: "^_.*?$", + }, + ], + + "import/order": [ + "warn", + { + groups: [ + "type", + "builtin", + "object", + "external", + "internal", + "parent", + "sibling", + "index", + ], + + pathGroups: [ + { + pattern: "~/**", + group: "external", + position: "after", + }, + ], + + "newlines-between": "always", + }, + ], + + "react/self-closing-comp": "warn", + + "react/jsx-sort-props": [ + "warn", + { + callbacksLast: true, + shorthandFirst: true, + noSortAlphabetically: false, + reservedFirst: true, + }, + ], + + "padding-line-between-statements": [ + "warn", + { + blankLine: "always", + prev: "*", + next: "return", + }, + { + blankLine: "always", + prev: ["const", "let", "var"], + next: "*", + }, + { + blankLine: "any", + prev: ["const", "let", "var"], + next: ["const", "let", "var"], + }, + ], + }, + }, +]); diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..e38d32a Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..102806f --- /dev/null +++ b/index.html @@ -0,0 +1,28 @@ + + + + + + + Vite + HeroUI + + + + + + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..ec4c72f --- /dev/null +++ b/package.json @@ -0,0 +1,65 @@ +{ + "name": "vite-template", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint --fix", + "preview": "vite preview" + }, + "dependencies": { + "@heroicons/react": "^2.2.0", + "@heroui/button": "^2.2.24", + "@heroui/code": "^2.2.18", + "@heroui/dropdown": "^2.3.24", + "@heroui/input": "^2.4.25", + "@heroui/kbd": "^2.2.19", + "@heroui/link": "^2.2.21", + "@heroui/navbar": "^2.2.22", + "@heroui/react": "^2.8.2", + "@heroui/snippet": "^2.2.25", + "@heroui/switch": "^2.2.22", + "@heroui/system": "^2.4.20", + "@heroui/theme": "^2.4.20", + "@heroui/use-theme": "2.1.10", + "@react-aria/visually-hidden": "3.8.26", + "@react-types/shared": "3.31.0", + "@tailwindcss/postcss": "4.1.11", + "@tailwindcss/vite": "4.1.11", + "clsx": "2.1.1", + "framer-motion": "11.18.2", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-router-dom": "6.23.0", + "tailwind-variants": "2.0.1", + "tailwindcss": "4.1.11" + }, + "devDependencies": { + "@eslint/compat": "1.2.8", + "@eslint/eslintrc": "3.3.1", + "@eslint/js": "9.25.1", + "@types/node": "20.5.7", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", + "@typescript-eslint/eslint-plugin": "8.31.1", + "@typescript-eslint/parser": "8.31.1", + "@vitejs/plugin-react": "^4.7.0", + "eslint": "9.25.1", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-jsx-a11y": "6.10.2", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-prettier": "5.2.1", + "eslint-plugin-react": "7.37.5", + "eslint-plugin-react-hooks": "5.2.0", + "eslint-plugin-unused-imports": "4.1.4", + "globals": "16.0.0", + "postcss": "8.5.6", + "prettier": "3.5.3", + "typescript": "5.6.3", + "vite": "6.0.11", + "vite-tsconfig-paths": "5.1.4" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..fe1e17e --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,5 @@ +export default { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; \ No newline at end of file diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..30a0ae6 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,15 @@ +import Navbar_create from "./Navbar"; +import ChatbotInterface from "./new chatbot-interaction"; + + +function App() { + return ( + <> + + + + + ); +} + +export default App; diff --git a/src/ChatbotInput.tsx b/src/ChatbotInput.tsx new file mode 100644 index 0000000..e30dcfa --- /dev/null +++ b/src/ChatbotInput.tsx @@ -0,0 +1,86 @@ +import { Input } from "@heroui/react"; +import { useState } from "react"; +import {Button} from "@heroui/react"; + +interface ChatbotInputProps { + onSubmit?: (question: string) => void; + placeholder?: string; + maxHeight?: number; + minHeight?: number; +} + +const ChatbotInput = ({ + onSubmit, + placeholder = "请输入你的问题...", + minHeight = 18, + maxHeight = 120, +}: ChatbotInputProps) => { + const [inputValue, setInputValue] = useState(""); + const [inputHeight, setInputHeight] = useState(minHeight); + + const handleInputChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setInputValue(value); + + const textarea = e.target; + textarea.style.height = `${minHeight}px`; + const newHeight = Math.min(textarea.scrollHeight, maxHeight); + setInputHeight(newHeight); + textarea.style.height = `${newHeight}px`; + }; + + const handleSubmit = () => { + const question = inputValue.trim(); + if (question && onSubmit) { + onSubmit(question); + setInputValue(""); + setInputHeight(18); + } + }; + + return ( +
+ + +