2 Commits
1.1.2 ... 1.1.4

Author SHA1 Message Date
Natxo
f39359ef67 Update package.json 2026-04-04 18:11:31 +02:00
9fefa6dcb1 repair docs 2026-04-04 18:09:23 +02:00
12 changed files with 637 additions and 134 deletions

View File

@@ -6230,6 +6230,11 @@
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
} }
.transition {
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.transition-all { .transition-all {
transition-property: all; transition-property: all;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));

2
css/sigpro.min.css vendored

File diff suppressed because one or more lines are too long

275
dist/sigpro-ui.esm.js vendored
View File

@@ -1,3 +1,14 @@
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, {
get: all[name],
enumerable: true,
configurable: true,
set: (newValue) => all[name] = () => newValue
});
};
// src/sigpro.js // src/sigpro.js
var activeEffect = null; var activeEffect = null;
var currentOwner = null; var currentOwner = null;
@@ -200,7 +211,10 @@ var $html2 = (tag, props = {}, content = []) => {
content = props; content = props;
props = {}; props = {};
} }
const el = document.createElement(tag), _sanitize = (key, val) => (key === "src" || key === "href") && String(val).toLowerCase().includes("javascript:") ? "#" : val; const svgTags = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "defs", "text", "tspan", "use"];
const isSVG = svgTags.includes(tag);
const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag);
const _sanitize = (key, val) => (key === "src" || key === "href") && String(val).toLowerCase().includes("javascript:") ? "#" : val;
el._cleanups = new Set; el._cleanups = new Set;
const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"]; const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"];
for (let [key, val] of Object.entries(props)) { for (let [key, val] of Object.entries(props)) {
@@ -236,7 +250,13 @@ var $html2 = (tag, props = {}, content = []) => {
el[key] = false; el[key] = false;
} }
} else { } else {
currentVal == null ? el.removeAttribute(key) : el.setAttribute(key, currentVal); if (currentVal == null) {
el.removeAttribute(key);
} else if (isSVG && typeof currentVal === "number") {
el.setAttribute(key, currentVal);
} else {
el.setAttribute(key, currentVal);
}
} }
})); }));
} else { } else {
@@ -277,20 +297,32 @@ var $html2 = (tag, props = {}, content = []) => {
append(content); append(content);
return el; return el;
}; };
var $if = (condition, thenVal, otherwiseVal = null) => { var $if = (condition, thenVal, otherwiseVal = null, transition = null) => {
const marker = document.createTextNode(""); const marker = document.createTextNode("");
const container = $html2("div", { style: "display:contents" }, [marker]); const container = $html2("div", { style: "display:contents" }, [marker]);
let current = null, last = null; let current = null, last = null;
$watch2(() => { $watch2(() => {
const state = !!(typeof condition === "function" ? condition() : condition); const state = !!(typeof condition === "function" ? condition() : condition);
if (state !== last) { if (state === last)
return;
last = state; last = state;
if (current && !state && transition?.out) {
transition.out(current.container, () => {
current.destroy();
current = null;
});
} else {
if (current) if (current)
current.destroy(); current.destroy();
current = null;
}
if (state || !state && otherwiseVal) {
const branch = state ? thenVal : otherwiseVal; const branch = state ? thenVal : otherwiseVal;
if (branch) { if (branch) {
current = _view(() => typeof branch === "function" ? branch() : branch); current = _view(() => typeof branch === "function" ? branch() : branch);
container.insertBefore(current.container, marker); container.insertBefore(current.container, marker);
if (state && transition?.in)
transition.in(current.container);
} }
} }
}); });
@@ -385,7 +417,8 @@ var $mount = (component, target) => {
MOUNTED_NODES.set(el, instance); MOUNTED_NODES.set(el, instance);
return instance; return instance;
}; };
var SigProCore = { $, $watch: $watch2, $html: $html2, $if, $for, $router, $mount }; var Fragment = ({ children }) => children;
var SigProCore = { $, $watch: $watch2, $html: $html2, $if, $for, $router, $mount, Fragment };
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const install = (registry) => { const install = (registry) => {
Object.keys(registry).forEach((key) => { Object.keys(registry).forEach((key) => {
@@ -398,12 +431,63 @@ if (typeof window !== "undefined") {
window[helperName] = (props, content) => $html2(tagName, props, content); window[helperName] = (props, content) => $html2(tagName, props, content);
} }
}); });
window.Fragment = Fragment;
window.SigPro = Object.freeze(registry); window.SigPro = Object.freeze(registry);
}; };
install(SigProCore); install(SigProCore);
} }
// src/components/index.js
var exports_components = {};
__export(exports_components, {
default: () => components_default,
Tooltip: () => Tooltip,
Toast: () => Toast,
Timeline: () => Timeline,
Tabs: () => Tabs,
Table: () => Table,
Swap: () => Swap,
Stat: () => Stat,
Stack: () => Stack,
Select: () => Select,
Rating: () => Rating,
Range: () => Range,
Radio: () => Radio,
Navbar: () => Navbar,
Modal: () => Modal,
Menu: () => Menu,
List: () => List,
Label: () => Label,
Input: () => Input,
Indicator: () => Indicator,
Fileinput: () => Fileinput,
Fieldset: () => Fieldset,
Fab: () => Fab,
Dropdown: () => Dropdown,
Drawer: () => Drawer,
Datepicker: () => Datepicker,
Colorpicker: () => Colorpicker,
Checkbox: () => Checkbox,
Button: () => Button,
Badge: () => Badge,
Autocomplete: () => Autocomplete,
Alert: () => Alert,
Accordion: () => Accordion
});
// src/components/Accordion.js
var exports_Accordion = {};
__export(exports_Accordion, {
Accordion: () => Accordion
});
// src/core/utils.js // src/core/utils.js
var exports_utils = {};
__export(exports_utils, {
val: () => val,
ui: () => ui,
getIcon: () => getIcon
});
var val = (t) => typeof t === "function" ? t() : t; var val = (t) => typeof t === "function" ? t() : t;
var ui = (baseClass, additionalClassOrFn) => typeof additionalClassOrFn === "function" ? () => `${baseClass} ${additionalClassOrFn() || ""}`.trim() : `${baseClass} ${additionalClassOrFn || ""}`.trim(); var ui = (baseClass, additionalClassOrFn) => typeof additionalClassOrFn === "function" ? () => `${baseClass} ${additionalClassOrFn() || ""}`.trim() : `${baseClass} ${additionalClassOrFn || ""}`.trim();
var getIcon = (icon) => { var getIcon = (icon) => {
@@ -446,6 +530,10 @@ var Accordion = (props, children) => {
}; };
// src/components/Alert.js // src/components/Alert.js
var exports_Alert = {};
__export(exports_Alert, {
Alert: () => Alert
});
var Alert = (props, children) => { var Alert = (props, children) => {
const { class: className, actions, type = "info", soft = true, ...rest } = props; const { class: className, actions, type = "info", soft = true, ...rest } = props;
const iconMap = { const iconMap = {
@@ -473,6 +561,12 @@ var Alert = (props, children) => {
].filter(Boolean)); ].filter(Boolean));
}; };
// src/components/Autocomplete.js
var exports_Autocomplete = {};
__export(exports_Autocomplete, {
Autocomplete: () => Autocomplete
});
// src/core/i18n.js // src/core/i18n.js
var i18n = { var i18n = {
es: { es: {
@@ -496,6 +590,10 @@ var currentLocale = $("es");
var tt = (t) => () => i18n[currentLocale()][t] || t; var tt = (t) => () => i18n[currentLocale()][t] || t;
// src/components/Input.js // src/components/Input.js
var exports_Input = {};
__export(exports_Input, {
Input: () => Input
});
var Input = (props) => { var Input = (props) => {
const { const {
class: className, class: className,
@@ -654,6 +752,10 @@ var Autocomplete = (props) => {
}; };
// src/components/Badge.js // src/components/Badge.js
var exports_Badge = {};
__export(exports_Badge, {
Badge: () => Badge
});
var Badge = (props, children) => { var Badge = (props, children) => {
const { class: className, ...rest } = props; const { class: className, ...rest } = props;
return $html2("span", { return $html2("span", {
@@ -663,6 +765,10 @@ var Badge = (props, children) => {
}; };
// src/components/Button.js // src/components/Button.js
var exports_Button = {};
__export(exports_Button, {
Button: () => Button
});
var Button = (props, children) => { var Button = (props, children) => {
const { class: className, loading, icon, ...rest } = props; const { class: className, loading, icon, ...rest } = props;
const iconEl = getIcon(icon); const iconEl = getIcon(icon);
@@ -678,6 +784,10 @@ var Button = (props, children) => {
}; };
// src/components/Checkbox.js // src/components/Checkbox.js
var exports_Checkbox = {};
__export(exports_Checkbox, {
Checkbox: () => Checkbox
});
var Checkbox = (props) => { var Checkbox = (props) => {
const { class: className, value, tooltip, toggle, label, ...rest } = props; const { class: className, value, tooltip, toggle, label, ...rest } = props;
const checkEl = $html2("input", { const checkEl = $html2("input", {
@@ -694,6 +804,10 @@ var Checkbox = (props) => {
}; };
// src/components/Colorpicker.js // src/components/Colorpicker.js
var exports_Colorpicker = {};
__export(exports_Colorpicker, {
Colorpicker: () => Colorpicker
});
var Colorpicker = (props) => { var Colorpicker = (props) => {
const { class: className, value, label, ...rest } = props; const { class: className, value, label, ...rest } = props;
const isOpen = $(false); const isOpen = $(false);
@@ -751,6 +865,10 @@ var Colorpicker = (props) => {
}; };
// src/components/Datepicker.js // src/components/Datepicker.js
var exports_Datepicker = {};
__export(exports_Datepicker, {
Datepicker: () => Datepicker
});
var Datepicker = (props) => { var Datepicker = (props) => {
const { class: className, value, range, label, placeholder, hour = false, ...rest } = props; const { class: className, value, range, label, placeholder, hour = false, ...rest } = props;
const isOpen = $(false); const isOpen = $(false);
@@ -957,6 +1075,10 @@ var Datepicker = (props) => {
}; };
// src/components/Drawer.js // src/components/Drawer.js
var exports_Drawer = {};
__export(exports_Drawer, {
Drawer: () => Drawer
});
var Drawer = (props, children) => { var Drawer = (props, children) => {
const { class: className, id, open, side, content, ...rest } = props; const { class: className, id, open, side, content, ...rest } = props;
const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`; const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`;
@@ -994,6 +1116,10 @@ var Drawer = (props, children) => {
}; };
// src/components/Dropdown.js // src/components/Dropdown.js
var exports_Dropdown = {};
__export(exports_Dropdown, {
Dropdown: () => Dropdown
});
var currentOpen = null; var currentOpen = null;
if (typeof window !== "undefined" && !window.__dropdownHandlerRegistered) { if (typeof window !== "undefined" && !window.__dropdownHandlerRegistered) {
window.addEventListener("click", (e) => { window.addEventListener("click", (e) => {
@@ -1056,6 +1182,10 @@ var Dropdown = (props) => {
}; };
// src/components/Fab.js // src/components/Fab.js
var exports_Fab = {};
__export(exports_Fab, {
Fab: () => Fab
});
var Fab = (props) => { var Fab = (props) => {
const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props;
return $html2("div", { return $html2("div", {
@@ -1085,6 +1215,10 @@ var Fab = (props) => {
}; };
// src/components/Fieldset.js // src/components/Fieldset.js
var exports_Fieldset = {};
__export(exports_Fieldset, {
Fieldset: () => Fieldset
});
var Fieldset = (props, children) => { var Fieldset = (props, children) => {
const { class: className, legend, ...rest } = props; const { class: className, legend, ...rest } = props;
return $html2("fieldset", { return $html2("fieldset", {
@@ -1100,6 +1234,10 @@ var Fieldset = (props, children) => {
}; };
// src/components/Fileinput.js // src/components/Fileinput.js
var exports_Fileinput = {};
__export(exports_Fileinput, {
Fileinput: () => Fileinput
});
var Fileinput = (props) => { var Fileinput = (props) => {
const { class: className, tooltip, max = 2, accept = "*", onSelect, ...rest } = props; const { class: className, tooltip, max = 2, accept = "*", onSelect, ...rest } = props;
const selectedFiles = $([]); const selectedFiles = $([]);
@@ -1182,6 +1320,10 @@ var Fileinput = (props) => {
}; };
// src/components/Indicator.js // src/components/Indicator.js
var exports_Indicator = {};
__export(exports_Indicator, {
Indicator: () => Indicator
});
var Indicator = (props, children) => { var Indicator = (props, children) => {
const { value, class: className, ...rest } = props; const { value, class: className, ...rest } = props;
return $html2("div", { return $html2("div", {
@@ -1196,6 +1338,10 @@ var Indicator = (props, children) => {
}; };
// src/components/Label.js // src/components/Label.js
var exports_Label = {};
__export(exports_Label, {
Label: () => Label
});
var Label = (props) => { var Label = (props) => {
const { children, value, floating = false, error, required, class: className, ...rest } = props; const { children, value, floating = false, error, required, class: className, ...rest } = props;
if (floating) { if (floating) {
@@ -1213,6 +1359,10 @@ var Label = (props) => {
}; };
// src/components/List.js // src/components/List.js
var exports_List = {};
__export(exports_List, {
List: () => List
});
var List = (props) => { var List = (props) => {
const { class: className, items, header, render, keyFn = (item, index) => item.id ?? index, ...rest } = props; const { class: className, items, header, render, keyFn = (item, index) => item.id ?? index, ...rest } = props;
const listItems = $for(items, (item, index) => $html2("li", { class: "list-row" }, [render(item, index)]), keyFn); const listItems = $for(items, (item, index) => $html2("li", { class: "list-row" }, [render(item, index)]), keyFn);
@@ -1223,6 +1373,10 @@ var List = (props) => {
}; };
// src/components/Menu.js // src/components/Menu.js
var exports_Menu = {};
__export(exports_Menu, {
Menu: () => Menu
});
var Menu = (props) => { var Menu = (props) => {
const { class: className, items, ...rest } = props; const { class: className, items, ...rest } = props;
const renderItems = (items2) => $for(() => items2 || [], (it) => $html2("li", {}, [ const renderItems = (items2) => $for(() => items2 || [], (it) => $html2("li", {}, [
@@ -1238,6 +1392,10 @@ var Menu = (props) => {
}; };
// src/components/Modal.js // src/components/Modal.js
var exports_Modal = {};
__export(exports_Modal, {
Modal: () => Modal
});
var Modal = (props, children) => { var Modal = (props, children) => {
const { class: className, title, buttons, open, ...rest } = props; const { class: className, title, buttons, open, ...rest } = props;
let dialogElement = null; let dialogElement = null;
@@ -1288,12 +1446,20 @@ var Modal = (props, children) => {
}; };
// src/components/Navbar.js // src/components/Navbar.js
var exports_Navbar = {};
__export(exports_Navbar, {
Navbar: () => Navbar
});
var Navbar = (props, children) => { var Navbar = (props, children) => {
const { class: className, ...rest } = props; const { class: className, ...rest } = props;
return $html2("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children); return $html2("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children);
}; };
// src/components/Radio.js // src/components/Radio.js
var exports_Radio = {};
__export(exports_Radio, {
Radio: () => Radio
});
var Radio = (props) => { var Radio = (props) => {
const { class: className, label, tooltip, value, inputValue, name, ...rest } = props; const { class: className, label, tooltip, value, inputValue, name, ...rest } = props;
const radioEl = $html2("input", { const radioEl = $html2("input", {
@@ -1317,6 +1483,10 @@ var Radio = (props) => {
}; };
// src/components/Range.js // src/components/Range.js
var exports_Range = {};
__export(exports_Range, {
Range: () => Range
});
var Range = (props) => { var Range = (props) => {
const { class: className, label, tooltip, value, ...rest } = props; const { class: className, label, tooltip, value, ...rest } = props;
const rangeEl = $html2("input", { const rangeEl = $html2("input", {
@@ -1336,6 +1506,10 @@ var Range = (props) => {
}; };
// src/components/Rating.js // src/components/Rating.js
var exports_Rating = {};
__export(exports_Rating, {
Rating: () => Rating
});
var Rating = (props) => { var Rating = (props) => {
const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props; const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props;
const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`; const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`;
@@ -1363,6 +1537,10 @@ var Rating = (props) => {
}; };
// src/components/Select.js // src/components/Select.js
var exports_Select = {};
__export(exports_Select, {
Select: () => Select
});
var Select = (props) => { var Select = (props) => {
const { class: className, label, items, value, ...rest } = props; const { class: className, label, items, value, ...rest } = props;
const selectEl = $html2("select", { const selectEl = $html2("select", {
@@ -1382,12 +1560,20 @@ var Select = (props) => {
}; };
// src/components/Stack.js // src/components/Stack.js
var exports_Stack = {};
__export(exports_Stack, {
Stack: () => Stack
});
var Stack = (props, children) => { var Stack = (props, children) => {
const { class: className, ...rest } = props; const { class: className, ...rest } = props;
return $html2("div", { ...rest, class: ui("stack", className) }, children); return $html2("div", { ...rest, class: ui("stack", className) }, children);
}; };
// src/components/Stat.js // src/components/Stat.js
var exports_Stat = {};
__export(exports_Stat, {
Stat: () => Stat
});
var Stat = (props) => { var Stat = (props) => {
const { class: className, icon, label, value, desc, ...rest } = props; const { class: className, icon, label, value, desc, ...rest } = props;
return $html2("div", { ...rest, class: ui("stat", className) }, [ return $html2("div", { ...rest, class: ui("stat", className) }, [
@@ -1399,6 +1585,10 @@ var Stat = (props) => {
}; };
// src/components/Swap.js // src/components/Swap.js
var exports_Swap = {};
__export(exports_Swap, {
Swap: () => Swap
});
var Swap = (props) => { var Swap = (props) => {
const { class: className, value, on, off, ...rest } = props; const { class: className, value, on, off, ...rest } = props;
return $html2("label", { ...rest, class: ui("swap", className) }, [ return $html2("label", { ...rest, class: ui("swap", className) }, [
@@ -1417,6 +1607,10 @@ var Swap = (props) => {
}; };
// src/components/Table.js // src/components/Table.js
var exports_Table = {};
__export(exports_Table, {
Table: () => Table
});
var Table = (props) => { var Table = (props) => {
const { class: className, items = [], columns = [], keyFn, zebra = false, pinRows = false, empty = tt("nodata")(), ...rest } = props; const { class: className, items = [], columns = [], keyFn, zebra = false, pinRows = false, empty = tt("nodata")(), ...rest } = props;
const tableClass = () => { const tableClass = () => {
@@ -1458,6 +1652,10 @@ var Table = (props) => {
}; };
// src/components/Tabs.js // src/components/Tabs.js
var exports_Tabs = {};
__export(exports_Tabs, {
Tabs: () => Tabs
});
var Tabs = (props) => { var Tabs = (props) => {
const { items, class: className, ...rest } = props; const { items, class: className, ...rest } = props;
const itemsSignal = typeof items === "function" ? items : () => items || []; const itemsSignal = typeof items === "function" ? items : () => items || [];
@@ -1514,6 +1712,10 @@ var Tabs = (props) => {
}; };
// src/components/Timeline.js // src/components/Timeline.js
var exports_Timeline = {};
__export(exports_Timeline, {
Timeline: () => Timeline
});
var Timeline = (props) => { var Timeline = (props) => {
const { class: className, items = [], vertical = true, compact = false, ...rest } = props; const { class: className, items = [], vertical = true, compact = false, ...rest } = props;
const iconMap = { const iconMap = {
@@ -1548,6 +1750,10 @@ var Timeline = (props) => {
}; };
// src/components/Toast.js // src/components/Toast.js
var exports_Toast = {};
__export(exports_Toast, {
Toast: () => Toast
});
var Toast = (message, type = "alert-success", duration = 3500) => { var Toast = (message, type = "alert-success", duration = 3500) => {
let container = document.getElementById("sigpro-toast-container"); let container = document.getElementById("sigpro-toast-container");
if (!container) { if (!container) {
@@ -1598,11 +1804,70 @@ var Toast = (message, type = "alert-success", duration = 3500) => {
}; };
// src/components/Tooltip.js // src/components/Tooltip.js
var exports_Tooltip = {};
__export(exports_Tooltip, {
Tooltip: () => Tooltip
});
var Tooltip = (props, children) => $html2("div", { var Tooltip = (props, children) => $html2("div", {
...props, ...props,
class: () => ui("tooltip", props.ui, props.class), class: () => ui("tooltip", props.ui, props.class),
"data-tip": props.tip "data-tip": props.tip
}, children); }, children);
// src/components/index.js
var Components = {
...exports_Accordion,
...exports_Alert,
...exports_Autocomplete,
...exports_Badge,
...exports_Button,
...exports_Checkbox,
...exports_Colorpicker,
...exports_Datepicker,
...exports_Drawer,
...exports_Dropdown,
...exports_Fab,
...exports_Fieldset,
...exports_Fileinput,
...exports_Indicator,
...exports_Input,
...exports_Label,
...exports_List,
...exports_Menu,
...exports_Modal,
...exports_Navbar,
...exports_Radio,
...exports_Range,
...exports_Rating,
...exports_Select,
...exports_Stack,
...exports_Stat,
...exports_Swap,
...exports_Table,
...exports_Tabs,
...exports_Timeline,
...exports_Toast,
...exports_Tooltip
};
var components_default = {
...Components,
install: (target = window) => {
Object.entries(Components).forEach(([name, component]) => {
target[name] = component;
});
console.log("\uD83D\uDE80 SigproUI");
}
};
// index.js
if (typeof window !== "undefined") {
Object.entries(exports_components).forEach(([name, component]) => {
window[name] = component;
});
window.Utils = exports_utils;
window.tt = tt;
window.SigProUI = { ...exports_components, Utils: exports_utils, tt };
console.log("\uD83C\uDFA8 SigProUI ready");
}
export { export {
val, val,
ui, ui,

File diff suppressed because one or more lines are too long

264
dist/sigpro-ui.js vendored
View File

@@ -270,7 +270,10 @@
content = props; content = props;
props = {}; props = {};
} }
const el = document.createElement(tag), _sanitize = (key, val) => (key === "src" || key === "href") && String(val).toLowerCase().includes("javascript:") ? "#" : val; const svgTags = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "defs", "text", "tspan", "use"];
const isSVG = svgTags.includes(tag);
const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag);
const _sanitize = (key, val) => (key === "src" || key === "href") && String(val).toLowerCase().includes("javascript:") ? "#" : val;
el._cleanups = new Set; el._cleanups = new Set;
const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"]; const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"];
for (let [key, val] of Object.entries(props)) { for (let [key, val] of Object.entries(props)) {
@@ -306,7 +309,13 @@
el[key] = false; el[key] = false;
} }
} else { } else {
currentVal == null ? el.removeAttribute(key) : el.setAttribute(key, currentVal); if (currentVal == null) {
el.removeAttribute(key);
} else if (isSVG && typeof currentVal === "number") {
el.setAttribute(key, currentVal);
} else {
el.setAttribute(key, currentVal);
}
} }
})); }));
} else { } else {
@@ -347,20 +356,32 @@
append(content); append(content);
return el; return el;
}; };
var $if = (condition, thenVal, otherwiseVal = null) => { var $if = (condition, thenVal, otherwiseVal = null, transition = null) => {
const marker = document.createTextNode(""); const marker = document.createTextNode("");
const container = $html2("div", { style: "display:contents" }, [marker]); const container = $html2("div", { style: "display:contents" }, [marker]);
let current = null, last = null; let current = null, last = null;
$watch2(() => { $watch2(() => {
const state = !!(typeof condition === "function" ? condition() : condition); const state = !!(typeof condition === "function" ? condition() : condition);
if (state !== last) { if (state === last)
return;
last = state; last = state;
if (current && !state && transition?.out) {
transition.out(current.container, () => {
current.destroy();
current = null;
});
} else {
if (current) if (current)
current.destroy(); current.destroy();
current = null;
}
if (state || !state && otherwiseVal) {
const branch = state ? thenVal : otherwiseVal; const branch = state ? thenVal : otherwiseVal;
if (branch) { if (branch) {
current = _view(() => typeof branch === "function" ? branch() : branch); current = _view(() => typeof branch === "function" ? branch() : branch);
container.insertBefore(current.container, marker); container.insertBefore(current.container, marker);
if (state && transition?.in)
transition.in(current.container);
} }
} }
}); });
@@ -455,7 +476,8 @@
MOUNTED_NODES.set(el, instance); MOUNTED_NODES.set(el, instance);
return instance; return instance;
}; };
var SigProCore = { $, $watch: $watch2, $html: $html2, $if, $for, $router, $mount }; var Fragment = ({ children }) => children;
var SigProCore = { $, $watch: $watch2, $html: $html2, $if, $for, $router, $mount, Fragment };
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const install = (registry) => { const install = (registry) => {
Object.keys(registry).forEach((key) => { Object.keys(registry).forEach((key) => {
@@ -468,12 +490,63 @@
window[helperName] = (props, content) => $html2(tagName, props, content); window[helperName] = (props, content) => $html2(tagName, props, content);
} }
}); });
window.Fragment = Fragment;
window.SigPro = Object.freeze(registry); window.SigPro = Object.freeze(registry);
}; };
install(SigProCore); install(SigProCore);
} }
// src/components/index.js
var exports_components = {};
__export(exports_components, {
default: () => components_default,
Tooltip: () => Tooltip,
Toast: () => Toast,
Timeline: () => Timeline,
Tabs: () => Tabs,
Table: () => Table,
Swap: () => Swap,
Stat: () => Stat,
Stack: () => Stack,
Select: () => Select,
Rating: () => Rating,
Range: () => Range,
Radio: () => Radio,
Navbar: () => Navbar,
Modal: () => Modal,
Menu: () => Menu,
List: () => List,
Label: () => Label,
Input: () => Input,
Indicator: () => Indicator,
Fileinput: () => Fileinput,
Fieldset: () => Fieldset,
Fab: () => Fab,
Dropdown: () => Dropdown,
Drawer: () => Drawer,
Datepicker: () => Datepicker,
Colorpicker: () => Colorpicker,
Checkbox: () => Checkbox,
Button: () => Button,
Badge: () => Badge,
Autocomplete: () => Autocomplete,
Alert: () => Alert,
Accordion: () => Accordion
});
// src/components/Accordion.js
var exports_Accordion = {};
__export(exports_Accordion, {
Accordion: () => Accordion
});
// src/core/utils.js // src/core/utils.js
var exports_utils = {};
__export(exports_utils, {
val: () => val,
ui: () => ui,
getIcon: () => getIcon
});
var val = (t) => typeof t === "function" ? t() : t; var val = (t) => typeof t === "function" ? t() : t;
var ui = (baseClass, additionalClassOrFn) => typeof additionalClassOrFn === "function" ? () => `${baseClass} ${additionalClassOrFn() || ""}`.trim() : `${baseClass} ${additionalClassOrFn || ""}`.trim(); var ui = (baseClass, additionalClassOrFn) => typeof additionalClassOrFn === "function" ? () => `${baseClass} ${additionalClassOrFn() || ""}`.trim() : `${baseClass} ${additionalClassOrFn || ""}`.trim();
var getIcon = (icon) => { var getIcon = (icon) => {
@@ -516,6 +589,10 @@
}; };
// src/components/Alert.js // src/components/Alert.js
var exports_Alert = {};
__export(exports_Alert, {
Alert: () => Alert
});
var Alert = (props, children) => { var Alert = (props, children) => {
const { class: className, actions, type = "info", soft = true, ...rest } = props; const { class: className, actions, type = "info", soft = true, ...rest } = props;
const iconMap = { const iconMap = {
@@ -543,6 +620,12 @@
].filter(Boolean)); ].filter(Boolean));
}; };
// src/components/Autocomplete.js
var exports_Autocomplete = {};
__export(exports_Autocomplete, {
Autocomplete: () => Autocomplete
});
// src/core/i18n.js // src/core/i18n.js
var i18n = { var i18n = {
es: { es: {
@@ -566,6 +649,10 @@
var tt = (t) => () => i18n[currentLocale()][t] || t; var tt = (t) => () => i18n[currentLocale()][t] || t;
// src/components/Input.js // src/components/Input.js
var exports_Input = {};
__export(exports_Input, {
Input: () => Input
});
var Input = (props) => { var Input = (props) => {
const { const {
class: className, class: className,
@@ -724,6 +811,10 @@
}; };
// src/components/Badge.js // src/components/Badge.js
var exports_Badge = {};
__export(exports_Badge, {
Badge: () => Badge
});
var Badge = (props, children) => { var Badge = (props, children) => {
const { class: className, ...rest } = props; const { class: className, ...rest } = props;
return $html2("span", { return $html2("span", {
@@ -733,6 +824,10 @@
}; };
// src/components/Button.js // src/components/Button.js
var exports_Button = {};
__export(exports_Button, {
Button: () => Button
});
var Button = (props, children) => { var Button = (props, children) => {
const { class: className, loading, icon, ...rest } = props; const { class: className, loading, icon, ...rest } = props;
const iconEl = getIcon(icon); const iconEl = getIcon(icon);
@@ -748,6 +843,10 @@
}; };
// src/components/Checkbox.js // src/components/Checkbox.js
var exports_Checkbox = {};
__export(exports_Checkbox, {
Checkbox: () => Checkbox
});
var Checkbox = (props) => { var Checkbox = (props) => {
const { class: className, value, tooltip, toggle, label, ...rest } = props; const { class: className, value, tooltip, toggle, label, ...rest } = props;
const checkEl = $html2("input", { const checkEl = $html2("input", {
@@ -764,6 +863,10 @@
}; };
// src/components/Colorpicker.js // src/components/Colorpicker.js
var exports_Colorpicker = {};
__export(exports_Colorpicker, {
Colorpicker: () => Colorpicker
});
var Colorpicker = (props) => { var Colorpicker = (props) => {
const { class: className, value, label, ...rest } = props; const { class: className, value, label, ...rest } = props;
const isOpen = $(false); const isOpen = $(false);
@@ -821,6 +924,10 @@
}; };
// src/components/Datepicker.js // src/components/Datepicker.js
var exports_Datepicker = {};
__export(exports_Datepicker, {
Datepicker: () => Datepicker
});
var Datepicker = (props) => { var Datepicker = (props) => {
const { class: className, value, range, label, placeholder, hour = false, ...rest } = props; const { class: className, value, range, label, placeholder, hour = false, ...rest } = props;
const isOpen = $(false); const isOpen = $(false);
@@ -1027,6 +1134,10 @@
}; };
// src/components/Drawer.js // src/components/Drawer.js
var exports_Drawer = {};
__export(exports_Drawer, {
Drawer: () => Drawer
});
var Drawer = (props, children) => { var Drawer = (props, children) => {
const { class: className, id, open, side, content, ...rest } = props; const { class: className, id, open, side, content, ...rest } = props;
const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`; const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`;
@@ -1064,6 +1175,10 @@
}; };
// src/components/Dropdown.js // src/components/Dropdown.js
var exports_Dropdown = {};
__export(exports_Dropdown, {
Dropdown: () => Dropdown
});
var currentOpen = null; var currentOpen = null;
if (typeof window !== "undefined" && !window.__dropdownHandlerRegistered) { if (typeof window !== "undefined" && !window.__dropdownHandlerRegistered) {
window.addEventListener("click", (e) => { window.addEventListener("click", (e) => {
@@ -1126,6 +1241,10 @@
}; };
// src/components/Fab.js // src/components/Fab.js
var exports_Fab = {};
__export(exports_Fab, {
Fab: () => Fab
});
var Fab = (props) => { var Fab = (props) => {
const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props;
return $html2("div", { return $html2("div", {
@@ -1155,6 +1274,10 @@
}; };
// src/components/Fieldset.js // src/components/Fieldset.js
var exports_Fieldset = {};
__export(exports_Fieldset, {
Fieldset: () => Fieldset
});
var Fieldset = (props, children) => { var Fieldset = (props, children) => {
const { class: className, legend, ...rest } = props; const { class: className, legend, ...rest } = props;
return $html2("fieldset", { return $html2("fieldset", {
@@ -1170,6 +1293,10 @@
}; };
// src/components/Fileinput.js // src/components/Fileinput.js
var exports_Fileinput = {};
__export(exports_Fileinput, {
Fileinput: () => Fileinput
});
var Fileinput = (props) => { var Fileinput = (props) => {
const { class: className, tooltip, max = 2, accept = "*", onSelect, ...rest } = props; const { class: className, tooltip, max = 2, accept = "*", onSelect, ...rest } = props;
const selectedFiles = $([]); const selectedFiles = $([]);
@@ -1252,6 +1379,10 @@
}; };
// src/components/Indicator.js // src/components/Indicator.js
var exports_Indicator = {};
__export(exports_Indicator, {
Indicator: () => Indicator
});
var Indicator = (props, children) => { var Indicator = (props, children) => {
const { value, class: className, ...rest } = props; const { value, class: className, ...rest } = props;
return $html2("div", { return $html2("div", {
@@ -1266,6 +1397,10 @@
}; };
// src/components/Label.js // src/components/Label.js
var exports_Label = {};
__export(exports_Label, {
Label: () => Label
});
var Label = (props) => { var Label = (props) => {
const { children, value, floating = false, error, required, class: className, ...rest } = props; const { children, value, floating = false, error, required, class: className, ...rest } = props;
if (floating) { if (floating) {
@@ -1283,6 +1418,10 @@
}; };
// src/components/List.js // src/components/List.js
var exports_List = {};
__export(exports_List, {
List: () => List
});
var List = (props) => { var List = (props) => {
const { class: className, items, header, render, keyFn = (item, index) => item.id ?? index, ...rest } = props; const { class: className, items, header, render, keyFn = (item, index) => item.id ?? index, ...rest } = props;
const listItems = $for(items, (item, index) => $html2("li", { class: "list-row" }, [render(item, index)]), keyFn); const listItems = $for(items, (item, index) => $html2("li", { class: "list-row" }, [render(item, index)]), keyFn);
@@ -1293,6 +1432,10 @@
}; };
// src/components/Menu.js // src/components/Menu.js
var exports_Menu = {};
__export(exports_Menu, {
Menu: () => Menu
});
var Menu = (props) => { var Menu = (props) => {
const { class: className, items, ...rest } = props; const { class: className, items, ...rest } = props;
const renderItems = (items2) => $for(() => items2 || [], (it) => $html2("li", {}, [ const renderItems = (items2) => $for(() => items2 || [], (it) => $html2("li", {}, [
@@ -1308,6 +1451,10 @@
}; };
// src/components/Modal.js // src/components/Modal.js
var exports_Modal = {};
__export(exports_Modal, {
Modal: () => Modal
});
var Modal = (props, children) => { var Modal = (props, children) => {
const { class: className, title, buttons, open, ...rest } = props; const { class: className, title, buttons, open, ...rest } = props;
let dialogElement = null; let dialogElement = null;
@@ -1358,12 +1505,20 @@
}; };
// src/components/Navbar.js // src/components/Navbar.js
var exports_Navbar = {};
__export(exports_Navbar, {
Navbar: () => Navbar
});
var Navbar = (props, children) => { var Navbar = (props, children) => {
const { class: className, ...rest } = props; const { class: className, ...rest } = props;
return $html2("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children); return $html2("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children);
}; };
// src/components/Radio.js // src/components/Radio.js
var exports_Radio = {};
__export(exports_Radio, {
Radio: () => Radio
});
var Radio = (props) => { var Radio = (props) => {
const { class: className, label, tooltip, value, inputValue, name, ...rest } = props; const { class: className, label, tooltip, value, inputValue, name, ...rest } = props;
const radioEl = $html2("input", { const radioEl = $html2("input", {
@@ -1387,6 +1542,10 @@
}; };
// src/components/Range.js // src/components/Range.js
var exports_Range = {};
__export(exports_Range, {
Range: () => Range
});
var Range = (props) => { var Range = (props) => {
const { class: className, label, tooltip, value, ...rest } = props; const { class: className, label, tooltip, value, ...rest } = props;
const rangeEl = $html2("input", { const rangeEl = $html2("input", {
@@ -1406,6 +1565,10 @@
}; };
// src/components/Rating.js // src/components/Rating.js
var exports_Rating = {};
__export(exports_Rating, {
Rating: () => Rating
});
var Rating = (props) => { var Rating = (props) => {
const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props; const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props;
const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`; const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`;
@@ -1433,6 +1596,10 @@
}; };
// src/components/Select.js // src/components/Select.js
var exports_Select = {};
__export(exports_Select, {
Select: () => Select
});
var Select = (props) => { var Select = (props) => {
const { class: className, label, items, value, ...rest } = props; const { class: className, label, items, value, ...rest } = props;
const selectEl = $html2("select", { const selectEl = $html2("select", {
@@ -1452,12 +1619,20 @@
}; };
// src/components/Stack.js // src/components/Stack.js
var exports_Stack = {};
__export(exports_Stack, {
Stack: () => Stack
});
var Stack = (props, children) => { var Stack = (props, children) => {
const { class: className, ...rest } = props; const { class: className, ...rest } = props;
return $html2("div", { ...rest, class: ui("stack", className) }, children); return $html2("div", { ...rest, class: ui("stack", className) }, children);
}; };
// src/components/Stat.js // src/components/Stat.js
var exports_Stat = {};
__export(exports_Stat, {
Stat: () => Stat
});
var Stat = (props) => { var Stat = (props) => {
const { class: className, icon, label, value, desc, ...rest } = props; const { class: className, icon, label, value, desc, ...rest } = props;
return $html2("div", { ...rest, class: ui("stat", className) }, [ return $html2("div", { ...rest, class: ui("stat", className) }, [
@@ -1469,6 +1644,10 @@
}; };
// src/components/Swap.js // src/components/Swap.js
var exports_Swap = {};
__export(exports_Swap, {
Swap: () => Swap
});
var Swap = (props) => { var Swap = (props) => {
const { class: className, value, on, off, ...rest } = props; const { class: className, value, on, off, ...rest } = props;
return $html2("label", { ...rest, class: ui("swap", className) }, [ return $html2("label", { ...rest, class: ui("swap", className) }, [
@@ -1487,6 +1666,10 @@
}; };
// src/components/Table.js // src/components/Table.js
var exports_Table = {};
__export(exports_Table, {
Table: () => Table
});
var Table = (props) => { var Table = (props) => {
const { class: className, items = [], columns = [], keyFn, zebra = false, pinRows = false, empty = tt("nodata")(), ...rest } = props; const { class: className, items = [], columns = [], keyFn, zebra = false, pinRows = false, empty = tt("nodata")(), ...rest } = props;
const tableClass = () => { const tableClass = () => {
@@ -1528,6 +1711,10 @@
}; };
// src/components/Tabs.js // src/components/Tabs.js
var exports_Tabs = {};
__export(exports_Tabs, {
Tabs: () => Tabs
});
var Tabs = (props) => { var Tabs = (props) => {
const { items, class: className, ...rest } = props; const { items, class: className, ...rest } = props;
const itemsSignal = typeof items === "function" ? items : () => items || []; const itemsSignal = typeof items === "function" ? items : () => items || [];
@@ -1584,6 +1771,10 @@
}; };
// src/components/Timeline.js // src/components/Timeline.js
var exports_Timeline = {};
__export(exports_Timeline, {
Timeline: () => Timeline
});
var Timeline = (props) => { var Timeline = (props) => {
const { class: className, items = [], vertical = true, compact = false, ...rest } = props; const { class: className, items = [], vertical = true, compact = false, ...rest } = props;
const iconMap = { const iconMap = {
@@ -1618,6 +1809,10 @@
}; };
// src/components/Toast.js // src/components/Toast.js
var exports_Toast = {};
__export(exports_Toast, {
Toast: () => Toast
});
var Toast = (message, type = "alert-success", duration = 3500) => { var Toast = (message, type = "alert-success", duration = 3500) => {
let container = document.getElementById("sigpro-toast-container"); let container = document.getElementById("sigpro-toast-container");
if (!container) { if (!container) {
@@ -1668,9 +1863,68 @@
}; };
// src/components/Tooltip.js // src/components/Tooltip.js
var exports_Tooltip = {};
__export(exports_Tooltip, {
Tooltip: () => Tooltip
});
var Tooltip = (props, children) => $html2("div", { var Tooltip = (props, children) => $html2("div", {
...props, ...props,
class: () => ui("tooltip", props.ui, props.class), class: () => ui("tooltip", props.ui, props.class),
"data-tip": props.tip "data-tip": props.tip
}, children); }, children);
// src/components/index.js
var Components = {
...exports_Accordion,
...exports_Alert,
...exports_Autocomplete,
...exports_Badge,
...exports_Button,
...exports_Checkbox,
...exports_Colorpicker,
...exports_Datepicker,
...exports_Drawer,
...exports_Dropdown,
...exports_Fab,
...exports_Fieldset,
...exports_Fileinput,
...exports_Indicator,
...exports_Input,
...exports_Label,
...exports_List,
...exports_Menu,
...exports_Modal,
...exports_Navbar,
...exports_Radio,
...exports_Range,
...exports_Rating,
...exports_Select,
...exports_Stack,
...exports_Stat,
...exports_Swap,
...exports_Table,
...exports_Tabs,
...exports_Timeline,
...exports_Toast,
...exports_Tooltip
};
var components_default = {
...Components,
install: (target = window) => {
Object.entries(Components).forEach(([name, component]) => {
target[name] = component;
});
console.log("\uD83D\uDE80 SigproUI");
}
};
// index.js
if (typeof window !== "undefined") {
Object.entries(exports_components).forEach(([name, component]) => {
window[name] = component;
});
window.Utils = exports_utils;
window.tt = tt;
window.SigProUI = { ...exports_components, Utils: exports_utils, tt };
console.log("\uD83C\uDFA8 SigProUI ready");
}
})(); })();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,10 +1,21 @@
// index.js // index.js
import './src/sigpro.js'; // El Core import './src/sigpro.js';
import * as Components from './src/components/index.js'; import * as Components from './src/components/index.js';
import * as Utils from './src/core/utils.js'; import * as Utils from './src/core/utils.js';
import { tt } from './src/core/i18n.js'; import { tt } from './src/core/i18n.js';
// Exportamos todo para que el Tree Shaking funcione
export * from './src/components/index.js'; export * from './src/components/index.js';
export * from './src/core/utils.js'; export * from './src/core/utils.js';
export { tt }; export { tt };
if (typeof window !== 'undefined') {
Object.entries(Components).forEach(([name, component]) => {
window[name] = component;
});
window.Utils = Utils;
window.tt = tt;
window.SigProUI = { ...Components, Utils, tt };
console.log("🎨 SigProUI ready");
}

View File

@@ -1,6 +1,6 @@
{ {
"name": "sigpro-ui", "name": "sigpro-ui",
"version": "1.1.2", "version": "1.1.4",
"main": "./index.js", "main": "./index.js",
"module": "./index.js", "module": "./index.js",
"devDependencies": { "devDependencies": {

View File

@@ -1,23 +0,0 @@
// src/bundle.js
import './sigpro.js'; // Ahora sí, están en la misma carpeta
import * as Components from './components/index.js';
import * as Utils from './core/utils.js';
import { tt } from './core/i18n.js';
if (typeof window !== 'undefined') {
// Registramos funciones globales: Div(), Input(), tt()...
Object.entries(Components).forEach(([name, component]) => {
window[name] = component;
});
window.Utils = Utils;
window.tt = tt;
window.SigProUI = { ...Components, Utils, tt };
console.log("🎨 SigProUI (Global Mode) ready");
}
// Re-exportamos por compatibilidad
export * from './components/index.js';
export * from './core/utils.js';
export { tt };

View File

@@ -7,7 +7,6 @@ const effectQueue = new Set();
let isFlushing = false; let isFlushing = false;
const MOUNTED_NODES = new WeakMap(); const MOUNTED_NODES = new WeakMap();
/** flush */
const flush = () => { const flush = () => {
if (isFlushing) return; if (isFlushing) return;
isFlushing = true; isFlushing = true;
@@ -19,7 +18,6 @@ const flush = () => {
isFlushing = false; isFlushing = false;
}; };
/** track */
const track = (subs) => { const track = (subs) => {
if (activeEffect && !activeEffect._deleted) { if (activeEffect && !activeEffect._deleted) {
subs.add(activeEffect); subs.add(activeEffect);
@@ -27,7 +25,6 @@ const track = (subs) => {
} }
}; };
/** trigger */
const trigger = (subs) => { const trigger = (subs) => {
for (const eff of subs) { for (const eff of subs) {
if (eff === activeEffect || eff._deleted) continue; if (eff === activeEffect || eff._deleted) continue;
@@ -41,7 +38,6 @@ const trigger = (subs) => {
if (!isFlushing) queueMicrotask(flush); if (!isFlushing) queueMicrotask(flush);
}; };
/** sweep */
const sweep = (node) => { const sweep = (node) => {
if (node._cleanups) { if (node._cleanups) {
node._cleanups.forEach((f) => f()); node._cleanups.forEach((f) => f());
@@ -50,7 +46,6 @@ const sweep = (node) => {
node.childNodes?.forEach(sweep); node.childNodes?.forEach(sweep);
}; };
/** _view */
const _view = (fn) => { const _view = (fn) => {
const cleanups = new Set(); const cleanups = new Set();
const prev = currentOwner; const prev = currentOwner;
@@ -80,17 +75,6 @@ const _view = (fn) => {
}; };
}; };
/**
* Creates a reactive Signal or a Computed Value.
* @param {any|Function} initial - Initial value or a getter function for computed state.
* @param {string} [key] - Optional. Key for automatic persistence in localStorage.
* @returns {Function} Signal getter/setter. Use `sig()` to read and `sig(val)` to write.
* @example
* const count = $(0); // Simple signal
* const double = $(() => count() * 2); // Computed signal
* const name = $("John", "user-name"); // Persisted signal
*/
const $ = (initial, key = null) => { const $ = (initial, key = null) => {
if (typeof initial === "function") { if (typeof initial === "function") {
const subs = new Set(); const subs = new Set();
@@ -148,16 +132,39 @@ const $ = (initial, key = null) => {
}; };
}; };
/** const $$ = (obj, cache = new WeakMap()) => {
* Watches for signal changes and executes a side effect. if (typeof obj !== "object" || obj === null) return obj;
* Handles automatic cleanup of previous effects. if (cache.has(obj)) return cache.get(obj);
* @param {Function|Array} target - Function to execute or Array of signals for explicit dependency tracking.
* @param {Function} [fn] - If the first parameter is an Array, this is the callback function. const subs = {};
* @returns {Function} Function to manually stop the watcher.
* @example const proxy = new Proxy(obj, {
* $watch(() => console.log("Count is:", count())); get(target, key) {
* $watch([count], () => console.log("Only runs when count changes")); if (activeEffect)
*/ track(subs[key] ??= new Set());
const value = Reflect.get(target, key);
return (typeof value === "object" && value !== null)
? $$(value, cache)
: value;
},
set(target, key, value) {
if (Object.is(target[key], value)) return true;
const res = Reflect.set(target, key, value);
if (subs[key])
trigger(subs[key]);
return res;
}
});
cache.set(obj, proxy);
return proxy;
};
const $watch = (target, fn) => { const $watch = (target, fn) => {
const isExplicit = Array.isArray(target); const isExplicit = Array.isArray(target);
@@ -212,28 +219,25 @@ const $watch = (target, fn) => {
return runner.stop; return runner.stop;
}; };
/**
* DOM element rendering engine with built-in reactivity.
* @param {string} tag - HTML tag name (e.g., 'div', 'span').
* @param {Object} [props] - Attributes, events (onEvent), or two-way bindings (value, checked).
* @param {Array|any} [content] - Children: text, other nodes, or reactive signals.
* @returns {HTMLElement} The configured reactive DOM element.
*/
const $html = (tag, props = {}, content = []) => { const $html = (tag, props = {}, content = []) => {
if (props instanceof Node || Array.isArray(props) || typeof props !== "object") { if (props instanceof Node || Array.isArray(props) || typeof props !== "object") {
content = props; props = {}; content = props; props = {};
} }
const el = document.createElement(tag),
_sanitize = (key, val) => (key === 'src' || key === 'href') && String(val).toLowerCase().includes('javascript:') ? '#' : val; const svgTags = ["svg", "path", "circle", "rect", "line", "polyline", "polygon", "g", "defs", "text", "tspan", "use"];
const isSVG = svgTags.includes(tag);
const el = isSVG
? document.createElementNS("http://www.w3.org/2000/svg", tag)
: document.createElement(tag);
const _sanitize = (key, val) => (key === 'src' || key === 'href') && String(val).toLowerCase().includes('javascript:') ? '#' : val;
el._cleanups = new Set(); el._cleanups = new Set();
const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"]; const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"];
for (let [key, val] of Object.entries(props)) { for (let [key, val] of Object.entries(props)) {
if (key === "ref") { (typeof val === "function" ? val(el) : (val.current = el)); continue; } if (key === "ref") { (typeof val === "function" ? val(el) : (val.current = el)); continue; }
const isSignal = typeof val === "function", const isSignal = typeof val === "function", isInput = ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName), isBindAttr = (key === "value" || key === "checked");
isInput = ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName),
isBindAttr = (key === "value" || key === "checked");
if (isInput && isBindAttr && isSignal) { if (isInput && isBindAttr && isSignal) {
el._cleanups.add($watch(() => { const currentVal = val(); if (el[key] !== currentVal) el[key] = currentVal; })); el._cleanups.add($watch(() => { const currentVal = val(); if (el[key] !== currentVal) el[key] = currentVal; }));
@@ -258,7 +262,13 @@ const $html = (tag, props = {}, content = []) => {
el[key] = false; el[key] = false;
} }
} else { } else {
currentVal == null ? el.removeAttribute(key) : el.setAttribute(key, currentVal); if (currentVal == null) {
el.removeAttribute(key);
} else if (isSVG && typeof currentVal === 'number') {
el.setAttribute(key, currentVal);
} else {
el.setAttribute(key, currentVal);
}
} }
})); }));
} else { } else {
@@ -298,42 +308,41 @@ const $html = (tag, props = {}, content = []) => {
return el; return el;
}; };
/** const $if = (condition, thenVal, otherwiseVal = null, transition = null) => {
* Conditional rendering component.
* @param {Function|boolean} condition - Reactive signal or boolean value.
* @param {Function|HTMLElement} thenVal - Content to show if true.
* @param {Function|HTMLElement} [otherwiseVal] - Content to show if false (optional).
* @returns {HTMLElement} A reactive container (display: contents).
*/
const $if = (condition, thenVal, otherwiseVal = null) => {
const marker = document.createTextNode(""); const marker = document.createTextNode("");
const container = $html("div", { style: "display:contents" }, [marker]); const container = $html("div", { style: "display:contents" }, [marker]);
let current = null, last = null; let current = null, last = null;
$watch(() => { $watch(() => {
const state = !!(typeof condition === "function" ? condition() : condition); const state = !!(typeof condition === "function" ? condition() : condition);
if (state !== last) { if (state === last) return;
last = state; last = state;
if (current && !state && transition?.out) {
transition.out(current.container, () => {
current.destroy();
current = null;
});
} else {
if (current) current.destroy(); if (current) current.destroy();
current = null;
}
if (state || (!state && otherwiseVal)) {
const branch = state ? thenVal : otherwiseVal; const branch = state ? thenVal : otherwiseVal;
if (branch) { if (branch) {
current = _view(() => typeof branch === "function" ? branch() : branch); current = _view(() => typeof branch === "function" ? branch() : branch);
container.insertBefore(current.container, marker); container.insertBefore(current.container, marker);
if (state && transition?.in) transition.in(current.container);
} }
} }
}); });
return container; return container;
}; };
$if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal); $if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal);
/**
* Optimized reactive loop with key-based reconciliation.
* @param {Function|Array} source - Signal containing an Array of data.
* @param {Function} render - Function receiving (item, index) and returning a node.
* @param {Function} keyFn - Function to extract a unique key from the item.
* @returns {HTMLElement} A reactive container (display: contents).
*/
const $for = (source, render, keyFn, tag = "div", props = { style: "display:contents" }) => { const $for = (source, render, keyFn, tag = "div", props = { style: "display:contents" }) => {
const marker = document.createTextNode(""); const marker = document.createTextNode("");
const container = $html(tag, props, [marker]); const container = $html(tag, props, [marker]);
@@ -379,11 +388,6 @@ const $for = (source, render, keyFn, tag = "div", props = { style: "display:cont
return container; return container;
}; };
/**
* Hash-based (#) routing system.
* @param {Array<{path: string, component: Function}>} routes - Route definitions.
* @returns {HTMLElement} The router outlet container.
*/
const $router = (routes) => { const $router = (routes) => {
const sPath = $(window.location.hash.replace(/^#/, "") || "/"); const sPath = $(window.location.hash.replace(/^#/, "") || "/");
window.addEventListener("hashchange", () => sPath(window.location.hash.replace(/^#/, "") || "/")); window.addEventListener("hashchange", () => sPath(window.location.hash.replace(/^#/, "") || "/"));
@@ -429,21 +433,6 @@ $router.to = (path) => (window.location.hash = path.replace(/^#?\/?/, "#/"));
$router.back = () => window.history.back(); $router.back = () => window.history.back();
$router.path = () => window.location.hash.replace(/^#/, "") || "/"; $router.path = () => window.location.hash.replace(/^#/, "") || "/";
/**
* Mounts a component or node into a DOM target element.
* It automatically handles the cleanup of any previously mounted SigPro instances
* in that target to prevent memory leaks and duplicate renders.
* * @param {Function|HTMLElement} component - The component function to render or a pre-built DOM node.
* @param {string|HTMLElement} target - A CSS selector string or a direct DOM element to mount into.
* @returns {Object|undefined} The view instance containing the `container` and `destroy` method, or undefined if target is not found.
* * @example
* // Mount using a component function
* $mount(() => Div({ class: "app" }, "Hello World"), "#root");
* * // Mount using a direct element
* const myApp = Div("Hello");
* $mount(myApp, document.getElementById("app"));
*/
const $mount = (component, target) => { const $mount = (component, target) => {
const el = typeof target === "string" ? document.querySelector(target) : target; const el = typeof target === "string" ? document.querySelector(target) : target;
if (!el) return; if (!el) return;
@@ -454,8 +443,9 @@ const $mount = (component, target) => {
return instance; return instance;
}; };
/** GLOBAL CORE REGISTRY */ export const Fragment = ({ children }) => children;
const SigProCore = { $, $watch, $html, $if, $for, $router, $mount };
const SigProCore = { $, $watch, $html, $if, $for, $router, $mount, Fragment };
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
const install = (registry) => { const install = (registry) => {
@@ -471,6 +461,7 @@ if (typeof window !== "undefined") {
} }
}); });
window.Fragment = Fragment;
window.SigPro = Object.freeze(registry); window.SigPro = Object.freeze(registry);
}; };