torch-glare 2.1.1 → 2.1.3

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 (73) hide show
  1. package/apps/lib/components/Avatar.tsx +1 -1
  2. package/apps/lib/components/BadgeField.tsx +2 -2
  3. package/apps/lib/components/Card.tsx +68 -54
  4. package/apps/lib/components/DataViews/ARCHITECTURE.md +439 -0
  5. package/apps/lib/components/DataViews/DataViewRadio.tsx +47 -0
  6. package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +427 -0
  7. package/apps/lib/components/DataViews/DataViewsHeader.tsx +228 -0
  8. package/apps/lib/components/DataViews/DataViewsLayout.tsx +330 -0
  9. package/apps/lib/components/DataViews/FilterPanel.tsx +469 -0
  10. package/apps/lib/components/DataViews/HeaderSearch.tsx +97 -0
  11. package/apps/lib/components/DataViews/InboxView.tsx +495 -0
  12. package/apps/lib/components/DataViews/InboxViewCard.tsx +136 -0
  13. package/apps/lib/components/DataViews/KanbanView.tsx +353 -0
  14. package/apps/lib/components/DataViews/PanelControls.tsx +49 -0
  15. package/apps/lib/components/DataViews/SettingsPanel.tsx +285 -0
  16. package/apps/lib/components/DataViews/TableView.tsx +232 -0
  17. package/apps/lib/components/DataViews/TreeView.tsx +392 -0
  18. package/apps/lib/components/DataViews/badgeAdapter.ts +45 -0
  19. package/apps/lib/components/DataViews/fieldRenderers.tsx +334 -0
  20. package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +113 -0
  21. package/apps/lib/components/DataViews/filters/PresetChips.tsx +45 -0
  22. package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +154 -0
  23. package/apps/lib/components/DataViews/index.ts +36 -0
  24. package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +54 -0
  25. package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +77 -0
  26. package/apps/lib/components/DataViews/types.ts +206 -0
  27. package/apps/lib/components/Radio.tsx +18 -21
  28. package/apps/lib/components/Switch.tsx +3 -1
  29. package/apps/lib/components/Table.tsx +1 -1
  30. package/apps/lib/components/TreeFolder/TreeFolder.tsx +410 -0
  31. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +80 -0
  32. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +363 -0
  33. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +60 -0
  34. package/apps/lib/components/TreeFolder/icons.tsx +63 -0
  35. package/apps/lib/components/TreeFolder/index.ts +17 -0
  36. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +114 -0
  37. package/apps/lib/components/TreeFolder/types.ts +77 -0
  38. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +261 -0
  39. package/apps/lib/hooks/useDataViewsState.ts +169 -0
  40. package/apps/lib/hooks/useIsMobile.ts +21 -0
  41. package/apps/lib/layouts/DataViewCard.tsx +76 -0
  42. package/apps/lib/utils/dataViews/columnUtils.ts +130 -0
  43. package/apps/lib/utils/dataViews/fieldUtils.ts +198 -0
  44. package/apps/lib/utils/dataViews/nestedDataUtils.tsx +364 -0
  45. package/apps/lib/utils/dataViews/pathUtils.ts +132 -0
  46. package/apps/lib/utils/dataViews/rangeUtils.ts +225 -0
  47. package/apps/lib/utils/dataViews/treeUtils.ts +403 -0
  48. package/dist/bin/index.js +3 -3
  49. package/dist/bin/index.js.map +1 -1
  50. package/dist/src/commands/add.d.ts.map +1 -1
  51. package/dist/src/commands/add.js +29 -6
  52. package/dist/src/commands/add.js.map +1 -1
  53. package/dist/src/commands/utils.d.ts.map +1 -1
  54. package/dist/src/commands/utils.js +22 -2
  55. package/dist/src/commands/utils.js.map +1 -1
  56. package/dist/src/shared/copyComponentsRecursively.d.ts.map +1 -1
  57. package/dist/src/shared/copyComponentsRecursively.js +17 -2
  58. package/dist/src/shared/copyComponentsRecursively.js.map +1 -1
  59. package/dist/src/shared/getDependenciesAndInstallNestedComponents.d.ts +18 -4
  60. package/dist/src/shared/getDependenciesAndInstallNestedComponents.d.ts.map +1 -1
  61. package/dist/src/shared/getDependenciesAndInstallNestedComponents.js +110 -40
  62. package/dist/src/shared/getDependenciesAndInstallNestedComponents.js.map +1 -1
  63. package/docs/components/data-views-config-panel.md +204 -0
  64. package/docs/components/data-views-layout.md +270 -0
  65. package/docs/components/form-stepper.md +244 -0
  66. package/docs/components/stepper.md +215 -0
  67. package/docs/components/timeline.md +248 -0
  68. package/package.json +6 -6
  69. package/apps/lib/components/Charts-dev.tsx +0 -365
  70. package/apps/lib/components/Command-dev.tsx +0 -151
  71. package/apps/lib/components/IosDatePicker-dev.tsx +0 -341
  72. /package/docs/components/{labeled-checkbox.md → labeled-check-box.md} +0 -0
  73. /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;
