Skip to content

Commit

Permalink
Upgrade Databrowser to React 19 #1026
Browse files Browse the repository at this point in the history
  • Loading branch information
Polleps committed Dec 10, 2024
1 parent 3a43928 commit c543d9d
Show file tree
Hide file tree
Showing 21 changed files with 427 additions and 460 deletions.
10 changes: 5 additions & 5 deletions browser/data-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
"prismjs": "^1.29.0",
"query-string": "^7.1.3",
"quick-score": "^0.2.0",
"react": "^18.3.1",
"react": "^19.0.0",
"react-colorful": "^5.6.1",
"react-dom": "^18.3.1",
"react-dom": "^19.0.0",
"react-dropzone": "^11.7.1",
"react-helmet-async": "^1.3.0",
"react-hot-toast": "^2.4.1",
"react-hotkeys-hook": "^3.4.7",
"react-icons": "^4.12.0",
"react-intersection-observer": "^9.13.1",
"react-is": "^18.3.1",
"react-is": "^19.0.0",
"react-markdown": "^8.0.7",
"react-pdf": "^9.1.1",
"react-router": "^6.27.0",
Expand All @@ -57,8 +57,8 @@
"devDependencies": {
"@swc/plugin-styled-components": "^2.0.12",
"@types/prismjs": "^1.26.5",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@types/react-pdf": "^7.0.0",
"@types/react-router-dom": "^5.3.3",
"@types/react-window": "^1.8.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ import { styled } from 'styled-components';
interface DialogGlobalContext {
openDialogs: string[];
setDialogOpen: (id: string, open: boolean) => void;
portal: RefObject<HTMLDivElement>;
portal: RefObject<HTMLDivElement | null>;
}

export const DialogContext = createContext<DialogGlobalContext>(null!);
export const DialogContext = createContext<DialogGlobalContext>({
openDialogs: [],
setDialogOpen: () => {},
portal: { current: null },
});

export const DialogGlobalContextProvider: FC<PropsWithChildren> = ({
children,
Expand Down
2 changes: 1 addition & 1 deletion browser/data-browser/src/components/Dialog/useDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type UseDialogOptions<E extends HTMLElement> = {
bindShow?: React.Dispatch<boolean>;
onCancel?: () => void;
onSuccess?: () => void;
triggerRef?: React.RefObject<E>;
triggerRef?: React.RefObject<E | null>;
};

/** Sets up state, and functions to use with a {@link Dialog} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const buildDefaultTrigger = (
): DropdownTriggerRenderFunction => {
const Comp = (
{ onClick, menuId, isActive }: DropdownTriggerProps,
ref: React.Ref<HTMLButtonElement>,
ref: React.Ref<HTMLButtonElement | null>,
) => {
const id = useId();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export const DropdownContainer: React.FC<React.PropsWithChildren<unknown>> = ({
const portalRef = useRef<HTMLDivElement>(null);

return (
<DropdownPortalContext.Provider value={portalRef}>
<DropdownPortalContext value={portalRef}>
{children}
<DropdownContainerDiv ref={portalRef}></DropdownContainerDiv>
</DropdownPortalContext.Provider>
</DropdownPortalContext>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { createContext } from 'react';

export const DropdownPortalContext = createContext<
React.RefObject<HTMLDivElement>
>(null!);
React.RefObject<HTMLDivElement | null>
>({
current: null,
});
2 changes: 1 addition & 1 deletion browser/data-browser/src/components/EditableTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { UnsavedIndicator } from './UnsavedIndicator';
export interface EditableTitleProps {
resource: Resource;
/** Uses `name` by default */
parentRef?: React.RefObject<HTMLInputElement>;
parentRef?: React.RefObject<HTMLInputElement | null>;
id?: string;
className?: string;
}
Expand Down
55 changes: 26 additions & 29 deletions browser/data-browser/src/components/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
ComponentType,
ButtonHTMLAttributes,
forwardRef,
PropsWithChildren,
AnchorHTMLAttributes,
} from 'react';
import { styled, DefaultTheme } from 'styled-components';
Expand Down Expand Up @@ -30,52 +28,51 @@ type BaseProps = {
};

export type IconButtonProps = BaseProps &
ButtonHTMLAttributes<HTMLButtonElement>;
ButtonHTMLAttributes<HTMLButtonElement> & {
ref?: React.Ref<HTMLButtonElement | null>;
};

export const IconButton = forwardRef<
HTMLButtonElement,
PropsWithChildren<IconButtonProps>
>(({ variant, children, color, ...props }, ref) => {
export const IconButton: React.FC<React.PropsWithChildren<IconButtonProps>> = ({
variant = IconButtonVariant.Simple,
color = 'inherit',
size = '1em',
children,
ref,
...props
}) => {
const Comp = ComponentMap.get(variant!) ?? SimpleIconButton;

return (
<Comp ref={ref} color={color!} {...props}>
<Comp ref={ref} color={color} size={size} {...props}>
{children}
</Comp>
);
});

IconButton.displayName = 'IconButton';

const defaultProps = {
variant: IconButtonVariant.Simple,
color: 'inherit',
size: '1em',
} as IconButtonProps;

IconButton.defaultProps = defaultProps;
};

export type IconButtonLinkProps = BaseProps &
AnchorHTMLAttributes<HTMLAnchorElement> & {
href: string;
ref?: React.Ref<HTMLAnchorElement | null>;
};

export const IconButtonLink = forwardRef<
HTMLAnchorElement,
PropsWithChildren<IconButtonLinkProps>
>(({ variant, children, color, ...props }, ref) => {
export const IconButtonLink: React.FC<
React.PropsWithChildren<IconButtonLinkProps>
> = ({
variant = IconButtonVariant.Simple,
color = 'inherit',
size = '1em',
ref,
children,
...props
}) => {
const Comp = ComponentMap.get(variant ?? IconButtonVariant.Simple)!;

return (
<Comp ref={ref} color={color!} as='a' {...props}>
<Comp ref={ref} color={color!} size={size} as='a' {...props}>
{children}
</Comp>
);
});

IconButtonLink.displayName = 'IconButtonLink';

IconButtonLink.defaultProps = defaultProps as IconButtonLinkProps;
};

interface ButtonBaseProps {
size?: string;
Expand Down
10 changes: 5 additions & 5 deletions browser/data-browser/src/components/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ const fadeIn = keyframes`
`;

const Content = styled(RadixPopover.Content)`
--popover-close-offset: ${p => p.theme.margin}rem;
--popover-close-offset: ${p => p.theme.size()};
--popover-close-size: 25px;
--popover-close-safe-area: calc(
var(--popover-close-size) + (var(--popover-close-offset) * 2) -
${p => p.theme.margin}rem
${p => p.theme.size()}
);
background-color: ${p => transparentize(0.2, p.theme.colors.bgBody)};
backdrop-filter: blur(10px);
Expand All @@ -110,16 +110,16 @@ const Arrow = styled(RadixPopover.Arrow)`
`;

const PopoverContainerContext =
createContext<RefObject<HTMLDivElement>>(createRef());
createContext<RefObject<HTMLDivElement | null>>(createRef());

export const PopoverContainer: FC<PropsWithChildren> = ({ children }) => {
const popoverContainerRef = useRef<HTMLDivElement>(null);

return (
<ContainerDiv ref={popoverContainerRef}>
<PopoverContainerContext.Provider value={popoverContainerRef}>
<PopoverContainerContext value={popoverContainerRef}>
{children}
</PopoverContainerContext.Provider>
</PopoverContainerContext>
</ContainerDiv>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type OnScrollCallbackOptions = {

export interface ActiveCellIndicatorProps {
sizeStr: string;
scrollerRef: React.RefObject<HTMLDivElement>;
scrollerRef: React.RefObject<HTMLDivElement | null>;
setOnScroll: (
onScroll: ({ scrollUpdateWasRequested }: OnScrollCallbackOptions) => void,
) => void;
Expand All @@ -29,7 +29,7 @@ const cursorGoesOffscreen = (parentRect: DOMRect, childRect: DOMRect) => {

const getCornerIfMultiSelect = (
cursorMode: CursorMode,
ref: React.MutableRefObject<HTMLDivElement | null>,
ref: React.RefObject<HTMLDivElement | null>,
) => {
if (cursorMode === CursorMode.MultiSelect && ref.current) {
return ref.current.getBoundingClientRect();
Expand Down Expand Up @@ -68,7 +68,7 @@ export function ActiveCellIndicator({

/** Measure the size and position of the current active cell and morph the indicator to the same values. */
const updatePosition = useCallback(
(followHorizontaly = true) => {
(followHorizontally = true) => {
if (!activeCellRef.current || !scrollerRef.current) {
setVisible(false);

Expand All @@ -83,7 +83,7 @@ export function ActiveCellIndicator({
multiSelectCornerCellRef,
);

if (followHorizontaly && cursorGoesOffscreen(scrollerRect, cellRect)) {
if (followHorizontally && cursorGoesOffscreen(scrollerRect, cellRect)) {
setTransitioningOffscreen(true);

scrollIntoView(scrollerRef.current, scrollerRect, cellRect);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type TableCommands = {
export type HandlerContext = {
tableContext: TableEditorContext;
event: React.KeyboardEvent;
tableRef: React.RefObject<HTMLDivElement>;
tableRef: React.RefObject<HTMLDivElement | null>;
translateCursor: (row: number, column: number) => void;
columnCount: number;
} & TableCommands;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function useIsScrolling<T extends HTMLElement>(
): void {
const scrollLeft = useRef(0);
const scrollTop = useRef(0);
const timeoutID = useRef<number | undefined>();
const timeoutID = useRef<number | undefined>(undefined);

const scrollPositionChanged = (): boolean => {
const node = ref.current;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ const matchModifier = (
const matchCondition = (handler: KeyboardHandler, context: HandlerContext) =>
handler.condition === undefined || handler.condition(context);

const tableHeaderHasFocus = (headerRef: React.RefObject<HTMLDivElement>) =>
headerRef.current?.contains(document.activeElement);
const tableHeaderHasFocus = (
headerRef: React.RefObject<HTMLDivElement | null>,
) => headerRef.current?.contains(document.activeElement);

export function useTableEditorKeyboardNavigation(
columnCount: number,
rowCount: number,
tableRef: React.RefObject<HTMLDivElement>,
headerRef: React.RefObject<HTMLDivElement>,
tableRef: React.RefObject<HTMLDivElement | null>,
headerRef: React.RefObject<HTMLDivElement | null>,
commands: TableCommands,
) {
const tableContext = useTableEditorContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ interface SearchBoxWindowProps {
scopes?: string[];
placeholder?: string;
allowsOnly?: string[];
triggerRef: RefObject<HTMLButtonElement>;
triggerRef: RefObject<HTMLButtonElement | null>;
onExit: (lostFocus: boolean) => void;
onChange: (value: string) => void;
onSelect: (value: string) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useDeferredValue, useLayoutEffect, useState } from 'react';

export function useAvailableSpace<T extends HTMLElement>(
trigger: boolean,
ref: React.RefObject<T>,
ref: React.RefObject<T | null>,
) {
const [space, setSpace] = useState({ above: 0, below: 0, width: 0 });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react';

export function useHTMLFormFieldValidation(): [
valid: boolean,
ref: React.RefObject<HTMLInputElement>,
ref: React.RefObject<HTMLInputElement | null>,
] {
const [valid, setValid] = useState(false);

Expand Down
2 changes: 1 addition & 1 deletion browser/data-browser/src/helpers/useHover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Listeners = {
};

export function useHover<T extends HTMLElement>(): [
ref: RefObject<T>,
ref: RefObject<T | null>,
isHovering: boolean,
listeners: Listeners,
] {
Expand Down
4 changes: 2 additions & 2 deletions browser/data-browser/src/hooks/useResizable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { styled } from 'styled-components';

interface UseResizeResult<E extends HTMLElement> {
size: string;
targetRef: React.RefObject<E>;
dragAreaRef: React.RefObject<HTMLDivElement>;
targetRef: React.RefObject<E | null>;
dragAreaRef: React.RefObject<HTMLDivElement | null>;
dragAreaListeners: Pick<React.DOMAttributes<HTMLDivElement>, 'onMouseDown'>;
isDragging: boolean;
}
Expand Down
31 changes: 14 additions & 17 deletions browser/data-browser/src/views/TablePage/useTableData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,23 @@ type UseTableDataResult = {
} & UseCollectionResult;

const useTableSorting = () =>
useReducer<(state: TableSorting, property: string) => TableSorting>(
(state, property) => {
if (state.prop === property && state.sortDesc) {
return DEFAULT_SORT;
}

if (state.prop === property) {
return {
...state,
sortDesc: true,
};
}
useReducer((state: TableSorting, property: string) => {
if (state.prop === property && state.sortDesc) {
return DEFAULT_SORT;
}

if (state.prop === property) {
return {
prop: property,
sortDesc: false,
...state,
sortDesc: true,
};
},
DEFAULT_SORT,
);
}

return {
prop: property,
sortDesc: false,
};
}, DEFAULT_SORT);

export function useTableData(resource: Resource): UseTableDataResult {
const [sorting, setSortBy] = useTableSorting();
Expand Down
Loading

0 comments on commit c543d9d

Please sign in to comment.