@farmzone/fz-react-ui 0.0.1 → 0.0.3

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.
package/dist/index.cjs CHANGED
@@ -309,6 +309,7 @@ function Button(props) {
309
309
  position: tooltipPosition,
310
310
  className: tooltipClassName,
311
311
  contentClassName: tooltipContentClassName,
312
+ asChild: true,
312
313
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block", children: buttonElement })
313
314
  }
314
315
  );
@@ -3161,7 +3162,6 @@ function Empty(props) {
3161
3162
  const useFullScreen = Boolean(defaultUI && fullScreen);
3162
3163
  const layout = useFullScreen ? "page" : "panel";
3163
3164
  const iconVariant = iconVariantProp ?? (icon ? "boxed" : "plain");
3164
- console.log("Asdf");
3165
3165
  const content = defaultUI ? /* @__PURE__ */ jsxRuntime.jsx(
3166
3166
  EmptyContent,
3167
3167
  {
@@ -5479,15 +5479,15 @@ function normalizeExtension(ext) {
5479
5479
  const lower = ext.replace(/^\./, "").toLowerCase();
5480
5480
  if (lower === "jpeg") return "jpg";
5481
5481
  if (lower === "svg+xml") return "svg";
5482
- return lower.split("+")[0];
5482
+ return lower.split("+")[0] || "";
5483
5483
  }
5484
5484
  function getExtensionFromPathname(pathname) {
5485
5485
  const segments = pathname.split("/");
5486
5486
  for (let i = segments.length - 1; i >= 0; i -= 1) {
5487
5487
  const segment = segments[i];
5488
- const dotIndex = segment.lastIndexOf(".");
5488
+ const dotIndex = segment?.lastIndexOf(".") ?? -1;
5489
5489
  if (dotIndex <= 0) continue;
5490
- return segment.slice(dotIndex + 1).toLowerCase();
5490
+ return segment?.slice(dotIndex + 1).toLowerCase() ?? "";
5491
5491
  }
5492
5492
  return null;
5493
5493
  }
@@ -5496,7 +5496,7 @@ function getExtensionFromSrc(src) {
5496
5496
  if (!pattern.test(src)) continue;
5497
5497
  if (type === "image") {
5498
5498
  const dataUrlMatch = src.match(/^data:image\/([a-zA-Z0-9+.-]+)/i);
5499
- return dataUrlMatch ? normalizeExtension(dataUrlMatch[1]) : "jpg";
5499
+ return dataUrlMatch ? normalizeExtension(dataUrlMatch[1] ?? "") : "jpg";
5500
5500
  }
5501
5501
  if (type === "pdf") return "pdf";
5502
5502
  }
@@ -8422,6 +8422,231 @@ function FileUploader(props) {
8422
8422
  /* @__PURE__ */ jsxRuntime.jsx(FilePreviewViewer, { ...viewer.viewerProps, fileTypes, fileNames: files.map((f) => f.name) })
8423
8423
  ] });
8424
8424
  }
