torch-glare 2.1.1 → 2.1.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 (62) hide show
  1. package/apps/lib/components/BadgeField.tsx +2 -2
  2. package/apps/lib/components/DataViews/ARCHITECTURE.md +439 -0
  3. package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +416 -0
  4. package/apps/lib/components/DataViews/DataViewsHeader.tsx +126 -0
  5. package/apps/lib/components/DataViews/DataViewsLayout.tsx +300 -0
  6. package/apps/lib/components/DataViews/FilterPanel.tsx +324 -0
  7. package/apps/lib/components/DataViews/InboxView.tsx +514 -0
  8. package/apps/lib/components/DataViews/KanbanView.tsx +242 -0
  9. package/apps/lib/components/DataViews/PanelControls.tsx +80 -0
  10. package/apps/lib/components/DataViews/SettingsPanel.tsx +285 -0
  11. package/apps/lib/components/DataViews/TableView.tsx +232 -0
  12. package/apps/lib/components/DataViews/TreeView.tsx +363 -0
  13. package/apps/lib/components/DataViews/badgeAdapter.ts +45 -0
  14. package/apps/lib/components/DataViews/fieldRenderers.tsx +334 -0
  15. package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +113 -0
  16. package/apps/lib/components/DataViews/filters/PresetChips.tsx +45 -0
  17. package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +154 -0
  18. package/apps/lib/components/DataViews/index.ts +30 -0
  19. package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +54 -0
  20. package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +77 -0
  21. package/apps/lib/components/DataViews/types.ts +177 -0
  22. package/apps/lib/components/TreeFolder/TreeFolder.tsx +387 -0
  23. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +80 -0
  24. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +235 -0
  25. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +60 -0
  26. package/apps/lib/components/TreeFolder/icons.tsx +63 -0
  27. package/apps/lib/components/TreeFolder/index.ts +17 -0
  28. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +114 -0
  29. package/apps/lib/components/TreeFolder/types.ts +68 -0
  30. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +261 -0
  31. package/apps/lib/hooks/useDataViewsState.ts +169 -0
  32. package/apps/lib/hooks/useIsMobile.ts +21 -0
  33. package/apps/lib/utils/dataViews/columnUtils.ts +130 -0
  34. package/apps/lib/utils/dataViews/fieldUtils.ts +198 -0
  35. package/apps/lib/utils/dataViews/nestedDataUtils.tsx +364 -0
  36. package/apps/lib/utils/dataViews/pathUtils.ts +132 -0
  37. package/apps/lib/utils/dataViews/rangeUtils.ts +225 -0
  38. package/apps/lib/utils/dataViews/treeUtils.ts +403 -0
  39. package/dist/bin/index.js +3 -3
  40. package/dist/bin/index.js.map +1 -1
  41. package/dist/src/commands/add.d.ts.map +1 -1
  42. package/dist/src/commands/add.js +29 -6
  43. package/dist/src/commands/add.js.map +1 -1
  44. package/dist/src/commands/utils.d.ts.map +1 -1
  45. package/dist/src/commands/utils.js +22 -2
  46. package/dist/src/commands/utils.js.map +1 -1
  47. package/dist/src/shared/copyComponentsRecursively.d.ts.map +1 -1
  48. package/dist/src/shared/copyComponentsRecursively.js +8 -1
  49. package/dist/src/shared/copyComponentsRecursively.js.map +1 -1
  50. package/dist/src/shared/getDependenciesAndInstallNestedComponents.d.ts +18 -4
  51. package/dist/src/shared/getDependenciesAndInstallNestedComponents.d.ts.map +1 -1
  52. package/dist/src/shared/getDependenciesAndInstallNestedComponents.js +110 -40
  53. package/dist/src/shared/getDependenciesAndInstallNestedComponents.js.map +1 -1
  54. package/docs/components/form-stepper.md +244 -0
  55. package/docs/components/stepper.md +215 -0
  56. package/docs/components/timeline.md +248 -0
  57. package/package.json +6 -6
  58. package/apps/lib/components/Charts-dev.tsx +0 -365
  59. package/apps/lib/components/Command-dev.tsx +0 -151
  60. package/apps/lib/components/IosDatePicker-dev.tsx +0 -341
  61. /package/docs/components/{labeled-checkbox.md → labeled-check-box.md} +0 -0
  62. /package/docs/components/{tree-dropdown.md → tree-drop-down.md} +0 -0
