Package library as @moduletrace/twui npm package

- Move components/ to src/ and compile to dist/ with tsc
- Add root barrel export plus deep-import subpath exports and base.css export
- Post-compile step: copy base.css, add .js import extensions, mark client modules
- Add publish.sh and .npmrc for the Gitea npm registry
- Fix type errors, guard TinyMCE env access, drop ace-builds type dependency
- Rename clashing props type names, remove Next.js scaffolding and unused deps

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-18 10:17:54 +01:00
co-authored by Claude Opus 5.5
parent d19d412066
commit 11da9b89e7
148 changed files with 937 additions and 500 deletions
+72
View File
@@ -0,0 +1,72 @@
import React from "react";
import { twMerge } from "tailwind-merge";
import ReactDOM from "react-dom";
import Button from "../layout/Button";
import { X } from "lucide-react";
import { type TWUI_MODAL_PROPS } from "../elements/Modal";
import Paper from "../elements/Paper";
import _ from "lodash";
type Props = TWUI_MODAL_PROPS & {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
};
/**
* # Modal Main Component
*/
export default function ModalComponent({
open,
setOpen,
no_cancel_button,
...props
}: Props) {
if (!open) return null;
return ReactDOM.createPortal(
<div
className={twMerge(
"fixed z-200 top-0 left-0 w-screen h-screen",
"flex flex-col items-center justify-center p-4",
"twui-modal-root",
)}
role="dialog"
aria-modal="true"
>
<div
className={twMerge(
"absolute top-0 left-0 bg-dark/80 z-0",
"w-screen h-screen",
)}
onClick={(e) => {
setOpen(false);
}}
></div>
<Paper
{..._.omit(props, ["targetWrapperProps"])}
className={twMerge(
"z-10 max-w-modal bg-background-light dark:bg-background-dark",
"w-full relative max-h-[95vh] overflow-y-auto",
"twui-modal-content",
props.className,
)}
>
{props.children}
{!no_cancel_button && (
<Button
className="absolute top-0 right-0 p-2"
variant="ghost"
color="gray"
onClick={() => {
setOpen(false);
}}
title="Close Modal Button"
>
<X size={30} />
</Button>
)}
</Paper>
</div>,
document.getElementById("twui-modal-root") as HTMLElement,
);
}
+116
View File
@@ -0,0 +1,116 @@
import React from "react";
import { twMerge } from "tailwind-merge";
import ReactDOM from "react-dom";
import type { TWUI_MODAL_PROPS } from "../elements/Modal";
import Paper from "../elements/Paper";
import _ from "lodash";
import twuiGrabPopoverStyles from "../(functions)/popver/grab-popover-styles";
type Props = TWUI_MODAL_PROPS & {
open: boolean;
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
targetElRef?: React.RefObject<HTMLElement | null>;
popoverTargetActiveRef: React.MutableRefObject<boolean>;
popoverContentActiveRef: React.MutableRefObject<boolean>;
};
/**
* # Modal Main Component
*/
export default function PopoverComponent({
open,
setOpen,
targetElRef,
position = "bottom",
trigger = "hover",
debounce,
popoverTargetActiveRef,
popoverContentActiveRef,
popoverReferenceRef,
isPopover,
...props
}: Props) {
if (!open) return null;
const [style, setStyle] = React.useState({});
React.useEffect(() => {
if (open && targetElRef?.current) {
const popoverStyle = twuiGrabPopoverStyles({
position,
targetElRef,
});
setStyle(popoverStyle);
}
}, [open, targetElRef, position]);
const closeTimeoutRef = React.useRef<any>(null);
const popoverEnterFn = React.useCallback(() => {
popoverContentActiveRef.current = true;
popoverTargetActiveRef.current = false;
window.clearTimeout(closeTimeoutRef.current);
setOpen(true);
}, []);
const popoverLeaveFn = React.useCallback(() => {
window.clearTimeout(closeTimeoutRef.current);
closeTimeoutRef.current = setTimeout(() => {
if (popoverTargetActiveRef.current) {
popoverTargetActiveRef.current = false;
return;
}
setOpen(false);
}, debounce);
}, []);
if (!open) return null;
return ReactDOM.createPortal(
<Paper
{...props}
className={twMerge(
"max-w-[300px] z-[250]",
"twui-popover-content",
props.className,
)}
style={{ ...style, ...props.style }}
onMouseEnter={
trigger === "hover" ? popoverEnterFn : props.onMouseEnter
}
onMouseLeave={
trigger === "hover" ? popoverLeaveFn : props.onMouseLeave
}
role="dialog"
aria-modal="true"
>
{/* <div
className="absolute w-0 h-0 border-8 border-transparent bg-white"
style={{
...(position === "bottom" && {
top: "-16px",
left: "50%",
transform: "translateX(-50%)",
}),
...(position === "top" && {
bottom: "-16px",
left: "50%",
transform: "translateX(-50%)",
}),
...(position === "right" && {
top: "50%",
left: "-16px",
transform: "translateY(-50%)",
}),
...(position === "left" && {
top: "50%",
right: "-16px",
transform: "translateY(-50%)",
}),
}}
/> */}
{props.children}
</Paper>,
document.getElementById("twui-popover-root") as HTMLElement,
);
}