🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

dyvix-ui

Package Overview
Dependencies
Maintainers
1
Versions
22
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.3.5
to
0.3.6
+9
src/components/select/dependencies/themes.json
[
{
"theme": "Singularity",
"class": "dyvix-select-lens",
"input-class": "dyvix-select-input-lens",
"dropdown-class": "dyvix-select-dropdown-lens",
"default-animation": "bubble"
}
]
import {
EvaluateFailure,
GuardStatus,
allowsNull
} from '../../utils/DyvixGuard';
import { ValidatAndLoadJSON } from '../../utils/Smart Json Caching/SJCManager';
const component = 'Select';
const CacheMapping = {
animation: {
jsonpath: '../../components/animations.json',
csspath: null
},
theme: {
jsonpath: '../../components/select/dependencies/themes.json',
csspath: '../../components/select/dependencies/style/themes.css'
}
};
const supportedTypes = ['select', 'autocomplete'];
export async function ValidateSelect(
elements,
type,
animation,
theme,
callback,
instance
) {
let normalizedAnimation = animation?.trim().toLowerCase();
const normalizedTheme =
theme?.trim().charAt(0).toUpperCase() + theme.trim().slice(1);
const isTheme = await ValidatAndLoadJSON(
CacheMapping,
normalizedTheme,
callback,
'theme',
component,
instance
);
if (normalizedAnimation === '!/' && isTheme?.config?.theme) {
normalizedAnimation = isTheme?.config?.theme['default-animation'];
}
const isAnimation = await ValidatAndLoadJSON(
CacheMapping,
normalizedAnimation,
callback,
'animation',
component
);
if (!isAnimation.status && !allowsNull(normalizedAnimation)) {
return {
status: GuardStatus.Error,
error: 'Please provide a valid animation.'
};
}
if (!Array.isArray(elements)) {
return {
status: GuardStatus.Error,
error: 'Elements should be included as an array.'
};
}
if (!supportedTypes.includes(type)) {
return {
status: GuardStatus.Error,
error: 'Please provide a valid select type.'
};
}
return { status: GuardStatus.Success };
}
+6
-0

@@ -32,1 +32,7 @@ # Contributors

