@pagamio/frontend-commons-lib 0.8.232 → 0.8.233
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.
|
@@ -132,6 +132,7 @@ import type { IconResolver, SidebarMenuGroup, SidebarMenuItemConfig, SidebarV2Pr
|
|
|
132
132
|
*/
|
|
133
133
|
interface ComingSoonBadgeProps {
|
|
134
134
|
className?: string;
|
|
135
|
+
button?: React.ReactNode;
|
|
135
136
|
}
|
|
136
137
|
/**
|
|
137
138
|
* Professional "Coming Soon" indicator with subtle yellow styling
|
|
@@ -141,6 +142,10 @@ interface MenuItemRendererProps {
|
|
|
141
142
|
item: SidebarMenuItemConfig;
|
|
142
143
|
depth?: number;
|
|
143
144
|
iconResolver?: IconResolver;
|
|
145
|
+
comingSoonBadgeClassName?: string;
|
|
146
|
+
comingSoonButtonClassName?: string;
|
|
147
|
+
comingSoonIconClassName?: string;
|
|
148
|
+
comingSoonTextClassName?: string;
|
|
144
149
|
}
|
|
145
150
|
/**
|
|
146
151
|
* Recursive menu item renderer
|
|
@@ -149,6 +154,10 @@ declare const MenuItemRenderer: React.FC<MenuItemRendererProps>;
|
|
|
149
154
|
interface MenuGroupRendererProps {
|
|
150
155
|
group: SidebarMenuGroup;
|
|
151
156
|
iconResolver?: IconResolver;
|
|
157
|
+
comingSoonBadgeClassName?: string;
|
|
158
|
+
comingSoonButtonClassName?: string;
|
|
159
|
+
comingSoonIconClassName?: string;
|
|
160
|
+
comingSoonTextClassName?: string;
|
|
152
161
|
}
|
|
153
162
|
/**
|
|
154
163
|
* Render a menu group
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
'use client';
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
-
import { IconChevronDown, IconChevronRight
|
|
13
|
+
import { IconChevronDown, IconChevronRight } from '@tabler/icons-react';
|
|
14
14
|
import React, { useMemo, useState } from 'react';
|
|
15
15
|
import { cn } from '../../helpers/utils';
|
|
16
16
|
import { useTranslation } from '../../translations';
|
|
@@ -20,13 +20,13 @@ import { defaultIconResolver, resolveIcon } from './iconResolver';
|
|
|
20
20
|
/**
|
|
21
21
|
* Professional "Coming Soon" indicator with subtle yellow styling
|
|
22
22
|
*/
|
|
23
|
-
const ComingSoonBadge = ({ className }) => {
|
|
24
|
-
return (_jsxs("
|
|
23
|
+
const ComingSoonBadge = ({ className, button }) => {
|
|
24
|
+
return (_jsxs("div", { className: "ml-auto inline-flex items-center gap-2", children: [_jsx("span", { className: cn('inline-flex items-center gap-1 rounded px-2 py-0.5', 'bg-yellow-200 dark:bg-yellow-900/20', 'text-[10px] font-medium text-yellow-600 dark:text-yellow-500', 'border border-yellow-200 rounded-full dark:border-yellow-800', className), children: "Soon" }), button] }));
|
|
25
25
|
};
|
|
26
26
|
/**
|
|
27
27
|
* Recursive menu item renderer
|
|
28
28
|
*/
|
|
29
|
-
const MenuItemRenderer = ({ item, depth = 0, iconResolver = defaultIconResolver }) => {
|
|
29
|
+
const MenuItemRenderer = ({ item, depth = 0, iconResolver = defaultIconResolver, comingSoonBadgeClassName, comingSoonButtonClassName, comingSoonIconClassName, comingSoonTextClassName, }) => {
|
|
30
30
|
const { open, isMobile, pathname, LinkComponent } = useSidebarV2();
|
|
31
31
|
const { t } = useTranslation();
|
|
32
32
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
@@ -59,7 +59,7 @@ const MenuItemRenderer = ({ item, depth = 0, iconResolver = defaultIconResolver
|
|
|
59
59
|
}
|
|
60
60
|
// Handle coming soon items
|
|
61
61
|
if (item.comingSoon) {
|
|
62
|
-
return (_jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { disabled: true, className: "cursor-not-allowed bg-yellow-50/50 hover:bg-yellow-50/50 dark:bg-yellow-900/10 dark:hover:bg-yellow-900/10", tooltip: item.tooltip || t(item.label), children: [IconComponent && _jsx(IconComponent, { className: "h-4 w-4 shrink-0 text-yellow-600 dark:text-yellow-500" }), (open || isMobile) && (_jsxs(_Fragment, { children: [_jsx("span", { className: "truncate text-yellow-700 dark:text-yellow-400", children: t(item.label) }), _jsx(ComingSoonBadge, {})] }))] }) }, itemKey));
|
|
62
|
+
return (_jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { disabled: true, className: cn("cursor-not-allowed bg-yellow-50/50 hover:bg-yellow-50/50 dark:bg-yellow-900/10 dark:hover:bg-yellow-900/10", comingSoonButtonClassName), tooltip: item.tooltip || t(item.label), children: [IconComponent && (_jsx(IconComponent, { className: cn("h-4 w-4 shrink-0 text-yellow-600 dark:text-yellow-500", comingSoonIconClassName) })), (open || isMobile) && (_jsxs(_Fragment, { children: [_jsx("span", { className: cn("truncate text-yellow-700 dark:text-yellow-400", comingSoonTextClassName), children: t(item.label) }), _jsx(ComingSoonBadge, { className: comingSoonBadgeClassName, button: item.comingSoonButton })] }))] }) }, itemKey));
|
|
63
63
|
}
|
|
64
64
|
// Handle items with children (collapsible)
|
|
65
65
|
if (item.items && item.items.length > 0) {
|
|
@@ -70,10 +70,10 @@ const MenuItemRenderer = ({ item, depth = 0, iconResolver = defaultIconResolver
|
|
|
70
70
|
}
|
|
71
71
|
// Non-collapsible sections (always visible children)
|
|
72
72
|
if (item.collapsible === false) {
|
|
73
|
-
return (_jsxs("div", { className: item.className, children: [item.showSeparator && _jsx(SidebarSeparator, {}), _jsxs(SidebarGroupLabel, { children: [IconComponent && _jsx(IconComponent, { className: "h-4 w-4" }), (open || isMobile) && t(item.label)] }), _jsx(SidebarMenu, { children: item.items.map((child, index) => (_jsx(MenuItemRenderer, { item: child, depth: depth + 1, iconResolver: iconResolver }, child.key || child.href || `${child.label}-${index}`))) })] }, itemKey));
|
|
73
|
+
return (_jsxs("div", { className: item.className, children: [item.showSeparator && _jsx(SidebarSeparator, {}), _jsxs(SidebarGroupLabel, { children: [IconComponent && _jsx(IconComponent, { className: "h-4 w-4" }), (open || isMobile) && t(item.label)] }), _jsx(SidebarMenu, { children: item.items.map((child, index) => (_jsx(MenuItemRenderer, { item: child, depth: depth + 1, iconResolver: iconResolver, comingSoonBadgeClassName: comingSoonBadgeClassName, comingSoonButtonClassName: comingSoonButtonClassName, comingSoonIconClassName: comingSoonIconClassName, comingSoonTextClassName: comingSoonTextClassName }, child.key || child.href || `${child.label}-${index}`))) })] }, itemKey));
|
|
74
74
|
}
|
|
75
75
|
// Regular collapsible menu
|
|
76
|
-
return (_jsxs(SidebarMenuItem, { children: [_jsxs(SidebarMenuButton, { onClick: () => setIsExpanded(!shouldBeExpanded), isActive: isActive && !hasActiveChild, tooltip: item.tooltip || t(item.label), className: cn(hasActiveChild && 'text-sidebar-accent-foreground'), children: [IconComponent && _jsx(IconComponent, { className: "h-4 w-4 shrink-0" }), (open || isMobile) && (_jsxs(_Fragment, { children: [_jsx("span", { className: "truncate", children: t(item.label) }), shouldBeExpanded ? (_jsx(IconChevronDown, { className: "ml-auto h-4 w-4 shrink-0 transition-transform" })) : (_jsx(IconChevronRight, { className: "ml-auto h-4 w-4 shrink-0 transition-transform" }))] }))] }), shouldBeExpanded && (open || isMobile) && (_jsx(SidebarMenuSub, { children: item.items.map((child, index) => (_jsx(SidebarMenuItem, { children: child.items ? (_jsx(MenuItemRenderer, { item: child, depth: depth + 1, iconResolver: iconResolver })) : child.href ? (_jsx(SidebarMenuSubButton, { asChild: true, isActive: pathname === child.href, children: _jsxs(LinkComponent, { href: child.href, target: child.target, className: "flex items-center gap-2 w-full", children: [resolveIcon(child.icon, iconResolver) &&
|
|
76
|
+
return (_jsxs(SidebarMenuItem, { children: [_jsxs(SidebarMenuButton, { onClick: () => setIsExpanded(!shouldBeExpanded), isActive: isActive && !hasActiveChild, tooltip: item.tooltip || t(item.label), className: cn(hasActiveChild && 'text-sidebar-accent-foreground'), children: [IconComponent && _jsx(IconComponent, { className: "h-4 w-4 shrink-0" }), (open || isMobile) && (_jsxs(_Fragment, { children: [_jsx("span", { className: "truncate", children: t(item.label) }), shouldBeExpanded ? (_jsx(IconChevronDown, { className: "ml-auto h-4 w-4 shrink-0 transition-transform" })) : (_jsx(IconChevronRight, { className: "ml-auto h-4 w-4 shrink-0 transition-transform" }))] }))] }), shouldBeExpanded && (open || isMobile) && (_jsx(SidebarMenuSub, { children: item.items.map((child, index) => (_jsx(SidebarMenuItem, { children: child.items ? (_jsx(MenuItemRenderer, { item: child, depth: depth + 1, iconResolver: iconResolver, comingSoonBadgeClassName: comingSoonBadgeClassName, comingSoonButtonClassName: comingSoonButtonClassName, comingSoonIconClassName: comingSoonIconClassName, comingSoonTextClassName: comingSoonTextClassName })) : child.href ? (_jsx(SidebarMenuSubButton, { asChild: true, isActive: pathname === child.href, children: _jsxs(LinkComponent, { href: child.href, target: child.target, className: "flex items-center gap-2 w-full", children: [resolveIcon(child.icon, iconResolver) &&
|
|
77
77
|
React.createElement(resolveIcon(child.icon, iconResolver), {
|
|
78
78
|
className: 'h-3.5 w-3.5 shrink-0',
|
|
79
79
|
}), _jsx("span", { className: "truncate", children: t(child.label) }), renderBadge(child.badge, t)] }) })) : (_jsx(SidebarMenuSubButton, { className: "cursor-default", children: _jsx("span", { className: "truncate", children: t(child.label) }) })) }, child.key || child.href || `${child.label}-${index}`))) }))] }, itemKey));
|
|
@@ -102,13 +102,13 @@ const renderBadge = (badge, t) => {
|
|
|
102
102
|
/**
|
|
103
103
|
* Render a menu group
|
|
104
104
|
*/
|
|
105
|
-
const MenuGroupRenderer = ({ group, iconResolver = defaultIconResolver }) => {
|
|
105
|
+
const MenuGroupRenderer = ({ group, iconResolver = defaultIconResolver, comingSoonBadgeClassName, comingSoonButtonClassName, comingSoonIconClassName, comingSoonTextClassName, }) => {
|
|
106
106
|
const { t } = useTranslation();
|
|
107
107
|
const { open, isMobile } = useSidebarV2();
|
|
108
108
|
return (_jsxs(SidebarGroup, { className: group.className, children: [group.label && (open || isMobile) && (_jsxs(SidebarGroupLabel, { children: [resolveIcon(group.icon, iconResolver) &&
|
|
109
109
|
React.createElement(resolveIcon(group.icon, iconResolver), {
|
|
110
110
|
className: 'h-4 w-4',
|
|
111
|
-
}), t(group.label)] })), _jsx(SidebarMenu, { children: group.items.map((item, index) => (_jsx(MenuItemRenderer, { item: item, iconResolver: iconResolver }, item.key || item.href || `${item.label}-${index}`))) })] }));
|
|
111
|
+
}), t(group.label)] })), _jsx(SidebarMenu, { children: group.items.map((item, index) => (_jsx(MenuItemRenderer, { item: item, iconResolver: iconResolver, comingSoonBadgeClassName: comingSoonBadgeClassName, comingSoonButtonClassName: comingSoonButtonClassName, comingSoonIconClassName: comingSoonIconClassName, comingSoonTextClassName: comingSoonTextClassName }, item.key || item.href || `${item.label}-${index}`))) })] }));
|
|
112
112
|
};
|
|
113
113
|
/**
|
|
114
114
|
* SidebarV2 - Complete sidebar component
|
|
@@ -132,9 +132,9 @@ const MenuGroupRenderer = ({ group, iconResolver = defaultIconResolver }) => {
|
|
|
132
132
|
* </SidebarV2Provider>
|
|
133
133
|
* ```
|
|
134
134
|
*/
|
|
135
|
-
const SidebarV2 = ({ header, footer, groups, items, showRail = false, iconResolver = defaultIconResolver, className, contentClassName, headerClassName, footerClassName, }) => {
|
|
135
|
+
const SidebarV2 = ({ header, footer, groups, items, showRail = false, iconResolver = defaultIconResolver, className, contentClassName, headerClassName, footerClassName, comingSoonBadgeClassName, comingSoonButtonClassName, comingSoonIconClassName, comingSoonTextClassName, }) => {
|
|
136
136
|
const { isMobile } = useSidebarV2();
|
|
137
|
-
return (_jsxs(SidebarContainer, { className: className, children: [header && _jsx(SidebarHeader, { className: headerClassName, children: header }), _jsxs(SidebarContent, { className: contentClassName, children: [groups?.map((group, index) => (_jsxs(React.Fragment, { children: [index > 0 && _jsx(SidebarSeparator, {}), _jsx(MenuGroupRenderer, { group: group, iconResolver: iconResolver })] }, group.key || group.label || `group-${index}`))), items && !groups && (_jsx(SidebarGroup, { children: _jsx(SidebarMenu, { children: items.map((item, index) => (_jsx(MenuItemRenderer, { item: item, iconResolver: iconResolver }, item.key || item.href || `${item.label}-${index}`))) }) }))] }), footer && _jsx(SidebarFooter, { className: footerClassName, children: footer }), showRail && _jsx(SidebarRail, {})] }));
|
|
137
|
+
return (_jsxs(SidebarContainer, { className: className, children: [header && _jsx(SidebarHeader, { className: headerClassName, children: header }), _jsxs(SidebarContent, { className: contentClassName, children: [groups?.map((group, index) => (_jsxs(React.Fragment, { children: [index > 0 && _jsx(SidebarSeparator, {}), _jsx(MenuGroupRenderer, { group: group, iconResolver: iconResolver, comingSoonBadgeClassName: comingSoonBadgeClassName, comingSoonButtonClassName: comingSoonButtonClassName, comingSoonIconClassName: comingSoonIconClassName, comingSoonTextClassName: comingSoonTextClassName })] }, group.key || group.label || `group-${index}`))), items && !groups && (_jsx(SidebarGroup, { children: _jsx(SidebarMenu, { children: items.map((item, index) => (_jsx(MenuItemRenderer, { item: item, iconResolver: iconResolver, comingSoonBadgeClassName: comingSoonBadgeClassName, comingSoonButtonClassName: comingSoonButtonClassName, comingSoonIconClassName: comingSoonIconClassName, comingSoonTextClassName: comingSoonTextClassName }, item.key || item.href || `${item.label}-${index}`))) }) }))] }), footer && _jsx(SidebarFooter, { className: footerClassName, children: footer }), showRail && _jsx(SidebarRail, {})] }));
|
|
138
138
|
};
|
|
139
139
|
export default SidebarV2;
|
|
140
140
|
export { SidebarV2, ComingSoonBadge, MenuItemRenderer, MenuGroupRenderer };
|
|
@@ -56,6 +56,8 @@ export interface SidebarMenuItemConfig {
|
|
|
56
56
|
isSectionHeader?: boolean;
|
|
57
57
|
/** Show "Coming Soon" badge and disable navigation */
|
|
58
58
|
comingSoon?: boolean;
|
|
59
|
+
/** Optional button/action to display in coming soon items */
|
|
60
|
+
comingSoonButton?: ReactNode;
|
|
59
61
|
/** Custom tooltip for collapsed state */
|
|
60
62
|
tooltip?: string;
|
|
61
63
|
/** Additional CSS classes */
|
|
@@ -177,6 +179,14 @@ export interface SidebarV2Props {
|
|
|
177
179
|
headerClassName?: string;
|
|
178
180
|
/** Footer className */
|
|
179
181
|
footerClassName?: string;
|
|
182
|
+
/** Custom className for coming soon badge */
|
|
183
|
+
comingSoonBadgeClassName?: string;
|
|
184
|
+
/** Custom className for coming soon menu button */
|
|
185
|
+
comingSoonButtonClassName?: string;
|
|
186
|
+
/** Custom className for coming soon icon */
|
|
187
|
+
comingSoonIconClassName?: string;
|
|
188
|
+
/** Custom className for coming soon text span */
|
|
189
|
+
comingSoonTextClassName?: string;
|
|
180
190
|
}
|
|
181
191
|
/**
|
|
182
192
|
* Props for internal menu item components
|
package/lib/styles.css
CHANGED
|
@@ -2862,6 +2862,10 @@ input[type="range"]::-ms-fill-lower {
|
|
|
2862
2862
|
--tw-bg-opacity: 1;
|
|
2863
2863
|
background-color: rgb(253 246 178 / var(--tw-bg-opacity, 1));
|
|
2864
2864
|
}
|
|
2865
|
+
.bg-yellow-200 {
|
|
2866
|
+
--tw-bg-opacity: 1;
|
|
2867
|
+
background-color: rgb(252 233 106 / var(--tw-bg-opacity, 1));
|
|
2868
|
+
}
|
|
2865
2869
|
.bg-yellow-400 {
|
|
2866
2870
|
--tw-bg-opacity: 1;
|
|
2867
2871
|
background-color: rgb(227 160 8 / var(--tw-bg-opacity, 1));
|
|
@@ -3082,9 +3086,6 @@ input[type="range"]::-ms-fill-lower {
|
|
|
3082
3086
|
.fill-yellow-400 {
|
|
3083
3087
|
fill: #E3A008;
|
|
3084
3088
|
}
|
|
3085
|
-
.stroke-\[1\.5\] {
|
|
3086
|
-
stroke-width: 1.5;
|
|
3087
|
-
}
|
|
3088
3089
|
.object-contain {
|
|
3089
3090
|
-o-object-fit: contain;
|
|
3090
3091
|
object-fit: contain;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pagamio/frontend-commons-lib",
|
|
3
3
|
"description": "Pagamio library for Frontend reusable components like the form engine and table container",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.233",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
7
7
|
"provenance": false
|