@greatapps/common 1.1.95 → 1.1.96
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/components/navigation/AppNavigation.mjs +2 -2
- package/dist/components/navigation/AppNavigation.mjs.map +1 -1
- package/dist/components/navigation/shells/TabsMobileShell.mjs +5 -4
- package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/navigation/AppNavigation.tsx +3 -2
- package/src/components/navigation/shells/TabsMobileShell.tsx +5 -4
|
@@ -10,12 +10,12 @@ import { ProjectSelector } from "./subcomponents/ProjectSelector";
|
|
|
10
10
|
import { PlanCard } from "./subcomponents/PlanCard";
|
|
11
11
|
import { CreditsCard } from "./subcomponents/CreditsCard";
|
|
12
12
|
import { NavItemsContext } from "./NavItemsContext";
|
|
13
|
-
function AppNavigationRoot({ children, mobileVariant = "sheet" }) {
|
|
13
|
+
function AppNavigationRoot({ children, mobileVariant = "sheet", mobileTabsOffset }) {
|
|
14
14
|
const [navItems, setNavItems] = useState([]);
|
|
15
15
|
return /* @__PURE__ */ jsxs(NavItemsContext.Provider, { value: { navItems, setNavItems, mobileVariant }, children: [
|
|
16
16
|
/* @__PURE__ */ jsx(DesktopShell, { children }),
|
|
17
17
|
/* @__PURE__ */ jsx(MdShell, { children }),
|
|
18
|
-
mobileVariant === "sheet" ? /* @__PURE__ */ jsx(MobileShell, { children }) : /* @__PURE__ */ jsx(TabsMobileShell, { children })
|
|
18
|
+
mobileVariant === "sheet" ? /* @__PURE__ */ jsx(MobileShell, { children }) : /* @__PURE__ */ jsx(TabsMobileShell, { topOffset: mobileTabsOffset, children })
|
|
19
19
|
] });
|
|
20
20
|
}
|
|
21
21
|
const AppNavigation = Object.assign(AppNavigationRoot, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/navigation/AppNavigation.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { ReactNode, useState } from 'react';\r\nimport { DesktopShell } from './shells/DesktopShell';\r\nimport { MdShell } from './shells/MdShell';\r\nimport { MobileShell } from './shells/MobileShell';\r\nimport { TabsMobileShell } from './shells/TabsMobileShell';\r\nimport { NavItems } from './subcomponents/NavItems';\r\nimport { ProjectSelector } from './subcomponents/ProjectSelector';\r\nimport { PlanCard } from './subcomponents/PlanCard';\r\nimport { CreditsCard } from './subcomponents/CreditsCard';\r\nimport { NavItemsContext } from './NavItemsContext';\r\nimport type { NavItemConfig } from './subcomponents/NavItems';\r\n\r\nexport type { NavItemConfig } from './subcomponents/NavItems';\r\nexport type { ProjectSelectorProps } from './subcomponents/ProjectSelector';\r\nexport type { PlanCardProps } from './subcomponents/PlanCard';\r\nexport type { CreditsCardProps } from './subcomponents/CreditsCard';\r\n\r\ninterface AppNavigationProps {\r\n children: ReactNode;\r\n mobileVariant?: 'sheet' | 'tabs';\r\n}\r\n\r\nfunction AppNavigationRoot({ children, mobileVariant = 'sheet' }: AppNavigationProps) {\r\n const [navItems, setNavItems] = useState<NavItemConfig[]>([]);\r\n\r\n return (\r\n <NavItemsContext.Provider value={{ navItems, setNavItems, mobileVariant }}>\r\n <DesktopShell>{children}</DesktopShell>\r\n <MdShell>{children}</MdShell>\r\n {mobileVariant === 'sheet' ? (\r\n <MobileShell>{children}</MobileShell>\r\n ) : (\r\n <TabsMobileShell>{children}</TabsMobileShell>\r\n )}\r\n </NavItemsContext.Provider>\r\n );\r\n}\r\n\r\nexport const AppNavigation = Object.assign(AppNavigationRoot, {\r\n NavItems,\r\n ProjectSelector,\r\n PlanCard,\r\n CreditsCard,\r\n});\r\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../src/components/navigation/AppNavigation.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { ReactNode, useState } from 'react';\r\nimport { DesktopShell } from './shells/DesktopShell';\r\nimport { MdShell } from './shells/MdShell';\r\nimport { MobileShell } from './shells/MobileShell';\r\nimport { TabsMobileShell } from './shells/TabsMobileShell';\r\nimport { NavItems } from './subcomponents/NavItems';\r\nimport { ProjectSelector } from './subcomponents/ProjectSelector';\r\nimport { PlanCard } from './subcomponents/PlanCard';\r\nimport { CreditsCard } from './subcomponents/CreditsCard';\r\nimport { NavItemsContext } from './NavItemsContext';\r\nimport type { NavItemConfig } from './subcomponents/NavItems';\r\n\r\nexport type { NavItemConfig } from './subcomponents/NavItems';\r\nexport type { ProjectSelectorProps } from './subcomponents/ProjectSelector';\r\nexport type { PlanCardProps } from './subcomponents/PlanCard';\r\nexport type { CreditsCardProps } from './subcomponents/CreditsCard';\r\n\r\ninterface AppNavigationProps {\r\n children: ReactNode;\r\n mobileVariant?: 'sheet' | 'tabs';\r\n mobileTabsOffset?: string;\r\n}\r\n\r\nfunction AppNavigationRoot({ children, mobileVariant = 'sheet', mobileTabsOffset }: AppNavigationProps) {\r\n const [navItems, setNavItems] = useState<NavItemConfig[]>([]);\r\n\r\n return (\r\n <NavItemsContext.Provider value={{ navItems, setNavItems, mobileVariant }}>\r\n <DesktopShell>{children}</DesktopShell>\r\n <MdShell>{children}</MdShell>\r\n {mobileVariant === 'sheet' ? (\r\n <MobileShell>{children}</MobileShell>\r\n ) : (\r\n <TabsMobileShell topOffset={mobileTabsOffset}>{children}</TabsMobileShell>\r\n )}\r\n </NavItemsContext.Provider>\r\n );\r\n}\r\n\r\nexport const AppNavigation = Object.assign(AppNavigationRoot, {\r\n NavItems,\r\n ProjectSelector,\r\n PlanCard,\r\n CreditsCard,\r\n});\r\n"],"mappings":";AA6BI,SACE,KADF;AA3BJ,SAAoB,gBAAgB;AACpC,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAchC,SAAS,kBAAkB,EAAE,UAAU,gBAAgB,SAAS,iBAAiB,GAAuB;AACtG,QAAM,CAAC,UAAU,WAAW,IAAI,SAA0B,CAAC,CAAC;AAE5D,SACE,qBAAC,gBAAgB,UAAhB,EAAyB,OAAO,EAAE,UAAU,aAAa,cAAc,GACtE;AAAA,wBAAC,gBAAc,UAAS;AAAA,IACxB,oBAAC,WAAS,UAAS;AAAA,IAClB,kBAAkB,UACjB,oBAAC,eAAa,UAAS,IAEvB,oBAAC,mBAAgB,WAAW,kBAAmB,UAAS;AAAA,KAE5D;AAEJ;AAEO,MAAM,gBAAgB,OAAO,OAAO,mBAAmB;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;","names":[]}
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useRef, useEffect } from "react";
|
|
4
4
|
import { AppNavigationContext } from "../AppNavigationContext";
|
|
5
5
|
import { useNavItemsContext } from "../NavItemsContext";
|
|
6
|
-
function InternalTabsBar() {
|
|
6
|
+
function InternalTabsBar({ topOffset = "72px" }) {
|
|
7
7
|
const { navItems } = useNavItemsContext();
|
|
8
8
|
const tabsListRef = useRef(null);
|
|
9
9
|
const activeTabRef = useRef(null);
|
|
@@ -23,7 +23,8 @@ function InternalTabsBar() {
|
|
|
23
23
|
"div",
|
|
24
24
|
{
|
|
25
25
|
ref: tabsListRef,
|
|
26
|
-
className: "md:hidden fixed
|
|
26
|
+
className: "md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide",
|
|
27
|
+
style: { top: topOffset },
|
|
27
28
|
children: navItems.map((item) => /* @__PURE__ */ jsxs(
|
|
28
29
|
"button",
|
|
29
30
|
{
|
|
@@ -46,10 +47,10 @@ function InternalTabsBar() {
|
|
|
46
47
|
}
|
|
47
48
|
);
|
|
48
49
|
}
|
|
49
|
-
function TabsMobileShell({ children }) {
|
|
50
|
+
function TabsMobileShell({ children, topOffset }) {
|
|
50
51
|
return /* @__PURE__ */ jsxs(AppNavigationContext.Provider, { value: { breakpoint: "mobile" }, children: [
|
|
51
52
|
/* @__PURE__ */ jsx("div", { className: "hidden", children }),
|
|
52
|
-
/* @__PURE__ */ jsx(InternalTabsBar, {})
|
|
53
|
+
/* @__PURE__ */ jsx(InternalTabsBar, { topOffset })
|
|
53
54
|
] });
|
|
54
55
|
}
|
|
55
56
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/navigation/shells/TabsMobileShell.tsx"],"sourcesContent":["'use client';\n\nimport { ReactNode, useRef, useEffect } from 'react';\nimport { AppNavigationContext } from '../AppNavigationContext';\nimport { useNavItemsContext } from '../NavItemsContext';\n\nfunction InternalTabsBar() {\n const { navItems } = useNavItemsContext();\n const tabsListRef = useRef<HTMLDivElement>(null);\n const activeTabRef = useRef<HTMLButtonElement>(null);\n\n const activeLabel = navItems.find((i) => i.isActive)?.label;\n\n // Scroll active tab into center when active item changes\n useEffect(() => {\n if (activeTabRef.current && tabsListRef.current) {\n const tabsList = tabsListRef.current;\n const activeTabElement = activeTabRef.current;\n const tabsListRect = tabsList.getBoundingClientRect();\n const activeTabRect = activeTabElement.getBoundingClientRect();\n const scrollLeft =\n activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;\n tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });\n }\n }, [activeLabel]);\n\n if (!navItems.length) return null;\n\n return (\n <div\n ref={tabsListRef}\n className=\"md:hidden fixed
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/navigation/shells/TabsMobileShell.tsx"],"sourcesContent":["'use client';\n\nimport { ReactNode, useRef, useEffect } from 'react';\nimport { AppNavigationContext } from '../AppNavigationContext';\nimport { useNavItemsContext } from '../NavItemsContext';\n\nfunction InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {\n const { navItems } = useNavItemsContext();\n const tabsListRef = useRef<HTMLDivElement>(null);\n const activeTabRef = useRef<HTMLButtonElement>(null);\n\n const activeLabel = navItems.find((i) => i.isActive)?.label;\n\n // Scroll active tab into center when active item changes\n useEffect(() => {\n if (activeTabRef.current && tabsListRef.current) {\n const tabsList = tabsListRef.current;\n const activeTabElement = activeTabRef.current;\n const tabsListRect = tabsList.getBoundingClientRect();\n const activeTabRect = activeTabElement.getBoundingClientRect();\n const scrollLeft =\n activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;\n tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });\n }\n }, [activeLabel]);\n\n if (!navItems.length) return null;\n\n return (\n <div\n ref={tabsListRef}\n className=\"md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide\"\n style={{ top: topOffset }}\n >\n {navItems.map((item) => (\n <button\n key={item.label}\n ref={item.isActive ? activeTabRef : undefined}\n onClick={item.onClick}\n className={`flex items-center gap-2 px-4 py-3 shrink-0 border-b-2 transition-colors ${\n item.isActive\n ? 'border-gray-950 text-gray-950'\n : 'border-transparent text-gray-500 hover:text-gray-900'\n }`}\n >\n {item.icon && <item.icon size={16} className=\"shrink-0\" />}\n <span\n className={\n item.isActive ? 'paragraph-small-semibold' : 'paragraph-small-medium'\n }\n >\n {item.label}\n </span>\n </button>\n ))}\n </div>\n );\n}\n\nexport function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {\n return (\n <AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>\n {/*\n Children are hidden visually, but NavItems' useEffect still fires inside\n display:none — React effects are tied to commit phase, not layout visibility.\n This registers navItems in NavItemsContext so InternalTabsBar can read them.\n */}\n <div className=\"hidden\">{children}</div>\n <InternalTabsBar topOffset={topOffset} />\n </AppNavigationContext.Provider>\n );\n}\n"],"mappings":";AAmCQ,SAUgB,KAVhB;AAjCR,SAAoB,QAAQ,iBAAiB;AAC7C,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AAEnC,SAAS,gBAAgB,EAAE,YAAY,OAAO,GAA2B;AACvE,QAAM,EAAE,SAAS,IAAI,mBAAmB;AACxC,QAAM,cAAc,OAAuB,IAAI;AAC/C,QAAM,eAAe,OAA0B,IAAI;AAEnD,QAAM,cAAc,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAGtD,YAAU,MAAM;AACd,QAAI,aAAa,WAAW,YAAY,SAAS;AAC/C,YAAM,WAAW,YAAY;AAC7B,YAAM,mBAAmB,aAAa;AACtC,YAAM,eAAe,SAAS,sBAAsB;AACpD,YAAM,gBAAgB,iBAAiB,sBAAsB;AAC7D,YAAM,aACJ,iBAAiB,aAAa,aAAa,QAAQ,IAAI,cAAc,QAAQ;AAC/E,eAAS,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,GAAG,UAAU,SAAS,CAAC;AAAA,IACzE;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,MAAI,CAAC,SAAS,OAAQ,QAAO;AAE7B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO,EAAE,KAAK,UAAU;AAAA,MAEvB,mBAAS,IAAI,CAAC,SACb;AAAA,QAAC;AAAA;AAAA,UAEC,KAAK,KAAK,WAAW,eAAe;AAAA,UACpC,SAAS,KAAK;AAAA,UACd,WAAW,2EACT,KAAK,WACD,kCACA,sDACN;AAAA,UAEC;AAAA,iBAAK,QAAQ,oBAAC,KAAK,MAAL,EAAU,MAAM,IAAI,WAAU,YAAW;AAAA,YACxD;AAAA,cAAC;AAAA;AAAA,gBACC,WACE,KAAK,WAAW,6BAA6B;AAAA,gBAG9C,eAAK;AAAA;AAAA,YACR;AAAA;AAAA;AAAA,QAhBK,KAAK;AAAA,MAiBZ,CACD;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,gBAAgB,EAAE,UAAU,UAAU,GAAgD;AACpG,SACE,qBAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,YAAY,SAAS,GAM3D;AAAA,wBAAC,SAAI,WAAU,UAAU,UAAS;AAAA,IAClC,oBAAC,mBAAgB,WAAsB;AAAA,KACzC;AAEJ;","names":[]}
|
package/package.json
CHANGED
|
@@ -20,9 +20,10 @@ export type { CreditsCardProps } from './subcomponents/CreditsCard';
|
|
|
20
20
|
interface AppNavigationProps {
|
|
21
21
|
children: ReactNode;
|
|
22
22
|
mobileVariant?: 'sheet' | 'tabs';
|
|
23
|
+
mobileTabsOffset?: string;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
function AppNavigationRoot({ children, mobileVariant = 'sheet' }: AppNavigationProps) {
|
|
26
|
+
function AppNavigationRoot({ children, mobileVariant = 'sheet', mobileTabsOffset }: AppNavigationProps) {
|
|
26
27
|
const [navItems, setNavItems] = useState<NavItemConfig[]>([]);
|
|
27
28
|
|
|
28
29
|
return (
|
|
@@ -32,7 +33,7 @@ function AppNavigationRoot({ children, mobileVariant = 'sheet' }: AppNavigationP
|
|
|
32
33
|
{mobileVariant === 'sheet' ? (
|
|
33
34
|
<MobileShell>{children}</MobileShell>
|
|
34
35
|
) : (
|
|
35
|
-
<TabsMobileShell>{children}</TabsMobileShell>
|
|
36
|
+
<TabsMobileShell topOffset={mobileTabsOffset}>{children}</TabsMobileShell>
|
|
36
37
|
)}
|
|
37
38
|
</NavItemsContext.Provider>
|
|
38
39
|
);
|
|
@@ -4,7 +4,7 @@ import { ReactNode, useRef, useEffect } from 'react';
|
|
|
4
4
|
import { AppNavigationContext } from '../AppNavigationContext';
|
|
5
5
|
import { useNavItemsContext } from '../NavItemsContext';
|
|
6
6
|
|
|
7
|
-
function InternalTabsBar() {
|
|
7
|
+
function InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {
|
|
8
8
|
const { navItems } = useNavItemsContext();
|
|
9
9
|
const tabsListRef = useRef<HTMLDivElement>(null);
|
|
10
10
|
const activeTabRef = useRef<HTMLButtonElement>(null);
|
|
@@ -29,7 +29,8 @@ function InternalTabsBar() {
|
|
|
29
29
|
return (
|
|
30
30
|
<div
|
|
31
31
|
ref={tabsListRef}
|
|
32
|
-
className="md:hidden fixed
|
|
32
|
+
className="md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide"
|
|
33
|
+
style={{ top: topOffset }}
|
|
33
34
|
>
|
|
34
35
|
{navItems.map((item) => (
|
|
35
36
|
<button
|
|
@@ -56,7 +57,7 @@ function InternalTabsBar() {
|
|
|
56
57
|
);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
export function TabsMobileShell({ children }: { children: ReactNode }) {
|
|
60
|
+
export function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {
|
|
60
61
|
return (
|
|
61
62
|
<AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>
|
|
62
63
|
{/*
|
|
@@ -65,7 +66,7 @@ export function TabsMobileShell({ children }: { children: ReactNode }) {
|
|
|
65
66
|
This registers navItems in NavItemsContext so InternalTabsBar can read them.
|
|
66
67
|
*/}
|
|
67
68
|
<div className="hidden">{children}</div>
|
|
68
|
-
<InternalTabsBar />
|
|
69
|
+
<InternalTabsBar topOffset={topOffset} />
|
|
69
70
|
</AppNavigationContext.Provider>
|
|
70
71
|
);
|
|
71
72
|
}
|