Skip to content

Commit

Permalink
fix(react-components): cogs fixups and bump to 0.60.2 (#4803)
Browse files Browse the repository at this point in the history
* chore: fix smaller things in UI

- Hide empty model lists
- Make "Select cover overlay" a section header
- Add padding to the right side of icons in flex list

* fix: enable closing toolbar button menus

* chore: make more improvements to SettingsButton et al.

* chore: lint fix

* chore: some cleanup and de-bold the label

* chore: lint fix

* feat: support dividers in BaseSettings

* fixup! feat: support dividers in BaseSettings

* fixup! feat: support dividers in BaseSettings

* chore: begin small rewrite

* chore: create divider command

* chore: suggested solution to show selected label

* chore: update visual test image

* chore: lint fix

* chore: remove unused file

* chore: move files, remove superfluous divider

* fix: Select box in option dropdown and filter button

* chore: Change chevron direction on open and refactor slightly

* chore: remove unused import

---------

Co-authored-by: Nils Petter Fremming <[email protected]>
  • Loading branch information
haakonflatval-cognite and nilscognite authored Oct 17, 2024
1 parent 940b87e commit c493c61
Show file tree
Hide file tree
Showing 18 changed files with 384 additions and 173 deletions.
2 changes: 1 addition & 1 deletion react-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cognite/reveal-react-components",
"version": "0.60.1",
"version": "0.60.2",
"exports": {
".": {
"import": "./dist/index.js",
Expand Down
10 changes: 10 additions & 0 deletions react-components/src/architecture/base/commands/DividerCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*!
* Copyright 2024 Cognite AS
*/
import { RenderTargetCommand } from './RenderTargetCommand';

export class DividerCommand extends RenderTargetCommand {
public override get isVisible(): boolean {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ export class MockCheckableCommand extends RenderTargetCommand {
this.value = !this.value;
return true;
}

public override get isToggle(): boolean {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*!
* Copyright 2024 Cognite AS
*/
import { type BaseCommand } from '../commands/BaseCommand';
import { DividerCommand } from '../commands/DividerCommand';

export class PointCloudDividerCommand extends DividerCommand {
public override get isVisible(): boolean {
return this.renderTarget.getPointClouds().next().value !== undefined;
}

public override equals(other: BaseCommand): boolean {
return this === other;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SetPointShapeCommand } from './SetPointShapeCommand';
import { PointCloudFilterCommand } from './PointCloudFilterCommand';
import { type TranslateKey } from '../utilities/TranslateKey';
import { type IconName } from '../utilities/IconName';
import { PointCloudDividerCommand } from './PointCloudDividerCommand';

export class SettingsCommand extends BaseSettingsCommand {
// ==================================================
Expand All @@ -20,6 +21,7 @@ export class SettingsCommand extends BaseSettingsCommand {
super();

this.add(new SetQualityCommand());
this.add(new PointCloudDividerCommand());
this.add(new SetPointSizeCommand());
this.add(new SetPointColorTypeCommand());
this.add(new SetPointShapeCommand());
Expand Down
130 changes: 95 additions & 35 deletions react-components/src/components/Architecture/DropdownButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,27 @@
*/

import { Button, Tooltip as CogsTooltip, ChevronDownIcon, ChevronUpIcon } from '@cognite/cogs.js';
import { Menu } from '@cognite/cogs-lab';
import { Menu, Option, Select } from '@cognite/cogs-lab';
import {
useCallback,
useEffect,
useMemo,
useState,
type ReactElement,
type MouseEvent
type SetStateAction,
type Dispatch
} from 'react';

import { useTranslation } from '../i18n/I18n';
import { type BaseCommand } from '../../architecture/base/commands/BaseCommand';
import { useRenderTarget } from '../RevealCanvas/ViewerContext';
import { type BaseOptionCommand } from '../../architecture/base/commands/BaseOptionCommand';
import {
getButtonType,
getDefaultCommand,
getFlexDirection,
getTooltipPlacement,
getIcon
} from './utilities';
import { getButtonType, getDefaultCommand, getTooltipPlacement, getIcon } from './utilities';
import { LabelWithShortcut } from './LabelWithShortcut';
import { type TranslateDelegate } from '../../architecture/base/utilities/TranslateKey';
import { DEFAULT_PADDING, OPTION_MIN_WIDTH } from './constants';
import { TOOLBAR_HORIZONTAL_PANEL_OFFSET } from '../constants';

import { offset } from '@floating-ui/dom';
import styled from 'styled-components';

export const DropdownButton = ({
inputCommand,
Expand All @@ -41,7 +35,6 @@ export const DropdownButton = ({
usedInSettings?: boolean;
}): ReactElement => {
const renderTarget = useRenderTarget();
const { t } = useTranslation();
const command = useMemo<BaseOptionCommand>(
() => getDefaultCommand<BaseOptionCommand>(inputCommand, renderTarget),
[]
Expand All @@ -66,52 +59,77 @@ export const DropdownButton = ({
};
}, [command]);

if (!isVisible || command.children === undefined) {
return <></>;
}
const placement = getTooltipPlacement(isHorizontal);
const label = usedInSettings ? undefined : command.getLabel(t);
const flexDirection = getFlexDirection(false); // Always vertical
const children = command.children;
return usedInSettings ? (
<MenuItemWithDropdown command={command} isVisible={isVisible} />
) : (
<DropdownElement
command={command}
isVisible={isVisible}
isOpen={isOpen}
setOpen={setOpen}
isEnabled={isEnabled}
isHorizontal={isHorizontal}
uniqueId={uniqueId}
/>
);
};

const DropdownElement = ({
command,
isVisible,
isOpen,
setOpen,
isEnabled,
isHorizontal,
uniqueId
}: {
command: BaseOptionCommand;
isVisible: boolean;
isOpen: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
isEnabled: boolean;
isHorizontal: boolean;
uniqueId: number;
}): ReactElement => {
const { t } = useTranslation();
const label = command.getLabel(t);
const selectedLabel = command.selectedChild?.getLabel(t);

const placement = getTooltipPlacement(isHorizontal);

const OpenButtonIcon = isOpen ? ChevronUpIcon : ChevronDownIcon;

if (!isVisible || command.children === undefined) {
return <></>;
}

return (
<Menu
style={{
minWidth: '0px',
overflow: 'auto',
flexDirection
}}
floatingProps={{ middleware: [offset(TOOLBAR_HORIZONTAL_PANEL_OFFSET)] }}
onOpenChange={(open: boolean) => {
setOpen(open);
}}
hideOnSelect={true}
appendTo={'parent'}
placement={usedInSettings ? 'bottom-end' : 'auto-start'}
placement={'bottom-start'}
renderTrigger={(props: any) => (
<CogsTooltip
content={<LabelWithShortcut label={label} command={command} />}
disabled={usedInSettings || label === undefined}
disabled={label === undefined}
appendTo={document.body}
placement={placement}>
<Button
style={{
padding: usedInSettings ? DEFAULT_PADDING : '8px 4px',
minWidth: usedInSettings ? OPTION_MIN_WIDTH : undefined
padding: '8px 4px'
}}
type={usedInSettings ? 'tertiary' : getButtonType(command)}
type={getButtonType(command)}
icon={<OpenButtonIcon />}
key={uniqueId}
disabled={!isEnabled}
iconPlacement="left"
aria-label={command.getLabel(t)}
label={selectedLabel}
toggled={isOpen}
{...props}
onClick={(event: MouseEvent<HTMLElement>) => {
onClick={(event) => {
event.stopPropagation();
event.preventDefault();
props.onClick?.(event);
Expand All @@ -120,13 +138,45 @@ export const DropdownButton = ({
</Button>
</CogsTooltip>
)}>
{children.map((child, _index): ReactElement => {
return createMenuItem(child, t);
})}
{command.children.map((child) => createMenuItem(child, t))}
</Menu>
);
};

const MenuItemWithDropdown = ({
command,
isVisible
}: {
command: BaseOptionCommand;
isVisible: boolean;
}): ReactElement => {
const { t } = useTranslation();
const label = command.getLabel(t);

if (!isVisible || command.children === undefined) {
return <></>;
}

return (
<StyledDropdownRow>
<label>{label}</label>
<Select
defaultValue={command.selectedChild}
fullWidth
aria-label={command.getLabel(t)}
onChange={(_event, value) => {
value?.invoke();
}}>
{command.children.map((child) => (
<Option value={child} key={child.uniqueId}>
{child.getLabel(t)}
</Option>
))}
</Select>
</StyledDropdownRow>
);
};

function createMenuItem(command: BaseCommand, t: TranslateDelegate): ReactElement {
return (
<Menu.ItemToggled
Expand All @@ -142,3 +192,13 @@ function createMenuItem(command: BaseCommand, t: TranslateDelegate): ReactElemen
/>
);
}

const StyledDropdownRow = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 8;
minwidth: ${OPTION_MIN_WIDTH};
padding: ${DEFAULT_PADDING};
`;
Loading

0 comments on commit c493c61

Please sign in to comment.