Migrating new components
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 3s

This commit is contained in:
2026-04-20 23:31:14 +02:00
parent 6fc32614b1
commit d900659d88
59 changed files with 1824 additions and 1554 deletions

9
components/Button.js Normal file
View File

@@ -0,0 +1,9 @@
import { Tag } from "sigpro";
export const Button = (props, children) => {
const { class: className, ...rest } = props;
return Tag("button", {
...rest,
class: `btn ${className || ''}`.trim()
}, children);
};

83
components/Colorpicker.js Normal file
View File

@@ -0,0 +1,83 @@
// components/Colorpicker.js
import { $, Tag, If } from "sigpro";
export const Colorpicker = (props) => {
const { class: className, value, label, ...rest } = props;
const isOpen = $(false);
const palette = [
...["#000", "#1A1A1A", "#333", "#4D4D4D", "#666", "#808080", "#B3B3B3", "#FFF"],
...["#450a0a", "#7f1d1d", "#991b1b", "#b91c1c", "#dc2626", "#ef4444", "#f87171", "#fca5a5"],
...["#431407", "#7c2d12", "#9a3412", "#c2410c", "#ea580c", "#f97316", "#fb923c", "#ffedd5"],
...["#713f12", "#a16207", "#ca8a04", "#eab308", "#facc15", "#fde047", "#fef08a", "#fff9c4"],
...["#064e3b", "#065f46", "#059669", "#10b981", "#34d399", "#4ade80", "#84cc16", "#d9f99d"],
...["#082f49", "#075985", "#0284c7", "#0ea5e9", "#38bdf8", "#7dd3fc", "#22d3ee", "#cffafe"],
...["#1e1b4b", "#312e81", "#4338ca", "#4f46e5", "#6366f1", "#818cf8", "#a5b4fc", "#e0e7ff"],
...["#2e1065", "#4c1d95", "#6d28d9", "#7c3aed", "#8b5cf6", "#a855f7", "#d946ef", "#fae8ff"],
];
const getColor = () => {
const v = value;
return (typeof v === "function" ? v() : v) || "#000000";
};
return Tag("div", { class: `relative w-fit ${className || ''}`.trim() }, [
Tag(
"button",
{
type: "button",
class: "btn px-3 bg-base-100 border-base-300 hover:border-primary/50 flex items-center gap-2 shadow-sm font-normal normal-case",
onclick: (e) => {
e.stopPropagation();
isOpen(!isOpen());
},
...rest,
},
[
Tag("div", {
class: "size-5 rounded-sm shadow-inner border border-black/10 shrink-0",
style: () => `background-color: ${getColor()}`,
}),
label ? Tag("span", { class: "opacity-80" }, label) : null,
],
),
If(isOpen, () =>
Tag(
"div",
{
class: "absolute left-0 mt-2 p-3 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[110] w-64 select-none",
onclick: (e) => e.stopPropagation(),
},
[
Tag(
"div",
{ class: "grid grid-cols-8 gap-1" },
palette.map((c) =>
Tag("button", {
type: "button",
style: `background-color: ${c}`,
class: () => {
const active = getColor().toLowerCase() === c.toLowerCase();
return `size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 p-0 min-h-0
${active ? "ring-2 ring-offset-1 ring-primary z-10 scale-110" : ""}`;
},
onclick: () => {
if (typeof value === "function") value(c);
isOpen(false);
},
}),
),
),
],
),
),
If(isOpen, () =>
Tag("div", {
class: "fixed inset-0 z-[100]",
onclick: () => isOpen(false),
}),
),
]);
};

7
components/Icon.js Normal file
View File

@@ -0,0 +1,7 @@
// components/Icon.js
import { Tag } from "sigpro";
export const Icon = (iconClass) => {
if (!iconClass) return null;
return Tag("span", { class: iconClass });
};

10
components/Input.js Normal file
View File

@@ -0,0 +1,10 @@
import { Tag } from "sigpro";
export const Input = (props) => {
const { class: className, type = "text", ...rest } = props;
return Tag("input", {
...rest,
type,
class: `input ${className || ''}`.trim()
});
};

