,
+ D extends Partial,
+>(props: P, defaults: D): P & D {
+ return useMemo(() => {
+ return { ...defaults, ...props };
+ }, [props, defaults]);
+}
diff --git a/packages/ui-react/src/utils/useSlotRegistry.ts b/packages/ui-react/src/utils/useSlotRegistry.ts
new file mode 100644
index 0000000..93871f7
--- /dev/null
+++ b/packages/ui-react/src/utils/useSlotRegistry.ts
@@ -0,0 +1,8 @@
+// useButtonSlots.ts
+import { useState } from "react";
+
+export function useSlotRegistry() {
+ const [slots, setSlots] = useState()
+
+ return { slots, setSlots }
+}
\ No newline at end of file
diff --git a/packages/ui-web/tsconfig.build.json b/packages/ui-react/tsconfig.build.json
similarity index 95%
rename from packages/ui-web/tsconfig.build.json
rename to packages/ui-react/tsconfig.build.json
index 4581f3b..e9fcb7d 100644
--- a/packages/ui-web/tsconfig.build.json
+++ b/packages/ui-react/tsconfig.build.json
@@ -10,6 +10,8 @@
},
"include": ["src"],
"exclude": [
+ "src/App.tsx",
+ "src/main.tsx",
"node_modules",
"dist",
".turbo/**/*",
diff --git a/packages/ui-react/tsconfig.json b/packages/ui-react/tsconfig.json
new file mode 100644
index 0000000..7b84f30
--- /dev/null
+++ b/packages/ui-react/tsconfig.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "target": "es2025",
+ "lib": [
+ "ES2025",
+ "DOM",
+ "DOM.Iterable"
+ ],
+ "module": "ESNext",
+ "types": [
+ "node",
+ "vite/client"
+ ],
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+ },
+ "include": [
+ "src",
+ "scripts",
+ "vite.config.ts",
+ ]
+}
\ No newline at end of file
diff --git a/packages/ui-react/vite.config.ts b/packages/ui-react/vite.config.ts
new file mode 100644
index 0000000..ea4923d
--- /dev/null
+++ b/packages/ui-react/vite.config.ts
@@ -0,0 +1,39 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import path from "path";
+
+export default defineConfig({
+ plugins: [react()],
+
+ build: {
+ cssMinify: false,
+
+ lib: {
+ entry: path.resolve(import.meta.dirname, "src/index.ts"),
+ formats: ["es", "cjs"],
+ fileName: (format) => `index.${format}.js`,
+ },
+
+ rolldownOptions: {
+ external: ["react", "react-dom", "react/jsx-runtime"],
+ output: {
+ // 强制将生成的 CSS 命名为 index.css
+ assetFileNames: (assetInfo) => {
+ if (assetInfo.name && assetInfo.name.endsWith(".css")) {
+ return "index.css";
+ }
+ return "[name].[hash][extname]";
+ },
+ globals: {
+ react: "React",
+ "react-dom": "ReactDOM",
+ },
+ },
+ },
+
+ emptyOutDir: true,
+ sourcemap: true,
+ cssCodeSplit: false,
+ outDir: "dist",
+ },
+});
diff --git a/packages/ui-web-tw/package.json b/packages/ui-web-tw/package.json
index ea245bd..f2b7727 100644
--- a/packages/ui-web-tw/package.json
+++ b/packages/ui-web-tw/package.json
@@ -24,7 +24,6 @@
"scripts": {
"gen-index": "ts-node scripts/gen-index.ts",
"gen-dts": "tsc -p tsconfig.build.json",
- "dev": "pnpm gen-index && vite build --watch",
"build": "pnpm gen-index && vite build && pnpm gen-dts"
},
"devDependencies": {
diff --git a/packages/ui-web-tw/src/index.css b/packages/ui-web-tw/src/index.css
index 6416da1..a461c50 100644
--- a/packages/ui-web-tw/src/index.css
+++ b/packages/ui-web-tw/src/index.css
@@ -1,16 +1 @@
-@import "tailwindcss";
-@import './component/accordion/Accordion.css';
-@import './component/avatar/Avatar.css';
-@import './component/checkbox/Checkbox.css';
-@import './component/tooltip/Tooltip.css';
-@import './styles/theme/global.css';
-@import './styles/utility/brand.css';
-@import './styles/utility/font.css';
-@import './styles/utility/gap.css';
-@import './styles/utility/height.css';
-@import './styles/utility/loading.css';
-@import './styles/utility/margin.css';
-@import './styles/utility/padding.css';
-@import './styles/utility/skin.css';
-@import './styles/utility/variant.css';
-@import './styles/utility/width.css';
\ No newline at end of file
+@import "tailwindcss";
\ No newline at end of file
diff --git a/packages/ui-web-tw/src/index.ts b/packages/ui-web-tw/src/index.ts
index f08a879..7505b6f 100644
--- a/packages/ui-web-tw/src/index.ts
+++ b/packages/ui-web-tw/src/index.ts
@@ -1,44 +1 @@
-import './index.css';
-
-export * from './assets/svg/BoldSvg';
-export * from './assets/svg/CheckIndicatorSvg';
-export * from './assets/svg/ChevronRightSvg';
-export * from './assets/svg/CutSvg';
-export * from './assets/svg/DownloadSvg';
-export * from './assets/svg/FileSvg';
-export * from './assets/svg/KeySvg';
-export * from './assets/svg/MeshSvg';
-export * from './assets/svg/MoonSvg';
-export * from './assets/svg/PasteSvg';
-export * from './assets/svg/Ruler';
-export * from './assets/svg/SearchSvg';
-export * from './assets/svg/SettingSvg';
-export * from './assets/svg/SpinnerSvg';
-export * from './assets/svg/SunSvg';
-export * from './assets/svg/UserSvg';
-export * from './assets/svg/VolumeHighSvg';
-export * from './assets/svg/VolumeLowSvg';
-export * from './assets/svg/VolumeMuteSvg';
-export * from './common/Box';
-export * from './common/CommonProps';
-export * from './common/Slot';
-export * from './component/accordion/Accordion';
-export * from './component/accordion/AccordionItem';
-export * from './component/accordion/AccordionPanel';
-export * from './component/accordion/AccordionTrigger';
-export * from './component/avatar/Avatar';
-export * from './component/button/Button';
-export * from './component/checkbox/Checkbox';
-export * from './component/icon/Icon';
-export * from './component/theme/Theme';
-export * from './component/theme/ThemeContext';
-export * from './component/theme/useTheme';
-export * from './component/tooltip/Tooltip';
-export * from './component/tooltip/TooltipPopup';
-export * from './component/tooltip/TooltipTrigger';
-export * from './component/username-field/UsernameField';
-export * from './styles/recipe/IinlineSize.recipe';
-export * from './styles/recipe/ItemSize.recipe';
-export * from './styles/recipe/brand.recipe';
-export * from './styles/recipe/variant.recipe';
-export * from '../../css/utils/clspm';
\ No newline at end of file
+import './index.css'
\ No newline at end of file
diff --git a/packages/ui-web/playground/App.tsx b/packages/ui-web/playground/App.tsx
deleted file mode 100644
index 03ffc26..0000000
--- a/packages/ui-web/playground/App.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { useState } from "react";
-
-function App() {
- return
;
-}
-
-export default App;
diff --git a/packages/ui-web/playground/index.html b/packages/ui-web/playground/index.html
deleted file mode 100644
index a3ed15d..0000000
--- a/packages/ui-web/playground/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
- vite-project
-
-
-
-
-
-
diff --git a/packages/ui-web/playground/main.tsx b/packages/ui-web/playground/main.tsx
deleted file mode 100644
index 4aff025..0000000
--- a/packages/ui-web/playground/main.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import App from './App.tsx'
-
-createRoot(document.getElementById('root')!).render(
-
-
- ,
-)
diff --git a/packages/ui-web/scripts/gen-index.ts b/packages/ui-web/scripts/gen-index.ts
deleted file mode 100644
index 64433db..0000000
--- a/packages/ui-web/scripts/gen-index.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-import fs from "fs";
-import path from "path";
-// 1. 引入 tinyglobby
-import { globSync } from "tinyglobby";
-
-interface Config {
- outputDir: string;
- outputFilenameWithExt: string;
- scanDirs: string[];
- importPrefix: string;
- predefineStatements: string[];
- includeExtensions: string[];
- excludeDirs: string[];
- excludeFileExtensions: string[];
- excludePatterns: RegExp[];
-}
-
-const cssConfig: Config = {
- outputDir: "src",
- outputFilenameWithExt: "index.css",
- scanDirs: ["src"],
- importPrefix: "@import",
- predefineStatements: [],
- includeExtensions: [".css"],
- excludeDirs: ["__tests__", "tests", "story", "stories", "types"],
- excludeFileExtensions: [],
- excludePatterns: [/^index\.(css)$/, /\.(test|spec)\./, /\.(story|stories)\./],
-};
-
-const tsConfig: Config = {
- outputDir: "src",
- outputFilenameWithExt: "index.ts",
- scanDirs: ["src"],
- importPrefix: "export * from",
- predefineStatements: ["import './index.css'"],
- includeExtensions: [".ts", "tsx", "js", "jsx"],
- excludeDirs: ["__tests__", "tests", "story", "stories", "types"],
- excludeFileExtensions: [".d.ts"],
- excludePatterns: [
- /^index\.(ts|tsx|js|jsx)$/,
- /\.(test|spec)\./,
- /\.(story|stories)\./,
- ],
-};
-
-const normalizePath = (p: string) => p.replace(/\\/g, "/");
-
-const isExcludeDir = (filePath: string, excludeDirs: string[]) => {
- const normalized = normalizePath(filePath);
- return excludeDirs.some((dir) => normalized.includes(`/${dir}/`));
-};
-
-const isExcludeFileExtensions = (
- filePath: string,
- excludeFileExtensions: string[],
-) => excludeFileExtensions.some((ext) => filePath.endsWith(ext));
-
-const isExcludePattern = (fileName: string, excludePatterns: RegExp[]) =>
- excludePatterns.some((pattern) => pattern.test(fileName));
-
-// ----------------------------------------
-function isValidFile(filePath: string, config: Config): boolean {
- const fileName = filePath.split(/[\\/]/).pop()!;
-
- if (isExcludeDir(filePath, config.excludeDirs)) return false;
- if (isExcludeFileExtensions(filePath, config.excludeFileExtensions))
- return false;
- if (isExcludePattern(fileName, config.excludePatterns)) return false;
-
- const ext = path.extname(filePath);
- return config.includeExtensions.includes(ext);
-}
-// -----------------------------------------
-function generateIndexFile(config: Config) {
- const currentPath = process.cwd();
- const outputPath = path.resolve(currentPath, config.outputDir);
- let exportStatements: string[] = [];
-
- // ------ scanDirs forEach start ------------------------
- config.scanDirs.forEach((dir) => {
- // 2. 路径模式保持不变,tinyglobby 能够正确处理
- const scanPattern = path.resolve(currentPath, dir, "**", "*.*");
-
- const allFilePath = globSync(scanPattern, {
- absolute: true,
- // 3. 移除了 windowsPathsNoEscape,tinyglobby 默认处理路径更智能
- });
-
- const validFiles = allFilePath.filter((filePath) => {
- return isValidFile(filePath, config);
- });
-
- if (validFiles.length === 0) {
- console.log(
- `⚠️ 未找到符合条件的文件,跳过生成 ${config.outputFilenameWithExt}`,
- );
- return;
- }
-
- validFiles.sort();
-
- validFiles.forEach((file) => {
- const relativePath = path.relative(outputPath, file);
- const importPath = `./${relativePath.replace(/\\/g, "/")}`;
- exportStatements.push(`${config.importPrefix} '${importPath}';`);
- });
- });
-
- // --------- scanDirs forEach end ----------------
-
- const indexFileContent = `
-${config.predefineStatements.join("\n")}
-${exportStatements.join("\n")}
-`.trim();
-
- const indexFilePath = path.resolve(
- currentPath,
- config.outputDir,
- config.outputFilenameWithExt,
- );
-
- // ✅ 内容比对,避免重复写入
- if (fs.existsSync(indexFilePath)) {
- const old = fs.readFileSync(indexFilePath, "utf8");
- if (old === indexFileContent) {
- console.log(
- `✅ ${config.outputFilenameWithExt} 内容无变化,无需重新生成`,
- );
- return;
- }
- }
-
- fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
- console.log(`✅ 成功生成 ${config.outputFilenameWithExt}: ${indexFilePath}`);
-}
-
-// --------------------------------------------------
-
-try {
- console.log(`🚀 [gen-index] 开始扫描`);
- generateIndexFile(cssConfig);
- generateIndexFile(tsConfig);
-} catch (err) {
- const msg = err instanceof Error ? err.message : String(err);
- console.error(`❌ [gen-index] 执行失败: ${msg}`);
- process.exit(1);
-}
diff --git a/packages/ui-web/src/componnets/button/ButtonIcon.tsx b/packages/ui-web/src/componnets/button/ButtonIcon.tsx
deleted file mode 100644
index 93df617..0000000
--- a/packages/ui-web/src/componnets/button/ButtonIcon.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Slot } from "../../utils/Slot";
-
-export const ButtonIcon = (props: any) => {
- const { children, ...rest } = props;
- return {children};
-};
-ButtonIcon.displayName = "ButtonIcon";
diff --git a/packages/ui-web/src/componnets/button/ButtonLoading.tsx b/packages/ui-web/src/componnets/button/ButtonLoading.tsx
deleted file mode 100644
index af1932a..0000000
--- a/packages/ui-web/src/componnets/button/ButtonLoading.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Slot } from "../../utils/Slot";
-
-export const ButtonLoading = (props: any) => {
- const { children, ...rest } = props;
- return {children};
-};
-ButtonLoading.displayName = "ButtonLoading";
diff --git a/packages/ui-web/src/componnets/button/ButtonRoot.tsx b/packages/ui-web/src/componnets/button/ButtonRoot.tsx
deleted file mode 100644
index dbd628d..0000000
--- a/packages/ui-web/src/componnets/button/ButtonRoot.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { type ComponentPropsWithoutRef, forwardRef } from "react";
-import { useButtonSlot } from "./useButtonSlots";
-import { useStateProps } from "../../utils/useStateProps";
-
-export type ButtonRootOwnProps = {
- iconOnly?: boolean;
- hideIcon?: boolean;
- loading?: boolean;
-};
-
-export type ButtonRootStateProps = {
- disabled?: boolean;
-};
-
-export type ButtonRootPrimitiveProps = Omit<
- ComponentPropsWithoutRef<"button">,
- keyof ButtonRootStateProps
->;
-
-export type ButtonRootProps = ButtonRootOwnProps &
- ButtonRootStateProps &
- ButtonRootPrimitiveProps;
-
-export const ButtonRoot = forwardRef(
- (props, ref) => {
- const {
- children,
- loading,
- iconOnly,
- hideIcon,
- disabled = false,
- ...rest
- } = props;
- const stateProps = useStateProps({ disabled: disabled });
- const filteredChildren = useButtonSlot(children, props);
-
- return (
-
- );
- },
-);
-ButtonRoot.displayName = "ButtonRoot";
diff --git a/packages/ui-web/src/componnets/button/useButtonSlots.ts b/packages/ui-web/src/componnets/button/useButtonSlots.ts
deleted file mode 100644
index 64affd3..0000000
--- a/packages/ui-web/src/componnets/button/useButtonSlots.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import {
- type ReactNode,
- Children,
- isValidElement,
- cloneElement,
- type ReactElement,
-} from "react";
-
-import { ButtonIcon } from "./ButtonIcon";
-import { ButtonLoading } from "./ButtonLoading";
-
-export function useButtonSlot(
- children: ReactNode,
- props: { hideIcon?: boolean; loading?: boolean },
-) {
- const filterNodes = (nodes: ReactNode): ReactNode => {
- // 存储挑出 Slot 后的纯净 children
- const filtered: ReactNode[] = [];
-
- Children.forEach(nodes, (child: any) => {
- if (!isValidElement(child)) {
- filtered.push(child);
- return;
- }
-
- // loading:只保留 Loading
- if (props.loading) {
- if (child.type === ButtonLoading) {
- filtered.push(child);
- }
- return;
- }
-
- // 隐藏图标:移除 ButtonIcon
- if (props.hideIcon && child.type === ButtonIcon) {
- return;
- }
-
- // 普通节点
- const element = child as ReactElement<{ children?: ReactNode }>;
-
- filtered.push(
- cloneElement(element, {
- children: filterNodes(element.props.children),
- }),
- );
- });
-
- return filtered;
- };
-
- return filterNodes(children);
-}
diff --git a/packages/ui-web/src/styles/recipe/inlineSizeRecipe.ts b/packages/ui-web/src/styles/recipe/inlineSizeRecipe.ts
deleted file mode 100644
index 3e68858..0000000
--- a/packages/ui-web/src/styles/recipe/inlineSizeRecipe.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { cvr } from "../utils/cvr";
-
-export const inlineSizeRecipe = cvr({
- base: "flex flex-nowrap justify-center items-center",
- variants: {
- size: {
- xs: "text-xs h-inline-xs gap-xs",
- sm: "text-sm h-inline-sm gap-sm",
- md: "text-md h-inline-md gap-md",
- lg: "text-lg h-inline-lg gap-lg",
- xl: "text-xl h-inline-xl gap-xl",
- "2xl": "text-2xl h-inline-2xl gap-2xl",
- },
- },
-});
diff --git a/packages/ui-web/src/styles/recipe/itemSizeRecipe.ts b/packages/ui-web/src/styles/recipe/itemSizeRecipe.ts
deleted file mode 100644
index 68ccf6b..0000000
--- a/packages/ui-web/src/styles/recipe/itemSizeRecipe.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { cvr } from "../utils/cvr";
-
-export const itemSizeRecipe = cvr({
- base: "relative select-none display-flex flex-nowrap justify-center items-center",
- variants: {
- size: {
- xs: "text-xs h-item-xs gap-xs px-xs",
- sm: "text-sm h-item-sm gap-sm px-sm",
- md: "text-md h-item-md gap-md px-md",
- lg: "text-lg h-item-lg gap-lg px-lg",
- xl: "text-xl h-item-xl gap-xl px-xl",
- "2xl": "text-2xl h-item-2xl gap-2xl px-2xl",
- },
- shape: {
- square: "rounded-none",
- rounded: "",
- circle: "rounded-full",
- },
- iconOnly: {
- true: "px-none",
- false: "",
- },
- },
- compoundVariants: [
- { iconOnly: false, size: "xs", class: "px-xs" },
- { iconOnly: false, size: "sm", class: "px-sm" },
- { iconOnly: false, size: "md", class: "px-md" },
- { iconOnly: false, size: "lg", class: "px-lg" },
- { iconOnly: false, size: "xl", class: "px-xl" },
- { iconOnly: false, size: "2xl", class: "px-2xl" },
- { shape: "rounded", size: "xs", class: "rounded-sm" },
- // ==================================================
- {
- shape: "rounded",
- size: "sm",
- class: "rounded-md",
- },
- {
- shape: "rounded",
- size: "md",
- class: "rounded-lg",
- },
- {
- shape: "rounded",
- size: "lg",
- class: "rounded-xl",
- },
- {
- shape: "rounded",
- size: "xl",
- class: "rounded-2xl",
- },
- {
- shape: "rounded",
- size: "2xl",
- class: "rounded-3xl",
- },
- // ==================================================
- {
- iconOnly: true,
- size: "xs",
- class: "w-item-xs",
- },
- {
- iconOnly: true,
- size: "sm",
- class: "w-item-sm",
- },
- {
- iconOnly: true,
- size: "md",
- class: "w-item-md",
- },
- {
- iconOnly: true,
- size: "lg",
- class: "w-item-lg",
- },
- {
- iconOnly: true,
- size: "xl",
- class: "w-item-xl",
- },
- {
- iconOnly: true,
- size: "2xl",
- class: "w-item-2xl",
- },
- ],
-});
diff --git a/packages/ui-web/src/styles/utility/size-insensitive/position.css b/packages/ui-web/src/styles/utility/size-insensitive/position.css
deleted file mode 100644
index 70d3bb9..0000000
--- a/packages/ui-web/src/styles/utility/size-insensitive/position.css
+++ /dev/null
@@ -1,21 +0,0 @@
-@layer utility {
- .position--static {
- position: static;
- }
-
- .position--fixed {
- position: fixed;
- }
-
- .position--absolute {
- position: absolute;
- }
-
- .position--relative {
- position: relative;
- }
-
- .position--sticky {
- position: sticky;
- }
-}
diff --git a/packages/ui-web/src/styles/utility/size-sensitive/margin-block.css b/packages/ui-web/src/styles/utility/size-sensitive/margin-block.css
deleted file mode 100644
index 6d949be..0000000
--- a/packages/ui-web/src/styles/utility/size-sensitive/margin-block.css
+++ /dev/null
@@ -1,67 +0,0 @@
-@layer utility {
- .my--e--none {
- margin-block-end: 0;
- }
- .my--e--xs {
- margin-block-end: var(--margin-xs);
- }
- .my--e--sm {
- margin-block-end: var(--margin-sm);
- }
- .my--e--md {
- margin-block-end: var(--margin-md);
- }
- .my--e--lg {
- margin-block-end: var(--margin-lg);
- }
- .my--e--xl {
- margin-block-end: var(--margin-xl);
- }
- .my--e--2xl {
- margin-block-end: var(--margin-2xl);
- }
- /* ------------------ */
- .my--s--none {
- margin-block-start: 0;
- }
- .my--s--xs {
- margin-block-start: var(--margin-xs);
- }
- .my--s--sm {
- margin-block-start: var(--margin-sm);
- }
- .my--s--md {
- margin-block-start: var(--margin-md);
- }
- .my--s--lg {
- margin-block-start: var(--margin-lg);
- }
- .my--s--xl {
- margin-block-start: var(--margin-xl);
- }
- .my--s--2xl {
- margin-block-start: var(--margin-2xl);
- }
- /* --------------------- */
- .my--none {
- margin-block: 0;
- }
- .my--xs {
- margin-block: var(--margin-xs);
- }
- .my--sm {
- margin-block: var(--margin-sm);
- }
- .my--md {
- margin-block: var(--margin-md);
- }
- .my--lg {
- margin-block: var(--margin-lg);
- }
- .my--xl {
- margin-block: var(--margin-xl);
- }
- .my--2xl {
- margin-block: var(--margin-2xl);
- }
-}
diff --git a/packages/ui-web/src/styles/utility/size-sensitive/margin-inline.css b/packages/ui-web/src/styles/utility/size-sensitive/margin-inline.css
deleted file mode 100644
index bc215b0..0000000
--- a/packages/ui-web/src/styles/utility/size-sensitive/margin-inline.css
+++ /dev/null
@@ -1,67 +0,0 @@
-@layer utility {
- .mx--e--none {
- margin-inline-end: 0;
- }
- .mx--e--xs {
- margin-inline-end: var(--margin-xs);
- }
- .mx--e--sm {
- margin-inline-end: var(--margin-sm);
- }
- .mx--e--md {
- margin-inline-end: var(--margin-md);
- }
- .mx--e--lg {
- margin-inline-end: var(--margin-lg);
- }
- .mx--e--xl {
- margin-inline-end: var(--margin-xl);
- }
- .mx--e--2xl {
- margin-inline-end: var(--margin-2xl);
- }
- /* ------------------ */
- .mx--s--none {
- margin-inline-start: 0;
- }
- .mx--s--xs {
- margin-inline-start: var(--margin-xs);
- }
- .mx--s--sm {
- margin-inline-start: var(--margin-sm);
- }
- .mx--s--md {
- margin-inline-start: var(--margin-md);
- }
- .mx--s--lg {
- margin-inline-start: var(--margin-lg);
- }
- .mx--s--xl {
- margin-inline-start: var(--margin-xl);
- }
- .mx--s--2xl {
- margin-inline-start: var(--margin-2xl);
- }
- /* --------------------- */
- .mx--none {
- margin-inline: 0;
- }
- .mx--xs {
- margin-inline: var(--margin-xs);
- }
- .mx--sm {
- margin-inline: var(--margin-sm);
- }
- .mx--md {
- margin-inline: var(--margin-md);
- }
- .mx--lg {
- margin-inline: var(--margin-lg);
- }
- .mx--xl {
- margin-inline: var(--margin-xl);
- }
- .mx--2xl {
- margin-inline: var(--margin-2xl);
- }
-}
diff --git a/packages/ui-web/src/styles/utility/size-sensitive/padding-long.css b/packages/ui-web/src/styles/utility/size-sensitive/padding-long.css
deleted file mode 100644
index dea45ad..0000000
--- a/packages/ui-web/src/styles/utility/size-sensitive/padding-long.css
+++ /dev/null
@@ -1,24 +0,0 @@
-@layer utility {
- .px--long--xs {
- /* 6px */
- padding-inline: var(--padding-long-xs);
- }
- .px--long--sm {
- /* 8px */
- padding-inline: var(--padding-long-sm);
- }
- .px--long--md {
- /* 10px */
- padding-inline: var(--padding-long-md);
- }
- .px--long--lg {
- /* 16px */
- padding-inline: var(--padding-long-lg);
- }
- .px--long--xl {
- padding-inline: var(--padding-long-xl);
- }
- .px--long--2xl {
- padding-inline: var(--padding-long-2xl);
- }
-}
diff --git a/packages/ui-web/src/styles/utils/cpm.ts b/packages/ui-web/src/styles/utils/cpm.ts
deleted file mode 100644
index 83ee851..0000000
--- a/packages/ui-web/src/styles/utils/cpm.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-export function cpm(...classes: (string[] | string)[]) {
- const map = new Map();
-
- function dealClass(cls: string) {
- // 提取多段 prefix,以“--”为分隔符
- const fragments = cls.split("--");
- // 前缀后面剩下的部分
- const suffix = fragments.pop() ?? "";
- // ['1', '1--2', '1--2--3']
- const stepwisePrefixList = fragments.map((_, index, array) => {
- if (index === 0) return array[0];
- // 截取子数组(注意不是子字符串)
- return array.slice(0, index + 1).join("--");
- });
-
- // 覆盖,短前缀
- stepwisePrefixList.forEach((key) => {
- map.delete(key);
- });
- // 覆盖延长前缀,overflow--x 会覆盖 overflow--x--l
- // 不覆盖分支前缀,overflow--x 不会覆盖 overfl--y
- for (const key of map.keys()) {
- if (key.includes(stepwisePrefixList[-1])) {
- // 包含 overflow--x 的全部删除
- map.delete(key);
- }
- }
- // 把本次值加进去
- map.set(stepwisePrefixList[-1], suffix);
- }
-
- classes.forEach((item) => {
- // 如果是 string 直接处理
- if (typeof item === "string") {
- dealClass(item);
- } else {
- // 否则肯定是 string[]
- item.forEach((i) => {
- dealClass(i);
- });
- }
- });
-
- const resultString = [...map]
- .map(([key, value]) => `${key}--${value}`)
- .join(" ");
-
- return resultString;
-}
diff --git a/packages/ui-web/src/utils/mergeProps.ts b/packages/ui-web/src/utils/mergeProps.ts
deleted file mode 100644
index 748f1fa..0000000
--- a/packages/ui-web/src/utils/mergeProps.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-function defaultClassMergeFn(...classes: string[]): string {
- return classes
- .map((str) => str.trim())
- .filter(Boolean)
- .join(" ")
- .trim();
-}
-
-// 重载1
-export function mergeProps(
- ...propsN: Record[]
-): Record;
-
-// 重载2
-export function mergeProps(
- options: { classMergeFn: Function },
- ...propsN: Record[]
-): Record;
-
-// 实现
-export function mergeProps(
- arg1: { classMergeFn: Function } | Record,
- ...rest: Record[]
-) {
- let options: { classMergeFn: Function } = {
- classMergeFn: defaultClassMergeFn,
- };
- let propsN: Record[];
-
- if (
- arg1 &&
- typeof arg1 === "object" &&
- !Array.isArray(arg1) &&
- "classMergeFn" in arg1 &&
- typeof (arg1 as any).classMergeFn === "function"
- ) {
- options = arg1 as { classMergeFn: Function };
- propsN = rest;
- } else {
- propsN = [arg1 as Record, ...rest];
- }
- // --------------------------------
- const result: any = {};
- const eventHandlerMap = new Map();
- const refs: any[] = [];
-
- propsN.forEach((props) => {
- if (!props) return;
-
- if (props.className) {
- result.className = options.classMergeFn(
- result.className || "",
- props.className,
- );
- }
-
- if (props.style) {
- result.style = { ...(result.style || {}), ...props.style };
- }
-
- if (props.ref) {
- refs.push(props.ref);
- }
-
- Object.keys(props).forEach((key) => {
- if (key.startsWith("on") && typeof props[key] === "function") {
- if (!eventHandlerMap.has(key)) {
- eventHandlerMap.set(key, []);
- }
- eventHandlerMap.get(key)!.push(props[key]);
- } else if (key !== "ref" && key !== "className" && key !== "style") {
- // 其他普通属性,后面的覆盖前面的
- result[key] = props[key];
- }
- });
- });
-
- // 合并 Refs
- if (refs.length > 0) {
- if (refs.length === 1) {
- result.ref = refs[0];
- } else {
- result.ref = (node: any) => {
- refs.forEach((ref) => {
- if (typeof ref === "function") {
- ref(node);
- } else if (ref) {
- ref.current = node;
- }
- });
- };
- }
- }
-
- // 合并事件处理器
- eventHandlerMap.forEach((handlers, key) => {
- result[key] = (...args: any[]) => {
- handlers.forEach((handler) => handler(...args));
- };
- });
-
- return result;
-}
diff --git a/packages/ui-web/src/utils/useStateProps.ts b/packages/ui-web/src/utils/useStateProps.ts
deleted file mode 100644
index c9e1485..0000000
--- a/packages/ui-web/src/utils/useStateProps.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export function useStateProps(props: Record) {
- const state: Record = {};
-
- Object.entries(props).forEach(([key, value]) => {
- const stateKey = `data-${key}:`;
- const stateValue = `"${value}"`;
-
- state[stateKey] = stateValue;
- });
-
- return state;
-}
diff --git a/packages/ui-web/vite.config.ts b/packages/ui-web/vite.config.ts
deleted file mode 100644
index 4418ded..0000000
--- a/packages/ui-web/vite.config.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { defineConfig } from "vite";
-import react from "@vitejs/plugin-react";
-import path from "path";
-
-export default defineConfig(({ command }) => {
- if (command === "serve") {
- return {
- plugins: [react()],
- root: "playground",
- };
- }
-
- return {
- plugins: [react()],
-
- build: {
- cssMinify: false,
-
- lib: {
- entry: path.resolve(import.meta.dirname, "src/index.ts"),
- formats: ["es", "cjs"],
- fileName: (format) => `index.${format}.js`,
- },
-
- rolldownOptions: {
- external: ["react", "react-dom", "react/jsx-runtime"],
- output: {
- globals: {
- react: "React",
- "react-dom": "ReactDOM",
- },
- },
- },
-
- emptyOutDir: true,
- sourcemap: true,
- cssCodeSplit: false,
- outDir: "dist",
- },
- };
-});
diff --git a/apps/vite-project/.gitignore b/playground/ui-gallery/.gitignore
similarity index 100%
rename from apps/vite-project/.gitignore
rename to playground/ui-gallery/.gitignore
diff --git a/apps/vite-project/README.md b/playground/ui-gallery/README.md
similarity index 100%
rename from apps/vite-project/README.md
rename to playground/ui-gallery/README.md
diff --git a/apps/vite-project/eslint.config.js b/playground/ui-gallery/eslint.config.js
similarity index 100%
rename from apps/vite-project/eslint.config.js
rename to playground/ui-gallery/eslint.config.js
diff --git a/apps/vite-project/index.html b/playground/ui-gallery/index.html
similarity index 91%
rename from apps/vite-project/index.html
rename to playground/ui-gallery/index.html
index 1a2df5a..a5fcab6 100644
--- a/apps/vite-project/index.html
+++ b/playground/ui-gallery/index.html
@@ -4,7 +4,7 @@
- vite-project
+ ui-gallery
diff --git a/apps/vite-project/package.json b/playground/ui-gallery/package.json
similarity index 66%
rename from apps/vite-project/package.json
rename to playground/ui-gallery/package.json
index d525600..be41462 100644
--- a/apps/vite-project/package.json
+++ b/playground/ui-gallery/package.json
@@ -1,5 +1,5 @@
{
- "name": "vite-project",
+ "name": "ui-gallery",
"private": true,
"version": "0.0.0",
"type": "module",
@@ -10,21 +10,22 @@
"preview": "vite preview"
},
"dependencies": {
- "react": "^19.2.5",
- "react-dom": "^19.2.5"
+ "react": "^19.2.6",
+ "react-dom": "^19.2.6",
+ "@dg/ui-react": "workspace:*"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
- "@types/node": "^24.12.2",
+ "@types/node": "^24.12.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
- "eslint": "^10.2.1",
+ "eslint": "^10.3.0",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
- "globals": "^17.5.0",
+ "globals": "^17.6.0",
"typescript": "~6.0.2",
- "typescript-eslint": "^8.58.2",
- "vite": "^8.0.10"
+ "typescript-eslint": "^8.59.2",
+ "vite": "^8.0.12"
}
}
diff --git a/playground/ui-gallery/public/favicon.svg b/playground/ui-gallery/public/favicon.svg
new file mode 100644
index 0000000..6893eb1
--- /dev/null
+++ b/playground/ui-gallery/public/favicon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/playground/ui-gallery/public/icons.svg b/playground/ui-gallery/public/icons.svg
new file mode 100644
index 0000000..e952219
--- /dev/null
+++ b/playground/ui-gallery/public/icons.svg
@@ -0,0 +1,24 @@
+
diff --git a/playground/ui-gallery/src/App.tsx b/playground/ui-gallery/src/App.tsx
new file mode 100644
index 0000000..8b939ca
--- /dev/null
+++ b/playground/ui-gallery/src/App.tsx
@@ -0,0 +1,12 @@
+import { ButtonGallery } from "./gallery/ButtonGallery";
+import "@dg/ui-react/index.css";
+
+function App() {
+ return (
+
+
+
+ );
+}
+
+export default App;
diff --git a/playground/ui-gallery/src/common/IW.tsx b/playground/ui-gallery/src/common/IW.tsx
new file mode 100644
index 0000000..a8b0ac5
--- /dev/null
+++ b/playground/ui-gallery/src/common/IW.tsx
@@ -0,0 +1,15 @@
+import type { ReactNode } from "react";
+
+export const IW = ({ children }: { children: ReactNode }) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/apps/vite-project/src/common/OuterWrapper.tsx b/playground/ui-gallery/src/common/OW.tsx
similarity index 58%
rename from apps/vite-project/src/common/OuterWrapper.tsx
rename to playground/ui-gallery/src/common/OW.tsx
index a17491a..1cc77b5 100644
--- a/apps/vite-project/src/common/OuterWrapper.tsx
+++ b/playground/ui-gallery/src/common/OW.tsx
@@ -1,14 +1,13 @@
-import { type ReactNode } from "react";
+import type { ReactNode } from "react";
-export const OuterWrapper = ({ children }: { children: ReactNode }) => {
+export const OW = ({ children }: { children: ReactNode }) => {
return (
{children}
diff --git a/playground/ui-gallery/src/gallery/ButtonGallery.tsx b/playground/ui-gallery/src/gallery/ButtonGallery.tsx
new file mode 100644
index 0000000..14fe531
--- /dev/null
+++ b/playground/ui-gallery/src/gallery/ButtonGallery.tsx
@@ -0,0 +1,18 @@
+import { Button, DownloadSvg } from "@dg/ui-react";
+import { IW } from "../common/IW";
+import { OW } from "../common/OW";
+
+export const ButtonGallery = () => {
+ return (
+
+
+
+
+
+
+ Default
+
+
+
+ );
+};
diff --git a/playground/ui-gallery/src/main.tsx b/playground/ui-gallery/src/main.tsx
new file mode 100644
index 0000000..5d4a2be
--- /dev/null
+++ b/playground/ui-gallery/src/main.tsx
@@ -0,0 +1,9 @@
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import App from "./App.tsx";
+
+createRoot(document.getElementById("root")!).render(
+
+
+ ,
+);
diff --git a/apps/vite-project/tsconfig.app.json b/playground/ui-gallery/tsconfig.app.json
similarity index 100%
rename from apps/vite-project/tsconfig.app.json
rename to playground/ui-gallery/tsconfig.app.json
diff --git a/apps/vite-project/tsconfig.json b/playground/ui-gallery/tsconfig.json
similarity index 100%
rename from apps/vite-project/tsconfig.json
rename to playground/ui-gallery/tsconfig.json
diff --git a/apps/vite-project/tsconfig.node.json b/playground/ui-gallery/tsconfig.node.json
similarity index 100%
rename from apps/vite-project/tsconfig.node.json
rename to playground/ui-gallery/tsconfig.node.json
diff --git a/playground/ui-gallery/vite.config.ts b/playground/ui-gallery/vite.config.ts
new file mode 100644
index 0000000..8b0f57b
--- /dev/null
+++ b/playground/ui-gallery/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [react()],
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2c29e74..235cabe 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,74 +12,6 @@ importers:
specifier: ^2.8.0
version: 2.9.12
- apps/vite-project:
- dependencies:
- react:
- specifier: ^19.2.5
- version: 19.2.6
- react-dom:
- specifier: ^19.2.5
- version: 19.2.6(react@19.2.6)
- devDependencies:
- '@eslint/js':
- specifier: ^10.0.1
- version: 10.0.1(eslint@10.3.0(jiti@2.7.0))
- '@types/node':
- specifier: ^24.12.2
- version: 24.12.3
- '@types/react':
- specifier: ^19.2.14
- version: 19.2.14
- '@types/react-dom':
- specifier: ^19.2.3
- version: 19.2.3(@types/react@19.2.14)
- '@vitejs/plugin-react':
- specifier: ^6.0.1
- version: 6.0.1(vite@8.0.12(@types/node@24.12.3)(jiti@2.7.0))
- eslint:
- specifier: ^10.2.1
- version: 10.3.0(jiti@2.7.0)
- eslint-plugin-react-hooks:
- specifier: ^7.1.1
- version: 7.1.1(eslint@10.3.0(jiti@2.7.0))
- eslint-plugin-react-refresh:
- specifier: ^0.5.2
- version: 0.5.2(eslint@10.3.0(jiti@2.7.0))
- globals:
- specifier: ^17.5.0
- version: 17.6.0
- typescript:
- specifier: ~6.0.2
- version: 6.0.3
- typescript-eslint:
- specifier: ^8.58.2
- version: 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- vite:
- specifier: ^8.0.10
- version: 8.0.12(@types/node@24.12.3)(jiti@2.7.0)
-
- packages/bookmark-sync:
- dependencies:
- typescript:
- specifier: ^6.0.3
- version: 6.0.3
- devDependencies:
- '@types/chrome':
- specifier: ^0.1.40
- version: 0.1.42
- '@types/firefox-webext-browser':
- specifier: ^143.0.0
- version: 143.0.0
- '@types/node':
- specifier: ^25.6.0
- version: 25.6.2
- '@types/webextension-polyfill':
- specifier: ^0.12.5
- version: 0.12.5
- webextension-polyfill:
- specifier: ^0.12.0
- version: 0.12.0
-
packages/css:
dependencies:
react:
@@ -114,8 +46,11 @@ importers:
specifier: ^8.0.10
version: 8.0.12(@types/node@25.6.2)(jiti@2.7.0)
- packages/ui-web-headless:
+ packages/ui-react:
dependencies:
+ '@dg/css':
+ specifier: workspace:*
+ version: link:../css
react:
specifier: ^19
version: 19.2.6
@@ -197,18 +132,24 @@ importers:
specifier: ^8.0.12
version: 8.0.12(@types/node@25.6.2)(jiti@2.7.0)
- templates/vite-react-lib:
+ playground/ui-gallery:
dependencies:
+ '@dg/ui-react':
+ specifier: workspace:*
+ version: link:../../packages/ui-react
react:
- specifier: ^19
+ specifier: ^19.2.6
version: 19.2.6
react-dom:
- specifier: ^19
+ specifier: ^19.2.6
version: 19.2.6(react@19.2.6)
devDependencies:
+ '@eslint/js':
+ specifier: ^10.0.1
+ version: 10.0.1(eslint@10.4.0(jiti@2.7.0))
'@types/node':
- specifier: ^25.6.0
- version: 25.6.2
+ specifier: ^24.12.3
+ version: 24.12.4
'@types/react':
specifier: ^19.2.14
version: 19.2.14
@@ -217,19 +158,28 @@ importers:
version: 19.2.3(@types/react@19.2.14)
'@vitejs/plugin-react':
specifier: ^6.0.1
- version: 6.0.1(vite@8.0.12(@types/node@25.6.2)(jiti@2.7.0))
- tinyglobby:
- specifier: ^0.2.16
- version: 0.2.16
- ts-node:
- specifier: ^10.9.2
- version: 10.9.2(@types/node@25.6.2)(typescript@6.0.3)
+ version: 6.0.1(vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0))
+ eslint:
+ specifier: ^10.3.0
+ version: 10.4.0(jiti@2.7.0)
+ eslint-plugin-react-hooks:
+ specifier: ^7.1.1
+ version: 7.1.1(eslint@10.4.0(jiti@2.7.0))
+ eslint-plugin-react-refresh:
+ specifier: ^0.5.2
+ version: 0.5.2(eslint@10.4.0(jiti@2.7.0))
+ globals:
+ specifier: ^17.6.0
+ version: 17.6.0
typescript:
- specifier: ^6.0.3
+ specifier: ~6.0.2
version: 6.0.3
+ typescript-eslint:
+ specifier: ^8.59.2
+ version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
vite:
- specifier: ^8.0.10
- version: 8.0.12(@types/node@25.6.2)(jiti@2.7.0)
+ specifier: ^8.0.12
+ version: 8.0.12(@types/node@24.12.4)(jiti@2.7.0)
packages:
@@ -253,8 +203,8 @@ packages:
resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==}
engines: {node: '>=6.9.0'}
- '@babel/helper-globals@7.28.0':
- resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
+ '@babel/helper-globals@7.29.7':
+ resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==}
engines: {node: '>=6.9.0'}
'@babel/helper-module-imports@7.28.6':
@@ -267,16 +217,16 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0
- '@babel/helper-string-parser@7.27.1':
- resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ '@babel/helper-string-parser@7.29.7':
+ resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
engines: {node: '>=6.9.0'}
- '@babel/helper-validator-identifier@7.28.5':
- resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ '@babel/helper-validator-identifier@7.29.7':
+ resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
engines: {node: '>=6.9.0'}
- '@babel/helper-validator-option@7.27.1':
- resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
+ '@babel/helper-validator-option@7.29.7':
+ resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
engines: {node: '>=6.9.0'}
'@babel/helpers@7.29.2':
@@ -358,8 +308,8 @@ packages:
resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
- '@eslint/config-helpers@0.5.5':
- resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==}
+ '@eslint/config-helpers@0.6.0':
+ resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
'@eslint/core@1.2.1':
@@ -694,32 +644,17 @@ packages:
'@tybys/wasm-util@0.10.2':
resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
- '@types/chrome@0.1.42':
- resolution: {integrity: sha512-tdT2roFqGecZZDjA9fUEAINb2STxSPifHMDvY6EfRjNRCjdrs/0FwKt5RCIA9MKMd1arAYZZL3nwEkp6ZLZu2w==}
-
'@types/esrecurse@4.3.1':
resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==}
'@types/estree@1.0.9':
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
- '@types/filesystem@0.0.36':
- resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==}
-
- '@types/filewriter@0.0.33':
- resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==}
-
- '@types/firefox-webext-browser@143.0.0':
- resolution: {integrity: sha512-865dYKMOP0CllFyHmgXV4IQgVL51OSQQCwSoihQ17EwugePKFSAZRc0EI+y7Ly4q7j5KyURlA7LgRpFieO4JOw==}
-
- '@types/har-format@1.2.16':
- resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==}
-
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
- '@types/node@24.12.3':
- resolution: {integrity: sha512-8oljBDGun9cIsZRJR6fkihn0TSXJI0UDOOhncYaERq6M0JMDoPLxyscwruJcb4GKS6dvK/d8xebYBg27h/duaQ==}
+ '@types/node@24.12.4':
+ resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==}
'@types/node@25.6.2':
resolution: {integrity: sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw==}
@@ -732,66 +667,63 @@ packages:
'@types/react@19.2.14':
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
- '@types/webextension-polyfill@0.12.5':
- resolution: {integrity: sha512-uKSAv6LgcVdINmxXMKBuVIcg/2m5JZugoZO8x20g7j2bXJkPIl/lVGQcDlbV+aXAiTyXT2RA5U5mI4IGCDMQeg==}
-
- '@typescript-eslint/eslint-plugin@8.59.3':
- resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==}
+ '@typescript-eslint/eslint-plugin@8.59.4':
+ resolution: {integrity: sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- '@typescript-eslint/parser': ^8.59.3
+ '@typescript-eslint/parser': ^8.59.4
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/parser@8.59.3':
- resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==}
+ '@typescript-eslint/parser@8.59.4':
+ resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/project-service@8.59.3':
- resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==}
+ '@typescript-eslint/project-service@8.59.4':
+ resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/scope-manager@8.59.3':
- resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==}
+ '@typescript-eslint/scope-manager@8.59.4':
+ resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/tsconfig-utils@8.59.3':
- resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==}
+ '@typescript-eslint/tsconfig-utils@8.59.4':
+ resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/type-utils@8.59.3':
- resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==}
+ '@typescript-eslint/type-utils@8.59.4':
+ resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/types@8.59.3':
- resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==}
+ '@typescript-eslint/types@8.59.4':
+ resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/typescript-estree@8.59.3':
- resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==}
+ '@typescript-eslint/typescript-estree@8.59.4':
+ resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/utils@8.59.3':
- resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==}
+ '@typescript-eslint/utils@8.59.4':
+ resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/visitor-keys@8.59.3':
- resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==}
+ '@typescript-eslint/visitor-keys@8.59.4':
+ resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@vitejs/plugin-react@6.0.1':
@@ -850,8 +782,8 @@ packages:
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
- baseline-browser-mapping@2.10.29:
- resolution: {integrity: sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==}
+ baseline-browser-mapping@2.10.32:
+ resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==}
engines: {node: '>=6.0.0'}
hasBin: true
@@ -867,8 +799,8 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
- caniuse-lite@1.0.30001792:
- resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==}
+ caniuse-lite@1.0.30001793:
+ resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
@@ -913,8 +845,8 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
- electron-to-chromium@1.5.353:
- resolution: {integrity: sha512-kOrWphBi8TOZyiJZqsgqIle0lw+tzmnQK83pV9dZUd01Nm2POECSyFQMAuarzZdYqQW7FH9RaYOuaRo3h+bQ3w==}
+ electron-to-chromium@1.5.361:
+ resolution: {integrity: sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -957,8 +889,8 @@ packages:
resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
- eslint@10.3.0:
- resolution: {integrity: sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==}
+ eslint@10.4.0:
+ resolution: {integrity: sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
hasBin: true
peerDependencies:
@@ -1233,8 +1165,9 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
- node-releases@2.0.38:
- resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==}
+ node-releases@2.0.46:
+ resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==}
+ engines: {node: '>=18'}
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
@@ -1315,8 +1248,8 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
- semver@7.8.0:
- resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
+ semver@7.8.1:
+ resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==}
engines: {node: '>=10'}
hasBin: true
@@ -1407,8 +1340,8 @@ packages:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
- typescript-eslint@8.59.3:
- resolution: {integrity: sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==}
+ typescript-eslint@8.59.4:
+ resolution: {integrity: sha512-Rw6+44QNFaXtgHSjPy+Kw8hrJniMYzR85E9yLmOLcfZ91/rz+JXQbDTCmc6ccxMPY6K6PgAq26f0JCBfR7LIPQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
@@ -1485,9 +1418,6 @@ packages:
yaml:
optional: true
- webextension-polyfill@0.12.0:
- resolution: {integrity: sha512-97TBmpoWJEE+3nFBQ4VocyCdLKfw54rFaJ6EVQYLBCXqCIpLSZkwGgASpv4oPt9gdKCJ80RJlcmNzNn008Ag6Q==}
-
which@2.0.1:
resolution: {integrity: sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==}
engines: {node: '>= 8'}
@@ -1525,7 +1455,7 @@ snapshots:
'@babel/code-frame@7.29.0':
dependencies:
- '@babel/helper-validator-identifier': 7.28.5
+ '@babel/helper-validator-identifier': 7.29.7
js-tokens: 4.0.0
picocolors: 1.1.1
@@ -1562,12 +1492,12 @@ snapshots:
'@babel/helper-compilation-targets@7.28.6':
dependencies:
'@babel/compat-data': 7.29.3
- '@babel/helper-validator-option': 7.27.1
+ '@babel/helper-validator-option': 7.29.7
browserslist: 4.28.2
lru-cache: 5.1.1
semver: 6.3.1
- '@babel/helper-globals@7.28.0': {}
+ '@babel/helper-globals@7.29.7': {}
'@babel/helper-module-imports@7.28.6':
dependencies:
@@ -1580,16 +1510,16 @@ snapshots:
dependencies:
'@babel/core': 7.29.0
'@babel/helper-module-imports': 7.28.6
- '@babel/helper-validator-identifier': 7.28.5
+ '@babel/helper-validator-identifier': 7.29.7
'@babel/traverse': 7.29.0
transitivePeerDependencies:
- supports-color
- '@babel/helper-string-parser@7.27.1': {}
+ '@babel/helper-string-parser@7.29.7': {}
- '@babel/helper-validator-identifier@7.28.5': {}
+ '@babel/helper-validator-identifier@7.29.7': {}
- '@babel/helper-validator-option@7.27.1': {}
+ '@babel/helper-validator-option@7.29.7': {}
'@babel/helpers@7.29.2':
dependencies:
@@ -1612,7 +1542,7 @@ snapshots:
dependencies:
'@babel/code-frame': 7.29.0
'@babel/generator': 7.29.1
- '@babel/helper-globals': 7.28.0
+ '@babel/helper-globals': 7.29.7
'@babel/parser': 7.29.3
'@babel/template': 7.28.6
'@babel/types': 7.29.0
@@ -1622,8 +1552,8 @@ snapshots:
'@babel/types@7.29.0':
dependencies:
- '@babel/helper-string-parser': 7.27.1
- '@babel/helper-validator-identifier': 7.28.5
+ '@babel/helper-string-parser': 7.29.7
+ '@babel/helper-validator-identifier': 7.29.7
'@base-ui/react@1.4.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
dependencies:
@@ -1668,9 +1598,9 @@ snapshots:
tslib: 2.8.1
optional: true
- '@eslint-community/eslint-utils@4.9.1(eslint@10.3.0(jiti@2.7.0))':
+ '@eslint-community/eslint-utils@4.9.1(eslint@10.4.0(jiti@2.7.0))':
dependencies:
- eslint: 10.3.0(jiti@2.7.0)
+ eslint: 10.4.0(jiti@2.7.0)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.2': {}
@@ -1683,7 +1613,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint/config-helpers@0.5.5':
+ '@eslint/config-helpers@0.6.0':
dependencies:
'@eslint/core': 1.2.1
@@ -1691,9 +1621,9 @@ snapshots:
dependencies:
'@types/json-schema': 7.0.15
- '@eslint/js@10.0.1(eslint@10.3.0(jiti@2.7.0))':
+ '@eslint/js@10.0.1(eslint@10.4.0(jiti@2.7.0))':
optionalDependencies:
- eslint: 10.3.0(jiti@2.7.0)
+ eslint: 10.4.0(jiti@2.7.0)
'@eslint/object-schema@3.0.5': {}
@@ -1932,28 +1862,13 @@ snapshots:
tslib: 2.8.1
optional: true
- '@types/chrome@0.1.42':
- dependencies:
- '@types/filesystem': 0.0.36
- '@types/har-format': 1.2.16
-
'@types/esrecurse@4.3.1': {}
'@types/estree@1.0.9': {}
- '@types/filesystem@0.0.36':
- dependencies:
- '@types/filewriter': 0.0.33
-
- '@types/filewriter@0.0.33': {}
-
- '@types/firefox-webext-browser@143.0.0': {}
-
- '@types/har-format@1.2.16': {}
-
'@types/json-schema@7.0.15': {}
- '@types/node@24.12.3':
+ '@types/node@24.12.4':
dependencies:
undici-types: 7.16.0
@@ -1969,17 +1884,15 @@ snapshots:
dependencies:
csstype: 3.2.3
- '@types/webextension-polyfill@0.12.5': {}
-
- '@typescript-eslint/eslint-plugin@8.59.3(@typescript-eslint/parser@8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/scope-manager': 8.59.3
- '@typescript-eslint/type-utils': 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/utils': 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/visitor-keys': 8.59.3
- eslint: 10.3.0(jiti@2.7.0)
+ '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/scope-manager': 8.59.4
+ '@typescript-eslint/type-utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/visitor-keys': 8.59.4
+ eslint: 10.4.0(jiti@2.7.0)
ignore: 7.0.5
natural-compare: 1.4.0
ts-api-utils: 2.5.0(typescript@6.0.3)
@@ -1987,85 +1900,85 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/scope-manager': 8.59.3
- '@typescript-eslint/types': 8.59.3
- '@typescript-eslint/typescript-estree': 8.59.3(typescript@6.0.3)
- '@typescript-eslint/visitor-keys': 8.59.3
+ '@typescript-eslint/scope-manager': 8.59.4
+ '@typescript-eslint/types': 8.59.4
+ '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3)
+ '@typescript-eslint/visitor-keys': 8.59.4
debug: 4.4.3
- eslint: 10.3.0(jiti@2.7.0)
+ eslint: 10.4.0(jiti@2.7.0)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/project-service@8.59.3(typescript@6.0.3)':
+ '@typescript-eslint/project-service@8.59.4(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@6.0.3)
- '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3)
+ '@typescript-eslint/types': 8.59.4
debug: 4.4.3
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/scope-manager@8.59.3':
+ '@typescript-eslint/scope-manager@8.59.4':
dependencies:
- '@typescript-eslint/types': 8.59.3
- '@typescript-eslint/visitor-keys': 8.59.3
+ '@typescript-eslint/types': 8.59.4
+ '@typescript-eslint/visitor-keys': 8.59.4
- '@typescript-eslint/tsconfig-utils@8.59.3(typescript@6.0.3)':
+ '@typescript-eslint/tsconfig-utils@8.59.4(typescript@6.0.3)':
dependencies:
typescript: 6.0.3
- '@typescript-eslint/type-utils@8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/type-utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/types': 8.59.3
- '@typescript-eslint/typescript-estree': 8.59.3(typescript@6.0.3)
- '@typescript-eslint/utils': 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/types': 8.59.4
+ '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
debug: 4.4.3
- eslint: 10.3.0(jiti@2.7.0)
+ eslint: 10.4.0(jiti@2.7.0)
ts-api-utils: 2.5.0(typescript@6.0.3)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/types@8.59.3': {}
+ '@typescript-eslint/types@8.59.4': {}
- '@typescript-eslint/typescript-estree@8.59.3(typescript@6.0.3)':
+ '@typescript-eslint/typescript-estree@8.59.4(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/project-service': 8.59.3(typescript@6.0.3)
- '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@6.0.3)
- '@typescript-eslint/types': 8.59.3
- '@typescript-eslint/visitor-keys': 8.59.3
+ '@typescript-eslint/project-service': 8.59.4(typescript@6.0.3)
+ '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3)
+ '@typescript-eslint/types': 8.59.4
+ '@typescript-eslint/visitor-keys': 8.59.4
debug: 4.4.3
minimatch: 10.2.5
- semver: 7.8.0
+ semver: 7.8.1
tinyglobby: 0.2.16
ts-api-utils: 2.5.0(typescript@6.0.3)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@2.7.0))
- '@typescript-eslint/scope-manager': 8.59.3
- '@typescript-eslint/types': 8.59.3
- '@typescript-eslint/typescript-estree': 8.59.3(typescript@6.0.3)
- eslint: 10.3.0(jiti@2.7.0)
+ '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0))
+ '@typescript-eslint/scope-manager': 8.59.4
+ '@typescript-eslint/types': 8.59.4
+ '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3)
+ eslint: 10.4.0(jiti@2.7.0)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/visitor-keys@8.59.3':
+ '@typescript-eslint/visitor-keys@8.59.4':
dependencies:
- '@typescript-eslint/types': 8.59.3
+ '@typescript-eslint/types': 8.59.4
eslint-visitor-keys: 5.0.1
- '@vitejs/plugin-react@6.0.1(vite@8.0.12(@types/node@24.12.3)(jiti@2.7.0))':
+ '@vitejs/plugin-react@6.0.1(vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0))':
dependencies:
'@rolldown/pluginutils': 1.0.0-rc.7
- vite: 8.0.12(@types/node@24.12.3)(jiti@2.7.0)
+ vite: 8.0.12(@types/node@24.12.4)(jiti@2.7.0)
'@vitejs/plugin-react@6.0.1(vite@8.0.12(@types/node@25.6.2)(jiti@2.7.0))':
dependencies:
@@ -2105,7 +2018,7 @@ snapshots:
balanced-match@4.0.4: {}
- baseline-browser-mapping@2.10.29: {}
+ baseline-browser-mapping@2.10.32: {}
brace-expansion@2.1.0:
dependencies:
@@ -2117,13 +2030,13 @@ snapshots:
browserslist@4.28.2:
dependencies:
- baseline-browser-mapping: 2.10.29
- caniuse-lite: 1.0.30001792
- electron-to-chromium: 1.5.353
- node-releases: 2.0.38
+ baseline-browser-mapping: 2.10.32
+ caniuse-lite: 1.0.30001793
+ electron-to-chromium: 1.5.361
+ node-releases: 2.0.46
update-browserslist-db: 1.2.3(browserslist@4.28.2)
- caniuse-lite@1.0.30001792: {}
+ caniuse-lite@1.0.30001793: {}
color-convert@2.0.1:
dependencies:
@@ -2155,7 +2068,7 @@ snapshots:
eastasianwidth@0.2.0: {}
- electron-to-chromium@1.5.353: {}
+ electron-to-chromium@1.5.361: {}
emoji-regex@8.0.0: {}
@@ -2170,20 +2083,20 @@ snapshots:
escape-string-regexp@4.0.0: {}
- eslint-plugin-react-hooks@7.1.1(eslint@10.3.0(jiti@2.7.0)):
+ eslint-plugin-react-hooks@7.1.1(eslint@10.4.0(jiti@2.7.0)):
dependencies:
'@babel/core': 7.29.0
'@babel/parser': 7.29.3
- eslint: 10.3.0(jiti@2.7.0)
+ eslint: 10.4.0(jiti@2.7.0)
hermes-parser: 0.25.1
zod: 4.4.3
zod-validation-error: 4.0.2(zod@4.4.3)
transitivePeerDependencies:
- supports-color
- eslint-plugin-react-refresh@0.5.2(eslint@10.3.0(jiti@2.7.0)):
+ eslint-plugin-react-refresh@0.5.2(eslint@10.4.0(jiti@2.7.0)):
dependencies:
- eslint: 10.3.0(jiti@2.7.0)
+ eslint: 10.4.0(jiti@2.7.0)
eslint-scope@9.1.2:
dependencies:
@@ -2196,12 +2109,12 @@ snapshots:
eslint-visitor-keys@5.0.1: {}
- eslint@10.3.0(jiti@2.7.0):
+ eslint@10.4.0(jiti@2.7.0):
dependencies:
- '@eslint-community/eslint-utils': 4.9.1(eslint@10.3.0(jiti@2.7.0))
+ '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0))
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.23.5
- '@eslint/config-helpers': 0.5.5
+ '@eslint/config-helpers': 0.6.0
'@eslint/core': 1.2.1
'@eslint/plugin-kit': 0.7.1
'@humanfs/node': 0.16.8
@@ -2437,7 +2350,7 @@ snapshots:
natural-compare@1.4.0: {}
- node-releases@2.0.38: {}
+ node-releases@2.0.46: {}
optionator@0.9.4:
dependencies:
@@ -2521,7 +2434,7 @@ snapshots:
semver@6.3.1: {}
- semver@7.8.0: {}
+ semver@7.8.1: {}
shebang-command@2.0.0:
dependencies:
@@ -2608,13 +2521,13 @@ snapshots:
dependencies:
prelude-ls: 1.2.1
- typescript-eslint@8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3):
+ typescript-eslint@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3):
dependencies:
- '@typescript-eslint/eslint-plugin': 8.59.3(@typescript-eslint/parser@8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/parser': 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/typescript-estree': 8.59.3(typescript@6.0.3)
- '@typescript-eslint/utils': 8.59.3(eslint@10.3.0(jiti@2.7.0))(typescript@6.0.3)
- eslint: 10.3.0(jiti@2.7.0)
+ '@typescript-eslint/eslint-plugin': 8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)
+ eslint: 10.4.0(jiti@2.7.0)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
@@ -2641,7 +2554,7 @@ snapshots:
v8-compile-cache-lib@3.0.1: {}
- vite@8.0.12(@types/node@24.12.3)(jiti@2.7.0):
+ vite@8.0.12(@types/node@24.12.4)(jiti@2.7.0):
dependencies:
lightningcss: 1.32.0
picomatch: 4.0.4
@@ -2649,7 +2562,7 @@ snapshots:
rolldown: 1.0.0
tinyglobby: 0.2.16
optionalDependencies:
- '@types/node': 24.12.3
+ '@types/node': 24.12.4
fsevents: 2.3.3
jiti: 2.7.0
@@ -2665,8 +2578,6 @@ snapshots:
fsevents: 2.3.3
jiti: 2.7.0
- webextension-polyfill@0.12.0: {}
-
which@2.0.1:
dependencies:
isexe: 2.0.0
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index ea14cf7..623d538 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,7 +1,7 @@
packages:
- "packages/*"
- "apps/*"
- - "templates/*"
+ - "playground/*"
allowBuilds:
esbuild: false
sharp: false
diff --git a/templates/vite-react-lib/playground/App.tsx b/templates/vite-react-lib/playground/App.tsx
deleted file mode 100644
index 8083649..0000000
--- a/templates/vite-react-lib/playground/App.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-function App() {
- return
;
-}
-
-export default App;
diff --git a/templates/vite-react-lib/playground/index.html b/templates/vite-react-lib/playground/index.html
deleted file mode 100644
index ce9e98b..0000000
--- a/templates/vite-react-lib/playground/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
vite-project
-
-
-
-
-
-
diff --git a/templates/vite-react-lib/playground/main.tsx b/templates/vite-react-lib/playground/main.tsx
deleted file mode 100644
index 4aff025..0000000
--- a/templates/vite-react-lib/playground/main.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import App from './App.tsx'
-
-createRoot(document.getElementById('root')!).render(
-
-
- ,
-)
diff --git a/templates/vite-react-lib/scripts/gen-index.ts b/templates/vite-react-lib/scripts/gen-index.ts
index 64433db..c685295 100644
--- a/templates/vite-react-lib/scripts/gen-index.ts
+++ b/templates/vite-react-lib/scripts/gen-index.ts
@@ -1,147 +1,254 @@
-import fs from "fs";
-import path from "path";
-// 1. 引入 tinyglobby
-import { globSync } from "tinyglobby";
+import * as fs from "fs";
+import * as path from "path";
-interface Config {
+/**
+ * 默认测试 / story / example / fixture / type 文件匹配规则
+ * 仅用于“识别”,不直接决定是否排除
+ */
+const DEFAULT_TEST_FILE_PATTERNS: RegExp[] = [
+ // =========================
+ // Test / Spec
+ // =========================
+ /\.(test|spec)\.(ts|tsx|js|jsx)$/,
+ /\.(test|spec)\.(ts|tsx|js|jsx)\?.*$/, // query param safe
+
+ // =========================
+ // E2E / Playwright / Cypress
+ // =========================
+ /\.(cy|playwright|e2e)\.(ts|tsx|js|jsx)$/,
+
+ // =========================
+ // Storybook
+ // =========================
+ /\.(story|stories)\.(ts|tsx|js|jsx|mdx)$/,
+
+ // =========================
+ // Snapshot / Mock / Fixture
+ // =========================
+ /\.snap$/,
+ /\.mock\.(ts|tsx|js|jsx)$/,
+ /\.fixture\.(ts|tsx|js|jsx)$/,
+
+ // =========================
+ // Type declarations
+ // =========================
+ /\.d\.ts$/,
+
+ // =========================
+ // Examples / Demos / Docs
+ // =========================
+ /\.(example|demo|docs)\.(ts|tsx|js|jsx)$/,
+];
+
+/**
+ * 测试 / 辅助目录(目录级排除)
+ */
+const DEFAULT_TEST_DIR_PATTERNS: RegExp[] = [
+ /[/\\](__tests__|tests|test|spec|__mocks__|__fixtures__|__snapshots__)[\/\\]/,
+ /[/\\](cypress|playwright|e2e|__e2e__|__playwright__)[\/\\]/,
+ /[/\\](story|stories|\.storybook)[\/\\]/,
+ /[/\\](types|type|typings|interfaces)[\/\\]/,
+ /[/\\](examples|example|demo|demos|docs)[\/\\]/,
+];
+
+type Config = {
outputDir: string;
- outputFilenameWithExt: string;
+ outputFile: string;
scanDirs: string[];
- importPrefix: string;
- predefineStatements: string[];
- includeExtensions: string[];
- excludeDirs: string[];
- excludeFileExtensions: string[];
- excludePatterns: RegExp[];
-}
-
-const cssConfig: Config = {
- outputDir: "src",
- outputFilenameWithExt: "index.css",
- scanDirs: ["src"],
- importPrefix: "@import",
- predefineStatements: [],
- includeExtensions: [".css"],
- excludeDirs: ["__tests__", "tests", "story", "stories", "types"],
- excludeFileExtensions: [],
- excludePatterns: [/^index\.(css)$/, /\.(test|spec)\./, /\.(story|stories)\./],
+ preamble?: string[];
+ importPrefix?: string;
+ entryFilePatterns?: RegExp[];
+ barrelFirstMode?: boolean;
+ includeFilePatterns?: RegExp[];
+ excludeFilePatterns?: RegExp[];
+ excludeDirPatterns?: RegExp[];
};
const tsConfig: Config = {
outputDir: "src",
- outputFilenameWithExt: "index.ts",
+ outputFile: "index.ts",
scanDirs: ["src"],
importPrefix: "export * from",
- predefineStatements: ["import './index.css'"],
- includeExtensions: [".ts", "tsx", "js", "jsx"],
- excludeDirs: ["__tests__", "tests", "story", "stories", "types"],
- excludeFileExtensions: [".d.ts"],
- excludePatterns: [
- /^index\.(ts|tsx|js|jsx)$/,
- /\.(test|spec)\./,
- /\.(story|stories)\./,
- ],
+ barrelFirstMode: true,
+ preamble: ["import './index.css';"],
+ entryFilePatterns: [/^index\.(js|ts|jsx|tsx)$/],
+ includeFilePatterns: [/\.(js|ts|jsx|tsx)$/],
+ excludeFilePatterns: DEFAULT_TEST_FILE_PATTERNS,
+ excludeDirPatterns: DEFAULT_TEST_DIR_PATTERNS,
};
-const normalizePath = (p: string) => p.replace(/\\/g, "/");
-
-const isExcludeDir = (filePath: string, excludeDirs: string[]) => {
- const normalized = normalizePath(filePath);
- return excludeDirs.some((dir) => normalized.includes(`/${dir}/`));
+const cssConfig: Config = {
+ outputDir: "src",
+ outputFile: "index.css",
+ scanDirs: ["src"],
+ importPrefix: "@import",
+ barrelFirstMode: false,
+ entryFilePatterns: [/^index\.(css)$/],
+ includeFilePatterns: [/\.(css)$/],
+ excludeFilePatterns: DEFAULT_TEST_FILE_PATTERNS,
+ excludeDirPatterns: DEFAULT_TEST_DIR_PATTERNS,
};
-const isExcludeFileExtensions = (
- filePath: string,
- excludeFileExtensions: string[],
-) => excludeFileExtensions.some((ext) => filePath.endsWith(ext));
+function isEntryFile(fileName: string, config: Config): boolean {
+ const regExps = config.entryFilePatterns;
-const isExcludePattern = (fileName: string, excludePatterns: RegExp[]) =>
- excludePatterns.some((pattern) => pattern.test(fileName));
+ if (!regExps || regExps.length === 0) return false;
-// ----------------------------------------
-function isValidFile(filePath: string, config: Config): boolean {
- const fileName = filePath.split(/[\\/]/).pop()!;
-
- if (isExcludeDir(filePath, config.excludeDirs)) return false;
- if (isExcludeFileExtensions(filePath, config.excludeFileExtensions))
- return false;
- if (isExcludePattern(fileName, config.excludePatterns)) return false;
-
- const ext = path.extname(filePath);
- return config.includeExtensions.includes(ext);
+ return regExps.some((regExp) => regExp.test(fileName));
}
-// -----------------------------------------
-function generateIndexFile(config: Config) {
- const currentPath = process.cwd();
- const outputPath = path.resolve(currentPath, config.outputDir);
- let exportStatements: string[] = [];
- // ------ scanDirs forEach start ------------------------
- config.scanDirs.forEach((dir) => {
- // 2. 路径模式保持不变,tinyglobby 能够正确处理
- const scanPattern = path.resolve(currentPath, dir, "**", "*.*");
+function isIncludeFile(fileName: string, config: Config): boolean {
+ const regExps = config.includeFilePatterns;
- const allFilePath = globSync(scanPattern, {
- absolute: true,
- // 3. 移除了 windowsPathsNoEscape,tinyglobby 默认处理路径更智能
+ if (!regExps || regExps.length === 0) return false;
+
+ return regExps.some((regExp) => regExp.test(fileName));
+}
+
+function isExcludeFile(fileName: string, config: Config): boolean {
+ const regExps = config.excludeFilePatterns;
+
+ if (!regExps || regExps.length === 0) return false;
+
+ return regExps.some((regExp) => regExp.test(fileName));
+}
+
+function isExcludeDir(filePath: string, config: Config): boolean {
+ const regExps = config.excludeDirPatterns;
+
+ if (!regExps || regExps.length === 0) return false;
+
+ return regExps.some((regExp) => regExp.test(filePath));
+}
+
+function isValidDir(filePath: string, config: Config): boolean {
+ if (isExcludeDir(filePath, config)) {
+ return false;
+ }
+ return true;
+}
+
+function isValidFile(fileName: string, config: Config): boolean {
+ if (isIncludeFile(fileName, config) && !isExcludeFile(fileName, config)) {
+ return true;
+ }
+
+ return false;
+}
+
+const buildExportStatement = (filePath: string, config: Config) => {
+ // 文件夹(不是文件)与目标文件的相对路径
+ let exportFilePath = path.relative(config.outputDir, filePath);
+
+ // 去除扩展名,并且转化成正斜杠
+ const exportFilePathWithoutExt = path
+ .join(
+ path.dirname(exportFilePath),
+ path.basename(exportFilePath, path.extname(exportFilePath)),
+ )
+ .replace(/\\/g, "/");
+
+ // 加上 ./ 前缀
+ return `${config.importPrefix} './${exportFilePathWithoutExt}';`;
+};
+
+function isOutputEntry(filePath: string, config: Config) {
+ const outputFilePath = path.resolve(config.outputDir, config.outputFile);
+ const targetFilePath = path.resolve(filePath);
+
+ return outputFilePath === targetFilePath;
+}
+
+function generateExports(dirPath: string, config: Config): string[] {
+ const fileNames = fs.readdirSync(dirPath);
+ const exports: string[] = [];
+
+ // =========================
+ // 逻辑分支:Barrel First Mode
+ // =========================
+ if (config.barrelFirstMode) {
+ // 查找当前目录有没有 index.ts
+ const entryFileName = fileNames.find((fileName) => {
+ const filePath = path.join(dirPath, fileName);
+ return fs.statSync(filePath).isFile() && isEntryFile(fileName, config);
});
+ // 如果有
+ if (entryFileName) {
+ const entryFilePath = path.join(dirPath, entryFileName);
- const validFiles = allFilePath.filter((filePath) => {
- return isValidFile(filePath, config);
- });
-
- if (validFiles.length === 0) {
- console.log(
- `⚠️ 未找到符合条件的文件,跳过生成 ${config.outputFilenameWithExt}`,
- );
- return;
- }
-
- validFiles.sort();
-
- validFiles.forEach((file) => {
- const relativePath = path.relative(outputPath, file);
- const importPath = `./${relativePath.replace(/\\/g, "/")}`;
- exportStatements.push(`${config.importPrefix} '${importPath}';`);
- });
- });
-
- // --------- scanDirs forEach end ----------------
-
- const indexFileContent = `
-${config.predefineStatements.join("\n")}
-${exportStatements.join("\n")}
-`.trim();
-
- const indexFilePath = path.resolve(
- currentPath,
- config.outputDir,
- config.outputFilenameWithExt,
- );
-
- // ✅ 内容比对,避免重复写入
- if (fs.existsSync(indexFilePath)) {
- const old = fs.readFileSync(indexFilePath, "utf8");
- if (old === indexFileContent) {
- console.log(
- `✅ ${config.outputFilenameWithExt} 内容无变化,无需重新生成`,
- );
- return;
+ // 如果是 outputFile 自身,则跳过
+ if (isOutputEntry(entryFilePath, config)) {
+ console.log(`⏭️ 跳过自身入口文件: ${entryFilePath}`);
+ } else {
+ exports.push(buildExportStatement(entryFilePath, config));
+ }
}
}
- fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
- console.log(`✅ 成功生成 ${config.outputFilenameWithExt}: ${indexFilePath}`);
+ // =========================
+ // 逻辑分支:index.ts 不存在,则继续正常遍历与递归
+ // =========================
+ fileNames.forEach((fileName) => {
+ const filePath = path.join(dirPath, fileName);
+ const stat = fs.statSync(filePath);
+
+ // 情况1:是文件,且通过了校验
+ if (
+ stat.isFile() &&
+ isValidFile(fileName, config) &&
+ !isEntryFile(fileName, config)
+ ) {
+ exports.push(buildExportStatement(filePath, config));
+ }
+ // 情况2:是文件夹,且通过了校验,递归扫描子文件夹
+ else if (stat.isDirectory() && isValidDir(filePath, config)) {
+ const subExports = generateExports(filePath, config);
+ exports.push(...subExports);
+ }
+ });
+
+ return exports;
}
-// --------------------------------------------------
+function genIndexFile(config: Config) {
+ // 确保输出目录存在,如果不存在就递归创建
+ if (!fs.existsSync(config.outputDir)) {
+ fs.mkdirSync(config.outputDir, { recursive: true });
+ }
+ const allExports: string[] = [];
+
+ // 遍历所有需要扫描的根目录
+ config.scanDirs.forEach((scanDir) => {
+ // 只有当目录真实存在时才进行扫描
+ if (fs.existsSync(scanDir)) {
+ const exports = generateExports(scanDir, config);
+ allExports.push(...exports);
+ } else {
+ console.warn(`⚠️ 警告:扫描目录不存在,已跳过 -> ${scanDir}`);
+ }
+ });
+
+ // 拼接最终的文件内容:前言 + 导出语句(使用 Set 自动去重)
+ const fileContent = [
+ ...(config.preamble ?? []),
+ ...Array.from(new Set(allExports)),
+ ].join("\n");
+
+ // 将内容写入到最终的 index.ts 文件中
+ const outputFilePath = path.join(config.outputDir, config.outputFile);
+ fs.writeFileSync(outputFilePath, fileContent, "utf-8");
+
+ console.log(`✨ 成功生成入口文件: ${outputFilePath}`);
+}
+
+// ================= 脚本执行入口 =================
try {
- console.log(`🚀 [gen-index] 开始扫描`);
- generateIndexFile(cssConfig);
- generateIndexFile(tsConfig);
-} catch (err) {
- const msg = err instanceof Error ? err.message : String(err);
- console.error(`❌ [gen-index] 执行失败: ${msg}`);
- process.exit(1);
+ console.log("🚀 开始扫描并生成入口文件...");
+ genIndexFile(tsConfig);
+ genIndexFile(cssConfig);
+ console.log("✅ 脚本执行完毕!");
+} catch (error) {
+ console.error("❌ 脚本执行失败:", error);
+ process.exit(1); // 如果报错,让进程以非 0 状态码退出
}
diff --git a/templates/vite-react-lib/src/index.css b/templates/vite-react-lib/src/index.css
new file mode 100644
index 0000000..e69de29
diff --git a/templates/vite-react-lib/src/index.ts b/templates/vite-react-lib/src/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/templates/vite-react-lib/vite.config.ts b/templates/vite-react-lib/vite.config.ts
index 4418ded..ea4923d 100644
--- a/templates/vite-react-lib/vite.config.ts
+++ b/templates/vite-react-lib/vite.config.ts
@@ -2,40 +2,38 @@ import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
-export default defineConfig(({ command }) => {
- if (command === "serve") {
- return {
- plugins: [react()],
- root: "playground",
- };
- }
+export default defineConfig({
+ plugins: [react()],
- return {
- plugins: [react()],
+ build: {
+ cssMinify: false,
- build: {
- cssMinify: false,
+ lib: {
+ entry: path.resolve(import.meta.dirname, "src/index.ts"),
+ formats: ["es", "cjs"],
+ fileName: (format) => `index.${format}.js`,
+ },
- lib: {
- entry: path.resolve(import.meta.dirname, "src/index.ts"),
- formats: ["es", "cjs"],
- fileName: (format) => `index.${format}.js`,
- },
-
- rolldownOptions: {
- external: ["react", "react-dom", "react/jsx-runtime"],
- output: {
- globals: {
- react: "React",
- "react-dom": "ReactDOM",
- },
+ rolldownOptions: {
+ external: ["react", "react-dom", "react/jsx-runtime"],
+ output: {
+ // 强制将生成的 CSS 命名为 index.css
+ assetFileNames: (assetInfo) => {
+ if (assetInfo.name && assetInfo.name.endsWith(".css")) {
+ return "index.css";
+ }
+ return "[name].[hash][extname]";
+ },
+ globals: {
+ react: "React",
+ "react-dom": "ReactDOM",
},
},
-
- emptyOutDir: true,
- sourcemap: true,
- cssCodeSplit: false,
- outDir: "dist",
},
- };
+
+ emptyOutDir: true,
+ sourcemap: true,
+ cssCodeSplit: false,
+ outDir: "dist",
+ },
});
diff --git a/turbo.json b/turbo.json
index f6f4952..bd6da81 100644
--- a/turbo.json
+++ b/turbo.json
@@ -1,15 +1,12 @@
{
- "$schema": "https://turborepo.dev/schema.json",
- "ui": "tui",
+ "$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
- "inputs": ["$TURBO_DEFAULT$", ".env*"],
- "outputs": [".next/**", "!.next/cache/**"]
+ "outputs": ["dist/**"]
},
"dev": {
- "cache": false,
- "persistent": true
+ "cache": false
}
}
}
Connect with us
-Join the Vite community
---
-
-
- GitHub
-
-
- -
-
-
- Discord
-
-
- -
-
-
- X.com
-
-
- -
-
-
- Bluesky
-
-
-
-