- [@LuisOrlando-code](https://github.com/LuisOrlando-code)
- [@hakkiai](https://github.com/hakkiai)
- [@Pranay-Kamble](https://github.com/Pranay-Kamble)
- [@LateeshaNarnolia104](https://github.com/LateeshaNarnolia104)
- [@TaH00R](https://github.com/TaH00R)
- [@arishaix](https://github.com/arishaix)
- [@uttam12331](https://github.com/uttam12331)
+1
-1
{
"name": "dyvix-ui",
"version": "0.3.5",
"version": "0.3.6",
"description": "Dyvix is an open source, modern, config-driven, animated component UI library. Beautiful by default, customizable by design.",

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

@@ -155,1 +155,40 @@ .dyvix-label-lens {

}
.dyvix-label-neon {
font-family: 'Geist';
color: #4deeea;
text-shadow:
0 0 8px rgba(77, 238, 234, 0.7),
0 0 20px rgba(240, 0, 255, 0.45);
transition:
color 0.3s ease-in-out,
text-shadow 0.3s ease-in-out,
transform 0.3s ease-in-out;
}
.dyvix-label-neon:hover {
color: #f000ff;
text-shadow:
0 0 12px rgba(77, 238, 234, 0.9),
0 0 30px rgba(240, 0, 255, 0.75);
transform: translateY(-1px);
}
.dyvix-label-aurora {
font-family: 'Geist';
color: #00ea8d;
text-shadow:
0 0 8px rgba(0, 234, 141, 0.55),
0 0 22px rgba(181, 61, 255, 0.35);
transition:
color 0.3s ease-in-out,
text-shadow 0.3s ease-in-out,
transform 0.3s ease-in-out;
}
.dyvix-label-aurora:hover {
color: #b53dff;
text-shadow:
0 0 12px rgba(0, 234, 141, 0.75),
0 0 34px rgba(181, 61, 255, 0.55);
transform: translateY(-1px);
}

@@ -46,3 +46,13 @@ [

"default-animation": "glide"
},
{
"theme": "Neon",
"class": "dyvix-label-neon",
"default-animation": "pulse"
},
{
"theme": "Aurora",
"class": "dyvix-label-aurora",
"default-animation": "aurora"
}
]

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

}
.modal:not([class*='dyvix-modal-']) .modal-element::placeholder{
.modal:not([class*='dyvix-modal-']) .modal-element::placeholder {
color: #1a1a1a !important;

@@ -60,0 +60,0 @@ }

@@ -159,4 +159,3 @@ import elementsData from './dependencies/elements.json';

const newErrors = handleValidation(data);
const allow =
Object.values(newErrors).every((val) => val === null);
const allow = Object.values(newErrors).every((val) => val === null);
if (typeof onSubmit === 'function' && allow) {

@@ -173,2 +172,18 @@ onSubmit(data);

const currentPreset = configs['preset'];
const themeTextStyle = {
color: currentTheme?.['text-color']
};
const themeInputStyle = {
...(currentTheme?.['input-background'] && {
background: currentTheme['input-background']
}),
...(currentTheme?.['input-color'] && {
color: currentTheme['input-color']
}),
...(currentTheme?.['input-border'] && {
border: currentTheme['input-border']
})
};
const serilaizedclassName =

@@ -324,3 +339,5 @@ className +

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

@@ -394,7 +411,10 @@ const elementDef =

fontSize: fontSize,
fontWeight: fontWeight
fontWeight: fontWeight,
...(elementDef['tag'] !== 'DyvixInput' && {
...themeInputStyle
})
},
...ariaAttributes,
...(id && id !== '!/' && { id: id }),
...(elementDef['is_custom'] && {animation: null}),
...(elementDef['is_custom'] && { animation: null }),
...(elementDef['supports-placeholder'] && {

@@ -437,3 +457,5 @@ placeholder: field.placeholder[j],

},
...((theme === '!/' || !theme) && {background: "transparent"} )
...((theme === '!/' || !theme) && {
background: 'transparent'
})
})

@@ -461,3 +483,7 @@ };

) : field.type === 'checkbox' ? (
<label key={j} className="modal-checkbox-label">
<label
key={j}
className="modal-checkbox-label"
style={themeTextStyle}
>
<Tag {...Tagprobs} />

@@ -464,0 +490,0 @@ {field.placeholder?.[j]}

.dyvix-select-wrapper {
width: 12rem;
width: fit-content;
height: fit-content;
position: relative;
z-index: 1;
}
.dyvix-select {
width: 100%;
transition: all 0.5s ease-in-out;
}
.dyvix-select-wrapper:hover {
transform: scale(1.02);
.dyvix-select-input {
background-color: rgba(255, 255, 255, 0.02);
border: 2px solid rgb(26, 27, 27);
border-radius: 8px;
box-sizing: border-box;
width: 100%;
height: 40px;
min-width: 50px;
padding: 0 12px;
color: #b9f7ff;
outline: none;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
transition: all 0.15s cubic-bezier(0.2, 0.2, 0.65, 0.3);
}
.dyvi-select {
width: 12rem;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 0.75rem;
height: 30px;
margin: 0 auto;
background: transparent;
padding: 0.5rem 1rem;
.dyvix-select-input:hover {
border: 2px solid rgb(194, 239, 255);
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.3),
0 0 10px rgba(185, 247, 255, 0.15);
cursor: text;
}
.dyvi-select:focus {
outline: none;
border-color: #0ea5e9;
.dyvix-select-input:focus {
background-color: rgba(255, 255, 255, 0.1);
border: 3px solid rgb(168, 231, 254);
border-color: #b9f7ff;
box-shadow:
inset 0 2px 4px rgba(0, 0, 0, 0.3),
0 0 12px rgba(185, 247, 255, 0.2);
}
.dyvix-select-input::placeholder {
color: rgba(255, 255, 255, 0.4);
font-size: 0.9rem;
}
.dyvix-dropdown-select {
position: absolute;
list-style: none;
top: 100%;
left: 0;
width: 100%;
margin: 2px 0 0 0;
list-style: none !important;
text-align: left;
width: 90px;
max-height: 60px;
max-height: 150px;
overflow-y: auto;
z-index: 1000;
padding: 0;
border-radius: 5px;
background-color: whitesmoke;
border: solid 1px #e2e8f0;
margin-left: 10px;
margin-top: 0.1rem;
padding: 4px 0;
border-radius: 8px;
background: whitesmoke;
border: 1px solid #e2e8f0;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
}

@@ -47,10 +74,10 @@ .dyvix-dropdown-select::-webkit-scrollbar {

.dyvix-dropdown-select li {
background-color: whitesmoke;
border-bottom: gainsboro 0.1px solid;
height: 20px !important;
font-size: xx-small;
font-family: 'Inter', 'Segoe UI', sans-serif;
font-weight: 500;
letter-spacing: 0.5px;
margin-left: 0.4rem;
background-color: transparent;
color: #fff;
border-bottom: 1px solid rgb(35, 40, 45);
padding: 10px 12px;
font-size: 0.9rem;
font-family: 'Inter', sans-serif;
cursor: pointer;
margin-left: 0;
}

@@ -57,0 +84,0 @@ .dyvix-dropdown-select li:active {

import './dependencies/style/styles.css';
import React from 'react';
import SelectEngine from './SelectEngine';
import animationsData from '../animations.json';
import { useGSAP } from '@gsap/react';
import { gsap } from 'gsap';
import { EvaluateFailure, GuardStatus } from '../../utils/DyvixGuard';
import { ValidateSelect } from './validation';
import Version from '../../../package.json';
const supportedTypes = ['select', 'autocomplete'];
const validAnimations = animationsData.map((e) => e.animation);
/**

@@ -20,3 +19,3 @@ * @param {Object} props

*/
function DynamicSelect({
function DyvixSelect({
elements = [],

@@ -26,5 +25,7 @@ onChange,

animation = 'fade',
theme = '!/',
className,
placeholder = '',
...props
style,
...rest
}) {

@@ -40,10 +41,8 @@ type = type.includes('-') ? type.split('-')[1] : type;

});
const selectWrapperRef = React.useRef(null);
const selectRef = React.useRef(null);
const [configs, SetConfig] = React.useState({});
const instanceId = React.useId();
const dropdownSelectRef = React.useRef(null);
const is_valid = ValidateInput(elements, type, animation);
if (is_valid.status === -1) {
console.error(is_valid.error);
return null;
}
function onChangeInternalCallback(data) {

@@ -99,6 +98,33 @@ onChange(data);

};
const currentAnimation = animationsData.find(
(e) => e.animation.trim().toLowerCase() === animation.trim().toLowerCase()
);
const currentAnimation = animation ? configs['animation'] : null;
const currentTheme = theme !== '!/' ? configs['theme'] : null;
className =
`dyvix-select-wrapper ${currentTheme?.class ?? ''} ${className !== '' ? ` ${className}` : ''}`.trim();
const dropdownThemeClass = currentTheme?.['dropdown-class'];
const inputThemeClass = currentTheme?.['input-class'];
React.useEffect(() => {
async function validate() {
const validator = await ValidateSelect(
elements,
type,
animation,
theme,
SetConfig,
instanceId
);
if (validator.status === GuardStatus.Error) {
return EvaluateFailure(validator.error, validator.status);
}
}
validate();
return () => {
const key = `DYVIX_${Version['version']}_Select_theme_${instanceId}`;
const ele = document.getElementById(key);
if (ele) ele.remove();
};
}, [animation, theme]);
function HandleKey(e, controller) {

@@ -145,5 +171,5 @@ if (Select.is_open == false) return;

useGSAP(() => {
if (!selectRef.current || !currentAnimation) return;
if (!selectWrapperRef.current || !currentAnimation) return;
gsap.fromTo(selectRef.current, currentAnimation.from, {
gsap.fromTo(selectWrapperRef.current, currentAnimation.from, {
...currentAnimation.to,

@@ -154,38 +180,54 @@ duration: currentAnimation['default-duration'],

}, [currentAnimation]);
const props = {
className: className,
style: style
};
const inputProps = {
autoComplete: 'off',
role: 'combobox',
'aria-autocomplete': 'list',
'aria-expanded': Select.is_open,
'aria-haspopup': 'listbox',
className: `dyvix-select-input ${inputThemeClass}`.trim(),
type: 'text',
...rest,
ref: selectRef,
placeholder: placeholder || undefined,
onChange: (e) => {
PopulateSelect(e.target.value, SetSelect, elements);
onChangeInternalCallback(e.target.value);
},
onFocus: (e) => {
TranslateEngineType(e.target.value, 'focus', SetSelect);
if (rest.onFocus) rest.onFocus(e);
},
onBlur: (e) => {
TranslateEngineType(e.target.value, 'blur', SetSelect);
if (rest.onBlur) rest.onBlur(e);
},
onKeyDown: (e) => {
HandleKey(e, SetSelect);
if (rest.onKeyDown) rest.onKeyDown(e);
}
};
const engineProps = {
elements: Select.elements,
is_open: Select.is_open,
is_rendered: Select.is_rendered,
inputRef: selectRef,
activeIndex: Select.activeIndex,
ref: dropdownSelectRef,
...(dropdownThemeClass && { className: dropdownThemeClass }),
controller: SetSelect,
OnChangeCallback: (value) => onChangeInternalCallback(value),
placeholder: placeholder || undefined
};
return (
<div className={`${className} dyvix-select-wrapper`}>
<input
autoComplete="off"
role="combobox"
aria-autocomplete="list"
aria-expanded={Select.is_open}
aria-haspopup="listbox"
className={`dyvi-select`}
type="text"
ref={selectRef}
placeholder={placeholder}
onChange={(e) => {
PopulateSelect(e.target.value, SetSelect, elements);
onChangeInternalCallback(e.target.value);
}}
onFocus={(e) => {
TranslateEngineType(e.target.value, 'focus', SetSelect);
}}
onBlur={(e) => {
TranslateEngineType(e.target.value, 'blur', SetSelect);
}}
onKeyDown={(e) => HandleKey(e, SetSelect)}
/>
<SelectEngine
elements={Select.elements}
is_open={Select.is_open}
is_rendered={Select.is_rendered}
inputRef={selectRef}
activeIndex={Select.activeIndex}
ref={dropdownSelectRef}
controller={SetSelect}
OnChangeCallback={(value) => onChangeInternalCallback(value)}
placeholder={placeholder}
/>
<div {...props} ref={selectWrapperRef}>
<div className="dyvix-select">
<input {...inputProps} />
</div>
<SelectEngine {...engineProps} />
</div>

@@ -195,15 +237,2 @@ );

function ValidateInput(elements, type, animation) {
if (!Array.isArray(elements)) {
return { status: -1, error: 'Elements should be included as an array.' };
}
if (!supportedTypes.includes(type)) {
return { status: -1, error: 'Please provide a valid select type.' };
}
if (animation !== '!/' && !validAnimations.includes(animation)) {
return { status: -1, error: 'Please provide a valid animation.' };
}
return { status: 1 };
}
export default DynamicSelect;
export default DyvixSelect;

@@ -13,3 +13,3 @@ import './dependencies/style/styles.css';

selectedElement = '',
placeholder = 'Select...',
placeholder = '',
controller,

@@ -19,3 +19,4 @@ activeIndex,

OnChangeCallback,
type
type,
className
},

@@ -55,3 +56,4 @@ ref

duration: 1.1,
ease: 'power2.inOut'
ease: 'power2.inOut',
overwrite: 'auto'
}

@@ -64,3 +66,4 @@ );

duration: 0.3,
ease: 'power2.inOut'
ease: 'power2.inOut',
overwrite: 'auto'
});

@@ -71,13 +74,2 @@ }

useEffect(() => {
const observer = new ResizeObserver(() => {
ref.current.style.width = inputRef.current.offsetWidth - 20 + 'px';
ref.current.style.marginLeft = 5;
});
observer.observe(inputRef.current);
return () => observer.disconnect();
}, []);
useEffect(() => {
if (activeIndex >= 0 && itemsRef.current[activeIndex]) {

@@ -92,9 +84,4 @@ itemsRef.current[activeIndex].scrollIntoView({ block: 'nearest' });

<ul
className="dyvix-dropdown-select"
className={`dyvix-dropdown-select ${className}`.trim()}
role="listbox"
style={
is_open
? { background: 'whitesmoke', border: '1px solid #e2e8f0' }
: { background: 'transparent', border: 'none' }
}
ref={ref}

@@ -110,3 +97,8 @@ >

index === activeIndex
? { backgroundColor: '#e0f7fa', cursor: 'pointer' }
? {
backgroundColor:
'var(--dyvix-select-active-bg, #e0f7fa)',
color: 'var(--dyvix-select-active-text, #141618)',
cursor: 'pointer'
}
: {}

@@ -113,0 +105,0 @@ }

@@ -64,2 +64,10 @@ .dyvix-table-wrapper {

}
.dyvix-table-sort-icon {
min-width: 16px;
max-width: 16px;
}
.table-sortable {
cursor: pointer;
user-select: none;
}
@media (max-width: 640px) {

@@ -66,0 +74,0 @@ .dyvix-table-wrapper {

@@ -23,2 +23,3 @@ .dyvix-table-lens {

}
.dyvix-table-crimson {

@@ -43,1 +44,255 @@ border-radius: 1rem;

}
.dyvix-table-midnight {
border-radius: 1rem;
font-family: 'Geist';
background: radial-gradient(circle at center, #00024d 0%, #000000 100%);
border: 1px solid rgba(112, 168, 247, 0.3);
color: #c8d8f8;
box-shadow:
0 0 40px 5px rgba(99, 102, 241, 0.2),
inset 0 0 15px rgba(112, 168, 247, 0.1);
-webkit-box-shadow:
0 0 40px 5px rgba(99, 102, 241, 0.2),
inset 0 0 15px rgba(112, 168, 247, 0.1);
-moz-box-shadow:
0 0 40px 5px rgba(99, 102, 241, 0.2),
inset 0 0 15px rgba(112, 168, 247, 0.1);
backdrop-filter: blur(10px);
transition:
transform 0.5s cubic-bezier(0.17, 0.88, 0.3, 1.67),
box-shadow 0.5s ease-in-out,
border-color 0.3s ease-in-out;
}
.dyvix-table-midnight:hover {
background: radial-gradient(circle at 40% 40%, #000375 0%, #000000 100%);
border-color: rgba(112, 168, 247, 0.6);
box-shadow:
0 0 60px 10px rgba(99, 102, 241, 0.4),
inset 0 0 20px rgba(112, 168, 247, 0.2);
-webkit-box-shadow:
0 0 60px 10px rgba(99, 102, 241, 0.4),
inset 0 0 20px rgba(112, 168, 247, 0.2);
-moz-box-shadow:
0 0 60px 10px rgba(99, 102, 241, 0.4),
inset 0 0 20px rgba(112, 168, 247, 0.2);
transform: translateY(-3px) scale(1.005);
}
.dyvix-table-forest {
border-radius: 1rem;
font-family: 'Geist';
background: #1f3b2c;
background: radial-gradient(
circle,
rgba(31, 59, 44, 1) 14%,
rgba(31, 59, 44, 1) 24%,
rgba(75, 58, 42, 1) 71%
);
border: 3px double #86a86b;
color: #d4eec4;
box-shadow: inset 0px 0px 30px 10px rgba(163, 236, 101, 0.15);
-webkit-box-shadow: inset 0px 0px 30px 10px rgba(163, 236, 101, 0.15);
-moz-box-shadow: inset 0px 0px 30px 10px rgba(163, 236, 101, 0.15);
transition:
transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275),
box-shadow 0.3s ease,
border-color 0.3s ease;
}
.dyvix-table-forest:hover {
border-color: #a3ec65;
box-shadow: inset 0px 0px 50px 15px rgba(163, 236, 101, 0.28);
-webkit-box-shadow: inset 0px 0px 50px 15px rgba(163, 236, 101, 0.28);
-moz-box-shadow: inset 0px 0px 50px 15px rgba(163, 236, 101, 0.28);
transform: translateY(-2px) scale(1.005);
}
.dyvix-table-sunset {
border-radius: 1rem;
font-family: 'Geist';
background: #1a0a00;
background: linear-gradient(
135deg,
#1a0a00 0%,
#3d1a00 40%,
#6b2d00 70%,
#8b3a00 100%
);
border: 1px solid rgba(255, 198, 15, 0.1);
border-bottom: 4px solid #a84600;
color: #ffd89b;
box-shadow: 0px 15px 38px -10px rgba(255, 198, 15, 0.5);
-webkit-box-shadow: 0px 15px 38px -10px rgba(255, 198, 15, 0.5);
-moz-box-shadow: 0px 15px 38px -10px rgba(255, 198, 15, 0.5);
transition:
transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
box-shadow 0.3s ease-in-out,
border-radius 0.2s ease-in-out;
}
.dyvix-table-sunset:hover {
transform: translateY(-2px);
box-shadow: 0 20px 50px -10px rgba(255, 198, 15, 0.6);
-webkit-box-shadow: 0 20px 50px -10px rgba(255, 198, 15, 0.6);
-moz-box-shadow: 0 20px 50px -10px rgba(255, 198, 15, 0.6);
border-radius: 0.9rem;
}
.dyvix-table-ocean {
border-radius: 1rem;
font-family: 'Geist';
background: linear-gradient(200deg, #001220, #023862);
border: 2px solid rgba(0, 150, 255, 0.3);
color: #e0f7ff;
box-shadow:
0 0 50px rgba(0, 100, 255, 0.15),
inset 0 0 30px rgba(0, 150, 255, 0.05);
-webkit-box-shadow:
0 0 50px rgba(0, 100, 255, 0.15),
inset 0 0 30px rgba(0, 150, 255, 0.05);
-moz-box-shadow:
0 0 50px rgba(0, 100, 255, 0.15),
inset 0 0 30px rgba(0, 150, 255, 0.05);
transition:
box-shadow 0.3s ease-in-out,
border 0.2s ease-in-out,
transform 0.4s;
}
.dyvix-table-ocean:hover {
border: 3px solid rgba(0, 150, 255, 0.6);
box-shadow:
0 0 70px rgba(0, 100, 255, 0.25),
inset 0 0 40px rgba(0, 150, 255, 0.08);
-webkit-box-shadow:
0 0 70px rgba(0, 100, 255, 0.25),
inset 0 0 40px rgba(0, 150, 255, 0.08);
-moz-box-shadow:
0 0 70px rgba(0, 100, 255, 0.25),
inset 0 0 40px rgba(0, 150, 255, 0.08);
transform: translateY(-2px) scale(1.005);
}
.dyvix-table-neon {
border-radius: 1rem;
font-family: 'Geist';
background: radial-gradient(
circle,
rgba(77, 238, 234, 0.15) 0%,
rgba(112, 186, 239, 0.1) 43%,
rgba(240, 0, 255, 0.15) 100%
);
border: 2px solid rgba(77, 238, 234, 0.5);
color: #e0fffe;
box-shadow:
0 0 40px rgba(252, 46, 255, 0.3),
0 0 80px rgba(77, 238, 234, 0.1),
inset 0 0 20px rgba(112, 186, 239, 0.05);
-webkit-box-shadow:
0 0 40px rgba(252, 46, 255, 0.3),
0 0 80px rgba(77, 238, 234, 0.1),
inset 0 0 20px rgba(112, 186, 239, 0.05);
-moz-box-shadow:
0 0 40px rgba(252, 46, 255, 0.3),
0 0 80px rgba(77, 238, 234, 0.1),
inset 0 0 20px rgba(112, 186, 239, 0.05);
transition:
transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
box-shadow 0.3s ease,
border-color 0.3s ease,
border-radius 0.2s ease-in-out;
}
.dyvix-table-neon:hover {
border-color: rgba(77, 238, 234, 0.8);
border-radius: 0.75rem;
box-shadow:
0 0 60px rgba(252, 46, 255, 0.5),
0 0 120px rgba(77, 238, 234, 0.2),
inset 0 0 30px rgba(112, 186, 239, 0.1);
-webkit-box-shadow:
0 0 60px rgba(252, 46, 255, 0.5),
0 0 120px rgba(77, 238, 234, 0.2),
inset 0 0 30px rgba(112, 186, 239, 0.1);
-moz-box-shadow:
0 0 60px rgba(252, 46, 255, 0.5),
0 0 120px rgba(77, 238, 234, 0.2),
inset 0 0 30px rgba(112, 186, 239, 0.1);
transform: translateY(-2px) scale(1.009);
}
.dyvix-table-blade {
border-radius: 0px;
font-family: 'Geist';
background-color: #0a0a0a;
color: #e2e8f0;
border-left: 3px solid #e2e8f0;
border-top: 3px solid #e2e8f0;
border-right: 1px solid #ffffff20;
border-bottom: 1px solid #ffffff20;
box-shadow: -4px -4px 20px rgba(255, 255, 255, 0.05);
-webkit-box-shadow: -4px -4px 20px rgba(255, 255, 255, 0.05);
-moz-box-shadow: -4px -4px 20px rgba(255, 255, 255, 0.05);
transition:
border-left 0.1s ease-in-out,
border-top 0.1s ease-in-out,
box-shadow 0.2s ease-in-out,
transform 0.3s ease-in-out;
}
.dyvix-table-blade:hover {
border-left: 4px solid #ffffff;
border-top: 4px solid #ffffff;
box-shadow: -6px -6px 30px rgba(255, 255, 255, 0.1);
-webkit-box-shadow: -6px -6px 30px rgba(255, 255, 255, 0.1);
-moz-box-shadow: -6px -6px 30px rgba(255, 255, 255, 0.1);
transform: translateY(-2px) scale(1.005);
}
.dyvix-table-aurora {
font-family: 'Geist';
background: linear-gradient(90deg, #14e81e 0%, #00ea8d 21%, #01b1b3 46%, #017ed5 76%, #b53dff 100%) border-box;
color: #e6fffb;
border-image: linear-gradient(
90deg,
rgba(20, 232, 30, 1) 0%,
rgba(0, 234, 141, 1) 21%,
rgba(1, 177, 179, 1) 46%,
rgba(1, 126, 213, 1) 76%,
rgba(181, 61, 255, 1) 100%
)
1;
box-shadow: 0px 0px 35px 0px rgba(1, 176, 179, 0.35);
-webkit-box-shadow: 0px 0px 35px 0px rgba(1, 176, 179, 0.35);
-moz-box-shadow: 0px 0px 35px 0px rgba(1, 176, 179, 0.35);
transition:
box-shadow 0.4s ease-in-out,
-webkit-box-shadow 0.4s ease-in-out,
-moz-box-shadow 0.4s ease-in-out,
transform 0.3s ease-in-out;
}
.dyvix-table-aurora:hover {
box-shadow: 0px 0px 55px 0px rgba(1, 176, 179, 0.55);
-webkit-box-shadow: 0px 0px 55px 0px rgba(1, 176, 179, 0.55);
-moz-box-shadow: 0px 0px 55px 0px rgba(1, 176, 179, 0.55);
transform: translateY(-2px) scale(1.005);
}

@@ -11,3 +11,38 @@ [

"default-animation": "float"
},
{
"theme": "Midnight",
"class": "dyvix-table-midnight",
"default-animation": "drift"
},
{
"theme": "Forest",
"class": "dyvix-table-forest",
"default-animation": "glide"
},
{
"theme": "Sunset",
"class": "dyvix-table-sunset",
"default-animation": "drop"
},
{
"theme": "Ocean",
"class": "dyvix-table-ocean",
"default-animation": "flip"
},
{
"theme": "Neon",
"class": "dyvix-table-neon",
"default-animation": "pulse"
},
{
"theme": "Blade",
"class": "dyvix-table-blade",
"default-animation": "drift"
},
{
"theme": "Aurora",
"class": "dyvix-table-aurora",
"default-animation": "aurora"
}
]

@@ -40,2 +40,3 @@ import React from 'react';

const [configs, SetConfig] = React.useState({});
const [sortConfig, setSortConfig] = React.useState([]);
const tableRef = React.useRef();

@@ -56,5 +57,54 @@ const [isValid, SetIsvalid] = React.useState(false);

};
const processedData = React.useMemo(() => {
if (!data || !columns) return [];
if (!sortConfig.length) return data;
return [...data].sort((a, b) => {
for (const { key, direction } of sortConfig) {
if (direction === 'none') continue;
const aVal = a[key];
const bVal = b[key];
let result = 0;
if (typeof aVal === 'number' && typeof bVal === 'number') {
result = aVal - bVal;
} else {
result = String(aVal).localeCompare(String(bVal));
}
if (result !== 0) return direction === 'asc' ? result : -result;
}
return 0;
});
}, [columns, data, isValid, sortConfig]);
const ConstructTable = () => {
const bodyRows = data.map((row) => columns.map((col) => row[col.key]));
const bodyRows = processedData.map((row) =>
columns.map((col) => row[col.key])
);
const handleSortClick = (key) => {
const isfound = sortConfig?.find((config) => config['key'] === key);
if (isfound) {
setSortConfig((prev) =>
prev.map((config) => {
if (config.key !== key) return config;
if (config.direction === 'asc')
return { ...config, direction: 'desc' };
if (config.direction === 'desc')
return { ...config, direction: 'none' };
return { ...config, direction: 'asc' };
})
);
} else {
const index = columns.findIndex((col) => col['key'] === key);
setSortConfig((prev) => [
...(prev || []),
{ key: key, direction: 'asc', index: index }
]);
}
};
return (

@@ -65,5 +115,29 @@ <>

{columns.map((col, i) => {
const isColumnSortable = col.sortable === true;
const activeSort = isColumnSortable
? sortConfig.find((config) => config.key === col.key)
: null;
let sortIndicator = null;
if (activeSort) {
if (activeSort.direction === 'asc') {
sortIndicator = ' ▲';
} else if (activeSort.direction === 'desc') {
sortIndicator = ' ▼';
}
}
return (
<DyvixTableHead key={col.key || i}>
<DyvixTableHead
key={col.key || i}
{...(isColumnSortable && {
onClick: () => handleSortClick(col.key),
className: 'table-sortable'
})}
>
{typeof col === 'string' ? col : col.label}
{isColumnSortable && (
<span className="dyvix-table-sort-icon">
{sortIndicator || ' ↕'}
</span>
)}
</DyvixTableHead>

@@ -115,3 +189,3 @@ );

};
}, [animation, columns, data]);
}, [animation, theme, columns, data]);
useGSAP(() => {

@@ -128,3 +202,3 @@ if (!tableRef.current || !currentAnimation) return;

() => (columns && isValid ? ConstructTable() : null),
[columns, isValid]
[columns, isValid, sortConfig]
);

@@ -131,0 +205,0 @@ children = children ? children : resultJSX;

@@ -69,3 +69,7 @@ import {

const isMalformed = columns.some(
(col) => typeof col !== 'object' || col === null || col.key === undefined
(col) =>
typeof col !== 'object' ||
col === null ||
col.key === undefined ||
(col.sortable !== undefined && typeof col.sortable !== 'boolean')
);

@@ -72,0 +76,0 @@

export { default as Modal } from './components/modal/modal';
export { default as DynamicSelect } from './components/select/SelectCompiler';
export { default as DyvixSelect } from './components/select/SelectCompiler';
export * from './constants';

@@ -4,0 +4,0 @@ export { default as DyvixToastContainer } from './components/toast/toastContainer';

@@ -16,2 +16,4 @@ import buttonThemesJSON from '../../components/button/dependencies/themes.json?raw';

import tableThemesCSS from '../../components/table/dependencies/style/themes.css?raw';
import selectThemesJSON from '../../components/select/dependencies/themes.json?raw';
import selectThemesCSS from '../../components/select/dependencies/style/themes.css?raw';

@@ -27,3 +29,4 @@ export const JSON_LIBRARY = {

'../../components/label/dependencies/themes.json': labelThemesJSON,
'../../components/table/dependencies/themes.json': tableThemesJSON
'../../components/table/dependencies/themes.json': tableThemesJSON,
'../../components/select/dependencies/themes.json': selectThemesJSON
};

@@ -37,3 +40,4 @@

'../../components/label/dependencies/style/themes.css': labelThemesCSS,
'../../components/table/dependencies/style/themes.css': tableThemesCSS
'../../components/table/dependencies/style/themes.css': tableThemesCSS,
'../../components/select/dependencies/style/themes.css': selectThemesCSS
};