Skip to content

Commit

Permalink
feat(context menu): add prop to hide the context menu kebab (#250)
Browse files Browse the repository at this point in the history
Add demo option to hide kebab context menus (#14)

add condition to contextSpace to fix label size

add check to TaskPill

remove hideContextMenuKebab from withContextMenuProps

add hideContextMenuKebab to NodeLabelProps to fix error

fix styles

remove semicolon

update info icon color token for drag hint

update font-size token
  • Loading branch information
jenny-s51 committed Dec 4, 2024
1 parent 159a0c1 commit 92c5b23
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 106 deletions.
20 changes: 10 additions & 10 deletions packages/demo-app-ts/src/demos/topologyPackageDemo/AreaDragHint.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
display: flex;
pointer-events: none;
position: absolute;
top: var(--pf-v5-global--spacer--sm);
top: var(--pf-t--global--spacer--sm);
left: 0;
right: 0;
z-index: 99;
}
.area-drag-hint__hint-background {
background-color: var(--pf-v5-global--BackgroundColor--100);
border: 1px solid var(--pf-v5-global--BorderColor--light-100);
background-color: var(--pf-t--global--background--color--primary--default);
border: 1px solid var(--pf-t--global--border--color--nonstatus--gray--default);
border-radius: 8px;
padding: var(--pf-v5-global--spacer--xs) var(--pf-v5-global--spacer--sm);
padding: var(--pf-t--global--spacer--xs) var(--pf-t--global--spacer--sm);
pointer-events: none;
}

Expand All @@ -21,23 +21,23 @@
display: flex;
}
.area-drag-hint__icon {
color: var(--pf-v5-global--palette--blue-300);
color: var(--pf-t--global--icon--color--status--info--default);
}
.area-drag-hint__text {
margin-left: var(--pf-v5-global--spacer--sm);
margin-left: var(--pf-t--global--spacer--sm);
}
.area-drag-hint-shortcut__cell {
padding-left: var(--pf-v5-global--spacer--sm);
padding-left: var(--pf-t--global--spacer--sm);
}

.area-drag-hint-shortcut__command:not(:last-child):after {
content: ' + ';
}

