torch-glare 1.0.8 → 1.1.0

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/dist/bin/index.js CHANGED
@@ -11,7 +11,7 @@ const program = new Command();
11
11
  program
12
12
  .name("torch-glare")
13
13
  .description("Torch Glare for managing React components")
14
- .version("1.0.7");
14
+ .version("1.0.8");
15
15
  program
16
16
  .command("init")
17
17
  .description("Initialize torch.json configuration file")
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Detect the package manager used in the project.
3
- * @returns {string} - The detected package manager (pnpm, yarn, or npm).
3
+ * @returns {string} - The detected package manager (pnpm, yarn, npm, bun, etc).
4
4
  */
5
5
  export declare function detectPackageManager(): string;
6
6
  //# sourceMappingURL=detectPackageManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectPackageManager.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/detectPackageManager.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C"}
1
+ {"version":3,"file":"detectPackageManager.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/detectPackageManager.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C"}
@@ -2,7 +2,7 @@ import * as fs from "fs";
2
2
  import path from "path";
3
3
  /**
4
4
  * Detect the package manager used in the project.
5
- * @returns {string} - The detected package manager (pnpm, yarn, or npm).
5
+ * @returns {string} - The detected package manager (pnpm, yarn, npm, bun, etc).
6
6
  */
7
7
  export function detectPackageManager() {
8
8
  if (fs.existsSync(path.join(process.cwd(), "pnpm-lock.yaml")))
@@ -11,6 +11,10 @@ export function detectPackageManager() {
11
11
  return "yarn";
12
12
  if (fs.existsSync(path.join(process.cwd(), "package-lock.json")))
13
13
  return "npm";
14
+ if (fs.existsSync(path.join(process.cwd(), "bun.lockb")))
15
+ return "bun";
16
+ if (fs.existsSync(path.join(process.cwd(), ".yarnrc.yml")))
17
+ return "yarn";
14
18
  return "npm"; // Default to npm if no lock file is found
15
19
  }
16
20
  //# sourceMappingURL=detectPackageManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectPackageManager.js","sourceRoot":"","sources":["../../../cli/src/shared/detectPackageManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAChC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7E,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACxE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,OAAO,KAAK,CAAC,CAAC,0CAA0C;AAC5D,CAAC"}
1
+ {"version":3,"file":"detectPackageManager.js","sourceRoot":"","sources":["../../../cli/src/shared/detectPackageManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAChC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7E,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACxE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC1E,OAAO,KAAK,CAAC,CAAC,0CAA0C;AAC5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindInit.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/tailwindInit.ts"],"names":[],"mappings":"AAqJA,wBAAgB,YAAY,IAAI,IAAI,CAqBnC"}
1
+ {"version":3,"file":"tailwindInit.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/tailwindInit.ts"],"names":[],"mappings":"AAGA,wBAAgB,YAAY,IAAI,IAAI,CASnC"}
@@ -1,21 +1,14 @@
1
- import path from "path";
2
- import fs from "fs";
3
1
  import { execSync } from "child_process";
4
2
  import { detectPackageManager } from "./detectPackageManager.js";
