diff --git a/.eslintrc.js b/.eslintrc.js
index 03cb26e2..82a43dba 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -46,7 +46,15 @@ module.exports = {
'error',
{
markupOnly: true,
- ignoreAttribute: ['data-testid', 'to', 'target'],
+ ignoreAttribute: [
+ 'data-testid',
+ 'to',
+ 'target',
+ 'justify',
+ 'align',
+ 'direction',
+ 'gap',
+ ],
},
],
'max-len': ['error', { ignoreComments: true, code: 125 }],
diff --git a/src/entities/Article/ui/AticleDetails/ArticleDetails.module.scss b/src/entities/Article/ui/AticleDetails/ArticleDetails.module.scss
index ead4c9ad..086c6a24 100644
--- a/src/entities/Article/ui/AticleDetails/ArticleDetails.module.scss
+++ b/src/entities/Article/ui/AticleDetails/ArticleDetails.module.scss
@@ -1,34 +1,3 @@
.ArticleDetails {
min-height: 100%;
}
-
-.avatar {
- margin: 0 auto;
-}
-
-.title {
- margin-top: 20px;
-}
-
-.skeleton {
- margin-top: 15px;
-}
-
-.articleInfo {
- display: flex;
- align-items: center;
-}
-
-.icon {
- margin-right: 8px;
-}
-
-.avatarWrapper {
- display: flex;
- width: 100%;
- justify-content: center;
-}
-
-.block {
- margin-top: 16px;
-}
diff --git a/src/entities/Article/ui/AticleDetails/ArticleDetails.tsx b/src/entities/Article/ui/AticleDetails/ArticleDetails.tsx
index ca0e8a3f..c5f1b69d 100644
--- a/src/entities/Article/ui/AticleDetails/ArticleDetails.tsx
+++ b/src/entities/Article/ui/AticleDetails/ArticleDetails.tsx
@@ -14,6 +14,7 @@ import EyeIcon from 'shared/assets/icons/eye.svg';
import CalendarIcon from 'shared/assets/icons/calendar.svg';
import { Icon } from 'shared/ui/Icon/Icon';
import { useInitialEffect } from 'shared/lib/hooks/useInitialEffect/useInitialEffect';
+import { HStack, VStack } from 'shared/ui/Stack';
import { ArticleBlock, ArticleBlockType } from '../../model/types/article';
import { fetchArticleById } from '../../model/services/fetchArticleById/fetchArticleById';
import cls from './ArticleDetails.module.scss';
@@ -35,7 +36,7 @@ interface ArticleDetailsProps {
const reducers: ReducersList = {
articleDetails: articleDetailsReducer,
};
-/* eslint-disable indent */
+
const renderBlock = (block: ArticleBlock) => {
switch (block.type) {
case ArticleBlockType.CODE:
@@ -66,7 +67,6 @@ const renderBlock = (block: ArticleBlock) => {
return null;
}
};
-/* eslint-enable indent */
export const ArticleDetails = memo(({ className, id }: ArticleDetailsProps) => {
const { t } = useTranslation('article-details');
@@ -83,50 +83,45 @@ export const ArticleDetails = memo(({ className, id }: ArticleDetailsProps) => {
if (isLoading) {
content = (
- <>
-
-
-
-
-
- >
+
+
+
+
+
+
+
);
} else if (error) {
content = (
-
+
+
+
);
} else {
content = (
<>
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
{article?.blocks.map(renderBlock)}
>
);
@@ -134,9 +129,13 @@ export const ArticleDetails = memo(({ className, id }: ArticleDetailsProps) => {
return (
-
+
{content}
-
+
);
});
diff --git a/src/entities/Comment/ui/CommentCard/CommentCard.module.scss b/src/entities/Comment/ui/CommentCard/CommentCard.module.scss
index 8c3792f8..72d55960 100644
--- a/src/entities/Comment/ui/CommentCard/CommentCard.module.scss
+++ b/src/entities/Comment/ui/CommentCard/CommentCard.module.scss
@@ -2,16 +2,3 @@
padding: 10px;
border: 1px solid var(--primary-color);
}
-
-.header {
- display: flex;
- align-items: center;
-}
-
-.text {
- margin-top: 10px;
-}
-
-.username {
- margin-left: 10px;
-}
diff --git a/src/entities/Comment/ui/CommentCard/CommentCard.tsx b/src/entities/Comment/ui/CommentCard/CommentCard.tsx
index 9d8f075c..9515ed82 100644
--- a/src/entities/Comment/ui/CommentCard/CommentCard.tsx
+++ b/src/entities/Comment/ui/CommentCard/CommentCard.tsx
@@ -4,6 +4,7 @@ import { Avatar } from 'shared/ui/Avatar/Avatar';
import { Text } from 'shared/ui/Text/Text';
import { AppLink } from 'shared/ui/AppLink/AppLink';
import { RoutePath } from 'shared/config/routeConfig/routeConfig';
+import { HStack, VStack } from 'shared/ui/Stack';
import cls from './CommentCard.module.scss';
import { Comment } from '../../model/types/comment';
@@ -17,17 +18,20 @@ export const CommentCard = memo(({ className, comment }: CommentCardProps) => {
return null;
}
return (
-
-
- {comment.user.avatar ? (
-
- ) : null}
-
+
+
+
+ {comment.user.avatar ? (
+
+ ) : null}
+
+
-
-
+
+
);
});
diff --git a/src/entities/Comment/ui/CommentList/CommentList.module.scss b/src/entities/Comment/ui/CommentList/CommentList.module.scss
deleted file mode 100644
index c1772621..00000000
--- a/src/entities/Comment/ui/CommentList/CommentList.module.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-.comment {
- margin-top: 20px;
-}
-
-.header {
- display: flex;
- align-items: center;
-}
-
-.text {
- margin-top: 10px;
-}
-
-.username {
- margin-left: 10px;
-}
diff --git a/src/entities/Comment/ui/CommentList/CommentList.tsx b/src/entities/Comment/ui/CommentList/CommentList.tsx
index 1fb3cb1b..19b0c880 100644
--- a/src/entities/Comment/ui/CommentList/CommentList.tsx
+++ b/src/entities/Comment/ui/CommentList/CommentList.tsx
@@ -3,7 +3,7 @@ import { classNames } from 'shared/lib/classNames/classNames';
import { useTranslation } from 'react-i18next';
import { Text } from 'shared/ui/Text/Text';
import { Skeleton } from 'shared/ui/Skeleton/Skeleton';
-import cls from './CommentList.module.scss';
+import { HStack, VStack } from 'shared/ui/Stack';
import { Comment } from '../../model/types/comment';
import { CommentCard } from '../CommentCard/CommentCard';
@@ -18,33 +18,25 @@ export const CommentList = memo(
const { t } = useTranslation('comments');
if (isLoading) {
return (
-
+
+
+
+
);
}
return (
-
+
{comments.length ? (
comments.map((comment) => (
-
+
))
) : (
)}
-
+
);
},
);
diff --git a/src/entities/Profile/ui/ProfileCard/ProfileCard.module.scss b/src/entities/Profile/ui/ProfileCard/ProfileCard.module.scss
index e1f07a00..03d39140 100644
--- a/src/entities/Profile/ui/ProfileCard/ProfileCard.module.scss
+++ b/src/entities/Profile/ui/ProfileCard/ProfileCard.module.scss
@@ -3,20 +3,7 @@
border: 2px solid var(--inverted-bg-color);
}
-.input {
- margin-top: 10px;
-}
-
.loading,
.error {
- display: flex;
- align-items: center;
- justify-content: center;
height: 300px;
}
-
-.avatarWrapper {
- width: 100%;
- display: flex;
- justify-content: center;
-}
diff --git a/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx b/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx
index 3a8ba13e..63280fb8 100644
--- a/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx
+++ b/src/entities/Profile/ui/ProfileCard/ProfileCard.tsx
@@ -6,6 +6,7 @@ import { Loader } from 'shared/ui/Loader/Loader';
import { Avatar } from 'shared/ui/Avatar/Avatar';
import { Currency, CurrencySelect } from 'entities/Currency';
import { Country, CountrySelect } from 'entities/Country';
+import { HStack, VStack } from 'shared/ui/Stack';
import cls from './ProfileCard.module.scss';
import { Profile } from '../../model/types/profile';
@@ -49,20 +50,24 @@ export const ProfileCard = (props: ProfileCardProps) => {
if (isLoading) {
return (
-
-
+
);
}
if (error) {
return (
- {
title={t('There was an error')}
align={TextAlign.CENTER}
/>
-
+
);
}
const onKeyPress = (event: React.KeyboardEvent) => {
@@ -84,69 +89,63 @@ export const ProfileCard = (props: ProfileCardProps) => {
};
return (
-
+
+ {data?.avatar && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.module.scss b/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.module.scss
index dc3a9b5c..a95f9918 100644
--- a/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.module.scss
+++ b/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.module.scss
@@ -1,11 +1,4 @@
.AddCommentForm {
border: 1px solid var(--primary-color);
padding: 16px;
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-
-.input {
- flex-grow: 1;
}
diff --git a/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.tsx b/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.tsx
index 39b1e96a..0a6c718a 100644
--- a/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.tsx
+++ b/src/features/AddCommentForm/ui/AddCommentForm/AddCommentForm.tsx
@@ -6,6 +6,7 @@ import { Button } from 'shared/ui/Button/Button';
import { useSelector } from 'react-redux';
import { useAppDispatch } from 'shared/lib/hooks/useAppDispatch/useAppDispatch';
import { DynamicModuleLoader } from 'shared/lib/components/DynamicModuleLoader/DynamicModuleLoader';
+import { HStack } from 'shared/ui/Stack';
import {
addCommentFormActions,
addCommentFormReducer,
@@ -50,17 +51,18 @@ const AddCommentForm = memo(
return (
-
-
+
);
},
diff --git a/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.module.scss b/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.module.scss
index 6acb60a2..cb35cea8 100644
--- a/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.module.scss
+++ b/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.module.scss
@@ -2,13 +2,7 @@
width: 100%;
}
-.commentTitle {
- margin-top: 24px;
-}
-
.recommendations {
- padding: 10px;
- margin-top: 24px;
flex-wrap: nowrap;
overflow-y: hidden;
overflow-x: auto;
diff --git a/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.tsx b/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.tsx
index 997523fa..ba2c6118 100644
--- a/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.tsx
+++ b/src/pages/ArticleDetailsPage/ui/ArticleDetailsPage/ArticleDetailsPage.tsx
@@ -21,6 +21,7 @@ import { AddCommentForm } from 'features/AddCommentForm';
import { Button, ButtonVariant } from 'shared/ui/Button/Button';
import { RoutePath } from 'shared/config/routeConfig/routeConfig';
import { Page } from 'widgets/Page';
+import { HStack, VStack } from 'shared/ui/Stack';
import { articleDetailsPageReducer } from '../../model/slices';
import { fetchArticleRecommendations } from '../../model/services/fetchArticleRecommendations/fetchArticleRecommendations';
import { getArticleRecommendationsIsLoading } from '../../model/selectors/recommendations';
@@ -81,18 +82,14 @@ const ArticleDetailsPage = ({ className }: ArticleDetailsPageProps) => {
let commentBlock;
if (!errorArticle) {
commentBlock = (
- <>
-
+
+
- >
+
);
}
@@ -101,23 +98,26 @@ const ArticleDetailsPage = ({ className }: ArticleDetailsPageProps) => {
-
-
-
-
- {commentBlock}
+
+
+
+
+
+
+
+ {commentBlock}
+
);
diff --git a/src/pages/ProfilePage/ui/ProfilePage.tsx b/src/pages/ProfilePage/ui/ProfilePage.tsx
index 875d11c8..4028d7d4 100644
--- a/src/pages/ProfilePage/ui/ProfilePage.tsx
+++ b/src/pages/ProfilePage/ui/ProfilePage.tsx
@@ -25,6 +25,7 @@ import { useTranslation } from 'react-i18next';
import { useInitialEffect } from 'shared/lib/hooks/useInitialEffect/useInitialEffect';
import { useParams } from 'react-router-dom';
import { Page } from 'widgets/Page';
+import { VStack } from 'shared/ui/Stack';
import { ProfilePageHeader } from './ProfilePageHeader/ProfilePageHeader';
const redusers: ReducersList = {
@@ -111,7 +112,6 @@ const ProfilePage = ({ className }: ProfilePageProps) => {
},
[dispatch],
);
-
const onChangeCountry = useCallback(
(country: Country) => {
dispatch(profileActions.updateProfile({ country }));
@@ -122,29 +122,31 @@ const ProfilePage = ({ className }: ProfilePageProps) => {
return (
-
- {validateErrors?.length &&
- validateErrors.map((error) => (
-
- ))}
-
+
+
+ {validateErrors?.length &&
+ validateErrors.map((error) => (
+
+ ))}
+
+
);
diff --git a/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.module.scss b/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.module.scss
deleted file mode 100644
index a559bef0..00000000
--- a/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.module.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-.ProfilePageHeader {
- display: flex;
- margin-bottom: 12px;
-
- .editBtn,
- .saveBtn {
- margin-left: auto;
- margin-right: 12px;
- }
-}
-
-.btnsWrapper {
- margin-left: auto;
-}
diff --git a/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.tsx b/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.tsx
index fc0f9235..8e4f52a3 100644
--- a/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.tsx
+++ b/src/pages/ProfilePage/ui/ProfilePageHeader/ProfilePageHeader.tsx
@@ -12,7 +12,7 @@ import {
import { useSelector } from 'react-redux';
import { useCallback } from 'react';
import { getUserAuthData } from 'entities/User';
-import cls from './ProfilePageHeader.module.scss';
+import { HStack, VStack } from 'shared/ui/Stack';
interface ProfilePageHeaderProps {
className?: string;
@@ -39,22 +39,24 @@ export const ProfilePageHeader = ({ className }: ProfilePageHeaderProps) => {
}, [dispatch]);
return (
-
+
{canEdit && (
-
+
{readOnly ? (
) : (
- <>
+
- >
+
)}
)}
-
+
);
};
diff --git a/src/shared/ui/Stack/Flex/Flex.module.scss b/src/shared/ui/Stack/Flex/Flex.module.scss
new file mode 100644
index 00000000..b5eacb0c
--- /dev/null
+++ b/src/shared/ui/Stack/Flex/Flex.module.scss
@@ -0,0 +1,63 @@
+.Flex {
+ display: flex;
+}
+
+.justifyStart {
+ justify-content: flex-start;
+}
+
+.justifyCenter {
+ justify-content: center;
+}
+
+.justifyEnd {
+ justify-content: flex-end;
+}
+
+.justifyBetween {
+ justify-content: space-between;
+}
+
+.alignStart {
+ align-items: flex-start;
+}
+
+.alignCenter {
+ align-items: center;
+}
+
+.alignEnd {
+ align-items: flex-end;
+}
+
+.directionRow {
+ flex-direction: row;
+}
+
+.directionColumn {
+ flex-direction: column;
+}
+
+.gap4 {
+ gap: 4px;
+}
+
+.gap8 {
+ gap: 8px;
+}
+
+.gap10 {
+ gap: 10px;
+}
+
+.gap12 {
+ gap: 12px;
+}
+
+.gap16 {
+ gap: 16px;
+}
+
+.max {
+ width: 100%;
+}
diff --git a/src/shared/ui/Stack/Flex/Flex.stories.tsx b/src/shared/ui/Stack/Flex/Flex.stories.tsx
new file mode 100644
index 00000000..7a374e7d
--- /dev/null
+++ b/src/shared/ui/Stack/Flex/Flex.stories.tsx
@@ -0,0 +1,92 @@
+/* eslint-disable i18next/no-literal-string */
+import { ComponentStory, ComponentMeta } from '@storybook/react';
+import { Flex } from './Flex';
+
+export default {
+ title: 'shared/Flex',
+ component: Flex,
+ argTypes: {
+ backgroundColor: { control: 'color' },
+ },
+} as ComponentMeta
;
+
+const Template: ComponentStory = (args) => ;
+
+export const Row = Template.bind({});
+Row.args = {
+ children: (
+ <>
+ flex
+ flex
+ flex
+ flex
+ >
+ ),
+};
+
+export const RowGap4 = Template.bind({});
+RowGap4.args = {
+ gap: '4',
+ children: (
+ <>
+ flex
+ flex
+ flex
+ flex
+ >
+ ),
+};
+
+export const RowGap16 = Template.bind({});
+RowGap16.args = {
+ gap: '16',
+ children: (
+ <>
+ flex
+ flex
+ flex
+ flex
+ >
+ ),
+};
+
+export const Column = Template.bind({});
+Column.args = {
+ direction: 'column',
+ children: (
+ <>
+ flex
+ flex
+ flex
+ flex
+ >
+ ),
+};
+
+export const ColumnGap4 = Template.bind({});
+ColumnGap4.args = {
+ direction: 'column',
+ gap: '4',
+ children: (
+ <>
+ flex
+ flex
+ flex
+ flex
+ >
+ ),
+};
+
+export const ColumnGap16 = Template.bind({});
+ColumnGap16.args = {
+ direction: 'column',
+ gap: '16',
+ children: (
+ <>
+ flex
+ flex
+ flex
+ flex
+ >
+ ),
+};
diff --git a/src/shared/ui/Stack/Flex/Flex.tsx b/src/shared/ui/Stack/Flex/Flex.tsx
new file mode 100644
index 00000000..cab93d49
--- /dev/null
+++ b/src/shared/ui/Stack/Flex/Flex.tsx
@@ -0,0 +1,76 @@
+import { classNames } from 'shared/lib/classNames/classNames';
+import { ReactNode } from 'react';
+import cls from './Flex.module.scss';
+
+export type FlexJustify = 'start' | 'center' | 'end' | 'between';
+export type FlexAlign = 'start' | 'center' | 'end';
+export type FlexDirection = 'row' | 'column';
+export type FlexGap = '4' | '8' | '10' | '12' | '16';
+
+const justifyClasses: Record = {
+ start: cls.justifyStart,
+ between: cls.justifyBetween,
+ center: cls.justifyCenter,
+ end: cls.justifyCenter,
+};
+
+const alignClasses: Record = {
+ start: cls.alignStart,
+ center: cls.alignCenter,
+ end: cls.alignCenter,
+};
+
+const directionClasses: Record = {
+ row: cls.directionRow,
+ column: cls.directionColumn,
+};
+
+const gapClasses: Record = {
+ 4: cls.gap4,
+ 8: cls.gap8,
+ 10: cls.gap10,
+ 12: cls.gap12,
+ 16: cls.gap16,
+};
+
+export interface FlexProps {
+ className?: string;
+ children: ReactNode;
+ justify?: FlexJustify;
+ align?: FlexAlign;
+ direction: FlexDirection;
+ gap?: FlexGap;
+ component?: keyof JSX.IntrinsicElements;
+ max?: boolean;
+}
+
+export const Flex = ({
+ className,
+ children,
+ justify = 'start',
+ align = 'center',
+ direction = 'row',
+ gap = '8',
+ component = 'div',
+ max,
+}: FlexProps) => {
+ const classes = [
+ className,
+ justifyClasses[justify],
+ alignClasses[align],
+ directionClasses[direction],
+ gap && gapClasses[gap],
+ ];
+
+ const mods = {
+ [cls.max]: max,
+ };
+
+ const ComponentWrapper = component;
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/shared/ui/Stack/HStack/HStack.tsx b/src/shared/ui/Stack/HStack/HStack.tsx
new file mode 100644
index 00000000..a6b21ce8
--- /dev/null
+++ b/src/shared/ui/Stack/HStack/HStack.tsx
@@ -0,0 +1,7 @@
+import { Flex, FlexProps } from '../Flex/Flex';
+
+type HStackProps = Omit;
+
+export const HStack = (props: HStackProps) => (
+
+);
diff --git a/src/shared/ui/Stack/VStack/VStack.tsx b/src/shared/ui/Stack/VStack/VStack.tsx
new file mode 100644
index 00000000..fa6488f5
--- /dev/null
+++ b/src/shared/ui/Stack/VStack/VStack.tsx
@@ -0,0 +1,7 @@
+import { Flex, FlexProps } from '../Flex/Flex';
+
+type VStackProps = Omit;
+
+export const VStack = ({ align = 'start', ...props }: VStackProps) => (
+
+);
diff --git a/src/shared/ui/Stack/index.ts b/src/shared/ui/Stack/index.ts
new file mode 100644
index 00000000..b20bde75
--- /dev/null
+++ b/src/shared/ui/Stack/index.ts
@@ -0,0 +1,2 @@
+export { HStack } from './HStack/HStack';
+export { VStack } from './VStack/VStack';
diff --git a/src/widgets/Sidebar/ui/Sidebar/Sidebar.module.scss b/src/widgets/Sidebar/ui/Sidebar/Sidebar.module.scss
index 67d53d37..b56fd28e 100644
--- a/src/widgets/Sidebar/ui/Sidebar/Sidebar.module.scss
+++ b/src/widgets/Sidebar/ui/Sidebar/Sidebar.module.scss
@@ -5,6 +5,7 @@
position: relative;
transition: width 0.2s;
flex-shrink: 0;
+ padding-left: 30px;
}
.switchers {
@@ -26,15 +27,9 @@
z-index: 1000;
}
-.items {
- margin-top: 20px;
- margin-left: 30px;
- display: flex;
- flex-direction: column;
-}
-
.collapsed {
width: var(--sidebar-width-collapsed);
+ padding-left: 0;
.switchers {
flex-direction: column;
diff --git a/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx b/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx
index 6a7e4b7b..7d7fbb01 100644
--- a/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx
+++ b/src/widgets/Sidebar/ui/Sidebar/Sidebar.tsx
@@ -4,6 +4,7 @@ import { ThemeSwitcher } from 'shared/ui/ThemeSwitcher/ThemeSwitcher';
import { LangSwitcher } from 'shared/ui/LangSwitcher/LangSwitcher';
import { Button, ButtonSize, ButtonVariant } from 'shared/ui/Button/Button';
import { useSelector } from 'react-redux';
+import { VStack } from 'shared/ui/Stack';
import { getSiderbarItems } from '../../model/selecotrs/getSidebarItems';
import cls from './Sidebar.module.scss';
import { SidebarItem } from '../SidebarItem/SidebarItem';
@@ -42,7 +43,9 @@ export const Sidebar = memo(({ className }: SidebarProps) => {
className,
])}
>
- {itemList}
+
+ {itemList}
+