Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

26 show class component #67

Merged
merged 11 commits into from
Dec 28, 2024
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
Loading