🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

dyvix-ui

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dyvix-ui - npm Package Compare versions

Comparing version
0.2.2
to
0.2.4
+83
src/components/button/button.jsx
import React from 'react';
import './dependencies/style/style.css';
import { EvaluateFailure, GaurdStatus } from '../../utils/DyvixGuard';
import gsap from 'gsap';
import { useGSAP } from '@gsap/react';
import { Validatebtn } from './validation';
import Version from '../../../package.json';
function DyvixButton({
children = 'Click Me',
animation = 'fade',
className = '',
theme = '!/',
background,
color,
onClick,
style,
...rest
}) {
const btnRef = React.useRef(null);
const [configs, SetConfig] = React.useState({});
const instanceId = React.useId();
const currentTheme = configs['theme'];
const currentAnimation = animation
? configs['animation']
: null;
function handleClick() {
if (typeof onClick === 'function') {
onClick();
}
}
className = `dyvix-button${currentTheme ? ` ${currentTheme.class}` : ''}${className !== '' ? ` ${className}` : ''}`;
React.useEffect(()=>{
async function validate() {
const validator = await Validatebtn(animation, theme, SetConfig, instanceId);
if (validator.status === GaurdStatus.Error) {
return EvaluateFailure(validator.error, validator.status);
}
}
validate();
return () => {
const key = `DYVIX_${Version['version']}_Button_theme_${instanceId}`;
const ele = document.getElementById(key);
if (ele) ele.remove();
};
},[theme, animation]);
useGSAP(() => {
if (!btnRef.current || !currentAnimation) return;
gsap.fromTo(btnRef.current, currentAnimation.from, {
...currentAnimation.to,
duration: currentAnimation['default-duration'],
ease: currentAnimation.ease
});
}, [currentAnimation]);
const props = {
className: className,
disabled: rest.disabled,
style: {
...(background && { background: background }),
...(color && { color: color }),
...style
}
};
return (
<div className="dyvix-btn-wrapper" ref={btnRef} {...rest}>
<button {...props} onClick={handleClick}>
{children}
</button>
</div>
);
}
export default DyvixButton;
.dyvix-btn-wrapper {
width: fit-content;
height: fit-content;
}
.dyvix-button {
position: relative;
background: #0d0d0f;
border: 1px solid rgba(255, 255, 255, 0.08);
padding: 10px 22px;
color: #d3e9ff;
border-radius: 6px;
cursor: pointer;
overflow: hidden;
font-weight: 500;
font-family: 'Geist', sans-serif;
letter-spacing: -0.02em;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.05);
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.dyvix-button:hover {
background: #161618;
border-color: rgba(255, 255, 255, 0.2);
color: #fff;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
.dyvix-button:active {
background: #161618;
border-color: rgb(255, 255, 255);
transform: translateY(2px);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
}
.dyvix-button-lens {
background: radial-gradient(circle, #000000 0%, #1a1a1a 100%);
box-shadow: 0 0 30px #b903e2;
-webkit-box-shadow: 0 0 30px #b903e2;
-moz-box-shadow: 0 0 30px #b903e2;
border: #450343 3px double;
border-radius: 10rem;
transition: all 0.3s ease-in-out;
}
.dyvix-button-lens:hover {
border: #000000 3px double;
transform: scale(1.09);
}
.dyvix-button-lens:active {
border: #000000 5px double;
transform: scale(1.09);
}
.dyvix-button-neon {
background: #4deeea;
background: radial-gradient(
circle,
rgba(77, 238, 234, 1) 0%,
rgba(112, 186, 239, 1) 43%,
rgba(240, 0, 255, 1) 100%
);
box-shadow: 0px 0px 20px 2px rgba(252, 46, 255, 0.4);
border: none;
color: white;
font-weight: bold;
border-radius: 4rem;
transition:
transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
border-radius 0.2s ease,
box-shadow 0.3s ease,
background 0.3s ease;
}
.dyvix-button-neon:hover {
border-radius: 2rem;
transform: scale(1.02);
background: #1c4241;
background: radial-gradient(
circle,
rgba(112, 186, 239, 1) 0%,
rgba(77, 238, 234, 1) 43%,
rgba(240, 0, 255, 1) 90%
);
box-shadow: 0px 0px 56px 4px rgba(252,61,255,1);
}
.dyvix-button-neon:active {
background-color: #5eeeec;
background: radial-gradient(
circle,
rgb(10, 152, 150) 0%,
rgb(110, 167, 207) 43%,
rgb(84, 4, 90) 100%
);
transform: scale(0.97);
}
.dyvix-button-aurora {
background: #14e81e;
background: linear-gradient(
99deg,
rgba(20, 232, 30, 1) 0%,
rgba(0, 234, 141, 1) 21%,
rgba(1, 177, 179, 1) 46%,
rgba(1, 126, 213, 1) 67%,
rgba(181, 61, 255, 1) 100%
);
border-radius: 3rem;
border: 1px solid rgba(165, 164, 164, 0.1);
box-shadow: 0px 0px 75px 0px rgba(1, 176, 179, 0.9);
transition:
box-shadow 0.3s ease-in-out,
transform 0.3s ease-in-out,
border-radius 0.2s ease-in-out,
background-color 0.1s ease-in-out;
}
.dyvix-button-aurora:hover {
border-radius: 5rem;
background: #14e81e;
background: linear-gradient(
99deg,
rgb(93, 189, 98) 0%,
rgba(0, 234, 141, 1) 21%,
rgba(1, 177, 179, 1) 46%,
rgb(100, 187, 250) 67%,
rgba(181, 61, 255, 1) 100%
);
transform: scale(1.04);
box-shadow: 0px 0px 50px 10px rgba(1, 176, 179, 0.8);
}
.dyvix-button-aurora:active {
border-radius: 5rem;
background: linear-gradient(
99deg,
rgb(165, 255, 169) 0%,
rgb(166, 248, 215) 21%,
rgb(189, 250, 251) 46%,
#b7ddf8 67%,
rgb(227, 181, 255) 100%
);
transform: scale(0.98);
filter: brightness(1.2);
box-shadow: 0px 0px 5px 8px rgba(1, 176, 179, 1);
}
[
{
"theme": "Singularity",
"class": "dyvix-button-lens",
"default-animation": "bubble"
},
{
"theme": "Neon",
"class": "dyvix-button-neon",
"default-animation": "pulse"
},
{
"theme": "Aurora",
"class": "dyvix-button-aurora",
"default-animation": "aurora"
}
]
import {
EvaluateFailure,
GaurdStatus,
allowsNull
} from '../../utils/DyvixGuard';
import { ValidatAndLoadJSON } from '../../utils/Smart Json Caching/SJCManager';
const component = "Button"
const CacheMapping = {
theme: {
jsonpath: '../../components/button/dependencies/themes.json',
csspath: '../../components/button/dependencies/style/themes.css'
},
animation: {
jsonpath: '../../components/animations.json',
csspath: null
}
};
export async function Validatebtn(animation, theme, callback, instance) {
const normalizedAnimation = animation?.trim().toLowerCase();
const normalizedTheme =
theme?.trim().charAt(0).toUpperCase() + theme.trim().slice(1);
const [isAnimation, isTheme] = await Promise.all([
ValidatAndLoadJSON(
CacheMapping,
normalizedAnimation,
callback,
'animation',
component
),
ValidatAndLoadJSON(
CacheMapping,
normalizedTheme,
callback,
'theme',
component,
instance
)
]);
if (
normalizedAnimation !== null &&
!isAnimation.status
) {
return {
status: GaurdStatus.Error,
error: 'Please provide a valid animation.'
};
}
if (normalizedTheme !== '!/' && !isTheme.status) {
return {
status: GaurdStatus.Error,
error: 'Please provide a valid theme.'
};
}
return { status: GaurdStatus.Success };
}
import { EvaluateFailure, GaurdStatus } from '../DyvixGuard';
import Version from '../../../package.json';
export const CACHETYPE = { CSS: 'css', Default: 'default' };
const VERSION = Version['version'];
export async function SJCManager(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey = '',
instance
) {
let result = null;
const key = generateCacheKey(component, utility);
result = await cachelayerOne(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey,
key
);
if (result === null)
result = await cachelayerTwo(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey,
key
);
if (result === null)
result = await cachelayerThree(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey,
key
);
if (result === null) return result;
if (result?.CSS !== undefined && result?.CSS !== null) {
InjectCSS(result.CSS, key, instance);
}
return result.JSON;
}
async function cachelayerThree(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey,
key
) {
let JsonArray = null;
let rawCSS = null;
let cssResult = null;
let jsonResult = null;
let keys = [key + '_L1', key + '_L2', key + '_L3'];
if (localStorage.getItem(keys[2])) {
const cachedData = JSON.parse(localStorage.getItem(keys[2]));
JsonArray = cachedData.JSON;
rawCSS = cachedData.CSS;
} else {
const rawJSONText = await extractFile(jsonpath);
JsonArray = JSON.parse(rawJSONText);
if (type === CACHETYPE.CSS) {
rawCSS = await extractFile(csspath);
}
}
jsonResult = JsonArray.find((e) => e[utility] === jsonKey);
let value = {
...(rawCSS !== null && { CSS: rawCSS }),
...(JsonArray !== null && { JSON: JsonArray })
};
localStorage.setItem(keys[2], JSON.stringify(value));
if (!jsonResult) {
return null;
}
cssResult = await extractCSSClass(jsonResult[jsonclasskey], null, rawCSS);
let result = {
...(cssResult !== null && { CSS: cssResult }),
...(jsonResult !== null && { JSON: jsonResult })
};
const rawL2Cache = localStorage.getItem(keys[1]);
const existingL2cache = rawL2Cache ? JSON.parse(rawL2Cache) : {};
existingL2cache[jsonKey] = result;
localStorage.setItem(keys[1], JSON.stringify(existingL2cache));
const rawL1Cache = localStorage.getItem(keys[0]);
const existingL1cache = rawL1Cache ? JSON.parse(rawL1Cache) : {};
existingL1cache[jsonKey] = {
...result,
expires: Date.now() + 30 * 24 * 60 * 60 * 1000
};
localStorage.setItem(keys[0], JSON.stringify(existingL1cache));
return result;
}
// Caches only the config ever used
async function cachelayerTwo(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey,
key
) {
let cssResult = null;
let jsonResult = null;
key += '_L2';
let cachedData = null;
if (!localStorage.getItem(key)) return null;
cachedData = JSON.parse(localStorage.getItem(key));
const entry = cachedData[jsonKey];
if (!entry) return null;
jsonResult = entry.JSON;
cssResult = entry.CSS;
let result = {
...(cssResult !== null && { CSS: cssResult }),
...(jsonResult !== null && { JSON: jsonResult })
};
return result;
}
// Caches only the config ever used in a month. Limited to 10.
async function cachelayerOne(
jsonpath,
csspath,
type,
component,
utility,
jsonKey,
jsonclasskey,
key
) {
let cssResult = null;
let jsonResult = null;
key += '_L1';
let cachedData = null;
if (!localStorage.getItem(key)) return null;
cachedData = JSON.parse(localStorage.getItem(key));
Object.keys(cachedData).forEach((element) => {
const expires_at = cachedData[element].expires;
if (expires_at && expires_at < Date.now()) {
delete cachedData[element];
}
});
localStorage.setItem(key, JSON.stringify(cachedData));
const entry = cachedData[jsonKey];
if (!entry) return null;
jsonResult = entry.JSON;
cssResult = entry.CSS;
let result = {
...(cssResult !== null && { CSS: cssResult }),
...(jsonResult !== null && { JSON: jsonResult })
};
return result;
}
async function extractFile(path) {
try {
const module = await import(/* @vite-ignore */ `${path}?raw`);
return module.default || module;
} catch (error) {
console.log('DyvixUI Sys error');
return null;
}
}
function generateCacheKey(component, utility) {
const key = `DYVIX_${VERSION}_${component}_${utility}`;
return key;
}
async function extractCSSClass(classname, Csspath = null, cssblock = null) {
let rawCSS = null;
if (Csspath !== null) {
try {
const module = await import(/* @vite-ignore */ `${Csspath}?raw`);
rawCSS = module.default || module;
} catch (error) {
console.log('DyvixUI Sys error');
}
} else if (cssblock !== null) {
rawCSS = cssblock;
} else {
return null;
}
const lines = rawCSS.replace(/\s+/g, ' ').trim().split('}');
let block = '';
const matches = lines
.filter((val) => val.trim().includes(classname))
.map((block) => block.trim() + '}');
block = matches.join('\n\n');
return block;
}
function InjectCSS(csstext, Key, instance) {
if (instance === null) return false;
Key = Key + `_${instance}`;
const existing = document.getElementById(Key);
if (existing) {
if (existing.textContent === csstext) return true;
existing.textContent = csstext;
return true;
}
const style = document.createElement('style');
style.id = Key;
style.type = 'text/css';
style.textContent = csstext;
document.head.appendChild(style);
return true;
}
export async function ValidatAndLoadJSON(
cacheMap,
key,
callback,
utilityKey,
component,
instance = null
) {
if (!cacheMap) return false;
const mapper = cacheMap[utilityKey];
let type = mapper?.csspath !== null ? CACHETYPE.CSS : CACHETYPE.Default;
const res = await SJCManager(
mapper['jsonpath'],
mapper['csspath'],
type,
component,
utilityKey,
key,
'class',
instance
);
callback((prev) => {
if (prev[utilityKey] === res) return prev;
return { ...prev, [utilityKey]: res };
});
return { config: { [utilityKey]: res }, status: res !== null };
}
+14
-6
{
"name": "dyvix-ui",
"version": "0.2.2",
"version": "0.2.4",
"description": "Dyvix is an open source, modern, config-driven, animated component UI library. Beautiful by default, customizable by design.",

@@ -8,5 +8,8 @@ "main": "src/index.jsx",

"license": "MIT",
"workspaces": [
"devbench"
],
"peerDependencies": {
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
"react": "^19.2.4",
"react-dom": "^19.2.4"
},

@@ -16,5 +19,5 @@ "devDependencies": {

"prettier": "^3.8.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"vite": "^8.0.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"vite": "8.0.8",
"vitepress": "^1.6.4"

@@ -36,2 +39,4 @@ },

"scripts": {
"dev": "npm run dev -w devbench",
"bench:install": "npm install -w devbench",
"format": "prettier --write . --ignore-path .gitignore",

@@ -43,3 +48,6 @@ "prebuild": "npm run dyvix:build",

"dyvix:build": "node dev-engine/scripts/generate-constants.js"
},
"overrides": {
"esbuild": "^0.25.0"
}
}

@@ -1,6 +0,5 @@

<h1 align="center">
<img width="100" height="100" alt="Dyvix logo" src="https://raw.githubusercontent.com/younisdev/dyvix-ui/main/src/static/logo.png" />
<br />
Dyvix UI
</h1>
<div align="center">
<img src="https://raw.githubusercontent.com/younisdev/dyvix-ui/main/src/static/logo.png" width="100" height="100" alt="Dyvix UI Logo" />
<h1>Dyvix UI</h1>
</div>
<h4 align="center">

@@ -7,0 +6,0 @@ Dyvix is an open source, modern, config-driven, animated component UI library. Beautiful by default, customizable by design.

@@ -164,3 +164,3 @@ .dyvix-modal-wrapper {

position: relative;
padding-bottom: 10px;
padding-bottom: 1rem;
align-items: center;

@@ -170,2 +170,6 @@ min-height: 40px;

.dyvix-error-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.75rem;
position: absolute;

@@ -172,0 +176,0 @@ bottom: -0.3rem;

@@ -19,3 +19,3 @@ export function ExecuteValidator(value, validators) {

export function ExecuteRegex(value, Rgx, errorMsg = 'Invalid format') {
console.log(Rgx)
console.log(Rgx);
const Regex = new RegExp(Rgx);

@@ -29,4 +29,3 @@ return { status: Regex.test(value), error: errorMsg };

return true;
}
catch(e) {
} catch (e) {
return false;

@@ -33,0 +32,0 @@ }

@@ -0,11 +1,3 @@

import { validType, eleData, validRules } from './modal';
import {
validType,
vaildThemes,
validAnimations,
eleData,
validPreset,
validRules
} from './modal';
import presetData from './dependencies/presets.json';
import {
EvaluateFailure,

@@ -16,3 +8,23 @@ GaurdStatus,

import { isValidRegex } from './dependencies/validator/validators';
import { ValidatAndLoadJSON } from '../../utils/Smart Json Caching/SJCManager';
const CacheMapping = {
theme: {
jsonpath: '../../components/modal/dependencies/themes.json',
csspath: '../../components/modal/dependencies/style/themes.css'
},
animation: {
jsonpath: '../../components/animations.json',
csspath: null
},
preset: {
jsonpath: '../../components/modal/dependencies/presets.json',
csspath: null
},
types: {
jsonpath: '../../components/modal/dependencies/types.json',
csspath: null
}
};
const component = 'Modal';
const defaultElement = {

@@ -39,4 +51,5 @@ type: '!/',

];
let config = null;
export function SerializeData(
export async function SerializeData(
title,

@@ -50,5 +63,7 @@ type,

Class,
onSubmit
onSubmit,
callback,
instance
) {
const validator = ValidateInput(
const validator = await ValidateInput(
title,

@@ -62,3 +77,5 @@ type,

Class,
onSubmit
onSubmit,
callback,
instance
);

@@ -69,10 +86,6 @@

}
elements =
preset !== '!/'
? presetData.find(
(e) => e.preset.trim().toLowerCase() === preset.trim().toLowerCase()
)?.['fields'] || elements
: elements;
const presetData = config.find((item) => item.preset);
const finalElements = preset !== '!/' ? presetData?.preset?.fields : elements;
const normalizedElements = normalizeElements(
elements.map((ele) => ({ ...defaultElement, ...ele }))
finalElements?.map((ele) => ({ ...defaultElement, ...ele }))
);

@@ -84,6 +97,5 @@ const eleValidator = validateElements(normalizedElements);

}
return normalizedElements;
}
export function ValidateInput(
export async function ValidateInput(
title,

@@ -97,6 +109,27 @@ type,

Class,
onSubmit
onSubmit,
callback,
instance
) {
const [isAnimation, isTheme, isPreset] = await Promise.all([
ValidatAndLoadJSON(
CacheMapping,
animation,
callback,
'animation',
component
),
ValidatAndLoadJSON(
CacheMapping,
theme,
callback,
'theme',
component,
instance
),
ValidatAndLoadJSON(CacheMapping, preset, callback, 'preset', component)
]);
if (preset !== '!/') {
if (!validPreset.includes(preset)) {
if (!isPreset.status) {
return {

@@ -109,7 +142,3 @@ status: GaurdStatus.Error,

if (
animation !== '!/' &&
!validAnimations.includes(animation) &&
allowsNull(animation)
) {
if (animation !== '!/' && !isAnimation.status && allowsNull(animation)) {
return {

@@ -120,3 +149,3 @@ status: GaurdStatus.Error,

}
if (!vaildThemes.includes(theme)) {
if (!isTheme.status) {
return {

@@ -127,2 +156,5 @@ status: GaurdStatus.Error,

}
config = [isTheme.config, isAnimation.config, isPreset.config];
if (onSubmit !== undefined && typeof onSubmit !== 'function') {

@@ -153,6 +185,6 @@ return {

}
function validateElements(elements) {
export function validateElements(elements) {
const MAX_ROWS = 9;
if (elements.length > MAX_ROWS) {
if (elements?.length > MAX_ROWS) {
console.warn(

@@ -162,3 +194,3 @@ `[Dyvix UI] Maximum of ${MAX_ROWS} rows allowed. Extra rows will be ignored.`

elements.splice(MAX_ROWS); // trims array IN-PLACE
elements?.splice(MAX_ROWS); // trims array IN-PLACE
}

@@ -240,10 +272,10 @@ for (const element of elements) {

}
// Handels Validator engine validator
// Supports regex
const rules = Array.isArray(element.validation)
? element.validation
: [element.validation];
const rules = Array.isArray(element.validation)
? element.validation
: [element.validation];
if(rules.length > element.amount) {
if (rules.length > element.amount) {
return {

@@ -255,13 +287,10 @@ status: GaurdStatus.Error,

for(const rule of rules)
{
if (rule === "!/") break;
for (const rule of rules) {
if (rule === '!/') break;
if (!rule || typeof rule !== 'string') continue;
if (rule.startsWith('$R'))
{
if (rule.startsWith('$R')) {
const [pattern, customError] = rule.slice(2).split('|');
if(!isValidRegex(pattern))
{
if (!isValidRegex(pattern)) {
return {

@@ -272,6 +301,3 @@ status: GaurdStatus.Error,

}
}
else if (!validRules.includes(rule))
{
} else if (!validRules.includes(rule)) {
return {

@@ -282,3 +308,2 @@ status: GaurdStatus.Error,

}
}

@@ -299,4 +324,4 @@ }

}
function normalizeElements(elements) {
return elements.map((ele) => ({
export function normalizeElements(elements) {
return elements?.map((ele) => ({
...ele,

@@ -303,0 +328,0 @@ placeholder:

import elementsData from './dependencies/elements.json';
import themesData from './dependencies/themes.json';
import DynamicSelect from '../select/SelectCompiler';
import animationsData from '../animations.json';
import validationData from './dependencies/validator/validators.json';
import typesData from './dependencies/types.json';
import presetData from './dependencies/presets.json';
import './dependencies/style/elements.css';
import './dependencies/style/themes.css';
import * as validatorsFunctions from './dependencies/validator/validators';

@@ -15,11 +11,18 @@ import {

} from './dependencies/validator/validators';
import {
SJCManager,
CACHETYPE
} from '../../utils/Smart Json Caching/SJCManager';
import React from 'react';
import { useGSAP } from '@gsap/react';
import gsap from 'gsap';
import { SerializeData } from './InputValidation';
import {
SerializeData,
normalizeElements,
validateElements
} from './InputValidation';
import { GaurdStatus } from '../../utils/DyvixGuard';
import Version from '../../../package.json';
export const vaildThemes = themesData.map((e) => e.theme);
export const validType = typesData.map((e) => e.type);
export const validAnimations = animationsData.map((e) => e.animation);
export const validPreset = presetData.map((e) => e.preset);
export const validRules = validationData.map((e) => e.preset);

@@ -60,15 +63,6 @@

const [status, SetStatus] = React.useState('entering');
const fields = SerializeData(
title,
type,
elements,
preset,
theme,
animation,
Id,
Class,
onSubmit
);
const [configs, SetConfig] = React.useState({});
const [fields, SetFields] = React.useState(null);
const instanceId = React.useId();
const modalRef = React.useRef(null);
function handleInputChange(name, value) {

@@ -126,25 +120,12 @@ const validation = handleValidation();

if (fields === null) {
return null;
}
const currentType = typesData.find(
(e) => e.type.trim().toLowerCase() === type.trim().toLowerCase()
);
const currentTheme = themesData.find(
(e) => e.theme.trim().toLowerCase() === theme.trim().toLowerCase()
);
const currentTheme = configs['theme'];
const animationQuery =
animation === '!/' ? currentTheme['default-animation'] : animation;
const currentAnimation = animation
? animationsData.find(
(e) =>
e.animation.trim().toLowerCase() ===
animationQuery.trim().toLowerCase()
)
: null;
const currentPreset = presetData.find(
(e) => e.preset.trim().toLowerCase() === preset.trim().toLowerCase()
);
animation === '!/' ? currentTheme?.['default-animation'] : animation;
const currentAnimation = configs['animation']; // add default animation for this new update
const currentPreset = configs['preset'];
const serilaizedClass =
Class + ` ${currentTheme.class}` + ` ${currentType.class}`;
Class + ` ${currentTheme?.class}` + ` ${currentType.class}`;
// Dynamicily calculate modal sizing and position

@@ -162,5 +143,5 @@ const heightMap = {

};
let idealSize = heightMap[fields.length] || '26rem';
const geometryBuffer = currentTheme['radiused']
? (2.5 * fields.length) / 3
let idealSize = heightMap[fields?.length] || '26rem';
const geometryBuffer = currentTheme?.radiused
? (2.5 * fields?.length) / 3
: 0;

@@ -171,11 +152,42 @@ idealSize = `calc(${idealSize} + ${geometryBuffer}rem)`;

const dynamicWidth = `min(${idealSize}, 95vw, 95vh)`;
const isCentered = fields.length <= 5;
const dynamicMargin = isCentered ? '15vh auto' : '1.5rem auto';
const isCentered = fields?.length <= 5;
const dynamicMargin = isCentered ? '12vh auto' : '1.5rem auto';
const modalStyles = {
height: dynamicHeight,
width: dynamicWidth,
margin: dynamicMargin,
transition: 'all 0.3s ease-out'
};
if (currentPreset) {
title = title !== '!/' ? title : currentPreset['default-title'];
}
React.useEffect(() => {
async function GetFields() {
const data = await SerializeData(
title,
type,
elements,
preset,
theme,
animation,
Id,
Class,
onSubmit,
SetConfig,
instanceId
);
SetFields(data);
}
GetFields();
return () => {
const key = `DYVIX_${Version['version']}_Modal_theme_${instanceId}`;
const ele = document.getElementById(key);
if (ele) ele.remove();
};
}, [theme, preset, elements, animation, title]);
React.useEffect(() => {
fields.forEach((field) => {
fields?.forEach((field) => {
field.name.forEach((name) => {

@@ -185,3 +197,3 @@ SetData((prev) => ({ ...prev, [name]: null }));

});
}, []);
}, [fields]);

@@ -231,7 +243,3 @@ // Auto-focus for the first input when modal opens

ref={modalRef}
style={{
height: dynamicHeight,
width: dynamicWidth,
position: 'relative'
}}
style={modalStyles}
>

@@ -244,4 +252,4 @@ {currentType.closable && (

style={{
top: currentTheme.radiused ? '2rem' : '1rem',
right: currentTheme.radiused ? '9rem' : '1rem'
top: currentTheme?.radiused ? '2rem' : '1rem',
right: currentTheme?.radiused ? '9rem' : '1rem'
}}

@@ -253,3 +261,3 @@ >

<h3 id="modal-header">{title}</h3>
{fields.map((field, i) => {
{fields?.map((field, i) => {
const elementDef =

@@ -256,0 +264,0 @@ elementsData.find((e) => e.element === field.type) ||

@@ -6,1 +6,2 @@ export { default as Modal } from './components/modal/modal';

export { default as dyvixToast } from './components/toast/bus';
export { default as DyvixButton } from './components/button/button';