|
1 | 1 | # Components |
2 | 2 |
|
3 | | -**Last Updated:** April 5, 2026 |
| 3 | +**Last Updated:** April 6, 2026 |
4 | 4 |
|
5 | 5 | Complete component specifications and guidelines for the Design System Starter Kit. |
6 | 6 |
|
@@ -1587,7 +1587,7 @@ const [isOpen, setIsOpen] = React.useState(false); |
1587 | 1587 |
|
1588 | 1588 | ## Navigation Components |
1589 | 1589 |
|
1590 | | -**Status:** Complete (HTML/CSS, React) — 4 components total |
| 1590 | +**Status:** Complete (HTML/CSS, React) — 5 components total |
1591 | 1591 |
|
1592 | 1592 | ### Menu |
1593 | 1593 |
|
@@ -1899,6 +1899,223 @@ const [isOpen, setIsOpen] = React.useState(false); |
1899 | 1899 |
|
1900 | 1900 | --- |
1901 | 1901 |
|
| 1902 | +### PageHeader |
| 1903 | + |
| 1904 | +**Status:** Complete (HTML/CSS, React) |
| 1905 | + |
| 1906 | +**Location:** `packages/components-{html|react}/src/PageHeader/` |
| 1907 | + |
| 1908 | +**Tokens:** `tokens/components/page-header.json` |
| 1909 | + |
| 1910 | +**Props:** `logoSlot`, `sticky` (`'none'` | `'sticky'` | `'auto-hide'`), `primaryNavigation`, `primaryNavigationLarge`, `secondaryNavigation`, `secondaryNavigationLarge`, `searchSlot`, `onMenuOpen`, `onMenuClose`, `onSearchOpen`, `onSearchClose`, `className` |
| 1911 | + |
| 1912 | +**Features:** |
| 1913 | + |
| 1914 | +- Mobile-first: hamburgerknop (inline-start) opent een `Drawer`, gecentreerd logo (CSS-grid `1fr auto 1fr`), zoekknop (inline-end) ontvouwt zoekpaneel direct onder de header |
| 1915 | +- Boven `64em` (~1024px): tweebandig large viewport layout via `display: none` switch |
| 1916 | + - **Masthead** — neutrale achtergrond met logo (inline-start), servicemenu en inline zoekveld (inline-end) |
| 1917 | + - **Navigatiebalk** — accent-1 achtergrond met primaire navigatie; MenuLink-items krijgen `min-block-size: 4rem` en `padding-inline: var(--dsn-space-inline-xl)` via token-overschrijving op de container |
| 1918 | +- `primaryNavigationLarge` / `secondaryNavigationLarge` — aparte slots voor large viewport; valt terug op de mobile variant wanneer weggelaten |
| 1919 | +- `sticky='sticky'`: `position: sticky; inset-block-start: 0` |
| 1920 | +- `sticky='auto-hide'`: sticky + verbergt bij scroll-down via JS `scroll`-eventlistener (`data-hidden` attribuut), CSS-transitie animeert de beweging |
| 1921 | +- Focus management: openen zoekpaneel → focus naar `<input>`; sluiten → focus terug naar zoekknop |
| 1922 | +- Unieke IDs via `useId()` voor `aria-controls` (zoekpaneel) en `aria-labelledby` (nav-elementen) |
| 1923 | +- De `Drawer` is altijd in de DOM (niet `hidden`) zodat focus management correct werkt |
| 1924 | + |
| 1925 | +**CSS-klassen:** |
| 1926 | + |
| 1927 | +| Klasse | Element | Beschrijving | |
| 1928 | +| --------------------------------- | ---------- | ----------------------------------------------------- | |
| 1929 | +| `dsn-page-header` | `<header>` | Basiscomponent | |
| 1930 | +| `dsn-page-header--sticky` | `<header>` | Sticky gedrag: `position: sticky` | |
| 1931 | +| `dsn-page-header--auto-hide` | `<header>` | Auto-hide sticky: CSS-transitie op `data-hidden` | |
| 1932 | +| `dsn-page-header__small-layout` | `<div>` | Zichtbaar op small viewport (`< 64em`) | |
| 1933 | +| `dsn-page-header__large-layout` | `<div>` | Zichtbaar op large viewport (`≥ 64em`) | |
| 1934 | +| `dsn-page-header__inner` | `<div>` | CSS-grid (`1fr auto 1fr`) voor gecentreerd logo | |
| 1935 | +| `dsn-page-header__start` | `<div>` | Inline-start slot (hamburgerknop) | |
| 1936 | +| `dsn-page-header__logo` | `<div>` | Logo-slot; `max-block-size` op directe child | |
| 1937 | +| `dsn-page-header__end` | `<div>` | Inline-end slot (zoekknop) | |
| 1938 | +| `dsn-page-header__search-panel` | `<div>` | Zoekpaneel (small viewport); verborgen via `[hidden]` | |
| 1939 | +| `dsn-page-header__search-inner` | `<div>` | Flex-container: zoekveld + zoekknop | |
| 1940 | +| `dsn-page-header__masthead` | `<div>` | Bovenste band large viewport (neutrale achtergrond) | |
| 1941 | +| `dsn-page-header__masthead-inner` | `<div>` | Flex-container: logo ↔ secondary-nav | |
| 1942 | +| `dsn-page-header__secondary-nav` | `<div>` | Servicemenu + zoekveld naast elkaar (inline-end) | |
| 1943 | +| `dsn-page-header__searchbox` | `<div>` | Inline zoekveld + zoekknop in masthead | |
| 1944 | +| `dsn-page-header__navbar` | `<div>` | Onderste band large viewport (accent-1 achtergrond) | |
| 1945 | + |
| 1946 | +**Design tokens:** |
| 1947 | + |
| 1948 | +| Token | Waarde | Beschrijving | |
| 1949 | +| ------------------------------------------------- | ------------------------------------ | ------------------------------------------- | |
| 1950 | +| `--dsn-page-header-background-color` | `{dsn.color.neutral.bg-document}` | Achtergrondkleur header | |
| 1951 | +| `--dsn-page-header-border-block-end-width` | `{dsn.border.width.thick}` | Breedte onderkantrand (4px, small viewport) | |
| 1952 | +| `--dsn-page-header-border-block-end-color` | `{dsn.color.accent-1.color-default}` | Kleur onderkantrand (merkkleur) | |
| 1953 | +| `--dsn-page-header-padding-block` | `{dsn.space.block.md}` | Verticale padding mobile binnenbalk | |
| 1954 | +| `--dsn-page-header-padding-inline` | `{dsn.space.inline.xl}` | Horizontale padding mobile binnenbalk | |
| 1955 | +| `--dsn-page-header-z-index` | `300` | Z-index sticky — onder backdrop (400) | |
| 1956 | +| `--dsn-page-header-logo-max-block-size` | `2rem` | Maximale hoogte logo (32px) | |
| 1957 | +| `--dsn-page-header-search-panel-background-color` | `{dsn.color.accent-1.bg-default}` | Achtergrond zoekpaneel (small viewport) | |
| 1958 | +| `--dsn-page-header-search-panel-padding-block` | `{dsn.space.block.md}` | Verticale padding zoekpaneel | |
| 1959 | +| `--dsn-page-header-search-panel-padding-inline` | `{dsn.space.inline.xl}` | Horizontale padding zoekpaneel | |
| 1960 | +| `--dsn-page-header-masthead-background-color` | `{dsn.color.neutral.bg-document}` | Masthead achtergrond (large viewport) | |
| 1961 | +| `--dsn-page-header-masthead-padding-block` | `{dsn.space.block.xl}` | Verticale padding masthead | |
| 1962 | +| `--dsn-page-header-masthead-padding-inline` | `{dsn.space.inline.xl}` | Horizontale padding masthead | |
| 1963 | +| `--dsn-page-header-navbar-background-color` | `{dsn.color.accent-1.bg-default}` | Navigatiebalk achtergrond | |
| 1964 | +| `--dsn-page-header-navbar-padding-inline` | `{dsn.space.inline.xl}` | Horizontale padding navigatiebalk | |
| 1965 | +| `--dsn-page-header-secondary-nav-gap` | `{dsn.space.column.3xl}` | Gap servicemenu ↔ zoekveld in masthead | |
| 1966 | + |
| 1967 | +**Usage:** |
| 1968 | + |
| 1969 | +```html |
| 1970 | +<!-- HTML/CSS — small viewport --> |
| 1971 | +<header class="dsn-page-header"> |
| 1972 | + <div class="dsn-page-header__small-layout"> |
| 1973 | + <div class="dsn-page-header__inner"> |
| 1974 | + <div class="dsn-page-header__start"> |
| 1975 | + <button |
| 1976 | + type="button" |
| 1977 | + class="dsn-button dsn-button--subtle" |
| 1978 | + aria-expanded="false" |
| 1979 | + aria-controls="nav-drawer" |
| 1980 | + > |
| 1981 | + <svg class="dsn-icon" aria-hidden="true"><!-- menu --></svg> |
| 1982 | + <span class="dsn-button__label">Menu</span> |
| 1983 | + </button> |
| 1984 | + </div> |
| 1985 | + <div class="dsn-page-header__logo"> |
| 1986 | + <a href="/"> |
| 1987 | + <svg class="dsn-logo" aria-hidden="true"><!-- logo --></svg> |
| 1988 | + <span class="dsn-visually-hidden" |
| 1989 | + >Naam organisatie — terug naar homepage</span |
| 1990 | + > |
| 1991 | + </a> |
| 1992 | + </div> |
| 1993 | + <div class="dsn-page-header__end"> |
| 1994 | + <button |
| 1995 | + type="button" |
| 1996 | + class="dsn-button dsn-button--subtle" |
| 1997 | + aria-expanded="false" |
| 1998 | + aria-controls="search-panel" |
| 1999 | + > |
| 2000 | + <svg class="dsn-icon" aria-hidden="true"><!-- search --></svg> |
| 2001 | + <span class="dsn-button__label">Zoeken</span> |
| 2002 | + </button> |
| 2003 | + </div> |
| 2004 | + </div> |
| 2005 | + <div class="dsn-page-header__search-panel" id="search-panel" hidden> |
| 2006 | + <div class="dsn-page-header__search-inner"> |
| 2007 | + <div class="dsn-search-input-wrapper"> |
| 2008 | + <input |
| 2009 | + type="search" |
| 2010 | + class="dsn-text-input" |
| 2011 | + placeholder="Zoeken…" |
| 2012 | + aria-label="Zoekopdracht" |
| 2013 | + /> |
| 2014 | + </div> |
| 2015 | + <button type="button" class="dsn-button dsn-button--strong"> |
| 2016 | + <span class="dsn-button__label">Zoeken</span> |
| 2017 | + </button> |
| 2018 | + </div> |
| 2019 | + </div> |
| 2020 | + </div> |
| 2021 | + |
| 2022 | + <!-- Large viewport (zichtbaar boven 64em) --> |
| 2023 | + <div class="dsn-page-header__large-layout"> |
| 2024 | + <div class="dsn-page-header__masthead"> |
| 2025 | + <div class="dsn-page-header__masthead-inner"> |
| 2026 | + <div class="dsn-page-header__logo"> |
| 2027 | + <a href="/" |
| 2028 | + ><svg class="dsn-logo" aria-hidden="true"><!-- logo --></svg></a |
| 2029 | + > |
| 2030 | + </div> |
| 2031 | + <div class="dsn-page-header__secondary-nav"> |
| 2032 | + <nav aria-labelledby="service-nav-id"> |
| 2033 | + <h2 id="service-nav-id" class="dsn-visually-hidden">Servicemenu</h2> |
| 2034 | + <ul class="dsn-menu dsn-menu--horizontal"> |
| 2035 | + <!-- MenuLink items --> |
| 2036 | + </ul> |
| 2037 | + </nav> |
| 2038 | + <div class="dsn-page-header__searchbox"> |
| 2039 | + <div class="dsn-search-input-wrapper"> |
| 2040 | + <input |
| 2041 | + type="search" |
| 2042 | + class="dsn-text-input" |
| 2043 | + placeholder="Zoeken…" |
| 2044 | + aria-label="Zoekopdracht" |
| 2045 | + /> |
| 2046 | + </div> |
| 2047 | + <button type="button" class="dsn-button dsn-button--strong"> |
| 2048 | + <span class="dsn-button__label">Zoeken</span> |
| 2049 | + </button> |
| 2050 | + </div> |
| 2051 | + </div> |
| 2052 | + </div> |
| 2053 | + </div> |
| 2054 | + <div class="dsn-page-header__navbar"> |
| 2055 | + <nav aria-labelledby="primary-nav-id"> |
| 2056 | + <h2 id="primary-nav-id" class="dsn-visually-hidden">Hoofdmenu</h2> |
| 2057 | + <ul class="dsn-menu dsn-menu--horizontal"> |
| 2058 | + <!-- MenuLink items --> |
| 2059 | + </ul> |
| 2060 | + </nav> |
| 2061 | + </div> |
| 2062 | + </div> |
| 2063 | +</header> |
| 2064 | +``` |
| 2065 | + |
| 2066 | +```tsx |
| 2067 | +// React |
| 2068 | +<PageHeader |
| 2069 | + logoSlot={ |
| 2070 | + <a href="/"> |
| 2071 | + <Logo aria-hidden={true} /> |
| 2072 | + <span className="dsn-visually-hidden"> |
| 2073 | + Naam organisatie — terug naar homepage |
| 2074 | + </span> |
| 2075 | + </a> |
| 2076 | + } |
| 2077 | + primaryNavigation={ |
| 2078 | + <Menu orientation="vertical"> |
| 2079 | + <MenuLink href="/home" level={1}> |
| 2080 | + Home |
| 2081 | + </MenuLink> |
| 2082 | + </Menu> |
| 2083 | + } |
| 2084 | + primaryNavigationLarge={ |
| 2085 | + <Menu orientation="horizontal"> |
| 2086 | + <MenuLink href="/home" level={1} current> |
| 2087 | + Home |
| 2088 | + </MenuLink> |
| 2089 | + </Menu> |
| 2090 | + } |
| 2091 | + secondaryNavigation={ |
| 2092 | + <Menu orientation="vertical"> |
| 2093 | + <MenuLink href="/contact" level={1}> |
| 2094 | + Contact |
| 2095 | + </MenuLink> |
| 2096 | + </Menu> |
| 2097 | + } |
| 2098 | + secondaryNavigationLarge={ |
| 2099 | + <Menu orientation="horizontal"> |
| 2100 | + <MenuLink href="/contact" level={1}> |
| 2101 | + Contact |
| 2102 | + </MenuLink> |
| 2103 | + </Menu> |
| 2104 | + } |
| 2105 | + searchSlot={ |
| 2106 | + <> |
| 2107 | + <SearchInput placeholder="Zoeken…" aria-label="Zoekopdracht" /> |
| 2108 | + <Button variant="strong">Zoeken</Button> |
| 2109 | + </> |
| 2110 | + } |
| 2111 | + sticky="auto-hide" |
| 2112 | +/> |
| 2113 | +``` |
| 2114 | + |
| 2115 | +**Tests:** React (38 tests) |
| 2116 | + |
| 2117 | +--- |
| 2118 | + |
1902 | 2119 | ## Branding Components |
1903 | 2120 |
|
1904 | 2121 | **Status:** Complete (HTML/CSS, React) — 1 component total |
@@ -2294,15 +2511,15 @@ defineButton('my-custom-button'); |
2294 | 2511 |
|
2295 | 2512 | ## Component Statistics |
2296 | 2513 |
|
2297 | | -**Total Components:** 48 |
| 2514 | +**Total Components:** 49 |
2298 | 2515 |
|
2299 | 2516 | **Implementations:** |
2300 | 2517 |
|
2301 | | -- **HTML/CSS:** 48 components |
2302 | | -- **React:** 48 components (1248 tests total, 62 test suites) |
| 2518 | +- **HTML/CSS:** 49 components |
| 2519 | +- **React:** 49 components (1282 tests total, 63 test suites) |
2303 | 2520 | - **Web Component:** 7 components (Button, Heading, Icon, Link, OrderedList, Paragraph, UnorderedList) |
2304 | 2521 |
|
2305 | | -**Test Coverage:** 1248 tests across 62 test suites |
| 2522 | +**Test Coverage:** 1282 tests across 63 test suites |
2306 | 2523 |
|
2307 | 2524 | --- |
2308 | 2525 |
|
|
0 commit comments