@campxdev/react-blueprint 3.0.0-alpha.8 → 3.0.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.
Files changed (43) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/cjs/types/src/components/Assets/Icons/IconComponents/CampxFullLogoIcon.d.ts +3 -1
  3. package/dist/cjs/types/src/components/Charts/TreeMap/TreeMap.d.ts +1 -2
  4. package/dist/cjs/types/src/components/DataDisplay/DataTable/components/TableHeaders/TableActionHeader.d.ts +2 -1
  5. package/dist/cjs/types/src/components/Input/MultiSelect/MultiSelect.d.ts +5 -1
  6. package/dist/cjs/types/src/components/Input/MultiSelect/components/MultiSelectInput.d.ts +1 -1
  7. package/dist/cjs/types/src/components/Input/SingleSelect/SingleSelect.d.ts +5 -1
  8. package/dist/cjs/types/src/components/Input/SingleSelect/components/SingleInput.d.ts +1 -1
  9. package/dist/cjs/types/src/components/Layout/AppLayout/AppLayout.d.ts +0 -1
  10. package/dist/cjs/types/src/shadcn-components/Charts/Chart.d.ts +8 -8
  11. package/dist/cjs/types/src/shadcn-components/Input/Command/Command.d.ts +1 -1
  12. package/dist/esm/index.js +2 -2
  13. package/dist/esm/types/src/components/Assets/Icons/IconComponents/CampxFullLogoIcon.d.ts +3 -1
  14. package/dist/esm/types/src/components/Charts/TreeMap/TreeMap.d.ts +1 -2
  15. package/dist/esm/types/src/components/DataDisplay/DataTable/components/TableHeaders/TableActionHeader.d.ts +2 -1
  16. package/dist/esm/types/src/components/Input/MultiSelect/MultiSelect.d.ts +5 -1
  17. package/dist/esm/types/src/components/Input/MultiSelect/components/MultiSelectInput.d.ts +1 -1
  18. package/dist/esm/types/src/components/Input/SingleSelect/SingleSelect.d.ts +5 -1
  19. package/dist/esm/types/src/components/Input/SingleSelect/components/SingleInput.d.ts +1 -1
  20. package/dist/esm/types/src/components/Layout/AppLayout/AppLayout.d.ts +0 -1
  21. package/dist/esm/types/src/shadcn-components/Charts/Chart.d.ts +8 -8
  22. package/dist/esm/types/src/shadcn-components/Input/Command/Command.d.ts +1 -1
  23. package/dist/index.d.ts +63 -4
  24. package/dist/styles.css +6 -4
  25. package/package.json +1 -1
  26. package/src/components/Assets/Icons/IconComponents/CampxFullLogoIcon.tsx +134 -19
  27. package/src/components/Charts/TreeMap/TreeMap.tsx +1 -3
  28. package/src/components/DataDisplay/DataTable/DataTable.tsx +1 -0
  29. package/src/components/DataDisplay/DataTable/components/CardsView.tsx +1 -1
  30. package/src/components/DataDisplay/DataTable/components/TableHeaders/TableActionHeader.tsx +23 -20
  31. package/src/components/Input/LabelWrapper/LabelWrapper.tsx +1 -1
  32. package/src/components/Input/MultiSelect/MultiSelect.tsx +18 -8
  33. package/src/components/Input/MultiSelect/components/MultiSelectInput.tsx +2 -3
  34. package/src/components/Input/SingleSelect/SingleSelect.tsx +23 -12
  35. package/src/components/Input/SingleSelect/components/SingleInput.tsx +2 -1
  36. package/src/components/Layout/AppLayout/AppLayout.tsx +0 -4
  37. package/src/components/Layout/PageContent/PageContent.tsx +1 -1
  38. package/src/components/Navigation/Dialog/Dialog.tsx +2 -1
  39. package/src/components/Navigation/DialogButton/DialogButton.tsx +2 -1
  40. package/src/shadcn-components/Charts/Chart.tsx +106 -106
  41. package/src/shadcn-components/DataDisplay/Card/Card.tsx +1 -1
  42. package/src/shadcn-components/Input/Command/Command.tsx +5 -0
  43. package/src/shadcn-components/Input/Label/Label.tsx +1 -1
