This commit is contained in:
熊潇 2025-05-10 03:49:47 +08:00
parent 1d10cf5888
commit b4c367b799
59 changed files with 61142 additions and 2384 deletions

67
.gitignore vendored
View File

@ -1,9 +1,64 @@
node_modules
.pnpm-debug.log
.vscode
dist
build
.env
# mac
.DS_Store
.env*
!.env*example
/dist
# build
/build
/logs
.turbo
/pack-dist
# astro
.astro
# next
.next
# nuxt
.nuxt
# vercel
.vercel
# vuepress
.vuepress/dist
# coverage
coverage/
# typescript
*.tsbuildinfo
# debug logs
*.log
*.tmp
# vscode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# idea
.idea
# system
Thumbs.db
ehthumbs.db
Desktop.ini
# temp files
*.tmp
*.temp
# local development
*.local

4
.npmrc
View File

@ -1,2 +1,2 @@
@abearxiong:registry=https://npm.pkg.github.com
@kevisual:registry=https://npm.xiongxiao.me
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"tailwindCSS.classFunctions": ["cva", "cx"]
}

3
apps/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"tailwindCSS.classFunctions": ["cva", "cx"]
}

66
apps/demo/.gitignore vendored Normal file
View File

@ -0,0 +1,66 @@
node_modules
# mac
.DS_Store
.env*
!.env*example
/dist
# build
/build
/logs
.turbo
/pack-dist
# astro
.astro
# next
.next
# nuxt
.nuxt
# vercel
.vercel
# vuepress
.vuepress/dist
# coverage
coverage/
# typescript
*.tsbuildinfo
# debug logs
*.log
*.tmp
# vscode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# idea
.idea
# system
Thumbs.db
ehthumbs.db
Desktop.ini
# temp files
*.tmp
*.temp
# local development
*.local
public/r

3
apps/demo/.npmrc Normal file
View File

@ -0,0 +1,3 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
ignore-workspace-root-check=true

View File

@ -0,0 +1,28 @@
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import react from '@astrojs/react';
// import sitemap from '@astrojs/sitemap';
import pkgs from './package.json';
import tailwindcss from '@tailwindcss/vite';
const isDev = process.env.NODE_ENV === 'development';
export default defineConfig({
// ...
// site: 'https://kevisual.xiongxiao.me/root/astro/',
base: isDev ? undefined : pkgs.basename,
integrations: [
mdx(),
react(), //
// sitemap(), // sitemap must be site has a domain
],
vite: {
plugins: [tailwindcss()],
define: {
BASE_NAME: JSON.stringify(pkgs.basename),
DEV_SERVER: JSON.stringify(isDev),
},
},
});

21
apps/demo/components.json Normal file
View File

@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

35
apps/demo/package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "demo",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"build:registry": "pnpm dlx shadcn@latest build"
},
"keywords": [],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
"license": "MIT",
"packageManager": "pnpm@10.10.0",
"type": "module",
"devDependencies": {
"@astrojs/mdx": "^4.2.6",
"@astrojs/react": "^4.2.7",
"@kevisual/types": "^0.0.10",
"@tailwindcss/vite": "^4.1.6",
"@types/react": "^19.1.3",
"astro": "^5.7.12",
"tailwindcss": "^4.1.6",
"tailwind-merge": "^3.2.0",
"tw-animate-css": "^1.2.9"
},
"dependencies": {
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.509.0",
"react": "^19.1.0",
"react-dom": "^19.1.0"
}
}

View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View File

@ -0,0 +1 @@
export const basename = DEV_SERVER ? '' : '/root/center';

View File

@ -0,0 +1,4 @@
---
import '../styles/global.css'
---
index

View File

@ -0,0 +1,120 @@
@import 'tailwindcss';
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

22
apps/demo/tsconfig.json Normal file
View File

@ -0,0 +1,22 @@
{
"extends": "@kevisual/types/json/frontend.json",
"compilerOptions": {
"baseUrl": ".",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@kevisual"
],
"paths": {
"@/*": [
"src/*"
],
"@/registry/*": [
"registry/*"
]
},
},
"include": [
"src/**/*",
"registry/**/*"
],
}

66
libs/registry/.gitignore vendored Normal file
View File

