From e6af43bce18055fb35b01fbbc77d59b80f2a3a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Girault?= Date: Mon, 23 May 2022 12:07:18 +0200 Subject: [PATCH] Refactored default styles * Less opinionated design * Using variables to allow for easier customization * Using CSS to format purpose attributes (previously parenthesis hard-coded into translations) --- dist/example-assets/style.css | 163 +----------- src/styles/orejime.scss | 363 +++++++++----------------- src/translations/de.yml | 4 +- src/translations/en.yml | 4 +- src/translations/fi.yml | 4 +- src/translations/fr.yml | 4 +- src/translations/hu.yml | 4 +- src/translations/it.yml | 4 +- src/translations/nb.yml | 4 +- src/translations/nl.yml | 4 +- src/translations/oc.yml | 4 +- src/translations/ro.yml | 4 +- src/translations/sv.yml | 4 +- src/ui/components/Main.tsx | 2 +- src/ui/themes/orejime/Modal.tsx | 2 +- src/ui/themes/orejime/ModalBanner.tsx | 2 +- src/ui/themes/orejime/Purpose.tsx | 32 +-- 17 files changed, 174 insertions(+), 434 deletions(-) diff --git a/dist/example-assets/style.css b/dist/example-assets/style.css index b2fc418f..88a13384 100644 --- a/dist/example-assets/style.css +++ b/dist/example-assets/style.css @@ -291,154 +291,17 @@ main { } } -.orejime-ModalOverlay, -.orejime-BannerOverlay { - background: rgba(54, 117, 145, 0.75); -} - -.orejime-Banner, -.orejime-Modal { - background: var(--cyan-darker); - background: linear-gradient(112.5deg, var(--cyan-dark) 0%, var(--cyan-darker) 100%); - color: var(--white); -} - -@media screen and (min-width: 990px) { - .orejime-Banner { - max-width: 40ch; - } -} - -.orejime-Banner-body { - padding: calc(var(--unit) / 2); -} - -.orejime-Banner-purposes { - color: var(--cyan-light); -} - -.orejime-Banner-description { - margin-bottom: calc(var(--unit) / 2); - text-align: center; -} - -.orejime-Banner-actions { - text-align: center; -} - -.orejime-Modal a { - color: var(--white); -} - -.orejime-Modal a:hover, -.orejime-Modal a:focus { - background: rgba(214, 8, 79, 0.3); -} - -.orejime-Modal-header { - border: 0; - padding: calc(1.5 * var(--unit)); - padding-bottom: 0; -} - -.orejime-Modal-title { - margin-bottom: var(--unit); - line-height: 1; - font-size: 2em; -} - -.orejime-Modal-body { - padding: calc(1.5 * var(--unit)); - padding-bottom: calc(var(--unit) / 2); -} - -.orejime-Modal-footer { - border: 0; - padding: calc(1.5 * var(--unit)); -} - -.orejime-Modal-title { - font-family: var(--headings-font); -} - -.orejime-PurposeToggles { - margin-bottom: calc(1.5 * var(--unit)); -} - -.orejime-PurposeToggles button { - margin: 0 1px 1px 0; -} - -.orejime-Purpose { - padding-left: calc(50px + var(--unit)); -} - -.orejime-Purpose-purposes { - color: var(--cyan-light); -} - -.orejime-Button { - padding: calc(var(--unit) / 4) calc(var(--unit) / 2); - font-weight: 600; - cursor: pointer; - transition: background-color 75ms ease-in; -} - -.orejime-Button--info { - background: var(--magenta); -} - -.orejime-Button--info:hover, -.orejime-Button--info:focus { - background: var(--magenta-focus); -} - -.orejime-Button--info:active { - background: var(--magenta-active); -} - -.orejime-Button--decline { - background: var(--negative); -} - -.orejime-Button--decline:hover, -.orejime-Button--decline:focus { - background: var(--negative-focus); -} - -.orejime-Button--decline:active { - background: var(--negative-active); -} - -.orejime-Button--save, -.orejime-Button--accept { - background: var(--positive); - color: var(--cyan-darker); -} - -.orejime-Button--save:hover, -.orejime-Button--save:focus, -.orejime-Button--accept:hover, -.orejime-Button--accept:focus { - background: var(--positive-focus); -} -.orejime-Button--save:active, -.orejime-Button--accept:active { - background: var(--positive-active); -} - -.orejime-Purpose-input:checked + .orejime-Purpose-label .orejime-Purpose-slider { - background: var(--magenta); -} - -.orejime-Purpose-input:indeterminate + .orejime-Purpose-label .orejime-Purpose-slider { - background: var(--magenta-indeterminate); -} - -.orejime-Modal-privacyPolicyLink { - color: var(--cyan-light); -} - -.orejime-Modal-poweredByLink { - display: none; +.orejime-Env { + --orejime-overlay-background: rgba(54, 117, 145, 0.75); + --orejime-background: var(--cyan-darker); + --orejime-background: linear-gradient( + 112.5deg, + var(--cyan-dark) 0%, + var(--cyan-darker) 100% + ); + --orejime-color: var(--white); + --orejime-color-subdued: var(--cyan-light); + --orejime-color-interactive: #feb752; + --orejime-color-interactive: #e3c0fa; + --orejime-font-family: inherit; } diff --git a/src/styles/orejime.scss b/src/styles/orejime.scss index 5585f7dc..66182197 100644 --- a/src/styles/orejime.scss +++ b/src/styles/orejime.scss @@ -1,24 +1,14 @@ -@use "sass:color"; - $orejime-box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.2), 5px 5px 10px 0 rgba(0, 0, 0, 0.19) !default; -$orejime-border-radius: 4px !default; - -$orejime-blue: #057EB6 !default; -$orejime-green: #008A28 !default; -$orejime-theme-bg: #333 !default; -$orejime-theme-border: 1px solid #555 !default; -$orejime-theme-color: #eee !default; -$orejime-theme-color-light: #aaa !default; - -$orejime-breakpoint-banner: 990px !default; +$orejime-breakpoint-notice: 990px !default; // micro css reset for everything orejime related [class^="orejime-"] { margin: 0; padding: 0; border: 0; - font-family: inherit; + line-height: var(--orejime-space-1); + font-family: var(--orejime-font-family); font-size: inherit; color: inherit; vertical-align: baseline; @@ -29,62 +19,78 @@ $orejime-breakpoint-banner: 990px !default; font-weight: normal; } -.orejime-Main, -.orejime-Modal { - font-size: 1em; - line-height: 1.5; +.orejime-Env { + --orejime-space-1: 1.4em; + --orejime-space-2: calc(2 * var(--orejime-space-1)); + --orejime-space-05: calc(var(--orejime-space-1) / 2); + --orejime-space-025: calc(var(--orejime-space-1) / 4); + --orejime-font-size-small: 0.8rem; + --orejime-font-family: sans-serif; + --orejime-gap: 1ch; + --orejime-radius: calc(var(--orejime-space-1) / 4); + --orejime-overlay-background: rgba(0,0,0,0.5); + --orejime-background: #fff; + --orejime-color: #222; + --orejime-color-subdued: #555; + --orejime-color-interactive: #d6084f; + --orejime-banner-max-width: 45ch; + --orejime-modal-max-width: 75ch; + + p { + margin: 0; + } + + a { + color: var(--orejime-color-interactive); + text-decoration: underline; + cursor: pointer; + } } .orejime-Button { + box-shadow: inset 0 0 0 2px currentColor; + margin: 0; border: 0; - color: #fff; - border-radius: $orejime-border-radius; - padding: 6px 10px; - margin-right: 0.5em; - border: 1px solid transparent; + border-radius: var(--orejime-radius); + padding: var(--orejime-space-025) var(--orejime-space-05); + color: var(--orejime-color-interactive); + background: transparent; + font: inherit; + cursor: pointer; &[disabled] { - opacity: 0.75; + color: var(--orejime-color-subdued); } } -.orejime-Button--save, -.orejime-Button--accept { - background: $orejime-green; - color: #fff; -} - -.orejime-Button--decline { - background: #666; -} - -.orejime-Button--info { - background: $orejime-blue; +.orejime-Button:not([disabled]):hover, +.orejime-Button:not([disabled]):focus { + box-shadow: inset 0 0 0 2px currentColor, 0 0 0 1px currentColor; } .orejime-Banner { - background: $orejime-theme-bg; + background: var(--orejime-background); + color: var(--orejime-color); position: fixed; z-index: 1000; width: 100%; bottom: 0; - font-size: 0.8em; - @media (min-width: $orejime-breakpoint-banner) { + @media (min-width: $orejime-breakpoint-notice) { box-shadow: $orejime-box-shadow; - border-radius: $orejime-border-radius; - bottom: 20px; - right: 20px; - max-width: 300px; + border-radius: var(--orejime-radius); + bottom: var(--orejime-space-1); + right: var(--orejime-space-1); + max-width: var(--orejime-banner-max-width); } - @media (max-width: $orejime-breakpoint-banner) { + @media (max-width: $orejime-breakpoint-notice) { border: none; border-radius: 0; } } -.orejime-Banner--mandatory { +.orejime-Banner--forced { position: absolute; bottom: 0; left: 0; @@ -93,57 +99,43 @@ $orejime-breakpoint-banner: 990px !default; max-width: none; } -.orejime-Banner--hidden { +.orejime-Banner[aria-hidden="true"] { display: none !important; } .orejime-Banner-body { - padding: 1em; + padding: var(--orejime-space-1); } .orejime-Banner-logo { - max-width: 200px; -} - -.orejime-Banner-title, -.orejime-Banner-description { - color: $orejime-theme-color; - margin-bottom: 0.5em; + max-width: 10ch; } .orejime-Banner-title { + margin-bottom: var(--orejime-space-05); font-weight: bold; - font-size: 1.2em; - line-height: 1.3; + font-size: 1em; + line-height: var(--orejime-space-1); +} + +.orejime-Banner-description { + white-space: pre-line; } .orejime-Banner-purposes { - color: $orejime-theme-color; + font-style: italic; } .orejime-Banner-changes { - color: $orejime-theme-color; - margin-bottom: 0.5em; + margin-top: var(--orejime-space-05); font-weight: bold; } -.orejime-Banner-privacyPolicyLink { - text-decoration: underline; - cursor: pointer; - - &, - &:hover { - color: inherit; - } - - &:hover, - &:focus { - text-decoration: none; - } -} - .orejime-Banner-actions { - display: block; + display: flex; + flex-wrap: wrap; + gap: var(--orejime-gap); + margin-top: var(--orejime-space-1); } .orejime-Banner-actionItem { @@ -168,7 +160,7 @@ $orejime-breakpoint-banner: 990px !default; .orejime-ModalOverlay, .orejime-BannerOverlay { z-index: 1000; - background: rgba(0,0,0,0.5); + background: var(--orejime-overlay-background); position: fixed; top: 0; left: 0; @@ -183,30 +175,29 @@ $orejime-breakpoint-banner: 990px !default; left: 50%; transform: translate(-50%, -50%); margin: 0; - width: 640px; + width: var(--orejime-modal-max-width); max-width: 100%; max-height: 100%; overflow: auto; } .orejime-Modal { - background: $orejime-theme-bg; - color: $orejime-theme-color; - border-radius: $orejime-border-radius; + padding: var(--orejime-space-2); + background: var(--orejime-background); + color: var(--orejime-color); + border-radius: var(--orejime-radius); box-shadow: $orejime-box-shadow; } .orejime-Modal-header { - padding: 1em; - border-bottom: $orejime-theme-border; + margin-bottom: calc(var(--orejime-space-1) + var(--orejime-space-05)); } .orejime-Modal-title { - margin: 0; - font-size: 2em; display: block; + margin: 0 0 var(--orejime-space-05) 0; + font-size: 2em; font-weight: bold; - padding-right: 20px; } .orejime-Modal-closeButton { @@ -214,201 +205,95 @@ $orejime-breakpoint-banner: 990px !default; background: none; color: inherit; position: absolute; - top: 1em; - right: 1em; + top: calc(-1 * var(--orejime-space-1)); + right: calc(-1 * var(--orejime-space-1)); } .orejime-CloseIcon { stroke: currentColor; - width: 12px; + width: 1em; } .orejime-Modal-body { - padding: 1em; + margin-bottom: var(--orejime-space-2); +} + +.orejime-Modal-description { + white-space: pre-line; } .orejime-Modal-footer { - padding: 1em; - border-top: $orejime-theme-border; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + gap: var(--orejime-gap); } -.orejime-Modal-privacyPolicyLink, .orejime-Modal-poweredByLink { - cursor: pointer; - text-decoration: underline; - color: inherit; - - &:hover, - &:focus, - &:active { - color: inherit; - } - - &:hover, - &:focus { - text-decoration: none; - } + display: inline-block; + font-size: var(--orejime-font-size-small); } -.orejime-Modal-poweredByLink { - position: absolute; - right: 1em; - color: $orejime-theme-color-light; - font-size: 0.8em; - padding: 6px 0; - - &:hover, - &:focus, - &:active { - color: $orejime-theme-color-light; - } +.orejime-PurposeToggles { + display: flex; + flex-wrap: wrap; + gap: var(--orejime-gap); + margin-bottom: var(--orejime-space-1); } .orejime-PurposeList { - display: block; - padding: 0; - margin: 0; + list-style: none; } -.orejime-PurposeList-item { - display: block; - position: relative; - line-height: 1.25; - vertical-align: middle; - min-height: 40px; - margin-top: 0.7em; +.orejime-Purpose { + margin-top: var(--orejime-space-05); } -.orejime-Purpose { - padding-left: 60px; - min-height: 50px; +.orejime-Purpose .orejime-Purpose { + padding-left: var(--orejime-space-2); } .orejime-Purpose-title { - font-size: 1.2em; font-weight: bold; cursor: pointer; } .orejime-Purpose-description { - font-size: 0.9em; -} - -.orejime-Purpose-exempt, -.orejime-Purpose-forced { - padding-left: 0.2em; - font-size: 0.8em; - color: $orejime-theme-color-light; -} - -.orejime-Purpose-input { - position: absolute; - top: 0; - left: 0; - opacity: 0; - width: 50px; - height: 30px; + padding-left: var(--orejime-space-2); + color: var(--orejime-color-subdued); + white-space: pre-line; } -.orejime-Purpose-switch { - position: absolute; - left: 0; - display: inline-block; - width: 50px; - height: 30px; +.orejime-Purpose-purposes { + font-size: var(--orejime-font-size-small); + color: var(--orejime-color-subdued); } -.orejime-Purpose-slider { - box-shadow: $orejime-box-shadow; - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #aaa; - -webkit-transition: .4s; - transition: .4s; - width: 50px; - display: inline-block; - border-radius: 30px; - border: 2px solid transparent; +.orejime-Purpose-attribute { + font-size: var(--orejime-font-size-small); + font-style: italic; + color: var(--orejime-color-subdued); &:before { - position: absolute; - content: ""; - height: 20px; - width: 20px; - left: 3px; - bottom: 3px; - background-color: white; - -webkit-transition: .4s; - transition: .4s; - border-radius: 50%; - border: 1px solid #555; + content: '- '; } -} - -.orejime-Purpose-switchLabel { - position: absolute; - width: 50px; - top: 34px; - overflow: ellipsis; - font-size: 0.8em; - text-align: center; -} -.orejime-Purpose-switch--disabled .orejime-Purpose-slider { - cursor: default; - opacity: 0.5; -} - -.orejime-Purpose-switch--disabled .orejime-Purpose-switchLabel { - color: #aaa; -} - -.orejime-Purpose-input:focus + .orejime-Purpose-label .orejime-Purpose-slider { - border-color: #fff; - outline-offset: 2px; -} - -.orejime-Purpose-input:checked + .orejime-Purpose-label .orejime-Purpose-slider { - background-color: $orejime-blue; -} - -.orejime-Purpose-input:checked + .orejime-Purpose-label .orejime-Purpose-slider:before { - -webkit-transform: translateX(20px); - -ms-transform: translateX(20px); - transform: translateX(20px); -} - -.orejime-Purpose-input:indeterminate + .orejime-Purpose-label .orejime-Purpose-slider { - background-color: color.mix($orejime-blue, #aaa) -} - -.orejime-Purpose-input:indeterminate + .orejime-Purpose-label .orejime-Purpose-slider:before { - -webkit-transform: translateX(10px); - -ms-transform: translateX(10px); - transform: translateX(10px); -} - -.orejime-PurposeToggles { - margin-bottom: 1em; - display: block; -} - -.orejime-PurposeToggles-item { - display: inline; -} - -.orejime-Purpose-children { - margin: 1em 0; + &[title] { + text-decoration: underline dotted; + } } -.orejime-Purpose-children .orejime-Purpose-title { - font-size: 0.9em; +.orejime-Purpose-input { + float: left; + margin-right: var(--orejime-space-1); + width: var(--orejime-space-1); + height: var(--orejime-space-1); + appearance: revert; + background: revert; + accent-color: var(--orejime-color-interactive); } -.orejime-Purpose-children .orejime-Purpose-description { - font-size: 0.8em; +.orejime-Purpose-input:disabled { + accent-color: var(--orejime-color-subdued); } diff --git a/src/translations/de.yml b/src/translations/de.yml index 7ba016bd..cd8d616a 100644 --- a/src/translations/de.yml +++ b/src/translations/de.yml @@ -26,9 +26,9 @@ modal: save: Speichern saveTitle: Speichern purpose: - mandatory: (immer notwendig) + mandatory: immer notwendig mandatoryTitle: Diese Anwendung wird immer benötigt - exempt: (Opt-Out) + exempt: Opt-Out exemptTitle: Diese Anwendung wird standarmäßig gelanden (aber Sie können sie deaktivieren) showMore: Mehr Details zeigen accept: Annehmen diff --git a/src/translations/en.yml b/src/translations/en.yml index 2b334556..97adffa0 100644 --- a/src/translations/en.yml +++ b/src/translations/en.yml @@ -25,9 +25,9 @@ modal: save: Save saveTitle: Save my configuration on collected information purpose: - mandatory: (always required) + mandatory: always required mandatoryTitle: This application is always required - exempt: (opt-out) + exempt: opt-out exemptTitle: This app is loaded by default (but you can opt out) showMore: Show more details accept: Accept diff --git a/src/translations/fi.yml b/src/translations/fi.yml index 9ca9a537..1d0aa939 100644 --- a/src/translations/fi.yml +++ b/src/translations/fi.yml @@ -25,9 +25,9 @@ modal: save: Tallenna saveTitle: null purpose: - mandatory: (vaaditaan) + mandatory: vaaditaan mandatoryTitle: Sivusto vaatii tämän aina - exempt: (ladataan oletuksena) + exempt: ladataan oletuksena exemptTitle: Ladataan oletuksena (mutta voit ottaa sen pois päältä) showMore: "" accept: "" diff --git a/src/translations/fr.yml b/src/translations/fr.yml index 463d049c..ae602d33 100644 --- a/src/translations/fr.yml +++ b/src/translations/fr.yml @@ -26,9 +26,9 @@ modal: save: Sauvegarder saveTitle: Sauvegarder ma configuration sur les informations collectées purpose: - mandatory: (toujours requis) + mandatory: toujours requis mandatoryTitle: Cette application est toujours requise - exempt: (opt-out) + exempt: opt-out exemptTitle: Cette application est chargée par défaut (mais vous pouvez la désactiver) showMore: Voir plus de détails accept: Accepter diff --git a/src/translations/hu.yml b/src/translations/hu.yml index bfb0c842..f4deaf20 100644 --- a/src/translations/hu.yml +++ b/src/translations/hu.yml @@ -25,9 +25,9 @@ modal: save: Mentés saveTitle: null purpose: - mandatory: (mindig kötelező) + mandatory: mindig kötelező mandatoryTitle: Ez az applikáció mindig kötelező - exempt: (leiratkozás) + exempt: leiratkozás exemptTitle: Ez az alkalmazás alapértelmezés szerint betöltött (de ki lehet kapcsolni) showMore: "" accept: "" diff --git a/src/translations/it.yml b/src/translations/it.yml index 8013fd88..e3248bc1 100644 --- a/src/translations/it.yml +++ b/src/translations/it.yml @@ -25,9 +25,9 @@ modal: save: Salva saveTitle: null purpose: - mandatory: (sempre richiesto) + mandatory: sempre richiesto mandatoryTitle: Quest'applicazione è sempre richiesta - exempt: (opt-out) + exempt: opt-out exemptTitle: Quest'applicazione è caricata di default (ma puoi disattivarla) showMore: "" accept: Accetto diff --git a/src/translations/nb.yml b/src/translations/nb.yml index 996b07d1..5cddbc18 100644 --- a/src/translations/nb.yml +++ b/src/translations/nb.yml @@ -25,9 +25,9 @@ modal: save: Opslaan saveTitle: null purpose: - mandatory: (alltid påkrevd) + mandatory: alltid påkrevd mandatoryTitle: Denne applikasjonen er alltid påkrevd - exempt: (opt-out) + exempt: opt-out exemptTitle: Denne appen er lastet som standard (men du kan skru det av) showMore: "" accept: "" diff --git a/src/translations/nl.yml b/src/translations/nl.yml index 3e859229..45f582bd 100644 --- a/src/translations/nl.yml +++ b/src/translations/nl.yml @@ -25,9 +25,9 @@ modal: save: Opslaan saveTitle: Mijn configuratie voor de informatievergaring opslaan purpose: - mandatory: (altijd verplicht) + mandatory: altijd verplicht mandatoryTitle: Deze applicatie is altijd vereist - exempt: (afmelden) + exempt: afmelden exemptTitle: Deze app is standaard geladen (maar je kunt je afmelden) showMore: "" accept: Aanvaarden diff --git a/src/translations/oc.yml b/src/translations/oc.yml index 2415b1f7..0b4e677f 100644 --- a/src/translations/oc.yml +++ b/src/translations/oc.yml @@ -26,9 +26,9 @@ modal: save: Salvagardar saveTitle: Salvagardar ma configuracion per las informacions collectadas purpose: - mandatory: (tojors requerit) + mandatory: tojors requerit mandatoryTitle: Aquesta aplicacion es totjorn requerida - exempt: (opt-out) + exempt: opt-out exemptTitle: Aquesta aplicacion es cargada per defaut (mas la podètz desactivar) showMore: "" accept: Acceptar diff --git a/src/translations/ro.yml b/src/translations/ro.yml index ab648f3e..9632906b 100644 --- a/src/translations/ro.yml +++ b/src/translations/ro.yml @@ -26,9 +26,9 @@ modal: save: Salvează saveTitle: null purpose: - mandatory: (întotdeauna necesar) + mandatory: întotdeauna necesar mandatoryTitle: Această aplicație este întotdeauna necesară - exempt: (opt-out) + exempt: opt-out exemptTitle: Această aplicație este încărcată în mod implicit (dar puteți renunța) showMore: "" accept: "" diff --git a/src/translations/sv.yml b/src/translations/sv.yml index 9e7c24f4..920ccda0 100644 --- a/src/translations/sv.yml +++ b/src/translations/sv.yml @@ -24,9 +24,9 @@ modal: save: Spara saveTitle: null purpose: - mandatory: (Krävs alltid) + mandatory: Krävs alltid mandatoryTitle: Den här applikationen krävs alltid - exempt: (Avaktivera) + exempt: Avaktivera exemptTitle: Den här appen laddas som standardinställning (men du kan avaktivera den) showMore: "" accept: "" diff --git a/src/ui/components/Main.tsx b/src/ui/components/Main.tsx index 782344db..6608615c 100644 --- a/src/ui/components/Main.tsx +++ b/src/ui/components/Main.tsx @@ -32,7 +32,7 @@ const Main: ForwardRefRenderFunction = (_, ref) => { })); return ( -
+
{isBannerOpen ? ( { return ( - {title} - + {title}{' '} {isMandatory ? ( {t.purpose.mandatory} - ) : null} - + ) : null}{' '} {isExempt ? ( {t.purpose.exempt} - ) : null} + ) : null}{' '} - {description ? (
) : null} -
{children}
);