{"id":641,"date":"2023-04-07T16:00:00","date_gmt":"2023-04-07T16:00:00","guid":{"rendered":"https:\/\/erdbeerbeet.com\/?p=641"},"modified":"2023-04-07T16:00:02","modified_gmt":"2023-04-07T16:00:02","slug":"customization-for-my-angular-application","status":"publish","type":"post","link":"https:\/\/erdbeerbeet.com\/de\/customization-for-my-angular-application","title":{"rendered":"Customization for my Angular Application"},"content":{"rendered":"\n<p>I&#8217;m recently taking this exiting course on web accessibility at edX: <a rel=\"noreferrer noopener\" href=\"https:\/\/learning.edx.org\/course\/course-v1:W3Cx+WAI0.1x+3T2019\/home\" target=\"_blank\">W3C &#8211; Introduction to Web Accessibility<\/a>, as recommended by a participant of the code pub event last june. Module 2 introduced users of assistive technology and how easy it is to make digital products more accessible by enabling customization for the user.<\/p>\n\n\n\n<p>Implementing full customization is the next step, but I think every user values an application, that he can bend to her needs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The problem<\/h2>\n\n\n\n<p>As I introduced recently, <a href=\"https:\/\/erdbeerbeet.com\/digital-accessibility-colors\" data-type=\"post\" data-id=\"637\">colors lacking contrast<\/a> are one of the most problematic barriers in digital products. Even when implementing the highes contrast of 1:7, there might be color combinations, that suit certain users even better. Additionally, I am ok if people don&#8217;t like the color scheme I choose for the app.<\/p>\n\n\n\n<p>As part of my user settings, I want to enable my users to choose background, text and highlight-colors, as well as text-size and line spacing. In the future I would love to expand this list with different fonts and some more options.<\/p>\n\n\n\n<p>I first need a preview of the chosen settings, followed by a button to apply the changes to the whole app. And save the variables.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The solution<\/h2>\n\n\n\n<p>I knew soon that I had to use css variables. They can be used in the styles to unify colors, sizes and paddings. And therefore be easily changes. The bonus of css-vars is, that they can be changed dynamically &#8211; and that&#8217;s exactly what I need.<\/p>\n\n\n\n<p>A great resource has been the article <a rel=\"noreferrer noopener\" href=\"https:\/\/medium.com\/@amcdnl\/theming-angular-with-css-variables-3c78a5b20b24\" target=\"_blank\" class=\"broken_link\">Theming Angular with CSS variables (by Austin)<\/a>.<\/p>\n\n\n\n<p>The changed customization must be saved and restored on a later visit, but I wont go into that in this post. Additionally, I want a preview to see the result my customization would make.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The actual coding<\/h2>\n\n\n\n<p>Within my settings page, there is now a customization component. On the right is a preview for the changes that are applied when clicking &#8220;save&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large wp-duotone-duotone-2\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"452\" src=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2023\/04\/Bildschirmfoto-2023-04-07-um-17.50.00-1024x452.png\" alt=\"\" class=\"wp-image-652\" srcset=\"https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2023\/04\/Bildschirmfoto-2023-04-07-um-17.50.00-1024x452.png 1024w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2023\/04\/Bildschirmfoto-2023-04-07-um-17.50.00-300x132.png 300w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2023\/04\/Bildschirmfoto-2023-04-07-um-17.50.00-768x339.png 768w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2023\/04\/Bildschirmfoto-2023-04-07-um-17.50.00-1536x678.png 1536w, https:\/\/erdbeerbeet.com\/wp-content\/uploads\/2023\/04\/Bildschirmfoto-2023-04-07-um-17.50.00-2048x904.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Customization Component<\/figcaption><\/figure>\n\n\n\n<p>The preview works by directly using the styles from the input elements. There is a bit of a delay but I think thats fine to work with. Here is an example for the different buttons:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>       &lt;div>\n          &lt;button\n            mat-raised-button\n            &#91;style.color]=\"textColorInput.value\"\n            &#91;style.background-color]=\"primaryColorInput.value\"\n          >Lorem&lt;\/button>\n          &lt;button\n            mat-raised-button\n            &#91;style.color]=\"backgroundColorInput.value\"\n            &#91;style.background-color]=\"secondaryColorInput.value\"\n          >Ipsum&lt;\/button>\n        &lt;\/div><\/code><\/pre>\n\n\n\n<p>When hitting &#8220;save&#8221; on my customization component, the ThemeService is called with the selected colors and values. backgroundColor, textSize, and the others are set by the user.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>this.themeService.updateTheme('wp', {\n    '--background-color': backgroundColor,\n    '--text-color': textColor,\n    '--primary-color': primaryColor,\n    '--accent-color': secondaryColor,\n    '--text-size': textSize.toString(),\n    '--line-spacing': lineSpacing.toString(),\n});<\/code><\/pre>\n\n\n\n<p>The ThemeService then updates the apps theme accordingly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>updateTheme(name: string, properties: { &#91;key: string]: string; }) {\n    const theme = this.getTheme(name);\n    theme.properties = {\n      ...theme.properties,\n      ...properties\n    };\n\n    if (name === this.theme) {\n      this.themeChange.emit(theme);\n    }\n  }<\/code><\/pre>\n\n\n\n<p>This then works because the styles use the css-variables. So here is a snippet from my styles.scss.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>body {\n  margin: 0;\n  font-family: Roboto, \"Helvetica Neue\", sans-serif;\n  font-size: var(--text-size);\n  line-height: var(--line-spacing);\n}\n\n.mat-app-background {\n  background-color: var(--background-color);\n}<\/code><\/pre>\n\n\n\n<p>In the main app.component.ts, there then is a subscription to update these variables whenever the theme is changed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{...\nthis.themeService.themeChange\n      .subscribe((theme: Theme) => this.updateTheme(theme));\n...}\n...\nprivate updateTheme(theme: Theme) {\n    const element = document.documentElement;\n\n    \/\/ project properties onto the element\n    for (const key in theme.properties) {\n      element.style.setProperty(key, theme.properties&#91;key])\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The result<\/h2>\n\n\n\n<p>My angular app is still on its way to a stable beta version, but in the meantime it is my perfect guinea pig for this kind of features.<\/p>\n\n\n\n<p>I absolutely love the customization feature (for myself) and I hope that it will bring value to my future users and to those, I have inspired.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>On my journey to accessibility for web, apps, and everything, I decided to build a feature into my app, to make the appearance fully customizable for the user.<\/p>\n","protected":false},"author":1,"featured_media":384,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41,42,70,12,49],"tags":[44,16,72,74,71,45],"class_list":["post-641","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-app-programming","category-accessibility","category-programming","category-word_progressor","tag-angular","tag-app","tag-colors","tag-customization","tag-digital-accessibility","tag-word-progressor"],"translation":{"provider":"WPGlobus","version":"3.0.0","language":"de","enabled_languages":["en","de"],"languages":{"en":{"title":true,"content":true,"excerpt":true},"de":{"title":false,"content":false,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts\/641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/comments?post=641"}],"version-history":[{"count":3,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts\/641\/revisions"}],"predecessor-version":[{"id":653,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/posts\/641\/revisions\/653"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/media\/384"}],"wp:attachment":[{"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/media?parent=641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/categories?post=641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/erdbeerbeet.com\/de\/wp-json\/wp\/v2\/tags?post=641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}