Improve icon panel layout and accessibility for smaller screens (Issue #125) (#138)

* feat: add dismissible drag-drop hint with persistent user preference in iconImport section

* feat: reorder import section below kubernetes for improved layout (#125)
This commit is contained in:
Dibyendu Sahoo
2025-09-18 13:29:41 +05:30
committed by GitHub
parent d698a1a120
commit 77231c97a2
4 changed files with 76 additions and 47 deletions

View File

@@ -27,6 +27,11 @@ export const IconSelectionControls = () => {
const { iconCategories } = useIconCategories();
const fileInputRef = useRef<HTMLInputElement>(null);
const [treatAsIsometric, setTreatAsIsometric] = useState(true);
const [showAlert, setShowAlert] = useState(() => {
// Check localStorage to see if user has dismissed the alert
return localStorage.getItem('fossflow-show-drag-hint') !== 'false';
});
const onMouseDown = useCallback(
(icon: Icon) => {
@@ -45,6 +50,11 @@ export const IconSelectionControls = () => {
fileInputRef.current?.click();
}, []);
const dismissAlert = useCallback(() => {
setShowAlert(false);
localStorage.setItem('fossflow-show-drag-hint', 'false');
}, []);
const handleFileSelect = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
const files = event.target.files;
if (!files || files.length === 0) return;
@@ -196,50 +206,6 @@ export const IconSelectionControls = () => {
<Box sx={{ marginTop: '8px' }}>
<Searchbox value={filter} onChange={setFilter} />
</Box>
<Box sx={{
border: '1px solid #e0e0e0',
borderRadius: 1,
p: 1.5,
backgroundColor: '#f5f5f5'
}}>
<Button
variant="outlined"
startIcon={<FileUploadIcon />}
onClick={handleImportClick}
fullWidth
>
Import Icons
</Button>
<FormControlLabel
control={
<Checkbox
checked={treatAsIsometric}
onChange={(e) => setTreatAsIsometric(e.target.checked)}
size="small"
/>
}
label={
<Typography variant="body2">
Treat as isometric (3D view)
</Typography>
}
sx={{ mt: 1, ml: 0 }}
/>
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.5 }}>
Uncheck for flat icons (logos, UI elements)
</Typography>
</Box>
<input
ref={fileInputRef}
type="file"
accept="image/*"
multiple
style={{ display: 'none' }}
onChange={handleFileSelect}
/>
<Alert severity="info">
You can drag and drop any item below onto the canvas.
</Alert>
</Stack>
</Section>
}
@@ -252,6 +218,61 @@ export const IconSelectionControls = () => {
{!filteredIcons && (
<Icons iconCategories={iconCategories} onMouseDown={onMouseDown} />
)}
<Section>
<Box sx={{
border: '1px solid #e0e0e0',
borderRadius: 1,
p: 1.5,
backgroundColor: '#f5f5f5'
}}>
<Button
variant="outlined"
startIcon={<FileUploadIcon />}
onClick={handleImportClick}
fullWidth
>
Import Icons
</Button>
<FormControlLabel
control={
<Checkbox
checked={treatAsIsometric}
onChange={(e) => setTreatAsIsometric(e.target.checked)}
size="small"
/>
}
label={
<Typography variant="body2">
Treat as isometric (3D view)
</Typography>
}
sx={{ mt: 1, ml: 0 }}
/>
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.5 }}>
Uncheck for flat icons (logos, UI elements)
</Typography>
</Box>
<input
ref={fileInputRef}
type="file"
accept="image/*"
multiple
style={{ display: 'none' }}
onChange={handleFileSelect}
/>
{showAlert && (
<Alert
severity="info"
onClose={dismissAlert}
sx={{ cursor: 'pointer', mt: 1 }}
>
You can drag and drop any item below onto the canvas.
</Alert>
)}
</Section>
</ControlsContainer>
);
};

View File

@@ -9,7 +9,8 @@ import {
DeleteOutline as DeleteOutlineIcon,
Undo as UndoIcon,
Redo as RedoIcon,
Settings as SettingsIcon
Settings as SettingsIcon,
} from '@mui/icons-material';
import { UiElement } from 'src/components/UiElement/UiElement';
import { IconButton } from 'src/components/IconButton/IconButton';
@@ -133,6 +134,9 @@ export const MainMenu = () => {
uiStateActions.setDialog(DialogTypeEnum.SETTINGS);
}, [uiStateActions]);
const sectionVisibility = useMemo(() => {
return {
actions: Boolean(
@@ -197,6 +201,7 @@ export const MainMenu = () => {
{t('redo')}
</MenuItem>
{(canUndo || canRedo) && sectionVisibility.actions && <Divider />}
{/* File Actions */}

View File

@@ -35,6 +35,7 @@ const initialState = () => {
hotkeyProfile: DEFAULT_HOTKEY_PROFILE,
panSettings: DEFAULT_PAN_SETTINGS,
connectorInteractionMode: 'click', // Default to click mode
actions: {
setView: (view) => {
set({ view });
@@ -94,10 +95,10 @@ const initialState = () => {
setEnableDebugTools: (enableDebugTools) => {
set({ enableDebugTools });
},
setRendererEl: (el) => {
setRendererEl: (el: HTMLDivElement) => {
set({ rendererEl: el });
},
setHotkeyProfile: (hotkeyProfile) => {
setHotkeyProfile: (hotkeyProfile: any) => {
set({ hotkeyProfile });
},
setPanSettings: (panSettings) => {

View File

@@ -154,6 +154,7 @@ export interface UiState {
hotkeyProfile: HotkeyProfile;
panSettings: PanSettings;
connectorInteractionMode: ConnectorInteractionMode;
}
export interface UiStateActions {
@@ -177,6 +178,7 @@ export interface UiStateActions {
setHotkeyProfile: (profile: HotkeyProfile) => void;
setPanSettings: (settings: PanSettings) => void;
setConnectorInteractionMode: (mode: ConnectorInteractionMode) => void;
}
export type UiStateStore = UiState & {