@adminlte/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/README.md +454 -0
  3. package/dist/context/accessibility.js +141 -0
  4. package/dist/context/body-class-sync.js +22 -0
  5. package/dist/context/color-mode-context.js +61 -0
  6. package/dist/context/command-palette-context.js +28 -0
  7. package/dist/context/html-dir.js +17 -0
  8. package/dist/context/link-context.js +18 -0
  9. package/dist/context/lte-behaviors.js +52 -0
  10. package/dist/context/sidebar-context.js +87 -0
  11. package/dist/css/adminlte.css +17259 -0
  12. package/dist/form/button.js +21 -0
  13. package/dist/form/input-color.js +30 -0
  14. package/dist/form/input-file.js +29 -0
  15. package/dist/form/input-flatpickr.js +45 -0
  16. package/dist/form/input-switch.js +26 -0
  17. package/dist/form/input-tom-select.js +59 -0
  18. package/dist/form/input.js +23 -0
  19. package/dist/form/select.js +25 -0
  20. package/dist/form/textarea.js +22 -0
  21. package/dist/hooks/use-card-widget.js +44 -0
  22. package/dist/hooks/use-direct-chat.js +16 -0
  23. package/dist/hooks/use-fullscreen.js +44 -0
  24. package/dist/hooks/use-push-menu.js +54 -0
  25. package/dist/hooks/use-sortable.js +26 -0
  26. package/dist/hooks/use-treeview-animation.js +27 -0
  27. package/dist/index.d.ts +1010 -0
  28. package/dist/index.js +145 -0
  29. package/dist/layout/app-content.js +18 -0
  30. package/dist/layout/auth-layout.js +25 -0
  31. package/dist/layout/color-mode-toggle.js +67 -0
  32. package/dist/layout/dashboard-layout.js +101 -0
  33. package/dist/layout/footer.js +19 -0
  34. package/dist/layout/sidebar-brand.js +16 -0
  35. package/dist/layout/sidebar-nav-item.js +46 -0
  36. package/dist/layout/sidebar-nav.js +43 -0
  37. package/dist/layout/sidebar-overlay.js +18 -0
  38. package/dist/layout/sidebar.js +48 -0
  39. package/dist/layout/topbar.js +128 -0
  40. package/dist/lib/class-name.js +6 -0
  41. package/dist/lib/flatten-menu.js +23 -0
  42. package/dist/tool/datatable.js +45 -0
  43. package/dist/tool/editor.js +72 -0
  44. package/dist/tool/modal.js +28 -0
  45. package/dist/types/direct-chat.js +0 -0
  46. package/dist/types/layout.js +0 -0
  47. package/dist/types/menu.js +0 -0
  48. package/dist/types/theme.js +0 -0
  49. package/dist/widget/accordion.js +35 -0
  50. package/dist/widget/alert.js +18 -0
  51. package/dist/widget/apex-chart.js +40 -0
  52. package/dist/widget/avatar.js +72 -0
  53. package/dist/widget/badge.js +20 -0
  54. package/dist/widget/breadcrumb.js +26 -0
  55. package/dist/widget/callout.js +11 -0
  56. package/dist/widget/card.js +84 -0
  57. package/dist/widget/carousel.js +56 -0
  58. package/dist/widget/command-palette.js +137 -0
  59. package/dist/widget/description-block.js +19 -0
  60. package/dist/widget/direct-chat.js +96 -0
  61. package/dist/widget/dropdown.js +63 -0
  62. package/dist/widget/info-box.js +24 -0
  63. package/dist/widget/list-group.js +47 -0
  64. package/dist/widget/nav-messages.js +48 -0
  65. package/dist/widget/nav-notifications.js +40 -0
  66. package/dist/widget/nav-tasks.js +60 -0
  67. package/dist/widget/offcanvas.js +61 -0
  68. package/dist/widget/pagination.js +93 -0
  69. package/dist/widget/profile-card.js +32 -0
  70. package/dist/widget/progress-group.js +23 -0
  71. package/dist/widget/progress.js +25 -0
  72. package/dist/widget/ratings.js +20 -0
  73. package/dist/widget/small-box.js +34 -0
  74. package/dist/widget/sparkline-chart.js +43 -0
  75. package/dist/widget/spinner.js +26 -0
  76. package/dist/widget/stepper.js +57 -0
  77. package/dist/widget/table.js +50 -0
  78. package/dist/widget/tabs.js +46 -0
  79. package/dist/widget/timeline.js +15 -0
  80. package/dist/widget/toast.js +41 -0
  81. package/dist/widget/tooltip.js +30 -0
  82. package/dist/widget/world-map.js +42 -0
  83. package/package.json +116 -0
