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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +207 -0
  3. package/cli/bin/addComponent.js +278 -0
  4. package/cli/bin/addHooks.js +75 -0
  5. package/cli/bin/addLayout.js +71 -0
  6. package/cli/bin/addProvider.js +71 -0
  7. package/cli/bin/addUtils.js +74 -0
  8. package/cli/bin/cli.js +73 -0
  9. package/cli/bin/init/init.js +15 -0
  10. package/cli/bin/init/tailwindInit.js +174 -0
  11. package/cli/bin/update.js +147 -0
  12. package/lib/components/ActionButton.tsx +63 -0
  13. package/lib/components/ActionsGroup.tsx +34 -0
  14. package/lib/components/AlertDialog.tsx +211 -0
  15. package/lib/components/Badge.tsx +116 -0
  16. package/lib/components/BadgeField.tsx +192 -0
  17. package/lib/components/Button.tsx +277 -0
  18. package/lib/components/Card.tsx +63 -0
  19. package/lib/components/Checkbox.tsx +122 -0
  20. package/lib/components/CountBadge.tsx +54 -0
  21. package/lib/components/DatePicker.tsx +464 -0
  22. package/lib/components/Drawer.tsx +118 -0
  23. package/lib/components/DropdownMenu.tsx +399 -0
  24. package/lib/components/FieldHint.tsx +76 -0
  25. package/lib/components/ImageAttachment.tsx +180 -0
  26. package/lib/components/InnerLabelField.tsx +155 -0
  27. package/lib/components/Input.tsx +179 -0
  28. package/lib/components/InputField.tsx +147 -0
  29. package/lib/components/Label.tsx +107 -0
  30. package/lib/components/LabelField.tsx +75 -0
  31. package/lib/components/LabeledCheckBox.tsx +65 -0
  32. package/lib/components/LabeledRadio.tsx +45 -0
  33. package/lib/components/LinkButton.tsx +94 -0
  34. package/lib/components/LoginButton.tsx +56 -0
  35. package/lib/components/PasswordLevel.tsx +58 -0
  36. package/lib/components/Popover.tsx +274 -0
  37. package/lib/components/ProfileMenu.tsx +90 -0
  38. package/lib/components/Radio.tsx +77 -0
  39. package/lib/components/RadioCard.tsx +72 -0
  40. package/lib/components/RingLoading.tsx +190 -0
  41. package/lib/components/SearchField.tsx +49 -0
  42. package/lib/components/Select.tsx +417 -0
  43. package/lib/components/SlideDatePicker.tsx +120 -0
  44. package/lib/components/SpinLoading.tsx +190 -0
  45. package/lib/components/Switcher.tsx +56 -0
  46. package/lib/components/TabFormItem.tsx +158 -0
  47. package/lib/components/Table.tsx +395 -0
  48. package/lib/components/Textarea.tsx +108 -0
  49. package/lib/components/Tooltip.tsx +111 -0
  50. package/lib/components/TransparentLabel.tsx +72 -0
  51. package/lib/components/TreeDropDown.tsx +69 -0
  52. package/lib/hooks/MobileSlidePicker/components/Picker.tsx +218 -0
  53. package/lib/hooks/MobileSlidePicker/components/PickerColumn.tsx +238 -0
  54. package/lib/hooks/MobileSlidePicker/components/PickerItem.tsx +64 -0
  55. package/lib/hooks/MobileSlidePicker/index.ts +10 -0
  56. package/lib/hooks/useActiveTreeItem.tsx +61 -0
  57. package/lib/hooks/useClickOutside.tsx +20 -0
  58. package/lib/hooks/useResize.tsx +78 -0
  59. package/lib/layouts/CLayout.tsx +326 -0
  60. package/lib/layouts/FieldSection.tsx +64 -0
  61. package/lib/layouts/TreeSubLayout.tsx +187 -0
  62. package/lib/providers/ThemeProvider.tsx +99 -0
  63. package/lib/utils/cn.ts +6 -0
  64. package/lib/utils/convertImageFileToDataUrl.ts +17 -0
  65. package/lib/utils/resize.ts +35 -0
  66. package/lib/utils/types.ts +12 -0
  67. package/package.json +28 -0
  68. 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;