Skip to content

Commit

Permalink
Popup improvements and acknowledgement of existing vite bug: vitejs/v…
Browse files Browse the repository at this point in the history
  • Loading branch information
budlin2 committed Nov 6, 2023
1 parent 1ce4df9 commit f38543d
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 78 deletions.
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@storybook/testing-library": "^0.2.2",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/storybook__react": "^5.2.1",
"@vitejs/plugin-react": "^1.3.0",
"babel-loader": "^8.2.5",
"storybook": "^7.5.2",
Expand Down
77 changes: 77 additions & 0 deletions src/components/Popup/Item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useState } from 'react';

import { PopupItemT } from './PopupTypes';

import _classes from './popup.module.css';
import { classNames } from '../../utils';

export interface ItemClassesT {
item?: string,
itemHover?: string,
itemActive?: string,
};

export interface ItemStylesT {
item?: React.CSSProperties,
itemHover?: React.CSSProperties,
itemActive?: React.CSSProperties,
};

interface Props {
classes?: ItemClassesT,
styles?: ItemStylesT,
item: PopupItemT,
};

const Item = ({
classes,
styles,
item,
}: Props) => {
//------------------------------------------------------------------------------------------------------------------
// State
//------------------------------------------------------------------------------------------------------------------
const [hovered, setHovered] = useState<boolean>(false);
const [active, setActive] = useState<boolean>(false);

//------------------------------------------------------------------------------------------------------------------
// Styling
//------------------------------------------------------------------------------------------------------------------
const itemClassName = classNames(
classNames(_classes?.item, classes?.item ),
hovered && classNames(_classes?.itemHover, classes?.itemHover),
active && classNames(_classes?.itemActive, classes?.itemActive),
);

console.log(itemClassName)

const itemStyle = {
...styles?.item,
...( hovered ? styles?.itemHover : {} ),
...( active ? styles?.itemActive : {} ),
};

//------------------------------------------------------------------------------------------------------------------
// Event Handlers
//------------------------------------------------------------------------------------------------------------------
const handleMouseEnter = () => setHovered(true);
const handleMouseLeave = () => setHovered(false);
const handleMouseDown = () => setActive(true);
const handleMouseUp = () => setActive(false);

return (
<div key={ item.id }
className ={ itemClassName }
style ={ itemStyle }
onClick ={ item.onClick }
onMouseEnter ={ handleMouseEnter }
onMouseLeave ={ handleMouseLeave }
onMouseDown ={ handleMouseDown }
onMouseUp ={ handleMouseUp }
>
{ item.label }
</div>
);
};

export default Item;
2 changes: 1 addition & 1 deletion src/components/Popup/PopupTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ID } from "../Tuple/TupleTypes";
import { ID } from '../Tuple/TupleTypes';

export type HorizontalRuleT = 'hr';

Expand Down
84 changes: 29 additions & 55 deletions src/components/Popup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
import { CSSProperties, useEffect, useState } from 'react';
import { CSSProperties, useEffect } from 'react';

import { PopupItemsT } from './PopupTypes';
import { classNames, getUniqueId } from '../../utils';
import Item, { ItemClassesT, ItemStylesT } from './Item';

import _classes from './popup.module.css';
import { classNames } from '../../utils';
import { ID } from '../Tuple/TupleTypes';

