@fluid-app/rep-sdk 0.1.3 → 0.1.5

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.js CHANGED
@@ -1,5 +1,5 @@
1
- import { themes_exports, useFluidApi, transformManifestToRepAppData, useThemeContext, useFluidAuthContext, MessagingScreen } from './chunk-7JMNKWPN.js';
2
- export { AUTH_CONSTANTS, ApiError, DEFAULT_AUTH_URL, DEFAULT_SDK_WIDGET_REGISTRY, FluidAuthProvider, FluidProvider, FluidThemeProvider, MessagingScreen, STORAGE_KEYS, URL_PARAMS, USER_TYPES, buildThemeDefinition, cleanTokenFromUrl, clearTokens, createDefaultAuthRedirect, createFluidClient, createFluidFileUploader, decodeToken, extractAllTokensFromUrl, extractCompanyTokenFromUrl, extractTokenFromUrl, getActiveThemeId, getStoredToken, getTokenExpiration, getTokenTimeRemaining, hasStoredToken, hasTokenInUrl, isApiError, isTokenExpired, isUserType, isValidToken, messagingScreenPropertySchema, normalizeComponentTree, storeToken, toNavigationItem, toScreenDefinition, transformManifestToRepAppData, transformThemes, useFluidApi, useFluidAuthContext, useFluidContext, useMessagingAuth, useMessagingConfig, useThemeContext, validateToken } from './chunk-7JMNKWPN.js';
1
+ import { themes_exports, useFluidApi, transformManifestToRepAppData, useThemeContext, useFluidAuthContext, MessagingScreen } from './chunk-O47ODLEF.js';
2
+ export { ApiError, DEFAULT_AUTH_URL, DEFAULT_SDK_WIDGET_REGISTRY, FluidAuthProvider, FluidProvider, FluidThemeProvider, MessagingScreen, buildThemeDefinition, createDefaultAuthRedirect, createFluidClient, createFluidFileUploader, getActiveThemeId, isApiError, messagingScreenPropertySchema, normalizeComponentTree, toNavigationItem, toScreenDefinition, transformManifestToRepAppData, transformThemes, useFluidApi, useFluidAuthContext, useFluidContext, useMessagingAuth, useMessagingConfig, useThemeContext } from './chunk-O47ODLEF.js';
3
3
  import { ContactsScreen } from './chunk-CMF2FYTD.js';
4
4
  export { ContactsScreen, contactsScreenPropertySchema } from './chunk-CMF2FYTD.js';
5
5
  import { OrdersScreen } from './chunk-WFPYEYC7.js';
@@ -10,9 +10,11 @@ import { ProductsScreen } from './chunk-QZMWG7EM.js';
10
10
  export { ProductsScreen, productsScreenPropertySchema } from './chunk-QZMWG7EM.js';
11
11
  import { CoreScreenPlaceholder } from './chunk-RS4OSTES.js';
12
12
  import './chunk-424PT5DM.js';
13
+ import * as React2 from 'react';
13
14
  import { createContext, memo, forwardRef, useContext, useRef, useEffect, useMemo, useState, useCallback } from 'react';
14
15
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
15
16
  import { useQuery } from '@tanstack/react-query';
17
+ export { AUTH_CONSTANTS, STORAGE_KEYS, URL_PARAMS, USER_TYPES, cleanTokenFromUrl, clearTokens, decodeToken, extractAllTokensFromUrl, extractCompanyTokenFromUrl, extractTokenFromUrl, getStoredToken, getTokenExpiration, getTokenTimeRemaining, hasStoredToken, hasTokenInUrl, isTokenExpired, isUserType, isValidToken, storeToken, validateToken } from '@fluid-app/auth';
16
18
  export { WIDGET_TYPE_NAMES, assertDefined, assertNever, isWidgetType, isWidgetTypeName, sectionLayoutConfig } from '@fluid-app/rep-core/types';
17
19
  export { AlertWidget, CalendarWidget, CarouselWidget, CatchUpWidget, ChartWidget, ContainerWidget, EmbedWidget, ImageWidget, LayoutWidget, ListWidget, MySiteWidget, NestedWidget, QuickShareWidget, RecentActivityWidget, SpacerWidget, TableWidget, TextWidget, ToDoWidget, VideoWidget, alertWidgetPropertySchema, calendarWidgetPropertySchema, carouselWidgetPropertySchema, catchUpWidgetPropertySchema, chartWidgetPropertySchema, containerWidgetPropertySchema, embedWidgetPropertySchema, imageWidgetPropertySchema, layoutWidgetPropertySchema, listWidgetPropertySchema, mySiteWidgetPropertySchema, nestedWidgetPropertySchema, quickShareWidgetPropertySchema, recentActivityWidgetPropertySchema, spacerWidgetPropertySchema, tableWidgetPropertySchema, textWidgetPropertySchema, toDoWidgetPropertySchema, videoWidgetPropertySchema, widgetPropertySchemas } from '@fluid-app/rep-widgets/widgets';
