mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 22:04:56 +00:00
Merge pull request #397 from johndoe6345789/copilot/sub-pr-246
Extract BlockSection and BlockFields from BlockItem component
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { Box, MenuItem, TextField, Typography } from '@mui/material'
|
||||
import type { BlockDefinition, LuaBlock } from '../types'
|
||||
import styles from '../LuaBlocksEditor.module.scss'
|
||||
|
||||
interface BlockFieldsProps {
|
||||
block: LuaBlock
|
||||
definition: BlockDefinition
|
||||
onUpdateField: (blockId: string, fieldName: string, value: string) => void
|
||||
}
|
||||
|
||||
export const BlockFields = ({ block, definition, onUpdateField }: BlockFieldsProps) => {
|
||||
if (definition.fields.length === 0) return null
|
||||
|
||||
return (
|
||||
<Box className={styles.blockFields}>
|
||||
{definition.fields.map((field) => (
|
||||
<Box key={field.name}>
|
||||
<Typography className={styles.blockFieldLabel}>{field.label}</Typography>
|
||||
{field.type === 'select' ? (
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
value={block.fields[field.name]}
|
||||
onChange={(event) => onUpdateField(block.id, field.name, event.target.value)}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
InputProps={{
|
||||
sx: { backgroundColor: 'rgba(255,255,255,0.95)' },
|
||||
}}
|
||||
>
|
||||
{field.options?.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
) : (
|
||||
<TextField
|
||||
size="small"
|
||||
value={block.fields[field.name]}
|
||||
onChange={(event) => onUpdateField(block.id, field.name, event.target.value)}
|
||||
placeholder={field.placeholder}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
type={field.type === 'number' ? 'number' : 'text'}
|
||||
InputProps={{
|
||||
sx: { backgroundColor: 'rgba(255,255,255,0.95)' },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
@@ -1,21 +1,9 @@
|
||||
import type { MouseEvent } from 'react'
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
IconButton,
|
||||
MenuItem,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from '@mui/material'
|
||||
import {
|
||||
Add as AddIcon,
|
||||
ArrowDownward,
|
||||
ArrowUpward,
|
||||
ContentCopy,
|
||||
Delete as DeleteIcon,
|
||||
} from '@mui/icons-material'
|
||||
import { Box, IconButton, Tooltip, Typography } from '@mui/material'
|
||||
import { ArrowDownward, ArrowUpward, ContentCopy, Delete as DeleteIcon } from '@mui/icons-material'
|
||||
import type { BlockDefinition, BlockSlot, LuaBlock } from '../types'
|
||||
import { BlockSection } from './BlockSection'
|
||||
import { BlockFields } from './BlockFields'
|
||||
import styles from '../LuaBlocksEditor.module.scss'
|
||||
|
||||
interface BlockItemProps {
|
||||
@@ -34,102 +22,6 @@ interface BlockItemProps {
|
||||
renderNestedList: (blocks?: LuaBlock[]) => JSX.Element
|
||||
}
|
||||
|
||||
interface BlockSectionProps {
|
||||
title: string
|
||||
blocks: LuaBlock[] | undefined
|
||||
parentId: string
|
||||
slot: BlockSlot
|
||||
onRequestAddBlock: (
|
||||
event: MouseEvent<HTMLElement>,
|
||||
target: { parentId: string | null; slot: BlockSlot }
|
||||
) => void
|
||||
renderNestedList: (blocks?: LuaBlock[]) => JSX.Element
|
||||
}
|
||||
|
||||
const BlockSection = ({
|
||||
title,
|
||||
blocks,
|
||||
parentId,
|
||||
slot,
|
||||
onRequestAddBlock,
|
||||
renderNestedList,
|
||||
}: BlockSectionProps) => (
|
||||
<Box className={styles.blockSection}>
|
||||
<Box className={styles.blockSectionHeader}>
|
||||
<Typography className={styles.blockSectionTitle}>{title}</Typography>
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={(event) => onRequestAddBlock(event, { parentId, slot })}
|
||||
startIcon={<AddIcon fontSize="small" />}
|
||||
>
|
||||
Add block
|
||||
</Button>
|
||||
</Box>
|
||||
<Box className={styles.blockSectionBody}>
|
||||
{blocks && blocks.length > 0 ? (
|
||||
renderNestedList(blocks)
|
||||
) : (
|
||||
<Box className={styles.blockEmpty}>Drop blocks here to build this section.</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
|
||||
const BlockFields = ({
|
||||
block,
|
||||
definition,
|
||||
onUpdateField,
|
||||
}: {
|
||||
block: LuaBlock
|
||||
definition: BlockDefinition
|
||||
onUpdateField: (blockId: string, fieldName: string, value: string) => void
|
||||
}) => {
|
||||
if (definition.fields.length === 0) return null
|
||||
|
||||
return (
|
||||
<Box className={styles.blockFields}>
|
||||
{definition.fields.map((field) => (
|
||||
<Box key={field.name}>
|
||||
<Typography className={styles.blockFieldLabel}>{field.label}</Typography>
|
||||
{field.type === 'select' ? (
|
||||
<TextField
|
||||
select
|
||||
size="small"
|
||||
value={block.fields[field.name]}
|
||||
onChange={(event) => onUpdateField(block.id, field.name, event.target.value)}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
InputProps={{
|
||||
sx: { backgroundColor: 'rgba(255,255,255,0.95)' },
|
||||
}}
|
||||
>
|
||||
{field.options?.map((option) => (
|
||||
<MenuItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
) : (
|
||||
<TextField
|
||||
size="small"
|
||||
value={block.fields[field.name]}
|
||||
onChange={(event) => onUpdateField(block.id, field.name, event.target.value)}
|
||||
placeholder={field.placeholder}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
type={field.type === 'number' ? 'number' : 'text'}
|
||||
InputProps={{
|
||||
sx: { backgroundColor: 'rgba(255,255,255,0.95)' },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export const BlockItem = ({
|
||||
block,
|
||||
definition,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { MouseEvent } from 'react'
|
||||
import { Box, Button, Typography } from '@mui/material'
|
||||
import { Add as AddIcon } from '@mui/icons-material'
|
||||
import type { BlockSlot, LuaBlock } from '../types'
|
||||
import styles from '../LuaBlocksEditor.module.scss'
|
||||
|
||||
interface BlockSectionProps {
|
||||
title: string
|
||||
blocks: LuaBlock[] | undefined
|
||||
parentId: string
|
||||
slot: BlockSlot
|
||||
onRequestAddBlock: (
|
||||
event: MouseEvent<HTMLElement>,
|
||||
target: { parentId: string | null; slot: BlockSlot }
|
||||
) => void
|
||||
renderNestedList: (blocks?: LuaBlock[]) => JSX.Element
|
||||
}
|
||||
|
||||
export const BlockSection = ({
|
||||
title,
|
||||
blocks,
|
||||
parentId,
|
||||
slot,
|
||||
onRequestAddBlock,
|
||||
renderNestedList,
|
||||
}: BlockSectionProps) => (
|
||||
<Box className={styles.blockSection}>
|
||||
<Box className={styles.blockSectionHeader}>
|
||||
<Typography className={styles.blockSectionTitle}>{title}</Typography>
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={(event) => onRequestAddBlock(event, { parentId, slot })}
|
||||
startIcon={<AddIcon fontSize="small" />}
|
||||
>
|
||||
Add block
|
||||
</Button>
|
||||
</Box>
|
||||
<Box className={styles.blockSectionBody}>
|
||||
{blocks && blocks.length > 0 ? (
|
||||
renderNestedList(blocks)
|
||||
) : (
|
||||
<Box className={styles.blockEmpty}>Drop blocks here to build this section.</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
Reference in New Issue
Block a user