@ -0,0 +1,66 @@
node_modules
# mac
.DS_Store
.env*
!.env*example
/dist
# build
/build
/logs
.turbo
/pack-dist
# astro
.astro
# next
.next
# nuxt
.nuxt
# vercel
.vercel
# vuepress
.vuepress/dist
# coverage
coverage/
# typescript
*.tsbuildinfo
# debug logs
*.log
*.tmp
# vscode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# idea
.idea
# system
Thumbs.db
ehthumbs.db
Desktop.ini
# temp files
*.tmp
*.temp
# local development
*.local
public/r

3
libs/registry/.npmrc Normal file
View File

@ -0,0 +1,3 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
ignore-workspace-root-check=true

3
libs/registry/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"tailwindCSS.classFunctions": ["cva", "cx"]
}

View File

@ -0,0 +1,28 @@
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import react from '@astrojs/react';
// import sitemap from '@astrojs/sitemap';
import pkgs from './package.json';
import tailwindcss from '@tailwindcss/vite';
const isDev = process.env.NODE_ENV === 'development';
export default defineConfig({
// ...
// site: 'https://kevisual.xiongxiao.me/root/astro/',
base: isDev ? undefined : pkgs.basename,
integrations: [
mdx(),
react(), //
// sitemap(), // sitemap must be site has a domain
],
vite: {
plugins: [tailwindcss()],
define: {
BASE_NAME: JSON.stringify(pkgs.basename),
DEV_SERVER: JSON.stringify(isDev),
},
},
});

View File

@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}

View File

@ -0,0 +1,41 @@
{
"name": "@kevisual/registry",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"build:registry": "pnpm dlx shadcn@latest build"
},
"keywords": [],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
"license": "MIT",
"packageManager": "pnpm@10.10.0",
"type": "module",
"devDependencies": {
"@astrojs/mdx": "^4.2.6",
"@astrojs/react": "^4.2.7",
"@kevisual/types": "^0.0.10",
"@tailwindcss/vite": "^4.1.6",
"@types/react": "^19.1.3",
"astro": "^5.7.12",
"tailwindcss": "^4.1.6",
"tw-animate-css": "^1.2.9"
},
"dependencies": {
"@inlang/paraglide-js": "^2.0.12",
"@inlang/paraglide-js-adapter-vite": "^1.2.40",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"i18next": "^25.1.2",
"i18next-browser-languagedetector": "^8.1.0",
"lucide-react": "^0.509.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-i18next": "^15.5.1",
"react-toastify": "^11.0.5",
"tailwind-merge": "^3.2.0"
}
}

View File

@ -0,0 +1,32 @@
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "shadcn",
"homepage": "https://ui.shadcn.com",
"items": [
{
"name": "hello-world",
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"files": [
{
"path": "registry/hello-world/hello-world.tsx",
"type": "registry:component"
}
]
},
{
"name": "basename",
"type": "registry:file",
"title": "Basename",
"description": "The basename for the router.",
"files": [
{
"path": "registry/modules/basename.ts",
"type": "registry:file",
"target": "src/modules/basename.ts"
}
]
}
]
}

View File

@ -0,0 +1,27 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
// 导入你的翻译资源
import enTranslation from './locales/en/translation.json';
import zhTranslation from './locales/zh/translation.json';
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: {
translation: enTranslation,
},
zh: {
translation: zhTranslation,
},
},
fallbackLng: 'en',
interpolation: {
escapeValue: false, // React 已经处理了转义
},
});
export default i18n;

View File

@ -0,0 +1,4 @@
{
"welcome": "Welcome to our site",
"about": "About us"
}

View File

@ -0,0 +1,4 @@
{
"welcome": "Welcome to our site",
"about": "About us"
}

View File

