mirror of
https://github.com/navikt/aksel.git
synced 2026-10-15 10:12:03 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6bc0c612f | ||
|
|
b796e306d5 | ||
|
|
0e9680dab9 | ||
|
|
6d2858c6e1 | ||
|
|
9294410ed8 | ||
|
|
e3653580e6 | ||
|
|
c9ab2e1516 | ||
|
|
bb1876df43 |
No files matched your search
@@ -96,7 +96,9 @@ jobs:
|
||||
|
||||
- name: Create a .npmrc file for NPM
|
||||
run: |
|
||||
echo "registry=https://registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
|
||||
echo "//registry=https://registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc
|
||||
echo "//registry=https://registry.npmjs.org/:always-auth=true" >> .npmrc
|
||||
npm whoami
|
||||
env:
|
||||
NPM_TOKEN: ${{secrets.NPM_AUTOMATION}}
|
||||
- name: Publish to NPM registry
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.navdsi-dropdown-menu {
|
||||
.navdsi-dropdown__menu {
|
||||
overflow: hidden;
|
||||
padding: var(--navds-spacing-4) 0;
|
||||
color: var(--navds-color-darkgray);
|
||||
@@ -7,18 +7,25 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.navdsi-dropdown-menu > :not(.navdsi-divider):not(.navdsi-dropdown-menu__list) {
|
||||
padding-left: var(--navds-spacing-4);
|
||||
padding-right: var(--navds-spacing-4);
|
||||
.navdsi-dropdown__menu > :not(.navdsi-divider):not(.navdsi-dropdown__list) {
|
||||
margin: 0 var(--navds-spacing-4) var(--navds-spacing-3);
|
||||
}
|
||||
|
||||
.navdsi-dropdown-menu__list {
|
||||
.navdsi-dropdown__list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.navdsi-dropdown-menu__item {
|
||||
.navdsi-dropdown__list-item {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.navdsi-dropdown__list-heading {
|
||||
margin: 0 var(--navds-spacing-4) var(--navds-spacing-4);
|
||||
}
|
||||
|
||||
.navdsi-dropdown__item {
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
@@ -35,15 +42,15 @@
|
||||
padding: var(--navds-spacing-1) var(--navds-spacing-4);
|
||||
}
|
||||
|
||||
.navdsi-dropdown-menu__item:hover {
|
||||
.navdsi-dropdown__item:hover {
|
||||
background-color: var(--navds-color-blue-10);
|
||||
}
|
||||
|
||||
.navdsi-dropdown-menu__item:active {
|
||||
.navdsi-dropdown__item:active {
|
||||
background-color: var(--navds-color-blue-20);
|
||||
}
|
||||
|
||||
.navdsi-dropdown-menu__item:focus {
|
||||
.navdsi-dropdown__item:focus {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 0 2px var(--navds-color-blue-80);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ button.navdsi-header__title {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.navdsi-header__dropdown-button {
|
||||
.navdsi-header__button {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0 var(--navds-spacing-3);
|
||||
@@ -60,23 +60,23 @@ button.navdsi-header__title {
|
||||
|
||||
a.navdsi-header__title:hover,
|
||||
button.navdsi-header__title:hover,
|
||||
.navdsi-header__dropdown-button:hover {
|
||||
.navdsi-header__button:hover {
|
||||
background-color: var(--navds-color-gray-80);
|
||||
}
|
||||
|
||||
.navdsi-header__title:focus,
|
||||
.navdsi-header__dropdown-button:focus {
|
||||
.navdsi-header__button:focus {
|
||||
box-shadow: var(--navdsi-header-focus);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a.navdsi-header__title:active,
|
||||
button.navdsi-header__title:active,
|
||||
.navdsi-header__dropdown-button:active {
|
||||
.navdsi-header__button:active {
|
||||
background-color: var(--navds-color-gray-60);
|
||||
}
|
||||
|
||||
.navdsi-header__dropdown-user-button {
|
||||
.navdsi-header__user-button {
|
||||
padding-left: var(--navds-spacing-5);
|
||||
gap: var(--navds-spacing-4);
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "divider.css";
|
||||
@import "dropdown-menu.css";
|
||||
@import "dropdown.css";
|
||||
@import "header.css";
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "0.3.1",
|
||||
"version": "0.5.0",
|
||||
"private": false,
|
||||
"description": "Css for NAV internal Designsystem components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "0.3.1",
|
||||
"version": "0.5.0",
|
||||
"private": false,
|
||||
"description": "NAV internal designsystem react components",
|
||||
"author": "NAV Designsystem team",
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { Placement } from "@popperjs/core";
|
||||
import { Popover, PopoverProps } from "@navikt/ds-react";
|
||||
import List, { DropdownMenuListType } from "./List";
|
||||
import Item, { DropdownMenuItemType } from "./Item";
|
||||
|
||||
export interface DropdownMenuProps extends PopoverProps {
|
||||
/**
|
||||
* Menu content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* Orientation for menu
|
||||
* @default "bottom-end"
|
||||
*/
|
||||
placement?: Placement;
|
||||
/**
|
||||
* Toggles rendering of arrow
|
||||
* @default false
|
||||
*/
|
||||
arrow?: boolean;
|
||||
/**
|
||||
* Distance from anchor to popover
|
||||
* @default 8 w/arrow, -4 w/no-arrow
|
||||
*/
|
||||
offset?: number;
|
||||
}
|
||||
|
||||
export interface DropdownMenuType<Props = DropdownMenuProps>
|
||||
extends React.ForwardRefExoticComponent<
|
||||
Props & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
List: DropdownMenuListType;
|
||||
Item: DropdownMenuItemType;
|
||||
}
|
||||
|
||||
const DropdownMenu = forwardRef<HTMLDivElement, DropdownMenuProps>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
children,
|
||||
placement = "bottom-end",
|
||||
arrow = false,
|
||||
offset,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<Popover
|
||||
{...rest}
|
||||
ref={ref}
|
||||
placement={placement}
|
||||
arrow={arrow}
|
||||
className={cl("navdsi-dropdown-menu", className)}
|
||||
offset={offset ?? arrow ? 8 : -4}
|
||||
>
|
||||
{children}
|
||||
</Popover>
|
||||
)
|
||||
) as DropdownMenuType;
|
||||
|
||||
DropdownMenu.List = List;
|
||||
DropdownMenu.Item = Item;
|
||||
|
||||
export default DropdownMenu;
|
||||
@@ -1,32 +0,0 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface DropdownMenuItemProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Menu item content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type DropdownMenuItemType = OverridableComponent<
|
||||
DropdownMenuItemProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
const Item: DropdownMenuItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
role="menuitem"
|
||||
className={cl(
|
||||
"navdsi-dropdown-menu__item navds-body-short navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
export default Item;
|
||||
@@ -1,31 +0,0 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface DropdownMenuListProps
|
||||
extends React.HTMLAttributes<HTMLUListElement> {
|
||||
/**
|
||||
* Menu item content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type DropdownMenuListType = React.ForwardRefExoticComponent<
|
||||
DropdownMenuListProps & React.RefAttributes<HTMLUListElement>
|
||||
>;
|
||||
|
||||
const List: DropdownMenuListType = forwardRef(
|
||||
({ className, children, ...rest }, ref) => (
|
||||
<ul
|
||||
{...rest}
|
||||
ref={ref}
|
||||
role="menu"
|
||||
className={cl("navdsi-dropdown-menu__list", className)}
|
||||
>
|
||||
{React.Children.map(children, (child) => (
|
||||
<li>{child}</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
);
|
||||
|
||||
export default List;
|
||||
@@ -1,2 +0,0 @@
|
||||
export { default as DropdownMenu } from "./DropdownMenu";
|
||||
export * from "./DropdownMenu";
|
||||
@@ -1,35 +0,0 @@
|
||||
import { Heading } from "@navikt/ds-react";
|
||||
import React, { useState } from "react";
|
||||
import { HashRouter as Router, Link } from "react-router-dom";
|
||||
import { ExternalLink } from "@navikt/ds-icons";
|
||||
import { DropdownMenu } from "..";
|
||||
import { Divider } from "../..";
|
||||
|
||||
export default {
|
||||
title: "ds-react-internal/dropdown-menu",
|
||||
component: DropdownMenu,
|
||||
};
|
||||
|
||||
export const All = () => {
|
||||
const [anchorEl, setAnchorEl] = useState<Element>();
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<span ref={(el) => setAnchorEl(el)} />
|
||||
<DropdownMenu open onClose={() => {}} anchorEl={anchorEl}>
|
||||
<Heading level="2" size="xsmall">
|
||||
Systemer og oppslagsverk
|
||||
</Heading>
|
||||
<DropdownMenu.Item as={Link} to="/settings">
|
||||
Innstillinger
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Item as="a" href="https://example.org" target="_blank">
|
||||
<span>Gosys</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</DropdownMenu.Item>
|
||||
<Divider />
|
||||
<DropdownMenu.Item onClick={() => {}}>Logg ut</DropdownMenu.Item>
|
||||
</DropdownMenu>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { createContext, useState } from "react";
|
||||
import Toggle, { ToggleType } from "./Toggle";
|
||||
import Menu, { MenuType } from "./Menu";
|
||||
|
||||
export interface DropdownType extends React.FC {
|
||||
Toggle: ToggleType;
|
||||
Menu: MenuType;
|
||||
}
|
||||
|
||||
export interface DropdownContextType {
|
||||
readonly isOpen: boolean;
|
||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
readonly anchorEl: Element | null;
|
||||
setAnchorEl: React.Dispatch<React.SetStateAction<Element | null>>;
|
||||
}
|
||||
|
||||
export const DropdownContext = createContext<DropdownContextType | null>(null);
|
||||
|
||||
const Dropdown = (({ children }) => {
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [anchorEl, setAnchorEl] = useState<Element | null>(null);
|
||||
|
||||
return (
|
||||
<DropdownContext.Provider
|
||||
value={{
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
anchorEl,
|
||||
setAnchorEl,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DropdownContext.Provider>
|
||||
);
|
||||
}) as DropdownType;
|
||||
|
||||
Dropdown.Toggle = Toggle;
|
||||
Dropdown.Menu = Menu;
|
||||
|
||||
export default Dropdown;
|
||||
@@ -0,0 +1,28 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface HeadingProps extends React.HTMLAttributes<HTMLDetailsElement> {
|
||||
/**
|
||||
* Heading
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type HeadingType = React.ForwardRefExoticComponent<
|
||||
HeadingProps & React.RefAttributes<HTMLElement>
|
||||
>;
|
||||
|
||||
const Heading: HeadingType = forwardRef(({ className, ...rest }, ref) => (
|
||||
<dt
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navdsi-dropdown__list-heading",
|
||||
"navds-heading",
|
||||
"navds-heading--xsmall",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
));
|
||||
|
||||
export default Heading;
|
||||
@@ -0,0 +1,31 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface ItemProps extends React.ButtonHTMLAttributes<HTMLElement> {
|
||||
/**
|
||||
* Menu item content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ItemType = OverridableComponent<ItemProps, HTMLButtonElement>;
|
||||
|
||||
const Item: ItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<dd className="navdsi-dropdown__list-item">
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navdsi-dropdown__item",
|
||||
"navds-body-short",
|
||||
"navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
</dd>
|
||||
)
|
||||
);
|
||||
|
||||
export default Item;
|
||||
@@ -0,0 +1,31 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import Heading, { HeadingType } from "./Heading";
|
||||
import Item, { ItemType } from "./Item";
|
||||
|
||||
export interface GroupedListProps
|
||||
extends React.HTMLAttributes<HTMLDListElement> {
|
||||
/**
|
||||
* Menu list content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface GroupedListType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
GroupedListProps & React.RefAttributes<HTMLDListElement>
|
||||
> {
|
||||
Heading: HeadingType;
|
||||
Item: ItemType;
|
||||
}
|
||||
|
||||
const DescriptionList = forwardRef(({ className, children, ...rest }, ref) => (
|
||||
<dl {...rest} ref={ref} className={cl("navdsi-dropdown__list", className)}>
|
||||
{children}
|
||||
</dl>
|
||||
)) as GroupedListType;
|
||||
|
||||
DescriptionList.Heading = Heading;
|
||||
DescriptionList.Item = Item;
|
||||
|
||||
export default DescriptionList;
|
||||
@@ -0,0 +1,32 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface ItemProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Menu item content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ItemType = OverridableComponent<ItemProps, HTMLButtonElement>;
|
||||
|
||||
const Item: ItemType = forwardRef(
|
||||
({ as: Component = "button", className, ...rest }, ref) => (
|
||||
<li className="navdsi-dropdown__list-item">
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl(
|
||||
"navdsi-dropdown__item",
|
||||
"navds-body-short",
|
||||
"navds-body-short--small",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
);
|
||||
|
||||
export default Item;
|
||||
@@ -0,0 +1,27 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import Item, { ItemType } from "./Item";
|
||||
|
||||
export interface ListProps extends React.HTMLAttributes<HTMLUListElement> {
|
||||
/**
|
||||
* Menu list content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface ListType
|
||||
extends React.ForwardRefExoticComponent<
|
||||
ListProps & React.RefAttributes<HTMLUListElement>
|
||||
> {
|
||||
Item: ItemType;
|
||||
}
|
||||
|
||||
const List = forwardRef(({ className, children, ...rest }, ref) => (
|
||||
<ul {...rest} ref={ref} className={cl("navdsi-dropdown__list", className)}>
|
||||
{children}
|
||||
</ul>
|
||||
)) as ListType;
|
||||
|
||||
List.Item = Item;
|
||||
|
||||
export default List;
|
||||
@@ -0,0 +1,53 @@
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import cl from "classnames";
|
||||
import { Popover } from "@navikt/ds-react";
|
||||
import List, { ListType } from "./List";
|
||||
import GroupedList, { GroupedListType } from "./GroupedList";
|
||||
import { DropdownContext } from "../Dropdown";
|
||||
|
||||
interface MenuProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Dropdown content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface MenuType<Props = MenuProps>
|
||||
extends React.ForwardRefExoticComponent<
|
||||
Props & React.RefAttributes<HTMLDivElement>
|
||||
> {
|
||||
List: ListType;
|
||||
GroupedList: GroupedListType;
|
||||
}
|
||||
|
||||
const Menu = forwardRef<HTMLDivElement, MenuProps>(
|
||||
({ className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("Dropdown.Menu has to be wrapped in <Dropdown />");
|
||||
return null;
|
||||
}
|
||||
|
||||
const { isOpen, anchorEl, setIsOpen } = context;
|
||||
|
||||
return (
|
||||
<Popover
|
||||
{...rest}
|
||||
ref={ref}
|
||||
placement="bottom-end"
|
||||
arrow={false}
|
||||
className={cl("navdsi-dropdown__menu", className)}
|
||||
offset={-4}
|
||||
anchorEl={anchorEl}
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
) as MenuType;
|
||||
|
||||
Menu.List = List;
|
||||
Menu.GroupedList = GroupedList;
|
||||
|
||||
export default Menu;
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import cl from "classnames";
|
||||
import { DropdownContext } from ".";
|
||||
|
||||
export interface ToggleProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Button content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type ToggleType = React.ForwardRefExoticComponent<
|
||||
ToggleProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
const Toggle: ToggleType = forwardRef(({ className, ...rest }, ref) => {
|
||||
const context = useContext(DropdownContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("Dropdown.Toggle has to be wrapped in <Dropdown />");
|
||||
return null;
|
||||
}
|
||||
|
||||
const { setAnchorEl, setIsOpen, isOpen } = context;
|
||||
|
||||
return (
|
||||
<button
|
||||
{...rest}
|
||||
ref={ref}
|
||||
onClick={(e) => {
|
||||
setAnchorEl(e.currentTarget);
|
||||
setIsOpen((isOpen) => !isOpen);
|
||||
}}
|
||||
aria-expanded={isOpen}
|
||||
aria-haspopup="menu"
|
||||
className={cl("navdsi-dropdown__toggle", className)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export default Toggle;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as Dropdown } from "./Dropdown";
|
||||
export * from "./Dropdown";
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { Heading } from "@navikt/ds-react";
|
||||
import { Dropdown } from "..";
|
||||
import { Divider } from "../..";
|
||||
|
||||
export default {
|
||||
title: "ds-react-internal/dropdown",
|
||||
component: Dropdown,
|
||||
};
|
||||
|
||||
export const All = () => (
|
||||
<>
|
||||
<Heading level="1" size="xlarge">
|
||||
Dropdown menu
|
||||
</Heading>
|
||||
<Dropdown>
|
||||
<Dropdown.Toggle>Toggle</Dropdown.Toggle>
|
||||
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.GroupedList>
|
||||
<Dropdown.Menu.GroupedList.Heading>
|
||||
Systemer og oppslagsverk
|
||||
</Dropdown.Menu.GroupedList.Heading>
|
||||
<Dropdown.Menu.GroupedList.Item>Gosys</Dropdown.Menu.GroupedList.Item>
|
||||
</Dropdown.Menu.GroupedList>
|
||||
<Divider />
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item>Gosys</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item>Psys</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</>
|
||||
);
|
||||
@@ -2,7 +2,7 @@ import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import HeaderTitle, { HeaderTitleType } from "./HeaderTitle";
|
||||
import HeaderUser, { HeaderUserType } from "./HeaderUser";
|
||||
import HeaderButton, { HeaderButtonType } from "./HeaderButton";
|
||||
import HeaderDropdown, { HeaderDropdownType } from "./HeaderDropdown";
|
||||
import HeaderUserButton, { HeaderUserButtonType } from "./HeaderUserButton";
|
||||
import cl from "classnames";
|
||||
|
||||
export interface HeaderProps extends HTMLAttributes<HTMLElement> {
|
||||
@@ -19,16 +19,16 @@ interface HeaderComponent
|
||||
Title: HeaderTitleType;
|
||||
User: HeaderUserType;
|
||||
Button: HeaderButtonType;
|
||||
Dropdown: HeaderDropdownType;
|
||||
UserButton: HeaderUserButtonType;
|
||||
}
|
||||
|
||||
const Header = forwardRef(({ className, ...rest }, ref) => (
|
||||
<header ref={ref} className={cl("navdsi-header", className)} {...rest} />
|
||||
<header {...rest} ref={ref} className={cl("navdsi-header", className)} />
|
||||
)) as HeaderComponent;
|
||||
|
||||
Header.Title = HeaderTitle;
|
||||
Header.User = HeaderUser;
|
||||
Header.Button = HeaderButton;
|
||||
Header.Dropdown = HeaderDropdown;
|
||||
Header.UserButton = HeaderUserButton;
|
||||
|
||||
export default Header;
|
||||
@@ -3,9 +3,9 @@ import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
|
||||
export interface HeaderButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
extends React.AnchorHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Button content
|
||||
* Application Button
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import cl from "classnames";
|
||||
import { HeaderDropdownContext } from ".";
|
||||
|
||||
export interface HeaderDropdownButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* Button content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type HeaderDropdownButtonType = React.ForwardRefExoticComponent<
|
||||
HeaderDropdownButtonProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
const HeaderDropdownButton: HeaderDropdownButtonType = forwardRef(
|
||||
({ className, ...rest }, ref) => {
|
||||
const context = useContext(HeaderDropdownContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn(
|
||||
"HeaderDropdownButton has to be wrapped in <HeaderDropdown />"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const { setAnchorEl, setIsOpen, isOpen, dropdownId } = context;
|
||||
|
||||
return (
|
||||
<button
|
||||
{...rest}
|
||||
ref={ref}
|
||||
onClick={(e) => {
|
||||
setAnchorEl(e.currentTarget);
|
||||
setIsOpen((isOpen) => !isOpen);
|
||||
}}
|
||||
aria-expanded={isOpen}
|
||||
aria-controls={dropdownId}
|
||||
aria-haspopup="menu"
|
||||
className={cl("navdsi-header__dropdown-button", className)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default HeaderDropdownButton;
|
||||
@@ -1,41 +0,0 @@
|
||||
import React, { forwardRef, useContext } from "react";
|
||||
import cl from "classnames";
|
||||
import { DropdownMenu, DropdownMenuType } from "../..";
|
||||
import { HeaderDropdownContext } from ".";
|
||||
|
||||
interface HeaderDropdownMenuProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
/**
|
||||
* Dropdown content
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export type HeaderDropdownMenuType = DropdownMenuType<HeaderDropdownMenuProps>;
|
||||
|
||||
const HeaderDropdownMenu = forwardRef(({ className, ...rest }, ref) => {
|
||||
const context = useContext(HeaderDropdownContext);
|
||||
|
||||
if (!context) {
|
||||
console.warn("HeaderDropdownMenu has to be wrapped in <HeaderDropdown />");
|
||||
return null;
|
||||
}
|
||||
|
||||
const { isOpen, anchorEl, setIsOpen, dropdownId } = context;
|
||||
|
||||
return (
|
||||
<DropdownMenu
|
||||
{...rest}
|
||||
ref={ref}
|
||||
anchorEl={anchorEl}
|
||||
id={dropdownId}
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
className={cl("navdsi-header-dropdown-menu", className)}
|
||||
/>
|
||||
);
|
||||
}) as HeaderDropdownMenuType;
|
||||
|
||||
HeaderDropdownMenu.List = DropdownMenu.List;
|
||||
HeaderDropdownMenu.Item = DropdownMenu.Item;
|
||||
|
||||
export default HeaderDropdownMenu;
|
||||
@@ -1,45 +0,0 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import HeaderDropdownButton from "./Button";
|
||||
import { BodyShort, Detail } from "@navikt/ds-react";
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
|
||||
export interface HeaderDropdownUserButtonProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* User name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* User description
|
||||
*/
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type HeaderDropdownUserButtonType = React.ForwardRefExoticComponent<
|
||||
HeaderDropdownUserButtonProps & React.RefAttributes<HTMLButtonElement>
|
||||
>;
|
||||
|
||||
const HeaderDropdownUserButton: HeaderDropdownUserButtonType = forwardRef(
|
||||
({ name, description, className, ...rest }, ref) => (
|
||||
<HeaderDropdownButton
|
||||
{...rest}
|
||||
ref={ref}
|
||||
className={cl("navdsi-header__dropdown-user-button", className)}
|
||||
>
|
||||
<div>
|
||||
<BodyShort size="small" as="div">
|
||||
{name}
|
||||
</BodyShort>
|
||||
{description && (
|
||||
<Detail size="small" as="div">
|
||||
{description}
|
||||
</Detail>
|
||||
)}
|
||||
</div>
|
||||
<Expand />
|
||||
</HeaderDropdownButton>
|
||||
)
|
||||
);
|
||||
|
||||
export default HeaderDropdownUserButton;
|
||||
@@ -1,51 +0,0 @@
|
||||
import { useId } from "@navikt/ds-react";
|
||||
import React, { createContext, useState } from "react";
|
||||
import HeaderDropdownButton, { HeaderDropdownButtonType } from "./Button";
|
||||
import HeaderDropdownMenu, { HeaderDropdownMenuType } from "./Menu";
|
||||
import HeaderDropdownUserButton, {
|
||||
HeaderDropdownUserButtonType,
|
||||
} from "./UserButton";
|
||||
|
||||
export interface HeaderDropdownType extends React.FC {
|
||||
Button: HeaderDropdownButtonType;
|
||||
Menu: HeaderDropdownMenuType;
|
||||
UserButton: HeaderDropdownUserButtonType;
|
||||
}
|
||||
|
||||
export interface HeaderDropdownContextType {
|
||||
readonly dropdownId: string;
|
||||
readonly isOpen: boolean;
|
||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
readonly anchorEl: Element | null;
|
||||
setAnchorEl: React.Dispatch<React.SetStateAction<Element | null>>;
|
||||
}
|
||||
|
||||
export const HeaderDropdownContext = createContext<HeaderDropdownContextType | null>(
|
||||
null
|
||||
);
|
||||
|
||||
const HeaderDropdown = (({ children }) => {
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [anchorEl, setAnchorEl] = useState<Element | null>(null);
|
||||
const id = useId();
|
||||
|
||||
return (
|
||||
<HeaderDropdownContext.Provider
|
||||
value={{
|
||||
dropdownId: `header-dropdown-${id}`,
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
anchorEl,
|
||||
setAnchorEl,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</HeaderDropdownContext.Provider>
|
||||
);
|
||||
}) as HeaderDropdownType;
|
||||
|
||||
HeaderDropdown.Button = HeaderDropdownButton;
|
||||
HeaderDropdown.Menu = HeaderDropdownMenu;
|
||||
HeaderDropdown.UserButton = HeaderDropdownUserButton;
|
||||
|
||||
export default HeaderDropdown;
|
||||
@@ -0,0 +1,48 @@
|
||||
import React, { forwardRef } from "react";
|
||||
import cl from "classnames";
|
||||
import { OverridableComponent } from "@navikt/ds-react";
|
||||
import { BodyShort, Detail } from "@navikt/ds-react";
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import HeaderButton from "./HeaderButton";
|
||||
|
||||
export interface HeaderUserButtonProps
|
||||
extends React.AnchorHTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
* User name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* User description
|
||||
*/
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export type HeaderUserButtonType = OverridableComponent<
|
||||
HeaderUserButtonProps,
|
||||
HTMLButtonElement
|
||||
>;
|
||||
|
||||
const HeaderUserButton: HeaderUserButtonType = forwardRef(
|
||||
({ as, name, description, className, ...rest }, ref) => (
|
||||
<HeaderButton
|
||||
{...rest}
|
||||
as={as}
|
||||
ref={ref}
|
||||
className={cl("navdsi-header__user-button", className)}
|
||||
>
|
||||
<div>
|
||||
<BodyShort size="small" as="div">
|
||||
{name}
|
||||
</BodyShort>
|
||||
{description && (
|
||||
<Detail size="small" as="div">
|
||||
{description}
|
||||
</Detail>
|
||||
)}
|
||||
</div>
|
||||
<Expand />
|
||||
</HeaderButton>
|
||||
)
|
||||
);
|
||||
|
||||
export default HeaderUserButton;
|
||||
@@ -2,7 +2,7 @@ import React from "react";
|
||||
import { BodyLong, BodyShort, Detail, Heading } from "@navikt/ds-react";
|
||||
import { Header } from "..";
|
||||
import { Expand, System, ExternalLink } from "@navikt/ds-icons";
|
||||
import { Divider } from "../..";
|
||||
import { Divider, Dropdown } from "../..";
|
||||
|
||||
export default {
|
||||
title: "ds-react-internal/header",
|
||||
@@ -42,30 +42,30 @@ export const All = () => (
|
||||
</Heading>
|
||||
<Header>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
<Header.Dropdown>
|
||||
<Header.Dropdown.Button style={{ marginLeft: "auto" }}>
|
||||
<Dropdown>
|
||||
<Header.Button as={Dropdown.Toggle} style={{ marginLeft: "auto" }}>
|
||||
<System
|
||||
style={{ fontSize: "1.5rem" }}
|
||||
title="Systemer og oppslagsverk"
|
||||
/>
|
||||
</Header.Dropdown.Button>
|
||||
<Header.Dropdown.Menu>
|
||||
<Header.Dropdown.Menu.List>
|
||||
<Header.Dropdown.Menu.Item>
|
||||
</Header.Button>
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item>
|
||||
<span>A.Inntekt</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Header.Dropdown.Menu.Item>
|
||||
<Header.Dropdown.Menu.Item>
|
||||
</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item>
|
||||
<span>Aa-registeret</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Header.Dropdown.Menu.Item>
|
||||
<Header.Dropdown.Menu.Item>
|
||||
</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item>
|
||||
<span>Gosys</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Header.Dropdown.Menu.Item>
|
||||
</Header.Dropdown.Menu.List>
|
||||
</Header.Dropdown.Menu>
|
||||
</Header.Dropdown>
|
||||
</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
<Header.User name="Kong Harald" description="D123456" />
|
||||
</Header>
|
||||
|
||||
@@ -84,75 +84,74 @@ export const All = () => (
|
||||
const Full = () => (
|
||||
<Header>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
<Header.Dropdown>
|
||||
<Header.Dropdown.Button style={{ marginLeft: "auto" }}>
|
||||
|
||||
<Dropdown>
|
||||
<Header.Button as={Dropdown.Toggle} style={{ marginLeft: "auto" }}>
|
||||
<System
|
||||
style={{ fontSize: "1.5rem" }}
|
||||
title="Systemer og oppslagsverk"
|
||||
/>
|
||||
</Header.Dropdown.Button>
|
||||
<Header.Dropdown.Menu>
|
||||
<BodyShort size="small" style={{ fontWeight: 600, marginBottom: 16 }}>
|
||||
Systemer og oppslagsverk
|
||||
</BodyShort>
|
||||
<Header.Dropdown.Menu.List>
|
||||
<Header.Dropdown.Menu.Item>
|
||||
<span>A.Inntekt</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Header.Dropdown.Menu.Item>
|
||||
<Header.Dropdown.Menu.Item>
|
||||
<span>Aa-registeret</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Header.Dropdown.Menu.Item>
|
||||
<Header.Dropdown.Menu.Item>
|
||||
<span>Gosys</span>
|
||||
<ExternalLink style={{ fontSize: "0.875rem" }} />
|
||||
</Header.Dropdown.Menu.Item>
|
||||
</Header.Dropdown.Menu.List>
|
||||
</Header.Dropdown.Menu>
|
||||
</Header.Dropdown>
|
||||
<Header.Dropdown>
|
||||
<Header.Dropdown.UserButton
|
||||
</Header.Button>
|
||||
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.GroupedList>
|
||||
<Dropdown.Menu.GroupedList.Heading>
|
||||
Systemer og oppslagsverk
|
||||
</Dropdown.Menu.GroupedList.Heading>
|
||||
<Dropdown.Menu.GroupedList.Item>
|
||||
A.Inntekt
|
||||
</Dropdown.Menu.GroupedList.Item>
|
||||
</Dropdown.Menu.GroupedList>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
|
||||
<Dropdown>
|
||||
<Header.UserButton
|
||||
as={Dropdown.Toggle}
|
||||
name="Kong Harald"
|
||||
description="Enhet: Skien"
|
||||
/>
|
||||
<Header.Dropdown.Menu>
|
||||
<Header.Dropdown.Menu.List>
|
||||
<Header.Dropdown.Menu.Item onClick={() => console.log("logg ut")}>
|
||||
<Dropdown.Menu>
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item onClick={() => console.log("logg ut")}>
|
||||
Logg ut
|
||||
</Header.Dropdown.Menu.Item>
|
||||
</Header.Dropdown.Menu.List>
|
||||
</Header.Dropdown.Menu>
|
||||
</Header.Dropdown>
|
||||
</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
);
|
||||
|
||||
const Initials = () => (
|
||||
<Header>
|
||||
<Header.Title href="/#home">NAV Sykepenger</Header.Title>
|
||||
<Header.Dropdown>
|
||||
<Header.Dropdown.Button style={{ marginLeft: "auto" }}>
|
||||
<Dropdown>
|
||||
<Header.Button as={Dropdown.Toggle} style={{ marginLeft: "auto" }}>
|
||||
<BodyShort size="small" title="Kong Harald">
|
||||
KH
|
||||
</BodyShort>
|
||||
<Expand />
|
||||
</Header.Dropdown.Button>
|
||||
<Header.Dropdown.Menu>
|
||||
<div style={{ marginBottom: "var(--navds-spacing-4)" }}>
|
||||
<BodyLong size="small">Kong Harald 16px</BodyLong>
|
||||
<Detail size="small">Ident nr 14px</Detail>
|
||||
<Detail size="small">Enhet: Skien</Detail>
|
||||
</Header.Button>
|
||||
<Dropdown.Menu>
|
||||
<div>
|
||||
<BodyLong size="small" as="div">
|
||||
Kong Harald 16px
|
||||
</BodyLong>
|
||||
<Detail size="small" as="div">
|
||||
<div>Ident nr 14px</div>
|
||||
<div>Enhet: Skien</div>
|
||||
</Detail>
|
||||
</div>
|
||||
<Divider />
|
||||
<Header.Dropdown.Menu.List>
|
||||
<Header.Dropdown.Menu.Item as="a" href="/#settings">
|
||||
<Dropdown.Menu.List>
|
||||
<Dropdown.Menu.List.Item as="a" href="/#settings">
|
||||
Innstillinger
|
||||
</Header.Dropdown.Menu.Item>
|
||||
<Header.Dropdown.Menu.Item onClick={() => console.log("logg ut")}>
|
||||
</Dropdown.Menu.List.Item>
|
||||
<Dropdown.Menu.List.Item onClick={() => console.log("logg ut")}>
|
||||
Logg ut
|
||||
</Header.Dropdown.Menu.Item>
|
||||
</Header.Dropdown.Menu.List>
|
||||
</Header.Dropdown.Menu>
|
||||
</Header.Dropdown>
|
||||
</Dropdown.Menu.List.Item>
|
||||
</Dropdown.Menu.List>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
);
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from "./divider";
|
||||
export * from "./dropdown-menu";
|
||||
export * from "./dropdown";
|
||||
export * from "./header";
|
||||
@@ -19,6 +19,16 @@ yarn storybook
|
||||
|
||||
[http://localhost:6006](http://localhost:6006) (port auto-incrementeres hvis den allerede er i bruk av en annen server)
|
||||
|
||||
### Yarn install med Mac M1 chip
|
||||
|
||||
For at `yarn install` skal funke på Mac med M1 chip krever sharp-pakken at du har "libvps" installert globalt. Libvps krever også gcc og xcode build tools CLI. Dette kan installeres med følgende kommandoer:
|
||||
|
||||
```sh
|
||||
xcode-select --install
|
||||
brew install gcc
|
||||
brew reinstall vips
|
||||
```
|
||||
|
||||
## Utviklingsmiljø
|
||||
|
||||
Vi tar nå i bruk storybook [https://storybook.js.org/](https://storybook.js.org/) som utviklermiljø.
|
||||
|
||||
Reference in new issue
Block a user