@papernote/ui 1.3.1 → 1.6.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.
- package/dist/components/ActionBar.d.ts +112 -0
- package/dist/components/ActionBar.d.ts.map +1 -0
- package/dist/components/BottomNavigation.d.ts +98 -0
- package/dist/components/BottomNavigation.d.ts.map +1 -0
- package/dist/components/Checkbox.d.ts +2 -0
- package/dist/components/Checkbox.d.ts.map +1 -1
- package/dist/components/CheckboxList.d.ts +81 -0
- package/dist/components/CheckboxList.d.ts.map +1 -0
- package/dist/components/Chip.d.ts +92 -1
- package/dist/components/Chip.d.ts.map +1 -1
- package/dist/components/ConfirmDialog.d.ts +43 -1
- package/dist/components/ConfirmDialog.d.ts.map +1 -1
- package/dist/components/DataTable.d.ts +10 -1
- package/dist/components/DataTable.d.ts.map +1 -1
- package/dist/components/DataTableCardView.d.ts +99 -0
- package/dist/components/DataTableCardView.d.ts.map +1 -0
- package/dist/components/ExpandablePanel.d.ts +142 -0
- package/dist/components/ExpandablePanel.d.ts.map +1 -0
- package/dist/components/FloatingActionButton.d.ts +98 -0
- package/dist/components/FloatingActionButton.d.ts.map +1 -0
- package/dist/components/Input.d.ts +45 -1
- package/dist/components/Input.d.ts.map +1 -1
- package/dist/components/MobileHeader.d.ts +98 -0
- package/dist/components/MobileHeader.d.ts.map +1 -0
- package/dist/components/MobileLayout.d.ts +121 -0
- package/dist/components/MobileLayout.d.ts.map +1 -0
- package/dist/components/Modal.d.ts +78 -1
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/PageHeader.d.ts +86 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PullToRefresh.d.ts +87 -0
- package/dist/components/PullToRefresh.d.ts.map +1 -0
- package/dist/components/QueryTransparency.d.ts +1 -1
- package/dist/components/QueryTransparency.d.ts.map +1 -1
- package/dist/components/SearchableList.d.ts +83 -0
- package/dist/components/SearchableList.d.ts.map +1 -0
- package/dist/components/Select.d.ts +16 -2
- package/dist/components/Select.d.ts.map +1 -1
- package/dist/components/Sidebar.d.ts +40 -1
- package/dist/components/Sidebar.d.ts.map +1 -1
- package/dist/components/SwipeActions.d.ts +93 -0
- package/dist/components/SwipeActions.d.ts.map +1 -0
- package/dist/components/Switch.d.ts +1 -0
- package/dist/components/Switch.d.ts.map +1 -1
- package/dist/components/Textarea.d.ts +13 -0
- package/dist/components/Textarea.d.ts.map +1 -1
- package/dist/components/index.d.ts +31 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/context/MobileContext.d.ts +168 -0
- package/dist/context/MobileContext.d.ts.map +1 -0
- package/dist/hooks/useResponsive.d.ts +158 -0
- package/dist/hooks/useResponsive.d.ts.map +1 -0
- package/dist/index.d.ts +1871 -51
- package/dist/index.esm.js +3025 -196
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3063 -194
- package/dist/index.js.map +1 -1
- package/dist/styles.css +434 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ActionBar.stories.tsx +246 -0
- package/src/components/ActionBar.tsx +242 -0
- package/src/components/BottomNavigation.stories.tsx +142 -0
- package/src/components/BottomNavigation.tsx +225 -0
- package/src/components/Checkbox.stories.tsx +162 -0
- package/src/components/Checkbox.tsx +22 -6
- package/src/components/CheckboxList.stories.tsx +311 -0
- package/src/components/CheckboxList.tsx +433 -0
- package/src/components/Chip.stories.tsx +389 -0
- package/src/components/Chip.tsx +182 -3
- package/src/components/ConfirmDialog.tsx +56 -4
- package/src/components/DataTable.tsx +60 -1
- package/src/components/DataTableCardView.stories.tsx +307 -0
- package/src/components/DataTableCardView.tsx +419 -0
- package/src/components/ExpandablePanel.stories.tsx +620 -0
- package/src/components/ExpandablePanel.tsx +383 -0
- package/src/components/FloatingActionButton.stories.tsx +197 -0
- package/src/components/FloatingActionButton.tsx +301 -0
- package/src/components/Grid.stories.tsx +16 -16
- package/src/components/Input.stories.tsx +214 -0
- package/src/components/Input.tsx +81 -4
- package/src/components/MobileHeader.stories.tsx +205 -0
- package/src/components/MobileHeader.tsx +233 -0
- package/src/components/MobileLayout.stories.tsx +338 -0
- package/src/components/MobileLayout.tsx +313 -0
- package/src/components/Modal.stories.tsx +388 -0
- package/src/components/Modal.tsx +122 -4
- package/src/components/PageHeader.stories.tsx +198 -0
- package/src/components/PageHeader.tsx +217 -0
- package/src/components/PullToRefresh.stories.tsx +321 -0
- package/src/components/PullToRefresh.tsx +294 -0
- package/src/components/QueryTransparency.tsx +1 -1
- package/src/components/SearchableList.stories.tsx +437 -0
- package/src/components/SearchableList.tsx +326 -0
- package/src/components/Select.stories.tsx +190 -0
- package/src/components/Select.tsx +353 -137
- package/src/components/Sidebar.tsx +193 -10
- package/src/components/SwipeActions.stories.tsx +327 -0
- package/src/components/SwipeActions.tsx +387 -0
- package/src/components/Switch.stories.tsx +158 -0
- package/src/components/Switch.tsx +12 -3
- package/src/components/Textarea.tsx +31 -1
- package/src/components/index.ts +69 -3
- package/src/context/MobileContext.tsx +296 -0
- package/src/hooks/useResponsive.ts +360 -0
- package/src/types/index.ts +4 -0
- package/tailwind.config.js +56 -1
package/src/components/index.ts
CHANGED
|
@@ -165,8 +165,14 @@ export type { MarkdownEditorProps } from './MarkdownEditor';
|
|
|
165
165
|
export { default as Menu, MenuDivider } from './Menu';
|
|
166
166
|
export type { MenuProps, MenuItem } from './Menu';
|
|
167
167
|
|
|
168
|
-
export { default as Chip } from './Chip';
|
|
169
|
-
export type { ChipProps } from './Chip';
|
|
168
|
+
export { default as Chip, ChipGroup } from './Chip';
|
|
169
|
+
export type { ChipProps, ChipGroupProps } from './Chip';
|
|
170
|
+
|
|
171
|
+
export { default as CheckboxList } from './CheckboxList';
|
|
172
|
+
export type { CheckboxListProps, CheckboxListItem } from './CheckboxList';
|
|
173
|
+
|
|
174
|
+
export { default as SearchableList } from './SearchableList';
|
|
175
|
+
export type { SearchableListProps, SearchableListItem } from './SearchableList';
|
|
170
176
|
|
|
171
177
|
export { default as NumberInput } from './NumberInput';
|
|
172
178
|
export type { NumberInputProps } from './NumberInput';
|
|
@@ -189,7 +195,10 @@ export type { BottomSheetProps } from './BottomSheet';
|
|
|
189
195
|
export { default as Collapsible } from './Collapsible';
|
|
190
196
|
export type { CollapsibleProps } from './Collapsible';
|
|
191
197
|
|
|
192
|
-
export {
|
|
198
|
+
export { default as ExpandablePanel, ExpandablePanelSpacer, ExpandablePanelContainer } from './ExpandablePanel';
|
|
199
|
+
export type { ExpandablePanelProps } from './ExpandablePanel';
|
|
200
|
+
|
|
201
|
+
export { Show, Hide } from './ResponsiveUtilities';
|
|
193
202
|
|
|
194
203
|
// Navigation Components
|
|
195
204
|
export { default as Breadcrumbs } from './Breadcrumbs';
|
|
@@ -243,6 +252,19 @@ export type { PageNavigationProps } from './PageNavigation';
|
|
|
243
252
|
export { default as Sidebar, SidebarGroup } from './Sidebar';
|
|
244
253
|
export type { SidebarProps, SidebarItem, SidebarGroupProps } from './Sidebar';
|
|
245
254
|
|
|
255
|
+
// Mobile Navigation Components
|
|
256
|
+
export { default as BottomNavigation, BottomNavigationSpacer } from './BottomNavigation';
|
|
257
|
+
export type { BottomNavigationProps, BottomNavItem } from './BottomNavigation';
|
|
258
|
+
|
|
259
|
+
export { default as MobileHeader, MobileHeaderSpacer } from './MobileHeader';
|
|
260
|
+
export type { MobileHeaderProps } from './MobileHeader';
|
|
261
|
+
|
|
262
|
+
export { default as FloatingActionButton, useFABScroll } from './FloatingActionButton';
|
|
263
|
+
export type { FloatingActionButtonProps, FABAction } from './FloatingActionButton';
|
|
264
|
+
|
|
265
|
+
export { default as PullToRefresh, usePullToRefresh } from './PullToRefresh';
|
|
266
|
+
export type { PullToRefreshProps } from './PullToRefresh';
|
|
267
|
+
|
|
246
268
|
// Logo
|
|
247
269
|
export { default as Logo } from './Logo';
|
|
248
270
|
export type { LogoProps } from './Logo';
|
|
@@ -255,6 +277,9 @@ export type { UserProfileButtonProps } from './UserProfileButton';
|
|
|
255
277
|
export { default as Layout } from './Layout';
|
|
256
278
|
export type { LayoutProps } from './Layout';
|
|
257
279
|
|
|
280
|
+
export { default as MobileLayout } from './MobileLayout';
|
|
281
|
+
export type { MobileLayoutProps } from './MobileLayout';
|
|
282
|
+
|
|
258
283
|
export { default as TwoColumnContent } from './TwoColumnContent';
|
|
259
284
|
export type { TwoColumnContentProps } from './TwoColumnContent';
|
|
260
285
|
|
|
@@ -287,6 +312,12 @@ export type {
|
|
|
287
312
|
ExpansionMode
|
|
288
313
|
} from './DataTable';
|
|
289
314
|
|
|
315
|
+
export { default as DataTableCardView } from './DataTableCardView';
|
|
316
|
+
export type { CardViewConfig, DataTableCardViewProps } from './DataTableCardView';
|
|
317
|
+
|
|
318
|
+
export { default as SwipeActions } from './SwipeActions';
|
|
319
|
+
export type { SwipeActionsProps, SwipeAction } from './SwipeActions';
|
|
320
|
+
|
|
290
321
|
// Spreadsheet
|
|
291
322
|
export { Spreadsheet, SpreadsheetReport } from './Spreadsheet';
|
|
292
323
|
export type { SpreadsheetProps, SpreadsheetCell, Matrix, CellBase } from './Spreadsheet';
|
|
@@ -349,6 +380,12 @@ export type { AppLayoutProps } from './AppLayout';
|
|
|
349
380
|
|
|
350
381
|
export { PageLayout } from './PageLayout';
|
|
351
382
|
|
|
383
|
+
export { default as PageHeader } from './PageHeader';
|
|
384
|
+
export type { PageHeaderProps, PageHeaderAction } from './PageHeader';
|
|
385
|
+
|
|
386
|
+
export { default as ActionBar, ActionBarLeft, ActionBarCenter, ActionBarRight } from './ActionBar';
|
|
387
|
+
export type { ActionBarProps, ActionBarAction } from './ActionBar';
|
|
388
|
+
|
|
352
389
|
export { AdminModal } from './AdminModal';
|
|
353
390
|
export type { AdminModalProps, AdminModalTab } from './AdminModal';
|
|
354
391
|
|
|
@@ -414,3 +451,32 @@ export type { ExcelColumn, ExportToExcelOptions, DataTableExportOptions, MultiSh
|
|
|
414
451
|
// Hooks
|
|
415
452
|
export { useColumnResize, useColumnReorder } from '../hooks/useTableEnhancements';
|
|
416
453
|
export type { UseColumnResizeOptions, UseColumnReorderOptions } from '../hooks/useTableEnhancements';
|
|
454
|
+
|
|
455
|
+
// Responsive Hooks
|
|
456
|
+
export {
|
|
457
|
+
useViewportSize,
|
|
458
|
+
useBreakpoint,
|
|
459
|
+
useMediaQuery,
|
|
460
|
+
useIsMobile,
|
|
461
|
+
useIsTablet,
|
|
462
|
+
useIsDesktop,
|
|
463
|
+
useIsTouchDevice,
|
|
464
|
+
useOrientation,
|
|
465
|
+
useBreakpointValue,
|
|
466
|
+
useResponsiveCallback,
|
|
467
|
+
useSafeAreaInsets,
|
|
468
|
+
usePrefersMobile,
|
|
469
|
+
BREAKPOINTS,
|
|
470
|
+
} from '../hooks/useResponsive';
|
|
471
|
+
export type { Breakpoint, ViewportSize, Orientation } from '../hooks/useResponsive';
|
|
472
|
+
|
|
473
|
+
// Mobile Context
|
|
474
|
+
export {
|
|
475
|
+
MobileProvider,
|
|
476
|
+
useMobileContext,
|
|
477
|
+
withMobileContext,
|
|
478
|
+
MobileOnly,
|
|
479
|
+
DesktopOnly,
|
|
480
|
+
Responsive,
|
|
481
|
+
} from '../context/MobileContext';
|
|
482
|
+
export type { MobileContextValue, MobileProviderProps } from '../context/MobileContext';
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import React, { createContext, useContext, useMemo, ReactNode } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
useIsMobile,
|
|
4
|
+
useIsTablet,
|
|
5
|
+
useIsDesktop,
|
|
6
|
+
useIsTouchDevice,
|
|
7
|
+
useBreakpoint,
|
|
8
|
+
useOrientation,
|
|
9
|
+
useViewportSize,
|
|
10
|
+
useSafeAreaInsets,
|
|
11
|
+
Breakpoint,
|
|
12
|
+
Orientation,
|
|
13
|
+
ViewportSize,
|
|
14
|
+
} from '../hooks/useResponsive';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Mobile context value interface
|
|
18
|
+
*
|
|
19
|
+
* Provides comprehensive responsive state for the entire application.
|
|
20
|
+
*/
|
|
21
|
+
export interface MobileContextValue {
|
|
22
|
+
/** True when viewport width < 768px */
|
|
23
|
+
isMobile: boolean;
|
|
24
|
+
/** True when viewport width is 768px - 1023px */
|
|
25
|
+
isTablet: boolean;
|
|
26
|
+
/** True when viewport width >= 1024px */
|
|
27
|
+
isDesktop: boolean;
|
|
28
|
+
/** True when device supports touch input */
|
|
29
|
+
isTouchDevice: boolean;
|
|
30
|
+
/** Current Tailwind breakpoint: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' */
|
|
31
|
+
breakpoint: Breakpoint;
|
|
32
|
+
/** Current orientation: 'portrait' | 'landscape' */
|
|
33
|
+
orientation: Orientation;
|
|
34
|
+
/** Current viewport dimensions */
|
|
35
|
+
viewport: ViewportSize;
|
|
36
|
+
/** Safe area insets for notched devices */
|
|
37
|
+
safeAreaInsets: {
|
|
38
|
+
top: number;
|
|
39
|
+
right: number;
|
|
40
|
+
bottom: number;
|
|
41
|
+
left: number;
|
|
42
|
+
};
|
|
43
|
+
/** True when mobile OR touch device (useful for UI decisions) */
|
|
44
|
+
useMobileUI: boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Default context value (SSR-safe defaults)
|
|
49
|
+
*/
|
|
50
|
+
const defaultContextValue: MobileContextValue = {
|
|
51
|
+
isMobile: false,
|
|
52
|
+
isTablet: false,
|
|
53
|
+
isDesktop: true,
|
|
54
|
+
isTouchDevice: false,
|
|
55
|
+
breakpoint: 'lg',
|
|
56
|
+
orientation: 'landscape',
|
|
57
|
+
viewport: { width: 1024, height: 768 },
|
|
58
|
+
safeAreaInsets: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
59
|
+
useMobileUI: false,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Mobile context
|
|
64
|
+
*/
|
|
65
|
+
const MobileContext = createContext<MobileContextValue>(defaultContextValue);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* MobileProvider props
|
|
69
|
+
*/
|
|
70
|
+
export interface MobileProviderProps {
|
|
71
|
+
/** Child components that will have access to mobile context */
|
|
72
|
+
children: ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Force mobile UI mode regardless of device detection.
|
|
75
|
+
* Useful for testing or forcing mobile layout on tablets.
|
|
76
|
+
*/
|
|
77
|
+
forceMobileUI?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Force desktop UI mode regardless of device detection.
|
|
80
|
+
* Useful for testing or forcing desktop layout on mobile.
|
|
81
|
+
*/
|
|
82
|
+
forceDesktopUI?: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* MobileProvider - Provides responsive state to the entire application
|
|
87
|
+
*
|
|
88
|
+
* Wrap your application with MobileProvider to enable auto-responsive
|
|
89
|
+
* behavior in notebook-ui components.
|
|
90
|
+
*
|
|
91
|
+
* @example Basic usage
|
|
92
|
+
* ```tsx
|
|
93
|
+
* import { MobileProvider } from 'notebook-ui';
|
|
94
|
+
*
|
|
95
|
+
* function App() {
|
|
96
|
+
* return (
|
|
97
|
+
* <MobileProvider>
|
|
98
|
+
* <YourApplication />
|
|
99
|
+
* </MobileProvider>
|
|
100
|
+
* );
|
|
101
|
+
* }
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @example Force mobile UI for testing
|
|
105
|
+
* ```tsx
|
|
106
|
+
* <MobileProvider forceMobileUI>
|
|
107
|
+
* <YourApplication />
|
|
108
|
+
* </MobileProvider>
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function MobileProvider({
|
|
112
|
+
children,
|
|
113
|
+
forceMobileUI = false,
|
|
114
|
+
forceDesktopUI = false,
|
|
115
|
+
}: MobileProviderProps) {
|
|
116
|
+
const isMobile = useIsMobile();
|
|
117
|
+
const isTablet = useIsTablet();
|
|
118
|
+
const isDesktop = useIsDesktop();
|
|
119
|
+
const isTouchDevice = useIsTouchDevice();
|
|
120
|
+
const breakpoint = useBreakpoint();
|
|
121
|
+
const orientation = useOrientation();
|
|
122
|
+
const viewport = useViewportSize();
|
|
123
|
+
const safeAreaInsets = useSafeAreaInsets();
|
|
124
|
+
|
|
125
|
+
const value = useMemo<MobileContextValue>(() => {
|
|
126
|
+
// Calculate effective mobile UI state
|
|
127
|
+
let useMobileUI = isMobile || isTouchDevice;
|
|
128
|
+
|
|
129
|
+
// Apply force overrides
|
|
130
|
+
if (forceMobileUI) {
|
|
131
|
+
useMobileUI = true;
|
|
132
|
+
} else if (forceDesktopUI) {
|
|
133
|
+
useMobileUI = false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
isMobile: forceMobileUI ? true : forceDesktopUI ? false : isMobile,
|
|
138
|
+
isTablet: forceMobileUI || forceDesktopUI ? false : isTablet,
|
|
139
|
+
isDesktop: forceDesktopUI ? true : forceMobileUI ? false : isDesktop,
|
|
140
|
+
isTouchDevice,
|
|
141
|
+
breakpoint: forceMobileUI ? 'xs' : forceDesktopUI ? 'lg' : breakpoint,
|
|
142
|
+
orientation,
|
|
143
|
+
viewport,
|
|
144
|
+
safeAreaInsets,
|
|
145
|
+
useMobileUI,
|
|
146
|
+
};
|
|
147
|
+
}, [
|
|
148
|
+
isMobile,
|
|
149
|
+
isTablet,
|
|
150
|
+
isDesktop,
|
|
151
|
+
isTouchDevice,
|
|
152
|
+
breakpoint,
|
|
153
|
+
orientation,
|
|
154
|
+
viewport,
|
|
155
|
+
safeAreaInsets,
|
|
156
|
+
forceMobileUI,
|
|
157
|
+
forceDesktopUI,
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<MobileContext.Provider value={value}>
|
|
162
|
+
{children}
|
|
163
|
+
</MobileContext.Provider>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* useMobileContext - Hook to access mobile responsive state
|
|
169
|
+
*
|
|
170
|
+
* Must be used within a MobileProvider. Returns comprehensive
|
|
171
|
+
* responsive state for making UI decisions.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```tsx
|
|
175
|
+
* function MyComponent() {
|
|
176
|
+
* const { isMobile, useMobileUI, breakpoint } = useMobileContext();
|
|
177
|
+
*
|
|
178
|
+
* return useMobileUI ? <MobileView /> : <DesktopView />;
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export function useMobileContext(): MobileContextValue {
|
|
183
|
+
const context = useContext(MobileContext);
|
|
184
|
+
|
|
185
|
+
if (context === undefined) {
|
|
186
|
+
// Return default value if used outside provider (graceful degradation)
|
|
187
|
+
console.warn(
|
|
188
|
+
'useMobileContext was used outside of MobileProvider. ' +
|
|
189
|
+
'Wrap your app with <MobileProvider> for full mobile support.'
|
|
190
|
+
);
|
|
191
|
+
return defaultContextValue;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return context;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* withMobileContext - HOC to inject mobile context as props
|
|
199
|
+
*
|
|
200
|
+
* For class components or when you prefer props over hooks.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```tsx
|
|
204
|
+
* interface Props {
|
|
205
|
+
* mobile: MobileContextValue;
|
|
206
|
+
* }
|
|
207
|
+
*
|
|
208
|
+
* class MyComponent extends React.Component<Props> {
|
|
209
|
+
* render() {
|
|
210
|
+
* const { isMobile } = this.props.mobile;
|
|
211
|
+
* return isMobile ? <Mobile /> : <Desktop />;
|
|
212
|
+
* }
|
|
213
|
+
* }
|
|
214
|
+
*
|
|
215
|
+
* export default withMobileContext(MyComponent);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
export function withMobileContext<P extends { mobile: MobileContextValue }>(
|
|
219
|
+
Component: React.ComponentType<P>
|
|
220
|
+
) {
|
|
221
|
+
const displayName = Component.displayName || Component.name || 'Component';
|
|
222
|
+
|
|
223
|
+
const WrappedComponent = (props: Omit<P, 'mobile'>) => {
|
|
224
|
+
const mobile = useMobileContext();
|
|
225
|
+
return <Component {...(props as P)} mobile={mobile} />;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
WrappedComponent.displayName = `withMobileContext(${displayName})`;
|
|
229
|
+
|
|
230
|
+
return WrappedComponent;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* MobileOnly - Renders children only on mobile devices
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```tsx
|
|
238
|
+
* <MobileOnly>
|
|
239
|
+
* <BottomNavigation items={navItems} />
|
|
240
|
+
* </MobileOnly>
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
export function MobileOnly({ children }: { children: ReactNode }) {
|
|
244
|
+
const { useMobileUI } = useMobileContext();
|
|
245
|
+
return useMobileUI ? <>{children}</> : null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* DesktopOnly - Renders children only on desktop devices
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```tsx
|
|
253
|
+
* <DesktopOnly>
|
|
254
|
+
* <Sidebar items={navItems} />
|
|
255
|
+
* </DesktopOnly>
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
export function DesktopOnly({ children }: { children: ReactNode }) {
|
|
259
|
+
const { useMobileUI } = useMobileContext();
|
|
260
|
+
return useMobileUI ? null : <>{children}</>;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Responsive - Renders different content based on device type
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```tsx
|
|
268
|
+
* <Responsive
|
|
269
|
+
* mobile={<MobileNavigation />}
|
|
270
|
+
* tablet={<TabletNavigation />}
|
|
271
|
+
* desktop={<DesktopNavigation />}
|
|
272
|
+
* />
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
export function Responsive({
|
|
276
|
+
mobile,
|
|
277
|
+
tablet,
|
|
278
|
+
desktop,
|
|
279
|
+
}: {
|
|
280
|
+
mobile?: ReactNode;
|
|
281
|
+
tablet?: ReactNode;
|
|
282
|
+
desktop?: ReactNode;
|
|
283
|
+
}) {
|
|
284
|
+
const { isMobile, isTablet, isDesktop } = useMobileContext();
|
|
285
|
+
|
|
286
|
+
if (isMobile && mobile) return <>{mobile}</>;
|
|
287
|
+
if (isTablet && tablet) return <>{tablet}</>;
|
|
288
|
+
if (isDesktop && desktop) return <>{desktop}</>;
|
|
289
|
+
|
|
290
|
+
// Fallback: desktop -> tablet -> mobile
|
|
291
|
+
if (isDesktop) return <>{desktop || tablet || mobile}</>;
|
|
292
|
+
if (isTablet) return <>{tablet || mobile || desktop}</>;
|
|
293
|
+
return <>{mobile || tablet || desktop}</>;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export default MobileContext;
|