# `hb-layout-desktop`

**Category:** layout · **Tags:** layout, shell, responsive · **Package:** `@htmlbricks/hb-layout-desktop`

Desktop application shell: a top **`hb-navbar`**, an optional left **`hb-sidebar-desktop`** when **`navlinks`** has at least one item, a main **`page`** slot column, an optional **`hb-cookie-law-banner`**, and **`hb-footer`**. Child packages are registered at runtime (`hb-footer`, `hb-offcanvas`, `hb-navbar`, `hb-cookie-law-banner`, `hb-sidebar-desktop`).

## When the sidebar appears

- **`navlinks`** non-empty **and** the internal navbar menu state is open (`switchopen` / off-canvas flow): the shell renders the two-column grid (sidebar track + main column).
- **`navlinks`** empty **or** the menu has been closed from the navbar switch: the sidebar rail is omitted; content runs full width under the navbar (same cookie/footer rules as the two-column variant).

The navbar still receives **`navlinks`** context for branding and burger behavior where applicable.

## Viewport height and scrolling

The host is constrained to the viewport (**`min-height` / `height` / `max-height`**: **`100vh`** / **`100dvh`**) with **`overflow: hidden`** so tall slotted content cannot stretch the shell or the sidebar rail. For a non-viewport parent, prefer giving the host a definite height (for example **`height: 100%`**) instead of relying only on dynamic viewport units—see comments in `styles/webcomponent.scss`.

### Default mode (`single_screen` off / falsy)

The main column scrolls as a whole. The **`page`** slot sits in a flex column with the optional cookie banner and footer below it; short content still gets a stretched middle region so the footer stays at the bottom of the scrollable band.

### Single-screen mode (`single_screen` truthy)

The cookie banner and footer stay pinned under the **`page`** area inside the main column; **only** the **`page`** region scrolls. When **`footer.type`** is **`auto`**, the footer is forced to the compact **`small`** variant; in default mode, **`auto`** maps to **`regular`**.

From HTML/attributes, **`single_screen`** is normalized as a string: anything other than **`"no"`** is treated as enabled; **`"no"`** disables it.

## Cookie banner visibility

**`hb-cookie-law-banner`** is mounted when any of these hold: **`cookielaw`** is **`"yes"`** or **`"true"`**; **`cookielawallowdecline`** is **`"yes"`** or **`"no"`**; **`cookielawlanguage`** is non-empty; **`cookielawuri4more`** is non-empty. The banner receives **`language`** from **`cookielawlanguage`** or falls back to **`i18nlang`**, plus **`allowdecline`** and **`cookielawuri4more`**.

## Props (attributes)

Web component **attributes** are **strings** in **`snake_case`**. Pass structured data (**`company`**, **`contacts`**, **`navlinks`**, **`usermenu`**, **`socials`**, **`columns`**, **`policies`**, **`sidebar`**, **`footer`**, **`i18nlanguages`**) as **JSON strings** from HTML, or assign parsed objects in JavaScript. Booleans follow the project convention **`yes`** / **`no`** where noted.