18
20
  export { createScreen, createWidgetFromShareable, createWidgetRegistry, groupChildrenByColumn } from '@fluid-app/rep-core/widget-utils';
@@ -21,10 +23,12 @@ import { AppShellLayout } from '@fluid-app/rep-core/shell/AppShellLayout';
21
23
  import { useThemeMode, ThemeModeProvider } from '@fluid-app/rep-core/shell/ThemeModeContext';
22
24
  export { ThemeModeProvider, getThemeModeAttribute, useThemeMode } from '@fluid-app/rep-core/shell/ThemeModeContext';
23
25
  import { normalizeSlug, getSystemNavigationBySection, isSystemNavigationItem } from '@fluid-app/rep-core/navigation/system-navigation-items';
24
- import { resolveTheme, applyTheme, removeAllThemes } from '@fluid-app/rep-core/theme';
25
- import { SidebarMenu, SidebarGroupLabel, SidebarMenuItem, SidebarMenuButton, useSidebar } from '@fluid-app/rep-core/shell/sidebar';
26
- import { RepIcon } from '@fluid-app/rep-core/components/RepIcon';
27
26
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
27
+ import { faEllipsis } from '@fortawesome/pro-regular-svg-icons/faEllipsis';
28
+ import { faXmark } from '@fortawesome/pro-regular-svg-icons/faXmark';
29
+ import { RepIcon } from '@fluid-app/rep-core/components/RepIcon';
30
+ import { SidebarMenu, SidebarGroupLabel, SidebarMenuItem, SidebarMenuButton, useSidebar } from '@fluid-app/rep-core/shell/sidebar';
31
+ import { resolveTheme, applyTheme, removeAllThemes } from '@fluid-app/rep-core/theme';
28
32
  import { faBars } from '@fortawesome/pro-regular-svg-icons/faBars';
29
33
  import { faSun } from '@fortawesome/pro-regular-svg-icons/faSun';
30
34
  import { faMoon } from '@fortawesome/pro-regular-svg-icons/faMoon';
