Skip to content

Commit

Permalink
[AP-138]: Asset preview component (#50)
Browse files Browse the repository at this point in the history
* Task: implement asset-preview and dropdown-menu

* Task: implement asset-preview and dropdown-menu

* Task: rename preview and extract menu items

* Fix: merge conflicts

* Fix: lint
  • Loading branch information
robertSt7 authored Feb 28, 2024
1 parent bfb6be8 commit 5297fbf
Show file tree
Hide file tree
Showing 29 changed files with 440 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import type { Preview } from "@storybook/react";
import "../assets/css/globals.css";
import { GlobalProvider } from "../assets/js/src/modules/app/components/global-provider";
import { GlobalProvider } from "../assets/js/src/modules/app/global-provider";
import { App } from 'antd'

const preview: Preview = {
Expand Down
3 changes: 3 additions & 0 deletions assets/js/src/assets/icons/core/delete-outlined.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions assets/js/src/assets/icons/core/dots-horizontal.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/js/src/assets/icons/core/download-02.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/js/src/assets/icons/core/rich-edit.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/js/src/assets/icons/core/right-outlined.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions assets/js/src/assets/icons/core/target.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 55 additions & 0 deletions assets/js/src/components/dropdown-menu/dropdown-menu.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { type Meta } from '@storybook/react'
import { DropdownMenu as DropdownMenuComponent, type DropdownMenuItemProps } from './dropdown-menu'
import { Button } from 'antd'
import { Icon } from '@Pimcore/components/icon/icon'
import React from 'react'
import i18n from '@Pimcore/app/i18n'

const config: Meta = {
title: 'Pimcore studio/UI/DropdownMenu',
component: DropdownMenuComponent,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
}

export default config

const children =
<Button
size="small"
icon={<Icon name="dots-horizontal"/>}
/>

const dropdownItems: DropdownMenuItemProps[] = [
{
iconNameLeft: 'target',
label: i18n.t('preview-card.locate-in-tree')
},
{
iconNameLeft: 'info-circle-outlined',
label: i18n.t('preview-card.info'),
iconNameRight: 'right-outlined'
},
{
iconNameLeft: 'rich-edit',
label: i18n.t('preview-card.rename')
},
{
iconNameLeft: 'download-02',
label: i18n.t('preview-card.download-zip')
},
{
iconNameLeft: 'delete-outlined',
label: i18n.t('preview-card.delete')
}
]

export const _default = {
args: {
children,
placement: 'bottomLeft',
dropdownItems
}
}
14 changes: 14 additions & 0 deletions assets/js/src/components/dropdown-menu/dropdown-menu.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createStyles } from 'antd-style'

export const useStyle = createStyles(({ token, css }) => {
return {
'menu-icon': css`
vertical-align: middle;
margin-right: ${token.marginXS}px;
`,
'flexbox-start-end': css`
display: flex;
justify-content: space-between;
`
}
})
80 changes: 80 additions & 0 deletions assets/js/src/components/dropdown-menu/dropdown-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Dropdown, type DropdownProps, type MenuProps } from 'antd'
import React, { type ReactElement } from 'react'
import { Icon } from '@Pimcore/components/icon/icon'
import { useStyle } from './dropdown-menu.styles'

export interface DropdownMenuItemProps {
iconNameLeft: string
label: string
onClick?: () => void
iconNameRight?: string
}

interface DropdownMenuProps extends React.PropsWithChildren {
children: ReactElement
placement: DropdownProps['placement']
dropdownItems: DropdownMenuItemProps[]
openClassName?: string
}

export const DropdownMenu = ({
children,
placement,
dropdownItems,
openClassName
}: DropdownMenuProps
): React.JSX.Element => {
const items: MenuProps['items'] = []

dropdownItems.forEach((item, index) => {
items.push(
{
key: index.toString(),
label: (
<MenuItemContent item={item} />
)
}
)
})

return (
<div>
<Dropdown menu={{ items }}
placement={placement}
openClassName={openClassName}
>
{children}
</Dropdown>
</div>
)
}