.area-drag-hint-shortcut__kbd {
border: var(--pf-v5-global--BorderWidth--sm) solid var(--pf-v5-global--BorderColor--100);
border: var(--pf-t--global--border--width--regular) solid var(--pf-t--global--border--color--nonstatus--gray--default);
border-radius: 3px;
color: var(--pf-v5-global--Color--200);
font-size: var(--pf-v5-global--FontSize--sm);
color: var(--pf-t--global--text--color--subtle);
font-size: var(--pf-t--global--font--size--sm);
padding: 1px 3px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ const DemoNode: React.FunctionComponent<DemoNodeProps> = observer(
showStatusDecorator={detailsLevel === ScaleDetailsLevel.high && options.showStatus}
statusDecoratorTooltip={nodeElement.getNodeStatus()}
onContextMenu={options.contextMenus ? onContextMenu : undefined}
hideContextMenuKebab={options.hideKebabMenu}
onShowCreateConnector={detailsLevel !== ScaleDetailsLevel.low ? onShowCreateConnector : undefined}
onHideCreateConnector={onHideCreateConnector}
labelIcon={options.icons && LabelIcon && <LabelIcon noVerticalAlign />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ const OptionsContextBar: React.FC = observer(() => {
>
Context Menus
</SelectOption>
<SelectOption
hasCheckbox
value="Hide context kebab menu"
isSelected={options.nodeOptions.hideKebabMenu}
isDisabled={!options.nodeOptions.contextMenus}
onClick={() =>
options.setNodeOptions({ ...options.nodeOptions, hideKebabMenu: !options.nodeOptions.hideKebabMenu })
}
>
Hide kebab for context menu
</SelectOption>
<SelectOption
hasCheckbox
value="Rectangle Groups"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface GeneratorNodeOptions {
badges?: boolean;
icons?: boolean;
contextMenus?: boolean;
hideKebabMenu?: boolean;
hulledOutline?: boolean;
}

Expand Down
6 changes: 5 additions & 1 deletion packages/module/src/components/nodes/DefaultNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ interface DefaultNodeProps {
contextMenuOpen?: boolean;
/** Flag indicating the label should move to the top layer when the node is hovered, set to `false` if you are already using TOP_LAYER on hover */
raiseLabelOnHover?: boolean; // TODO: Update default to be false, assume demo code will be followed
/** Hide context menu kebab for the node */
hideContextMenuKebab?: boolean;
}

const SCALE_UP_TIME = 200;
Expand Down Expand Up @@ -169,7 +171,8 @@ const DefaultNodeInner: React.FunctionComponent<DefaultNodeInnerProps> = observe
onShowCreateConnector,
onContextMenu,
contextMenuOpen,
raiseLabelOnHover = true
raiseLabelOnHover = true,
hideContextMenuKebab
}) => {
const [hovered, hoverRef] = useHover();
const status = nodeStatus || element.getNodeStatus();
Expand Down Expand Up @@ -370,6 +373,7 @@ const DefaultNodeInner: React.FunctionComponent<DefaultNodeInnerProps> = observe
badgeLocation={badgeLocation}
onContextMenu={onContextMenu}
contextMenuOpen={contextMenuOpen}
hideContextMenuKebab={hideContextMenuKebab}
hover={isHover}
labelIconClass={labelIconClass}
labelIcon={labelIcon}
Expand Down
7 changes: 5 additions & 2 deletions packages/module/src/components/nodes/labels/NodeLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export type NodeLabelProps = {
badgeBorderColor?: string;
badgeClassName?: string;
badgeLocation?: BadgeLocation;
hideContextMenuKebab?: boolean;
} & Partial<WithContextMenuProps>;

/**
Expand Down Expand Up @@ -77,6 +78,7 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
dropTarget,
onContextMenu,
contextMenuOpen,
hideContextMenuKebab,
actionIcon,
actionIconClassName,
onActionIconClick,
Expand Down Expand Up @@ -124,7 +126,7 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
const height = Math.max(textSize.height, badgeSize?.height ?? 0) + paddingY * 2;
const iconSpace = labelIconClass || labelIcon ? (height + paddingY * 0.5) / 2 : 0;
const actionSpace = actionIcon && actionSize ? actionSize.width : 0;
const contextSpace = onContextMenu && contextSize ? contextSize.width : 0;
const contextSpace = !hideContextMenuKebab && onContextMenu && contextSize ? contextSize.width : 0;
const primaryWidth = iconSpace + badgeSpace + paddingX + textSize.width + actionSpace + contextSpace + paddingX;
const secondaryWidth = secondaryLabel && secondaryTextSize ? secondaryTextSize.width + 2 * paddingX : 0;
const width = Math.max(primaryWidth, secondaryWidth);
Expand Down Expand Up @@ -184,6 +186,7 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
labelIcon,
actionIcon,
actionSize,
hideContextMenuKebab,
onContextMenu,
contextSize,
secondaryLabel,
Expand Down Expand Up @@ -293,7 +296,7 @@ const NodeLabel: React.FunctionComponent<NodeLabelProps> = ({
/>
</>
)}
{textSize && onContextMenu && (
{textSize && onContextMenu && !hideContextMenuKebab && (
<>
<line
className={css(styles.topologyNodeSeparator)}
Expand Down
102 changes: 11 additions & 91 deletions packages/module/src/css/topology-components.css
Original file line number Diff line number Diff line change
Expand Up @@ -197,99 +197,16 @@

--pf-topology__connector-square--m-source--Fill: var(--pf-t--global--background--color--secondary--default);

--pf-topology-default-create-connector__arrow--Fill: var(--pf-v5-global--Color--light-200);
--pf-topology-default-create-connector__arrow--Fill: var(--pf-t--global--background--color--secondary--default);

--pf-topology-default-create-connector--m-hover--line--Stroke: var(--pf-v5-global--Color--100);
--pf-topology-default-create-connector--m-hover--arrow--Fill: var(--pf-v5-global--Color--100);
--pf-topology-default-create-connector--m-hover--arrow--Stroke: var(--pf-v5-global--Color--100);
--pf-topology-default-create-connector--m-hover--line--Stroke: var(--pf-t--global--border--color--default);
--pf-topology-default-create-connector--m-hover--arrow--Fill: var(--pf-t--global--border--color--default);
--pf-topology-default-create-connector--m-hover--arrow--Stroke: var(--pf-t--global--border--color--default);

--pf-topology__area-select-rect--Fill: var(--pf-v5-global--palette--black-500);
--pf-topology__area-select-rect--Opacity: 0.4;
}

/* DARK THEME OVERRIDES */
:root:where(.pf-v5-theme-dark) {
--pf-topology-visualization-surface--BackgroundColor: var(--pf-v5-global--BackgroundColor--200);

--pf-topology__node--Color: var(--pf-v5-global--Color--100);

/* dark create connector */
--pf-topology__create-connector-color--Stroke: var(--pf-v5-global--palette--black-300);
--pf-topology__create-connector-color--Fill: var(--pf-v5-global--palette--black-100);
--pf-topology-default-create-connector__arrow--Fill: var(--pf-v5-global--BackgroundColor--100);
--pf-topology-default-create-connector--m-hover--line--Stroke: var(--pf-v5-global--palette--black-100);
--pf-topology-default-create-connector--m-hover--arrow--Fill: var(--pf-v5-global--palette--black-100);
--pf-topology-default-create-connector--m-hover--arrow--Stroke: var(--pf-v5-global--palette--black-100);

/* dark node */
--pf-topology__node__background--Fill: var(--pf-v5-global--BackgroundColor--300);
--pf-topology__node__background--Stroke: var(--pf-v5-global--palette--black-300);

--pf-topology__node--m-disabled--Background--Fill: var(--pf-topology__node__background--Fill);
--pf-topology__node--m-disabled--Background--Stroke: var(--pf-v5-global--palette--black-500);

--pf-topology__node--m-dragging--background--StrokeWidth: 2px;

--pf-topology__node--m-hover--background--Stroke: var(--pf-v5-global--palette--black-100);
--pf-topology__node--m-hover--label__background--Stroke: var(--pf-v5-global--palette--black-100);

/* dark node labels */
--pf-topology__node__label__background--Fill: var(--pf-v5-global--BackgroundColor--300);
--pf-topology__node__label__background--Stroke: var(--pf-v5-global--BorderColor--300);
--pf-topology__node__label--m-dragging--background--StrokeWidth: 2px;
--pf-topology__node__label__text--Fill: var(--pf-v5-global--Color--100);

/* dark selected nodes */
--pf-topology__node--m-selected--node__background--Stroke: var(--pf-v5-global--primary-color--300);
--pf-topology__node--m-selected--node__label__background--Stroke: var(--pf-v5-global--primary-color--300);
--pf-topology__node--m-selected--node__label__background--Fill: var(--pf-v5-global--primary-color--300);

--pf-topology__node--m-selected--node__label__text--Fill: var(--pf-v5-global--Color--100);
--pf-topology__node--m-selected--m-info--node__label__text--Fill: var(--pf-v5-global--palette--black-900);
--pf-topology__node--m-selected--m-danger--node__label__text--Fill: var(--pf-v5-global--palette--black-900);
--pf-topology__node--m-selected--m-warning--node__label__text--Fill: var(--pf-v5-global--palette--black-900);
--pf-topology__node--m-selected--m-success--node__label__text--Fill: var(--pf-v5-global--palette--black-900);

--pf-topology__node--m-selected--node__label__text--m-secondary--Fill: var(--pf-topology__node--m-selected--node__label__text--Fill);
--pf-topology__node--m-selected--m-info--node__label__text--m-secondary--Fill: var(--pf-topology__node--m-selected--m-info--node__label__text--Fill);
--pf-topology__node--m-selected--m-warning--node__label__text--m-secondary--Fill: var(--pf-topology__node--m-selected--m-warning--node__label__text--Fill);
--pf-topology__node--m-selected--m-success--node__label__text--m-secondary--Fill: var(--pf-topology__node--m-selected--m-success--node__label__text--Fill);
--pf-topology__node--m-selected--m-danger--node__label__text--m-secondary--Fill: var(--pf-v5-global--palette--black-900);

--pf-topology__node__label__icon--Color: var(--pf-v5-global--palette--black-600);

--pf-topology__node__action-icon__icon--Color: var(--pf-v5-global--Color--100);

/* dark group */
--pf-topology__group__background--Fill: var(--pf-v5-global--BackgroundColor--300);
--pf-topology__group__background--Stroke: var(--pf-v5-global--palette--black-300);
--pf-topology__group--m-alt-group--topology__group__background--Fill: var(--pf-v5-global--palette--black-500);
--pf-topology__group--m-alt-group--topology__group__background--Stroke: var(--pf-v5-global--BorderColor--100);
--pf-topology__group--m-selected--topology__group__background--Fill: var(--pf-v5-global--primary-color--300);
--pf-topology__group--m-selected--topology__group__background--Stroke: var(--pf-v5-global--active-color--300);
--pf-topology__group--m-hover--topology__group__background--Stroke: var(--pf-v5-global--primary-color--light-100);
--pf-topology__group--m-selected--m-hover--topology__group__background--Stroke: var(--pf-v5-global--palette--blue-100);
--pf-topology__group--m-drop-target--topology__group__background--Stroke: var(--pf-v5-global--palette--blue-300);

--pf-topology__group__label__node__label__background--StrokeWidth: 2px;
--pf-topology__group__label__node__label__background--Stroke: var(--pf-v5-global--palette--black-300);
--pf-topology__group--m-hover--label__node__label__background--Stroke: var(--pf-v5-global--palette--black-100);
--pf-topology__group--m-selected--label__node__label__background--Stroke: var(--pf-v5-global--primary-color--300);

--pf-topology__group--m-selected--group__label__node__label__background--Fill: var(--pf-v5-global--primary-color--300);

/* dark edge */
--pf-topology__edge--HoverStroke: var(--pf-v5-global--palette--black-300);
--pf-topology__edge--m-hover--background--Stroke: var(--pf-v5-global--palette--black-600);

--pf-topology__edge--ActiveStroke: var(--pf-v5-global--palette--blue-300);
--pf-topology__edge--m-selected--background--Stroke: var(--pf-v5-global--palette--black-600);

--pf-topology__edge__tag__background--Fill: var(--pf-v5-global--palette--black-300);
--pf-topology__edge__tag__text--Fill: var(--pf-v5-global--palette--black-900);
--pf-topology__edge__tag__text--Stroke: var(--pf-v5-global--palette--black-900);

--pf-topology__area-select-rect--Fill: var(--pf-v5-global--palette--black-300);
--pf-topology__area-select-rect--Fill: var(--pf-t--global--border--color--clicked);
--pf-topology__area-select-rect--Stroke: var(--pf-t--global--color--brand--clicked);
--pf-topology__area-select-rect--StrokeWidth: var(--pf-t--global--border--width--regular);
--pf-topology__area-select-rect--Opacity: 0.3;
}

.pf-topology-visualization-surface {
Expand Down Expand Up @@ -957,4 +874,7 @@
.pf-topology-area-select-rect {
fill: var(--pf-topology__area-select-rect--Fill);
opacity: var(--pf-topology__area-select-rect--Opacity);
stroke: var(--pf-topology__area-select-rect--Stroke);
stroke-width: var(--pf-topology__area-select-rect--StrokeWidth);
border: 1px dashed;
}
2 changes: 2 additions & 0 deletions packages/module/src/pipelines/components/nodes/TaskNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ export interface TaskNodeProps {
onContextMenu?: (e: React.MouseEvent) => void;
/** Flag indicating that the context menu for the node is currently open */
contextMenuOpen?: boolean;
/** Hide context menu kebab for the node */
hideContextMenuKebab?: boolean;
/** Number of shadowed pills to show */
shadowCount?: number;
/** Offset for each shadow */
Expand Down
6 changes: 4 additions & 2 deletions packages/module/src/pipelines/components/nodes/TaskPill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const TaskPill: React.FC<TaskPillProps> = observer(
onSelect,
onContextMenu,
contextMenuOpen,
hideContextMenuKebab,
actionIcon,
actionIconClassName,
onActionIconClick,
Expand Down Expand Up @@ -147,7 +148,7 @@ const TaskPill: React.FC<TaskPillProps> = observer(
const actionSpace = actionIcon && actionSize ? actionSize.width + paddingX : 0;

const contextStartX = actionStartX + actionSpace;
const contextSpace = onContextMenu && contextSize ? contextSize.width + paddingX / 2 : 0;
const contextSpace = !hideContextMenuKebab && onContextMenu && contextSize ? contextSize.width + paddingX / 2 : 0;

const pillWidth = contextStartX + contextSpace + paddingX / 2;

Expand Down Expand Up @@ -185,6 +186,7 @@ const TaskPill: React.FC<TaskPillProps> = observer(
badge,
actionIcon,
actionSize,
hideContextMenuKebab,
onContextMenu,
contextSize,
verticalLayout,
Expand Down Expand Up @@ -416,7 +418,7 @@ const TaskPill: React.FC<TaskPillProps> = observer(
/>
</>
)}
{textSize && onContextMenu && (
{textSize && onContextMenu && !hideContextMenuKebab && (
<>
<line
className={css(topologyStyles.topologyNodeSeparator)}
Expand Down

0 comments on commit 92c5b23

Please sign in to comment.