@ -0,0 +1,45 @@
import React from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { twMerge } from 'tailwind-merge';
const button = cva('button', {
variants: {
intent: {
primary: ['bg-blue-500', 'text-white', 'border-transparent'],
secondary: ['bg-white', 'text-gray-800', 'border-gray-400'],
},
size: {
small: ['text-sm', 'py-1', 'px-2'],
medium: ['text-base', 'py-2', 'px-4'],
},
disabled: {
false: null,
true: ['opacity-50', 'cursor-not-allowed'],
},
},
compoundVariants: [
{
intent: 'primary',
disabled: false,
class: 'hover:bg-blue-600',
},
{
intent: 'secondary',
disabled: false,
class: 'hover:bg-gray-100',
},
{ intent: 'primary', size: 'medium', class: 'uppercase' },
],
defaultVariants: {
disabled: false,
intent: 'primary',
size: 'medium',
},
});
export interface ButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'disabled'>, VariantProps<typeof button> {}
export const Button: React.FC<ButtonProps> = ({ className, intent, size, disabled, ...props }) => (
<button className={twMerge('cursor-pointer', button({ intent, size, disabled, className }))} disabled={disabled || undefined} {...props} />
);

View File

@ -0,0 +1,36 @@
// components/card.ts
import type { VariantProps } from "class-variance-authority";
import { cva, cx } from "class-variance-authority";
/**
* Box
*/
export type BoxProps = VariantProps<typeof box>;
export const box = cva(["box", "box-border"], {
variants: {
margin: { 0: "m-0", 2: "m-2", 4: "m-4", 8: "m-8" },
padding: { 0: "p-0", 2: "p-2", 4: "p-4", 8: "p-8" },
},
defaultVariants: {
margin: 0,
padding: 0,
},
});
/**
* Card
*/
type CardBaseProps = VariantProps<typeof cardBase>;
const cardBase = cva(["card", "border-solid", "border-slate-300", "rounded"], {
variants: {
shadow: {
md: "drop-shadow-md",
lg: "drop-shadow-lg",
xl: "drop-shadow-xl",
},
},
});
export interface CardProps extends BoxProps, CardBaseProps {}
export const card = ({ margin, padding, shadow }: CardProps = {}) =>
cx(box({ margin, padding }), cardBase({ shadow }));

View File

@ -0,0 +1,3 @@
export const HelloWorld = () => {
return <div>Hello Wrold</div>;
};

View File

@ -0,0 +1 @@
export const basename = DEV_SERVER ? '' : '/root/center';

View File

@ -0,0 +1,13 @@
import { ToastContainer } from 'react-toastify';
type ToastProviderProps = {
children?: React.ReactNode;
};
export const ToastProvider = ({ children }: ToastProviderProps) => {
return (
<>
{children}
<ToastContainer />
</>
);
};

View File

@ -0,0 +1,42 @@
import { toast } from 'react-toastify';
import { useTranslation } from 'react-i18next';
// Custom message component
const LoginMessage = (props: ToastLoginProps) => {
const { t } = useTranslation();
const handleClick = () => {
const currentUrl = window.location.href;
const redirect = encodeURIComponent(props?.redirectUrl || currentUrl);
const loginUrl = props?.loginUrl || '/user/login/';
const newUrl = location.origin + loginUrl + '?redirect=' + redirect;
window.open(newUrl, '_self');
};
return (
<div className='msg-container' onClick={handleClick} style={{ cursor: 'pointer' }}>
<p className='msg-title'>{t('Please login')}</p>
<p className='msg-description'>{t('Click here to go to the login page.')}</p>
</div>
);
};
type ToastLoginProps = {
/**
* , /user/login
*/
loginUrl?: string;
/**
* ,
*/
redirectUrl?: string;
};
/**
*
* @param props
* @example
* toastLogin({
* loginUrl: '/user/login/',
* redirectUrl: window.location.href,
* });
*/
export const toastLogin = (props: ToastLoginProps = {}) => {
toast.info(<LoginMessage {...props} />);
};

View File

@ -0,0 +1,27 @@
// src/components/LanguageSwitcher.tsx
"use client";
import * as m from "@/paraglide/messages";
import { setLanguageTag, languageTag } from "@/paraglide/runtime";
export function LanguageSwitcher() {
return (
<div>
<h1>{m.welcome()}</h1>
<p>{m.about()}</p>
<button
onClick={() => setLanguageTag("en")}
disabled={languageTag() === "en"}
>
English
</button>
<button
onClick={() => setLanguageTag("zh")}
disabled={languageTag() === "zh"}
>
</button>
</div>
);
}

View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View File

