Skip to content

Commit

Permalink
Merge pull request #4 from shawkyebrahim2514/Development
Browse files Browse the repository at this point in the history
Modification and Refactoring
  • Loading branch information
shawkyebrahim2514 authored Dec 5, 2024
2 parents 58b06b1 + 0a21272 commit 51d6716
Show file tree
Hide file tree
Showing 16 changed files with 356 additions and 193 deletions.
1 change: 1 addition & 0 deletions react-frontend/src/Types/contexts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
type ColorLevels = {
0: string,
50: string,
100: string,
200: string,
Expand Down
4 changes: 3 additions & 1 deletion react-frontend/src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ type ButtonProps = {
readonly size?: keyof typeof differentSizes;
readonly style?: React.CSSProperties;
readonly pointer?: boolean;
readonly children?: JSX.Element[];
}

export default function Button({ icon, text, onClick, size = "lg", style, pointer }: ButtonProps) {
export default function Button({ icon, text, onClick, size = "lg", style, pointer, children }: ButtonProps) {
const { theme } = useThemeContext();
const buttonStyle = useMemo(() => css({
padding: differentSizes[size].padding,
Expand All @@ -50,6 +51,7 @@ export default function Button({ icon, text, onClick, size = "lg", style, pointe
onKeyDown={handleKeyDown} >
{icon}
{text}
{children}
</div >
)
}
2 changes: 1 addition & 1 deletion react-frontend/src/components/CenteredSection/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function HeaderTitle({ title, icon }: Readonly<Pick<HeaderProps, "title" | "icon
alignItems: "center",
justifyContent: "center",
gap: "0.5rem",
color: theme.colors.base[600],
color: theme.colors.base[700],
}
}, [theme.colors]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type AncherLinkMarkdownProps = {
const AncherLinkMarkdown = ({ node, ...props }: AncherLinkMarkdownProps) => {
const title = props.children as string;
const link = node?.properties?.href as string;
// `[[Google]](https://www.google.com)`
const matchButtonLink = /\[(.*)\]/.exec(title);
if (matchButtonLink) {
return (
Expand All @@ -23,6 +24,7 @@ const AncherLinkMarkdown = ({ node, ...props }: AncherLinkMarkdownProps) => {
/>
)
}
// `[Google](https://www.google.com)`
return (
<Header
title={title}
Expand Down
64 changes: 7 additions & 57 deletions react-frontend/src/components/HTMLMarkdown/BlockquoteMarkdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useThemeContext } from '../../contexts/ThemeContext';
import type { Element, Node, Text, Parent, RootContent } from 'hast'
import type { Element, RootContent } from 'hast'
import MainSection from '../MainSection';
import { toJsxRuntime } from 'hast-util-to-jsx-runtime'
import { Fragment, jsx, jsxs } from 'react/jsx-runtime'
Expand All @@ -16,65 +16,17 @@ type BlockquoteMarkdownProps = {
node?: Element,
} & React.HTMLAttributes<HTMLQuoteElement>;

const isTextNode = (node: Node): node is Text => {
return node?.type === 'text';
};

const isParentNode = (node: Node): node is Parent => {
return node && 'children' in node;
};

const dfsVisit = (currentNode: Node, callback: (node: Node) => boolean | undefined): boolean => {
let isFinished = false;
if (isParentNode(currentNode)) {
for (const child of currentNode.children) {
isFinished = callback(child) || isFinished;
if (!isFinished) {
isFinished = dfsVisit(child, callback) || isFinished;
}
}
}
return isFinished;
};

const BlockquoteMarkdown = ({ node, ...props }: BlockquoteMarkdownProps) => {
const BlockquoteMarkdown = ({ node, className, ...props }: BlockquoteMarkdownProps) => {
const { theme } = useThemeContext();

let { className, title, content } = useMemo(() => {
let className = props?.className?.split(' ') || [];
let title = '';
let content: Node[] = node?.children || [];
let completed = false;
dfsVisit(node as Node, (currentNode: Node) => {
if (completed) {
content.push(currentNode);
} else if (isTextNode(currentNode)) {
if (currentNode.value) {
const match = /\[!(.+)\](.*)/.exec(currentNode.value);
if (match) {
match[1].trim().split(' ').forEach((element) => {
className.push(element);
});
title = match[2].trim();
content = [];
completed = true;
return true;
}
}
}
return false;
});
return { className, title, content };
}, [node, props.className]);

const contentJSXElementsFromAST = useMemo(() => (
content.map((element) => toJsxRuntime(element as RootContent, {
node?.children.map((element) => toJsxRuntime(element as RootContent, {
Fragment, jsx, jsxs, passNode: true, components: {
...markdownComponents,
br: () => null,
}
}))
), [content]);
), [node?.children]);

const targetElement = useMemo((): TargetElementType => ({
"highlight-background": {
Expand Down Expand Up @@ -104,10 +56,9 @@ const BlockquoteMarkdown = ({ node, ...props }: BlockquoteMarkdownProps) => {
let colorType = useMemo((): BlockquoteColorType => className?.includes("secondary") ? "secondary" : "base", [className]);
let colors = useMemo(() => targetElement[backgroundType][colorType], [backgroundType, colorType, targetElement]);

if (className.includes("popup")) {
if (className?.includes("popup")) {
return (
<MainSection
title={title}>
<MainSection>
{contentJSXElementsFromAST}
</MainSection>
);
Expand All @@ -118,13 +69,12 @@ const BlockquoteMarkdown = ({ node, ...props }: BlockquoteMarkdownProps) => {
className='blockquote'
style={{
...props.style,
padding: "1rem",
padding: "0 1rem",
position: "relative",
margin: "1rem 0",
backgroundColor: `${colors.containerBackgroundColor}`,
color: `${colors.barColor}`
}}>
<h3>{title}</h3>
<div style={{
position: "absolute",
left: 0,
Expand Down
100 changes: 63 additions & 37 deletions react-frontend/src/components/HTMLMarkdown/HeadingMarkdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,88 @@ type HeadingMarkdownProps = React.HTMLAttributes<HTMLHRElement> & {
headingNumber: "one" | "two" | "three" | "four" | "five" | "six",
}

const HeadingMarkdown = ({ headingNumber, ...props }: HeadingMarkdownProps) => {
const HeadingMarkdown = ({ headingNumber, children, ...props }: HeadingMarkdownProps) => {
const { theme } = useThemeContext();
const HTMLHeadingStyles: Record<HeadingMarkdownProps["headingNumber"], React.CSSProperties> = {
one: {
fontSize: "3.8rem",
fontWeight: 700,
color: theme.colors.base[800]
// color: theme.colors.base[800]
},
two: {
fontSize: "2.2rem",
color: theme.colors.base[800]
fontWeight: 700,
// color: theme.colors.base[800]
},
three: {
fontSize: "1.8rem"
fontSize: "1.8rem",
fontWeight: 700,
// color: theme.colors.base[800]
},
four: {
fontSize: "1.4rem"
fontSize: "1.4rem",
fontWeight: 700,
// color: theme.colors.base[800]
},
five: {
fontSize: "1.2rem"
fontSize: "1.2rem",
fontWeight: 700,
// color: theme.colors.base[800]
},
six: {
fontSize: "1.1rem"
fontSize: "1.1rem",
color: theme.colors.base[800]
}
}
const HTMLHeadings: Record<HeadingMarkdownProps["headingNumber"], JSX.Element> = {
one: <h1 {...props}
style={{
...props.style,
...HTMLHeadingStyles.one
}} />,
two: <h2 {...props}
style={{
...props.style,
...HTMLHeadingStyles.two
}} />,
three: <h3 {...props}
style={{
...props.style,
...HTMLHeadingStyles.three
}} />,
four: <h4 {...props}
style={{
...props.style,
...HTMLHeadingStyles.four
}} />,
five: <h5 {...props}
style={{
...props.style,
...HTMLHeadingStyles.five
}} />,
six: <h6 {...props}
style={{
...props.style,
...HTMLHeadingStyles.six
}} />
one:
<h1 {...props}
style={{
...props.style,
...HTMLHeadingStyles.one
}}>
{children}
</h1>,
two:
<h2 {...props}
style={{
...props.style,
...HTMLHeadingStyles.two
}}>
{children}
</h2>,
three:
<h3 {...props}
style={{
...props.style,
...HTMLHeadingStyles.three
}}>
{children}
</h3>,
four:
<h4 {...props}
style={{
...props.style,
...HTMLHeadingStyles.four
}}>
{children}
</h4>,
five:
<h5 {...props}
style={{
...props.style,
...HTMLHeadingStyles.five
}}>
{children}
</h5>,
six:
<h6 {...props}
style={{
...props.style,
...HTMLHeadingStyles.six
}}>
{children}
</h6>,
}

return HTMLHeadings[headingNumber];
Expand Down
2 changes: 1 addition & 1 deletion react-frontend/src/components/HTMLMarkdown/HrMarkdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const HrMarkdown = ({ ...props }: React.HTMLAttributes<HTMLHRElement>) => {
margin: "1rem 0",
backgroundColor: theme.colors.base[200],
height: "1px",
}), []);
}), [theme.colors.base]);
return (
<div {...props} style={{
...props.style,
Expand Down
Loading

0 comments on commit 51d6716

Please sign in to comment.