8425
+ function Sidebar(props) {
8426
+ const navigate = reactRouter.useNavigate();
8427
+ const { isOpen: isOpen2, onClose, menuSections, header, className, showCollapseButton = false } = props;
8428
+ const { pathname } = reactRouter.useLocation();
8429
+ const [isCollapsed, setIsCollapsed] = React6.useState(false);
8430
+ const [isContentVisible, setIsContentVisible] = React6.useState(true);
8431
+ const [expandedItems, setExpandedItems] = React6.useState(/* @__PURE__ */ new Set());
8432
+ const [expandedSubItems, setExpandedSubItems] = React6.useState(/* @__PURE__ */ new Set());
8433
+ React6.useEffect(() => {
8434
+ if (isCollapsed) return;
8435
+ const timer = setTimeout(() => setIsContentVisible(true), 300);
8436
+ return () => clearTimeout(timer);
8437
+ }, [isCollapsed]);
8438
+ React6.useEffect(() => {
8439
+ menuSections.forEach((section) => {
8440
+ section.items.forEach((item) => {
8441
+ if (!item.children) return;
8442
+ const allLeafPaths = item.children.flatMap(
8443
+ (child) => child.children ? child.children.map((gc) => gc.path) : child.path ? [child.path] : []
8444
+ );
8445
+ if (!allLeafPaths.includes(pathname)) return;
8446
+ setExpandedItems((prev) => {
8447
+ if (prev.has(item.label)) return prev;
8448
+ const next = new Set(prev);
8449
+ next.add(item.label);
8450
+ return next;
8451
+ });
8452
+ item.children.forEach((child) => {
8453
+ if (!child.children) return;
8454
+ const gcPaths = child.children.map((gc) => gc.path);
8455
+ if (!gcPaths.includes(pathname)) return;
8456
+ const subKey = `${item.label}::${child.label}`;
8457
+ setExpandedSubItems((prev) => {
8458
+ if (prev.has(subKey)) return prev;
8459
+ const next = new Set(prev);
8460
+ next.add(subKey);
8461
+ return next;
8462
+ });
8463
+ });
8464
+ });
8465
+ });
8466
+ }, [pathname, menuSections]);
8467
+ const toggleExpand = (label) => {
8468
+ setExpandedItems((prev) => {
8469
+ const next = new Set(prev);
8470
+ if (next.has(label)) next.delete(label);
8471
+ else next.add(label);
8472
+ return next;
8473
+ });
8474
+ };
8475
+ const toggleSubExpand = (subKey) => {
8476
+ setExpandedSubItems((prev) => {
8477
+ const next = new Set(prev);
8478
+ if (next.has(subKey)) next.delete(subKey);
8479
+ else next.add(subKey);
8480
+ return next;
8481
+ });
8482
+ };
8483
+ const handleItemClick = (path) => {
8484
+ if (path.includes("https")) {
8485
+ window.open(path, "_blank", "noopener,noreferrer");
8486
+ } else if (path !== "") {
8487
+ navigate(path);
8488
+ onClose();
8489
+ }
8490
+ };
8491
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8492
+ isOpen2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 bg-black/10 bg-opacity-50 z-40 lg:hidden", onClick: onClose }),
8493
+ /* @__PURE__ */ jsxRuntime.jsxs(
8494
+ "aside",
8495
+ {
8496
+ className: `
8497
+ ${isCollapsed ? "w-11 min-w-11" : "min-w-60 w-62"}
8498
+ ${isOpen2 ? "translate-x-0" : "-translate-x-full lg:translate-x-0"}
8499
+ hide-scrollbar fixed lg:relative top-0 left-0 h-screen bg-white border-r border-gray-200 z-50 shrink-0 overflow-y-auto
8500
+ transition-transform duration-300 ease-in-out
8501
+ ${className ?? ""}
8502
+ `,
8503
+ children: [
8504
+ showCollapseButton && /* @__PURE__ */ jsxRuntime.jsx(
8505
+ "button",
8506
+ {
8507
+ onClick: () => {
8508
+ if (!isCollapsed) setIsContentVisible(false);
8509
+ setIsCollapsed((prev) => !prev);
8510
+ },
8511
+ className: "absolute top-4 right-2 z-20 w-6.5 h-6.5 bg-gray-50 rounded-full flex items-center justify-center hover:bg-gray-50 transition-colors cursor-pointer hover:bg-gray-100",
8512
+ children: isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightClose, { size: 18, color: "var(--color-sub-darkgray)" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftClose, { size: 18, color: "var(--color-sub-darkgray)" })
8513
+ }
8514
+ ),
8515
+ isContentVisible && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-6 pl-6 pr-4", children: [
8516
+ /* @__PURE__ */ jsxRuntime.jsx(
8517
+ "button",
8518
+ {
8519
+ onClick: onClose,
8520
+ className: "lg:hidden absolute top-4 right-4 p-2 hover:bg-gray-100 rounded-lg transition-colors text-2xl leading-none",
8521
+ "aria-label": "Close menu",
8522
+ children: "x"
8523
+ }
8524
+ ),
8525
+ header && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-10 mt-2", children: header }),
8526
+ /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "space-y-6", children: menuSections.map((section, sectionIndex) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8527
+ section.title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs font-semibold text-gray-500 tracking-wider mb-3", children: section.title }),
8528
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8529
+ /* @__PURE__ */ jsxRuntime.jsxs(
8530
+ "button",
8531
+ {
8532
+ onClick: () => {
8533
+ if (item.children) {
8534
+ toggleExpand(item.label);
8535
+ } else if (item.path) {
8536
+ handleItemClick(item.path);
8537
+ }
8538
+ },
8539
+ className: `
8540
+ w-full text-left flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors
8541
+ ${!item.children && pathname === item.path ? "bg-blue-50 text-blue-600" : "text-gray-700 hover:bg-gray-100"}
8542
+ cursor-pointer
8543
+ `,
8544
+ children: [
8545
+ /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: "w-4 h-4 flex-shrink-0" }),
8546
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1", children: item.label }),
8547
+ item.children && /* @__PURE__ */ jsxRuntime.jsx(
8548
+ "svg",
8549
+ {
8550
+ className: `w-4 h-4 transition-transform ${expandedItems.has(item.label) ? "rotate-90" : ""}`,
8551
+ fill: "none",
8552
+ stroke: "currentColor",
8553
+ viewBox: "0 0 24 24",
8554
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
8555
+ }
8556
+ ),
8557
+ item.path?.includes("https") && /* @__PURE__ */ jsxRuntime.jsx(
8558
+ "svg",
8559
+ {
8560
+ className: "w-4 h-4 flex-shrink-0 text-gray-400",
8561
+ fill: "none",
8562
+ stroke: "currentColor",
8563
+ viewBox: "0 0 24 24",
8564
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8565
+ "path",
8566
+ {
8567
+ strokeLinecap: "round",
8568
+ strokeLinejoin: "round",
8569
+ strokeWidth: 2,
8570
+ d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
8571
+ }
8572
+ )
8573
+ }
8574
+ )
8575
+ ]
8576
+ }
8577
+ ),
8578
+ item.children && expandedItems.has(item.label) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-[25px] mt-1 space-y-1", children: item.children.map((child, childIndex) => {
8579
+ if (child.children && child.children.length > 0) {
8580
+ const subKey = `${item.label}::${child.label}`;
8581
+ const isSubExpanded = expandedSubItems.has(subKey);
8582
+ const isSubActive = child.children.some((gc) => gc.path === pathname);
8583
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8584
+ /* @__PURE__ */ jsxRuntime.jsxs(
8585
+ "button",
8586
+ {
8587
+ onClick: () => toggleSubExpand(subKey),
8588
+ className: `
8589
+ w-full text-left flex items-center justify-between px-3 py-1.5 rounded-lg text-sm transition-colors cursor-pointer
8590
+ ${isSubActive ? "text-blue-600 font-medium" : "text-gray-600 hover:bg-gray-50 hover:text-gray-900"}
8591
+ `,
8592
+ children: [
8593
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: child.label }),
8594
+ /* @__PURE__ */ jsxRuntime.jsx(
8595
+ "svg",
8596
+ {
8597
+ className: `w-3 h-3 transition-transform ${isSubExpanded ? "rotate-90" : ""}`,
8598
+ fill: "none",
8599
+ stroke: "currentColor",
8600
+ viewBox: "0 0 24 24",
8601
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8602
+ "path",
8603
+ {
8604
+ strokeLinecap: "round",
8605
+ strokeLinejoin: "round",
8606
+ strokeWidth: 2,
8607
+ d: "M9 5l7 7-7 7"
8608
+ }
8609
+ )
8610
+ }
8611
+ )
8612
+ ]
8613
+ }
8614
+ ),
8615
+ isSubExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-3 mt-0.5 space-y-0.5 border-l border-gray-200 pl-2", children: child.children.map((grandchild) => /* @__PURE__ */ jsxRuntime.jsx(
8616
+ "button",
8617
+ {
8618
+ onClick: () => handleItemClick(grandchild.path),
8619
+ className: `
8620
+ w-full text-left px-3 py-1 rounded-lg text-sm transition-colors cursor-pointer
8621
+ ${pathname === grandchild.path ? "text-blue-600 font-medium" : "text-gray-500 hover:bg-gray-50 hover:text-gray-900"}
8622
+ `,
8623
+ children: grandchild.label
8624
+ },
8625
+ grandchild.path
8626
+ )) })
8627
+ ] }, child.label);
8628
+ }
8629
+ return /* @__PURE__ */ jsxRuntime.jsx(
8630
+ "button",
8631
+ {
8632
+ onClick: () => handleItemClick(child.path ?? ""),
8633
+ className: `
8634
+ w-full text-left px-3 py-1.5 rounded-lg text-sm transition-colors cursor-pointer
8635
+ ${pathname === child.path ? "bg-blue-50 text-blue-600 font-medium" : "text-gray-600 hover:bg-gray-50 hover:text-gray-900"}
8636
+ `,
8637
+ children: child.label
8638
+ },
8639
+ childIndex
8640
+ );
8641
+ }) })
8642
+ ] }, item.label)) })
8643
+ ] }, section.title ?? sectionIndex)) })
8644
+ ] })
8645
+ ]
8646
+ }
8647
+ )
8648
+ ] });
8649
+ }
8425
8650
  function useDetailController(params = {}) {
8426
8651
  const { mode: controlledMode, onModeChange } = params;
8427
8652
  const [internalMode, setInternalMode] = React6.useState("read");
@@ -9015,6 +9240,7 @@ function useScrollToTop(containerId) {
9015
9240
  }
9016
9241
 
9017
9242
  exports.Badge = Badge;
9243
+ exports.BaseUploader = BaseUploader;
9018
9244
  exports.BreadCrumb = BreadCrumb;
9019
9245
  exports.Button = Button;
9020
9246
  exports.Carousel = Carousel_default;
@@ -9067,6 +9293,7 @@ exports.SelectScrollUpButton = SelectScrollUpButton;
9067
9293
  exports.SelectSeparator = SelectSeparator;
9068
9294
  exports.SelectTrigger = SelectTrigger;
9069
9295
  exports.SelectValue = SelectValue;
9296
+ exports.Sidebar = Sidebar;
9070
9297
  exports.SimplePopover = SimplePopover;
9071
9298
  exports.Skeleton = Skeleton;
9072
9299
  exports.Slider = Slider;
@@ -9086,6 +9313,7 @@ exports.cn = cn;
9086
9313
  exports.confirmModal = confirmModal;
9087
9314
  exports.findParentMenuItem = findParentMenuItem;
9088
9315
  exports.findParentMenuName = findParentMenuName;
9316
+ exports.getFileLabel = getFileLabel;
9089
9317
  exports.switchTrackSizes = switchTrackSizes;
9090
9318
  exports.textVariants = textVariants;
9091
9319
  exports.toast = toast;
@@ -9093,6 +9321,7 @@ exports.useBlockModalConfirm = useBlockModalConfirm;
9093
9321
  exports.useBreadCrumbItems = useBreadCrumbItems;
9094
9322
  exports.useCustomBlocker = useCustomBlocker;
9095
9323
  exports.useDetailController = useDetailController;
9324
+ exports.useFilePreviewViewer = useFilePreviewViewer;
9096
9325
  exports.useModal = useModal;
9097
9326
  exports.useMultiTabStore = useMultiTabStore;
9098
9327
  exports.useScrollToTop = useScrollToTop;