@ -0,0 +1,16 @@
import { toastLogin } from '@/registry/modules/toast/ToastLogin';
import { ToastProvider } from '@/registry/modules/toast/Provider';
import { Button } from '@/registry/button/button';
export const ShowLogin = () => {
return (
<ToastProvider>
<Button
onClick={() => {
toastLogin();
console.log('clicked');
}}>
Click me
</Button>
</ToastProvider>
);
};

View File

@ -0,0 +1,8 @@
---
import '../styles/global.css';
import '@/registry/astro/i18n'; // 初始化i18n
import { ShowLogin } from '@/modules/demo/ShowLogin';
---
<h1 class='text-4xl'>Registry</h1>
<ShowLogin client:load />

View File

@ -0,0 +1,10 @@
---
---
# Download shadcn
```sh
pnpm dlx shadcn@latest add http://localhost:4321/r/basename.json
```

View File

@ -0,0 +1,119 @@
@import 'tailwindcss';
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}

View File

@ -0,0 +1,22 @@
{
"extends": "@kevisual/types/json/frontend.json",
"compilerOptions": {
"baseUrl": ".",
"typeRoots": [
"./node_modules/@types",
"./node_modules/@kevisual"
],
"paths": {
"@/*": [
"src/*"
],
"@/registry/*": [
"registry/*"
]
},
},
"include": [
"src/**/*",
"registry/**/*"
],
}

View File

@ -11,7 +11,7 @@
"license": "ISC",
"packageManager": "pnpm@10.10.0",
"devDependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "^19.1.0",
"react-dom": "^19.1.0"
}
}

View File

@ -0,0 +1,2 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

19
packages/codemirror/dist/editor.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
import { EditorView } from 'codemirror';
declare let editor: EditorView;
type CreateOpts = {
jsx?: boolean;
typescript?: boolean;
};
/**
*
* @param el
* @returns
*/
declare const createEditorInstance: (el?: HTMLDivElement, opts?: CreateOpts) => EditorView;
/**
*
* @param el
* @returns
*/
export declare const createEditor: (el: HTMLDivElement, opts?: CreateOpts) => EditorView;
export { editor, createEditorInstance };

27136
packages/codemirror/dist/editor.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
import { EditorView } from 'codemirror';
declare let editor: EditorView;
/**
*
* @param el
* @returns
*/
declare const createEditorInstance: (el?: HTMLDivElement) => EditorView;
/**
*
* @param el
* @returns
*/
export declare const createEditor: (el: HTMLDivElement) => EditorView;
export { editor, createEditorInstance };

26271
packages/codemirror/dist/editor.json.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# kevisual codemirror
```ts
import { createEditorInstance } from '@kevisual/codemirror';
const editor = createEditorInstance(ref.current!, { typescript: false });
editor.dom.style.height = '100%';
```

View File

@ -1 +1,2 @@
@build:registry=https://npm.xiongxiao.me
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

View File