5
- import { getCurrentInstalledDependencies } from "./getCurrentInstalledDependencies.js";
6
- const tailwindConfigPath = path.join(process.cwd(), "tailwind.config.ts");
7
- function generatePlugins() {
8
- return `
9
- require('tailwindcss-animate'),
10
- require('tailwind-scrollbar-hide'),
11
- require('glare-typography'),
12
- require('glare-themes'),
13
- require('glare-torch-mode'),
14
- function ({ addVariant }: any) {
15
- addVariant("rtl", '&[dir="rtl"]');
16
- addVariant("ltr", '&[dir="ltr"]');
17
- },
18
- `;
3
+ export function tailwindInit() {
4
+ const dependencies = [
5
+ "tailwindcss-animate",
6
+ "tailwind-scrollbar-hide",
7
+ "glare-typography",
8
+ "mapping-color-system",
9
+ "glare-torch-mode",
10
+ ];
11
+ installDependencies(dependencies);
19
12
  }
20
13
  /**
21
14
  * Installs dependencies using the detected package manager.
@@ -31,21 +24,23 @@ function installDependencies(dependencies = []) {
31
24
  console.log(`📦 Detected package manager: ${packageManager}`);
32
25
  // Generate the install command based on the package manager
33
26
  let installCommand;
34
- const latestDeps = dependencies.map(dep => `${dep}@latest`).join(" ");
27
+ const latestDeps = dependencies.map(dep => `${dep}`).join(" ");
35
28
  switch (packageManager) {
36
29
  case "pnpm":
37
- installCommand = `pnpm add ${latestDeps}`;
30
+ installCommand = `pnpm add ${latestDeps} --prefer-offline`;
38
31
  break;
39
32
  case "yarn":
40
- installCommand = `yarn add ${latestDeps}`;
33
+ installCommand = `yarn add ${latestDeps} --ignore-engines --ignore-platform --prefer-offline`;
41
34
  break;
42
- case "npm":
43
- default:
44
- installCommand = `npm install ${latestDeps}`;
35
+ case "bun":
36
+ installCommand = `bun add ${latestDeps} --no-save && bun install`;
45
37
  break;
38
+ default:
39
+ installCommand = `npm install ${latestDeps} --legacy-peer-deps`;
46
40
  }
47
41
  try {
48
42
  // Execute the install command
43
+ console.log(`Running: ${installCommand}`);
49
44
  execSync(installCommand, { stdio: "inherit" });
50
45
  console.log("✅ Dependencies installed successfully.");
51
46
  }
@@ -59,86 +54,11 @@ function installDependencies(dependencies = []) {
59
54
  else if (error.message.includes("not found")) {
60
55
  console.error("💡 The package manager might not be installed. Please ensure it is installed and available in your PATH.");
61
56
  }
62
- else {
63
- console.error("💡 Check your internet connection and try again.");
64
- }
65
- }
66
- }
67
- function createTailwindConfig() {
68
- const tailwindConfig = `
69
- import type { Config } from "tailwindcss";
70
- export default {
71
- content: [
72
- "./app/**/*.{js,ts,jsx,tsx}",
73
- "./index.html",
74
- "./src/**/*.{js,ts,jsx,tsx}",
75
- "./pages/**/*.{js,ts,jsx,tsx,mdx}",
76
- "./features/**/*.{js,ts,jsx,tsx,mdx}",
77
- "./components/**/*.{js,ts,jsx,tsx,mdx}",
78
- "./layout/**/*.{js,ts,jsx,tsx,mdx}",
79
- ],
80
- theme: {
81
- extend: {},
82
- },
83
- screens: {
84
- sm: "600px",
85
- md: "768px",
86
- lg: "1024px",
87
- xl: "1280px",
88
- "2xl": "1536px",
89
- },
90
- plugins: [${generatePlugins()}],
91
- }satisfies Config;
92
- `;
93
- fs.writeFileSync(tailwindConfigPath, tailwindConfig);
94
- console.log("✅ Created tailwind.config.ts");
95
- }
96
- function modifyTailwindConfig() {
97
- let tailwindConfigContent = fs.readFileSync(tailwindConfigPath, "utf-8");
98
- if (!tailwindConfigContent.includes("glare-typography") && !tailwindConfigContent.includes("glare-themes")) {
99
- if (!tailwindConfigContent.includes("plugins")) {
100
- tailwindConfigContent = tailwindConfigContent.replace("],", `],plugins: [${generatePlugins()}],`);
57
+ else if (error.message.includes("ERESOLVE") || error.message.includes("peer dependency conflict")) {
58
+ console.error("💡 There are dependency conflicts. Try manually installing with 'npm install --force' or 'npm install --legacy-peer-deps'.");
101
59
  }
102
60
  else {
103
- tailwindConfigContent = tailwindConfigContent.replace("plugins: [", `plugins: [${generatePlugins()}`);
104
- }
105
- console.log("✅ Modified tailwind.config.ts");
106
- }
107
- fs.writeFileSync(tailwindConfigPath, tailwindConfigContent);
108
- }
109
- /**
110
- * Checks if the installed Tailwind CSS version is less than v4.
111
- * @param {string} version - The version string of Tailwind CSS.
112
- * @returns {boolean} - True if the version is less than v4, otherwise false.
113
- */
114
- function isTailwindVersionLessThanV4(version) {
115
- if (!version) {
116
- console.warn("⚠️ Tailwind CSS is not installed.");
117
- return false; // Assume it needs to be installed
118
- }
119
- // Extract the major version number
120
- const majorVersion = parseInt(version?.replace(/^[^0-9]*/, "").split(".")[0] || "3", 10);
121
- return majorVersion < 4;
122
- }
123
- export function tailwindInit() {
124
- const dependencies = [
125
- "tailwindcss-animate",
126
- "tailwind-scrollbar-hide",
127
- "glare-typography",
128
- "glare-themes",
129
- "glare-torch-mode",
130
- ];
131
- installDependencies(dependencies);
132
- const { depsNamesAndVersions } = getCurrentInstalledDependencies();
133
- if (depsNamesAndVersions["tailwindcss"]) {
134
- const tailwindVersion = depsNamesAndVersions["tailwindcss"];
135
- if (isTailwindVersionLessThanV4(tailwindVersion)) {
136
- if (!fs.existsSync(tailwindConfigPath)) {
137
- createTailwindConfig();
138
- }
139
- else {
140
- modifyTailwindConfig();
141
- }
61
+ console.error("💡 Check your internet connection and try again.");
142
62
  }
143
63
  }
144
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindInit.js","sourceRoot":"","sources":["../../../cli/src/shared/tailwindInit.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAEvF,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;AAI1E,SAAS,eAAe;IACtB,OAAO;;;;;;;;;;GAUN,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,eAAyB,EAAE;IACtD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,6BAA6B;IAC7B,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,gCAAgC,cAAc,EAAE,CAAC,CAAC;IAE9D,4DAA4D;IAC5D,IAAI,cAAc,CAAC;IACnB,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEtE,QAAQ,cAAc,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,cAAc,GAAG,YAAY,UAAU,EAAE,CAAC;YAC1C,MAAM;QACR,KAAK,MAAM;YACT,cAAc,GAAG,YAAY,UAAU,EAAE,CAAC;YAC1C,MAAM;QACR,KAAK,KAAK,CAAC;QACX;YACE,cAAc,GAAG,eAAe,UAAU,EAAE,CAAC;YAC7C,MAAM;IACV,CAAC;IAED,IAAI,CAAC;QACH,8BAA8B;QAC9B,QAAQ,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE7B,0CAA0C;QAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,KAAK,CACX,oIAAoI,CACrI,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,KAAK,CACX,0GAA0G,CAC3G,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;AACH,CAAC;AAGD,SAAS,oBAAoB;IAC3B,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;kBAsBP,eAAe,EAAE;;GAEhC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,oBAAoB;IAC3B,IAAI,qBAAqB,GAAG,EAAE,CAAC,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAEzE,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC3G,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,qBAAqB,GAAG,qBAAqB,CAAC,OAAO,CACnD,IAAI,EACJ,eAAe,eAAe,EAAE,IAAI,CACrC,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,qBAAqB,GAAG,qBAAqB,CAAC,OAAO,CACnD,YAAY,EACZ,aAAa,eAAe,EAAE,EAAE,CACjC,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;AAC9D,CAAC;AAGD;;;;GAIG;AACH,SAAS,2BAA2B,CAAC,OAA2B;IAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC,CAAC,kCAAkC;IAClD,CAAC;IAED,mCAAmC;IACnC,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACzF,OAAO,YAAY,GAAG,CAAC,CAAC;AAC1B,CAAC;AAGD,MAAM,UAAU,YAAY;IAC1B,MAAM,YAAY,GAAG;QACnB,qBAAqB;QACrB,yBAAyB;QACzB,kBAAkB;QAClB,cAAc;QACd,kBAAkB;KACnB,CAAC;IACF,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAElC,MAAM,EAAE,oBAAoB,EAAE,GAAG,+BAA+B,EAAE,CAAC;IACnE,IAAI,oBAAoB,CAAC,aAAa,CAAC,EAAE,CAAC;QACxC,MAAM,eAAe,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAC5D,IAAI,2BAA2B,CAAC,eAAe,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACvC,oBAAoB,EAAE,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,oBAAoB,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"tailwindInit.js","sourceRoot":"","sources":["../../../cli/src/shared/tailwindInit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,UAAU,YAAY;IAC1B,MAAM,YAAY,GAAG;QACnB,qBAAqB;QACrB,yBAAyB;QACzB,kBAAkB;QAClB,sBAAsB;QACtB,kBAAkB;KACnB,CAAC;IACF,mBAAmB,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC;AAGD;;;GAGG;AACH,SAAS,mBAAmB,CAAC,eAAyB,EAAE;IACtD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,6BAA6B;IAC7B,MAAM,cAAc,GAAG,oBAAoB,EAAE,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,gCAAgC,cAAc,EAAE,CAAC,CAAC;IAE9D,4DAA4D;IAC5D,IAAI,cAAc,CAAC;IACnB,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/D,QAAQ,cAAc,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,cAAc,GAAG,YAAY,UAAU,mBAAmB,CAAC;YAC3D,MAAM;QACR,KAAK,MAAM;YACT,cAAc,GAAG,YAAY,UAAU,sDAAsD,CAAC;YAC9F,MAAM;QACR,KAAK,KAAK;YACR,cAAc,GAAG,WAAW,UAAU,2BAA2B,CAAC;YAClE,MAAM;QACR;YACE,cAAc,GAAG,eAAe,UAAU,qBAAqB,CAAC;IACpE,CAAC;IAED,IAAI,CAAC;QAEH,8BAA8B;QAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,cAAc,EAAE,CAAC,CAAC;QAC1C,QAAQ,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE7B,0CAA0C;QAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,KAAK,CACX,oIAAoI,CACrI,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,OAAO,CAAC,KAAK,CACX,0GAA0G,CAC3G,CAAC;QACJ,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;YACpG,OAAO,CAAC,KAAK,CACX,4HAA4H,CAC7H,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;AACH,CAAC"}
package/docs/Cover.png ADDED
Binary file
package/docs/README.md ADDED
@@ -0,0 +1,207 @@
1
+ # TORCH Glare Components Library
2
+
3
+ Welcome to the **TORCH Glare Components Library**! This library provides a collection of reusable React components to help you build user interfaces efficiently. Additionally, a CLI tool (**torch-glare CLI**) is available to streamline component management.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Installation](#installation)
8
+ 2. [Usage](#usage)
9
+ 3. [CLI Commands](#cli-commands)
10
+ 4. [Theming](#theming)
11
+ 5. [Contributing](#contributing)
12
+ 6. [License](#license)
13
+
14
+ ## Installation
15
+
16
+
17
+ ## 1. Initialize Your Project
18
+
19
+ To install the TORCH Glare Components Library, run the following command:
20
+
21
+ ```sh
22
+ npx torch-glare@latest init
23
+ ```
24
+
25
+ This command will:
26
+ - Create or modify the `tailwind.config.js` file to support Tailwind CSS for Tailwind versions less then 4.
27
+ - Generate a `torch.json` file where you can customize the installation path for components.
28
+
29
+ ### Tailwind CSS Requirement
30
+ Ensure that Tailwind CSS is installed in your project before running the initialization command.
31
+
32
+ ## 2. Add Essential Plugins for Tailwind CSS
33
+
34
+ If you're using Tailwind CSS version 4 or above, add the following plugins to your global CSS file:
35
+
36
+ ```css
37
+ @import "tailwindcss";
38
+ /* Essential plugins */
39
+ @plugin 'glare-typography';
40
+ @plugin 'mapping-color-system';
41
+ @plugin 'glare-torch-mode';
42
+ @plugin 'tailwind-scrollbar-hide';
43
+ @plugin 'tailwindcss-animate';
44
+ ```
45
+
46
+
47
+ ### 2. Add Remix Icon Library
48
+ Include the following in `index.html` or nextjs `layout.tsx` or meta data for icon support:
49
+
50
+ ```html
51
+ <html>
52
+ <head>
53
+ <link
54
+ href="https://cdn.jsdelivr.net/npm/remixicon@4.5.0/fonts/remixicon.css"
55
+ rel="stylesheet"
56
+ />
57
+ </head>
58
+ <body></body>
59
+ </html>
60
+
61
+ ```
62
+
63
+ ## 3. Configure Installation Path
64
+
65
+ Adjust the `glare.json` file to specify where you want to install components:
66
+
67
+ ```json
68
+ {
69
+ "path": "./src" // The directory where components will be installed
70
+ }
71
+ ```
72
+
73
+ ### 4. Add Components
74
+ To add a specific component, run:
75
+
76
+ ```sh
77
+ npx torch-glare@latest add [component-name]
78
+ ```
79
+
80
+ Or, to add components interactively:
81
+
82
+ ```sh
83
+ npx torch-glare@latest add
84
+ ```
85
+
86
+ ## Usage
87
+
88
+ Once installed, import and use the components as needed:
89
+
90
+ ```tsx
91
+ import React from "react";
92
+ import { Button } from "./components";
93
+
94
+ const App = () => {
95
+ return (
96
+ <div>
97
+ <Button >Hello.</Button>
98
+ </div>
99
+ );
100
+ };
101
+
102
+ export default App;
103
+ ```
104
+
105
+ ## CLI Commands
106
+
107
+ ### Initialize Configuration
108
+ ```sh
109
+ npx torch-glare@latest init
110
+ ```
111
+ - Creates a `torch.json` configuration file.
112
+ - Create or modify `tailwind.config.ts` file for tailwind support.
113
+
114
+ ### Add Components
115
+ ```sh
116
+ npx torch-glare@latest add [component]
117
+ ```
118
+ Adds a specific component or runs an interactive prompt if no name is provided.
119
+
120
+ ### Add Hooks
121
+ ```sh
122
+ npx torch-glare@latest hook [hook]
123
+ ```
124
+ Adds a specific hook or runs an interactive prompt if no name is provided.
125
+
126
+ ### Add Utilities
127
+ ```sh
128
+ npx torch-glare@latest util [util]
129
+ ```
130
+ Adds a specific utility or runs an interactive prompt if no name is provided.
131
+
132
+ ### Providers
133
+ ```sh
134
+ npx torch-glare@latest provider [provider]
135
+ ```
136
+ Adds a specific provider or runs an interactive prompt if no name is provided.
137
+
138
+ ### Update Installed Resources
139
+
140
+ ```sh
141
+ npx torch-glare@latest update
142
+ ```
143
+ Updates all installed components, hooks, utilities, and providers.
144
+
145
+
146
+ ## Theming
147
+
148
+ The TORCH Glare Components Library supports both light and dark themes. You can set a fixed theme for your components using the `theme` attribute.
149
+
150
+ ### Setting a Fixed Theme
151
+
152
+ To apply a fixed theme (dark or light) to a component, add the `theme `attribute with the desired theme value:
153
+
154
+ ```tsx
155
+ import React from "react";
156
+ import { Button } from "./components";
157
+
158
+ const App = () => {
159
+ return (
160
+ <div>
161
+ <Button theme="dark">Dark Theme Button</Button>
162
+ <Button theme="light">Light Theme Button</Button>
163
+ </div>
164
+ );
165
+ };
166
+
167
+ export default App;
168
+ ```
169
+
170
+ ### Global Theme
171
+
172
+ To apply a theme globally, wrap your application with the `ThemeProvider` and set the optional `defaultTheme` props:
173
+
174
+
175
+ ```tsx
176
+ import { ThemeProvider } from "./components";
177
+
178
+ const App = () => {
179
+ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
180
+ <ThemeProvider defaultTheme="light" defaultThemeMode="TORCH">
181
+ <App />
182
+ </ThemeProvider>
183
+ );
184
+ };
185
+
186
+ export default App;
187
+ ```
188
+
189
+ ## Contributing
190
+
191
+ We welcome contributions! Follow these steps:
192
+
193
+ 1. Fork the repository.
194
+ 2. Create a new branch.
195
+ 3. Implement your changes.
196
+ 4. Commit with a clear message.
197
+ 5. Push your changes and open a pull request.
198
+
199
+ ### Contribution Guidelines
200
+ - Follow existing code style.
201
+ - Update documentation if necessary.
202
+
203
+ ## License
204
+
205
+ This project is licensed under the **MIT License**.
206
+
207
+
@@ -4,8 +4,8 @@ import * as React from "react"
4
4
  import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
5
5
 
6
6
  import { cn } from "../utils/cn"
7
- import { buttonVariants } from "./Button"
8
- import { ButtonVariant } from "@/utils/types"
7
+ import { Button, buttonVariants } from "./Button"
8
+ import { ButtonVariant } from "../utils/types"
9
9
  import { cva } from "class-variance-authority"
10
10
 
11
11
  const StatusTextStyle = cva("", {
@@ -55,10 +55,18 @@ const AlertDialogContent = React.forwardRef<
55
55
  <AlertDialogOverlay />
56
56
  <AlertDialogPrimitive.Content
57
57
  ref={ref}
58
- className={cn(StatusTextStyle({ variant }),
59
- "text-content-presentation-global-primary max-w-[800px] !m-1 sm:m-0",
60
- "fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-2 border bg-background-presentation-body-overlay-primary p-2 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
61
- "rounded-[16px] border-2 border-border-presentation-global-primary",
58
+ className={cn(
59
+ StatusTextStyle({ variant }),
60
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-[800px] translate-x-[-50%] translate-y-[-50%]",
61
+ "gap-2 rounded-[16px] border-2 border-border-presentation-global-primary",
62
+ "bg-background-presentation-body-overlay-primary p-[12px]",
63
+ "text-content-presentation-global-primary",
64
+ "shadow-lg duration-200",
65
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
66
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
67
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
68
+ "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
69
+ "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
62
70
  className
63
71
  )}
64
72
  {...props}
@@ -120,11 +128,11 @@ const AlertDialogLabel = React.forwardRef<
120
128
  return (
121
129
  <AlertDialogPrimitive.Title
122
130
  ref={ref}
123
- className={cn("text-lg font-semibold", className)}
131
+ className={cn("typography-display-medium-semibold", className)}
124
132
  {...props}
125
133
  >
126
- <p className="first-letter:uppercase" >
127
- <strong >{firstWord}</strong>
134
+ <p className="first-letter:uppercase typography-display-medium-semibold" >
135
+ <strong className="typography-display-medium-semibold" >{firstWord}</strong>
128
136
  {restOfTitle.length > 0 && ' ' + restOfTitle}
129
137
  </p>
130
138
  </AlertDialogPrimitive.Title>
@@ -139,14 +147,15 @@ const AlertDialogDescription = React.forwardRef<
139
147
  <AlertDialogPrimitive.Description
140
148
  data-description=""
141
149
  ref={ref}
142
- className={cn("bg-background-presentation-form-base border border-border-presentation-global-primary p-2 rounded-[8px]"
143
- , "p-[12px_8px_12px_8px] sm:p-[24px_48px_48px_48px] typography-body-large-medium",
144
- className)}
145
-
150
+ className={cn(
151
+ "typography-body-large-medium",
152
+ "bg-background-presentation-form-base",
153
+ "border border-border-presentation-global-primary",
154
+ "rounded-[8px] p-[24px_48px_48px_48px]",
155
+ className
156
+ )}
146
157
  {...props}
147
- >
148
- {props.children}
149
- </AlertDialogPrimitive.Description>
158
+ />
150
159
  ))
151
160
  AlertDialogDescription.displayName =
152
161
  AlertDialogPrimitive.Description.displayName
@@ -166,8 +175,10 @@ const AlertDialogAction = React.forwardRef<
166
175
  <AlertDialogPrimitive.Action
167
176
  ref={ref}
168
177
  className={cn(buttonVariants({ variant: variant, size: size, buttonType: buttonType }), className)}
169
- {...props}
170
- />
178
+ asChild
179
+ >
180
+ <Button size={size} variant={variant} buttonType={buttonType} {...props} />
181
+ </AlertDialogPrimitive.Action>
171
182
  ))
172
183
  AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
173
184
 
@@ -11,9 +11,9 @@ import { Tooltip, ToolTipSide } from "./Tooltip";
11
11
  import { Popover, PopoverContent, PopoverTrigger } from "./Popover";
12
12
  import { Themes } from "../utils/types";
13
13
  import { Icon, Input, Group, Trilling } from "./Input";
14
- import { useClickOutside } from "@/hooks/useClickOutside";
14
+ import { useClickOutside } from "../hooks/useClickOutside";
15
15
  import { Badge } from "./Badge";
16
- import { Tag, useTagSelection } from "@/hooks/useTagSelection";
16
+ import { Tag, useTagSelection } from "../hooks/useTagSelection";
17
17
 
18
18
 
19
19
  interface Props
@@ -30,6 +30,7 @@ interface Props
30
30
  actionButton?: ReactNode
31
31
  tags: Tag[]
32
32
  onValueChange?: (tags: Tag[]) => void
33
+ singleSelect?: boolean
33
34
  }
34
35
 
35
36
 
@@ -50,9 +51,9 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
50
51
  tags,
51
52
  onValueChange,
52
53
  children,
54
+ singleSelect = false,
53
55
  ...props
54
56
  },
55
- forwardedRef
56
57
  ) => {
57
58
  const [dropDownListWidth, setDropDownListWidth] = useState(0);
58
59
  const popoverContentRef = useRef<HTMLDivElement>(null);
@@ -79,7 +80,7 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
79
80
  focusedPopoverIndex,
80
81
  isPopoverOpen,
81
82
  setIsPopoverOpen,
82
- } = useTagSelection({ Tags: tags, onTagsChange: onValueChange, inputRef });
83
+ } = useTagSelection({ Tags: tags, onTagsChange: onValueChange, inputRef, singleSelect });
83
84
 
84
85
  return (
85
86
  <Popover open={isPopoverOpen}>
@@ -93,7 +94,6 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
93
94
  <Group
94
95
  error={errorMessage !== undefined}
95
96
  onTable={onTable}
96
- data-theme={theme}
97
97
  variant={variant}
98
98
  tabIndex={isPopoverOpen ? 0 : -1}
99
99
  onKeyDown={handleKeyDown}
@@ -102,9 +102,9 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
102
102
  onFocus={(e: any) => {
103
103
  setDropDownListWidth(e.currentTarget.offsetWidth);
104
104
  }}
105
- className={cn("flex gap-1 flex-row w-full relative p-1 flex-nowrap overflow-hidden justify-end h-fit items-center",
105
+ className={cn("flex gap-1 flex-row w-full relative p-1 flex-nowrap overflow-hidden justify-start items-center",
106
106
  {
107
- "flex-wrap justify-start": isPopoverOpen,
107
+ "flex-wrap justify-start h-fit": isPopoverOpen && !singleSelect,
108
108
  },
109
109
  className
110
110
  )}
@@ -163,7 +163,6 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
163
163
  </Tooltip>
164
164
 
165
165
  <PopoverContent
166
- data-theme={theme}
167
166
  ref={popoverContentRef}
168
167
  style={{ width: dropDownListWidth }}
169
168
  variant={variant}
@@ -12,7 +12,7 @@ const glareCheckBoxStyles = cva(
12
12
  "border border-border-presentation-action-checkbox-primary",
13
13
  "bg-background-presentation-action-borderstyle",
14
14
  "focus:bg-blue-sparkle-alpha-15 focus:border-border-presentation-state-focus",
15
- 'disabled:bg-background-presentation-state-information-primary disabled:border-transparent disabled:cursor-not-allowed',
15
+ 'disabled:bg-background-presentation-action-disabled disabled:border-border-presentation-action-disabled disabled:cursor-not-allowed',
16
16
  "data-[state=checked]:bg-blue-sparkle-600 data-[state=checked]:border-blue-sparkle-600",
17
17
  "hover:border-border-presentation-action-hover",
18
18
  ],
@@ -37,7 +37,7 @@ const DialogContent = React.forwardRef<
37
37
  <DialogPrimitive.Content
38
38
  ref={ref}
39
39
  className={cn(
40
- "fixed left-[50%] top-[50%] z-50 flex flex-col items-start w-full translate-x-[-50%] translate-y-[-50%] shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
40
+ "fixed left-[50%] top-[50%] z-50 flex flex-col items-start w-fit translate-x-[-50%] translate-y-[-50%] shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
41
41
  "flex justify-center items-center",
42
42
  className
43
43
  )}
@@ -7,7 +7,7 @@ import { AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogCancel
7
7
 
8
8
  const dropZoneStyles = cva(
9
9
  [
10
- "w-full min-w-[200px] h-[65px] flex flex-col rounded-lg border-dashed !border-2 transition-all duration-300 ease-in-out ",
10
+ "w-full h-[65px] flex flex-col rounded-lg border-dashed !border-2 transition-all duration-300 ease-in-out ",
11
11
  "!border-border-presentation-action-borderstyle bg-background-presentation-badge-gray",
12
12
  "hover:border-border-presentation-action-borderstyle hover:bg-background-presentation-badge-gray",
13
13
  ],
@@ -60,7 +60,7 @@ const ImageAttachment = forwardRef<HTMLInputElement, Props>(
60
60
  <h1 className="text-content-presentation-action-light-primary typography-body-large-medium">
61
61
  {mainLabel}
62
62
  </h1>
63
- <p className="text-content-presentation-action-light-secondary typography-body-small-medium">
63
+ <p className="text-content-presentation-action-light-secondary typography-body-small-medium text-wrap whitespace-pre-wrap text-center">
64
64
  {secondaryLabel}
65
65
  </p>
66
66
  <input ref={ref} {...props} type="file" hidden />
@@ -11,17 +11,19 @@ interface InputGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, "size"> {
11
11
  className?: string;
12
12
  }
13
13
 
14
- export const Group = ({ size = 'M', variant = "PresentationStyle", error = false, onTable = false, ref, className, ...props }: InputGroupProps) => {
15
- return (
16
- <div
17
- className={cn(GroupStyles({ size, variant, error, onTable }), className)}
18
- ref={ref}
19
- {...props}>
20
- </div>
21
- )
22
- }
23
-
14
+ export const Group = forwardRef<HTMLDivElement, InputGroupProps>(
15
+ ({ size = 'M', variant = "PresentationStyle", error = false, onTable = false, className, ...props }, ref) => {
16
+ return (
17
+ <div
18
+ className={cn(GroupStyles({ size, variant, error, onTable }), className)}
19
+ ref={ref}
20
+ {...props}>
21
+ </div>
22
+ )
23
+ }
24
+ );
24
25
 
26
+ Group.displayName = "Group";
25
27
 
26
28
  interface IconProps {
27
29
  children: React.ReactNode;
@@ -116,10 +118,10 @@ export const GroupStyles = cva(
116
118
  "transition-all duration-200 ease-in-out",
117
119
  "hover:shadow-[0px_1px_6px_0px_rgba(0,0,0,0.30)]",
118
120
  "[&_i]:leading-[0px] leading-[0px]",
119
- '[&:has(input[disabled="true"])]:!border-border-presentation-action-disabled',
120
- '[&:has(input[disabled="true"])]:!bg-background-presentation-action-disabled',
121
- '[&:has(input[disabled="true"])]:hover:border-border-presentation-action-disabled',
122
- '[&:has(input[disabled="true"])]:hover:bg-background-presentation-action-disabled',
121
+ '[&:has(input[disabled])]:!border-border-presentation-action-disabled',
122
+ '[&:has(input[disabled])]:!bg-background-presentation-action-disabled',
123
+ '[&:has(input[disabled])]:hover:border-border-presentation-action-disabled',
124
+ '[&:has(input[disabled])]:hover:bg-background-presentation-action-disabled',
123
125
  ],
124
126
  {
125
127
  variants: {
@@ -98,7 +98,7 @@ export const InputField = forwardRef<HTMLInputElement, Props>(
98
98
  <Trilling >
99
99
  {childrenSide}
100
100
  {popoverChildren && (
101
- <PopoverActionButton size={size} variant={variant} isPopoverOpen={isPopoverOpen} />
101
+ <PopoverActionButton size={size} variant={variant} isPopoverOpen={isPopoverOpen} disabled={props.disabled} />
102
102
  )}
103
103
  </Trilling>
104
104
  </Group>
@@ -107,7 +107,7 @@ export const InputField = forwardRef<HTMLInputElement, Props>(
107
107
 
108
108
 
109
109
  {
110
- popoverChildren && (
110
+ (popoverChildren && !props.disabled) && (
111
111
  <PopoverContent
112
112
  theme={theme}
113
113
  variant={variant}
@@ -125,16 +125,16 @@ export const InputField = forwardRef<HTMLInputElement, Props>(
125
125
 
126
126
  InputField.displayName = "InputField";
127
127
 
128
- const PopoverActionButton = ({ size, variant, isPopoverOpen }: { size: "S" | "M", variant: "SystemStyle" | "PresentationStyle", isPopoverOpen: boolean }) => {
128
+ const PopoverActionButton = ({ size, variant, isPopoverOpen, disabled }: { size: "S" | "M", variant: "SystemStyle" | "PresentationStyle", isPopoverOpen: boolean, disabled?: boolean }) => {
129
129
  return (
130
- <ActionButton size={size}>
130
+ <ActionButton disabled={disabled} size={size}>
131
131
  <i
132
132
  className={cn(
133
133
  "ri-arrow-down-s-line",
134
134
  "transition-[transform,rotate]",
135
135
  "duration-200",
136
136
  "ease-in-out",
137
- { "rotate-180": isPopoverOpen },
137
+ { "rotate-180": (isPopoverOpen && !disabled) },
138
138
  { "!text-[16px]": size === "S" },
139
139
  { "!text-[26px]": size === "M" },
140
140
  { "text-white": variant === "SystemStyle" }
@@ -77,7 +77,7 @@ const InputOTPSeparator = React.forwardRef<
77
77
  React.ComponentPropsWithoutRef<"div">
78
78
  >(({ ...props }, ref) => (
79
79
  <div ref={ref} role="separator" {...props}>
80
- <i className="ri-subtract-line"></i>
80
+ <i className="ri-subtract-line text-border-presentation-global-primary"></i>
81
81
  </div>
82
82
  ))
83
83
  InputOTPSeparator.displayName = "InputOTPSeparator"
@@ -49,15 +49,14 @@ export const LinkButton: React.FC<Props> = ({ theme, className, size = "S", asCh
49
49
  className
50
50
  )}
51
51
  >
52
- <div className="px-[3px]">{props.children}</div>
52
+ <div className="px-[3px] whitespace-nowrap break-keep">{props.children}</div>
53
53
  <div
54
54
  className={cn(
55
55
  "rounded-[4px]",
56
56
  "bg-background-presentation-state-information-primary",
57
57
  "transition-all duration-[100] ease-in-out",
58
58
  "h-0 w-0 p-0",
59
- "opacity-0 group-hover:opacity-100",
60
- "p-[3px]",
59
+ "opacity-0 group-hover:opacity-100 group-hover:p-[3px]",
61
60
  {
62
61
  "group-hover:w-[20px] group-hover:h-[20px]": size === "S",
63
62
  "group-hover:w-[22px] group-hover:h-[22px]": size === "M",
@@ -227,9 +227,8 @@ const SelectContentStyles = cva(
227
227
  [
228
228
  "p-1",
229
229
  "rounded-[8px]",
230
- "border",
231
- "max-h-[200px]",
232
230
  "min-w-[240px]",
231
+ "border",
233
232
  "outline-none",
234
233
  "overflow-scroll",
235
234
  "data-[state=open]:animate-in",
@@ -238,6 +237,7 @@ const SelectContentStyles = cva(
238
237
  "data-[state=open]:fade-in-0",
239
238
  "overflow-x-hidden",
240
239
  "scrollbar-hide",
240
+ "z-[1000]",
241
241
  ],
242
242
  {
243
243
  variants: {
@@ -408,7 +408,7 @@ const PopoverTriggerStyles = cva(
408
408
  "[&_span]:h-[28px] [&_span]:w-[28px] [&_p]:typography-body-large-medium",
409
409
  ],
410
410
  XL: [
411
- "h-[40px] p-[4px] rounded-[6px] [&_span]:h-[32px] [&_span]:w-[32px] [&_p]:typography-body-small-regular [&_p]:px-[4px]",
411
+ "h-[40px] p-[4px] rounded-[6px] [&_span]:h-[32px] [&_span]:w-[32px] [&_p]:typography-body-large-regular [&_p]:px-[4px]",
412
412
  ],
413
413
  },
414
414
  },
@@ -6,7 +6,7 @@ function Skeleton({
6
6
  }: React.HTMLAttributes<HTMLDivElement>) {
7
7
  return (
8
8
  <div
9
- className={cn("animate-pulse rounded-md bg-primary/10", className)}
9
+ className={cn("animate-pulse rounded-md bg-border-presentation-global-primary", className)}
10
10
  {...props}
11
11
  />
12
12
  )
@@ -32,7 +32,7 @@ const TabFormItem: React.FC<Props> = ({
32
32
  {...props}
33
33
  className={cn(
34
34
  formBarItemStyles({ componentType, active, buttonType }),
35
- className
35
+ className,
36
36
  )}
37
37
  >
38
38
  {props.children}
@@ -188,9 +188,10 @@ const TableCell = React.forwardRef<
188
188
  >
189
189
  <div
190
190
  className={cn(
191
- "flex justify-start items-center gap-1 w-[200px] min-w-full overflow-hidden",
191
+ "flex justify-start items-center gap-1 w-[200px] min-w-full overflow-hidden has-input:bg-blue-200",
192
192
  "[mask-image:linear-gradient(to_right,black_0%,black_0%,black_75%,transparent_100%)]",
193
193
  "rtl:[mask-image:linear-gradient(to_left,black_0%,black_0%,black_75%,transparent_100%)]",
194
+ "[&:has(input)]:[mask-image:none]",
194
195
  { "w-auto justify-center": isDummy }, childrenClassName)}
195
196
  >
196
197
  {props.children}
@@ -5,7 +5,7 @@ export function useClickOutside<T extends HTMLElement>(callback: (event?: any) =
5
5
 
6
6
  useEffect(() => {
7
7
  function handleOutsideClick(event: MouseEvent) {
8
- if (ref.current) {
8
+ if (ref.current && !ref.current.contains(event.target as Node)) {
9
9
  callback(event);
10
10
  }
11
11
  }
@@ -12,17 +12,27 @@ export interface Tag {
12
12
  export const useTagSelection = ({
13
13
  Tags,
14
14
  onTagsChange,
15
- inputRef
15
+ inputRef,
16
+ singleSelect = false
16
17
  }: {
17
18
  Tags: Tag[],
18
19
  onTagsChange?: (selectedTags: Tag[]) => void,
19
- inputRef?: React.RefObject<HTMLInputElement | null>
20
+ inputRef?: React.RefObject<HTMLInputElement | null>,
21
+ singleSelect?: boolean
20
22
  }) => {
23
+ // Split initial tags into selected and unselected
24
+ const initialSelectedTags = Tags.filter(tag => tag.isSelected);
25
+ const initialUnselectedTags = Tags.filter(tag => !tag.isSelected);
26
+
21
27
  // Initialize with available tags (excluding any initially selected ones)
22
- const [tags, setTags] = useState<Tag[]>(Tags);
28
+ const [tags, setTags] = useState<Tag[]>(initialUnselectedTags);
23
29
 
24
30
  // Initialize with any pre-selected tags
25
- const [selectedTagsStack, setSelectedTagsStack] = useState<Tag[]>([]);
31
+ const [selectedTagsStack, setSelectedTagsStack] = useState<Tag[]>(
32
+ singleSelect && initialSelectedTags.length > 0
33
+ ? [initialSelectedTags[0]]
34
+ : initialSelectedTags
35
+ );
26
36
  const [searchTags, filterTagsBySearch] = useState('');
27
37
  const [focusedTagIndex, setFocusedTagIndex] = useState<number | null>(null);
28
38
  const [focusedPopoverIndex, setFocusedPopoverIndex] = useState<number | null>(null);
@@ -47,11 +57,29 @@ export const useTagSelection = ({
47
57
  tag.name.toLowerCase().includes(searchTags.toLowerCase())
48
58
  );
49
59
 
60
+ // Filter selected tags based on search input
61
+ const filteredSelectedTags = searchTags.length > 0
62
+ ? selectedTagsStack.filter(tag =>
63
+ tag.name.toLowerCase().includes(searchTags.toLowerCase()))
64
+ : selectedTagsStack;
65
+
50
66
  const handleSelectTag = (id: string) => {
51
67
  const tagToSelect = tags.find(tag => tag.id === id);
52
68
  if (tagToSelect) {
53
- setSelectedTagsStack(prev => [...prev, { ...tagToSelect, isSelected: true }]);
54
- setTags(prev => prev.filter(tag => tag.id !== id));
69
+ // If in single select mode, replace the current selection
70
+ if (singleSelect) {
71
+ // Move any currently selected tag back to available tags
72
+ if (selectedTagsStack.length > 0) {
73
+ const currentSelected = selectedTagsStack[0];
74
+ setTags(prev => [...prev, { ...currentSelected, isSelected: false }]);
75
+ }
76
+ setSelectedTagsStack([{ ...tagToSelect, isSelected: true }]);
77
+ setTags(prev => prev.filter(tag => tag.id !== id));
78
+ } else {
79
+ // Multi-select behavior (original)
80
+ setSelectedTagsStack(prev => [...prev, { ...tagToSelect, isSelected: true }]);
81
+ setTags(prev => prev.filter(tag => tag.id !== id));
82
+ }
55
83
  }
56
84
  filterTagsBySearch('');
57
85
  setFocusedPopoverIndex(null);
@@ -68,8 +96,13 @@ export const useTagSelection = ({
68
96
 
69
97
  // Reset the hook state with new data
70
98
  const reset = (newTags: Tag[] = [], newSelectedTags: Tag[] = []) => {
99
+ // In single select mode, ensure we only have at most one selected tag
100
+ const selectedTags = singleSelect && newSelectedTags.length > 0
101
+ ? [newSelectedTags[0]]
102
+ : newSelectedTags;
103
+
71
104
  setTags(newTags);
72
- setSelectedTagsStack(newSelectedTags);
105
+ setSelectedTagsStack(selectedTags);
73
106
  filterTagsBySearch('');
74
107
  setFocusedTagIndex(null);
75
108
  setFocusedPopoverIndex(null);
@@ -169,11 +202,13 @@ export const useTagSelection = ({
169
202
  setFocusedPopoverIndex,
170
203
  filterTagsBySearch,
171
204
  filteredTags,
205
+ filteredSelectedTags,
172
206
  focusedTagIndex,
173
207
  focusedPopoverIndex,
174
208
  isPopoverOpen,
175
209
  setIsPopoverOpen,
176
- reset
210
+ reset,
211
+ singleSelect
177
212
  };
178
213
  };
179
214
 
@@ -58,7 +58,7 @@ export function FieldSection({
58
58
  </div>
59
59
 
60
60
  {/* Flexible section that takes up the remaining space */}
61
- <div className="flex flex-col items-end gap-[12px]">{children}</div>
61
+ <div className="grid grid-cols-1 place-items-end gap-[12px]">{children}</div>
62
62
  </section>
63
63
  );
64
64
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "torch-glare",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist",
8
- "lib"
8
+ "lib",
9
+ "docs"
9
10
  ],
10
11
  "bin": {
11
12
  "torch-glare": "dist/bin/index.js"
@@ -15,7 +16,7 @@
15
16
  },
16
17
  "scripts": {
17
18
  "build": "tsc -b",
18
- "deploy": "tsc && node ./scripts/publish/index.js"
19
+ "deploy": "tsc && node ./scripts/bin/publish/index.js"
19
20
  },
20
21
  "dependencies": {
21
22
  "commander": "^13.1.0",