Skip to content

Commit

Permalink
Merge pull request #67 from ls1intum/26-show-class-component
Browse files Browse the repository at this point in the history
  • Loading branch information
egenerse authored Dec 28, 2024
2 parents e1b485a + db2d18f commit 9539d13
Show file tree
Hide file tree
Showing 21 changed files with 901 additions and 76 deletions.
44 changes: 28 additions & 16 deletions library/lib/App.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import {
ReactFlow,
ReactFlowInstance,
ReactFlowProvider,
type Node,
type Edge,
Background,
BackgroundVariant,
Controls,
MiniMap,
DefaultEdgeOptions,
type NodeTypes,
MarkerType,
ConnectionLineType,
ConnectionMode,
ReactFlowInstance,
} from "@xyflow/react"

import "@xyflow/react/dist/style.css"
import { MAX_SCALE_TO_ZOOM_IN, MIN_SCALE_TO_ZOOM_OUT } from "./contants"
import { defaultEdges, defaultNodes } from "./initialElements"
import "@/styles/app.css"
import { Class, Package, ColorDescription } from "./nodes"

const nodeTypes: NodeTypes = {
package: Package,
class: Class,
colorDescription: ColorDescription,
}

const initialNodes: Node[] = [
{ id: "1", position: { x: 0, y: 0 }, data: { label: "1" } },
{ id: "2", position: { x: 0, y: 100 }, data: { label: "2" } },
]
const initialEdges: Edge[] = [{ id: "e1-2", source: "1", target: "2" }]
const defaultEdgeOptions: DefaultEdgeOptions = {
type: "smoothstep",
markerEnd: { type: MarkerType.ArrowClosed },
style: { strokeWidth: 2 },
}

interface AppProps {
onReactFlowInit: (instance: ReactFlowInstance) => void
Expand All @@ -27,10 +39,14 @@ function App({ onReactFlowInit }: AppProps) {
return (
<div style={{ width: "100vw", height: "100vh" }}>
<ReactFlow
nodes={initialNodes}
edges={initialEdges}
onInit={onReactFlowInit}
nodeTypes={nodeTypes}
defaultEdgeOptions={defaultEdgeOptions}
defaultNodes={defaultNodes}
defaultEdges={defaultEdges}
connectionLineType={ConnectionLineType.SmoothStep}
connectionMode={ConnectionMode.Loose}
fitView
onInit={(instance) => onReactFlowInit(instance)}
minZoom={MIN_SCALE_TO_ZOOM_OUT}
maxZoom={MAX_SCALE_TO_ZOOM_IN}
>
Expand All @@ -42,11 +58,7 @@ function App({ onReactFlowInit }: AppProps) {
)
}

export function AppWithProvider({
onReactFlowInit,
}: {
onReactFlowInit: (instance: ReactFlowInstance) => void
}) {
export function AppWithProvider({ onReactFlowInit }: AppProps) {
return (
<ReactFlowProvider>
<App onReactFlowInit={onReactFlowInit} />
Expand Down
49 changes: 49 additions & 0 deletions library/lib/components/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from "react"

type Props = {
children: React.ReactNode
fill?: string
x?: string | number
y?: string | number
dominantBaseline?: string
textAnchor?: string
fontWeight?: string
pointerEvents?: string
noX?: boolean
noY?: boolean
}

export const Text: React.FC<Props & Record<string, unknown>> = ({
children,
fill,
x = "50%",
y = "50%",
dominantBaseline = "middle",
textAnchor = "middle",
fontWeight = "bold",
pointerEvents = "none",
noX = false,
noY = false,
...props
}: Props) => {
const pos: { x?: string | number; y?: string | number } = {}
if (!noX) {
pos.x = x
}
if (!noY) {
pos.y = y
}
return (
<text
{...pos}
style={fill ? { fill } : {}}
dominantBaseline={dominantBaseline}
textAnchor={textAnchor}
fontWeight={fontWeight}
pointerEvents={pointerEvents}
{...props}
>
{children}
</text>
)
}
121 changes: 121 additions & 0 deletions library/lib/components/ThemedElements.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import baseStyled from "styled-components"

// Default Colors
const defaultStrokeColor = "black"
const defaultFillColor = "white"
const defaultPrimaryContrast = "#ffffff" // Example: white
const defaultBackground = "#000000" // Example: black

// Themed Polyline
export const ThemedPolyline = baseStyled.polyline.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultFillColor,
strokeColor: props.strokeColor || defaultStrokeColor,
stroke: props.strokeColor || defaultStrokeColor,
fill: props.fillColor || defaultFillColor,
})
)`
fill: ${(props) => props.fillColor || defaultBackground};
stroke: ${(props) => props.strokeColor || defaultPrimaryContrast};
`

// Themed Path
export const ThemedPath = baseStyled.path.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultFillColor,
strokeColor: props.strokeColor || defaultStrokeColor,
stroke: props.strokeColor || defaultStrokeColor,
fill: props.fillColor || defaultFillColor,
})
)`
fill: ${(props) => props.fillColor || defaultBackground};
stroke: ${(props) => props.strokeColor || defaultPrimaryContrast};
`

// Themed Path Contrast
export const ThemedPathContrast = baseStyled.path.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultBackground,
strokeColor: props.strokeColor || defaultPrimaryContrast,
stroke: props.strokeColor || defaultPrimaryContrast,
fill: props.fillColor || defaultBackground,
})
)`
fill: ${(props) => props.fillColor || defaultPrimaryContrast};
stroke: ${(props) => props.strokeColor || defaultBackground};
`