@@ -115,7 +115,7 @@ export interface TreeMapProps {
115
115
  * />
116
116
  * );
117
117
  */
118
- const TreeMap: React.FC<TreeMapProps> = ({
118
+ export const TreeMap: React.FC<TreeMapProps> = ({
119
119
  title = 'Tree Map',
120
120
  titleProps = { variant: 'large' },
121
121
  showSubtitle = false,
@@ -177,8 +177,6 @@ const TreeMap: React.FC<TreeMapProps> = ({
177
177
  );
178
178
  };
179
179
 
180
- export default TreeMap;
181
-
182
180
  /**
183
181
  * CustomizedContent Component
184
182
  * Renders custom content for treemap cells with text labels and borders.
@@ -366,6 +366,7 @@ const DataTable = <TData extends Record<string, any> = any>(
366
366
  uniqueId={tableActionProps.uniqueId}
367
367
  columns={tableColumns}
368
368
  viewsProps={tableActionProps.viewsProps}
369
+ hasCardView={!!props.card}
369
370
  />
370
371
  )}
371
372
  </>
@@ -64,7 +64,7 @@ const CardsView = <TData extends Record<string, any> = any>({
64
64
  ) : card && rows && rows.length > 0 ? (
65
65
  rows.map((row, index) => card(row, index))
66
66
  ) : (
67
- <div className="col-span-full p-4 text-center border rounded-md">
67
+ <div className="col-span-full p-4 text-center border rounded-md min-h-[300px]">
68
68
  <p className="text-muted-foreground">No items available</p>
69
69
  </div>
70
70
  )}
@@ -20,6 +20,7 @@ type TableActionHeaderProps = {
20
20
  type: string;
21
21
  axios: Axios;
22
22
  };
23
+ hasCardView?: boolean;
23
24
  };
24
25
 
25
26
  const TableActionHeader = ({
@@ -28,6 +29,7 @@ const TableActionHeader = ({
28
29
  uniqueId,
29
30
  columns,
30
31
  viewsProps,
32
+ hasCardView = false,
31
33
  }: TableActionHeaderProps) => {
32
34
  const { data: views, isLoading } = useQuery(
33
35
  viewsProps.type,
@@ -71,11 +73,11 @@ const TableActionHeader = ({
71
73
 
72
74
  {/* Tablet & Desktop: Icon + Text */}
73
75
  <Button
74
- variant="default"
76
+ variant="link"
75
77
  size="sm"
76
78
  onClick={open}
77
79
  startIcon={<Plus />}
78
- className="hidden md:flex"
80
+ className="hidden hover:no-underline md:flex"
79
81
  >
80
82
  Add View
81
83
  </Button>
@@ -97,30 +99,31 @@ const TableActionHeader = ({
97
99
  <div className="flex items-center gap-2">
98
100
  {layoutMode === 'table' && (
99
101
  <>
100
- {' '}
101
102
  {/* Density Selector */}
102
103
  <DensitySelector uniqueId={uniqueId} />
103
104
  {/* Column Selector */}
104
105
  <ColumnSelector columns={columns} uniqueId={uniqueId} />
105
106
  </>
106
107
  )}
107
- {/* Layout Switcher */}
108
- <div className="flex gap-1 border rounded-md flex-shrink-0 bg-background">
109
- <Button
110
- variant={layoutMode === 'table' ? 'default' : 'ghost'}
111
- size="sm"
112
- onClick={() => onLayoutChange('table')}
113
- >
114
- <Table />
115
- </Button>
116
- <Button
117
- variant={layoutMode === 'card' ? 'default' : 'ghost'}
118
- size="sm"
119
- onClick={() => onLayoutChange('card')}
120
- >
121
- <LayoutGrid />
122
- </Button>
123
- </div>
108
+ {/* Layout Switcher - Only show if card view is available */}
109
+ {hasCardView && (
110
+ <div className="flex gap-1 border rounded-md flex-shrink-0 bg-background">
111
+ <Button
112
+ variant={layoutMode === 'table' ? 'default' : 'ghost'}
113
+ size="sm"
114
+ onClick={() => onLayoutChange('table')}
115
+ >
116
+ <Table />
117
+ </Button>
118
+ <Button
119
+ variant={layoutMode === 'card' ? 'default' : 'ghost'}
120
+ size="sm"
121
+ onClick={() => onLayoutChange('card')}
122
+ >
123
+ <LayoutGrid />
124
+ </Button>
125
+ </div>
126
+ )}
124
127
  </div>
125
128
  </Card>
126
129
  );
@@ -47,7 +47,7 @@ export const LabelWrapper = ({
47
47
  {typeof label === 'string' ? (
48
48
  <Label htmlFor={name}>
49
49
  {label}
50
- {required && <span className="text-destructive ml-1">*</span>}
50
+ {required && <span className="text-destructive">*</span>}
51
51
  </Label>
52
52
  ) : (
53
53
  label
@@ -22,6 +22,8 @@ export type MultiSelectProps = {
22
22
  name?: string;
23
23
  getValue?: (option: any) => any;
24
24
  value?: any[];
25
+ defaultValue?: any[];
26
+ placeholder?: string;
25
27
  dbValueProps?: {
26
28
  valueKey: string;
27
29
  isObjectId?: boolean;
@@ -70,6 +72,8 @@ export type MultiSelectProps = {
70
72
  * @param {boolean} [props.loading] - Whether options are loading
71
73
  * @param {boolean} [props.disableClear] - Whether to hide the clear button
72
74
  * @param {boolean} [props.fullWidth] - Whether the select takes full width
75
+ * @param {any[]} [props.defaultValue] - Default values when component is uncontrolled (overridden by value prop)
76
+ * @param {string} [props.placeholder] - Placeholder text shown when no values are selected
73
77
  * @param {'input' | 'filter'} [props.type='input'] - Display type
74
78
  * @param {(event: SyntheticEvent) => void} [props.onOpen] - Callback when menu opens
75
79
  * @param {(event: SyntheticEvent, reason: string) => void} [props.onClose] - Callback when menu closes
@@ -92,7 +96,9 @@ export const MultiSelect = ({
92
96
  optionsApiEndpointParams,
93
97
  externalAxios,
94
98
  getValue,
95
- value = [],
99
+ value,
100
+ defaultValue,
101
+ placeholder,
96
102
  onChange,
97
103
  dbValueProps = {
98
104
  valueKey: 'id',
@@ -110,16 +116,18 @@ export const MultiSelect = ({
110
116
  type = 'input',
111
117
  ...restProps
112
118
  }: MultiSelectProps) => {
119
+ // Prioritize value over defaultValue (value takes precedence if both exist)
120
+ const effectiveValue = value !== undefined ? value : defaultValue ?? [];
113
121
  const initialState: MultiSelectState = {
114
122
  open: false,
115
123
  loadingInternalOptions: false,
116
124
  loadingInitialInternalOptions: false,
117
125
  internalOptions: options ?? [],
118
126
  internalOptionsMap: generateOptionsMap(options ?? [], getValue),
119
- selectedValues: value,
127
+ selectedValues: effectiveValue,
120
128
  selectedOptionsMap: generateSelectedOptionsMap(
121
129
  options ?? [],
122
- value,
130
+ effectiveValue,
123
131
  getValue,
124
132
  ),
125
133
  limit: 10,
@@ -415,7 +423,7 @@ export const MultiSelect = ({
415
423
  ...(dbValueProps.isObjectId && { isObjectId: true }),
416
424
  ...(dbValueProps.isInt && { isInt: true }),
417
425
  ...(dbValueProps.isFloat && { isFloat: true }),
418
- selectedValueData: value,
426
+ selectedValueData: effectiveValue,
419
427
  filterBySelectedValues: true,
420
428
  },
421
429
  dbLabelProps,
@@ -429,7 +437,7 @@ export const MultiSelect = ({
429
437
  internalOptionsMap: generateOptionsMap(res.data, getValue),
430
438
  selectedOptionsMap: generateSelectedOptionsMap(
431
439
  res.data,
432
- value,
440
+ effectiveValue,
433
441
  getValue,
434
442
  ),
435
443
  },
@@ -444,7 +452,7 @@ export const MultiSelect = ({
444
452
  };
445
453
 
446
454
  useEffect(() => {
447
- if (value && value.length > 0 && optionsApiEndPoint) {
455
+ if (effectiveValue && effectiveValue.length > 0 && optionsApiEndPoint) {
448
456
  loadSelectedOptions().finally(() => {
449
457
  dispatch({
450
458
  actionType: MultiSelectActionsTypes.LOAD_SELECTED_OPTIONS_END,
@@ -470,7 +478,8 @@ export const MultiSelect = ({
470
478
  state={state}
471
479
  optionsApiEndPoint={optionsApiEndPoint}
472
480
  getValue={getValue}
473
- value={value}
481
+ value={effectiveValue}
482
+ placeholder={placeholder}
474
483
  dbLabelProps={dbLabelProps}
475
484
  {...restProps}
476
485
  />
@@ -488,7 +497,8 @@ export const MultiSelect = ({
488
497
  state={state}
489
498
  optionsApiEndPoint={optionsApiEndPoint}
490
499
  getValue={getValue}
491
- value={value}
500
+ value={effectiveValue}
501
+ placeholder={placeholder}
492
502
  dbLabelProps={dbLabelProps}
493
503
  {...restProps}
494
504
  />
@@ -43,6 +43,7 @@ export const MultiSelectInput = ({
43
43
  name,
44
44
  getValue,
45
45
  value = [],
46
+ placeholder = '',
46
47
  onChange,
47
48
  error,
48
49
  helperText,
@@ -155,9 +156,7 @@ export const MultiSelectInput = ({
155
156
  >
156
157
  <div className="flex items-center gap-2 flex-1 overflow-hidden">
157
158
  {selectedChips.length === 0 ? (
158
- <span className="text-muted-foreground">
159
- Select options...
160
- </span>
159
+ <span className="text-muted-foreground">{placeholder}</span>
161
160
  ) : (
162
161
  <>
163
162
  <Badge variant={'default'}>{firstChip.label}</Badge>
@@ -30,6 +30,8 @@ export type SingleSelectProps = {
30
30
  name?: string;
31
31
  getValue?: (option: any) => any;
32
32
  value?: any;
33
+ defaultValue?: any;
34
+ placeholder?: string;
33
35
  dbValueProps?: {
34
36
  valueKey: string;
35
37
  isObjectId?: boolean;
@@ -78,6 +80,8 @@ export type SingleSelectProps = {
78
80
  * @param {boolean} [props.loading] - Whether options are loading
79
81
  * @param {boolean} [props.disableClear] - Whether to hide the clear button
80
82
  * @param {boolean} [props.fullWidth] - Whether the select takes full width
83
+ * @param {any} [props.defaultValue] - Default value when component is uncontrolled (overridden by value prop)
84
+ * @param {string} [props.placeholder] - Placeholder text shown when no value is selected
81
85
  * @param {'input' | 'filter'} [props.type='input'] - Display type
82
86
  * @param {(event: SyntheticEvent) => void} [props.onOpen] - Callback when menu opens
83
87
  * @param {(event: SyntheticEvent, reason: string) => void} [props.onClose] - Callback when menu closes
@@ -101,6 +105,8 @@ export const SingleSelect = ({
101
105
  externalAxios,
102
106
  getValue,
103
107
  value,
108
+ defaultValue,
109
+ placeholder,
104
110
  onChange,
105
111
  dbValueProps = {
106
112
  valueKey: 'id',
@@ -139,6 +145,9 @@ export const SingleSelect = ({
139
145
 
140
146
  const internalAxios = externalAxios || axios;
141
147
 
148
+ // Prioritize value over defaultValue (value takes precedence if both exist)
149
+ const effectiveValue = value !== undefined ? value : defaultValue;
150
+
142
151
  const handleOpen = async (event: SyntheticEvent) => {
143
152
  dispatch({
144
153
  actionType: SingleSelectActionsTypes.OPEN,
@@ -211,10 +220,10 @@ export const SingleSelect = ({
211
220
  actionType: SingleSelectActionsTypes.CLEAR_SEARCH,
212
221
  stateChanges: {
213
222
  internalOptions: internalOptions.filter(
214
- (o: any) => o.value === value,
223
+ (o: any) => o.value === effectiveValue,
215
224
  ),
216
225
  internalOptionsMap: generateOptionsMap(
217
- internalOptions.filter((o: any) => o.value === value),
226
+ internalOptions.filter((o: any) => o.value === effectiveValue),
218
227
  ),
219
228
  },
220
229
  });
@@ -246,7 +255,7 @@ export const SingleSelect = ({
246
255
  ...(dbValueProps.isObjectId && { isObjectId: true }),
247
256
  ...(dbValueProps.isInt && { isInt: true }),
248
257
  ...(dbValueProps.isFloat && { isFloat: true }),
249
- selectedValueData: value,
258
+ selectedValueData: effectiveValue,
250
259
  },
251
260
  dbLabelProps: {
252
261
  search: search,
@@ -284,10 +293,10 @@ export const SingleSelect = ({
284
293
  actionType: SingleSelectActionsTypes.CLEAR_SEARCH,
285
294
  stateChanges: {
286
295
  internalOptions: internalOptions.filter(
287
- (o: any) => o.value === value,
296
+ (o: any) => o.value === effectiveValue,
288
297
  ),
289
298
  internalOptionsMap: generateOptionsMap(
290
- internalOptions.filter((o: any) => o.value === value),
299
+ internalOptions.filter((o: any) => o.value === effectiveValue),
291
300
  ),
292
301
  },
293
302
  });
@@ -307,7 +316,7 @@ export const SingleSelect = ({
307
316
  ...(dbValueProps.isObjectId && { isObjectId: true }),
308
317
  ...(dbValueProps.isInt && { isInt: true }),
309
318
  ...(dbValueProps.isFloat && { isFloat: true }),
310
- selectedValueData: value,
319
+ selectedValueData: effectiveValue,
311
320
  },
312
321
  dbLabelProps: {
313
322
  search: searchValue,
@@ -324,11 +333,11 @@ export const SingleSelect = ({
324
333
  stateChanges: {
325
334
  internalOptions: [
326
335
  ...options,
327
- ...internalOptions.filter((o: any) => o.value === value),
336
+ ...internalOptions.filter((o: any) => o.value === effectiveValue),
328
337
  ],
329
338
  internalOptionsMap: generateOptionsMap([
330
339
  ...options,
331
- ...internalOptions.filter((o: any) => o.value === value),
340
+ ...internalOptions.filter((o: any) => o.value === effectiveValue),
332
341
  ]),
333
342
  },
334
343
  });
@@ -360,7 +369,7 @@ export const SingleSelect = ({
360
369
  ...(dbValueProps.isObjectId && { isObjectId: true }),
361
370
  ...(dbValueProps.isInt && { isInt: true }),
362
371
  ...(dbValueProps.isFloat && { isFloat: true }),
363
- selectedValueData: value,
372
+ selectedValueData: effectiveValue,
364
373
  filterBySelectedValues: true,
365
374
  },
366
375
  dbLabelProps,
@@ -384,7 +393,7 @@ export const SingleSelect = ({
384
393
  };
385
394
 
386
395
  useEffect(() => {
387
- if (value && optionsApiEndPoint) {
396
+ if (effectiveValue && optionsApiEndPoint) {
388
397
  loadSelectedOptions().finally(() => {
389
398
  dispatch({
390
399
  actionType: SingleSelectActionsTypes.LOAD_SELECTED_OPTIONS_END,
@@ -408,7 +417,8 @@ export const SingleSelect = ({
408
417
  state={state}
409
418
  optionsApiEndPoint={optionsApiEndPoint}
410
419
  getValue={getValue}
411
- value={value}
420
+ value={effectiveValue}
421
+ placeholder={placeholder}
412
422
  dbLabelProps={dbLabelProps}
413
423
  {...restProps}
414
424
  />
@@ -424,7 +434,8 @@ export const SingleSelect = ({
424
434
  state={state}
425
435
  optionsApiEndPoint={optionsApiEndPoint}
426
436
  getValue={getValue}
427
- value={value}
437
+ value={effectiveValue}
438
+ placeholder={placeholder}
428
439
  dbLabelProps={dbLabelProps}
429
440
  {...restProps}
430
441
  />
@@ -39,6 +39,7 @@ export const SingleInput = ({
39
39
  name,
40
40
  getValue,
41
41
  value,
42
+ placeholder,
42
43
  onChange,
43
44
  error,
44
45
  helperText,
@@ -140,7 +141,7 @@ export const SingleInput = ({
140
141
  'border-destructive focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',
141
142
  )}
142
143
  >
143
- {selectedOption?.label || 'Select an option...'}
144
+ {selectedOption?.label || placeholder || 'Select an option...'}
144
145
  <ChevronDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
145
146
  </Button>
146
147
  </span>
@@ -15,7 +15,6 @@ import { AppLayoutProps } from './types';
15
15
  * @param {SideMenuItemProps[]} menu - Navigation menu items for the sidebar
16
16
  * @param {ReactNode | ((params: { collapsed: boolean }) => ReactNode)} [actions] - Optional action elements or function that receives collapsed state
17
17
  * @param {string} [mainContainerClassName=''] - Additional CSS classes for the main content container
18
- * @param {HelpDocsConfig} [helpDocsConfig] - Configuration for context-based help documentation
19
18
  * @param {boolean} [initialCollapsed] - Initial state of sidebar collapse (auto-determined on small screens)
20
19
  * @param {UserProfilePopupProps} [userProfileParams] - Configuration for user profile popup/menu
21
20
  *
@@ -41,7 +40,6 @@ export const AppLayout: React.FC<AppLayoutProps> = ({
41
40
  menu,
42
41
  actions,
43
42
  mainContainerClassName = '',
44
- helpDocsConfig,
45
43
  initialCollapsed,
46
44
  userProfileParams,
47
45
  }) => {
@@ -53,7 +51,6 @@ export const AppLayout: React.FC<AppLayoutProps> = ({
53
51
  menu={menu}
54
52
  actions={actions}
55
53
  mainContainerClassName={mainContainerClassName}
56
- helpDocsConfig={helpDocsConfig}
57
54
  userProfileParams={userProfileParams}
58
55
  >
59
56
  {children}
@@ -67,7 +64,6 @@ const AppLayoutContent: React.FC<AppLayoutProps> = ({
67
64
  menu,
68
65
  actions,
69
66
  mainContainerClassName = '',
70
- helpDocsConfig,
71
67
  userProfileParams,
72
68
  }) => {
73
69
  const { collapsed, setCollapsed } = useSidebar();
@@ -37,7 +37,7 @@ const PageContent = ({ children, className, styles }: PageContentProps) => {
37
37
  className,
38
38
  )}
39
39
  style={{
40
- height: isSmallScreen ? 'calc(100vh - 101px)' : `calc(100vh - 80px)`,
40
+ height: isSmallScreen ? 'calc(100vh - 149px)' : `calc(100vh - 85px)`,
41
41
  overflowY: 'auto',
42
42
  ...styles,
43
43
  }}
@@ -89,6 +89,7 @@ const Dialog = ({
89
89
  lg: 'max-w-lg',
90
90
  xl: 'max-w-xl',
91
91
  '2xl': 'max-w-2xl',
92
+ '3xl': 'max-w-3xl',
92
93
  };
93
94
 
94
95
  return (
@@ -105,7 +106,7 @@ const Dialog = ({
105
106
  showCloseButton={showCloseButton}
106
107
  >
107
108
  {title && (
108
- <DialogHeader className="pl-4 py-4 border-b">
109
+ <DialogHeader className="p-4 pr-0 border-b">
109
110
  <ShadcnDialogTitle>{title}</ShadcnDialogTitle>
110
111
  </DialogHeader>
111
112
  )}
@@ -102,6 +102,7 @@ export const DialogButton = ({
102
102
  lg: 'max-w-lg',
103
103
  xl: 'max-w-xl',
104
104
  '2xl': 'max-w-2xl',
105
+ '3xl': 'max-w-3xl',
105
106
  };
106
107
 
107
108
  const onClose = () => {
@@ -134,7 +135,7 @@ export const DialogButton = ({
134
135
  showCloseButton={showCloseButton}
135
136
  >
136
137
  {title && (
137
- <DialogHeader className="pl-4 pt-4">
138
+ <DialogHeader className="p-4 pr-0 border-b">
138
139
  <ShadcnDialogTitle>{title}</ShadcnDialogTitle>
139
140
  </DialogHeader>
140
141
  )}