@@ -0,0 +1,21 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ function Button({
3
+ theme = "primary",
4
+ outline,
5
+ size,
6
+ icon,
7
+ label,
8
+ children,
9
+ className,
10
+ ...props
11
+ }) {
12
+ const btnClass = outline ? `btn btn-outline-${theme}` : `btn btn-${theme}`;
13
+ const sizeClass = size ? `btn-${size}` : "";
14
+ return /* @__PURE__ */ jsxs("button", { className: `${btnClass} ${sizeClass} ${className || ""}`.trim(), ...props, children: [
15
+ icon && /* @__PURE__ */ jsx("i", { className: `bi ${icon} ${label ? "me-2" : ""}` }),
16
+ label || children
17
+ ] });
18
+ }
19
+ export {
20
+ Button
21
+ };
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ function InputColor({
4
+ name,
5
+ label,
6
+ fgroupClass,
7
+ error,
8
+ className,
9
+ defaultValue = "#0d6efd",
10
+ ...props
11
+ }) {
12
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
13
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
14
+ /* @__PURE__ */ jsx(
15
+ "input",
16
+ {
17
+ type: "color",
18
+ name,
19
+ id: props.id || name,
20
+ className: `form-control form-control-color ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
21
+ defaultValue,
22
+ ...props
23
+ }
24
+ ),
25
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error })
26
+ ] });
27
+ }
28
+ export {
29
+ InputColor
30
+ };
@@ -0,0 +1,29 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ function InputFile({
3
+ name,
4
+ label,
5
+ fgroupClass,
6
+ error,
7
+ multiple,
8
+ className,
9
+ ...props
10
+ }) {
11
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
12
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
13
+ /* @__PURE__ */ jsx(
14
+ "input",
15
+ {
16
+ type: "file",
17
+ name: multiple ? `${name}[]` : name,
18
+ id: props.id || name,
19
+ className: `form-control ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
20
+ multiple,
21
+ ...props
22
+ }
23
+ ),
24
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error })
25
+ ] });
26
+ }
27
+ export {
28
+ InputFile
29
+ };
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ function InputFlatpickr({
5
+ name,
6
+ label,
7
+ fgroupClass,
8
+ error,
9
+ dateType = "text",
10
+ options,
11
+ className,
12
+ ...props
13
+ }) {
14
+ const inputRef = useRef(null);
15
+ useEffect(() => {
16
+ const element = inputRef.current;
17
+ if (!element) return;
18
+ import("flatpickr").then(({ default: flatpickr }) => {
19
+ flatpickr(element, {
20
+ enableTime: dateType === "time" || dateType === "datetime",
21
+ noCalendar: dateType === "time",
22
+ dateFormat: dateType === "time" ? "H:i" : "Y-m-d",
23
+ ...options
24
+ });
25
+ });
26
+ }, [dateType, options]);
27
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
28
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
29
+ /* @__PURE__ */ jsx(
30
+ "input",
31
+ {
32
+ ref: inputRef,
33
+ type: dateType === "time" ? "text" : dateType,
34
+ name,
35
+ id: props.id || name,
36
+ className: `form-control ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
37
+ ...props
38
+ }
39
+ ),
40
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error })
41
+ ] });
42
+ }
43
+ export {
44
+ InputFlatpickr
45
+ };
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from "react";
4
+ const InputSwitch = forwardRef(function InputSwitch2({ name, label, id, checked, defaultChecked, onChange, fgroupClass, error }, ref) {
5
+ const inputId = id || name;
6
+ return /* @__PURE__ */ jsxs("div", { className: `form-check form-switch ${fgroupClass || ""}`, children: [
7
+ /* @__PURE__ */ jsx(
8
+ "input",
9
+ {
10
+ ref,
11
+ type: "checkbox",
12
+ className: `form-check-input ${error ? "is-invalid" : ""}`,
13
+ id: inputId,
14
+ name,
15
+ checked,
16
+ defaultChecked,
17
+ onChange: (e) => onChange?.(e.target.checked)
18
+ }
19
+ ),
20
+ label && /* @__PURE__ */ jsx("label", { className: "form-check-label", htmlFor: inputId, children: label }),
21
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error })
22
+ ] });
23
+ });
24
+ export {
25
+ InputSwitch
26
+ };
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ function InputTomSelect({
5
+ name,
6
+ label,
7
+ fgroupClass,
8
+ error,
9
+ options,
10
+ tomSelectOptions,
11
+ className,
12
+ "aria-label": ariaLabelProp,
13
+ ...props
14
+ }) {
15
+ const selectRef = useRef(null);
16
+ const ariaLabel = ariaLabelProp ?? label;
17
+ useEffect(() => {
18
+ const element = selectRef.current;
19
+ if (!element) return;
20
+ let instance;
21
+ let active = true;
22
+ import("tom-select").then(({ default: TomSelect }) => {
23
+ if (!active || !element) return;
24
+ const ts = new TomSelect(element, {
25
+ create: false,
26
+ allowEmptyOption: true,
27
+ ...tomSelectOptions
28
+ });
29
+ instance = ts;
30
+ if (ariaLabel) {
31
+ const control = ts.control_input;
32
+ control?.setAttribute("aria-label", ariaLabel);
33
+ }
34
+ });
35
+ return () => {
36
+ active = false;
37
+ instance?.destroy();
38
+ };
39
+ }, [tomSelectOptions, ariaLabel]);
40
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
41
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
42
+ /* @__PURE__ */ jsx(
43
+ "select",
44
+ {
45
+ ref: selectRef,
46
+ name,
47
+ id: props.id || name,
48
+ "aria-label": ariaLabel,
49
+ className: `form-select ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
50
+ ...props,
51
+ children: options?.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
52
+ }
53
+ ),
54
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error })
55
+ ] });
56
+ }
57
+ export {
58
+ InputTomSelect
59
+ };
@@ -0,0 +1,23 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ const Input = forwardRef(function Input2({ name, label, igroupSize, fgroupClass, error, hint, className, ...props }, ref) {
4
+ const sizeClass = igroupSize ? `form-control-${igroupSize}` : "";
5
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
6
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
7
+ /* @__PURE__ */ jsx(
8
+ "input",
9
+ {
10
+ ref,
11
+ name,
12
+ id: props.id || name,
13
+ className: `form-control ${sizeClass} ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
14
+ ...props
15
+ }
16
+ ),
17
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error }),
18
+ hint && /* @__PURE__ */ jsx("small", { className: "form-text text-muted", children: hint })
19
+ ] });
20
+ });
21
+ export {
22
+ Input
23
+ };
@@ -0,0 +1,25 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ const Select = forwardRef(function Select2({ name, label, fgroupClass, error, options, children, className, ...props }, ref) {
4
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
5
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
6
+ /* @__PURE__ */ jsxs(
7
+ "select",
8
+ {
9
+ ref,
10
+ name,
11
+ id: props.id || name,
12
+ className: `form-select ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
13
+ ...props,
14
+ children: [
15
+ options?.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value)),
16
+ children
17
+ ]
18
+ }
19
+ ),
20
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error })
21
+ ] });
22
+ });
23
+ export {
24
+ Select
25
+ };
@@ -0,0 +1,22 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ const Textarea = forwardRef(function Textarea2({ name, label, fgroupClass, error, hint, className, ...props }, ref) {
4
+ return /* @__PURE__ */ jsxs("div", { className: `mb-3 ${fgroupClass || ""}`, children: [
5
+ label && /* @__PURE__ */ jsx("label", { htmlFor: props.id || name, className: "form-label", children: label }),
6
+ /* @__PURE__ */ jsx(
7
+ "textarea",
8
+ {
9
+ ref,
10
+ name,
11
+ id: props.id || name,
12
+ className: `form-control ${error ? "is-invalid" : ""} ${className || ""}`.trim(),
13
+ ...props
14
+ }
15
+ ),
16
+ error && /* @__PURE__ */ jsx("div", { className: "invalid-feedback", children: error }),
17
+ hint && /* @__PURE__ */ jsx("small", { className: "form-text text-muted", children: hint })
18
+ ] });
19
+ });
20
+ export {
21
+ Textarea
22
+ };
@@ -0,0 +1,44 @@
1
+ import { useState } from "react";
2
+ function useCardWidget(initialCollapsed = false) {
3
+ const [isCollapsed, setIsCollapsed] = useState(initialCollapsed);
4
+ const [isMaximized, setIsMaximized] = useState(false);
5
+ const [isRemoved, setIsRemoved] = useState(false);
6
+ const collapse = () => setIsCollapsed(true);
7
+ const expand = () => setIsCollapsed(false);
8
+ const toggleCollapse = () => setIsCollapsed((v) => !v);
9
+ const maximize = () => {
10
+ setIsMaximized(true);
11
+ if (typeof document !== "undefined") {
12
+ document.documentElement.classList.add("maximized-card");
13
+ }
14
+ };
15
+ const minimize = () => {
16
+ setIsMaximized(false);
17
+ if (typeof document !== "undefined") {
18
+ document.documentElement.classList.remove("maximized-card");
19
+ }
20
+ };
21
+ const toggleMaximize = () => {
22
+ if (isMaximized) {
23
+ minimize();
24
+ } else {
25
+ maximize();
26
+ }
27
+ };
28
+ const remove = () => setIsRemoved(true);
29
+ return {
30
+ isCollapsed,
31
+ isMaximized,
32
+ isRemoved,
33
+ collapse,
34
+ expand,
35
+ toggleCollapse,
36
+ maximize,
37
+ minimize,
38
+ toggleMaximize,
39
+ remove
40
+ };
41
+ }
42
+ export {
43
+ useCardWidget
44
+ };
@@ -0,0 +1,16 @@
1
+ import { useState } from "react";
2
+ function useDirectChat() {
3
+ const [isContactsOpen, setIsContactsOpen] = useState(false);
4
+ const toggleContacts = () => setIsContactsOpen((v) => !v);
5
+ const openContacts = () => setIsContactsOpen(true);
6
+ const closeContacts = () => setIsContactsOpen(false);
7
+ return {
8
+ isContactsOpen,
9
+ toggleContacts,
10
+ openContacts,
11
+ closeContacts
12
+ };
13
+ }
14
+ export {
15
+ useDirectChat
16
+ };
@@ -0,0 +1,44 @@
1
+ import { useEffect, useState } from "react";
2
+ function useFullscreen() {
3
+ const [isFullscreen, setIsFullscreen] = useState(false);
4
+ useEffect(() => {
5
+ if (typeof document === "undefined") return;
6
+ const handleFullscreenChange = () => {
7
+ setIsFullscreen(!!document.fullscreenElement);
8
+ };
9
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
10
+ return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
11
+ }, []);
12
+ const enterFullscreen = async () => {
13
+ try {
14
+ await document.documentElement.requestFullscreen();
15
+ } catch (err) {
16
+ console.error("Failed to enter fullscreen:", err);
17
+ }
18
+ };
19
+ const exitFullscreen = async () => {
20
+ try {
21
+ if (document.fullscreenElement) {
22
+ await document.exitFullscreen();
23
+ }
24
+ } catch (err) {
25
+ console.error("Failed to exit fullscreen:", err);
26
+ }
27
+ };
28
+ const toggleFullscreen = async () => {
29
+ if (isFullscreen) {
30
+ await exitFullscreen();
31
+ } else {
32
+ await enterFullscreen();
33
+ }
34
+ };
35
+ return {
36
+ isFullscreen,
37
+ toggleFullscreen,
38
+ enterFullscreen,
39
+ exitFullscreen
40
+ };
41
+ }
42
+ export {
43
+ useFullscreen
44
+ };
@@ -0,0 +1,54 @@
1
+ import { useState, useEffect } from "react";
2
+ function usePushMenu(options = {}) {
3
+ const { sidebarBreakpoint = 992, enablePersistence = false, isMiniMode = false } = options;
4
+ const [isCollapsed, setIsCollapsed] = useState(false);
5
+ const [isMobileOpen, setIsMobileOpen] = useState(false);
6
+ const [windowWidth, setWindowWidth] = useState(null);
7
+ useEffect(() => {
8
+ if (typeof window === "undefined") return;
9
+ setWindowWidth(window.innerWidth);
10
+ if (enablePersistence) {
11
+ const saved = localStorage.getItem("lte.sidebar.state");
12
+ if (saved) {
13
+ try {
14
+ const { collapsed } = JSON.parse(saved);
15
+ setIsCollapsed(collapsed);
16
+ } catch {
17
+ }
18
+ }
19
+ }
20
+ }, [enablePersistence]);
21
+ useEffect(() => {
22
+ if (typeof window === "undefined" || !enablePersistence) return;
23
+ localStorage.setItem("lte.sidebar.state", JSON.stringify({ collapsed: isCollapsed }));
24
+ }, [isCollapsed, enablePersistence]);
25
+ useEffect(() => {
26
+ const handleResize = () => {
27
+ setWindowWidth(window.innerWidth);
28
+ };
29
+ window.addEventListener("resize", handleResize);
30
+ return () => window.removeEventListener("resize", handleResize);
31
+ }, []);
32
+ useEffect(() => {
33
+ if (windowWidth === null) return;
34
+ const isMobileSize = windowWidth <= sidebarBreakpoint;
35
+ if (isMobileSize && !isMobileOpen && !isCollapsed) {
36
+ setIsCollapsed(true);
37
+ } else if (!isMobileSize && isCollapsed && !isMiniMode) {
38
+ setIsCollapsed(false);
39
+ }
40
+ }, [windowWidth, sidebarBreakpoint, isMobileOpen, isCollapsed, isMiniMode]);
41
+ const toggle = () => setIsCollapsed((v) => !v);
42
+ const collapse = () => {
43
+ setIsCollapsed(true);
44
+ setIsMobileOpen(false);
45
+ };
46
+ const expand = () => {
47
+ setIsCollapsed(false);
48
+ setIsMobileOpen(false);
49
+ };
50
+ return { isCollapsed, isMobileOpen, toggle, collapse, expand };
51
+ }
52
+ export {
53
+ usePushMenu
54
+ };
@@ -0,0 +1,26 @@
1
+ import { useEffect } from "react";
2
+ function useSortable(enabled = true) {
3
+ useEffect(() => {
4
+ if (!enabled || typeof window === "undefined") return;
5
+ const initSortable = async () => {
6
+ const { default: Sortable } = await import("sortablejs");
7
+ const sortableElements = document.querySelectorAll(".connectedSortable");
8
+ sortableElements.forEach((el) => {
9
+ new Sortable(el, {
10
+ group: "shared",
11
+ handle: ".card-header",
12
+ animation: 200
13
+ });
14
+ });
15
+ const cardHeaders = document.querySelectorAll(".connectedSortable .card-header");
16
+ cardHeaders.forEach((header) => {
17
+ ;
18
+ header.style.cursor = "move";
19
+ });
20
+ };
21
+ initSortable().catch(console.error);
22
+ }, [enabled]);
23
+ }
24
+ export {
25
+ useSortable
26
+ };
@@ -0,0 +1,27 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ function useTreeviewAnimation(isOpen, speed = 300) {
3
+ const ref = useRef(null);
4
+ const [height, setHeight] = useState(0);
5
+ useEffect(() => {
6
+ const element = ref.current;
7
+ if (!element) return;
8
+ if (isOpen) {
9
+ const fullHeight = element.scrollHeight;
10
+ setHeight(fullHeight);
11
+ const timer = setTimeout(() => {
12
+ setHeight("auto");
13
+ }, speed);
14
+ return () => clearTimeout(timer);
15
+ }
16
+ setHeight(0);
17
+ }, [isOpen, speed]);
18
+ const style = {
19
+ height,
20
+ overflow: "hidden",
21
+ transition: `height ${speed}ms ease-in-out`
22
+ };
23
+ return { ref, style };
24
+ }
25
+ export {
26
+ useTreeviewAnimation
27
+ };