diff --git a/src/_app-theme.scss b/src/_app-theme.scss
index 8f12a110e..b13d4be70 100644
--- a/src/_app-theme.scss
+++ b/src/_app-theme.scss
@@ -12,6 +12,7 @@
@use './app/shared/footer/footer-theme';
@use './app/shared/navbar/navbar-theme';
@use './app/shared/table-of-contents/table-of-contents-theme';
+@use './app/shared/cookie-popup/cookie-popup-theme';
@use './styles/api-theme';
@use './styles/markdown-theme';
@use './styles/svg-theme';
@@ -70,4 +71,5 @@
@include not-found-theme.theme($theme);
@include navbar-theme.theme($theme);
@include table-of-contents-theme.theme($theme);
+ @include cookie-popup-theme.theme($theme);
}
diff --git a/src/app/app-module.ts b/src/app/app-module.ts
index 921dc1d91..6d2b72df3 100644
--- a/src/app/app-module.ts
+++ b/src/app/app-module.ts
@@ -7,6 +7,7 @@ import {RouterModule} from '@angular/router';
import {MaterialDocsApp} from './material-docs-app';
import {MATERIAL_DOCS_ROUTES} from './routes';
import {NavBarModule} from './shared/navbar';
+import {CookiePopupModule} from './shared/cookie-popup/cookie-popup-module';
@NgModule({
imports: [
@@ -18,6 +19,7 @@ import {NavBarModule} from './shared/navbar';
relativeLinkResolution: 'corrected'
}),
NavBarModule,
+ CookiePopupModule,
],
declarations: [MaterialDocsApp],
providers: [{provide: LocationStrategy, useClass: PathLocationStrategy}],
diff --git a/src/app/material-docs-app.html b/src/app/material-docs-app.html
index b7b9af2d0..3fe93ffbe 100644
--- a/src/app/material-docs-app.html
+++ b/src/app/material-docs-app.html
@@ -1,2 +1,3 @@
+
diff --git a/src/app/shared/cookie-popup/_cookie-popup-theme.scss b/src/app/shared/cookie-popup/_cookie-popup-theme.scss
new file mode 100644
index 000000000..14695010b
--- /dev/null
+++ b/src/app/shared/cookie-popup/_cookie-popup-theme.scss
@@ -0,0 +1,21 @@
+@use 'sass:map';
+@use '~@angular/material' as mat;
+
+@mixin theme($theme) {
+ $primary: map.get($theme, primary);
+ $accent: map.get($theme, accent);
+ $warn: map.get($theme, warn);
+ $background: map.get($theme, background);
+ $foreground: map.get($theme, foreground);
+ $is-dark-theme: map.get($theme, is-dark);
+
+ app-cookie-popup {
+ .popup {
+ color: if($is-dark-theme,
+ map.get(map.get(mat.$grey-palette, contrast), 50),
+ map.get(mat.$dark-theme-foreground-palette, secondary-text)
+ );
+ background: if($is-dark-theme, map.get(mat.$grey-palette, 50), #252525);
+ }
+ }
+}
diff --git a/src/app/shared/cookie-popup/cookie-popup-module.ts b/src/app/shared/cookie-popup/cookie-popup-module.ts
new file mode 100644
index 000000000..0c3eddf9e
--- /dev/null
+++ b/src/app/shared/cookie-popup/cookie-popup-module.ts
@@ -0,0 +1,11 @@
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {MatButtonModule} from '@angular/material/button';
+import {CookiePopup} from './cookie-popup';
+
+@NgModule({
+ imports: [CommonModule, MatButtonModule],
+ declarations: [CookiePopup],
+ exports: [CookiePopup]
+})
+export class CookiePopupModule {}
diff --git a/src/app/shared/cookie-popup/cookie-popup.html b/src/app/shared/cookie-popup/cookie-popup.html
new file mode 100644
index 000000000..60e1e3ed9
--- /dev/null
+++ b/src/app/shared/cookie-popup/cookie-popup.html
@@ -0,0 +1,13 @@
+
diff --git a/src/app/shared/cookie-popup/cookie-popup.scss b/src/app/shared/cookie-popup/cookie-popup.scss
new file mode 100644
index 000000000..4c900a241
--- /dev/null
+++ b/src/app/shared/cookie-popup/cookie-popup.scss
@@ -0,0 +1,26 @@
+@use '~@angular/cdk' as cdk;
+@use '~@angular/material' as mat;
+
+$_inner-spacing: 16px;
+
+.popup {
+ @include mat.elevation(6);
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ margin: 24px;
+ max-width: 430px;
+ z-index: cdk.$overlay-container-z-index + 1;
+ padding: $_inner-spacing $_inner-spacing $_inner-spacing / 2;
+ border-radius: 4px;
+}
+
+.buttons {
+ display: flex;
+ justify-content: flex-end;
+ margin: $_inner-spacing $_inner-spacing / -2 0 0;
+
+ .mat-button {
+ text-transform: uppercase;
+ }
+}
diff --git a/src/app/shared/cookie-popup/cookie-popup.ts b/src/app/shared/cookie-popup/cookie-popup.ts
new file mode 100644
index 000000000..c822b1022
--- /dev/null
+++ b/src/app/shared/cookie-popup/cookie-popup.ts
@@ -0,0 +1,33 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+
+const STORAGE_KEY = 'docs-cookies';
+
+@Component({
+ selector: 'app-cookie-popup',
+ templateUrl: './cookie-popup.html',
+ styleUrls: ['./cookie-popup.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class CookiePopup {
+ /** Whether the user has accepted the cookie disclaimer. */
+ hasAccepted: boolean;
+
+ constructor() {
+ // Needs to be in a try/catch, because some browsers will
+ // throw when using `localStorage` in private mode.
+ try {
+ this.hasAccepted = localStorage.getItem(STORAGE_KEY) === 'true';
+ } catch {
+ this.hasAccepted = false;
+ }
+ }
+
+ /** Accepts the cookie disclaimer. */
+ accept() {
+ try {
+ localStorage.setItem(STORAGE_KEY, 'true');
+ } catch {}
+
+ this.hasAccepted = true;
+ }
+}