diff --git a/app/components/footer.module.css b/app/components/footer.module.css
index ce4ffbc780d..98b8b5a67d7 100644
--- a/app/components/footer.module.css
+++ b/app/components/footer.module.css
@@ -1,4 +1,4 @@
-:root {
+:root, [data-theme="classic"] {
--footer-bg-color: var(--green800);
--footer-header-color: var(--yellow500);
--footer-header-shadow-color: var(--green900);
@@ -7,6 +7,10 @@
--footer-link-hover-shadow-color: var(--green900);
}
+[data-theme="new-design"] {
+ --footer-bg-color: var(--grey900);
+}
+
.footer {
display: grid;
justify-items: center;
diff --git a/app/components/radio-button.hbs b/app/components/radio-button.hbs
new file mode 100644
index 00000000000..447cfca59bf
--- /dev/null
+++ b/app/components/radio-button.hbs
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/app/components/settings-page.hbs b/app/components/settings-page.hbs
index 12c3245014c..229639d6997 100644
--- a/app/components/settings-page.hbs
+++ b/app/components/settings-page.hbs
@@ -1,6 +1,9 @@
Profile
+ {{#if this.design.showToggleButton}}
+ Appearance
+ {{/if}}
Email Notifications
API Tokens
diff --git a/app/components/settings-page.js b/app/components/settings-page.js
new file mode 100644
index 00000000000..2b134e1e6c5
--- /dev/null
+++ b/app/components/settings-page.js
@@ -0,0 +1,6 @@
+import { inject as service } from '@ember/service';
+import Component from '@glimmer/component';
+
+export default class SettingsPage extends Component {
+ @service design;
+}
diff --git a/app/components/theme-preview.hbs b/app/components/theme-preview.hbs
new file mode 100644
index 00000000000..ce141935e69
--- /dev/null
+++ b/app/components/theme-preview.hbs
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/app/components/theme-preview.module.css b/app/components/theme-preview.module.css
new file mode 100644
index 00000000000..8c444a4ac53
--- /dev/null
+++ b/app/components/theme-preview.module.css
@@ -0,0 +1,93 @@
+.preview {
+ display: grid;
+ grid-template-rows: 1fr 4fr 2fr;
+ background-color: var(--main-bg);
+ border: 1px solid var(--main-bg-dark);
+ border-radius: 4px;
+ overflow: hidden;
+}
+
+.header {
+ display: flex;
+ align-items: center;
+ background-color: var(--header-bg-color);
+
+ .logo {
+ margin-left: 5%;
+ height: 35%;
+ aspect-ratio: 1;
+ border-radius: 99999px;
+ background-color: var(--yellow500);
+ }
+
+ .title {
+ margin-left: 5%;
+ height: 35%;
+ width: 40%;
+ border-radius: 99999px;
+ background-color: white;
+ }
+}
+
+.main {
+ background-color: var(--main-bg);
+
+ .text {
+ margin-top: 4%;
+ margin-left: 5%;
+ height: calc(35% / 4);
+ width: 70%;
+ border-radius: 99999px;
+ background-color: var(--main-color);
+
+ & + .text {
+ width: 50%;
+ }
+ }
+
+ .box {
+ display: inline-block;
+ margin-top: 5%;
+ margin-left: 5%;
+ height: 40%;
+ width: 50%;
+ border-radius: 2px;
+ background-color: white;
+
+ .text {
+ margin-top: 7%;
+ margin-left: 5%;
+ height: calc(35% / (4 * 0.4));
+ width: 50%;
+ border-radius: 99999px;
+ background-color: var(--main-color);
+
+ & + .text {
+ width: 70%;
+ background-color: var(--main-color-light);
+ }
+ }
+ }
+}
+
+.footer {
+ background-color: var(--footer-bg-color);
+
+ .title {
+ margin-top: 4%;
+ margin-left: 5%;
+ height: calc(35% / 3);
+ width: 15%;
+ border-radius: 99999px;
+ background-color: var(--footer-header-color);
+ }
+
+ .link {
+ margin-top: 4%;
+ margin-left: 5%;
+ height: calc(35% / 3);
+ width: 25%;
+ border-radius: 99999px;
+ background-color: var(--footer-link-color);
+ }
+}
diff --git a/app/controllers/settings/appearance.js b/app/controllers/settings/appearance.js
new file mode 100644
index 00000000000..aa201c2d2a8
--- /dev/null
+++ b/app/controllers/settings/appearance.js
@@ -0,0 +1,15 @@
+import Controller from '@ember/controller';
+import { action } from '@ember/object';
+import { inject as service } from '@ember/service';
+
+import { alias } from 'macro-decorators';
+
+export default class AppearanceSettingsController extends Controller {
+ @service design;
+
+ @alias('design.theme') theme;
+
+ @action setTheme(theme) {
+ this.theme = theme;
+ }
+}
diff --git a/app/router.js b/app/router.js
index ba5abd6876c..17bde8638e3 100644
--- a/app/router.js
+++ b/app/router.js
@@ -32,6 +32,7 @@ Router.map(function () {
this.route('pending-invites');
});
this.route('settings', function () {
+ this.route('appearance');
this.route('email-notifications');
this.route('profile');
this.route('tokens');
diff --git a/app/services/design.js b/app/services/design.js
index 4670aebfbaa..ca9df2a51e9 100644
--- a/app/services/design.js
+++ b/app/services/design.js
@@ -1,26 +1,23 @@
-import { action } from '@ember/object';
import Service, { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
-import window from 'ember-window-mock';
-
import config from '../config/environment';
import * as localStorage from '../utils/local-storage';
+const KNOWN_THEMES = new Set(['classic', 'new-design']);
+
export default class DesignService extends Service {
@service fastboot;
- @tracked useNewDesign = !this.fastboot.isFastBoot && localStorage.getItem('use-new-design') === 'true';
- @tracked showToggleButton = config.environment === 'development';
+ @tracked _theme = localStorage.getItem('theme');
+ @tracked showToggleButton = config.environment === 'development' || config.environment === 'test';
- constructor() {
- super(...arguments);
- window.toggleDesign = () => this.toggle();
+ get theme() {
+ return KNOWN_THEMES.has(this._theme) ? this._theme : 'classic';
}
- @action
- toggle() {
- this.useNewDesign = !this.useNewDesign;
- localStorage.setItem('use-new-design', String(this.useNewDesign));
+ set theme(theme) {
+ this._theme = theme;
+ localStorage.setItem('theme', theme);
}
}
diff --git a/app/styles/application.module.css b/app/styles/application.module.css
index 1c7b338ae63..cb85369db02 100644
--- a/app/styles/application.module.css
+++ b/app/styles/application.module.css
@@ -1,4 +1,4 @@
-:root {
+:root, [data-theme="classic"] {
--violet800: hsl(252, 44%, 24%);
--grey900: hsl(200, 15%, 19%);
--grey700: hsl(200, 11%, 43%);
@@ -29,10 +29,9 @@
--placeholder-bg2: hsl(213, 16%, 75%);
}
-:root[data-theme="new-design"] {
+[data-theme="new-design"] {
--header-bg-color: var(--violet800);
--main-bg: white;
- --footer-bg-color: var(--grey900);
}
* {
@@ -122,23 +121,3 @@ noscript {
margin: 15px 0;
padding: 0 15px;
}
-
-.toggle-design-button {
- position: fixed;
- bottom: 30px;
- left: 30px;
- z-index: 100;
- padding: 10px;
- border: none;
- border-radius: 5px;
- background: white;
- box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
- color: black;
- font-family: sans-serif;
- cursor: pointer;
-
- &:hover {
- background: #f7f7f7;
- box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);
- }
-}
diff --git a/app/styles/settings/appearance.module.css b/app/styles/settings/appearance.module.css
new file mode 100644
index 00000000000..8a4d790e653
--- /dev/null
+++ b/app/styles/settings/appearance.module.css
@@ -0,0 +1,19 @@
+.themes-form {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+
+.theme-label {
+ display: inline-block;
+ padding: 16px;
+ background: white;
+ border-radius: 6px;
+ box-shadow: 0 2px 3px hsla(51, 50%, 44%, .35);
+}
+
+.theme-preview {
+ width: 200px;
+ height: 160px;
+ margin-bottom: 16px;
+}
diff --git a/app/templates/application.hbs b/app/templates/application.hbs
index 5d46acc6a2b..e31664b969b 100644
--- a/app/templates/application.hbs
+++ b/app/templates/application.hbs
@@ -1,7 +1,7 @@
{{page-title "crates.io: Rust Package Registry" separator=' - ' prepend=true}}
-{{set-theme (if this.design.useNewDesign "new-design")}}
+{{set-theme this.design.theme}}
@@ -14,10 +14,4 @@
-