@@ -1653,7 +1657,7 @@ function RequireAuth({
1653
1657
 
1654
1658
  // src/screens/index.ts
1655
1659
  var screenPropertySchemas = {
1656
- MessagingScreen: () => import('./MessagingScreen-4H7ZBO3V.js').then((m) => m.messagingScreenPropertySchema),
1660
+ MessagingScreen: () => import('./MessagingScreen-BBINFP67.js').then((m) => m.messagingScreenPropertySchema),
1657
1661
  ContactsScreen: () => import('./ContactsScreen-33AJ5XUB.js').then((m) => m.contactsScreenPropertySchema),
1658
1662
  OrdersScreen: () => import('./OrdersScreen-IPPZLEYF.js').then((m) => m.ordersScreenPropertySchema),
1659
1663
  CustomersScreen: () => import('./CustomersScreen-E4HXBKV7.js').then((m) => m.customersScreenPropertySchema),
@@ -1759,6 +1763,113 @@ function registerCorePageTemplates() {
1759
1763
  });
1760
1764
  }
1761
1765
  registerCorePageTemplates();
1766
+ function isInSection(item, currentSlug) {
1767
+ const normalized = normalizeSlug(currentSlug);
1768
+ if (normalizeSlug(item.slug) === normalized) return true;
1769
+ return item.children?.some((child) => normalizeSlug(child.slug) === normalized) ?? false;
1770
+ }
1771
+ function getNavTarget(item) {
1772
+ if (item.slug && (!item.children || item.children.length === 0)) {
1773
+ return normalizeSlug(item.slug);
1774
+ }
1775
+ if (item.children && item.children.length > 0) {
1776
+ const firstChild = item.children[0];
1777
+ if (firstChild?.slug) return normalizeSlug(firstChild.slug);
1778
+ }
1779
+ return null;
1780
+ }
1781
+ function SdkBottomNav({
1782
+ navItems,
1783
+ currentSlug,
1784
+ onNavigate,
1785
+ maxVisibleItems = 5
1786
+ }) {
1787
+ const { isMobile, useBottomNav } = useSidebar();
1788
+ const [moreOpen, setMoreOpen] = React2.useState(false);
1789
+ if (!isMobile || !useBottomNav) return null;
1790
+ const navigableItems = navItems.filter((item) => !item.parent_id).filter((item) => item.slug || item.children && item.children.length > 0);
1791
+ const hasOverflow = navigableItems.length > maxVisibleItems;
1792
+ const visibleItems = hasOverflow ? navigableItems.slice(0, maxVisibleItems - 1) : navigableItems;
1793
+ const overflowItems = hasOverflow ? navigableItems.slice(maxVisibleItems - 1) : [];
1794
+ const handleItemClick = (item) => {
1795
+ const target = getNavTarget(item);
1796
+ if (target) onNavigate(target);
1797
+ setMoreOpen(false);
1798
+ };
1799
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1800
+ /* @__PURE__ */ jsxs("nav", { className: "fixed right-0 bottom-0 left-0 z-40 flex h-16 items-end justify-around border-t border-border bg-sidebar pb-[env(safe-area-inset-bottom)]", children: [
1801
+ visibleItems.map((item) => {
1802
+ const isActive = isInSection(item, currentSlug);
1803
+ return /* @__PURE__ */ jsxs(
1804
+ "button",
1805
+ {
1806
+ type: "button",
1807
+ onClick: () => handleItemClick(item),
1808
+ className: `flex flex-1 flex-col items-center justify-center gap-0.5 py-2 text-[10px] font-medium transition-colors ${isActive ? "text-primary" : "text-muted-foreground"}`,
1809
+ children: [
1810
+ item.icon ? /* @__PURE__ */ jsx(RepIcon, { name: item.icon, className: "size-5" }) : /* @__PURE__ */ jsx("span", { className: "size-5" }),
1811
+ /* @__PURE__ */ jsx("span", { className: "max-w-[72px] truncate", children: item.label })
1812
+ ]
1813
+ },
1814
+ item.id ?? item.slug ?? item.label
1815
+ );
1816
+ }),
1817
+ hasOverflow && /* @__PURE__ */ jsxs(
1818
+ "button",
1819
+ {
1820
+ type: "button",
1821
+ onClick: () => setMoreOpen(true),
1822
+ className: `flex flex-1 flex-col items-center justify-center gap-0.5 py-2 text-[10px] font-medium transition-colors ${overflowItems.some((item) => isInSection(item, currentSlug)) ? "text-primary" : "text-muted-foreground"}`,
1823
+ children: [
1824
+ /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: faEllipsis, className: "size-5" }),
1825
+ /* @__PURE__ */ jsx("span", { children: "More" })
1826
+ ]
1827
+ }
1828
+ )
1829
+ ] }),
1830
+ moreOpen && /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex flex-col", children: [
1831
+ /* @__PURE__ */ jsx(
1832
+ "div",
1833
+ {
1834
+ className: "flex-1 bg-black/50",
1835
+ onClick: () => setMoreOpen(false),
1836
+ "aria-hidden": "true"
1837
+ }
1838
+ ),
1839
+ /* @__PURE__ */ jsxs("div", { className: "rounded-t-2xl bg-sidebar pb-[env(safe-area-inset-bottom)]", children: [
1840
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 pt-4 pb-2", children: [
1841
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", children: "More" }),
1842
+ /* @__PURE__ */ jsx(
1843
+ "button",
1844
+ {
1845
+ type: "button",
1846
+ onClick: () => setMoreOpen(false),
1847
+ className: "flex items-center justify-center rounded-full p-1 text-muted-foreground hover:bg-sidebar-accent",
1848
+ "aria-label": "Close",
1849
+ children: /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: faXmark, className: "size-5" })
1850
+ }
1851
+ )
1852
+ ] }),
1853
+ /* @__PURE__ */ jsx("div", { className: "px-2 pb-4", children: overflowItems.map((item) => {
1854
+ const isActive = isInSection(item, currentSlug);
1855
+ return /* @__PURE__ */ jsxs(
1856
+ "button",
1857
+ {
1858
+ type: "button",
1859
+ onClick: () => handleItemClick(item),
1860
+ className: `flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors ${isActive ? "bg-sidebar-primary text-sidebar-primary-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent"}`,
1861
+ children: [
1862
+ item.icon && /* @__PURE__ */ jsx(RepIcon, { name: item.icon, className: "size-5" }),
1863
+ /* @__PURE__ */ jsx("span", { children: item.label })
1864
+ ]
1865
+ },
1866
+ item.id ?? item.slug ?? item.label
1867
+ );
1868
+ }) })
1869
+ ] })
1870
+ ] })
1871
+ ] });
1872
+ }
1762
1873
  var SPIN_STYLE_ID2 = "fluid-app-shell-loading-spin";
