Contextual Zoom
This example shows how the current zoom level can be used by a node to decide which content to show.
We are using selecting the zoom via the useStore hook to update our custom node whenever the zoom changes.
/* xyflow theme files. Delete these to start from our base */
.react-flow {
--xy-background-color: #f7f9fb;
/* Custom Variables */
--xy-theme-selected: #f57dbd;
--xy-theme-hover: #c5c5c5;
--xy-theme-edge-hover: black;
--xy-theme-color-focus: #e8e8e8;
/* Built-in Variables see https://reactflow.dev/learn/customization/theming */
--xy-node-border-default: 1px solid #ededed;
--xy-node-boxshadow-default: 0px 3.54px 4.55px 0px #00000005, 0px 3.54px 4.55px 0px #0000000d, 0px 0.51px 1.01px 0px #0000001a;
--xy-node-border-radius-default: 8px;
--xy-handle-background-color-default: #ffffff;
--xy-handle-border-color-default: #aaaaaa;
--xy-edge-label-color-default: #505050;
--xy-node-background-color-default: #ffffff;
--xy-theme-panel-bg: #ffffff;
--xy-theme-panel-text: #111827;
--xy-theme-resize-handle-bg: #ffffff;
--xy-theme-focus-border: #d9d9d9;
--xy-theme-muted-bg: #f3f4f6;
--xy-theme-subtle-border: #d1d5db;
}
.react-flow.dark {
--xy-background-color: #101012;
--xy-node-background-color-default: #1a1b1e;
--xy-node-border-default: 1px solid #303238;
--xy-handle-background-color-default: #141519;
--xy-handle-border-color-default: #5a5d66;
--xy-edge-label-color-default: #e6e7ea;
--xy-theme-hover: #7a7d86;
--xy-theme-edge-hover: #f3f4f6;
--xy-theme-panel-bg: #141519;
--xy-theme-panel-text: #f3f4f6;
--xy-theme-resize-handle-bg: #141519;
--xy-theme-focus-border: #5f6470;
--xy-theme-muted-bg: #24262c;
--xy-theme-subtle-border: #3f434c;
--xy-node-boxshadow-default: none;
--xy-theme-color-focus: #4b4e57;
--color-background: #1a1b1e;
--color-hover-bg: #24262c;
--color-disabled: #8b9099;
}
.react-flow {
background-color: var(--xy-background-color);
}
/* Customizing Default Theming */
.react-flow__node {
box-shadow: var(--xy-node-boxshadow-default);
border-radius: var(--xy-node-border-radius-default);
background-color: var(--xy-node-background-color-default);
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 10px;
font-size: 12px;
flex-direction: column;
border: var(--xy-node-border-default);
color: var(--xy-node-color, var(--xy-node-color-default));
}
.react-flow__node.selectable:focus {
box-shadow: 0px 0px 0px 4px var(--xy-theme-color-focus);
border-color: var(--xy-theme-focus-border);
}
.react-flow__node.selectable:focus:active {
box-shadow: var(--xy-node-boxshadow-default);
}
.react-flow__node.selectable:hover,
.react-flow__node.draggable:hover {
border-color: var(--xy-theme-hover);
}
.react-flow__node.selectable.selected {
border-color: var(--xy-theme-selected);
box-shadow: var(--xy-node-boxshadow-default);
}
.react-flow__node-group {
background-color: rgba(207, 182, 255, 0.4);
border-color: #9e86ed;
}
.react-flow.dark .react-flow__node-group {
background-color: rgba(123, 107, 148, 0.22);
border-color: #7b6b94;
}
.react-flow__edge.selectable:hover .react-flow__edge-path,
.react-flow__edge.selectable.selected .react-flow__edge-path {
stroke: var(--xy-theme-edge-hover);
}
.react-flow__handle {
background-color: var(--xy-handle-background-color-default);
}
.react-flow__handle.connectionindicator:hover {
pointer-events: all;
border-color: var(--xy-theme-edge-hover);
background-color: var(--xy-handle-background-color-default);
}
.react-flow__handle.connectionindicator:focus,
.react-flow__handle.connectingfrom,
.react-flow__handle.connectingto {
border-color: var(--xy-theme-edge-hover);
}
.react-flow__node-resizer {
border-radius: 0;
border: none;
}
.react-flow__resize-control.handle {
background-color: var(--xy-theme-resize-handle-bg);
border-color: #9e86ed;
border-radius: 0;
width: 5px;
height: 5px;
}
/*
Custom Example CSS - This CSS is to improve the example experience.
You can remove it if you want to use the default styles.
New Theme Classes:
.xy-theme__button - Styles for buttons.
.xy-theme__input - Styles for text inputs.
.xy-theme__checkbox - Styles for checkboxes.
.xy-theme__select - Styles for dropdown selects.
.xy-theme__label - Styles for labels.
Use these classes to apply consistent theming across your components.
*/
:root {
--color-primary: #ff0073;
--color-background: #fefefe;
--color-hover-bg: #f6f6f6;
--color-disabled: #76797e;
}
.xy-theme__button-group {
display: flex;
align-items: center;
.xy-theme__button:first-child {
border-radius: 100px 0 0 100px;
}
.xy-theme__button:last-child {
border-radius: 0 100px 100px 0;
margin: 0;
}
}
/* Custom Button Styling */
.xy-theme__button {
display: inline-flex;
align-items: center;
justify-content: center;
height: 2.5rem;
padding: 0 1rem;
border-radius: 100px;
border: 1px solid var(--color-primary);
background-color: var(--color-background);
color: var(--color-primary);
transition:
background-color 0.2s ease,
border-color 0.2s ease;
box-shadow: var(--xy-node-boxshadow-default);
cursor: pointer;
}
.xy-theme__button.active {
background-color: var(--color-primary);
color: white;
border-color: var(--color-primary);
}
.xy-theme__button.active:hover,
.xy-theme__button.active:active {
background-color: var(--color-primary);
opacity: 0.9;
}
.xy-theme__button:hover {
background-color: var(--xy-controls-button-background-color-hover-default);
}
.xy-theme__button:active {
background-color: var(--color-hover-bg);
}
.xy-theme__button:disabled {
color: var(--color-disabled);
opacity: 0.8;
cursor: not-allowed;
border: 1px solid var(--color-disabled);
}
.xy-theme__button > span {
margin-right: 0.2rem;
}
/* Add gap between adjacent buttons */
.xy-theme__button + .xy-theme__button {
margin-left: 0.3rem;
}
/* Example Input Styling */
.xy-theme__input {
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-primary);
border-radius: 7px;
background-color: var(--color-background);
transition:
background-color 0.2s ease,
border-color 0.2s ease;
font-size: 1rem;
color: var(--xy-theme-panel-text);
}
.xy-theme__input:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3);
}
/* Specific Checkbox Styling */
.xy-theme__checkbox {
appearance: none;
-webkit-appearance: none;
width: 1.25rem;
height: 1.25rem;
border-radius: 7px;
border: 2px solid var(--color-primary);
background-color: var(--color-background);
transition:
background-color 0.2s ease,
border-color 0.2s ease;
cursor: pointer;
display: inline-block;
vertical-align: middle;
margin-right: 0.5rem;
}
.xy-theme__checkbox:checked {
background-color: var(--color-primary);
border-color: var(--color-primary);
}
.xy-theme__checkbox:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3);
}
/* Dropdown Styling */
.xy-theme__select {
padding: 0.5rem 0.75rem;
border: 1px solid var(--color-primary);
border-radius: 50px;
background-color: var(--color-background);
transition:
background-color 0.2s ease,
border-color 0.2s ease;
font-size: 1rem;
color: var(--xy-theme-panel-text);
margin-right: 0.5rem;
box-shadow: var(--xy-node-boxshadow-default);
}
.xy-theme__select:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3);
}
.xy-theme__label {
margin-top: 10px;
margin-bottom: 3px;
display: inline-block;
color: var(--xy-theme-panel-text);
}Last updated on