Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Erstatte Radix tabs med egen implementasjon av Tabs og rowing-tabindex #2587

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions @navikt/core/react/src/accordion/AccordionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import cl from "clsx";
import React, {
createContext,
forwardRef,
useContext,
useRef,
useState,
} from "react";
import { AccordionContext } from "./AccordionContext";
import React, { createContext, forwardRef, useContext, useRef } from "react";
import { omit } from "../util";
import { useControllableState } from "../util/hooks/useControllableState";
import { AccordionContext } from "./AccordionContext";

export interface AccordionItemProps
extends React.HTMLAttributes<HTMLDivElement> {
Expand All @@ -26,6 +21,10 @@ export interface AccordionItemProps
* @default false
*/
defaultOpen?: boolean;
/**
* Callback for current open-state
*/
onOpenChange?: (open: boolean) => void;
}

export interface AccordionItemContextProps {
Expand All @@ -37,20 +36,21 @@ export const AccordionItemContext =
createContext<AccordionItemContextProps | null>(null);

const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(
({ children, className, open, defaultOpen = false, ...rest }, ref) => {
const [internalOpen, setInternalOpen] = useState<boolean>(defaultOpen);
const context = useContext(AccordionContext);
(
{ children, className, open, defaultOpen = false, onOpenChange, ...rest },
ref
) => {
const [_open, _setOpen] = useControllableState({
defaultValue: defaultOpen,
value: open,
onChange: onOpenChange,
});

const [_open, _setOpen] = useState(defaultOpen);
const context = useContext(AccordionContext);
const shouldAnimate = useRef<boolean>(!(Boolean(open) || defaultOpen));

const handleOpen = () => {
if (open === undefined) {
const newOpen = !_open;
_setOpen(newOpen);
setInternalOpen(newOpen);
} else {
setInternalOpen(!open);
}
_setOpen((x) => !x);
shouldAnimate.current = true;
};

Expand All @@ -61,7 +61,7 @@ const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(
return (
<div
className={cl("navds-accordion__item", className, {
"navds-accordion__item--open": open ?? internalOpen,
"navds-accordion__item--open": _open,
"navds-accordion__item--neutral": context?.variant === "neutral",
"navds-accordion__item--no-animation": !shouldAnimate.current,
})}
Expand All @@ -70,7 +70,7 @@ const AccordionItem = forwardRef<HTMLDivElement, AccordionItemProps>(
>
<AccordionItemContext.Provider
value={{
open: open ?? internalOpen,
open: _open,
toggleOpen: handleOpen,
}}
>
Expand Down
13 changes: 8 additions & 5 deletions @navikt/core/react/src/accordion/accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useState } from "react";
import { Accordion, AccordionProps } from ".";
import { Table } from "..";
import AccordionContent from "./AccordionContent";
import AccordionHeader from "./AccordionHeader";
import AccordionItem from "./AccordionItem";
import { Accordion, AccordionProps } from ".";
import { Table } from "..";

export default {
title: "ds-react/Accordion",
Expand Down Expand Up @@ -78,22 +78,25 @@ const Item = (props) => {

if (props.defaultOpen) {
return (
<Accordion.Item defaultOpen={props.defaultOpen}>
<Accordion.Item
defaultOpen={props.defaultOpen}
onOpenChange={console.log}
>
<Accordion.Header>Accordion header text</Accordion.Header>
<SmallContent />
</Accordion.Item>
);
}

return props.controlled ? (
<Accordion.Item open={open}>
<Accordion.Item open={open} onOpenChange={console.log}>
<Accordion.Header onClick={() => setOpen(!open)}>
Accordion header text
</Accordion.Header>
<Content />
</Accordion.Item>
) : (
<Accordion.Item>
<Accordion.Item onOpenChange={console.log}>
<Accordion.Header>Accordion header text</Accordion.Header>
<Content />
</Accordion.Item>
Expand Down
25 changes: 15 additions & 10 deletions @navikt/core/react/src/dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from "react";
import { useControllableState } from "../util/hooks/useControllableState";
import Menu, { MenuType } from "./Menu";
import Toggle, { ToggleProps } from "./Toggle";
import { DropdownContext } from "./context";
Expand All @@ -22,6 +23,10 @@ export interface DropdownProps {
* Controlled state of the dropdown. When set, you will need to handle onClose and onSelect manually.
*/
open?: boolean;
/**
* Change handler for open
*/
onOpenChange?: (open: boolean) => void;
}

export interface DropdownType extends React.FC<DropdownProps> {
Expand Down Expand Up @@ -74,28 +79,28 @@ export const Dropdown = (({
closeOnSelect = true,
defaultOpen = false,
open,
onOpenChange,
}) => {
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
const [anchorEl, setAnchorEl] = useState<Element | null>(null);

const handleToggle = (v: boolean) => {
if (open === undefined) {
setIsOpen(v);
}
};
const [_open, _setOpen] = useControllableState({
defaultValue: defaultOpen,
value: open,
onChange: onOpenChange,
});

const handleToggle = (v: boolean) => _setOpen(v);

return (
<DropdownContext.Provider
value={{
isOpen: open ?? isOpen,
isOpen: _open,
handleToggle,
anchorEl,
setAnchorEl,
onSelect: (event) => {
onSelect?.(event);
if (closeOnSelect) {
open === undefined && setIsOpen(false);
}
closeOnSelect && _setOpen(false);
},
}}
>
Expand Down
28 changes: 17 additions & 11 deletions @navikt/core/react/src/read-more/ReadMore.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import cl from "clsx";
import React, { forwardRef, useState } from "react";
import React, { forwardRef } from "react";
import { ChevronDownIcon } from "@navikt/aksel-icons";
import { BodyLong } from "../typography";
import { useControllableState } from "../util/hooks/useControllableState";

export interface ReadMoreProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
Expand All @@ -23,6 +24,10 @@ export interface ReadMoreProps
* @default false
*/
defaultOpen?: boolean;
/**
* Callback for current open-state
*/
onOpenChange?: (open: boolean) => void;
/**
* Changes fontsize for content
* @default medium
Expand Down Expand Up @@ -57,21 +62,24 @@ export const ReadMore = forwardRef<HTMLButtonElement, ReadMoreProps>(
defaultOpen = false,
onClick,
size = "medium",
onOpenChange,
...rest
},
ref
) => {
const [internalOpen, setInternalOpen] = useState<boolean>(defaultOpen);

const isOpened = open ?? internalOpen;
const [_open, _setOpen] = useControllableState({
defaultValue: defaultOpen,
value: open,
onChange: onOpenChange,
});

return (
<div
className={cl(
"navds-read-more",
`navds-read-more--${size}`,
className,
{ "navds-read-more--open": isOpened }
{ "navds-read-more--open": _open }
)}
>
<button
Expand All @@ -82,12 +90,10 @@ export const ReadMore = forwardRef<HTMLButtonElement, ReadMoreProps>(
"navds-body-short--small": size === "small",
})}
onClick={(e) => {
if (open === undefined) {
setInternalOpen((isOpen) => !isOpen);
}
_setOpen((x) => !x);
onClick?.(e);
}}
aria-expanded={isOpened}
aria-expanded={_open}
>
<ChevronDownIcon
className="navds-read-more__expand-icon"
Expand All @@ -98,9 +104,9 @@ export const ReadMore = forwardRef<HTMLButtonElement, ReadMoreProps>(

<BodyLong
as="div"
aria-hidden={!isOpened}
aria-hidden={!_open}
className={cl("navds-read-more__content", {
"navds-read-more__content--closed": !isOpened,
"navds-read-more__content--closed": !_open,
})}
size={size}
>
Expand Down
4 changes: 4 additions & 0 deletions @navikt/core/react/src/read-more/readmore.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default meta;
export const Default: StoryFn<{
controlled: boolean;
size: "medium" | "small";
defaultOpen: boolean;
}> = (props) => {
const [state, setState] = useState(false);

Expand All @@ -20,6 +21,8 @@ export const Default: StoryFn<{
onClick={() => setState((x) => !x)}
header="Grunnen til at vi spør om dette og i tillegg ber om vedlegg"
size={props.size}
onOpenChange={console.log}
defaultOpen={props.defaultOpen}
>
<div style={{ maxWidth: 300 }}>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia,
Expand All @@ -32,6 +35,7 @@ export const Default: StoryFn<{
Default.args = {
controlled: false,
size: "medium",
defaultOpen: false,
};
Default.argTypes = {
size: {
Expand Down
30 changes: 16 additions & 14 deletions @navikt/core/react/src/table/ExpandableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ChevronDownIcon } from "@navikt/aksel-icons";
import cl from "clsx";
import React, { forwardRef, useState } from "react";
import React, { forwardRef } from "react";
import { ChevronDownIcon } from "@navikt/aksel-icons";
import { useId } from "../util";
import AnimateHeight from "../util/AnimateHeight";
import { useControllableState } from "../util/hooks/useControllableState";
import DataCell from "./DataCell";
import Row, { RowProps } from "./Row";

Expand Down Expand Up @@ -69,15 +70,16 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
},
ref
) => {
const [internalOpen, setInternalOpen] = useState<boolean>(defaultOpen);
const [_open, _setOpen] = useControllableState({
defaultValue: defaultOpen,
value: open,
onChange: onOpenChange,
});

const id = useId();
const isOpen = open ?? internalOpen;

const expansionHandler = (e) => {
onOpenChange?.(!isOpen);
if (open === undefined) {
setInternalOpen((oldOpen) => !oldOpen);
}
_setOpen((x) => !x);
e.stopPropagation();
};

Expand All @@ -90,7 +92,7 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
{...rest}
ref={ref}
className={cl("navds-table__expandable-row", className, {
"navds-table__expandable-row--open": isOpen,
"navds-table__expandable-row--open": _open,
"navds-table__expandable-row--expansion-disabled":
expansionDisabled,
"navds-table__expandable-row--clickable": expandOnRowClick,
Expand All @@ -103,32 +105,32 @@ export const ExpandableRow: ExpandableRowType = forwardRef(
{togglePlacement === "right" && children}
<DataCell
className={cl("navds-table__toggle-expand-cell", {
"navds-table__toggle-expand-cell--open": isOpen,
"navds-table__toggle-expand-cell--open": _open,
})}
>
{!expansionDisabled && (
<button
className="navds-table__toggle-expand-button"
type="button"
aria-controls={id}
aria-expanded={isOpen}
aria-expanded={_open}
onClick={expansionHandler}
>
<ChevronDownIcon
className="navds-table__expandable-icon"
title={isOpen ? "Vis mindre" : "Vis mer"}
title={_open ? "Vis mindre" : "Vis mer"}
/>
</button>
)}
</DataCell>
{togglePlacement === "left" && children}
</Row>
<tr className="navds-table__expanded-row" aria-hidden={!isOpen} id={id}>
<tr className="navds-table__expanded-row" aria-hidden={!_open} id={id}>
<td colSpan={colSpan} className="navds-table__expanded-row-cell">
<AnimateHeight
className="navds-table__expanded-row-collapse"
innerClassName="navds-table__expanded-row-content"
height={isOpen ? "auto" : 0}
height={_open ? "auto" : 0}
duration={250}
>
{content}
Expand Down
Loading
Loading