View File

@@ -1,4 +1,4 @@
// components/Spinner.js
// components/Loading.js
import { Tag } from "sigpro";
export const Spinner = (props) => {

25
components/Select.js Normal file
View File

@@ -0,0 +1,25 @@
// components/Select.js
import { Tag, For } from "sigpro";
export const Select = (props, children) => {
const { class: className, ...rest } = props;
return Tag("select", {
...rest,
class: `select ${className || ''}`.trim()
}, children);
};
export const Options = (props) => {
const { items, placeholder, placeholderDisabled = true, ...rest } = props;
const itemArray = typeof items === "function" ? items() : (items || []);
return [
placeholder && Tag("option", { disabled: placeholderDisabled, selected: true }, placeholder),
For(itemArray, (item) => {
const val = typeof item === "string" ? item : item.value;
const label = typeof item === "string" ? item : item.label;
return Tag("option", { value: val, ...rest }, label);
})
];
};

27
components/Stat.js Normal file
View File

@@ -0,0 +1,27 @@
// components/Stats.js
import { Tag } from "sigpro";
export const Stats = (props, children) => {
const { class: className, vertical = false, ...rest } = props;
const direction = vertical ? "stats-vertical" : "stats-horizontal";
return Tag("div", {
...rest,
class: `stats ${direction} ${className || ''}`.trim()
}, children);
};
export const Stat = (props) => {
const { class: className, label, value, desc, icon, actions, children, ...rest } = props;
if (children !== undefined) {
return Tag("div", { ...rest, class: `stat ${className || ''}`.trim() }, children);
}
return Tag("div", { ...rest, class: `stat ${className || ''}`.trim() }, [
icon && Tag("div", { class: "stat-figure" }, icon),
label && Tag("div", { class: "stat-title" }, label),
value && Tag("div", { class: "stat-value" }, value),
desc && Tag("div", { class: "stat-desc" }, desc),
actions && Tag("div", { class: "stat-actions" }, actions)
]);
};

9
components/Textarea.js Normal file
View File

@@ -0,0 +1,9 @@
import { Tag } from "sigpro";
export const Textarea = (props) => {
const { class: className, ...rest } = props;
return Tag("textarea", {
...rest,
class: `textarea ${className || ''}`.trim()
});
};

1289
dist/sigpro-ui.esm.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1287
dist/sigpro-ui.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

248
dist/sigpro.css vendored
View File

@@ -1500,6 +1500,42 @@
}
}
}
.radial-progress {
@layer daisyui.l1.l2.l3 {
position: relative;
display: inline-grid;
height: var(--size);
width: var(--size);
place-content: center;
border-radius: calc(infinity * 1px);
background-color: transparent;
vertical-align: middle;
box-sizing: content-box;
--value: 0;
--size: 5rem;
--thickness: calc(var(--size) / 10);
--radialprogress: calc(var(--value) * 1%);
transition: --radialprogress 0.3s linear;
&:before {
position: absolute;
inset: calc(0.25rem * 0);
border-radius: calc(infinity * 1px);
content: "";
background: radial-gradient(farthest-side, currentColor 98%, #0000) top/var(--thickness) var(--thickness) no-repeat, conic-gradient(currentColor var(--radialprogress), #0000 0);
webkit-mask: radial-gradient( farthest-side, #0000 calc(100% - var(--thickness)), #000 calc(100% + 0.5px - var(--thickness)) );
mask: radial-gradient( farthest-side, #0000 calc(100% - var(--thickness)), #000 calc(100% + 0.5px - var(--thickness)) );
}
&:after {
position: absolute;
border-radius: calc(infinity * 1px);
background-color: currentcolor;
transition: transform 0.3s linear;
content: "";
inset: calc(50% - var(--thickness) / 2);
transform: rotate(calc(var(--value) * 3.6deg - 90deg)) translate(calc(var(--size) / 2 - 50%));
}
}
}
.list {
@layer daisyui.l1.l2.l3 {
display: flex;
@@ -2134,6 +2170,34 @@
}
}
}
.chat-bubble {
@layer daisyui.l1.l2.l3 {
position: relative;
display: block;
width: fit-content;
border-radius: var(--radius-field);
background-color: var(--color-base-300);
padding-inline: calc(0.25rem * 4);
padding-block: calc(0.25rem * 2);
color: var(--color-base-content);
grid-row-end: 3;
min-height: 2rem;
min-width: 2.5rem;
max-width: 90%;
&:before {
position: absolute;
bottom: calc(0.25rem * 0);
height: calc(0.25rem * 3);
width: calc(0.25rem * 3);
background-color: inherit;
content: "";
mask-repeat: no-repeat;
mask-image: var(--mask-chat);
mask-position: 0px -1px;
mask-size: 0.8125rem;
}
}
}
.select {
@layer daisyui.l1.l2.l3 {
border: var(--border) solid #0000;
@@ -3689,6 +3753,12 @@
font-size: 0.75rem;
}
}
.stat-actions {
@layer daisyui.l1.l2.l3 {
grid-column-start: 1;
white-space: nowrap;
}
}
.col-start-1 {
grid-column-start: 1;
}
@@ -3698,6 +3768,28 @@
.col-start-3 {
grid-column-start: 3;
}
.chat-image {
@layer daisyui.l1.l2.l3 {
grid-row: span 2 / span 2;
align-self: flex-end;
}
}
.chat-footer {
@layer daisyui.l1.l2.l3 {
grid-row-start: 3;
display: flex;
gap: calc(0.25rem * 1);
font-size: 0.6875rem;
}
}
.chat-header {
@layer daisyui.l1.l2.l3 {
grid-row-start: 1;
display: flex;
gap: calc(0.25rem * 1);
font-size: 0.6875rem;
}
}
.row-start-2 {
grid-row-start: 2;
}
@@ -3973,6 +4065,14 @@
.ml-6 {
margin-left: calc(var(--spacing) * 6);
}
.carousel-item {
@layer daisyui.l1.l2.l3 {
box-sizing: content-box;
display: flex;
flex: none;
scroll-snap-align: start;
}
}
.status {
@layer daisyui.l1.l2.l3 {
display: inline-block;
@@ -4293,6 +4393,78 @@
mask-size: 100% 100%;
--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M18 6L6 18M6 6l12 12'/%3E%3C/svg%3E");
}
.kbd {
box-shadow: none;
@layer daisyui.l1.l2.l3 {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-field);
background-color: var(--color-base-200);
vertical-align: middle;
padding-inline: 0.5em;
border: var(--border) solid var(--color-base-content);
@supports (color: color-mix(in lab, red, red)) {
border: var(--border) solid color-mix(in srgb, var(--color-base-content) 20%, #0000);
}
border-bottom: calc(var(--border) + 1px) solid var(--color-base-content);
@supports (color: color-mix(in lab, red, red)) {
border-bottom: calc(var(--border) + 1px) solid color-mix(in srgb, var(--color-base-content) 20%, #0000);
}
--size: calc(var(--size-selector, 0.25rem) * 6);
font-size: 0.875rem;
height: var(--size);
min-width: var(--size);
}
}
.text-rotate {
height: 1lh;
@layer daisyui.l1.l2.l3 {
display: inline-block;
overflow: hidden;
vertical-align: bottom;
white-space: nowrap;
transition-property: none;
--duration: var(--tw-duration);
> * {
display: grid;
justify-items: start;
height: calc(var(--items, 1) * 100%);
&:has(*:nth-child(2)) {
--items: 2;
animation: rotator var(--duration, 10s) linear(0 0% 49%, 0.5 50% 99%, 1 100% 100%) infinite;
}
&:has(*:nth-child(3)) {
--items: 3;
animation: rotator var(--duration, 10s) linear(0 0% 32%, 0.333333 33% 65%, 0.666666 66% 99%, 1 100% 100%) infinite;
}
&:has(*:nth-child(4)) {
--items: 4;
animation: rotator var(--duration, 10s) linear(0 0% 24%, 0.25 25% 49%, 0.5 50% 74%, 0.75 75% 99%, 1 100% 100%) infinite;
}
&:has(*:nth-child(5)) {
--items: 5;
animation: rotator var(--duration, 10s) linear(0 0% 19%, 0.2 20% 39%, 0.4 40% 59%, 0.6 60% 79%, 0.8 80% 99%, 1 100% 100%) infinite;
}
&:has(*:nth-child(6)) {
--items: 6;
animation: rotator var(--duration, 10s) linear( 0 0% 15%, 0.16666 16% 32%, 0.333333 33% 49%, 0.5 50% 65%, 0.666666 66% 82%, 0.833333 83% 99%, 1 100% 100% ) infinite;
}
> * {
align-content: baseline;
clip-path: inset(0.5px 0px 0.5px 0px);
&:nth-child(1) {
translate: var(--first-item-position);
}
}
}
&:hover {
> * {
animation-play-state: paused;
}
}
}
}
.tabs {
@layer daisyui.l1.l2.l3 {
display: flex;
@@ -4396,6 +4568,20 @@
}
}
}
.carousel {
@layer daisyui.l1.l2.l3 {
display: inline-flex;
overflow-x: scroll;
scroll-snap-type: x mandatory;
scrollbar-width: none;
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
&::-webkit-scrollbar {
display: none;
}
}
}
.alert {
border-width: var(--border);
border-color: var(--alert-border-color, var(--color-base-200));
@@ -4438,6 +4624,23 @@
grid-auto-rows: max-content;
}
}
.chat {
@layer daisyui.l1.l2.l3 {
display: grid;
grid-auto-rows: min-content;
column-gap: calc(0.25rem * 3);
padding-block: calc(0.25rem * 1);
--mask-chat: url("data:image/svg+xml,%3csvg width='13' height='13' xmlns='http://www.w3.org/2000/svg'%3e%3cpath fill='black' d='M0 11.5004C0 13.0004 2 13.0004 2 13.0004H12H13V0.00036329L12.5 0C12.5 0 11.977 2.09572 11.8581 2.50033C11.6075 3.35237 10.9149 4.22374 9 5.50036C6 7.50036 0 10.0004 0 11.5004Z'/%3e%3c/svg%3e");
}
}
.card-actions {
@layer daisyui.l1.l2.l3 {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: calc(0.25rem * 2);
}
}
.card-title {
@layer daisyui.l1.l2.l3 {
display: flex;
@@ -4557,6 +4760,9 @@
.h-3\.5 {
height: calc(var(--spacing) * 3.5);
}
.h-4 {
height: calc(var(--spacing) * 4);
}
.h-8 {
height: calc(var(--spacing) * 8);
}
@@ -4792,6 +4998,22 @@
.transform {
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
}
.skeleton {
@layer daisyui.l1.l2.l3 {
border-radius: var(--radius-box);
background-color: var(--color-base-300);
@media (prefers-reduced-motion: reduce) {
transition-duration: 15s;
}
will-change: background-position;
background-image: linear-gradient( 105deg, #0000 0% 40%, var(--color-base-100) 50%, #0000 60% 100% );
background-size: 200% auto;
background-position-x: -50%;
@media (prefers-reduced-motion: no-preference) {
animation: skeleton 1.8s ease-in-out infinite;
}
}
}
.animate-pulse {
animation: var(--animate-pulse);
}
@@ -4804,6 +5026,32 @@
.list-none {
list-style-type: none;
}
.stats-horizontal {
@layer daisyui.l1.l2 {
grid-auto-flow: column;
overflow-x: auto;
.stat:not(:last-child) {
border-inline-end: var(--border) dashed currentColor;
@supports (color: color-mix(in lab, red, red)) {
border-inline-end: var(--border) dashed color-mix(in oklab, currentColor 10%, #0000);
}
border-block-end: none;
}
}
}
.stats-vertical {
@layer daisyui.l1.l2 {
grid-auto-flow: row;
overflow-y: auto;
.stat:not(:last-child) {
border-inline-end: none;
border-block-end: var(--border) dashed currentColor;
@supports (color: color-mix(in lab, red, red)) {
border-block-end: var(--border) dashed color-mix(in oklab, currentColor 10%, #0000);
}
}
}
}
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}

2
dist/sigpro.min.css vendored

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,38 +1,47 @@
import * as AccordionModule from './src/components/Accordion.js';
import * as AlertModule from './src/components/Alert.js';
import * as AutocompleteModule from './src/components/Autocomplete.js';
import * as BadgeModule from './src/components/Badge.js';
import * as ButtonModule from './src/components/Button.js';
import * as CheckboxModule from './src/components/Checkbox.js';
import * as ColorpickerModule from './src/components/Colorpicker.js';
import * as DatepickerModule from './src/components/Datepicker.js';
import * as DrawerModule from './src/components/Drawer.js';
import * as DropdownModule from './src/components/Dropdown.js';
import * as FabModule from './src/components/Fab.js';
import * as FieldsetModule from './src/components/Fieldset.js';
import * as FileinputModule from './src/components/Fileinput.js';
import * as IconModule from './src/components/Icon.js';
import * as IndicatorModule from './src/components/Indicator.js';
import * as InputModule from './src/components/Input.js';
import * as LabelModule from './src/components/Label.js';
import * as ListModule from './src/components/List.js';
import * as MenuModule from './src/components/Menu.js';
import * as ModalModule from './src/components/Modal.js';
import * as NavbarModule from './src/components/Navbar.js';
import * as RadioModule from './src/components/Radio.js';
import * as RangeModule from './src/components/Range.js';
import * as RatingModule from './src/components/Rating.js';
import * as SelectModule from './src/components/Select.js';
import * as SpinnerModule from './src/components/Spinner.js';
import * as StackModule from './src/components/Stack.js';
import * as StatModule from './src/components/Stat.js';
import * as SwapModule from './src/components/Swap.js';
import * as TableModule from './src/components/Table.js';
import * as TabsModule from './src/components/Tabs.js';
import * as TimelineModule from './src/components/Timeline.js';
import * as ToastModule from './src/components/Toast.js';
import * as TooltipModule from './src/components/Tooltip.js';
import { Locale, tt } from './src/utils.js';
import * as AccordionModule from './components/Accordion.js';
import * as AlertModule from './components/Alert.js';
import * as AutocompleteModule from './components/Autocomplete.js';
import * as BadgeModule from './components/Badge.js';
import * as ButtonModule from './components/Button.js';
import * as CardModule from './components/Card.js';
import * as CarouselModule from './components/Carousel.js';
import * as ChatModule from './components/Chat.js';
import * as CheckboxModule from './components/Checkbox.js';
import * as ColorpickerModule from './components/Colorpicker.js';
import * as DatepickerModule from './components/Datepicker.js';
import * as DrawerModule from './components/Drawer.js';
import * as DropdownModule from './components/Dropdown.js';
import * as FabModule from './components/Fab.js';
import * as FieldsetModule from './components/Fieldset.js';
import * as FileinputModule from './components/Fileinput.js';
import * as IconModule from './components/Icon.js';
import * as IndicatorModule from './components/Indicator.js';
import * as KdbModule from './components/Kdb.js';
import * as InputModule from './components/Input.js';
import * as ListModule from './components/List.js';
import * as LoadingModule from './components/Loading.js';
import * as MenuModule from './components/Menu.js';
import * as ModalModule from './components/Modal.js';
import * as NavbarModule from './components/Navbar.js';
import * as RadialModule from './components/Radial.js';
import * as RadioModule from './components/Radio.js';
import * as RangeModule from './components/Range.js';
import * as RatingModule from './components/Rating.js';
import * as SkeletonModule from './components/Skeleton.js';
import * as SelectModule from './components/Select.js';
import * as StackModule from './components/Stack.js';
import * as StatModule from './components/Stat.js';
import * as StepsModule from './components/Stat.js';
import * as SwapModule from './components/Swap.js';
import * as TableModule from './components/Table.js';
import * as TabsModule from './components/Tabs.js';
import * as TextareaModule from './components/Textarea.js';
import * as TextRotateModule from './components/TextRotate.js';
import * as TimelineModule from './components/Timeline.js';
import * as ToastModule from './components/Toast.js';
import * as ToggleModule from './components/Toggle.js';
import * as TooltipModule from './components/Tooltip.js';
import { Locale, tt } from './utils.js';
export const Components = {
...AccordionModule,
@@ -40,6 +49,9 @@ export const Components = {
...AutocompleteModule,
...BadgeModule,
...ButtonModule,
...CardModule,
...CarouselModule,
...ChatModule,
...CheckboxModule,
...ColorpickerModule,
...DatepickerModule,
@@ -50,24 +62,30 @@ export const Components = {
...FileinputModule,
...IconModule,
...IndicatorModule,
...KdbModule,
...InputModule,
...LabelModule,
...ListModule,
...LoadingModule,
...MenuModule,
...ModalModule,
...NavbarModule,
...RadialModule,
...RadioModule,
...RangeModule,
...RatingModule,
...SkeletonModule,
...SelectModule,
...SpinnerModule,
...StackModule,
...StatModule,
...StepsModule,
...SwapModule,
...TableModule,
...TabsModule,
...TextareaModule,
...TextRotateModule,
...TimelineModule,
...ToastModule,
...ToggleModule,
...TooltipModule
};

View File

@@ -44,9 +44,9 @@
},
"scripts": {
"clean": "rm -rf ./dist ./css/*.css ./docs/*.js ./docs/*.css",
"build:cssmin": "tailwindcss -i ./src/sigpro.css -o ./dist/sigpro.min.css --content './src/**/*.js' --minify",
"build:css": "tailwindcss -i ./src/sigpro.css -o ./dist/sigpro.css --content './src/**/*.js'",
"build:cssdocs": "tailwindcss -i ./src/sigpro.css -o ./docs/sigpro.css --content './src/**/*.js' --minify",
"build:cssmin": "tailwindcss -i ./sigpro.css -o ./dist/sigpro.min.css --content './src/**/*.js' --minify",
"build:css": "tailwindcss -i ./sigpro.css -o ./dist/sigpro.css --content './src/**/*.js'",
"build:cssdocs": "tailwindcss -i ./sigpro.css -o ./docs/sigpro.css --content './src/**/*.js' --minify",
"build:js": "bun run build:js:iife && bun run build:js:esm",
"build:js:iife": "bun build ./index.js --bundle --outfile=./dist/sigpro-ui.js --format=iife --global-name=SigProUI && bun build ./index.js --bundle --outfile=./dist/sigpro-ui.min.js --format=iife --global-name=SigProUI --minify",
"build:js:esm": "bun build ./index.js --bundle --outfile=./dist/sigpro-ui.esm.js --format=esm && bun build ./index.js --bundle --outfile=./dist/sigpro-ui.esm.min.js --format=esm --minify",

View File

@@ -147,7 +147,7 @@
}
}
@layer utilities {
/* @layer utilities {
button {
@apply btn;
}
@@ -207,7 +207,7 @@
[role="alert"] {
@apply alert;
}
}
} */
/* sigpro-ui daisyUI classes - extracted from components */

View File

@@ -1,14 +0,0 @@
// components/Input.js
import { Tag } from "sigpro";
export const Input = (props) => {
const { type = "text", value, oninput, class: className, ...rest } = props;
return Tag("input", {
...rest,
type,
value,
oninput,
class: className,
});
};

View File

@@ -1,10 +0,0 @@
// components/Stat.js
import { Tag } from "sigpro";
export const Stat = (props, children) => {
const { class: className, ...rest } = props;
return Tag("div", {
...rest,
class: `stat ${className || ''}`.trim()
}, children);
};