1763
1874
  function ensureSpinStyle2() {
1764
1875
  if (typeof document === "undefined") return;
@@ -1965,6 +2076,7 @@ function QuickLinksDropdown({ onNavigate }) {
1965
2076
  }
1966
2077
  function SdkHeader({
1967
2078
  tabs,
2079
+ mobileTabs,
1968
2080
  currentSlug,
1969
2081
  onNavigate,
1970
2082
  navSlugs
@@ -1974,8 +2086,9 @@ function SdkHeader({
1974
2086
  const match = matchSlugPrefix(currentSlug, navSlugs);
1975
2087
  const baseSlug = match?.matchedSlug ?? normalizeSlug(currentSlug);
1976
2088
  const themeIcon = themeMode.mode === "dark" ? faMoon : faSun;
2089
+ const activeTabs = sidebar.isMobile && sidebar.useBottomNav && mobileTabs ? mobileTabs : tabs;
1977
2090
  return /* @__PURE__ */ jsxs("header", { className: "flex h-[52px] shrink-0 items-center gap-2 bg-sidebar px-6", children: [
1978
- sidebar.isMobile && /* @__PURE__ */ jsx(
2091
+ sidebar.isMobile && !sidebar.useBottomNav && /* @__PURE__ */ jsx(
1979
2092
  "button",
1980
2093
  {
1981
2094
  type: "button",
@@ -1985,7 +2098,7 @@ function SdkHeader({
1985
2098
  children: /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: faBars, className: "size-5" })
1986
2099
  }
1987
2100
  ),
1988
- /* @__PURE__ */ jsx("nav", { className: "scrollbar-none flex flex-1 items-center gap-1 overflow-x-auto", children: tabs.map((tab) => {
2101
+ /* @__PURE__ */ jsx("nav", { className: "scrollbar-none flex flex-1 items-center gap-1 overflow-x-auto", children: activeTabs.map((tab) => {
1989
2102
  const tabSlug = normalizeSlug(tab.slug);
1990
2103
  if (!tabSlug) return null;
1991
2104
  const isActive = tabSlug === baseSlug;
@@ -2224,6 +2337,11 @@ function AppShell({
2224
2337
  if (profileNav && profileNav.length > 0) return profileNav;
2225
2338
  return DEFAULT_NAVIGATION;
2226
2339
  }, [navigationProp, appData?.profile?.navigation?.navigation_items]);
2340
+ const mobileNavItems = useMemo(() => {
2341
+ const mobileNav = appData?.profile?.mobile_navigation?.navigation_items;
2342
+ if (mobileNav && mobileNav.length > 0) return mobileNav;
2343
+ return navItems;
2344
+ }, [appData?.profile?.mobile_navigation?.navigation_items, navItems]);
2227
2345
  const screens = appData?.screens;
2228
2346
  const navSlugs = useMemo(() => collectNavSlugs(navItems), [navItems]);
2229
2347
  const [themeMode, setThemeMode] = useState(getInitialThemeMode);
@@ -2289,6 +2407,8 @@ function AppShell({
2289
2407
  const restParams = slugMatch?.rest ?? "";
2290
2408
  const currentSection = findCurrentSection(navItems, baseSlug);
2291
2409
  const secondLevelTabs = currentSection?.children ?? [];
2410
+ const mobileCurrentSection = findCurrentSection(mobileNavItems, baseSlug);
2411
+ const mobileSecondLevelTabs = mobileCurrentSection?.children ?? [];
2292
2412
  const currentNavItem = findNavItem(navItems, baseSlug);
2293
2413
  const content = typeof children === "function" ? children({ currentSlug: activeSlug, currentNavItem }) : children ?? /* @__PURE__ */ jsx(
2294
2414
  PageRouter,
@@ -2337,6 +2457,7 @@ function AppShell({
2337
2457
  SdkHeader,
2338
2458
  {
2339
2459
  tabs: secondLevelTabs,
2460
+ mobileTabs: mobileSecondLevelTabs,
2340
2461
  currentSlug: activeSlug,
2341
2462
  onNavigate: handleNavigate,
2342
2463
  navSlugs
@@ -2344,6 +2465,15 @@ function AppShell({
2344
2465
  ),
2345
2466
  sidebarHeader,
2346
2467
  sidebarFooter,
2468
+ useBottomNav: true,
2469
+ afterContent: /* @__PURE__ */ jsx(
2470
+ SdkBottomNav,
2471
+ {
2472
+ navItems: mobileNavItems,
2473
+ currentSlug: activeSlug,
2474
+ onNavigate: handleNavigate
2475
+ }
2476
+ ),
2347
2477
  children: content
2348
2478
  }
2349
2479
  )