Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { FC, useEffect, useRef } from 'react'

import { MarkdownEditor } from '@baseapp-frontend/design-system/components/web/inputs'
import { setFormRelayErrors } from '@baseapp-frontend/utils'

import { zodResolver } from '@hookform/resolvers/zod'
Expand Down Expand Up @@ -144,6 +145,9 @@ const MessageUpdate: FC<MessageUpdateProps> = ({
ariaLabel: 'save message edit',
cancelAriaLabel: 'cancel message edit',
}}
SocialTextFieldProps={{
TextField: MarkdownEditor,
}}
{...SocialInputProps}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DownloadIcon,
PenEditIcon,
} from '@baseapp-frontend/design-system/components/web/icons'
import { Markdown } from '@baseapp-frontend/design-system/components/web/markdowns'
import { useNotification } from '@baseapp-frontend/utils'

import { Typography } from '@mui/material'
Expand Down Expand Up @@ -80,7 +81,7 @@ const MessageItem: FC<MessageItemProps> = ({
>
{deletedMessage && <BlockIcon sx={{ fontSize: '20px', color: 'grey.500' }} />}
{deletedMessage && ' '}
{message?.content}
<Markdown>{message?.content}</Markdown>
</Typography>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { forwardRef } from 'react'

import { useCurrentProfile } from '@baseapp-frontend/authentication'
import { MarkdownEditor } from '@baseapp-frontend/design-system/components/web/inputs'
import { setFormRelayErrors } from '@baseapp-frontend/utils'

import { zodResolver } from '@hookform/resolvers/zod'
Expand Down Expand Up @@ -124,6 +125,9 @@ const SendMessage = forwardRef<HTMLInputElement, SendMessageProps>(
form={form}
submit={onSubmit}
isLoading={isMutationInFlight}
SocialTextFieldProps={{
TextField: MarkdownEditor,
}}
{...SocialInputProps}
/>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'

import { Meta, StoryFn, StoryObj } from '@storybook/react'

import LazyLoadImage from '..'
import { LazyLoadImageProps } from '../types'

const meta: Meta = {
title: '@baseapp-frontend-template / Design System/Displays/LazyLoadImage',
component: LazyLoadImage,
}

export default meta

type Story = StoryObj<LazyLoadImageProps>

const Template: StoryFn<LazyLoadImageProps> = (args: any) => <LazyLoadImage {...args} />

export const Default: Story = Template.bind({})
Default.args = {
src: '/png/home-banner.png',
alt: 'Example lazy-loaded image',
ratio: '16/9',
width: 200,
height: 225,
overlay: 'rgba(0, 0, 0, 0.5)',
disabledEffect: false,
}
119 changes: 119 additions & 0 deletions packages/design-system/components/web/images/LazyLoadImage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
'use client'

import { forwardRef } from 'react'

import Box from '@mui/material/Box'
import { alpha, useTheme } from '@mui/material/styles'
import { LazyLoadImage as ReactLazyLoadImage } from 'react-lazy-load-image-component'

import { LazyLoadImageProps } from './types'
import { getRatio } from './utils'

export type * from './types'

const LazyLoadImage = forwardRef<HTMLSpanElement, LazyLoadImageProps>(
(
{
ratio,
overlay,
disabledEffect = false,
alt,
src,
afterLoad,
delayTime,
threshold,
beforeLoad,
delayMethod,
placeholder,
wrapperProps,
scrollPosition,
effect = 'blur',
visibleByDefault,
wrapperClassName,
useIntersectionObserver,
sx,
...other
},
ref,
) => {
const theme = useTheme()

const overlayStyles = !!overlay && {
'&:before': {
content: "''",
top: 0,
left: 0,
width: 1,
height: 1,
zIndex: 1,
position: 'absolute',
background: overlay || alpha(theme.palette.grey[900], 0.48),
},
}

const content = (
<Box
component={ReactLazyLoadImage}
alt={alt}
src={src}
afterLoad={afterLoad}
delayTime={delayTime}
threshold={threshold}
beforeLoad={beforeLoad}
delayMethod={delayMethod}
placeholder={placeholder}
wrapperProps={wrapperProps}
scrollPosition={scrollPosition}
visibleByDefault={visibleByDefault}
effect={disabledEffect ? undefined : effect}
useIntersectionObserver={useIntersectionObserver}
wrapperClassName={wrapperClassName || 'component-image-wrapper'}
placeholderSrc={disabledEffect ? '/assets/transparent.png' : '/assets/placeholder.svg'}
sx={{
width: 1,
height: 1,
objectFit: 'cover',
verticalAlign: 'bottom',
...(!!ratio && {
top: 0,
left: 0,
position: 'absolute',
}),
}}
/>
)

return (
<Box
ref={ref}
component="span"
className="component-image"
sx={{
overflow: 'hidden',
position: 'relative',
verticalAlign: 'bottom',
display: 'inline-block',
...(!!ratio && {
width: 1,
}),
'& span.component-image-wrapper': {
width: 1,
height: 1,
verticalAlign: 'bottom',
backgroundSize: 'cover !important',
...(!!ratio && {
pt: getRatio(ratio),
}),
},
...overlayStyles,
...sx,
}}
{...other}
>
{content}
</Box>
)
},
)

export default LazyLoadImage
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BoxProps } from '@mui/material/Box'
import { LazyLoadImageProps as ReactLazyLoadImageProps } from 'react-lazy-load-image-component'

export type LazyLoadImageRatio =
| '4/3'
| '3/4'
| '6/4'
| '4/6'
| '16/9'
| '9/16'
| '21/9'
| '9/21'
| '1/1'

export type LazyLoadImageProps = BoxProps &
ReactLazyLoadImageProps & {
overlay?: string
ratio?: LazyLoadImageRatio
disabledEffect?: boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// ----------------------------------------------------------------------

export function getRatio(ratio = '1/1') {
return {
'4/3': 'calc(100% / 4 * 3)',
'3/4': 'calc(100% / 3 * 4)',
'6/4': 'calc(100% / 6 * 4)',
'4/6': 'calc(100% / 4 * 6)',
'16/9': 'calc(100% / 16 * 9)',
'9/16': 'calc(100% / 9 * 16)',
'21/9': 'calc(100% / 21 * 9)',
'9/21': 'calc(100% / 9 * 21)',
'1/1': '100%',
}[ratio]
}
3 changes: 3 additions & 0 deletions packages/design-system/components/web/images/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ export { default as Iconify } from './Iconify'
export type * from './Iconify/types'
export { default as ImageWithFallback } from './ImageWithFallback'
export type * from './ImageWithFallback/types'

export { default as LazyLoadImage } from './LazyLoadImage'
export type * from './LazyLoadImage/types'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* Remove borders and paddings from the editor */
.container {
border: 1px solid transparent;
padding-bottom: 5px;
width: 100%;
max-width: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use client'

import React, { FC } from 'react'

import { withController } from '@baseapp-frontend/utils'

import MDEditor from '@uiw/react-md-editor'
import rehypeSanitize from 'rehype-sanitize'

import './index.css'
// TODO check custom css is not appling with the new build method
import { MarkdownEditorProps } from './types'

const MarkdownEditor: FC<MarkdownEditorProps> = ({
value,
onChange,
onKeyDown,
placeholder,
...props
}) => (
<div className="container" style={{ maxWidth: '100%', width: '100%' }}>
<div data-color-mode="light">
<MDEditor
height={150}
preview="edit"
value={value}
onChange={onChange}
previewOptions={{
rehypePlugins: [[rehypeSanitize]],
}}
textareaProps={{
placeholder,
onKeyDown: (e) => {
onKeyDown?.(e)
},
}}
{...props}
/>
</div>
</div>
)

export default withController(MarkdownEditor)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { KeyboardEventHandler } from 'react'

import { FormControl } from '@baseapp-frontend/utils'

import { MDEditorProps } from '@uiw/react-md-editor'

export type MarkdownEditorProps = MDEditorProps &
FormControl & {
onKeyDown?: KeyboardEventHandler<HTMLTextAreaElement>
placeholder?: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const SocialTextField: FC<SocialTextFieldProps> = ({
isReply,
replyTargetName,
onCancelReply,
TextField = TextareaField,
...props
}) => (
<Container>
Expand All @@ -48,7 +49,8 @@ const SocialTextField: FC<SocialTextFieldProps> = ({
</div>
</OutsideReplyContainer>
)}
<TextareaField {...props} />
{/* @ts-ignore TODO: Type this properly */}
<TextField {...props} />
<div className="flex justify-between px-3 pb-3">{children}</div>
</Container>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { PropsWithChildren } from 'react'
import { FC, PropsWithChildren } from 'react'

import { FormControl } from '@baseapp-frontend/utils'

import { MarkdownEditorProps } from '../MarkdownEditor/types'
import { TextFieldProps } from '../TextField/types'
import { TextareaFieldProps } from '../TextareaField/types'

export type SocialTextFieldProps = FormControl &
TextFieldProps &
PropsWithChildren & {
isReply?: boolean
onCancelReply?: () => void
replyTargetName?: string | null
TextField?: FC<TextareaFieldProps> | FC<MarkdownEditorProps>
}
2 changes: 2 additions & 0 deletions packages/design-system/components/web/inputs/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use client'

export { default as MarkdownEditor } from './MarkdownEditor'
export type * from './MarkdownEditor/types'
export { default as PhoneNumberField } from './PhoneNumberField'
export type * from './PhoneNumberField/types'
export { default as Searchbar } from './Searchbar'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import hljs from 'highlight.js'
import 'highlight.js/styles/base16/tomorrow-night.css'

declare global {
interface Window {
hljs: any
}
}

hljs.configure({
languages: ['javascript', 'sh', 'bash', 'html', 'scss', 'css', 'json'],
})

if (typeof window !== 'undefined') {
window.hljs = hljs
}
Loading
Loading