@rpg-engine/long-bow 0.8.38 → 0.8.39
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/InformationCenter/InformationCenter.d.ts +1 -0
- package/dist/components/shared/AdvancedFilters/AdvancedFilters.d.ts +1 -0
- package/dist/long-bow.cjs.development.js +43 -22
- package/dist/long-bow.cjs.development.js.map +1 -1
- package/dist/long-bow.cjs.production.min.js +1 -1
- package/dist/long-bow.cjs.production.min.js.map +1 -1
- package/dist/long-bow.esm.js +43 -22
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/InformationCenter/InformationCenter.tsx +4 -0
- package/src/components/shared/AdvancedFilters/AdvancedFilters.tsx +46 -18
package/package.json
CHANGED
|
@@ -29,6 +29,7 @@ interface IInformationCenterProps {
|
|
|
29
29
|
loading?: boolean;
|
|
30
30
|
error?: string;
|
|
31
31
|
initialSearchQuery?: string;
|
|
32
|
+
onClose?: () => void;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export const InformationCenter: React.FC<IInformationCenterProps> = ({
|
|
@@ -44,6 +45,7 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
|
|
|
44
45
|
loading = false,
|
|
45
46
|
error,
|
|
46
47
|
initialSearchQuery = '',
|
|
48
|
+
onClose,
|
|
47
49
|
}) => {
|
|
48
50
|
const [activeTab, setActiveTab] = useState('bestiary');
|
|
49
51
|
const isMobile = isMobileOrTablet();
|
|
@@ -108,6 +110,8 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
|
|
|
108
110
|
width={isMobile ? '95%' : '80%'}
|
|
109
111
|
minWidth="300px"
|
|
110
112
|
cancelDrag=".PaginatedContent-content"
|
|
113
|
+
isFullScreen={isMobile}
|
|
114
|
+
onCloseButton={onClose}
|
|
111
115
|
>
|
|
112
116
|
<Container>
|
|
113
117
|
<InternalTabs
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isMobileOrTablet } from '@rpg-engine/shared';
|
|
1
2
|
import React, { useEffect, useRef } from 'react';
|
|
2
3
|
import {
|
|
3
4
|
AiFillCaretRight,
|
|
@@ -30,6 +31,7 @@ interface IAdvancedFiltersProps {
|
|
|
30
31
|
sections: IFilterSection[];
|
|
31
32
|
onClearAll: () => void;
|
|
32
33
|
hasActiveFilters: boolean;
|
|
34
|
+
onClose?: () => void;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
export const AdvancedFilters: React.FC<IAdvancedFiltersProps> = ({
|
|
@@ -38,6 +40,7 @@ export const AdvancedFilters: React.FC<IAdvancedFiltersProps> = ({
|
|
|
38
40
|
sections,
|
|
39
41
|
onClearAll,
|
|
40
42
|
hasActiveFilters,
|
|
43
|
+
onClose,
|
|
41
44
|
}) => {
|
|
42
45
|
const renderFilterSection = (section: IFilterSection) => {
|
|
43
46
|
switch (section.type) {
|
|
@@ -106,13 +109,13 @@ export const AdvancedFilters: React.FC<IAdvancedFiltersProps> = ({
|
|
|
106
109
|
});
|
|
107
110
|
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
108
111
|
const panelRef = useRef<HTMLDivElement>(null);
|
|
112
|
+
const isMobile = isMobileOrTablet();
|
|
109
113
|
|
|
110
114
|
useEffect(() => {
|
|
111
115
|
if (isOpen && buttonRef.current) {
|
|
112
116
|
const rect = buttonRef.current.getBoundingClientRect();
|
|
113
|
-
const isMobileView = window.innerWidth < 480;
|
|
114
117
|
|
|
115
|
-
if (
|
|
118
|
+
if (isMobile) {
|
|
116
119
|
// For mobile, position in center of screen
|
|
117
120
|
setButtonPosition({
|
|
118
121
|
top: window.innerHeight / 2,
|
|
@@ -128,7 +131,7 @@ export const AdvancedFilters: React.FC<IAdvancedFiltersProps> = ({
|
|
|
128
131
|
});
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
|
-
}, [isOpen]);
|
|
134
|
+
}, [isOpen, isMobile]);
|
|
132
135
|
|
|
133
136
|
// Handle click outside to close the panel
|
|
134
137
|
useEffect(() => {
|
|
@@ -153,6 +156,13 @@ export const AdvancedFilters: React.FC<IAdvancedFiltersProps> = ({
|
|
|
153
156
|
};
|
|
154
157
|
}, [isOpen, onToggle]);
|
|
155
158
|
|
|
159
|
+
const handleClose = () => {
|
|
160
|
+
onToggle();
|
|
161
|
+
if (onClose) {
|
|
162
|
+
onClose();
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
156
166
|
return (
|
|
157
167
|
<Container>
|
|
158
168
|
<FilterButton
|
|
@@ -185,24 +195,20 @@ export const AdvancedFilters: React.FC<IAdvancedFiltersProps> = ({
|
|
|
185
195
|
|
|
186
196
|
{isOpen && (
|
|
187
197
|
<Portal>
|
|
198
|
+
{isMobile && <Overlay />}
|
|
188
199
|
<FiltersPanel
|
|
189
200
|
ref={panelRef}
|
|
190
201
|
style={{
|
|
191
202
|
position: 'fixed',
|
|
192
|
-
top:
|
|
193
|
-
left: buttonPosition.
|
|
194
|
-
? '50vw'
|
|
195
|
-
: `${buttonPosition.left}px`,
|
|
196
|
-
transform: buttonPosition.isMobile
|
|
197
|
-
? 'translate(-50%, -50%)'
|
|
198
|
-
: 'translateX(-50%)',
|
|
203
|
+
top: isMobile ? '50vh' : `${buttonPosition.top}px`,
|
|
204
|
+
left: isMobile ? '50vw' : `${buttonPosition.left}px`,
|
|
199
205
|
zIndex: 9999,
|
|
200
206
|
}}
|
|
201
|
-
$isMobile={
|
|
207
|
+
$isMobile={isMobile}
|
|
202
208
|
>
|
|
203
209
|
<FilterHeader>
|
|
204
210
|
<FilterTitle>Advanced Filters</FilterTitle>
|
|
205
|
-
<CloseButton onClick={
|
|
211
|
+
<CloseButton onClick={handleClose}>×</CloseButton>
|
|
206
212
|
</FilterHeader>
|
|
207
213
|
|
|
208
214
|
{sections.map(renderFilterSection)}
|
|
@@ -267,19 +273,21 @@ const FiltersPanel = styled.div<{ $isMobile?: boolean }>`
|
|
|
267
273
|
background: #1a1a1a;
|
|
268
274
|
border: 1px solid #333;
|
|
269
275
|
border-radius: 6px;
|
|
270
|
-
padding: 1rem;
|
|
271
|
-
width: 280px;
|
|
276
|
+
padding: ${props => (props.$isMobile ? '0.75rem' : '1rem')};
|
|
277
|
+
width: ${props => (props.$isMobile ? '240px' : '280px')};
|
|
272
278
|
max-width: calc(100vw - 20px);
|
|
273
279
|
display: flex;
|
|
274
280
|
flex-direction: column;
|
|
275
|
-
gap: 1rem;
|
|
281
|
+
gap: ${props => (props.$isMobile ? '0.75rem' : '1rem')};
|
|
276
282
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
277
283
|
font-family: 'Press Start 2P', cursive;
|
|
284
|
+
transform: ${props =>
|
|
285
|
+
props.$isMobile ? 'translate(-50%, -50%) scale(0.9)' : 'translateX(-50%)'};
|
|
278
286
|
|
|
279
287
|
@media (max-width: 320px) {
|
|
280
|
-
width:
|
|
281
|
-
padding: 0.
|
|
282
|
-
gap: 0.
|
|
288
|
+
width: 220px;
|
|
289
|
+
padding: 0.65rem;
|
|
290
|
+
gap: 0.65rem;
|
|
283
291
|
}
|
|
284
292
|
|
|
285
293
|
&:before {
|
|
@@ -306,6 +314,26 @@ const FilterHeader = styled.div`
|
|
|
306
314
|
border-bottom: 1px solid #333;
|
|
307
315
|
`;
|
|
308
316
|
|
|
317
|
+
const Overlay = styled.div`
|
|
318
|
+
position: fixed;
|
|
319
|
+
top: 0;
|
|
320
|
+
left: 0;
|
|
321
|
+
right: 0;
|
|
322
|
+
bottom: 0;
|
|
323
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
324
|
+
z-index: 9998;
|
|
325
|
+
animation: fadeIn 0.2s ease-out;
|
|
326
|
+
|
|
327
|
+
@keyframes fadeIn {
|
|
328
|
+
from {
|
|
329
|
+
opacity: 0;
|
|
330
|
+
}
|
|
331
|
+
to {
|
|
332
|
+
opacity: 1;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
`;
|
|
336
|
+
|
|
309
337
|
const FilterTitle = styled.div`
|
|
310
338
|
font-weight: 600;
|
|
311
339
|
color: #ffd700;
|