torch-glare 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/cli/bin/addComponent.js +278 -0
- package/cli/bin/addHooks.js +75 -0
- package/cli/bin/addLayout.js +71 -0
- package/cli/bin/addProvider.js +71 -0
- package/cli/bin/addUtils.js +74 -0
- package/cli/bin/cli.js +73 -0
- package/cli/bin/init/init.js +15 -0
- package/cli/bin/init/tailwindInit.js +174 -0
- package/cli/bin/update.js +147 -0
- package/lib/components/ActionButton.tsx +63 -0
- package/lib/components/ActionsGroup.tsx +34 -0
- package/lib/components/AlertDialog.tsx +211 -0
- package/lib/components/Badge.tsx +116 -0
- package/lib/components/BadgeField.tsx +192 -0
- package/lib/components/Button.tsx +277 -0
- package/lib/components/Card.tsx +63 -0
- package/lib/components/Checkbox.tsx +122 -0
- package/lib/components/CountBadge.tsx +54 -0
- package/lib/components/DatePicker.tsx +464 -0
- package/lib/components/Drawer.tsx +118 -0
- package/lib/components/DropdownMenu.tsx +399 -0
- package/lib/components/FieldHint.tsx +76 -0
- package/lib/components/ImageAttachment.tsx +180 -0
- package/lib/components/InnerLabelField.tsx +155 -0
- package/lib/components/Input.tsx +179 -0
- package/lib/components/InputField.tsx +147 -0
- package/lib/components/Label.tsx +107 -0
- package/lib/components/LabelField.tsx +75 -0
- package/lib/components/LabeledCheckBox.tsx +65 -0
- package/lib/components/LabeledRadio.tsx +45 -0
- package/lib/components/LinkButton.tsx +94 -0
- package/lib/components/LoginButton.tsx +56 -0
- package/lib/components/PasswordLevel.tsx +58 -0
- package/lib/components/Popover.tsx +274 -0
- package/lib/components/ProfileMenu.tsx +90 -0
- package/lib/components/Radio.tsx +77 -0
- package/lib/components/RadioCard.tsx +72 -0
- package/lib/components/RingLoading.tsx +190 -0
- package/lib/components/SearchField.tsx +49 -0
- package/lib/components/Select.tsx +417 -0
- package/lib/components/SlideDatePicker.tsx +120 -0
- package/lib/components/SpinLoading.tsx +190 -0
- package/lib/components/Switcher.tsx +56 -0
- package/lib/components/TabFormItem.tsx +158 -0
- package/lib/components/Table.tsx +395 -0
- package/lib/components/Textarea.tsx +108 -0
- package/lib/components/Tooltip.tsx +111 -0
- package/lib/components/TransparentLabel.tsx +72 -0
- package/lib/components/TreeDropDown.tsx +69 -0
- package/lib/hooks/MobileSlidePicker/components/Picker.tsx +218 -0
- package/lib/hooks/MobileSlidePicker/components/PickerColumn.tsx +238 -0
- package/lib/hooks/MobileSlidePicker/components/PickerItem.tsx +64 -0
- package/lib/hooks/MobileSlidePicker/index.ts +10 -0
- package/lib/hooks/useActiveTreeItem.tsx +61 -0
- package/lib/hooks/useClickOutside.tsx +20 -0
- package/lib/hooks/useResize.tsx +78 -0
- package/lib/layouts/CLayout.tsx +326 -0
- package/lib/layouts/FieldSection.tsx +64 -0
- package/lib/layouts/TreeSubLayout.tsx +187 -0
- package/lib/providers/ThemeProvider.tsx +99 -0
- package/lib/utils/cn.ts +6 -0
- package/lib/utils/convertImageFileToDataUrl.ts +17 -0
- package/lib/utils/resize.ts +35 -0
- package/lib/utils/types.ts +12 -0
- package/package.json +28 -0
- package/torch-glare.js +24 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getConfig } from "./cli.js";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { ensureDirectoryExists, getComponentPaths, copyComponent } from "./addComponent.js";
|
|
6
|
+
import inquirer from "inquirer";
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Define the path to the provider templates directory
|
|
12
|
+
const providerTemplatesDir = path.resolve(__dirname, "../../lib/providers");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Main function to add a provider and its dependencies.
|
|
16
|
+
* @param {string} provider - The name of the provider to add.
|
|
17
|
+
*/
|
|
18
|
+
export async function addProvider(provider) {
|
|
19
|
+
const config = getConfig();
|
|
20
|
+
const availableProviders = getAvailableProviders(providerTemplatesDir);
|
|
21
|
+
|
|
22
|
+
// If no provider is provided, prompt the user to select one
|
|
23
|
+
if (!provider) {
|
|
24
|
+
provider = await promptProviderSelection(availableProviders);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Validate if the provider exists in the provider templates directory
|
|
28
|
+
if (!availableProviders.includes(provider)) {
|
|
29
|
+
console.error(`❌ Provider "${provider}" not found.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Get the path and create the target directory
|
|
34
|
+
const { source, targetDir } = getComponentPaths(provider, config, providerTemplatesDir, "providers");
|
|
35
|
+
const target = path.join(targetDir, provider);
|
|
36
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
37
|
+
|
|
38
|
+
// Ensure the target directory exists
|
|
39
|
+
ensureDirectoryExists(targetDir);
|
|
40
|
+
|
|
41
|
+
// Copy the provider (file or directory) and install dependencies
|
|
42
|
+
copyComponent(source, target, addProvider);
|
|
43
|
+
|
|
44
|
+
console.log(`✅ ${provider} has been added to ${config.path}!`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get a list of available providers from the provider templates directory.
|
|
49
|
+
* @param {string} providerTemplatesDir - Path to the provider templates directory.
|
|
50
|
+
* @returns {string[]} - Array of provider names.
|
|
51
|
+
*/
|
|
52
|
+
function getAvailableProviders(providerTemplatesDir) {
|
|
53
|
+
return fs.readdirSync(providerTemplatesDir).map((file) => path.basename(file));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Prompt the user to select a provider from a list.
|
|
58
|
+
* @param {string[]} availableProviders - Array of available providers.
|
|
59
|
+
* @returns {string} - The selected provider.
|
|
60
|
+
*/
|
|
61
|
+
async function promptProviderSelection(availableProviders) {
|
|
62
|
+
const { selectedProvider } = await inquirer.prompt([
|
|
63
|
+
{
|
|
64
|
+
type: "list",
|
|
65
|
+
name: "selectedProvider",
|
|
66
|
+
message: "Which provider would you like to add?",
|
|
67
|
+
choices: availableProviders,
|
|
68
|
+
},
|
|
69
|
+
]);
|
|
70
|
+
return selectedProvider;
|
|
71
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getConfig } from "./cli.js";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { ensureDirectoryExists, getComponentPaths, copyComponent } from "./addComponent.js";
|
|
6
|
+
import inquirer from "inquirer";
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Define the path to the utils templates directory
|
|
12
|
+
const utilsTemplatesDir = path.resolve(__dirname, "../../lib/utils");
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Main function to add a utility file and its dependencies.
|
|
17
|
+
* @param {string} util - The name of the utility file to add.
|
|
18
|
+
*/
|
|
19
|
+
export async function addUtil(util) {
|
|
20
|
+
const config = getConfig();
|
|
21
|
+
const availableUtils = getAvailableUtils(utilsTemplatesDir);
|
|
22
|
+
|
|
23
|
+
// If no utility file is provided, prompt the user to select one
|
|
24
|
+
if (!util) {
|
|
25
|
+
util = await promptUtilSelection(availableUtils);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Validate if the utility file exists in the utils templates directory
|
|
29
|
+
if (!availableUtils.includes(util)) {
|
|
30
|
+
console.error(`❌ Utility file "${util}" not found.`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// get the path and create the create the target directory
|
|
35
|
+
const { source, targetDir } = getComponentPaths(util, config, utilsTemplatesDir, "utils");
|
|
36
|
+
const target = path.join(targetDir, util);
|
|
37
|
+
|
|
38
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
39
|
+
|
|
40
|
+
// Ensure the target directory exists
|
|
41
|
+
ensureDirectoryExists(targetDir);
|
|
42
|
+
|
|
43
|
+
// Copy the utility file and install dependencies
|
|
44
|
+
copyComponent(source, target, addUtil);
|
|
45
|
+
|
|
46
|
+
console.log(`✅ ${util} has been added to ${config.path}!`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get a list of available utility files from the utils templates directory.
|
|
51
|
+
* @param {string} utilsTemplatesDir - Path to the utils templates directory.
|
|
52
|
+
* @returns {string[]} - Array of utility file names.
|
|
53
|
+
*/
|
|
54
|
+
function getAvailableUtils(utilsTemplatesDir) {
|
|
55
|
+
return fs.readdirSync(utilsTemplatesDir).map((file) => path.basename(file));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Prompt the user to select a utility file from a list.
|
|
61
|
+
* @param {string[]} availableUtils - Array of available utility files.
|
|
62
|
+
* @returns {string} - The selected utility file.
|
|
63
|
+
*/
|
|
64
|
+
async function promptUtilSelection(availableUtils) {
|
|
65
|
+
const { selectedUtil } = await inquirer.prompt([
|
|
66
|
+
{
|
|
67
|
+
type: "list",
|
|
68
|
+
name: "selectedUtil",
|
|
69
|
+
message: "Which utility file would you like to add?",
|
|
70
|
+
choices: availableUtils,
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
73
|
+
return selectedUtil;
|
|
74
|
+
}
|
package/cli/bin/cli.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { initConfig } from "./init/init.js";
|
|
6
|
+
import { addComponent } from "./addComponent.js";
|
|
7
|
+
import { addHook } from "./addHooks.js";
|
|
8
|
+
import { updateInstalledComponents } from "./update.js";
|
|
9
|
+
import { addUtil } from "./addUtils.js";
|
|
10
|
+
import { addProvider } from "./addProvider.js";
|
|
11
|
+
import { addLayout } from "./addLayout.js";
|
|
12
|
+
|
|
13
|
+
const program = new Command();
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const CONFIG_FILE = "glare.json";
|
|
16
|
+
|
|
17
|
+
export function getConfig() {
|
|
18
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
19
|
+
console.error('❌ glare.json not found. Run "npx torch-glare@latest init" first');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error("❌ Error reading glare.json:", error.message);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.name("torch-glare")
|
|
33
|
+
.description("Torch Glare for managing React components")
|
|
34
|
+
.version("0.0.0");
|
|
35
|
+
|
|
36
|
+
program
|
|
37
|
+
.command("init")
|
|
38
|
+
.description("Initialize torch.json configuration file")
|
|
39
|
+
.action(() => initConfig(CONFIG_FILE));
|
|
40
|
+
|
|
41
|
+
program
|
|
42
|
+
.command("add [component]")
|
|
43
|
+
.description("Add a component interactively or install a specified one")
|
|
44
|
+
.action((component) => addComponent(component && `${component}.tsx`));
|
|
45
|
+
|
|
46
|
+
program
|
|
47
|
+
.command("hook [hook]")
|
|
48
|
+
.description("Add a hook interactively or install a specified one")
|
|
49
|
+
.action((hook) => addHook(hook && `${hook}`));
|
|
50
|
+
|
|
51
|
+
program
|
|
52
|
+
.command("layout [layout]")
|
|
53
|
+
.description("Add a Layout interactively or install a specified one")
|
|
54
|
+
.action((layout) => addLayout(layout && `${layout}.tsx`));
|
|
55
|
+
|
|
56
|
+
program
|
|
57
|
+
.command("util [util]")
|
|
58
|
+
.description("Add a utils interactively or install a specified one")
|
|
59
|
+
.action((util) => addUtil(util && `${util}.ts`));
|
|
60
|
+
|
|
61
|
+
program
|
|
62
|
+
.command("provider [provider]")
|
|
63
|
+
.description("Add a provider interactively or install a specified one")
|
|
64
|
+
.action((provider) => addProvider(provider && `${provider}`));
|
|
65
|
+
|
|
66
|
+
program
|
|
67
|
+
.command("update")
|
|
68
|
+
.description("Update everything installed")
|
|
69
|
+
.action(() => updateInstalledComponents());
|
|
70
|
+
|
|
71
|
+
program.parse(process.argv);
|
|
72
|
+
|
|
73
|
+
export { CONFIG_FILE, __filename };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { tailwindInit } from "./tailwindInit.js";
|
|
3
|
+
export async function initConfig(CONFIG_FILE) {
|
|
4
|
+
const defaultConfig = { path: "./" };
|
|
5
|
+
|
|
6
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
7
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(defaultConfig, null, 2));
|
|
8
|
+
console.log("✅ Created glare.json configuration file");
|
|
9
|
+
} else {
|
|
10
|
+
console.log("⚠️ glare.json already exists, skipping creation.");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Initialize Tailwind CSS config if not exists
|
|
14
|
+
tailwindInit();
|
|
15
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
import { detectPackageManager, getCurrentInstalledDependencies } from "../addComponent.js";
|
|
5
|
+
|
|
6
|
+
const tailwindConfigPath = path.join(process.cwd(), "tailwind.config.ts");
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
function generatePlugins() {
|
|
11
|
+
return `
|
|
12
|
+
require('tailwindcss-animate'),
|
|
13
|
+
require('tailwind-scrollbar-hide'),
|
|
14
|
+
require('glare-typography'),
|
|
15
|
+
require('glare-themes'),
|
|
16
|
+
require('glare-torch-mode'),
|
|
17
|
+
function ({ addVariant }: any) {
|
|
18
|
+
addVariant("rtl", '&[dir="rtl"]');
|
|
19
|
+
addVariant("ltr", '&[dir="ltr"]');
|
|
20
|
+
},
|
|
21
|
+
`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Installs dependencies using the detected package manager.
|
|
26
|
+
* @param {string[]} dependencies - List of dependencies to install.
|
|
27
|
+
*/
|
|
28
|
+
function installDependencies(dependencies = []) {
|
|
29
|
+
if (!dependencies.length) {
|
|
30
|
+
console.warn("⚠️ No dependencies provided to install.");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Detect the package manager
|
|
35
|
+
const packageManager = detectPackageManager();
|
|
36
|
+
console.log(`📦 Detected package manager: ${packageManager}`);
|
|
37
|
+
|
|
38
|
+
// Generate the install command based on the package manager
|
|
39
|
+
let installCommand;
|
|
40
|
+
const latestDeps = dependencies.map(dep => `${dep}@latest`).join(" ");
|
|
41
|
+
|
|
42
|
+
switch (packageManager) {
|
|
43
|
+
case "pnpm":
|
|
44
|
+
installCommand = `pnpm add ${latestDeps}`;
|
|
45
|
+
break;
|
|
46
|
+
case "yarn":
|
|
47
|
+
installCommand = `yarn add ${latestDeps}`;
|
|
48
|
+
break;
|
|
49
|
+
case "npm":
|
|
50
|
+
default:
|
|
51
|
+
installCommand = `npm install ${latestDeps}`;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
// Execute the install command
|
|
57
|
+
execSync(installCommand, { stdio: "inherit" });
|
|
58
|
+
console.log("✅ Dependencies installed successfully.");
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error("❌ Error installing dependencies:");
|
|
61
|
+
console.error(error.message);
|
|
62
|
+
|
|
63
|
+
// Provide additional troubleshooting tips
|
|
64
|
+
if (error.message.includes("EACCES")) {
|
|
65
|
+
console.error(
|
|
66
|
+
"💡 It seems you don't have permission to install packages globally. Try running the command with sudo or fix your npm permissions."
|
|
67
|
+
);
|
|
68
|
+
} else if (error.message.includes("not found")) {
|
|
69
|
+
console.error(
|
|
70
|
+
"💡 The package manager might not be installed. Please ensure it is installed and available in your PATH."
|
|
71
|
+
);
|
|
72
|
+
} else {
|
|
73
|
+
console.error("💡 Check your internet connection and try again.");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
function createTailwindConfig() {
|
|
80
|
+
const tailwindConfig = `
|
|
81
|
+
import type { Config } from "tailwindcss";
|
|
82
|
+
export default {
|
|
83
|
+
content: [
|
|
84
|
+
"./app/**/*.{js,ts,jsx,tsx}",
|
|
85
|
+
"./index.html",
|
|
86
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
87
|
+
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
|
88
|
+
"./features/**/*.{js,ts,jsx,tsx,mdx}",
|
|
89
|
+
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
90
|
+
"./layout/**/*.{js,ts,jsx,tsx,mdx}",
|
|
91
|
+
],
|
|
92
|
+
theme: {
|
|
93
|
+
extend: {},
|
|
94
|
+
},
|
|
95
|
+
screens: {
|
|
96
|
+
sm: "600px",
|
|
97
|
+
md: "768px",
|
|
98
|
+
lg: "1024px",
|
|
99
|
+
xl: "1280px",
|
|
100
|
+
"2xl": "1536px",
|
|
101
|
+
},
|
|
102
|
+
plugins: [${generatePlugins()}],
|
|
103
|
+
}satisfies Config;
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
fs.writeFileSync(tailwindConfigPath, tailwindConfig);
|
|
107
|
+
console.log("✅ Created tailwind.config.ts");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function modifyTailwindConfig() {
|
|
111
|
+
let tailwindConfigContent = fs.readFileSync(tailwindConfigPath, "utf-8");
|
|
112
|
+
|
|
113
|
+
if (!tailwindConfigContent.includes("glare-typography") && !tailwindConfigContent.includes("glare-themes")) {
|
|
114
|
+
if (!tailwindConfigContent.includes("plugins")) {
|
|
115
|
+
tailwindConfigContent = tailwindConfigContent.replace(
|
|
116
|
+
"],",
|
|
117
|
+
`],plugins: [${generatePlugins()}],`
|
|
118
|
+
);
|
|
119
|
+
} else {
|
|
120
|
+
tailwindConfigContent = tailwindConfigContent.replace(
|
|
121
|
+
"plugins: [",
|
|
122
|
+
`plugins: [${generatePlugins()}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
console.log("✅ Modified tailwind.config.ts");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fs.writeFileSync(tailwindConfigPath, tailwindConfigContent);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Checks if the installed Tailwind CSS version is less than v4.
|
|
134
|
+
* @param {string} version - The version string of Tailwind CSS.
|
|
135
|
+
* @returns {boolean} - True if the version is less than v4, otherwise false.
|
|
136
|
+
*/
|
|
137
|
+
function isTailwindVersionLessThanV4(version) {
|
|
138
|
+
if (!version) {
|
|
139
|
+
console.warn("⚠️ Tailwind CSS is not installed.");
|
|
140
|
+
return false; // Assume it needs to be installed
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Extract the major version number
|
|
144
|
+
const majorVersion = parseInt(version.replace(/^[^0-9]*/, "").split(".")[0], 10);
|
|
145
|
+
return majorVersion < 4;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
export function tailwindInit() {
|
|
150
|
+
const dependencies = [
|
|
151
|
+
"tailwindcss-animate",
|
|
152
|
+
"tailwind-scrollbar-hide",
|
|
153
|
+
"glare-typography",
|
|
154
|
+
"glare-themes",
|
|
155
|
+
"glare-torch-mode",
|
|
156
|
+
];
|
|
157
|
+
installDependencies(dependencies);
|
|
158
|
+
|
|
159
|
+
const { depsNamesAndVersions } = getCurrentInstalledDependencies()
|
|
160
|
+
if (depsNamesAndVersions["tailwindcss"]) {
|
|
161
|
+
const tailwindVersion = depsNamesAndVersions["tailwindcss"]
|
|
162
|
+
if (isTailwindVersionLessThanV4(tailwindVersion)) {
|
|
163
|
+
if (!fs.existsSync(tailwindConfigPath)) {
|
|
164
|
+
createTailwindConfig();
|
|
165
|
+
} else {
|
|
166
|
+
modifyTailwindConfig();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getConfig } from "./cli.js";
|
|
4
|
+
import { addComponent, copyDirectorySync, getComponentPaths, installDependencies } from "./addComponent.js";
|
|
5
|
+
import { tailwindInit } from "./init/tailwindInit.js";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import readline from "readline";
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
|
|
11
|
+
// Get the current file and directory paths
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// Define the path to the templates directory
|
|
15
|
+
const templatesDir = path.resolve(__dirname, "../../lib");
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Update all installed components, hooks, and utility files by syncing them with the latest templates.
|
|
19
|
+
*/
|
|
20
|
+
export async function updateInstalledComponents() {
|
|
21
|
+
const config = getConfig();
|
|
22
|
+
|
|
23
|
+
// Ask the user if they are sure about updating
|
|
24
|
+
const rl = readline.createInterface({
|
|
25
|
+
input: process.stdin,
|
|
26
|
+
output: process.stdout,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const answer = await new Promise((resolve) => {
|
|
30
|
+
rl.question("Are you sure you want to update all installed components, hooks, and utils? (y/n): ", (input) => {
|
|
31
|
+
resolve(input.trim().toLowerCase());
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
rl.close();
|
|
36
|
+
|
|
37
|
+
if (answer !== "y") {
|
|
38
|
+
console.log("Update cancelled.");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Update components
|
|
43
|
+
await updateItems("components", config);
|
|
44
|
+
|
|
45
|
+
// Update hooks
|
|
46
|
+
await updateItems("hooks", config);
|
|
47
|
+
|
|
48
|
+
// Update utils
|
|
49
|
+
await updateItems("utils", config);
|
|
50
|
+
|
|
51
|
+
// Reinitialize Tailwind CSS configuration
|
|
52
|
+
tailwindInit();
|
|
53
|
+
console.log("✅ All installed items have been updated.");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Update items (components, hooks, or utils) by syncing them with the latest templates.
|
|
58
|
+
* @param {string} type - The type of items to update (e.g., "components", "hooks", "utils").
|
|
59
|
+
* @param {object} config - Configuration object.
|
|
60
|
+
*/
|
|
61
|
+
async function updateItems(type, config) {
|
|
62
|
+
const installedItemsDir = getInstalledItemsDir(config, type);
|
|
63
|
+
|
|
64
|
+
// Exit if no installed items are found
|
|
65
|
+
if (!checkIfItemsExist(installedItemsDir)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Get the list of installed items
|
|
70
|
+
const installedItems = getInstalledItems(installedItemsDir);
|
|
71
|
+
|
|
72
|
+
// Exit if there are no items to update
|
|
73
|
+
if (installedItems.length === 0) {
|
|
74
|
+
console.log(`✅ No ${type} to update.`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
console.log(`🔄 Updating installed ${type}...`);
|
|
79
|
+
|
|
80
|
+
// Update each installed item
|
|
81
|
+
installedItems.forEach((item) => {
|
|
82
|
+
updateItem(item, config, type);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get the directory path for installed items (components, hooks, or utils).
|
|
88
|
+
* @param {object} config - Configuration object.
|
|
89
|
+
* @param {string} type - The type of items (e.g., "components", "hooks", "utils").
|
|
90
|
+
* @returns {string} - Path to the installed items directory.
|
|
91
|
+
*/
|
|
92
|
+
function getInstalledItemsDir(config, type) {
|
|
93
|
+
const normalizedPath = config.path.replace("@/", "");
|
|
94
|
+
return path.join(process.cwd(), normalizedPath, type);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Check if the installed items directory exists.
|
|
99
|
+
* @param {string} installedItemsDir - Path to the installed items directory.
|
|
100
|
+
* @returns {boolean} - True if the directory exists, false otherwise.
|
|
101
|
+
*/
|
|
102
|
+
function checkIfItemsExist(installedItemsDir) {
|
|
103
|
+
if (!fs.existsSync(installedItemsDir)) {
|
|
104
|
+
console.log(`❌ No installed ${path.basename(installedItemsDir)} found.`);
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get the list of installed items.
|
|
112
|
+
* @param {string} installedItemsDir - Path to the installed items directory.
|
|
113
|
+
* @returns {string[]} - Array of installed item names.
|
|
114
|
+
*/
|
|
115
|
+
function getInstalledItems(installedItemsDir) {
|
|
116
|
+
return fs.readdirSync(installedItemsDir).map((file) => path.basename(file));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Update a single item (component, hook, or utility file) by syncing it with the latest template.
|
|
121
|
+
* @param {string} item - The name of the item to update.
|
|
122
|
+
* @param {object} config - Configuration object.
|
|
123
|
+
* @param {string} type - The type of item (e.g., "components", "hooks", "utils").
|
|
124
|
+
*/
|
|
125
|
+
function updateItem(item, config, type) {
|
|
126
|
+
const { source, targetDir } = getComponentPaths(item, config, `${templatesDir}/${type}`, type);
|
|
127
|
+
const target = path.join(targetDir, item);
|
|
128
|
+
|
|
129
|
+
// Check if the item template exists
|
|
130
|
+
if (fs.existsSync(source)) {
|
|
131
|
+
console.log(`🔄 Updating ${item}...`);
|
|
132
|
+
|
|
133
|
+
// Copy the item (directory or file)
|
|
134
|
+
if (fs.lstatSync(source).isDirectory()) {
|
|
135
|
+
copyDirectorySync(source, target, addComponent);
|
|
136
|
+
} else {
|
|
137
|
+
fs.copyFileSync(source, target);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Install dependencies for the updated item
|
|
141
|
+
// installDependencies(source, type);
|
|
142
|
+
|
|
143
|
+
console.log(`✅ ${item} updated.`);
|
|
144
|
+
} else {
|
|
145
|
+
console.log(`⚠️ Template for ${item} not found. Skipping...`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { ButtonHTMLAttributes } from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
import { Button } from "./Button";
|
|
4
|
+
import { cn } from "../utils/cn";
|
|
5
|
+
import { ButtonVariant, Themes } from "../utils/types";
|
|
6
|
+
|
|
7
|
+
const buttonVariants = cva("", {
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
XS: "h-[18px] w-[18px] text-[12px]",
|
|
11
|
+
S: "h-[22px] w-[22px] text-[12px]",
|
|
12
|
+
M: "h-[32px] w-[32px] text-[18px]",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
size: "M",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
interface Props
|
|
22
|
+
extends ButtonHTMLAttributes<HTMLButtonElement>,
|
|
23
|
+
VariantProps<typeof buttonVariants> {
|
|
24
|
+
is_loading?: boolean;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
asChild?: boolean;
|
|
27
|
+
as?: React.ElementType;
|
|
28
|
+
theme?: Themes
|
|
29
|
+
variant?: ButtonVariant
|
|
30
|
+
}
|
|
31
|
+
export const ActionButton = function ({
|
|
32
|
+
size,
|
|
33
|
+
asChild,
|
|
34
|
+
as: Tag = "button",
|
|
35
|
+
className,
|
|
36
|
+
variant,
|
|
37
|
+
children,
|
|
38
|
+
theme,
|
|
39
|
+
...props
|
|
40
|
+
}: Props) {
|
|
41
|
+
return (
|
|
42
|
+
<Button
|
|
43
|
+
theme={theme}
|
|
44
|
+
asChild={asChild}
|
|
45
|
+
buttonType="icon"
|
|
46
|
+
size={
|
|
47
|
+
size == "XS" ? "S" :
|
|
48
|
+
size == "S" ? "M" :
|
|
49
|
+
size == "M" ? "L" : "S"
|
|
50
|
+
}
|
|
51
|
+
variant={variant}
|
|
52
|
+
className={cn(
|
|
53
|
+
buttonVariants({
|
|
54
|
+
size,
|
|
55
|
+
})
|
|
56
|
+
, className
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
>
|
|
60
|
+
{children}
|
|
61
|
+
</Button>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { HTMLAttributes } from "react";
|
|
2
|
+
import { cn } from "../utils/cn";
|
|
3
|
+
import { Themes } from "../utils/types";
|
|
4
|
+
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
6
|
+
withDivider?: boolean; // to display the divider line if you pass it see on figma design file
|
|
7
|
+
theme?: Themes
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const ActionsGroup: React.FC<Props> = ({
|
|
11
|
+
withDivider,
|
|
12
|
+
className,
|
|
13
|
+
children,
|
|
14
|
+
theme,
|
|
15
|
+
...props
|
|
16
|
+
}) => {
|
|
17
|
+
return (
|
|
18
|
+
<section
|
|
19
|
+
{...props}
|
|
20
|
+
data-theme={theme}
|
|
21
|
+
className={cn("flex items-center gap-2 flex-1", className)}
|
|
22
|
+
>
|
|
23
|
+
{withDivider && (
|
|
24
|
+
<div className="flex border-t border-solid border-border-presentation-global-primary flex-1 px-2" />
|
|
25
|
+
)}
|
|
26
|
+
{children}
|
|
27
|
+
{withDivider && (
|
|
28
|
+
<div className="flex border-t border-solid border-border-presentation-global-primary flex-1 px-2" />
|
|
29
|
+
)}
|
|
30
|
+
</section>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default ActionsGroup;
|