diff --git a/documentation/docs/api/Components/Scaffold.mdx b/documentation/docs/api/Components/Scaffold.mdx
new file mode 100644
index 00000000..9efeb2b0
--- /dev/null
+++ b/documentation/docs/api/Components/Scaffold.mdx
@@ -0,0 +1,31 @@
+---
+id: 'Scaffold'
+title: 'Scaffold'
+sidebar_label: 'Scaffold'
+sidebar_position: 2.1
+---
+
+import Type from '../_type-definitions/ScaffoldProps.md';
+
+```ts
+import { Scaffold } from '@orfium/toolbox';
+```
+
+:::info
+Must be a descendant of [`ThemeProvider`](https://designlab.orfium.com/?path=/docs/design-system-themeprovider--setting-up-a-button-example).
+:::
+
+## Description
+
+A component that provides the basic HTML structure for all Orfium applications.
+
+## Props
+
+Ƭ [`ScaffoldProps`](../types/ScaffoldProps)
+
+
+
+:::warning
+While you can pass any valid `ReactElement` to the `navigationSlot` and `headerSlot` props, it is really only intended to be
+used with [`Navigation`](./Navigation) and [`TopBar`](./TopBar) respectively.
+:::
\ No newline at end of file
diff --git a/documentation/docs/api/Types/ScaffoldProps.mdx b/documentation/docs/api/Types/ScaffoldProps.mdx
new file mode 100644
index 00000000..a9770284
--- /dev/null
+++ b/documentation/docs/api/Types/ScaffoldProps.mdx
@@ -0,0 +1,17 @@
+---
+id: 'ScaffoldProps'
+title: 'ScaffoldProps'
+sidebar_label: 'ScaffoldProps'
+sidebar_position: 1
+---
+import Type from '../_type-definitions/ScaffoldProps.md';
+
+
+```ts
+import { type ScaffoldProps } from '@orfium/toolbox';
+```
+
+### Definition
+
+
+
diff --git a/documentation/docs/api/_type-definitions/ScaffoldProps.md b/documentation/docs/api/_type-definitions/ScaffoldProps.md
new file mode 100644
index 00000000..561bee5e
--- /dev/null
+++ b/documentation/docs/api/_type-definitions/ScaffoldProps.md
@@ -0,0 +1,5 @@
+| Name | Type | Info |
+|:-----------------| :------------- | ----------------------------------------------------------------------------------------- |
+| `navigationSlot` | `ReactElement` | This **must** be an instance of [`Navigation`](/docs/api/Components/Navigation) component |
+| `headerSlot` | `ReactElement` | This **must** be an instance of [`TopBar`](/docs/api/Components/TopBar) component |
+| `children` | `ReactNode` | |
diff --git a/documentation/docs/tutorials/01-Installation and Usage/UI/navigation-component.md b/documentation/docs/tutorials/01-Installation and Usage/UI/navigation-component.md
index a43fbdb1..9d4c290d 100644
--- a/documentation/docs/tutorials/01-Installation and Usage/UI/navigation-component.md
+++ b/documentation/docs/tutorials/01-Installation and Usage/UI/navigation-component.md
@@ -25,13 +25,13 @@ In order to make usage easier for the user, the `Navigation` component:
In order to use the `Navigation` component, you only have to import it from `@orfium/toolbox` and add it to the file where you build your product's overall layout.
Keep in mind that `@orfium/ictinus` must be installed in your app. Follow these [steps](https://ictinus.herokuapp.com/?path=/story/guide-getting-started--page) before you proceed.
-```jsx
-...
+```tsx
+//...
// highlight-next-line
import { Navigation } from '@orfium/toolbox';
-...
+//...
-const Page: React.FC = () => {
+function Page() {
return (
<...>
diff --git a/documentation/docs/tutorials/01-Installation and Usage/UI/scaffold-component.md b/documentation/docs/tutorials/01-Installation and Usage/UI/scaffold-component.md
new file mode 100644
index 00000000..adadc2b0
--- /dev/null
+++ b/documentation/docs/tutorials/01-Installation and Usage/UI/scaffold-component.md
@@ -0,0 +1,58 @@
+---
+id: 'Scaffold Component'
+sidebar_label: 'Scaffold Component'
+sidebar_position: 3
+---
+
+# Scaffold Component
+
+## Overview
+
+In general, the basic HTML structure of almost all Orfium client apps is the following:
+
+- The [`Navigation`](../../../api/Components/Navigation.mdx) element on the left
+- The [`TopBar`](../../../api/Components/TopBar.mdx) element at the top, on the right of the [`Navigation`](../../../api/Components/Navigation.mdx) element
+- The main content below the [`TopBar`](../../../api/Components/TopBar.mdx), on the right of the [`Navigation`](../../../api/Components/Navigation.mdx) element
+
+![Orfium app structure example](/img/example_structure.png)
+
+The [`Scaffold`](../../../api/Components/Scaffold.mdx) component provides an out-of-the-box solution for setting up your
+app with the aforementioned HTML structure.
+
+:::info
+Using [`Scaffold`](../../../api/Components/Scaffold.mdx) is not required in order to use [`Navigation`](../../../api/Components/Navigation.mdx) and [`TopBar`](../../../api/Components/TopBar.mdx).
+:::
+
+## Usage
+
+In order to use the [`Scaffold`](../../../api/Components/Scaffold.mdx) component, you only have to import it from `@orfium/toolbox` and add it to the file where you build your product's overall layout.
+Keep in mind that `@orfium/ictinus` must be installed in your app. Follow these [steps](https://ictinus.herokuapp.com/?path=/story/guide-getting-started--page) before you proceed.
+
+```tsx
+//...
+// highlight-next-line
+import { Navigation, Scaffold, TopBar } from '@orfium/toolbox';
+//...
+
+function Layout() {
+ // ....
+
+ return (
+
+ }
+ headerSlot={}
+ >
+ {children}
+
+ );
+}
+```
diff --git a/documentation/docs/tutorials/01-Installation and Usage/UI/top-bar-component.md b/documentation/docs/tutorials/01-Installation and Usage/UI/top-bar-component.md
index 73023ca5..07422b55 100644
--- a/documentation/docs/tutorials/01-Installation and Usage/UI/top-bar-component.md
+++ b/documentation/docs/tutorials/01-Installation and Usage/UI/top-bar-component.md
@@ -19,13 +19,13 @@ breadcrumbs, or whatever is necessary based on product requirements.
In order to use the `TopBar` component you only have to import it from `@orfium/toolbox` and add it to the file where you build your product's overall layout.
Keep in mind that `@orfium/ictinus` must be installed in your app. Follow these [steps](https://ictinus.herokuapp.com/?path=/story/guide-getting-started--page) before you proceed.
-```jsx
-...
+```tsx
+// ...
// highlight-next-line
import { TopBar } from '@orfium/toolbox';
-...
+// ...
-const Page: React.FC = () => {
+function Page() {
return (
<...>
diff --git a/documentation/static/img/example_structure.png b/documentation/static/img/example_structure.png
new file mode 100644
index 00000000..6797c689
Binary files /dev/null and b/documentation/static/img/example_structure.png differ
diff --git a/src/ui/Navigation/Navigation.styles.tsx b/src/ui/Navigation/Navigation.styles.tsx
index a070d940..50760130 100644
--- a/src/ui/Navigation/Navigation.styles.tsx
+++ b/src/ui/Navigation/Navigation.styles.tsx
@@ -1,13 +1,6 @@
import styled from '@emotion/styled';
export const Wrapper = styled.div`
- height: 100%;
+ height: 100vh;
display: flex;
`;
-
-export const LocalNav = styled.div`
- position: relative;
- height: 100%;
- display: flex;
- flex-direction: column;
-`;
diff --git a/src/ui/Navigation/common.styles.ts b/src/ui/Navigation/common.styles.ts
index 4e3ab4dc..3d6a34ab 100644
--- a/src/ui/Navigation/common.styles.ts
+++ b/src/ui/Navigation/common.styles.ts
@@ -5,6 +5,10 @@ import { flexCenter, transition } from '@orfium/ictinus/dist/theme/functions';
import { getFocus } from '@orfium/ictinus/dist/theme/states';
import { rem } from 'polished';
+export function getGlobalNavWidth(theme: Theme) {
+ return `calc(7 * ${theme.spacing.sm})`; // 56px
+}
+
export const menuItemStyle = (theme: Theme) => css`
height: ${rem(44)};
color: ${theme.utils.getColor('darkGrey', 850)};
diff --git a/src/ui/Navigation/components/Drawer/Drawer.styles.ts b/src/ui/Navigation/components/Drawer/Drawer.styles.ts
index 5903dddb..b42d1ea5 100644
--- a/src/ui/Navigation/components/Drawer/Drawer.styles.ts
+++ b/src/ui/Navigation/components/Drawer/Drawer.styles.ts
@@ -1,15 +1,17 @@
import styled from '@emotion/styled';
import { transition } from '@orfium/ictinus/dist/theme/functions';
import { rem } from 'polished';
-import { menuItemStyle } from '../../common.styles';
+import { getGlobalNavWidth, menuItemStyle } from '../../common.styles';
export const DrawerContainer = styled.div<{
expanded: boolean;
isDesktop: boolean;
}>`
- ${transition(0.2)};
+ ${transition(0.2, 'width')};
width: ${({ expanded }) => (expanded ? rem('308px') : 0)};
- background-color: white;
+ background-color: ${({ theme }) => theme.palette.white};
+ position: ${({ isDesktop }) => (isDesktop ? 'relative' : 'absolute')};
+ left: ${({ theme, isDesktop }) => (isDesktop ? 0 : getGlobalNavWidth(theme))};
flex-shrink: 0;
height: 100%;
min-height: 100%;
diff --git a/src/ui/Navigation/components/GlobalNav/GlobalNav.styles.ts b/src/ui/Navigation/components/GlobalNav/GlobalNav.styles.ts
index e963d991..6ff91d07 100644
--- a/src/ui/Navigation/components/GlobalNav/GlobalNav.styles.ts
+++ b/src/ui/Navigation/components/GlobalNav/GlobalNav.styles.ts
@@ -4,9 +4,10 @@ import { Theme } from '@orfium/ictinus';
import { rem } from 'polished';
import { LinkProps, NavLink } from 'react-router-dom';
import { DEFAULT_NAVBAR_HEIGHT } from '../../../consts';
+import { getGlobalNavWidth } from '../../common.styles';
export const Wrapper = styled.div`
- width: calc(7 * ${({ theme }) => `${theme.spacing.sm}`}); // 56px
+ width: ${({ theme }) => getGlobalNavWidth(theme)};
display: flex;
flex-basis: calc(7 * ${({ theme }) => `${theme.spacing.sm}`}); // 56px
flex-direction: column;
diff --git a/src/ui/Scaffold/Scaffold.styles.ts b/src/ui/Scaffold/Scaffold.styles.ts
new file mode 100644
index 00000000..fd786a43
--- /dev/null
+++ b/src/ui/Scaffold/Scaffold.styles.ts
@@ -0,0 +1,33 @@
+import styled from '@emotion/styled';
+
+export const GridContainer = styled.div`
+ display: grid;
+ grid-template-columns: auto 1fr;
+ grid-template-rows: 0fr;
+ grid-template-areas:
+ 'sidebar header'
+ 'sidebar main'
+ 'sidebar main';
+ height: 100vh;
+`;
+
+export const Header = styled.header`
+ grid-area: header;
+ position: sticky;
+ top: 0;
+ padding: 0 ${({ theme }) => theme.spacing.md};
+`;
+
+export const Contents = styled.main`
+ grid-area: main;
+ position: relative;
+ padding: ${({ theme }) => theme.spacing.md} ${({ theme }) => theme.spacing.md}
+ ${({ theme }) => theme.spacing.lg};
+`;
+
+export const SideNav = styled.aside`
+ grid-area: sidebar;
+ transition: all 0.2s ease-in-out;
+ position: relative;
+ z-index: 101;
+`;
diff --git a/src/ui/Scaffold/Scaffold.tsx b/src/ui/Scaffold/Scaffold.tsx
new file mode 100644
index 00000000..54178ce4
--- /dev/null
+++ b/src/ui/Scaffold/Scaffold.tsx
@@ -0,0 +1,20 @@
+import { type ReactElement, type ReactNode } from 'react';
+import { Contents, GridContainer, Header, SideNav } from './Scaffold.styles';
+
+export type ScaffoldProps = {
+ navigationSlot: ReactElement;
+ headerSlot: ReactElement;
+ children: ReactNode;
+};
+
+export function Scaffold(props: ScaffoldProps) {
+ const { navigationSlot, headerSlot, children } = props;
+
+ return (
+
+ {navigationSlot}
+
+ {children}
+
+ );
+}
diff --git a/src/ui/Scaffold/index.ts b/src/ui/Scaffold/index.ts
new file mode 100644
index 00000000..c3b1792b
--- /dev/null
+++ b/src/ui/Scaffold/index.ts
@@ -0,0 +1 @@
+export * from './Scaffold';
diff --git a/src/ui/index.ts b/src/ui/index.ts
index 938f269e..5ff8f412 100644
--- a/src/ui/index.ts
+++ b/src/ui/index.ts
@@ -1,3 +1,4 @@
export { DEFAULT_NAVBAR_HEIGHT } from './consts';
export { Navigation, type MenuItem, type NavigationProps } from './Navigation';
+export { Scaffold, type ScaffoldProps } from './Scaffold';
export { TopBar, type TopBarProps } from './TopBar';