function MenuItemContent (prop): React.JSX.Element {
const { item } = prop
const { styles } = useStyle()
const iconOptions = { width: '16px', height: '16px' }

if (item.iconNameRight as boolean) {
return (
<div onClick={item.onClick}
className={styles['flexbox-start-end']}
>
<div>
<Icon name={item.iconNameLeft} options={iconOptions} className={styles['menu-icon']}/>
{item.label}
</div>
<div>
<Icon name={item.iconNameRight} options={iconOptions} className={styles['menu-icon']}/>
</div>
</div>

)
}

return (
<div onClick={item.onClick}>
<Icon name={item.iconNameLeft} options={iconOptions} className={styles['menu-icon']} />
{item.label}
</div>
)
}
14 changes: 11 additions & 3 deletions assets/js/src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,29 @@ const icons = {
'view-details': React.lazy(async () => await import('@Pimcore/assets/icons/core/view-details.inline.svg')),
'tag-two-tone': React.lazy(async () => await import('@Pimcore/assets/icons/core/tag-two-tone.inline.svg')),
workflow: React.lazy(async () => await import('@Pimcore/assets/icons/core/workflow.inline.svg')),
'unordered-list-outlined': React.lazy(async () => await import('@Pimcore/assets/icons/core/unordered-list-outlined.inline.svg'))
'unordered-list-outlined': React.lazy(async () => await import('@Pimcore/assets/icons/core/unordered-list-outlined.inline.svg')),
'dots-horizontal': React.lazy(async () => await import('@Pimcore/assets/icons/core/dots-horizontal.inline.svg')),
target: React.lazy(async () => await import('@Pimcore/assets/icons/core/target.inline.svg')),
'info-circle-outlined': React.lazy(async () => await import('@Pimcore/assets/icons/core/info-circle-outlined.inline.svg')),
'right-outlined': React.lazy(async () => await import('@Pimcore/assets/icons/core/right-outlined.inline.svg')),
'rich-edit': React.lazy(async () => await import('@Pimcore/assets/icons/core/rich-edit.inline.svg')),
'download-02': React.lazy(async () => await import('@Pimcore/assets/icons/core/download-02.inline.svg')),
'delete-outlined': React.lazy(async () => await import('@Pimcore/assets/icons/core/delete-outlined.inline.svg'))
}

export interface IconProps {
name: string
options?: React.SVGProps<SVGSVGElement>
className?: string
}

export const Icon = ({ name, options }: IconProps): React.JSX.Element => {
export const Icon = ({ name, options, className }: IconProps): React.JSX.Element => {
const SvgIcon = icons[name]
const width = options?.width ?? 16
const height = options?.height ?? 16

return (
<div style={{ width, height }} className={`pimcore-icon pimcore-icon-${name} anticon`}>
<div style={{ width, height }} className={`pimcore-icon pimcore-icon-${name} anticon ${className}`}>
<Suspense fallback={<div />}>
<SvgIcon width={width} height={height} {...options} />
</Suspense>
Expand Down
21 changes: 21 additions & 0 deletions assets/js/src/components/pimcore-image/pimcore-image.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { type Meta } from '@storybook/react'
import { PimcoreImage as PimcoreImageComponent } from './pimcore-image'

const config: Meta = {
title: 'Pimcore studio/UI/PimcoreImage',
component: PimcoreImageComponent,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
}

export default config

export const _default = {
args: {
src: 'https://pimcore.com/brand/Website-Banners/image-thumb__23862__header-sujet-img__2019--slider/2024-Pimcore-Home-Main.webp',
alt: 'Pimconaut',
className: ''
}
}
11 changes: 11 additions & 0 deletions assets/js/src/components/pimcore-image/pimcore-image.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createStyles } from 'antd-style'

export const useStyle = createStyles(({ token, css }) => {
return {
'loading-div': css`
position: absolute;
top: calc(50% - 11px);
left: calc(50% - 8px);
`
}
})
24 changes: 24 additions & 0 deletions assets/js/src/components/pimcore-image/pimcore-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Image, type ImageProps, Spin } from 'antd'
import React from 'react'
import { useStyle } from '@Pimcore/components/pimcore-image/pimcore-image.styles'

interface PimcoreImageProps extends ImageProps {
}

export const PimcoreImage = (
props: PimcoreImageProps
): React.JSX.Element => {
const { styles } = useStyle()

return (
<Image
placeholder={
<div className={styles['loading-div']}>
<Spin size="small" />
</div>
}
preview={false}
{...props}
/>
)
}
48 changes: 48 additions & 0 deletions assets/js/src/components/preview-card/preview-card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { type Meta } from '@storybook/react'
import { PreviewCard as PreviewCardComponent } from './preview-card'
import { type DropdownMenuItemProps } from '@Pimcore/components/dropdown-menu/dropdown-menu'
import i18n from '@Pimcore/app/i18n'

const config: Meta = {
title: 'Pimcore studio/UI/PreviewCard',
component: PreviewCardComponent,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
}

export default config

const dropdownItems: DropdownMenuItemProps[] = [
{
iconNameLeft: 'target',
label: i18n.t('preview-card.locate-in-tree')
},
{
iconNameLeft: 'info-circle-outlined',
label: i18n.t('preview-card.info'),
iconNameRight: 'right-outlined'
},
{
iconNameLeft: 'rich-edit',
label: i18n.t('preview-card.rename')
},
{
iconNameLeft: 'download-02',
label: i18n.t('preview-card.download-zip')
},
{
iconNameLeft: 'delete-outlined',
label: i18n.t('preview-card.delete')
}
]

export const _default = {
args: {
name: 'Pimconaout0_123.jpg',
selected: false,
imgSrc: 'https://pimcore.com/brand/Website-Banners/image-thumb__23862__header-sujet-img__2019--slider/2024-Pimcore-Home-Main.webp',
dropdownItems
}
}
Loading

0 comments on commit 5297fbf

Please sign in to comment.