476 lines
15 KiB
TypeScript
476 lines
15 KiB
TypeScript
|
|
import { CUSTOM_COMPONENTS, HTML_ELEMENTS } from '@/components/codeLayout/data/componentDefinitions'
|
|||
|
|
import generatedComponentProps from './generated/componentProps.json'
|
|||
|
|
import type { DesignerComponentDefinition, DesignerNodeKind } from './types'
|
|||
|
|
|
|||
|
|
interface GeneratedProperty {
|
|||
|
|
name: string
|
|||
|
|
tsType: string
|
|||
|
|
type: 'string' | 'boolean' | 'number' | 'function' | 'object' | 'array' | 'select'
|
|||
|
|
required: boolean
|
|||
|
|
options?: string[]
|
|||
|
|
defaultValue?: unknown
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
interface GeneratedComponentMetadata {
|
|||
|
|
interfaceName: string
|
|||
|
|
sourceFile: string
|
|||
|
|
properties: GeneratedProperty[]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const generatedMetadata = generatedComponentProps as Record<string, GeneratedComponentMetadata>
|
|||
|
|
const CONTAINER_NAMES = new Set(['div', 'Card', 'FormContainer', 'Tabs', 'Timeline'])
|
|||
|
|
const DATA_COMPONENT_NAMES = new Set(['AutoComplete', 'Grid', 'Menu', 'Pagination', 'Select', 'Table'])
|
|||
|
|
const HTML_UI_DUPLICATES = new Set(['input', 'button', 'textarea', 'select', 'checkbox'])
|
|||
|
|
const UI_PROPERTY_ALIASES: Record<string, Record<string, string>> = {
|
|||
|
|
Select: {
|
|||
|
|
clearable: 'isClearable',
|
|||
|
|
disabled: 'isDisabled',
|
|||
|
|
multiple: 'isMulti',
|
|||
|
|
onSearch: 'onInputChange',
|
|||
|
|
searchable: 'isSearchable',
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
export const DESIGNER_PRIMARY_EVENTS: Record<string, string[]> = {
|
|||
|
|
Button: ['onClick'],
|
|||
|
|
Checkbox: ['onChange'],
|
|||
|
|
Input: ['onChange'],
|
|||
|
|
Menu: ['onSelect'],
|
|||
|
|
Select: ['onChange'],
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const DESIGNER_EVENT_SNIPPETS: Record<string, Record<string, string>> = {
|
|||
|
|
Button: {
|
|||
|
|
onClick: `// Butona tıklandığında çalışır.
|
|||
|
|
console.log('Button clicked', event)`,
|
|||
|
|
},
|
|||
|
|
Checkbox: {
|
|||
|
|
onChange: `// Checkbox bileşeninin yeni checked değeri.
|
|||
|
|
const checked = event.checked
|
|||
|
|
console.log('Checked:', checked)`,
|
|||
|
|
},
|
|||
|
|
Input: {
|
|||
|
|
onChange: `// Input alanının güncel metin değeri.
|
|||
|
|
const value = event.target.value
|
|||
|
|
console.log('Value:', value)`,
|
|||
|
|
},
|
|||
|
|
Menu: {
|
|||
|
|
onSelect: `// Seçilen menü öğesinin value değeridir.
|
|||
|
|
console.log('Menu value:', event)`,
|
|||
|
|
},
|
|||
|
|
Select: {
|
|||
|
|
onChange: `// Seçilen option nesnesi; temizlendiğinde null olur.
|
|||
|
|
const selectedValue = event?.value ?? null
|
|||
|
|
const selectedLabel = event?.label ?? ''
|
|||
|
|
console.log({ selectedValue, selectedLabel })`,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export const getDesignerEventSnippet = (componentName: string, eventName: string) =>
|
|||
|
|
DESIGNER_EVENT_SNIPPETS[componentName]?.[eventName] ||
|
|||
|
|
`// ${componentName}.${eventName}(event)\nconsole.log(event)`
|
|||
|
|
const COLLECTION_ITEMS_PROPERTY = {
|
|||
|
|
name: 'items',
|
|||
|
|
type: 'array' as const,
|
|||
|
|
value: [],
|
|||
|
|
category: 'properties' as const,
|
|||
|
|
description: 'Statik veya endpoint kaynaklı veri koleksiyonu',
|
|||
|
|
tsType: 'unknown[]',
|
|||
|
|
options: undefined,
|
|||
|
|
required: false,
|
|||
|
|
}
|
|||
|
|
const GRID_COMPACT_PROPERTY = {
|
|||
|
|
name: 'compact',
|
|||
|
|
type: 'boolean' as const,
|
|||
|
|
value: false,
|
|||
|
|
category: 'properties' as const,
|
|||
|
|
description: 'Satır ve hücre boşluklarını azaltır',
|
|||
|
|
tsType: 'boolean',
|
|||
|
|
options: undefined,
|
|||
|
|
required: false,
|
|||
|
|
}
|
|||
|
|
const GRID_TABLE_BEHAVIOR_PROPERTIES = [
|
|||
|
|
{
|
|||
|
|
name: 'hoverable',
|
|||
|
|
type: 'boolean' as const,
|
|||
|
|
value: true,
|
|||
|
|
category: 'properties' as const,
|
|||
|
|
description: 'Satırların üzerine gelindiğinde vurgu rengi gösterir',
|
|||
|
|
tsType: 'boolean',
|
|||
|
|
options: undefined,
|
|||
|
|
required: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'overflow',
|
|||
|
|
type: 'boolean' as const,
|
|||
|
|
value: true,
|
|||
|
|
category: 'properties' as const,
|
|||
|
|
description: 'Geniş tablolarda yatay kaydırmayı etkinleştirir',
|
|||
|
|
tsType: 'boolean',
|
|||
|
|
options: undefined,
|
|||
|
|
required: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'borderlessRow',
|
|||
|
|
type: 'boolean' as const,
|
|||
|
|
value: false,
|
|||
|
|
category: 'properties' as const,
|
|||
|
|
description: 'Veri satırları arasındaki kenarlıkları kaldırır',
|
|||
|
|
tsType: 'boolean',
|
|||
|
|
options: undefined,
|
|||
|
|
required: false,
|
|||
|
|
},
|
|||
|
|
]
|
|||
|
|
const SELECT_OPTIONS_PROPERTY = {
|
|||
|
|
name: 'options',
|
|||
|
|
type: 'array' as const,
|
|||
|
|
value: [
|
|||
|
|
{ label: 'Seçenek 1', value: '1' },
|
|||
|
|
{ label: 'Seçenek 2', value: '2' },
|
|||
|
|
],
|
|||
|
|
category: 'properties' as const,
|
|||
|
|
description: 'Select items; statik olarak veya endpoint koleksiyonundan beslenebilir',
|
|||
|
|
tsType: 'Array<{ label: string; value: unknown }>',
|
|||
|
|
options: undefined,
|
|||
|
|
required: false,
|
|||
|
|
}
|
|||
|
|
const MENU_ITEMS_PROPERTY = {
|
|||
|
|
...SELECT_OPTIONS_PROPERTY,
|
|||
|
|
name: 'items',
|
|||
|
|
description: 'Menu items; statik olarak veya endpoint koleksiyonundan beslenebilir',
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const normalizeDefinition = (
|
|||
|
|
definition: (typeof CUSTOM_COMPONENTS)[number],
|
|||
|
|
kind: DesignerNodeKind,
|
|||
|
|
toolboxGroup: DesignerComponentDefinition['toolboxGroup'],
|
|||
|
|
): DesignerComponentDefinition => {
|
|||
|
|
const sourceProperties =
|
|||
|
|
definition.name === 'Grid'
|
|||
|
|
? definition.properties.filter((property) => property.name !== 'children')
|
|||
|
|
: definition.properties
|
|||
|
|
let properties =
|
|||
|
|
['Grid', 'Table'].includes(definition.name) &&
|
|||
|
|
!sourceProperties.some((property) => property.name === 'items')
|
|||
|
|
? [COLLECTION_ITEMS_PROPERTY, ...sourceProperties]
|
|||
|
|
: sourceProperties
|
|||
|
|
if (definition.name === 'Grid' && !properties.some((property) => property.name === 'compact')) {
|
|||
|
|
properties = [GRID_COMPACT_PROPERTY, ...properties]
|
|||
|
|
}
|
|||
|
|
if (definition.name === 'Grid') {
|
|||
|
|
properties = [
|
|||
|
|
...GRID_TABLE_BEHAVIOR_PROPERTIES.filter(
|
|||
|
|
(candidate) => !properties.some((property) => property.name === candidate.name),
|
|||
|
|
),
|
|||
|
|
...properties,
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
...definition,
|
|||
|
|
properties,
|
|||
|
|
kind,
|
|||
|
|
toolboxGroup,
|
|||
|
|
acceptsChildren: CONTAINER_NAMES.has(definition.name),
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const fallbackValue = (type: GeneratedProperty['type']) => {
|
|||
|
|
if (type === 'boolean') return false
|
|||
|
|
if (type === 'number') return 0
|
|||
|
|
if (type === 'array') return []
|
|||
|
|
if (type === 'object') return {}
|
|||
|
|
return ''
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const inferUiCategory = (name: string) => {
|
|||
|
|
if (
|
|||
|
|
new Set([
|
|||
|
|
'AutoComplete',
|
|||
|
|
'Checkbox',
|
|||
|
|
'Chips',
|
|||
|
|
'ColorPicker',
|
|||
|
|
'DatePicker',
|
|||
|
|
'Input',
|
|||
|
|
'Knob',
|
|||
|
|
'Radio',
|
|||
|
|
'Rate',
|
|||
|
|
'Select',
|
|||
|
|
'Slider',
|
|||
|
|
'Switcher',
|
|||
|
|
'TimeInput',
|
|||
|
|
'Upload',
|
|||
|
|
]).has(name)
|
|||
|
|
)
|
|||
|
|
return 'form'
|
|||
|
|
if (new Set(['Alert', 'Notification', 'Progress', 'Skeleton', 'Spinner']).has(name))
|
|||
|
|
return 'feedback'
|
|||
|
|
if (new Set(['Breadcrumb', 'Dropdown', 'Menu', 'Pagination', 'Steps', 'Tabs']).has(name))
|
|||
|
|
return 'navigation'
|
|||
|
|
return 'display'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const generatedPropertiesToDesigner = (
|
|||
|
|
generated: GeneratedComponentMetadata,
|
|||
|
|
existingProperties = new Map<string, (typeof CUSTOM_COMPONENTS)[number]['properties'][number]>(),
|
|||
|
|
) =>
|
|||
|
|
generated.properties.map((property) => {
|
|||
|
|
const existing = existingProperties.get(property.name)
|
|||
|
|
return {
|
|||
|
|
name: property.name,
|
|||
|
|
type: property.type,
|
|||
|
|
value:
|
|||
|
|
property.defaultValue !== undefined
|
|||
|
|
? property.defaultValue
|
|||
|
|
: existing?.value !== undefined
|
|||
|
|
? existing.value
|
|||
|
|
: fallbackValue(property.type),
|
|||
|
|
options: property.options || existing?.options,
|
|||
|
|
description: property.tsType,
|
|||
|
|
category:
|
|||
|
|
property.type === 'function'
|
|||
|
|
? ('events' as const)
|
|||
|
|
: existing?.category ||
|
|||
|
|
(property.name === 'className' || property.name === 'style'
|
|||
|
|
? ('styling' as const)
|
|||
|
|
: ('properties' as const)),
|
|||
|
|
tsType: property.tsType,
|
|||
|
|
required: property.required,
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const normalizeUiDefinition = (
|
|||
|
|
definition: (typeof CUSTOM_COMPONENTS)[number],
|
|||
|
|
): DesignerComponentDefinition => {
|
|||
|
|
const generated = generatedMetadata[definition.name]
|
|||
|
|
if (!generated) {
|
|||
|
|
return normalizeDefinition(
|
|||
|
|
definition,
|
|||
|
|
'ui',
|
|||
|
|
DATA_COMPONENT_NAMES.has(definition.name) ? 'data' : 'ui',
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const propertyAliases = UI_PROPERTY_ALIASES[definition.name] || {}
|
|||
|
|
const curatedProperties = definition.properties
|
|||
|
|
.filter(
|
|||
|
|
(property) =>
|
|||
|
|
(definition.name !== 'Select' || property.name !== 'items') &&
|
|||
|
|
(definition.name !== 'Menu' || property.name !== 'variant') &&
|
|||
|
|
(definition.name !== 'Table' || !['columns', 'data'].includes(property.name)),
|
|||
|
|
)
|
|||
|
|
.map((property) => ({
|
|||
|
|
...property,
|
|||
|
|
name: propertyAliases[property.name] || property.name,
|
|||
|
|
}))
|
|||
|
|
const existingProperties = new Map(curatedProperties.map((property) => [property.name, property]))
|
|||
|
|
const generatedProperties = generatedPropertiesToDesigner(generated, existingProperties)
|
|||
|
|
if (
|
|||
|
|
['Select', 'AutoComplete', 'Menu'].includes(definition.name) &&
|
|||
|
|
!generatedProperties.some(
|
|||
|
|
(property) => property.name === (definition.name === 'Menu' ? 'items' : 'options'),
|
|||
|
|
)
|
|||
|
|
) {
|
|||
|
|
generatedProperties.unshift(
|
|||
|
|
definition.name === 'Menu' ? MENU_ITEMS_PROPERTY : SELECT_OPTIONS_PROPERTY,
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
if (
|
|||
|
|
['Grid', 'Table'].includes(definition.name) &&
|
|||
|
|
!generatedProperties.some((property) => property.name === 'items')
|
|||
|
|
) {
|
|||
|
|
generatedProperties.unshift(COLLECTION_ITEMS_PROPERTY)
|
|||
|
|
}
|
|||
|
|
const generatedPropertyNames = new Set(generatedProperties.map((property) => property.name))
|
|||
|
|
const properties = [
|
|||
|
|
...generatedProperties,
|
|||
|
|
// Keep explicitly curated inherited React props such as Input.value and placeholder.
|
|||
|
|
...curatedProperties.filter((property) => !generatedPropertyNames.has(property.name)),
|
|||
|
|
].filter(
|
|||
|
|
(property) =>
|
|||
|
|
!(definition.name === 'Checkbox' && property.name === 'defaultChecked') &&
|
|||
|
|
!(definition.name === 'Menu' && property.name === 'variant'),
|
|||
|
|
)
|
|||
|
|
const primaryEvents = DESIGNER_PRIMARY_EVENTS[definition.name]
|
|||
|
|
return {
|
|||
|
|
...definition,
|
|||
|
|
kind: 'ui',
|
|||
|
|
toolboxGroup: DATA_COMPONENT_NAMES.has(definition.name) ? 'data' : 'ui',
|
|||
|
|
acceptsChildren: CONTAINER_NAMES.has(definition.name),
|
|||
|
|
sourceFile: generated.sourceFile,
|
|||
|
|
interfaceName: generated.interfaceName,
|
|||
|
|
properties: primaryEvents
|
|||
|
|
? properties.filter(
|
|||
|
|
(property) =>
|
|||
|
|
(property.category !== 'events' && property.type !== 'function') ||
|
|||
|
|
primaryEvents.includes(property.name),
|
|||
|
|
)
|
|||
|
|
: properties,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const platformDefinition = (
|
|||
|
|
name: string,
|
|||
|
|
sourceName: string,
|
|||
|
|
description: string,
|
|||
|
|
height = '520px',
|
|||
|
|
): DesignerComponentDefinition => ({
|
|||
|
|
name,
|
|||
|
|
sourceName,
|
|||
|
|
icon: 'PanelsTopLeft',
|
|||
|
|
category: 'platform',
|
|||
|
|
kind: 'platform',
|
|||
|
|
toolboxGroup: 'platform',
|
|||
|
|
description,
|
|||
|
|
properties: [
|
|||
|
|
{ name: 'listFormCode', type: 'string', value: '', category: 'properties', required: true },
|
|||
|
|
{ name: 'height', type: 'string', value: height, category: 'styling' },
|
|||
|
|
],
|
|||
|
|
hooks: [],
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
export const PLATFORM_COMPONENTS: DesignerComponentDefinition[] = [
|
|||
|
|
platformDefinition(
|
|||
|
|
'ListView',
|
|||
|
|
'List',
|
|||
|
|
'Tüm etkin platform görünümlerini /admin/list/:listFormCode ile aynı şekilde yönetir',
|
|||
|
|
),
|
|||
|
|
platformDefinition('DataGridView', 'Grid', 'Sozsoft dinamik veri grid görünümü'),
|
|||
|
|
platformDefinition('TreeView', 'Tree', 'Sozsoft dinamik ağaç görünümü'),
|
|||
|
|
platformDefinition('GanttView', 'GanttView', 'Sozsoft dinamik Gantt görünümü'),
|
|||
|
|
platformDefinition('TodoBoard', 'TodoBoard', 'Sozsoft dinamik iş panosu'),
|
|||
|
|
platformDefinition('CardView', 'CardView', 'Sozsoft dinamik kart görünümü'),
|
|||
|
|
platformDefinition('SchedulerView', 'SchedulerView', 'Sozsoft dinamik planlayıcı görünümü'),
|
|||
|
|
platformDefinition('PivotView', 'Pivot', 'Sozsoft dinamik pivot görünümü'),
|
|||
|
|
platformDefinition('ChartView', 'Chart', 'Sozsoft dinamik grafik görünümü', '420px'),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
export const DESIGNER_EXTRAS: DesignerComponentDefinition[] = [
|
|||
|
|
{
|
|||
|
|
name: 'PageContainer',
|
|||
|
|
icon: 'PanelTop',
|
|||
|
|
category: 'layout',
|
|||
|
|
kind: 'layout',
|
|||
|
|
toolboxGroup: 'layout',
|
|||
|
|
description: 'Intranet içeriği için ortalanmış sayfa alanı',
|
|||
|
|
acceptsChildren: true,
|
|||
|
|
properties: [
|
|||
|
|
{ name: 'maxWidth', type: 'string', value: '1280px', category: 'styling' },
|
|||
|
|
{ name: 'padding', type: 'number', value: 24, category: 'styling' },
|
|||
|
|
{ name: 'gap', type: 'number', value: 16, category: 'styling' },
|
|||
|
|
{ name: 'className', type: 'string', value: '', category: 'styling' },
|
|||
|
|
],
|
|||
|
|
hooks: [],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'TwoColumns',
|
|||
|
|
icon: 'Columns2',
|
|||
|
|
category: 'layout',
|
|||
|
|
kind: 'layout',
|
|||
|
|
toolboxGroup: 'layout',
|
|||
|
|
description: 'Sayfayı iki eşit kolona böler',
|
|||
|
|
acceptsChildren: true,
|
|||
|
|
properties: [
|
|||
|
|
{ name: 'gap', type: 'number', value: 16, category: 'styling' },
|
|||
|
|
{ name: 'className', type: 'string', value: '', category: 'styling' },
|
|||
|
|
],
|
|||
|
|
hooks: [],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'SidebarContent',
|
|||
|
|
icon: 'PanelLeft',
|
|||
|
|
category: 'layout',
|
|||
|
|
kind: 'layout',
|
|||
|
|
toolboxGroup: 'layout',
|
|||
|
|
description: 'Dar sidebar ve geniş içerik alanı',
|
|||
|
|
acceptsChildren: true,
|
|||
|
|
properties: [
|
|||
|
|
{ name: 'sidebarWidth', type: 'string', value: '280px', category: 'styling' },
|
|||
|
|
{ name: 'gap', type: 'number', value: 16, category: 'styling' },
|
|||
|
|
{ name: 'className', type: 'string', value: '', category: 'styling' },
|
|||
|
|
],
|
|||
|
|
hooks: [],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'HeaderContent',
|
|||
|
|
icon: 'PanelTop',
|
|||
|
|
category: 'layout',
|
|||
|
|
kind: 'layout',
|
|||
|
|
toolboxGroup: 'layout',
|
|||
|
|
description: 'Üst alan ve alt içerik için dikey yerleşim',
|
|||
|
|
acceptsChildren: true,
|
|||
|
|
properties: [
|
|||
|
|
{ name: 'gap', type: 'number', value: 16, category: 'styling' },
|
|||
|
|
{ name: 'className', type: 'string', value: '', category: 'styling' },
|
|||
|
|
],
|
|||
|
|
hooks: [],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'FlexRow',
|
|||
|
|
icon: 'Columns3',
|
|||
|
|
category: 'layout',
|
|||
|
|
kind: 'layout',
|
|||
|
|
toolboxGroup: 'layout',
|
|||
|
|
description: 'Yatay ve responsive yerleşim',
|
|||
|
|
acceptsChildren: true,
|
|||
|
|
properties: [
|
|||
|
|
{ name: 'gap', type: 'number', value: 16, category: 'styling' },
|
|||
|
|
{ name: 'wrap', type: 'boolean', value: true, category: 'styling' },
|
|||
|
|
{
|
|||
|
|
name: 'align',
|
|||
|
|
type: 'select',
|
|||
|
|
value: 'stretch',
|
|||
|
|
options: ['stretch', 'start', 'center', 'end'],
|
|||
|
|
category: 'styling',
|
|||
|
|
},
|
|||
|
|
{ name: 'className', type: 'string', value: '', category: 'styling' },
|
|||
|
|
],
|
|||
|
|
hooks: [],
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: 'Spacer',
|
|||
|
|
icon: 'Space',
|
|||
|
|
category: 'layout',
|
|||
|
|
kind: 'layout',
|
|||
|
|
toolboxGroup: 'layout',
|
|||
|
|
description: 'Bileşenler arasında boşluk',
|
|||
|
|
properties: [{ name: 'height', type: 'number', value: 24, category: 'styling' }],
|
|||
|
|
hooks: [],
|
|||
|
|
},
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
export const getDesignerCatalog = (customNames: string[] = []): DesignerComponentDefinition[] => {
|
|||
|
|
const html = HTML_ELEMENTS.filter((definition) => !HTML_UI_DUPLICATES.has(definition.name)).map(
|
|||
|
|
(definition) => normalizeDefinition(definition, 'html', 'html'),
|
|||
|
|
)
|
|||
|
|
const ui = CUSTOM_COMPONENTS.map(normalizeUiDefinition)
|
|||
|
|
const definedUiNames = new Set(CUSTOM_COMPONENTS.map((definition) => definition.name))
|
|||
|
|
const generatedOnlyUi: DesignerComponentDefinition[] = Object.entries(generatedMetadata)
|
|||
|
|
.filter(([name]) => !definedUiNames.has(name))
|
|||
|
|
.map(([name, metadata]) => ({
|
|||
|
|
name,
|
|||
|
|
icon: 'Blocks',
|
|||
|
|
category: inferUiCategory(name),
|
|||
|
|
kind: 'ui',
|
|||
|
|
toolboxGroup: DATA_COMPONENT_NAMES.has(name) ? 'data' : 'ui',
|
|||
|
|
description: `${metadata.interfaceName} sözleşmesini kullanan Sozsoft UI component’i`,
|
|||
|
|
sourceFile: metadata.sourceFile,
|
|||
|
|
interfaceName: metadata.interfaceName,
|
|||
|
|
acceptsChildren: CONTAINER_NAMES.has(name),
|
|||
|
|
properties: generatedPropertiesToDesigner(metadata),
|
|||
|
|
hooks: [],
|
|||
|
|
}))
|
|||
|
|
const custom: DesignerComponentDefinition[] = customNames.map((name) => ({
|
|||
|
|
name,
|
|||
|
|
icon: 'Blocks',
|
|||
|
|
category: 'custom',
|
|||
|
|
kind: 'custom',
|
|||
|
|
toolboxGroup: 'custom',
|
|||
|
|
description: 'Veritabanındaki yeniden kullanılabilir bileşen',
|
|||
|
|
acceptsChildren: true,
|
|||
|
|
properties: [{ name: 'className', type: 'string', value: '', category: 'styling' }],
|
|||
|
|
hooks: [],
|
|||
|
|
}))
|
|||
|
|
|
|||
|
|
return [...DESIGNER_EXTRAS, ...PLATFORM_COMPONENTS, ...html, ...ui, ...generatedOnlyUi, ...custom]
|
|||
|
|
}
|