Skip to content

Commit

Permalink
chore: finish profile add/overwrite modal styling
Browse files Browse the repository at this point in the history
  • Loading branch information
jessebofill committed Jan 9, 2024
1 parent 5e5b147 commit 45bca81
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 42 deletions.
63 changes: 43 additions & 20 deletions src/components/generic/ScrollableWindow.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,65 @@
import { GamepadButton } from 'decky-frontend-lib';
import { FC, Fragment } from 'react';
import { GamepadButton, gamepadDialogClasses, scrollPanelClasses } from 'decky-frontend-lib';
import { FC, Fragment, useRef } from 'react';
import { ModalPosition, Panel, ScrollPanelGroup } from '../docs/Scrollable';
import { useIsOverflowing } from '../../hooks/useIsOverflowing';

export interface ScrollableWindowProps {
height: string;
fadePercent: number;
fadeAmount: string;
scrollBarWidth?: string;
}
export const ScrollableWindow: FC<ScrollableWindowProps> = ({ height, fadePercent, children }) => {
export const ScrollableWindow: FC<ScrollableWindowProps> = ({ height, fadeAmount, scrollBarWidth, children }) => {
const barWidth = scrollBarWidth === undefined || scrollBarWidth === '' ? '4px' : scrollBarWidth;

const scrollPanelRef = useRef();
const isOverflowing = useIsOverflowing(scrollPanelRef);

const panel = (
<ScrollPanelGroup ref={scrollPanelRef} focusable={false} style={{ flex: 1, minHeight: 0 }}>
<Panel
focusable={isOverflowing}
noFocusRing={true}
actionDescriptionMap={{
[GamepadButton.DIR_UP]: 'Scroll Up',
[GamepadButton.DIR_DOWN]: 'Scroll Down'
}}>
{children}
</Panel>
</ScrollPanelGroup>
);

return (
<>
<style>
{`.modal-position-container .gamepaddialog_ModalPosition_30VHl {
{`.modal-position-container .${gamepadDialogClasses.ModalPosition} {
top: 0;
bottom: 0;
padding: 0;
}
.modal-position-container .${scrollPanelClasses.ScrollPanel}::-webkit-scrollbar {
display: initial !important;
width: ${barWidth};
}
.modal-position-container .${scrollPanelClasses.ScrollPanel}::-webkit-scrollbar-thumb {
border: 0;
}`}
</style>
<div
className='modal-position-container'
style={{
position: 'relative',
height: height,
WebkitMaskImage: `linear-gradient(to bottom, transparent, black ${fadePercent}%, black ${100 - fadePercent}%, transparent 100%)`
WebkitMask: `linear-gradient(to right , transparent, transparent calc(100% - ${barWidth}), white calc(100% - ${barWidth})), linear-gradient(to bottom, transparent, black ${fadeAmount}, black calc(100% - ${fadeAmount}), transparent 100%)`
}}>
<ModalPosition>

<ScrollPanelGroup focusable={false} style={{ flex: 1, minHeight: 0 }}>
<Panel
focusable={true}
noFocusRing={true}
actionDescriptionMap={{
[GamepadButton.DIR_UP]: 'Scroll Up',
[GamepadButton.DIR_DOWN]: 'Scroll Down'
}}>
{children}
</Panel>
</ScrollPanelGroup>
</ModalPosition>
{isOverflowing ? (
<ModalPosition key={'modal-position'}>
{panel}
</ModalPosition>
) : (
<div className={`${gamepadDialogClasses.ModalPosition} ${gamepadDialogClasses.WithStandardPadding} Panel`} key={'modal-position'}>
{panel}
</div>
)}
</div>
</>
);
Expand Down
61 changes: 39 additions & 22 deletions src/components/modals/TabProfileModals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { TabMasterManager } from '../../state/TabMasterManager';
import { TabMasterContextProvider } from "../../state/TabMasterContext";
import { TabProfileModalStyles } from "../styles/TabProfileModalStyles";
import { TabListLabel } from '../TabListLabel';
import { ScrollableWindow } from '../generic/ScrollableWindow';

export interface CreateTabProfileModalProps {
tabMasterManager: TabMasterManager,
Expand Down Expand Up @@ -40,17 +41,17 @@ export const CreateTabProfileModal: VFC<CreateTabProfileModalProps> = ({ tabMast
</>
} />
</div>
{/* <ScrollableWindow height='180px' fadePercent={7}> */}
<div style={{ padding: '0 20px'}}>
{visibleTabs.map(tabContainer => {
return (
<div style={{ marginRight: '-4px' }}>
<ScrollableWindow height='180px' fadeAmount={'12px'}>
<div style={{ padding: '0 20px' }}>
{visibleTabs.map(tabContainer =>
<TabItem >
<TabListLabel tabContainer={tabContainer} microSDeckDisabled={false} />
</TabItem>
);
})}
</div>
{/* </ScrollableWindow> */}
)}
</div>
</ScrollableWindow>
</div>
</ConfirmModal>
</div>
</TabMasterContextProvider>
Expand All @@ -77,14 +78,35 @@ export const OverwriteTabProfileModal: VFC<OverwriteTabProfileModalProps> = ({ p
}}
onCancel={() => closeModal!()}
>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<div>
New Tabs:
{visibleTabsList.map(tabContainer => <div>{tabContainer.title}</div>)}
<div>
<div style={{ display: 'flex', flexDirection: 'row', padding: '0 20px', gap: '30px' }}>
<div className={quickAccessControlsClasses.PanelSectionTitle} style={{ flex: 1, paddingBottom: 0 }}>
New Tabs
</div>
<div className={quickAccessControlsClasses.PanelSectionTitle} style={{ flex: 1, paddingBottom: 0 }}>
Existing Tabs
</div>
</div>
<div>
Existing Tabs:
{existingTabs.map(tabContainer => <div>{tabContainer?.title}</div>)}
<div style={{ height: '1.5px', background: '#ffffff1a' }} />
<div style={{ marginRight: '-4px' }}>
<ScrollableWindow height='200px' fadeAmount={'12px'}>
<div style={{ display: 'flex', flexDirection: 'row', padding: '0 20px', gap: '30px' }}>
<div style={{ flex: 1 }}>
{visibleTabsList.map(tabContainer =>
<TabItem >
<TabListLabel tabContainer={tabContainer} microSDeckDisabled={false} />
</TabItem>
)}
</div>
<div style={{ flex: 1 }}>
{existingTabs.map(tabContainer =>
<TabItem >
<TabListLabel tabContainer={tabContainer!} microSDeckDisabled={false} />
</TabItem>
)}
</div>
</div>
</ScrollableWindow>
</div>
</div>
</ConfirmModal>
Expand All @@ -94,18 +116,13 @@ export const OverwriteTabProfileModal: VFC<OverwriteTabProfileModalProps> = ({ p
};

const TabItem: FC<{}> = ({ children }) => {

return (
<>
<div style={{ padding: '0 15px', height: '28px', display: 'flex', fontSize: 'small' }}>
{children}
</div>
<div
style={{
height: '2px',
background: 'rgba(255,255,255,.1)',
flexShrink: '0'
}}
/>
<div style={{ height: '.5px', background: '#ffffff1a' }} />
</>
);
};
Expand Down
19 changes: 19 additions & 0 deletions src/hooks/useIsOverflowing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MutableRefObject, useLayoutEffect, useState } from 'react';

export const useIsOverflowing = (ref: MutableRefObject<HTMLElement | undefined>) => {
const [isOverflow, setIsOverflow] = useState(false);

useLayoutEffect(() => {
const { current } = ref;
const trigger = () => {
const hasOverflow = current!.scrollHeight > current!.clientHeight;
setIsOverflow(hasOverflow);
};

if (current) {
trigger();
}
}, [ref]);

return isOverflow;
};

0 comments on commit 45bca81

Please sign in to comment.