@m4l/components 9.3.43 → 9.4.0-JA-20251207-Beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/export.d.ts +2 -2
- package/@types/types.d.ts +18 -10
- package/components/CheckableList/CheckableList.d.ts +20 -0
- package/components/CheckableList/CheckableList.js +225 -0
- package/components/CheckableList/CheckableList.styles.d.ts +2 -0
- package/components/CheckableList/CheckableList.styles.js +247 -0
- package/components/CheckableList/constants.d.ts +5 -0
- package/components/CheckableList/constants.js +17 -0
- package/components/CheckableList/dictionary.d.ts +14 -0
- package/components/CheckableList/dictionary.js +14 -0
- package/components/CheckableList/hooks/index.d.ts +6 -0
- package/components/CheckableList/hooks/useCheckableListHandlers.d.ts +21 -0
- package/components/CheckableList/hooks/useCheckableListHandlers.js +66 -0
- package/components/CheckableList/hooks/useCheckableListItems.d.ts +19 -0
- package/components/CheckableList/hooks/useCheckableListItems.js +79 -0
- package/components/CheckableList/hooks/useCheckableListRender.d.ts +52 -0
- package/components/CheckableList/hooks/useCheckableListRender.js +223 -0
- package/components/CheckableList/hooks/useCheckableListSelection.d.ts +19 -0
- package/components/CheckableList/hooks/useCheckableListSelection.js +69 -0
- package/components/CheckableList/hooks/useCheckableListState.d.ts +17 -0
- package/components/CheckableList/hooks/useCheckableListState.js +59 -0
- package/components/CheckableList/hooks/useCheckableListVirtualization.d.ts +14 -0
- package/components/CheckableList/hooks/useCheckableListVirtualization.js +42 -0
- package/components/CheckableList/icons.d.ts +5 -0
- package/components/CheckableList/icons.js +8 -0
- package/components/CheckableList/index.d.ts +3 -0
- package/components/CheckableList/index.js +1 -0
- package/components/CheckableList/slots/index.d.ts +2 -0
- package/components/CheckableList/slots/index.js +1 -0
- package/components/CheckableList/slots/slots.d.ts +26 -0
- package/components/CheckableList/slots/slots.js +30 -0
- package/components/CheckableList/slots/styled.d.ts +72 -0
- package/components/CheckableList/slots/styled.js +130 -0
- package/components/CheckableList/types.d.ts +277 -0
- package/components/CommonActions/components/ActionFormCancel/ActionFormCancel.js +1 -1
- package/components/DataGrid/Datagrid.styles.js +8 -8
- package/components/DataGrid/subcomponents/CheckboxCellAdapter/index.js +2 -2
- package/components/DataGrid/subcomponents/Table/subcomponents/RadioFormatter.d.ts +6 -0
- package/components/DataGrid/subcomponents/Table/subcomponents/RadioFormatter.js +12 -0
- package/components/DataGrid/subcomponents/Table/subcomponents/RadioSelectColumn.js +2 -2
- package/components/DynamicFilter/store/DynamicFilterContext.js +11 -0
- package/components/DynamicFilter/store/DynamicFilterStore.js +9 -0
- package/components/DynamicFilter/subcomponents/DynamicFilterBase/useDynamicFilterBase.d.ts +1 -1
- package/components/DynamicFilter/types.d.ts +4 -0
- package/components/DynamicSort/store/DynamicSortStore.js +6 -0
- package/components/DynamicSort/subcomponents/DynamicSortBase/useDynamicSortBase.d.ts +1 -1
- package/components/DynamicSort/types.d.ts +4 -0
- package/components/MFIsolationApp/slots/MFIsolationAppSlots.d.ts +2 -2
- package/components/ObjectLogs/slots/ObjectLogsSlots.d.ts +1 -1
- package/components/Stepper/Stepper.styles.js +13 -8
- package/components/WindowBase/hooks/useDynamicMFParameters/index.d.ts +4 -4
- package/components/areas/contexts/AreasContext/store.js +2 -2
- package/components/commercial/SectionCommercial/styles.d.ts +1 -1
- package/components/hook-form/RHFCheckableList/RHFCheckableList.d.ts +7 -0
- package/components/hook-form/RHFCheckableList/RHFCheckableList.js +91 -0
- package/components/hook-form/RHFCheckableList/RHFCheckableList.styles.d.ts +2 -0
- package/components/hook-form/RHFCheckableList/RHFCheckableList.styles.js +30 -0
- package/components/hook-form/RHFCheckableList/constants.d.ts +8 -0
- package/components/hook-form/RHFCheckableList/constants.js +11 -0
- package/components/hook-form/RHFCheckableList/index.d.ts +2 -0
- package/components/hook-form/RHFCheckableList/index.js +1 -0
- package/components/hook-form/RHFCheckableList/slots/RHFCheckableListEnum.d.ts +6 -0
- package/components/hook-form/RHFCheckableList/slots/RHFCheckableListEnum.js +10 -0
- package/components/hook-form/RHFCheckableList/slots/RHFCheckableListSlots.d.ts +20 -0
- package/components/hook-form/RHFCheckableList/slots/RHFCheckableListSlots.js +29 -0
- package/components/hook-form/RHFCheckableList/slots/index.d.ts +2 -0
- package/components/hook-form/RHFCheckableList/types.d.ts +60 -0
- package/components/hook-form/RHFColorPicker/hooks/useColorPicker/useColorPicker.d.ts +1 -1
- package/components/hook-form/RHFPeriod/subcomponents/Period/Period.js +3 -4
- package/components/hook-form/RHFRadioGroup/RHFRadioGroup.d.ts +3 -3
- package/components/hook-form/RHFRadioGroup/RHFRadioGroup.js +66 -24
- package/components/hook-form/RHFRadioGroup/RHFRadioGroup.styles.d.ts +5 -0
- package/components/hook-form/RHFRadioGroup/RHFRadioGroup.styles.js +29 -0
- package/components/hook-form/RHFRadioGroup/constants.d.ts +5 -0
- package/components/hook-form/RHFRadioGroup/constants.js +8 -0
- package/components/hook-form/RHFRadioGroup/formatters/OptionIconLabelFormatter/index.d.ts +2 -2
- package/components/hook-form/RHFRadioGroup/slots/slots.d.ts +5 -0
- package/components/hook-form/RHFRadioGroup/slots/slots.js +9 -0
- package/components/hook-form/RHFRadioGroup/slots/styled.d.ts +9 -0
- package/components/hook-form/RHFRadioGroup/slots/styled.js +20 -0
- package/components/hook-form/RHFRadioGroup/types.d.ts +55 -11
- package/components/hook-form/RHFUpload/RHFUploadImage/subcomponents/UploadImage/UploadImage.js +1 -1
- package/components/hook-form/index.d.ts +1 -0
- package/components/index.d.ts +1 -0
- package/components/mui_extended/CheckBox/CheckBox.js +2 -0
- package/components/mui_extended/Radio/Radio.d.ts +20 -0
- package/components/mui_extended/{RadioButton/RadioButton.js → Radio/Radio.js} +27 -26
- package/components/mui_extended/Radio/Radio.styles.d.ts +2 -0
- package/components/mui_extended/{RadioButton/RadioButton.styles.js → Radio/Radio.styles.js} +17 -42
- package/components/mui_extended/Radio/constants.d.ts +2 -0
- package/components/mui_extended/Radio/constants.js +8 -0
- package/components/mui_extended/Radio/index.d.ts +1 -0
- package/components/mui_extended/Radio/index.js +1 -0
- package/components/mui_extended/Radio/slots/slots.d.ts +6 -0
- package/components/mui_extended/Radio/slots/slots.js +10 -0
- package/components/mui_extended/{RadioButton/slots/RadioButtonSlots.d.ts → Radio/slots/styled.d.ts} +6 -12
- package/components/mui_extended/Radio/slots/styled.js +28 -0
- package/components/mui_extended/Radio/types.d.ts +53 -0
- package/components/mui_extended/Stack/Stack.d.ts +1 -1
- package/components/mui_extended/Stack/Stack.js +5 -2
- package/components/mui_extended/index.d.ts +1 -1
- package/hooks/useDynamicFilterAndSort/slots/DynamicFilterAndSortEnum.d.ts +2 -1
- package/hooks/useDynamicFilterAndSort/slots/DynamicFilterAndSortEnum.js +1 -0
- package/hooks/useDynamicFilterAndSort/slots/DynamicFilterAndSortSlots.d.ts +6 -3
- package/hooks/useDynamicFilterAndSort/slots/DynamicFilterAndSortSlots.js +6 -0
- package/hooks/useDynamicFilterAndSort/styles.js +23 -0
- package/hooks/useDynamicFilterAndSort/types.d.ts +2 -0
- package/hooks/useDynamicFilterAndSort/useDynamicFilterAndSort.js +27 -21
- package/index.js +145 -139
- package/package.json +1 -1
- package/components/DataGrid/subcomponents/Table/subcomponents/RadioButtonFormatter.d.ts +0 -6
- package/components/DataGrid/subcomponents/Table/subcomponents/RadioButtonFormatter.js +0 -12
- package/components/hook-form/RHFRadioGroup/formatters/OptionIconLabelFormatter/index.js +0 -16
- package/components/mui_extended/RadioButton/RadioButton.d.ts +0 -24
- package/components/mui_extended/RadioButton/RadioButton.styles.d.ts +0 -2
- package/components/mui_extended/RadioButton/constants.d.ts +0 -1
- package/components/mui_extended/RadioButton/constants.js +0 -4
- package/components/mui_extended/RadioButton/index.d.ts +0 -1
- package/components/mui_extended/RadioButton/slots/RadioButtonEnum.d.ts +0 -8
- package/components/mui_extended/RadioButton/slots/RadioButtonEnum.js +0 -12
- package/components/mui_extended/RadioButton/slots/RadioButtonSlots.js +0 -39
- package/components/mui_extended/RadioButton/types.d.ts +0 -50
- /package/components/{mui_extended/RadioButton → CheckableList/hooks}/index.js +0 -0
- /package/components/DataGrid/tests/table/subcomponents/{RadioButtonFormatter.test.d.ts → RadioFormatter.test.d.ts} +0 -0
- /package/components/mui_extended/{RadioButton → Radio}/icons.d.ts +0 -0
- /package/components/mui_extended/{RadioButton → Radio}/icons.js +0 -0
- /package/components/mui_extended/{RadioButton/tests/RadioButton.test.d.ts → Radio/tests/Radio.test.d.ts} +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
const useCheckableListHandlers = ({
|
|
3
|
+
value,
|
|
4
|
+
onChange,
|
|
5
|
+
multiple = true,
|
|
6
|
+
disabled = false,
|
|
7
|
+
normalizedItems,
|
|
8
|
+
getGroupItems,
|
|
9
|
+
isGroupFullySelected,
|
|
10
|
+
isItemSelected,
|
|
11
|
+
areAllItemsSelected
|
|
12
|
+
}) => {
|
|
13
|
+
const handleItemToggle = useCallback(
|
|
14
|
+
(itemId) => {
|
|
15
|
+
if (!onChange || disabled) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (multiple) {
|
|
19
|
+
const newValue = isItemSelected(itemId) ? value.filter((id) => id !== itemId) : [...value, itemId];
|
|
20
|
+
onChange(newValue);
|
|
21
|
+
} else {
|
|
22
|
+
onChange(isItemSelected(itemId) ? [] : [itemId]);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
[onChange, disabled, multiple, value, isItemSelected]
|
|
26
|
+
);
|
|
27
|
+
const handleGroupToggle = useCallback(
|
|
28
|
+
(group) => {
|
|
29
|
+
if (!onChange || disabled) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const groupItems = getGroupItems(group);
|
|
33
|
+
const allSelected = isGroupFullySelected(group);
|
|
34
|
+
if (allSelected) {
|
|
35
|
+
const newValue = value.filter(
|
|
36
|
+
(id) => !groupItems.some((item) => item.id === id)
|
|
37
|
+
);
|
|
38
|
+
onChange(newValue);
|
|
39
|
+
} else {
|
|
40
|
+
const itemIds = groupItems.map((item) => item.id);
|
|
41
|
+
const newValue = [.../* @__PURE__ */ new Set([...value, ...itemIds])];
|
|
42
|
+
onChange(newValue);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
[onChange, disabled, value, getGroupItems, isGroupFullySelected]
|
|
46
|
+
);
|
|
47
|
+
const handleSelectAllToggle = useCallback(() => {
|
|
48
|
+
if (!onChange || disabled) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (areAllItemsSelected) {
|
|
52
|
+
onChange([]);
|
|
53
|
+
} else {
|
|
54
|
+
const allIds = normalizedItems.map((item) => item.id);
|
|
55
|
+
onChange(allIds);
|
|
56
|
+
}
|
|
57
|
+
}, [onChange, disabled, areAllItemsSelected, normalizedItems]);
|
|
58
|
+
return {
|
|
59
|
+
handleItemToggle,
|
|
60
|
+
handleGroupToggle,
|
|
61
|
+
handleSelectAllToggle
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export {
|
|
65
|
+
useCheckableListHandlers as u
|
|
66
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CheckableListItem, CheckableListGroup, VirtualizedItem } from '../types';
|
|
2
|
+
interface UseCheckableListItemsProps {
|
|
3
|
+
items?: CheckableListItem[];
|
|
4
|
+
groups?: CheckableListGroup[];
|
|
5
|
+
searchQuery: string;
|
|
6
|
+
filterFn?: (item: CheckableListItem, query: string) => boolean;
|
|
7
|
+
expandedGroups: Set<string | number>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Hook para manejar la normalización, filtrado y construcción de items virtualizados
|
|
11
|
+
*/
|
|
12
|
+
export declare const useCheckableListItems: ({ items, groups, searchQuery, filterFn, expandedGroups, }: UseCheckableListItemsProps) => {
|
|
13
|
+
isGrouped: boolean;
|
|
14
|
+
normalizedItems: CheckableListItem[];
|
|
15
|
+
filteredItems: CheckableListItem[];
|
|
16
|
+
filteredGroups: CheckableListGroup[];
|
|
17
|
+
virtualizedItems: VirtualizedItem[];
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
const useCheckableListItems = ({
|
|
3
|
+
items = [],
|
|
4
|
+
groups,
|
|
5
|
+
searchQuery,
|
|
6
|
+
filterFn,
|
|
7
|
+
expandedGroups
|
|
8
|
+
}) => {
|
|
9
|
+
const isGrouped = !!groups && groups.length > 0;
|
|
10
|
+
const normalizedItems = useMemo(() => {
|
|
11
|
+
if (isGrouped) {
|
|
12
|
+
return groups.flatMap((group) => group.items);
|
|
13
|
+
}
|
|
14
|
+
return items;
|
|
15
|
+
}, [items, groups, isGrouped]);
|
|
16
|
+
const filteredItems = useMemo(() => {
|
|
17
|
+
if (!searchQuery.trim()) {
|
|
18
|
+
return normalizedItems;
|
|
19
|
+
}
|
|
20
|
+
const query = searchQuery.toLowerCase();
|
|
21
|
+
const defaultFilter = (item) => item.label.toLowerCase().includes(query) || item.description?.toLowerCase().includes(query);
|
|
22
|
+
return normalizedItems.filter(
|
|
23
|
+
(item) => filterFn ? filterFn(item, searchQuery) : defaultFilter(item)
|
|
24
|
+
);
|
|
25
|
+
}, [normalizedItems, searchQuery, filterFn]);
|
|
26
|
+
const filteredGroups = useMemo(() => {
|
|
27
|
+
if (!isGrouped || !searchQuery.trim()) {
|
|
28
|
+
return groups || [];
|
|
29
|
+
}
|
|
30
|
+
const normalizedQuery = searchQuery.toLowerCase();
|
|
31
|
+
const defaultGroupFilter = (candidate) => candidate.label.toLowerCase().includes(normalizedQuery) || candidate.description?.toLowerCase().includes(normalizedQuery);
|
|
32
|
+
return (groups || []).map((group) => ({
|
|
33
|
+
...group,
|
|
34
|
+
items: group.items.filter(
|
|
35
|
+
(groupItem) => filterFn ? filterFn(groupItem, searchQuery) : defaultGroupFilter(groupItem)
|
|
36
|
+
)
|
|
37
|
+
})).filter((group) => group.items.length > 0);
|
|
38
|
+
}, [groups, isGrouped, searchQuery, filterFn]);
|
|
39
|
+
const virtualizedItems = useMemo(() => {
|
|
40
|
+
if (isGrouped) {
|
|
41
|
+
const virtualizedList = [];
|
|
42
|
+
filteredGroups.forEach((group, groupIndex) => {
|
|
43
|
+
const isExpanded = expandedGroups.has(group.id);
|
|
44
|
+
virtualizedList.push({
|
|
45
|
+
type: "group",
|
|
46
|
+
data: group,
|
|
47
|
+
index: virtualizedList.length,
|
|
48
|
+
groupIndex
|
|
49
|
+
});
|
|
50
|
+
if (isExpanded) {
|
|
51
|
+
group.items.forEach((item) => {
|
|
52
|
+
virtualizedList.push({
|
|
53
|
+
type: "item",
|
|
54
|
+
data: item,
|
|
55
|
+
index: virtualizedList.length,
|
|
56
|
+
groupIndex
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return virtualizedList;
|
|
62
|
+
}
|
|
63
|
+
return filteredItems.map((item, index) => ({
|
|
64
|
+
type: "item",
|
|
65
|
+
data: item,
|
|
66
|
+
index
|
|
67
|
+
}));
|
|
68
|
+
}, [isGrouped, filteredGroups, filteredItems, expandedGroups]);
|
|
69
|
+
return {
|
|
70
|
+
isGrouped,
|
|
71
|
+
normalizedItems,
|
|
72
|
+
filteredItems,
|
|
73
|
+
filteredGroups,
|
|
74
|
+
virtualizedItems
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export {
|
|
78
|
+
useCheckableListItems as u
|
|
79
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { MouseEvent, ChangeEvent } from 'react';
|
|
2
|
+
import { ListChildComponentProps } from 'react-window';
|
|
3
|
+
import { Sizes } from '@m4l/styles';
|
|
4
|
+
import { CheckableListItem, CheckableListGroup, CheckableListRenderItemParams } from '../types';
|
|
5
|
+
export interface CheckableListRenderGroupParams {
|
|
6
|
+
group: CheckableListGroup;
|
|
7
|
+
items: CheckableListItem[];
|
|
8
|
+
index: number;
|
|
9
|
+
expanded: boolean;
|
|
10
|
+
disabled: boolean;
|
|
11
|
+
size: Extract<Sizes, 'small' | 'medium'>;
|
|
12
|
+
variant: 'standard' | 'outlined' | 'compact';
|
|
13
|
+
checkboxState: boolean | 'indeterminate';
|
|
14
|
+
onToggleExpand: (event: MouseEvent) => void;
|
|
15
|
+
onToggleGroup: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
16
|
+
selectedCount: number;
|
|
17
|
+
totalCount: number;
|
|
18
|
+
}
|
|
19
|
+
interface UseCheckableListRenderProps {
|
|
20
|
+
isItemSelected: (itemId: string | number) => boolean;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
size?: Extract<Sizes, 'small' | 'medium'>;
|
|
23
|
+
variant?: 'standard' | 'outlined' | 'compact';
|
|
24
|
+
checkboxSize?: 'small' | 'medium';
|
|
25
|
+
handleItemToggle: (itemId: string | number) => void;
|
|
26
|
+
renderItem?: (params: CheckableListRenderItemParams) => React.ReactNode;
|
|
27
|
+
expandedGroups: Set<string | number>;
|
|
28
|
+
isGroupFullySelected: (group: CheckableListGroup) => boolean;
|
|
29
|
+
isGroupPartiallySelected: (group: CheckableListGroup) => boolean;
|
|
30
|
+
getGroupItems: (group: CheckableListGroup) => CheckableListItem[];
|
|
31
|
+
indeterminateBehavior?: 'select-all' | 'indicate-some';
|
|
32
|
+
renderGroup?: (params: CheckableListRenderGroupParams) => React.ReactNode;
|
|
33
|
+
groupable?: boolean;
|
|
34
|
+
showCheckboxOnGroup?: boolean;
|
|
35
|
+
handleGroupExpandToggle: (groupId: string | number) => void;
|
|
36
|
+
handleGroupToggle: (group: CheckableListGroup) => void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Tipo de retorno del hook useCheckableListRender
|
|
40
|
+
*/
|
|
41
|
+
interface UseCheckableListRenderReturn {
|
|
42
|
+
renderItemContent: (item: CheckableListItem, index: number) => React.ReactNode;
|
|
43
|
+
renderGroupContent: (group: CheckableListGroup, index: number) => React.ReactNode;
|
|
44
|
+
renderVirtualizedItem: (props: ListChildComponentProps) => React.ReactNode;
|
|
45
|
+
urlIconSearch: string;
|
|
46
|
+
urlIconNoResults: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Hook para manejar el renderizado de items y grupos
|
|
50
|
+
*/
|
|
51
|
+
export declare const useCheckableListRender: ({ isItemSelected, disabled, size, variant, checkboxSize, handleItemToggle, renderItem, expandedGroups, isGroupFullySelected, isGroupPartiallySelected, getGroupItems, indeterminateBehavior, renderGroup, groupable, showCheckboxOnGroup, handleGroupExpandToggle, handleGroupToggle, }: UseCheckableListRenderProps) => UseCheckableListRenderReturn;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { useEnvironment } from "@m4l/core";
|
|
4
|
+
import { I as ICONS } from "../icons.js";
|
|
5
|
+
import { I as ItemLabelTypografyStyled, e as ItemDescriptionTypografyStyled, f as ItemWrapperStyled, g as ItemCheckboxStyled, h as ItemIconStyled, i as ItemContentWrapperStyled, G as GroupLabelCountWrapperStyled, j as GroupLabelTypografyStyled, C as ChipCountTypografyStyled, k as GroupWrapperStyled, l as GroupHeaderStyled, m as GroupCheckboxStyled, n as GroupIconStyled, o as GroupToggleButtonStyled } from "../slots/styled.js";
|
|
6
|
+
const useCheckableListRender = ({
|
|
7
|
+
isItemSelected,
|
|
8
|
+
disabled = false,
|
|
9
|
+
size = "medium",
|
|
10
|
+
variant = "standard",
|
|
11
|
+
checkboxSize = "medium",
|
|
12
|
+
handleItemToggle,
|
|
13
|
+
renderItem,
|
|
14
|
+
expandedGroups,
|
|
15
|
+
isGroupFullySelected,
|
|
16
|
+
isGroupPartiallySelected,
|
|
17
|
+
getGroupItems,
|
|
18
|
+
indeterminateBehavior = "indicate-some",
|
|
19
|
+
renderGroup,
|
|
20
|
+
groupable = true,
|
|
21
|
+
showCheckboxOnGroup = true,
|
|
22
|
+
handleGroupExpandToggle,
|
|
23
|
+
handleGroupToggle
|
|
24
|
+
}) => {
|
|
25
|
+
const { host_static_assets, environment_assets } = useEnvironment();
|
|
26
|
+
const urlIconExpanded = `${host_static_assets}/${environment_assets}/frontend/components/checkable_list/assets/icons/${ICONS.EXPANDED_LIST}`;
|
|
27
|
+
const urlIconCompact = `${host_static_assets}/${environment_assets}/frontend/components/checkable_list/assets/icons/${ICONS.COMPACT_LIST}`;
|
|
28
|
+
const urlIconSearch = `${host_static_assets}/${environment_assets}/frontend/components/checkable_list/assets/icons/${ICONS.SEARCH}`;
|
|
29
|
+
const urlIconNoResults = `${host_static_assets}/${environment_assets}/frontend/components/no_item_selected/assets/icons/no_selected.svg`;
|
|
30
|
+
const renderItemContent = useCallback(
|
|
31
|
+
(item, index) => {
|
|
32
|
+
const checked = isItemSelected(item.id);
|
|
33
|
+
const itemDisabled = Boolean(disabled || item.disabled);
|
|
34
|
+
const customContent = renderItem?.({
|
|
35
|
+
item,
|
|
36
|
+
checked,
|
|
37
|
+
index,
|
|
38
|
+
disabled: itemDisabled,
|
|
39
|
+
size,
|
|
40
|
+
variant
|
|
41
|
+
});
|
|
42
|
+
const fallbackContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
43
|
+
/* @__PURE__ */ jsx(
|
|
44
|
+
ItemLabelTypografyStyled,
|
|
45
|
+
{
|
|
46
|
+
ownerState: { size, variant, disabled: itemDisabled },
|
|
47
|
+
variant: "body",
|
|
48
|
+
color: "text.primary",
|
|
49
|
+
disabled: itemDisabled,
|
|
50
|
+
children: item.label
|
|
51
|
+
}
|
|
52
|
+
),
|
|
53
|
+
item.description && /* @__PURE__ */ jsx(
|
|
54
|
+
ItemDescriptionTypografyStyled,
|
|
55
|
+
{
|
|
56
|
+
ownerState: { size, variant },
|
|
57
|
+
variant: "body",
|
|
58
|
+
color: "text.secondary",
|
|
59
|
+
disabled: itemDisabled,
|
|
60
|
+
children: item.description
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
] });
|
|
64
|
+
return /* @__PURE__ */ jsxs(
|
|
65
|
+
ItemWrapperStyled,
|
|
66
|
+
{
|
|
67
|
+
ownerState: { size, variant, disabled: itemDisabled, selected: checked },
|
|
68
|
+
onClick: () => !itemDisabled && handleItemToggle(item.id),
|
|
69
|
+
children: [
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
ItemCheckboxStyled,
|
|
72
|
+
{
|
|
73
|
+
checked,
|
|
74
|
+
disabled: itemDisabled,
|
|
75
|
+
size: checkboxSize,
|
|
76
|
+
onChange: (e) => {
|
|
77
|
+
e.stopPropagation();
|
|
78
|
+
handleItemToggle(item.id);
|
|
79
|
+
},
|
|
80
|
+
onClick: (e) => e.stopPropagation()
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
item.icon && /* @__PURE__ */ jsx(ItemIconStyled, { children: item.icon }),
|
|
84
|
+
/* @__PURE__ */ jsx(ItemContentWrapperStyled, { children: customContent ?? fallbackContent })
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
},
|
|
89
|
+
[
|
|
90
|
+
isItemSelected,
|
|
91
|
+
disabled,
|
|
92
|
+
renderItem,
|
|
93
|
+
size,
|
|
94
|
+
variant,
|
|
95
|
+
checkboxSize,
|
|
96
|
+
handleItemToggle
|
|
97
|
+
]
|
|
98
|
+
);
|
|
99
|
+
const renderGroupContent = useCallback(
|
|
100
|
+
(group, index) => {
|
|
101
|
+
const isExpanded = expandedGroups.has(group.id);
|
|
102
|
+
const groupDisabled = Boolean(disabled || group.disabled);
|
|
103
|
+
const fullySelected = isGroupFullySelected(group);
|
|
104
|
+
const partiallySelected = isGroupPartiallySelected(group);
|
|
105
|
+
const groupItems = getGroupItems(group);
|
|
106
|
+
let checkboxState = false;
|
|
107
|
+
if (fullySelected) {
|
|
108
|
+
checkboxState = true;
|
|
109
|
+
} else if (partiallySelected && indeterminateBehavior === "indicate-some") {
|
|
110
|
+
checkboxState = "indeterminate";
|
|
111
|
+
}
|
|
112
|
+
const handleExpand = (event) => {
|
|
113
|
+
event.stopPropagation();
|
|
114
|
+
if (groupDisabled || !groupable) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
handleGroupExpandToggle(group.id);
|
|
118
|
+
};
|
|
119
|
+
const handleToggleGroup = (event) => {
|
|
120
|
+
event.stopPropagation();
|
|
121
|
+
handleGroupToggle(group);
|
|
122
|
+
};
|
|
123
|
+
const selectedCount = groupItems.filter(
|
|
124
|
+
(item) => isItemSelected(item.id)
|
|
125
|
+
).length;
|
|
126
|
+
const customGroupContent = renderGroup?.({
|
|
127
|
+
group,
|
|
128
|
+
items: groupItems,
|
|
129
|
+
index,
|
|
130
|
+
expanded: isExpanded,
|
|
131
|
+
disabled: groupDisabled,
|
|
132
|
+
size,
|
|
133
|
+
variant,
|
|
134
|
+
checkboxState,
|
|
135
|
+
onToggleExpand: handleExpand,
|
|
136
|
+
onToggleGroup: handleToggleGroup,
|
|
137
|
+
selectedCount,
|
|
138
|
+
totalCount: groupItems.length
|
|
139
|
+
});
|
|
140
|
+
const fallbackGroupLabel = /* @__PURE__ */ jsxs(GroupLabelCountWrapperStyled, { children: [
|
|
141
|
+
/* @__PURE__ */ jsx(
|
|
142
|
+
GroupLabelTypografyStyled,
|
|
143
|
+
{
|
|
144
|
+
ownerState: { size, variant, disabled: groupDisabled },
|
|
145
|
+
ellipsis: true,
|
|
146
|
+
variant: "captionDens",
|
|
147
|
+
children: group.label
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
/* @__PURE__ */ jsxs(
|
|
151
|
+
ChipCountTypografyStyled,
|
|
152
|
+
{
|
|
153
|
+
ownerState: { size, variant, disabled: groupDisabled, color: group.color },
|
|
154
|
+
children: [
|
|
155
|
+
selectedCount,
|
|
156
|
+
"/",
|
|
157
|
+
groupItems.length
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
] });
|
|
162
|
+
const groupBodyContent = customGroupContent ?? fallbackGroupLabel;
|
|
163
|
+
return /* @__PURE__ */ jsx(GroupWrapperStyled, { ownerState: { size, variant, grouped: true, selected: checkboxState === true }, children: /* @__PURE__ */ jsxs(
|
|
164
|
+
GroupHeaderStyled,
|
|
165
|
+
{
|
|
166
|
+
ownerState: { size, variant, disabled: groupDisabled },
|
|
167
|
+
onClick: handleExpand,
|
|
168
|
+
children: [
|
|
169
|
+
showCheckboxOnGroup && /* @__PURE__ */ jsx(
|
|
170
|
+
GroupCheckboxStyled,
|
|
171
|
+
{
|
|
172
|
+
checked: checkboxState === true,
|
|
173
|
+
indeterminate: checkboxState === "indeterminate",
|
|
174
|
+
disabled: groupDisabled,
|
|
175
|
+
size: checkboxSize,
|
|
176
|
+
onChange: handleToggleGroup,
|
|
177
|
+
onClick: (e) => e.stopPropagation()
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
group.icon && /* @__PURE__ */ jsx(GroupIconStyled, { children: group.icon }),
|
|
181
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: groupBodyContent }),
|
|
182
|
+
groupable && /* @__PURE__ */ jsx(
|
|
183
|
+
GroupToggleButtonStyled,
|
|
184
|
+
{
|
|
185
|
+
size,
|
|
186
|
+
variant: "text",
|
|
187
|
+
icon: isExpanded ? urlIconCompact : urlIconExpanded,
|
|
188
|
+
onClick: handleExpand
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
) });
|
|
194
|
+
},
|
|
195
|
+
[expandedGroups, disabled, isGroupFullySelected, isGroupPartiallySelected, getGroupItems, indeterminateBehavior, renderGroup, size, variant, showCheckboxOnGroup, checkboxSize, groupable, urlIconCompact, urlIconExpanded, handleGroupExpandToggle, handleGroupToggle, isItemSelected]
|
|
196
|
+
);
|
|
197
|
+
const renderVirtualizedItem = useCallback(
|
|
198
|
+
({ index, style, data }) => {
|
|
199
|
+
const virtualizedItems = data;
|
|
200
|
+
const item = virtualizedItems[index];
|
|
201
|
+
if (!item) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return (
|
|
205
|
+
/**
|
|
206
|
+
* Sobre este div React-Window aplica los estilos de posicionamiento y tamaño.
|
|
207
|
+
*/
|
|
208
|
+
/* @__PURE__ */ jsx("div", { style, children: item.type === "group" ? renderGroupContent(item.data, index) : renderItemContent(item.data, index) })
|
|
209
|
+
);
|
|
210
|
+
},
|
|
211
|
+
[renderGroupContent, renderItemContent]
|
|
212
|
+
);
|
|
213
|
+
return {
|
|
214
|
+
renderItemContent,
|
|
215
|
+
renderGroupContent,
|
|
216
|
+
renderVirtualizedItem,
|
|
217
|
+
urlIconSearch,
|
|
218
|
+
urlIconNoResults
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
export {
|
|
222
|
+
useCheckableListRender as u
|
|
223
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CheckableListItem, CheckableListGroup } from '../types';
|
|
2
|
+
interface UseCheckableListSelectionProps {
|
|
3
|
+
value: (string | number)[];
|
|
4
|
+
normalizedItems: CheckableListItem[];
|
|
5
|
+
groups?: CheckableListGroup[];
|
|
6
|
+
isGrouped: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Hook para manejar la lógica de selección del componente CheckableList
|
|
10
|
+
*/
|
|
11
|
+
export declare const useCheckableListSelection: ({ value, normalizedItems, groups, isGrouped, }: UseCheckableListSelectionProps) => {
|
|
12
|
+
getGroupItems: (group: CheckableListGroup) => CheckableListItem[];
|
|
13
|
+
isItemSelected: (itemId: string | number) => boolean;
|
|
14
|
+
isGroupFullySelected: (group: CheckableListGroup) => boolean;
|
|
15
|
+
isGroupPartiallySelected: (group: CheckableListGroup) => boolean;
|
|
16
|
+
areAllItemsSelected: boolean;
|
|
17
|
+
areSomeItemsSelected: boolean;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
2
|
+
const useCheckableListSelection = ({
|
|
3
|
+
value,
|
|
4
|
+
normalizedItems,
|
|
5
|
+
groups,
|
|
6
|
+
isGrouped
|
|
7
|
+
}) => {
|
|
8
|
+
const getGroupItems = useCallback(
|
|
9
|
+
(group) => {
|
|
10
|
+
if (isGrouped && groups) {
|
|
11
|
+
return groups.find((g) => g.id === group.id)?.items || [];
|
|
12
|
+
}
|
|
13
|
+
return [];
|
|
14
|
+
},
|
|
15
|
+
[isGrouped, groups]
|
|
16
|
+
);
|
|
17
|
+
const isItemSelected = useCallback(
|
|
18
|
+
(itemId) => {
|
|
19
|
+
return value.includes(itemId);
|
|
20
|
+
},
|
|
21
|
+
[value]
|
|
22
|
+
);
|
|
23
|
+
const isGroupFullySelected = useCallback(
|
|
24
|
+
(group) => {
|
|
25
|
+
const groupItems = getGroupItems(group);
|
|
26
|
+
if (groupItems.length === 0) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return groupItems.every((item) => isItemSelected(item.id));
|
|
30
|
+
},
|
|
31
|
+
[getGroupItems, isItemSelected]
|
|
32
|
+
);
|
|
33
|
+
const isGroupPartiallySelected = useCallback(
|
|
34
|
+
(group) => {
|
|
35
|
+
const groupItems = getGroupItems(group);
|
|
36
|
+
if (groupItems.length === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const selectedCount = groupItems.filter(
|
|
40
|
+
(item) => isItemSelected(item.id)
|
|
41
|
+
).length;
|
|
42
|
+
return selectedCount > 0 && selectedCount < groupItems.length;
|
|
43
|
+
},
|
|
44
|
+
[getGroupItems, isItemSelected]
|
|
45
|
+
);
|
|
46
|
+
const areAllItemsSelected = useMemo(() => {
|
|
47
|
+
if (normalizedItems.length === 0) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return normalizedItems.every((item) => isItemSelected(item.id));
|
|
51
|
+
}, [normalizedItems, isItemSelected]);
|
|
52
|
+
const areSomeItemsSelected = useMemo(() => {
|
|
53
|
+
if (normalizedItems.length === 0) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return normalizedItems.some((item) => isItemSelected(item.id));
|
|
57
|
+
}, [normalizedItems, isItemSelected]);
|
|
58
|
+
return {
|
|
59
|
+
getGroupItems,
|
|
60
|
+
isItemSelected,
|
|
61
|
+
isGroupFullySelected,
|
|
62
|
+
isGroupPartiallySelected,
|
|
63
|
+
areAllItemsSelected,
|
|
64
|
+
areSomeItemsSelected
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export {
|
|
68
|
+
useCheckableListSelection as u
|
|
69
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CheckableListGroup } from '../types';
|
|
2
|
+
interface UseCheckableListStateProps {
|
|
3
|
+
groups?: CheckableListGroup[];
|
|
4
|
+
expandAllGroups?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Hook para manejar el estado local del componente CheckableList
|
|
8
|
+
*/
|
|
9
|
+
export declare const useCheckableListState: ({ groups, expandAllGroups, }: UseCheckableListStateProps) => {
|
|
10
|
+
searchQuery: string;
|
|
11
|
+
setSearchQuery: import('react').Dispatch<import('react').SetStateAction<string>>;
|
|
12
|
+
expandedGroups: Set<string | number>;
|
|
13
|
+
itemHeights: Map<number, number>;
|
|
14
|
+
setItemHeights: import('react').Dispatch<import('react').SetStateAction<Map<number, number>>>;
|
|
15
|
+
handleGroupExpandToggle: (groupId: string | number) => void;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from "react";
|
|
2
|
+
const useCheckableListState = ({
|
|
3
|
+
groups,
|
|
4
|
+
expandAllGroups = true
|
|
5
|
+
}) => {
|
|
6
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
7
|
+
const [expandedGroups, setExpandedGroups] = useState(
|
|
8
|
+
() => {
|
|
9
|
+
if (!groups) {
|
|
10
|
+
return /* @__PURE__ */ new Set();
|
|
11
|
+
}
|
|
12
|
+
return expandAllGroups ? new Set(groups.map((g) => g.id)) : new Set(groups.filter((g) => !g.collapsed).map((g) => g.id));
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
const [itemHeights, setItemHeights] = useState(
|
|
16
|
+
/* @__PURE__ */ new Map()
|
|
17
|
+
);
|
|
18
|
+
const previousGroupIdsRef = useRef([]);
|
|
19
|
+
const previousExpandAllGroupsRef = useRef(expandAllGroups);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!groups) {
|
|
22
|
+
setExpandedGroups(/* @__PURE__ */ new Set());
|
|
23
|
+
previousGroupIdsRef.current = [];
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const currentGroupIds = groups.map((g) => g.id);
|
|
27
|
+
const previousGroupIds = previousGroupIdsRef.current;
|
|
28
|
+
const groupIdsChanged = currentGroupIds.length !== previousGroupIds.length || currentGroupIds.some((id, index) => id !== previousGroupIds[index]);
|
|
29
|
+
const expandAllGroupsChanged = previousExpandAllGroupsRef.current !== expandAllGroups;
|
|
30
|
+
if (groupIdsChanged || expandAllGroupsChanged) {
|
|
31
|
+
const newExpandedGroups = expandAllGroups ? new Set(groups.map((g) => g.id)) : new Set(groups.filter((g) => !g.collapsed).map((g) => g.id));
|
|
32
|
+
setExpandedGroups(newExpandedGroups);
|
|
33
|
+
previousGroupIdsRef.current = currentGroupIds;
|
|
34
|
+
previousExpandAllGroupsRef.current = expandAllGroups;
|
|
35
|
+
}
|
|
36
|
+
}, [groups, expandAllGroups]);
|
|
37
|
+
const handleGroupExpandToggle = (groupId) => {
|
|
38
|
+
setExpandedGroups((prev) => {
|
|
39
|
+
const next = new Set(prev);
|
|
40
|
+
if (next.has(groupId)) {
|
|
41
|
+
next.delete(groupId);
|
|
42
|
+
} else {
|
|
43
|
+
next.add(groupId);
|
|
44
|
+
}
|
|
45
|
+
return next;
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
searchQuery,
|
|
50
|
+
setSearchQuery,
|
|
51
|
+
expandedGroups,
|
|
52
|
+
itemHeights,
|
|
53
|
+
setItemHeights,
|
|
54
|
+
handleGroupExpandToggle
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
useCheckableListState as u
|
|
59
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { VirtualizedItem } from '../types';
|
|
2
|
+
interface UseCheckableListVirtualizationProps {
|
|
3
|
+
virtualizedItems: VirtualizedItem[];
|
|
4
|
+
itemHeights: Map<number, number>;
|
|
5
|
+
defaultItemRowHeight?: number;
|
|
6
|
+
defaultGroupRowHeight?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Hook para manejar la virtualización de items
|
|
10
|
+
*/
|
|
11
|
+
export declare const useCheckableListVirtualization: ({ virtualizedItems, itemHeights, defaultItemRowHeight, defaultGroupRowHeight, }: UseCheckableListVirtualizationProps) => {
|
|
12
|
+
getItemSize: (index: number) => number;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { a as CHECKABLE_LIST_DEFAULT_ITEM_ROW_HEIGHT, b as CHECKABLE_LIST_DEFAULT_GROUP_ROW_HEIGHT, c as CHECKABLE_LIST_DEFAULT_ITEM_ROW_HEIGHT_WITH_DESCRIPTION } from "../constants.js";
|
|
3
|
+
const useCheckableListVirtualization = ({
|
|
4
|
+
virtualizedItems,
|
|
5
|
+
itemHeights,
|
|
6
|
+
defaultItemRowHeight,
|
|
7
|
+
defaultGroupRowHeight
|
|
8
|
+
}) => {
|
|
9
|
+
const getItemSize = useCallback(
|
|
10
|
+
(index) => {
|
|
11
|
+
const storedHeight = itemHeights.get(index);
|
|
12
|
+
if (storedHeight) {
|
|
13
|
+
return storedHeight;
|
|
14
|
+
}
|
|
15
|
+
const item = virtualizedItems[index];
|
|
16
|
+
if (!item) {
|
|
17
|
+
return defaultItemRowHeight ?? CHECKABLE_LIST_DEFAULT_ITEM_ROW_HEIGHT;
|
|
18
|
+
}
|
|
19
|
+
if (item.type === "group") {
|
|
20
|
+
return defaultGroupRowHeight ?? CHECKABLE_LIST_DEFAULT_GROUP_ROW_HEIGHT;
|
|
21
|
+
}
|
|
22
|
+
const checkableItem = item.data;
|
|
23
|
+
if (typeof checkableItem.rowHeight === "number") {
|
|
24
|
+
return checkableItem.rowHeight;
|
|
25
|
+
}
|
|
26
|
+
const hasDescription = !!checkableItem.description;
|
|
27
|
+
return defaultItemRowHeight ?? (hasDescription ? CHECKABLE_LIST_DEFAULT_ITEM_ROW_HEIGHT_WITH_DESCRIPTION : CHECKABLE_LIST_DEFAULT_ITEM_ROW_HEIGHT);
|
|
28
|
+
},
|
|
29
|
+
[
|
|
30
|
+
virtualizedItems,
|
|
31
|
+
itemHeights,
|
|
32
|
+
defaultItemRowHeight,
|
|
33
|
+
defaultGroupRowHeight
|
|
34
|
+
]
|
|
35
|
+
);
|
|
36
|
+
return {
|
|
37
|
+
getItemSize
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
useCheckableListVirtualization as u
|
|
42
|
+
};
|