@@ -35,10 +42,18 @@ export function copyDirectorySync(source, target) {
35
42
  if (item.isDirectory()) {
36
43
  copyDirectorySync(sourcePath, targetPath);
37
44
  }
38
- else {
45
+ else if (isCopyableFile(item.name)) {
39
46
  fs.copyFileSync(sourcePath, targetPath);
40
47
  installDependencies(sourcePath);
41
48
  }
42
49
  }
43
50
  }
51
+ /**
52
+ * Decide whether a file should be copied into the user's project. Skips
53
+ * documentation/meta files that live alongside source for maintainers but add
54
+ * noise to a consumer's drop-in (e.g. ARCHITECTURE.md inside a component folder).
55
+ */
56
+ function isCopyableFile(fileName) {
57
+ return !/\.(md|mdx)$/i.test(fileName);
58
+ }
44
59
  //# sourceMappingURL=copyComponentsRecursively.js.map
@@ -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,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACxC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,QAAgB;IACpC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC1C,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":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,yCAAyC,CACrD,aAAqB,EACrB,qBAAkC;IAElC,MAAM,gBAAgB,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,gDAAgD,CAAC;IACrE,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAExC,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU;YAAE,SAAS;QAE1B,sDAAsD;QACtD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1C,CAAC;YACD,SAAS;QACb,CAAC;QAED,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAErC,2DAA2D;QAC3D,IAAI,OAAO,KAAK,CAAC;YAAE,SAAS;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAErB,qDAAqD;QACrD,uCAAuC;QACvC,uCAAuC;QACvC,sEAAsE;QACtE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACnB,0CAA0C;YAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACzB,IAAI,SAAS,EAAE,CAAC;gBACZ,OAAO,CAAC,SAAS,CAAC,CAAA;YACtB,CAAC;QACL,CAAC;aAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACzB,IAAI,SAAS,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,SAAS,KAAK,CAAC,CAAA;YAC9B,CAAC;QACL,CAAC;aAAM,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACzB,IAAI,SAAS,EAAE,CAAC;gBACZ,gEAAgE;gBAChE,GAAG,CAAC,SAAS,CAAC,CAAA;YAClB,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,6EAA6E;YAC7E,iFAAiF;YACjF,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACX,eAAe,CAAC,QAAQ,CAAC,CAAA;YAC7B,CAAC;iBAAM,CAAC;gBACJ,wCAAwC;gBACxC,GAAG,CAAC,IAAI,CAAC,CAAA;YACb,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,qBAAqB,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,OAAe,EAAE,UAAkB;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAA;IACjH,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IAClC,CAAC;IACD,OAAO,IAAI,CAAA;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,OAAe;IACpC,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACnC,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAM;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAChD,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;IACrB,IAAI,CAAC,KAAK;QAAE,OAAM;IAClB,QAAQ,MAAM,EAAE,CAAC;QACb,KAAK,YAAY;YAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YAAC,MAAK;QAC9C,KAAK,OAAO;YAAO,OAAO,CAAC,KAAK,CAAC,CAAC;YAAC,MAAK;QACxC,KAAK,OAAO;YAAO,OAAO,CAAC,KAAK,CAAC,CAAC;YAAC,MAAK;QACxC,KAAK,SAAS;YAAK,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YAAC,MAAK;IAClD,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,204 @@
1
+ ---
2
+ title: DataViewsConfigPanel
3
+ description: Slide-in side panel for DataViews — Saved View list, show/hide & drag-reorder columns, default sort, and a Filters tab. Used automatically by DataViewsLayout, or rendered standalone in composable mode.
4
+ group: Data Display
5
+ keywords: [data-views, config panel, config-panel, settings panel, saved view, saved-view, column visibility, reorder columns, default sort, filters tab, side panel, dark panel]
6
+ ---
7
+
8
+ # DataViewsConfigPanel
9
+
10
+ > The settings/filters side panel for DataViews. In tab mode `DataViewsLayout`
11
+ > mounts and animates this for you. Render it yourself only in composable mode
12
+ > (custom layouts) or when you need real Saved View persistence.
13
+
14
+ ## Installation
15
+
16
+ Part of `torch-glare`. Ships with the `DataViews` folder when you run
17
+ `npx torch-glare add DataViews` — no separate install. It depends on the
18
+ shared `Radio`, `Switch`, `Label`, `FilterPanel`, and a colocated internal
19
+ `PanelControls` file (see "Internal: PanelControls" below).
20
+
21
+ ## Import
22
+
23
+ ```tsx
24
+ import { DataViewsConfigPanel } from "torch-glare"
25
+ import type { DataViewsConfigPanelProps } from "torch-glare"
26
+ ```
27
+
28
+ ## When to use it directly
29
+
30
+ | Situation | Use |
31
+ |---|---|
32
+ | Standard tabbed dashboard | **Don't.** Use `DataViewsLayout` — it renders this panel for you via the header settings cog. |
33
+ | Custom composed layout (e.g. Table + Kanban side by side) | Render `DataViewsConfigPanel` yourself alongside `useDataViewsState`. |
34
+ | You need working Saved View persistence | Render it yourself and pass `savedViews` + `onSavedViewChange` + `onSaveNewView` wired to your store. (Not possible through `DataViewsLayout` today — see "Saved View status".) |
35
+
36
+ ## Standalone Example (composable mode)
37
+
38
+ ```tsx
39
+ import {
40
+ DataViewsConfigPanel,
41
+ TableView,
42
+ useDataViewsState,
43
+ } from "torch-glare"
44
+ import { useState } from "react"
45
+
46
+ function CustomScreen({ data, fields }) {
47
+ const s = useDataViewsState({ data, fields })
48
+ const [panelOpen, setPanelOpen] = useState(true)
49
+
50
+ // Your own saved-view persistence:
51
+ const [savedViews] = useState([
52
+ { id: "all", label: "All Records" },
53
+ { id: "mine", label: "Assigned to Me" },
54
+ ])
55
+ const [activeView, setActiveView] = useState("all")
56
+
57
+ return (
58
+ <div className="flex h-screen gap-2 bg-black p-2">
59
+ <div className="min-w-0 flex-1">
60
+ <TableView
61
+ data={s.flatItems}
62
+ fields={s.resolvedFields}
63
+ config={s.config}
64
+ filterState={s.filterState}
65
+ onFilterChange={s.setFilterState}
66
+ showFilters={false}
67
+ />
68
+ </div>
69
+
70
+ {panelOpen && (
71
+ <DataViewsConfigPanel
72
+ state="open"
73
+ config={s.config}
74
+ onConfigChange={s.setConfig}
75
+ onClose={() => setPanelOpen(false)}
76
+ currentView={s.currentView}
77
+ fields={s.resolvedFields}
78
+ data={s.flatItems}
79
+ filterState={s.filterState}
80
+ onFilterChange={s.setFilterState}
81
+ savedViews={savedViews}
82
+ activeSavedView={activeView}
83
+ onSavedViewChange={setActiveView}
84
+ onSaveNewView={() => {
85
+ /* open your "name this view" modal, then persist */
86
+ }}
87
+ />
88
+ )}
89
+ </div>
90
+ )
91
+ }
92
+ ```
93
+
94
+ ## API Reference
95
+
96
+ ### `DataViewsConfigPanelProps`
97
+
98
+ | Prop | Type | Required | Description |
99
+ |---|---|---|---|
100
+ | `config` | `ViewConfig` | ✅ | Current view config. `tableColumns` drives the column list; `sortBy`/`sortOrder` drive Default Sort. |
101
+ | `onConfigChange` | `(config: Partial<ViewConfig>) => void` | ✅ | Called with a partial patch when columns are toggled/reordered or a sort field is picked. Merge it into your config state. |
102
+ | `onClose` | `() => void` | ✅ | Fires when the panel's close (X) button is pressed. |
103
+ | `currentView` | `ViewType` | ✅ | **Currently unused inside the panel body** (declared on the prop type but not read). Still required by the type; pass the active view for forward-compatibility. |
104
+ | `fields` | `FieldConfig[]` | ✅ | Same field map you pass to the views. Drives the Filters tab and the column labels. |
105
+ | `data` | `DynamicRecord[]` | ✅ | Flat records — passed to the Filters tab (`FilterPanel`) to compute filter options. |
106
+ | `filterState` | `FilterState` | ✅ | Current filter values. The Filters tab reads/writes this. |
107
+ | `onFilterChange` | `(filters: FilterState) => void` | ✅ | Called with the full next filter object on any filter change (and on "Clear all" → `{}`). |
108
+ | `filterConfig` | `DynamicFilterConfig[]` | — | Optional explicit filter config forwarded to `FilterPanel`. |
109
+ | `savedViews` | `{ id: string; label: string }[]` | — | Saved View radio list. Defaults to a single `{ id: "default", label: "Default View" }`. |
110
+ | `activeSavedView` | `string` | — | Controlled selected saved-view id. If supplied, the panel is controlled (see "Controlled vs uncontrolled"). |
111
+ | `onSavedViewChange` | `(id: string) => void` | — | Called when a saved-view radio is selected. Required for controlled behaviour. |
112
+ | `onSaveNewView` | `() => void` | — | Called when "Save a New View" is clicked. No-op if omitted. |
113
+ | `state` | `"open" \| "closed"` | — | Drives the slide/opacity animation. Default `"open"`. Keep the panel mounted through the close animation, then unmount. |
114
+
115
+ > Note: `DataViewsConfigPanelProps` is a plain `type` (not extending HTML
116
+ > attributes). There is no `className`/`theme` passthrough — the panel is
117
+ > intentionally always-dark chrome (see "Theming").
118
+
119
+ ### Controlled vs uncontrolled Saved View
120
+
121
+ The Saved View list follows the standard controlled/uncontrolled pattern:
122
+
123
+ - **Controlled** — pass both `activeSavedView` and `onSavedViewChange`. You own
124
+ the selected id; the panel reflects it.
125
+ - **Uncontrolled** — omit them. The panel keeps internal state (initialised to
126
+ `savedViews[0]?.id`) so the radios are still interactive, but nothing
127
+ persists and it resets on unmount.
128
+
129
+ ```tsx
130
+ // Controlled
131
+ <DataViewsConfigPanel activeSavedView={id} onSavedViewChange={setId} ... />
132
+
133
+ // Uncontrolled (still clickable, local only)
134
+ <DataViewsConfigPanel savedViews={views} ... />
135
+ ```
136
+
137
+ ### Saved View status
138
+
139
+ Through `DataViewsLayout` (tab mode) the four `savedView*` props are **not
140
+ forwarded**, so Saved View there is presentational only. To get real behaviour,
141
+ render `DataViewsConfigPanel` yourself (example above) or extend the layout
142
+ (below).
143
+
144
+ ## Sections
145
+
146
+ | Section | Backed by | Behaviour |
147
+ |---|---|---|
148
+ | Saved View | `savedViews` / `activeSavedView` | Radio list + "Save a New View" button. |
149
+ | Table Columns | `config.tableColumns` | Green `Switch` per column toggles `visible`; rows are drag-reorderable (HTML5 DnD) and patch `order`. |
150
+ | Default Sort | `config.sortBy` | Single-choice radio; selecting sets `sortBy`. Direction stays on `config.sortOrder`. |
151
+ | Filters tab | `filterState` + `fields` | Renders `FilterPanel` restyled full-width/transparent. |
152
+
153
+ ## Internal: PanelControls
154
+
155
+ The panel's radio rows and column toggle are a colocated, **non-exported**
156
+ file: `DataViews/PanelControls.tsx` (`RadioRow`, `DataViewsSwitch`). They are
157
+ deliberately **not** shared library components — the panel chrome is always
158
+ dark and hardcodes Figma hex values, which conflicts with the design-system
159
+ token / `data-theme` convention used by public components.
160
+
161
+ You normally never import these. They ship automatically because the CLI
162
+ copies the entire `DataViews/` folder recursively, so the relative import
163
+ `./PanelControls` resolves in the consumer's copy with no registry wiring.
164
+
165
+ If you need a themed radio elsewhere, use the shared `Radio` component instead
166
+ — not `PanelControls`.
167
+
168
+ ## Extending the panel
169
+
170
+ Common changes and where to make them:
171
+
172
+ | You want to… | Do this |
173
+ |---|---|
174
+ | Make Saved View work through `DataViewsLayout` | Add `savedViews` / `activeSavedView` / `onSavedViewChange` / `onSaveNewView` to `DataViewsLayoutProps`, hold them in layout state (or accept from the host), and forward them to `<DataViewsConfigPanel>` at its render site in `DataViewsLayout.tsx`. |
175
+ | Add a new Config section | Add a new block inside the Config. tab in `DataViewsConfigPanel.tsx`, backed by a `config.*` field so `onConfigChange` persists it. |
176
+ | Restyle a radio/toggle | Edit `PanelControls.tsx`. Keep values matching the Figma spec; do not swap in the shared `Radio`/`Label` (they impose theming/layout that fights the dark panel — this was deliberate). |
177
+ | Change the dark chrome | The root forces `data-theme="dark"` and uses hardcoded hex (`#1C1D1F`, `#252729`, `#005ECC`, `#626467`, `#0AC713`). These are intentional Figma values, not tokens. |
178
+
179
+ After any change to the panel docs or component, update this file and rebuild
180
+ the MCP server (`cd mcp && pnpm build`) so the docs the server serves stay in
181
+ sync.
182
+
183
+ ## Accessibility
184
+
185
+ - Saved View / Default Sort use Radix `RadioGroup`; the whole row is the click
186
+ target with keyboard support.
187
+ - Column toggles are accessible `Switch`es; reorder is pointer-based HTML5 DnD
188
+ (provide a non-DnD path if your audience needs keyboard reordering).
189
+ - The close button has `aria-label="Close panel"`; tab buttons expose
190
+ `aria-pressed`.
191
+
192
+ ## Theming
193
+
194
+ Intentionally **always dark**. The root sets `data-theme="dark"` so child
195
+ themed components resolve dark tokens even when the host app runs light, and
196
+ the panel-specific chrome uses hardcoded Figma hex values rather than design
197
+ tokens. There is no `theme` prop — this is by design to match the Figma
198
+ "Cun" (#000000) panel spec.
199
+
200
+ ## Related
201
+
202
+ - [`DataViewsLayout`](./data-views-layout.md) — renders this panel for you in tab mode
203
+ - [`Radio`](./radio.md) — the themed radio to use **outside** this panel
204
+ - [`Switch`](./switch.md) — the shared switch the column toggles wrap