// Themed Rect
export const ThemedRect = baseStyled.rect.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultFillColor,
strokeColor: props.strokeColor || defaultStrokeColor,
stroke: props.strokeColor || defaultStrokeColor,
fill: props.fillColor || defaultFillColor,
})
)`
fill: ${(props) => props.fillColor || defaultBackground};
stroke: ${(props) => props.strokeColor || defaultPrimaryContrast};
`

// Themed Rect Contrast
export const ThemedRectContrast = baseStyled.rect.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultBackground,
strokeColor: props.strokeColor || defaultPrimaryContrast,
stroke: props.strokeColor || defaultPrimaryContrast,
fill: props.fillColor || defaultBackground,
})
)`
fill: ${(props) => props.fillColor || defaultPrimaryContrast};
stroke: ${(props) => props.strokeColor || defaultBackground};
`

// Themed Circle
export const ThemedCircle = baseStyled.circle.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultFillColor,
strokeColor: props.strokeColor || defaultStrokeColor,
stroke: props.strokeColor || defaultStrokeColor,
fill: props.fillColor || defaultFillColor,
})
)`
fill: ${(props) => props.fillColor || defaultBackground};
stroke: ${(props) => props.strokeColor || defaultPrimaryContrast};
`

// Themed Circle Contrast
export const ThemedCircleContrast = baseStyled.circle.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultBackground,
strokeColor: props.strokeColor || defaultPrimaryContrast,
stroke: props.strokeColor || defaultPrimaryContrast,
fill: props.fillColor || defaultBackground,
})
)`
fill: ${(props) => props.fillColor || defaultPrimaryContrast};
stroke: ${(props) => props.strokeColor || defaultBackground};
`

// Themed Ellipse
export const ThemedEllipse = baseStyled.ellipse.attrs(
(props: { fillColor?: string; strokeColor?: string }) => ({
fillColor: props.fillColor || defaultFillColor,
strokeColor: props.strokeColor || defaultStrokeColor,
stroke: props.strokeColor || defaultStrokeColor,
fill: props.fillColor || defaultFillColor,
})
)`
fill: ${(props) => props.fillColor || defaultBackground};
stroke: ${(props) => props.strokeColor || defaultPrimaryContrast};
`

// Themed Line
export const ThemedLine = baseStyled.line.attrs(
(props: { strokeColor?: string }) => ({
strokeColor: props.strokeColor || defaultStrokeColor,
stroke: props.strokeColor || defaultStrokeColor,
})
)`
stroke: ${(props) => props.strokeColor || defaultPrimaryContrast};
`
2 changes: 2 additions & 0 deletions library/lib/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./Text"
export * from "./ThemedElements"
5 changes: 3 additions & 2 deletions library/lib/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import ReactDOM from "react-dom/client"
import { AppWithProvider } from "./App"
import { ReactFlowInstance, type Node } from "@xyflow/react"
import { ReactFlowInstance, type Node, type Edge } from "@xyflow/react"

export { type Node } from "@xyflow/react"

export class Apollon2 {
private root: ReactDOM.Root | null = null
private reactFlowInstance: ReactFlowInstance | null = null
private reactFlowInstance: ReactFlowInstance<Node, Edge> | null = null

constructor(element: HTMLElement) {
this.root = ReactDOM.createRoot(element)
Expand Down
134 changes: 134 additions & 0 deletions library/lib/initialElements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { type Edge, type Node } from "@xyflow/react"

export const defaultNodes: Node[] = [
{
id: "1",
type: "package",
position: { x: -100, y: 200 },
width: 200,
height: 200,
selected: false,
data: { name: "Package" },
},
{
id: "2",
type: "class",
position: { x: 400, y: -100 },
width: 296,
height: 170,
selected: false,
data: {
name: "Class",
methods: [
{ id: "1", name: "method1" },
{ id: "2", name: "method2" },
],
attributes: [
{ id: "1", name: "attribute1" },
{ id: "2", name: "attribute2" },
],
},
},
{
id: "3",
type: "class",
position: { x: 400, y: 100 },
width: 296,
height: 170,
selected: false,
data: {
stereotype: "abstract",
name: "AbstractClass",
methods: [
{ id: "1", name: "method1" },
{ id: "2", name: "method2" },
],
attributes: [
{ id: "1", name: "attribute1" },
{ id: "2", name: "attribute2" },
],
},
},
{
id: "4",
type: "class",
position: { x: 400, y: 300 },
width: 296,
height: 170,
selected: false,
data: {
name: "InterfaceClass",
stereotype: "interface",
methods: [
{ id: "1", name: "method1" },
{ id: "2", name: "method2" },
],
attributes: [
{ id: "1", name: "attribute1" },
{ id: "2", name: "attribute2" },
],
},
},
{
id: "5",
type: "class",
position: { x: 400, y: 500 },
width: 296,
height: 170,
selected: false,
data: {
name: "EnumerationClass",
stereotype: "enumaration",
methods: [
{ id: "1", name: "method1" },
{ id: "2", name: "method2" },
],
attributes: [
{ id: "1", name: "attribute1" },
{ id: "2", name: "attribute2" },
],
},
},
{
id: "6",
type: "colorDescription",
position: { x: -100, y: 600 },
width: 160,
height: 50,
selected: false,
data: {
description: "Color description",
},
},
]

export const defaultEdges: Edge[] = [
{
id: "1->2",
source: "1",
target: "2",
sourceHandle: "right",
targetHandle: "left",
},
{
id: "2->3",
source: "2",
target: "3",
sourceHandle: "bottom",
targetHandle: "top",
},
{
id: "2->4",
source: "2",
target: "4",
sourceHandle: "right",
targetHandle: "right",
},
{
id: "5->3",
source: "5",
target: "3",
sourceHandle: "left",
targetHandle: "left",
},
]
Loading

0 comments on commit 9539d13

Please sign in to comment.