-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: canvas template added (#4227)
* chore: canvas template added * chore: set pentaho as app default theme * chore: add missing theme to HvBaseTheme * chore: leverage css vars inside base node * chore: clean up base hook sample
- Loading branch information
1 parent
fd75cf6
commit 2cff9c6
Showing
35 changed files
with
1,590 additions
and
869 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { css } from "@emotion/css"; | ||
import { StoryObj } from "@storybook/react"; | ||
import { | ||
canvasPanelClasses, | ||
canvasToolbarClasses, | ||
} from "@hitachivantara/uikit-react-pentaho"; | ||
|
||
import Canvas from "../../templates/Canvas"; | ||
import CanvasRaw from "../../templates/Canvas?raw"; | ||
|
||
export default { | ||
title: "Templates/Canvas", | ||
}; | ||
|
||
const classes = { | ||
// Needed to override the styles specific to the app but can't be used in Storybook | ||
root: css({ | ||
"& > div": { height: "calc(100vh - 40px)" }, | ||
[`& .${canvasToolbarClasses.root}`]: { top: 8 }, | ||
[`& .${canvasPanelClasses.root}`]: { top: 8, height: "calc(100% - 8px)" }, | ||
}), | ||
}; | ||
|
||
export const Main: StoryObj = { | ||
parameters: { | ||
docs: { | ||
source: { | ||
code: CanvasRaw, | ||
}, | ||
}, | ||
}, | ||
decorators: [(Story) => <div className={classes.root}>{Story()}</div>], | ||
render: () => <Canvas />, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { | ||
createContext, | ||
Dispatch, | ||
SetStateAction, | ||
useContext, | ||
useMemo, | ||
useState, | ||
} from "react"; | ||
|
||
interface SelectedTable { | ||
id: string; | ||
label: React.ReactNode; | ||
} | ||
|
||
interface CanvasContextValue { | ||
selectedTable: string; | ||
setSelectedTable?: Dispatch<SetStateAction<string>>; | ||
openedTables?: SelectedTable[]; | ||
setOpenedTables?: Dispatch<SetStateAction<SelectedTable[] | undefined>>; | ||
} | ||
|
||
const CanvasContext = createContext<CanvasContextValue>({ | ||
selectedTable: "none", | ||
}); | ||
|
||
interface CanvasProviderProps { | ||
children?: React.ReactNode; | ||
} | ||
|
||
export const CanvasProvider = ({ children }: CanvasProviderProps) => { | ||
const [openedTables, setOpenedTables] = useState<SelectedTable[]>(); | ||
const [selectedTable, setSelectedTable] = useState<string>("none"); | ||
|
||
const value = useMemo( | ||
() => ({ | ||
openedTables, | ||
setOpenedTables, | ||
selectedTable, | ||
setSelectedTable, | ||
}), | ||
[openedTables, selectedTable], | ||
); | ||
|
||
return ( | ||
<CanvasContext.Provider value={value}>{children}</CanvasContext.Provider> | ||
); | ||
}; | ||
|
||
export const useCanvasContext = () => useContext(CanvasContext); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import { forwardRef, useRef, useState } from "react"; | ||
import { useDraggable } from "@dnd-kit/core"; | ||
import { css, cx } from "@emotion/css"; | ||
import { | ||
HvInput, | ||
HvInputProps, | ||
HvListContainer, | ||
HvListItem, | ||
HvListItemProps, | ||
HvTypography, | ||
outlineStyles, | ||
theme, | ||
useForkRef, | ||
useUniqueId, | ||
} from "@hitachivantara/uikit-react-core"; | ||
import { Drag } from "@hitachivantara/uikit-react-icons"; | ||
|
||
import { NodeData } from "./Node"; | ||
import { iconsMapping, iconsMappingKeys } from "./utils"; | ||
|
||
const classes = { | ||
root: css({ display: "flex", flexDirection: "column", gap: theme.space.sm }), | ||
item: css({ | ||
display: "flex", | ||
justifyContent: "space-between", | ||
alignItems: "center", | ||
border: `1px solid ${theme.colors.atmo3}`, | ||
borderRadius: "12px", | ||
backgroundColor: theme.colors.atmo1, | ||
padding: theme.space.xs, | ||
height: "unset", | ||
"&:focus-visible": { | ||
...outlineStyles, | ||
}, | ||
}), | ||
itemTitle: css({ | ||
display: "flex", | ||
alignItems: "center", | ||
gap: theme.space.xs, | ||
}), | ||
icon: css({ | ||
borderRadius: theme.radii.round, | ||
backgroundColor: theme.colors.cat6_60, | ||
}), | ||
dragging: css({ | ||
border: `2px solid ${theme.colors.primary_80}`, | ||
}), | ||
}; | ||
|
||
const items = iconsMappingKeys.map((key, index) => ({ | ||
id: `item${index + 1}`, | ||
title: `Item ${index + 1}`, | ||
subtitle: `Description ${index + 1}`, | ||
icon: key, | ||
})); | ||
|
||
interface ItemProps { | ||
id: string; | ||
title: string; | ||
subtitle: string; | ||
icon: string; | ||
} | ||
|
||
interface ItemCardProps | ||
extends Omit<HvListItemProps, "title">, | ||
Omit<ItemProps, "id"> { | ||
isDragging?: boolean; | ||
} | ||
|
||
const ItemCard = forwardRef<HTMLLIElement, ItemCardProps>( | ||
({ icon, title, subtitle, isDragging, ...others }, ref) => { | ||
return ( | ||
<HvListItem | ||
ref={ref} | ||
classes={{ root: cx(classes.item, { [classes.dragging]: isDragging }) }} | ||
{...others} | ||
> | ||
<div className={classes.itemTitle}> | ||
<div className={classes.icon}>{iconsMapping[icon]}</div> | ||
<HvTypography variant="label">{title}</HvTypography> | ||
</div> | ||
<Drag /> | ||
</HvListItem> | ||
); | ||
}, | ||
); | ||
|
||
const DraggableItemCard = ({ icon, title, id, subtitle }: ItemProps) => { | ||
const itemRef = useRef<HTMLLIElement>(null); | ||
|
||
const { attributes, listeners, setNodeRef, isDragging, transform } = | ||
useDraggable({ | ||
id, | ||
data: { | ||
// Data needed to be dropped in HvFlow | ||
hvFlow: { | ||
// HvFlow will use this value to populate the node's data.nodeLabel | ||
label: title, | ||
// Node type from nodeTypes property provided to HvFlow | ||
type: "node", | ||
// Item position: used by HvFlow to position the node when dropped | ||
x: itemRef.current?.getBoundingClientRect().x, | ||
y: itemRef.current?.getBoundingClientRect().y, | ||
// Values to be added to the node's data | ||
data: { | ||
subtitle, | ||
color: "cat6_60", | ||
icon, | ||
output: { | ||
id: "data", | ||
label: "Data", | ||
}, | ||
input: { | ||
id: "data", | ||
label: "Data", | ||
}, | ||
} satisfies NodeData, | ||
}, | ||
// Data needed for the DragOverlay component | ||
dragOverlay: { | ||
component: ( | ||
<ItemCard | ||
icon={icon} | ||
title={title} | ||
subtitle={subtitle} | ||
isDragging | ||
/> | ||
), | ||
}, | ||
}, | ||
}); | ||
|
||
const style = transform | ||
? { | ||
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`, | ||
} | ||
: undefined; | ||
|
||
const forkedRef = useForkRef(itemRef, setNodeRef); | ||
|
||
return ( | ||
<ItemCard | ||
ref={forkedRef} | ||
style={style} | ||
icon={icon} | ||
title={title} | ||
subtitle={subtitle} | ||
isDragging={isDragging} | ||
{...attributes} | ||
{...listeners} | ||
/> | ||
); | ||
}; | ||
|
||
export const ListView = () => { | ||
const [listItems, setListItems] = useState(items); | ||
|
||
const listId = useUniqueId(); | ||
|
||
const handleSearch: HvInputProps["onChange"] = (event, value) => { | ||
if (value) { | ||
setListItems( | ||
items.filter((item) => | ||
item.title.toLowerCase().trim().includes(value.toLowerCase().trim()), | ||
), | ||
); | ||
} else { | ||
setListItems(items); | ||
} | ||
}; | ||
|
||
return ( | ||
<div className={classes.root}> | ||
<HvInput | ||
type="search" | ||
placeholder="Search for a node..." | ||
aria-controls={listId} | ||
aria-owns={listId} | ||
onChange={handleSearch} | ||
inputProps={{ autoComplete: "off" }} | ||
/> | ||
<HvListContainer id={listId}> | ||
{listItems.map((item) => ( | ||
<DraggableItemCard key={item.id} {...item} /> | ||
))} | ||
</HvListContainer> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.