export interface PopupStylesT {
export interface PopupStylesT extends ItemStylesT {
popup?: CSSProperties,
itemHover?: CSSProperties,
itemActive?: CSSProperties,
item?: CSSProperties,
hr?: CSSProperties,
};

export interface PopupClassesT {
export interface PopupClassesT extends ItemClassesT {
popup?: string,
itemHover?: string,
itemActive?: string,
item?: string,
hr?: string,
};

export interface Props {
position: { x: number, y: number },
items: PopupItemsT,
classes?: PopupClassesT,
styles?: PopupStylesT,
onClose?: () => void,
position: { x: number, y: number },
items: PopupItemsT,
classes?: PopupClassesT,
styles?: PopupStylesT,
onClose?: () => void,
}

const Popup = ({
Expand All @@ -37,64 +31,44 @@ const Popup = ({
styles,
onClose,
}: Props) => {
//------------------------------------------------------------------------------------------------------------------
// State
//------------------------------------------------------------------------------------------------------------------
const [hoveredId, setHoveredId] = useState<ID>(null);
const [activeId, setActiveId] = useState<ID>(null);

//------------------------------------------------------------------------------------------------------------------
// Styling
//------------------------------------------------------------------------------------------------------------------
const popupClassName = classNames(_classes?.popup, classes?.popup);
const popupStyle: CSSProperties = { ...styles?.popup, left: x, top: y };

const itemClassNameBase = classNames(_classes?.item, classes?.item);
const itemClasses = {
item: classes?.item,
itemHover: classes?.itemHover,
itemActive: classes?.itemActive,
};

const itemStyles = {
item: styles?.item,
itemHover: styles?.itemHover,
itemActive: styles?.itemActive,
};

const hrClassName = classNames(_classes?.hr, classes?.hr);

//------------------------------------------------------------------------------------------------------------------
// Event Handlers
// Effects
//------------------------------------------------------------------------------------------------------------------
const handleMouseEnter = (id: ID) => setHoveredId(id);
const handleMouseLeave = () => setHoveredId(null);
const handleMouseDown = (id: ID) => setActiveId(id);

// TODO: WTF is this?
useEffect(() => (() => onClose()), []);

return (
<div className={popupClassName} style={popupStyle}>
{ items.map( item => {
if (item == 'hr')
return <hr className={ hrClassName } style={ styles?.hr } />;

const itemClassName = classNames(
itemClassNameBase,
hoveredId === item.id && _classes?.itemHover,
hoveredId === item.id && classes?.itemHover,
activeId === item.id && _classes?.itemActive,
activeId === item.id && classes?.itemActive,
);

console.log(itemClassName)

const itemStyle = {
...styles?.item,
...( hoveredId === item.id ? styles?.itemHover : {} ),
...( activeId === item.id ? styles?.itemActive : {} ),
};
return <hr key={ getUniqueId() } className={ hrClassName } style={ styles?.hr } />;

return (
<div key={ item.id }
className ={ itemClassName }
style ={ itemStyle }
onClick ={ item.onClick }
onMouseEnter ={ () => handleMouseEnter(item.id) }
onMouseLeave ={ handleMouseLeave }
onMouseDown ={ () => handleMouseDown(item.id) }
>
{ item.label }
</div>
<Item key={ item.id }
classes ={ itemClasses }
styles ={ itemStyles }
item ={ item }
/>
);
})}
</div>
Expand Down
23 changes: 14 additions & 9 deletions src/components/Popup/popup.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
height: 1px;
width: 100%;
margin: 0;
background-color: black; /* line color */
background: black; /* line color */
}

.item {
Expand All @@ -26,12 +26,17 @@
cursor: pointer;
}

.itemHover {
background: rgba(0, 0, 0, 0.5);
color: white;
}
/*
Not providing default styles for itemHover and itemActive:
This active issue details why:
https://github.com/vitejs/vite/issues/3924
Basically, Vite is screwing up the order by which CSS modules
are loaded, so the styles for itemHover and itemActive are
are being applied before the styles passed into them via
the `classes` prop.
It's weird. If I clear the cache, it will be correct on the first
page render and then incorrect on every subsequent page render.
.itemActive {
background: black;
color: white;
}
Keep an eye on styles that get passed in a production app.
*/
12 changes: 3 additions & 9 deletions src/components/Tuple/Tree/Leaf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,9 @@ const Leaf = ({
const leafClassName = classNames(
_classes?.leaf_base,
classes?.leaf_base,
isDraggedOver
? classNames(_classes?.leaf_dragOver, classes?.leaf_dragOver)
: '',
hovering
? classNames(_classes?.leaf_hover, classes?.leaf_hover)
: '',
renaming
? classNames(_classes?.leaf_active, classes?.leaf_active)
: '',
isDraggedOver && classNames(_classes?.leaf_dragOver, classes?.leaf_dragOver),
hovering && classNames(_classes?.leaf_hover, classes?.leaf_hover),
renaming && classNames(_classes?.leaf_active, classes?.leaf_active),
);

const newNodeClassName = classNames(
Expand Down
6 changes: 4 additions & 2 deletions src/components/Tuple/Tree/Tree.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import _classes from './tree.module.css';

import { useContext, useEffect, useRef, useState } from 'react';

import Root from './Root';
Expand All @@ -6,12 +8,12 @@ import { PopupDetailsT, TreeT } from './TreeTypes';
import { ID, TupleContextT } from '../TupleTypes';
import Trashcan from './Trashcan';
import ScrollPane from '../../ScrollPane';
import Popup, { PopupClassesT, PopupStylesT } from '../../Popup';
import Branches from './Branches';

import _classes from './tree.module.css';
import { classNames } from '../../../utils';

import Popup, { PopupClassesT, PopupStylesT } from '../../Popup';


export interface TreeProps {
tree: TreeT,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Tuple/Tree/tree.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -240,5 +240,5 @@

.popupItem_hover {
background: var(--COLOR-SECONDARY-3);
color: red;
color: var(--COLOR-PRIMARY-1);
}
2 changes: 1 addition & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ const getRandomWord = () => {

export const isObject = (obj: any) => typeof obj === 'object' && !Array.isArray(obj) && obj !== null;

export const classNames = (...classNames: string[]): string => classNames.reduce((acc, cur) => cur ? (acc + ' ' + cur) : acc, '');
export const classNames = (...classNames: string[]): string => classNames.reduce((acc, cur) => (cur ? (acc + cur) : acc) + ' ', '').trim();

0 comments on commit f38543d

Please sign in to comment.