@koobiq/react-components 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Button/Button.js +4 -0
- package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroup.js +5 -6
- package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroupContext.d.ts +2 -1
- package/dist/components/IconButton/IconButton.js +3 -0
- package/dist/components/List/List.d.ts +2 -1
- package/dist/components/List/List.js +16 -3
- package/dist/components/List/List.module.css.js +4 -1
- package/dist/components/Menu/Menu.js +1 -1
- package/dist/components/Menu/components/MenuInner/MenuInner.js +1 -1
- package/dist/components/Select/Select.d.ts +3 -2
- package/dist/components/Select/Select.js +83 -101
- package/dist/components/Select/Select.module.css.js +8 -2
- package/dist/components/Select/components/SelectList/SelectList.d.ts +8 -0
- package/dist/components/Select/components/SelectList/SelectList.js +51 -0
- package/dist/components/Select/components/SelectList/SelectList.module.css.js +11 -0
- package/dist/components/Select/components/SelectList/index.d.ts +1 -0
- package/dist/components/Select/components/SelectOption/SelectOption.d.ts +7 -0
- package/dist/components/Select/components/SelectOption/SelectOption.js +42 -0
- package/dist/components/Select/components/SelectOption/index.d.ts +1 -0
- package/dist/components/Select/components/Tag/Tag.d.ts +17 -0
- package/dist/components/Select/components/Tag/Tag.js +64 -0
- package/dist/components/Select/components/Tag/index.d.ts +1 -0
- package/dist/components/Select/components/Tag/intl.json.js +7 -0
- package/dist/components/Select/components/Tag/utils.d.ts +3 -0
- package/dist/components/Select/components/Tag/utils.js +9 -0
- package/dist/components/Select/components/TagGroup/TagGroup.d.ts +13 -0
- package/dist/components/Select/components/TagGroup/TagGroup.js +24 -0
- package/dist/components/Select/components/TagGroup/TagGroup.module.css.js +23 -0
- package/dist/components/Select/components/TagGroup/TagGroupMultiline.d.ts +3 -0
- package/dist/components/Select/components/TagGroup/TagGroupMultiline.js +47 -0
- package/dist/components/Select/components/TagGroup/TagGroupResponsive.d.ts +3 -0
- package/dist/components/Select/components/TagGroup/TagGroupResponsive.js +66 -0
- package/dist/components/Select/components/TagGroup/index.d.ts +1 -0
- package/dist/components/Select/components/TagGroup/utils.d.ts +1 -0
- package/dist/components/Select/components/TagGroup/utils.js +4 -0
- package/dist/components/Select/components/index.d.ts +3 -0
- package/dist/components/Select/intl.d.ts +2 -0
- package/dist/components/Select/intl.js +15 -0
- package/dist/components/Select/types.d.ts +35 -42
- package/dist/components/Select/types.js +7 -0
- package/dist/index.js +2 -0
- package/dist/style.css +230 -130
- package/package.json +5 -5
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { useLocalizedStringFormatter, mergeProps, clsx, isNotNil } from "@koobiq/react-core";
|
|
4
|
+
import { IconXmarkS16 } from "@koobiq/react-icons";
|
|
5
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
6
|
+
import s from "../../../TagGroup/components/Tag/Tag.module.css.js";
|
|
7
|
+
import intlMessages from "./intl.json.js";
|
|
8
|
+
import { matchVariantToCloseButton } from "./utils.js";
|
|
9
|
+
import { IconButton } from "../../../IconButton/IconButton.js";
|
|
10
|
+
const textNormalMedium = utilClasses.typography["text-normal-medium"];
|
|
11
|
+
const Tag = forwardRef((props, ref) => {
|
|
12
|
+
const {
|
|
13
|
+
variant = "theme-fade",
|
|
14
|
+
icon,
|
|
15
|
+
className,
|
|
16
|
+
style,
|
|
17
|
+
isDisabled,
|
|
18
|
+
children,
|
|
19
|
+
onRemove
|
|
20
|
+
} = props;
|
|
21
|
+
const stringFormatter = useLocalizedStringFormatter(intlMessages);
|
|
22
|
+
const rootProps = mergeProps({
|
|
23
|
+
className: clsx(
|
|
24
|
+
s.base,
|
|
25
|
+
s[variant],
|
|
26
|
+
isDisabled && s.disabled,
|
|
27
|
+
textNormalMedium,
|
|
28
|
+
className
|
|
29
|
+
),
|
|
30
|
+
style
|
|
31
|
+
});
|
|
32
|
+
const removeButtonProps = {
|
|
33
|
+
isCompact: true,
|
|
34
|
+
isDisabled,
|
|
35
|
+
className: s.cancelIcon,
|
|
36
|
+
variant: matchVariantToCloseButton[variant],
|
|
37
|
+
"aria-label": stringFormatter.format("remove")
|
|
38
|
+
};
|
|
39
|
+
const contentProps = mergeProps({
|
|
40
|
+
className: s.content
|
|
41
|
+
});
|
|
42
|
+
const iconProps = mergeProps({
|
|
43
|
+
className: s.icon
|
|
44
|
+
});
|
|
45
|
+
return /* @__PURE__ */ jsxs("div", { ref, ...rootProps, children: [
|
|
46
|
+
isNotNil(icon) && /* @__PURE__ */ jsx("span", { ...iconProps, children: icon }),
|
|
47
|
+
isNotNil(children) && /* @__PURE__ */ jsx("span", { ...contentProps, children }),
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
IconButton,
|
|
50
|
+
{
|
|
51
|
+
as: "div",
|
|
52
|
+
size: "l",
|
|
53
|
+
...removeButtonProps,
|
|
54
|
+
tabIndex: void 0,
|
|
55
|
+
onPress: onRemove,
|
|
56
|
+
children: /* @__PURE__ */ jsx(IconXmarkS16, {})
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
] });
|
|
60
|
+
});
|
|
61
|
+
Tag.displayName = "SelectTag";
|
|
62
|
+
export {
|
|
63
|
+
Tag
|
|
64
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Tag';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { MultiSelectState } from '@koobiq/react-primitives';
|
|
3
|
+
import type { SelectPropSelectedTagsOverflow } from '../../types';
|
|
4
|
+
export type TagGroupProps<T> = {
|
|
5
|
+
state: MultiSelectState<T>;
|
|
6
|
+
states: {
|
|
7
|
+
isInvalid?: boolean;
|
|
8
|
+
isDisabled?: boolean;
|
|
9
|
+
isRequired?: boolean;
|
|
10
|
+
};
|
|
11
|
+
selectedTagsOverflow?: SelectPropSelectedTagsOverflow;
|
|
12
|
+
};
|
|
13
|
+
export declare const TagGroup: FC<TagGroupProps<unknown>>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { logger } from "@koobiq/logger";
|
|
3
|
+
import { TagGroupMultiline } from "./TagGroupMultiline.js";
|
|
4
|
+
import { TagGroupResponsive } from "./TagGroupResponsive.js";
|
|
5
|
+
function assertNever(x) {
|
|
6
|
+
logger.error(`Unhandled selectedTagsOverflow variant: ${x}`);
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const TagGroup = ({
|
|
10
|
+
selectedTagsOverflow = "responsive",
|
|
11
|
+
...rest
|
|
12
|
+
}) => {
|
|
13
|
+
switch (selectedTagsOverflow) {
|
|
14
|
+
case "responsive":
|
|
15
|
+
return /* @__PURE__ */ jsx(TagGroupResponsive, { ...rest });
|
|
16
|
+
case "multiline":
|
|
17
|
+
return /* @__PURE__ */ jsx(TagGroupMultiline, { ...rest });
|
|
18
|
+
default:
|
|
19
|
+
return assertNever(selectedTagsOverflow);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
TagGroup
|
|
24
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const container = "kbq-taggroup-container-c4d544";
|
|
2
|
+
const hasStartAddon = "kbq-taggroup-hasStartAddon-40d1f9";
|
|
3
|
+
const base = "kbq-taggroup-8253a5";
|
|
4
|
+
const tag = "kbq-taggroup-tag-b9306f";
|
|
5
|
+
const more = "kbq-taggroup-more-b2d6b9";
|
|
6
|
+
const hidden = "kbq-taggroup-hidden-eadb46";
|
|
7
|
+
const s = {
|
|
8
|
+
container,
|
|
9
|
+
hasStartAddon,
|
|
10
|
+
base,
|
|
11
|
+
tag,
|
|
12
|
+
more,
|
|
13
|
+
hidden
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
base,
|
|
17
|
+
container,
|
|
18
|
+
s as default,
|
|
19
|
+
hasStartAddon,
|
|
20
|
+
hidden,
|
|
21
|
+
more,
|
|
22
|
+
tag
|
|
23
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLocalizedStringFormatter, clsx } from "@koobiq/react-core";
|
|
3
|
+
import intlMessages from "../../intl.js";
|
|
4
|
+
import s from "./TagGroup.module.css.js";
|
|
5
|
+
import { Tag } from "../Tag/Tag.js";
|
|
6
|
+
import { useFieldInputGroup } from "../../../FieldComponents/FieldContentGroup/FieldContentGroupContext.js";
|
|
7
|
+
const TagGroupMultiline = ({
|
|
8
|
+
state,
|
|
9
|
+
states
|
|
10
|
+
}) => {
|
|
11
|
+
const { isDisabled, isInvalid } = states;
|
|
12
|
+
const t = useLocalizedStringFormatter(intlMessages);
|
|
13
|
+
const { hasStartAddon } = useFieldInputGroup();
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
className: clsx(s.container, hasStartAddon && s.hasStartAddon),
|
|
18
|
+
"aria-hidden": true,
|
|
19
|
+
children: /* @__PURE__ */ jsx(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
className: s.base,
|
|
23
|
+
"data-limit-tags": "multiline",
|
|
24
|
+
"aria-label": t.format("selected items"),
|
|
25
|
+
children: state.selectedItems?.map((item) => /* @__PURE__ */ jsx(
|
|
26
|
+
Tag,
|
|
27
|
+
{
|
|
28
|
+
className: s.tag,
|
|
29
|
+
isDisabled,
|
|
30
|
+
variant: isInvalid ? "error-fade" : "contrast-fade",
|
|
31
|
+
onRemove: () => {
|
|
32
|
+
if (state.selectionManager.isSelected(item.key)) {
|
|
33
|
+
state.selectionManager.toggleSelection(item.key);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
children: item.textValue
|
|
37
|
+
},
|
|
38
|
+
item.key
|
|
39
|
+
))
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
TagGroupMultiline
|
|
47
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useHideOverflowItems, useLocalizedStringFormatter, clsx } from "@koobiq/react-core";
|
|
3
|
+
import intlMessages from "../../intl.js";
|
|
4
|
+
import s from "./TagGroup.module.css.js";
|
|
5
|
+
import { getHiddenCount } from "./utils.js";
|
|
6
|
+
import { useFieldInputGroup } from "../../../FieldComponents/FieldContentGroup/FieldContentGroupContext.js";
|
|
7
|
+
import { Tag } from "../Tag/Tag.js";
|
|
8
|
+
const TagGroupResponsive = ({
|
|
9
|
+
state,
|
|
10
|
+
states
|
|
11
|
+
}) => {
|
|
12
|
+
const { isDisabled, isInvalid } = states;
|
|
13
|
+
const length = state?.selectedItems?.length || 0;
|
|
14
|
+
const { parentRef, visibleMap, itemsRefs } = useHideOverflowItems({
|
|
15
|
+
length: length + 1,
|
|
16
|
+
pinnedIndex: 0
|
|
17
|
+
});
|
|
18
|
+
const hiddenCount = getHiddenCount(visibleMap);
|
|
19
|
+
const t = useLocalizedStringFormatter(intlMessages);
|
|
20
|
+
const { hasStartAddon } = useFieldInputGroup();
|
|
21
|
+
return /* @__PURE__ */ jsxs(
|
|
22
|
+
"div",
|
|
23
|
+
{
|
|
24
|
+
className: clsx(s.container, hasStartAddon && s.hasStartAddon),
|
|
25
|
+
ref: parentRef,
|
|
26
|
+
"aria-hidden": true,
|
|
27
|
+
children: [
|
|
28
|
+
/* @__PURE__ */ jsx(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
className: s.base,
|
|
32
|
+
"data-limit-tags": "responsive",
|
|
33
|
+
"aria-label": t.format("selected items"),
|
|
34
|
+
children: state.selectedItems?.map((item, i) => /* @__PURE__ */ jsx(
|
|
35
|
+
Tag,
|
|
36
|
+
{
|
|
37
|
+
ref: itemsRefs[i],
|
|
38
|
+
className: clsx(s.tag, !visibleMap[i] && s.hidden),
|
|
39
|
+
isDisabled,
|
|
40
|
+
variant: isInvalid ? "error-fade" : "contrast-fade",
|
|
41
|
+
onRemove: () => {
|
|
42
|
+
if (state.selectionManager.isSelected(item.key)) {
|
|
43
|
+
state.selectionManager.toggleSelection(item.key);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
children: item.textValue
|
|
47
|
+
},
|
|
48
|
+
item.key
|
|
49
|
+
))
|
|
50
|
+
}
|
|
51
|
+
),
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
ref: itemsRefs[itemsRefs.length - 1],
|
|
56
|
+
className: clsx(s.more, !visibleMap[length] && s.hidden),
|
|
57
|
+
children: t.format("more", { count: hiddenCount })
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
export {
|
|
65
|
+
TagGroupResponsive
|
|
66
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TagGroup';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getHiddenCount: (map: boolean[]) => number;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const intlMessages = {
|
|
2
|
+
"ru-RU": {
|
|
3
|
+
"selected items": "Выбранные элементы",
|
|
4
|
+
clear: "Очистить",
|
|
5
|
+
more: ({ count }) => `еще ${count}`
|
|
6
|
+
},
|
|
7
|
+
"en-US": {
|
|
8
|
+
"selected items": "Selected items",
|
|
9
|
+
clear: "Clear",
|
|
10
|
+
more: ({ count }) => `${count} more`
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
export {
|
|
14
|
+
intlMessages as default
|
|
15
|
+
};
|
|
@@ -1,49 +1,38 @@
|
|
|
1
1
|
import type { ComponentRef, CSSProperties, ReactElement, ReactNode, Ref } from 'react';
|
|
2
|
-
import type { ExtendableProps
|
|
3
|
-
import type { AriaSelectProps } from '@koobiq/react-primitives';
|
|
2
|
+
import type { ExtendableProps } from '@koobiq/react-core';
|
|
3
|
+
import type { AriaSelectProps, MultiSelectState, useMultiSelectState } from '@koobiq/react-primitives';
|
|
4
4
|
import type { FieldErrorProps, FieldLabelProps, FieldSelectProps, FieldCaptionProps, FieldInputGroupProps } from '../FieldComponents';
|
|
5
|
+
import type { IconButtonProps } from '../IconButton';
|
|
5
6
|
import type { ListProps } from '../List';
|
|
6
7
|
import type { PopoverProps } from '../Popover';
|
|
7
|
-
export
|
|
8
|
-
type
|
|
9
|
-
|
|
10
|
-
* If `true`, the component is disabled.
|
|
11
|
-
* @default false
|
|
12
|
-
* @deprecated
|
|
13
|
-
* The "disabled" prop is deprecated. Use "isDisabled" prop to replace it.
|
|
14
|
-
*/
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* If `true`, the input will indicate an error.
|
|
18
|
-
* @default false
|
|
19
|
-
* @deprecated
|
|
20
|
-
* The "error" prop is deprecated. Use "isInvalid" prop to replace it.
|
|
21
|
-
*/
|
|
22
|
-
error?: boolean;
|
|
23
|
-
/**
|
|
24
|
-
* If `true`, the label is displayed as required and the input element is required.
|
|
25
|
-
* @default false
|
|
26
|
-
* @deprecated
|
|
27
|
-
* The "required" prop is deprecated. Use "isRequired" prop to replace it.
|
|
28
|
-
*/
|
|
29
|
-
required?: boolean;
|
|
8
|
+
export declare const selectPropSelectedTagsOverflow: readonly ["multiline", "responsive"];
|
|
9
|
+
export type SelectPropSelectedTagsOverflow = (typeof selectPropSelectedTagsOverflow)[number];
|
|
10
|
+
export type SelectProps<T> = ExtendableProps<{
|
|
30
11
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
12
|
+
* Defines how selected tags are displayed when they exceed the available space.
|
|
13
|
+
*
|
|
14
|
+
*- `"multiline"` — tags wrap to multiple lines.
|
|
15
|
+
*- `"responsive"` — tags collapse into a summary (e.g., "3 more").
|
|
16
|
+
* @default "responsive"
|
|
34
17
|
*/
|
|
35
|
-
|
|
18
|
+
selectedTagsOverflow?: SelectPropSelectedTagsOverflow;
|
|
19
|
+
/** Handler that is called when the clear button is clicked. */
|
|
20
|
+
onClear?: () => void;
|
|
21
|
+
/** Sets the CSS [`className`](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the element. */
|
|
22
|
+
className?: string;
|
|
23
|
+
/** The initial selected keys in the collection (uncontrolled). */
|
|
24
|
+
defaultSelectedKeys?: Parameters<typeof useMultiSelectState>['0']['defaultSelectedKeys'];
|
|
25
|
+
/** Whether the field can be emptied. */
|
|
26
|
+
isClearable?: boolean;
|
|
27
|
+
/** Handler that is called when the selection changes. */
|
|
28
|
+
onSelectionChange?: Parameters<typeof useMultiSelectState>['0']['onSelectionChange'];
|
|
29
|
+
/** The currently selected keys in the collection (controlled). */
|
|
30
|
+
selectedKeys?: Parameters<typeof useMultiSelectState>['0']['selectedKeys'];
|
|
36
31
|
/**
|
|
37
|
-
*
|
|
38
|
-
* @default
|
|
39
|
-
* @deprecated
|
|
40
|
-
* The "hiddenLabel" prop is deprecated. Use "isLabelHidden" prop to replace it.
|
|
32
|
+
* The type of selection that is allowed in the collection.
|
|
33
|
+
* @default 'single'
|
|
41
34
|
*/
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
export type SelectProps<T> = ExtendableProps<{
|
|
45
|
-
/** Additional CSS-classes. */
|
|
46
|
-
className?: string;
|
|
35
|
+
selectionMode?: 'single' | 'multiple';
|
|
47
36
|
/** Addon placed before the children. */
|
|
48
37
|
startAddon?: ReactNode;
|
|
49
38
|
/** Addon placed after the children. */
|
|
@@ -69,18 +58,22 @@ export type SelectProps<T> = ExtendableProps<{
|
|
|
69
58
|
/** Ref to the control */
|
|
70
59
|
ref?: Ref<HTMLDivElement>;
|
|
71
60
|
/** A render function for displaying the selected value. */
|
|
72
|
-
renderValue?: (
|
|
61
|
+
renderValue?: (state: MultiSelectState<T>, states: {
|
|
62
|
+
isInvalid?: boolean;
|
|
63
|
+
isDisabled?: boolean;
|
|
64
|
+
isRequired?: boolean;
|
|
65
|
+
}) => ReactNode;
|
|
73
66
|
/** The props used for each slot inside. */
|
|
74
67
|
slotProps?: {
|
|
75
68
|
popover?: PopoverProps;
|
|
76
69
|
label?: FieldLabelProps;
|
|
77
70
|
list?: ListProps<T>;
|
|
78
|
-
control?: FieldSelectProps
|
|
71
|
+
control?: FieldSelectProps<'div'>;
|
|
79
72
|
caption?: FieldCaptionProps;
|
|
80
73
|
group?: FieldInputGroupProps;
|
|
81
74
|
errorMessage?: FieldErrorProps;
|
|
75
|
+
clearButton?: IconButtonProps;
|
|
82
76
|
};
|
|
83
|
-
}
|
|
77
|
+
}, Omit<AriaSelectProps<T>, 'description' | 'validate' | 'validationBehavior' | 'validationState' | 'selectedKey' | 'onSelectionChange' | 'defaultSelectedKey'>>;
|
|
84
78
|
export type SelectComponent = <T>(props: SelectProps<T>) => ReactElement | null;
|
|
85
79
|
export type SelectRef = ComponentRef<'div'>;
|
|
86
|
-
export {};
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,7 @@ import { List, ListInner } from "./components/List/List.js";
|
|
|
62
62
|
import { ListItemText } from "./components/List/components/ListItemText/ListItemText.js";
|
|
63
63
|
import { AnimatedIcon } from "./components/AnimatedIcon/AnimatedIcon.js";
|
|
64
64
|
import { Select } from "./components/Select/Select.js";
|
|
65
|
+
import { selectPropSelectedTagsOverflow } from "./components/Select/types.js";
|
|
65
66
|
import { Divider } from "./components/Divider/Divider.js";
|
|
66
67
|
import { dividerPropDisplay } from "./components/Divider/types.js";
|
|
67
68
|
import { Menu } from "./components/Menu/Menu.js";
|
|
@@ -177,6 +178,7 @@ export {
|
|
|
177
178
|
radioGroupPropSize,
|
|
178
179
|
radioPropLabelPlacement,
|
|
179
180
|
radioPropSize,
|
|
181
|
+
selectPropSelectedTagsOverflow,
|
|
180
182
|
sidePanelPropPlacement,
|
|
181
183
|
sidePanelPropPosition,
|
|
182
184
|
sidePanelPropSize,
|