| Name | Role |
|------|------|
| **`i18nlang`** | Active locale code forwarded to **`hb-sidebar-desktop`**. |
| **`i18nlanguages`** | Language picker entries: JSON array of **`{ code, label }`** (or equivalent string form). |
| **`id`**, **`style`** | Standard host passthrough. |
| **`company`** | Company block for footer (JSON); navbar left brand may use **`company.logoUri`** and **`company.siteName`**. |
| **`page_title`** | Preferred string for **`hb-navbar`** **`companybrandname`**; falls back to **`company.siteName`**. |
| **`navlinks`** | Sidebar navigation (**`INavLink[]`** as JSON). Empty array removes the sidebar column (see above). |
| **`pagename`** | Current page key forwarded as **`hb-sidebar-desktop`** **`navpage`**. |
| **`usermenu`** | Navbar user menu payload (JSON). |
| **`socials`**, **`contacts`**, **`columns`**, **`policies`** | Forwarded to **`hb-footer`** as JSON strings inside the shadow tree. |
| **`sidebar`** | JSON object: **`title`**, **`logo`**, **`type`**, plus **`enablefooter`** / **`enablethemeswitch`** (**`yes`** / **`no`**) for **`hb-sidebar-desktop`**. |
| **`footer`** | JSON object: **`type`** **`auto`** \| **`small`** \| **`regular`** \| **`large`**; **`disable_expanding_small`** boolean maps to **`yes`**/**`no`** on **`hb-footer`**. Parsed from a string in an effect if needed. |
| **`cookielaw`**, **`cookielawuri4more`**, **`cookielawallowdecline`**, **`cookielawlanguage`** | Cookie-law banner wiring (see visibility rules). |
| **`single_screen`** | String or boolean; controls pinned footer/cookie vs scrolling column (see above). |

The authoritative TypeScript shape is **`types/webcomponent.type.d.ts`** (including nested types from **`hb-footer`**, **`hb-navbar`**, **`hb-sidenav-link`**, **`hb-sidebar-desktop`**).

## Events

All events are **`CustomEvent`** instances on **`hb-layout-desktop`**.

| Event | `detail` |
|-------|----------|
| **`offcanvasswitch`** | **`{ isOpen: boolean }`** — forwarded from **`hb-navbar`** when the nav menu open state changes. |
| **`pageChange`** | **`{ page: string }`** — forwarded from **`hb-sidebar-desktop`**. |
| **`navbarDropDownClick`** | **`{ key: string }`** — forwarded from **`hb-navbar`**. |
| **`navbarSlotClick`** | **`{ side: "left" \| "right" \| "center" }`** — forwarded from **`hb-navbar`**. |
| **`footerClick`** | **`{ elClick: string }`** — forwarded from **`hb-footer`**. |
| **`themeChange`** | **`{ mode: "light" \| "dark" \| "auto" }`** — forwarded from **`hb-sidebar-desktop`**. |
| **`languageChange`** | **`{ code: string }`** — forwarded from **`hb-sidebar-desktop`**. |

## Slots

| Slot | Description |
|------|-------------|
| **`nav-center-slot`** | Projected into **`hb-navbar`** **`center-slot`** (titles or inline controls). |
| **`nav-right-slot`** | Projected into **`hb-navbar`** **`right-slot`** (actions, extras). |
| **`page`** | Main application view body in the desktop content column. |

## CSS custom properties

Theme and layout tokens (Bulma variables and host-specific sizing) are documented in **`extra/docs.ts`** under **`styleSetup.vars`**. Highlights:

| Variable | Purpose |
|----------|---------|
| **`--hb-layout-desktop-sidebar-width`** | First grid track width for the sidebar column (default **`240px`**). |
| **`--bulma-navbar-item-img-max-height`** | Caps the optional brand image in the navbar left area. |
| **`--bulma-text`**, **`--bulma-background`**, **`--bulma-border`** | Shell chrome aligned with [Bulma CSS variables](https://bulma.io/documentation/features/css-variables/). |

## CSS `::part` names

| Part | Description |
|------|-------------|
| **`navbar`** | The top **`hb-navbar`** strip. |
| **`container`** | The main flex column under the navbar (grid row or full-width main). |
| **`page`** | The scrollable main content region beside the optional sidebar. |
| **`footer`** | The bottom **`hb-footer`** region. |

## Navigation icons

Optional **`icon`** fields on each **`navlinks`** entry use **Bootstrap Icons** glyph names only (for example **`house-door`**). See the **`hb-sidebar-desktop`** package README for conventions.

## Custom element

```html
<hb-layout-desktop
  navlinks='[{"label":"Home","key":"home","icon":"house-door"}]'
  pagename="home"
  page_title="My app"
  single_screen="no"
>
  <span slot="page">…</span>
</hb-layout-desktop>
```

Adjust attribute payloads to match your JSON schema for **`company`**, **`footer`**, **`usermenu`**, and other structured props.

## Types

Authoring types for **`Component`** and **`Events`** live in **`types/webcomponent.type.d.ts`**. Generated consumer typings (**`types/html-elements.d.ts`**, **`types/svelte-elements.d.ts`**) are produced on **`npm run build:wc`** from the builder package.
