userface
Version:
Universal Data-Driven UI Engine with live data, validation, and multi-platform support
140 lines (139 loc) • 5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderReactNative = exports.RenderReactNative = void 0;
// Условные импорты для поддержки Node.js
let React = null;
let createElement = null;
// Проверяем доступность React Native
if (typeof window !== 'undefined' && window.React) {
React = window.React;
createElement = React.createElement;
}
else if (typeof require !== 'undefined') {
try {
React = require('react');
createElement = React.createElement;
}
catch (error) {
console.warn('React not available in Node.js environment');
}
}
class RenderReactNative {
constructor(options = {}) {
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.options = {
enableStyleConversion: true,
enableEventConversion: true,
...options
};
}
render(userFace, schema) {
if (!React) {
throw new Error('React is not available for React Native rendering');
}
try {
const { component, ...props } = userFace;
// Конвертируем пропсы для React Native
const convertedProps = this.convertProps(props);
// Создаем React Native элемент
return createElement(component, convertedProps);
}
catch (error) {
console.error('React Native render error:', error);
throw error;
}
}
convertProps(props) {
const converted = {};
Object.entries(props).forEach(([key, value]) => {
// Конвертируем события
if (this.options.enableEventConversion && key === 'onClick') {
converted.onPress = value;
}
else if (this.options.enableEventConversion && key === 'onChange') {
converted.onChangeText = value;
}
else if (this.options.enableEventConversion && key === 'onSubmit') {
converted.onSubmitEditing = value;
}
else {
// Конвертируем стили
if (this.options.enableStyleConversion && key === 'className') {
converted.style = this.convertClassNameToStyle(value);
}
else if (this.options.enableStyleConversion && key === 'style' && typeof value === 'string') {
converted.style = this.convertCssToStyle(value);
}
else {
converted[key] = value;
}
}
});
return converted;
}
convertClassNameToStyle(className) {
// Простая конвертация CSS классов в React Native стили
const styles = {};
if (className.includes('primary')) {
styles.backgroundColor = '#007AFF';
}
if (className.includes('secondary')) {
styles.backgroundColor = '#5856D6';
}
if (className.includes('success')) {
styles.backgroundColor = '#34C759';
}
if (className.includes('danger')) {
styles.backgroundColor = '#FF3B30';
}
if (className.includes('warning')) {
styles.backgroundColor = '#FF9500';
}
return styles;
}
convertCssToStyle(css) {
// Простая конвертация CSS в React Native стили
const styles = {};
// Цвета
const colorMatch = css.match(/color:\s*([^;]+)/);
if (colorMatch) {
styles.color = colorMatch[1].trim();
}
// Фон
const bgMatch = css.match(/background(?:-color)?:\s*([^;]+)/);
if (bgMatch) {
styles.backgroundColor = bgMatch[1].trim();
}
// Размеры
const widthMatch = css.match(/width:\s*([^;]+)/);
if (widthMatch) {
styles.width = widthMatch[1].trim();
}
const heightMatch = css.match(/height:\s*([^;]+)/);
if (heightMatch) {
styles.height = heightMatch[1].trim();
}
// Отступы
const paddingMatch = css.match(/padding:\s*([^;]+)/);
if (paddingMatch) {
styles.padding = paddingMatch[1].trim();
}
const marginMatch = css.match(/margin:\s*([^;]+)/);
if (marginMatch) {
styles.margin = marginMatch[1].trim();
}
return styles;
}
}
exports.RenderReactNative = RenderReactNative;
// Экспортируем функцию рендеринга
const renderReactNative = (userFace, schema) => {
const renderer = new RenderReactNative();
return renderer.render(userFace, schema);
};
exports.renderReactNative = renderReactNative;