@ -0,0 +1,40 @@
@import 'tailwindcss';
@utility {
.btn {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.card {
@apply bg-white shadow-md rounded-lg p-4;
.card-title {
@apply text-lg font-bold;
}
.card-subtitle {
@apply text-sm text-gray-500;
}
.card-description {
@apply text-gray-700 break-words;
}
.card-code {
@apply bg-gray-100 p-2;
}
.card-body {
@apply text-gray-700;
}
.card-key {
@apply text-xs text-gray-400;
}
.card-footer {
@apply text-sm text-gray-500;
}
}
}
@utilities {
.layout-menu {
@apply bg-gray-900 p-2 text-white flex justify-between h-12;
}
.bg-custom-blue {
background-color: #3490dc;
}
}

View File

@ -1,15 +1,23 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss';
@layer base {
html,
body {
width: 100%;
height: 100%;
font-size: 16px;
font-family: 'Montserrat', sans-serif;
}
@theme {
--color-primary: #ffc107;
--color-secondary: #ffa000;
--color-text-primary: #000000;
--color-text-secondary: #000000;
--color-success: #28a745;
--color-scrollbar-thumb: #999999;
--color-scrollbar-track: rgba(0, 0, 0, 0.1);
--color-scrollbar-thumb-hover: #666666;
--scrollbar-color: #ffc107; /* 滚动条颜色 */
}
html,
body {
width: 100%;
height: 100%;
font-size: 16px;
font-family: 'Montserrat', sans-serif;
h1 {
@apply text-2xl font-bold;
}
@ -20,42 +28,60 @@
@apply text-lg font-bold;
}
}
@layer components {
.btn {
@apply bg-blue-500 text-white font-bold py-2 px-4 rounded;
}
.card {
@apply bg-white shadow-md rounded-lg p-4;
.card-title {
@apply text-lg font-bold;
}
.card-subtitle {
@apply text-sm text-gray-500;
}
.card-description {
@apply text-gray-700 break-words;
}
.card-code {
@apply bg-gray-100 p-2;
}
.card-body {
@apply text-gray-700;
}
.card-key {
@apply text-xs text-gray-400;
}
.card-footer {
@apply text-sm text-gray-500;
}
}
/* font-family */
@utility font-family-mon {
font-family: 'Montserrat', sans-serif;
}
@utility font-family-rob {
font-family: 'Roboto', sans-serif;
}
@utility font-family-int {
font-family: 'Inter', sans-serif;
}
@utility font-family-orb {
font-family: 'Orbitron', sans-serif;
}
@utility font-family-din {
font-family: 'DIN', sans-serif;
}
@layer utilities {
.layout-menu {
@apply bg-gray-900 p-2 text-white flex justify-between h-12;
@utility flex-row-center {
@apply flex flex-row items-center justify-center;
}
@utility flex-col-center {
@apply flex flex-col items-center justify-center;
}
@utility scrollbar {
overflow: auto;
/* 整个滚动条 */
&::-webkit-scrollbar {
width: 3px;
height: 3px;
}
.bg-custom-blue {
background-color: #3490dc;
&::-webkit-scrollbar-track {
background-color: var(--color-scrollbar-track);
}
/* 滚动条有滑块的轨道部分 */
&::-webkit-scrollbar-track-piece {
background-color: transparent;
border-radius: 1px;
}
/* 滚动条滑块(竖向:vertical 横向:horizontal) */
&::-webkit-scrollbar-thumb {
cursor: pointer;
background-color: var(--color-scrollbar-thumb);
border-radius: 5px;
}
/* 滚动条滑块hover */
&::-webkit-scrollbar-thumb:hover {
background-color: var(--color-scrollbar-thumb-hover);
}
/* 同时有垂直和水平滚动条时交汇的部分 */
&::-webkit-scrollbar-corner {
display: block; /* 修复交汇时出现的白块 */
}
}

View File

@ -1,6 +1,6 @@
@tailwind components;
@import 'tailwindcss';
@layer components {
@utility {
.loading {
@apply w-full h-full flex justify-center items-center;
> div {
@ -11,3 +11,4 @@
@apply w-4 h-4 border-t-2 border-b-2 rounded-full animate-spin;
}
}

View File

@ -1,4 +1,5 @@
.scrollbar {
@import 'tailwindcss';
@utility .scrollbar {
/* 整个滚动条 */
&::-webkit-scrollbar {
width: 3px;

View File

@ -1,3 +1,3 @@
@import "./css/globals.css";
@import "./css/loading.css";
@import "./css/scrollbar.css"
/* @import "./css/scrollbar.css" */

View File

@ -1,6 +1,6 @@
{
"name": "@build/tailwind",
"version": "1.0.2-alpha-2",
"name": "@kevisual/tailwind",
"version": "1.0.3",
"description": "",
"main": "plugin/index.js",
"type": "module",

View File

@ -15,39 +15,38 @@
"author": "",
"license": "ISC",
"dependencies": {
"@abearxiong/ui": "0.0.1-alpha.0",
"@kevisual/codemirror": "workspace:^",
"@kevisual/ui": "workspace:^",
"antd": "^5.20.6",
"antd": "^5.25.1",
"clsx": "^2.1.1",
"immer": "^10.1.1",
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router": "^6.26.2",
"react-router-dom": "^6.26.2",
"react-toastify": "^10.0.5",
"zustand": "^4.5.5"
"nanoid": "^5.1.5",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router": "^7.6.0",
"react-router-dom": "^7.6.0",
"react-toastify": "^11.0.5",
"zustand": "^5.0.4"
},
"devDependencies": {
"@eslint/js": "^9.10.0",
"@eslint/js": "^9.26.0",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/typography": "^0.5.15",
"@types/node": "^22.5.5",
"@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.20",
"eslint": "^9.10.0",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.12",
"globals": "^15.9.0",
"tailwind-merge": "^2.5.2",
"tailwindcss": "^3.4.12",
"@tailwindcss/typography": "^0.5.16",
"@types/node": "^22.15.17",
"@types/react": "^19.1.3",
"@types/react-dom": "^19.1.3",
"@vitejs/plugin-react": "^4.4.1",
"autoprefixer": "^10.4.21",
"eslint": "^9.26.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.1.0",
"tailwind-merge": "^3.2.0",
"tailwindcss": "^4.1.6",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.6.2",
"typescript-eslint": "^8.6.0",
"vite": "^5.4.6"
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.0",
"vite": "^6.3.5"
}
}

View File

@ -1,4 +1,4 @@
import { createEditorInstance } from '@kevisual/codemirror/dist/editor.json';
import { createEditorInstance } from '@kevisual/codemirror/json';
import { useEffect, useRef } from 'react';
export const App = () => {
const ref = useRef<HTMLDivElement>(null);

View File

@ -11,7 +11,6 @@ export const App = ({ typescript }: AppProps) => {
}, []);
const init = () => {
const editor = createEditorInstance(ref.current!, { typescript });
editor.dom.style.height = '100%';
};
return (
<div className='h-full w-full bg-gray-400'>

View File

@ -21,24 +21,23 @@
"keywords": [],
"author": "abearxiong",
"devDependencies": {
"@emotion/serialize": "^1.3.2",
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-node-resolve": "^15.3.0",
"@emotion/serialize": "^1.3.3",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.1",
"@rollup/plugin-typescript": "^12.1.2",
"@types/postcss-import": "^14.0.3",
"@types/react": "^18.3.12",
"autoprefixer": "^10.4.20",
"@types/react": "^19.1.3",
"autoprefixer": "^10.4.21",
"cross-env": "^7.0.3",
"cssnano": "^7.0.6",
"cssnano": "^7.0.7",
"immer": "^10.1.1",
"nanoid": "^5.0.8",
"nanoid": "^5.1.5",
"postcss-import": "^16.1.0",
"rollup": "^4.24.3",
"rollup": "^4.40.2",
"rollup-plugin-postcss": "^4.0.2",
"typescript": "^5.6.3",
"zustand": "5.0.1",
"@kevisual/system-ui": "^0.0.2"
"typescript": "^5.8.3",
"zustand": "5.0.4"
},
"dependencies": {
"dayjs": "^1.11.13",

View File

@ -1,5 +1,5 @@
{
"name": "@build/vite",
"name": "@kevisual/vite",
"version": "0.0.1",
"description": "",
"main": "index.js",
@ -17,22 +17,22 @@
"src"
],
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.1",
"@rollup/plugin-typescript": "^12.1.2",
"@types/postcss-import": "^14.0.3",
"@types/react": "^18.3.12",
"autoprefixer": "^10.4.20",
"@types/react": "^19.1.3",
"autoprefixer": "^10.4.21",
"cross-env": "^7.0.3",
"cssnano": "^7.0.6",
"cssnano": "^7.0.7",
"immer": "^10.1.1",
"nanoid": "^5.0.8",
"nanoid": "^5.1.5",
"postcss-import": "^16.1.0",
"rollup": "^4.24.3",
"rollup-plugin-dts": "^6.1.1",
"rollup": "^4.40.2",
"rollup-plugin-dts": "^6.2.1",
"rollup-plugin-postcss": "^4.0.2",
"typescript": "^5.6.3",
"vite": "^5.4.6"
"typescript": "^5.8.3",
"vite": "^6.3.5"
}
}

8802
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,5 @@
packages:
- 'packages/*'
- 'submodules/*'
- 'packages/*'
- 'apps/*'
- 'libs/*'

View File

@ -1,36 +0,0 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": "./",
"types": [],
"paths": {
"@/*": [
"src/*"
]
},
/* Linting */
"strict": true,
"noImplicitAny": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": true
},
"include": [
"src",
]
}