@@ -1,4 +1,5 @@
1
1
  import path from "path";
2
+ import fs from "fs";
2
3
  import inquirer from "inquirer";
3
4
  import { fileURLToPath } from "url";
4
5
  import { ensureDirectoryExists } from "../shared/ensureDirectoryExists.js";
@@ -25,15 +26,16 @@ export async function add(component, replace = false) {
25
26
  if (!component) {
26
27
  component = await promptComponentSelection(availableComponents);
27
28
  }
28
- // Validate if the component exists in the templates directory
29
- if (!availableComponents.includes(component)) {
29
+ // Resolve user input to an actual entry accepts "Button", "Button.tsx", or "DataViews" (folder).
30
+ const resolved = resolveComponentEntry(component, availableComponents, templatesDir);
31
+ if (!resolved) {
30
32
  console.error(`❌ Component "${component}" not found.`);
31
33
  return;
32
34
  }
33
- const { source, targetDir } = getInstallPaths(component, targetFile, templatesDir, "components");
35
+ const { source, targetDir } = getInstallPaths(resolved, targetFile, templatesDir, "components");
34
36
  // Check if component already exists
35
- if (isFileExists(targetDir, component) && !replace) {
36
- console.log(`⚠️ Component "${component}" already exists.`);
37
+ if (isFileExists(targetDir, resolved) && !replace) {
38
+ console.log(`⚠️ Component "${resolved}" already exists.`);
37
39
  return;
38
40
  }
39
41
  // Ensure the target directory exists
@@ -41,7 +43,28 @@ export async function add(component, replace = false) {
41
43
  ensureDirectoryExists(targetDir);
42
44
  // Copy the component (directory or file) and install dependencies
43
45
  copyComponentsRecursively(source, targetDir);
44
- console.log(`✅ ${component} has been added to ${targetFile.path}!`);
46
+ console.log(`✅ ${resolved} has been added to ${targetFile.path}!`);
47
+ }
48
+ /**
49
+ * Resolve a user-provided component name to an actual entry in the templates
50
+ * directory. Tries (in order):
51
+ * 1. exact match (e.g. "Button.tsx" or "DataViews")
52
+ * 2. with `.tsx` suffix (e.g. user typed "Button")
53
+ * 3. with `.ts` suffix (for non-JSX modules)
54
+ * Returns the matching entry name, or null if nothing matches.
55
+ */
56
+ function resolveComponentEntry(input, available, dir) {
57
+ if (available.includes(input))
58
+ return input;
59
+ const candidates = [`${input}.tsx`, `${input}.ts`];
60
+ for (const c of candidates) {
61
+ if (available.includes(c))
62
+ return c;
63
+ }
64
+ // Last-ditch: see if it exists on disk even if `getAvailableFiles` missed it.
65
+ if (fs.existsSync(path.join(dir, input)))
66
+ return input;
67
+ return null;
45
68
  }
46
69
  /**
47
70
  * Prompt the user to select a component from a list.
@@ -1 +1 @@
1
- {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../cli/src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAElD,2CAA2C;AAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,6CAA6C;AAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,8BAA8B,CAAC,CAAC;AAI7E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,SAAkB,EAAE,UAAmB,KAAK;IAClE,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAW,CAAC;IACpD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAE5D,6DAA6D;IAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,SAAS,GAAG,MAAM,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;IACpE,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,KAAK,CAAC,gBAAgB,SAAS,cAAc,CAAC,CAAC;QACvD,OAAO;IACX,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IAEjG,oCAAoC;IACpC,IAAI,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,iBAAiB,SAAS,mBAAmB,CAAC,CAAC;QAC3D,OAAO;IACX,CAAC;IAED,qCAAqC;IACrC,4CAA4C;IAE5C,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAEjC,kEAAkE;IAClE,yBAAyB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAE7C,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,sBAAsB,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;AACxE,CAAC;AAID;;;;GAIG;AACH,KAAK,UAAU,wBAAwB,CAAC,mBAA6B;IACjE,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAChD;YACI,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,wCAAwC;YACjD,OAAO,EAAE,mBAAmB;SAC/B;KACJ,CAAC,CAAC;IACH,OAAO,iBAAiB,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../cli/src/commands/add.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../cli/src/commands/utils.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCpF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../cli/src/commands/utils.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCpF"}
@@ -24,11 +24,13 @@ export async function addUtil(util, replace = false) {
24
24
  if (!util) {
25
25
  util = await promptUtilSelection(availableUtils);
26
26
  }
27
- // Validate if the utility file exists in the utils templates directory
28
- if (!availableUtils.includes(util)) {
27
+ // Resolve user input accepts "cn", "cn.ts", or a folder name like "dataViews".
28
+ const resolved = resolveUtilEntry(util, availableUtils, utilsTemplatesDir);
29
+ if (!resolved) {
29
30
  console.error(`❌ Utility file "${util}" not found.`);
30
31
  return;
31
32
  }
33
+ util = resolved;
32
34
  // get the path and create the create the target directory
33
35
  const { source, targetDir } = getInstallPaths(util, targetFile, utilsTemplatesDir, "utils");
34
36
  const target = path.join(targetDir, util);
@@ -52,6 +54,24 @@ export async function addUtil(util, replace = false) {
52
54
  function getAvailableUtils(utilsTemplatesDir) {
53
55
  return fs.readdirSync(utilsTemplatesDir).map((file) => path.basename(file));
54
56
  }
57
+ /**
58
+ * Resolve a user-provided util name to an actual entry. Tries:
59
+ * 1. exact match (e.g. "cn.ts" or "dataViews")
60
+ * 2. with `.ts` suffix
61
+ * 3. with `.tsx` suffix
62
+ */
63
+ function resolveUtilEntry(input, available, dir) {
64
+ if (available.includes(input))
65
+ return input;
66
+ const candidates = [`${input}.ts`, `${input}.tsx`];
67
+ for (const c of candidates) {
68
+ if (available.includes(c))
69
+ return c;
70
+ }
71
+ if (fs.existsSync(path.join(dir, input)))
72
+ return input;
73
+ return null;
74
+ }
55
75
  /**
56
76
  * Prompt the user to select a utility file from a list.
57
77
  * @param {string[]} availableUtils - Array of available utility files.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../cli/src/commands/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../cli/src/commands/utils.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"copyComponentsRecursively.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/copyComponentsRecursively.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAa9E;AACD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACf,IAAI,CAiBN"}
1
+ {"version":3,"file":"copyComponentsRecursively.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/copyComponentsRecursively.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAqB9E;AACD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACf,IAAI,CAiBN"}
@@ -8,7 +8,14 @@ import path from "path";
8
8
  */
9
9
  export function copyComponentsRecursively(source, target) {
10
10
  if (fs.lstatSync(source).isDirectory()) {
11
- copyDirectorySync(source, target);
11
+ // If target already exists as a directory, nest the source folder
12
+ // inside it (so `add DataViews` ends up at ./components/DataViews/,
13
+ // not flattened into ./components/). Otherwise the target IS the
14
+ // destination directory (legacy behavior).
15
+ const finalTarget = fs.existsSync(target) && fs.lstatSync(target).isDirectory()
16
+ ? path.join(target, path.basename(source))
17
+ : target;
18
+ copyDirectorySync(source, finalTarget);
12
19
  }
13
20
  else {
14
21
  let finalTarget = target;
@@ -1 +1 @@
1
- {"version":3,"file":"copyComponentsRecursively.js","sourceRoot":"","sources":["../../../cli/src/shared/copyComponentsRecursively.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,MAAc;IACpE,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACJ,IAAI,WAAW,GAAG,MAAM,CAAC;QAEzB,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9D,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACrC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;AACL,CAAC;AACD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC7B,MAAc,EACd,MAAc;IAEd,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhD,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACJ,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACxC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"copyComponentsRecursively.js","sourceRoot":"","sources":["../../../cli/src/shared/copyComponentsRecursively.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,MAAc;IACpE,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACrC,kEAAkE;QAClE,oEAAoE;QACpE,iEAAiE;QACjE,2CAA2C;QAC3C,MAAM,WAAW,GACb,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE;YACvD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1C,CAAC,CAAC,MAAM,CAAC;QACjB,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACJ,IAAI,WAAW,GAAG,MAAM,CAAC;QAEzB,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9D,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACrC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;AACL,CAAC;AACD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC7B,MAAc,EACd,MAAc;IAEd,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhD,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACJ,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACxC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -1,8 +1,22 @@
1
1
  /**
2
- * this function used to read the component file and collect dependencies and copy nested components.
3
- * @param {string} componentPath - Path to the component file.
4
- * @param {Set<string>} installedDependencies - Set of installed dependencies.
5
- * @returns {Set<string>} - Set of dependencies to install.
2
+ * Walk a copied component file's imports and (a) collect 3rd-party deps to
3
+ * install, (b) recursively pull in any referenced glare components, hooks, or
4
+ * utils so the user gets a self-contained drop-in.
5
+ *
6
+ * Import-path forms understood:
7
+ * "lucide-react" → 3rd-party
8
+ * "./TableView" → sibling (already copied by folder copy)
9
+ * "../Button" → ../components/Button.tsx
10
+ * "../../components/Button" → same
11
+ * "../utils/cn" → util "cn"
12
+ * "../../utils/cn" → util "cn"
13
+ * "../../utils/dataViews/pathUtils" → util folder "dataViews" (whole folder)
14
+ * "../hooks/useIsMobile" → hook "useIsMobile.ts"
15
+ * "../../hooks/useIsMobile" → same
16
+ *
17
+ * @param componentPath - File whose imports we're walking.
18
+ * @param installedDependencies - Already-present 3rd-party packages.
19
+ * @returns Set of 3rd-party deps still to install.
6
20
  */
7
21
  export declare function getDependenciesAndInstallNestedComponents(componentPath: string, installedDependencies: Set<string>): Set<string>;
8
22
  //# sourceMappingURL=getDependenciesAndInstallNestedComponents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getDependenciesAndInstallNestedComponents.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/getDependenciesAndInstallNestedComponents.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AAEH,wBAAgB,yCAAyC,CACrD,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,GACnC,GAAG,CAAC,MAAM,CAAC,CAgEb"}
1
+ {"version":3,"file":"getDependenciesAndInstallNestedComponents.d.ts","sourceRoot":"","sources":["../../../cli/src/shared/getDependenciesAndInstallNestedComponents.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yCAAyC,CACrD,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,GACnC,GAAG,CAAC,MAAM,CAAC,CAgEb"}
@@ -4,63 +4,133 @@ import { addUtil } from "../commands/utils.js";
4
4
  import { addHook } from "../commands/hook.js";
5
5
  import { add } from "../commands/add.js";
6
6
  /**
7
- * this function used to read the component file and collect dependencies and copy nested components.
8
- * @param {string} componentPath - Path to the component file.
9
- * @param {Set<string>} installedDependencies - Set of installed dependencies.
10
- * @returns {Set<string>} - Set of dependencies to install.
7
+ * Walk a copied component file's imports and (a) collect 3rd-party deps to
8
+ * install, (b) recursively pull in any referenced glare components, hooks, or
9
+ * utils so the user gets a self-contained drop-in.
10
+ *
11
+ * Import-path forms understood:
12
+ * "lucide-react" → 3rd-party
13
+ * "./TableView" → sibling (already copied by folder copy)
14
+ * "../Button" → ../components/Button.tsx
15
+ * "../../components/Button" → same
16
+ * "../utils/cn" → util "cn"
17
+ * "../../utils/cn" → util "cn"
18
+ * "../../utils/dataViews/pathUtils" → util folder "dataViews" (whole folder)
19
+ * "../hooks/useIsMobile" → hook "useIsMobile.ts"
20
+ * "../../hooks/useIsMobile" → same
21
+ *
22
+ * @param componentPath - File whose imports we're walking.
23
+ * @param installedDependencies - Already-present 3rd-party packages.
24
+ * @returns Set of 3rd-party deps still to install.
11
25
  */
12
26
  export function getDependenciesAndInstallNestedComponents(componentPath, installedDependencies) {
13
27
  const componentContent = fs.readFileSync(componentPath, "utf-8");
14
- const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
28
+ const importRegex = /import\s+(?:[\s\S]*?from\s+)?['"]([^'"]+)['"]/g;
15
29
  const dependenciesToInstall = new Set();
30
+ const dir = path.dirname(componentPath);
16
31
  let match;
17
32
  while ((match = importRegex.exec(componentContent)) !== null) {
18
33
  const moduleName = match[1];
19
- // get dependencies from the component
20
- if (moduleName && !moduleName.startsWith(".") && !installedDependencies.has(moduleName)) {
21
- dependenciesToInstall.add(moduleName);
22
- }
23
- // install component required utils.
24
- else if (moduleName &&
25
- moduleName.startsWith("../utils") &&
26
- !installedDependencies.has(moduleName)) {
27
- addUtil(moduleName.slice(9) + ".ts");
34
+ if (!moduleName)
35
+ continue;
36
+ // ----- 3rd-party packages (no relative prefix) -----
37
+ if (!moduleName.startsWith(".")) {
38
+ if (!installedDependencies.has(moduleName)) {
39
+ dependenciesToInstall.add(moduleName);
40
+ }
41
+ continue;
28
42
  }
29
- // install component required hooks.
30
- else if (moduleName &&
31
- moduleName.startsWith("../hooks") &&
32
- !installedDependencies.has(moduleName)) {
33
- addHook(moduleName.slice(9) + ".ts");
43
+ // ----- Relative imports -----
44
+ const segments = moduleName.split("/").filter(s => s && s !== ".");
45
+ const dotDots = segments.filter(s => s === "..").length;
46
+ const rest = segments.slice(dotDots);
47
+ // Sibling import (no ..): handled by directory copy, skip.
48
+ if (dotDots === 0)
49
+ continue;
50
+ const head = rest[0];
51
+ // Implicit-or-explicit segment header — handle both:
52
+ // "../utils/cn" (head = "utils")
53
+ // "../../utils/cn" (head = "utils")
54
+ // "../Button" (head = "Button") → component sibling
55
+ if (head === "utils") {
56
+ // utils/cn or utils/dataViews/pathUtils
57
+ const utilEntry = rest[1];
58
+ if (utilEntry) {
59
+ addUtil(utilEntry);
60
+ }
34
61
  }
35
- // install required nested components
36
- else if (moduleName &&
37
- (moduleName.startsWith("./") ||
38
- !moduleName.startsWith("../components")) &&
39
- !installedDependencies.has(moduleName)) {
40
- const baseName = moduleName.slice(2);
41
- const dir = path.dirname(componentPath);
42
- // Try .tsx first, fall back to .ts for non-JSX files
43
- if (fs.existsSync(path.join(dir, baseName + ".tsx"))) {
44
- add(baseName + ".tsx");
62
+ else if (head === "hooks") {
63
+ const hookEntry = rest[1];
64
+ if (hookEntry) {
65
+ addHook(`${hookEntry}.ts`);
45
66
  }
46
- else {
47
- add(baseName + ".ts");
67
+ }
68
+ else if (head === "components") {
69
+ const compEntry = rest[1];
70
+ if (compEntry) {
71
+ // Use bare name; the add() resolver figures out folder-vs-file.
72
+ add(compEntry);
48
73
  }
49
74
  }
50
- // install required for layouts components
51
- else if (moduleName &&
52
- moduleName.startsWith("../components") &&
53
- !installedDependencies.has(moduleName)) {
54
- const baseName = moduleName.slice(14);
55
- const componentsDir = path.resolve(path.dirname(componentPath), "../components");
56
- if (fs.existsSync(path.join(componentsDir, baseName + ".tsx"))) {
57
- add(baseName + ".tsx");
75
+ else {
76
+ // Bare relative — assume sibling component (e.g. "../Button" from a layout).
77
+ // Resolve against the file system to decide whether to call addUtil/addHook/add.
78
+ const resolved = resolveRelative(dir, moduleName);
79
+ if (resolved) {
80
+ routeByLocation(resolved);
58
81
  }
59
82
  else {
60
- add(baseName + ".ts");
83
+ // Fallback: try as a sibling component.
84
+ add(head);
61
85
  }
62
86
  }
63
87
  }
64
88
  return dependenciesToInstall;
65
89
  }
90
+ /**
91
+ * Resolve a relative import to an absolute file or folder path inside
92
+ * apps/lib (skipping extension guesses — caller knows what they want).
93
+ * Returns null when nothing exists.
94
+ */
95
+ function resolveRelative(fromDir, moduleName) {
96
+ const base = path.resolve(fromDir, moduleName);
97
+ const candidates = [base, `${base}.tsx`, `${base}.ts`, path.join(base, "index.ts"), path.join(base, "index.tsx")];
98
+ for (const c of candidates) {
99
+ if (fs.existsSync(c))
100
+ return c;
101
+ }
102
+ return null;
103
+ }
104
+ /**
105
+ * Given an absolute path inside apps/lib, route it to the right add* command
106
+ * by inspecting which top-level folder it lives in.
107
+ */
108
+ function routeByLocation(absPath) {
109
+ const marker = `${path.sep}apps${path.sep}lib${path.sep}`;
110
+ const idx = absPath.indexOf(marker);
111
+ if (idx === -1)
112
+ return;
113
+ const after = absPath.slice(idx + marker.length);
114
+ const [folder, ...rest] = after.split(path.sep);
115
+ const entry = rest[0];
116
+ if (!entry)
117
+ return;
118
+ switch (folder) {
119
+ case "components":
120
+ add(stripExt(entry));
121
+ break;
122
+ case "hooks":
123
+ addHook(entry);
124
+ break;
125
+ case "utils":
126
+ addUtil(entry);
127
+ break;
128
+ case "layouts":
129
+ add(stripExt(entry));
130
+ break;
131
+ }
132
+ }
133
+ function stripExt(name) {
134
+ return name.replace(/\.(tsx?|jsx?)$/, "");
135
+ }
66
136
  //# sourceMappingURL=getDependenciesAndInstallNestedComponents.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getDependenciesAndInstallNestedComponents.js","sourceRoot":"","sources":["../../../cli/src/shared/getDependenciesAndInstallNestedComponents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getDependenciesAndInstallNestedComponents.js","sourceRoot":"","sources":["../../../cli/src/shared/getDependenciesAndInstallNestedComponents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,244 @@
1
+ ---
2
+ title: FormStepper
3
+ description: Pill-shaped multi-step indicator for forms and wizards. Three semantic step types (default, success, negative) with resting, hover, selected, and selected-hover states. Full LTR and RTL support.
4
+ component: true
5
+ group: Forms
6
+ keywords: [form-stepper, stepper, wizard, steps, pill, multi-step, form, indicator, RTL]
7
+ ---
8
+
9
+ # FormStepper
10
+
11
+ A pill-shaped multi-step indicator for forms and wizards. Each step renders a circular indicator and a label inside a pill. Selection swaps the pill background to black with a white label; hover deepens the shadow on selected pills and grows the label gap on non-selected ones. The status badge on the indicator switches the visual to `success` (green check) or `negative` (red info).
12
+
13
+ The component is composed of `FormStepper`, `FormStep`, `FormStepIndicator`, and `FormStepLabel`.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npx torch-glare@latest add FormStepper
19
+ ```
20
+
21
+ ## Imports
22
+
23
+ ```typescript
24
+ import {
25
+ FormStepper,
26
+ FormStep,
27
+ FormStepIndicator,
28
+ FormStepLabel,
29
+ } from '@/components/FormStepper'
30
+ ```
31
+
32
+ ## Basic Usage
33
+
34
+ ```tsx
35
+ import { useState } from 'react'
36
+ import {
37
+ FormStepper,
38
+ FormStep,
39
+ FormStepIndicator,
40
+ FormStepLabel,
41
+ } from '@/components/FormStepper'
42
+
43
+ export function BasicFormStepper() {
44
+ const [activeStep, setActiveStep] = useState(0)
45
+
46
+ return (
47
+ <FormStepper activeStep={activeStep}>
48
+ <FormStep index={0} type="success" onClick={() => setActiveStep(0)}>
49
+ <FormStepIndicator />
50
+ <FormStepLabel>Account</FormStepLabel>
51
+ </FormStep>
52
+ <FormStep index={1} type="default" onClick={() => setActiveStep(1)}>
53
+ <FormStepIndicator />
54
+ <FormStepLabel>Profile</FormStepLabel>
55
+ </FormStep>
56
+ <FormStep index={2} type="negative" onClick={() => setActiveStep(2)}>
57
+ <FormStepIndicator />
58
+ <FormStepLabel>Payment</FormStepLabel>
59
+ </FormStep>
60
+ <FormStep index={3} type="default" onClick={() => setActiveStep(3)}>
61
+ <FormStepIndicator />
62
+ <FormStepLabel>Confirm</FormStepLabel>
63
+ </FormStep>
64
+ </FormStepper>
65
+ )
66
+ }
67
+ ```
68
+
69
+ `FormStepper.activeStep` drives which pill renders selected — each `FormStep` auto-selects when its `index` matches. Pass `selected` on a step to override the match.
70
+
71
+ ## Examples
72
+
73
+ ### Step Types
74
+
75
+ Three semantic types. `success` and `negative` add a small status badge on the indicator (check / info icon) and use filled colors when selected. `default` uses a gray ring at rest, blue ring on hover, and a solid blue fill when selected.
76
+
77
+ ```tsx
78
+ export function StepTypes() {
79
+ return (
80
+ <FormStepper>
81
+ <FormStep index={0} type="default" selected={false}>
82
+ <FormStepIndicator />
83
+ <FormStepLabel>Default</FormStepLabel>
84
+ </FormStep>
85
+ <FormStep index={1} type="success" selected={false}>
86
+ <FormStepIndicator />
87
+ <FormStepLabel>Success</FormStepLabel>
88
+ </FormStep>
89
+ <FormStep index={2} type="negative" selected={false}>
90
+ <FormStepIndicator />
91
+ <FormStepLabel>Negative</FormStepLabel>
92
+ </FormStep>
93
+ </FormStepper>
94
+ )
95
+ }
96
+ ```
97
+
98
+ ### Selected state
99
+
100
+ ```tsx
101
+ export function SelectedSteps() {
102
+ return (
103
+ <FormStepper>
104
+ <FormStep index={0} type="default" selected>
105
+ <FormStepIndicator />
106
+ <FormStepLabel>Default</FormStepLabel>
107
+ </FormStep>
108
+ <FormStep index={1} type="success" selected>
109
+ <FormStepIndicator />
110
+ <FormStepLabel>Success</FormStepLabel>
111
+ </FormStep>
112
+ <FormStep index={2} type="negative" selected>
113
+ <FormStepIndicator />
114
+ <FormStepLabel>Negative</FormStepLabel>
115
+ </FormStep>
116
+ </FormStepper>
117
+ )
118
+ }
119
+ ```
120
+
121
+ ### RTL direction
122
+
123
+ The pill, label spacing, and indicator badge all flip under `dir="rtl"`.
124
+
125
+ ```tsx
126
+ export function RTLFormStepper() {
127
+ return (
128
+ <div dir="rtl">
129
+ <FormStepper>
130
+ <FormStep index={0} type="default" selected>
131
+ <FormStepIndicator />
132
+ <FormStepLabel>افتراضي</FormStepLabel>
133
+ </FormStep>
134
+ <FormStep index={1} type="success">
135
+ <FormStepIndicator />
136
+ <FormStepLabel>نجاح</FormStepLabel>
137
+ </FormStep>
138
+ <FormStep index={2} type="negative">
139
+ <FormStepIndicator />
140
+ <FormStepLabel>خطأ</FormStepLabel>
141
+ </FormStep>
142
+ </FormStepper>
143
+ </div>
144
+ )
145
+ }
146
+ ```
147
+
148
+ ### Custom badge icon
149
+
150
+ `FormStepIndicator.badgeIcon` overrides the default check / info icon for `success` / `negative` types.
151
+
152
+ ```tsx
153
+ <FormStep index={0} type="success" selected>
154
+ <FormStepIndicator badgeIcon={<i className="ri-shield-check-line" />} />
155
+ <FormStepLabel>Verified</FormStepLabel>
156
+ </FormStep>
157
+ ```
158
+
159
+ ### Custom indicator content
160
+
161
+ Children of `FormStepIndicator` replace the auto-rendered step number.
162
+
163
+ ```tsx
164
+ <FormStep index={0} type="default" selected>
165
+ <FormStepIndicator>
166
+ <i className="ri-user-line" />
167
+ </FormStepIndicator>
168
+ <FormStepLabel>Account</FormStepLabel>
169
+ </FormStep>
170
+ ```
171
+
172
+ ## API Reference
173
+
174
+ ### FormStepper
175
+
176
+ | Prop | Type | Default | Description |
177
+ | ------------ | ------------------------------- | ------- | ----------------------------------------------------------------- |
178
+ | `activeStep` | `number` | `0` | Zero-based index of the currently selected step. |
179
+ | `theme` | `'dark' \| 'light' \| 'default'` | — | Theme override applied via `data-theme`. |
180
+ | `className` | `string` | — | Extra classes merged onto the root `<div>`. |
181
+
182
+ Standard `HTMLAttributes<HTMLDivElement>` are forwarded.
183
+
184
+ ### FormStep
185
+
186
+ | Prop | Type | Default | Description |
187
+ | ----------- | --------------------------------------- | ----------- | -------------------------------------------------------------------------- |
188
+ | `index` | `number` | `0` | Zero-based step index. Matched against `FormStepper.activeStep`. |
189
+ | `type` | `'default' \| 'success' \| 'negative'` | `'default'` | Visual type. `success` and `negative` add a status badge on the indicator. |
190
+ | `selected` | `boolean` | — | Force the selected state, overriding the index/`activeStep` match. |
191
+ | `className` | `string` | — | Extra classes merged onto the pill root. |
192
+
193
+ Standard `HTMLAttributes<HTMLDivElement>` (minus `type`) are forwarded — typical use is `onClick` for navigation.
194
+
195
+ ### FormStepIndicator
196
+
197
+ | Prop | Type | Default | Description |
198
+ | ----------- | ----------- | ------- | ----------------------------------------------------------------------------- |
199
+ | `badgeIcon` | `ReactNode` | — | Override the default badge icon (check for `success`, info for `negative`). |
200
+ | `children` | `ReactNode` | — | Replaces the auto-rendered step number. |
201
+ | `className` | `string` | — | Extra classes merged onto the indicator `<div>`. |
202
+
203
+ ### FormStepLabel
204
+
205
+ Forwards `HTMLAttributes<HTMLDivElement>`. Color and label spacing follow the parent `FormStep` selection state.
206
+
207
+ ## Styling
208
+
209
+ - Pill height: `28px`, fully rounded, `2px` inner padding.
210
+ - Indicator: `24×24px` circle, `border-[3px]` for `default`, solid fill for `success`/`negative`.
211
+ - Status badge: `15×15px` circle pinned to the top-right of the indicator (top-left under RTL), with `border` matching the page background.
212
+ - Selection: `bg-[#000000]` pill with `text-[#FFFFFF]` label and a `0 0 32px 2px rgba(0,0,0,0.05)` shadow that deepens on hover.
213
+ - Non-selected hover: `bg-[#FFFFFF]` pill, label gap grows from `6px` to `9px`, ring color flips to `#004699`.
214
+
215
+ ## TypeScript Types
216
+
217
+ ```typescript
218
+ type FormStepperType = 'default' | 'success' | 'negative'
219
+
220
+ interface FormStepperProps extends React.HTMLAttributes<HTMLDivElement> {
221
+ activeStep?: number
222
+ theme?: 'dark' | 'light' | 'default'
223
+ }
224
+
225
+ interface FormStepProps
226
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, 'type'> {
227
+ index?: number
228
+ type?: FormStepperType
229
+ selected?: boolean
230
+ }
231
+ ```
232
+
233
+ ## Accessibility
234
+
235
+ - Each `FormStep` is a focusable interactive surface — attach `onClick` and (if needed) `role="button"` plus `tabIndex={0}` for keyboard navigation.
236
+ - The status badge is `aria-hidden`; the meaning should be carried by the label text (e.g. `"Payment — error"`).
237
+ - Color is never the sole signal for `success`/`negative` — pair with text or an off-screen description.
238
+
239
+ ## Best Practices
240
+
241
+ 1. Drive selection with `activeStep` from the parent form state — avoid setting `selected` per step manually.
242
+ 2. Use `success` only for *completed and validated* steps, `negative` only for *failed* steps. Default = pending or current.
243
+ 3. Keep labels short — the pill grows by `~3px` on hover, and long labels make that animation jittery.
244
+ 4. Wire `onClick` for non-linear navigation (jump-to-step). For strict wizards, omit `onClick` on future steps.